2012-05-18 24 views
20

एंड्रॉइड मीडियाआरकॉर्डर में MediaRecorder के लिए एंड्रॉइड के getMaxAmplitude() फ़ंक्शन वास्तव में मुझे क्या देता है?

.getMaxAmplitude();
फ़ंक्शन है, जो API मुझे बताता है, "इस विधि के अंतिम कॉल के बाद से नमूना किया गया अधिकतम पूर्ण आयाम देता है।" लेकिन मुझे यह नहीं पता कि यह किस आयाम है? क्या यह पास्कल या वाट में है?

मुझे वेब पर कई पेजों पर पाया गया है कि आप डेसिबल का उपयोग करके बारीकी से मूल्य की गणना कर सकते हैं (जैसा कि here सुझाया गया है)।

double db = (20 * Math.log10(amplitude/REFERENCE)); 

जो मुझे लगता है कि दिए गए मान कुछ रैखिक पैमाने में है दिया जाएगा (शायद milipascal की तरह कुछ ...)

संदर्भ = 0.1 (मुझे पता है कि यह होना चाहिए हूँ कुछ की तरह 2 * 10^(- 5) पास्कल ((20 uPascal)), लेकिन यह अजीब मूल्यों ... 0.1 अजीब बेहतर काम करता है)

अभी मैं मापने MaxAmplitude()

getMaxAmplitude()
का उपयोग कर और चर आयाम में डाल देता है।

public double getNoiseLevel() 
{ 
    //Log.d("SPLService", "getNoiseLevel() "); 
    int x = mRecorder.getMaxAmplitude(); 
    double x2 = x; 
    Log.d("SPLService", "x="+x); 
    double db = (20 * Math.log10(x2/REFERENCE)); 
    //Log.d("SPLService", "db="+db); 
    if(db>0) 
    { 
     return db; 
    } 
    else 
    { 
     return 0; 
    } 
} 

यह आधे सेकंड में 5 बार किया जाता है, जो औसत

for(int i=0; i<5; i++) 
{ 
    try 
    { 
      Thread.sleep(100); 
    } 
    catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
      return 0; 
    } 
    level = level+getNoiseLevel(); 
    if(level>0) 
    { 
     counter++; 
    } 
} 
level=level/counter; 
Log.d(LOG_TAG, "level="+level); 

की तरह हो जाता है मैं कुछ है कि थोड़े डेसिबल की तरह लग रहा मिलता है लेकिन मैं:

इस विधि है मुझे यकीन नहीं है कि यह वास्तव में decibel है ...

तो, क्या कोई इस पर मेरी मदद कर सकता है? यह बहुत अजीब लगता है कि एपीआई वापस लौटाए गए सभी चीज़ों पर specefy नहीं है ...

+0

यह काम करता है, यह समझाने के लिए धन्यवाद कि MaxAmplitude क्या प्राप्त करता है। लेकिन मुझे यकीन नहीं है कि ये सही डीबी मूल्य हैं या नहीं। जब मैं कुछ मामलों में परीक्षण करता हूं और मूल्यों की तुलना करने की कोशिश करता हूं: http://www.newton.dep.anl.gov/askasci/phy99/phy99405.htm, 30 डीबी गायब है। क्या आपको कोई विचार है क्यों? – Wissem

+1

कई कारण हो सकते हैं: 1. यह एल्गोरिदम गणना के लिए आधार के रूप में getMaxAmplitude का उपयोग करता है जिसका अर्थ है कि अवधि में सभी कम जोरदार घटनाओं को अनदेखा किया जाता है। इससे परिणामस्वरूप वास्तविक डीबी स्तर (और आमतौर पर प्राकृतिक वातावरण में) 2. फोन के माइक्रोफ़ोन अलग-अलग होते हैं। कुछ तो दूसरों को अधिक सेंसिबल हैं। यह एल्गोरिदम किसी भी फोन पर समान गणना करने पर इसे ध्यान में नहीं लेता है। इन दुविधाओं के कारण कुछ फोन काफी अधिक या कम मूल्य दे सकते हैं। –

