waveIn、waveOut系プログラミングについて

このQ&Aのポイント
  • waveInとwaveOut系のプログラミングについて、メッセージ処理のタイミングや関数の関係について説明してください。
  • win32APIを用いた録音再生プログラムの作成中に、waveIn系とwaveOut系の関数の挙動とメッセージの関係を理解できていないので、教えてください。
  • 具体的には、waveInPrepareやwaveInAddBufferなどの関数がどのタイミングで行われるべきか、録音前に準備する必要性などが気になっています。また、MMSYSERR_~というエラーメッセージの調べ方も教えていただけると助かります。
回答を見る
  • ベストアンサー

waveIn、waveOut系プログラミングについて

立て続けに投稿させて頂いております。 【要点】 メッセージ処理のタイミングについて。  現在win32APIを用いた録音再生をするプログラムを作成中です。最終目的はPCが音声をスピーカーから出力し、それを再度PCに録音するというものです。  waveIn系、waveOut系の関数を用いたプログラムについて様々なホームページを参考にさせて 頂いたのですがホームページごとに関数とメッセージの関係が異なっていた為、挙動をしっかりと 理解する為教えて頂きたいです。  例えば最初にGUI上の録音ボタンを押したときに waveInOpen→waveInPrepare→waveInAddBuffer→waveInStart と行っているのですが 私の認識ではwaveInPrepareはMM_WIM_OPENメッセージを受け取ってから行うものだと考えていたのですが あるホームページではMM_WIM_OPENに対する処理が記述されていない、つまりcase MM_WIM_OPENがないサンプルソース もあり、メッセージを処理するタイミングがわからなくなってしまいました。 1: waveInOpenによりMM_WIM_OPENが発行されるとしたら発行されたかわからないタイミングでwaveInPrepareはやるべきでないと思ったのです。 2: その他waveInAddはどのタイミングで行うのか、等もアドバイスいただけると助かります。 3: 私が見た限りのソースでは録音ボタンを押すとWAVEHDR、HWAVEINを行っているのですが などの準備を行っているのですが、録音前に準備しておけばタイムラグがないのに、、と考えるのですが何か意図が あるのでしょうか。 4:MMSYSERR_~というエラーをwave系関数は出すようなのですがそれについて調べたいのですがMSDN等で調べられるのでしょうか(私が調べた限りなさそうでした) 質問が多くて申し訳ないのですが極力自分で調べたので よろしくお願いいたします。具体的な回答でなくとも 調べるヒントなどいただければ幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
noname#30727
noname#30727
回答No.1

1. MM_WIM_OPEN は、デバイスがオープンされた後に送られるとあるので、そのメッセージを受け取るまで、その他の処理をしないほうが良いように思いますが、waveInOpen から戻って来た時点で既にメッセージが送られていることが明かであれば、特に待たなくても支障は無いでしょう。 (私なら待ちますが) 2. k_shin さんの手順で正しいと思います。 waveInOpen (非同期) ↓ WM_WIM_OPEN メッセージ待ち ↓ waveInPrepareHeader (同期) ↓ waveInAddBuffer (同期) ↓ waveInStart (非同期) 3. 録音ボタンを押さない限り、入力デバイスが存在しなかったとしてもエラー表示をしなくてもよくなるので、プログラムの構造が単純化できる利点はあると思います。タイムラグが大きくて録音が必須な状況であれば、先に準備するべきですよね。 4. waveInOpen だけでも以下のような戻り値があると書いてありますね。 >MMSYSERR_ALLOCATED Specified resource is already allocated. >MMSYSERR_BADDEVICEID Specified device identifier is out of range. >MMSYSERR_NODRIVER No device driver is present. >MMSYSERR_NOMEM Unable to allocate or lock memory. >WAVERR_BADFORMAT Attempted to open with an unsupported waveform-audio format.

k_shin
質問者

お礼

ありがとうございます。 メッセージのタイミングについて教えて頂けたのは本当に助かりました。 MSDNについても調べ方のコツがわかってきたのでこのアドバイスを元に作成していこうと思います。 (検索は.comでないと駄目&関数のみ検索も不可なんですね。) なお、この質問投稿は今日1日待ってから締め切りたいと思います。 丁寧なご回答ありがとうございました。

k_shin
質問者

