30. 聴力補助ツールHAT21の完成

 いよいよ最終回になりました。前回基板に組み付けたボード類の配線を行ってケースに収納します。イヤフォンジャックやプッシュスイッチを取り付けてハードウェアを完成させます。続いてソフトウェアの追加・変更を行い、必要なチューニングを行ってHAT21システムを仕上げます。
 写真は完成した聴力補助ツールHAT21です。ずいぶん回り道をしましたが、このような成果物を手にすることができました。まだ十分な調整はできていませんが、単純な音声増幅器と違って音域別の感度補正ができるので、聴き取りやすく大いに重宝しそうです。大きさも小型のウェストバッグに収納できるサイズ(バッテリー込みで W20 x D12 x H3 cm)になり、手軽に連れ出せそうです。

 ※ソースコードと関連ファイルは右側の[Download]ボタンでダウンロードしてください。   


 <訂正>
    2021/10/05 ダウンロードファイル内のfilter3.cに誤りがありましたので訂正しました。


〔ダウンロードファイルの扱い〕

 ダウンロード後の操作は「2.稼働環境の整備」で説明しています。



1.ボード間とパーツの配線

 写真は、配線済みの基板がケースに収まった状態です。ボードやパーツ間の配線の説明で、配線の色や場所などを確認する際の参考にしてください。前章の「レイアウトを考える」で掲げた写真も分かりやすいのであわせて参照してください。
 なお、以下の配線についての説明は、それぞれのボードや部品が、他のどのボードや部品から結線されているかを相互関係で示しています。


①マイクロUSB電源ボード

 コネクターに繋がれたモバイルバッテリーから、他のボードに給電します。[-]は電源のマイナスと同時に、他のボードのGNDやケース(シャーシー:Chassis)に接続します。
[[ MicroUSB Connector ]] Usage ..... Device:Wire Color(Function) [+] Raspberry Pi:Red(5V) [+] DC booster:Red(Input) [-] Raspberry Pi:Black(GND) [-] DC booster:Black(GND) [-] Transister switch:Black(GND), Chassis:Black(Electric Ground)


②Raspberry Pi Zero

 今まで何度も見てきた図ですが、接続先がかなり増えています。また配線のカラーも変わっています。接続が大きく変わっているのは次の点です。
  ・電源を第4ピン、第6ピンで受けている。
  ・電源ONプッシュボタンスイッチ(PB-SW)をGPIO3とGNDに繋いでいる。
  ・トランジスタースイッチのトリガーをGPIO23から供給している。
 なお、ここで使っているプッシュボタンは、プッシュ状態でOFFになる端子と、プッシュ状態でONになる端子があるので、後者に接続するよう注意してください。
[[ Raspberry Pi Zero ]] Usage ..... Device:Wire Color(Function) Mic:Red(3V) *3.3V 3V3 (1) (2) 5V GPIO2 (3) (4) 5V USB Connector:Red(5V+) PB-SW:Green GPIO3 (5) (6) GND USB Connector:Black(5V-) GPIO4 (7) (8) GPIO14 Mic:Black(GND), PB-SW:Blue GND (9) (10) GPIO15 GPIO17 (11) (12) GPIO18 Mic:Yellow(BCLK) GPIO27 (13) (14) GND GPIO22 (15) (16) GPIO23 Transister-SW:Green(Signal) 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 Amp:Purple(Left) Amp:White(Right) GPIO13 (33) (34) GND Amp:Black(GND) Mic:Wite(LRCL) GPIO19 (35) (36) GPIO16 GPIO26 (37) (38) GPIO20 Mic:Red(DOUT) GND (39) (40) GPIO21


③昇圧電源

 入力端子とGNDをUSB電源ポートに接続し、出力端子をトランジスタースイッチの[Input]へ接続します。GNDはヘッドフォンアンプ電源のマイナスラインへ繋いでおきます。なお、Output端子とGNDの間にはリップルを改善するために、昇圧電源キット付属の電解コンデンサーと0.1μFの積層セラミックコンデンサーをハンダ付けしています。
[[ DC booster ]] Usage ..... Device:Wire Color(Function) [Input] MicroUSB Connector:Red([+]) [GND] MicroUSB Connector:Black([-]) [GND] Headphone Amp.:Black(-) ___ [Output] Transister-SW:Red(Input) ___」<--- 47μF、0.1μF


