Sıfır dolgu tek uzunlukta FFT olduğunda gerçek değerli zil sesi


13

Bu yüzden bir sinyalin frekans yanıtını ve ters dönüşümleri sıfırlayan bir frekans-etki alanı enterpolatörü yazmaya çalışıyorum. Ele almam gereken iki durum var:

  1. Eşit uzunluklu tepki - belirsiz olduğu için bölmesini bölmek zorundasınız . Bu yüzden spektrumun negatif kısmını kopyalarım ve arasına sıfırlar ekliyorum .Fs/2n*(interp-1)-1
  2. Tek uzunluk yanıtı - kutusu yoktur, bu yüzden pozitif / negatif frekansı bölün ve aralarına sıfır ekleyin .Fs/2n*(interp-1)

Sıfır dolgusu yapan kod burada görülebilir

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

İlk durum iyi çalışıyor, bir cıvıltı sinyali üzerinde test ediyorum ve sadece iyi enterpolasyon yapıyor, biraz sayısal gürültü var, ama yuvarlak bir FFT aracılığıyla takıldı, böylece ne yapabilirsiniz (ilk veya benzeri) sinyal gösterisi):50μs

Sorun tek uzunluk dönüşümü ile, sadece gerçek örnekler üzerinde oldukça heinous geçici bir yanıt alıyorum ( tekrar , gerçek):50μs

Hayali kanalın üzerinde küçük bir dalgalanma var, ama neredeyse o kadar kötü değil:

Sanki garip durumda berbat ettim , ama kutusu yok, bu yüzden çok şaşkınım. Kimsenin düşüncesi var mı?F s / 2Fs/2Fs/2


Çizimlerinizi görmek biraz zor, çünkü küçülüyorlar.
Jason R

@Jason üzgünüm bağlı olduklarını düşündüm, şimdi tam boyut için tıklayabilmeleri için html'yi değiştirdim.
gct

3
Girdi olarak kullandığınız kod veya örnek dosyanız var mı? Akılda tutulması gereken bir şey, DFT tarafından kabul edilen sınır koşullarının olmasıdır. Özellikle, ilgili sinyalin periyodik olduğuna dair doğal bir varsayım vardır. Yani, tek uzunluk girişindeki ilk ve son örnekler arasında bir süreksizlik varsa, gözlemlediğiniz gibi zil sesi görebilirsiniz. Eşit uzunluktaki numunenin baştan sona daha devamlı olması mümkündür, bu nedenle bu fenomeni görmezsiniz.
Jason R

Başkalarının kolayca sindirebileceği bir formatta verilerim yok, ama haklı olduğunu düşünüyorum. Ben sadece burada çalışmak için var ve benim kod yeniden derlenmiş / bir test girişi (1 saniye içinde 10Hz-100Hz cıvıltı) rejenere ve kodu yeniden koştu ve zil alamadım. Yorumunuzu gördüm ve frekansı 10-100.314 olarak değiştirdim ve şimdi hem tek hem de tek dönüşümlerde çınlıyor görüyorum.
gct

1
Verilerinize bir pencere işlevi uygulamayı denediniz mi? Bu normalde zil sesini azaltır.
MarkSci

Yanıtlar:


1

Yüksek frekanslı kutuları sıfırlayarak, sinyalin spektrumunu dikdörtgen bir fonksiyonla etkili bir şekilde çoğalttınız. Frekansta çarpma zaman içinde evrişimdir ve bir rektifin Fourier çifti bir samimidir. Yani gerçekten yaptığınız şey, zaman alanı sinyalini, rektörün uzunluğuyla ters orantılı olarak içkinin ana lobunun genişliği ile bir içgüdüyle ikna etmekti. Bu nedenle, "geçiş bölgesi" veya "geçiş" bandı olarak adlandırılan Park-McClellan tasarımı gibi çok sayıda filtre tasarım tekniği , böylece filtrenin frekans tepkisinde ani bir değişiklik olmaz. Bu filtre tasarım teknikleri önemlidir çünkü kullandığınız "ideal" filtrenin zaman alanında bu tür istenmeyen etkileri vardır.


0

Frekans alanında bir adım, zaman alanında dalgalanmalar olarak görünür. Frekans verilerinizi bir pencere fonksiyonu (örneğin Hamming penceresi) ile düzeltirseniz, dalgalanmalar önemli ölçüde azalmalıdır.

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.