Использование SoX для изменения уровня громкости диапазона времени в аудиофайле

Я хочу изменить уровень громкости определенного временного диапазона / фрагмента в аудиофайле с помощью SoX.

Прямо сейчас мне нужно:

  1. Обрежьте исходный файл три раза, чтобы получить: часть до изменения звукового эффекта, часть во время (где я изменяю уровень звука) и часть после
  2. Выполните эффект, чтобы изменить уровень звука на извлеченном «среднем» фрагменте звука в его собственном файле.
  3. Соедините все вместе, принимая во внимание 5-миллисекундное перекрытие затухания / перекрестного затухания, которое рекомендует SoX

Есть ли лучший способ сделать это, не требующий написания сценария для выполнения вышеуказанного?


person Edward Ocampo-Gooding    schedule 21.11.2013    source источник
comment
Вы нашли лучшее решение? Получил аналогичную задачу, и описанное вами решение кажется единственно возможным.   -  person jdevelop    schedule 17.10.2014
comment
@jdevelop Нет, к сожалению :( В итоге мне пришлось сделать то, что я описал выше. Хотя создание сценария для решения оказалось нормальным.   -  person Edward Ocampo-Gooding    schedule 21.10.2014
comment
Я понял, что это можно сделать с помощью ffmpeg и -filter_complex   -  person jdevelop    schedule 21.10.2014


Ответы (2)


Для тех, кто наткнется на эту высоко оцененную ветку в поисках способа уклониться от середины аудиофайла:

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

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

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

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


Рабочий однострочный пример, протестированный в SoX 14.4.2 Windows:

Он затухает (утки) на -6 дБ за 2 секунды, возвращаясь к 0 дБ через 5 секунд (с использованием линейных затуханий 0,4 секунды):

sox -m -t wav "|sox -V1 inputfile.wav -t wav - fade t 0 2.2 0.4" -t wav "|sox -V1 inputfile.wav -t wav - trim 1.8 fade t 0.4 3.4 0.4 gain -6 pad 1.8" -t wav "|sox -V1 inputfile.wav -t wav - trim 4.8 fade t 0.4 0 0 pad 4.8" outputfile.wav gain 9.542

Давайте сделаем это здесь более читабельным, разбив его на разделы:

Раздел 1 = полный объем, Раздел 2 = приглушенный, Раздел 3 = полный объем

sox -m
    -t wav "|sox -V1 inputfile.wav -t wav - fade t 0 2.2 0.4" 
    -t wav "|sox -V1 inputfile.wav -t wav - trim 1.8 fade t 0.4 3.4 0.4 gain -6 pad 1.8"
    -t wav "|sox -V1 inputfile.wav -t wav - trim 4.8 fade t 0.4 0 0 pad 4.8"
    outputfile.wav gain 9.542

Теперь, чтобы разбить это, очень тщательно

'-m' .. говорит, что мы собираемся смешать (это автоматически снижает усиление, см. последний параметр)

'-t wav' .. говорит, что следующая за конвейером команда вернет WAV (похоже, что заголовок WAV теряется в конвейере)

Затем .. ПЕРВАЯ трубная часть (полный объем до утка)

'-V1' ... указывает игнорировать предупреждения - будет предупреждение о том, что длина выходного файла для этого конкретного раздела не известна, поскольку он выводится по конвейеру, но других предупреждений от этой операции быть не должно.

затем имя входного файла

'-t wav' .. принудительно устанавливает тип вывода

'-' .. - это стандартное имя передаваемого по конвейеру вывода, который возвращается в командную строку SoX.

'fade t 0 2.2 0.4'… затемняет всю часть громкости. t = линейный. 0 плавно появляется. Затем (поскольку мы хотим, чтобы промежуточная точка кроссфейда была на 2 секундах), мы исчезаем на 2,2 секунды, с затуханием на 0,4 секунды (параметр постепенного затухания предназначен для того, когда плавное затухание ЗАКОНЧИВАЕТСЯ!)

'-t wav' .. чтобы указать тип следующей части - как указано выше

Затем .. ВТОРАЯ трубопроводная часть (загнутый участок)

'-V1' .. снова, чтобы игнорировать предупреждение о длине вывода - см. выше, тогда то же имя входного файла

'-t wav' .. форсирует тип вывода, как указано выше

'-' .. для конвейерного вывода см. выше

'trim 1.8' ... потому что эта средняя часть попадет в середину перехода через 2 секунды, поэтому (с кроссфейдом 0,4 секунды) приглушенный аудиофайл начнется за 0,2 секунды до этого.

'fade t 0,4 3,4 0,4 ​​' ... для исчезновения в приглушенной части и снова для исчезновения. Итак, постепенное увеличение на 0,4. Затем (самая сложная часть), поскольку следующий кроссфейд закончится через 5,2 секунды, мы должны взять это число за вычетом обрезанного количества для этого раздела, поэтому 5,2-1,8 = 3,4 (опять же, потому что положение плавного затухания имеет дело с время окончания затухания)

"усиление -6" - это величина в дБ, на которую мы должны пригнуться

"pad 1.8" ... должен соответствовать приведенному выше значению обрезки, чтобы в начале было вставлено количество тишины, чтобы синхронизировать его при смешивании разделов.

'-t wav' .. чтобы указать тип следующей части - как указано выше

Затем .. ТРЕТЬЯ трубопроводная часть (возврат на полный уровень)

'-V1' .. снова - см. выше

тогда то же имя входного файла

-t wav '.. чтобы указать тип вывода, как указано выше

- '.. для конвейерного вывода см. выше

trim 4.8 '.. этот последний раздел начнется через 5 секунд, но (с кроссфейдом 0,4 секунды) звук начнется за 0,2 секунды до этого.

'fade t 0.4 0 0' ... просто переходите к этому разделу полной громкости. Нет исчезновения

'pad 4.8' .. должно соответствовать приведенному выше значению обрезки, как описано выше, а затем имя файла вывода.

'gain 9,542' ... выглядит сложным, но в основном, когда вы "-m" смешиваете 3 файла, SoX уменьшает громкость до 1/3 (одной трети), чтобы дать запас места.

Вместо того, чтобы победить это, мы увеличиваем до 300%. По формуле 20 * log (3) / log (10) мы получаем величину 9,542 дБ.


Если вы скопируете и вставите одну строчку куда-нибудь, вы сможете легко все увидеть, это намного менее страшно, чем объяснение!

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

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

Дайте мне знать, если помогут дополнительные разъяснения!

осциллограмма смелости

person dingles    schedule 07.10.2015
comment
Отличный ответ! Спасибо: D - person Edward Ocampo-Gooding; 08.10.2015
comment
Вы можете использовать -p вместо -t wav - внутри подкоманд и удалить -t wav перед подкомандами. Это также избавит от предупреждений, и вам не придется их игнорировать: sox -m "|sox inputfile.wav -p fade ..." "|sox inputfile.wav -p trim ..." ... - person danadam; 18.04.2019
comment
Чтобы фактически уменьшить громкость до полного отключения звука, коэффициент усиления в приведенном выше фрагменте кода следует изменить с -6 на -40. - person Pe Dro; 24.02.2020

Хорошо, с ffmpeg и фильтрами все довольно просто.

Представьте, что у вас есть 2 дорожки, A и B. И вы хотите обрезать их и что-то сделать с громкостью. Итак, решение было бы таким:

ffmpeg -y -i 1.mp3 -i 2.mp3 i f454495482c151aea8761dda.mp3 -i f5544954796af4a171f11b57.mp3 -i f754495448788e35e6123679.mp3 -i f754495448788e35e6123679.mp3 -i f85449545e646dea98e5dd19.mp3 \
-filter_complex "[0]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume='if(between(t,129.00,129.20),0.15000*(t - 129.00) + 0.03,1)':eval=frame,volume='if(between(t,129.20,181.50),-0.00057*(t - 129.20) + 0.06,1)':eval=frame,volume='if(between(t,181.50,181.60),0.40000*(t - 181.50) + 0.03,1)':eval=frame,volume='if(between(t,181.60,183.50),-0.03684*(t - 181.60) + 0.07,1)':eval=frame,volume='if(between(t,183.50,188.00),0.00000*(t - 183.50) + 0.00,1)':eval=frame,atrim=0.00:56.00,adelay=129000|129000|129000|129000,apad[0:o];[1]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume='if(between(t,0.00,134.00),0.00000*(t - 0.00) + 0.06,1)':eval=frame,atrim=0.00:134.00,apad[1:o];[0:o][1:o]amix=inputs=28,atrim=duration=185.00" -shortest -ac 2 output.mp3

который принимает 2 входных файла, преобразует оба потока в соответствующий формат, а затем применяет фильтры объема.

Синтаксис для объема прост: если время t равно между некоторым началом и концом время - затем примените фильтр громкости на основе желаемого начального уровня громкости плюс некоторый коэффициент, умноженный на разницу между временем начала и текущим временем t.

Это увеличит громкость линейно от начального до желаемого значения в диапазоне.

atrim обрежет звуковой фрагмент после регулировки громкости во всех диапазонах.

ffmpeg просто потрясающий, выражения могут быть очень сложными, и в выражениях можно использовать многие математические функции.

person jdevelop    schedule 24.10.2014
comment
Этот подход выглядит действительно интересным, но он использует ffmpeg, а также выглядит очень сложным в командной строке. Я все равно дам вам очки за ответ, но было бы лучше прочитать, если бы этот ответ был расширен с помощью переменных оболочки или чего-то еще. В любом случае спасибо за ответ! Прикольно видеть, как тайна наконец-то раскрыта. - person Edward Ocampo-Gooding; 24.10.2014
comment
Что ж, мне потребовалось 2 дня, чтобы погрузиться в этот таинственный комплекс фильтров. Я уже упростил командную строку (вы не хотите видеть, как это выглядит для 27 мр3 файлов со сложным фильтром - всего около 10 Кбайт :)) Если у вас есть еще вопросы - снимайте. - person jdevelop; 24.10.2014