16. ADCで試すアナログマイク①

 以前に試した「高感度アンプ付きコンデンサーマイク」を、ステレオマイクらしくちょっと工作。それを前回製作したADコンバーター経由でRaspberry Pi Zeroに接続して再生テストを行います。



1.アナログマイクの製作

 第4章で試した「高感度アンプ付きコンデンサーマイク」をカラーボードの台から取り外します。次にマイク部分のハンダを溶かして基板から外します。熱を加えすぎると内部の素子が破損するので、注意深く手早く行います。

 写真④のようなマイクを作るために①から③までの手順で進めます。まず写真①のように、マイクが基板と直角に外側を向くようにハンダ付けして、両方のマイクの[VCC]同士、[GND]同士を結線します。線の長さは出来上がりの長さを考えて1cm前後に揃えます。次に、内径が20mm、長さ60mm程度のプラスチックパイプを準備します。ここでは、精密プリント基板用の糸ハンダが入っていたケースを利用しました。中央に3mmの穴をあけてシールドケーブルを通します(②)。
 さてこのケーブルですが、今後I2Sデジタル出力マイクで同様のものを作ることを考えて、4芯ケーブルを調達することにしました(I2Sの信号線に3本、+電源供給に1本、そしてシールド網をGND)。今回は左右のマイク出力と+電源供給に合計3本を使います。この線材は、オヤイデ電気インターネット通販部から極細フレキシブル4芯シールド(2929) AWG28を調達しました。写真のような、外形2.7mmのしなやかなケーブルです。
 写真③のように赤線を[VCC]、黄色を右側[OUT]、白色を左側[OUT]、シールドを[GND]にハンダ付けしてマイクをプラスチックパイプに納めます。黒線は切り捨てます。ケーブルのもう一方は6Pのピンソケット(メス)にハンダ付けして、ADコンバーターとはジャンパーワイヤーで接続できるようにします。




2.テスト環境の配線

 Raspberry Pi ZeroとADC、マイク、ヘッドフォンアンプ、それぞれの電源系統を写真のように接続します。


 Raspberry Pi Zero、AD Converter、マイクロフォン、ヘッドフォンアンプのそれぞれから見た接続デバイスと端子、写真で使用しているワイヤーの色をまとめておきます。
 ①Raspberry Pi Zero

[[ Raspberry Pi ]] Usage ..... Device:Wire Color(Function) ADC:Orange(3.3) *3.3V 3V3 (1) (2) 5V *5V ADC:Red(+5V) GPIO2 (3) (4) 5V GPIO3 (5) (6) GND *GND ADC:Brown(GND) GPIO4 (7) (8) GPIO14 GND (9) (10) GPIO15 GPIO17 (11) (12) GPIO18 *CLK ADC:Yellow(BCK) GPIO27 (13) (14) GND GPIO22 (15) (16) GPIO23 3V3 (17) (18) GPIO24 GPIO10 (19) (20) GND GPIO9 (21) (22) GPIO25 GPIO11 (23) (24) GPIO8 GND (25) (26) GPIO7 GPIO0 (27) (28) GPIO1 GPIO5 (29) (30) GND GPIO6 (31) (32) GPIO12 *PWM0 Amp:Brown(Left) Amp:White(Right) *PWM1 GPIO13 (33) (34) GND *GND Amp:Black(GND) ADC:Blue(LRC) *FS GPIO19 (35) (36) GPIO16 GPIO26 (37) (38) GPIO20 *DIN ADC:Green(OUT) GND (39) (40) GPIO21 *DOUT


②ADC(AD Converter)

    [[ AD Converter ]] Usage ...... ----> Target-device [Function] Wire-color  ・[+5V] ----> Pi Zero [5V] Red  ・[3.3] ----> Pi Zero [3.3V] Orange  ・[GND] ----> Pi Zero [GND] Brown  ・[BCK] ----> Pi Zero [GPIO18] Yellow  ・[OUT] ----> Pi Zero [GPIO20] Green  ・[LRC] ----> Pi Zero [GPIO19] Blue  ・[Lin] ----> Microphone[Left] Green  ・[GND] ----> Microphone[GND] Black  ・[Rin] ----> Microphone[Right]White


 ③Microphone

    [[ Microphone ]] Usage ...... ----> Target-device [Function] Wire-color  ・[GND] ----> Battery 3V[-] Black  ・[GND] ----> ADC[GND] Black  ・[VCC] ----> Battery 3V[+] Red  ・[Left] ---> ADC[Lin] Green  ・[Right] --> ADC[Rin] White


 ④Amp(Headphone Amp.)

    [[ Headphone Amp. ]] Usage ...... ----> Target-device [Function] Wire-color  ・[Left] ---> ADC[Lin] Brown  ・[GND] ----> ADC[GND] Black  ・[Right] --> ADC[Rin] White  ・[+] ------> Battery 9V[+] Red  ・[-] ------> Battery 9V[-] Black  ・Phone plug ===> Earphone (Phone cable)


