0
0

We use webm video format in our game,which the audio part of it is ogg.
I separatede the video and audio data by using libwebm.
Can I use fmod to play the audio data?
libwebm parse the file piece by piece. So I can’t get the whole audio data at the beginnning.
Is there any examples if fmod support this?

  • You must to post comments
1
0

This is off-topic, but there is a race condition in the code sample you posted. You should be calling ResetEvent inside the first critical section block e.g. if ( bAudioFrameQueueEmpty ) ResetEvent(..);

For the second question, createStream() is the correct function to be calling.

  • You must to post comments
0
0

Oh,There do have a race condition. It’s my fault.
I have fixed this error and play both sounds and pictures.
Thanks for your help.

  • You must to post comments
0
0

Thanks for your reply.
I have played the sound in this way.
But I met another problem when I try to play both pictures and sounds.
Don’t consider synching picture with sound.Main thread decode the image and display it.
When meeting a audio frame,it put the audio frame into a queue.
PCMCALLBACK pick data from the queue.It will wait if there is not enough data in the queue.
[code:26nds9al]

//put the audio frame in a std::deque (main thread)
else if(pTrack->GetType() == mkvparser::Track::kAudio)
{
const mkvparser::Block::Frame& Frame = block_ptr->GetFrame(m_frame_state.m_frame_idx);
const mkvparser::Block::Frame* pFrame = &Frame;

            EnterCriticalSection(&g_AudioC_S);
            m_AudioFrameDeque.push_back(pFrame);

            std::deque<const mkvparser::Block::Frame*>::size_type size = m_AudioFrameDeque.size();

            if (size > 20)
            {
                SetEvent(g_hAudioDequeEvent);
            }

            LeaveCriticalSection(&g_AudioC_S);

}//kAudio
[/code:26nds9al]

[code:26nds9al]
// pick data from deque (PCMCALLBACK)
while ( datalen > 0 )
{
EnterCriticalSection(&g_AudioC_S);

    bAudioFrameQueueEmpty = m_AudioFrameDeque.empty();

    LeaveCriticalSection(&g_AudioC_S);

    if ( bAudioFrameQueueEmpty )
    {
        WaitForSingleObject(g_hAudioDequeEvent, INFINITE);

        ResetEvent(g_hAudioDequeEvent);

        if (g_bQuit)
        {
            return -1;
        }
    }

    EnterCriticalSection(&g_AudioC_S);

    std::deque<const mkvparser::Block::Frame*>::size_type size = m_AudioFrameDeque.size();
    if ( size <= 0 )
    {
    }

    const mkvparser::Block::Frame* pFrame = m_AudioFrameDeque.front();
    m_AudioFrameDeque.pop_front();

    LeaveCriticalSection(&g_AudioC_S);

           ...

     }

[/code:26nds9al]

But sometimes WaitForSingleObject can’t block the thread when g_hAudioDequeEvent is non-signaled, even through the return value is WAIT_OBJECT_0. Then lead to an error.
This is only two place used the deque and g_hAudioDequeEvent EVENT.

Another question is

