voxforge.org
VoxForge Dev

root/Trunk/SpeechSubmission/VFSpeechSubmission/java/src/speechrecorder/CapturePlayback.java

Revision 2524, 59.9 kB (checked in by kmaclean, 3 months ago)

fix windows encoding problems with text files created during submission process. All files now set to UTF-8.

Line 
1 package speechrecorder;
2 /**
3 *
4 * Note: This is a copy of the CapturePlayback class provided in the
5 * JavaSoundDemo, but modified for use with the SpeechRecorder
6 * applet.
7 *
8 */
9
10
11 /*
12  * @(#)CapturePlayback.java     1.11    99/12/03
13  *
14  * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
15  *
16  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
17  * modify and redistribute this software in source and binary code form,
18  * provided that i) this copyright notice and license appear on all copies of
19  * the software; and ii) Licensee does not utilize the software in a manner
20  * which is disparaging to Sun.
21  *
22  * This software is provided "AS IS," without a warranty of any kind. ALL
23  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
24  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
25  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
26  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
27  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
28  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
29  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
30  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
31  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGES.
33  *
34  * This software is not designed or intended for use in on-line control of
35  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
36  * the design, construction, operation or maintenance of any nuclear
37  * facility. Licensee represents and warrants that it will not use or
38  * redistribute the Software for such purposes.
39  */
40
41
42 import java.awt.*;
43 import java.awt.event.*;
44 import java.awt.font.*;
45 import java.awt.geom.Line2D;
46 import java.io.*;
47 import java.net.URL;
48 import java.text.*;
49 import java.util.Vector;
50 import javax.sound.sampled.*;
51 import javax.swing.*;
52 import javax.swing.border.*;
53 import net.sf.postlet.UploadManager;
54 import netscape.javascript.JSObject;
55 import java.util.zip.ZipEntry;
56 import java.util.zip.ZipOutputStream;
57 import java.util.Calendar;
58 import java.util.Random;
59 import speechrecorder.License;
60 import speechrecorder.Prompts;
61 import speechrecorder.LabelLocalizer;
62 // !!!!!!
63 import speechrecorder.MultiLineLabel;
64
65 /**
66  * Capture/Playback sample.  Record audio in different formats and then playback the recorded audio.  The captured audio can  be saved either as a WAVE, AU or AIFF.  Or load an audio file for streaming playback.
67  * @version  @(#)CapturePlayback.java   1.11    99/12/03
68  * @author  Brian Lichtenwalter
69  */
70 public class CapturePlayback extends JPanel implements ActionListener, net.sf.postlet.PostletInterface {
71
72     final int bufSize = 16384;
73     public static int BUFFER_SIZE = 10240;
74     public static final String fileType = "wav";     
75     public static final int samplingRate = 48000;// jre 1.4.2 only supports max of 44100
76     public static final int samplingRateFormat = 16;     
77     public static final int numberChannels = 1;     
78    
79     AudioFormat format = new AudioFormat(samplingRate, samplingRateFormat, numberChannels, true, false);
80
81     Capture capture = new Capture();
82     Playback playback = new Playback();
83     ConvertAndUpload convertAndUpload = new ConvertAndUpload();
84     CapturePlayback capturePlayback; // Needed for referencing within the inner classes
85
86     AudioInputStream audioInputStream;
87     SamplingGraph samplingGraph;
88
89     // int numberofPrompts = 5;
90     int numberofPrompts = 10;
91     JButton [] playA = new JButton [numberofPrompts]; //creates the array, not the objects!
92     JButton [] captA = new JButton [numberofPrompts]; //creates the array, not the objects!
93     
94     JButton uploadB;
95     JButton moreInfoB;   
96     JButton aboutB;
97
98     boolean [] play_stateA = new boolean [numberofPrompts];
99     boolean [] capt_stateA = new boolean [numberofPrompts];
100
101     License licenseObject = new License();
102     String license = licenseObject.getLicense();
103     String VFlicense = licenseObject.getVFLicense();
104
105     JTextField textField;
106
107     String fileName = "untitled";
108     String errStr;
109
110     double [] durationA= new double [numberofPrompts];
111     double duration = 0;
112
113     double seconds;
114
115     long [] totalBytesWrittenA= new long [numberofPrompts];
116     long totalBytesWritten = 0L;
117      
118     File file;
119     Vector lines = new Vector();
120  
121     private File wavFile;
122     private File[] wavFileA = new File [numberofPrompts];
123  
124     private File [] uploadWavFileA = new File [numberofPrompts];
125  
126     private File promptsFile; 
127     private File readmeFile;   
128     private File licenseFile;   
129     private File licenseNoticeFile;   
130
131     JProgressBar progBar;
132     int sentBytes;
133     int totalBytes;
134     int buttonClicked;
135
136     JTextField subjectBox;
137     String subject;
138
139     String [] promptA = new String [numberofPrompts];
140     String [] promptidA = new String [numberofPrompts];;
141  
142 //  required for the PHP uploader to work properly
143     String fileFieldName = "userfile";
144 //  ############ Localized Fields ####################################   
145     JTextField usernameTextField; 
146     String usernamePanelLabel;
147     String userName;
148     String usernamePanelText;
149    
150     String copyrightName;
151     String gplAccepted;
152    
153     String pleaseSelect;
154     String notApplicable;
155    
156     String genderPanelLabel;
157     JComboBox genderChooser;       
158     String[] genderSelection;
159     String gender;
160    
161     String ageRangePanelLabel;
162     JComboBox ageRangeChooser;
163     String[] ageSelection;
164     String ageRange;
165
166     String dialectPanelLabel;
167     JComboBox dialectChooser;
168     String[] dialectSelection;
169     String dialect; 
170    
171     String microphonePanelLabel;
172     JComboBox microphoneChooser;     
173     String[] microphoneSelection;
174     String microphone; 
175    
176     String uploadText;
177     String uploadButtonLabel;
178    
179     String moreInfoText;
180     String moreInfoButtonLabel;   
181
182     String disclaimerText;
183     String aboutButtonLabel;
184    
185     String recordButton;
186     String stopButton;
187     String playButton;
188    
189     String peakWarningLabel;
190     String sampleGraphFileLabel;
191     String sampleGraphLengthLabel;
192     String sampleGraphPositionLabel;
193     String uploadingMessageLabel;
194     String uploadCompletedMessageLabel;
195 //  ############ Localized Fields ####################################   
196     URL endPageURL;
197     URL helpPageURL;
198     URL destinationURL;
199     String language;
200     String endpage;
201     String helppage;
202     String cookie;
203  
204         String tempdir = getTempDir();
205 public CapturePlayback(String language, URL destinationURL,
206         URL endPageURL, URL helpPageURL, String cookie) {       
207 //  ############ Localized Fields ####################################
208         // !!!!!!
209         this.language = language;
210         // this.language = "NL"; // for testing
211         // !!!!!!
212         System.err.println("CapturePlayback Language:" + this.language + ":"); // debug
213
214     LabelLocalizer labels = new LabelLocalizer(this.language);
215     usernamePanelLabel = labels.getUsernamePanelLabel();
216     usernamePanelText = labels.getUsernamePanelText();
217    
218     copyrightName = labels.getCopyrightName();
219     gplAccepted = labels.getGplAccepted();
220    
221     pleaseSelect = labels.getPleaseSelect();
222     notApplicable = labels.getNotApplicable();
223    
224     genderPanelLabel = labels.getGenderPanelLabel();
225     genderSelection = labels.getGenderSelection();
226     gender = notApplicable; // default selection
227     
228     ageRangePanelLabel = labels.getAgeRangePanelLabel();
229     ageSelection = labels.getAgeSelection();
230     ageRange = notApplicable; // default selection
231
232     dialectPanelLabel = labels.getDialectPanelLabel();
233     dialectSelection = labels.getDialectSelection();
234     dialect = notApplicable;  // default selection
235     
236     microphonePanelLabel = labels.getMicrophonePanelLabel();
237     microphoneSelection = labels.getMicrophoneSelection();
238     microphone = notApplicable;  // default selection
239     
240     uploadText = labels.getUploadText();
241     uploadButtonLabel = labels.getUploadButtonLabel();
242    
243     moreInfoText = labels.getMoreInfoText();
244     moreInfoButtonLabel = labels.getMoreInfoButtonLabel();   
245
246     disclaimerText = labels.getDisclaimerText() ;
247     aboutButtonLabel = labels.getAboutButtonLabel();
248    
249     recordButton = labels.getRecordButton();
250     stopButton = labels.getStopButton();
251     playButton = labels.getPlayButton();
252    
253     peakWarningLabel = labels.getPeakWarningLabel();
254     sampleGraphFileLabel = labels.getSampleGraphFileLabel();
255     sampleGraphLengthLabel = labels.getSampleGraphLengthLabel();
256     sampleGraphPositionLabel = labels.getSampleGraphPositionLabel();
257    
258     uploadingMessageLabel = labels.getUploadingMessageLabel();
259     uploadCompletedMessageLabel = labels.getUploadCompletedMessageLabel();
260 //  ############ Localized Fields #################################### 
261    // if (promptA[0] == null || promptA[0].length() == 0) {
262         //Prompts prompts = new Prompts(numberofPrompts, this.language);
263         //String [][] promptArray = prompts.getPrompts();
264         
265     // !!!!!!
266         String [][] promptArray = (new Prompts(numberofPrompts,this.language)).getPrompts();
267     for (int i = 0; i < numberofPrompts; i++) {
268         this.promptidA [i] = promptArray[0][i];
269         this.promptA [i] = promptArray[1][i];
270         // System.err.println("Prompts:" + this.promptidA[i] + ":"+ this.promptA [i]);
271     }
272    
273 //  this.language = language;
274     this.destinationURL = destinationURL;
275     this.endPageURL = endPageURL;
276     this.helpPageURL = helpPageURL;
277     this.cookie = cookie;
278    
279     capturePlayback = this;
280
281         // Create WAV files to hold recordings
282         try {
283         for (int i = 0; i < numberofPrompts; i++) {
284                 wavFileA [i] = new File(tempdir + "wavFile" + i + ".wav");
285                 wavFileA[i].deleteOnExit();
286         }
287         for (int i = 0; i < numberofPrompts; i++) {
288                         uploadWavFileA[i] = new File(tempdir + this.promptidA [i] + ".wav");
289                         uploadWavFileA[i].deleteOnExit();
290         }
291                 promptsFile = new File(tempdir + "prompts.txt");                       
292                 promptsFile.deleteOnExit();             
293                 readmeFile = new File(tempdir + "readme.txt");                 
294                 readmeFile.deleteOnExit();             
295                 licenseFile = new File(tempdir + "GPL_license.txt");                   
296                 licenseFile.deleteOnExit();                     
297                 licenseNoticeFile = new File(tempdir + "license.txt"); 
298                 licenseFile.deleteOnExit();     
299         } catch (Exception e) {
300                 System.err.println("Unable to create WAV cache file for storing audio\n" + e);
301                 return;
302         }
303     for (int i = 0; i < numberofPrompts; i++) {                 
304                 System.err.println("CapturePlayback's WAV file for recording uploadWavFile" + i + "is:" + uploadWavFileA[i]);
305     }
306
307 //  ############ GUI Display ####################################   
308                 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
309         EmptyBorder eb = new EmptyBorder(5,5,5,5);
310         SoftBevelBorder sbb = new SoftBevelBorder(SoftBevelBorder.LOWERED);
311
312         JPanel p2 = new JPanel();
313         p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
314 //      ############ User name ####################################             
315 //      userName is read when user clicks Upload
316         JPanel usernamePanel = new JPanel();
317         usernamePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
318         usernamePanel.add(new JLabel(usernamePanelLabel));
319         usernamePanel.add(usernameTextField = new JTextField(20));
320         usernamePanel.add(new JLabel(usernamePanelText));     
321         p2.add(usernamePanel); 
322 // ############ Gender ####################################             
323         JPanel genderPanel = new JPanel();
324         genderPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); 
325         genderPanel.add(new JLabel(genderPanelLabel));
326         genderPanel.add(genderChooser = new JComboBox(genderSelection));
327         genderChooser.setSelectedIndex(0);       
328         genderChooser.addActionListener(new ActionListener(){
329                  public void actionPerformed(ActionEvent e){
330                      gender = (String)genderChooser.getSelectedItem();
331                  }
332                 });
333         p2.add(genderPanel);
334 // ############ Age Range ####################################             
335         JPanel ageRangePanel = new JPanel();
336         ageRangePanel.setLayout(new FlowLayout(FlowLayout.CENTER)); 
337         ageRangePanel.add(new JLabel(ageRangePanelLabel));
338         ageRangePanel.add(ageRangeChooser = new JComboBox(ageSelection));
339         ageRangeChooser.setSelectedIndex(0);         
340         ageRangeChooser.addActionListener(new ActionListener(){
341                  public void actionPerformed(ActionEvent e){
342                      ageRange = (String)ageRangeChooser.getSelectedItem();
343                  }
344                 });
345         p2.add(ageRangePanel);
346 //      ############ Pronunciation Dialect: ####################################       
347         JPanel dialectPanel = new JPanel();
348         dialectPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
349         dialectPanel.add(new JLabel(dialectPanelLabel));
350         dialectPanel.add(dialectChooser = new JComboBox(dialectSelection));
351         dialectChooser.setSelectedIndex(0); 
352         dialectChooser.addActionListener(new ActionListener(){
353                     public void actionPerformed(ActionEvent e){
354                         dialect = (String)dialectChooser.getSelectedItem();
355                     }
356             });
357         p2.add(dialectPanel);
358 //      ############ Microphone Type: ####################################       
359         JPanel microphonePanel = new JPanel();
360         microphonePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
361         microphonePanel.add(new JLabel(microphonePanelLabel));
362         microphonePanel.add(microphoneChooser = new JComboBox(microphoneSelection));
363         microphoneChooser.setSelectedIndex(0); 
364  //       microphoneChooser.setEditable(true); // user can add whatever they want ...
365         microphoneChooser.addActionListener(new ActionListener(){
366                  public void actionPerformed(ActionEvent e){
367                      microphone = (String)microphoneChooser.getSelectedItem();
368                  }
369                 });
370         p2.add(microphonePanel);
371         //############ Prompt container ####################################   
372         JPanel promptsContainer = new JPanel();
373         promptsContainer.setLayout(new FlowLayout(FlowLayout.CENTER));
374         Color voxforgeColour    = new Color(197, 216, 234);
375          int startPromptCount = 0;
376         // !!!!!!
377         //int promptsPerPane = 10;
378         int promptsPerPane = numberofPrompts;
379         // !!!!!!
380 //      ############ Prompts panel ####################################         
381         JPanel prompts = new JPanel();
382         prompts.setLayout(new BoxLayout(prompts, BoxLayout.Y_AXIS));
383         //Color voxforgeColour  = new Color(197, 216, 234);
384         prompts.setBorder(BorderFactory.createLineBorder (voxforgeColour, 3));
385    
386         int maxWidth = 40;
387
388         //JPanel promptPanelA[] = new JPanel[numberofPrompts];
389         //JPanel promptInnerPanelA[] = new JPanel[numberofPrompts];   
390         JPanel promptPanelA[] = new JPanel[promptsPerPane];
391         JPanel promptInnerPanelA[] = new JPanel[promptsPerPane];
392         for (int i = startPromptCount; i < promptsPerPane; i++) {
393                 promptPanelA[i] = new JPanel();
394                 promptPanelA[i].setLayout(new FlowLayout(FlowLayout.LEFT));   
395                 promptInnerPanelA [i]= new JPanel();
396                 promptInnerPanelA[i].setBorder(BorderFactory.createLineBorder (voxforgeColour, 1));
397                 //promptInnerPanelA[i].add(new MultiLineLabel(promptPanelA[i], i+":"+this.promptA[i], maxWidth));
398                 promptInnerPanelA[i].add(new MultiLineLabel(promptPanelA[i], this.promptA[i], maxWidth));
399                 promptPanelA[i].add(promptInnerPanelA[i]);
400                 playA[i] = addButton(playButton, promptPanelA[i], false);
401                 if (i==0) {
402                         captA[i] = addButton(recordButton, promptPanelA[i], true); // only turn on first record button
403                 } else {
404                         captA[i] = addButton(recordButton, promptPanelA[i], false);
405                 }
406                 prompts.add(promptPanelA[i]); 
407         }
408         //############ Prompt container ####################################   
409         promptsContainer.add(prompts);
410         p2.add(promptsContainer);
411
412 //      ############ Sampling Graph ####################################         
413         JPanel samplingPanel = new JPanel(new BorderLayout());
414         eb = new EmptyBorder(10,20,5,20);
415         samplingPanel.setBorder(new CompoundBorder(eb, sbb));
416         samplingPanel.add(samplingGraph = new SamplingGraph());
417         p2.add(samplingPanel);
418 //      ############ Upload Text ####################################             
419         JPanel uploadTextPanel = new JPanel();
420         uploadTextPanel.add(new JLabel(uploadText));               
421         p2.add(uploadTextPanel);
422 //              ############ Upload ####################################         
423          JPanel uploadButtonPanel = new JPanel();
424          uploadButtonPanel.setBorder(new EmptyBorder(5,0,5,0));
425          uploadB = addButton(uploadButtonLabel, uploadButtonPanel, false); // upload all submissions
426          p2.add(uploadButtonPanel);
427 //              ############ Upload Progress bar ####################################
428          progBar = new JProgressBar();
429          progBar.setStringPainted(false);
430          progBar.setString("Ready");
431          //progBar.setVisible(false);
432          p2.add(progBar);               
433 //              ############ More Information Button ####################################         
434          JPanel moreInfoButtonPanel = new JPanel();
435          moreInfoButtonPanel.add(new JLabel(moreInfoText));
436          moreInfoB = addButton(moreInfoButtonLabel, moreInfoButtonPanel, true);
437          p2.add(moreInfoButtonPanel);   
438 //              ############ Disclaimer #################################### 
439          JPanel DisclaimerPanel = new JPanel();
440          DisclaimerPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
441          JPanel DisclaimerInnerPanel = new JPanel();
442          DisclaimerInnerPanel.add(new JLabel(disclaimerText));
443          aboutB = addButton(aboutButtonLabel, DisclaimerInnerPanel, true);
444          DisclaimerInnerPanel.setBorder(BorderFactory.createLineBorder (voxforgeColour, 3));
445          DisclaimerPanel.add(DisclaimerInnerPanel);       
446          p2.add(DisclaimerPanel);
447 //#########################################################################   
448          add(p2);
449     }
450
451     public void open() { }
452
453     private String getTempDir() {
454         String tempdir=null;
455                 try {
456                 File dir=File.createTempFile("VF-dir",null);
457                 dir.delete();
458                 dir.mkdir();
459                 tempdir = dir.toString();
460                 if ( !(tempdir.endsWith("/") || tempdir.endsWith("\\")) )
461                            tempdir = tempdir + System.getProperty("file.separator");
462
463                 } catch (Exception e) {
464                         System.err.println("Unable to create temp directory\n" + e);
465                 }
466                 return tempdir;
467     }
468
469     public void close() {
470         if (playback.thread != null) {
471             for (int i = 0; i < numberofPrompts; i++) {
472                 playA[i].doClick(0);
473             }
474         }
475         if (capture.thread != null) {
476             for (int i = 0; i < numberofPrompts; i++) {
477                 captA[i].doClick(0);
478             }
479         }
480     }
481
482     private JButton addButton(String name, JPanel p, boolean state) {
483         JButton b = new JButton(name);
484         b.addActionListener(this);
485         p.add(b);
486         b.setEnabled(state);
487         return b;
488     }
489    
490     private void setButtonsOff() {
491         for (int i = 0; i < numberofPrompts; i++) {
492                 playA[i].setEnabled(false);
493                 captA[i].setEnabled(false);
494             //System.err.println("setButtonsOff" + "playA" + i + playA[i].isEnabled()+ ";captA" + i + captA[i].isEnabled());// !!!!!!
495         }
496     }
497    
498     private void saveButtonState() {
499         for (int i = 0; i < numberofPrompts; i++) {
500                 // System.err.println("playA[i]" +  i ); // !!!!!!
501                 if (playA[i].isEnabled()) {play_stateA [i] = true;} else {play_stateA [i] = false;}
502                 if (captA[i].isEnabled()) {capt_stateA [i] = true;} else {capt_stateA [i] = false;}
503             //System.err.println("saveButtonState" + "playA" + i + playA[i].isEnabled()+ ";captA" + i + captA[i].isEnabled());// !!!!!!
504         }
505     }
506    
507     private void restoreButtonState() {
508         for (int i = 0; i < numberofPrompts; i++) {
509                 if (play_stateA[i]) {playA[i].setEnabled(true);} else {playA[i].setEnabled(false);}
510                 if (capt_stateA[i]) {captA[i].setEnabled(true);} else {captA[i].setEnabled(false);}
511             // System.err.println("restoreButtonState" + "playA" + i + playA[i].isEnabled()+ ";captA" + i + captA[i].isEnabled());// !!!!!!
512         }
513     }
514     // !!!!!!
515     /* public boolean equals(Object obj) {
516         for (int i = 0; i < numberofPrompts; i++) {
517             if (obj.equals(playA[i])) {
518                 return (this == obj);
519             }
520         }
521         return (this == obj);
522         } */
523     // !!!!!!
524     public void actionPerformed(ActionEvent e) {
525         Object obj = e.getSource();
526          
527 // ################### Play #######################################       
528         // !!!!!!
529         for (int i = 0; i < numberofPrompts; i++) {
530                 //System.err.println("playA[i]" +  i ); // !!!!!!
531             if (obj.equals(playA[i])) {
532                 if (playA[i].getText().startsWith(playButton)) {
533                     wavFile = wavFileA[i];     
534                     duration = durationA[i];
535                     totalBytesWritten = totalBytesWrittenA[i];
536                     System.err.println("=== Play " + (i+1) + " ===");// !!!!!!
537                     playback.start();
538                         System.err.println("duration:" + duration);
539                     fileName = promptidA[i]; 
540                     samplingGraph.start();
541                         saveButtonState();
542                         setButtonsOff();
543                     captA[i].setEnabled(false);
544                     playA[i].setEnabled(true);
545                     playA[i].setText(stopButton);
546                 } else {
547                     playback.stop();
548                     samplingGraph.stop();
549                         restoreButtonState();
550                     captA[i].setEnabled(true);
551                     playA[i].setText(playButton);
552                 }
553             }
554         }
555  
556             for (int x = 0; x < numberofPrompts; x++) {
557                 if (obj.equals(captA[x])) {
558                     if (captA[x].getText().startsWith(recordButton)) {
559                         file = null;
560                         wavFile = wavFileA[x]; 
561                                 System.err.println("=== Record " + (x+1) + " ==="); // !!!!!!
562                         capture.start(uploadWavFileA[x]); 
563                         fileName = promptidA[x];
564                         samplingGraph.start();
565                         saveButtonState();
566                         setButtonsOff();
567                         captA[x].setEnabled(true);   
568                         captA[x].setText(stopButton);
569                         moreInfoB.setEnabled(false); 
570                         aboutB.setEnabled(false);
571                     } else {
572                         lines.removeAllElements(); 
573                         capture.stop();
574                         totalBytesWrittenA[x] = totalBytesWritten; // !!!!!!
575                         durationA[x]= totalBytesWritten / (double) (format.getSampleRate() * format.getSampleSizeInBits()/ 8);
576                                 System.err.println("duration1:" + durationA[x]);
577                         samplingGraph.stop();
578                         restoreButtonState();
579                         playA[x].setEnabled(true);
580                         captA[x].setText(recordButton);
581                         moreInfoB.setEnabled(true); 
582                         aboutB.setEnabled(true);
583                         captA[x].setEnabled(true);
584                         if (x < numberofPrompts-1) {
585                                 captA[x+1].setEnabled(true);
586                         }
587                         if (x == numberofPrompts-1) {
588                                 uploadB.setEnabled(true);
589                         }
590                     }
591                 }
592             }
593
594 //          ################### Upload #######################################               
595             if (obj.equals(uploadB)) {
596                 for (int i = 0; i < numberofPrompts; i++) {
597                         playA[i].setEnabled(false);
598                     captA[i].setEnabled(false);
599                 }
600                uploadB.setEnabled(false);               
601                 try {
602                    usernameTextField.selectAll();
603                    userName = usernameTextField.getText();
604                    // see   java.util.regex.Pattern
605                    //      \w   A word character: [a-zA-Z_0-9]
606                    //      \W   A non-word character: [^\w]
607                            userName = (usernameTextField.getText().replaceAll("\\W",""));
608                    if (userName.length() == 0 ) {
609                        userName = "anonymous";
610                    } else {
611                                    if (userName.length() > 40 ) {
612                                            userName = userName.substring(0,40);
613                            }
614                    }
615                 } catch (NullPointerException ex) {
616                userName = "anonymous";
617             }
618            convertAndUpload.start();
619         }
620 //      ################### More Information #######################################     
621         else if (obj.equals(moreInfoB)) {
622              JTextArea textArea = new JTextArea(license);
623              textArea.setLineWrap(true);
624              textArea.setWrapStyleWord(true);
625              JScrollPane areaScrollPane = new JScrollPane(textArea);
626              areaScrollPane.setVerticalScrollBarPolicy(
627                         JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
628              areaScrollPane.setPreferredSize(new Dimension(600, 600));
629  
630             JOptionPane.showMessageDialog(this, areaScrollPane,
631                     "More info on Copyright and GPL license", JOptionPane.PLAIN_MESSAGE);
632         }
633 //      ################### About #######################################
634         else if (obj.equals(aboutB)) {
635             JTextArea textArea = new JTextArea(VFlicense);
636             textArea.setLineWrap(true);
637             textArea.setWrapStyleWord(true);
638             JScrollPane areaScrollPane = new JScrollPane(textArea);
639             areaScrollPane.setVerticalScrollBarPolicy(
640                         JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
641             areaScrollPane.setPreferredSize(new Dimension(600, 600));
642  
643            JOptionPane.showMessageDialog(this, areaScrollPane,
644                    "About VoxForge Speech Submission Application", JOptionPane.PLAIN_MESSAGE);
645        }
646     }
647
648     public void createAudioInputStream(File file, boolean updateComponents) {
649         if (file != null && file.isFile()) {
650             try {
651                 this.file = file;
652                 errStr = null;
653                 audioInputStream = AudioSystem.getAudioInputStream(file);
654                 fileName = file.getName();
655                 long milliseconds = (long)((audioInputStream.getFrameLength() * 1000) / audioInputStream.getFormat().getFrameRate());
656                 duration = milliseconds / 1000.0;
657                 // !!!!!!
658                         System.err.println("createAudioInputStream duration:" + duration);
659                 // !!!!!!
660                 if (updateComponents) {
661 //DEL                    formatControls.setFormat(audioInputStream.getFormat());
662                     samplingGraph.createWaveForm(null);
663                 }
664             } catch (Exception ex) {
665                 reportStatus(ex.toString());
666             }
667         } else {
668             reportStatus("Audio file required.");
669         }
670     }
671
672
673    public void saveToFile(String name, AudioFileFormat.Type fileType) {
674
675         if (audioInputStream == null) {
676             reportStatus("No loaded audio to save");
677             return;
678         } else if (file != null) {
679             createAudioInputStream(file, false);
680         }
681
682         // reset to the beginning of the captured data
683         try {
684             audioInputStream.reset();
685         } catch (Exception e) {
686             reportStatus("Unable to reset stream " + e);
687             return;
688         }
689
690         File file = new File(fileName = name);
691         try {
692             if (AudioSystem.write(audioInputStream, fileType, file) == -1) {
693                 throw new IOException("Problems writing to file");
694             }
695         } catch (Exception ex) { reportStatus(ex.toString()); }
696         samplingGraph.repaint();
697     }
698    
699    public void saveToFile(File file, AudioFileFormat.Type fileType) {
700
701        if (audioInputStream == null) {
702            reportStatus("No loaded audio to save");
703            return;
704        } else if (file != null) {
705            createAudioInputStream(file, false);
706        }
707
708        // reset to the beginning of the captured data
709        try {
710            audioInputStream.reset();
711        } catch (Exception e) {
712            reportStatus("Unable to reset stream " + e);
713            return;
714        }
715
716  //      File file = new File(fileName = name);
717        try {
718            if (AudioSystem.write(audioInputStream, fileType, file) == -1) {
719                throw new IOException("Problems writing to file");
720            }
721        } catch (Exception ex) { reportStatus(ex.toString()); }
722        samplingGraph.repaint();
723    }
724    
725     private void reportStatus(String msg) {
726         if ((errStr = msg) != null) {
727             System.out.println(errStr);
728             samplingGraph.repaint();
729         }
730     }
731
732
733     /**
734      * Write data to the OutputChannel.
735      */
736     public class Playback implements Runnable {
737
738         SourceDataLine line;
739         Thread thread;
740
741         public void start() {
742             errStr = null;
743             thread = new Thread(this);
744             thread.setName("Playback");
745             thread.start();
746         }
747      
748         public void stop() {
749             thread = null;
750         }
751        
752         private void shutDown(String message) {
753             if ((errStr = message) != null) {
754                 System.err.println(errStr);
755                 samplingGraph.repaint();
756             }
757             if (thread != null) {
758                 thread = null;
759                 samplingGraph.stop();
760                 for (int i = 0; i < numberofPrompts; i++) {
761                         if (playA[i].getText().startsWith(stopButton)) { //play button gets set to "Stop" after play is pressed
762                                 captA[i].setEnabled(true);
763                         }
764                 }
765               for (int i = 0; i < numberofPrompts; i++) {
766                   playA[i].setText(playButton);
767               }
768             }
769         }
770
771         public void run() {
772                         getAudioInputStream();
773