package local.ua;
import local.media.AudioInput;
import local.media.AudioOutput;
import local.media.RtpStreamSender;
import local.media.RtpStreamReceiver;
import org.zoolu.sip.provider.SipStack;
import org.zoolu.tools.Log;
import org.zoolu.tools.LogLevel;
import java.net.DatagramSocket;
import javax.sound.sampled.AudioFormat;
// Test..
import local.media.ToneInputStream;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioInputStream;
/** Audio launcher based on javax.sound */
public class JAudioLauncher implements MediaLauncher
{
/** 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=500;
/** Frame rate [frames per second] */
int frame_rate=16; //=sample_rate/(frame_size/sample_size);
AudioFormat.Encoding codec=AudioFormat.Encoding.ULAW;
boolean signed=false;
boolean big_endian=false;
//String filename="audio.wav";
/** 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;
/** Costructs the audio launcher */
public JAudioLauncher(RtpStreamSender rtp_sender, RtpStreamReceiver rtp_receiver, Log logger)
{ log=logger;
sender=rtp_sender;
receiver=rtp_receiver;
}
/** Costructs the audio launcher */
public JAudioLauncher(int local_port, String remote_addr, int remote_port, int direction, Log logger)
{ log=logger;
try
{ socket=new DatagramSocket(local_port);
dir=direction;
// sender
if (dir>=0)
{ printLog("new audio sender to "+remote_addr+":"+remote_port,LogLevel.MEDIUM);
//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
if (dir<=0)
{ printLog("new audio receiver on "+local_port,LogLevel.MEDIUM);
//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); }
}
/** Costructs the audio launcher */
public JAudioLauncher(int local_port, String remote_addr, int remote_port, int direction, String audiofile_in, String audiofile_out, int sample_rate, int sample_size, int frame_size, Log logger)
{ log=logger;
frame_rate=sample_rate/frame_size;
try
{ socket=new DatagramSocket(local_port);
dir=direction;
// sender
if (dir>=0 && audiofile_in!=null && audiofile_in.equals(JAudioLauncher.TONE))
{ printLog("new audio sender to "+remote_addr+":"+remote_port,LogLevel.MEDIUM);
printLog("Tone generator: "+tone_freq+" Hz");
tone=new ToneInputStream(tone_freq,tone_amp,sample_rate,sample_size,ToneInputStream.PCM_LINEAR_UNSIGNED,big_endian);
sender=new RtpStreamSender(tone,true,payload_type,frame_rate,frame_size,socket,remote_addr,remote_port);
}
else
if (dir>=0 && audiofile_in!=null)
{ printLog("new audio sender to "+remote_addr+":"+remote_port,LogLevel.MEDIUM);
File file=new File(audiofile_in);
if (audiofile_in.indexOf(".wav")>0)
{ AudioFileFormat format=AudioSystem.getAudioFileFormat(file);
printLog("File audio format: "+format);
AudioInputStream input_stream=AudioSystem.getAudioInputStream(file);
sender=new RtpStreamSender(input_stream,true,payload_type,frame_rate,frame_size,socket,remote_addr,remote_port);
}
else
{ FileInputStream input_stream=new FileInputStream(file);
sender=new RtpStreamSender(input_stream,true,payload_type,frame_rate,frame_size,socket,remote_addr,remote_port);
}
}
else
if (dir>=0)
{ printLog("new audio sender to "+remote_addr+":"+remote_port,LogLevel.MEDIUM);
//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
if (dir<=0 && audiofile_out!=null)
{ printLog("new audio receiver on "+local_port,LogLevel.MEDIUM);
File file=new File(audiofile_out);
FileOutputStream output_stream=new FileOutputStream(file);
receiver=new RtpStreamReceiver(output_stream,socket);
}
else
if (dir<=0)
{ printLog("new audio receiver on "+local_port,LogLevel.MEDIUM);
//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); }
}
/** Starts media application */
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 */
private void printLog(String str)
{ printLog(str,LogLevel.HIGH);
}
/** Adds a new string to the default Log */
private void printLog(String str, int level)
{ if (log!=null) log.println("AudioLauncher: "+str,level+SipStack.LOG_LEVEL_UA);
if (level<=LogLevel.HIGH) System.out.println("AudioLauncher: "+str);
}
/** Adds the Exception message to the default Log */
void printException(Exception e,int level)
{ if (log!=null) log.printException(e,level+SipStack.LOG_LEVEL_UA);
if (level<=LogLevel.HIGH) e.printStackTrace();
}
}