④トランジスタースイッチ

 スイッチON/OFF制御のためのシグナルをRaspberry PiのGPIO23から受けます。入力は昇圧器からの9V。出力はヘッドフォンアンプの+電源に接続します。
[[ Transister Switch ]] Usage ..... Device:Wire Color(Function)   [Input] DC booster:Red(Output) [Output] Headphone Amp.:Red(+) [Signal] Raspberry Pi:Green(GPIO23) [GND] MicroUSB Connector:Black([-])


⑤マイクロフォンコネクター

 マイクの各ラインはすべてRaspberry Piに接続します。
[[ Microphone connector ]] Usage ..... Device:Wire Color(Function) [BCLK] Raspberry Pi:Yellow(GPIO18) [DOUT] Raspberry Pi:Red(GPIO20) [LRLC] Raspberry Pi:White(GPIO19) [3V] Raspberry Pi:Red(3V3) [GND] Raspberry Pi:Black(GND)


⑥ヘッドフォンアンプ

 トランジスタースイッチから給電され、入力側の音声シグナルはRaspberry PiのPWM出力から受けます。
[[ Headphone Amp. ]] Usage ..... Device:Wire Color(Function) [+] Transister-SW:Red(Output) [-] DC booster:Black(GND) [IN.Right] Raspberry Pi:White(GPIO13) [IN.Left] Raspberry Pi:Purple(GPIO12) [IN.GND] Raspberry Pi:Black(GND)


⑦ヘッドフォンジャック

 ヘッドフォンアンプの出力側から接続します。
[[ Headphone jack ]] Usage ..... Device:Wire Color(Function)   [Right] Headphone Amp.:White(OUT.Right)   [Left] Headphone Amp.:Purple(OUT.Left)   [GND] Headphone Amp.:Black(OUT.GND)


⑧赤色LED

 マイクラインの3Vからカーボン抵抗を介してGNDに接続します。
[[ LED *Red* ]] Usage ..... Device:Wire Color(Function)   [+] Mic.3V   [-] 4.7KΩ ---> Mic.GND


⑨青色LED

 トランジスタースイッチの出力側からカーボン抵抗を介してGNDに接続します。
[[ LED *Blue* ]] Usage ..... Device:Wire Color(Function)   [+] Transister-SW:Blue(Output)   [-] 30KΩ ---> Mic.GND


⑩プッシュスイッチ

 Raspberry PiのGPIO3をGNDへショートさせるように接続します。
[[ Push switch ]] Usage ..... Device:Wire Color(Function)   [・] Raspberry Pi:Green(GPIO3)   [・] Raspberry Pi:Blue(GND)


 以上ですべてのボードとパーツ間の配線が完了します。参考までに、写真左にマイクロフォンコネクターとLED、プッシュスイッチ周辺の配線をピックアップしました。赤青のLEDは、それぞれLEDの足を曲げて、フロントパネルの穴から見える位置に調整します。
 またシャーシーのアースは、写真右のようにリアパネルの穴を利用してアース線を設置し、マイクロUSB電源ボードの[-]にハンダ付けします。このビスとナットは、基板後方部が上方向にずれるのを防ぐ役目もしています。
 なお、マイクケーブルは写真左のように装着するので、ケーブルが通るように、金工用糸鋸などを使って、ケース上蓋の左手前に必要サイズだけ切り込み穴を開けます。


2.稼働環境の整備

①ダウンロードファイルの扱い

 ダウンロードしたzipファイルをパソコンの適当な場所で解凍してください。解凍後のファイルは下図のような構成になっています。今回、HAT21のバージョンは1.00になっていて、ディレクトリー名やファイル構成が変わっています。また以前と同名のファイルでも内容が変更されているものがあります。
 hat21フォルダーは、既存の開発環境とは別に新たなフォルダーとして配置してください。webappの内容は、従来のPi Zeroのドキュメントルート(/var/www/html)に上書きしてください。srciptフォルダーの内容は、以降の手順に沿って、従来の内容を書き換えてください。
 なお以降の操作は、Pi ZeroにSSHターミナルソフト(ここではPoderosa)を接続したWindows10から行っています。
