PCM -> AAC (Encoder) -> PCM(Decoder) in real-time with correct optimization

After testing this is what I came up with from modifying your code:

 package com.example.app;

    import android.app.Activity;

    import android.media.AudioManager;
    import android.media.MediaCodecInfo;
    import android.media.MediaFormat;
    import android.os.Bundle;

    import android.media.AudioFormat;
    import android.media.AudioRecord;
    import android.media.AudioTrack;
    import android.media.MediaCodec;

    import android.media.MediaRecorder.AudioSource;

    import android.util.Log;

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketAddress;
    import java.net.SocketException;
    import java.nio.ByteBuffer;

    public class MainActivity extends Activity
    {
        private AudioRecord recorder;
        private AudioTrack player;

        private MediaCodec encoder;
        private MediaCodec decoder;

        private short audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        private short channelConfig = AudioFormat.CHANNEL_IN_MONO;

        private int bufferSize;
        private boolean isRecording;
        private boolean isPlaying;

        private Thread IOrecorder;

        private Thread IOudpPlayer;


        private DatagramSocket ds;
        private final int localPort = 39000;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            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);
                           // Log.d("AudioRecoder", read + " bytes read");
                            //------------------------

                            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("AudioEncoder ", outData.length + " bytes encoded");
                                //-------------
                                packet = new DatagramPacket(outData, outData.length,
                                        InetAddress.getByName("127.0.0.1"), localPort);
                                ds.send(packet);
                                //------------

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

                            }
                            // ----------------------;

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



            IOudpPlayer = new Thread(new Runnable()
            {
                public void run()
                {
                    SocketAddress sockAddress;
                    String address;

                    int len = 2048
                    byte[] buffer2 = new byte[len];
                    DatagramPacket packet;

                    byte[] data;

                    ByteBuffer[] inputBuffers;
                    ByteBuffer[] outputBuffers;

                    ByteBuffer inputBuffer;
                    ByteBuffer outputBuffer;

                    MediaCodec.BufferInfo bufferInfo;
                    int inputBufferIndex;
                    int outputBufferIndex;
                    byte[] outData;
                    try
                    {
                        player.play();
                        decoder.start();
                        isPlaying = true;
                        while (isPlaying)
                        {
                            try
                            {
                                packet = new DatagramPacket(buffer2, len);
                                ds.receive(packet);

                                sockAddress = packet.getSocketAddress();
                                address = sockAddress.toString();

                             //   Log.d("UDP Receiver"," received !!! from " + address);

                                data = new byte[packet.getLength()];
                                System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());

                               // Log.d("UDP Receiver",  data.length + " bytes received");

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

                                    inputBuffer.put(data);

                                    decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
                                }

                                bufferInfo = new MediaCodec.BufferInfo();
                                outputBufferIndex = decoder.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("AudioDecoder", outData.length + " bytes decoded");

                                    player.write(outData, 0, outData.length);

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

Leave a Comment