Методы кастомной реализации TargetDataLine не вызываются

Я попытался работать с пакетом javax.sound.sampled.

Я попытался реализовать свою собственную версию TargetDataLine (на данный момент для целей тестирования). Однако, к моему большому разочарованию, когда я закончил и попытался «воспроизвести» его, ни один из его методов не был вызван (и не было возбуждено никаких исключений), а вместо этого программа зависла.

Рассматриваемый сегмент кода выглядит следующим образом:

try {
  // create stream.
  AssembledDataLine line = new AssembledDataLine();
  AudioInputStream stream = new AudioInputStream(line);

  // create content.
  int size = 65536;
  byte[] array = new byte[size];
  byte inc = 1;
  byte pos = (byte) 0;
  for (int i = 0; i < size; ++i) {
    array[i] = (pos += inc);
    if (pos == 127) {
      inc = -1;
    } else if (pos == -128) {
      inc = 1;
    }
  }
  line.writeArray(array);

  // play.
  System.out.println("starting to play.");
  Clip clip = AudioSystem.getClip();
  clip.loop(Clip.LOOP_CONTINUOUSLY);
  System.out.println("got clip");
  clip.open(stream);
  System.out.println("opened");
  clip.start();
  Thread.sleep(5000);
  System.out.println("started");
  clip.close();
  System.out.println("end.");
} catch (Exception e) {
  e.printStackTrace();
  System.out.println("error");
}

Вышеупомянутый код никогда не достигнет «открытого» оператора или не выдаст исключение. Я пытался вставить распечатку в каждый метод, реализованный в AssembledDataLine, но ни один из них никогда не вызывается (за исключением writeArray, который вызывается перед открытием потока).

Итак, на данный момент я думаю, что метод Clip.open(stream) зависает еще до того, как он достигает точки получения входных данных из потока.

Я попытался открыть файл таким же образом, и это сработало, поэтому я полагаю, что это связано с тем, как я создаю экземпляр AudioInputStream.


person TreffnonX    schedule 05.02.2014    source источник
comment
Вы пытались выполнить отладку метода Clip.open()? Какую реализацию Clip вы используете? Как он использует объект AudioInputStream?   -  person mdewitt    schedule 06.02.2014
comment
Clip — это класс из пакета javax.sound.sampled, поэтому я не могу его напрямую отлаживать. То же самое касается AudioInputStream, поэтому я не могу ответить ни на один из приведенных выше вопросов. Я пытался разобраться в документации этих классов и их объектов, но безуспешно:/   -  person TreffnonX    schedule 06.02.2014
comment
Вы можете добавить банку из javax. к вашему пути к классу, а затем вы можете отлаживать его. Используйте jdk во время выполнения вместо jre и добавьте jr из библиотеки jdk в свой путь к классам. Но вы должны хотя бы использовать отладчик, чтобы увидеть, какая реализация Clip возвращается из AudioSystem.getClip().   -  person mdewitt    schedule 06.02.2014
comment
Кроме того, следует ли звонить clip.loop(Clip.LOOP_CONTINUOUSLY) перед тем, как звонить clip.open()? Я думаю, это может быть ваша проблема? Что произойдет, если вы измените порядок этих двух вызовов   -  person mdewitt    schedule 06.02.2014
comment
System.out.println(clip.getClass()); говорит мне: com.sun.media.sound.DirectAudioDevice$DirectClip. Я удалил цикл, но он все равно не запускается. Кроме того, я добавил это после того, как проблема уже существовала, я подумал, что, возможно, clip.open() просто заблокирует поток до тех пор, пока не будет решен, и подумал, что, возможно, ввод был слишком коротким, чтобы его можно было услышать, но это было не так =)   -  person TreffnonX    schedule 06.02.2014


Ответы (1)


Ответ заключался в том, что Clip, хотя и не вызывает напрямую метод AssembledDataLine, будет спрашивать обертку AudioInputStream, какой формат используется. В этом была моя ошибка. Я поменял местами значения FRAME_RATE и FRAME_SIZE при создании аудиоформата. Это означало, что аудиоформат был недопустимым, и поэтому клип зависал при выделении достаточного количества памяти для фактического воспроизведения входных данных.

person TreffnonX    schedule 06.02.2014