STM32F4DISCOVERYでWAV再生
こんばんは。
STM32F4DISCOVERYに載っているオーディオコーデック(アンプ付DAC)CS43L22の
音質を確かめてみたかったのでwav再生を試してみました。
○ソフト
STマイクロのファームウェアの中にあるCS43L22のAPIサンプルと、
MMCをFatFsから読み出せるように移植されたねむいさんのライブラリを使わせて頂きました。
プログラムの構成は以下のようになっています。
1.DMAをサーキュラーモードに設定してバッファ全体をSDカードから音声データで埋める。
2.I2Sはコーデックへの送信前にDMAへリクエストを送り、バッファからからデータを受け取る。
3.I2Sはサンプリング周波数の周期でコーデックに音声データを送信。
4.バッファの半分、もしくは全てが送信されるとDMAが割り込みを発生させる。
5.割り込み時にバッファへ半分ずつSDカードからデータを埋める。
6. 2~5を繰り返す。
○嵌ったポイント
1.DMAのバッファサイズ
STのライブラリの関数「Audio_MAL_Play」ではI2Sインターフェイス時のDMAバッファサイズの設定が
Size /2 となっています。
しかし引数の「Size」は4バイトで、DMA送信サイズが2バイトなので、DMA_BufferSize=(データ転送回数)はSize×2としなければいけません。
ここを変更しなければデータ転送がバッファの一部だけになって、まともに音楽が再生できません。
1517行目が修正箇所
2.I2S_PLLの設定
サンプリングレートに応じたI2Sクロックを設定する為にはerrorの低いI2S_PLLの設定値が必要です。
パラメータが多いので手計算では難しいのですが、pcm1723さんが
計算用プログラムを公開されていたので使わせて頂きました。
結果を載せておきます。
基準周波数1MHz HSE=8MHz, PLLM=8)
そこでループを小さくする為にC28に電源を直接配線しました。

ノイズが小さくなったのが分かるでしょうか?
3.SPI周波数の変更
最後にSDカードのSPIの信号ノイズが小さくなるように必要最低限までSPIの周波数を下げました。
STM32F4DISCOVERYに載っているオーディオコーデック(アンプ付DAC)CS43L22の
音質を確かめてみたかったのでwav再生を試してみました。
○ソフト
STマイクロのファームウェアの中にあるCS43L22のAPIサンプルと、
MMCをFatFsから読み出せるように移植されたねむいさんのライブラリを使わせて頂きました。
プログラムの構成は以下のようになっています。
1.DMAをサーキュラーモードに設定してバッファ全体をSDカードから音声データで埋める。
2.I2Sはコーデックへの送信前にDMAへリクエストを送り、バッファからからデータを受け取る。
3.I2Sはサンプリング周波数の周期でコーデックに音声データを送信。
4.バッファの半分、もしくは全てが送信されるとDMAが割り込みを発生させる。
5.割り込み時にバッファへ半分ずつSDカードからデータを埋める。
6. 2~5を繰り返す。
○嵌ったポイント
1.DMAのバッファサイズ
STのライブラリの関数「Audio_MAL_Play」ではI2Sインターフェイス時のDMAバッファサイズの設定が
Size /2 となっています。
しかし引数の「Size」は4バイトで、DMA送信サイズが2バイトなので、DMA_BufferSize=(データ転送回数)はSize×2としなければいけません。
ここを変更しなければデータ転送がバッファの一部だけになって、まともに音楽が再生できません。

2.I2S_PLLの設定
サンプリングレートに応じたI2Sクロックを設定する為にはerrorの低いI2S_PLLの設定値が必要です。
パラメータが多いので手計算では難しいのですが、pcm1723さんが
計算用プログラムを公開されていたので使わせて頂きました。
結果を載せておきます。

基準周波数2MHz (HSE=8MHz, PLLM=4)

○音量の調整
サンプルの設定では音量が物足りなく感じました。
「Codec_Init」内の設定を以下のように変更しました。
PCMボリュームは最大値にしています。
Headphone Analog Gainはまだ大きく出来ますがデータシートで音質に影響が出ると
警告があったので影響のない範囲で一番大きな値にしました。
この設定でMasterVolumeを最大にしましたが、残念ながらまだ音量が物足りなく感じました。
CS43L22のチップサイズから見てこれが限界なのでしょうか。
実用レベル以下なので、何か設定が間違っている可能性が高いと思います。
もしも、音量をさらに上げられる設定をご存知の方が居たら教えてもらえると非常に助かります。
音量調整できました! 音質改善の最後に追記しています。
○視聴と音質の改善
1.改善前
聞きながらノイズが気になったので何度か改善を試みました。
まず、電源をUSBからリニア電源へ変更して再生した音楽を録音したものがこちらです。
使用曲はgoing_on (44.1kHz 16bit ステレオ)。
サンプルの設定では音量が物足りなく感じました。
「Codec_Init」内の設定を以下のように変更しました。
PCMボリュームは最大値にしています。
Headphone Analog Gainはまだ大きく出来ますがデータシートで音質に影響が出ると
警告があったので影響のない範囲で一番大きな値にしました。

