読者です 読者をやめる 読者になる 読者になる

ごちゃログ

はなまるデジタル創作紀行(DTM、TAS、いろいろな技術)

ピコカキコ向けに高音質なDPCMを用意する手順(私的メモ)

音楽 音楽-MML

いろいろ試した結果、個人的にはだいたいこうなりました。

リサンプリング等の手順を何度か行うと思いますが、その際の値はピッチ補正値を決めるのに必要になると思うので、メモをしておきましょう。

  1. 変換元サンプルのループポイント以前のサンプルを削除する(先頭サンプルからしかループできないため)
  2. サンプルレートをバイナリエディタで書き換え、変換後の音程(o4程度の低めの音)に設定する
  3. 33143 Hz にリサンプリングする(foobar2000 の Resampler は品質もそこそこで何より手軽に使える)
  4. サンプル数が 32648 サンプルを大幅に超える場合、NiceLoop 等で短いサンプルになるようにトリミングする(アップサンプリング)
  5. DPCMのサンプル長になるよう再度リサンプリングする(※リサンプリングを繰り返してもDPCMの品質に大きく影響する劣化はおそらくない)
  6. 調整の末、とにかくDPCMで扱えるサンプル数にすることと、サンプリングレートを 33143 Hz にすること(MakeDPCM でリサンプリングさせないため)
  7. MakeDPCM で読み込んで変換する。音量(ダイナミックレンジ)が大きいと思うように変換されないので、音量50%あたりに設定する
    • DPCMの仕様上、波形の急激な変化を記録できないので、周波数の高い波形やダイナミックレンジが大きい波形は不利である
    • 音量を下げるほど良いわけでもない。DPCMの仕様上、波形は常に上下を繰り返してノイズを発しているので、信号レベルが下がることはS/N比が下がることにつながる(と思う)
  8. DMC ファイルを base64 に変換して WAV9 定義にする(わたしは 010 Editor という高機能バイナリエディタ(有料)を使用していますが、無料の方法はいくらでもあります)
  9. おしまい(鳴らすついでに音階の限界も調べておくと良いです)

なお、逆に行わないことにしたのは以下です。

  • 変換前のサンプルを予めローパスフィルターで処理することも特に行わない。高域のサンプルはディザリングの代わりにいいように使われてくれると思う(たぶん)
  • 単純波形のようなサンプルであれば、ディザリングが有効かもしれない?(ただ、そのようなサンプルを WAV9 で鳴らすのはそもそもおすすめできない)

そのほか

  • Lコマンドによる補正値を各波形で一律に揃えたい人は、33143 Hz でチューニング済みの音が鳴るようにリサンプリングする。サンプル数の融通が効かないのでループ作成が大変ですが、クロスフェード等でうまく対処しましょう(という感じだと思うのだけど、わたしにはその方針でやる気力はないので、一律にしている人は尊敬します)
    • もっとも、本当にファミコンで使うようなDPCMはそうするほかありません。

関連

Bizhawk - Multitrack recording とは

ゲーム ゲーム-TAS

ホットキー設定の一覧を眺めていると「Multitrack」で始まる項目がいくつかあることに気づきます。これは複数のプレイヤーの入力を個々に入力するための機能です(1フレームずつではなく、もっとまとまった単位で)。ただ、どこにも使い方の説明がなかったので、IRCで聞いてみました。

簡単な例**

  1. 2プレイヤーで NES のムービー記録を開始する。(スロット0とかに)ステートセーブして toggle multiple track キーを押したら、increment/decrement を使ってプレイヤー1に設定して、適当に操作する。
  2. プレイヤー2にインクリメントしてステートをロードする。プレイヤー1のボタンを使うと今度はプレイヤー2が操作されて、プレイヤー1はさっき記録した入力が繰り返される。
  3. increment/decrement はあんまり賢くなくて、5プレイヤーまでハードコードされてるよ。利用可能でないプレイヤーを記録しようとしないでね。

らしいです。

Lua for Windows の LUA_PATH 設定(EmuLua からモジュールを使う)

技術 技術-プログラミング 技術-プログラミング-Lua ゲーム ゲーム-TAS

