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基板の回路図)
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を接続してみる




■参考になる資料



(追記) 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)回路図やプログラムやデータにバグや欠陥があったとしても、修正や改良の義務を負い ません。