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...