Author Topic: Playing multiple tracks at once and keeping them synchronized  (Read 255 times)

srylain

  • Posts: 18
Hey there, newbie to Bass.NET here. I've been using Bass.NET as a stand-in for Unity's audio engine (mostly because it's pretty bad) for a game I've been making (think Guitar Hero/Rock Band), and I have songs with multiple tracks, or stems, that need to be played altogether (each stem is for an instrument, so you'd have one for guitar, one for bass, and so on). The reason they need to be split up is for the gameplay, as in if one player stops playing correctly then their instrument cuts out (by dropping the volume of their track to zero).

The problem I'm having is that some of my players are saying that during long songs there's times where the tracks will de-synchronize from each other, and my question is how would I best be able to about making sure they stay synchronized? I've tried just setting the channel position every so often, but every time it happens it makes the gameplay stutter and an audible "pop" can be heard.

So would anyone have any advice on how to potentially fix this issue?

srylain

  • Posts: 18
I also am now hearing about another issue my users are having. Not sure what distros they're using, but it seems like Bass.NET on Linux is causing pretty bad desync issues with all the channels. This doesn't appear to happen on Windows (outside of just gradual desync when playing 10+ minute long songs).

radio42

  • Posts: 4574
As Bass.Net is just the API wrapper, I doubt, that your effects are caused by Bass.Net.
However, I don't even understand why you mean by 'desync' - not in sync with what?

Ian @ un4seen

  • Administrator
  • Posts: 20401
If the files start playing (on the same device) in sync then they should stay in sync. Are you sure they do start in sync and gradually drift apart? If so, are the files looping, and if so, are they all exactly the same length? You could use the pre-compiled WRITEWAV.EXE example included in the BASS package (C\BIN folder) to convert each of them to WAV and check that the WAV files have the same length as each other.

If the files aren't in sync from the start, you could try linking the streams via BASS_ChannelSetLink before starting playback. Please see the BASS_ChannelSetLink documentation for details.

srylain

  • Posts: 18
The files are all the same length, same sampling rate, played on the same device, and all started on the same frame. I haven't had it happen to myself, but from what I've been told is that the channels start to desync from each other after an amount of time (usually 10 minutes or so). I'm not sure if this could be a problem, but I think the users that have this happening are using broadcasting software to stream to Twitch and Youtube. I have no idea if the extra CPU usage from those softwares could be causing it.

I'll look into the BASS_ChannelSetLink, thanks.

Ian @ un4seen

  • Administrator
  • Posts: 20401
Can you add periodic logging of each stream's position to your game, to confirm when and how much they are drifting apart? Log both the playback position and the decoding position, using BASS_ChannelGetPosition with and without the BASS_POS_DECODE flag.

Also confirm how you are looping the files, eg. by using the BASS_SAMPLE_LOOP flag or syncs?

srylain

  • Posts: 18
I'll work on getting that logging in place. During gameplay I'm not looping the audio at all, just loading it and playing from start to finish. The channels aren't currently synced to each other (with Bass_ChannelSetLink), I just load the files into separate channels and play them all on the same frame.

Ian @ un4seen

  • Administrator
  • Posts: 20401
Ah, so perhaps the files don't drift apart but actually sometimes just start apart? If so, using BASS_ChannelSetLink will hopefully help with that.

Another option (for perfect sync) is to use a mixer (BASSmix add-on) to play the files, something like this:

Code: [Select]
// create decoders for the files
for (int n = 0; n < sourcecount; n++)
source[n] = BASS_StreamCreateFile(FALSE, filenames[n], 0, 0, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE);

...

BASS_CHANNELINFO ci;
BASS_ChannelGetinfo(source[0], &ci); // get the file sample format
mixer = BASS_Mixer_StreamCreate(ci.freq, ci.chans, BASS_MIXER_END); // create a mixer with same format
// add the sources to the mixer
for (int n = 0; n < sourcecount; n++) {
BASS_ChannelSetPosition(source[n], 0, BASS_POS_BYTE); // rewind in case it has been played before
BASS_Mixer_StreamAddChannel(mixer, source[n], 0);
}
BASS_ChannelPlay(mixer, 0); // start playing

Please see the documentation for details on the mentioned functions.

srylain

  • Posts: 18
I think BASS_ChannelSetLink worked, time will tell if there's still a problem. I never had any problems with the channels desyncing, but I think the players who did were all on Linux (I'm on Win10). I was starting them individually before (all on the same frame though), so hopefully that was the cause and linking them fixed it.

Thanks for the help. I'll look into the mixer method if problems still happen.