我正在使用Win API在C ++中使用简单的音序器应用程序。我的应用程序使用wav文件播放鼓节拍,使用midi演奏和弦和低音线。每个wav文件在它们自己的线程中播放如下(省略错误处理):
while(_runThread)
{
// Wait for the event telling us to play the sound
WaitForSingleObject(_threadEventHandle, INFINITE);
ResetEvent(_threadEventHandle);
if(_runThread)
{
// Clear anything currently playing
waveOutReset(_waveOutHandle);
while(_sampleDataIndex < _sampleDataSize)
{
for(int i = 0; i < NUM_BUFFERS; i++)
{
if(_runThread && _waveHdr[i].dwFlags & WHDR_DONE)
{
PrepareAudioBuffer(i);
_result = waveOutWrite(_waveOutHandle, &_waveHdr[i], sizeof(WAVEHDR));
}
}
// Wait for the event telling us the device has completed playback to be signaled
if(_runThread)
{
WaitForSingleObject(_waveDoneEventHandle, INFINITE);
ResetEvent(_waveDoneEventHandle);
}
}
_sampleDataIndex = 0;
}
}
PrepareAudioBuffer函数只是将样本加载到缓冲区中。通过以下来自计时器的调用激活该线程:
SetEvent(_threadEventHandle);
通过以下方式实现Midi播放:
#define MIDI_MESSAGE(volume, note, command) ((volume << 16) | (note << 8) | command)
midiOutShortMsg(_midiOutHandle, MIDI_MESSAGE(volume, note, command));
中间和音频播放均由相同的定时器逻辑触发。然而,我需要修复的2的播放之间存在轻微但明显的差距。我怀疑这是因为在单独的线程中播放wav并等待SetEvent以及上下文切换引入的任何延迟。我知道有可能以完美的同步方式播放音频和midi,因为像Cubase,Sonar等应用程序这样做。感激不尽的任何想法或建议。