วิธี resample เสียงโดยใช้ FFT หรือ DFT


12

ฉันทำการสุ่มตัวอย่างเสียงด้วยการแสดง FFT ก่อนจากนั้นจึงนำเฉพาะส่วนของผลลัพธ์ที่ฉันต้องการจากนั้นจึงแสดง FFT ที่ตรงกันข้าม อย่างไรก็ตามมันทำงานได้อย่างถูกต้องเมื่อฉันใช้ความถี่ที่มีทั้งสองกำลังพูดตัวอย่างจาก 32768 ถึง 8192 ฉันทำการ FFT กับข้อมูล 32k ทิ้ง 3/4 ของข้อมูลแล้วทำ FFT ผกผันในส่วนที่เหลือ 1/4

อย่างไรก็ตามเมื่อใดก็ตามที่ฉันพยายามทำสิ่งนี้กับข้อมูลที่ไม่สอดคล้องกันหนึ่งในสองสิ่งที่เกิดขึ้น: ห้องสมุดคณิตศาสตร์ที่ฉันใช้ (Aforge.Math) โดยใช้แบบเต็มเพราะตัวอย่างของฉันไม่ใช่พลังของทั้งสอง ถ้าฉันพยายามทำให้แผ่นตัวอย่างเป็นศูนย์เพื่อให้พวกมันกลายเป็นพลังของ twos มันจะพูดพล่อยๆที่ปลายอีกด้าน ฉันพยายามใช้ DFT แทน แต่มันก็ช้าลงอย่างบ้าคลั่ง (ต้องทำแบบเรียลไทม์)

ฉันจะไปยังศูนย์ข้อมูล FFT อย่างถูกต้องทั้งใน FFT เริ่มต้นและ FFT ผกผันในตอนท้ายได้อย่างไร สมมติว่าฉันมีตัวอย่างที่ 44.1 กิโลเฮิร์ตซ์ที่ต้องไปถึง 16 กิโลเฮิร์ตซ์ตอนนี้ฉันลองแบบนี้ตัวอย่างที่มีขนาด 1,000

  1. แพดข้อมูลอินพุตที่ 1024 ในตอนท้าย
  2. ดำเนินการ FFT
  3. อ่าน 512 รายการแรกในอาร์เรย์ (ฉันต้องการเพียง 362 ตัวแรก แต่ต้องการ ^ 2)
  4. ดำเนินการ FFT แบบผกผัน
  5. อ่าน 362 รายการแรกในบัฟเฟอร์การเล่นเสียง

จากนี้ฉันก็ทิ้งขยะในตอนท้าย ทำสิ่งเดียวกัน แต่ไม่ต้องติดแผ่นในขั้นตอนที่ 1 และ 3 เนื่องจากตัวอย่างที่มีอยู่แล้วเป็น ^ 2 จะให้ผลลัพธ์ที่ถูกต้อง

c#  audio 

9
FFT ไม่ใช่วิธีที่ถูกต้องในการทำเช่นนี้ คุณต้องการตัวกรองโพลีเฟสสำหรับประสิทธิภาพสูงสุด แต่ถ้าคุณแค่ต้องการแก้ปัญหาให้เพิ่มอัพตัวอย่างแรกไปที่ GCD จากนั้นผ่านไปต่ำ ๆ แล้วลดขนาดตัวอย่างลง
Bjorn Roche

สวัสดี Bjorn: "GCD" คืออะไร?
SpeedCoder5

คำตอบ:


16

ขั้นตอนแรกคือการยืนยันว่าทั้งอัตราตัวอย่างเริ่มต้นของคุณและอัตราตัวอย่างเป้าหมายของคุณสรุปตัวเลข เนื่องจากเป็นจำนวนเต็มจึงเป็นจำนวนตรรกยะโดยอัตโนมัติ หากหนึ่งในนั้นไม่ได้เป็นจำนวนตรรกยะก็ยังคงเป็นไปได้ที่จะทำการเปลี่ยนแปลงอัตราตัวอย่าง แต่มันเป็นกระบวนการที่แตกต่างกันมากและยากขึ้น

