0
0

Hello,

I’m implementing a gapless media player (on flac streams) using the subsound/sentence api (I create a sentence with 2 subsounds and loop it indefinitely, changing the non active subsound whenever I reach the end of a Stream).

When subsound0 is active, everything is fine: getPosition with FMOD_TIMEUNIT_SEQUENCE_MS returns the position of the active Stream, and setPosition with the same parameter allows me to seek Inside the Stream.
When subsound1 is active (detected with _currentChannel->getPosition(&newCurrentIndex, FMOD_TIMEUNIT_SENTENCE_SUBSOUND | FMOD_TIMEUNIT_BUFFERED))
– if I do not change the Stream affected to subsound0, everything is fine as well
– if I change the Stream affected to subsound0 (to prepare the next track to be played gaplessly), weirdness occurs :
-getPosition with FMOD_TIMEUNIT_SEQUENCE_MS returns wrong value (most of the time it’s "duration of old track in subsound0" + "actual position in subsound1" but not always).
-setPosition with FMOD_TIMEUNIT_SEQUENCE_MS make playback switch to somewhere in the track in subsound0 (it seems not to be random, but I don’t know where exactly it goes).
-sometimes, mostly when the old track in subsound0 was long (5+ minutes), the sound in subsound1 is not played to its end (but playback rolls back to the beginning of the new track in subsound0)

  • You must to post comments
0
0

I can’t say for sure, but for the last "weirdness" item, I have the feeling that the track in subsound1 is truncated by an amount of "duration of old track in subsound0" – "duration of new track in subsound0".

For example I have the following tracklist (durations):

track 1 (2:30)
track 2 (4:20)
track 3 (6:20)
track 4 (3:00)
track 5 (4:20)

with subsound rolling playback (subsound0 is reset as sound as subsound1 is reached)

track 1 : everything fine
track 2 : get/setPosition do weird things
track 3 : everything fine
track 4 : get/setPosition do weird things, track is truncated after about 1 min (not measured accurately)
track 5 : everything fine

Maybe I’m doing something wrong, but I don’t see where… If it’s a bug, I hope this test scenario can help !

Simon

  • You must to post comments
0
0

Sentencing has some known issues, and has been removed from the upcoming FMOD studio lowlevel API. Use Channel::setDelay() as a better solution to your problem.

See this knowledge base entry for sample code for seamless stitching of audio viewtopic.php?f=18&t=14630.

  • You must to post comments
0
0

Hi, thanks for the answer.

I managed to do something with setDelays, but as I need to support seeking, I did this (this is called when I am within the 2 last seconds of the current track and the scheduling is invalidated when sound is paused or seeked) :

[code:1hug9ca5]
void BasicSequencer::ScheduleNextSound()
{
if(_currentChannel == nullptr || _nextSoundScheduled)
{
return;
}

uint32 startTimeHi, startTimeLo;

_fmodSys->getDSPClock(&startTimeHi, &startTimeLo);
int32 sampleRate;
_fmodSys->getSoftwareFormat(&sampleRate, nullptr, nullptr, nullptr, nullptr, nullptr);


float frequency;
uint32 currentLength_pcm;
auto fmodRes = _currentSound->getDefaults(&frequency, 0, 0, 0);
FmodErrorToEx(fmodRes);
fmodRes = _currentSound->getLength(&currentLength_pcm, FMOD_TIMEUNIT_PCM);
FmodErrorToEx(fmodRes);
uint32 currentPos_pcm;
fmodRes = _currentChannel->getPosition(&currentPos_pcm, FMOD_TIMEUNIT_PCM);
FmodErrorToEx(fmodRes);

uint64 currentLength_Samples = (uint64)currentLength_pcm * (uint64)sampleRate;
uint64 currentPos_Samples = (uint64)currentPos_pcm * (uint64)sampleRate;
uint32 currentLength_dsp = unsigned int((currentLength_Samples / frequency) + 0.5f);
uint32 currentPos_dsp = unsigned int((currentPos_Samples / frequency) + 0.5f);
uint32 currentRemaining_dsp = currentLength_dsp - currentPos_dsp;

FMOD_64BIT_ADD(startTimeHi, startTimeLo, 0, currentRemaining_dsp);

fmodRes = _fmodSys->playSound(FMOD_CHANNEL_FREE, _nextSound.get(), true,
    &_nextChannel);
FmodErrorToEx(fmodRes);
fmodRes = _nextChannel->setDelay(FMOD_DELAYTYPE_DSPCLOCK_START, startTimeHi, startTimeLo);
FmodErrorToEx(fmodRes);
_nextChannel->setPaused(false);
_nextSoundScheduled = true;

}[/code:1hug9ca5]

However, I sometimes get a perceptible gap (even if my audio files are FLAC and correctly cut). It is not always the case, but it happens.
Do you have a sample that supports seeking as well as gapless playback ?

Thanks,
Simon

  • You must to post comments
0
0

Instead of using getPosition() and getLength(), you could try using Channel::getDelay(FMOD_DELAYTYPE_DSPCLOCK_END, …) on the playing channel to get the clock for scheduling the next channel.

  • You must to post comments
0
0

Hello,

It is what I was doing before but getDelay(FMOD_DELAYTYPE_DSPCLOCK_END) returns 0 (at least when there has been a seek using setPosition during playback).
I am using v4.44.04 in win8 metro.

  • You must to post comments
0
0

Hello,

in v4.44.05 getDelay(FMOD_DELAYTYPE_DSPCLOCK_END) still returns 0 (even without setting its position while playing), and the perceived gap is even worse than in previous version.
Do you have a reliable sample of gapless playing with an unbounded count of sounds using a Rolling subsounds mechanism or something equivalent ? I really need this feature as well as seeking Inside the tracks and retrieving correct playback position.

  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.