Raspberry Pi I2S 出力 24bit 48kHz 再生

公式フォーラムではこのドライバをちょこっと修正で192kHzでも再生出来た~って書き込みがありますね。

じゃ~試してみよう!...と、思っても192kHzなデータは持ってません。
そんなわけで24bit 48kHzを試してみました。
PCM1716を使えるようにしたのもこれを試したかったからなのよね~(´―`)

ちなみに何もドライバを修正せずに48kHzの音楽を鳴らしてみるとハングアップしてしまいます。
電源をOFFにするしかない状態です。( ̄~ ̄;)

修正前にちょっと準備します。
クロスコンパイル環境でコンパイルしてもいいのですが、何度も「コンパイル > RPiに転送」は面倒くさいので RPi 上でドライバだけコンパイル出来るようにします。
https://github.com/koalo/linux
からソースコードの linux-rpi-3.8.y-asocdev.zip をダウンロードし、/usr/src に展開します。
ディレクトリ名は 3.8.10+ とでもしておきます。
既にクロスコンパイル環境で作成したカーネル 3.8.10+ で起動しているものとします。
cd /usr/src/3.8.10+
zcat /proc/config.gz > .config
make oldconfig
make modules_prepare
クロスコンパイル環境から Module.symvers を RPi の /usr/src/3.8.10+ へコピー
これでドライバのコンパイル準備完了です。

まずは /usr/src/3.8.10+/sound/soc/bcm2708/bcm2708-i2s.c 420行目辺りを修正します。
今回はIISフォーマット入力可能なDACを使用するため、以前紹介した標準フォーマット出力の修正は行いません。
//      if (bcm2708_clk_freq[clk_src] % target_frequency == 0
//                      && bit_master && frame_master) {
//              divi = bcm2708_clk_freq[clk_src]/target_frequency;
//              divf = 0;
//      } else {
                uint64_t dividend;

                /*
                 * Overwrite half frame length, because the
                 * above trick is not needed.
                 * This is fixed, because a bit clock of 64*fs
                 * seems to be what most codecs want.
                 * Is it necessary to have this dynamic?
                 */
                half_frame = 32;
                target_frequency = sampling_rate*half_frame*2;

                clk_src = BCM2708_CLK_SRC_PLLD;
                mash = BCM2708_CLK_MASH_1;

                dividend = bcm2708_clk_freq[clk_src];
                dividend *= 1024;
                do_div(dividend, target_frequency);
                divi = dividend / 1024;
                divf = dividend % 1024;
  if (sampling_rate == 48000) {
     divi = 162;
     divf = 3000;
  }
//      }
どうやら48kHzの場合、if文のほうに流れて後の処理でハングアップするようです。
ので、コメントアウトしちゃいます。
でもって、diviとdivfで出力周波数を設定するようです。else内の計算だと48.1kHzになっちゃうので48kHzデータの場合は自前で値を代入しちゃってます。上記の数値でだいたい48.008kHzになります。
で、コンパイル!
cd /usr/src/3.8.10+/sound/soc/bcm2708
make -C /usr/src/3.8.10+ M=/usr/src/3.8.10+/sound/soc/bcm2708 modules
次に /usr/src/3.8.10+/sound/soc/codecs/tda1541a.c 24行目を修正します。
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
32bitのデータを受け付けるようにします。
この修正をしない場合は mplayer かドライバが16bitに変換するようです。
あと24bitを表す定数は存在するけど意味ないっぽいです。
mplayerだと24bitの音楽ファイルでも32bitとして扱っているみたいです。この辺はよくわかりません~(;´д`)
で、コンパイル!
cd /usr/src/3.8.10+/sound/soc/codecs
make -C /usr/src/3.8.10+ M=/usr/src/3.8.10+/sound/soc/codecs modules
でもって、ドライバを登録します。
cd /usr/src/3.8.10+/sound/soc/bcm2708
sudo insmod snd-soc-bcm2708-i2s.ko
sudo insmod snd-soc-rpi-tda1541a.ko
sudo insmod ../codecs/snd-soc-tda1541a.ko
あとはmplayerなどで再生すればOK!ヽ( ´ー`)ノ
もちろん、DAC側でIISを入力出来るようにしておく必要があります。PCM1716だとIIS、IW0ピンをHにします。


上がデータ、下がLRクロックです。24bitで出力されているようですね。


さて、16bit 44.1kHz と 24bit 48kHzの違いですが...あんまり変わらない...( ̄~ ̄;)
市販のAVアンプだと結構変わった印象があったので、ちょっと期待していたのですが残念ですなぁ。

MPDで使用する場合は /etc/mpd.conf を以下のように修正しておきましょう。
audio_output {
        type            "alsa"
        name            "ALSA I2S Device"
        device          "hw:1,0"        # optional
#        format          "44100:16:2"    # optional
}
formatはコメントアウトしておかないと常に 44.1kHz 16bit で出力されるようです。


あと、ついでなのでOPアンプを NJM2114DD から OPA2604 に変えました。
OPアンプの交換は変化がわかりやすいですね~
NJM2114DDは平べったい音で眠気を誘う音でしたが、OPA2604はメリハリがあり、聴いてて楽しい音です。
ここでフト思ったのですが、眠気を誘うアンプって以外と需要あったりしないのだろうか?
そんな時はNJM2114DDのような音をお試しあれ~(´―`)




2 件のコメント:

  1. USBドライバのコンパイル環境を作りたくて参考にさせていただきました。特にModule.symversのところです。

    返信削除
    返信
    1. 少しでもお役に立ててよかったです。

      削除