Lua for Windows には多数のライブラリが含まれていますが、それらをTAS用エミュレータ組み込みの Lua から使おうとしてもロードに失敗します。これはパス設定が適切ではないためです。ロードが成功するようにパス設定を見直しましょう。

このようなタイトルですが、他の環境でライブラリがうまく検索されない場合も同じ解決策を取ることになるでしょう。

環境変数の設定

以下、Lua for Windows v5.1.4-46 についての設定です。

gd.dll などのバイナリモジュールは package.cpath から検索されます。環境変数 LUA_CPATH を設定することで任意のパスを追加できますが、Lua for Windows のインストールでは設定されないようです。よって自前で設定することになります。

LUA_CPATH=;;C:\Program Files (x86)\Lua\5.1\clibs\?.dll

冒頭の ";;" はデフォルトパスを展開するための記述なので、消してはいけません。

Lua モジュールは同様に package.path から検索され、環境変数 LUA_PATH で設定します。一見するとインストール時に設定されるように見えるのですが、拡張子が ?.clua となっているため、*.lua を読み込もうとすると失敗します。よって、こちらも値を変更しなければなりません。

# ?.lua と ?.luac を両方含むように設定する
LUA_PATH=;;C:\Program Files (x86)\Lua\5.1\lua\?.lua;C:\Program Files (x86)\Lua\5.1\lua\?.luac

これで無事にモジュールが使えるようになります。個々のエミュレータディレクトリを汚す必要がなくなるのですっきりしますよ。

MIDI(SMF)→MML変換ツール「PetiteMM」の紹介・アルゴリズム

音楽 音楽-MML

このたび、ごちゃと loveemu さんで PetiteMM という変換ツールを発表しました。開発着手時に「既に優れたツールがあれば開発する必要はないのでは?」と思い各種MIDI2MMLプログラムを比較してみたものの、納得のいくものが見つかりませんでした。

PetiteMM と類似プログラムの性能は比較記事で紹介していますが、PetiteMM は譜面の簡素化と演奏精度の保持を両方がんばっちゃおうという欲張りコンバータです。

インストール・使用方法

PetiteMM からアーカイブファイルをダウンロードして適当なフォルダに展開します。

PetiteMM.bat に MIDI ファイルをドラッグアンドドロップすることで変換が可能です。「'java' は内部コマンドまたは外部コマンド~として認識されていません」と表示される場合、Java のインストールとパス設定が行われていない状態なので、無料Javaソフトウェアをダウンロードしてください。

コマンドオプション

より高度な変換を行う場合、オプション指定を伴うと効果的です。オプションの一覧はバッチファイルをダブルクリックして起動すると表示されます。

PetiteMM.bat の動作時にオプションを有効にしたい場合、PetiteMM.bat をテキストエディタで開き、最初の方にある PMMOPTS 変数にオプションを記述します。

@set PMMOPTS="--dots 2 --no-quantize"

現時点で利用可能なオプションは下記の通りです。

オプション 引数 説明
-o <filename> 出力ファイル名の指定(バッチファイルからは使用しない)
--dots <count> 付点の最大数制限、-1で制限なし(デフォルトは-1)
--timebase <TPQN> MMLの分解能、0でMIDIファイルに合わせる(デフォルトは48)
--input-timebase <TPQN> MIDIファイルの正しい分解能、0なら入力どおり(デフォルトは0、nsf2midiなど特殊用途向け)
--quantize-precision <length> クオンタイズ時の最小ノート長(2のn乗で指定)*1
--no-quantize クオンタイズによるノート長の調整を行わない。タイミングが正確になる代わりに複雑な音符が多くなる。
--octave-reverse オクターブ記号を大小反転する
--use-triplet 三連符らしき箇所を三連符記法に置換する(賢くなく、実用性に乏しい)*2

使い方は以上です。以降は PetiteMM の技術的アプローチに関する説明です。知らなくても特に問題ありませんが、中身を知っているとお望みの変換がしやすくなるかもしれません。

開発動機

既存のツールの出力に満足できなかったので開発しました。

