Şu anda Apple'a özgü (Accelerate) vDSP işlevi vDSP_deq22'yi Android'e (Accelerate mevcut değil) kullanan bir filterbank portu yapıyorum. Filterbank, her biri kendi bantları için RMS büyüklüğünü döndüren bir grup bant geçiren filtrelerdir. Şu anda (NVDSP uyarlanmıştır ObjectiveC++) kodu aşağıdaki gibidir:Biquad IIR için Reimplement vDSP_deq22 El ile filtrele
- (float) filterContiguousData: (float *)data numFrames:(UInt32)numFrames channel:(UInt32)channel {
// Init float to store RMS volume
float rmsVolume = 0.0f;
// Provide buffer for processing
float tInputBuffer[numFrames + 2];
float tOutputBuffer[numFrames + 2];
// Copy the two frames we stored into the start of the inputBuffer, filling the rest with the current buffer data
memcpy(tInputBuffer, gInputKeepBuffer[channel], 2 * sizeof(float));
memcpy(tOutputBuffer, gOutputKeepBuffer[channel], 2 * sizeof(float));
memcpy(&(tInputBuffer[2]), data, numFrames * sizeof(float));
// Do the processing
vDSP_deq22(tInputBuffer, 1, coefficients, tOutputBuffer, 1, numFrames);
vDSP_rmsqv(tOutputBuffer, 1, &rmsVolume, numFrames);
// Copy the last two data points of each array to be put at the start of the next buffer.
memcpy(gInputKeepBuffer[channel], &(tInputBuffer[numFrames]), 2 * sizeof(float));
memcpy(gOutputKeepBuffer[channel], &(tOutputBuffer[numFrames]), 2 * sizeof(float));
return rmsVolume;
}
here görüldüğü gibi, deq22 özyinelemeli fonksiyonu ile belirli bir giriş vektör üzerinde bir süzgecinin filtre uygular.
- A =: Bu dokümanlar ile ilgili fonksiyon açıklaması tek hassas gerçek giriş vektörü
- IA =: 5 tek hassasiyetli: A.
- B = Stride girişler (filtre katsayıları), adım 1 ile.
- C =: Tek duyarlıklı gerçek çıkış vektörü.
- IC =: C için adım
- N =: Üretilecek yeni çıkış öğelerinin sayısı.
// N is fixed on init to be the same size as buffer.count, below // 'input' and 'output' are initialised with (N+2) length and filled with 0s func getFilteredRMSMagnitudeFromBuffer(var buffer: [Float]) -> Float { let inputStride = 1 // hardcoded for now let outputStride = 1 input[0] = input[N] input[1] = input[N+1] output[0] = output[N] output[1] = output[N+1] // copy the current buffer into input input[2 ... N+1] = buffer[0 ..< N] // Not sure if this is neccessary, just here to duplicate NVDSP behaviour: output[2 ... N+1] = [Float](count: N, repeatedValue: 0)[0 ..< N] // Again duplicating NVDSP behaviour, can probably just start at 0: var sumOfSquares = (input[0] * input[0]) + (input[1] * input[1]) for n in (2 ... N+1) { let sumG = (0...2).reduce(Float(0)) { total, p in return total + input[(n - p) * inputStride] * coefficients[p] } let sumH = (3...4).reduce(Float(0)) { total, p in return total + output[(n - p + 2) * outputStride] * coefficients[p] } let filteredFrame = sumG - sumH output[n] = filteredFrame sumOfSquares = filteredFrame * filteredFrame } let meanSquare = sumOfSquares/Float(N + 2) // we added 2 values by hand, before the loop let rootMeanSquare = sqrt(meanSquare) return rootMeanSquare }
filtre olsa deq22 için farklı büyüklük çıktıyı verir:
Bu şimdiye kadar (o zaten Android üzerinde çalışan var kod temeli kalanı gibi, Swift öyle) ne var ve içinde döngüsel bir ısınma dairesel 'gürültü' var gibi görünüyor (sabit bir giriş tonuyla, frekansın büyüklüğü aşağı yukarı pompalanır).
Katsayılar dizilerinin her uygulama arasında aynı olduğundan emin olmak için kontrol ettik. Her filtre aslında doğru frekansı (ve sadece bu frekansı) seçmesiyle "çalışır" gibi görünür ve bu sadece bu pompalamadır ve RMS büyüklük çıktısı vDSP'lerden çok daha büyüktür, çoğunlukla büyüklük sırasına göre:
Naive | vDSP
3.24305e-06 0.000108608
1.57104e-06 5.53645e-05
1.96445e-06 4.33506e-05
2.05422e-06 2.09781e-05
1.44778e-06 1.8729e-05
4.28997e-07 2.72648e-05
Mantığımla ilgili herhangi bir sorun görülebilir mi?
Düzenleme: Burada, sabit bir 440Hz tonu olan sonucun bir gif videosudur. Çeşitli yeşil çubuklar bireysel filtre bantlarıdır. 3. bant (burada gösterilmektedir) 440Hz'e ayarlanmış olanıdır.
NVDSP versiyonu sadece beklenen giriş hacmi ile orantılı okuma sabit (dışı dalgalı) büyüklüğünü göstermektedir.
Bu harika! :) – bartolsthoorn
@bartolsthoorn teşekkürler :) Bakınız [burada] (https: // orta.com/@ ephemer/neden-we-put-an-app-in-the-android-play-mağaza-kullanarak-swift-96ac87c88dfc) Eğer neden bu – ephemer
harika bir hikaye yapıyor endişeli ve NVDSP için teşekkürler hehe;) Bu arada, 2013 yılında NVDSP yaratma mücadelesi hakkında kendime bir not yazdım (doğru anladınız, Google çeviri yapmak zorunda olduğum çok az doküman vardı): https://medium.com/ @ bartolsthoorn/cesur ses filtreleri-1964521efbc7 # .vdsj4j83m – bartolsthoorn