Author Topic: WASAPI: BASS_Mixer_ChannelGetPosition is not in sync with actual played position  (Read 175 times)

MikaelS

  • Posts: 188
Hello,

I'm using WASAPI with a quite large buffer (on purpose for this test), 8s.
The playback is made via BASS_MIX.

When I play a song which contains 2s of noise, followed by 2s of silence (repeated 10 times), the position returned from BASS_Mixer_ChannelGetPosition is delayed about ~2.5s compared to the actual position thats heard (this can easily be seen when using a spectrogram to display the position).

The larger the WASAPI buffer is, the more delay will be added.

I thought that BASS_Mixer_ChannelGetPosition should compensate for buffering, is there a better way to keep heard position and visual position in sync?

Thanks in advance.

Ian @ un4seen

  • Administrator
  • Posts: 19987
Are you setting the BASS_ATTRIB_MIXER_LATENCY attribute to the output latency? When standard BASS output isn't used, BASSmix doesn't know about the output latency/buffering without being told via the BASS_ATTRIB_MIXER_LATENCY attribute. Another option is to use BASS_Mixer_ChannelGetPositionEx (instead of BASS_Mixer_ChannelGetPosition), which has an additional parameter to specify the latency. A little demonstration of using that can be found in the CONTEST.C example included in the BASSWASAPI package.

MikaelS

  • Posts: 188
Thanks for your reply Ian.

Previously I did not used any of the suggested methods, which I have now tried.
The result got better, but not perfect.

When setting BASS_ATTRIB_MIXER_LATENCY, it does not seem to matter how much latency I set as the attribute.
No matter if I choose 2 or 15, the same latency is still applied.

The same applies to BASS_Mixer_ChannelGetPositionEx which returns the same latency, but if I set a to large value as the delay parameter, I would get a negative extermely small number returned.

I have compared the latency (not sure if I have made it the correct way) by comparing BASS_ChannelGetPosition for the active stream vs. BASS_Mixer_ChannelGetPosition.
The difference seems to be constant, BASS_Mixer_ChannelGetPosition is two seconds prior to BASS_ChannelGetPosition.

When using a WASAPI buffer of 8s I would expect that the difference would be eight seconds or similar.

When using a smaller WASAPI buffer, say 3s, it will be nearly perfect as expected.

Is there some way that I can get a larger latency interval?

Ian @ un4seen

  • Administrator
  • Posts: 19987
I forgot to say that you will also need to raise the BASS_CONFIG_MIXER_POSEX setting if your output latency/buffering is more than 2 seconds (the default setting). You should also include the BASS_MIXER_POSEX flag in your BASS_Mixer_StreamCreate call.

MikaelS

  • Posts: 188
Thanks Ian,

I tried this, unfortunately with the same results.
My code is setup as this: (code is using Bass.Net)

1) Init Bass
2) Init WASAPI. Buffer is set to 8s
3) Init BassMix. Flags used: BASSFlag.BASS_SAMPLE_FLOAT,BASSFlag.BASS_STREAM_DECODE,BASSFlag.BASS_MIXER_POSEX,BASSFlag.BASS_MIXER_END
4) Set config, Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_MIXER_POSEX, buf). Buf = 8000ms
5) When channel is plugged into mixer, I set the latency attribute:
Bass.BASS_ChannelSetAttribute(_mixerHandle, BASSAttribute.BASS_ATTRIB_MIXER_LATENCY, 8f)
6) When I try get the position I use the following code:
                var b = Bass.BASS_ChannelSeconds2Bytes(ActiveStream.Stream, 8);
                var pos = BassMix.BASS_Mixer_ChannelGetPositionEx(ActiveStream.Stream, BASSMode.BASS_POS_BYTES, (int)b); // 8s delay

The call to get the position returns:
BASS_ERROR_ILLPARAM

If I lower the delay in step 6 to 2 it will get me a position that's 2s corrected, but I cannot get it to use larger delay.

Have I missed anything vital?

Ian @ un4seen

  • Administrator
  • Posts: 19987
Did you set the BASS_CONFIG_MIXER_POSEX value before creating the mixer? If not, please try that, as a mixer will use the value at the time of its creation.

Regarding the BASS_ERROR_ILLPARAM error, that indicates that the "delay" parameter is higher than the amount of data that the mixer has outputted, eg. if you try to request a delay of 8s after only 1s. You can use BASS_WASAPI_GetData (with BASS_DATA_AVAILABLE) to check what the latency currently is. A demonstration of doing that can be found in the CONTEST.C example.

MikaelS

  • Posts: 188
Still no luck :(

I tried to set the BASS_CONFIG_MIXER_POSEX creating a mixer. This resulted in BASS_ERROR_ILLPARAM.
Setting it directly after the mixer was created worked fine.

I then tried to do the following call (taken from the contest.c sample):
Code: [Select]
                var a = BassWasapi.BASS_WASAPI_GetData(IntPtr.Zero, (int)BASSData.BASS_DATA_AVAILABLE);
                var b = Bass.BASS_ChannelSeconds2Bytes(ActiveStream.Stream, HeliumGlobal.Instance.WasapiBufferLength);
                if (b > a)
                    b = a;
                // b is now corrected to the available length.
                var pos = BassMix.BASS_Mixer_ChannelGetPositionEx(ActiveStream.Stream, BASSMode.BASS_POS_BYTES, (int)b);

This code ran for a while but suddenly I got BASS_ERROR_NOTAVAIL when making the call to BASS_Mixer_ChannelGetPositionEx.
The value returned from Bass_Wasapi_GetData was 695392.
After a while it worked again, but it never came up to the requested buffer value which was just above 2000000.

Ian @ un4seen

  • Administrator
  • Posts: 19987
I tried to set the BASS_CONFIG_MIXER_POSEX creating a mixer. This resulted in BASS_ERROR_ILLPARAM.

Perhaps the problem is that BASSMIX.DLL hasn't been loaded yet. You could try calling a BASSmix function to force it to be loaded before then, eg. BASS_Mixer_GetVersion during initialization.

MikaelS

  • Posts: 188
Perfect! Thanks for the hint!
This seems to have solved it. I will make some more test, but the basic ones seems to work great.