/* 
 * Created on 2004/12/05 
 * Author aki@www.xucker.jpn.org 
 * License Apache2.0 or Common Public License 
 */ 
package org.jpn.xucker.repeatrecorder; 
 
 
 
import java.util.Date; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Vector; 
 
import org.apache.commons.io.FileUtils; 
import org.apache.commons.lang.SystemUtils; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.eclipse.swt.SWT; 
import org.eclipse.swt.dnd.DND; 
import org.eclipse.swt.dnd.DropTarget; 
import org.eclipse.swt.dnd.DropTargetAdapter; 
import org.eclipse.swt.dnd.DropTargetEvent; 
import org.eclipse.swt.dnd.FileTransfer; 
import org.eclipse.swt.dnd.Transfer; 
import org.eclipse.swt.events.MouseEvent; 
import org.eclipse.swt.events.MouseListener; 
import org.eclipse.swt.events.SelectionEvent; 
import org.eclipse.swt.events.SelectionListener; 
import org.eclipse.swt.events.ShellEvent; 
import org.eclipse.swt.events.ShellListener; 
import org.eclipse.swt.graphics.Color; 
import org.eclipse.swt.graphics.Image; 
import org.eclipse.swt.layout.RowData; 
import org.eclipse.swt.layout.RowLayout; 
import org.eclipse.swt.program.Program; 
import org.eclipse.swt.widgets.Button; 
import org.eclipse.swt.widgets.Canvas; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.FileDialog; 
import org.eclipse.swt.widgets.Label; 
import org.eclipse.swt.widgets.MessageBox; 
import org.eclipse.swt.widgets.Shell; 
import org.jpn.xucker.commons.audio.AudioStopper; 
import org.jpn.xucker.commons.audio.JavaSoundAudioPlayer; 
import org.jpn.xucker.commons.util.ApplicationUtil; 
import org.jpn.xucker.snacksoundtoolkit.ESPS; 
import org.jpn.xucker.snacksoundtoolkit.ESPSParser; 
import org.jpn.xucker.snacksoundtoolkit.PitchCanvas; 
 
import com.sun.imageio.plugins.png.PNGImageWriter; 
import com.sun.imageio.plugins.png.PNGImageWriterSpi; 
 
import java.io.BufferedWriter; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
 
import javax.imageio.stream.FileImageOutputStream; 
import javax.sound.sampled.AudioFileFormat; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.TargetDataLine; 
 
import java.awt.AWTException; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.image.BufferedImage; 
 
 
 
public class RepeatRecorder implements ShellListener{ 
  /** 
   * @param shell 
   */ 
   
 
  Shell shell; 
   
 
  private static boolean sm_bDebug=true; 
   
  File deleteFile; 
 
  public static void out(String text){ 
      System.out.println(text); 
  } 
   
   
  private boolean doplay=false; 
   
  private File currentFile; 
   
  private RepeatRecorderUI ui; 
   
  private File applicationBaseDir; 
   
private double version=0.1; 
  private String HOMEPAGE_URL="http://www.xucker.jpn.org/product/repeatrecorder.html"; 
    private String APP_NAME="RepeatRecorder"; 
 
     
    RepeatRecorderPreference preference; 
 
    private String confFileName="repeat_recorder_conf.xml"; 
    List controledObjectList=new Vector(); 
     
     
    
     
   public static Log log=LogFactory.getLog(RepeatRecorder.class); 
   
  //  public static Logger log=Logger.getLogger("name"); 
     
     
  public RepeatRecorder(Shell shell) { 
      //for log 
       
      // 
      //menu 
      RepeatRecorderMenu menu=new RepeatRecorderMenu(shell); 
      menu.setExecuteObject(this); 
       
      // 
      File confFile=ApplicationUtil.searchFileAroundClass(confFileName); 
      if(confFile==null){ 
           
          MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); 
          box.setText("エラー"); 
          box.setMessage("設定ファイル "+confFileName+"\r\nがありません。"); 
          //int result=box.open(); 
          //never use result int,for PMD 
          box.open(); 
          shell.close(); 
          return; 
      }else{ 
      applicationBaseDir=confFile.getParentFile();     
      } 
       
      shell.addShellListener(this); 
      shell.setText(APP_NAME); 
                                                