補足

補足というより追加質問なのですが メッセージを通るポイントに応じてVCのデバッグを使って値を見たのですが WAVEHDRのメンバのdwFlagsの値が18や3、1等の値をとていました。 フラグに使われる値のWHDR_BEGINLOOPが実際にどんな値か調べる為に printf("%d",WHDR_BEGINLOOP)というように、値を調べたところ、 WHDR_BEGINLOOP  4 WHDR_DONE     1 WHDR_ENDLOOP 8 WHDR_INQUEUE 16 WHDR_PREPARED 2 でした。 デバッグ中に現れた18,3にあたる数字はこの5つの中にないのですが どのような可能性が考えられるのでしょうか。 ちなみにwaveInOpenをした時が18,waveInDoneで3といった感じでした。ご意見お願いいたします。

その他の回答 (1)

noname#30727
noname#30727
回答No.2

>デバッグ中に現れた18,3にあたる数字はこの5つの中にないのですが dwFlags メンバはビットの集合です。 ですから、 3 = (1 | 2) = (WHDR_DONE | WHDR_PREPARED) 18 = (2 | 16) = (WHDR_PREPARED | WHDR_INQUEUE) と考えればいいです。 もちろん、たとえば WHDR_DONE かどうか見る場合は、 if (wavehdr.dwFlags & WHDR_DONE) のようにします。

k_shin
質問者

お礼

ありがとうございます。 大変参考になりました。 まだ再生はできませんが色々デバッグしてみます。 今日の0時まで一応締め切らずにおきます。 ありがとうございました。

