Вывод многоканального звука через динамики объемного звучания

Я работаю над интерактивной звуковой инсталляцией, которая, среди прочего, работает с использованием Processing и Minim. Для этого проекта требуется нечто большее, чем просто левый/правый выход (если быть точным, 5 динамиков), что, судя по тому, что я прочитал, означает, что Java Sound API является моим основным вариантом с моей настройкой. Я новичок в обработке и совершенно не знаком с Java более низкого уровня.

Я запускаю все это на Macbook Pro 2011 года с этой внешней звуковой картой USB: http://amzn.com/B004Y0ERRO, который, кажется, отлично распознается как один USB-аудиоинтерфейс на Mac. При использовании Java Sound API теоретически я должен иметь возможность получить список линий из микшера, который будет соответствовать трем стереовыходным разъемам, к которым мне нужен доступ, но я не могу понять, как и где их найти проведя много времени в документах API Java Audio и связанных с ними учебных сайтах.

РЕДАКТИРОВАТЬ: Оказывается, большинство звуковых карт с объемным звуком совместимы только со стереозвуком на 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

Я чувствую, что копаю не в том месте, как USB-карта объемного звука может иметь только один закрытый целевой порт SPEAKER, когда на устройстве 10 разъемов? Как бы внимательно я ни читал документацию, я не могу понять, где я ошибаюсь. Спасибо за чтение, и я очень ценю любую информацию, которую вы можете предоставить!

РЕДАКТИРОВАТЬ:

Версия приведенного выше скетча с базовым воспроизведением минималистичных изображений включает:

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

person Russ    schedule 30.11.2015    source источник


Ответы (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. Обработка не знает, как напечатать экземпляр Line (класс Line не переопределяет метод toString()), поэтому вы просто получите его хэш-код вместо какой-либо полезной информации. Вместо этого попробуйте распечатать экземпляр Line.Info:

println(lineInfo);

Изменить. Что касается вашей ошибки о неоднозначности Line, это связано с тем, что вы используете импорт с подстановочными знаками — вы импортируете все в пакетах ddf.minim, ddf.minim.ugens и javax.sound.sampled. Проблема в том, что ddf.minim и javax.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()){

Обратите внимание, что вам придется делать это для каждой строки, которая может быть неоднозначной, поэтому лучшим решением будет прямой импорт классов.

person Kevin Workman    schedule 30.11.2015
comment
Благодарю вас! Это шаг в правильном направлении, теперь код выглядит так: 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 То же, что и раньше. - person Russ; 30.11.2015
comment
@Russ Ну, теперь вам нужно выяснить, какая линия идет к какому устройству. Вы пробовали просто воспроизвести звук на линии и посмотреть, где он выходит? - person Kevin Workman; 30.11.2015
comment
Я добавил версию кода с минимумом, генерирующим синусоидальную волну, в конец моего исходного вопроса. Я получаю сообщение об ошибке for оператора try, говорящее The type Line is ambiguous. Однажды я получил эту ошибку, что побудило меня исключить миним из уравнения для устранения неполадок. - person Russ; 30.11.2015
comment
Еще раз спасибо. Я думаю, что я включил их по отдельности в свой пост. Теперь я, как ни странно, получаю сообщение об ошибке «Не удается найти класс или тип с именем «LineUnavailableException» в операторе catch. Странный! Раньше с этой ошибкой не было проблем. - person Russ; 30.11.2015
comment
@Russ Если вы удалили импорт подстановочных знаков, вам также придется напрямую импортировать класс LineUnavailableException. - person Kevin Workman; 30.11.2015
comment
Я переключился на микшер 4 (как я думал раньше), и теперь я получаю синусоиду из правой и левой пары динамиков. Так это что-то! - person Russ; 01.12.2015