<注意>
 配線が増えると、テスト中に接続部の接触不良やボードのブラつきなどで大きなノイズが発生しやすくなります。耳を守るために、ボードや配線がブラつかないように十分注意してください。
 作業台代わりに滑りにくい「シリコン鍋敷き(正方形)」を使うと便利です。


3.I2Sモジュールの再セットアップ

 順序が逆になって、ソフトウェアの準備をする前にテスト環境の配線をしてしまいました。この状態で第9章『9.I2Sデジタル出力マイクのテスト』の「6.I2Sデジタル出力マイクの評価」と同様のテストをすることもできますが、イヤフォンからは大きなノイズが出るだけです。
 いったん電池部分の配線を外して以下のセットアップを行いましょう。

 第8章『8.I2Sとサウンドモジュール』の「3.I2Sモジュールのセットアップ」の直前で、その時点のシステム(マイクロSDカード)をバックアップするようにお願いしました。以降は、その内容を復元したものに対してI2Sモジュールの再セットアップを行います。もしバックアップしていなければ、もう一度、最初から(OSのバックアップをしていればそれを復元した状態から)、第8章のバックアップ直前までの一連のインストールや設定を行う必要があります。
 また、現在のI2Sデジタル出力マイク(ADMP441)の動作環境を別の名前でバックアップして、以前のバックアップした内容を上書きしてもかまわないのですが、できれば現在のSDカードはそのまま保管し、新たなSDカードを準備してバックアップ内容を復元することをお勧めします。

 では、なぜI2Sモジュールの再セットアップが必要なのでしょうか。前章で見たようにADCのインターフェイスモードにはマスターモードとスレーブモードがあります。I2Sデジタル出力マイク(ADMP441)内蔵のADCはスレーブに設定されていて、Pi Zeroがマスターで動作します。つまり、シリアルワード選択のLRCK(LRC)とビットクロックのBCKはPi Zeroから供給されています。これに対して、前章で作成したADCはこれらのクロックを自前で用意して、マスターモードで動作します。したがって、Pi Zeroがスレーブモードで動くように設定する必要があるわけです。

 ところが、この設定についての資料がまったく見あたらず悪戦苦闘。そんな折り、平坂久門さんの『ラズパイにADC PCM1803A(master)をI2S接続する地雷回避情報』に助けられました。重要な手がかりをありがとうございます。インストールの手順と内容はほとんど第8章の「3.I2Sモジュールのセットアップ」と重複しますが、新たな追加部分を赤色で表示して以下に再掲載します。

○念のために

 復元したSDカードをセットしてPi Zeroの電源を入れた後、「gpio readall」コマンドでGPIOピンの状態を確認しておきましょう。次のようになっていればOKです。


<< ヒント >>
 例によって、一連の作業にはかなり時間がかかります。数時間を見込んで余裕をもって取り組んでください。
 なお、以降の作業は、本文中のコマンド等を[コピー]して、poderosa(SSHターミナルエミュレーター)の[ペースト]で貼り付けると簡単確実です!


①I2Sの有効化

 I2Sインターフェースは初期状態で無効となっているため有効化します。/boot/config.txtファイルにある記述「#dtparam=i2s=on」のコメント記号、「#」を削除して2行を追加します。
$ sudo nano /boot/config.txt dtparam=i2s=on dtoverlay=hifiberry-dac dtoverlay=i2s-mmap


②サウンドモジュールの有効化

 /etc/modulesファイルの末尾に「snd-bcm2835」と「my_loader」を追加して、リブートします。