ขั้นตอนต่อไปคือการคำนึงถึงอัตราตัวอย่างสองอัตรา อัตราตัวอย่างเริ่มต้นในกรณีนี้คือ 44100 ซึ่งปัจจัยที่ 2 อัตราตัวอย่างเป้าหมาย 16000, ปัจจัยที่ 3 ดังนั้นการแปลงจากอัตราตัวอย่างเริ่มต้นกับอัตราเป้าหมายที่เราจะต้องฆ่าทิ้งโดยและตีความโดย 52 7 * 5 3 3 2 * 7 2 2 5 * 52232527227533272255

ขั้นตอนก่อนหน้านี้จะต้องทำไม่ว่าคุณต้องการที่จะสุ่มข้อมูล ตอนนี้เรามาพูดถึงวิธีการทำกับ FFT เคล็ดลับในการ resampling กับ FFT อีกครั้งคือการเลือกความยาว FFT ที่ทำให้ทุกอย่างออกมาดี นั่นหมายถึงการเลือกความยาว FFT ที่เป็นอัตราการทำลายล้างจำนวนมาก (441 ในกรณีนี้) เพื่อประโยชน์ของตัวอย่างลองเลือกความยาว FFT ที่ 441 แม้ว่าเราจะได้เลือก 882 หรือ 1323 หรือผลคูณบวกอื่น ๆ ของ 441

เพื่อให้เข้าใจว่ามันทำงานอย่างไรมันช่วยในการมองเห็นมัน คุณเริ่มต้นด้วยสัญญาณเสียงที่มีลักษณะเหมือนในโดเมนความถี่บางอย่างเช่นรูปด้านล่าง อัตราตัวอย่าง 44.1 kHz

เมื่อคุณทำการประมวลผลเสร็จแล้วคุณต้องการลดอัตราตัวอย่างเป็น 16 kHz แต่คุณต้องการความเพี้ยนน้อยที่สุด คุณต้องการเก็บทุกอย่างจากภาพด้านบนจาก -8 kHz ถึง +8 kHz และปล่อยทุกอย่างอื่น ผลลัพธ์ในภาพด้านล่าง ป้อนคำอธิบายรูปภาพที่นี่

โปรดทราบว่าอัตราตัวอย่างไม่ได้ปรับขนาดพวกเขาอยู่ที่นั่นเพียงเพื่อแสดงแนวคิด

ความงามของการเลือกความยาว FFT ที่เป็นปัจจัยการทำลายล้างหลายประการคือคุณสามารถสุ่มตัวอย่างใหม่ได้ง่ายๆโดยการวางส่วนของผลลัพธ์ FFT จากนั้นจึงย้อนกลับ FFT ที่เหลืออยู่ ในกรณีของตัวอย่างของเราคุณตัวอย่างข้อมูล FFT 441 ซึ่งทำให้คุณได้รับตัวอย่างที่ซับซ้อน 441 โดเมนในโดเมนความถี่ เราต้องการที่จะสังหาร 441 และสอดแทรก 160 ( ) ดังนั้นเราจึงเก็บตัวอย่าง 160 ตัวอย่างที่เป็นตัวแทนของความถี่จาก -8 kHz ถึง +8 kHz จากนั้นเราจะผกผัน FFT ตัวอย่างและ presto! คุณมีตัวอย่างโดเมนเวลา 160 ตัวอย่างที่สุ่มตัวอย่างที่ 16 kHz255

