BASS_Encode_ServerInit delay

Started by Chris Oakley,

Chris Oakley

QuoteIs "_VirtualCableUrl" a BASSenc server started with BASS_Encode_ServerInit, and if so, is it still serving PCM data? If it's a diferent format now and that happens to be VBR, then the duration of the same amount of buffered data can vary. You can call BASS_StreamGetFilePosition with BASS_FILEPOS_BUFFER before BASS_ChannelPlay/Start, to check if the amount of pre-buffered data is the same each time.

Yes it is started from a ServerInit and it is PCM.

QuoteYou could try using the BASS_POS_DECODETO option with BASS_ChannelSetPosition to flush all buffered data, ie. use up all the buffered data by seeking as far ahead as possible.

That seems to do the trick. I was trying to do something similiar but I wasn't using the BASS_POS_DECODETO flag.

I'm going to deploy and see if it holds now.

Ian @ un4seen

Quote from: Chris OakleyYes it is started from a ServerInit and it is PCM.

What "burst" parameter are you using in the BASS_Encode_ServerInit call? That will determine how much data is sent immediately to new clients, so you may want to lower it for less delay (more data = more delay). With plain PCM data, you can use BASS_ChannelSeconds2Bytes to get a "burst" value.

Chris Oakley

QuoteWhat "burst" parameter are you using in the BASS_Encode_ServerInit call?

I'm currently using 64000. Should I lower that? If I was to use the BASS_ChannelSeconds2Bytes, what am I doing with that? Am I asking it for the bytes in 0.03 for example?

I'm also noticiing that each instance of the application running on the same machine, gradually goes out of sync. Not by much, but they all start bang on with each other, but over a period of about 12 hours they drift a little. Not a massive amount. Only about 500ms to 750ms each, but it's enough for me to be concerned because it's not what I expect.

Ian @ un4seen

Quote from: Chris Oakley
QuoteWhat "burst" parameter are you using in the BASS_Encode_ServerInit call?

I'm currently using 64000. Should I lower that? If I was to use the BASS_ChannelSeconds2Bytes, what am I doing with that? Am I asking it for the bytes in 0.03 for example?

The meaning of that number will depend on the exact sample format, eg. assuming 44100hz 16-bit stereo then 64000 = 0.363s (64000/176400). If that's correct in your case then it would be strange to sometimes have a 1 second delay at the start. Are you possibly delaying the BASS_ChannelPlay call sometimes?

Quote from: Chris OakleyI'm also noticiing that each instance of the application running on the same machine, gradually goes out of sync. Not by much, but they all start bang on with each other, but over a period of about 12 hours they drift a little. Not a massive amount. Only about 500ms to 750ms each, but it's enough for me to be concerned because it's not what I expect.

I would generally expect streams on the same system to maintain their initial sync with each other (assuming no stalls). Are you making BASS_ATTRIB_FREQ adjustments as discussed earlier? If so, that could be causing the sync changes, ie. the streams aren't all getting identical adjustments.

Chris Oakley

QuoteThe meaning of that number will depend on the exact sample format, eg. assuming 44100hz 16-bit stereo then 64000 = 0.363s (64000/176400). If that's correct in your case then it would be strange to sometimes have a 1 second delay at the start. Are you possibly delaying the BASS_ChannelPlay call sometimes?

I'm not actually starting it playing. It's being added to a mixer which is a decode mixer so it starts as soon as it is attached if I'm not mistaken on how this works. This mixer is then added to another mixer which is outputting to the No Sound device and playing on that.

QuoteI would generally expect streams on the same system to maintain their initial sync with each other (assuming no stalls). Are you making BASS_ATTRIB_FREQ adjustments as discussed earlier? If so, that could be causing the sync changes, ie. the streams aren't all getting identical adjustments.

I'm not making any adjustements with BASS_ATTRIB_FREQ at all.

Ian @ un4seen

Quote from: Chris OakleyI'm not actually starting it playing. It's being added to a mixer which is a decode mixer so it starts as soon as it is attached if I'm not mistaken on how this works. This mixer is then added to another mixer which is outputting to the No Sound device and playing on that.