$ sudo nano /etc/modules   snd-bcm2835 my_loader $ sudo reboot
リブート後に、次のコマンドでモジュールがロードされていることを確認します。
  「snd_pcm_dmaengine,snd_soc_bcm2835_i2s,snd_bcm2835,snd_soc_core」が含まれていればOK。
$ lsmod | grep snd snd_soc_bcm2835_i2s 20480 0 regmap_mmio 16384 1 snd_soc_bcm2835_i2s snd_soc_core 192512 1 snd_soc_bcm2835_i2s snd_compress 20480 1 snd_soc_core snd_pcm_dmaengine 16384 1 snd_soc_core snd_bcm2835 24576 1 snd_pcm 98304 4 snd_pcm_dmaengine,snd_soc_bcm2835_i2s,snd_bcm2835,snd_soc_core snd_timer 32768 1 snd_pcm snd 73728 7 snd_compress,snd_timer,snd_bcm2835,snd_soc_core,snd_pcm


③カーネルのダウンロードとコンパイル

 I2S オーディオドライバを組み込む際に使用するLinuxカーネルを最新バージョンに更新して、リブートします。
$ sudo apt update $ sudo apt install rpi-update $ sudo rpi-update       :     (省 略)       : ############################################################# WARNING: This update bumps to rpi-5.4.y linux tree See: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=269769 'rpi-update' should only be used if there is a specific reason to do so - for example, a request by a Raspberry Pi engineer or if you want to help the testing effort and are comfortable with restoring if there are regressions. DO NOT use 'rpi-update' as part of a regular update process. ############################################################## Would you like to proceed? (y/N) <=== 'n'を返答します! $ sudo reboot


④依存関係パッケージのインストール

 カーネルの取得・コンパイルに必要なパッケージをインストールします。「続行しますか?」には 'y'を入力します。
$ sudo apt install git bc libncurses5-dev bison flex libssl-dev

 カーネルソースをダウンロードしてコンパイルします。かなり時間がかかります。
  (注意)
    最終行の「rpi-source --skip-gcc」の実行では、
       Code coverage for fuzzing (KCOV) [N/y/?] (NEW)」
    と表示されたら、デフォールトを指示するために [Enter]をクリックします。
$ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source    <---- 前の行に続いています! $ sudo chmod +x /usr/bin/rpi-source $ /usr/bin/rpi-source -q --tag-update $ rpi-source --skip-gcc


⑤I2Sモジュールの準備

 I2Sが使用できるかを確認します。次の入力で「mount: debugs is already mounted」などのように表示されればOKです。
$ sudo mount -t debugfs debugs /sys/kernel/debug

 次のコマンドで、モジュール名「20203000.i2s」が表示されることを確認する。
$ sudo cat /sys/kernel/debug/asoc/components 20203000.i2s 20203000.i2s pcm5102a-codec snd-soc-dummy snd-soc-dummy


⑥サウンドモジュールのソースコードをダウンロードする

 次のようにダウンロードします。
$ git clone https://github.com/PaulCreaser/rpi-i2s-audio $ cd rpi-i2s-audio
 続いて、nanoでソースコードファイルmy_loader.cを開いて次の3カ所を変更します。
   ・.platform = "3f203000.i2s" → .platform = "20203000.i2s"
   ・.name = "3f203000.i2s" → .name = "20203000.i2s"
   ・SND_SOC_DAIFMT_CBS_CFS → SND_SOC_DAIFMT_CBM_CFM
$ sudo nano my_loader.c

 ちなみに、SND_SOC_DAIFMT_CBS_CFSはlinux/sound/soc-dai.hで以下のように定義されています。  
  /*    * DAI hardware clock masters.    *    * This is wrt the codec, the inverse is true for the interface    * i.e. if the codec is clk and FRM master then the interface is    * clk and frame slave.    */   #define SND_SOC_DAIFMT_CBM_CFM  (1 << 12) /* codec clk & FRM master */   #define SND_SOC_DAIFMT_CBS_CFM  (2 << 12) /* codec clk slave & FRM master */   #define SND_SOC_DAIFMT_CBM_CFS  (3 << 12) /* codec clk master & frame slave */   #define SND_SOC_DAIFMT_CBS_CFS  (4 << 12) /* codec clk & FRM slave */
 今回はBCKとLRCKをコーデック側で作ってPi Zeroへ送るため、SND_SOC_DAIFMT_CBM_CFMを指定するように変更したわけです。


