問題タブ [waveoutwrite]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
9 に答える
5612 参照

c++ - waveOutWrite() がデバッグ ヒープで例外を引き起こすのはなぜですか?

この問題を調査しているときに、オンラインで次のシナリオについて複数の言及を見つけましたが、プログラミング フォーラムでは常に未回答の質問として扱われていました。これをここに投稿することが、少なくとも私の調査結果を文書化するのに役立つことを願っています.

まず、症状: waveOutWrite() を使用して PCM オーディオを出力する非常に標準的なコードを実行しているときに、デバッガーで実行すると、次のようになることがあります。

明らかに疑わしいのはコード内の別の場所でのヒープの破損ですが、そうではないことがわかりました。さらに、次のコードを使用してこの問題を再現することができました (これは、ダイアログ ベースの MFC アプリケーションの一部です:)

これについて誰かがコメントする前に、はい、サンプル コードは初期化されていないメモリを再生します。スピーカーを最大に上げた状態でこれを試さないでください。

一部のデバッグにより、次の情報が明らかになりました。 waveOutPrepareHeader() は、header.reserved に、最初の 2 つのメンバーとして少なくとも 2 つのポインターを含む構造体のように見えるものへのポインターを設定します。最初のポインターは NULL に設定されます。waveOutWrite() を呼び出した後、このポインターはグローバル ヒープに割り当てられたポインターに設定されます。擬似コードでは、次のようになります。

通常、ヘッダーは、wdmaud.dll の内部関数である waveCompleteHeader() によってアプリケーションに返されます。waveCompleteHeader() は、GlobalHandle()/GlobalUnlock() などを呼び出して、waveOutWrite() によって割り当てられたポインターの割り当てを解除しようとします。上記のように、GlobalHandle() が爆発することがあります。

さて、最初に疑ったように、GlobalHandle() が爆発する理由は、ヒープの破損によるものではありません。内部構造の最初のポインターを有効なポインターに設定せずに waveOutWrite() が返されたためです。戻る前に、そのポインタが指すメモリを解放すると思われますが、まだ逆アセンブルしていません。

これは、Wave 再生システムのバッファーが不足している場合にのみ発生するようです。そのため、これを再現するために単一のヘッダーを使用しています。

この時点で、これが私のアプリケーションのバグであるということに対してかなり良いケースがあります。結局のところ、私のアプリケーションは実行さえしていません。誰もこれを見たことがありますか?

これは Windows XP SP2 で見られます。オーディオ カードは SigmaTel 製で、ドライバーのバージョンは 5.10.0.4995 です。

ノート:

将来の混乱を防ぐために、再生中のバッファを管理するために malloc()/free() を使用することに問題があることを示唆する答えは単に間違っていることを指摘したいと思います。より多くの人が同じ間違いを犯すのを防ぐために、提案を反映するために上記のコードを変更したことに注意してください。違いはありません。waveCompleteHeader() によって解放されるバッファーは、PCM データを含むものではなく、PCM バッファーを解放する責任はアプリケーションにあり、特定の方法で割り当てる必要はありません。

また、使用する waveOut API 呼び出しがどれも失敗しないようにしています。

現在のところ、これは Windows のバグか、オーディオ ドライバのバグであると推測しています。反対意見はいつでも大歓迎です。

0 投票する
3 に答える
2770 参照

windows - waveOutWrite API メソッドからのコールバックの待ち時間 (または遅延) 時間は?

別のフォーラムで、MIDI イベント (Note On メッセージなど) を正確に生成することについて、何人かの開発者と議論しています。人間の耳はわずかなタイミングの不正確さに非常に敏感であり、主な問題は、イベントを約 15 ミリ秒間隔で量子化する比較的低解像度のタイマーを使用していることにあると思います (これは、知覚できる不正確さを引き起こすのに十分な大きさです)。

約 10 年前、私はソフトウェア シンセサイザーと MIDI プレーヤーを組み合わせたサンプル アプリケーション (Windows 95 上の Visual Basic 5) を作成しました。基本的な前提は、各バッファーが 16 分音符のデュレーションであるリープフロッグ バッファー再生システムでした (例: 1 分あたり 120 の 4 分音符の場合、各 4 分音符は 500 ms であり、したがって各 16 分音符は 125 ms であったため、各バッファーはバッファは 5513 サンプルです)。各バッファは waveOutWrite メソッドを介して再生され、このメソッドからのコールバック関数を使用して、次のバッファをキューに入れ、MIDI メッセージを送信しました。これにより、WAV ベースのオーディオと MIDI オーディオの同期が保たれました。

私の耳には、この方法は完璧に機能しました。MIDI ノートはわずかにずれても聞こえませんでした (一方、15 ミリ秒の精度の通常のタイマーを使用して MIDI ノートを再生すると、著しくずれて聞こえます)。