この設定でMasterVolumeを最大にしましたが、残念ながらまだ音量が物足りなく感じました。
CS43L22のチップサイズから見てこれが限界なのでしょうか。
実用レベル以下なので、何か設定が間違っている可能性が高いと思います。
もしも、音量をさらに上げられる設定をご存知の方が居たら教えてもらえると非常に助かります。
音量調整できました! 音質改善の最後に追記しています。
○視聴と音質の改善
1.改善前
聞きながらノイズが気になったので何度か改善を試みました。
まず、電源をUSBからリニア電源へ変更して再生した音楽を録音したものがこちらです。
使用曲はgoing_on (44.1kHz 16bit ステレオ)。
そこでループを小さくする為にC28に電源を直接配線しました。

ノイズが小さくなったのが分かるでしょうか?
3.SPI周波数の変更
最後にSDカードのSPIの信号ノイズが小さくなるように必要最低限までSPIの周波数を下げました。
SPI2のBaudRatePrescalerを2→16へ
小さくなったとはいえ、まだ聞こえますね。
4.音量の調整
ホワイトノイズが主たるノイズですので、出力にシリアルに抵抗を繋げてS/N比を改善したいのですが、
CS43L22が出力できる最大音量が小さいので、抵抗で出力を抑えると音楽が小さくなってしまいます。
追記:音量が小さくなっていた原因が分かりました。
STのライブラリの初期設定と音量の設定関数は下記のような
ユーザーが設定したボリュームを変更するマクロが挿入されています。
このVOLUME_CONVERTマクロによって100を超える設定値は全て100になっていたのです。
設定値100以下の場合は100分率で最大255に変換するマクロで、
このマクロの存在を知らなかった自分は255を設定してしまっていたという事でした。
設定値を100に変更したところ非常に大きな音が鳴りました。(耳が痛い!)
大体50程度が通常の音量だと思います。
改めて録音しました。非常にいい音になっています!
小さくなったとはいえ、まだ聞こえますね。
ホワイトノイズが主たるノイズですので、出力にシリアルに抵抗を繋げてS/N比を改善したいのですが、
CS43L22が出力できる最大音量が小さいので、抵抗で出力を抑えると音楽が小さくなってしまいます。
追記:音量が小さくなっていた原因が分かりました。
STのライブラリの初期設定と音量の設定関数は下記のような
ユーザーが設定したボリュームを変更するマクロが挿入されています。

設定値100以下の場合は100分率で最大255に変換するマクロで、
このマクロの存在を知らなかった自分は255を設定してしまっていたという事でした。
設定値を100に変更したところ非常に大きな音が鳴りました。(耳が痛い!)
大体50程度が通常の音量だと思います。
改めて録音しました。非常にいい音になっています!
設定を調整して音量UP
5.抵抗の挿入(アッテネータ)
録音した音楽ではほとんど聞こえないのですが、実際にイヤホンを付けて聞いていると
ホワイトノイズがまだかすかに聞こえます。
対策としてDISCOVERYボードの出力に直列に抵抗を挿入する事にします。
ボリュームに関わらずホワイトノイズは一定ですので、抵抗でホワイトノイズを含む
全体の音量を下げた後ボリュームを上げればホワイトノイズを抑える事が出来ます。
DISCOVERYボードの改造はパターンの配線上難しかったので
ステレオジャックから自作のアッテネータを中継してイヤホンに接続するようにしました。
アッテネータといっても、各チャンネルの入出力間に47Ωを経由させるだけのものです。
録音しました。
ホワイトノイズは完全に消えています。
直列に抵抗を挿入すると若干周波数特性が変化しますが、自分は許容範囲内でした。
5.抵抗の挿入(アッテネータ)
録音した音楽ではほとんど聞こえないのですが、実際にイヤホンを付けて聞いていると
ホワイトノイズがまだかすかに聞こえます。
対策としてDISCOVERYボードの出力に直列に抵抗を挿入する事にします。
ボリュームに関わらずホワイトノイズは一定ですので、抵抗でホワイトノイズを含む
全体の音量を下げた後ボリュームを上げればホワイトノイズを抑える事が出来ます。
DISCOVERYボードの改造はパターンの配線上難しかったので
ステレオジャックから自作のアッテネータを中継してイヤホンに接続するようにしました。
アッテネータといっても、各チャンネルの入出力間に47Ωを経由させるだけのものです。
録音しました。
ホワイトノイズは完全に消えています。
直列に抵抗を挿入すると若干周波数特性が変化しますが、自分は許容範囲内でした。