scipy и numpy обратный fft возвращает комплексные числа, а не числа с плавающей точкой, не может быть сохранен как wav - PullRequest
0 голосов
/ 23 марта 2020

Я изучаю преобразования Фурье и как их использовать в python для обработки звука. Но просто взяв fft и ifft аудиоданных преобразует их в сложную форму, и я не могу сохранить его как wav. Код и ошибка приведены ниже.

    import librosa
    import scipy
    audio,sr=librosa.load("sample2.wav")
    aud_fft=scipy.fft.fft(audio)
    ref_aud=scipy.fft.ifft(aud_fft)
    librosa.output.write_wav("test.wav",ref_aud,sr)

Ошибка:

File "fft_test.py", line 6, in <module>
    librosa.output.write_wav("test.wav",ref_aud,sr)
  File "<decorator-gen-10>", line 2, in write_wav
  File "/home/vineeth/.local/lib/python3.8/site-packages/librosa/util/decorators.py", line 58, in __wrapper
    return func(*args, **kwargs)
  File "/home/vineeth/.local/lib/python3.8/site-packages/librosa/output.py", line 239, in write_wav
    util.valid_audio(y, mono=False)
  File "/home/vineeth/.local/lib/python3.8/site-packages/librosa/util/utils.py", line 264, in valid_audio
    raise ParameterError('Audio data must be floating-point')
librosa.util.exceptions.ParameterError: Audio data must be floating-point

Все, что я делаю, это беру fft, а затем беру ifft из вывода. Это должно вернуться к аудио данным, верно? Куда я иду не так или чего мне не хватает?

1 Ответ

0 голосов
/ 23 марта 2020

Это не столько проблема кода, сколько математическая проблема.

Преобразование Фурье пытается извлечь компоненты сложного сигнала. Этот сигнал может быть реальным или теоретическим. Таким образом, Фурье выдает комплексные числа с действительными и мнимыми компонентами, чтобы лучше описать сигнал в диапазоне -Гц -> + Гц. Вы хотите абсолютные значения и диапазон 0 -> + Гц для описания реального сигнала.

Чтобы ограничить ваши данные реальными компонентами, вам нужно сделать две вещи - найти абсолютные значения сложных точек данных и удалить отрицательный диапазон Гц (вторая половина выходного массива FFT).

Попробуйте выполнить следующее:

import numpy as np

number_of_datapoints = len(audio)

complex_fft=scipy.fft.fft(audio)
real_absolute_fft = 2.0/number_of_datapoints * \
                    np.abs(complex_fft[:number_of_datapoints//2])

Жонглирование с использованием 2.0/ и //2 происходит из-за идиосинкразии с нечетными и четными массивами и преобразованием Фурье.

Редактировать: Может быть полезно знать частоты вашего сигнала. Вы можете рассчитать их с помощью метода fftfreq, который требует только вашего интервала выборки и длины массива данных.

time_interval = 1/sampling_rate
frequencies = scipy.fftpack.fftfreq(number_of_datapoints, \
                                  d=time_interval)[:number_of_datapoints//2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...