我使用portaudio(http://www.portaudio.com/)。它可以让你以便携的方式创建PCM流。然后你只需将样品推入流中,他们就会播放。
@edit:使用PortAudio非常简单。您初始化库。我使用浮点示例使其变得非常容易。我不喜欢这样写道:
PaError err = Pa_Initialize();
if (err != paNoError)
return false;
mPaParams.device = Pa_GetDefaultOutputDevice();
if (mPaParams.device == paNoDevice)
return false;
mPaParams.channelCount = NUM_CHANNELS;
mPaParams.sampleFormat = paFloat32;
mPaParams.suggestedLatency =
Pa_GetDeviceInfo(mPaParams.device)->defaultLowOutputLatency;
mPaParams.hostApiSpecificStreamInfo = NULL;
然后,当你想播放声音创建了一个流,2路立体声,在44kHz的,适合MP3音频后:
PaError err = Pa_OpenStream(&mPaStream,
NULL, // no input
&mPaParams,
44100, // params
NUM_FRAMES, // frames per buffer
0,
sndCallback,
this
);
然后你实现回调以填充PCM音频流。该回调函数是一个c函数,但我只需调用我的C++类来处理音频。我从我的代码中撕下了这个,现在可能不是100%正确的,因为我删除了大量你不关心的东西。但它的作品有点像这样:
static int sndCallback(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
{
Snd* snd = (Snd*)userData;
return snd->callback((float*)outputBuffer, framesPerBuffer);
}
u32 Snd::callback(float* outbuf, u32 nFrames)
{
mPlayMutex.lock(); // use mutexes because this is asyc code!
// clear the output buffer
memset(outbuf, 0, nFrames * NUM_CHANNELS * sizeof(float));
// mix all the sounds.
if (mChannels.size())
{
// I have multiple audio sources I'm mixing. That's what mChannels is.
for (s32 i = mChannels.size(); i > 0; i--)
{
for (u32 j = 0; j < frameCount * NUM_CHANNELS; j++)
{
float f = outbuf[j] + getNextSample(i) // <------------------- your code here!!!
if (f > 1.0) f = 1.0; // clamp it so you don't get clipping.
if (f < -1.0) f = -1.0;
outbuf[j] = f;
}
}
}
mPlayMutex.unlock_p();
return 1; // when you are done playing audio return zero.
}
因此,我假设Windows是因为您提到了'beep()',但您应该真正告诉我们您的目标平台是什么。 C++没有音频的概念,你使用的任何东西都将取决于平台(除非你找到一个从你那里抽象出来的库,但是,这可能不是必需的)。 – 2012-07-26 21:17:15
它将在Windows上,谢谢指出,我会编辑它。 – AniMerrill 2012-07-26 21:18:36
@AniMerrill,我知道没有简单的方法(在Windows API中)为您的程序生成要播放的声音数据。一个图书馆可能是你最好的选择。 – chris 2012-07-26 21:22:17