Here is how I create the Sound
[code:26nds9al]
FMOD_CREATESOUNDEXINFO infopcm;
memset(&infopcm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
infopcm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
infopcm.numchannels = 2;
infopcm.defaultfrequency = 44100;
infopcm.decodebuffersize = 0;
infopcm.length = infopcm.defaultfrequency * infopcm.numchannels * 4 * kvm_r.GetAudioDurationInSecond();
infopcm.format = FMOD_SOUND_FORMAT_PCMFLOAT;
infopcm.pcmreadcallback = pcmreadcallback;
infopcm.pcmsetposcallback = pcmsetposcallback;

result = g_pFmodSystem->createStream(0, 
    FMOD_OPENUSER | FMOD_LOOP_OFF | FMOD_2D | FMOD_OPENONLY, &infopcm, &sound);
if ( result != FMOD_OK )
{
    printf("FMOD::System::createStream failed");
}
result = g_pFmodSystem->playSound(sound, 0, false, &channel);
if ( result != FMOD_OK )
{
    printf("FMOD::System::playSound failed");
}

[/code:26nds9al]

After turn result = g_pFmodSystem->createStream(…) to
result = g_pFmodSystem->createSound(…)

PCMCALLBACK is not invoked anymore.

  • You must to post comments
0
0

And The audio data parsed by libwebm is still ogg data,not decoded.
thanks in advance

  • You must to post comments
0
0

I have a look at user_created_sound example. Looks like FMOD_SOUND_PCMREADCALLBACK can achieve what I want.
But I have two questions here.
I read a ogg file into memory and want to use PCMREADCALLBACK to play it.I do this just want to learn how to use PCMREADCALLBACK.
It can be played in FMOD_OPENMEMORY mode with nothing wrong.
But there is only noise in FMOD_OPENUSER mode.
[code:2cltuv3w]
//read the file into memory
BYTE* bufferpcm = 0;
unsigned int havereadpcm = 0;
FILE* filepcm = NULL;
fopen_s( &filepcm, "20_cairo.ogg", "rb" );
fseek( filepcm, 0, SEEK_END );
long lenpcm = ftell( filepcm );
fseek( filepcm, 0, SEEK_SET );
bufferpcm = (BYTE*)malloc( lenpcm );
fread( bufferpcm, 1, lenpcm, filepcm );
fclose( filepcm );

FMOD_CREATESOUNDEXINFO infopcm;
memset(&infopcm, 0, sizeof(FMOD_CREATESOUNDEXINFO));
infopcm.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
infopcm.numchannels = 2;
infopcm.defaultfrequency = 44100;
infopcm.decodebuffersize = 44100;
infopcm.length = (unsigned int)lenpcm;
infopcm.format = FMOD_SOUND_FORMAT_PCM16;
infopcm.pcmreadcallback = pcmreadcallback;
infopcm.pcmsetposcallback = pcmsetposcallback;
infopcm.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS;

FMOD::Sound* pPCMSound = NULL;
FMOD::Channel* pPCMChannel = NULL;
FMOD_RESULT result;
result = m_pFmodSystem->createSound(0, FMOD_OPENUSER|FMOD_CREATESTREAM, &infopcm, &pPCMSound);
if ( FMOD_OK == result )
{       
    result = m_pFmodSystem->playSound(pPCMSound, 0, false, &pPCMChannel);
    if (result != FMOD_OK)
    {
        return -1;
    }
}

//PCMREADCALLBACK
FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND* sound, void* data, unsigned int datalen)
{
memcpy(data, (bufferpcm + havereadpcm), datalen);
havereadpcm += datalen;
return FMOD_OK;
}

FMOD_RESULT F_CALLBACK pcmsetposcallback(FMOD_SOUND* sound, int subsound, unsigned int position, FMOD_TIMEUNIT posttype)
{
return FMOD_OK;
}
[/code:2cltuv3w]

I don’t understand where’s wrong.

And the other qustion, I notice that the first param of createSound is 0 in FMOD_OPENUSER.
But sometimes it play more than one video at the same time in our game.
what should I do?

  • You must to post comments
0
0

I have a look at manaualdecode example in fmodex sdk.(Just a suggestion, please supplement examples in fmod api sdk if you have time.Newbie like me which never use fmodex before don’t even know there are so many examples)
My understanding is I can’t pass encoded data to PCMREADCALLBACK, data come from Sound::readData have been decoded by fmod.So my previous code is wrong.
But libwebm parse the video file piece by piece so I can’t get the whole audio file at the beginning.
Because fmod can decode a ogg file and play it, I think I do not must use libvorbis to decode the data then pass it to PCMREADCALLBACK.
But how to do?
I believe that someone here must have this kind of experience.
Any advice is appreciated.

  • You must to post comments
0
0

WebM does not contain ogg data, it contains vorbis data. Ogg is a container format, vorbis is an audio codec. FMOD cannot decode raw vorbis data, it can only decode it from within a container such as ogg or fsb (our own container format).

If you use libvorbis to decode vorbis to PCM you can feed it to FMOD piece-wise using the PCMREADCALLBACK.

  • You must to post comments
Showing 7 results
Your Answer

Please first to submit.