Фильтрация и искажение аудио, хранящегося в байтовом массиве Java

Я еще не начал кодировать раздел, но мне было интересно, знал ли кто-нибудь о решении для этого/имеет ли какие-либо источники, которые были бы для него полезны.

Я пытаюсь эмулировать насыщение ленты на массиве байтов 44,1 кГц PCM 16-битных (с прямым порядком байтов) аудиоданных, которые уже были записаны (у меня уже есть класс записи, готовый и работающий). Я хочу исказить и отфильтровать байты данных, чтобы имитировать звук ленты.

Теоретически, я думаю, нам нужно использовать симметричное мягкое отсечение для искажения (я просмотрел пример на странице 118 в этом учебнике для цифрового аудио FX, я просто понятия не имею, как это реализовать: https://books.google.it/books?id=h90HIV0uwVsC&printsec=frontcover&hl=en#v=onepage&q&f=false), а затем отфильтровать весь сигнал с помощью фильтра нижних частот?

Я не уверен, с чего начать, но если вы знаете какие-либо решения, которые можно преобразовать в функцию, я был бы очень признателен.


person owain    schedule 17.03.2020    source источник
comment
Что касается обработки звука в Java, Jipes может быть полезен, хотя он выглядит посредственно для этой цели. . Что касается того, как сделать часть DSP, я бы задал этот вопрос на dsp.stackexchange.com   -  person Hendrik    schedule 18.03.2020


Ответы (1)


Необходимые элементы:

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

Я не знаю, какой лучший алгоритм искажения может быть для ваших целей. В бесплатной книге DSP Related есть ряд предложений Физическая обработка аудиосигнала. Я помню, что в CCRMA Стэнфордского университета тоже было несколько интересных статей на эту тему, но у меня нет ссылок удобный.

Моим любимым искажением является функция tanh. Ниже приведен код Java, который я использую для синтезированного патча с довольно густым гитарным искажением:

float distortVal = (float)Math.tanh(noteVal * (1 + timbreNormal * 5));

В этом случае noteVal — это одно значение PCM. У меня есть переменная timbreNormal в диапазоне от 0 до 1, и я считываю ее с эквивалента контроллера ножной педали. Значение антипаттерна «магическое число» 5 — это константа, которую я лениво вставил. Она определяет максимальную величину, на которую усиливается сигнал перед применением алгоритма искажения. Какой бы алгоритм искажения вы ни использовали, интенсивность искажения будет зависеть от степени усиления сигнала перед применением алгоритма. Если вам нужен более тонкий эффект, значение «магического числа» можно установить ниже.

Передискретизация очень помогает на этапе фильтрации. Я передискретизировал на 8 и использую двухполюсный фильтр Баттерворта. Мне пришлось бы серьезно покопаться, чтобы найти значения, используемые в конструкции фильтра. Но я думаю, что вы можете понять суть программы из этого ответа.

person Phil Freihofner    schedule 18.03.2020