Tìm hiểu sơ lược về tín hiệu số của audio
Đầu tiên giả sử bạn đặt tần số lấy mẫu từ mic của bạn ở 8000hz, và chọn một kích thước chunk là 2048 để capture từ mic của bạn. bạn sẽ có độ phân giải tần số = 3,9063 (8000/2048). Để có được tần số của bất kỳ đỉnh nào, bạn có thể lấy như sau: freq = i * Fs / N; Trong đó freq = tần số (Hz) ...
Đầu tiên giả sử bạn đặt tần số lấy mẫu từ mic của bạn ở 8000hz, và chọn một kích thước chunk là 2048 để capture từ mic của bạn. bạn sẽ có độ phân giải tần số = 3,9063 (8000/2048).
Để có được tần số của bất kỳ đỉnh nào, bạn có thể lấy như sau:
freq = i * Fs / N;
Trong đó
freq = tần số (Hz)
i =index của peak
Fs = tần số lấy mẫu (ví dụ: 8000 Hz trong trường hợp ta đang nói đến)
N = kích thước của FFT (ví dụ: 2048 trong trường hợp ta đang nói đến)
như vậy bạn sẽ có tần số tại các đỉnh là
1 -> 3,90625 hz
2 -> 7.8125 hz
3 -> 11.71875 hz
...
1024 -> 4000 hz
...
2048 -> 8000 hz
Theo mình hiểu thì dữ liệu sẽ được mô tả bởi tập hợp các số phức ,
mỗi số phức có thể biểu đạt độ lớn của tần số
với các phần thực là ở index 2 * i,
các phần ảo nằm ở index 2 * i + 1.
Để có được độ lớn của phổ tại index i bạn làm như sau:
phần thực
real = fft [2 * i];
phần ảo
imaginary = fft [2 * i + 1];
độ mạnh của của tần số đc tính bằng modun của số phức
magnitude [i] = sqrt (real * real + imaginary * imaginary);
lưu ý nếu bạn không áp dụng một window function phù hợp với dữ liệu đầu vào miền thời gian thì bạn sẽ nhận được một lượng rò rỉ quang phổ nhất định và phổ sẽ có vẻ "bị bẩn".
Để mở rộng thêm về điều này, đây là pseudo-code cho một ví dụ hoàn chỉnh, mà mình lấy dữ liệu âm thanh và xác định tần số của đỉnh lớn nhất:
N = 1024 // size of FFT and sample window Fs = 44100 // sample rate = 44.1 kHz data[N] // input PCM data buffer fft[N * 2] // FFT complex buffer (interleaved real/imag) magnitude[N / 2] // power spectrum capture audio in data[] buffer apply window function to data[] // copy real input data to complex FFT buffer for i = 0 to N - 1 fft[2*i] = data[i] fft[2*i+1] = 0 perform in-place complex-to-complex FFT on fft[] buffer // calculate power spectrum (magnitude) values from fft[] for i = 0 to N / 2 - 1 re = fft[2*i] im = fft[2*i+1] magnitude[i] = sqrt(re*re+im*im) // find largest peak in power spectrum max_magnitude = -INF max_index = -1 for i = 0 to N / 2 - 1 if magnitude[i] > max_magnitude max_magnitude = magnitude[i] max_index = i // convert index of largest peak to frequency freq = max_index * Fs / N