0

VFW とオーディオ キャプチャ コールバックを使用して、Webcam からオーディオデータをキャプチャしています。同時に、同じキャプチャ コールバックの本体内で、waveOutWrite を使用して、サンプリングされたデータをデフォルトの MAPPER に転送します。

Webcam からの信号品質は、1 チャネル/8 ビット/11025 サンプル/秒です。FORMAT_QUERYフラグを指定したwaveOpenのおかげで、サウンド形式はデフォルトのオーディオ デバイスでサポートされています。

waveWriteOutの戻り値はNOERRORですが、私の予想とはかけ離れています。部屋の中は静かで、空のホワイトノイズのような音のはずです。

Pls、音のYouTube録音を聞いてください

16K 程度のサイズのパックごとに開始し、WAVEHDR 構造は問題ありません。その後、徐々に速度が低下し、システムの回復不能エラーで終了します。

それは何に似ていますか?

以下は VFW からのオーディオ dta レシーバー コードです。lpWHdr は視覚的には問題ありません。内部フラグが 2 = Prepared にトリガーされていても、VFW と WaveAudio が互いに作成されているようです :)

public static void capAudioStreamCallback(UIntPtr hWnd, ref WAVE.WAVEHDR lpWHdr) {
    Say(String.Format(DateTime.Now.ToString("mm:ss:fff ") + "Received {0} of audio data", lpWHdr.dwBytesRecorded.ToString()));
    Application.DoEvents();
    WA.WAVEHDR_FLAGS flag = (WA.WAVEHDR_FLAGS) lpWHdr.dwFlags;
    if ((WA.WAVEHDR_FLAGS)lpWHdr.dwFlags != WA.WAVEHDR_FLAGS.WHDR_PREPARED)
                CheckWAError("waveOutPrepareHeader", WA.waveOutPrepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
    CheckWAError("waveOutWrite", WA.waveOutWrite(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
    CheckWAError("waveOutUnprepareHeader", WA.waveOutUnprepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
    return;
}

    static void CheckWAError(string Func, WA.MMSYSERR err) {
        if (err == WA.MMSYSERR.MMSYSERR_BASE_NOERROR) { Say(Func + " WA Ok"); return; }
        IntPtr str = Marshal.AllocHGlobal(200);
        string s = "";
        WA.waveOutGetErrorText(err, str, 200);
        s = Marshal.PtrToStringAnsi(str);
        Marshal.FreeHGlobal(str);
        Say(Func + " err: " + s);
    }

DateTimeミリ秒のスタンプが表示され、1400ミリ秒ごとに刻み、サンプルレート= 11025であり、バッファサイズは約16500バイト= OKのように見えるため、バッファはオーバーランしていないと思います..

UPD:管理されていないバッファーを管理対象にコピーし、その値を調べました。鋸歯または過負荷の副鼻腔のように見えます。0 4 0 3 0 32 109 213 255 251 255 243 241 97 0 7 0 2 1 1 0 5 0 そして、ほぼ同じ数と同じ周期で再び上下します。正確ではありませんが、ほぼ同じです (+/-)。また、そのカムからの信号を内蔵の Windows レコーダーを使用して録音することもできます。また、信号レベルが上下にジャンプするように、自分の声の上下が見えるので、Web カメラのマイクも問題ありません。 VFW入力オーディオ信号フィーダーが間違っています。WAVEFORMATEX を受け入れて WAVEHDR を送り返しても、どちらも問題ありません... しかし、バッファ データには Web カメラではなく他のソースが入力されていますが、VFW は Web カメラからのものである必要があると言っています。 、そしてそれは機能しています。私は1つの余分なメッセージを追加しました: SendMessage(camHwnd, WM_CAP_SET_CALLBACK_WAVESTREAM, 0, audioCallback); VFW の代わりに waveIn を使用すれば、問題なく動作することはほぼ確実です.後で確認します..

4

1 に答える 1

0

問題は非常に単純で、USB ハードウェアの故障でした。USBカメラを取り外して、再度接続する必要がありました。

とにかく、それについての私の知識を共有したいと思います。

1)オーディオデータのパックを取得して再生側に送信する非同期メカニズムを使用する必要があります。最初のバッファが再生されるまで、新しいバッファを再生に送信しないようにする必要があります。このメソッドは、「ダブル」または「トリプル」バッファリングと呼ばれます。また、VFW を使用すると、WM_CAP_GET_SEQUENCE_SETUP メッセージと CAPTUREPARAMS 構造体を使用して、非常に快適に整理できます。wNumAudioRequested パラメータは、オーディオデータを audioCallback に送信するために、循環的に使用される異なるバッファの数を設定するために使用されます。デフォルトでは 10 に設定されていますが、これで十分です。

2) オーディオ信号が有効な信号であるかどうかを確認する最良の方法は、次のとおりです。WAVESTREAM コールバックで、受信したバッファからのバイトを audiodata と共に管理された静的バイト配列にマーシャリングします。次に、コールバック内で、Console.Write(array[i] + " ") を使用して 50 ~ 100 個のサンプル値を出力し、声の上下で値が変化しているかどうかを確認します。ゼロ レベルが WAVEFORMATEX->wBitsPerSample 値の中間にあることを考慮してください。私の場合 (8 ビット/サンプル)、値は 125 126 127 128 129 です。無音、信号なし、またはゼロ ノイズとして受け入れられます。 . オーディオデータが正しいことを確認したら、目標にさらに進むことができます。

3) マイク モードで録音する場合は、ローカル出力ウェーブ デバイスを閉じた方がよいことを忘れないでください。あなたの目標は、録音またはネットワーク経由で送信するオーディオ データを収集することです。データを取得してローカルで waveOuit しようとしないでください。スピーカーのレイテンシー値がマイクデータのサンプリング速度よりも少し高い場合があり、私の場合のようにバッファーが乱雑になることがあります。次に、「録音とは、オーディオデータを収集、保存、または送信することであり、録音後または同時にエンドポイント PC で再生する必要があります。

4) コードの続き

于 2015-08-29T02:56:27.683 に答える