⑦モジュールをコンパイルする

 モジュールをコンパイルしてインストールします。
$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules $ sudo insmod my_loader.ko

 以下の2通りの方法で、モジュールが正常にインストールできているか確認します。
  1) lsmod を実行し、my_loader で始まる行が出力されること。
$ lsmod | grep my_loader my_loader 16384 0

  2) dmesg を実行し、カーネルメッセージログの最後に下記の内容を含む行が表示されていること。
    asoc-simple-card asoc-simple-card.0: snd-doc-dummy-dai <-> 3d203000.i2s mapping ok
$ dmesg | tail [ 35.948393] Bluetooth: BNEP socket layer initialized [ 36.793450] Bluetooth: RFCOMM TTY layer initialized [ 36.793486] Bluetooth: RFCOMM socket layer initialized [ 36.793537] Bluetooth: RFCOMM ver 1.11 [ 50.643759] fuse init (API version 7.27) [ 2054.447163] my_loader: loading out-of-tree module taints kernel. [ 2054.492918] request module load 'bcm2708-dmaengine': 0 [ 2054.493215] register platform device 'asoc-simple-card': 0 [ 2054.493230] Hello World :) [ 2054.609760] asoc-simple-card asoc-simple-card.0: snd-soc-dummy-dai <-> 20203000.i2s mapping ok


⑧起動時に自動でモジュールをロードするように設定

 Raspberry Pi Zero起動時にモジュールを自動ロードするように設定します。
$ sudo cp my_loader.ko /lib/modules/$(uname -r) $ echo 'my_loader' | sudo tee --append /etc/modules > /dev/null $ sudo depmod -a $ sudo modprobe my_loader $ sudo reboot


4.ソフトウェアボリュームの設定

 第9章『9. I2Sデジタル出力マイク(ADMP441)のテスト』の「4.ソフトウェアボリュームの設定」と同様にして、ソフトウェアボリュームを設定します。重複しますが再掲します。以下の要領で進めてください。

 nanoエディターでasoundrcファイルを作成して、以下の定義情報を書き込みます。

$ sudo nano ~/.asoundrc
#This section makes a reference to your I2S hardware, adjust the card name # to what is shown in arecord -l after card x: before the name in [] #You may have to adjust channel count also but stick with default first pcm.dmic_hw { type hw card sndrpisimplecar channels 2 format S32_LE } #This is the software volume control, it links to the hardware above and after # saving the .asoundrc file you can type alsamixer, press F6 to select # your I2S mic then F4 to set the recording volume and arrow up and down # to adjust the volume # After adjusting the volume - go for 50 percent at first, you can do # something like # arecord -D dmic_sv -c2 -r 48000 -f S32_LE -t wav -V mono -v myfile.wav pcm.dmic_sv { type softvol slave.pcm dmic_hw control { name "Boost Capture Volume" card sndrpisimplecar } min_dB -3.0 max_dB 30.0 }

 この定義情報を有効にするには、いちどarecordコマンドを実行する必要があります。次のようにコマンドを入力し、動作し始めたら[ctrl]+[c]で止めてください。

 ※前回製作したADコンバーターのサンプルレートは96kHzでした。そこでこのADコンバーターを使用する場合は、以下のようにサンプルレートで96000を指定する点に注意してください。

$ arecord -D hw:1,0 -c2 -r 96000 -f S32_LE -t wav -V stereo -v | aplay


5.ソフトウェアボリュームのテスト

 これもすでに第9章で行ったことと同じなのですが、ソフトウェアボリュームがどのように設定されたかを確認します。次のようにPortAudioのexampleフォルダーに移動して、pa_devs.cをコンパイル実行します。

$ cd $ cd portaudio/examples $ gcc pa_devs.c -lportaudio $ ./a.out

 以下の内容が表示され、#4にソフトウェアボリュームdmic_svが登録されていることがわかります。
