通过环绕立体声扬声器输出多声道音频

时间:2015-11-30 19:25:04

标签: java processing minim

我正在开发一个使用Processing和Minim运行的交互式声音安装。这个项目需要的不仅仅是简单的左/右输出(5个扬声器,具体而言),从我读过的内容来看,Java Sound api是我设置的主要选项。我对Processing非常陌生,而且对于低级Java来说是全新的。

我在2011 Macbook Pro上使用这款外置USB声卡运行这一切:http://amzn.com/B004Y0ERRO,它似乎在Mac上检测为单个USB音频接口。当使用Java Sound api时,理论上我应该能够从混音器获得一个行列表,它对应于我需要访问的3个立体声输出插孔,但我似乎无法弄清楚如何以及在何处找到它们花了很多时间在Java Audio api文档和相关的教程网站上。

编辑:原来大多数环绕声声卡只能在Mac上立体声兼容,这解释了我的大部分麻烦。我将用3个立体声声卡重试这个。

以下是我在Processing中使用的演示的简单版本:

import javax.sound.sampled.*;

Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
Mixer mixer = AudioSystem.getMixer(mixerInfo[8]);

void setup()
{
  size(200, 200);

  printArray(mixerInfo);

  for(Line.Info lineInfo : mixer.getTargetLineInfo()){
    Line thisLine = mixer.getLine(lineInfo);
    thisLine.open();
    println(thisLine);
  }

}

printArray返回:

[0] Default Audio Device, version Unknown Version
[1] Built-in Microphone, version Unknown Version
[2] Built-in Input, version Unknown Version
[3] Built-in Output, version Unknown Version
[4] USB Sound Device        , version Unknown Version
[5] Port Built-in Microphone, version Unknown Version
[6] Port Built-in Input, version Unknown Version
[7] Port Built-in Output, version Unknown Version
[8] Port USB Sound Device        , version Unknown Version

据推测,我想要最后一个设备(8)或者4个。我无法分辨,因为我无法看到每个设备属于哪些线路/端口。当我尝试使用时:

mixer.getTargetLineInfo()

我只得到一个结果:

SPEAKER target port

最后的for循环应该遍历混音器中的所有行并打开它们(直到此时你必须注释掉这部分不会抛出错误)但是我得到了这个错误:

Unhandled exception type LineUnavailableException

我觉得我必须挖到错误的地方,当设备上有10个插孔时,环绕声USB卡怎么只有一个单独的SPEAKER目标端口?无论我如何仔细阅读文档,我都无法弄清楚我哪里出错了。感谢您的阅读,我非常感谢您提供的任何见解!

编辑:

包含基本微量回放的上述草图版本:

import ddf.minim.Minim;
import ddf.minim.ugens.Oscil;
import ddf.minim.AudioOutput;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Line;

Minim       minim;
AudioOutput out;
Oscil       wave;

Mixer.Info[] mixerInfo;
javax.sound.sampled.Line.Info lineInfo;
javax.sound.sampled.Line Line;


void setup()
{
  size(200, 200);

  minim = new Minim(this);

  mixerInfo = AudioSystem.getMixerInfo();   
  Mixer mixer = AudioSystem.getMixer(mixerInfo[8]);

  try {
    for (Line.Info lineInfo : mixer.getTargetLineInfo()) {
      Line thisLine = mixer.getLine(lineInfo);
      thisLine.open();
      println(lineInfo);
    }
  }
  catch(LineUnavailableException e) {
    e.printStackTrace();
  }

  minim.setOutputMixer(mixer);

  out = minim.getLineOut(Minim.STEREO);

  wave = new Oscil( 440, 0.5f, Waves.SINE );
  wave.patch( out );
}

1 个答案:

答案 0 :(得分:1)

您收到Unhandled exception type LineUnavailableException错误,因为这两行都可以抛出LineUnavailableException

Line thisLine = mixer.getLine(lineInfo);
thisLine.open();

这意味着你必须将这些行包装在try-catch块中:

  try {
    for (Line.Info lineInfo : mixer.getTargetLineInfo()) {
      Line thisLine = mixer.getLine(lineInfo);
      thisLine.open();
      println(thisLine);
    }
  }
  catch(LineUnavailableException e) {
    e.printStackTrace();
  }

我可以尝试解决其余的问题,但第一步是解决这个问题,因为这是一个编译错误,可能会阻止您实际运行任何代码。

另外,请看这一行:

println(thisLine);

您正在打印Line个实例。 Processing不知道如何打印Line实例(Line类不会覆盖toString()方法),因此您只需获取其哈希码而不是任何有用信息。尝试打印出`Line.Info实例:

println(lineInfo);

修改:关于Line含糊不清的错误,那是因为您正在使用通配符导入 - 您在{{导入所有内容 1}},ddf.minimddf.minim.ugens个包。问题是javax.sound.sampledddf.minim都有一个javax.sound.sampled类,所以Processing无法知道你的意思是哪个类!

“真正的”解决方案可能是专门导入类而不是使用导入通配符:

Line

lazy 解决方案是使用完全限定名称,以便处理确切地知道您所说的import ddf.minim.Minim; import javax.sound.sampled.Line; //1 import statement for each class... 类:

Line

请注意,您必须为每个可能不明确的行执行此操作,因此更好的解决方案是直接导入类。