SDカードとPWMが出来たら、定番のWAV再生を行わない理由は無い。
また、SDカードアクセスのパフォーマンスを測る指針ともなる。
以前にR8Cで、トライした時は、色々な問題にぶつかって、実用性が薄い事
から、あまり深く掘り下げなかった。
・R8Cでは、UARTとSPIが共有している為、どちらか片方しか、利用
する事が出来ず、不満が残る。
※SPIをハードで行い、UARTをソフト処理する事も考えられるが、受信
動作は困難と思われる。
・R8CのPWMでは、コンペアレジスターがバッファされていない為、書き
込んだタイミングと、前の値との組み合わせにより、グリッチが発生する、そ
の為、「プツプツ」とノイズが気になる。
結局、SPIをソフトで処理して、実装してみたが、11.025KHz、8
ビット、ステレオが限界だった・・
これは、かなり微妙な結果だと言うしかない、UARTを諦めて、SPIをハ
ードで扱う事も考えたが、プツプツと発生するノイズ、PWMの仕様上の問題
をナチュラルに解決する方法を思いつけなかったので、中途半端だったが諦め
た。
RL78では、その全てを改善できるであろう事が判っていた、8ビットの
PWM変調に起因する音質以外は、ほぼ満足なものとなると思われる。
早速実装して、音を出してみたら、思った通りの結果だった、PWMのレジス
タ書き換えに起因するノイズも聞こえない、(RL78では、バッファされて
いる)48KHz、16ビット、ステレオのファイルも、難なく再生出来た。
※16ビットの下位8ビットは捨てている。
※つまり、他の処理も考え合わせると、ゆうに200キロバイト毎秒以上の
読み込み速度が出ていると思われる。
※SDカードの速度は次のブログを参照
-----
PWM周期は、8ビットの分解能が必要なので、カウンタのクロックを
16MHzとして、256で割った、62.5KHzとした。
これで、一応48KHzのサンプリング・レートに対応できる。
多少難しい問題として、PWMのサンプルレート、62.5KHzと、ファイル
のサンプリングをどのようにマッチさせるか、この微妙な周期の違いを、簡潔に
解決する方法を考慮する必要がある。
62.5KHz毎に起動する割り込みで、波形値をバッファから取り出して、
PWMのコンペアレジスタに設定している。
バッファのポインター移動は、サンプリング周期/62.5KHzの分数で行い、
小数点以下の誤差が全く出ないように工夫した。
※簡単な整数計算だけで行なえるので、シンプル。
device::TAU01::TDRL = buff_[pos_ + l_ofs_] + wofs_;
device::TAU02::TDRL = buff_[pos_ + r_ofs_] + wofs_;
inc_ += rate_;
if(inc_ >= 6250) {
inc_ -= 6250;
pos_ += skip_;
pos_ &= 1024 - 1;
}
分数計算で、分子が、分母(6250)を超えたら、テーブルのポインターを進
める、また、分子から、6250を引く。
・6250は、62.5KHzの1/10で、「rate_」は、波形ファイルのサン
プリング周波数を1/10にしてある。
※つまり、48KHzなら4800、44.1KHzなら4410、
22.05KHzなら2205となる。
・1/10にするのは、計算レンジを16ビット以内に納まるようにする為の工夫。
・「skip_」は、8ビットモノラルなら「1」、8ビットステレオなら「2」、
16ビットモノラルは「2」、16ビットステレオなら「4」にする。
・8ビットファイルの場合、無音は「0x80」だが、16ビットファイルでは、
無音は「0x0000」となるので「wofs_」で調整する。
・WAVファイルは、リトルエンディアンなので、「l_ofs_、r_ofs_」で、掴む
位置を微調整する。
・バッファサイズは、SDカードの読み込みでは、512バイトの倍数が効率が
良いようなので、ピンポンバッファにする為、倍の1Kバイトとした。
-----
PWM出力は、適当なローパスフィルターを通す事で、アナログ出力を得られる。
今回は、2Kオームと、0.01uFのネットワークとした。
少し贅沢ではあるけども、フルスイング・オペアンプを使って、バッファーを組ん
でみたが、オペアンプを使わず、大きめのカップリングコンデンサを入れただけの
回路でも、問題無いだろう。
※RL78がリセット状態や、停止中は、出力に直流が乗るので注意。
・ターミナルからのコマンドで WAV ファイルを再生する。
・「dir」ディレクトリーリスト
・「play file-name」再生
・「play *」カード内の WAV 形式ファイルを全て再生
・再生中、「<」曲の先頭に戻る、「>」次の曲
・再生中「SPACE」を押す毎に、一時停止、再開
※この写真は、オペアンプを使っていないRCフィルター
RL78/G13 WAV file player サンプル
参考回路とKiCADのプロジェクト:
WAV_Player KiCAD Project