1

i'm trying to stream audio from android app to java-server. first of all i've tried simple streaming PCM data with CMG711 compression but it kills the wifi-network as a lot of data sends. So the solution was to make better compression i guess. I prepared code based on this one

public class CompressedStream {

private AudioRecord recorder;
private MediaCodec encoder;
private static final int SAMPLE_RATE     = 44100;
private static final int CHANNEL_CONFIG  = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_FORMAT    = AudioFormat.ENCODING_PCM_16BIT;
//todo recreate if config changes
private static final int MIN_BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE,
        CHANNEL_CONFIG,
        AUDIO_FORMAT);
private short audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private short channelConfig = AudioFormat.CHANNEL_IN_MONO;

private int bufferSize = 1024*4;
private boolean isRecording;

private Thread IOrecorder;

private DatagramSocket ds;

public CompressedStream() {
}

private boolean setEncoder()
{
    try {
    encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
    MediaFormat format = new MediaFormat();
    format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);
    format.setInteger(MediaFormat.KEY_AAC_PROFILE,
            MediaCodecInfo.CodecProfileLevel.AACObjectHE);
    encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return true;
}


public void compress(){
    setEncoder();

    recorder =  new AudioRecord(MediaRecorder.AudioSource.MIC,
            SAMPLE_RATE,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            MIN_BUFFER_SIZE * 10);
    try {
        ds = new DatagramSocket();
    } catch (SocketException e) {
        e.printStackTrace();
    }

    IOrecorder = new Thread(new Runnable()
    {
        public void run()
        {
            int read;
            byte[] buffer1 = new byte[bufferSize];

            ByteBuffer[] inputBuffers;
            ByteBuffer[] outputBuffers;

            ByteBuffer inputBuffer;
            ByteBuffer outputBuffer;

            MediaCodec.BufferInfo bufferInfo;
            int inputBufferIndex;
            int outputBufferIndex;

            byte[] outData;

            DatagramPacket packet;
            try
            {
                encoder.start();
                recorder.startRecording();
                isRecording = true;
                while (isRecording)
                {
                    read = recorder.read(buffer1, 0, bufferSize);

                    inputBuffers = encoder.getInputBuffers();
                    outputBuffers = encoder.getOutputBuffers();
                    inputBufferIndex = encoder.dequeueInputBuffer(-1);
                    if (inputBufferIndex >= 0)
                    {
                        inputBuffer = inputBuffers[inputBufferIndex];
                        inputBuffer.clear();

                        inputBuffer.put(buffer1);

                        encoder.queueInputBuffer(inputBufferIndex, 0, buffer1.length, 0, 0);
                    }

                    bufferInfo = new MediaCodec.BufferInfo();
                    outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);

                    while (outputBufferIndex >= 0)
                    {
                        outputBuffer = outputBuffers[outputBufferIndex];

                        outputBuffer.position(bufferInfo.offset);
                        outputBuffer.limit(bufferInfo.offset + bufferInfo.size);

                        outData = new byte[bufferInfo.size];
                        outputBuffer.get(outData);

                        Log.d("dataSend","len = " + outData.length);
                        packet = new DatagramPacket(outData, outData.length,
                                InetAddress.getByName(Settings.STREAM_TO_IP), 8001);
                        ds.send(packet);

                        encoder.releaseOutputBuffer(outputBufferIndex, false);
                        outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);

                    }
                }
                encoder.stop();
                recorder.stop();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });

    IOrecorder.start();
}
}

and the wifi-network become fells better. the compression was about x11. the problem is that now I need to decompress this data. i've tried jaad but without success. I need to push DecoderSpecificInfo as an input to decoder class (if i understand correctly). first i've tried to pass just header data 0xfff1 - no success. then i've applied this logic to create container but without success also, here the full code:

public static void runStreamListener() throws IOException {
    DatagramSocket serverSocket = new DatagramSocket(testPOrt);
    byte[] receiveData = new byte[1280];

    format = new AudioFormat(sampleRate, 16, 1, true, false);

    while (status == true) {

        receivePacket = new DatagramPacket(receiveData, receiveData.length);

        serverSocket.receive(receivePacket);

        final byte[] byteArray = new byte[receivePacket.getLength()];

        toSpeaker(byteArray);
       ).start();
    }
}