わたしが時々使用していたのは tinymm という簡素なツールだったのですが、連符や細かいタイミングに対応していないため精度は低く、ソースコード非公開のため修正もできませんでした。別のツールを探していくつも試してみたのですが、同じような問題を抱えていたり、複雑なMMLが出力されたりして、満足感が得られませんでした。

  • タイミングのずれを最大限起こさないよう変換する
  • 演奏精度への影響を最小にしつつ、ノートを簡素化して出力する
  • MMLの内部仕様や方言に極力依存せず、幅広く利用できる
  • ソースコードが公開されており、誰でも改変できる

これらを満たしたツールを新たに創造しようとして作られたのが PetiteMM です。

PetiteMM の変換フロー

処理の詳細は後述しますが、以下が変換の主な流れです。

*1:あくまでクオンタイズ時の基準を示すもので、--quantize-precision で16分音符を指定しても、発音タイミングが細ければさらに短い休符等が出現することはある。細かい音符を完全に排除したい場合は --timebase で調整を行う。

*2:--use-triplet を使わない場合でも c12 などの三連符相当の音符は出現する。これを防ぎたい場合は --timebase で3の倍数を指定しなければ良い。

続きを読む

各種MIDI2MMLプログラムを比較してみた

音楽 音楽-MML 技術

このたび、ごちゃと loveemu さんで PetiteMM という変換ツールを発表しました。開発に着手する前「既に優れたツールがあれば開発する必要はないのでは?」と思ったのですが、いくつか探して試した限りでは納得行くものが見つかりませんでした。

そんなわけで、この記事ではサンプルファイル mmldec.mid を各種MIDIコンバータにかけて難癖をつけながら、PetiteMM のステマを行っていきたいと思います。

PetiteMM (2013-09-02)

t128r1
/* 最も変換しやすそうな旋律(ベタ打ち) */
o5c8d8e8f8g4a8f8
e8r8d8r8c4.r8
/* Gate ×0.85 */
c16.r32d16.r32e16.r32f16.r32g8..r32a16.r32f16.r32
e16.r8r32d16.r8r32c3r6
/* Gate -4 */
c16.r32d16.r32e16.r32f16.r32g8..r32a16.r32f16.r32
e16.r8r32d16.r8r32c4.r8
/* 途中で長い休符を挟む */
g8.f16e16r16g16r1
r1
r1
r16
f16r16e16r16d8.r16
/* ベロシティ変更 */
g8.f16e16r16g16r16f16r16e16r16d8.r16
d1
/* 三連符、クオンタイズ変更、休符も入れる */
c6d6e6f16r48g16r48a16r48f16r12r48f16r48
/* 長い音符 */
e16e16e16e16d16r16d16r16c1&c1&c4
r4
/* 拍子変更(試しに小節の区切りをまたぐ) */
c8d8e8f8g8a4
f8e16.r32e16.r32d16.r32d16.r32
c2r4
/* 4分音符±1tick */
c4r4c4r4
/* 付点4分音符±1tick */
e4.r8e4.r8
/* 複付点4分音符±1tick */
g4..r16g4..r16
/* クオンタイズを伴う「中途半端なトラック終了」 */
c16d16e16f16g8a16f16e24r12d24r12c48&c64

変換結果を再生できるようにニコニコ大百科にも置きました。タイを ^ から & に置換してコメントを記入しましたが、それ以外はデフォルト設定で変換した通りの出力です。