+0

इसके अतिरिक्त, सीमित कारक के कारण (मान केवल 32767 तक पहुंच जाता है), बहुत जोरदार शोर सटीक रूप से नहीं पता चला है। आमतौर पर कटऑफ लगभग 100 डीबी पर होगा। –

उत्तर

15

मुझे इस प्रश्न का उत्तर मिल सकता है और मैं इसे यहां किसी भी व्यक्ति के लिए साझा करूंगा जो परवाह करता है: MediaRecorder.getMaxAmplitude() फ़ंक्शन रिटर्न हस्ताक्षरित 16-बिट पूर्णांक मान (0-32767)। जो सीडी-गुणवत्ता नमूना मानों की केवल एबीएस() है जो -32768 से 32767 तक है। इसका मतलब है कि वे शायद माइक्रोफोन निर्माण के 0-100% अधिकतम वोल्टेज रेंज से विद्युत उत्पादन के 16-बिट डिजिटलकरण का प्रतिनिधित्व करते हैं उस मोबाइल फोन में। चूंकि मोबाइल के एक ब्रांड में भी इन माइक्रोफ़ोन कभी-कभी अपनी सटीक सीमा में भिन्न होते हैं, यहां तक ​​कि समान फ़ोनों के लिए भी वही मूल्य उसी ध्वनि स्रोत को उसी दूरी पर नहीं दिया जाएगा।

यह मान हालांकि पास्कल में ध्वनि दबाव से संबंधित है क्योंकि यह सोलंड दबाव का एक रैखिक क्वांटिज़ेशन भी है, उस क्षेत्र में जहां ध्वनि को दिए गए माइक्रोफ़ोन के साथ मापा जा सकता है (जो पूरे स्पैक्ट्रम को सीमाओं के कारण कवर नहीं करेगा फ़ोन)।

13

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

यह मानते हुए कि 90 डीबी (एसपीएल) अधिकतम है, यह गणना कर सकता है कि यह mic पर 0.6325 Pa के दबाव के अनुरूप होगा। अब यह मानते हुए कि p0 = 0.0002 Pa संदर्भ न्यूनतम है और यह मानता है कि यह getMaxAmplitude() से 0 के रूप में पंजीकृत होगा (जो वास्तव में कभी नहीं होगा) हम micMaxAmplitude() फ़ंक्शन से मान को कोर पर अधिकतम दबाव के साथ कोरलेट कर सकते हैं। इसका मतलब है कि getMaxAmplitude() से 16375 का परिणाम 0.3165 Pa अधिकतम दबाव के अनुरूप होगा। यह निश्चित रूप से बहुत वैज्ञानिक नहीं है क्योंकि अधिकतम और न्यूनतम मान शुद्ध संयोग हैं, लेकिन यह हमें एक प्रारंभिक बिंदु देता है।अब हम माइक पर दबाव हम डीबी (एसपीएल) की गणना कर सकते सर्वविदित सूत्र

एक्स = 20 log_10 साथ -value को जानने का

पी = getMaxAmplitude()/51805,5336

साथ पी गणना कर सकते हैं (पी/पी 0)

यह अभी भी एक मान देगा जो उच्चतम है क्योंकि केवल गणना में अधिकतम आयाम का उपयोग किया जाता है। हल करने के लिए यह एक getMaxAmplitude (उपयोग नहीं करना चाहिए) और जब तक यह इस सवाल का ध्यान केंद्रित बाहर slighly है, मैं कोड में वैसे भी आशा में डाल दिया जाएगा, यह मदद करता है कि

public class NoiseRecorder 
{ 

private final String TAG = SoundOfTheCityConstants.TAG; 
public static double REFERENCE = 0.00002; 

public double getNoiseLevel() throws NoValidNoiseLevelException 
{ 
    Logging.e(TAG, "start new recording process"); 
    int bufferSize = AudioRecord.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_DEFAULT,AudioFormat.ENCODING_PCM_16BIT); 
    //making the buffer bigger.... 
    bufferSize=bufferSize*4; 
    AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
      44100, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 

