JorenSix / TarsosDSP

A Real-Time Audio Processing Framework in Java
http://0110.be/tag/TarsosDSP
GNU General Public License v3.0
1.97k stars 472 forks source link

AudioFloatConversion16 littleEndian conversion issue #174

Open 89iuv opened 5 years ago

89iuv commented 5 years ago

AudioFloatConversion16SB does not work properly when converting a littleEndian format.

Code:

TarsosDSPAudioFormat format = new TarsosDSPAudioFormat(
                TarsosDSPAudioFormat.Encoding.PCM_SIGNED, 48000, 16, 1, 2, 48000, false );

TarsosDSPAudioFloatConverter converter = TarsosDSPAudioFloatConverter.getConverter(format);

byte[] bytes = new byte[]{0, 0, 127, 127, 64, 64, 0, 127, 0, 64};
float[] floats = new float[bytes.length / format.getFrameSize()];
byte[] convertedBytes = new byte[bytes.length];

converter.toFloatArray(bytes, floats);
converter.toByteArray(floats, convertedBytes);

IntStream.range(0, bytes.length).forEach(i -> System.out.print(bytes[i] + " "));
System.out.println();

IntStream.range(0, floats.length).forEach(i -> System.out.print(floats[i] + " "));
System.out.println();

IntStream.range(0, convertedBytes.length).forEach(i -> System.out.print(convertedBytes[i] + " "));
System.out.println();

Output: 0 0 127 127 64 64 0 127 0 64 0.0 0.99609363 0.50196844 0.9922178 0.50001526 0 0 127 127 63 64 -1 126 -1 63

Doing the conversion from byte array to float array and back to byte array does not produce the same result.

rybandrei2014 commented 4 years ago

Hi @89iuv , have you found a solution for this conversion issue, thank you for any feedback :)

ritschwumm commented 4 years ago

sounds like a rounding issue to me - i'd guess if https://github.com/JorenSix/TarsosDSP/blob/master/src/core/be/tarsos/dsp/io/TarsosDSPAudioFloatConverter.java#L400 and https://github.com/JorenSix/TarsosDSP/blob/master/src/core/be/tarsos/dsp/io/TarsosDSPAudioFloatConverter.java#L411 used a conversion factor of 32768 instead of 32767, this would work as expected

rybandrei2014 commented 4 years ago

Hi @ritschwumm , I thought it might be a rounding issue, I would definitely try your solution. Thank you for the feedback :)

ritschwumm commented 4 years ago

if you ask me, using a conversion factor of 32767 is problematic anyway: 16 bit signed can represent values within [-32768,+32767], and i'd expect audio signals represented as a floating point value to stay within [-1,+1]. -32768.0 / 32767.0 is smaller than -1.0, though..