package org.mobicents.media.server.impl.dsp.audio.g729; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.log4j.Logger; import org.mobicents.media.Buffer; import org.mobicents.media.Format; import org.mobicents.media.server.impl.codec.g729.Bits; import org.mobicents.media.server.impl.codec.g729.CodLD8K; import org.mobicents.media.server.impl.codec.g729.LD8KConstants; import org.mobicents.media.server.impl.codec.g729.PreProc; import org.mobicents.media.server.impl.codec.g729.Util; import org.mobicents.media.server.spi.DebugUtils; import org.mobicents.media.server.spi.dsp.Codec; import org.mobicents.media.server.spi.dsp.SignalingProcessor; public class Encoder implements Codec { int frame = 0; CodLD8K encoder = new CodLD8K(); PreProc preProc = new PreProc(); CircularBuffer circularBuffer = new CircularBuffer(32000); int prm[] = new int[LD8KConstants.PRM_SIZE]; short serial[] = new short[LD8KConstants.SERIAL_SIZE]; private transient Logger logger = Logger.getLogger(Encoder.class); /* For Debugging Only */ FileInputStream testData = null; FileOutputStream outdbg = null; public Encoder() { preProc.init_pre_process(); encoder.init_coder_ld8k(); try { // testData = new FileInputStream("speech-java.bit.itu"); // testData = new FileInputStream("french.in"); // outdbg = new FileOutputStream("/home/vralev/speech-dbg.bit"); } catch (Exception e) { e.printStackTrace(); } } public Format getSupportedInputFormat() { return Codec.LINEAR_AUDIO; } public Format getSupportedOutputFormat() { return Codec.G729; } public void process(Buffer buffer) { byte[] data = (byte[]) buffer.getData(); int offset = buffer.getOffset(); int length = buffer.getLength(); byte[] media = new byte[length - offset]; System.arraycopy(data, 0, media, 0, media.length); circularBuffer.addData(media); int frameSize = 2 * LD8KConstants.L_FRAME; byte[] speechWindow = circularBuffer.getData(2 * frameSize); byte[] resultingBytes = null; if (speechWindow == null) { resultingBytes = new byte[0]; // No data available right now, send // empty buffer } else { // Process two frames = 20ms byte[] one = new byte[frameSize]; byte[] two = new byte[frameSize]; for (int q = 0; q < frameSize; q++) { one[q] = speechWindow[q]; two[q] = speechWindow[q + frameSize]; } one = process(one); two = process(two); if (one.length != two.length) { throw new RuntimeException( "The two frames are not equal in size!"); } resultingBytes = new byte[one.length + two.length]; for (int q = 0; q < one.length; q++) { resultingBytes[q] = one[q]; resultingBytes[q + one.length] = two[q]; } } int length1 = resultingBytes.length; System.arraycopy(resultingBytes, 0, (byte[])buffer.getData(), 0, length1); buffer.setOffset(0); buffer.setFormat(Codec.G729); buffer.setLength(length1); } /** * Perform compression. * * @param input * media * @return compressed media. */ public byte[] process(byte[] media) { frame++; float[] new_speech = new float[media.length]; short[] shortMedia = Util.byteArrayToShortArray(media); for (int i = 0; i < LD8KConstants.L_FRAME; i++) { new_speech[i] = (float) shortMedia[i]; } preProc.pre_process(new_speech, LD8KConstants.L_FRAME); encoder.loadSpeech(new_speech); encoder.coder_ld8k(prm, 0); //byte[] a = new byte[10]; Bits.prm2bits_ld8k(prm, serial); // return a; return Bits.toRealBits(serial); } /* These methods are just for debugging */ public void processTestDecoderWithFileITUEncoded(Buffer buffer) { byte[] data = (byte[]) buffer.getData(); int offset = buffer.getOffset(); int length = buffer.getLength(); byte[] media = new byte[length - offset]; System.arraycopy(data, 0, media, 0, media.length); int frameSize = 160; byte[] speechWindow160 = new byte[2 * frameSize]; try { int r = testData.read(speechWindow160); outdbg.write(speechWindow160); outdbg.flush(); if (r != speechWindow160.length) { logger.info("Diferent frame size" + r); } } catch (IOException e) { e.printStackTrace(); } byte[] res = null; if (speechWindow160 == null) { res = new byte[0]; } else { byte[] one = new byte[frameSize]; byte[] two = new byte[frameSize]; for (int q = 0; q < frameSize; q++) { one[q] = speechWindow160[q]; two[q] = speechWindow160[q + frameSize]; } one = process(one); two = process(two); if (one.length != two.length) { logger.error("UNEQUAL SIZE OF G729 FRAMES!!!"); } res = new byte[one.length + two.length]; for (int q = 0; q < one.length; q++) { res[q] = one[q]; res[q + one.length] = two[q]; } logger.debug("Incoming:\n" + DebugUtils.debugArray(Util.byteArrayToShortArray(speechWindow160))); logger.debug("Outgoing:\n" + DebugUtils.debugArray(res)); } buffer.setData(res); buffer.setOffset(0); buffer.setLength(res.length); } public void processTestFileWithoutDecoding(Buffer buffer) { byte[] res = null; try { byte[] data = new byte[20]; byte[] tmp = new byte[82 * 2]; testData.read(tmp); short[] sdata = Util.byteArrayToShortArray(tmp); byte[] bits = Bits.toRealBits(sdata); for (int q = 0; q < 10; q++) { data[q] = bits[q]; } testData.read(tmp); sdata = Util.byteArrayToShortArray(tmp); bits = Bits.toRealBits(sdata); for (int q = 0; q < 10; q++) { data[10 + q] = bits[q]; } res = data; } catch (Exception e) { e.printStackTrace(); } buffer.setData(res); buffer.setOffset(0); buffer.setLength(res.length); } public void setProc(SignalingProcessor processor) { } }