static byte[] info ;
static byte[] ENCodedByteArray = new byte[7] ;
static int profile;
static  int frequency_index;
static  int channel_config;
public static void toSpeaker(byte soundbytes[]) {
    try {

        if (soundbytes.length == 2){
            info = soundbytes;
            profile = (info[0]>>3)&0x1f;
            frequency_index = (info[0]&0x7) <<1 | (info[1]>>7) &0x1;
            channel_config  = (info[1]>>3) &0xf;
            return;
        }

        int finallength = soundbytes.length + 7;
        ENCodedByteArray[0] = (byte) 0xff;
        ENCodedByteArray[1] = (byte) 0xf1;
        ENCodedByteArray[2] = (byte) ( ((profile - 1) << 6) + (frequency_index << 2) +(channel_config >> 2));
        ENCodedByteArray[3] = (byte) (((channel_config & 0x3) << 6) + (finallength >> 11));
        ENCodedByteArray[4] = (byte)( (finallength & 0x7ff) >> 3);
        ENCodedByteArray[5] = (byte) (((finallength & 7) << 5) + 0x1f) ;
        ENCodedByteArray[6] = (byte) 0xfc;

        Decoder dec =  new Decoder(ENCodedByteArray);

        SampleBuffer buf = new SampleBuffer();
        dec.decodeFrame(soundbytes, buf);
        //the aacFrame array contains the AAC frame to decode
        byte[] audio = buf.getData(); //this array contains the raw PCM audio data

        DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
        SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

        sourceDataLine.open(format);

        sourceDataLine.start();
        sourceDataLine.open(format);

        sourceDataLine.start();

        System.out.println("format? :" + sourceDataLine.getFormat());

        sourceDataLine.write(audio, 0, audio.length);
        System.out.println(audio.toString());
        sourceDataLine.drain();
        sourceDataLine.close();
    } catch (Exception e) {
        System.out.println("Not working in speakers...");
        e.printStackTrace();
    }
}

the result i've got is an exceprion unsupported profile: -1 on the line Decoder dec = new Decoder(ENCodedByteArray);

so, which is the right way to decompress aac data?

UPDATE

i've lost first 2 bytes of stream. when we compress audio via MediaCodec we got first array with 2 bytes only, guess it releted to format(header data) but for this sample it was [19,-120] (in hex 0x1388) and not 0xfff1 as i expected, if we push this data as an input to Decoder class constructor no exception appears, but looks the data decompressed incorrectly (btw, before compressian and after decompression pack size is 4096):

