2011年09月10日

マイクからリアルタイムで音声を取得する(C++)



タイトルの通り、マイクからの入力をリアルタイムで分析するソースを書いてみました。


手順は

 マイクから音声を取得
   ↓
 高速フーリエ変換(FFT)
   ↓
 リアルタイムで音程を取得

といった感じです。
内容としては比較的簡単だと思われます。



@ マイクから音声を取得

参考ページ
音声の入力

それぞれの関数について詳しく説明されているので非常にわかりやすいです。
紹介ページの半分より下のソースを改造していきます。

大まかな手順としては

0.1秒程度のメモリ領域を2つ確保しておいて、
片方が満杯になったらもう一方で録音を始め、
満杯になった方の波形を表示する。
これを繰り返す。

といった感じ。


まずはC++でコンパイルする際に出るエラーを潰していきます


「'void *' から 'BYTE *' に変換できません。」

malloc(動的メモリの確保?)関数を使うときに、C言語であれば自動で変換してくれるのですが、
C++ではしてくれないようなので型の変換を明示する必要があります。

bWave1 = (BYTE*)malloc(N);



「'BYTE *' から 'LPSTR' に変換できません。」

whdr.lpData = bWave; の部分のせいだと思われます。
これもまた、C言語なら勝手に変換してくれるのですがC++では自動で型変換してくれないためです。
型変換を明示すればなんとかなります。

whdr.lpData = (char*) bWave;



これでとりあえず動作はするはずです。


波形を描画するために、設定に若干の変更を加えます。

#define SRATE 11025
 ↓
#define SRATE 44100 // サンプリング周波数

whdr1.dwBufferLength = SRATE;
 ↓
whdr1.dwBufferLength = N ; // Nはフーリエ変換する際の長さ。


後は、MM_WIM_DATAメッセージが送られて来たときの処理を変更すれば完成です。

	case MM_WIM_DATA:
		MyDraw( ((PWAVEHDR)lp)->lpData ) ; // 波形を描画する関数
		waveInAddBuffer(hWaveIn , (PWAVEHDR)lp , sizeof(WAVEHDR));
		return 0;



これで録音は完成です。

FFTや音程取得は需要があれば記事を上げようと思います(`・ω・´)



posted by ヒホ at 17:03| Comment(1) | TrackBack(0) | C++ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
こんにちわ。
とてもわかりやすくて、いつもいろいろと参考にさせていただいています。

今回、マイクからの入力に関しての記事なんですが、いざ実行してみようとすると、

static WAVEFORMATEX wfe;
static HWAVEOUT hWaveOut;
static HWAVEIN hWaveIn;
static BYTE *bWave;
static WAVEHDR whdr;

の部分がエラーに引っ掛かります。
もしよろしければ、何かアドバイスをいただけないでしょうか?

私の理解力が足りないばかりにお手数をおかけしますが、よろしくお願いします。
Posted by at 2011年12月22日 14:24
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
最近の記事