関連するQ&A

  • 音量のプログラミング

    現在waveIn()関数を使って音声を取得するプログラムを作っています。このプログラムにある一定の音量以上でメッセージを出し、それ以下なら別のメッセージを出すというのをリアルタイムで実行したいのですが、どんな関数を使えばいいのかで戸惑っています。 何かいいものがあれば教えてください。

  • windowsプログラムのデバッグ

     最近VCでwin32API Applicationを作り始めたのですが イベントに対する挙動をチェックしたいのですが方法がわかりません。  今まではConsoleプログラムだけなのでプログラムが動かなかった場合、どこまで動いているのかprintfで チェックしていたのですがwindowsプログラムの場合どうすればそのような動作チェックができるのでしょうか。  プログラム自体はwaveIn、waveOut系を使った録音・再生するだけのプログラムです。 具体的なバグは録音終了を表すMM_WIM_DATAメッセージが 送られてきた場合に再生ボタンを使用可したいのですが 設定した録音時間の3秒をすぎても使用可能になりません。 デバッグ方法がわかればMM_WIM_DATAが本当に行われているのか、 行われていた場合どこでとまっているのか、がわかると思うので教えて頂きたいです。 【開発環境】 環境:VC++6.0ProffessionalEditon OS:Windows2000 【その他】 C言語の知識は入門書を一通り理解できる程度。 リソースファイルは使用しておりません。

  • waveIn、waveOutでの音声録音・再生プログラミングを作成して

    waveIn、waveOutでの音声録音・再生プログラミングを作成しています。 内容は、マルチバッファリング機能で音声の取り込みを行い、同時にファイルへの書き込みと、スピーカーへの出力をするのですが、当然waveInで取り込み後にwaveOutするので、元の音声とずれて音がスピーカーへ出力されます。 WAVEFORMATEX構造体のメンバには秒単位での設定値であるため、最小1秒のずれが計算上でます。実際のズレは1秒も無いですが、かなり気になります。 同様の機能のフリーソフトでは、若干のズレはあってもこのプログラムほどではありません。どのようにすれば、このズレを少なく出来るのでしょうか。 どなたか、ご教示願いたくお願いします。

  • wave系関数のエラーについて

    引き続きwave系のプログラムについての質問をさせて頂きます。  waveInUnPrepared関数で戻り値に5つまりMMSYSERR_INVALHANDLEが返ってくる原因について。  APIによる録音再生プログラムを作っています。 マイクによる録音をしている途中で停止ボタンを押すと waveInResetを呼び出し、MM_WIM_DATAを受け取ったら waveInCloseをし、最後にMM_WIM_CLOSEでwaveInUnPreparedを行い録音終了とするようにました。 ですがwaveInReset、waveInCloseはともに戻り値が0なのですがwaveInUnPreparedは戻り値が5でした。MMSYS.hによると5はMMSYSERR_INVALHANDLEということでした。 現在このプログラムは録音を開始してバッファがいっぱいになったら(3秒)録音を終了する、そのバッファ分再生する。ということはできるですが録音中(3秒以内)に停止ボタンを押してその分だけ再生すると言うことができません。 MMSYSERR_INVALHANDLEが発生する原因についてどのようなものが考えられるのでしょうか。 なおバッファ分の録音&再生時にも戻り値は5でした。 手順 録音ボタン→録音処理→(3秒以内に)停止ボタン→MM_WIM_DATAでwaveInClose→MM_WIM_CLOSEでwaveInUnPrepared 環境 VC+6.0 win2000

  • プログラミングに関して

    プログラミングの勉強をしているのですが、一通り基礎的な本は読破しましたが、長いソースプログラムを白紙の状態から自分で書くことなど出来そうにありません。オープンソースなどの長いソースコードは全て誰かが白紙の状態からあれ程までの長いソースコードを書いているのでしょうか?それとも何かを応用したりどこかの関数を引用したりして書かれているのでしょうか?

  • C言語でのWindowsプログラム

    C言語でウィンドウを作るプログラムを作っているときにふと思ったのですが、Windowsが発行したメッセージを処理する関数(ウィンドウプロジャーでしたっけ?)なのですが、あれはどこの時点で呼び出されているのですか? 教えてください

  • プログラミング言語の説明

    大学4年の者です.  プログラミング言語で作成したアプリケーションについての論文を作成しているのですが,プログラムの説明(変数や関数)についてはどのように説明を行えばよいでしょうか コメントを記載したソースコードを張り付ける方法も考えましたが,それだと文ではないだろうと考え辞めました. 関数の処理はかきつらねるべきなのか段落に番号を振ってわけるのかなど,同期にプログラミング言語を使った論文を書いている人がいないので困っています.

  • Win32 画像処理プログラミング

    Win32プログラムを使って画像処理を行えるプログラムを作成したいのですが、自分ひとりではどうにもなりません。 プログラムの仕様は、 (1) メニューバー「ファイル」、「画像処理」、「ヘルプ」の作成。 (2) 「ファイル」のカスケードメニュー「画像を開く」、「画像を保存する」、「プログラムを終了する」の実行。 (3) 「画像処理」のカスケードメニュー「ビットプレーンの作成」、「領域分割」、「輝度分布の計算」の実行。 この3点です。 関数や構造体を使って最初から組まなければ成りません。 なるべく詳しいプログラムを教えてください。 ( ソースコードを教えていただけるとありがたいです。 ) よろしくお願いします。

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • WindowsマルチメディアのwaveOutに関する質問です。

    WindowsマルチメディアのwaveOutに関する質問です。 複数のWaveOutデバイスにそれぞれ別の音を出すためにwinmm.libを使ってプログラムを組みました。 waveOutGetNumDevs:デバイス数取得 waveOutGetDevCaps:デバイス列挙 waveOutOpen:デバイスのオープン(CALLBACK_FUNCTIONでコールバック使用) ※バッファを10KB×3用意 waveOutPrepareHeader:送信準備 waveOutWrite:送信 コールバック関数: WOM_DONE→ データがあれば終了バッファに新しいデータを充当 waveOutPrepareHeader:送信準備 waveOutWrite:送信 データが無ければデバイスを閉じる と、これで目的の音を鳴らす事は出来たのですが、再生終了後にデバイスを閉じようとすると処理が戻ってきません。 waveOutReset:リセット(これが戻ってこない) waveOutUnprepareHeader:ブロックの解放 waveOutClose:クローズ(リセットをコメントにした場合、これも戻ってこない) そこで質問です。 1.コールバック内からクローズする事に問題はあるのでしょうか。 2.途中で再生を止めようと思い、再生途中でwaveOutResetを行おうとしても同様の現象が起きるのですが、どうやって止めるのが妥当なのでしょうか。 3.参考になるサイトやコード等があれば教えて頂きたいです。 よろしくお願いします。 VisualStudio2008 VC++9 Windows 7 Pro

専門家に質問してみよう