2013-07-14 2 views
-1

У меня есть не так простой вопрос о Java Sound (пакет javax.sound).Гладкий звук искать

Я реализую MP3-плеер с перекрестным затуханием и плавным регулированием громкости и поиска.

Я читаю звук как поток в 4096 байтовых кусках и вычисляю позицию в милисекундах вручную.

Когда я хочу искать() (изменить базовое положение, откуда поток будет красным), я слышу действительно уродливый «прыжок» в звуковой волне. Я попробовал изучить JLayer и другие MP3-интерфейсы, но у них вообще нет функции seek(), или у них есть этот «уродливый звук».

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

У вас возникли проблемы?

Знаете ли вы решение?

Вставьте здесь пример кода, чтобы быть уверенным.

public void seek(long pPosition) 
{ 
    sourceDataLine.flush(); 

    seekIndex = (sourceDataLine.getMicrosecondPosition()/1000) - currentPositionInMilliseconds; 

} 

public long getPositionInMilliseconds() 
{ return (sourceDataLine.getMicrosecondPosition()/1000) - seekIndex; } 

«положение в миллисекундах» необходимо из-за DataLine API из javax.sound

Спасибо Я разочарован ...

+0

Звучит это неудобно? http://www.youtube.com/watch?v=5KPeirc4rqU –

ответ

0

Вы не можете создать плавный переход, если куски, которые вы хотите перевести, слишком коротки для перекрестного затухания, но вы можете устранить наихудший из артефактов с границ.

Плохой артефакт Im, ссылающийся на часто звучит как щелчок или поп, но если их много подряд, это может звучать как звук обмолота или может даже ввести определенный шаг, если интервалы регулярны , Этот вид артефакта является результатом создания произвольных блоков звука, поскольку амплитуда звука на границах может переходить от одного блока к другому или от конца блока до молчания. Существует несколько способов его устранения, наиболее распространенным из которых является перемещение границы от произвольного местоположения до ближайшего «пересечения нуля», так что больше нет скачка или разрыва. В качестве альтернативы, поскольку ваши блоки гниют друг над другом, вы можете что-то сделать, чтобы найти место, где значение блоков пересекает друг друга, предпочтительно, в том же направлении.

+0

Я пробовал это. Я попробовал совпадение и «усреднение» перехода между каждым куском, я попытался даже выравнивать прыжок «шаг» с модульной модуляцией усиления, но суть проблемы в том, что DataLine - это канал InputStream (это то, как Java это сделал, и с тех пор 3 родные библиотеки в JDX13 подписаны. JVM не позволит мне использовать звуковую карту любым другим способом). Поэтому я не могу интерполировать, потому что «я не знаю, что будет дальше» - это поток. И если я «прочитал это, сделайте интерполяцию, а затем слейте источник». Это требует времени (около 10 мс), что делает очень тяжелые звуковые скачки в быстрой пересылке ... –

+0

И поэтому я не «выхожу из источника» функцию поиска в нативную функцию, написанную на C, потому что JVM не позволит я обращаюсь к этим адресам по соображениям безопасности. –

+0

Mabye Я не знаю некоторую шумовую модуляцию, которая бы отменила «слишком много прыгающих» волн чего-то подобного. Что-то умное, что бы облегчить API. Я знаю, что это может быть сделано тяжеловесом, но это не решение, которое я ищу ... –

0

Единственный способ, которым я это знаю, - работать непосредственно с данными на уровне кадра. Вы должны «открыть» звуки, чтобы получить байты и непосредственно выполнять свои вычисления. Большинство встроенных элементов управления Java имеют степень детализации, которая затруднена размером буфера, то есть может обрабатывать только одно изменение громкости, по сути, на каждый буфер звуковых данных.

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

Я сделал «кликер-слайсер», например, который использует эквивалент клипа в качестве исходного звука. Он принимает случайные фрагменты образца и соединяет их вместе. Достаточно 16 кадров перекрывающейся интерполяции, чтобы поддерживать плавный ход звука. Использование 1/10 второго фрагмента с 16-кадровыми перекрытиями хорошо работало для создания бесконечно потокового потока из 4-секундной записи.

Я сделал Термен, который принимает места прослушивания мышки для громкости и высоты тона. Я получил его для работы довольно плавно с 30 или 40 кадрами.Трюк заключался в том, что выбивали выходы мыши-движения-слушателя и основывали элементы управления на расчетах, сделанных на этих данных, поскольку события не поступают или не обрабатываются плавно в реальном времени, создавая застежки-молнии или другие разрывы.

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