Java-从TargetDataLine读取音频-仅读取零/

Java-从TargetDataLine读取音频-仅读取零/,java,audio,Java,Audio,我在使用TargetDataLine时遇到问题-它一直只从混音器中读取零 下面使用的是一个工作正常的arecord: arecord-D plughw:1,0,0-r 44100-f s16_le-c 2-D 3/tmp/file.wav 当我用javax.sound.sampled尝试这个时,我总是得到零。以下内容使用线程打开TargetDataLine,以在5秒后停止读取。读取缓冲区始终用零填充 package com.example; import javax.sound.sampled

我在使用TargetDataLine时遇到问题-它一直只从混音器中读取零

下面使用的是一个工作正常的arecord:

arecord-D plughw:1,0,0-r 44100-f s16_le-c 2-D 3/tmp/file.wav

当我用javax.sound.sampled尝试这个时,我总是得到零。以下内容使用线程打开TargetDataLine,以在5秒后停止读取。读取缓冲区始终用零填充

package com.example;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.Mixer.Info;

public class AudioTest {
    
    static final long RECORD_TIME = 5000; 
    private TargetDataLine line;
    private boolean isRecording = false;
    
    private void run() {

        Thread stopper = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(RECORD_TIME);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                System.out.println("\nSleep for " + RECORD_TIME + " complete - attempting to end");
                finish();
            }
        });
        
        stopper.start();
        
        try {
            AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
            
            Info[] infos = AudioSystem.getMixerInfo();
            
            int mixerNumber = 3;  // This is the one that matches the one that works with arecord.
            
            Mixer mixer = AudioSystem.getMixer(infos[mixerNumber]);
            
            System.out.println("Using infos " + mixerNumber + ", " + infos[mixerNumber].getName() + ", " +infos[mixerNumber].getDescription());
            System.out.println("Using format to open TargetDataLine: " + format.toString());
            
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
 
            line = (TargetDataLine)mixer.getLine(info);
             
             int BUFFER_SIZE = 2048;
             byte[] bytesBuffer = new byte[BUFFER_SIZE];
             int bytesRead = -1;
             
             line.open(format);
             isRecording = true;

             while (((bytesRead = line.read(bytesBuffer, 0 , BUFFER_SIZE)) != -1) && (isRecording)) {
                 
                 if (bytesRead != 0)
                     System.out.println("Read Something - yeah");
             }
             
             System.out.println("");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private void finish() {
        line.stop();
        line.close();
        isRecording = false;
    }
    
    public static void main(String[] args) {
        AudioTest audioTest = new AudioTest();
        audioTest.run();
    }
    
}
输出通常如下所示:

Using infos 3, Loopback [plughw:1,0], Direct Audio Device: Loopback, Loopback PCM, Loopback PCM
Using format to open TargetDataLine: PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
Sleep for 5000 complete - attempting to end
logout

是否有任何明显的信息我遗漏了-谢谢

您的主机是否显示了许多“Read something-yeah”消息?在5秒钟内,我想你应该得到400多条。你用来指定TargetDataLine的方法——也许是一个更简单的表单
TargetDataLine tdl=AudioSystem.getTargetDataLine(audioFormat,mixerInfo)其中mixerInfo是您想要录制的特定源?最后一个想法是,不要将-1作为返回值进行测试(麦克风会返回-1吗?您的输入是有限长度的文件吗?),而是在while循环测试中放置一个布尔实例“isRunning”,并将计时线程设置为“isRunning”以停止录制。也许这些想法中的一个会有所帮助。我只实现了一次基本的TargetDataLine麦克风录音机,这些想法反映了我实现它的方式与您的不同之处。因为我只做过一次,所以我当然不需要专业知识。