我使用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,
&mPaParams,
44100,
NUM_FRAMES,
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();
memset( outbuf, 0, nFrames * NUM_CHANNELS * sizeof( float ));
if ( mChannels.size() )
{
for ( s32 i = mChannels.size(); i > 0; i-- )
{
for ( u32 j = 0; j < frameCount * NUM_CHANNELS; j++ )
{
float f = outbuf[j] + getNextSample( i )
if ( f > 1.0 ) f = 1.0;
if ( f < -1.0 ) f = -1.0;
outbuf[j] = f;
}
}
}
mPlayMutex.unlock_p();
return 1;
}
beep()
,但你应该真正告诉我们你要针对哪个平台。C ++没有音频概念,任何你使用的都将取决于平台(除非你找到一个可以为你抽象这个问题的库,但即使如此,这也可能不是必需的)。 - Ed S.