2012-04-19 60 views
6

Vì vậy, tôi đã làm việc với FFT, và tôi hiện đang cố gắng để có được một dạng sóng âm thanh từ một tập tin với FFT, (sửa đổi nó cuối cùng), nhưng sau đó đầu ra sửa đổi dạng sóng trở lại một tập tin. Tôi đã nhận được FFT của soundwave và sau đó sử dụng một chức năng FFT nghịch đảo trên nó, nhưng các tập tin đầu ra không âm thanh ở tất cả. Tôi đã không thực hiện bất kỳ lọc trên dạng sóng - Tôi chỉ kiểm tra ra nhận được dữ liệu tần số và sau đó đưa nó trở lại vào một tập tin - nó sẽ âm thanh giống nhau, nhưng nó âm thanh cực kỳ khác nhau. Bất kỳ ý tưởng?Python NumPy - FFT và FFT nghịch đảo?

- EDIT -

Tôi đã làm việc trong dự án này một chút nhưng chưa nhận được kết quả mong muốn. Các tập tin âm thanh xuất ra là ồn ào (cả lớn hơn, cũng như tiếng ồn thêm không có trong tập tin gốc), và âm thanh từ một kênh bị rò rỉ vào kênh khác (trước đây đã bị tắt tiếng). Tệp âm thanh đầu vào là tệp âm thanh nổi, 2 kênh có âm thanh chỉ phát ra từ một kênh. Đây là mã của tôi:

import scipy 
import wave 
import struct 
import numpy 
import pylab 

from scipy.io import wavfile 

rate, data = wavfile.read('./TriLeftChannel.wav') 

filtereddata = numpy.fft.rfft(data, axis=0) 

print (data) 

filteredwrite = numpy.fft.irfft(filtereddata, axis=0) 

print (filteredwrite) 

wavfile.write('TestFiltered.wav', rate, filteredwrite) 

Tôi không hiểu tại sao điều này không hiệu quả ...?

EDIT: Tôi đã nén lên tệp .py và tệp âm thanh có vấn đề, nếu điều đó có thể giúp giải quyết vấn đề here.

+3

thử thêm 'filterwrite = numpy.round (filterwrite) .astype ('int16')' trước khi bạn lưu –

+0

@Bago - Cảm ơn rất nhiều! Điều đó hoàn toàn khắc phục được vấn đề. Tôi đã tự hỏi, không buộc ifft lọc để 'int16' có nghĩa là nó sẽ là một tập tin âm thanh sâu 16-bit? – SolarLune

+0

Tôi không biết nhiều về các tệp wav, tôi luôn cho rằng chúng là dữ liệu thô, không nén, nhưng bạn sẽ phải đọc kỹ thông số định dạng wav để biết chắc chắn. –

Trả lời

4
>>> import numpy as np 
>>> a = np.vstack([np.ones(11), np.arange(11)]) 

# We have two channels along axis 0, the signals are along axis 1 
>>> a 
array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], 
     [ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1) 
array([[ 1.1  , 1.1  , 1.1  , 1.1  , 
      1.1  , 1.1  , 1.1  , 1.1  , 
      1.1  , 1.1  ], 
     [ 0.55  , 1.01836542, 2.51904294, 3.57565618, 
      4.86463721, 6.05  , 7.23536279, 8.52434382, 
      9.58095706, 11.08163458]]) 
# irfft returns an even number along axis=1, even though a was (2, 11) 

# When a is even along axis 1, we get a back after the irfft. 
>>> a = np.vstack([np.ones(10), np.arange(10)]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1) 
array([[ 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00], 
     [ 7.10542736e-16, 1.00000000e+00, 2.00000000e+00, 
      3.00000000e+00, 4.00000000e+00, 5.00000000e+00, 
      6.00000000e+00, 7.00000000e+00, 8.00000000e+00, 
      9.00000000e+00]]) 

# It seems like you signals are along axis 0, here is an example where the signals are on axis 0 
>>> a = np.vstack([np.ones(10), np.arange(10)]).T 
>>> a 
array([[ 1., 0.], 
     [ 1., 1.], 
     [ 1., 2.], 
     [ 1., 3.], 
     [ 1., 4.], 
     [ 1., 5.], 
     [ 1., 6.], 
     [ 1., 7.], 
     [ 1., 8.], 
     [ 1., 9.]]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=0), axis=0) 
array([[ 1.00000000e+00, 7.10542736e-16], 
     [ 1.00000000e+00, 1.00000000e+00], 
     [ 1.00000000e+00, 2.00000000e+00], 
     [ 1.00000000e+00, 3.00000000e+00], 
     [ 1.00000000e+00, 4.00000000e+00], 
     [ 1.00000000e+00, 5.00000000e+00], 
     [ 1.00000000e+00, 6.00000000e+00], 
     [ 1.00000000e+00, 7.00000000e+00], 
     [ 1.00000000e+00, 8.00000000e+00], 
     [ 1.00000000e+00, 9.00000000e+00]]) 
6
  1. Bạn dường như không được áp dụng bất kỳ bộ lọc ở đây
  2. Bạn có thể muốn lấy ifft của fft (sau lọc), chứ không phải của dạng sóng đầu vào.
4

Không được giống như thế này?

filtereddata = numpy.fft.fft(data) 
# do fft stuff to filtereddata 
filteredwrite = numpy.fft.ifft(filtereddata) 
wavfile.write('TestFiltered.wav', rate, filteredwrite) 
+0

@wim - Xin lỗi về điều đó - đã chỉnh sửa bài đăng gốc của tôi để có thêm thông tin. – SolarLune

2

Hai vấn đề.

Bạn đang FFTING 2 dữ liệu kênh. Bạn chỉ nên FFT 1 kênh dữ liệu đơn sắc cho các kết quả FFT để có ý nghĩa thông thường. Nếu bạn muốn xử lý 2 kênh dữ liệu âm thanh nổi, bạn nên IFFT (FFT()) mỗi kênh riêng biệt.

Bạn đang sử dụng một fft thực, mà ném đi thông tin, và do đó làm cho fft không thể đảo ngược.

Nếu bạn muốn đảo ngược, bạn sẽ cần sử dụng FFT tạo kết quả phức tạp, sau đó IFFT vector miền tần số phức tạp này quay lại miền thời gian. Nếu bạn sửa đổi vector miền tần số, hãy đảm bảo nó vẫn liên hợp đối xứng nếu bạn muốn có kết quả thực sự nghiêm ngặt (trừ nhiễu số).

+0

bạn có thể fft dữ liệu đa kênh, bạn chỉ cần sử dụng mảng 2d và đảm bảo rằng từ khóa trục được đặt chính xác (-1 theo mặc định) và 'irfft (rfft (n)) 'sẽ trả về n (trong độ chính xác của máy)). –

+0

* 'irfft (rfft (n))' có vẻ là hành vi tốt nhất nếu n.shape [trục] là chẵn. –

+0

@Bago - Xin lỗi vì đã mất quá nhiều thời gian để thực hiện việc này, nhưng bạn có thể mở rộng một chút về ý bạn không? Bạn có ý nghĩa gì khi 'sử dụng một mảng 2d'? Bạn có nghĩa là một mảng NumPy, phải không? – SolarLune