Raspberry Piを使ってI2S DACのTDA1543の音楽再生
Raspberry Piを使ってI2S出力をしている記事を見かけたので、実際に、自作のI2S DACのTDA1543基板を Raspberry Pi Type B基板につないで、I2S出力が動いて音がでるかどうかの実験してみた。
カーネルイメージの 2014-01-07-wheezy-raspbianを使うと、2種類のI2S DAC基板用のモジュール
HifiBerry DAC ----- hifiberry_dac.c / pcm5102a.c ICの内部にPLLがありマスタークロックが不要。
RPi-DAC -----
rpi-dac.c
/pcm1794a.c PCM_CLK(BCK)が64fsの固定になっている。マスタークロックが必要(補注)。
が入っているので、カーネルの再構築(コンパイル)は不要である。 ちなみに、カーネルソースもインストールした環境では、
/usr/src/linux/sound/soc/bcm/hifiberry_dac.c
/usr/src/linux/sound/soc/codecs/pcm5102a.cにある。
TDA1543は16ビットで4倍速対応のDACなので、 hifiberry_dac/
pcm5102aのモジュールを使って動かすことにした。 rpi-dac / pcm1794a
だと PCM_CLK(BCK)が高速すぎて TDA1543がついていけなくなる可能性があったためだ。 hifiberry_dac/
pcm5102aのモジュールを使って サンプリング周波数(fs)44.1KHz, 48KHz, 96KHz,192KHz の wav
ファイルが再生することを、(表示上では)確認できた。
/etc/modules の中身は以下のようになっている。
snd-bcm2835
i2c-dev
snd_soc_bcm2708 <--- 実際にはこれは存在していない。lsmod しても出てこない。
snd_soc_bcm2708_i2s
bcm2708_dmaengine
snd_soc_pcm5102a
snd_soc_hifiberry_dac
#snd-soc-pcm1794a
#snd-soc-rpi-dac
(自作のI2S DACのTDA1543基板の回路図)
(S24_3LE から S24_LE への変換)
24bitのwavファイルを再生しようとして 問題に遭遇した。
どうやら このモジュールは、 4バイト長の24ビットデータ(S24_LE)のwavしか扱っておらず、 3バイト長の24ビットデータ
(S24_3LE)のwavを再生しようとすると、エラーまたは 2バイト長の16ビット(S16_LE)データに変換されてしまうようだ。これでは、
せっかくの24ビット精度の音楽データの意味がなくなってしまう。
ALSAの設定の .asoundrc の中で plugin でwavのフォーマット変換(S24_3LE ->
S24_LE)できそうに見えたので 色々試してみたが 結局 上手く行かなかった。 そこで、暫定的に、windows上で動くフォーマット変換(S24_3LE -> S24_LE)ソフトを作ってみた。
S24_3LE ---- 24bit データを3バイトで扱うフォーマット、無駄がない。
S24_LE -----24bitデータを4バイトで扱うフォーマット。32ビットデータの下位の24ビット分が有効なデータと解釈するようだ。 ちなみに、windows上でCDからWAVを作るとS16_LEになる。
(補足)
その後、新しいソースでモジュールをmakeしたところ, S24_LEは再生できなくなったしまった。
pcm5102a.cの中身を見ると
// SNDRV_PCM_FMTBIT_S24_LE | : disable for now, it causes white noise with xbmc
となっており、S24_LEは対象外になっている。このコメントアウトをはずしても、もとに戻らない?
その代わり、aplayに変換機能を追加した aplayexを見つけた。これにより、S24_3LEも再生できるようになった。
aplayexはソースをダウンロードして Piの中でmakeして作成したものを使っている。
(補足2)
aplay(ex)ではボリュームがないので、wavファイルを入力して ボリューム処理をおこなって標準出力に出す、プログラムwavvを作ってみた。
また、出力には32ビット(S32_LE)も選べるように作ってみた。
(Linux上のコマンドのメモ)
aplay -vD hw:1,0 ***.wav ***.wavファイルを指定して I2S 出力から再生する。
aplay -vD hw:1,0 test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Hardware PCM card 1 'snd_rpi_hifiberry_dac' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 16
aplay -vD hw:1,0 test24LE.wav <--- フォーマット変換(S24_3LE -> S24_LE)したwavファイル
Playing WAVE 'test24LE.wav' : Signed 24 bit Little Endian, Rate 44100 Hz, Stereo
Hardware PCM card 1 'snd_rpi_hifiberry_dac' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S24_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 32 <--- データ長さは32ビットでるが、有効データは24ビット
aplay -vD hw:1,0 test192K.wav
Playing WAVE '6_1920R.wav' : Signed 16 bit Little Endian, Rate 192000 Hz, Stereo
Hardware PCM card 1 'snd_rpi_hifiberry_dac' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 192000
exact rate : 192000 (192000/1)
msbits : 16
aplay -l 接続されているサウンドカードが表示される。 I2S用はカード1番になる。
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
aplayexを使って96KHzサンプリングのwavファイルを再生した場合の表示
$ ./aplayex -vD hw:1,0
96_24.wav <---
頭に ./ をつけて このディレクトリーにあるaplayexを実行している。
Playing WAVE '96_24.wav' : Signed 24 bit Little Endian in 3bytes, Rate 96000 Hz, Stereo
I/O format is "signed 24bit Little Endian in 3bytes format".
Device format is "signed 32bit Little Endian".
Hardware PCM card 1 'snd_rpi_hifiberry_dac' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 96000
exact rate : 96000 (96000/1)
msbits : 32
buffer_size : 48000
period_size : 12000
period_time : 125000
tstamp_mode : NONE
period_step : 1
avail_min : 12000
period_event : 0
start_threshold : 48000
stop_threshold : 48000
silence_threshold: 0
silence_size : 0
boundary : 1572864000
appl_ptr : 0
hw_ptr : 0
また、flacファイルを再生する場合、例えば、test.flacをデバイス hw:1,0で再生する場合
flac -d test.flac -c | ./aplayex -vD hw:1,0
のように標準入出力のパイプを介してできるようである。サンプリング周波数96KHz24ビットのsin波形をデフォルトの圧縮率でflacエンコードしたものが再生できた。
Raspberry PiにI2SのADCを接続してみる
■参考になる資料
- aplayex ビット長とエンディアンの違いを変換して、 再生できるようにするaplayです。 サンプリング周波数とチャネル数の違いは、変換できません。
- aplayexのコンパイル: alsa-project-pub-utils aplayerなどのソースが置いてある中から、今回は、Piの中の/usr/include/alsa/version.hヘッダーファイルのバージョンと同じalsa-utils-1.0.25.tarを使って/configureをして準備した。次に、オリジナルの aplayが問題なくmakeできることを確認する。 aplayexのページの中の aplayex_src をダウンロードしたものを展開してmake するとaplayex ができる。
- Libsamplerate サンプリング周波数変換ソフト。 Piでどの程度の変換処理が可能かどうか試してみた。
(追記) Raspberry Pi2 のI2S端子 Pi2でも、I2S
DACから音が出ることを確認してみた。昔のPiからコネクター配置が変更になっていて、カーネルイメージがARM7対応?(kernel7.img)に
なっているので、昔のPi用のカーネルイメージではそもそも動かない(Pi2とそれ以前用に2種類のカーネルイメージが存在する)。昔のPi基板上では
カーネルの再構築に10時間ぐらいかかったが、Pi2基板では2時間ぐらいでモジュール含めてビルドできる(make -j 6
マルティスレッドのオプションを使って4コアすべて動かす)。 気のせいかもしれないが、基板上のヘッドホン出力からの音も安定したみたい、昔はノイズが
ひどかった。
■
警告
PI基板をつかって接続する場合は、電気的なことをよく理解した上でお
使いください。そうしないと、PI基板と接続した相手などを破壊する危険があります。
■免責
(1)回路図やプログラムやデータの使用により、使用者に損失が生じたとしても、その責任
を負いません。
(2)回路図やプログラムやデータにバグや欠陥があったとしても、修正や改良の義務を負い
ません。