0
0

Hello, I have an issue using FMOD sound engine. The issue shows up executing the following:

include "stdafx.h"

include "fmod.hpp"

include <windows.h>

define CHECK_FMOD(Expression) \

{ \
FMOD_RESULT l_eFMODResult__ = (Expression); \
if (l_eFMODResult__ != FMOD_OK) \
printf(#Expression " Failed.\n"); \
} ((void) 0)

int _tmain(int argc, _TCHAR* argv[])
{
FMOD_RESULT l_eResult;
FMOD::System* l_pFMODSystem = NULL;
FMOD::System_Create(&l_pFMODSystem);

CHECK_FMOD(l_pFMODSystem-&gt;init(64, FMOD_INIT_NORMAL, NULL));

FMOD_MODE l_eMode = 
    FMOD_2D |
    FMOD_OPENMEMORY |
    FMOD_OPENRAW |
    FMOD_LOOP_NORMAL;

// Poppulate FMOD Sound info struct. 
FMOD_CREATESOUNDEXINFO l_oFMODSoundInfo;
l_oFMODSoundInfo.cbsize = sizeof(l_oFMODSoundInfo);
l_oFMODSoundInfo.fileoffset = 0;
l_oFMODSoundInfo.length = 352800; // 2 channels * 16bits (2 bytes) * 44100Hz * 2 seconds.
l_oFMODSoundInfo.format = FMOD_SOUND_FORMAT_PCM16;
l_oFMODSoundInfo.numchannels = 2;
l_oFMODSoundInfo.defaultfrequency = 44100;
l_oFMODSoundInfo.decodebuffersize = 0;
l_oFMODSoundInfo.initialsubsound = 0;
l_oFMODSoundInfo.numsubsounds = 0;
l_oFMODSoundInfo.inclusionlist = NULL;
l_oFMODSoundInfo.inclusionlistnum = 0;
l_oFMODSoundInfo.pcmreadcallback = 0;
l_oFMODSoundInfo.pcmsetposcallback = 0;
l_oFMODSoundInfo.nonblockcallback = 0;
l_oFMODSoundInfo.dlsname = NULL;
l_oFMODSoundInfo.encryptionkey = NULL;
l_oFMODSoundInfo.maxpolyphony = 0;
l_oFMODSoundInfo.userdata = NULL;
l_oFMODSoundInfo.suggestedsoundtype = FMOD_SOUND_TYPE_UNKNOWN;

char l_szSoundData[352800];
memset(l_szSoundData, 0, 352800);

FMOD::Sound* l_pSound = NULL;
CHECK_FMOD(l_eResult = l_pFMODSystem-&gt;createSound(l_szSoundData, l_eMode, &amp;l_oFMODSoundInfo, &amp;l_pSound));

FMOD::Channel* l_pChannel = NULL;
CHECK_FMOD(l_eResult = l_pFMODSystem-&gt;playSound(FMOD_CHANNEL_FREE, l_pSound, true, &amp;l_pChannel));

CHECK_FMOD(l_eResult = l_pChannel-&gt;setPaused(false));

bool l_bIsPlaying = false;
l_pChannel-&gt;isPlaying(&amp;l_bIsPlaying);
while (l_bIsPlaying)
{
    static unsigned int ls_uDebugCount = 0;
    if (ls_uDebugCount &lt; 100)
    {
        unsigned int l_uPosition = 0;
        CHECK_FMOD(l_pChannel-&gt;getPosition(&amp;l_uPosition, FMOD_TIMEUNIT_PCMBYTES));

        char l_szText[256];
        memset(l_szText, 0, 256);
        sprintf(l_szText, &quot;Pos = %d\n&quot;, l_uPosition);
        printf(l_szText);
        OutputDebugStringA(l_szText);

        ls_uDebugCount++;
    }

    CHECK_FMOD(l_pChannel-&gt;isPlaying(&amp;l_bIsPlaying));
}

l_pFMODSystem-&gt;release();

getchar();

return 0;

}

===========================================

The output I get is:

Pos = 0
Pos = 0
Pos = 0
Pos = 0
Pos = 80
Pos = 136
Pos = 196
Pos = 284
Pos = 344
Pos = 372
Pos = 432
Pos = 48
Pos = 80
Pos = 168
Pos = 224
Pos = 284
Pos = 344
Pos = 404
Pos = 432
Pos = 80
Pos = 136
Pos = 196
Pos = 224
Pos = 256
Pos = 344
Pos = 404

[…]

Pos = 80
Pos = 136
Pos = 168
Pos = 224
Pos = 284
Pos = 432
Pos = 48
Pos = 108
Pos = 136
Pos = 224
Pos = 256
Pos = 284
Pos = 344
Pos = 404
Pos = 432
Pos = 136
Pos = 224
Pos = 256
Pos = 316
Pos = 372
Pos = 432
Pos = 48
Pos = 80
Pos = 136
Pos = 224
Pos = 284
Pos = 316
Pos = 404
Pos = 432
Pos = 520
Pos = 576
Pos = 636
Pos = 664
Pos = 784
Pos = 844
Pos = 872
Pos = 960
Pos = 988
Pos = 1016
Pos = 1076
Pos = 1164
Pos = 1224
Pos = 1252
Pos = 1312
Pos = 1400
Pos = 1456
Pos = 1516
Pos = 1576
Pos = 1636
Pos = 1664
Pos = 1724

As you can see, the position increases slowly for a couple ticks, but then gets back and restarts, increases a couple ticks, gets back again, and then after a few loops, it gets on track and keeps increasing until the end of the sound.

This is a big issue in my code as I have implemented my own streaming and I keep track of the position through FMOD::Channel::getPosition() to know what sound data was processed and find out up to where some new sound data can be written in the circular buffer using FMOD::Sound::lock().

Now if getPosition() returns a smaller value than the previous getPosition() call, I have to assume the play cursor of the buffer has just reached the end of the buffer and started processing data at the beginning of the buffer. And because here the position suddenly gets smaller, some sound data gets overwritten before it was processed to audio output.

What is going on here? Is this a bug? Is there a way to avoid this behavior? I noticed that creating the sound from a wave file instead of raw data taken from memory, the issue doesn’t show up.

Anyways, any input would be highly appreciated. Thanks a lot,

  • You must to post comments
0
0

yeah I just found out how to emphasize my code correctly in a post, so here it is for better readability 😉

[code:3vy97y7p]#include "stdafx.h"

include "fmod.hpp"

include <windows.h>

define CHECK_FMOD(Expression) \

{ \
FMOD_RESULT l_eFMODResult__ = (Expression); \
if (l_eFMODResult__ != FMOD_OK) \
printf(#Expression " Failed.\n"); \
} ((void) 0)

int _tmain(int argc, _TCHAR* argv[])
{
FMOD_RESULT l_eResult;
FMOD::System* l_pFMODSystem = NULL;
FMOD::System_Create(&l_pFMODSystem);

CHECK_FMOD(l_pFMODSystem-&gt;init(64, FMOD_INIT_NORMAL, NULL));

FMOD_MODE l_eMode = 
    FMOD_2D |
    FMOD_OPENMEMORY |
    FMOD_OPENRAW |
    FMOD_LOOP_NORMAL;

// Poppulate FMOD Sound info struct. 
FMOD_CREATESOUNDEXINFO l_oFMODSoundInfo;
l_oFMODSoundInfo.cbsize = sizeof(l_oFMODSoundInfo);
l_oFMODSoundInfo.fileoffset = 0;
l_oFMODSoundInfo.length = 352800; // 2 channels * 16bits (2 bytes) * 44100Hz * 2 seconds.
l_oFMODSoundInfo.format = FMOD_SOUND_FORMAT_PCM16;
l_oFMODSoundInfo.numchannels = 2;
l_oFMODSoundInfo.defaultfrequency = 44100;
l_oFMODSoundInfo.decodebuffersize = 0;
l_oFMODSoundInfo.initialsubsound = 0;
l_oFMODSoundInfo.numsubsounds = 0;
l_oFMODSoundInfo.inclusionlist = NULL;
l_oFMODSoundInfo.inclusionlistnum = 0;
l_oFMODSoundInfo.pcmreadcallback = 0;
l_oFMODSoundInfo.pcmsetposcallback = 0;
l_oFMODSoundInfo.nonblockcallback = 0;
l_oFMODSoundInfo.dlsname = NULL;
l_oFMODSoundInfo.encryptionkey = NULL;
l_oFMODSoundInfo.maxpolyphony = 0;
l_oFMODSoundInfo.userdata = NULL;
l_oFMODSoundInfo.suggestedsoundtype = FMOD_SOUND_TYPE_UNKNOWN;

char l_szSoundData[352800];
memset(l_szSoundData, 0, 352800);

FMOD::Sound* l_pSound = NULL;
CHECK_FMOD(l_eResult = l_pFMODSystem-&gt;createSound(l_szSoundData, l_eMode, &amp;l_oFMODSoundInfo, &amp;l_pSound));

FMOD::Channel* l_pChannel = NULL;
CHECK_FMOD(l_eResult = l_pFMODSystem-&gt;playSound(FMOD_CHANNEL_FREE, l_pSound, true, &amp;l_pChannel));

CHECK_FMOD(l_eResult = l_pChannel-&gt;setPaused(false));

bool l_bIsPlaying = false;
l_pChannel-&gt;isPlaying(&amp;l_bIsPlaying);
while (l_bIsPlaying)
{
    static unsigned int ls_uDebugCount = 0;
    if (ls_uDebugCount &lt; 100)
    {
        unsigned int l_uPosition = 0;
        CHECK_FMOD(l_pChannel-&gt;getPosition(&amp;l_uPosition, FMOD_TIMEUNIT_PCMBYTES));

        char l_szText[256];
        memset(l_szText, 0, 256);
        sprintf(l_szText, &quot;Pos = %d\n&quot;, l_uPosition);
        printf(l_szText);
        OutputDebugStringA(l_szText);

        ls_uDebugCount++;
    }

    CHECK_FMOD(l_pChannel-&gt;isPlaying(&amp;l_bIsPlaying));
}

l_pFMODSystem-&gt;release();

getchar();

return 0;

}[/code:3vy97y7p]

  • You must to post comments
0
0

I could make a patch that successfully worked. What I did is not to update any data in the circular buffer until the circular buffer read cursor (value returned by getPosition()) has not got out of the unstable zone for the first time at beginning of the buffer (for position values under roughly 2000 PCMBYTES). After that point all getPosition() values returned are consistent and everything works fine.

This is an ugly patch but it works.

However it would be better withtout the patch, so if the bug (is it a bug? or am I the bug? :-?) could get fixed, that would be nice.

Thanks,

  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.