//package SndEnc4; // version 4: added Base64 encoding which cleaned up audio quality // version 5: added voiceChatReplay to work with voice message board. // version 6: added getCodeBase code to get URL this instance is downloaded // from. Added destroy to stop continuing thread after leaving page. /* Now you will be able to perform actions when a button is clicked to get and place text in/out a textfield and to get the state of checkboxes. This example will only let the button do actions. */ import java.awt.*; import java.applet.*; // import an extra class for the ActionListener import java.awt.event.*; import java.io.*; import javax.sound.sampled.*; import java.lang.String; import java.lang.reflect.Array; import java.lang.Integer; import java.net.*; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; //import Base64Coder; // Tells the applet you will be using the ActionListener methods. public class VoiceChat6 extends Applet implements MouseListener { boolean stopCapture = false; ByteArrayOutputStream byteArrayOutputStream; AudioFormat audioFormat; TargetDataLine targetDataLine; AudioInputStream audioInputStream; SourceDataLine sourceDataLine; boolean buttonFromJavaClicked = false; int voiceChatStatus = 0; int playStatus = 1; String msgStr = "Press & hold Voice Chat"; String passStr = ""; String lastSentVC = ""; String lastPlayedVC = ""; Button voiceChatButton; Checkbox echoCheckBox; Base64Coder base64Coder; /* Button testButton; Button testButton2; Button recordButton; Button stopButton; Button playbackButton; TextArea strTextArea; TextField strField; */ checkJavaScriptEvent evt = new checkJavaScriptEvent(); public void init() { // Now we will use the FlowLayout evt.start(); setLayout(new FlowLayout()); // Label URL_label = new Label(getCodeBase().toString()); // add(URL_label); // Label msg_label = new Label(msgStr); // add(msg_label); voiceChatButton = new Button("Voice Chat"); echoCheckBox = new Checkbox("echo", true); base64Coder = new Base64Coder(); /* testButton = new Button("Test"); testButton2 = new Button("Test2"); recordButton = new Button("Record"); stopButton = new Button("Stop"); playbackButton = new Button("Play Back"); strTextArea = new TextArea("sound data", 5, 60, 1); strField = new TextField("byte array length",50); */ add(voiceChatButton); add(echoCheckBox); voiceChatButton.addMouseListener(this); getNextVC(1);//6/14/09 DmT: find the last VC filename to set lastPlayedVC } // Here we will show the results of our actions public void paint(Graphics g) { g.setColor(Color.red); g.drawString(msgStr,10,40); } //This method captures audio input // from a microphone and saves it in // a ByteArrayOutputStream object. public void captureAudio(){ try{ //Get everything set up for // capture audioFormat = getAudioFormat(); DataLine.Info dataLineInfo = new DataLine.Info( TargetDataLine.class, audioFormat); targetDataLine = (TargetDataLine) AudioSystem.getLine( dataLineInfo); targetDataLine.open(audioFormat); targetDataLine.start(); //Create a thread to capture the // microphone data and start it // running. It will run until // the Stop button is clicked. Thread captureThread = new Thread( new CaptureThread()); captureThread.start(); } catch (Exception e) { msgStr = e.getMessage(); repaint(); }//end catch }//end captureAudio method //This method plays back the audio // data that has been saved in the // ByteArrayOutputStream public void playAudio() { try{ //Get everything set up for // playback. //Get the previously-saved data // into a byte array object. byte audioData[] = byteArrayOutputStream. toByteArray(); //Get an input stream on the // byte array containing the data InputStream byteArrayInputStream = new ByteArrayInputStream( audioData); AudioFormat audioFormat = getAudioFormat(); audioInputStream = new AudioInputStream( byteArrayInputStream, audioFormat, audioData.length/audioFormat. getFrameSize()); DataLine.Info dataLineInfo = new DataLine.Info( SourceDataLine.class, audioFormat); sourceDataLine = (SourceDataLine) AudioSystem.getLine( dataLineInfo); sourceDataLine.open(audioFormat); sourceDataLine.start(); //Create a thread to play back // the data and start it // running. It will run until // all the data has been played // back. Thread playThread = new Thread(new PlayThread()); playThread.start(); } catch (Exception e) { msgStr = e.getMessage(); repaint(); }//end catch }//end playAudio //This method creates and returns an // AudioFormat object for a given set // of format parameters. If these // parameters don't work well for // you, try some of the other // allowable parameter values, which // are shown in comments following // the declarations. private AudioFormat getAudioFormat(){ float sampleRate = 8000.0F; //8000,11025,16000,22050,44100 int sampleSizeInBits = 8;//16; //8,16 int channels = 1; //1,2 boolean signed = true; //true,false boolean bigEndian = false; //true,false return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian); }//end getAudioFormat //===================================// //Inner class to capture data from // microphone class CaptureThread extends Thread{ //An arbitrary-size temporary holding // buffer byte tempBuffer[] = new byte[10000]; public void run(){ byteArrayOutputStream = new ByteArrayOutputStream(); stopCapture = false; try{//Loop until stopCapture is set // by another thread that // services the Stop button. while(!stopCapture){ //Read data from the internal // buffer of the data line. int cnt = targetDataLine.read( tempBuffer, 0, tempBuffer.length); if(cnt > 0){ //Save data in output stream // object. byteArrayOutputStream.write( tempBuffer, 0, cnt); }//end if }//end while byteArrayOutputStream.close(); targetDataLine.close(); if(voiceChatStatus == 2){ voiceChatStatus = 3; } }catch (Exception e) { msgStr = e.getMessage(); repaint(); // System.out.println(e); // System.exit(0); }//end catch }//end run }//end inner class CaptureThread //===================================// //Inner class to play back the data // that was saved. class PlayThread extends Thread{ byte tempBuffer[] = new byte[10000]; public void run(){ try{ int cnt; //Keep looping until the input // read method returns -1 for // empty stream. while((cnt = audioInputStream. read(tempBuffer, 0, tempBuffer.length)) != -1){ if(cnt > 0){ //Write data to the internal // buffer of the data line // where it will be delivered // to the speaker. sourceDataLine.write( tempBuffer, 0, cnt); }//end if }//end while //Block and wait for internal // buffer of the data line to // empty. sourceDataLine.drain(); sourceDataLine.close(); playStatus = 0; }catch (Exception e) { msgStr = e.getMessage(); repaint(); // System.out.println(e); // System.exit(0); }//end catch }//end run }//end inner class PlayThread //===================================// class checkJavaScriptEvent extends Thread { //http://forums.sun.com/thread.jspa?threadID=508908 //this gets around the security exception caused //by javascript calling restricted function. //instead javascript calls function that merely sets a variable. public void run() { while (true) { if (buttonFromJavaClicked) { //System.out.println("OK buttonfromjava is true"); buttonFromJavaClicked = false; //fromJavaScript2(); voiceChatStart(); } if(voiceChatStatus == 0 && playStatus == 0){ getNextVC(2);// check for/get next voice chat } if(voiceChatStatus == 3 ){ msgStr = "Sending Voice Chat"; repaint(); getString(); getNextVC(3);// send voice chat voiceChatStatus = 0; } try { Thread.sleep(300);//runs every 300 ms } catch (Exception e) { msgStr = "exception in sleep: " + e.getMessage(); repaint(); } } } } //===================================// public void mouseClicked(MouseEvent mEvt){ } public void mouseEntered(MouseEvent mEvt){ } public void mouseExited(MouseEvent mEvt){ } public void mousePressed(MouseEvent mEvt){ if(mEvt.getSource() == voiceChatButton){voiceChatStart();} } public void mouseReleased(MouseEvent mEvt){ voiceChatStop(); } //===================================// // Javascript control functions (called from webpage). public void startCapture(){ buttonFromJavaClicked = true; // security exception if try to call captureAudio() directly // so instead just set a variable. // captureAudio(); //msgStr = "Recording. Press Stop to stop recording."; //repaint(); } public void stopCapture(){ //stopCapture = true; voiceChatStop(); //msgStr = "Stopped. Press Play Back button to listen to recording."; //repaint(); } public void playCapture(){ playAudio(); msgStr = "Playing recorded sound back."; repaint(); } public String getString(){ java.lang.String returnStr = ""; java.lang.Integer tempInt = 0; byte rtnBytes[] = byteArrayOutputStream. toByteArray(); try { /* int i; int len = Array.getLength(rtnBytes); for(i=0; i 1) {str = "\n" + str;} getDataStr = getDataStr + str; } input.close (); if(downloadedVC != null){ switch(getMode){ case 1: lastPlayedVC = downloadedVC; playStatus = 0; break; case 2: if(lastSentVC.equals(downloadedVC) == false ){ //getDataStr = URLDecoder.decode(getDataStr); playString(getDataStr); playStatus = 2; // strTextArea.setText("downloadedVC: '" + downloadedVC + "'\nlastSentVC: '" + lastSentVC + "'"); msgStr = "Voice Chat Received"; repaint(); } lastPlayedVC = downloadedVC; break; case 3: if(echoCheckBox.getState() == false){ lastSentVC = downloadedVC; // strTextArea.setText("lastSentVC: " + lastSentVC); } msgStr = "Voice Chat Sent"; repaint(); break; } } } catch (Exception e) { msgStr = e.getMessage(); repaint(); System.out.println(e); System.out.println(e.getMessage()); }//end catch } public void voiceChatStart(){ //buttonFromJavaClicked = true; // security exception if try to call captureAudio() directly // so instead just set a variable. // captureAudio(); if(voiceChatStatus == 0){ voiceChatStatus = 1; // startCapture(); captureAudio(); msgStr = "Recording Voice Chat."; repaint(); } } public void voiceChatStop(){ stopCapture = true; if(voiceChatStatus == 1){ voiceChatStatus = 2; msgStr = "Stopped recording Voice Chat."; repaint(); } } public void voiceChatReplay(String playThis){ lastPlayedVC = playThis; msgStr = "Setting last played to " + lastPlayedVC; repaint(); } public void destroy(){ // 6/28/09 DmT: stop currently running threads // or applet may continue to run after leaving page. // which causes annoying "echo" effect since more than one voice // chat applet is receiving sounds from the website. //checkJavaScriptEvent = null; evt = null; } }