When playing through a mixer, there may be an additional delay based on how much data the mixer has buffered. For example, if the mixer has 500ms of buffered data then the new source won't be heard until after that. You can avoid that by disabling buffering via the BASS_ATTRIB_BUFFER option (on the mixer).

What values do you see if you check the stream's pre-buffered data with BASS_StreamGetFilePosition (BASS_FILEPOS_BUFFER) immediately after BASS_StreamCreateURL? It generally shouldn't exceed the BASS_Encode_ServerInit "burst" value.

Quote from: Chris OakleyI'm not making any adjustements with BASS_ATTRIB_FREQ at all.

In that case, perhaps there's some stalling or missed update cycles. What BASS.DLL version are you using? The 2.4.17 release version doesn't give the "No Sound" device much leeway for delayed update cycles and will start dropping them when more than 1 whole cycle late. A dedicated option to configure that will be in the next release, but in the meantime, the latest builds use the BASS_CONFIG_DEV_BUFFER option to determine the leeway.

   www.un4seen.com/stuff/bass.zip

Chris Oakley

QuoteYou can avoid that by disabling buffering via the BASS_ATTRIB_BUFFER option (on the mixer).

Thanks. Yes I've got that set on all mixers.

QuoteWhat values do you see if you check the stream's pre-buffered data with BASS_StreamGetFilePosition (BASS_FILEPOS_BUFFER) immediately after BASS_StreamCreateURL?

I'll see what it says and report back.

QuoteWhat BASS.DLL version are you using?

We currently have 2.4.17.4 but I see the dll version in the download you linked to is 2.4.17.16 - should we give that a spin? If so so I need to set BASS_CONFIG_DEV_BUFFER?

Ian @ un4seen

No harm in trying the latest build, but 2.4.17.4 did already have the BASS_CONFIG_DEV_BUFFER support mentioned, so in either case you can try raising that via BASS_SetConfig before initializing the "No Sound" device to give it more leeway.

Chris Oakley

In the BASS.NET documentation it says:
QuoteThis config option is only available on Linux, Android and Windows CE. The device's buffer is determined automatically on other platforms.

This suggests it would make no difference on Windows 10 and 11 which is the platform we develop for. Is this correct?

Ian @ un4seen

The BASS_CONFIG_DEV_BUFFER setting has no effect on Windows in the BASS 2.4.17 release version, but it is used (for the "No Sound" device only) in the updates.

Chris Oakley

So I've checked the default setting using this:

Dim bufLen As Integer = Bass.BASS_GetConfig(BASSConfig.BASS_CONFIG_DEV_BUFFER)
Debug.Print("BufLen " & bufLen.ToString)

It's telling me the value is 30 which I presume, from the documentation, means 30 milliseconds. If I was to raise it, what sort of value are we talking?

Ian @ un4seen

The setting is the maximum amount of time that the "No Sound" device is prepared to catch-up after any processing delays, ie. anything beyond that will be dropped. If you want to avoid any dropped update cycles then you can pretty much go as high as you like. I guess 1000 (1 second) should be plenty.

Chris Oakley

I've been going through the code and I found an area where the Mixer, which the virtual cable is plugged into, is Split and plugged into the Mixer which is outputting to the No Sound device. I do this with
Dim i As Integer = BassMix.BASS_Split_StreamCreate(_PlayerContainer.ContainerID, BASSFlag.BASS_STREAM_DECODE, Nothing)
I then saw the config option BASS_CONFIG_SPLIT_BUFFER which in the documentation says it's default buffer is 2000 ms. Could this be the problem? Could doing a
Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_SPLIT_BUFFER, 100)
Go some way to solving this puzzler?

Ian @ un4seen

Are there other splitters on the same mixer, and are you currently setting BASS_CONFIG_SPLIT_BUFFER to 100 or just thinking of doing so? If there are other splitters then a short splitter buffer could potentially mean that some of them miss some data, so you probably don't want that in this case. The only reason I see for using a short buffer is when low latency is more important than keeping all data.

Chris Oakley

QuoteAre there other splitters on the same mixer
Yes, due to the configurable routing approach we have, it's possible that there will be other splitters on the same mixer, but in the current setup where I'm seeing this, there isn't.

Quoteare you currently setting BASS_CONFIG_SPLIT_BUFFER to 100 or just thinking of doing so?
Just a thought from what I saw in the documentation.

