Author Topic: Gapless playback with a mixer stream  (Read 2233 times)

3delite

  • Posts: 926
Gapless playback with a mixer stream
« on: 11 Oct '12 - 09:50 »
Hi!

I'd like to achieve gapless transition of 2 decode channels with a mixer channel that is a non-stop channel.

My first try was setting a BASS_SYNC_END on the 1st channel, where I plug in the next channel into the mixer stream.
I recorded the output and the problem is that the 2 source streams overlap, as I noticed, 0.1 seconds always (I am testing this with 2 sine WAV files - so I can clearly see what's happening).

Then I tried a different approach and set a sync on the mixer channel in the 'plugin in' function, like mixer's current position + converted the length of the source to seconds and that back to bytes for the mixer channel. Interestingly this resulted exactly the same result.

So my question is how to accomplish this?

Thank you!

Ian @ un4seen

  • Administrator
  • Posts: 21210
Re: Gapless playback with a mixer stream
« Reply #1 on: 11 Oct '12 - 14:38 »
Your 2nd approach is the correct one, ie. the sync should be set on the mixer rather than the source. The sync should also be "mix-time" (BASS_SYNC_MIXTIME flag). Something like this...

Code: [Select]
BASS_ChannelLock(mixer, TRUE); // lock mixer to block processing in the middle of this
BASS_Mixer_StreamAddChannel(mixer, source, BASS_MIXER_NORAMPIN); // add new source to the mix
QWORD pos=BASS_ChannelGetPosition(mixer, BASS_POS_BYTE|BASS_POS_DECODE); // get mixer's current position
pos+=BASS_ChannelSeconds2Bytes(mixer, BASS_ChannelBytes2Seconds(source, BASS_ChannelGetLength(source, BASS_POS_BYTE))); // add source's length
BASS_ChannelSetSync(mixer, BASS_SYNC_POS|BASS_SYNC_MIXTIME, pos, SyncProc, 0); // set a sync at source's end position
BASS_ChannelLock(mixer, FALSE); // unlock mixer

If the mixer will be playing a single source at a time, then another way to achieve gapless playback is with a BASS_SYNC_END sync. Here's an example of doing that...

   www.un4seen.com/forum/?topic=6159.msg41390#msg41390

3delite

  • Posts: 926
Re: Gapless playback with a mixer stream
« Reply #2 on: 13 Oct '12 - 13:04 »
Thank you works fine. Adding the BASS_POS_DECODE flag for the mixer's position query fixed my existing code.

However looking at the recorded output there seems to be a little overlap still. Probably not noticeable by listening but it seems like a couple of samples do overlap.

Snapshot

Above is the second stream, in the middle the first's and where I added two little spikes to see where it is ending in the output and below is the recorded output.
As I see the second spike is a couple of samples overlaped with the second stream.

Is this expected or what could be causing this?

OK. It doesn't matter that much but interesting.

Ian @ un4seen

  • Administrator
  • Posts: 21210
Re: Gapless playback with a mixer stream
« Reply #3 on: 15 Oct '12 - 13:37 »
It's kind of hard to make out exactly how much overlap there is in that screenshot. For a clearer picture, you could try making the 2 streams contain a flat DC offset (ie. the waveform is a flat line). For example, if the 1st has a +0.5 offset and the 2nd has a -0.25 offset, then the mix should have a sudden jump from 0.5 to -0.25. If there are some 0 samples in between, then there is a gap, and if there are some +0.25 samples, then there is an overlap.
   
Also, how are you making the recording, eg. is it directly from the mixer or are you capturing it from a recording device? If the latter, please try the former.

stevenmmm

  • Posts: 118
Re: Gapless playback with a mixer stream
« Reply #4 on: 6 Jan '13 - 10:51 »
i can get gapless playback working perfectly using either of the suggested approaches with DirectSound.
However with WASAPI what i find is if the number of bytes in current song does not have an exact multiple of the buffer size then a small click can be heard on the transition to the following song (you actually hear it a little after the next song has started but i guess that is just playback latency).
In my test i split a sine generated .WAV file, and checking using a DSP proc on the mixer channel the data is perfectly formed so the data being fed for output is correct.

Are there any additional steps were required to the above suggested approaches for WASAPI?
« Last Edit: 7 Jan '13 - 06:52 by stevenmmm »

Ian @ un4seen

  • Administrator
  • Posts: 21210
Re: Gapless playback with a mixer stream
« Reply #5 on: 7 Jan '13 - 16:57 »
Yes, when using exclusive mode WASAPI (or ASIO) output, the sample data does indeed need to be provided in whole blocks, otherwise there will be a gap in the output. So, to avoid a gap between tracks, your WASAPIPROC function would need to get data from the new track to fulfil any remainder of the request that the old track couldn't satisfy. I think that should be automatic if you're using a mixer. If you're having trouble with it, please post the code that you're using to setup the mixer and its sources.