先日書いた、
の続編でぇす.
今回が最終回でぇす.挫折して撤退でぇす.
前回の最後にこのように書いた.
抜本的解決策は、2本のbufferを交互にDMAでI2Sへ流し込むようにするしかないかしらね?
keywordはDMAだっっ!
I2Sライブラリのsourceを読んでみたら、I2SライブラリがDMA対応になってるの.
すなわち、I2S DACに向けて音声データを送信するには2つの関数が用意されている.
1) I2S.write( 変数 );
2) I2S.write( バッファ、 サイズ );
1は逐次送信するので非DMAである.2はDMAで送信してくれるのだ.あらラッキー!
さっそくDMAでsine波を生成するようにしてみたのがこれ.
ところがsine波形がブチブチ切れてしまってダメだった.
ブチブチの原因はAruduino M0の計算速度が遅いことだった.
計算速度への期待としては、48kHz/LRchをon the flyでsin()演算できてほしかった.しかしそうはいかなかった.
ブチ切れsine波はこんな状況だ.
解説する.
①は、fs=16kHz、32 sample bufferによってDACから出力されたsine波で、約2msのバースト状になってしまっている.連続波であって欲しいところだが.
②は、ArduinoがDMAを起動するまでの諸手続きに要する時間で1msぐらい.DMA起動routineからは瞬時にreturnしてくれているのでそこは律速ではないと確認済み.
③が問題である.たかが32個のbufferを埋めるためのsin()演算に8.6mSもかかっているのだ.SAMD21 CPUの仕様は知らないけれど、浮動小数点演算moduleとか載ってないのだろうな.これじゃぁon the flyでsine波を生成させるのは無理だと思う.
deep bufferにあらかじめsine dataを記憶させておく手も使えそうにない.RAMサイズが小さすぎるからだ.
というわけで、Aruduino M0とI2S DACで様々な関数波形を出そうという取り組みは挫折撤退となったのであった.
#またひとつ rapsberry piが偉く思えてきた ♪
エイメン
0 件のコメント:
コメントを投稿