C& Fmod Ex - 实时播放PCM阵列/缓冲区

时间:2010-11-08 16:48:45

标签: audio real-time buffer pcm fmod

我使用数组来处理无线电信号并获得原始PCM音频。我正在拼命尝试使用Fmod Ex。

播放此音频

基本上,是否可以创建与我的循环缓冲区相对应的流,我可以以线程安全的方式访问?任何有关使用哪种方法的基本信息都将不胜感激。

如果不是,那么任何其他Windows 7 API都可以解决这个问题吗? (ASIO,Wasapi ......)

Thx° - °

1 个答案:

答案 0 :(得分:2)

我假设您的数据是连续的(始终更新),因此您可能希望将其流式传输到FMOD中,为此您可以覆盖特定声音的文件回调。使用FMOD API usercreatedsound示例有一个很好的例子。如果您只想播放静态缓冲区,只需填写描述数据的createsoundexinfo结构,使用FMOD_OPENMEMORY标志并通过createSound将指针传递给name_or_data。下面是一个更复杂的流案例的例子:

创建声音时,您将使用FMOD_CREATESOUNDEXINFO指定数据的详细信息,然后将其传递给createStream。请注意,除了使用FMOD_OPENUSER,设置解码大小并指定回调以读取数据而不是FMOD_OPENMEMORY并通过name_or_data参数传递数据之外,这基本上是静态样例的处理方式:

FMOD_CREATESOUNDEXINFO exinfo;

memset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));

exinfo.cbsize            = sizeof(FMOD_CREATESOUNDEXINFO);              /* required. */
exinfo.decodebuffersize  = 44100;                                       /* Chunk size of stream update in samples.  This will be the amount of data passed to the user callback. */
exinfo.length            = 44100 * channels * sizeof(signed short) * 5; /* Length of PCM data in bytes of whole song (for Sound::getLength) */
exinfo.numchannels       = channels;                                    /* Number of channels in the sound. */
exinfo.defaultfrequency  = 44100;                                       /* Default playback rate of sound. */
exinfo.format            = FMOD_SOUND_FORMAT_PCM16;                     /* Data format of sound. */
exinfo.pcmreadcallback   = pcmreadcallback;                             /* User callback for reading. */
exinfo.pcmsetposcallback = pcmsetposcallback;                           /* User callback for seeking. */

result = system->createStream(NULL, FMOD_OPENUSER, &exinfo, &sound);
ERRCHECK(result);

这里你说你将提供PCM16 44khz数据,根据需要进行自定义,并为读取和设置位置提供两个函数回调,FMOD将调用这些函数来要求您寻找缓冲区或从中读取内容:

FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen)
{
    // Read from your buffer here...
    return FMOD_OK;
}


FMOD_RESULT F_CALLBACK pcmsetposcallback(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
{
    // Seek to a location in your data, may not be required for what you want to do
    return FMOD_OK;
}

这应该是让FMOD播放缓冲区所需的一切。