Удаление «звенящей» помехи
Вторая часть работы (она же дополнительная) заключается в том, чтобы создать файл аудиозаписи, в котором будет заметна на слух «звенящая» помеха и попробовать удалить её, используя режекторный фильтр. В качестве основы для формирования исходной записи сигнала с помехой были выбраны первые 8 секунд из песни Rednex - Cotton Eye Joe [3]. В таблице 2 приведён список используемых переменных, а в листинге 2 – исходный программный код.
Таблица 2. Список используемых переменных
Название |
Тип |
Описание |
Sample_rate |
Целочисленный |
Частота дискретизации звука |
Signal |
Двумерный массив |
Исходный двухканальный звук |
Min_freq |
Целочисленный |
Нижняя граница фильтрации |
Max_freq |
Целочисленный |
Верхняя граница фильтрации |
N_min_freq |
Целочисленный |
Индекс нижней границы фильтрации |
N_max_freq |
Целочисленный |
Индекс верхней границы фильтрации |
Fft_spectrum_input |
Двумерный массив |
Спектр входного сигнала |
Fft_spectrum_output |
Двумерный массив |
Спектр выходного сигнала |
Fft_spectrum_output_LOW |
Двумерный массив |
Спектр выходного сигнала нижних частот |
Fft_spectrum_output_HIGH |
Двумерный массив |
Спектр выходного сигнала верхних частот |
Output_signal |
Двумерный массив |
Обратно преобразованный звук |
Листинг 2. Реализация режекторного фильтра на Python
def notch_filter(min_freq: int, max_freq: int, signal, sample_rate): # Переводим Гц в индексы массива n_min_freq = int(len(signal) * min_freq/sample_rate) n_max_freq = int(len(signal) * max_freq/sample_rate)
# Создаем спектр входного и выходного сигнала fft_spectrum_input = np.fft.fft2(signal) fft_spectrum_output_LOW = np.zeros_like(fft_spectrum_input) + 10**(-10) fft_spectrum_output_HIGH = np.zeros_like(fft_spectrum_input) + 10**(-10)
# Реализация РФ for i in range(1, n_min_freq): fft_spectrum_output_LOW[i, :] = fft_spectrum_input[i, :] fft_spectrum_output_LOW[len(signal)-i, :] = fft_spectrum_input[len(signal)-i, :] for i in range(1, n_max_freq): fft_spectrum_output_HIGH[i, :] = fft_spectrum_input[i, :] fft_spectrum_output_HIGH[len(signal)-i, :] = fft_spectrum_input[len(signal)-i, :] fft_spectrum_output_LOW[0, :] = fft_spectrum_input[0, :] fft_spectrum_output_HIGH[0, :] = fft_spectrum_input[0, :] fft_spectrum_output_HIGH -= fft_spectrum_input fft_spectrum_output = fft_spectrum_output_LOW + fft_spectrum_output_HIGH
# Обратное преобразование в звук output_signal = np.real(np.fft.ifft2(fft_spectrum_output)) return output_signal
# Функция добавления помехи def create_noise(freq: int, amplitude: float, signal, sample_rate: int): duration = len(signal) / sample_rate
# Генерируем звуковой сигнал t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False) noise = np.sin(2 * np.pi * freq * t) * amplitude final_noise = np.column_stack((noise, noise)) noisy_signal = signal + final_noise return noisy_signal
# Считываем файл и создаем АЧХ signal, sample_rate = sf.read("2/extra_task_input.wav") amplitude_frequency_response(signal[:,0], sample_rate, '(исходный)')
# Добавляем помеху, создаём АЧх, сохраняем файл signal = create_noise(12000, 0.5, signal, sample_rate) amplitude_frequency_response(signal[:,0], sample_rate, '(c помехой)') sf.write("2/extra_task_noisy.wav", signal, sample_rate)
# Пропускаем сигнал через РФ и создаём АЧХ signal = notch_filter(8000, 17000, signal, sample_rate) amplitude_frequency_response(signal[:,0], sample_rate, '(после РФ)')
# Выводим получившиеся рисунки + сохраняем в файл plt.show() sf.write("2/extra_task_cleaned.wav", signal, sample_rate)
|
Далее необходимо протестировать работу данной программы на тестовой аудиозаписи. Сперва, на рисунке 3 показан исходный амплитудный спектр звукового файла.
Рисунок 3 – Исходная АЧХ записи
Далее, добавим к данной записи высокочастотную «звенящую» помеху с частотой 12 кГц. Получившийся амплитудный спектр показан на рисунке 4.
Рисунок 4 – АЧХ записи вместе с помехой
Из данного рисунка видно, что помеха очень сильно выбивается на фоне остальных частот и при прослушивании «зашумленной» записи её можно четко услышать. Далее, применим режекторный фильтр к полученной аудиозаписи с полосой 9-17 кГц и посмотрим на полученный частотный спектр, который показан на рисунке 5.
Рисунок 5 – АЧХ после применения РФ
По полученному графику видно, что верхний диапазон частот просто удалён из исходной записи. При прослушивании и сравнении оригинальной и «очищенной» записи разница присутствует, но она настолько незначительная, что это можно списать на погрешность воспроизводящей аппаратуры.
Также, был произведён эксперимент по добавлению и последующему удалению низкочастотной помехи. Так, на рисунке 6 показан амплитудный спектр с помехой на частоте 30 Гц, а на рисунке 7 – амплитудный спектр после применения РФ с частотами 20-40 Гц.
Рисунок 6 – АЧХ с помехой
Рисунок 7 – АЧХ после применения РФ
При сравнении исходного и «очищенного» аудиофайла разницу не удалось обнаружить в имеющейся звуковоспроизводящей аппаратуре. Возможно, разницу удастся услышать в более профессиональном оборудовании, но это всего лишь гипотеза, поскольку помеха находится на нижней границе восприятия человеческим ухом.
Выводы
Подводя итоги к проделанной работе, можно сделать вывод о том, что в ходе выполнения данной лабораторной работы мною были изучены основы обработки аудиосигналов на примере фильтрации сигналов в спектральном пространстве. Первым делом я исказил звук аудиофайла, удалив из него нижние частоты («басы») при помощи ФВЧ. При этом разница в качестве звука была значительной. Далее было произведено удаление звуковой помехи определённой частоты при помощи режекторного фильтра. Разницу между исходным и «очищенным» звуком в ходе 2-ух экспериментов выявить не удалось, поскольку помеха выделялась на фоне остальных частот. Однако, если бы помеха была бы на средних частотах, то изменения после применения РФ были бы более заметны