0
0

For some reason, I can’t get wav files to use loop-points. They just loop from the start to the end.

I’m using the latest FMOD Ex and it’s running under SOFTWARE mode.

Here is my code:

[code:1doqotsu]
””””’ PLAYSOUNDPAUSED() ””””’

wavinfo_t waveInfo = GetWavinfo( (char*)sample, pMemFile, wavlength );

        if( waveInfo.loopstart == 0 )       
            pChannel->setMode( FMOD_LOOP_NORMAL );
        if( waveInfo.loopstart > 0 )
        {
            int sample_length = (waveInfo.samples * waveInfo.channels * waveInfo.width);            
            pChannel->setMode( FMOD_LOOP_NORMAL );
            pChannel->setLoopPoints( waveInfo.loopstart, FMOD_TIMEUNIT_PCMBYTES, sample_length, FMOD_TIMEUNIT_PCMBYTES );
            pChannel->setPosition( 0, FMOD_TIMEUNIT_MS );
        }
        else
            pChannel->setMode( FMOD_LOOP_OFF );

””””’ UNPAUSESOUND() ””””’
[/code:1doqotsu]

Am I calling functions in the wrong order? I debugged the loop start position, and it is coming back correctly.

e.g. the loop start point defined in the WAV file’s data chunk is "23395" and the sample length is calculated to be "54997".

  • You must to post comments
0
0

Actually it looks to me like you’re thinking the 3rd parameter is loop length when it is not. It is loopend, so you probably have to subtract 1 * width etc

  • You must to post comments
0
0

Please also note that:
pChannel->setPosition( 0, FMOD_TIMEUNIT_MS );

Is called after loop points are set. I’m doing this because I wish to have the sound play from the start the first time, and from then on, use the loop points.

If setPosition() isn’t used/called, loop points still don’t work, and the sound plays from the start of the file to the end of the file continuously.

  • You must to post comments
0
0

Why does it work with fmod::sound->setLoopPoints(), then?

Loopend should be at the end of the file. That’s why sample_length is specified as the third paramter in setLoopPoints. It works…

Just when doing it on the fly with channel->setLoopPoints(), it says invalid parameter. Are you saying I must subtract (1 * width) only when using the channel interface?

  • You must to post comments
0
0

hahaha! This is why humans shouldn’t program code.

I’ve been looking at this issue for a few hours and my looping sounds would stop playing if they didn’t have a loop start point. All along I forgot an "else if"

pChannel->setMode( FMOD_LOOP_OFF ); is always called!
😉 😳

If a wav file DOES have a loopstart position, however, setLoopPoints still does not work.

  • You must to post comments
0
0

no, it is not just for channels, it is both.
length is not the same as loopend. Ie a length of 10 has a loopstart 0 and loopend 9.

Can you reproduce your issue in one of the fmod examples.

  • You must to post comments
0
0

More information:

Channel->SetLoopPoints still doesn’t work.

  • You must to post comments
0
0

If I use Sound->setLoopPoints (Not Channel->setLoopPoints) when the sounds are first loaded into memory by FMOD Ex, it works correctly.

Channel->setLoopPoints says "(36) An Invalid parameter was passed to this function."

Is this a bug? I’m using the identical parameters.

  • You must to post comments
0
0

You’re going to have to provide a wav, and more information on what you are doing (you didnt say if it was a stream or sample), with a full source repro preferred. I’ve tried to reproduce your issue with no luck, either stream or sample, channel setlooppoints works fine each time.

  • You must to post comments
0
0

Nope, not a stream.
Sounds are created with system->createSound() at startup, and played with system->playSound()

I’ll upload one of the wav files. These are Half-Life 1 wav files, so as far as I know, I think they were created using CoolEdit by Valve.

I’m using the Quake 1 source (WaveInfo() function) to read the file data.
[code:1wzol1tu]
typedef struct wavinfo_s
{
int rate;
int width;
int channels;
int loopstart;
int samples;
int dataofs; // chunk starts this many bytes from file start
} wavinfo_t;

wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
{
wavinfo_t info;
int i;
int format;
int samples;

memset (&info, 0, sizeof(info));

if (!wav)
    return info;

iff_data = wav;
iff_end = wav + wavlength;

// find "RIFF" chunk
FindChunk("RIFF");
if (!(data_p && !strncmp(data_p+8, "WAVE", 4)))
{
printf("Missing RIFF/WAVE chunks\n");
return info;
}

// get "fmt " chunk
iff_data = data_p + 12;
// DumpChunks ();

FindChunk("fmt ");
if (!data_p)
{
    printf("Missing fmt chunk\n");
    return info;
}
data_p += 8;
format = GetLittleShort();
if (format != 1)
{
    printf("Microsoft PCM format only\n");
    return info;
}

info.channels = GetLittleShort();
info.rate = GetLittleLong();
data_p += 4+2;
info.width = GetLittleShort() / 8;

// get cue chunk
FindChunk("cue ");
if (data_p)
{
data_p += 32;
info.loopstart = GetLittleLong();
// Com_Printf("loopstart=%d\n", sfx->loopstart);

// if the next chunk is a LIST chunk, look for a cue length marker
    FindNextChunk ("LIST");
    if (data_p)
    {
        if (!strncmp (data_p + 28, "mark", 4))
        {  // this is not a proper parse, but it works with cooledit...
            data_p += 24;
            i = GetLittleLong ();   // samples in loop
            info.samples = info.loopstart + i;
        }
    }
}
else
    info.loopstart = -1;

// find data chunk
FindChunk("data");
if (!data_p)
{
printf("Missing data chunk\n");
return info;
}

data_p += 4;
samples = GetLittleLong ();

if (info.samples)
{
    if (samples < info.samples)
        Error ("Sound %s has a bad loop length", name);
}
else
    info.samples = samples;

info.dataofs = data_p - wav;

return info;

}[/code:1wzol1tu]

