如何在javax.sound.sampled.Line上播放/录制声音

时间:2015-09-02 07:42:05

标签: java audio javax.sound.sampled

我有一个数组,里面装满了所有当前连接麦克风的javax.sound.sampled.Line.Info对象

Info[] sourceInfos = AudioSystem.getSourceLineInfo(Port.Info.MICROPHONE);

使用它们我可以得到所有麦克风的线条

for (Info sourceInfo : sourceInfos) {
    Line sourceLine = AudioSystem.getLine(sourceInfo);
    // record sound from those lines
}

扬声器也是如此

Info[] sourceInfos = AudioSystem.getSourceLineInfo(Port.Info.SPEAKER);
for (Info sourceInfo : sourceInfos) {
    Line sourceLine = AudioSystem.getLine(sourceInfo);
    // play sound on those lines
}

现在我只需要弄清楚如何在一条线上播放声音以及如何从一条线上录制声音。这是我卡住的地方,无法找到解决方案。

所以只是说它,问题是,我如何读/写一行? 由于
Baschdi

1 个答案:

答案 0 :(得分:1)

您可以尝试此示例来捕获和播放音频。它基于Java Sound API文档中提供的示例。

以下是您可以参考的资源:

  1. Accessing Audio System Resources
  2. Capturing audio
  3. Playing audio

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    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.Mixer;
    import javax.sound.sampled.SourceDataLine;
    import javax.sound.sampled.TargetDataLine;
    
    public class Audio {
    
    boolean stopCapture = false;
    ByteArrayOutputStream byteArrayOutputStream;
    AudioFormat audioFormat;
    TargetDataLine targetDataLine;
    AudioInputStream audioInputStream;
    SourceDataLine sourceDataLine;
    byte tempBuffer[] = new byte[500];
    
    public static void main(String[] args) {
        Audio audio = new Audio();
        audio.captureAudio();
    
    }
    
    private AudioFormat getAudioFormat() {
        float sampleRate = 8000.0F;
        int sampleSizeInBits = 16;
        int channels = 1;
        boolean signed = true;
        boolean bigEndian = true;
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    }
    
    private void captureAudio() {
        try {
    
            /* ~~~~~ UPDATE THIS PART OF CODE ~~~~~*/
    
            Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();    //get available mixers
            System.out.println("Available mixers:");
            for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
                System.out.println(mixerInfo[cnt].getName());
            }
            audioFormat = getAudioFormat();     //get the audio format
    
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
    
            Mixer mixer = AudioSystem.getMixer(mixerInfo[3]);   //getting the mixer for capture device
    
            /* ~~~~~ UPDATE THIS PART OF CODE ~~~~~*/ 
    
            targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
            targetDataLine.open(audioFormat);
            targetDataLine.start();
    
            DataLine.Info dataLineInfo1 = new DataLine.Info(SourceDataLine.class, audioFormat);
            sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo1);
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();
    
            Thread captureAndPlayThread = new captureAndPlayThread();   //thread to capture and play audio
            captureAndPlayThread.start();
    
        } catch (LineUnavailableException e) {
            System.out.println(e);
            System.exit(0);
        }
    }
    
    class captureAndPlayThread extends Thread {
    
        @Override
        public void run() {
            byteArrayOutputStream = new ByteArrayOutputStream();
            stopCapture = false;
            try {
                int readCount;
                while (!stopCapture) {
                    readCount = targetDataLine.read(tempBuffer, 0, tempBuffer.length);  //capture sound into tempBuffer
                    if (readCount > 0) {
                        byteArrayOutputStream.write(tempBuffer, 0, readCount);
                        sourceDataLine.write(tempBuffer, 0, 500);   //playing audio available in tempBuffer
                    }
                }
                byteArrayOutputStream.close();
            } catch (IOException e) {
                System.out.println(e);
                System.exit(0);
            }
        }
    }
    
    }
    

    `

  4. 修改:请使用此代码更新以前的代码。以下代码段仅在支持麦克风即TargetDataLine时才选择混音器。类似地,你可以为扬声器做,即SourceDataLine。

            Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();    //get available mixers
            System.out.println("Available mixers:");
            Mixer mixer = null;
            for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
                System.out.println(cnt + " " + mixerInfo[cnt].getName());
                mixer = AudioSystem.getMixer(mixerInfo[cnt]);
    
                Line.Info[] lineInfos = mixer.getTargetLineInfo();
                if (lineInfos.length >= 1 && lineInfos[0].getLineClass().equals(TargetDataLine.class)) {
                    System.out.println(cnt + " Mic is supported!");
                    break;
                }
            }
    
            audioFormat = getAudioFormat();     //get the audio format
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);