converting 16bit int to 32bit float
i'm reading portions of a soundfile into ram using java's read( byte
[] b ) method of the AudioInputStream class.
in order to do some processing, i need to convert the byte[] into
32bit floats.
assuming the file format is 16bit signed integer (which it is im my
case) i do the following:
- wrap the byte[] into a bytebuffer and call it's getShort() method
to decode to 16bit data
- convert the 16bit data to 32bit float by scaling it into a range of
-1. / +1.
i hope this makes sense so far.
16bit signed integer has a range of -32768 to 32767.
my question is, how do i deal correctly with the asymmetry?
somewhere on apples site i found this code snippet:
if (inputSample >= 0) {
*floatDestBuf = inputSample / 32767.0;
} else {
*floatDestBuf = inputSample / 32768.0;
}
but i can't believe this is true...
my tests* have shown that it is more likely to be just a simple
division by 32768. (regardless wether input is positive or negativ).
but maybe my test routine was just wrong...
any comments on that would be great.
volker.
* writing a value of +1.0 into a buffer and saving as 16bit int file
(big endian), i end up with two bytes: 127, -1
the getShort() method converts this to a value of 32767
writing a value of -1.0 into a buffer, ends up with bytes: -128, 1
the getShort() method converts this to a value of -32767
dividing both values by 32768 i get 0.9999695 and -0.9999695, which
seems ok.
loading the file back into a buffer and checking the values with
peek~, i get the same results (0.999969).
On 09 Feb 2007, at 23:10, topher lafata wrote:
> Have you looked at the com.cycling74.msp.AudioFileBuffer class?
> Look in the C74/java/java-doc/api directory for docs and the
> mxj~ examples directory for an example of its use.It will load
> an audio file and do the decoding into float data for you.
thanks, i found it, and it works fine for my needs.
i'm still interested in the correct conversion in general.
if someone feels like commenting on that, i'd be happy.
volker.
>
> any comments?
Only that there is no fundamentally *right* way to perform this
conversion, as either one could be argued for. It depends entirely on
how the audio was converted to the 16bit range in the first place.
Some code will multiply by 32767, and some code will multiply by
32768. Since it is based on how the source is recorded, and since
this isn't typpically embedded in the audio file, I don't know how
anyone could claim which is correct. It's like is big endian or
little endian more correct?
There probably won't be any changes to existing behavior in the near
future, so the best thing for you to do is to establish what is
happening where you need to know and take it into account
accordingly. You could just use float32 audio files. Pre-converted
with the algorithm of your choice if you need to convert from 16bit
source which you know to have been recorded with the appropriate
conversion constant.
-Joshua
On 10 Feb 2007, at 18:41, Joshua Kit Clayton wrote:
>>
>> any comments?
>
> Only that there is no fundamentally *right* way to perform this
> conversion, as either one could be argued for. It depends entirely
> on how the audio was converted to the 16bit range in the first
> place. Some code will multiply by 32767, and some code will
> multiply by 32768. Since it is based on how the source is recorded,
> and since this isn't typpically embedded in the audio file, I don't
> know how anyone could claim which is correct.
ok, this aproofs my findings. thanks for the confirmation.
> It's like is big endian or little endian more correct?
well, endianess is embedded in the file. handled correctly, it
doesn't change the sample values, as i understand it.
>
> There probably won't be any changes to existing behavior in the
> near future, so the best thing for you to do is to establish what
> is happening where you need to know and take it into account
> accordingly. You could just use float32 audio files. Pre-converted
> with the algorithm of your choice if you need to convert from 16bit
> source which you know to have been recorded with the appropriate
> conversion constant.
ja, no problem. i was just surprised to find that there's obviously
some arbitrary factor in storing/recalling soundfiles, that has a
direct effect on the sample values, while everybody is so hysterical
about sr and bitdeth etc.
thanks for your comments, joshua.
volker.
Thanks, Ben. That was it.
On 2/13/07 12:59 PM, "Ben Nevile" wrote:
> look for duplicate jitter.jar files on your machine.
>
> Ben
>
> On 2/13/07, Gary Lee Nelson wrote:
>> I just upgraded to the current max 4.6 and jitter 1.6.2 on a G4 laptop PPC.
>> Got this error.
>>
>> € error: java.lang.NoSuchMethodError: copyMatrixToArray
>>
>> Any advice?
>>
>> Cheers
>> Gary Lee Nelson
>> Oberlin College
>> www.timara.oberlin.edu/GaryLeeNelson
>>
>>
>>
>>
>
Cheers
Gary Lee Nelson
Oberlin College
www.timara.oberlin.edu/GaryLeeNelson
On 13-Feb-2007, at 19:00, Gary Lee Nelson wrote:
> Sorry. I forgot to change the subject.
It's still the same thread.
Changing the subject line does not create a new thread for threaded
readers.
Oh, well.
-------------- http://www.bek.no/~pcastine/Litter/ -------------
Peter Castine +--> Litter Power & Litter Bundle for Jitter
Universal Binaries on the way
iCE: Sequencing, Recording &
Interface Building for |home | chez nous|
Max/MSP Extremely cool |bei uns | i nostri|
http://www.dspaudio.com/ http://www.castine.de
> > Sorry. I forgot to change the subject.
>
> It's still the same thread.
>
> Changing the subject line does not create a new thread for threaded
> readers.
In some email environments (eg GMail) it does.
Ben
Hello everyone
I know this topic is kindof old, but I've been trying to do the exact same thing with a java library I found and got stuck in the byte to float conversion. I've never worked with bytes before, my experience with coding is mostly trough web...
Volker's description in the first post describes raughly the steps to follow, and I get the big picture, but when trying to implement it the confusion comes.
The original code is part of an ogg decoding library ( by Tor-Einar Jarnbjo ). This belongs to a class that converts the ogg data into pcm and saves to a wav file, so I'm trying to get the transformed bytes and pass them to the mxj object output.
This is the code that gets the converted bytes and saves them to the file:
try {
// read pcm data from the vorbis channel and
// write the data to the wav file
while(true) {
int read=vs.readPcm(buffer, 0, buffer.length);
// fuffer size here = 65536 and vs is a VorbisStream object
//returning the amount of bytes written to the buffer
for(int i=0; i
// swap from big endian to little endian
byte tB=buffer[i];
buffer[i]=buffer[i+1];
buffer[i+1]=tB;
}
outFile.write(buffer, 0, read);
len+=read;
}
}
catch(EndOfOggStreamException e) {
// not really an error, but we've
// reached the end of the vorbis stream
// and so exit the loop
}
So if I understand correctly...the bytes we are writing to the buffer (65536) are 16 but pcm data, which means that if I take the buffer where we are writing it to a file, that's what it will contain, is this the byte[] data that I should wrap into a byteBuffer in order to call its getShort?
Should I take all the data in the buffer at once and get its short value to convert afterwards?
Should I put this code this inside the perform loop in my mxj object?
I know it's a lot of questions, and that's because I'm slightly confused with this, so any direction in what should I be looking into or understanding better would be very much appreciated.
Thanks in advance
-
Victor