【问题标题】:Outputting multichannel audio through surround sound speakers通过环绕声扬声器输出多声道音频
【发布时间】:2016-03-04 13:05:32
【问题描述】:

我正在开发一个使用 Processing 和 Minim 运行的交互式声音装置。这个项目需要的不仅仅是一个简单的左/右输出(具体来说是 5 个扬声器),据我所知,这意味着 Java Sound api 是我设置的主要选项。我对处理相当陌生,对较低级别的 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 );
}

【问题讨论】:

    标签: java processing minim


    【解决方案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 模棱两可的错误,那是因为您使用通配符导入 - 您正在导入ddf.minim 中的所有内容ddf.minim.ugensjavax.sound.sampled 包。问题是ddf.minimjavax.sound.sampled 都有一个Line 类,所以Processing 无法知道你指的是哪个类!

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

    import ddf.minim.Minim;
    import javax.sound.sampled.Line;
    //1 import statement for each class...
    

    惰性解决方案是使用完全限定名称,因此 Processing 知道您的意思是什么 Line 类:

    for (javax.sound.sampled.Line.Info [] lineInfo : mixer.getTargetLineInfo()){
    

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

    【讨论】:

    • 谢谢!这是朝着正确方向迈出的一步,代码现在为:import javax.sound.sampled.*; Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); Mixer mixer = AudioSystem.getMixer(mixerInfo[8]); void setup() { size(200, 200); //printArray(mixerInfo); try { for (Line.Info lineInfo : mixer.getTargetLineInfo()) { Line thisLine = mixer.getLine(lineInfo); thisLine.open(); println(lineInfo); } } catch(LineUnavailableException e) { e.printStackTrace(); } },打印语句返回:SPEAKER target port 与以前相同。
    • @Russ 好吧,现在您必须弄清楚哪条线路连接到哪个设备。您是否尝试过只在线路上播放声音并查看它的输出位置?
    • 我在原始问题的底部添加了一个带有最小生成正弦波的代码版本。我在 try 语句的 for 上收到错误消息 The type Line is ambiguous。之前我遇到过这个错误,这促使我从等式中提取 minim 进行故障排除。
    • 再次感谢您。我想我已经将它们单独包含在我的帖子中。现在我奇怪地在 catch 语句中收到“找不到名为'LineUnavailableException'的类或类型”的错误。诡异的!之前抛出该错误没有问题。
    • @Russ 如果您取出通配符导入,那么您也必须直接导入 LineUnavailableException 类。
    猜你喜欢
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多