【谜底已解;对于那些寻求解释的人,它在这篇文章的底部]
下面是我尝试使用 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) 我找不到任何有关 waveOut API 线程安全性的信息。
创建新的 waveOut 句柄后,我有这些线程:
线程 1:缓冲区处理。使用这些 API 函数:
线程2:Gui,控制器线程。使用这些 API 函数:
这两个线程在同时使用相同的 waveOut 句柄时运行。在我的测试中,我没有发现功能有任何问题,但这并不意味着它是安全的。
这个架构是线程安全的吗?有没有关于waveOut API 线程安全的文档?关于 waveOut API 线程安全性还有其他建议吗?
谢谢。
我正在使用Windows waveOut API(又名MME或多媒体扩展)mmsystem.h。某些程序会更改音频播放采样率(例如,从44.1kHz更改为48kHz),这对于我的程序检测当前播放采样率非常有用,因此它可以警告用户Windows将重新采样程序的输出。
根据此文档http://msdn.microsoft.com/zh-cn/library/aa909811.aspx,waveOutGetPlaybackRate返回设备当前正在执行的重采样百分比(例如,设备以44.1播放,程序以44.1播放音频因此它将返回1.0)。我很好奇是否有一种方法可以获取设备的绝对采样率,而不是相对的。在Windows Vista / 7/8中,您可以通过以下方式手动找到该值:控制面板>声音>播放,右键单击默认播放设备,然后选择属性,然后选择高级选项卡。因此,我试图通过查询操作系统来获取此“默认格式”值。
有问题的程序是用Pascal编写的,但是,我通常使用C / C ++引用。
实际上是c ++中的新手.我写了这段代码,但说无法从"waveOutProc"转换为"DWORD_PTR".你能告诉我如何修复它吗?
谢谢
void CALLBACK Audio::waveOutProc(HWAVEOUT hWaveOut, unsigned int uMsg,
unsigned long dwInstance, unsigned long dwParam1,
unsigned long dwParam2)
{
/*
* pointer to free block counter
*/
int* freeBlockCounter = (int*)dwInstance;
/*
* ignore calls that occur due to openining and closing the
* device.
*/
if(uMsg != WOM_DONE) { return ; }
EnterCriticalSection(&waveCriticalSection) ;
(*freeBlockCounter)++ ;
LeaveCriticalSection(&waveCriticalSection) ;
}
Run Code Online (Sandbox Code Playgroud)
////////////////////////////////////////////////// ////////////////////////////////
void Audio::playSound(const char* filename)
{
HWAVEOUT hWaveOut ;
HANDLE hFile;
WAVEFORMATEX wfx ;
char buffer[1024];
int i; …Run Code Online (Sandbox Code Playgroud) 我需要制作Delphi库/组件来获取当前播放的声音(它不播放我的应用程序,只是播放扬声器上的一般声音)返回数据(左声道和右声道的幅度)。目前我通过麦克风扫描来处理它。他正在寻找,我尝试了网上不同的VU表(Torry...),但它们与Win7及更高版本不兼容。有人知道解决方案吗?谢谢
我正在与另一个论坛上的一些开发人员就准确生成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回调之间可能存在一些轻微的延迟.有谁知道这种延迟实际上有多大?
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,我不知道。