使用TargetDataLine从葡萄酒中捕获声音

2022-08-31 22:13:48

我编写了一个用于测试目的的小型Java应用程序,该应用程序在ubuntu 12.04上从混音器捕获声音。

代码工作正常,我可以从所有应用程序中捕获声音,除了Wine下运行的任何内容。

每当我启动我的程序时,在启动Wine之后,调用将永远阻止targetDataLine.read()

当 Wine 未在后台运行时,它会在没有输入时正确输出,或者如预期的那样,在有输入时读取的字节数。0

如果我在启动 Wine 之前启动我的程序,则声音驱动程序在 wine 中将不可用。

我尝试使用Alsa提供的混音器以及默认设备,结果相同。

我可以想象葡萄酒以某种方式锁定了Alsa(无论出于何种原因),但是为什么在Wine中,一个简单的调用会导致声音失败呢? 顺便说一句,在我的系统上是默认的,当然,该应用程序总是使用oracle最新的JRE(7)在Wine之外运行。TargetDataLine.read()mixerInfo[0]

private void readSound ()
{
    byte tempBuffer[] = new byte[10000];
    int cnt = 0;
    Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();

    System.out.println("Available mixers:");
    for (int p = 0; p < mixerInfo.length; p++)
        System.out.println(mixerInfo[p].getName());

    format = getAudioFormat();
    DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
    Mixer mixer = AudioSystem.getMixer(mixerInfo[0]);

    try
    {
         targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
         targetDataLine.open(format);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    targetDataLine.start();

    while (true)
    {
        i++;
        cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);
        System.out.println("read " + cnt + " bytes:" + tempBuffer[i]);            
        calculateLevel(tempBuffer, 0, 200);
        targetDataLine.flush();
        System.out.println(level);
   }
}

答案 1

使用 AudioSystem.write() 方法。这要容易得多

targetDataLine.open(format);
targetDataLine.start();
AudioInputStream ais=new AudioInputStream(targetDataLine);
AudioFileFormat.Type fileformat=AudioFileFormat.Type.WAVE;
/*
Other Audio file formats supported:
AudioFileFormat.Type.AU
AudioFileFormat.Type.AIFF
AudioFileFormat.Type.AIFC
AudioFileFormat.Type.SND
*/
File audoutputfile=new File('myfile');
//adjust extension according to AudioFileFormat
AudioSystem.write(ais,fileformat, audoutputfile);

答案 2

推荐