I'm trying to get an NDK port of the Speex encoder/decoder working and need some help converting bytes to shorts and vice versa...
I have the audio bytes (as an array) from a .wav file, these play fine using the AudioTrack library so i am sure i correctly extracted the bytes from the .wav file.
Now i need to convert this array of bytes into audio frames where each audio frame is an array of 160 shorts.
(The first audio frame should be bytes 0 to 319 for example).
The encoder encodes each audio frame (array of short) and returns an array of bytes.
Once all audio frames have been encoded i want to decode them to test that i have the original sound.
The decoder decodes an array of bytes (compressed audio frame) to an array of shorts (uncompressed audio frame).
I've tried many variations of code to convert bytes to shorts and back again but never get the correct sound back from the encode then decode process.
The .wav byte array represents data as 2's complement signed integers with little endian byte order and the NDK library works with shorts that have little endian byte order (i think!).
So here's my code to convert the .wav array of bytes to audio frames where each audio frame is an array of shorts to be passed to the encoder:
And the code to convert the arrays of shorts (audio frames) from the NDK library to a single array of bytes:
I've tried many variations on the bitshifting and the final sound varies from white noise to unrecogniseable sound.
Anyone know what i'm doing wrong?
Thanks.
Martin.
I have the audio bytes (as an array) from a .wav file, these play fine using the AudioTrack library so i am sure i correctly extracted the bytes from the .wav file.
Now i need to convert this array of bytes into audio frames where each audio frame is an array of 160 shorts.
(The first audio frame should be bytes 0 to 319 for example).
The encoder encodes each audio frame (array of short) and returns an array of bytes.
Once all audio frames have been encoded i want to decode them to test that i have the original sound.
The decoder decodes an array of bytes (compressed audio frame) to an array of shorts (uncompressed audio frame).
I've tried many variations of code to convert bytes to shorts and back again but never get the correct sound back from the encode then decode process.
The .wav byte array represents data as 2's complement signed integers with little endian byte order and the NDK library works with shorts that have little endian byte order (i think!).
So here's my code to convert the .wav array of bytes to audio frames where each audio frame is an array of shorts to be passed to the encoder:
B4X:
public byte[] Encode(byte[] Data) throws IOException{
int byteCount=Data.length;
int byteIndex=0;
ByteArrayOutputStream encodedBytes=new ByteArrayOutputStream(8192);
short[] frame;
int frameIndex;
int frameSize=getObject().getFrameSize();
while(byteIndex<byteCount){
frame=new short[frameSize];
frameIndex=0;
while(frameIndex<frameSize && byteIndex<byteCount){
frame[frameIndex]=(short) ((Data[byteIndex]) | Data[byteIndex+1] << 8);
frameIndex++;
byteIndex+=2;
}
byte[] encodedData=getObject().encode(frame);
// Log.d("B4A", "encodedData.length = "+encodedData.length);
encodedBytes.write(encodedData); // optimise - get a reference to the encoder
}
encodedBytes.close();
return encodedBytes.toByteArray();
}
And the code to convert the arrays of shorts (audio frames) from the NDK library to a single array of bytes:
B4X:
public byte[] Decode(byte[] Data, int FrameSize) throws IOException{
int byteCount=Data.length;
int byteIndex=0;
ByteArrayOutputStream decodedBytes=new ByteArrayOutputStream(8192);
byte[] frame;
int frameIndex;
short[] temp;
while(byteIndex<byteCount){
frame=new byte[FrameSize*2];
frameIndex=0;
while(frameIndex<FrameSize && byteIndex+frameIndex<byteCount){
frame[frameIndex]=Data[byteIndex+frameIndex];
frame[frameIndex+1]=Data[byteIndex+frameIndex+1];
frameIndex+=2;
byteIndex+=2;
}
temp=getObject().decode(frame);
for(int j=0, k=temp.length; j<k; j++){
// convert byte order?
decodedBytes.write((byte) temp[j]);
decodedBytes.write((byte) (temp[j] >> 8));
}
}
decodedBytes.close();
return decodedBytes.toByteArray();
}
I've tried many variations on the bitshifting and the final sound varies from white noise to unrecogniseable sound.
Anyone know what i'm doing wrong?
Thanks.
Martin.