Number of devices = 6 --------------------------------------- device #0 [ Default Output ] Name = bcm2835 ALSA: IEC958/HDMI (hw:0,1) Host API = ALSA Max inputs = 0, Max outputs = 8 Default low input latency = -1.0000 Default low output latency = 0.0016 Default high input latency = -1.0000 Default high output latency = 0.0348 Default sample rate = 44100.00 Supported standard sample rates for half-duplex 16 bit 8 channel output = 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 --------------------------------------- device #1 Name = bcm2835 ALSA: IEC958/HDMI1 (hw:0,2) Host API = ALSA Max inputs = 0, Max outputs = 8 Default low input latency = -1.0000 Default low output latency = 0.0016 Default high input latency = -1.0000 Default high output latency = 0.0348 Default sample rate = 44100.00 Supported standard sample rates for half-duplex 16 bit 8 channel output = 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 --------------------------------------- device #2 [ Default Input ] Name = snd_rpi_simple_card: simple-card_codec_link snd-soc-dummy-dai-0 (hw:1,0) Host API = ALSA Max inputs = 2, Max outputs = 2 Default low input latency = 0.0058 Default low output latency = 0.0087 Default high input latency = 0.0348 Default high output latency = 0.0348 Default sample rate = 44100.00 Supported standard sample rates for half-duplex 16 bit 2 channel input = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for half-duplex 16 bit 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for full-duplex 16 bit 2 channel input, 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 --------------------------------------- device #3 Name = dmic_hw Host API = ALSA Max inputs = 2, Max outputs = 2 Default low input latency = 0.0058 Default low output latency = 0.0087 Default high input latency = 0.0348 Default high output latency = 0.0348 Default sample rate = 44100.00 Supported standard sample rates for half-duplex 16 bit 2 channel input = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for half-duplex 16 bit 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for full-duplex 16 bit 2 channel input, 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 --------------------------------------- device #4 Name = dmic_sv Host API = ALSA Max inputs = 2, Max outputs = 2 Default low input latency = 0.0058 Default low output latency = 0.0087 Default high input latency = 0.0348 Default high output latency = 0.0348 Default sample rate = 44100.00 Supported standard sample rates for half-duplex 16 bit 2 channel input = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for half-duplex 16 bit 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 Supported standard sample rates for full-duplex 16 bit 2 channel input, 2 channel output = 8000.00, 11025.00, 16000.00, 22050.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00 --------------------------------------- device #5 Name = dmix Host API = ALSA Max inputs = 0, Max outputs = 2 Default low input latency = -1.0000 Default low output latency = 0.0213 Default high input latency = -1.0000 Default high output latency = 0.0213 Default sample rate = 48000.00 Supported standard sample rates for half-duplex 16 bit 2 channel output = 48000.00 ----------------------------------------------


 次に、Windowsリモート デスクトップ接続でPi Zeroに接続し、alsamixerを起動してマイクの入力感度を設定します。LXTerminalを起動して「alsamixer」と入力し、ファンクションキーで切り替えながら設定します。下図は、設定画面の推移を合成したものです。


 再生レベルは以前と同じ85に設定。録音は、[F6]で表示される「サウンドカード」選択から[snd_rpi_simple_card]を選択して、音量レベルを84あたりに設定します。

 では、イヤフォンを装着して、ソフトウェアボリュームdmic_svを使ってマイク入力するよう指示してみましょう。電池部分の配線を元に戻してイヤフォンを接続してください。

<危険・注意!>
 次のコマンドを入力する前に、DCコンバーターの半固定ボリュームを中央位置に合わせます。そして、ヘッドフォンアンプの音量を完全に絞ってください!


$ arecord -D dmic_sv -c2 -r 96000 -f S32_LE -t wav -V stereo -v | aplay

 ヘッドフォンアンプのボリュームをほんの少し上げると、十分な音量で再生できることがわかります。コンデンサーマイクのアンプ基板の増幅率が大きいので、ADコンバーター側のボリュームも適宜調整して適切な音量に設定してください。arecord|aplayコマンドなので遅延が発生しますが、明瞭に再生できている感じです。ステレオの分離状態もまずまずで、マイクの配線によるノイズも問題ないようです。

 今回はI2Sモジュールやソフトウェアボリュームの再設定といった、以前に行った作業の繰り返しが中心になってしまいました。このような作業は気分的にキツイのですが、今しばしご辛抱を! しかも記述が長くなってしまったので、とりあえずここで終わります。
 次回は、以前にI2Sデジタル出力マイクで行ったリアルタイムサウンド処理を組み込みます。ADコンバーターの動作波形なども観測する予定です。お楽しみに!