package iax.audio.ulaw; import java.io.InputStream; import iax.audio.AudioListener; import iax.audio.Recorder; import iax.audio.RecorderException; import iax.protocol.call.Call; import java.io.FileOutputStream; import java.io.FileNotFoundException; /** * ULAW audio recorder. * Reads audio from inStream and sends it to a class implementing AudioListener. * Analog to PCMRecorder */ public class ULAWRecorder extends Recorder { private AudioListener call; private boolean recording; private final int buffer_size; private final int buffer_time; private Thread captureThread; private InputStream inStream; /** * Constructor. Initializes recorder. * @throws RecorderException */ public ULAWRecorder(Call call, InputStream inStream) throws RecorderException { this.call = call; if (inStream == null) throw new RecorderException("inStream null"); this.inStream = inStream; buffer_size = 160; buffer_time = 20; recording = false; } /** * Starts recording. * @param al Object that is going to process the recorded audio data. */ public void record(AudioListener al) { call = al; captureThread = new Thread(new CaptureThread(), "UlawRecorder"); recording = true; captureThread.start(); } /** * Stops recording. */ public void stop() { recording = false; } class CaptureThread implements Runnable { private FileOutputStream fos; private byte[] silence; private byte silenceByte; public CaptureThread() { try { fos = new FileOutputStream("njiax_sent.raw"); } catch (FileNotFoundException ex) { ex.printStackTrace(); } silenceByte = 0x7F; silence = new byte[buffer_size]; for (int i = 0; i < buffer_size; i++) { silence[i] = silenceByte; } } public void run() { byte buffer[] = new byte[buffer_size]; int count; long startTime; long endTime; //byte silenceBuffer[] = new byte[buffer_size]; /*for (int i = 0; i < silenceBuffer.length; i++) { silenceBuffer[i] = 0x7f; }*/ try { while (recording) { //Start measuring time //startTime = System.currentTimeMillis(); startTime = (long)(System.nanoTime() * 1E-6); //System.out.println("SSns: "+startTime + "\nSSss: " + System.currentTimeMillis() ); if (inStream.available() > 0) { //Read buffer from app to send to Asterisk count = inStream.read(buffer, 0, buffer.length); //System.err.println("ULawRecorder DATA AVAILABLE: "+count); } else { count = 0; //System.err.println("ULawRecorder NO DATA AVAILABLE"); } /*if (count == 0) { //System.err.println("ULAWRECORDER.... WILL SEND SILENCE........"); System.arraycopy(silenceBuffer, 0, buffer, 0, buffer_size); count = buffer_size; try { Thread.sleep(buffer_time); } catch (InterruptedException ex1) { ex1.printStackTrace(); } }*/ if (count > 0) { if (count != buffer_size) { System.err.println(">>> WILL SEND LESS BYTES THAN EXPECTED!!!!!!!!!!!!!!!!!: "+count + " vs: " + buffer_size); } fos.write(buffer, 0, buffer_size); //not count because want to log read failures.... // synchronized (buffer) { //long start = System.currentTimeMillis(); call.listen(buffer, 0, count); //endTime = System.currentTimeMillis(); endTime = (long)(System.nanoTime() * 1E-6); //} double nBytes = ((endTime - startTime) / 8000f) * 1000f; for (int i = (int) Math.ceil(nBytes); i-- > 0; ) { fos.write(silenceByte); } long procTime = endTime - startTime; long sleepTime = buffer_time; if (procTime > 0) { sleepTime -= procTime; } //sleepTime *= 0.95; sleepTime -= 5; if (sleepTime > 0) { //try { // long startSleepTime = System.currentTimeMillis(); //System.out.println("\t\t\t\t\t\tCaptureThread will sleep: "+sleepTime); //Thread.currentThread().sleep(0, (int)sleepTime * 1000); Thread.sleep(sleepTime); //Thread.sleep(0, 999999); //sleepTime--; //PreciseTimer.sleep(sleepTime); ///////////////////////////fos.write(silence); // long endtSleepTime = System.currentTimeMillis(); // long sleptBy = endtSleepTime - startSleepTime; /* if (sleptBy > sleepTime) { System.err.println("Slept more than it should: " + sleptBy + " should be: "+sleepTime); }*/ /*} catch (InterruptedException ex) { ex.printStackTrace(); }*/ } } else if (count == 0) { //System.out.println("nothing to write"); //try { //PreciseTimer.sleep((long)(buffer_time)); Thread.sleep(buffer_time - 1); //Thread.sleep(buffer_time); /*} catch (InterruptedException ex1) { ex1.printStackTrace(); }*/ fos.write(silence); } }//while } catch (Exception e) { e.printStackTrace(); } } } }