理論的には、この方法は、サンプル、つまり 0.0227 ミリ秒 (1 ミリ秒あたり 44.1 サンプルがあるため) に対して正確な MIDI タイミングを生成します。バッファが終了してから waveOutWrite コールバックが通知されるまでの間にわずかな遅延があると思われるため、これがこのアプローチの真のレイテンシであるとは思えません。この遅延が実際にどれくらい大きくなるか知っている人はいますか?

0 投票する
2 に答える
1328 参照

winapi - HWAVEOUT ハンドルの Wave 形式のクエリ

コンテキスト: waveOut ハンドル (HWAVEOUT) の値を認識するコードがあります。ただし、コードはハンドルを作成しなかったため、ハンドルの作成時に waveOutOpen に渡された WAVEFORMATEX は不明です。

waveOutOpen 呼び出しに渡された WAVEFORMATEX 構造体の内容を調べたいと思います。

これが使用される場所の詳細: コードは、waveOutWrite の代わりに呼び出されるフック関数で実行されます。したがって、コードはハンドル値を認識していますが、ハンドル作成の詳細は認識していません。

人々が調べる必要がないように:
waveOutOpen の署名は次のとおりです。

waveOutWrite のシグネチャは次のとおりです。

注: waveOutOpen もフックしていますが、フックを作成する前に既に呼び出されている可能性があります。

0 投票する
1 に答える
929 参照

c# - Control.Invoke()とそのデリゲートの呼び出しの間の遅延はどのくらいですか?

waveOutOpenメソッドとwaveOutWriteAPIメソッドを使用して小さなチャンクを連続して再生することで長いWAVファイルを再生するコードエンジンがあります。ファイルの再生中にUIを更新するために、各バッファーの再生が完了するとコールバック関数から、フォームのメソッドを呼び出す別のスレッドを呼び出します(コールバック関数内で実行することはできるだけ少なくしたいため)。

EventHandlerフォームには、 UI要素を新しい情報で更新するメソッドを処理するクラスレベルが含まれています。waveOutWriteコールバック関数から呼び出されるformメソッドでは、次のようにInvokeメソッドを使用します。

すべてが機能しますが、UI要素の更新に顕著な遅延または遅延があるように見えます。UpdateDisplayメソッドを使用してアニメーションを駆動しているため、これは簡単にわかります。そのため、遅延は「一時的な中断」として表示され、スプライトは予想される位置にジャンプする前に一瞬フリーズします。

このようなクロススレッド通信には、長い(おそらく10〜15ミリ秒)遅延が発生する可能性がありますか?もしそうなら、このようなものを処理するためのより良い方法は何ですか?

更新:ちなみに、それがここの原因かどうかは確かにわかりませInvoke。もう1つの可能性は、オーディオのチャンクの再生が終了してからコールバック関数が実際に呼び出されるまでの遅延です。

更新2itowlsonの提案に従って、メソッド呼び出しSystem.Diagnostics.Stopwatch間のラグをベンチマークするためにを使用しました。Invoke1156回の測定のうち、0msで1146、1msで8、2msで2を取得しました。Invokeここでの私の犯人ではないと言っても差し支えないと思います。

0 投票する
3 に答える
2247 参照

c# - waveOutWriteおよびwaveOutGetPositionデッドロックの問題

waveOut...からのAPIを使用してオーディオを継続的に再生するアプリに取り組んでいますwinmm.dll。このアプリは「リープフロッグ」バッファーを使用します。これは基本的に、オーディオキューにダンプするサンプルの配列の集まりです。Windowsはそれらを順番にシームレスに再生し、各バッファーが完了すると、Windowsはコールバック関数を呼び出します。この関数内で、次のサンプルセットをバッファーにロードし、それらを処理してから、バッファーをオーディオキューにダンプします。このようにして、オーディオは無期限に再生されます。

アニメーションの目的で、アプリケーションに組み込んwaveOutGetPositionでいます(「バッファ完了」コールバックは不規則であるため、アニメーションがぎくしゃくします)。 waveOutGetPosition再生の現在の位置を返すため、超高精度です。

問題は、私のアプリケーションで、を呼び出すと、waveOutGetPosition最終的にアプリケーションがロックされることです。サウンドが停止し、呼び出しが戻らないということです。問題を示す簡単なアプリにまとめました。ここでアプリを実行できます:

http://www.musigenesis.com/SO/waveOut%20demo.exe

ほんの少しのピアノを何度も聞くだけなら、それは機能しています。問題を実証するためだけのものです。このプロジェクトのソースコードはここにあります(すべての肉はLeapFrogPlayer.csにあります):

http://www.musigenesis.com/SO/WaveOutDemo.zip

