0
0

I have a TV app that uses FMOD to playback the PCM stream from a capture card. The example in 3.75 (record/Main.cpp) worked extremely well for syncing the recorded stream with the playback device and handled the difference in frequency quite nicely.

I’ve tried converting the code to the new API with little success. I’ve tried creating a stream (FMOD::Sound) and using lock/unlock to get a pointer to the buffer and copying the PCM stream into the buffer. I have not yet found a combination of flags for which this works, I’ve pretty much tried every combination of FMOD_OPENUSER, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT, FMOD_OPENRAW with FMOD_SOFTWARE and FMOD_LOOP_NORMAL. All I get is silence, which is what was originally in the buffer.

I’ve resisted converting the code to use a callback to fill the buffer, as that would require a massive change to the surrounding code.

Is there a way to make this work with the new API?

  • You must to post comments
0
0

I think your main issue would be the fact that you’re using a stream – you can’t lock or unlock a stream.

What does your new code look like?

In the record example it was
FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255);
I would think the equivalent in FMOD Ex is

FMOD::Sound *sample;
FMOD_CREATESOUNDEXINFO exinfo;
FMOD_RESULT result;

memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.defaultfrequency = RECORDRATE;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.channels = 2;
exinfo.length = RECORDLEN * exinfo.channels * sizeof(short);

result = System->createSound(0, FMOD_OPENUSER, &exinfo, &sample);

I didnt compile so excuse any typos.

  • You must to post comments
0
0

Here is the code that I’ve been using. I also have it playing back OGG music files when TV is not active, and that is working perfectly. This is using 4.40.04 on Ubuntu Linux. I’ve tried many other combination of the flags and setting/not setting the suggestedsoundtype.

[code:60rasvdv]
Initialize() {
FMOD_RESULT result;
result = FMOD::System_Create(&m_pFmodSystem);
if (result != FMOD_OK) {
// Should not happen....
printf("Cannot create FMOD system\n");
}

unsigned int version;
result = m_pFmodSystem->getVersion(&version);
if (result != FMOD_OK) {
    // Should not happen....
    printf("Cannot get FMOD version\n");
}
if (version < FMOD_VERSION) {
    // out of date FMOD version, should not happen...
    printf("FMOD version mismatch\n");
}

result = m_pFmodSystem->init(32, FMOD_INIT_NORMAL, 0);
if (result != FMOD_OK) {
    // Should not happen....
    printf("Cannot initialize FMOD\n");
}

//
// Make the buffer roughly 1/2 a second
//
m_totalSamples = 1536 * 16;
m_lowerSamples = (3 * m_totalSamples / 8);
m_upperSamples = (5 * m_totalSamples / 8);
m_playbackSpeed = 48000;
m_currentSpeed = 48000;

FMOD_CREATESOUNDEXINFO soundInfo;
memset(&soundInfo, 0, sizeof(soundInfo));
soundInfo.cbsize = sizeof(soundInfo);
soundInfo.numchannels = 2;
soundInfo.defaultfrequency = 48000;
soundInfo.format = FMOD_SOUND_FORMAT_PCM16;
soundInfo.length = m_totalSamples * 2 * sizeof(short);
soundInfo.suggestedsoundtype = FMOD_SOUND_TYPE_RAW;

m_pTVAudioBuffer = (char*) malloc(soundInfo.length);

memset(m_pTVAudioBuffer, 0, soundInfo.length);

int flags = FMOD_SOFTWARE | FMOD_LOOP_NORMAL | FMOD_OPENMEMORY_POINT;

result = m_pFmodSystem->createStream(m_pTVAudioBuffer , flags, &soundInfo, &m_pSampleTVAudio);
if (result != FMOD_OK) {
    printf("Cannot create FMOD TV Audio buffer\n");
    assert(0);
}

}

WriteToBuffer()
{
...

int offset = m_recordSample * 4;
int length = pFrame->GetLength();
void *ptr1;
void *ptr2;
unsigned int len1 = 0;
unsigned int len2 = 0;

m_pSampleTVAudio->lock(offset, length, &ptr1, &ptr2, &len1, &len2);

memcpy(ptr1, pFrame->GetBuffer(), len1);
if (len2 > 0) {
    memcpy(ptr2, pFrame->GetBuffer() + len1, len2);
}

m_pSampleTVAudio->unlock(ptr1, ptr2, len1, len2);

...

if (!m_bTVAudioStarted) {
    //
    // Start the stream if we have filled 1/2 of the stream buffer
    //
    if (m_recordSample >= m_totalSamples/2) {
        FMOD_RESULT result;

        result = m_pFmodSystem->playSound(FMOD_CHANNEL_FREE, m_pSampleTVAudio, true, &m_pChannelTVAudio);
        if (result != FMOD_OK) {
            printf("Error starting TV audio playback\n");
        }

        FMOD::Sound* pSound = 0;

        if (m_pChannelTVAudio->getCurrentSound(&pSound) != FMOD_OK) {
            printf("Channel not pointing to a sound!\n");
            assert(0);
        }
        else if (pSound != m_pSampleTVAudio) {
            printf("Channel pointing to the wrong sound!\n");
            assert(0);
        }

        m_pChannelTVAudio->setVolume((float) 1.0);
        m_pChannelTVAudio->setPaused(false);

        bool isPlaying = false;
        m_pChannelTVAudio->isPlaying(&isPlaying);
        if (!isPlaying) {
            printf("FMOD TV Audio channel was not started!!\n");
            assert(0);
        }

        m_bTVAudioStarted = true;
    }
}

...
}
[/code:60rasvdv]

  • You must to post comments
0
0

I’ll just repeat what I said in my last post 😀

[quote:1wbdgbjq]I think your main issue would be the fact that you’re using a stream – you can’t lock or unlock a stream.[/quote:1wbdgbjq]

Your calls to fmod should be returning errors, i would suggest checking every single return value for error codes, it would have helped you track down your issue I would say.

  • You must to post comments
0
0

Thanks Brett!

I somehow convinced myself that I had to use createStream for a changing audio stream.

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.