使用 wasapi 渲染音频的问题

Posted

技术标签:

【中文标题】使用 wasapi 渲染音频的问题【英文标题】:problems rendering audio with wasapi 【发布时间】:2020-05-01 04:35:14 【问题描述】:

一段时间后,音频音调变得更尖锐,然后只发出噪音 这让我觉得问题出在我填充缓冲区的方式上

int AudioThreadProc(AUDiosTRUCT* audio) 
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
    HANDLE buffReady = CreateEvent(0, 0, 1, 0);
    audio->client->lpVtbl->SetEventHandle(audio->client, buffReady);

    unsigned int soundBuffSize;
    audio->client->lpVtbl->GetBufferSize(audio->client, &soundBuffSize);
    audio->client->lpVtbl->Start(audio.client);

    static float time = 0;
    float dtime = 1 / (float)44100;

    for (;;) 
        WaitForSingleObject(buffReady, INFINITE);

        unsigned int soundFrames;
        audio->client->lpVtbl->GetCurrentPadding(audio->client, &soundFrames);
        unsigned int FramesToFill = soundBuffSize - soundFrames;
        unsigned short int* soundBuff;
        audio->render->lpVtbl->GetBuffer(audio.render, FramesToFill, &soundBuff);

        for (unsigned int i = 0; i < FramesToFill; i++) 
            unsigned short int soundWave = audio->callback(time);
            time += dtime;
            *soundBuff++ = soundWave;
            *soundBuff++ = soundWave;
        
        audio->render->lpVtbl->ReleaseBuffer(audio.render, FramesToFill, 0);

    
    return 0;

回调函数只是一个正弦波发生器

float callback(float time)
 returns sin(pitch * PI2 * time) * 0xFFFF;


//...
audio.callback = callback;

【问题讨论】:

这看起来不像是有效的 C:AudioThreadProc 有一个 void 参数,这是不允许的,但可能意味着 void * 用于通用参数。但即便如此,它也必须转换为正确的结构类型才能引用它。这甚至可以编译吗? 它是void*,它指向一个包含renderclient和audioclient的结构 没有强制转换就不能引用 void 指针,而且“audio.client”无论如何都不正确。此代码是否在没有警告的情况下编译?你打开最大警告吗? 【参考方案1】:

我认为这里的答案几乎等同于我几年前给出的this answer。随着time 的上升,计算pitch*2π*time 的浮点精度会下降。调整您的代码,使time 在您完成一波数据后重置为零或从零开始偏移。

类似这样的:

time += dtime;
if (time > 1.0) 
    time -= 1.0;

此外,每个样本调用函数的总开销也可能是一个问题。将您的 callback 转换为宏。你不会后悔的。

【讨论】:

谢谢你,它现在可以工作了,我不敢相信它是如此简单

以上是关于使用 wasapi 渲染音频的问题的主要内容,如果未能解决你的问题,请参考以下文章

直接渲染到 WASAPI 时,两个流之一没有音频输出

使用 WASAPI 录制音频流

使用 WASAPI 捕获蓝牙音频数据

我应该为我的音频项目使用 DirectSound 还是 WASAPI?

WASAPI 音频设备的同步

UE4 使用WASAPI获取系统音频