2012-09-20 2 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 등을 기록하기위한 변경

의 선은 다음과 같습니다 .WAV 파일이 코드를 통해 재생하지만, aiff 등 파일을하지 않는 이유

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

누구나 알아?

-EDIT- 또한 접미사로 .aif를 사용했지만 사용하지 못했습니다. 그리고 AIFF-C 오디오로 저장되는 파일과 관련이있을 수도 있지만 더 이상 찾을 수 없습니다.

+1

자바로 오디오 작업을 해본 적이 없지만 압축 된 오디오 데이터를 오디오 장치로 전송하고있는 것으로 보입니다. – yms

+0

감사. 나는 .AIFF가 그것을 압축 할 것이기 때문에 그것을 저장하는 것을 깨닫지 못했다. – Robert

답변

1

AIFF-C is a compressed audio format이므로 오디오 장치에는 "있는 그대로"보내지 않아야합니다. 먼저 PCM으로 압축을 풀어야합니다.

+0

감사합니다. "AudioFileFormat.Type.AIFF"가 AIFF가 아닌 AIFF-C로 저장하는 이유는 무엇입니까? – Robert