2012-09-20 31 views
1

作爲我的(尚未解決的)以前的問題的後續,GUI event not triggering consistently,我發現了另一個怪癖。下面的代碼創建和播放.wav文件:.wav文件播放但.aiff文件不需要

import java.awt.FlowLayout; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
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.Mixer; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.TargetDataLine; 
import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JRadioButton; 

public class audioTest extends JFrame { 

private static final long serialVersionUID = 1L; 
TargetDataLine targetDataLine; 
AudioCapture audCap = new AudioCapture(); 

public static void main(String[] args) { 
    new audioTest(); 
} 

public audioTest() { 

    layoutTransporButtons(); 
    getContentPane().setLayout(new FlowLayout()); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setSize(350, 100); 
    setVisible(true); 
} 

public void layoutTransporButtons() { 

    final JPanel guiButtonPanel = new JPanel(); 
    final JButton captureBtn = new JButton("Record"); 
    final JButton stopBtn = new JButton("Stop"); 
    final JButton playBtn = new JButton("Playback"); 
    guiButtonPanel.setLayout(new GridLayout()); 
    this.add(guiButtonPanel); 
    captureBtn.setEnabled(true); 
    stopBtn.setEnabled(false); 
    playBtn.setEnabled(true); 

    JRadioButton[] radioBtnArray; 
    AudioFileFormat.Type[] fileTypes; 

    // Register anonymous listeners 
    captureBtn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      captureBtn.setEnabled(false); 
      stopBtn.setEnabled(true); 
      playBtn.setEnabled(false); 
      // Capture input data from the microphone 
      audCap.captureAudio(); 
     } 
    }); 
    guiButtonPanel.add(captureBtn); 

    stopBtn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      captureBtn.setEnabled(true); 
      stopBtn.setEnabled(false); 
      playBtn.setEnabled(true); 
      audCap.stopRecordAndPlayback = true; 
      audCap.stopRecording(); 
     } 
    }); 
    guiButtonPanel.add(stopBtn); 

    playBtn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      stopBtn.setEnabled(true); 
      audCap.playAudio(); 
     } 
    }); 
    guiButtonPanel.add(playBtn); 
} 

class AudioCapture { 

    volatile boolean stopRecordAndPlayback = false; 
    AudioFormat audioFormat; 
    AudioInputStream audioInputStream; 
    SourceDataLine sourceDataLine; 
    private String wavName; 
    private File audioFile; 

    /** 
    * capture audio input from microphone and save as .wav file 
    */ 
    public void captureAudio() { 

     wavName = JOptionPane.showInputDialog(null, 
       "enter name of file to be recorded:"); 
     try { 
      Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); 
      // Select an available mixer 
      Mixer mixer = AudioSystem.getMixer(mixerInfo[1]); 
      // Get everything set up for capture 
      audioFormat = getAudioFormat(); 
      DataLine.Info dataLineInfo = new DataLine.Info(
        TargetDataLine.class, audioFormat); 
      // Get a TargetDataLine on the selected mixer. 
      targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo); 
      // Prepare the line for use. 
      targetDataLine.open(audioFormat); 
      targetDataLine.start(); 
      // Create a thread to capture the microphone 
      Thread captureThread = new CaptureThread(); 
      captureThread.start(); 
     } catch (Exception e) { 
      System.out.println(e); 
      System.exit(0); 
     } 
    } 

    /** 
    * This method plays back the audio data that has 
    * been chosen by the user 
    */ 
    public void playAudio() { 
     // add file chooser 
     JFileChooser chooser = new JFileChooser(); 
     chooser.setCurrentDirectory(audioFile); 
     int returnVal = chooser.showOpenDialog(chooser); 
     // retrieve chosen file 
     if (returnVal == JFileChooser.APPROVE_OPTION) { 
      // create the file 
      audioFile = chooser.getSelectedFile(); 
     } 
     // play chosen file 
     try { 
      audioInputStream = AudioSystem.getAudioInputStream(audioFile); 
      audioFormat = audioInputStream.getFormat(); 
      DataLine.Info dataLineInfo = new DataLine.Info(
        SourceDataLine.class, audioFormat); 
      sourceDataLine = (SourceDataLine) AudioSystem 
        .getLine(dataLineInfo); 
      // Create a thread to play back the data 
      new PlayThread().start(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(0); 
     } 
    } 

    /** 
    * This method creates and returns an AudioFormat object 
    */ 
    private AudioFormat getAudioFormat() { 
     float sampleRate = 44100.0F; 
     // 8000,11025,16000,22050,44100 
     int sampleSizeInBits = 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); 
    } 

    /** 
    * 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() { 
      // reset stopCapture to false 
      stopRecordAndPlayback = false; 
      // record as wave 
      AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE; 
      // take user input file name and append file type 
      audioFile = new File(wavName + ".wav"); 

      try { 
       targetDataLine.open(audioFormat); 
       targetDataLine.start(); 
       while (!stopRecordAndPlayback) { 
        AudioSystem.write(new AudioInputStream(targetDataLine), 
          fileType, audioFile); 
       } 
       targetDataLine.stop(); 
       targetDataLine.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    /** 
    * method to stop capture 
    */ 
    public void stopRecording() { 
     // targetDataLine.stop(); 
     // targetDataLine.close(); 
     // System.out.println("stopped"); 
    } 

    /** 
    * Inner class to play back the data 
    */ 
    class PlayThread extends Thread { 
     byte tempBuffer[] = new byte[10000]; 

     public void run() { 
      // reset stop button 
      stopRecordAndPlayback = false; 

      try { 
       sourceDataLine.open(audioFormat); 
       sourceDataLine.start(); 
       int cnt; 
       while ((cnt = audioInputStream.read(tempBuffer, 0, 
         tempBuffer.length)) != -1 
         && stopRecordAndPlayback == false) { 
        if (cnt > 0) { 
         sourceDataLine.write(tempBuffer, 0, cnt); 
        } 
       } 
       sourceDataLine.drain(); 
       sourceDataLine.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       System.exit(0); 
      } 
     } 
    } 
} 
} 

我試圖改變捕獲部分記錄的.AIFF文件來代替,該作品,但回放現在處於靜音狀態。我可以找到該文件並通過其他方式進行播放,並且工作正常,但不在此程序中。

我改變了記錄.AIFF的線路有:

// record as aiff 
AudioFileFormat.Type fileType = AudioFileFormat.Type.AIFF; 
// take user input file name and append file type 
audioFile = new File(wavName + ".AIFF"); 

任何人都知道爲什麼.wav文件通過這個代碼播放,但.AIFF文件沒有?

-EDIT- 我也嘗試使用.aif作爲後綴,但那也沒有工作。 我想到它可能與作爲AIFF-C音頻存儲的文件有關,但我無法在此找到任何進一步信息。

+1

我還沒有在Java中使用過音頻,但在我看來,您正在將壓縮音頻數據發送到音頻設備,而且我認爲這不起作用。 – yms

+0

謝謝。我沒有意識到將它保存爲.AIFF會壓縮它。 – Robert

回答

1

AIFF-C is a compressed audio format,所以你不應該「按原樣」發送到音頻設備。您需要首先將其解壓縮到PCM。

+0

謝謝。任何想法爲什麼「AudioFileFormat.Type.AIFF」會將其存儲爲AIFF-C,而不僅僅是AIFF? – Robert