Đổ chuông có giá trị thực khi FFT có độ dài không đệm


13

Vì vậy, tôi đang cố gắng viết một bộ nội suy miền tần số không đệm cho đáp ứng tần số của tín hiệu và các biến đổi nghịch đảo. Có hai trường hợp tôi phải giải quyết:

  1. Phản hồi có độ dài bằng nhau - phải chia thùng vì nó không rõ ràng. Vì vậy, tôi sao chép phần âm của phổ và thêm các số 0 ở giữa.Fs/2n*(interp-1)-1
  2. Đáp ứng độ dài lẻ - không có thùng nên chỉ cần phân chia tần số dương / âm và chèn các số 0 giữa chúng.Fs/2n*(interp-1)

Mã không đệm ở đây có thể được nhìn thấy ở đây

// Copy negative frequency components to end of buffer and zero out middle
//  inp    - input buffer of complex floats
//    n    - transform size
//  interp - interpolation amount
void zero_pad_freq(cfloat_t *inp, size_t n, size_t interp) {
    if ((n % 2) == 0) {
        memmove(inp + n*interp - n/2, inp + n/2,     n/2*sizeof(cfloat_t));
        memset (inp + n/2 + 1, 0,       (n*(interp-1)-1)*sizeof(cfloat_t)); // Duplicate Fs/2 so we need one less zero

        inp[n/2]          /= 2.0;
        inp[n*interp-n/2] /= 2.0;
    } else {
        memmove(inp + n*interp - n/2, inp + (n+1)/2, n/2*sizeof(cfloat_t));
        memset (inp + (n+1)/2, 0,         (n*(interp-1))*sizeof(cfloat_t));
    }
}

Trường hợp đầu tiên được làm việc tốt, tôi đang thử nghiệm nó trên một tín hiệu chirp và nó nội suy tốt, có một chút tiếng ồn số, nhưng nó tròn vấp qua một FFT vì vậy những gì bạn có thể làm (lần đầu tiên hoặc lâu hơn của tín hiệu chỉ):50μs

50μs

Kênh tưởng tượng có một gợn nhỏ trên đó, nhưng gần như không tệ:

Fs/2Fs/2


Âm mưu của bạn hơi khó nhìn vì chúng đã bị thu nhỏ.
Jason R

@Jason xin lỗi tôi nghĩ rằng chúng đã được liên kết, tôi đã điều chỉnh html để chúng có thể nhấp vào kích thước đầy đủ ngay bây giờ.
gct

3
Bạn có bất kỳ mã hoặc tệp ví dụ nào cho những gì bạn đang sử dụng làm đầu vào không? Một điều cần lưu ý là các điều kiện biên được giả định bởi DFT. Cụ thể, có một giả định cố hữu rằng tín hiệu quan tâm là định kỳ. Vì vậy, nếu có sự gián đoạn giữa các mẫu đầu tiên và mẫu cuối cùng trong đầu vào có độ dài lẻ, thì bạn có thể thấy đổ chuông như những gì bạn quan sát được. Có thể là mẫu có độ dài đồng đều liên tục hơn từ đầu đến cuối, vì vậy bạn không thấy hiện tượng này.
Jason R

Tôi không có dữ liệu ở định dạng mà bất kỳ ai khác cũng có thể dễ dàng tiêu hóa, nhưng tôi nghĩ bạn đã đúng. Tôi vừa mới đến đây để làm việc và biên dịch lại mã của mình / tạo lại đầu vào kiểm tra (tiếng kêu 10Hz-100Hz trong hơn 1 giây) và chạy lại mã và không nhận được tiếng chuông. Tôi đã thấy nhận xét của bạn và thay đổi tần số thành 10-100.314 và bây giờ tôi thấy đổ chuông trên cả hai biến đổi chẵn và lẻ.
gct

1
Bạn đã thử áp dụng một chức năng cửa sổ cho dữ liệu của bạn? Điều đó thường sẽ làm giảm tiếng chuông.
MarkSci

Câu trả lời:


1

Bằng cách loại bỏ các thùng tần số cao, bạn đã nhân hiệu quả phổ của tín hiệu với hàm hình chữ nhật. Phép nhân trong tần số là tích chập trong thời gian và cặp Fourier của một trực tràng là một sự chân thành. Vì vậy, những gì bạn thực sự đã làm là kết hợp tín hiệu miền thời gian với độ rộng với độ rộng của thùy chính của tỷ lệ nghịch với chiều dài của trực tràng. Đây là lý do tại sao nhiều kỹ thuật thiết kế bộ lọc như Công viên-McClellan thiết kế trong dải được gọi là "vùng chuyển tiếp" hoặc "chuyển tiếp" để không có sự thay đổi tức thời trong đáp ứng tần số của bộ lọc. Các kỹ thuật thiết kế bộ lọc này rất quan trọng vì bộ lọc "lý tưởng" như bạn đã sử dụng có tác dụng không mong muốn như vậy trong miền thời gian.


0

Một bước trong miền tần số sẽ hiển thị dưới dạng các gợn sóng trong miền thời gian. Nếu bạn làm mịn dữ liệu tần số của mình bằng chức năng cửa sổ (ví dụ: cửa sổ Hamming), nó sẽ làm giảm đáng kể các gợn sóng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.