package net.sourceforge.gjtapi.raw.mjsip.ua;
import java.io.OutputStream;
import java.io.InputStream;
import local.media.AudioInput;
import local.media.AudioOutput;
import local.media.RtpStreamSender;
import local.media.RtpStreamReceiver;
import local.media.ToneInputStream;
import org.zoolu.sip.provider.SipStack;
import org.zoolu.tools.LogLevel;
import org.zoolu.tools.Log;
import java.net.DatagramSocket;
import javax.sound.sampled.AudioFormat;
/** Audio launcher based on javax.sound */
public class JAudioLauncher extends local.ua.JAudioLauncher {
/** Event logger. */
Log log = null;
/** Payload type */
int payload_type = 0;
/** Sample rate [bytes] */
int sample_rate = 8000;
/** Sample size [bytes] */
int sample_size = 1;
/** Frame size [bytes] */
int frame_size = 1024;///////////////////////////////////500;
/** Frame rate [frames per second] */
int frame_rate = 8;/////16; //=sample_rate/(frame_size/sample_size);
AudioFormat.Encoding codec = AudioFormat.Encoding.ULAW;
boolean signed = false;
boolean big_endian = false;
/** Test tone */
public static final String TONE = "TONE";
/** Test tone frequency [Hz] */
public static int tone_freq = 100;
/** Test tone ampliture (from 0.0 to 1.0) */
public static double tone_amp = 1.0;
/** Runtime media process */
Process media_process = null;
int dir; // duplex= 0, recv-only= -1, send-only= +1;
DatagramSocket socket = null;
RtpStreamSender sender = null;
RtpStreamReceiver receiver = null;
AudioInput audio_input = null;
AudioOutput audio_output = null;
ToneInputStream tone = null;
public JAudioLauncher(int local_port, String remote_addr, int remote_port,
int direction, InputStream audioStream_in,
OutputStream audioStream_out, int sample_rate,
int sample_size, int frame_size, Log logger) {
super(null, null, logger);
log = logger;
frame_rate = sample_rate / frame_size;
try {
socket = new DatagramSocket(local_port);
dir = direction;
//SENDER (PLAY)
if (dir >= 0 /*&& audioStream_in != null*/) {
printLog("new audio sender to " + remote_addr + ":" +
remote_port, LogLevel.MEDIUM);
//System.out.println("sender oki doki! new audio sender to " + remote_addr + ":" + remote_port + " payload: "+payload_type);
sender = new RtpStreamSender(audioStream_in, true, payload_type,
frame_rate, frame_size, socket,
remote_addr, remote_port);
} /*else
if (dir >= 0) {
//TEST ONLY - Sound Card audio
printLog("new audio sender to " + remote_addr + ":" +
remote_port, LogLevel.MEDIUM);
System.out.println("sender NOT oki doki! new audio sender to " + remote_addr + ":" + remote_port);
//audio_input=new AudioInput();
AudioFormat format = new AudioFormat(codec, sample_rate,
8 * sample_size, 1, sample_size, sample_rate,
big_endian);
audio_input = new AudioInput(format);
//sender=new RtpStreamSender(audio_input.getInputStream(),false,payload_type,frame_rate,frame_size,socket,remote_addr,remote_port);
sender = new RtpStreamSender(audio_input.getInputStream(), true,
payload_type, frame_rate,
frame_size, socket, remote_addr,
remote_port);
sender.setSyncAdj(2);
}*/
// RECEIVER (RECORD)
if (dir <= 0 /*&& audioStream_out != null*/) {
printLog("new audio receiver on " + local_port, LogLevel.MEDIUM);
//System.out.println("receiver oki doki! new audio receiver on " + local_port);
receiver = new RtpStreamReceiver(audioStream_out, socket);
}/* else
if (dir <= 0) {
//TEST ONLY - Sound Card audio
printLog("new audio receiver on " + local_port, LogLevel.MEDIUM);
System.out.println("receiver NOT oki doki! new audio receiver on " + local_port);
//audio_output=new AudioOutput();
AudioFormat format = new AudioFormat(codec, sample_rate,
8 * sample_size, 1, sample_size, sample_rate,
big_endian);
audio_output = new AudioOutput(format);
receiver = new RtpStreamReceiver(audio_output.getOuputStream(),
socket);
}*/
} catch (Exception e) {
printException(e, LogLevel.HIGH);
}
}
public boolean isMediaRunning() {
boolean globalStatus = false;
if (sender != null) {
globalStatus |= sender.isRunning();
}
if (receiver != null) {
globalStatus |= receiver.isRunning();
}
return globalStatus;
}
public void waitForEndOfMedia() {
while (isMediaRunning()) {
try {
Thread.currentThread().sleep(15);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void waitForEndOfPlay() {
if (sender != null) {
while (sender.isRunning()) {
try {
Thread.currentThread().sleep(15);
} catch (InterruptedException ex) {
}
}
}
}
public void waitForEndOfRecord() {
if (receiver != null) {
while (receiver.isRunning()) {
try {
Thread.currentThread().sleep(15);
} catch (InterruptedException ex) {
}
}
}
}
public boolean startMedia() {
printLog("starting java audio..", LogLevel.HIGH);
if (sender != null) {
printLog("start sending", LogLevel.LOW);
sender.start();
if (audio_input != null)
audio_input.play();
}
if (receiver != null) {
printLog("start receiving", LogLevel.LOW);
receiver.start();
if (audio_output != null)
audio_output.play();
}
return true;
}
/** Stops media application */
public boolean stopMedia() {
printLog("halting java audio..", LogLevel.HIGH);
if (sender != null) {
sender.halt();
sender = null;
printLog("sender halted", LogLevel.LOW);
}
if (audio_input != null) {
audio_input.stop();
audio_output = null;
}
if (receiver != null) {
receiver.halt();
receiver = null;
printLog("receiver halted", LogLevel.LOW);
}
if (audio_output != null) {
audio_output.stop();
audio_output = null;
}
// take into account the resilience of RtpStreamSender
// (NOTE: it does not take into acconunt the resilience of RtpStreamReceiver; this can cause SocketException)
try {
Thread.sleep(RtpStreamReceiver.SO_TIMEOUT);
} catch (Exception e) {}
socket.close();
return true;
}
// ****************************** Logs *****************************
/** Adds a new string to the default Log */
public void printLog(String str, int level) {
if (log != null)
log.println("AudioLauncher: " + str, level + SipStack.LOG_LEVEL_UA);
if (level <= LogLevel.HIGH)
log.println("AudioLauncher: " + str);
}
/** Adds the Exception message to the default Log */
public void printException(Exception e, int level) {
if (log != null)
log.printException(e, level + SipStack.LOG_LEVEL_UA);
if (level <= LogLevel.HIGH)
e.printStackTrace();
}
}