มูลค่าจริงเมื่อเสียงเรียกเข้าเป็นศูนย์เมื่อระยะห่างในช่องว่าง FFT คี่


13

ดังนั้นฉันจึงพยายามเขียน interpolator โดเมนความถี่ที่ zero-pads ตอบสนองความถี่ของสัญญาณและการแปลงผกผัน มีสองกรณีที่ฉันต้องจัดการกับ:

  1. การตอบสนองแบบยาว - ต้องแยกถังขยะเพราะมันไม่ชัดเจน ดังนั้นฉันจึงคัดลอกส่วนลบของสเปกตรัมและเพิ่มศูนย์ในระหว่างFs/2n*(interp-1)-1
  2. การตอบกลับที่มีความยาวแปลก ๆ - ไม่มีดังนั้นเพียงแยกความถี่บวก / ลบและแทรกศูนย์ระหว่างพวกเขาFs/2n*(interp-1)

รหัสที่ทำให้เกิดช่องว่างภายในสามารถดูได้ที่นี่

// 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));
    }
}

กรณีแรกทำงานได้ดีฉันกำลังทดสอบสัญญาณ chirp และมันสอดแทรกได้ดีมีสัญญาณรบกวนเล็กน้อย แต่รอบดีดขึ้นเป็น FFT คุณสามารถทำอะไรได้ (แรกหรือมากกว่านั้น สัญญาณแสดง):50μs

ปัญหาอยู่ที่การแปลงความยาวคี่ฉันได้รับการตอบสนองชั่วคราวชั่วร้ายสำหรับตัวอย่างจริงเท่านั้น (อีกครั้งจริง):50μs

ช่องจินตภาพมีระลอกคลื่นเล็ก ๆ อยู่ แต่ไม่เกือบแย่:

มันเหมือนกับว่าฉันได้เมา bin ในกรณีแปลก ๆ แต่ไม่มี bin ดังนั้นฉันก็งงมาก ใครมีความคิดบ้างF s / 2Fs/2Fs/2


แปลงของคุณดูค่อนข้างยากเนื่องจากถูกหด
Jason R

@ Jason ขอโทษฉันคิดว่าพวกเขาเชื่อมโยงฉัน tweaked html เพื่อให้พวกเขาสามารถคลิกขนาดเต็มตอนนี้
GCT

3
คุณมีรหัสหรือไฟล์ตัวอย่างสำหรับสิ่งที่คุณใช้เป็นอินพุตหรือไม่ สิ่งหนึ่งที่ต้องจำไว้คือเงื่อนไขขอบเขตที่สันนิษฐานโดย DFT โดยเฉพาะมีข้อสมมติฐานโดยธรรมชาติว่าสัญญาณของดอกเบี้ยเป็นระยะ ดังนั้นหากมีความไม่ต่อเนื่องระหว่างตัวอย่างแรกและสุดท้ายในอินพุตที่มีความยาวคี่คุณจะเห็นเสียงเรียกเข้าดังที่คุณสังเกต เป็นไปได้ว่าตัวอย่างที่มีความยาวเท่ากันนั้นมีความต่อเนื่องตั้งแต่ต้นจนจบดังนั้นคุณจะไม่เห็นปรากฏการณ์นี้
Jason R

ฉันไม่มีข้อมูลในรูปแบบที่ใคร ๆ ก็สามารถย่อยได้ง่าย แต่ฉันคิดว่าคุณพูดถูก ฉันเพิ่งมาถึงที่นี่เพื่อทำงานและคอมไพล์รหัสของฉันใหม่ / สร้างการทดสอบอินพุตใหม่ (10Hz-100Hz chirp มากกว่า 1 วินาที) และรันโค้ดอีกครั้งและไม่ได้รับเสียงเรียกเข้า ฉันเห็นความคิดเห็นของคุณและเปลี่ยนความถี่เป็น 10-100.314 และฉันเห็นเสียงเรียกเข้าในการแปลงทั้งคู่และคี่ตอนนี้
GCT

1
คุณได้ลองใช้ฟังก์ชั่นหน้าต่างกับข้อมูลของคุณหรือไม่? ปกติแล้วจะลดเสียงเรียกเข้า
MarkSci

คำตอบ:


1

คุณสามารถคูณสเปกตรัมของสัญญาณอย่างมีประสิทธิภาพด้วยฟังก์ชันสี่เหลี่ยม การทวีคูณความถี่คือการโน้มน้าวใจในเวลาและฟูริเยร์คู่ของ rect เป็นซิน ดังนั้นสิ่งที่คุณทำจริง ๆ ก็คือทำให้สัญญาณโดเมนเวลากับ sinc ที่มีความกว้างของกลีบหลักของ sinc แปรผกผันกับความยาวของ rect นี่คือเหตุผลที่เทคนิคการออกแบบตัวกรองจำนวนมากเช่นการออกแบบParks-McClellanในสิ่งที่เรียกว่าแถบ "ช่วงการเปลี่ยนภาพ" หรือ "ช่วงการเปลี่ยนภาพ" เพื่อไม่ให้มีการเปลี่ยนแปลงความถี่ในการตอบสนองความถี่ของตัวกรองทันที เทคนิคการออกแบบตัวกรองเหล่านี้มีความสำคัญเนื่องจากตัวกรอง "อุดมคติ" ที่คุณใช้มีผลกระทบที่ไม่พึงประสงค์ดังกล่าวในโดเมนเวลา


0

ขั้นตอนในโดเมนความถี่จะแสดงเป็นระลอกในโดเมนเวลา หากคุณปรับข้อมูลความถี่ของคุณให้ราบรื่นด้วยฟังก์ชั่นหน้าต่าง (เช่นหน้าต่าง Hamming) ควรลดระลอกคลื่นอย่างมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.