У меня есть сырые данные 16 бит 48 кГц PCM. Мне нужно убрать все данные, которые находятся вне диапазона человеческого слуха.
Сейчас я просто делаю сумму всех сэмплов, а затем делю их на количество сэмплов, чтобы рассчитать пиковый уровень звука, но мне нужно уменьшить количество ложных срабатываний.
У меня все время большой пиковый уровень, говорящие и другие звуки, которые я слышу, увеличивая уровни лишь немного, поэтому мне нужно применить некоторую фильтрацию. Я совсем не знаком с обработкой звука, поэтому в настоящее время я не использую никакой фильтрации, потому что я не понимаю, как ее создать. Мой текущий код выглядит так:
for(size_t i = 0; i < buffer.size(); i++)
level += abs(buffer[i]);
level /= buffer.size();
Как я могу реализовать этот вид фильтрации с помощью C ++?
Использовать полосовой фильтр.
Полосовой фильтр — это устройство, которое пропускает частоты в пределах
определенный диапазон и отклоняет (ослабляет) частоты за пределами этого диапазона.
Это похоже на тот фильтр, который вы ищете.
У меня был быстрый поиск в Google и нашел этот поток, который обсуждает реализацию в C ++.
Звучит так, будто вы хотите что-то сделать (возможно, начать запись), если уровень звука превышает определенный порог. Это иногда называют «воротами». Это также звучит так, как будто у вас проблемы с ложными срабатываниями. Иногда это делается с помощью «боковой цепи», применяемой к воротам.
Общий принцип гейта состоит в том, чтобы создать огибающую вашего сигнала, а затем контролировать конверт, чтобы определить, когда он превышает определенный порог. Если оно превышает пороговое значение, ваши ворота «включены», если нет — ваши ворота «выключены». Если вы обрабатываете свой сигнал до создания огибающей каким-либо образом, чтобы сделать его более или менее чувствительным к различным частям вашего сигнала / шума, это называется «боковой цепью».
Вам придется узнать подробности самостоятельно, потому что слишком много для Q&Сайт, но, может быть, этого достаточно для начала:
float[] buffer; //defined elsewhere
float HOLD = .9999 ; //there are precise ways to compute this, but experimentation might work fine
float THRESH = .7 ; //or whatever
float env = 0; //we initialize to 0, but in real code be sure to save this between runs
for(size_t i = 0; i < buffer.size(); i++) {
// side-chain, if used, goes here
float b = buffer[i];
// create envelope:
float tmp = abs(b); // you could also do buffer[i] * buffer[i]
env = env * HOLD + tmp * (1-HOLD);
// threshold detection
if( env > THRESH ) {
//gate is "on"} else {
//gate is "off"}
}
Боковая цепь может состоять из фильтров, таких как эквалайзер. Вот учебник по разработке аудио эквалайзера: http://blog.bjornroche.com/2012/08/basic-audio-eqs.html