Многие многочисленные дубликаты этого вопроса задают вопрос о влиянии округления с плавающей запятой на конкретные числа. На практике легче понять, как это работает, глядя на точные результаты вычислений, а не просто на чтение. Некоторые языки предоставляют способы сделать это - например, преобразование 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, который заканчивается четной цифрой и, следовательно, является правильным результатом.
amix
масштабирует громкость каждого входа на 1/n
, где n = нет. активных входов. Это оценивается для каждого звукового кадра. Таким образом, когда вход выпадает, объем остальных входов уменьшается на меньшую величину, поэтому их объемы увеличиваются.
Изменение перехода dropout_ransition для всех более ранних входов, как это предлагается в других ответах, является одним из подходов, но я думаю, что это приведет к грубым модуляционным модуляциям. Лучший способ - нормализовать звук после amix.
В настоящее время у вас есть две опции: громкоговоритель или фильтр dynaudnorm . Последнее намного быстрее
Синтаксис заключается в том, чтобы добавить его после amix, поэтому
[aud11][aud12]amix=inputs=13:duration=first:dropout_transition=0,dynaudnorm"
Прочитайте документацию, если вы хотите настроить параметры для максимальной громкости или нормализации режима RMS. .etc
попытайтесь сменить переход с выбыванием на длительность первого ввода:
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
Решение, которое я нашел, это указать громкость для каждого трека в порядке «потомка» и затем не использовать фильтр нормализации.
Я использую этот пример, где я объединяю один и тот же аудиофайл в разных положениях:
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 изменяет громкость; так или иначе; Я долгое время рылся за хорошим решением.
Решение кажется комбинацией «pre-amp» или умножения, как говорит Максим, и вы должны установить dropout_transition >= max delay + max input length
(или очень высокое число):
amix=inputs=13:dropout_transition=1000,volume=13
Примечания:
amix
в любом случае должен повторно сбрасывать float, поэтому нет недостатков с добавлением фильтра volume
(который по умолчанию также перетаскивает в float ). И поскольку мы используем поплавки, нет никакой обрезки и (почти) потери точности. remix
Sox имеет переключатель -m
, который отключает настройку 1/n
. overlay
и сохраняет только окончательный выходной файл и один сегмент в памяти (тогда как ffmpeg и sox, похоже, сохраняют все сегменты в памяти). Попробуйте использовать умножение:
"amix=inputs="+ chunks.length + ":duration=first:dropout_transition=3,volume=" + chunks.length
Извините, что не отправлял вывод 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;
}