Android визуализирует данные PCM с помощью библиотеки JTransform - PullRequest
0 голосов
/ 28 мая 2018

Я пытаюсь отобразить эффект визуализации некоторых данных PCM.Цель состоит в том, чтобы отобразить что-то вроде следующего:

enter image description here

Я искал и обнаружил, что JTransform является правильной библиотекой для использования.Тем не менее, я не могу найти хорошее руководство о том, как использовать эту библиотеку.Как я могу перевести мои данные PCM в данные о полосе / частоте, которые можно использовать для рисования полос?

Большое спасибо.

1 Ответ

0 голосов
/ 28 мая 2018

PCM audio - это цифровое упрощение аналоговой кривой звука ... этот сигнал во временной области может поступать в вызов API дискретного преобразования Фурье для преобразования данных в эквивалентную ему частотную область ... мнимые числа и формула Эйлера - вашидрузья

Легкая часть - вызвать fft, он более сложен для анализа выходных данных ... заполнить буфер не менее чем 1024 (убедитесь, что его степень 2) точек от вашего PCM и просто передать это вкакой-то вызов API FFT ... это вернет вам эквивалент его частотной области ... Приколоть документ к тому вызову API дискретного преобразования Фурье, который вы используете ... Понятие предела Найквиста ... Основное представление о частотном бине ...держите под рукой количество сэмплов на буфер и частоту сэмплирования вашего звука PCM

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

Вот функция, которую я написал в golang, которая является оберткой вокруг вызова DFT, где я передаю ему необработанный звуковой буфер PCM, нормализованный в плавающийточка, которая изменяется от -1 до +1, где она выполняет вызов дискретного преобразования Фурье (fft), а затем вычисляет величину каждого частотного бина, используя массив комплексных чисел, возвращаемых из DFT ... часть проекта, которая синтезирует аудио путем просмотра видео (изображение за один раз) затем он может прослушивать этот звук для синтеза выходных изображений ... достигнутая цель, когда выходное фото в основном совпадает с входным фото ...... входное изображение -> аудио -> выходное изображение

func discrete_time_fourier_transform(aperiodic_audio_wave []float64, flow_data_spec *Flow_Spec) ([]discrete_fft, float64, float64, []float64) {

    min_freq := flow_data_spec.min_freq
    max_freq := flow_data_spec.max_freq

    //      https://www.youtube.com/watch?v=mkGsMWi_j4Q
    //      Discrete Fourier Transform - Simple Step by Step 

    var complex_fft []complex128

    complex_fft = fft.FFTReal(aperiodic_audio_wave) // input time domain ... output frequency domain of equally spaced freqs

    number_of_samples := float64(len(complex_fft))

    nyquist_limit_index := int(number_of_samples / 2)

    all_dft := make([]discrete_fft, 0) // 20171008

    /*
       0th term of complex_fft is sum of all other terms
       often called the bias shift
    */

    var curr_real, curr_imag, curr_mag, curr_theta, max_magnitude, min_magnitude float64

    max_magnitude = -999.0
    min_magnitude = 999.0
    min_magnitude = 999.0

    all_magnitudes := make([]float64, 0)

    curr_freq := 0.0
    incr_freq := flow_data_spec.sample_rate / number_of_samples

    for index, curr_complex := range complex_fft { // we really only use half this range + 1

        // if index <= nyquist_limit_index {
        if index <= nyquist_limit_index && curr_freq >= min_freq && curr_freq < max_freq {

            curr_real = real(curr_complex) // pluck out real portion of imaginary number
            curr_imag = imag(curr_complex) // ditto for im

            curr_mag = 2.0 * math.Sqrt(curr_real*curr_real+curr_imag*curr_imag) / number_of_samples

            curr_theta = math.Atan2(curr_imag, curr_real)

            curr_dftt := discrete_fft{

                real:      2.0 * curr_real,
                imaginary: 2.0 * curr_imag,
                magnitude: curr_mag,
                theta:     curr_theta,
            }

            if curr_dftt.magnitude > max_magnitude {

                max_magnitude = curr_dftt.magnitude
            }

            if curr_dftt.magnitude < min_magnitude {

                min_magnitude = curr_dftt.magnitude
            }

            // ... now stow it

            all_dft = append(all_dft, curr_dftt) 

            all_magnitudes = append(all_magnitudes, curr_mag)
        }

        curr_freq += incr_freq
    }

    return all_dft, max_magnitude, min_magnitude, all_magnitudes
}

Теперь у вас есть массив all_magnitude, где каждый элемент массива является величиной этого частотного бина ... каждый частотный бин равномерно распределен по приращению частоты, определенному выше var var incr_freq ... нормализуйте амплитуду, используя min и max_magnitude... готов к подаче в сюжет X, Yчтобы дать вам визуализацию спектрограммы

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

...