Winapi IAudioClient-播放结束时收到通知?

Winapi IAudioClient-播放结束时收到通知?,winapi,audio,notifications,wasapi,Winapi,Audio,Notifications,Wasapi,我不断地将数据发送到IAudioClient(GetBufferSize/getcurrentppadding/GetBuffer/ReleaseBuffer),但我想知道音频设备何时播放完我发送的最后一个数据。我不想假设播放器仅仅因为我向设备发送了最后一块数据而停止:它可能仍然在播放缓冲数据 我尝试使用IAudioClock/IAudioClock 2检查硬件缓冲区位置,但从发送最后一个块的那一刻起,它就保持不变 我在imnotificationclient和IAudioSessionNoti

我不断地将数据发送到
IAudioClient
GetBufferSize/getcurrentppadding/GetBuffer/ReleaseBuffer
),但我想知道音频设备何时播放完我发送的最后一个数据。我不想假设播放器仅仅因为我向设备发送了最后一块数据而停止:它可能仍然在播放缓冲数据

我尝试使用
IAudioClock
/
IAudioClock 2
检查硬件缓冲区位置,但从发送最后一个块的那一刻起,它就保持不变

我在
imnotificationclient
IAudioSessionNotification
接口中也没有看到任何相关内容

我错过了什么


谢谢

imNotificationClient和IAudioSessionNotification对您没有帮助,它们分别用于检测新设备/新应用程序会话。据我所知,当设备(独占模式)或音频引擎(共享模式)使用最后一个样本时,WASAPI中没有显式发送事件的内容。我在过去使用的一个技巧(虽然是DirectSound,但在WASAPI中应该同样有效)是连续检查音频缓冲区中的可用空间(对于WASAPI,使用GetCurrentPadding)。发送最后一个样本后,立即记录当前填充,假设它是N帧。然后继续向AudioClient写入零,直到处理完N帧(如IAudioClock(2)所报告的,或者只是使用计时器进行guestimate),然后停止流。这是否适用于独占事件驱动模式流是驱动程序质量问题;驱动程序可以选择报告“真实”播放位置,也可以只处理完整缓冲区大小的块。

IAudioClock::GetPosition/etc。无论音频是否播放,始终返回相同的值。我可以使用IAudioMeterInformation.GetPeakValue并检查返回值是否==0。在我的情况下,这似乎是可行的(音频是一个麦克风录制,至少有一些环境噪音),但我并不真的喜欢它作为一个通用的解决方案-在音频流中肯定会有一段时间处于静默状态。只要不停止流,AudioClock应该返回不断增加的位置。有没有重现这个问题的示例代码?我没有什么可以发布的-我有一个Delphi应用程序可以流式处理数据(工作正常),流式处理时,我有一个计时器每50毫秒触发一次(只是一个测试),然后调用AudioClock::GetPosition。两个返回值都被记录。它们始终保持不变,只有在我重新初始化设备时才会有所不同。事实证明,您可以仅使用GetCurrentPadding来实现这一点。一旦发送最后一个数据包,记录填充(=缓冲区中的有效音频),然后立即用零填充缓冲区的其余部分。在此之后,如果缓冲区中有P帧有效音频,只需继续写入零,直到至少按下P帧静音。通过这种方式,您可以确保音频引擎获取了有效音频数据的P帧(可能还有一些额外的静音)。看见