Вопрос или проблема
Я искал страницы о том, как это сделать, и нашел код на C, но не на Java.
Пример на C: https://kiritchatterjee.wordpress.com/2014/11/10/a-simple-digital-low-pass-filter-in-c/
В приведенной ссылке выше не упоминаются массивы, потому что, вероятно, это делается как что-то, где аудио передается через микрофон, например, чего я не ищу сделать. Я хочу применить низкочастотный или высокочастотный фильтр к записям аудио и затем сохранить результат фильтрации.
ПРИМЕЧАНИЕ: Я просто добавляю [] рядом с массивом, чтобы сделать объяснение более наглядным для читающего.
По сути, что я хотел бы сделать, это следующее:
-
Прочитать .wav файл, используя код на Java
-
Преобразовать данные .wav в массив double [] (преобразовав массив byte [] в массив double [] с использованием библиотеки StdAudio)
-
Отсюда я хотел бы применить высокочастотный/низкочастотный фильтр к данным аудио – применив его к массиву double []
-
Когда высокочастотный или низкочастотный фильтр будет применён к массиву double [], тогда у меня в итоге получится совершенно новый массив double []
Ошибка, которую я получаю для кода в цикле for:
Оператор ‘-‘ не может быть применен к ‘double’, ‘double[]’
Другая проблема:
На самом деле я не знаю, будет ли мой код в цикле for делать низкочастотную фильтрацию аудио, даже если я не получаю ошибок.
КОД:
import StdAudio.*;
public class PassAudio
{
public static int RawData;
public static double SmoothData;
public static double LPF_Beta = 0.025; // 0<ß<1
public static void main(String[] args)
{
//читаем файл и преобразуем его в массив double
double[] music =
StdAudio.read("https://introcs.cs.princeton.edu/java/stdlib/BaseDrum.wav");
double [] lowPassedAudio = new double [music.length];
//низкочастотная фильтрация аудио
for(int i = 0; i < music.length; i++)
{
//высокочастотная/низкочастотная фильтрация данных аудио
lowPassedAudio [i] = lowPassedAudio [i] - (LPF_Beta *
(lowPassedAudio [i] - music));
}
StdAudio.play(lowPassedAudio);
}
}
В lowPassedAudio[i] = lowPassedAudio[i] - (LPF_Beta * (lowPassedAudio[i] - music));
вы пытаетесь вычесть целый массив (music
) из lowPassedAudio[i]
, который является double. Вам нужно использовать индекс для music
.
public static void main(String[] args) {
double[] music = StdAudio.read("https://introcs.cs.princeton.edu/java/stdlib/BaseDrum.wav");
double[] lowPassedAudio = new double[music.length];
lowPassedAudio[0] = music[0];
for (int i = 1; i < music.length; i++) {
lowPassedAudio[i] = lowPassedAudio[i - 1] + LPF_Beta * (music[i] - lowPassedAudio[i - 1]);
}
StdAudio.play(lowPassedAudio);
}
Ответ или решение
Чтобы выполнить фильтрацию аудиоданных с помощью низкочастотного и высокочастотного фильтра в Java, используя массивы типа double[]
, следуйте приведенным ниже шагам. Мы воспользуемся библиотекой StdAudio для чтения и воспроизведения аудиофайлов.
1. Чтение .wav файла и преобразование в массив double[]
Прежде всего, вам нужно загрузить аудиофайл и преобразовать его в массив с плавающей запятой (типа double[]
). Ниже приведён пример кода:
import StdAudio.*;
public class PassAudio {
public static double LPF_Beta = 0.025; // Коэффициент для низкочастотного фильтра
public static void main(String[] args) {
// Чтение файла и преобразование в массив double[]
double[] music = StdAudio.read("https://introcs.cs.princeton.edu/java/stdlib/BaseDrum.wav");
// Применение низкочастотного фильтра
double[] lowPassedAudio = applyLowPassFilter(music, LPF_Beta);
// Воспроизведение отфильтрованного аудио
StdAudio.play(lowPassedAudio);
}
// Метод для применения низкочастотного фильтра
public static double[] applyLowPassFilter(double[] music, double beta) {
double[] lowPassedAudio = new double[music.length];
// Начальное значение
lowPassedAudio[0] = music[0];
// Цикл для фильтрации
for (int i = 1; i < music.length; i++) {
lowPassedAudio[i] = lowPassedAudio[i - 1] + beta * (music[i] - lowPassedAudio[i - 1]);
}
return lowPassedAudio;
}
}
2. Применение высокочастотного фильтра
Аналогично, мы можем создать метод для высокочастотного фильтра, который будет использовать обратный подход, чтобы устранить низкие частоты:
// Метод для применения высокочастотного фильтра
public static double[] applyHighPassFilter(double[] music, double beta) {
double[] highPassedAudio = new double[music.length];
// Начальное значение
highPassedAudio[0] = music[0];
// Цикл для фильтрации
for (int i = 1; i < music.length; i++) {
highPassedAudio[i] = beta * (highPassedAudio[i - 1] + music[i] - music[i - 1]);
}
return highPassedAudio;
}
3. Вызов фильтров в основной программе
Вы можете вызвать оба метода фильтрации из метода main
для использования в зависимости от ваших потребностей:
public static void main(String[] args) {
// Чтение файла и преобразование в массив double[]
double[] music = StdAudio.read("https://introcs.cs.princeton.edu/java/stdlib/BaseDrum.wav");
// Применение низкочастотного фильтра
double[] lowPassedAudio = applyLowPassFilter(music, LPF_Beta);
// Воспроизведение низкочастотного аудио
StdAudio.play(lowPassedAudio);
// Применение высокочастотного фильтра
double[] highPassedAudio = applyHighPassFilter(music, LPF_Beta);
// Воспроизведение высокочастотного аудио
StdAudio.play(highPassedAudio);
}
Детали реализации
- В коде для низкочастотного фильтра используется параметр
beta
, который контролирует степень фильтрации. Значениеbeta
должно находиться в диапазоне (0, 1), где более низкие значения приведут к более сильной фильтрации. - Высокочастотный фильтр реализует простую схему, которая использует разность между текущим и предыдущим значением сигнала, чтобы выделить высокие частоты.
Заключение
Этот код предоставляет основную структуру для выполнения низкочастотной и высокочастотной фильтрации аудио в Java. Вы можете регулировать коэффициенты фильтров и настраивать фильтрацию в зависимости от ваших аудиотреков. Не забудьте добавить библиотеку StdAudio в ваш проект для успешного запуска этого кода.