\hat21sys \hat21 HAT21アプリケーション filter3.c filter3.h filter3.o hat.h hat21 hat21.c msec_timer.c msec_timer.h msec_timer.o \script シェルスクリプト autostart.sh poweroff.sh prmcrontab \webapp リモートコンソール \js hat21sub.js .htaccess finalpage.html hat21.html hiddenpage.html


②自動起動スクリプトの変更

 自動起動スクリプトを変更します。ダウンロードファイルautostart.shを利用して、/usr/local/bin/autostart.shの内容を次のように変更してください。なお、cdコマンドによる開発ディレクトリ(hat21の実行形式ファイルが存在する場所)は、それぞれの環境に合わせて修正してください。
#!/bin/bash cd /home/share/hat21 # <=== それぞれの環境に合わせてください! ./hat21 weblink


③電源オフスクリプトの変更

 リモートコンソールからHAT21の電源が確実にOFFにできるようにするための変更です。以前の内容にダウンロードファイルpoweroff.shの内容を上書きしてください。対象ファイルは、/usr/local/bin/poweroff.shです。
#!/bin/bash wait sudo shutdown -h now


④crontab

 コマンド実行スケジュール管理コマンドcrontabの指定を確認します。
    crontab -e
と入力して、表示された画面の最下行を、ダウンロードファイルprmcrontabの内容で置き換えてください。
@reboot bash /usr/local/bin/autostart.sh


ついでながら、今回初めてシェルスクリプトファイルを作成した場合は、

$ sudo chmod +x ~~.sh

として(~~はスクリプトファイルの名前)実行権限を与えてください。また、crontabの指定を有効にするには、

$ sudo reboot

のように再起動すれば有効になります。


3.アプリケーションソフトの仕上

 前章で述べたように、HAT21のソースコードは、従来のhat21c.cのサンプリングレートを44,100Hzに修正したものをベースにしています。しがって、基本的なプログラム・ロジックは、第26章でリモートコンソールとの連動をさせたものと同じと考えて差しつかえありません。
 アプリケーションの仕上と題していますが、実際に手を加えたのは、ノイズ除去のためにタイミング制御や、トランジスタースイッチのON/OFF制御といったところです。特にノイズについては、その原因であるPortAudioの不規則なアンダーフローエラーの発生を完全には抑えきれず、今後に課題を残します。
 ここでは変更部分だけをピックアップして説明します。引用しているソースコードはフィックス直前のもので、今後の追加修正などによって記述位置がずれる可能性があります。行番号は目安程度と考えてください。

①GPIO制御

 トランジスタースイッチのON/OFF制御にGPIOピンを使用します。Raspberry PiでGPIOを制御するにはWiring Pinというライブラリーを使うので、ヘッダーファイルwiringPi.hをインクルードする必要があります。
#include <wiringPi.h>
 トリガーに使用するGPIOピンを定義します。ピンの番号は、「gpio readall」コマンドで表示されるGPIOピンの割り当て一覧から、「wpi」欄に表示されている番号で指定します。
#define SWITCH_PIN			4			// wpi-4 (GPIO23)
 ヘッダーファイルwiringPi.hをインクルードすると、wiringPiのセットアップやピンのモード設定、LOW/HIGH制御などの関数が使えるようになります。
	/* スイッチ制御ピンの設定 */
	wiringPiSetup();
	pinMode(SWITCH_PIN, OUTPUT) ;
	digitalWrite(SWITCH_PIN, LOW);
 wiringPiSetup関数は、wiringPi systemの初期化をします。実は、wpiピンナンバーの使用はこの関数を実行することで宣言されます。別の関数を呼ぶとGPIO番号などで指定することもできますが、ここでは省略します。
 pinMode関数で対象ピンの入出力モードを設定し、digitalWrite関数でそのピンをLOWまたはHIGHにすることができます。


②自動起動の時間制御

 自動起動時に一定の時間だけ待ってヘッドフォンアンプの電源をONにするために、次のグローバル変数を準備します。当面の待機時間は20秒に設定しています。
