Java Question Speex and byte order

warwound

Expert
Licensed User
Longtime User
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:

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.
 

warwound

Expert
Licensed User
Longtime User
Great it now works.
I have ultra low quality encoding and decoding!

@agraham I've used the ShortsFromBytes and ShortsToBytes methods from ByteConverter internally in the library.
Would you have any objection to me copying these two methods into my library so that the user doesn't have to include the ByteConverter library in their projects?

Thanks.

Martin.
 

yazak

Member
Licensed User
Longtime User
Did you ever release the library you made?
I am guessing you didn't as sound quality you were getting seemed to low,

When I used Speex Library in windows took me ages to get the quantity good enough,
but with right settings I manged to even at low bandwidth and with 8khz 16bit

Please can you release the library so I can test it for you see if workings as it should. or let me have a copy of what you have made.
 

Ian Garton

Member
Licensed User
Longtime User
Hi Martin et al
Has this library progressed at all? I've been using a modified version of Erel's walkie-talkie sample on here for PTT communications with a Windows PC, however the Speex codec seems to be the way to go, and looks to even allow for group broadcasts.
I've been reviewing several libraries/wrappers on Github but am struggling to work out how to wrap these for B4A.
 

warwound

Expert
Licensed User
Longtime User
@Ian Garton
I never released the Speex library to the forum - someone paid me to develop it and didn't want me to release it freely.
I think the version of Speex i used is now well and truly out of date.
Send me a PM if you want to see the source code.
 

KlausElsner

New Member
Licensed User
Longtime User
Hi warwound,
is your Speex library really working. I'd be interested. Please tell me how much your customer charges.
Tx
 

Igor_zenon

Member
Licensed User
Dear All,

I am interesting in your product Library codec Speex.

Please advise me, How can I get it from you.

Best Regard,

Igor
 

Maan Bseiso

Member
Licensed User
@Ian Garton
I never released the Speex library to the forum - someone paid me to develop it and didn't want me to release it freely.
I think the version of Speex i used is now well and truly out of date.
Send me a PM if you want to see the source code.
Hi Martin
I saw your posts on the Speex library and I need one for an app we are doing for Push To Talk ..we have a very bad mobile network and i need a codec that can handle speech in such low quality and low throughput ..
is you speex library capable of handling such service
if so I am interested in getting it. ..
please let me know about the details.

thanks in advance
 
Top