标签: waveoutwrite

为什么waveOutWrite()会在调试堆中导致异常?

在研究这个问题时,我在网上发现了以下场景的多个提及,总是作为编程论坛上未解答的问题.我希望在此发布此内容至少可以记录我的发现.

首先,症状:在运行使用waveOutWrite()输出PCM音频的相当标准代码时,我有时会在调试器下运行时得到这个:

 ntdll.dll!_DbgBreakPoint@0()   
 ntdll.dll!_RtlpBreakPointHeap@4()  + 0x28 bytes    
 ntdll.dll!_RtlpValidateHeapEntry@12()  + 0x113 bytes   
 ntdll.dll!_RtlDebugGetUserInfoHeap@20()  + 0x96 bytes  
 ntdll.dll!_RtlGetUserInfoHeap@20()  + 0x32743 bytes    
 kernel32.dll!_GlobalHandle@4()  + 0x3a bytes   
 wdmaud.drv!_waveCompleteHeader@4()  + 0x40 bytes   
 wdmaud.drv!_waveThread@4()  + 0x9c bytes   
 kernel32.dll!_BaseThreadStart@8()  + 0x37 bytes    
Run Code Online (Sandbox Code Playgroud)

虽然明显的嫌疑人会在代码中的其他地方出现堆损坏,但我发现事实并非如此.此外,我能够使用以下代码重现此问题(这是基于对话框的MFC应用程序的一部分:)

void CwaveoutDlg::OnBnClickedButton1()
{
    WAVEFORMATEX wfx;
    wfx.nSamplesPerSec = 44100; /* sample rate */
    wfx.wBitsPerSample = 16; /* sample size */
    wfx.nChannels = 2;
    wfx.cbSize = 0; /* size of _extra_ info */
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nBlockAlign …
Run Code Online (Sandbox Code Playgroud)

c++ windows audio waveoutwrite

13
推荐指数
1
解决办法
5231
查看次数

Control.Invoke()与其Delegate的调用之间有多长时间的延迟?

我有一个代码引擎,通过使用waveOutOpen和waveOutWrite API方法连续播放较小的块来播放长WAV文件.为了在文件播放时更新我的​​UI,在每个缓冲区完成播放时从回调函数更新我调用一个单独的线程(因为你想在回调函数中做尽可能少的事情)调用我的表单中的方法.

该表单包含一个类级别EventHandler,该级别处理一个方法,在该方法中我使用新信息更新UI元素.在从waveOutWrite回调函数调用的form方法中,我使用Invoke方法,如下所示:

if (_updatedisplay == null)
{
    // UpdateDisplay contains code to set control properties on the form
    _updatedisplay = new EventHandler(UpdateDisplay);
}
Invoke(_updatedisplay);
Run Code Online (Sandbox Code Playgroud)

Everythings工作,但似乎偶尔会有UI元素更新的明显延迟或延迟.这很容易看到,因为我使用UpdateDisplay方法来驱动动画,因此延迟显示为"打嗝",其中精灵在跳转到其预期位置之前会在一瞬间冻结.

这样的跨线程通信有时可能会有很长(可能是10-15毫秒)的延迟吗?如果是这样,处理这样的事情的更好方法是什么?

更新:顺便说一下,我绝对相信Invoke是这里的罪魁祸首.另一种可能性是在一大块音频完成播放和实际调用回调函数之间存在滞后.

更新2:根据itowlson建议,我用a System.Diagnostics.Stopwatch来衡量Invoke和方法调用之间的滞后.在1156次测量中,我在0ms获得1146,在1ms获得8,在2ms获得2.我认为可以说Invoke这不是我的罪魁祸首.

.net c# multithreading waveoutwrite

6
推荐指数
1
解决办法
735
查看次数

双缓冲 waveOutWrite() 像地狱一样口吃

【谜底已解;对于那些寻求解释的人,它在这篇文章的底部]

下面是我尝试使用 WindowswaveOut*()函数编写的 Windows 音调生成器。

尽管按照 MSDN 实际上做了所有事情(例如应该手动重置的回调事件),但我无法从该死的东西中获得平滑的方波播放 - 实际上,任何平滑的播放,但为了简单起见,我演示了方块。缓冲区边框总是用点击来迎接我!看起来 Windows 只是忽略了我使用双缓冲的事实。

生成器本身与缓冲区大小无关,如果我使用更大的缓冲区,无缝播放会持续更长的时间——但是当缓冲区最终结束时,会发出咔哒声。