Here is a link to the loop-point based looping file, rocket1.wav used in Half-Life 1:
http://www.svencoop.com/davemcd/rocket1.wav

It does work just fine with Sound->setLoopPoints… so I’m not sure why it is saying ‘Invalid parameter’ for Channel->setLoopPoints.

  • You must to post comments
0
0

you are not giving complete info, for some reason you gave us some wav loading code? (why would you be using this when fmod supports wav files)
I am more interested in what you called createSound with, parameters and flags.

  • You must to post comments
0
0

Ahh, I thought you wanted to know how I extracted the wav data info, which gets passed to channel->setLoopPoints().

Here is my file parser / sound loading code…

[code:fzucwq9q]//—————————————————————–
// LoadSoundList()
// Purpose: Enumerates and loads sounds from the server-generated
// sound list. This allows the server to send indexes
// rather than strings to play sound effects.
//—————————————————————–
bool CSoundEngine :: LoadSoundList( void )
{
if( !m_fServiceReady || (m_flNextLoadCheck > gEngfuncs.GetClientTime()) )
return false;

ClearSoundArrays(); //Make sure we're all ready to go.

FILE *pFile;
char filename[256]; //We need to account for very long directory/filenames.
sprintf( filename, "%s/sound/auto_soundlist.txt", gEngfuncs.pfnGetGameDirectory() );
pFile = fopen(filename,"r");

int cSounds = 0; //sound counter

if (pFile)
{
    //-----------------------------------------------------------------
    // Check if the correct file is available for this map
    //-----------------------------------------------------------------
    const char *pActualLevelName = gEngfuncs.pfnGetLevelName();
    char ScannedLevelName[96];
    fscanf( pFile, "%s\n", ScannedLevelName );
    if( strcmp( ScannedLevelName, pActualLevelName ) )
    {
        m_flNextLoadCheck = gEngfuncs.GetClientTime() + 3; //Try again in 3 seconds
        return false; //Version mismatch
    }

    while ( !feof( pFile ) && cSounds < MAX_SOUNDS )
    {
        fscanf(pFile, "%s\n", m_SoundList[cSounds]);
        cSounds++;
    }
    fclose (pFile);
    //ALERT(at_console,"Finished enumerating the sound list.\n");
}
else
{
    //Error... we don't have a sound list to parse! 
    m_flNextLoadCheck = gEngfuncs.GetClientTime() + 3; //Try again in 3 seconds
    return false;
}

char sound_filename[256]; //We need to account for very long directory/filenames.
FMOD::Sound *pSound;

//Loop through all loaded sounds
for( int i = 0; i < cSounds; i++ )
{
    if( m_SoundList[i] != NULL )
    {
        sprintf(sound_filename,"%s/sound/%s", gEngfuncs.pfnGetGameDirectory(), m_SoundList[i]);
        FMOD_RESULT result = FMODsystem->createSound( sound_filename, (FMOD_3D | FMOD_SOFTWARE), NULL, &pSound );

        if( result != FMOD_OK )
        {
            if( result == FMOD_ERR_FILE_BAD )
            {
                //Error loading file...
                ALERT(at_console, "FMOD - Error loading sound: %s\n", sound_filename );
                continue;
            }
            else if( result == FMOD_ERR_FILE_NOTFOUND )
            {
                ALERT(at_console, "FMOD - File not found: %s\n", sound_filename );
                continue;
            }

            StatusResult(result);
            continue; //Some other sort of error caused this.
        }

        //-------------------------------------------------------------
        // Initialize loop mode (sound based, not channel based...)
        //-------------------------------------------------------------
        char parsed_filename[256]; //We need to account for very long directory/filenames.
        sprintf(parsed_filename,"/sound/%s", m_SoundList[i]);

        int wavlength = 0;
        byte *pMemFile = gEngfuncs.COM_LoadFile( parsed_filename, 5, &wavlength );
        if ( pMemFile )
        {
            wavinfo_t waveInfo = GetWavinfo( (char*)m_SoundList[i], pMemFile, wavlength );
            if( waveInfo.loopstart == 0 )
            {              
                FMOD_RESULT result = pSound->setMode( FMOD_LOOP_NORMAL );
                StatusResult( result );
            }
            else if( waveInfo.loopstart > 0 )
            {
                int sample_length = (waveInfo.samples * waveInfo.channels * waveInfo.width);
                FMOD_RESULT result = pSound->setLoopPoints( waveInfo.loopstart, FMOD_TIMEUNIT_PCMBYTES, sample_length, FMOD_TIMEUNIT_PCMBYTES );
                StatusResult( result );
                pSound->setMode( FMOD_LOOP_NORMAL );
            }
            else
                pSound->setMode( FMOD_LOOP_OFF );
        }

        m_FMODSoundList[i] = new CFMODSoundList;
        m_FMODSoundList[i]->pLoadedSound = pSound;
        strcpy( m_FMODSoundList[i]->pFilename,  m_SoundList[i] );
    }
    else
        break;
}

ALERT(at_console,"Finished loading sound list.\n");
m_fSoundsInitialized = true;
return true;

}[/code:fzucwq9q]

FMOD Ex doesn’t support wav files that have loop points specified with "CUE" markers. That’s why I had to port the wav loader code from Quake 1.

  • You must to post comments
0
0

Read this earlier while working on the interface to fmod ex:

http://52.88.2.202/forum/viewtopic.php … nts+marker

  • You must to post comments
0
0

Any other information needed?

  • You must to post comments
Showing 13 results
Your Answer

Please first to submit.