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

发布于 2024-10-01 08:37:03 字数 209 浏览 10 评论 0原文

我使用数组来处理无线电信号并获取原始 PCM 音频。我拼命尝试使用 Fmod Ex 播放此音频。

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

如果不能,任何其他 Windows 7 API 是否可以实现此目的以及如何实现? (ASIO、Wasapi...)

Thx °-°

I use an array to process radio signal and to obtain raw PCM audio. I am desperately trying to play this audio using Fmod Ex.

Basically, would it be possible to create a stream corresponding to my circular buffer, that I could access in a thread-safe way ? Any basic information about what methods to use would be greatly appreciated.

If no, could any other Windows 7 API do the trick and how ? (ASIO, Wasapi...)

Thx °-°

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葮薆情 2024-10-08 08:37:03

我假设您的数据是连续的(总是更新),因此您希望将其流式传输到 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 数据,根据需要自定义,并为 read 和 setposition 提供两个函数回调,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 回放缓冲区所需的一切。

I'm assuming your data is continuous (always updating) so you would want to stream it into FMOD, to do this you could override the file callbacks for a particular sound. There is a good example of doing this with the FMOD API usercreatedsound example. If you just want to play a static buffer simply fill out a createsoundexinfo struct describing the data, use the FMOD_OPENMEMORY flag and pass a pointer to the data through createSound as name_or_data. Below is an example of the more complex stream case:

When creating the sound you would use FMOD_CREATESOUNDEXINFO to specify the details of your data, then pass that to createStream. Note this is basically how you would do the static sample case except you are using FMOD_OPENUSER, setting decode size and specifying the callbacks to read the data instead of FMOD_OPENMEMORY and passing the data via the name_or_data param:

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);

Here you are saying that you will provide PCM16 44khz data, customize as required, and give two function callbacks for read and setposition which FMOD will call asking you to either seek your buffer or read something from it:

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;
}

That should be everything you need to get FMOD playing back your buffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文