График высоты звука (частоты) звука - PullRequest
34 голосов
/ 17 января 2011

Я хочу отобразить высоту звука в графике.

В настоящее время я могу построить амплитуду. График ниже создан из данных, возвращаемых getUnscaledAmplitude():

alt text

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(file)));
byte[] bytes = new byte[(int) (audioInputStream.getFrameLength()) * (audioInputStream.getFormat().getFrameSize())];
audioInputStream.read(bytes);

// Get amplitude values for each audio channel in an array.
graphData = type.getUnscaledAmplitude(bytes, 1);


public int[][] getUnscaledAmplitude(byte[] eightBitByteArray, int nbChannels)
{
    int[][] toReturn = new int[nbChannels][eightBitByteArray.length / (2 * nbChannels)];
    int index = 0;

    for (int audioByte = 0; audioByte < eightBitByteArray.length;)
    {
        for (int channel = 0; channel < nbChannels; channel++)
        {
            // Do the byte to sample conversion.
            int low = (int) eightBitByteArray[audioByte];
            audioByte++;
            int high = (int) eightBitByteArray[audioByte];
            audioByte++;
            int sample = (high << 8) + (low & 0x00ff);

            toReturn[channel][index] = sample;
        }
        index++;
    }

    return toReturn;
}

Но мне нужно показать высоту звука, а не амплитуду. Быстрое преобразование Фурье , кажется, получает высоту тона, но ему нужно знать больше переменных, чем у необработанных байтов, и это очень сложно и математически.

Есть ли способ, которым я могу это сделать?

Ответы [ 3 ]

48 голосов
/ 17 января 2011

Частота (объективная метрика) - это не то же самое, что шаг (субъективная величина). В общем, обнаружение основного тона - очень сложная проблема.

Предполагая, что на данный момент вы просто хотите построить график частотного отклика, у вас нет другого выбора, кроме как использовать БПФ, поскольку это THE метод для получения частотного отклика данных во временной области. (Ну, есть и другие методы, такие как дискретное косинусное преобразование, но они так же сложны в реализации и более сложны для интерпретации).

Если вы боретесь с реализацией БПФ, обратите внимание, что это действительно просто эффективный алгоритм для вычисления дискретного преобразования Фурье (ДПФ); см. http://en.wikipedia.org/wiki/Discrete_Fourier_transform. Базовый алгоритм DFT намного проще (всего два вложенных цикла), но работает на лот медленнее (O (N ^ 2), а не O (N log N)).

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

23 голосов
/ 17 января 2011

Быстрое преобразование Фурье не должно знать больше, чем ваши входные байты. Не пугайтесь статьи из Википедии. Алгоритм FFT будет принимать ваш входной сигнал (при использовании общих алгоритмов FFT число выборок должно быть степенью 2, например 256, 512, 1024) и возвращать вектор комплексных чисел с одинаковым размером. Поскольку ваши входные данные действительны, а не сложны (мнимая часть установлена ​​на ноль), возвращаемый вектор будет симметричным. Только половина из них будет содержать данные. Поскольку вам не важна фаза, вы можете просто взять величину комплексных чисел, которая равна sqrt (a ^ 2 + b ^ 2). Может также сработать просто взять абсолютное значение комплексного числа, в некоторых языках это эквивалентно предыдущему выражению.

Доступны Java-реализации FFT, например: http://www.cs.princeton.edu/introcs/97data/FFT.java.html

Псевдокод будет выглядеть примерно так:

Complex in[1024];
Complex out[1024];
Copy your signal into in
FFT(in, out)
for every member of out compute sqrt(a^2+b^2)
To find frequency with highest power scan for the maximum value in the first 512 points in out

Выход будет содержать значения для частот от нуля до половины частоты дискретизации.

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

Более подробную информацию можно найти в Интернете, например: БПФ для начинающих

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

2 голосов
/ 17 января 2011

Есть несколько другие вопросы по stackoverflow об этой проблеме.Возможно, это поможет.

Вместо этого вы можете попытаться найти копию Digital Audio с Java Крейга Линдли.Я не думаю, что это больше напечатано, но копия на моем столе имеет раздел о БПФ, а также пример приложения гитарного тюнера.

...