SORU
3 AĞUSTOS 2010, Salı


Apple FFT kullanarak ve Çerçeve Hızlandırmak

Henüz kimse bir iPhone uygulaması için Apple FFT kullanmış ya da kullanmak için nasıl bir örnek uygulama nerede bulabilirim? Apple bazı örnek kod gönderdi biliyorum, ama gerçekten gerçek bir proje haline uygulamak için nasıl emin değilim.

CEVAP
4 Kasım 2010, PERŞEMBE


Sadece FFT kodu iPhone bir proje için çalışıyor:

  • yeni bir proje oluşturun
  • ana hariç tüm Dosyaları Sil.m ve xxx_info.plıst
  • ayarlar ve pch için arama projesi olacak ve yüklemek için çalışıyor durdurmak .pch (sadece silinmiş olarak görmek)
  • kopya ne ana var kod örneği yapıştırın.m
  • satırını kaldırın bu #include Karbon. Karbon).
  • tüm çerçeveleri Sil ve Ekle hızlandırmak çerçeve

Ayrıca bilgi girişi kaldırmak gerekebilir.plist bu proje bir xib yüklemek için söyler, ama 'ı benim için rahatsız olmanıza gerek yok.

NOT: sonuçlar bir hata olmadığını 0.000 olarak çıkıp sadece çok hızlı çok ... konsol Program çıktıları

Bu kod gerçekten aptalca belirsiz; cömertçe yorumladı, ama bu yorum aslında hayat hiç kolay değil.

Bunun merkezinde temelde

vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);
vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_INVERSE);

N gerçek FFT yüzer ve sonra tekrar başladığımız yere geri almak için ters. ıp anlamına gelir Ve üzerine hangi yerinde duruyor Bu değeri göndermek gibi aynı alana dönüş değeri squash, böylece tüm bu özel ambalaj malarkey -- nedeni var.

Bazı perspektif gibi (gibi: neden ilk etapta bu fonksiyonu kullanmadan olur muyuz?) vermek Hadi mikrofon girişi pitch algılama gerçekleştirmek istiyoruz demek ve mikrofonu 1024 olur her zaman harekete biraz geri yüzer diye ayarlamış olabilir. Mikrofon örnekleme oranı diyelim. ~44 kare / sn, böylece 44,1 kHz.

Yani, bizim zaman penceresi 1024 örneklerin bekleme süresi ne olursa olsun, 1/44 s yani.

1024 ile Bir mikrofon, log2n=10 set(2^10=1024)gelen yüzer, bazı bobin (setupReal) önceden hesaplamak ve: pack

vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);

Şimdi Bir n/2 karmaşık sayılar içerir. Bu n/2 frekans kutuları temsil eder:

  • bin[1].idealFreq = 44Hz -- güvenilir bir şekilde, bu çerçeve içinde BİR tam dalga, 44Hz bir dalga ıe tespit edebiliriz En düşük frekans yani.

  • bin[2].= 2 * 44Hz idealFreq

  • vb.

  • bin[512].idealFreq = 512 * 44Hz-en yüksek frekansı algılayabilir (bilinen Nyquist frekansı) bulunduğu her çifti noktaları gösteren bir dalga, yani 512 tam dalgaları içinde pencere, ıe 512 * 44Hz ya: n/2 * bin[1].idealFreq

  • Aslında genellikle olarak adlandırılan fazladan bir Bin, bir Bin[0] 'DC Offset'. Bu kadar Bin[0] ve Bin[n/2] her zaman karmaşık bileşen 0, yani A[0] olur.realp Bin[0] ve[0] saklamak için kullanılır.imagp Bin[n/2] saklamak için kullanılır

Ve her karmaşık sayının büyüklüğünü enerji miktarını frekans etrafında titriyor.

Gördüğünüz gibi, neredeyse iyi yeterince ayrıntı yok gibi çok büyük bir aşama dedektörü olmaz. Kurnaz bir hile Extracting precise frequencies from FFT Bins using phase change between frames verilen bir bin için kesin frekans elde etmektir.

Tamam, kodu üzerine Şimdi

Not '' vDSP_fft_zrip, = 'yerinde' yani çıkış Bir yazar ('r' gerçek girişler gerektiği anlamına geliyor) . ıp

VDSP_fft_zrip, belgelerine bakın

Gerçek veri bölünmüş karmaşık saklanır form, tek gerçek, saklanan bölünmüş karmaşık hayali yan form ve hatta gerçekte de içinde saklı gerçek tarafı.

bu muhtemelen anlamak için en zor şey. Aynı kap (&A) sürecin sonuna kadar kullanıyoruz. başlangıçta n gerçek sayılar ile doldurmak istiyoruz. FFT sonra/2 karmaşık sayılar n holding olacak. biz daha sonra ters dönüşüm içine atmak, ve umarım orijinal n gerçek sayımız olsun.

şimdi karmaşık değerleri için bu Bir kur yapısı. VDSP içine gerçek sayılar pack nasıl standardize etmek gerekir.

yani ilk n gerçek sayılar üreten: 1, 2, ..., n

for (i = 0; i < n; i  )
    originalReal[i] = (float) (i   1);

/2 olarak n Bir kompleks içine koyduktan sonraki #ler:

// 1. masquerades n real #s as n/2 complex #s = {1 2i, 3 4i, ...}
// 2. splits to 
//   A.realP = {1,3,...} (n/2 elts)
//   A.compP = {2,4,...} (n/2 elts)
//
vDSP_ctoz(
          (COMPLEX *) originalReal, 
          2,                            // stride 2, as each complex # is 2 floats
          &A, 
          1,                            // stride 1 in A.realP & .compP
          nOver2);                      // n/2 elts

Gerçekten bu belgelerde COMPLEX_SPLİT aramak belki de tahsis ne kadar bakmak gerekir.

A.realp = (float *) malloc(nOver2 * sizeof(float));
A.imagp = (float *) malloc(nOver2 * sizeof(float));

Gelecek önceden bir hesaplama yapıyoruz.


Matematik için hızlı DSP sınıf büyükler: Fourier teorisi başınızın etrafında almak için uzun bir süre (birkaç yıl için açık ve kapalı şimdi aradım) alır

Bir cisoid

z = exp(i.theta) = cos(theta)   i.sin(theta)

karmaşık düzlemde birim çember üzerinde bir nokta yani.

Karmaşık sayılar ile çarp, açıları ekleyin. Yani z^k birim çemberin etrafında atlamalı devam edecektir; z^k açı k bulunabilir.teta

  • Gerçek ekseninden = 0 1i, yani z1 çeyrek tur seçin ve z1^2 z1^3 z1^4 başka bir çeyrek kadar z1^4 = 1 şunu ver her dikkat edin

  • Z2 = -1, yani bir yarım dönüş seçin. ayrıca = ^4 z2 1 ama z2 bu noktada 2 devir (z2^2 = 1) tamamladı. Temel frekans olarak z1 ve ilk harmonik olarak z2 düşünüyorum

  • Benzer şekilde z3 = 'bir devrim' yani ben diyorum 3 döngülerini tamamlar, ama aslında ileriye 3/4 her zaman geriye gitmeyi 1/4 her seferinde aynıdır . üç-çeyrek

yani sadece z3 z1 ama ters yönde aliasing denir

z2 4 örnekleri tam bir dalga tutmak için seçtik anlamlı olarak en yüksek frekans.

  • = 1 0i z0, z0^(bir şey)=1, DC ofset

4-herhangi bir z0 z1 doğrusal bir kombinasyonu ve z2 sinyal olarak ifade edebilirsiniz yani bu temel vektörleri üzerine yansıtıyorsun

ama "bir cisoid üzerine bir sinyal projesi için ne ifade ediyor?" sorusunu duyar

İğne cisoid yuvarlak döner, örnek k, iğne yönde k işaret ediyor.şöyle düşün: teta ve uzunluğu, sinyal[k]. Bu cisoid frekans eşleşen bir sinyal tam olarak bir yöne sonuçlanan şeklinde belirtiler olur. Eğer bütün katkıları eklerseniz, sonuç güçlü bir vektör elde edersiniz. Eğer frekansı yaklaşık eşleşirse, çıkıntı daha küçük olacak ve yavaş yavaş yukarı hareket edecektir. Frekans eşleşmeyen bir sinyal için, katkıları birbirini iptal eder.

http://complextoreal.com/tutorials/tutorial-4-fourier-analysis-made-easy-part-1/sezgisel bir anlayış yardımcı olacaktır.

Ama işin özü; eğer {z0,...,z512} üzerine 1024 örnekleri proje için seçtik Eğer önceden hesaplamak z0 thru z512, ve olurdubu precalculation adımdır.


Eğer gerçek kod bunu yapıyor iseniz muhtemelen bu uygulamayı yüklediğinde bir kez ve bir kez sonlandırıldığında tamamlayıcı yayın işlevi çağırmak istiyorum unutmayın. Bu kez bir dolu yapma pahalıdır.

// let's say log2n = 8, so n=2^8=256 samples, or 'harmonics' or 'terms'
// if we pre-calculate the 256th roots of unity (of which there are 256) 
// that will save us time later.
//
// Note that this call creates an array which will need to be released 
// later to avoid leaking
setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);

Eğer herhangi bir fft fonksiyonu içine bu önceden hesaplanmış değerleri atabilir 8, örneğin log2n kurarsak bu kararı < kullanan belirtmekte yarar var;= 2^8. Yani ultimate bellek optimizasyonu istemiyorsanız) ihtiyacınız olacak yüksek çözünürlüklü bir set oluşturmak, ve her şey için kullanmak.

Şimdi gerçek, biz sadece önceden hesaplanmış şeyler yararlanarak dönüştürür:

vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);

A/2 karmaşık sayılar, sadece ilk bir iki gerçek Sayılar n içeren olacak bu noktada (DC ofset, Nyquist #) bir karmaşık sayı kılığına girmiş. Belgelere genel bakış bu ambalaj açıklıyor. Aynı belleğe dolu alanlar ayak izi olarak (gerçek, ama tuhaf bir şekilde paketlenmiş) girdilerin (karmaşık) sonuçları sağlar oldukça temiz, esasen.

vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_INVERSE);

ve yine... yine de tam olarak dışarı ile başladığımız işi var geri aldığımıza bakmamız karşılaştırın A., önceden bizim bobin bırakın ve yapılan orijinal dizi açmak için ihtiyacımız olacak!

Ama bekleyin! paketten önce yapılması gereken son bir şey var:

// Need to see the documentation for this one...
// in order to optimise, different routines return values 
// that need to be scaled by different amounts in order to 
// be correct as per the math
// In this case...
scale = (float) 1.0 / (2 * n);

vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, nOver2);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ciaran Blumenfeld

    Ciaran Blume

    20 NİSAN 2009
  • Doc Adams

    Doc Adams

    20 HAZİRAN 2007
  • SellerDp

    SellerDp

    27 EKİM 2009