帮助。

#define _WIN32_IE 0x0500
#define _WIN32_WINNT 0x0501
#define WINVER _WIN32_WINNT

#include <windows.h>
#include <mmsystem.h>
#include <commctrl.h>

#include <stdint.h>
#include <stdio.h>
#include <math.h>



short freq, ampl;



typedef struct {
    long chnl, smpl, bits, size, swiz;
    void *sink, *data[2];
} WAVE;



LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wPrm, LPARAM lPrm) {
    switch (uMsg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        case WM_NOTIFY:
            switch (((NMHDR*)lPrm)->idFrom) { …
Run Code Online (Sandbox Code Playgroud)

c++ windows audio waveoutwrite waveout

5
推荐指数
1
解决办法
1300
查看次数

waveOutWrite API方法回调的延迟(或延迟)时间是多少?

我正在与另一个论坛上的一些开发人员就准确生成MIDI事件(Note On messages等)进行辩论.人耳对于轻微的定时误差非常敏感,我认为他们的主要问题来自于他们使用相对低分辨率的定时器,这些定时器以大约15毫秒的间隔量化它们的事件(这足以引起可察觉的不准确性).

大约10年前,我编写了一个示例应用程序(Windows 95上的Visual Basic 5),它是一个组合的软件合成器和MIDI播放器.基本前提是一个蛙跳缓冲回放系统,每个缓冲区是十六分音符的持续时间(例如:每分钟120个四分音符,每个四分音符是500毫秒,因此每个十六分音符是125毫秒,所以每个缓冲液是5513个样品).每个缓冲区都通过waveOutWrite方法播放,此方法的回调函数用于排队下一个缓冲区并发送MIDI消息.这使基于WAV的音频和MIDI音频保持同步.

在我看来,这种方法工作得非常完美 - MIDI音符听起来甚至没有声音(如果你使用一个普通的计时器,精确到15毫秒来播放MIDI音符,它们会听起来明显不合时宜).

理论上,这种方法可以产生对样本准确的MIDI定时,或0.0227毫秒(因为每毫秒有44.1个样本).我怀疑这是这种方法的真正延迟,因为在缓冲区完成和通知waveOutWrite回调之间可能存在一些轻微的延迟.有谁知道这种延迟实际上有多大?

windows audio waveoutwrite waveout

1
推荐指数
1
解决办法
2407
查看次数

使用 WaveOUT API 产生无失真的音调声音所需的最小音频缓冲区是多少

WaveOut API 对当前播放的缓冲区大小是否有一些内部限制?我的意思是,如果我提供一个非常小的缓冲区,它会以某种方式影响扬声器播放的声音吗?当我用小缓冲区生成和播放正弦波时,我遇到了非常奇怪的噪音。类似峰值或“BUMP”的东西。

完整的故事:

我编写了一个可以实时生成窦声音信号的程序。可变参数是频率和音量。项目要求最大延迟为 50 毫秒。因此,该程序必须能够实时产生可手动调节音频信号频率的正弦信号。

我使用 Windows WaveOut API、C# 和 P/invoke 来访问 API。

当声音缓冲区大小为 1000 毫秒时,一切正常。如果我根据延迟要求将缓冲区最小化到 50 毫秒,那么对于某些频率,我会在每个缓冲区末尾遇到噪音或“BUMP”。我不明白生成的声音是否格式错误(我检查过但没有),或者音频芯片发生了什么问题,或者初始化和播放过程中出现了一些延迟。

当我将生成的音频保存到 .wav 文件时,一切都很完美。

这意味着我的代码中一定存在一些错误,或者音频子系统对发送给它的缓冲区块有限制。

对于那些不知道 WaveOut 必须首先初始化,然后必须为每个缓冲区准备音频标头,其中包含需要播放的字节数以及指向包含需要播放的音频的内存的指针。成为玩家。

更新

以下组合出现噪声:44100 采样率、16 位、2 通道、50 ms 缓冲区,并生成 201Hz、202Hz、203Hz、204Hz、205Hz ... 219Hz、220Hz、240 Hz 的正弦音频信号,正常

为什么会相差20,我不知道。

audio buffer signals waveoutwrite waveout

1
推荐指数
1
解决办法
2948
查看次数

标签 统计

waveoutwrite ×5

audio ×4

waveout ×3

windows ×3

c++ ×2

.net ×1

buffer ×1

c# ×1

multithreading ×1

signals ×1