レトロな音源にSCCなどの波形メモリ音源がありますが、そのちょっと豪華版を作ってみました。
仕様は以下の通り。
波形は8ビットx32サンプル
左右独立ボリューム(256段階)
サンプル間の補間あり(1/128サンプル単位)
同時発音数は64で、それぞれ独立に256音色の中から選べます。
波形にメモリを使わないPSGモードもあり、矩形波(デューティ比1/2,1/4,1/8)、三角波から選べます。
今回は、マイクロSDカードとスピーカーがあれば試せるようにTang Console 60k用に作りました。
使用する波形は、自作FM音源
https://github.com/kwhr0/FM-tone-generator
の出力を元に生成しました。
32サンプルで1周期になるように、fs=48kHzなら基音=1.5kHzで発音し、
全てのキャリアがサステインに移行し、さらに0.1秒経過した部分から32サンプルを取得します。
品質を向上させるため、以下のような処理をしています。
DCオフセットをキャンセルするため、32サンプルの平均値が0になるようにオフセット
アタックが急峻な場合にクリックノイズになるので、0に最も近いサンプルから始まるようにローテート
全音色の中で最大のものがフルスケールになるようにスケーリング
カード読み出し、MIDI解釈、サウンドドライバを担当するのはレトロっぽくMC6800バイナリ互換の
https://github.com/kwhr0/f6800wide
を使用しました。コンパイラは
https://github.com/zu2/chibicc-6800-v1
を使いました。
クロックについて:
1音の処理に8クロックかかるので、64音で512クロックかかります。
fs=96kHzだと49.152MHzが必要になります。
それよりちょっと低いのですが48MHzに設定しています。
マイクロSDカードは、FAT32でフォーマットし、ルートディレクトリにMIDIという名前のディレクトリを作ります。
その中にSMF0フォーマット、拡張子.MIDのファイルを入れておきます。階層ディレクトリもOKです。
表示・キー入力はUSBシリアルで行います。
Macの場合はコマンドラインで
screen /dev/tty.usbserial-*1 115200
とします。
操作は、主にテンキーを使うことを想定しています。
/ 一つ後に
= 一つ前に
- ボリューム下げる
+ ボリューム上げる
enter 再生/ディレクトリ下に
* 停止/ディレクトリ上に
他に、頭文字でそこに移動する機能があります。
以下のようなコンフィグが可能です。
アッテネータの調整
発音がオーバーフローする場合はクリッピングしているので歪みます。そのような場合はwtsg.vの
localparam ATT = 3;
を一つずつ大きくしてみて下さい。
PSGモード
snd.cの
#define WAVE 1
を0にし、wtsg.vの
localparam WAVE = 3;
を0にします。
ステレオモード
Tang Consoleはモノラルですが、ハードを追加するなどしてステレオにする場合はsnd.cの
#define STEREO 0
を1にします。
https://github.com/kwhr0/wavetable-tone-generator