      shell.setImage(new Image(Display.getCurrent(),this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/icon.png"))); 
    this.shell=shell; 
     
    shell.setBounds(5,5,644,182); 
    RowLayout layout=new RowLayout(); 
    shell.setLayout(layout); 
     
 
     ui=new RepeatRecorderUI(this,shell); 
     controledObjectList.add(ui); 
     preference=new RepeatRecorderPreference(); 
     controledObjectList.add(preference); 
      
     ui.setSelection("imgShow",true); 
     ui.setSelection("pitchShow",true); 
      
     preference.setSelection("imgShow",true); 
     preference.setSelection("pitchShow",true); 
  } 
   
 
  public static class RepeatRecorderUI implements ControledObject ,MouseListener,SelectionListener{ 
      private Button recordButton; 
      private Button exportPitchButton; 
 
      private Button pitchSaveCheckButton; 
 
      private Button pitchShowCheckButton; 
 
      private Button imgShowCheckButton; 
       
      private Image recIcon; 
 
      private Image stopIcon; 
 
        public Image getDoPlayIcon() { 
            return doPlayIcon; 
        } 
        public void setDoPlayIcon(Image doPlayIcon) { 
            this.doPlayIcon = doPlayIcon; 
        } 
        public Button getExportImgButton() { 
            return exportImgButton; 
        } 
        public void setExportImgButton(Button exportImgButton) { 
            this.exportImgButton = exportImgButton; 
        } 
        public Button getExportPitchButton() { 
            return exportPitchButton; 
        } 
        public void setExportPitchButton(Button exportPitchButton) { 
            this.exportPitchButton = exportPitchButton; 
        } 
        public Button getExportWavButton() { 
            return exportWavButton; 
        } 
        public void setExportWavButton(Button exportWavButton) { 
            this.exportWavButton = exportWavButton; 
        } 
        public Button getImgSaveCheckButton() { 
            return imgSaveCheckButton; 
        } 
        public void setImgSaveCheckButton(Button imgSaveCheckButton) { 
            this.imgSaveCheckButton = imgSaveCheckButton; 
        } 
        public Button getImgShowCheckButton() { 
            return imgShowCheckButton; 
        } 
        public void setImgShowCheckButton(Button imgShowCheckButton) { 
            this.imgShowCheckButton = imgShowCheckButton; 
        } 
        public PitchCanvas getPitchCanvas() { 
            return pitchCanvas; 
        } 
        public void setPitchCanvas(PitchCanvas pitchCanvas) { 
            this.pitchCanvas = pitchCanvas; 
        } 
        public Button getPitchSaveCheckButton() { 
            return pitchSaveCheckButton; 
        } 
        public void setPitchSaveCheckButton(Button pitchSaveCheckButton) { 
            this.pitchSaveCheckButton = pitchSaveCheckButton; 
        } 
        public Button getPitchShowCheckButton() { 
            return pitchShowCheckButton; 
        } 
        public void setPitchShowCheckButton(Button pitchShowCheckButton) { 
            this.pitchShowCheckButton = pitchShowCheckButton; 
        } 
        public Button getPlayButton() { 
            return playButton; 
        } 
        public void setPlayButton(Button playButton) { 
            this.playButton = playButton; 
        } 
        public Image getRecIcon() { 
            return recIcon; 
        } 
        public void setRecIcon(Image recIcon) { 
            this.recIcon = recIcon; 
        } 
        public Button getRecordButton() { 
            return recordButton; 
        } 
        public void setRecordButton(Button recordButton) { 
            this.recordButton = recordButton; 
        } 
        public Image getStopIcon() { 
            return stopIcon; 
        } 
        public void setStopIcon(Image stopIcon) { 
            this.stopIcon = stopIcon; 
        } 
        public Image getStopPlayIcon() { 
            return stopPlayIcon; 
        } 
        public void setStopPlayIcon(Image stopPlayIcon) { 
            this.stopPlayIcon = stopPlayIcon; 
        } 
        public Button getWavSaveCheckButton() { 
            return wavSaveCheckButton; 
        } 
        public void setWavSaveCheckButton(Button wavSaveCheckButton) { 
            this.wavSaveCheckButton = wavSaveCheckButton; 
        } 
      private Button wavSaveCheckButton; 
      private Button imgSaveCheckButton; 
       
      private Image doPlayIcon; 
 
      private Image stopPlayIcon; 
 
      private Button playButton; 
 
      private Button exportImgButton; 
      private Button exportWavButton; 
 
      private PitchCanvas pitchCanvas; 
       
      private Map widgetMap=new HashMap(); //not use yet. 
       
     
      private RepeatRecorder recorder; 
      public RepeatRecorderUI(RepeatRecorder recorder,Shell shell){ 
      this.recorder=recorder; 
      //押してる間だけ録音 
  recordButton=new Button(shell,SWT.NULL); 
  recordButton.setToolTipText("押してる間だけ録音します"); 
 
  recIcon = new Image(Display.getCurrent(),this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/rec.png")); 
  recordButton.setImage(recIcon); 
 
  stopIcon = new Image(Display.getCurrent(),this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/rec_stop.png")); 
  recordButton.setImage(stopIcon); 
 
 
 
//  recordButton.addSelectionListener(this); 
  recordButton.addMouseListener(this); 
  RowData recordButton_data=new RowData(); 
  recordButton.setLayoutData(recordButton_data); 
 
  playButton = new Button(shell,SWT.NULL); 
  doPlayIcon = new Image(Display.getCurrent(),this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/doplay.png")); 
  stopPlayIcon = new Image(Display.getCurrent(),this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/stopplay.png")); 
  playButton.setImage(stopPlayIcon); 
  playButton.setEnabled(false); 
  playButton.addSelectionListener(this); 
 
  Canvas canvas=new Canvas(shell,SWT.NULL); 
  RowData canvasLayout=new RowData(); 
  canvasLayout.width=220; 
  canvas.setLayoutData(canvasLayout); 
  canvas.setLayout(new RowLayout()); 
   
  pitchSaveCheckButton = new Button(canvas,SWT.CHECK); 
  pitchSaveCheckButton.setText("save pitch"); 
  pitchSaveCheckButton.addSelectionListener(this); 
 
  imgSaveCheckButton = new Button(canvas,SWT.CHECK); 
  imgSaveCheckButton.setText("save img"); 
  imgSaveCheckButton.addSelectionListener(this); 
   
  wavSaveCheckButton = new Button(canvas,SWT.CHECK); 
  wavSaveCheckButton.setText("save wav"); 
  wavSaveCheckButton.addSelectionListener(this); 
 
 
  pitchShowCheckButton = new Button(canvas,SWT.CHECK); 
  pitchShowCheckButton.setForeground(new Color(null,64,64,64)); 
  pitchShowCheckButton.setText("show pitch"); 
  pitchShowCheckButton.addSelectionListener(this); 
 
  imgShowCheckButton = new Button(canvas,SWT.CHECK); 
  imgShowCheckButton.setForeground(new Color(null,64,64,64)); 
  imgShowCheckButton.setText("show img"); 
  imgShowCheckButton.addSelectionListener(this); 
 
  Label tmpLabel=new Label(shell,SWT.NULL); 
  RowData tmpData=new RowData(); 
  tmpData.width=70; 
  tmpLabel.setLayoutData(tmpData); 
 
 
 
  exportPitchButton = new Button(shell,SWT.NULL); 
  exportPitchButton.setImage(new Image(null,this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/exppitch.png"))); 
  exportPitchButton.addSelectionListener(this); 
 
  exportWavButton = new Button(shell,SWT.NULL); 
  exportWavButton.setImage(new Image(null,this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/expwav.png"))); 
  exportWavButton.addSelectionListener(this); 
   
  exportImgButton = new Button(shell,SWT.NULL); 
  exportImgButton.setImage(new Image(null,this.getClass().getClassLoader().getResourceAsStream("org/jpn/xucker/repeatrecorder/resource/expimg.png"))); 
  exportImgButton.addSelectionListener(this); 
 
  pitchCanvas = new PitchCanvas(shell); 
  RowData pitchData=new RowData(); 
  pitchData.height=80; 
  pitchData.width=shell.getClientArea().width-6; 
  pitchCanvas.setLayoutData(pitchData); 
 
 
  Transfer[] types = new Transfer[] {FileTransfer.getInstance()}; 
 
  int operations = DND.DROP_MOVE | DND.DROP_COPY ; 
 
 
 
 
    DropTarget target = new DropTarget (pitchCanvas, operations); 
    target.setTransfer(types); 
 
    target.addDropListener(new DropMonitor(recorder)); 
      } 
        /* (non-Javadoc) 
         * @see org.jpn.xucker.repeatrecorder.ControledObject#setSelection(java.lang.String, boolean) 
         */ 
        public void setSelection(String key, boolean value) { 
            if(key.equals("saveWav")){ 
               wavSaveCheckButton.setSelection(value); 
          } 
          else if(key.equals("saveImg")){ 
               imgSaveCheckButton.setSelection(value); 
          } 
          else if(key.equals("savePitch")){ 
               pitchSaveCheckButton.setSelection(value); 
          } 
          else if(key.equals("pitchShow")){ 
               pitchShowCheckButton.setSelection(value); 
          }else if(key.equals("imgShow")){ 
               imgShowCheckButton.setSelection(value); 
          } 
        } 
        /* (non-Javadoc) 
         * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) 
         */ 
        public void mouseDoubleClick(MouseEvent e) { 
            // TODO Auto-generated method stub 
             
        } 
         
         
        public void mouseDown(MouseEvent e) { 
            // TODO Auto-generated method stub 
           recorder.do_recordButton(); 
        } 
 
        /* (non-Javadoc) 
         * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) 
         */ 
        public void mouseUp(MouseEvent e) { 
            recorder.do_stop(); 
             
        } 
         
      public void widgetSelected(SelectionEvent event) { 
        Object target=event.getSource(); 
           if(target==null){ 
             //maybe not happen. 
             System.out.println("target==null"); 
             } 
           //押してる間だけ録音 
      else if(target==this.getRecordButton()){ 
      recorder.do_recordButton(); 
        } 
      else if(target==this.getPlayButton()){ 
          recorder.do_playButton(); 
            } 
      else if(target==exportImgButton){ //which call better? widget or container? 
          recorder.action_exportImg(this); 
      }else if(target==exportPitchButton){ 
          recorder.action_exportPitch(this); 
      }else if(target==exportWavButton){ 
          recorder.action_exportWav(this); 
      }else if(target==wavSaveCheckButton){ 
          recorder.action_wavSaveCheck(this); 
      }else if(target==imgSaveCheckButton){ 
          recorder.action_imgSaveCheck(this); 
      }else if(target==pitchSaveCheckButton){ 
          recorder.action_pitchSaveCheck(this); 
      }else if(target==pitchShowCheckButton){ 
          recorder.action_pitchShowCheck(this); 
      }else if(target==imgShowCheckButton){ 
          recorder.action_imgShowCheck(this); 
      } 
          } 
       
        /* (non-Javadoc) 
         * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) 
         */ 
        public void widgetDefaultSelected(SelectionEvent e) { 
            // TODO Auto-generated method stub 
             
        } 
        /** 
         *  
         */ 
        public void setPlayMode() { 
             
            //recorder.shell.getDisplay().asyncExec(new ImageChanger()); 
            setPlayImage(); 
             
            //playButton.setEnabled(false); 
            // TODO Auto-generated method stub 
             
            recordButton.setEnabled(false); 
        } 
         
        public void setPlayImage(){ 
            playButton.setImage(doPlayIcon); 
        } 
        public class ImageChanger implements Runnable{ 
 
            /* (non-Javadoc) 
             * @see java.lang.Runnable#run() 
             */ 
            public void run() { 
                setPlayImage(); 
            } 
             
        } 
        /** 
         *  
         */ 
        public void setNormalMode() { 
             
            playButton.setImage(stopPlayIcon); 
            playButton.redraw(); 
            recordButton.setEnabled(true); 
            exportImgButton.setEnabled(true); 
        } 
        /** 
         *  
         */ 
        public void setRecordMode() { 
            playButton.setEnabled(false); 
        } 
        /* (non-Javadoc) 
         * @see org.jpn.xucker.repeatrecorder.ControledObject#getSelection(java.lang.String) 
         */ 
        public boolean getSelection(String key) { 
             
            if(key.equals("saveWav")){ 
              return wavSaveCheckButton.getSelection(); 
          } 
          else if(key.equals("saveImg")){ 
              return imgSaveCheckButton.getSelection(); 
          } 
          else if(key.equals("savePitch")){ 
              return pitchSaveCheckButton.getSelection(); 
          } 
          else if(key.equals("pitchShow")){ 
              return pitchShowCheckButton.getSelection(); 
          }else if(key.equals("imgShow")){ 
              return imgShowCheckButton.getSelection(); 
          } 
          return false; 
        } 
       
  } 
  public static class RepeatRecorderPreference implements ControledObject{ 
      private boolean saveWav; 
      private boolean saveImg; 
      private boolean savePitch; 
      private boolean showImg; 
      private boolean showPitch; 
       
       
        public boolean isSaveImg() { 
            return saveImg; 
        } 
        public void setSaveImg(boolean saveImg) { 
            this.saveImg = saveImg; 
        } 
        public boolean isSavePitch() { 
            return savePitch; 
        } 
        public void setSavePitch(boolean savePitch) { 
            this.savePitch = savePitch; 
        } 
        public boolean isSaveWav() { 
            return saveWav; 
        } 
        public void setSaveWav(boolean saveWav) { 
            this.saveWav = saveWav; 
        } 
        public boolean isShowImg() { 
            return showImg; 
        } 
        public void setShowImg(boolean showImg) { 
            this.showImg = showImg; 
        } 
        public boolean isShowPitch() { 
            return showPitch; 
        } 
        public void setShowPitch(boolean showPitch) { 
            this.showPitch = showPitch; 
        } 
      public void setSelection(String key,boolean value){ 
          if(key.equals("saveWav")){ 
              saveWav=value; 
          } 
          else if(key.equals("saveImg")){ 
              saveImg=value; 
          } 
          else if(key.equals("savePitch")){ 
              savePitch=value; 
          } 
          else if(key.equals("pitchShow")){ 
              showPitch=value; 
          }else if(key.equals("imgShow")){ 
              showImg=value; 
          }else{ 
              throw new RuntimeException("not support select:"+key); 
          } 
      } 
        /* (non-Javadoc) 
         * @see org.jpn.xucker.repeatrecorder.ControledObject#getSelection(java.lang.String) 
         */ 
        public boolean getSelection(String key) { 
            // TODO Auto-generated method stub 
            return false; 
        } 
  } 
   
   
   
  public static class DropMonitor extends DropTargetAdapter{ 
     RepeatRecorder recorder; 
      public DropMonitor(RepeatRecorder recorder){ 
          this.recorder=recorder; 
      } 
    public void dragEnter(DropTargetEvent event){ 
      //System.out.println("drag enter:"+event.data); 
    } 
    public void dragOver(DropTargetEvent event){ 
      //System.out.println("drag over:"+event.data); 
      } 
    public void drop(DropTargetEvent event){ 
      //System.out.println("drop:"+event.data); 
       
      //System.out.println(event.data.getClass().getName()); 
      String files[]=(String[])event.data; 
       
      if(files[0].toLowerCase().endsWith(".wav")){ 
          recorder.do_open(new File(files[0])); 
      } 
       
      } 
  }  
 
  public static void main(String[] args) { 
   
      RepeatRecorder main=null; 
    Display display=new Display(); 
    Shell shell=new Shell(display,SWT.CLOSE|SWT.MIN); 
   try { 
             main=new RepeatRecorder(shell); 
 
            shell.open(); 
 
            while (!shell.isDisposed()) { 
                if (!display.readAndDispatch()) { 
                    display.sleep(); 
                } 
            } 
            display.dispose(); 
        } catch (Exception e) { 
            RepeatRecorder.log.fatal(e.getMessage(),e); 
        } finally { 
            if (!shell.isDisposed()) { 
                shell.close(); 
            } 
 
            display.dispose(); 
            System.exit(0); 
        } 
 
    } 
     
     
 
   
 
 
 
 
 
    /** 
     *  
     */ 
    public void action_imgShowCheck(ControledObject object) { 
        ControledObject[] controledObject=(ControledObject[])controledObjectList.toArray(new ControledObject[controledObjectList.size()]); 
        for (int i = 0; i < controledObject.length; i++) { 
            controledObject[i].setSelection("imgShow",object.getSelection("imgShow")); 
        } 
    } 
 
 
 
 
    /** 
     *  
     */ 
    public void action_pitchShowCheck(ControledObject object) { 
        ControledObject[] controledObject=(ControledObject[])controledObjectList.toArray(new ControledObject[controledObjectList.size()]); 
        for (int i = 0; i < controledObject.length; i++) { 
            controledObject[i].setSelection("pitchShow",object.getSelection("pitchShow")); 
        } 
    } 
 
 
 
 
    /** 
     *  
     */ 
    public void action_pitchSaveCheck(ControledObject object) { 
        ControledObject[] controledObject=(ControledObject[])controledObjectList.toArray(new ControledObject[controledObjectList.size()]); 
        for (int i = 0; i < controledObject.length; i++) { 
            controledObject[i].setSelection("savePitch",object.getSelection("savePitch")); 
        } 
    } 
 
 
 
 
    /** 
     *  
     */ 
    public void action_imgSaveCheck(ControledObject object) { 
        ControledObject[] controledObject=(ControledObject[])controledObjectList.toArray(new ControledObject[controledObjectList.size()]); 
        for (int i = 0; i < controledObject.length; i++) { 
            controledObject[i].setSelection("saveImg",object.getSelection("saveImg")); 
        } 
    } 
 
 
 
 
    /** 
     *  
     */ 
    public void action_wavSaveCheck(ControledObject object) { 
        ControledObject[] controledObject=(ControledObject[])controledObjectList.toArray(new ControledObject[controledObjectList.size()]); 
        for (int i = 0; i < controledObject.length; i++) { 
            controledObject[i].setSelection("saveWav",object.getSelection("saveWav")); 
        } 
    } 
 
 
 
 
    /** 
     *  
     */ 
    public void action_exportPitch(ControledObject object) { 
        do_exportPitch(); 
    } 
 
 
 
 
    /** 
     *  
     */ 
    private void do_exportPitch() { 
        if(espsList!=null && espsList.size()>0){ 
            FileDialog dialog=new FileDialog(shell,SWT.SAVE); 
            dialog.setFilterExtensions(new String[]{"*.csv"}); 
            String path=dialog.open(); 
            if(path!=null){ 
                exportPitch((ESPS[])espsList.toArray(new ESPS[espsList.size()]),new File(path)); 
            } 
        } 
    } 
 
 
 
 
 
 
 
    public void action_open(ControledObject object){ 
        FileDialog dialog=new FileDialog(shell,SWT.NULL); 
        dialog.setFilterExtensions(new String[]{"*.wav"}); 
        String path=dialog.open(); 
         
        if(path!=null){ 
            do_open(new File(path)); 
             
        } 
    } 
     
     
 
    public void action_exit(ControledObject object){ 
        shell.close(); 
    } 
 
    public void action_about(ControledObject object){ 
        execVersion(); 
    } 
    public void action_homepage(ControledObject object){ 
        execHomepage(); 
    } 
    /** 
     *  
     */ 
    public void action_exportImg(ControledObject object) { 
        do_exportImg(); 
    } 
 
     
  /** 
     * @param recorderUI 
     */ 
    public void action_exportWav(ControledObject object) { 
        do_exportWav(); 
    } 
 
    private void exportImg(BufferedImage img,File file){ 
        PNGImageWriter imageWriter = new PNGImageWriter(new PNGImageWriterSpi()); 
         
         
        FileImageOutputStream stream; 
        try { 
            stream = new FileImageOutputStream(file); 
            imageWriter.setOutput(stream); 
            imageWriter.write(img); 
            imageWriter.dispose(); 
            stream.close(); 
        } catch (FileNotFoundException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } catch (IOException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
         
    } 
    private BufferedImage  captureImg(){ 
        BufferedImage img=null; 
        Rectangle speRect=new Rectangle(shell.getBounds().x+4,30+shell.getBounds().height+shell.getBounds().y,640,480); 
        Robot robot; 
         
            try { 
                robot = new Robot(); 
                img=robot.createScreenCapture(speRect); 
            } catch (AWTException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
             
            return img; 
    } 
    public void do_exportImg(){ 
        BufferedImage img=captureImg(); 
        FileDialog dialog=new FileDialog(shell,SWT.SAVE); 
        dialog.setFilterExtensions(new String[]{"*.png"}); 
        String savePath=dialog.open(); 
         
        if(savePath!=null){ 
            exportImg(img,new File(savePath)); 
        } 
        
        img=null; 
    } 
 
 
    /** 
     *  
     */ 
    private void do_exportWav() { 
        // TODO Auto-generated method stub 
        if(outputFile!=null){ 
            FileDialog dialog=new FileDialog(shell,SWT.SAVE); 
            dialog.setFilterExtensions(new String[]{"*.wav"}); 
            String path=dialog.open(); 
            if(path!=null){ 
                try { 
                    FileUtils.copyFile(outputFile,new File(path)); 
                } catch (IOException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
                } 
            } 
        } 
    } 
 
 
 
 
 
 
 
 
 
    public String getTimeString(){ 
      DateFormat format=new SimpleDateFormat("yyyyMMddHHmmss"); 
      return format.format(new Date()); 
  } 
     
   
 
     
    /** 
     *  
     */ 
    private void do_playButton() { 
         
        if(outputFile!=null && doplay==false){ 
            
            setPlayMode(); 
            //play 
            playAudio(outputFile); 
            //setNormalMode(); 
        }else if(doplay){ 
            //stopaudio 
            if(player!=null){ 
                player.setStopped(true); 
            } 
        } 
    } 
 
    AudioPlayer player; 
    Thread thread; 
    /** 
     * @param outputFile2 
     */ 
    private void playAudio(File outputfile) { 
        player=new AudioPlayer(outputfile); 
         
        Thread thread=new Thread(player); 
        thread.start(); 
         
         
    } 
     
    public class SetNormalMode implements Runnable{ 
    public void run(){ 
        setNormalMode();  //??? 
    } 
    } 
    public class AudioPlayer implements Runnable,AudioStopper{ 
        private File outputFile; 
        private boolean stopped=false; 
        AudioPlayer(File file){ 
            this.outputFile=file; 
        } 
        /* (non-Javadoc) 
         * @see java.lang.Runnable#run() 
         */ 
        public void run() { 
            JavaSoundAudioPlayer player=new JavaSoundAudioPlayer(); 
            player.setStopper(this); 
            player.play(outputFile); 
            shell.getDisplay().asyncExec(new SetNormalMode()); 
        } 
        /* (non-Javadoc) 
         * @see org.jpn.xucker.commons.audio.AudioStopper#isStopped() 
         */ 
        public boolean isStopped() { 
            // TODO Auto-generated method stub 
            return stopped; 
        } 
        /* (non-Javadoc) 
         * @see org.jpn.xucker.commons.audio.AudioStopper#setStopped(boolean) 
         */ 
        public void setStopped(boolean bool) { 
           this.stopped=bool; 
        } 
         
         
    } 
 
     
    /** 
     *  
     */ 
    private void setPlayMode() { 
        
        doplay=true; 
        ui.setPlayMode(); 
        
        //exportImgButton.setEnabled(false); 
    } 
 
    /** 
     *  
     */ 
    private void setNormalMode() { 
        //System.out.println("normalmode"); 
        ui.setNormalMode(); 
         
        ui.getPlayButton().setEnabled(outputFile!=null); 
       
        doplay=false; 
    } 
    private void setRecordMode(){ 
        ui.setRecordMode(); 
      
 
        //exportImgButton.setEnabled(false); 
    } 
 
  
     
    public String findPythonPath(){ 
        if(new File("C:\\Python24\\python.exe").exists()){ 
            return "C:\\Python24\\python.exe"; 
        }else{ 
            return "C:\\Python23\\python.exe"; 
        } 
    } 
     
    public void createSpectogram(File file){ 
        String path="\""+applicationBaseDir.getAbsolutePath()+"\\java\\spectrogram.py"+"\""; 
        Runtime runtime=Runtime.getRuntime(); 
         
        try { 
             
            process = runtime.exec(new String[]{findPythonPath(),path,file.getAbsolutePath(),""+shell.getBounds().x,""+(shell.getBounds().y+shell.getBounds().height),""+shell.getBounds().width,""+shell.getBounds().height}); 
             
            // 
            // 
            //Thread.sleep(5000); 
            //process.destroy(); 
        } catch (IOException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        }  
         
    } 
   
    SimpleRecorder  recorder = null; 
 
    private File outputFile; 
 
    private Process process; 
 
 
    private List espsList; 
 
    
    private boolean recording; 
  //押してる間だけ録音 
public void do_recordButton(){ 
    log.info("start record"); 
    if(recording){ 
        return; 
    } 
    recording=true; 
    setRecordMode(); 
    log.info("changing ui icon"); 
    ui.getRecordButton().setImage(ui.getRecIcon()); 
    log.info("changed"); 
    String baseDir=SystemUtils.USER_HOME+"\\My Documents\\"; 
    log.info("basedir="+baseDir); 
    //timeName 
    String dateFormat=getTimeString(); 
    log.info("dateformat:"+dateFormat); 
     
    outputFile = new File(baseDir+dateFormat+".wav"); 
    log.info("output:"+outputFile.getAbsolutePath()); 
   /* AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,  
            48000.0F,  
            16,  
            2,  
            4,  
            48000.0F,  
            false);*/ 
     
    AudioFormat audioFormat = new AudioFormat( 
            48000.0F,  
            16,  
            1,  
            true, 
            false); 
     
//  データラインの情報オブジェクトを生成します 
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat); 
    // 指定されたデータライン情報に一致するラインを取得します 
    TargetDataLine targetDataLine=null; 
    try { 
        targetDataLine = (TargetDataLine) AudioSystem.getLine(info); 
        targetDataLine.open(audioFormat); 
    } catch (LineUnavailableException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    } 
    // 指定されたオーディオ形式でラインを開きます 
   
     
    AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE; 
   
     
     
    recorder = new SimpleRecorder( 
      targetDataLine, 
      targetType, 
      outputFile); 
   
    if(process!=null){ 
        process.destroy();  
    } 
     
    deleteTmpFile(); 
     
    //for after deleting. 
    if(!preference.isSaveWav()){ 
        deleteFile=outputFile; 
    } 
     
    recorder.start(); 
    //plot 
    //spe 
  } 
 
private void deleteTmpFile(){ 
//  delete old file this time. and final 
  if(deleteFile!=null){ 
      log.info("delete record file"+deleteFile.getAbsolutePath()); 
      deleteFile.delete(); 
  } 
  if(tmpOpenFile!=null){ 
  tmpOpenFile.deleteOnExit(); 
  log.info("delete tmp open file "+tmpOpenFile.getAbsolutePath()); 
  }   
  //delete  
} 
 
 
 
 
public static class SimpleRecorder 
extends Thread 
 
{ 
  private AudioInputStream  audioInputStream; 
  private TargetDataLine  dataLine; 
  private AudioFileFormat.Type  audioFileFormatType; 
  private File      recordFile; 
  private boolean    recorderRecoding; 
 
 
 
  public SimpleRecorder(TargetDataLine dataLine, 
        AudioFileFormat.Type audioFileFormatType, 
        File recordFile) 
  { 
    this.dataLine = dataLine; 
    this.audioFileFormatType = audioFileFormatType; 
    this.recordFile = recordFile; 
     
    audioInputStream = new AudioInputStream(dataLine); 
  } 
 
 
 
  /**  Starts the recording. 
   *  To accomplish this, (i) the line is started and (ii) the 
   *  thread is started. 
   */ 
  public void start() 
  { 
       
    dataLine.start(); 
    super.start(); 
  } 
 
 
 
  public void stopRecording() 
  { 
    // for recording, the line needs to be stopped 
    // before draining (especially if you're still 
    // reading from it) 
    dataLine.stop(); 
    dataLine.drain(); 
    dataLine.close(); 
    recorderRecoding = false; 
  } 
   
  public void run() 
  { 
    try 
    { 
       
      AudioSystem.write( 
              audioInputStream, 
              audioFileFormatType, 
        recordFile); 
       
    } 
    catch (IOException e) 
    { 
      e.printStackTrace(); 
    } 
  } 
} 
 
 
 
 
 
 
 
   
  public void execHomepage(){ 
    Program program=Program.findProgram("html"); 
    if(program!=null){ 
        program.execute(HOMEPAGE_URL); 
    } 
    
} 
public void execVersion() { 
    MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); 
    box.setMessage(APP_NAME+" v" + version + "\r\n\r\n" 
            + "License CPL or Apache2.0\r\n (c)アッキー  2004\r\n" 
            + HOMEPAGE_URL); 
 
    //int result=box.open(); 
    //never use result int,for PMD 
    box.open(); 
} 
 
 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) 
 */ 
 
 
public void do_open(File file){ 
    if(process!=null){ 
        process.destroy(); 
    } 
     
    if(tmpOpenFile!=null){ 
        tmpOpenFile.delete(); 
    } 
     
    try { 
        tmpOpenFile = File.createTempFile("tmp",".wav"); 
        log.info("create tmpfile "+tmpOpenFile.getAbsolutePath()); 
        FileUtils.copyFile(file,tmpOpenFile); 
        log.info("copy file "+file.getAbsolutePath() +" to "+tmpOpenFile.getAbsolutePath()); 
         
    } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    } 
     
     
     
    
    outputFile=tmpOpenFile; 
     
    do_showPitch(); 
    do_showSpectogram(); 
     
     
     
    setNormalMode(); 
} 
 
/** 
 *  
 */ 
private void do_stop() { 
    ui.getRecordButton().setImage(ui.getStopIcon()); 
//  TODO Auto-generated method stub 
    if(recorder!=null){ 
        recorder.stopRecording(); 
    } 
    recorder=null; 
     
    do_showPitch(); 
    do_showSpectogram(); 
     
     
     
     
    /* 
    long maxWait=10000; 
    long start=System.currentTimeMillis(); 
    while(start+maxWait>System.currentTimeMillis()){ 
        if(active==false){ 
            break; 
        } 
         
        try { 
            Thread.sleep(30); 
        } catch (InterruptedException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
    }*/ 
     
    do_savePitch(); 
    if(preference.saveImg){ 
    reserveSave=true; 
     
    }else{ 
        recording=false; 
    } 
   // do_saveImg(); //reserver save and de 
     
    setNormalMode(); 
} 
 
private boolean reserveSave; 
 
 
private File tmpOpenFile; 
/** 
 *  
 */ 
 
private void exportPitch(ESPS esps[],File file){ 
    try { 
        BufferedWriter writer=new BufferedWriter(new FileWriter(file)); 
        for (int i = 0; i < esps.length; i++) { 
            writer.write(esps[i].toString()+SystemUtils.LINE_SEPARATOR); 
        } 
        writer.close(); 
    } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    } 
} 
private void do_savePitch() { 
     
    if(preference.isSavePitch()){ 
        String defaultPath=toChangeExtensionName(outputFile,".csv"); 
        
        if(espsList!=null && espsList.size()>0){ 
            ESPS[] esps=(ESPS[])espsList.toArray(new ESPS[espsList.size()]); 
            exportPitch(esps,new File(defaultPath)); 
            
             
        } 
        //get 
        //tostring  
        //write. 
    } 
} 
 
/** 
 *  
 */ 
private void do_saveImg() { 
    
    if(preference.isSaveImg()){ 
       String defaultPath=toChangeExtensionName(outputFile,".png"); 
       exportImg(captureImg(),new File(defaultPath)); 
    } 
} 
 
private String toChangeExtensionName(File file,String extension){ 
    String result=null; 
    if(file.isFile()){ 
        int last=file.getName().lastIndexOf("."); 
        if(last!=-1){ 
            result=file.getParent()+SystemUtils.FILE_SEPARATOR+file.getName().substring(0,last)+extension; 
        }else{ 
            result=file.getAbsolutePath()+extension; 
        } 
    } 
     
    return result; 
} 
 
 
 
 
 
 
 
 
public void do_showPitch(){ 
    if(preference.isShowPitch()){ 
    createPitch(outputFile); 
    }else{ 
        ui.getPitchCanvas().setEspsList(null); 
        ui.getPitchCanvas().redraw(); 
    } 
} 
 
public void do_showSpectogram(){ 
    if(preference.isShowImg()){ 
        createSpectogram(outputFile); 
    } 
} 
/** 
 * @param outputFile2 
 */ 
private void createPitch(File output) { 
    //call 
     
    String path="\""+applicationBaseDir+"\\java\\pitch.py"+"\""; 
    Runtime runtime=Runtime.getRuntime(); 
     
    try { 
        //Process process = runtime.exec(new String[]{"C:\\Python23\\python.exe",path,output.getAbsolutePath()}); 
        Process pitchProcess = runtime.exec(new String[]{"cmd.exe"}); 
        PrintWriter writer=new PrintWriter(pitchProcess.getOutputStream()); 
        System.out.println(path+" \""+output.getAbsolutePath()+"\"\r\n"); 
        writer.write(path+" \""+output.getAbsolutePath()+"\"\r\n"); 
        writer.close(); 
        ESPSParser parser=new ESPSParser(); 
         
        espsList = parser.parse(pitchProcess.getInputStream()); 
        //process.destroy(); 
        ui.getPitchCanvas().setEspsList(espsList); 
        ui.getPitchCanvas().redraw(); 
         
        // 
        //Thread.sleep(5000); 
        //process.destroy(); 
    } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    }  
     
     
    //save? 
} 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent) 
 */ 
public void shellActivated(ShellEvent e) { 
    // TODO Auto-generated method stub 
     
} 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent) 
 */ 
public void shellClosed(ShellEvent e) { 
    // TODO Auto-generated method stub 
    if(process!=null){ 
        process.destroy(); 
    } 
     
    deleteTmpFile(); 
     
    e.doit=true; 
} 
 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent) 
 */ 
public void shellDeactivated(ShellEvent e) { 
    if(reserveSave){ 
        try { 
            Thread.sleep(300); 
        } catch (InterruptedException e1) { 
            // TODO Auto-generated catch block 
            e1.printStackTrace(); 
        } 
        do_saveImg(); 
        reserveSave=false; 
        recording=false; 
    } 
} 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent) 
 */ 
public void shellDeiconified(ShellEvent e) { 
    // TODO Auto-generated method stub 
     
} 
 
/* (non-Javadoc) 
 * @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent) 
 */ 
public void shellIconified(ShellEvent e) { 
    // TODO Auto-generated method stub 
     
} 
 
}
    
    |