最初のボタンは、を呼び出さずにアプリをリープフロッグモードで実行しますwaveOutGetPosition。これをクリックすると、アプリは中断することなく永久に再生されます(Xボタンで閉じてシャットオフします)。waveOutGetPosition2番目のボタンは、リープフロガーを開始し、を呼び出して現在の位置を表示するフォームタイマーも開始します。これをクリックすると、アプリがしばらく実行されてからロックされます。私のラップトップでは、通常15〜30秒でロックされます。せいぜい1分かかります。

私はこれを修正する方法がわからないので、どんな助けや提案も大歓迎です。この問題に関する投稿はほとんど見つかりませんでしたが、複数の呼び出しから、waveOutGetPositionまたはそれへの呼び出しからwaveOutWrite、同時に発生する潜在的なデッドロックがあるようです。これを頻繁に呼び出しているため、システムで処理できない可能性があります。

編集:言及するのを忘れました、私はこれをWindowsVistaで実行しています。これは、他のOSではまったく発生しない可能性があります。

編集2:これらの(未回答の)投稿を除いて、私はこの問題についてオンラインでほとんど見つけていません:

http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7

編集3:さて、私は今、この問題を自由に再現することができます。waveOutGetPosition(次のコード行で)直後に呼び出すとwaveOutWrite、アプリケーションは毎回ハングします。また、特にひどい方法でハングします。アプリ自体だけでなく、OS全体がしばらくの間ロックされているようです。したがって、文字通り同時にではなく、ほぼ同時にwaveOutGetPositionデッドロックが発生した場合は、デッドロックが発生しているように見えます。これは、ロックが機能していない理由を説明している可能性があります。うん。waveOutWrite

0 投票する
2 に答える
2515 参照

audio - WaveOUT API で歪みのないトーン サウンドを生成するために必要な最小のオーディオ バッファーはどれくらいですか?

WaveOut API には、現在再生中のバッファのサイズに関する内部制限がありますか? つまり、非常に小さなバッファーを提供すると、スピーカーに再生されるサウンドに何らかの影響がありますか。小さなバッファで正弦波を生成して再生すると、非常に奇妙なノイズが発生します。ピークのようなもの、または「BUMP」。

完全なストーリー:

洞音信号をリアルタイムで生成できるプログラムを作りました。可変パラメータは、Frequency と Volume です。プロジェクトの要件は、最大レイテンシを 50 ミリ秒にすることでした。したがって、プログラムは、オーディオ信号の周波数を手動で調整できる正弦波信号をリアルタイムで生成できなければなりません。

Windows WaveOut API、C#、および P/invoke を使用して API にアクセスしました。

サウンド バッファが 1000 ミリ秒の場合、すべて正常に動作します。遅延要件に従ってバッファを 50 ミリ秒に最小化すると、特定の周波数ですべてのバッファの最後にノイズまたは「バンプ」が発生します。生成されたサウンドの形式が正しくない (チェックしたところ、そうではない) のか、オーディオ チップで何かが発生したのか、初期化と再生に遅延が発生したのか、私にはわかりません。

制作したオーディオを .wav ファイルに保存すると、すべてが完璧になります。

これは、私のコードに何らかのバグがあるか、オーディオ サブシステムに送信されるバッファ チャンクに制限があることを意味します。

WaveOut を最初に初期化する必要があることを知らない人のために、再生する必要があるバイト数と、再生する必要があるオーディオを含むメモリへのポインターを含む各バッファーのオーディオ ヘッダーを準備する必要があります。プレーヤーになります。

アップデート

ノイズは次の組み合わせで発生します 44100 SamplingRate、16 ビット、2 チャネル、50 ms バッファ、および生成された 201Hz、202Hz、203Hz、204Hz、205Hz ... 219Hz、220Hz、240 Hz の Sinus オーディオ信号は問題ありません

なぜこの 20 の差なのか、私にはわかりません。

0 投票する
1 に答える
463 参照

audio - Windows CE 6.0 R3 で WaveOut API を P/Invoke する方法

Windows CE 6.0 R3 で WaveOut API を P/Invoke する方法は?

これを入れると

Windows XP、7 では動作しますが、Wnidows CE 6.0 では「Can't P/Invoke winmm.dll」というメッセージがスローされます。

私は何を間違っていますか?WaveOut API は他の dll に移動されましたか、それとも別のものですか?

とにかく、SoundPlayer (.NET Compact Framework 3.5 から) は正しく動作します。

0 投票する
1 に答える
149 参照

windows - Webcam オーディオ キャプチャ コールバックから直接 WaveOutWrite

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

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

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

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

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

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

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

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 を使用すれば、問題なく動作することはほぼ確実です.後で確認します..