Подтвердить что ты не робот

Графическое отображение высоты тона (частоты) звука

Я хочу построить шаг звука в график.

В настоящее время я могу построить амплитуду. График ниже создается данными, возвращаемыми 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;
}

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

Есть ли способ сделать это?

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Существуют Java-реализации БПФ, например: 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 принимает повторяющийся сигнал, вы можете применить window к вашему входному сигналу. Но сначала не беспокойтесь об этом.

Дополнительную информацию можно найти в Интернете, например: FFT для начинающих

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

Ответ 3

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

Вместо этого вы можете попытаться найти копию Digital Audio with Java от Craig Lindley. Я больше не думаю, что это печатает, но на моем столе есть раздел о FFT, а также пример приложения гитарного тюнера.