クオンタイズのための r32 が少々邪魔に感じられますが、精度を16分音符単位に落とせば取り除くことも可能です。

  • MMLの内容のシンプルさを追求しつつ、クオンタイズを極力損なわないよう休符を挿入します。
    • シンプルさを犠牲にしてタイミングを正確に出力できるオプションも備えています。
  • 仕組み上、連符や短い音符によってトラック間でずれが広がっていくようなことは絶対に起こりません。
  • 細かすぎる音符や付点の数を制御する仕組みがあり、ターゲットの制約に合わせた変換が可能です。
  • SMFフォーマット1で単一チャンネルの演奏を複数トラックに分けている場合、個別トラックで出力します。
  • 拍子情報にもとづいて、小節ごとに改行します。(ただしタイでつながっている音符は改行しない*1
  • tick単位による出力 c%24 などは一切出現しません。
  • 和音のあるトラックは単音のみが変換されます。

改善できそうな点もありますが、なかなか良さそうではないでしょうか! (*>ヮ<*)

開発着手時は「きっと既存のツールだって同等以上の性能があるだろう」と思って探したのですが……。

*1:タイで改行しないのは特別に意図があってそうしたわけでもないです。半ば開発上の経緯的な問題です。

続きを読む

FlMMLでPCエンジンのノイズを再現したいと思ったけど

音楽 音楽-MML

FlMMLPCエンジンのノイズを再現したいと思ったので、周波数からGB音源やFC音源に近似させてみたいと思いました。

REG FRQ(PCE) FRQ(GB) FlMML
0 1804.21 1638.40 o2c+
1 1864.35 2048.00 o2c
2 1928.63 2048.00 o2c
3 1997.51 2048.00 o2c
4 2071.50 2048.00 o2c
5 2151.17 2048.00 o2c
6 2237.22 2340.57 o1b
7 2330.43 2340.57 o1b
8 2431.76 2340.57 o1b
9 2542.29 2730.67 o1a+
10 2663.35 2730.67 o1a+
11 2796.52 2730.67 o1a+
12 2943.71 2730.67 o1a+
13 3107.24 3276.80 o1a
14 3290.02 3276.80 o1a
15 3495.65 3276.80 o1a
16 3728.69 4096.00 o1g+
17 3995.03 4096.00 o1g+
18 4302.34 4096.00 o1g+
19 4660.87 4681.14 o1g
20 5084.58 5461.33 o1f+
21 5593.04 5461.33 o1f+
22 6214.49 6553.60 o1f
23 6991.30 6553.60 o1f
24 7990.06 8192.00 o1e
25 9321.73 9362.29 o1d+
26 11186.08 10922.67 o1d
27 13982.60 13107.20 o1c+
28 18643.47 18724.57 o0b
29 27965.20 26214.40 o0a
30 55930.40 52428.80 o0f
31 111860.80 131072.00 o0d

あれれー。

REG FRQ(PCE) FRQ(NES) FlMML
0 1804.21 1759.85 o1d
1 1864.35 1759.85 o1d
2 1928.63 1759.85 o1d
3 1997.51 1759.85 o1d
4 2071.50 1759.85 o1d
5 2151.17 1759.85 o1d
6 2237.22 1759.85 o1d
7 2330.43 1759.85 o1d
8 2431.76 1759.85 o1d
9 2542.29 1759.85 o1d
10 2663.35 3523.17 o1c+
11 2796.52 3523.17 o1c+
12 2943.71 3523.17 o1c+
13 3107.24 3523.17 o1c+
14 3290.02 3523.17 o1c+
15 3495.65 3523.17 o1c+
16 3728.69 3523.17 o1c+
17 3995.03 3523.17 o1c+
18 4302.34 4697.57 o1c
19 4660.87 4697.57 o1c
20 5084.58 4697.57 o1c
21 5593.04 4697.57 o1c
22 6214.49 7046.35 o0b
23 6991.30 7046.35 o0b
24 7990.06 7046.35 o0b
25 9321.73 9419.86 o0a+
26 11186.08 9419.86 o0a+
27 13982.60 14092.70 o0a
28 18643.47 17720.52 o0g+
29 27965.20 27965.20 o0f+
30 55930.40 55930.39 o0e
31 111860.80 111860.78 o0d+

結構かぶっちゃうんですね。

@4 のノイズはあれはあれで、乱数ステップのタイミングが線形周期じゃないみたいに見えるので、@N の範囲が128段階とはいえ複雑です。

最初鳴らし方を間違えていて「全然違う」と思ったのですが、正しく鳴らしてみたらほどほど悪くはない近似具合でした。

ピコカキコ - WAV9で音階付きメロディ楽器を鳴らす方法・ポイント・仕組み

音楽 音楽-MML

このピコカキコを聴くと、ストリングスの音が綺麗になっています。音階が必要なサンプル波形がどうしてこのように鳴らせるのでしょうか?

FlMMLDPCMLFO をかけると、通常のメロディ波形のように音程が取れるようになります。波形のループも可能です。上記MMLではこの技を使っています。

DPCM 楽器の具体的な使い方

  1. DPCM Converter などで音色の定義を作成(FamiTracker など他のツールでも可、DPCMの制約については後述の「ループ波形を作成する際の注意」も参照)
  2. 音色指定時に下記のように @L を伴って指定する(音量を持続したければ @E1 も忘れずに)
/* 音色指定 */
@9-0 @L3882,0,2 @E1,0,0,350,0

/* 発音テスト */
o4a

/* 波形定義:波形再生ループ時は3番目のパラメータを1にする */
#WAV9 0,64,0,...

/* おまけ:ちなみに、普通に LFO が使いたい場合、音程補正は @D でも NS でも代用可 */
@9-0 @L50,48,0,24,2 @E1,0,0,350,0 @D3882

@L の記述はディチューンと同等です(ただし負数は指定不可)。最初のパラメータは cent 単位の音程指定なので、これを±100して音階を調節します。では下二桁は00で良いのかというとそうではなく、この値は入力サンプルレートに依存します(ただし、後述のとおり自由なサンプルレートが使えるので、下記の表は気にしなくて良いです)。

番号 サンプルレート @L指定値(下二桁) @L指定値(o4a/220Hz基準)
0 4181.71 Hz 02 or 98 298
1 4709.93 Hz 04 or 96 504
2 5264.04 Hz 03 or 97 697
3 5593.04 Hz 02 or 98 802
4 6257.95 Hz 04 or 96 996
5 7046.35 Hz 02 or 98 1202
6 7919.35 Hz 04 or 96 1404
7 8363.42 Hz 02 or 98 1498
8 9419.86 Hz 04 or 96 1704
9 11186.08 Hz 02 or 98 2002
10 12604.03 Hz 08 or 92 2208
11 13982.60 Hz 12 or 88 2388
12 16884.65 Hz 15 or 85 2714
13 21306.82 Hz 17 or 83 3117
14 24857.95 Hz 16 or 84 3384
15 33143.94 Hz 18 or 82 3882

音程の上限としては @L2400,0,2 の場合で o8g+ まで出せるようです。@L3600,0,2 のように補正を1オクターブ上げると、指定可能なノートの上限は o7g+ に下がります。サンプルレートが上がるほど、高い音は出なくなります。

波形あたりのサンプル数は、最大 32647 サンプルです。

高品質な音色を使うポイント「サンプルレート」

上記の情報を元に 33.14 kHz の DPCM を作成しても、波形のノイズ等に満足できないこともあると思います。これを解決するにはさらに大きくサンプルレートを上げてしまいましょう。

解決法はさまざまですが、手軽な方法を一例として紹介します。聞々ハヤえもんで波形を読み込んで、「再生周波数 25.0%」にしたファイルを保存・DPCM変換しましょう。きっと感じがだいぶ変わると思います。(なお、ごちゃ版の DPCMConverter.swf であれば、高サンプルレートのWAVEファイルをリサンプリングなしで変換することも可能です)

サンプルレートを上げることで、品質向上が狙える可能性があります。その理由は2つ。

  • 高域が失われないため、こもった感じがなくなる(一般的なハイサンプリングの利点)
  • ファミコンDPCMは差分を1bit(±1)で記録するため、サンプル同士の変化が激しいと誤差が大きくなり劣化を生む。同じ鳴り方をする波形でも高サンプルレートにすることでサンプル間の差が小さくなれば、誤差が軽減されて音質が改善される可能性がある。
    • DPCMは「変動なし」という情報を記録できないため、サンプル間の差が小さすぎる場合にも振動による誤差が生じる。差が大きすぎる場合に比べて弊害は少ないが、サンプル数を上げれば必ず音質が改善されるとは言えないことに注意。

一方で、下記のようなデメリットがあります。

  • 波形の長さ(秒)はサンプルレートに反比例して短くなります。
  • サンプルレートを上げると音程補正の度合いも大きくなる分、鳴らせる音階の幅はせまくなります。

このあたりの調整は、ひとつの頑張りどころと言えそうです。

任意のサンプルレートを持つ波形が o4a で鳴るようにするための cent 補正値が知りたい場合、下記の式を Google に計算してもらえばOKです。

(log(任意のサンプルレート / 220 / 16) * 1200) / log(2)

DPCM を作成する際の注意(特にループ波形)

下記の点に留意する必要があります。

  • 常に波形の先頭からループする(中間にループポイントは設定不可)
  • 波形サイズは 1+16n バイトでなくてはなりません(ループに関わらず NES DMC の仕様)
    • ピコカキコのプレイヤーはこの制約をちゃんと守っており、余剰バイトは内部で捨てられます。
    • 波形サイズは 1+16n バイトというのは、レート変換後の波形サンプル数が 8+256n でなければならないことを意味します。厄介ですが仕様なので仕方ありません。
  • DPCM がループする際に音量値は初期値に戻らない。つまり1周目と2周目で波形が異なってしまう可能性がある。
  • 最大サイズは $FF1 バイト、サンプル数にして 32648 サンプル。

使用するコンバータはお好みで良いのですが、私見を以下に記します。

  • arche さん作の DPCMConverter.swf には致命的なバグ*1があるので使わないほうが良いです(2013年5月2日時点)。また、DPCMのサイズ境界(1+16n)も考慮されていないため、末尾のサンプルが消失してしまう問題も抱えています。本記事でリンクしているバージョンはいずれも修正済であるため問題ありません。
  • 細かい違いはありますが、FamiTracker (PCMImport.cpp) と DMCconv の変換処理はほぼ同等です。FamiTracker の方が高品質なリサンプリングを行う。どちらも入力サンプル数が8で割り切れない場合は余った末尾サンプルを捨てます。どちらも最初の出力サンプルは初期値になりません(初期値同士を比較して符号化しているため)。

ポイントをまとめると以下のようになります。

  • バグがある DPCMConverter.swf は使わない。あとは各自の好みでOK。
  • ループ波形は長さを 8+256n サンプルにしなければならない。
  • ループ波形は1周目と2周目で異なる波形を出力しうる。波形の終端で音量が大きく元に戻らない場合、波形終端をフェードアウトしたり、サンプルレートを上げたりすることで収束しやすくなるかもしれない。
  • 変換前にLPFをかけておくと、波形が滑らかになってDPCM変換向きになる可能性がある(眉唾)

おまけ:LFO で音階利用の仕組み周り

本来、WAV9 の DPCM は指定するノートによって16段階の周波数で発音できます(周波数は表にもとづいていて、音程差は均等ではない)。LFO コマンドを使うとリアルタイムで再計算が必要になる都合により、周波数の計算が他の波形と同じような形になります。具体的にソースコードで言うと、普通は MOscFcDpcm.as の setNoteNo() で周波数が決まるところを、LFO が setFrequency() によって周波数を書き換えてしまいます。一般的な波形では o5a を 440 Hz で再生しますが、setFrequency() では値を16倍しているため、WAV9 では o5a が 7040 Hz で鳴ります。

LFO の内容は長さ0の三角波です。長さ0なので振動しません。仕様的に三角波の変位は0から開始ではないため、指定した音程の変化が即時に行われるわけです。

これがわかれば、あとはひたすらどのように高品質な波形を用意するかが問題だと思います。上記の通り気をつけなければいけないことが多々ありますが、がんばるしかないです。

何か素敵な技がありましたら、ぜひぜひおしえてください。 (ノヮ=*)

おまけ:DPCMのサンプル長

Bytes Samples
$001 8
$011 136
$021 264
$031 392
$041 520
$051 648
$061 776
$071 904
$081 1032
$091 1160
$0A1 1288
$0B1 1416
$0C1 1544
$0D1 1672
$0E1 1800
$0F1 1928
$101 2056
$111 2184
$121 2312
$131 2440
$141 2568
$151 2696
$161 2824
$171 2952
$181 3080
$191 3208
$1A1 3336
$1B1 3464
$1C1 3592
$1D1 3720
$1E1 3848
$1F1 3976
$201 4104
$211 4232
$221 4360
$231 4488
$241 4616
$251 4744
$261 4872
$271 5000
$281 5128
$291 5256
$2A1 5384
$2B1 5512
$2C1 5640
$2D1 5768
$2E1 5896
$2F1 6024
$301 6152
$311 6280
$321 6408
$331 6536
$341 6664
$351 6792
$361 6920
$371 7048
$381 7176
$391 7304
$3A1 7432
$3B1 7560
$3C1 7688
$3D1 7816
$3E1 7944
$3F1 8072
$401 8200
$411 8328
$421 8456
$431 8584
$441 8712
$451 8840
$461 8968
$471 9096
$481 9224
$491 9352
$4A1 9480
$4B1 9608
$4C1 9736
$4D1 9864
$4E1 9992
$4F1 10120
$501 10248
$511 10376
$521 10504
$531 10632
$541 10760
$551 10888
$561 11016
$571 11144
$581 11272
$591 11400
$5A1 11528
$5B1 11656
$5C1 11784
$5D1 11912
$5E1 12040
$5F1 12168
$601 12296
$611 12424
$621 12552
$631 12680
$641 12808
$651 12936
$661 13064
$671 13192
$681 13320
$691 13448
$6A1 13576
$6B1 13704
$6C1 13832
$6D1 13960
$6E1 14088
$6F1 14216
$701 14344
$711 14472
$721 14600
$731 14728
$741 14856
$751 14984
$761 15112
$771 15240
$781 15368
$791 15496
$7A1 15624
$7B1 15752
$7C1 15880
$7D1 16008
$7E1 16136
$7F1 16264
$801 16392
$811 16520
$821 16648
$831 16776
$841 16904
$851 17032
$861 17160
$871 17288
$881 17416
$891 17544
$8A1 17672
$8B1 17800
$8C1 17928
$8D1 18056
$8E1 18184
$8F1 18312
$901 18440
$911 18568
$921 18696
$931 18824
$941 18952
$951 19080
$961 19208
$971 19336
$981 19464
$991 19592
$9A1 19720
$9B1 19848
$9C1 19976
$9D1 20104
$9E1 20232
$9F1 20360
$A01 20488
$A11 20616
$A21 20744
$A31 20872
$A41 21000
$A51 21128
$A61 21256
$A71 21384
$A81 21512
$A91 21640
$AA1 21768
$AB1 21896
$AC1 22024
$AD1 22152
$AE1 22280
$AF1 22408
$B01 22536
$B11 22664
$B21 22792
$B31 22920
$B41 23048
$B51 23176
$B61 23304
$B71 23432
$B81 23560
$B91 23688
$BA1 23816
$BB1 23944
$BC1 24072
$BD1 24200
$BE1 24328
$BF1 24456
$C01 24584
$C11 24712
$C21 24840
$C31 24968
$C41 25096
$C51 25224
$C61 25352
$C71 25480
$C81 25608
$C91 25736
$CA1 25864
$CB1 25992
$CC1 26120
$CD1 26248
$CE1 26376
$CF1 26504
$D01 26632
$D11 26760
$D21 26888
$D31 27016
$D41 27144
$D51 27272
$D61 27400
$D71 27528
$D81 27656
$D91 27784
$DA1 27912
$DB1 28040
$DC1 28168
$DD1 28296
$DE1 28424
$DF1 28552
$E01 28680
$E11 28808
$E21 28936
$E31 29064
$E41 29192
$E51 29320
$E61 29448
$E71 29576
$E81 29704
$E91 29832
$EA1 29960
$EB1 30088
$EC1 30216
$ED1 30344
$EE1 30472
$EF1 30600
$F01 30728
$F11 30856
$F21 30984
$F31 31112
$F41 31240
$F51 31368
$F61 31496
$F71 31624
$F81 31752
$F91 31880
$FA1 32008
$FB1 32136
$FC1 32264
$FD1 32392
$FE1 32520
$FF1 32648

*1:DACは7bitだが、波形の変動は下位1bitを無視した6bitの範囲で行うのが正しい。しかし、arche さんのコンバータは単なる7bitで扱っているため、内部で想定する波形がまったく異なってしまう。