package uk.co.mmscomputing.device.phone; import java.io.*; import java.util.*; import java.text.*; import javax.sound.sampled.*; import uk.co.mmscomputing.util.*; import uk.co.mmscomputing.concurrent.*; import uk.co.mmscomputing.sound.WaveOutputFile; public class PhoneCallSaver extends Thread implements PhoneConstants,PhoneCallHandler{ protected Properties properties; protected boolean isrunning; private Player player=null; private String filename=null; private InputStream pin; public PhoneCallSaver(){} public String getFile(){return filename;} public void init(Properties properties){this.properties=properties;} public void run(String local,String remote,final InputStream pin,final OutputStream pout){ // called by a PhoneAnswerer in own thread this.pin=pin; WaveOutputFile fout=null; try{ isrunning=true; player=new Player(pout); // play start msg, wait a bit, play end msg player.start(); filename = createFilePath(local,remote); // save phone input as wav file fout = new WaveOutputFile(new File(filename),pcmformat); write(pin,fout); player.stopPlaying(); stopRunning(); }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".run\n\tDisconnected call.\n\t"+e); e.printStackTrace(); }finally{ try{ pin.close(); pout.close(); if(fout!=null){ fout.close(); } }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".run\n\tCould not close an i/o stream.\n\t"+e); } } } public void stopRunning(){ isrunning=false; } public void stopPlaying(){ if(player!=null){ player.stopPlaying(); } } static private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SSS-"); static private int msgno=0; private String createFilePath(String localno,String remoteno){ File file,parent=new File(properties.getProperty(phoneFileDirID)); String rno=remoteno.replaceAll("\\*\\*",""); // PBX: internal dialling String destfile=sdf.format(new Date())+(msgno++)+"_"+localno+"_"+rno+".wav"; try{ parent.mkdirs(); file=new File(parent.getAbsolutePath(),destfile); }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".createFilePath:\n\tCould not create directory:\n\t" +parent.getAbsolutePath()); file=new File(destfile); } return file.getAbsolutePath(); } protected void write(InputStream pin,WaveOutputFile fout)throws IOException{ int count;byte[] buffer = new byte[DefaultPhonePCMBlockSize]; while(isrunning){ count=pin.read(buffer); if(count==-1){break;} fout.write(buffer,0,count); } } private class Player extends Thread{ private boolean isplaying; private Semaphore recordBlocker; private OutputStream pout; public Player(OutputStream pout){ this.pout=pout; isplaying=true; recordBlocker = new Semaphore(0,true); } public void stopPlaying(){ if(isplaying){ isplaying=false; recordBlocker.release(); } } public void run(){ try{ String startmsg=properties.getProperty(phoneStartMsgID); String endmsg=properties.getProperty(phoneEndMsgID); int time; try{ time=Integer.parseInt(properties.getProperty(phoneTimeToRecordID)); }catch(Exception e){ time=60; } if((startmsg!=null)&&!startmsg.equals("")){ play(startmsg,pout); // play start message } if(isplaying){ for(int i=0;i<time;i++){ // block so that input thread can record x secs before we disconnect if(!isrunning){break;} recordBlocker.tryAcquire(1000,TimeUnit.MILLISECONDS); } if(isplaying){ if((endmsg!=null)&&!endmsg.equals("")){ play(endmsg,pout); // play end message } } } }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".run\n\t"+e); }finally{ if(isplaying){ isplaying=false; stopRunning(); } } } private void play(String file,OutputStream pout){ int count; AudioInputStream in = null; try{ in = AudioSystem.getAudioInputStream(new JarFile(file)); // get sound file in=AudioSystem.getAudioInputStream(pcmformat,in); // convert to pcm if necessary byte[] buffer = new byte[DefaultPhonePCMBlockSize]; while(isrunning&&isplaying&&(count=in.read(buffer))!=-1){ // read sound data and, pout.write(buffer,0,count); // write to phone output } }catch(IOException e){ System.out.println("3\b"+getClass().getName()+".play\n\t"+e); }catch(Exception e){ System.out.println("9\b"+getClass().getName()+".play\n\t"+e); e.printStackTrace(); }finally{ try{ if(in!=null){in.close();} }catch(IOException e){ System.out.println("3\b"+getClass().getName()+".play\n\t"+e); } } } } }