first parts of arrays that have been sent (before compression) buffer1:

 p1: [-27, -4, -122, -2, 49, 0, 49, -2, 59, -3, -63, -4, 49, -7, 43, -7, -111, -3, 47, -2, -115, -5, -115, -5, 24, -2, -33, -2, -83, -4, -115, -4, 14, -1, -16, -2, -4, -4, 29, -3, -47, -6, -40, -9, 32, -5, -95, -2, 6, -3, -47, -6, 33, -4, -110, -2, 57, -2, 84, -4, 75, -3, 38, -2, -120, -4, 112, -4, 106, -4, 107, -7, -2, -8, -95, -5, -69, -4, -36, -5, -17, -6, 34, -4, -37, -4, -61, -5, -74, -5, 79, -3, -103, -3, -101, -4, 54, -5, -28, -8, 118, -7, 61, -3, -61, -4, -39, -7, -28, -7, 120, -5, -122, -4, -31, -4, 93, -3, 57, -2, 93, -4, 67, -5, 103, -3, 122, -5, 76, -9, -50, -7, 20, -2, -58, -4, -125, -6, -75, -5, 37, -3, -29, -6, -7, -7, -38, -3, 37, 0, 80, -3, -125, -5, 123, -5, -48, -8, -87, -8, -56, -4, -10, -3, 90, -5, -44, -6, 45, -3, -3, -3, -64, -5, 87, -5, -4, -3, 59, -2, -15, -4, 3, -3, -86, -6, -32, -9, -56, -6, -3, -3, 34, -4, 106, -6, 98, -4, 107, -2, 22, -3, -9, -5, 72, -2, 73, -1, -40, -4, 51, -4, 111, -5, -39, -8, -13, -7, -64, -3, -37, -3, 62, -5, 4, -5, -59, -3, 125, -2, -80, -4, 72, -4, 25, -3, 50, -3, -63, -4, 2, -3, 121, -5, 56, -6, -118, -5, 98, -3, -59, -4, 83, -6, -57, -5, 7, -1, 6, -3, -82, -6, 59, -4, -33, -3, 49, -3, -25, -5, 88, -4, 85, -3, 60, -4, 112, -4, 57, -3, -38, -7, 54, -8, 117, -4, 82, -1, 81, -3, 89, -5, -60, -4, -51, -3, 12, -4, 32, -4, -6, -2, -77, -1, -38, -3, -125, -3, 65, -4, -36, -8, -1, -7, -31, -3, -11, -3, 53, -4, 45, -3, -64, -1, -1, -2, 90, -4, 1, -3, 88, -1, 0, -1, 51, -2, -30, -3, 77, -6, -113, -8, -108, -4, -71, -2, 125, -4, 4, -4, -33, -2, -82, 0, -80, -2, 104, -3, 126, -1, 3, 0, -82, -3, 82, -3, 52, -4, 27, -7, -105, -6, 0, -1, -44, -2, 65, -4, -46, -4, 39, -1, 89, -1, -69, -3, -46, -2, 38, 1, 51, -1, 124, -3, 32, -3, -59, -7, -20, -7, 8, -2, 74, -2, 72, -3, -104, -3, 17, -1, 
 p2: [-41, -8, -66, -9, -110, -7, 121, -6, -13, -7, -54, -6, -37, -5, -59, -4, -17, -6, 24, -7, -22, -5, -23, -6, -98, -11, -68, -10, 51, -4, 25, -3, -33, -6, -26, -6, -64, -4, 52, -4, 127, -5, 124, -2, -5, -1, 117, -4, 34, -6, -68, -6, 97, -8, 22, -10, 116, -8, 70, -5, 104, -6, 25, -7, -127, -6, -9, -5, 24, -5, -98, -6, -110, -4, 119, -4, -97, -5, 9, -4, 48, -7, 83, -9, -42, -6, -26, -5, -88, -6, -93, -6, -88, -5, 14, -3, 98, -4, -24, -5, -122, -3, 117, -4, -115, -5, 42, -3, -122, -6, -99, -10, -30, -7, -1, -2, -73, -3, -49, -6, -28, -5, -109, -2, -55, -3, 46, -3, -72, -1, -27, 0, 73, -2, 102, -3, -70, -3, -38, -7, 57, -7, -10, -3,
 p3: [-94, -4, 42, -6, -70, -10, -67, -8, 56, -2, -126, -3, -16, -7, -17, -5, 117, -2, -50, -4, 9, -5, -69, -4, -94, -1, 119, -3, 127, -6, -31, -6, 88, -7, 61, -7, 12, -4, 8, -4, 101, -5, -52, -5, -17, -4, -66, -2, -82, -3, 124, -4, 99, -3, 73, -4, -20, -4, -47, -4, -90, -8, -107, -8, -70, -4, -12, -4, -91, -5, -108, -5, -88, -4, 72, -3, 11, -4, -111, -3, 41, -1, -120, -3, -45, -4, -57, -4, -81, -7, 93, -10, -2, -8, -95, -2, 96, -3, 124, -7, 20, -5, 48, -3, 108, -4, -4, -5, -34, -3, -91, -1, -61, -4, 15, -5, 41, -4, -42, -7, -56, -7, -79, -4, 26, -3, -118, -4, -13, -4, -110, -2, -81, -1, 95, -3, 109, -4, -110, -3, -60, -3, 48, -1, -23, -2, 1, -5, -8, -7, -60, -4, -87, -2, -60, -3, -6, -5, -12, -4, -20, -3, 21, -3, -56, -4, -82, -4, 102, -4, -97, -4, -6, -4, -107, -4, -1, -6, 109, -5, 22, -4, -8, -6, 61, -5, 74, -4, 22, -4, -89, -4, -108, -4, -43, -5, -38, -5, -65, -4, -35, -3, 35, -4, -49, -7, 65, -5, -103, -3, 41, -4, 18, -6, -97, -6, -79, -4, -85, -4, 96, -4, 87, -3, 35, -3, 125, -5, -1, -6, 76, -3, 75, -2, -108, -4, 113, -5, -73, -5, -74, -5, -27, -5, 3, -4, 57, -4, 5, -5, -14, -6, -97, -4, -13, -3, -99, -3, -3, -4, -32, -4, 28, -4, -69, -4, -57, -4, -119, -6, -11, -5, 81, -2, -17, -5, -123, -5, -109, -3, 31, -2, 108, -3, -69, -4, -69, -2, -113, -1, -75, -4, 121, -3, 1, -1, -100, -4, 46, -5, -124, -4, -125, -2, 108, -2, -29, -4, 61,
 p4: [22, -2, 66, -2, 85, -3, -85, -3, 127, -3, -69, -6, 30, -6, 23, -4, 25, -3, 37, -5, -21, -6, 42, -2, 58, 0, 81, -2, 49, -4, 73, -4, -79, -4, 109, -4, 87, -3, 104, -3, -114, -6, -1, -5, -81, -2, -115, -3, 72, -5, 96, -4, 39, 0, -8, 0, -68, -3, 116, -3, -47, -3, -124, -6, -103, -7, 97, -4, -116, -2, -107, -3, 85, -3, 9, -1, 43, -2, -48, -5, 29, -3, 30, -1, -122, -2, 52, -4, 125, -4, -121, -2, -91, -3, -47, -5, -117, -5, -61, -4, 69, -4, 35, -4, 100, -1, -98, -1, -29, -6, -33, -7, 103, -4, 18, -2, 104, -3, -127, -5, 32, -4, -38, -4, 123, -4, -89, -3, 
 p5: [108, -3, 15, -2, 72, -1, 58, -1, -27, -2, 120, -2, 103, -2, -55, -2, 58, -2, 55, -3, 36, -3, 4, -2, 30, -1, -56, -2, 81, -2, -91, -3, 19, -2, -95, -2, -72, -3, -31, -4, 104, -3, 122, -2, -54, -2, 39, -2, -17, -3, -63, -3, 41, -2, 49, -2, 25, -3, -53, -4, -120, -3, -81, -2, -110, -2, 26, -2, -93, -3, -115, -3, 80, -2, -25, -3, -45, -4, -60, -4, -100, -3, 123, -2, 18, -2, -9, -3, -94, -3, 14, -2, -83, -2, -42, -3, -2, -4, 43, -3, 38, -2, 127, -2, 6, -2, -7, -3, -54, -3, 85, -2, 118, -2, 70, -3, -15, -4, -110, -3, -80, -2, 113, -2, -33, -3, -127, 

but after compression i got (and it sounds like noize only):

p1[0, 0, 0, 0, zeros only]
p2[a lot of zeros, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 2, -1, -1, 0, 0, 0, 0, -1, -2, 0, 2, -1, -1, 0, 1, 0, 3, -1, -1, 0, 4, -1, -1, -1, -1, 0, 2, -1, -5, 0, 2, 0, 0, 0, 0, 0, 7, -1, -2, 0, 4, 0, 1, -1, -5, 0, 4, -1, -6, 0, 1, 0, 4, -1, -3, 0, 10, -1, -1, 0, 1, 0, 5, -1, -9, 0, 4, -1, -4, -1, -3, 0, 9, -1, -5, 0, 9, 0, 3, -1, -3, 0, 8, -1, -11, 0, 0, 0, 0, -1, -9, 0, 11, -1, -4, 0, 5, 0, 8, -1, -8, 0, 8, -1, -9, -1, -6, 0, 4, -1, -12, 0, 10, 0, 1, -1, -1, 0, 13, -1, -10, 0, 4, -1, -4, -1, -13, 0, 7, -1, -12, 0, 5, 0, 6, -1, -6, 0, 14, -1, -8, -1, -2, 0, 1, -1, -17, 0, 5, -1, -7, -1, -2, 0, 11, -1, -8, 0, 11, -1, -3, -1, -9, 0, 5, -1, -17, 0, 0, -1, -1, -1, -7, 0, 14, -1, -5, 0, 4, 0, 3, -1, -13, 0, 4, -1, -11, -1, -4, 0, 5, -1, -9, 0, 10, 0, 0, -1, -2, 0, 7, -1, -11, 0, 1, -1, -5, -1, -10, 0, 7, -1, -6, 0, 3, 0, 6, -1, -5, 0, 8, -1, -3, -1, -3, 0, 3, -1, -16, -1, -14, -1, -4, 0, 10, 0, 29, 0, 21, -1, -8, -1, -28, -1, -20, -1, -49, -1, -32, 0, 115, 0, 97, -1, -85, -1, -67, -1, -24, -1, -90, 0, 23, 0, -102, 0, 51, -1, -87, -1, -86, -1, -2, -1, -54, -1, -102, 0, -90, 0, -60, -1, 85, -1, 125, 0, 61, -1, -79, -1, -55, 0, 91, 0, 105, 0, 44, -1, 77, -1, 104, 0, 76, -1, -30, 0, 27, 0, -69, -1, -69, -1, 113, -1, -27, -1, -99, -1, -48, 0, 74, 0, -103, 0, 87, -1, 104, -1, 127, -1, -69, -1, 99, 0, 27, 0, -24, 0, -125, -1, -121, -1, 78, -1, -30, -1, -121, -1, -48, 1, 21, 0, 91, -1, 81, -2, -41, zeros again]
p3[zeros, 0, 5, 0, 15, 0, 26, 0, 27, 0, 33, 0, 58, 0, 61, 0, 39, 0, 27, -1, -16, -1, -39, -1, -26, -1, -86, -1, -78, -1, -36, -1, -109, -1, -65, 0, 7, 0, 7, 0, 120, 0, 101, 0, 24, 0, 112, 0, 101, 0, 79, 0, -96, 0, -92, 0, -126, 0, 105, 0, 66, 0, 15, 0, 24, 0, 83, 0, 44, -1, -19, -1, -109, -1, 63, -1, 127, -1, -113, -1, -79, 0, 102, 0, 116, 0, 1, 0, 83, 0, -1, 1, 29, 1, 122, 2, 112, 2, -80, 2, 103, 2, 125, 2, -20, 3, 3, 2, -102, 3, 71, 3, -51, 2, -117, 1, -51, 1, -77, 1, -64, 1, -65, 1, 5, 1, -67, 1, 116, -2, -121, -2, 50, -2, -22, -2, 24, -2, 12, -2, 14, -3, -29, -4, -15, -5, 79, -5, -38, -4, -96, -5, -3, -4, 2, -4, -125, -4, -117, -4, 8, -4, 77, -3, -77, -2, 56, -2, 92, -1, 115, -1, -2, -1, 49, -1, 68, 0, -105, data]
p4[0, 1, 0, 2, 0, 4, 0, 5, 0, 6, 0, 11, 0, 14, 0, 11, 0, 10, 0, 11, 0, 13, 0, 16, 0, 20, 0, 25, 0, 26, 0, 21, 0, 19, 0, 22, 0, 20, 0, 24, 0, 35, 0, 27, 0, 14, 0, 21, 0, 18, 0, 5, 0, 11, 0, 22, 0, 31, 0, 19, -1, -8, 0, 9, 0, 24, -1, -6, 0, 6, 0, 33, 0, 20, 0, 12, 0, 4, 0, 14, 0, 37, 0, 13, 0, 15, 0, 46, 0, 24, 0, 21, 0, 42, 0, 32, 0, 40, 0, 44, 0, 27, 0, 41, 0, 66, 0, 80, 0, 82, 0, 69, 0, 79, 0, 93, 0, 63, 0, 71, 0, 127, 0, 111, 0, 46, 0, 47, 0, 79, 0, 62, 0, 38, 0, 79, 0, 115,loks like data]
p5[0, 1, 0, 1, 0, 1, 0, 4, 0, 8, 0, 6, 0, 2, 0, 2, 0, 9, 0, 15, 0, 9, 0, 17, 0, 24, 0, 7, 0, 11, 0, 21, 0, 16, 0, 29, 0, 29, 0, 15, 0, 26, 0, 20, 0, 5, 0, 16, 0, 27, 0, 37, 0, 43, 0, 19, 0, 16, 0, 33, 0, 14, 0, looks like data]

so... what's going wrong?

UPDATE

looks value 1388 related to video format...

Community
  • 1
  • 1
Siarhei
  • 2,358
  • 3
  • 27
  • 63

0 Answers0