ในขณะที่คุณอาจสงสัยว่ามีปัญหาที่อาจเกิดขึ้นสองสามอย่าง ฉันจะผ่านแต่ละคนและอธิบายว่าคุณจะเอาชนะพวกเขาได้อย่างไร

  1. คุณจะทำอย่างไรถ้าข้อมูลของคุณไม่ได้เป็นตัวคูณที่ดีของปัจจัยการทำลายล้าง คุณสามารถเอาชนะสิ่งนี้ได้อย่างง่ายดายโดยการเติมจุดสิ้นสุดของข้อมูลของคุณด้วยค่าศูนย์ที่เพียงพอเพื่อให้มันเป็นปัจจัยการทำลายล้างที่หลากหลาย ข้อมูลจะถูกเสริมก่อนที่จะเป็น FFT

  2. แม้ว่าวิธีการที่ฉันอธิบายนั้นง่ายมาก แต่ก็ไม่เหมาะอย่างยิ่งที่จะสามารถแนะนำเสียงเรียกเข้าและสิ่งประดิษฐ์ที่น่ารังเกียจอื่น ๆ ในโดเมนเวลา คุณสามารถหลีกเลี่ยงได้โดยการกรองข้อมูลโดเมนความถี่ก่อนที่จะลดลงข้อมูลความถี่สูง คุณทำเช่นนี้โดย FFT กำลังกรองตัวกรองความยาวเติมข้อมูล (ก่อน FFT'ing) อย่างน้อยl - 1ll1ศูนย์ (โปรดทราบว่าจำนวนตัวอย่างข้อมูลและจำนวนของชิ้นส่วนแพ็ดดิ้งจะต้องเป็นตัวคูณบวกจำนวนหนึ่งของปัจจัยด้านการทำลาย - คุณสามารถเพิ่มความยาวของช่องว่างภายในเพื่อให้เป็นไปตามข้อ จำกัด นี้), FFT ข้อมูลและตัวกรองจากนั้นการสร้างสมนามความถี่สูง (> 8 kHz) จะส่งผลให้ผลลัพธ์ความถี่ต่ำ (<8 kHz) ลดลงก่อนที่จะลดผลลัพธ์ความถี่สูง น่าเสียดายที่เนื่องจากการกรองในโดเมนความถี่เป็นหัวข้อใหญ่ในสิทธิ์ของตนเองฉันจึงไม่สามารถระบุรายละเอียดเพิ่มเติมในคำตอบนี้ได้ ฉันจะบอกว่าถ้าคุณกรองและประมวลผลข้อมูลมากกว่าหนึ่งอันคุณจะต้องใช้Overlap-and-AddหรือOverlap-and-Saveเพื่อทำการกรองอย่างต่อเนื่อง

ฉันหวังว่านี่จะช่วยได้.

แก้ไข: ความแตกต่างระหว่างจำนวนเริ่มต้นของตัวอย่างโดเมนความถี่และจำนวนเป้าหมายของตัวอย่างโดเมนความถี่จำเป็นต้องเป็นเช่นนั้นเพื่อให้คุณสามารถลบตัวอย่างจำนวนเดียวกันจากด้านบวกของผลลัพธ์เป็นด้านลบของผลลัพธ์ ในตัวอย่างของเราจำนวนตัวอย่างเริ่มต้นคืออัตราการทำลายล้างหรือ 441 และจำนวนเป้าหมายของตัวอย่างคืออัตราการแก้ไขหรือ 160 ความแตกต่างคือ 279 ซึ่งไม่เท่ากัน วิธีแก้ไขคือเพิ่มความยาว FFT เป็นสองเท่าเป็น 882 ซึ่งทำให้จำนวนเป้าหมายของกลุ่มตัวอย่างเพิ่มเป็นสองเท่าถึง 320 ตอนนี้ความแตกต่างคือเท่ากันและคุณสามารถวางตัวอย่างโดเมนความถี่ที่เหมาะสมโดยไม่มีปัญหา


ดีมาก. คุณกำลังทำตัวเลขที่ดีเช่นนี้ได้อย่างไร Jim
สเปซีย์

@ Mohammad ฉันมักจะใช้ Powerpoint ในกรณีนี้ฉันใช้ Powerpoint เวอร์ชัน Libre Office ซึ่งฉันเชื่อว่าเรียกว่า "Impress"
Jim Clay

สวัสดีฉันมีคำถามในประเด็นของคุณ (2) คุณหมายถึงอะไรอย่างแม่นยำในขั้นตอนนี้: "... จากนั้นนามแฝงความถี่สูง (> 8 kHz) จะแสดงผลลัพธ์ลงในผลลัพธ์ความถี่ต่ำ (<8 kHz) ก่อนที่จะวางผลลัพธ์ความถี่สูง" ฉันเข้าใจขั้นตอนก่อนหน้านั้น หลังจากที่ฉันคูณข้อมูลโดเมน f กับโดเมน f ของตัวกรองของฉันแล้วจะเป็นอย่างไร นอกจากนี้วิธีนี้ใช้งานได้หากคุณต้องการเก็บตัวอย่างข้อมูลของคุณด้วยหรือไม่? ขอบคุณ.
TheGrapeBeyond

@TheGrapeBeyond เมื่อคุณนามแฝงในโดเมนเวลาคุณเพิ่มโซน Nyquist ทั้งหมดเข้าด้วยกัน องค์ประกอบแรกของโซน Nyquist ทั้งหมดจะถูกรวมเข้าด้วยกันและกลายเป็นองค์ประกอบแรกของโซน Nyquist แรก องค์ประกอบที่สองของโซน Nyquist ทั้งหมดได้รับการรวมเข้าด้วยกันและกลายเป็นองค์ประกอบที่สองใหม่ของโซน Nyquist แรกและอื่น ๆ
Jim Clay

อืมฉันไม่แน่ใจว่าฉันเข้าใจวิธีที่คุณทำ resampling ตาม FFT เพราะเมื่อฉันลองที่นี่ฉันได้รับผลลัพธ์ที่แปลกมาก ฉันจะตั้งคำถามกับมัน
TheGrapeBeyond

3

ในขณะที่คำตอบข้างต้นเสร็จสมบูรณ์จริง ๆ :

นี่คือส่วนสำคัญของมัน:

  1. เพื่อดาวน์ตัวอย่างสัญญาณจะต้องเป็นจำนวนเต็ม ก่อนที่การสุ่มสัญญาณลงคุณจะต้องกรองสัญญาณ
  2. คุณสามารถลดจำนวนตัวอย่างที่มีเหตุผลได้ด้วยการสุ่มตัวอย่าง / แก้ไขสัญญาณก่อน
  3. การอัปแซมปลิงเป็นเพียงการใส่ค่าศูนย์แล้วกรองสัญญาณ
  4. ดังนั้นเพื่อให้ได้อัตราตัวอย่าง 3/4 ยกตัวอย่างสัญญาณโดยการแทรก 4 ศูนย์ระหว่างทุกตัวอย่างสัญญาณ ใช้ตัวกรอง จากนั้นกรองสัญญาณและลบทุก ๆ 3 จากทุก ๆ 4 สัญญาณตัวอย่าง

รายละเอียดเกี่ยวกับเรื่องนี้:

http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/EE523_files/Ch_14_1%20Subband%20Intro%20&%20Multirate%20(PPT).pdf

นอกจากนี้: หากจำเป็นอย่างยิ่งห้ามใช้คอมพิวเตอร์ FFT เพื่อคำนวณ IFFT มันเป็นกระบวนการที่ช้าอย่างไม่น่าเชื่อและถือว่าไม่เหมาะสมสำหรับงานประมวลผลสัญญาณส่วนใหญ่ FFT มักจะใช้สำหรับการวิเคราะห์ปัญหาหรือใช้การประมวลผลสัญญาณในโดเมนความถี่เท่านั้น


1

ดังที่ Bjorn Roche กำลังพูดการใช้ FFT สำหรับสิ่งนี้จะไม่มีประโยชน์มากนัก แต่ที่นี่มันเป็นไปอย่างเรียบง่ายมากโดยใช้วิธีการกรองตัวอย่างและคัดกรองตัวอย่างในโดเมนความถี่

1 - รับสัญญาณเวกเตอร์ที่ต้องการความยาว N

2 - ดำเนินการ N point FFT

3 - เติม PFT ด้วย Zero เป็นศูนย์ 160 * N ที่กึ่งกลางของเวกเตอร์ FFT

4 - ดำเนินการ IFFT

5 - เลือกหนึ่งตัวอย่างจาก 441 ตัวอย่างทิ้งอีก 440

คุณจะเหลือเวกเตอร์ที่มีความยาว N * 160/441 นั่นคือสัญญาณที่คุณ resampled

อย่างที่คุณเห็นคุณกำลังทำการคำนวณแบบไร้จุดหมายมากมายเพราะผลลัพธ์ส่วนใหญ่จะถูกโยนทิ้งไป แต่ถ้าคุณเข้าถึงรหัสที่ใช้ FFT คุณสามารถปรับแต่งได้เล็กน้อยดังนั้นมันจะคำนวณผลลัพธ์ IFFT ที่คุณจะได้รับเท่านั้นไม่ใช่สิ่งที่คุณจะทิ้งไป

หวังว่ามันจะช่วย

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