    short data [] = new short[bufferSize]; 
    double average = 0.0; 
    recorder.startRecording(); 
    //recording data; 
    recorder.read(data, 0, bufferSize); 

    recorder.stop(); 
    Logging.e(TAG, "stop"); 
    for (short s : data) 
    { 
     if(s>0) 
     { 
      average += Math.abs(s); 
     } 
     else 
     { 
      bufferSize--; 
     } 
    } 
    //x=max; 
    double x = average/bufferSize; 
    Logging.e(TAG, ""+x); 
    recorder.release(); 
    Logging.d(TAG, "getNoiseLevel() "); 
    double db=0; 
    if (x==0){ 
     NoValidNoiseLevelException e = new NoValidNoiseLevelException(x); 
     throw e; 
    } 
    // calculating the pascal pressure based on the idea that the max amplitude (between 0 and 32767) is 
    // relative to the pressure 
    double pressure = x/51805.5336; //the value 51805.5336 can be derived from asuming that x=32767=0.6325 Pa and x=1 = 0.00002 Pa (the reference value) 
    Logging.d(TAG, "x="+pressure +" Pa"); 
    db = (20 * Math.log10(pressure/REFERENCE)); 
    Logging.d(TAG, "db="+db); 
    if(db>0) 
    { 
     return db; 
    } 
    NoValidNoiseLevelException e = new NoValidNoiseLevelException(x); 
    throw e; 
} 
} 

ये मान अब से प्राप्त कर रहे 4 सेकंड के नमूने में सभी आयामों का औसत और इस प्रकार अधिक सटीक। बाद में ऊपर वर्णित गणना की जाती है। यह एक और यथार्थवादी डेसिबल मूल्य देगा। ध्यान दें कि मोबाइल फोन एमआईक्स अभी भी चूसते हैं और यह एल्गोरिदम वास्तविक डीबी (एसपीएल) का उत्पादन नहीं करेगा, लेकिन पहले एक ही बेहतर अनुमान लगाएगा।

कुछ ऐप्स के प्रदर्शन को प्राप्त करने के लिए कुछ और करने की आवश्यकता होगी। इनमें से अधिकतर ऐप्स स्लाइडिंग विंडो का उपयोग करते हैं, जिसका अर्थ है रिकॉर्डिंग रखना और ध्वनि स्तर का आकलन करने के लिए x सेकंड की एक विंडो स्लाइड करना। इसके अलावा मैं कुछ मूल्यांकन करूँगा जो डीबी वैल्यू अधिकतम के रूप में उपयोग करने के लिए सबसे उपयुक्त है, अभी यह 90 डीबी (एसपीएल) /0.6325 पा है जो कि एक उचित अनुमान है, यह संभवतः उस से ऊपर की ओर होगा।

जैसे ही मेरे पास अधिक जानकारी होगी, मैं जानकारी अपडेट करूंगा।

+0

आपको बहुत धन्यवाद - यह बहुत उपयोगी है –

+0

क्या आप जानते हैं कि, 'recorder.read (डेटा, 0, बफर आकार) विधि को कॉल करते समय;', अगर रिकॉर्डर हो रहा है परिवर्धन और उन्हें संक्षिप्त डेटा सरणी में संग्रहित करना? अगर मैं समझता हूं कि विधि क्या कर रही है तो मुझे पूरी तरह से यकीन नहीं है। –

+0

ये संग्रहीत माइक्रोफ़ोन से नमूने मान हैं। ये (माइक्रोफोन पर दबाव के रूप में) सकारात्मक और नकारात्मक मूल्यों के बीच मिल जाएगा। तो आयाम प्राप्त करने के लिए आपको किसी प्रकार का औसत या भारित गणना का उपयोग करना होगा .. –