1. ホーム
  2. java

[解決済み] javax.sound.sampled.Lineで音を再生/録音する方法

2022-02-07 11:13:22

質問

現在接続されているすべてのマイクの 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
}

あとは、LINEで音を出す方法と、LINEから音を録音する方法を考えなければなりません。このあたりで行き詰まり、解決策を見つけることができませんでした。

ということで、一応質問ですが、LINEの読み書きをするにはどうしたらいいのでしょうか?
ありがとうございます。
バシュディ

解決方法は?

この例では、オーディオをキャプチャして再生することができます。これは、Java Sound API ドキュメントで提供されているサンプルに基づいています。

以下は、参考になる資料です。

  1. オーディオシステムのリソースにアクセスする
  2. オーディオのキャプチャ .
  3. オーディオの再生 .

    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);
            }
        }
    }
    
    }
    
    

    `

編集 : 前のコードをこのコードで更新してください。以下のコードでは、マイクをサポートしているミキサー(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);