// Wait time control
time_t	entry_time, end_time;			// 自動起動経過時間計測用
time_t	wait_time = 20;					// 自動起動後の待機時間(秒)
int		wait_sw = 1;					// 待機モード
 実際の時間待ち処理は、音声再生処理ループの先頭に記述しています。自動起動、つまりweblinkが1の場合だけが対象です。最初はwait_swが1なので、アプリケーション開始時間から待機時間が経過するまで待ちます。経過を待って、対象ピンをHIGHにしてから、再び待機を繰り返さないように、wait_swをゼロにします。
 待機中は、一連の音声ストリームの出入力が繰り返され、ヘッドフォン出力だけが切り離されて待っている状態になります。
	/* 音声入力再生処理 */
	while (1) {
		// 自動起動時は待ち時間経過までヘッドフォン電源を入れない
		if (weblink == 1 && wait_sw == 1) {
			end_time = time(NULL);
			if ((end_time - entry_time) >= wait_time) {
				digitalWrite (SWITCH_PIN, HIGH);
				wait_sw = 0;
			}
		}


③ミリ秒単位でタイミングをコントロール

 ミリ秒単位でタイミングをコントロールするために、次のような関数を作成します。
/*
	ミリ秒だけスリープする
*/
void sleep_msec(int msec) {
    struct timespec ts;
    ts.tv_sec = 0;
    ts.tv_nsec = (long)msec * 1000000L;
    nanosleep(&ts, NULL);
}
 オーディオ処理のハイライトの部分にミリ秒スリープ関数を配置しました。理論的な根拠はなく、それらしい位置に適当なスリープ時間を設定したものです。試行を繰り返す中で、この状態でそこそこノイズを抑制できたというところです。
	/* オーディオ処理開始 */
	memset(sampleBlock, SAMPLE_SILENCE, numBytes);
	memset(buffer, SAMPLE_SILENCE, sizeof(buffer));
	printf("\nApplied : [%s]", getFilterName(process_mode));
	
  RESTART:
	err = Pa_OpenStream(&stream, &inputParameters, &outputParameters,
				SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, NULL, NULL);
	if(err != paNoError)	goto error1;
	sleep_msec(10);

	err = Pa_StartStream(stream);
	if(err != paNoError)	goto error1;
	sleep_msec(10);

	/* 音声入力再生処理 */
	while (1) {
		// 自動起動時は待ち時間経過までヘッドフォン電源を入れない
		if (weblink == 1 && wait_sw == 1) {
			end_time = time(NULL);
			if ((end_time - entry_time) >= wait_time) {
				digitalWrite (SWITCH_PIN, HIGH);
				wait_sw = 0;
			}
		}
		// エラーが発生したらリスタートさせる
		err = Pa_WriteStream(stream, buffer, FRAMES_PER_BUFFER);
        if( err ) { 
			printf("*"); fflush(stdout);
			if (logging == 1)	writeLog(&logctrl, LOGID_ERRUDF);
			Pa_StopStream(stream);
			sleep_msec(50);
			Pa_CloseStream(stream);
			sleep_msec(50);
			goto RESTART;
		}
        err = Pa_ReadStream(stream, sampleBlock, FRAMES_PER_BUFFER);
        if( err ) { 
			printf("$"); fflush(stdout);
			if (logging == 1)	writeLog(&logctrl, LOGID_ERROVF);
		}


④電源制御

 マニュアル起動された場合は、即ヘッドフォンアンプの電源をONにします。まず、263行目でSWITCH_PINをHIGHにしています。この状態はトランジスタースイッチの[Signal]端子に伝達されてスイッチがONになり、ヘッドフォンアンプの電源が入ります。次の行で、自動起動の際の待機処理をバイパスさせるためにwait_swをゼロにしています。
 271行目では、自動起動時の待機処理の起点になる開始時刻を取得しています。
	/* == Web連携の要否設定 == */
	if (weblink != 1)	// Web連携モードでなければ(自動起動でなければ)以下を確認する
	{
		while (1) {
			printf("    Web連携チューニングを有効にしますか(y/n)? : ");
			char ans = getchar();
			if (ans == 'y') {
				weblink = 1;	break;
			}
			if (ans == 'n') {
				weblink = 0;	break;
			}
		}
		digitalWrite (SWITCH_PIN, HIGH);
		wait_sw = 0;
	}
	if (weblink == 1) {
		printf("  ** Web連携で動作中 **\n");
		// 250ミリ秒タイマーを開始する
		start_msec_timer(250);
		/* 開始時刻の取得 */
		entry_time = time(NULL);
	}
 終了処理では、まずSWITCH_PINをLOWにしてヘッドフォンアンプの電源を切断します(609行目)。
 リモートコンソールで[Power Off]ボタンが押されると、グローバル変数doPoweroffに1が設定されます。618行ではそれをチェックしてシェルスクリプトpoweroff.shを実行させます。この部分は以前と類似していますが、bashコマンドで実行するように変更しています。
  FinalProc:
	/* 終了処理 */
	printf("\nHAT21: Hearing Assist Tool Closed!\n\n"); fflush(stdout);
	digitalWrite (SWITCH_PIN, LOW);
	createWebCommomFile();
	err = Pa_StopStream(stream);
	if(err != paNoError)	goto error1;
	free(sampleBlock);
	Pa_Terminate();
	if (logging == 1)	writeLog(&logctrl, LOGID_FINAL);
	putBasicInfo("base.ctrl");
	closeLog(&logctrl);
	if (doPoweroff == 1)
		system("bash /usr/local/bin/poweroff.sh");
	return 0;

/* エラー処理 */
error1:
	free(sampleBlock);
error2:
	if(stream) {
		Pa_AbortStream(stream);
		Pa_CloseStream(stream);
	}
	Pa_Terminate();
	digitalWrite (SWITCH_PIN, LOW);
	fprintf(stderr, "An error occured while using the portaudio stream\n");
	fprintf(stderr, "Error number: %d\n", err);
	fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
	if (logging == 1)	writeLog(&logctrl, LOGID_ABEND);
	putBasicInfo("base.ctrl");
	closeLog(&logctrl);
	return -1;
}

 アプリケーションの変更は以上です。


4.動作検証

(1)コンパイルと起動

 カレントディレクトリーが開発環境の\hat21にある状態で、次のコマンドでコンパイルすることができます。Wiring Pinライブラリーを使うので、-lwiringPiを追加しています。
$ gcc hat21.c -o hat21 filter2.o msec_timer.o -lportaudio -lm -lwiringPi
 追加的な開発を行ったり、フィルターの条件をマニュアル設定する場合は次のように起動します。
$ ./hat21
 通常はHAT21を立ち上げるだけなので、リブートして自動起動を待ちます。
$ sudo reboot


(2)HAT21の起動と停止

 電源が切れた状態でUSB電源ポートにケーブルを差し込むと起動します。ケーブルを差し込んだ時点で赤色LEDが点灯し、音声信号処理が始まると青色LEDが点灯します。この状態でマイクから集音した音声がイヤフォンから聞き取れるようになります。
 使用が終わったら、スマートフォンなどにインストールしているリモートコンソールの[Power Off]スイッチにタップして電源を切ります。HAT21は必要な終了処理をして安全にシャットダウンします。同時に青色LEDが消えます。
 電源が切れてもモバイルバッテリーに接続されているので、赤色LEDは点灯したままになっています。この状態で再度起動する場合は、フロントパネル中央のプッシュボタンを押します。外部からは確認できませんが、電源がONになって準備処理が始まり、しばらく待つと(50秒少々で)青色LEDが点灯します。


(3)HAT21の手動操作

 イコライザー以外のフィルターのカットオフ周波数を調整したり、プログラムの修正を行う場合は、HAT21が動作している状態で次の操作をします。
  ・パソコンのSSHターミナルソフトを立ち上げます。
  ・Pi Zroの開発環境(hat21.cや実行形式ソフトがあるディレクトリー)に移動します。
  ・実行中のhat21のプロセスを検索して強制終了します。
$ ps aux | grep hat21     :     : $ kill プロセス番号
 hat21プロセスが実行中のままで新たにhat21を起動すると、重複実行で意味不明のエラーが発生するので注意してください。
 続いて、次のようにHAT21をSSHターミナルから起動して必要な調整を行います。調整が終わったらスペースキーを押して処理を終了しリブートします。
$ ./hat21     :     : Hearing Assist Tool HAT21 Version 1.00 Start! Web連携チューニングを有効にしますか(y/n)? : n     :     : HAT21: Hearing Assist Tool Closed! $ sudo reboot
 プログラム修正をする場合は、使いなれたエディターなどでソースプログラムを編集し、コンパイルを行って手動でテストを行います。終わればリブートします。


(4)充電と再開の手順

 手元のモバイルバッテリーは給電しながら充電できるパススルー機能が無いので、バッテリーの充電プラグを差し込むとHAT21への給電が即停止します。これはPi Zeroの電源プラグを引っこ抜くのと同じように危険なので、充電は次の手順で行います。
  ・充電する前にHAT21をリモートコンソールから[Power Off]する。
  ・モバイルバッテリーはHAT21に接続した状態で充電プラグを挿す(外してもかまわない)。
  ・充電が完了したら充電プラグを外す。
  ・モバイルバッテリーを外していた場合は、USB電源ポートに接続し直すとHAT21が起動する。
  ・外していなかった場合は、モバイルバッテリーの充電確認ボタンを押すとHAT21が起動する。


(5)HAT21のチューニング

 コンデンサーマイク用の複雑な構成に比べて、デジタルマイク版は調整も大変簡単です。最初に行うのは、フィルターのNON(素通しモード)を選択することです。HAT21は単なる音声増幅器として動作するので、音量調整をするにはこのモードが最適です。
 まず、Volume Controlのスライドバーのノブを中央位置に合わせて、マイクを音源の方向に正しく向けます。次にHAT21の上蓋を外して、左奥に設置したヘッドフォンアンプのボリュームを調整します。聴きやすい音量で、左右のバランスがいい位置を見つけます。音量のバランス調整はこれだけです。

 HAT21は、通常は左右の聴力を細かく調整できるイコライザーモードで使用されることになるでしょう。図のようにモード選択でEqualizerを選択すると、周波数バンド別の感度調整スライドバーが変更できるようになります。最初はすべてのバンドのスライドバーを中心にあわせます。続いて、左右のバンド別の感度を調整してもっとも自然に、よく聴き取れるように調整します。
 各バンドの中央周波数は次のとおりです。スライドバーのツマミの位置によって、この周波数を中心にした周辺の音量が増減されます。
   Band-1 : 32 Hz
   Band-2 : 64 Hz
   Band-3 : 128 Hz
   Band-4 : 256 Hz
   Band-5 : 512 Hz
   Band-6 : 1024 Hz
   Band-7 : 2048 Hz
   Band-8 : 4096 Hz
   Band-9 : 8192 Hz
 操作は簡単なのですが、調整による変化は実に微妙で、時間をかけてしっかり調整することが必要です。「よく聴こえる」に加えて「疲れないで聴こえる」周波数分布を探しましょう。聴力検査の結果(オージオグラム)があれば、左右の周波数帯域別の聴力がわかるので、調整の助けになります。

 その他のフィルターのカットオフ周波数は既定値で次のように設定されています。環境によっては別のフィルターに切り替えた方が適切な場合もあるでしょう。いずれもカットオフ周波数の調整ができるので、必要に応じて取り組んでみてください。
   LPF : 8000 Hz (ローパス:カットオフ周波数)
   HPF : 800 Hz (ハイパス:カットオフ周波数)
   BPF : 8000 ~ 400 Hz (バンドパス:低域側カットオフ周波数 ~ 高域側カットオフ周波数)
   変更ステップごとの増減値 : 100 Hz
 具体的な変更の詳細は「第21章 デジタルフィルターの実装」のオプション機能とテストを参照してください。


5.プロジェクトのレビューと今後の課題

 プロジェクト『Raspberry Piによる音声信号処理と聴覚補助ツールの製作』を開始して1年1カ月が経過しました。試行錯誤で紆余曲折のコースをたどりながら、何とか成果物を得ることができました。ここでの成果物とは、でき上がったHAT21だけでなく、自分にとってはその間の不思議や未知との出会いすべてが成果だと感じています。そしてインターネットの素晴らしさを、今さらながら感動しています。昔なら図書館や書店に足を運んで調べる他なかったものが、簡単に手元でできるということに加え、数々の問題へのヒントや解決方法をワールドワイドに入手できる現実には感謝です。とりわけ、難解な問題についての支援サイトに巡り会って、目から鱗が落ちた経験は貴重でした。
 ところで、この間に作成した電子回路やボード類は掲載したもの以外にも多数あり、屑籠に放り込んだパーツ類は数知れません。後期高齢者に突入した眼には微細なハンダ付けで失敗が多発したり、緊張を欠いて配線を間違えたりで、年齢を感じさせられた取り組みでもありました。捨て置いたパーツ類には合掌です。

 こうしてプロジェクトを終えるわけですが、なおいくつかの課題を残しています。その主なものを書き留めておきます。

○コンデンサーマイク用のシステムを完成させること

 このプロジェクトの中でも、ADコンバーターの理論や製作はたいへん面白いテーマであり、音声処理やデジタルフィルターを理解する上でも有益でした。また、製作したマイクアンプが、安価なコンデンサーマイクから十分な情報を引き出してくれたことは驚きでした。
 製作した電源ボードに一連のボード類を接続したときの感度と音質には感動しました。しかし持ち運びにはサイズが大きすぎることからいったん保留し、その後に試したMEMSマイク版に道を譲ることになりました。
 再度全体の構成を眺めると、次のような方法で小型化が可能と思われます。
  ・マイクアンプは半固定抵抗器をカーボン抵抗に置換し、接続端子を省略して小型化を図る。
  ・ADコンバーターは秋月電子の「PCM1808PWR DIP化キット」を使って、なお小型なものを自作する。
  ・ヘッドフォンアンプは、オペアンプのDIP化キットを使って小型なものを自作する。
  ・電源ボードはMEMSマイク版のように分割し、Pi ZeroにはGPIOピンから給電する。
 どこまで取り組めるかわかりませんが、大きな課題として掲げておきたいと思います。


○未解決の問題の積み残し

 動作検証では終始、PortAudioライブラリーのストリーム出力で発生するアンダーフローエラーに悩まされました。原因や解決方法についての情報収集で決め手を欠き、試行錯誤の結果からoutputParameters.suggestedLatencyを設定して動作を安定させることができました。また、エラー発生時の対処方法も独自判断でコードを作成しています。さらに、ミリ秒単位のスリープを含むいくつかの不可思議なコードは、エラーの発生状況を観察しながら追加したものです。いくらかの効果はあるようですが、理論的な意味を欠いたものです。
 このような中で、2021年4月6日に5年ぶりの新バージョン(Version 19.7)発表を目にしました。これを知ったのは今月(2021年9月)上旬で、さっそくダウンロードして、現在ベースにしているRaspbian Buster最終バージョン「raspbian-2020-02-14版」にインストールすると、I2SモジュールのセットアップでOSとのバージョン不一致によるエラーが発生してダメ。
 しかたなく「Raspberry Pi Imager」を使って最新の「Raspberry Pi OS (32-bit) Release 2021-05-07」を導入。それにPortAudioをインストールしたのですが、結果を確認すると「bcm2835 ALSA」が抜け落ちていて動作テストすらできません。これは短期間で解決できそうになく、恥ずかしながら悪戦苦闘の末にギブアップ。今後の課題として棚上げです。


○新たな機能の付加

 他にも録音機能や音楽プレーヤ機能の追加、Bluetoothイヤフォンへの対応など、新たな機能の組み込みもやってみたいですね。できれば、さらにいくつかのマイクを追加して、複数マイクでの距離、角度計測による目標音源へのピント合わせなども興味深いのですが、これは簡単ではなさそうです。


 いくつもの課題を残しながらも、とりあえずデジタル出力マイク版が完成したところで一段落とさせていただきます。オーディオ処理の基礎理論からリアルタイム音声処理、聴力補助ツールに必要なハード製作とデジタルフィルターの実装など、網羅的に取り組んできました。積み重ねてきた内容がいくらかでもお役に立てれば幸いです。振り返ると、ハード製作などで説明が足りない部分も多々見受けられますが、ご容赦ください。
 今後の取り組みで新たな展開があれば、形を変えて(別のテーマとして)発表したいと思います。長らくお付き合いいただきまして大変ありがとうございました。皆様のご健康とご健闘を祈念いたします。


 
Copyright (C) 2011-2024 Marchan, All rights reserved.