मैं एक फ़िल्टरबैंक पोर्ट कर रहा हूं जो वर्तमान में एंड्रॉइड के लिए ऐप्पल-विशिष्ट (एक्सीलरेट) वीडीएसपी फ़ंक्शन vDSP_deq22 का उपयोग करता है (जहां त्वरण उपलब्ध नहीं है)। फ़िल्टरबैंक बैंडपास फिल्टर का एक सेट है जो प्रत्येक अपने संबंधित बैंड के लिए आरएमएस परिमाण को वापस करता है। वर्तमान में कोड (ObjectiveC++, NVDSP से रूपांतरित) इस तरह दिखता है:बाइकैड आईआईआर फ़िल्टर के लिए वीडीएसपी_डेक 22 को हाथ से
- (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 के रूप में, deq22 एक पुनरावर्ती समारोह के माध्यम से दिए गए इनपुट वेक्टर पर एक biquad फिल्टर लागू करता है।
- एक =:: यह डॉक्स से समारोह का वर्णन है एकल परिशुद्धता असली इनपुट वेक्टर
- आइए =: 5 एकल परिशुद्धता: ए
- बी = के लिए स्ट्राइड इनपुट (फ़िल्टर गुणांक), 1 के साथ 1.
- सी = एकल-सटीक वास्तविक आउटपुट वेक्टर।
- आईसी =: सी
- एन = उत्पादन के लिए नए आउटपुट तत्वों की संख्या।
// 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 }
फिल्टर एक अलग परिमाण उत्पादन हालांकि deq22 करने देता है:
यह वही है मैं अब तक (यह codebase के बाकी है कि मैं पहले से ही Android पर चल चुके हैं, स्विफ्ट में है) है , और इसमें एक चक्रीय घुमावदार सर्कुलर 'शोर' लगता है (एक स्थिर इनपुट स्वर के साथ, आवृत्ति की परिमाण ऊपर और नीचे पंप)।
मैंने यह सुनिश्चित करने के लिए जांच की है कि गुणांक सरणी प्रत्येक कार्यान्वयन के बीच समान हैं। प्रत्येक फ़िल्टर वास्तव में "काम" लगता है कि यह सही आवृत्ति (और केवल उस आवृत्ति) को चुनता है, यह सिर्फ यह पंपिंग है, और आरएमएस परिमाण आउटपुट वीडीएसपी की तुलना में बहुत शांत है, अक्सर परिमाण के आदेश:
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
क्या कोई मेरे तर्क के साथ कोई समस्या देख सकता है?
संपादित करें: यहां निरंतर 440 हर्ट्ज टोन के साथ परिणाम का एक gif वीडियो है। विभिन्न हरे रंग के सलाखों में व्यक्तिगत फ़िल्टर बैंड होते हैं। तीसरा बैंड (यहां दिखाया गया) एक 440 हर्ट्ज तक ट्यून किया गया है।
NVDSP संस्करण सिर्फ एक निरंतर (गैर अस्थिर) परिमाण इनपुट मात्रा के लिए आनुपातिक पढ़ना, अपेक्षा के अनुरूप पता चलता है।
यह कमाल है! :) – bartolsthoorn
@ बार्टोलस्टोर्न धन्यवाद :) देखें [यहां] (https: // माध्यम।com/@ ephemer/why-we-put-an-app-in-the -roid-play-store-use-swift-96ac87c88dfc) यदि आप रुचि रखते हैं कि हम – ephemer
महान कहानी और एनवीडीएसपी के लिए धन्यवाद क्यों करते हैं हेहे का जिक्र करें;) वैसे, 2013 में मैंने एनवीडीएसपी बनाने के संघर्ष के बारे में स्वयं को एक छोटा सा नोट लिखा था (आपको यह सही मिला, Google अनुवाद का उपयोग करने के लिए मुझे बहुत कम दस्तावेज था): https://medium.com/ @ Bartolsthoorn/बहादुर-ऑडियो-फिल्टर -1964521efbc7 # .vdsj4j83m – bartolsthoorn