C & Fmod Ex - воспроизведение массива / буфера PCM в реальном времени - PullRequest
3 голосов
/ 08 ноября 2010

Я использую массив для обработки радиосигнала и для получения необработанного звука PCM. Я отчаянно пытаюсь воспроизвести этот звук с помощью Fmod Ex.

По сути, возможно ли создать поток, соответствующий моему циклическому буферу, к которому я мог бы обращаться потокобезопасным способом? Будем весьма благодарны за любую основную информацию о том, какие методы использовать.

Если нет, может ли какой-либо другой API Windows 7 добиться цели и как? (ASIO, Васапи ...)

Thx ° - °

1 Ответ

2 голосов
/ 10 ноября 2010

Я предполагаю, что ваши данные непрерывны (всегда обновляются), поэтому вы захотите передать их в FMOD, чтобы сделать это, вы можете переопределить обратные вызовы файлов для определенного звука. Есть хороший пример того, как сделать это, с примером FMOD API usercreatedsound. Если вы просто хотите воспроизвести статический буфер, просто заполните структуру createoundexinfo, описывающую данные, используйте флаг 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 44 кГц, настроите их по необходимости и дадите две функции обратного вызова для чтения и установки, которые 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 воспроизводил ваш буфер.

...