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

SampleProvider AIFF 8-bit PCM audio data signedness #1178

Open
karip opened this issue Aug 15, 2024 · 1 comment
Open

SampleProvider AIFF 8-bit PCM audio data signedness #1178

karip opened this issue Aug 15, 2024 · 1 comment

Comments

@karip
Copy link

karip commented Aug 15, 2024

AIFF files with 8-bit PCM audio data are read incorrectly by NAudio. Audio bytes seem to be read as unsigned 8-bit integers, but they should be read as signed 8-bit integers.

The test file aiff-samplesize-8.aiff contains 8-bit PCM audio data and it's raw audio data starts with these hex values: 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x80, 0x83, 0x85, 0x88, 0x8A, 0x8D, 0x8F, 0x92

Those hex values can be converted to signed decimal values [-128, 127]: 10, 10, 10, 10, 10, 10, 10, 10, -128, -125, -123, -120, -118, -115, -113, -110

Those values can be converted to floating point values [-1.0, 1.0] by dividing by 128: 0.078125, 0.078125, 0.078125, 0.078125, 0.078125, 0.078125, 0.078125, 0.078125, -1, -0.9765625, -0.9609375, -0.9375, -0.921875, -0.8984375, -0.8828125, -0.859375

However, reading the file with NAudio SampleProvider returns these floating point values: -0.921875, -0.921875, -0.921875, -0.921875, -0.921875, -0.921875, -0.921875, -0.921875, 0, 0.0234375, 0.0390625, 0.0625, 0.078125, 0.1015625, 0.1171875, 0.140625

So, it seems that NAudio isn't reading the values correctly.

I had a look at the NAudio source code. It is using SampleProviderConverters:22 to convert raw audio data to samples. Pcm8BitToSampleProvider:33 converts bytes to floating point values: buffer[outIndex++] = sourceBuffer[n] / 128f - 1.0f;

It should be converting bytes to floating point values like this: buffer[outIndex++] = sourceBuffer[n] < 128 ? sourceBuffer[n] / 128f : (sourceBuffer[n] / 128f) - 2.0f;

Of course, Pcm8BitToSampleProvider.cs can't be changed, because then it would return incorrect values for WAV files, which contain unsigned 8-bit data.

@karip
Copy link
Author

karip commented Aug 16, 2024

I think this could be fixed by converting 8-bit bytes from signed to unsigned in AiffFileReader. It already performs endianness conversion for AIFF files, so it could also perform signedness conversion.

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