マイコン工作実験日記

Microcontroller を用いての工作、実験記録

ABDACBから音を出す

2013-06-15 19:32:41 | SAM4
SAM4LにはDACCという通常のD/A変換器機能も用意されています。ABDACBはオーディオ用となっているのですが、それでは何がオーディオ用に違っているのかという点についてまずは書いておこうと思います。

DACCは10bit, 1チャンネルですが、ABDACBはひとつで16bit, 2チャンネル。ABDACBではDAC/DACNのコンプリメンタリ出力が可能となっており、音量調節機能も用意されています。前記事で書いたように、LPFを介してアンプを接続することができます。サンプリング周波数としては、8000Hzから44.KHz, 48KHzまでをサポートしていますので、電話の音声通話からCD/DVDクオリティの音楽再生データを扱うことができます。

さらにオーディオ用にオーバサンプリングの機能を有しているのが、通常のDACであるDACCとの大きな違いです。基本的に128倍の周波数でのアップサンプリングによる元データの補間をおこなうことができます。USB用のクリスタルを使えるように、125倍や136倍のアップサンプリングを使用するモードも用意されています。今回の基板ではすでに、12MHzのクリスタルを実装済みですので、このモードを使用することにします。

ABDACBもDMAが使えますので、IISCから受信したオーディオデータをいったんメモリに蓄えて、それをそのままABDACBにDMA送信してやれば、それだけで再生が可能です。もちろん、IISCで受信するデータとABDACBで送信するデータの形式が同一になっていなければなりません。今回はどちらも16bitのコンパクト・ステレオ形式を使いました。この形式では32bitワードのなかに左チャンネル16bitと右チャンネル16bitをまとめて入れてワード単位で転送します。いっぺんに、2チャンネル分の転送ができてしまうので、DMAチャネルもひとつしか使わずに済みます。

このようにDMA転送するだけで再生できるので、CPUにはほとんど負荷かかりません。しかしながら、今回の方式にはひとつ大きな問題があります。それはクロックの同期がとれていないことです。IISCはスレーブ動作となっているので、44.1kHzオーディオデータはWT32側が出力するマスタークロックに同期して受信されます。一方、ABDACBも44.1kHzのサンプリングレートで、データを送信しますが、こちらはGCLK6で生成される48MHzを元に動作します。この2つのクロックの同期がとれていれば問題無いのですが、全く独立に動いているために受信と送信のペースが同じにはなりません。特にABDACBではオーバサンプリング・クロックとして本来であれば、47.9808MHzが必要であるところを、48MHzで済ませています。そのために、送信のペースがちょっと早めになってしまいます。どのくらい早いかを、もう少し具体的に確認してみましょう。

47.9808Mhzという周波数は、44.1Khzを8 ×136倍した数字です。本来であれば、このクロックを8 ×136で割ることで、44.1KHzのサンプリング周波数を得て、そのタイミングでデータを送信すべきです。このクロックが48MHzになると...

48000000 / 8 / 136 = 44117.647

となり、毎秒17, 18サンプルも多く送信してしまうことになります。



この問題に対処するために、IISCで受信したデータはいったんバッファ・キューにためて、送信処理はこのキューからバッファを取り出しながら行うこととしました。キューの残りが少なくなったらならば、ABDACBに送信すべきサンプルデータをひとつ重複させることで送信ペースを落としてやります。この処理を追加して、音楽を再生してみた時の様子が次のログです。



送受信は128サンプル単位でおこなっています。Normalが通常の128サンプル単位で送信した回数、slowerが速度調整のために、1サンプル加えた129サンプル単位で送信した回数です。およそ10秒間でslowerが200から210程度増えるようです。予想よりちょっと多めですがクロック速度誤差の影響かな? 実際に音楽を聞いてみると、もちろんちゃんと聞こえます。これでいいような気がしたのですが、試しにサイン波を再生してみると、"バサバサ"というノイズが入っているのがはっきりとわかります。つじつま合わせで1サンプル追加している影響でしょうか?うーん、困ったなぁ。

秋月に24.576MHzのクリスタルがあるようなので、こいつにクリスタルを交換すれば少しは改善されるかもしれません。試してみようかなぁ。でも、これをやってしまうと、今度はUSB用の48MHzをどうやって作るかを考えねばなりません。