SSブログ

RP2040で音の再生実験 その3 [DCCデコーダ]

 気づいたら、1月も半分が終わっていますね。昨日はトンガの噴火が原因で、携帯から津波注意報が何回も流れていたようですが、私は気づきませんでした。理由は、ハーゲンダッツのラムレーズンを半分食べたのですが、アルコールがきつすぎて、寝込んでいたせいです。
 さて、RP2040での音の再生実験ですが、細々と続けています。(時間はすごいかかっています)
 動画として見せられるようなものはありませんが・・・。
DSC03571.jpg

やることは、
(1)PWMレジスタにDMA伝送する機能の追加。
(2)DMA用のバッファ(0.5秒分x2?)の定義の追加、バッファに書き出す処理の追加(今の割込みごとを、0.5秒分まとめてガツンと書くなど)
(3)LittleFSでのサウンドデータアクセス
でしたが、もちろん全然できていません。

 前回、(3)をやってみたものの、LittleFSでデータアクセスすると、処理量が増えるためか、同時発音が増えるとともに、音が揺れて遅くなるという現象があり、オシロで見ていてもPWM変更の割込みがずれまくります。
 で、原因はタイマーでした。
https://github.com/khoih-prog/RPI_PICO_TimerInterrupt
を使っていたのですが、もしかしたら使い方が悪いだけかもですが、割込みの呼ばれ方が、割込み処理が終了したら、XX us後にまた割込みが入るというもののようで、いろいろと処理が立て込んでくると、音用のサンプリングクロックが遅くなっていたようでした。
 調べていったら、もともとpico SDKにある、repeating_timerで十分で、
https://qiita.com/keyyum/items/3ce448c098c546dced20
に、わかりやすく書いてありましたが、-の値を入れると設定したタイマー周期で呼び出してくれることがわかりました。音も揺れなくなったし、コンパイルのWarningも出なくなったし、早速乗り換えました。
 https://raspberrypi.github.io/pico-sdk-doxygen/group__repeating__timer.html

 メモですが、デバッグしているときに、割込みに時間がどのくらいかかるのかというので、Arduino標準のdigitalWriteを使ってPinに出力を出してオシロで見ていたのですが、RP2040には、gpio_putという高速な命令があります。
一回の時間を計ってみたら、
digitalwrite:672ns
gpio_put:39ns
と17倍速いです。
 というかDigitalWriteを使うと、割込みの時間を計っているつもりがdigitalWriteの時間を計っているような状態になっていました・・・。割込み内の処理(PWMの切り替えとBuffferの切り替え)は
500ns~600nsぐらいで、なんか工夫しないでも十分速いです。

 次に、音のRepeatの話です。Esuと同様のものを目指すなら、音が終了した後に継ぎ目なく、次の音を入れないといけませんが、そこをBufferでとなると、配列のどこからどう入れるかというので、音の継ぎ目が・・・と試行錯誤しながらできました。順序回路で作り直しました。44KHzでも、サイン波のなかに、1個だけ唐突に0とかが入っていると、継ぎ目音として聞こえます。
 ということで、現在、の出来は、
・100ms周期程度のバッファ(Ach,Bchの2ch)
・モノラル同時8音の発声
・44kHz 8bit(DAC(PWMだけど)を10bitとしているので、元音は8bitでよいのかなあと思っている。44kHzなら125MHzなので、11bitぐらいまでなら可能。I2S使うなら16bitも可能かと思うけど)
・同じファイル/違うファイルで継ぎ目のない、継ぎ目再生
が可能となりました。
次は、
・フローファイルに基づいて、音をだす(警笛のStart,Repeat,Endみたいなところ)
・各音のボリューム機能( interp機能でとても速くできそう。)
https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__interp.html
・音階を変える機能(できると、疑似音の和音での遷移ができるが、必要かどうかは不明)
・べた書きしたもののクラス化。
あたりです。

 今回のスケッチになります。
https://desktopstation.net/wiki/lib/exe/fetch.php/timer_test2_752_31.zip
 なお、前回までA0ピンにPWMを出していたのですが、デバッグ中の不注意で12Vを入れてしまい、A0~A3が死んでしまいましたので、現在D4に出しています・・・。
 あと、Core1で実行すると、グダグダになります。(割込みとかも守られないし、それに合わせて音もとぎれとぎれ、・・・。なぜでしょう。)

(1)、(2)のDMA関係はArduinoでのPIOのコンパイル環境がまだなさそうですので、誰かが作ってくれてからにしようかなあと思います。
 
コメント(0) 

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。