Перейти к позиции в аудиофайле с помощью Java Sound API - PullRequest
0 голосов
/ 19 августа 2011

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

У меня проблемы:

  • markSupported() возвращает false на мой AudioInputStream. Так что я не могу использовать мой первоначальный подход для вызова reset() затем skip() (что Я уже думал, что было некрасиво ...)
  • Я бы действительно предпочел не сносить InputStrea m и создать новый, просто чтобы перейти на позицию до моей текущей отметки.
  • SourceLineData.getLongFramePosition() не кажется очень надежным ... Я знаю, что у него есть буфер, но даже если учесть, что byte s осталось в буфере, я не понимаю поведение

Я рассмотрел использование Memory-Mapped File для подачи байтов в строку таким образом, чтобы я мог прыгать куда угодно, но я не хочу добавлять сложность к функции, если у меня нет к. Есть ли хороший способ сделать это, что я скучаю? также кто-нибудь может объяснить, что на самом деле означает номер кадра, возвращаемый getLongFramePosition()? это количество кадров, пропущенных через динамики (не похоже)?

Ответы [ 2 ]

1 голос
/ 15 сентября 2011

Самым чистым способом, который я мог придумать, было использование FileChannel для считывания байтов в SourceDataLine таким образом, основываясь на том, что пользователь перемещал ползунок, и я мог определить позицию байта в файле (не забудьте настроить или округлите его, чтобы выровнять по кадру), затем установите это положение в FileChannel и затем продолжите воспроизведение. Я очистил линию, когда это не позволило воспроизвести оставшиеся байты.

1 голос
/ 23 августа 2011

BigClip работал на вас?

Если нет, то вот что может сработать. Предупреждение, это маленький запутанный. http://hexara.com/VSL/VSL2.htm

С помощью этого апплета вы можете загрузить wav - я загрузил wavs дольше 5 минут, и он работал нормально, но аудиоданные действительно занимают много оперативной памяти.

После загрузки WAV вы можете навести курсор мыши на любую точку и воспроизвести, удерживая ее нажатой и перетаскивая. Очевидно, это не совсем то, что ВЫ хотите сделать, так как вы хотите воспроизвести с точки, а не беспокоиться о перетаскивании или скорости перетаскивания. Но путь, который я выбрал, чтобы привести данные в воспроизводимое состояние, все равно должен работать для вас.

Если у вас есть работающие AudioInputStream и AudioFileFormat, вы можете настроить внутренний массив и считывать данные непосредственно в него. Формат аудиофайла дает вам кодировку и длину в кадрах, которые вы можете использовать для расчета размера вашего массива.

Затем создайте TargetDataLine, который получает свои аудиоданные из созданного вами массива. TDL должен иметь переменную, которая отмечает, где начнется следующее чтение. Вы можете использовать свой JSlider, чтобы изменить содержимое этой переменной так, чтобы она указывала на любой желаемый кадр.

Если у вас нет рабочего AudioInputStream, есть способы его получить ... но он более запутанный, включая объекты ByteArrayOutput и Input Stream. Наверное, нет необходимости идти туда. (Я использую их для чтения данных клиента в вышеупомянутом апплете.)

Что касается вашего вопроса о текущем расположении фрейма, ключевая проблема заключается в том, что JVM обрабатывает аудиоданные порциями и имеет тенденцию опережать то, что слышно в пакетах. Я долго бился об эту проблему, потом придумал: http://www.java -gaming.org / index.php / тема, 24605.0.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...