Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible StreamDecoder.Read() bug #1

Open
allsorts46 opened this issue Aug 17, 2024 · 0 comments
Open

Possible StreamDecoder.Read() bug #1

allsorts46 opened this issue Aug 17, 2024 · 0 comments

Comments

@allsorts46
Copy link

allsorts46 commented Aug 17, 2024

Hi, thanks for bringing NVorbis up to date for modern .NET! I've used it very successfully today in combination with MonoGame's DynamicSoundEffectInstance to implement streaming music, and it works great on both DesktopGL and Android platforms.

I may have found a problem with one of the overloads of StreamDecoder.Read():

The overload with signature int Read(Span<float> buffer) works as you would expect, simply filling the provided buffer with as much data as poissible. Eg if I pass a new float[32] and it's a stereo file, I'll get 16 samples populated, filling my array.

In a specific case, I wanted to fetch fewer samples than would fit in the array I have, so I tried the int Read(Span<float> buffer, int samplesToRead, int channelStride) overload, however it didn't work like I thought it would. Calling Read(buffer, 4, 0) where buffer is my new float[32], I get only the first 4 elements (0-3) populated, so only 2 samples for 2 channels. I wasn't sure what the channelStride parameter is for, but I saw that the implementation of the first override just passes constant zero so I did the same. I did try passing other values, but discovered that this just causes an offset into the array to be populated, eg passing '2' with the example above causes the 4 elements with index 2-5 to be populated instead of 0-3. I can see in the code it's being added to an offset rather than multiplied, which seems suspect.

Nothing I tried produced the results I was expecting, where I can request to read a specific number of samples into my array. Trying to just pass double the number of samples doesn't work due to the validation in Read(), which (correctly) throws an exception with message 'The buffer is too small for the requested amount'.

Initially I couldn't understand why this overload produced completely different results to the simpler one, but eventually noticed that they parse different values for the interleave parameter on the third hidden (private) overload int Read(Span<float> buffer, int samplesToRead, int channelStride, bool interleave). I don't understand why one passes true and one passes false, but maybe there is a reason for it.

I could easily make the small changes needed to make this work as I expected, but since I don't really know what the channelStride parameter is for, or what other code might be depending on the current behaviour, I thought it best to check whether this is actually intended behaviour or not before making a PR.

If it is, can we possibly either change the third private overload to public, or add a fourth overload int Read(Span<float> buffer, int samplesToRead) which would call through with interleave=true, so that it's possible to request fewer samples than can fit in the provided buffer. At the moment there's no (public) way to do this.

Thanks for reading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant