FFT veya DFT kullanarak ses yeniden örnekleme


12

Önce bir FFT gerçekleştirerek, sonra sadece ihtiyacım olan bölümün parçalarını alarak ve sonra ters bir FFT gerçekleştirerek ses sesini indiriyorum. Ancak, sadece ikisinin gücü olan frekansları kullandığımda düzgün çalışıyor, örneğin 32768'den 8192'ye aşağı örnekleme. 32k veri üzerinde bir FFT gerçekleştiriyorum, verilerin üst 3/4'ünü atıyorum ve sonra bir geri kalan 1/4.

Bununla birlikte, bunu düzgün bir şekilde hizalamayan verilerle yapmaya çalıştığımda iki şeyden biri olur: Kullandığım matematik kütüphanesi (Aforge.Math) bir uyum sağlar, çünkü örneklerim iki güç değildir. Eğer örnekleri ikiye katlamak için sıfır-pad yapmaya çalışırsam, diğer tarafta anlamsızlaşır. Bunun yerine bir DFT kullanmaya çalıştım, ancak bu son derece yavaş oluyor (bunun gerçek zamanlı yapılması gerekiyor).

Hem ilk FFT'de hem de sonunda ters FFT'de FFT verilerini düzgün bir şekilde sıfırlamak için ne yapmalıyım? 44.1khz'de 16khz'ye ulaşması gereken bir örneğim olduğunu varsayarsak, şu anda böyle bir şey deniyorum, örnek 1000 boyutunda.

  1. Sonundaki veri girişini 1024'e getirin
  2. FFT yap
  3. Bir diziye ilk 512 öğeyi okuyun (sadece ilk 362'ye ihtiyacım var, ancak ^ 2'ye ihtiyacım var)
  4. Ters FFT gerçekleştirin
  5. Ses çalma arabelleğine ilk 362 öğeyi okuyun

Buradan sonunda çöp çıkarıyorum. Aynı şeyi yapmak, ancak numuneler ^ 2 olduğundan dolayı 1. ve 3. adımda ped yapmak zorunda kalmadan, doğru sonuç verir.

c#  audio 

9
FFT bunu yapmanın doğru yolu değil. Maksimum verimlilik için çok fazlı bir filtre bankası istiyorsunuz, ancak sorunu çözmek istiyorsanız, önce GCD'ye, sonra lowpass'a, sonra downsample'ye örnekleyin.
Bjorn Roche

Merhaba Bjorn: "GCD" nedir?
SpeedCoder5

Yanıtlar:


16

İlk adım, hem başlangıç ​​numune oranınızın hem de hedef numune oranınızın rasyonel sayılar olduğunu doğrulamaktır . Tamsayı oldukları için otomatik olarak rasyonel sayılardır. Bunlardan biri rasyonel bir sayı olmasaydı, örnekleme oranını değiştirmek yine de mümkün olurdu, ama bu çok daha farklı bir süreç ve daha zordur.

Bir sonraki adım, iki numune hızını hesaba katmaktır. Başlangıç ​​örnek oranı, bu durumda, etkileyen 44100'dür . Hedef örnek oranı, 16000, 2 75 3'ü etkiler . Bu nedenle, başlangıç ​​numune hızından hedef hıza dönüştürmek için 3 27 2 ile ara vermeli ve 2 55 ile enterpolasyon yapmalıyız .22*32*52*7227*5332*7225*5

Verileri nasıl yeniden örneklemek istediğinizden bağımsız olarak önceki adımların gerçekleştirilmesi gerekir. Şimdi FFT'lerle nasıl yapılacağı hakkında konuşalım. FFT'lerle yeniden örneklemenin hilesi, her şeyin iyi çalışmasını sağlayan FFT uzunluklarını seçmektir. Bu, decimation oranının katı olan bir FFT uzunluğunun seçilmesi anlamına gelir (bu durumda 441). Örnek uğruna, 441'lik bir FFT uzunluğu seçelim, ancak 882 veya 1323'ü veya 441'in herhangi bir pozitif katını seçebilirdik.

Bunun nasıl çalıştığını anlamak görselleştirmeye yardımcı olur. Frekans alanında, aşağıdaki şekle benzeyen bir ses sinyali ile başlarsınız. 44,1 kHz örnekleme hızı

İşleminiz bittiğinde, örnek hızını 16 kHz'e düşürmek istiyorsunuz, ancak mümkün olduğunca az bozulma istiyorsunuz. Başka bir deyişle, yukarıdaki resimdeki her şeyi -8 kHz'den +8 kHz'ye kadar tutmak ve diğer her şeyi bırakmak istersiniz. Bu aşağıdaki resim ile sonuçlanır. resim açıklamasını buraya girin

Örnekleme oranlarının ölçeklendirilmediğini, sadece kavramları göstermek için orada olduklarını lütfen unutmayın.

25*5

Şüphelendiğiniz gibi, birkaç potansiyel sorun var. Her birini gözden geçireceğim ve nasıl üstesinden gelebileceğinizi açıklayacağım.

  1. Verileriniz belirleme faktörünün hoş bir katı değilse ne yaparsınız? Verilerinizin sonunu, belirleme faktörünün bir katı yapmak için yeterli sıfırla doldurarak bunu kolayca aşabilirsiniz. Veriler FFT'den önce doldurulur.

  2. Açıkladığım yöntem çok basit olsa da, zaman alanında zil ve diğer kötü eserler sunabilmesi de ideal değildir. Yüksek frekanslı verileri bırakmadan önce frekans alanı verilerini filtreleyerek bundan kaçınabilirsiniz. Bunu, l uzunluk filtrenizi FFT 'yaparak yapabilirsiniz.l verilerinizi (FFT' 'den önce) en az ile doldurarak yaparsınız.l-1sıfırlar (lütfen veri örneklerinin sayısının ve dolgu örneklerinin sayısının İKİ belirleme faktörünün pozitif bir katı olması gerektiğini unutmayın - bu kısıtlamayı karşılamak için dolgu uzunluğunu artırabilirsiniz), yastıklı verileri FFT'leme, frekans alanını çarpma veri ve filtre ile yüksek frekans (> 8 kHz) örtüştükten sonra yüksek frekanslı sonuçlar düşmeden önce düşük frekanslı (<8 kHz) sonuçlara dönüşür. Ne yazık ki, frekans alanında filtreleme kendi başına büyük bir konu olduğundan, bu cevapta daha fazla ayrıntıya giremeyeceğim. Bununla birlikte, verileri birden fazla yığın halinde filtreliyor ve işliyorsanız, filtrelemeyi sürekli hale getirmek için Çakışma ve Ekle veya Çakışma ve Kaydet'i uygulamanız gerektiğini söyleyeceğim .

Umarım bu yardımcı olur.

DÜZENLEME: Sonuçların negatif tarafı ile sonuçların pozitif tarafından aynı sayıda örneği kaldırabilmeniz için, sıklık etki alanı örneklerinin başlangıç ​​sayısı ile hedef sıklık etki alanı örnekleri arasındaki farkın eşit olması gerekir. Örneğimizde, örneklerin başlangıç ​​sayısı, decimation oranı veya 441'dir ve hedef numune sayısı, enterpolasyon oranı veya 160'tır. Aradaki fark 279'dur. Çözüm, FFT uzunluğunu 882'ye iki katına çıkarmaktır, bu da hedef örnek sayısının da 320'ye iki katına çıkmasına neden olur. Şimdi fark eşittir ve uygun frekans alanı örneklerini sorunsuz bırakabilirsiniz.


Çok hoş. Bu kadar güzel figürleri anında nasıl yapıyorsun Jim?
Spacey

@Mohammad Genellikle Powerpoint kullanıyorum. Bu durumda Powerpoint'in "Impress" olarak adlandırıldığını düşündüğüm Libre Office sürümünü kullandım.
Jim Clay

Merhaba, konuyla ilgili bir sorum var (2). Bu adımda tam olarak ne demek istiyorsun: "... ve sonra yüksek frekansı (> 8 kHz) yumuşatmak, yüksek frekanslı sonuçları düşürmeden önce düşük frekanslı (<8 kHz) sonuçlara yol açar." Ondan önceki adımları anlıyorum. F-domain verilerimi filtrenin f-domain'i ile çarptıktan sonra ne olacak? Ayrıca, verilerinizi de örneklemek istiyorsanız bu yöntem işe yarıyor mu? Teşekkür ederim.
TheGrapeBeyond

@TheGrapeBeyond Zaman etki alanında takma ad oluşturduğunuzda, tüm Nyquist bölgelerini birlikte eklersiniz. Tüm Nyquist bölgelerinin ilk öğeleri bir araya getirilir ve ilk Nyquist bölgesinin yeni ilk öğesi olur. Tüm Nyquist bölgelerinin ikinci öğesi bir araya getirilir ve ilk Nyquist bölgesinin vb. Yeni ikinci öğesi haline gelir
Jim Clay

Hmm, FFT tabanlı yeniden örneklemeyi nasıl yaptığınızı anladığımdan emin değilim, çünkü burada denediğimde çok garip sonuçlar alıyorum. Bu konuda bir soru soracağım.
TheGrapeBeyond

3

Yukarıdaki cevap gerçekten tamamlanmış olsa da:

İşte özü:

  1. bir sinyali aşağı örneklemek için bir tam sayı olması gerekir. Bir sinyalin aşağı örneklemesinden önce, sinyali FİLTRE ETMELİSİNİZ.
  2. önce sinyali yukarı örnekleyerek / enterpolasyon yaparak rasyonel sayı altörneklemesine erişebilirsiniz.
  3. Örnekleme, yalnızca sıfırları ekler ve sonra sinyali FİLTRELEMEDİR.
  4. böylece 3/4 örnek oranı elde etmek. Her sinyal örneği arasına 4 sıfır ekleyerek sinyali örnekleyin. Bir filtre uygulayın. Ardından sinyali FİLTRE EDİN ve her 4 sinyal örneğinden 3'ünü silin.

Bununla ilgili ayrıntılar:

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

Ayrıca: kesinlikle gerekli olmadıkça, IFFT'yi hesaplamak için FFT'yi bilgisayar ETMEYİN. Bu inanılmaz derecede yavaş bir süreç ve çoğu sinyal işleme görevi için uygunsuz olarak kabul edilir. FFT genellikle bir sorunu analiz etmek veya yalnızca frekans alanında sinyal işleme uygulamak için kullanılır.


1

Bjorn Roche'un dediği gibi, bunun için FFT kullanmak çok yetersiz olacaktır. Ancak burada, frekans alanında üst örnek filtre ve alt örnek yöntemini kullanarak çok basit bir şekilde gider.

1 - N uzunluğunda istenen vektör sinyalini alın.

2 - N noktası FFT gerçekleştirin.

3 - FFT'yi FFT vektörünün ortasında 160 * N sıfırlarla doldurun.

4 - IFFT gerçekleştirin

5 - Diğer 440'ı atarak 441 örnekten birini seçin.

Yeniden örneklenmiş sinyaliniz olacak olan N * 160/441 uzunluğunda bir vektörle kalacaksınız.

Gördüğünüz gibi birçok anlamsız hesaplama yapıyorsunuz, çünkü sonuçların çoğu atılacak. Ancak, FFT'yi gerçekleştiren koda erişiminiz varsa, bunu biraz değiştirebilirsiniz, böylece sadece atacağınız IFFT sonuçlarını hesaplar ve atacağınız sonuçları hesaplar.

Umarım yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.