STマイクロから提供されているCubeMX群の中にX-CUBE-MEMSMIC1があります。X-CUBE-MEMSMIC1はMEMSマイクに関するサンプルファイルや応用ライブラリが用意されています。例えば、PDM出力をPCM出力に変換するライブラリやFFT処理、USBオーディオ、音の位置検出(Sound Source Localization)、音の向きに応じた増幅(Beamforming)といったライブラリが準備されています。
今回は音の位置検出(Sound Source Localization)、Acoustic SLライブラリについて紹介します。Acoustic SLライブラリを使用して、2つor4つのマイクの情報を入力すると音の方向を角度として出力することができます。マイク2つの場合は-90~90度で検出され、4つの場合は0~360度で検出できます。
Acoustic SLライブラリでは、XCORR cross correlationアルゴリズム、GCC-PHATアルゴリズム、BMPHアルゴリズムが実装されており、3つからアルゴリズムを選択できます。Acoustic SLライブラリの紹介PDFに記載されている各アルゴリズムの違いについて下記に記します。
・XCORR cross correlation
-時間領域で処理
-計算処理が軽い
-角度分解能は低い
-マイクの距離を離す必要がある
・GCC-PHATアルゴリズム
-周波数領域で処理
-XCORRより計算処理が必要
-角度分解能は比較的高い
-マイクの距離に影響しない
・BMPHアルゴリズム
-周波数領域で処理
-XCORRよりも計算処理が必要だが、PHATよりも軽い
-マイクの距離に影響しない
-安定性を高めるために過去データに基づいた処理
ヘルプファイルに記載されているアルゴリズム比較を参考に記します。
Acoustic SLライブラリはソースコード形式でなく、*.a形式のライブラリとして提供されており、ライブラリを組み込んで使用します。組み込み方については以前に紹介したこちらを参照してください。また、使用できるSTM32マイコンの中でもM4、M7コアのみ対応と記載されており、STM32シリーズだとF3、F4、F7、G4、H7、L4のみ対応ということになります。
角度検出で使用する関数は下記の通りです。
@メモリ設定関数AcousticSL_getMemorySize
A初期化関数AcousticSL_Init
B閾値設定関数AcousticSL_setConfig
C音データ入力関数AcousticSL_Data_Input
D音源角度取得関数AcousticSL_Process
各関数の設定例を紹介します。
@メモリ設定関数AcousticSL_getMemorySizeとA初期化関数AcousticSL_Init
設定のポイントは下記の通りです。
・音データ配列インクリメント数
音データの入力時にどのような配列かに応じて数が変わります。
例えば、4つの音データが1つの配列に順番に入る場合は4つずつポインタを進めるため、4となります。
int16_t val[512]={マイク1,マイク2,マイク3,マイク4,マイク1,マイク2,マイク3,マイク4,...}
例えば、マイクごとに配列を準備して音データを入力する場合はポインタを1つずつ進めるため、1となります。
int16_t mic1[16]={マイク1,マイク1,...}
int16_t mic2[16]={マイク1,マイク1,...}
・処理までのサンプリング数
角度検出するためのサンプリング数の設定です。4つのマイク合計でのサンプリング数を設定します。
なお、サンプリング周波数16kHz、サンプリング数512の場合、AcousticSL_Data_Inputで1回あたり、各マイク16個のデータ(計64個)を入力し、同様のAcousticSL_Data_Inputを32サイクル繰り返すとAcousticSL_Processで角度を得ることができます。
16個x4chx32cycle=512サンプル
サンプリング周波数16kHz、サンプリング数256の場合は16cycle、サンプリング周波数16kHz、サンプリング数128の場合は8cycleとなります。
uint32_t error_value = 0;
AcousticSL_Handler_t SSL_Handler_Instance;
AcousticSL_Config_t SSL_Config_Instance;
AcousticSL_Config_t SSL_Config_Instance;
SSL_Handler_Instance.channel_number = 4;//マイク数2or4
SSL_Handler_Instance.M12_distance =50;//マイク同士の距離 単位mm
SSL_Handler_Instance.M34_distance =50;//マイク同士の距離 単位mm
SSL_Handler_Instance.sampling_frequency = 16000;//サンプリング周波数
SSL_Handler_Instance.algorithm = ACOUSTIC_SL_ALGORITHM_GCCP;//処理アルゴリズム
SSL_Handler_Instance.ptr_M1_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M2_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M3_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M4_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.samples_to_process = 512;//処理までのサンプリング数 全マイク合計 32,64,128...
SSL_Handler_Instance.M12_distance =50;//マイク同士の距離 単位mm
SSL_Handler_Instance.M34_distance =50;//マイク同士の距離 単位mm
SSL_Handler_Instance.sampling_frequency = 16000;//サンプリング周波数
SSL_Handler_Instance.algorithm = ACOUSTIC_SL_ALGORITHM_GCCP;//処理アルゴリズム
SSL_Handler_Instance.ptr_M1_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M2_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M3_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.ptr_M4_channels = 1;//音データ配列インクリメント数
SSL_Handler_Instance.samples_to_process = 512;//処理までのサンプリング数 全マイク合計 32,64,128...
AcousticSL_getMemorySize( &SSL_Handler_Instance);//サンプリング数に応じた必要メモリ領域
SSL_Handler_Instance.pInternalMemory=(uint32_t *)malloc(SSL_Handler_Instance.internal_memory_size);//メモリ確保
SSL_Handler_Instance.pInternalMemory=(uint32_t *)malloc(SSL_Handler_Instance.internal_memory_size);//メモリ確保
if(SSL_Handler_Instance.pInternalMemory == NULL)
{
printf("SSL Malloc Error\n\r");
}
{
printf("SSL Malloc Error\n\r");
}
error_value = AcousticSL_Init( &SSL_Handler_Instance);//初期化
if(error_value != 0)
{
printf("SSL Config Error\n\r");
}
{
printf("SSL Config Error\n\r");
}
B閾値設定関数AcousticSL_setConfig
分解能は角度分解能を設定します。分解能は内部的に処理されます。
環境音変化閾値はどれくらいの音の変化で音源検出を実行するかを設定します。0~1000の範囲で設定します。
例えば、テストデータとしてsin波等を与えて検証する際は環境音(ノイズ)がないため、0を設定すると常に角度検出されます。
環境音が大きく、大きな音だけで反応させたい場合は値を大きく設定します。
SSL_Config_Instance.resolution=10;//分解能
SSL_Config_Instance.threshold=24;//環境音変化閾値
error_value = AcousticSL_setConfig(&SSL_Handler_Instance, &SSL_Config_Instance);
SSL_Config_Instance.threshold=24;//環境音変化閾値
error_value = AcousticSL_setConfig(&SSL_Handler_Instance, &SSL_Config_Instance);
if(error_value != 0)
{
printf("SSL Config Error\n\r");
}
{
printf("SSL Config Error\n\r");
}
C音データ入力関数AcousticSL_Data_Input
サンプリング周波数16kHz、サンプリング数512の場合、1回のAcousticSL_Data_Inputでは16個x4chデータを入力します。これを32cycle分実行するとサンプリング数512となり、角度データを取得できます。サンプリング数に達していない状態でAcousticSL_Processを実行すると処理が異常終了します。
int16_t val[4][16];
//各チャンネル16個分の音データを変数に入力
res=AcousticSL_Data_Input( (int16_t *)&val[0][0], (int16_t *)&val[1][0],
(int16_t *)&val[2][0], (int16_t *)&val[3][0],
&SSL_Handler_Instance );
(int16_t *)&val[2][0], (int16_t *)&val[3][0],
&SSL_Handler_Instance );
resが1の場合は処理に必要なサンプリング数に達したため、AcousticSL_Processで角度データを取得できます。
resが0の場合は処理に必要なサンプリング数に達していないため、サンプリング数に達するまでAcousticSL_Data_Inputを繰り返して音データを入力します。
D音源角度取得関数AcousticSL_Process
AcousticSL_Data_Inputの返数が1であることを確認後にAcousticSL_Processを実行して音源角度情報を取得します。検出された角度は配列の1番目に0~360(マイク2つの場合は-90~90)の範囲でそのまま角度として出力されます。環境音変化閾値に0以外を設定した場合で環境音変化閾値以下の場合は角度検出されず、-100が返されます。
int32_t result[2];
res=AcousticSL_Process((int32_t *)&result, &SSL_Handler_Instance);
if(result[0]==ACOUSTIC_SL_NO_AUDIO_DETECTED)
{
printf("SoundSource is not detected!::%lo\n\r",result[0]);
}
else
{
printf("SoundSource is detected!::%lo \n\r",result[0]);
}
{
printf("SoundSource is not detected!::%lo\n\r",result[0]);
}
else
{
printf("SoundSource is detected!::%lo \n\r",result[0]);
}
マイクの配置は下記の通りに配置します。
X-CUBE-MEMSMIC1ライブラリは様々な応用例が準備されている一方でPDFやヘルプ資料だけでは情報が少なく、サンプルコードや実際の関数を使用しながら調べる必要があります。使いこなすまでに苦労したため、情報としてまとめてみました。