почему изменился объем после слияния? в ffmpeg. Как отключить объем изменения [дубликат]

Многие многочисленные дубликаты этого вопроса задают вопрос о влиянии округления с плавающей запятой на конкретные числа. На практике легче понять, как это работает, глядя на точные результаты вычислений, а не просто на чтение. Некоторые языки предоставляют способы сделать это - например, преобразование float или double в BigDecimal в Java.

Так как это вопрос, связанный с языком, ему нужны языковые агностические инструменты, такие как как Десятичный преобразование с плавающей запятой .

Применяя его к числам в вопросе, рассматриваемым как удваивает:

0,1 преобразуется в 0,1000000000000000055511151231257827021181583404541015625,

0,2 преобразуется в 0.200000000000000011102230246251565404236316680908203125,

0,3 конвертируется в 0,29999999999999999989897769753748434595763683319091796875 и

0,30000000000000004 преобразуется в 0,3000000000000000444089209850062616169452667236328125.

Добавление первых двух чисел вручную или в десятичный калькулятор, такой как Full Precision Calculator , показывает точную сумму фактических входов: 0.3000000000000000166533453693773481063544750213623046875.

Если округлить до эквивалента 0,3, ошибка округления будет 0.0000000000000000277555756156289135105907917022705078125. Округление до эквивалента 0,30000000000000004 также дает ошибку округления 0,0000000000000000277555756156289135105907917022705078125.

Возвращаясь к конвертеру с плавающей запятой, необработанный шестнадцатеричный показатель для 0.30000000000000004 равен 3fd3333333333334, который заканчивается четной цифрой и, следовательно, является правильным результатом.

2
задан Stan Reshetnyk 19 February 2016 в 16:53
поделиться

6 ответов

amix масштабирует громкость каждого входа на 1/n, где n = нет. активных входов. Это оценивается для каждого звукового кадра. Таким образом, когда вход выпадает, объем остальных входов уменьшается на меньшую величину, поэтому их объемы увеличиваются.

Изменение перехода dropout_ransition для всех более ранних входов, как это предлагается в других ответах, является одним из подходов, но я думаю, что это приведет к грубым модуляционным модуляциям. Лучший способ - нормализовать звук после amix.

В настоящее время у вас есть две опции: громкоговоритель или фильтр dynaudnorm . Последнее намного быстрее

Синтаксис заключается в том, чтобы добавить его после amix, поэтому

[aud11][aud12]amix=inputs=13:duration=first:dropout_transition=0,dynaudnorm"

Прочитайте документацию, если вы хотите настроить параметры для максимальной громкости или нормализации режима RMS. .etc

5
ответ дан Gyan 25 August 2018 в 03:48
поделиться

попытайтесь сменить переход с выбыванием на длительность первого ввода:

duration=first:dropout_transition=_duration_of_the_first_input_in_seconds_

вот моя команда ffmpeg:

ffmpeg -y -i long.wav -i short.wav  -filter_complex "[1:a]adelay=6000|6000[a1];[1:a]adelay=10000|10000[a2];[1:a]adelay=14000|14000[a3];[1:a]adelay=18000|18000[a4];[1:a]adelay=21000|21000[a5];[1:a]adelay=25500|25500[a6];[0:a][a1][a2][a3][a4][a5][a6]amix=inputs=7:duration=first:dropout_transition=32[aout]" -map "[aout]" -ac 2 -b:a 192k -ar 44100 output.mp3

см. два перехода с выпадением в виде Скриншот

0
ответ дан CAHbKA 25 August 2018 в 03:48
поделиться

Решение, которое я нашел, это указать громкость для каждого трека в порядке «потомка» и затем не использовать фильтр нормализации.

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

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

Подробнее см. это изображение. Первый трек - обычное микширование, второе - с указанными томами; третий - оригинальный трек. Как мы видим, 2-й трек выглядит нормально.

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0[a];[1]adelay=2000|2000[b];[2]adelay=4000|4000[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-no-volume.mp3

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

Я не могу понять, почему amix изменяет громкость; так или иначе; Я долгое время рылся за хорошим решением.

0
ответ дан klodoma 25 August 2018 в 03:48
поделиться

Решение кажется комбинацией «pre-amp» или умножения, как говорит Максим, и вы должны установить dropout_transition >= max delay + max input length (или очень высокое число):

amix=inputs=13:dropout_transition=1000,volume=13

Примечания:

  • amix в любом случае должен повторно сбрасывать float, поэтому нет недостатков с добавлением фильтра volume (который по умолчанию также перетаскивает в float ). И поскольку мы используем поплавки, нет никакой обрезки и (почти) потери точности.
  • H't to @Mulvya для анализа, но их решение расстраивает не математическое
  • Я изначально пытался сделать это с помощью sox , который был слишком медленным. Фильтр remix Sox имеет переключатель -m, который отключает настройку 1/n.
  • Хотя быстрее ffmpeg использует больше памяти для одной и той же задачи. YMMV - я не тестировал это полностью, потому что я, наконец, остановился на небольшом скрипте python, который использует функцию pydub overlay и сохраняет только окончательный выходной файл и один сегмент в памяти (тогда как ffmpeg и sox, похоже, сохраняют все сегменты в памяти).
0
ответ дан kubi 25 August 2018 в 03:48
поделиться

Попробуйте использовать умножение:

"amix=inputs="+ chunks.length + ":duration=first:dropout_transition=3,volume=" + chunks.length
2
ответ дан Maxim Firsoff 25 August 2018 в 03:48
поделиться

Извините, что не отправлял вывод ffmpeg.

В конце концов, мы закончили тем, что написали небольшую утилиту на C ++ для микширования аудио. Но сначала мы преобразовали формат mp4 в raw (pcm). Это отлично подходит для нас, даже требует дополнительного места для жестких дисков для промежуточных промежуточных файлов.

Код выглядит так:

short addSounds(short a, short b) {
    double da = a;
    da /= 65536.0;
    da += 0.5;
    double db = b;
    db /= 65536.0;
    db += 0.5;
    double z = 0;
    if (da < 0.5 && db < 0.5) {
        z = 2 * da*db;
    }
    else {
        z = 2 * ( da + db ) - 2 * da* db - 1;
    }
    z -= 0.5;
    z *= 65536.0;
    return (short)z;
}
1
ответ дан Stan Reshetnyk 25 August 2018 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: