Preface
やりたかったのは、(半)自作したオーディオDAコンバーター PCM1792A をソフトウェア制御して DSD ストリームが来た時だけDSDモードに切り替えること。
その辺を趣味にしてないとなんだかわからないと思いますが、要は自作の機器でお手軽にDSDフォーマットの音源を聞きたかった、ということです。DSDって何?iTunesと何か違うの?という人にはほとんど不要な記事。ただe-Onkyoでハイレゾの音源を購入して聴きはじめ、DSDというのがあるらしくて気になってる、安く聞く機器を導入できないかな、という向きにはちょっとだけ役に立つかも。
ハードウェア
Qiita ってそもそもハードウェア主体の記事はオッケーなんだっけか。とか。でもまあいいや、問題があれば指摘よろ。
半自作オーディオDAコンバータの主要部分として相当前に買って組み立てて使ってたのはこちらです。
[24bit 192kHz DAコンバータ独立実験基板「DAC_1792_B」] (http://blog.digit-parts.com/archives/51750846.html)
ここで使われてるテキサス・インスツルメンツ製DAコンバータ PCM1792A ってのは、リリースはもう結構前だけれど今でもオーディオ機器に使われてる一線級のDAコンバータです。んで、実はこれだけでは足りなくて、この記事
[192kHz対応 オーディオ用D/Aコンバータを作ろう!] (http://blog.digit-parts.com/archives/51798857.html)
の下のほうに書いてある、電流-電圧変換と平衡-不平衡変換、電源、それに肝心なUSB-DDCってのが必要なんですが、これらはそのうちちゃんと説明します。要はいろいろ周辺回路も必要なんですよ、ってことです。なので実は高いように思われた2万円前後の「DSD対応USB DAコンバータ」ってのは妥当な金額なんですよね。
まあそれはそれとして、一応組みあがって普通に .flac や .wav のハイレゾ音源は聴けるようになっている、という前提で。
PCM1792A のソフトウェア制御
PCM1792Aのデータシートが読みづらい!という声が結構見られますが、オーディオ系としてはふつうじゃないかなあ、と個人的には思います。が、結構わかってる人ベースで書かれてるところはつらいかも。
PCMだけ聞く分には何の制御もいらず、単にI2Sのデータをぶっこむだけなのですが、DSDに切り替えるには内部のレジスタにアクセスしてフラグを書き換える必要があります。PCM1792Aのソフトウェア制御のやり方は2種類あって、SPIとI2Cです。ようやくArduinoやRaspberry Piな方々にはなじみのある略号が出てきましたw 。ここでは、I2Cを使います。なんたって線の数が少ないのと、小さな液晶を同じバスにぶら下げられるからです。
最初の罠
このデジットのキットを使ってI2C制御しようとすると、最初に罠があります。それは「I2Cバスが1KΩでプルアップされている」というところです。たぶんキットの設計者はI2C制御はやったことないのでしょうが、1KΩのプルアップだと同じバスにつなげたほとんどの機器が(必要な電流が多すぎて)LOWレベルに引っ張れません。つまり動かなくなります。まず最初に、キットの状態だと1KΩの集合抵抗をつけない、つけちゃった場合はなくなく半田をはがすことになります。やれやれ。ここに気づかなくて結構はまりました。
ちゃんと切り替わるのか?
I2Cは技術背景があんまりわかってなくても制御できる便利なバスです。要は、バスにぶら下がったデバイスそれぞれがアドレスを持ち、そのアドレスめがけてデータ書いたり読んだりする、というものです。Raspberry Piをお持ちなら実は簡単に試せるので、PCM1792Aとつなげてみて試してみましょう。
まず、Raspberry PiでI2Cを使えるようにします。この辺の記事
[Raspberry Piで「I2C LCD Breakout」を使ってみた] (http://mag.switch-science.com/2013/07/30/use-i2c-lcd-brakeout-board-on-raspberry-pi/)
が参考になると思います。ただ最近のRaspbianだと、configだけでenableにできるようです。
$ sudo raspi-config
あとはメニューに従うだけ。
で、I2C Tools というのをインストールします。
$ sudo apt-get install i2c-tools
PCM1792A基板のCN3Bの3(SCL) 4(SDA) 5(GND)とRaspberry Pi(該当ピンは調べてください)をI2Cで接続した後で先ほどの記事にあったように、
$ i2cdetect -y -r 1
とたたくと、PCM1792AのI2Cアドレスが見える「はずです」。
おおっとここにも罠が! w
見えませんw。おかしいなあプルアップ(はラズパイ側を使用)も直したし線は3本だし。ここでPCM1792Aというデバイスとその基盤をじっくり見てみましょう...。そうすると、気づきますよね。「クロックがないじゃん」そうです、こいつは単体ではクロックを持ってない。なので、クロックを外部入力してやらないと、I2Cクロックが来てもデバイスが起動してない。で、よく見ると、クロックはI2Sつまりオーディオデータのほうにはあるわけです。つまりPCM1792Aは全体としてオーディオデータのクロックに依存して動いているわけです。
ここでさらに1日費やす、と。やれやれ。
つまりUSB-DDC/I2Sに何らかのデータを流してやらないといけなかったんですね。早速PCと接続し、適当に音楽を鳴らす。お、ようやく見えました。
レジスタ20
DSDフラグはレジスタ20のビット5です。なので、コンソールから
$ i2cset -y 1 <アドレス> 20 0x20
これでDSDモードに切り替わった、と思ったんですがw
まだまだ罠が
データシートをよく読めばいいんですけどね。もう一つDSDモードにする条件がありました。I2Sデータ入力のBCLK(ビットクロック)端子をLOWにしないといけないんだそうです。USB-DDCによっては勝手にLOWになってくれるものもあるかもしれませんが、筆者が使ってるのは出所不明のXMOSベースのUSB DDCなのか?そんな機能はありませんでした。
さあこれでDSDデータを流してみましょう。PCMはすでに再生できてるはずなので、USB-DDCとPCM1792Aの間はちゃんと結線されてると。DSD再生の方法は割愛しますが、PCではfoobar2000にasioとSACDプラグインの組み合わせが定番だと思います。その辺は詳しいサイトを探してください。MacではDSDネイティブは流せず、DoPという方式のみだったと思います。筆者はPCはfoobar2000、MacはJRiverという定番で試しました。
こ、このノイズは...
それはもう、愕然とするノイズ。それも昔懐かしいwカセットテープのヒスノイズのような、サー、っというノイズまみれで音楽が聞こえてきます。
さあ、もう一度データシートへ。ん?FIRフィルタの設定がどうのこうの、というのがありますね。DSDはPCMとは違って基本DA変換ではなく「フィルタ」でデータを音にします。実はUSB-DDCのDSDデータ出力をヘッドフォンにつなげると音が鳴る!んです。PWMという方式に近いのですね。PCM1792Aはそのフィルタの役割を果たしているのですが、その「係数」を変えることができるんです。じゃあ物は試し、やってみるかと。
FIRフィルタの設定はレジスタ18のビット2と3です。00がデフォルト、01がモード2、10が3、11が4になって、それぞれのフィルタ特性はデータシートに書かれています。今回は一番カットオフ周波数が低いモード2にしてみます。
$ i2cset -y 1 <アドレス> 18 0x54
0x50の意味はデータシートでw
これをセットしたとたん、すぅっとノイズは消え、お気に入りの広瀬菜緒のソプラノ、パーセルの "I attempt love's sickness" が聞こえてきました。
課題が。
DSDモードからPCMモードに戻すには、BCLKをちゃんとつないだうえで
$ i2cset -y 1 <アドレス> 20 0
で。ただ結構大きめのノイズが出ます。DSDモードに移行する時には出なかったのに。どうやらこのDAコンバータの特性のようですね。そして、全体をミュートにするフラグがレジスタ18にあるのですが、DSDモードの時は有効じゃないと。やれやれ。つまり外付け回路を作って切り替え時には出力をいったんカットする必要がありそうです。めんどーだな...。
まとめ
とりあえず、はまったところだけをまとめてみました。解決に結構時間を費やしました。ただここから先は一本道なので、ラズパイそのままでも、Arduinoでも、それがもったいなければPICやほかのワンチップマイコンでも切り替えは容易にできるでしょう。筆者はLPC1114を選びました。というのも最初LPC810という8pinのマイコンで切り替えようとしていたんだけれど、I2Cドライブ能力が足りず、小型液晶と同時にドライバできなかったので...。これが今回最後の罠w。
(追記1)
小型液晶AQM802Aのドライブ能力不足はあちこちで問題になってますね(トラ技2016年8月号137ページ)。I2Cは便利なのだけど、つながってるデバイスがタコだと全部動かなくなるのが困りものです。ロジアナ、最低でも400KHzが見えるオシロがないと、トラブル解決はしんどいなー。
切り替え機構全景。LPC1114を使って、USB-DDC(上部)のDSD端子がハイレベルになったらDSDモードに切り替えるコマンドをPCM1792A(右上)に送る。同時に左下の液晶にも表示。また74HC02を使い、DSD端子がハイレベルになるとBCLKをLOWに落とす回路も。