Как сложить оцифрованные аудиосигналы? День добрый!
Генерирую звук на определенной частоте (неважно, в виде синусоиды, пилы, треугольника) в виде массива значений double (1-максимальная амплитуда). Проигрывается норм.
Если сгенерировать несколько таких звуков на разной частоте, сложить их, обработать , то:
1) сложение с дальнейшей линейной апроксимацией в максимальную амплитуду 1 (combineWithNormalize) будет звучать корректно, но очень тихо....
2) сложение с линейной (combineWithLinearDynaRangeCompression) компрессией или логарифмической(combineWithLnDynaRangeCompression) приводят к хрипам (игрался с пороговым значением threshold).
Собственно вопрос - возможно я последующие шаги пропустил, или еще что. Что я делаю не так?
Пробовал и стартовые минисмещения добавлять при генерации исходных сигналов, чтобы минизировать появление пиков при кратных частотах и т.п.
Какие вообще существуют приемлимые алгоритмы сложения аудиосигналов из нескольких исходных с формированием итогового файла (а не онлайн игра громкостью), который например в синтезаторах используется?
Чтобы без хрипов, и в то же время не очень тихо. Может порекомендуете хорошие статьи/книги (можно англоязычные)
Спасибо заранее.
Код (неоптимизированная Java):public class Combines {
/**
* Складывает аудиосигналы + проводит постнормализацию в [-1;1]
* @param audio входные аудиосигналы
* @return сложенный аудиосигнал
*/
public static double[] combineWithNormalize( double[]... audio) {
if (audio.length == 0) return null;
if (audio.length == 1) return audio[0];
int maxIdx = 0;
// Найдем самый длинный семпл
for(double[] arr: audio)
if (arr.length > maxIdx)
maxIdx = arr.length;
// Приведем все входные семплы к максимальной длине
for(int i=0; i normalizer)
normalizer = res;
}
double coeff = 1.0/ normalizer;
if (normalizer !=1.0)
for (int i = 0; i = 1 || threshold maxIdx)
maxIdx = arr.length;
// Приведем все входные семплы к максимальной длине
for(int i=0; i = 1 || threshold maxIdx)
maxIdx = arr.length;
// Приведем все входные семплы к максимальной длине
for(int i=0; i < audio.length; i++)
if (audio[i].length < maxIdx)
audio[i] = Arrays.copyOf(audio[i], maxIdx);
double[] result = Arrays.copyOf(audio[0], maxIdx); // Нормализованный результируюший массив.
double expCoeff = alphaT[(int) threshold*100];
for (int j = 1; j < maxIdx; j++) {
double res = 0;
for (int i = 0; i < audio.length; i++)
res = res + audio[i][j];
double absRes = Math.abs(res);
if (absRes <= threshold)
result[j] = res;
else
result[j] = Math.signum(res) * (threshold + (1 - threshold) *
Math.log(1.0 + expCoeff * (absRes - threshold) / (2 - threshold)) /
Math.log(1.0 + expCoeff));
}
return result;
}
// Решение уравнений pow(1+x,1/x)=exp((1-t)/(2-t)) при t=0, 0.01, 0.02 ... 0.99
final private static double[] alphaT = {
2.51286, 2.54236, 2.57254, 2.60340, 2.63499, 2.66731, 2.70040, 2.73428, 2.76899, 2.80454,
2.84098, 2.87833, 2.91663, 2.95592, 2.99622, 3.03758, 3.08005, 3.12366, 3.16845, 3.21449,
3.26181, 3.31048, 3.36054, 3.41206, 3.46509, 3.51971, 3.57599, 3.63399, 3.69380, 3.75550,
3.81918, 3.88493, 3.95285, 4.02305, 4.09563, 4.17073, 4.24846, 4.32896, 4.41238, 4.49888,
4.58862, 4.68178, 4.77856, 4.87916, 4.98380, 5.09272, 5.20619, 5.32448, 5.44790, 5.57676,
5.71144, 5.85231, 5.99980, 6.15437, 6.31651, 6.48678, 6.66578, 6.85417, 7.05269, 7.26213,
7.48338, 7.71744, 7.96541, 8.22851, 8.50810, 8.80573, 9.12312, 9.46223, 9.82527, 10.21474,
10.63353, 11.08492, 11.57270, 12.10126, 12.67570, 13.30200, 13.98717, 14.73956, 15.56907, 16.48767,
17.50980, 18.65318, 19.93968, 21.39661, 23.05856, 24.96984, 27.18822, 29.79026, 32.87958, 36.59968,
41.15485, 46.84550, 54.13115, 63.74946, 76.95930, 96.08797, 125.93570, 178.12403, 289.19889, 655.12084
};
}

21 Авг 2019 в 06:17
203 +1
0
Ответы
1

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

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

Чтобы изучить алгоритмы сложения и обработки аудиосигналов более глубоко, вам могут помочь следующие ресурсы:

"Digital Audio Signal Processing" от Udo Zölzer - книга о цифровой обработке аудиосигналов."Introduction to Sound Processing" от Davide Rocchesso - книга об основах обработки звука.Блоги, форумы и сообщества для аудиоинженеров и звукорежиссеров, где можно найти обсуждения и рекомендации по обработке аудиосигналов.

Надеюсь, это поможет вам улучшить процесс сложения и обработки аудиосигналов. Если у вас остались конкретные вопросы или нужна дополнительная помощь, не стесняйтесь обращаться. Удачи в вашем проекте!

20 Апр в 13:20
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 92 017 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир