2011-04-25 22 views
38

का उपयोग कर विशिष्ट आवृत्ति परिमाण को पुनर्प्राप्त करने के लिए एंड्रॉइड ऑडियो एफएफटी वर्तमान में मैं एंड्रॉइड का उपयोग करके कुछ कोड लागू करने की कोशिश कर रहा हूं, यह पता लगाने के लिए कि फोन के माइक्रोफ़ोन के माध्यम से कई विशिष्ट ऑडियो फ्रीक्वेंसी श्रेणियां खेली जाती हैं।एंड्रॉइड ऑडियो एफएफटी ऑडियो आवृत्ति

int channel_config = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
int format = AudioFormat.ENCODING_PCM_16BIT; 
int sampleSize = 8000; 
int bufferSize = AudioRecord.getMinBufferSize(sampleSize, channel_config, format); 
AudioRecord audioInput = new AudioRecord(AudioSource.MIC, sampleSize, channel_config, format, bufferSize); 

ऑडियो तो में पढ़ा जाता है:

short[] audioBuffer = new short[bufferSize]; 
audioInput.startRecording(); 
audioInput.read(audioBuffer, 0, bufferSize); 

एक FFT प्रदर्शन जहाँ मैं अटक हो जाते हैं, के रूप में मैं इस क्षेत्र में बहुत कम अनुभव है है मैं AudioRecord वर्ग का उपयोग कर वर्ग की स्थापना की है । मैं इस वर्ग का उपयोग करने के प्रयास कर रहे हैं:

FFT in Java और Complex class to go with it

मैं तो निम्न मान भेज रहा हूँ:

Complex[] fftTempArray = new Complex[bufferSize]; 
for (int i=0; i<bufferSize; i++) 
{ 
    fftTempArray[i] = new Complex(audio[i], 0); 
} 
Complex[] fftArray = fft(fftTempArray); 

यह आसानी से मुझे गलत समझ कैसे इस वर्ग के काम करने के लिए है हो सकता है, लेकिन मूल्य पूरे स्थान पर कूदते हैं और चुप्पी में भी लगातार आवृत्ति के प्रतिनिधि नहीं हैं। क्या कोई इस कार्य को करने के तरीके से अवगत है, या क्या मैं ग्राफिकल प्रतिनिधित्व के रूप में इसे आकर्षित करने के बजाय आवृत्ति श्रेणियों की केवल एक छोटी संख्या को कोशिश करने और पकड़ने के लिए मामलों को कम करता हूं?

+10

अरे, अगर आप यह पता लगा, तो आप कोड के अंतिम संस्करण पोस्ट करें सकता है? thx –

उत्तर

33

सबसे पहले आपको यह सुनिश्चित करने की आवश्यकता है कि आपको जो परिणाम मिल रहा है वह सही ढंग से एक फ्लोट/डबल में परिवर्तित हो गया है। मुझे यकीन नहीं है कि छोटा [] संस्करण कैसे काम करता है, लेकिन बाइट [] संस्करण केवल कच्चे बाइट संस्करण को लौटाता है। इस बाइट सरणी को फिर एक फ़्लोटिंग पॉइंट नंबर में ठीक से परिवर्तित करने की आवश्यकता है। रूपांतरण के लिए कोड इस तरह कुछ दिखना चाहिए:

double[] micBufferData = new double[<insert-proper-size>]; 
    final int bytesPerSample = 2; // As it is 16bit PCM 
    final double amplification = 100.0; // choose a number as you like 
    for (int index = 0, floatIndex = 0; index < bytesRecorded - bytesPerSample + 1; index += bytesPerSample, floatIndex++) { 
     double sample = 0; 
     for (int b = 0; b < bytesPerSample; b++) { 
      int v = bufferData[index + b]; 
      if (b < bytesPerSample - 1 || bytesPerSample == 1) { 
       v &= 0xFF; 
      } 
      sample += v << (b * 8); 
     } 
     double sample32 = amplification * (sample/32768.0); 
     micBufferData[floatIndex] = sample32; 
    } 

फिर आप अपनी इनपुट जटिल सरणी बनाने के लिए micBufferData [] का उपयोग करते हैं।

परिणाम मिलने के बाद, परिणामों में जटिल संख्याओं की परिमाण का उपयोग करें। वास्तविकता वाले आवृत्तियों को छोड़कर अधिकांश परिमाण शून्य के करीब होना चाहिए।

आप आवृत्तियों के लिए इस तरह के परिमाण को सरणी सूचकांक कन्वर्ट करने के लिए नमूना आवृत्ति की जरूरत है:

private double ComputeFrequency(int arrayIndex) { 
    return ((1.0 * sampleRate)/(1.0 * fftOutWindowSize)) * arrayIndex; 
} 
+2

आपके उत्तर के लिए बहुत बहुत धन्यवाद, लेकिन मुझे अभी भी कुछ समस्याएं हैं। 'ComputeFrequency' विधि चलाने से पहले, क्या मुझे अभी भी लौटे जटिल सरणी से मान निकालने में सक्षम होना चाहिए? एक ही समस्या अभी भी 10 से लगभग 3000 तक दिखाई देने वाली स्पोरैडिक संख्याओं के साथ अनुमति देती है, जबकि कमरे मौन में है दुर्भाग्यवश – user723060

+0

हां, आपको अभी भी जटिल सरणी से मूल्य निकालने में सक्षम होना चाहिए, आप की परिमाण का उपयोग करना चाहते हैं जटिल संख्या (यानी वर्ग (पुनः * पुनः + आईएम * आईएम))। भले ही कमरा पूरी तरह से चुप्पी में है, फिर भी माइक्रो द्वारा पेश किया गया पृष्ठभूमि शोर हो सकता है जो एफएफटी पर दिखाई देगा। दिखाए जाने वाले सटीक आवृत्तियों को देखने के लिए सरणी इंडेक्स को आवृत्तियों में कनवर्ट करें। उन आवृत्तियों के मूल्य यह समझने में सहायता कर सकते हैं कि वे पृष्ठभूमि शोर हैं या नहीं। – shams

+0

मैं उत्सुक हूं यदि मैं काल्पनिक संख्याओं के संबंध में जटिल सरणी को सही तरीके से बुला रहा हूं। जिस तरह से मैंने इसे कार्यान्वित किया है, वही है जैसा मैंने अपने मूल उदाहरण में किया था, लेकिन अब मैं नए micBufferData सरणी के माध्यम से साइकिल चला रहा हूं और प्रत्येक मान को जटिल सरणी में असाइन कर रहा हूं क्योंकि वास्तविक संख्या के साथ वास्तविक संख्या 0. यह हो सकता है कि मैं गलत कहां जा रहा हूं, लेकिन पिछले उदाहरण मैंने पढ़ा है यह इंगित करता है कि यह सही तरीका है। क्या कोई विचार है कि वहां जाने के लिए कुछ और है? एक बार फिर धन्यवाद! – user723060

संबंधित मुद्दे