Ian @ un4seen

If there are no other splitters then the BASS_CONFIG_SPLIT_BUFFER setting won't really have any effect, as a single splitter will always be getting fresh data from the source rather than depending on the splitter buffer.

Chris Oakley

Okay, good to know. I'll leave it as it. I don't like blindly just changing values as you end up with other issue that become impossible to trace.

I'm just running a test to see if it might be something to do with the No Sound mixer being encoded and casted. I've seen some really weird behaviour surrounding when this is in place. Even using the ENCODE_QUEUE flag. I've got the
_VirtualCableId = Bass.BASS_StreamCreateURL(_VirtualCableUrl, 0, BASSFlag.BASS_STREAM_DECODE, Nothing, IntPtr.Zero)
Open on three inputs and one of them is casting to a shoutcast stream. I want to see if the two that aren't stay in sync and the one casting goes out.

Chris Oakley

So I expected 2 of the 3 inputs to be in sync, as they were setup exactly the same, but even they went out of sync, and this is in the same application. I've tried setting up a physical input along side them too, each input taking the same record stream, and even they went out of sync. So I'm not sure right now that this is specifically a stream Url issue.

I'm just absolutely stumped at the moment. Something is really odd. Breaking it down in code this is what we have in the class, which we then instance, set up the same, we have the main No Sound mixer:
Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)
_NodeID = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_NONSTOP)
Bass.BASS_ChannelSetAttribute(_NodeID, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)

We have the mixer which will take a number of different sources like recording / input channels, streams etc:
_Mixer = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_MIXER_NONSTOP)
Bass.BASS_ChannelSetAttribute(_Mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)
_VUMeter = New DSP_PeakLevelMeter(_Mixer, 1) With {.CalcRMS = True,.UpdateTime = 0.08}
Note: The _VUMeter is the DSP we use to monitor the audio. It's from here you can visually see when each input has gone out, since the No Sound mixer doesn't provide any sound.

We have to split this _Mixer so we can plug it into the _NodeId mixer. This is done like this:
Dim i As Integer = BassMix.BASS_Split_StreamCreate(_Mixer, BASSFlag.BASS_STREAM_DECODE, Nothing)
Ret = BassMix.BASS_Mixer_StreamAddChannel(_NodeID, i, BASSFlag.BASS_DEFAULT)

Then to take a PCM stream which is at 44100 16bits we do this:
_VirtualCableId = Bass.BASS_StreamCreateURL(_VirtualCableUrl, 0, BASSFlag.BASS_STREAM_DECODE, Nothing, IntPtr.Zero)
BassMix.BASS_Mixer_StreamAddChannel(_Mixer, _VirtualCableId, BASSFlag.BASS_DEFAULT)

or if we want a recording channel we do this:
_RecordMonitorStream = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, Nothing, IntPtr.Zero)
BassMix.BASS_Mixer_StreamAddChannel(_Mixer, _RecordMonitorStream, BASSFlag.BASS_DEFAULT)
Bass.BASS_ChannelPlay(_RecordMonitorStream, False)

As you can see, noting too clever, nothing fancy. Can you see anything here that we're doing wrong. It seems like it should be pretty cut and dried.

Ian @ un4seen

Quote from: Chris OakleySo I expected 2 of the 3 inputs to be in sync, as they were setup exactly the same, but even they went out of sync, and this is in the same application. I've tried setting up a physical input along side them too, each input taking the same record stream, and even they went out of sync. So I'm not sure right now that this is specifically a stream Url issue.

If you aren't already, please try setting BASS_SYNC_STALL syncs on all mixer sources (including sub-mixers) via BASS_Mixer_ChannelSetSync and see if any get triggered. Also try setting an encoder on the final mixer (feeding the "No Sound" device) to write the mix to file, and then confirm that the file's content matches what you see in your VU displays, ie. you can hear the inputs similarly out of sync in it. Note the encoder should have the BASS_ENCODE_QUEUE flag set to avoid delaying the mixing.

To confirm whether the problem is specific to streaming URLs, you could also try local files instead, ie. BASS_StreamCreateFile instead of BASS_StreamCreateURL.

Chris Oakley

Before I do that, what would cause a stall? I would have thought the data through put would be constant.