iOS 音頻分貝的計算


https://blog.csdn.net/ioszg/article/details/42553061

https://cloud.tencent.com/developer/article/1121060

https://github.com/qiubaiying/Noise-meter-Demo

 

https://www.oschina.net/question/565065_138761

  16位二進制數的最小值是0000000000000000,最大值是1111111111111111,對應的十進制數就是0和65535,也就是最大和最小值之間的差值是65535,也就是說,它量化的模擬量的動態范圍可以差65535,也就是96.32分貝,所以,量化精度只和動態范圍有關,和頻率響應沒關系。(摘抄)

計算公式:96.32=20*lg(65535);  

 

70分貝 大聲說話,舒適度上限(比這個聲音大的就很吵了)
40~60分貝 一般說話
50-53分貝:洗衣機的工作聲
50分貝 辦公室
40分貝 圖書館,閱覽室(超過這個聲音就影響睡眠
 
 

目錄

 

 

返回目錄 

1. 關於錄音和Audio Session Categories

如果AVAudioRecorder的averagePowerForChannel和peakPowerForChannel方法總是返回-160的話,那么很有可能是當前的Audio Session Categories不允許進行音頻輸入(也就是麥克風輸入)。如:AVAudioSessionCategorySoloAmbient/kAudioSessionCategory_SoloAmbientSound,或者AVAudioSessionCategoryPlayback/kAudioSessionCategory_MediaPlayback。

 

如果這樣的話,我們需要把當前Audio Session Categories設置成AVAudioSessionCategoryRecord/kAudioSessionCategory_RecordAudio,或者AVAudioSessionCategoryPlayAndRecord/kAudioSessionCategory_PlayAndRecord。

可以使用兩套API,一種是AVFoundation Framework中的API。如下:

NSError *setCategoryError = nil;

BOOL success = [[AVAudioSession sharedInstance]

                setCategory: AVAudioSessionCategoryRecord

                //或者AVAudioSessionCategoryPlayAndRecord

                error: &setCategoryError];

 

另一種是使用AudioToolbox Framework,它是基於C的API,如下:

//或者使用kAudioSessionCategory_PlayAndRecord

UInt32 sessionCategory = kAudioSessionCategory_RecordAudio;

OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);

 

返回目錄 

2. 分貝數據的處理

根據Apple文檔,AVAudioRecorder的averagePowerForChannel和peakPowerForChannel方法返回的是分貝數據,數值在-160 - 0之間(可能會返回大於0的值如果超出了極限)。在實際測試中,比如我在辦公室(不算吵也不算特別安靜的環境下)我測試averagePowerForChannel的返回值平均在-35左右徘徊。

有很多方法可以把這個原始的分貝數據轉化成更可讀或者更可用的形式。如Apple SpeakHere Sample

或者自己手動設置一個分貝的范圍,然后根據比例輸出自己需要的分貝范圍:比如下段代碼:

//用於監控AVAudioRecorder數據的Timer回調方法。

//注意設置AVAudioRecorder的meteringEnabled屬性為YES。

//recorder變量是AVAudioRecorder對象。

- (void)timerCallback:(NSTimer *)timer

{

    [recorder updateMeters];

    //averagePowerForChannel調用結果

    float avg = [recorder averagePowerForChannel:0];

    //比如把-60作為最低分貝

    float minValue = -60;

    //把60作為獲取分配的范圍

    float range = 60;

    //把100作為輸出分貝范圍

    float outRange = 100;

    //確保在最小值范圍內

    if (avg < minValue)

    {

        avg = minValue;

    }

    //計算顯示分貝

    float decibels = (avg + range) / range * outRange;

    NSLog(@"%f",  decibels);

}

在辦公室下分貝大約在40左右。

 

還有這種方法,覺得他更符合現實的分貝數據,代碼:

//用於監控AVAudioRecorder數據的Timer回調方法。

//注意設置AVAudioRecorder的meteringEnabled屬性為YES。

//recorder變量是AVAudioRecorder對象。

//http://stackoverflow.com/questions/9247255/am-i-doing-the-right-thing-to-convert-decibel-from-120-0-to-0-120/16192481#16192481

- (void)levelTimerCallback:(NSTimer *)timer {

[recorder updateMeters];

   

    float   level;                // The linear 0.0 .. 1.0 value we need.

    float   minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room.

    float   decibels = [recorder averagePowerForChannel:0];

    if (decibels < minDecibels)

    {

        level = 0.0f;

    }

    else if (decibels >= 0.0f)

    {

        level = 1.0f;

    }

    else

    {

        float   root            = 2.0f;

        float   minAmp          = powf(10.0f, 0.05f * minDecibels);

        float   inverseAmpRange = 1.0f / (1.0f - minAmp);

        float   amp             = powf(10.0f, 0.05f * decibels);

        float   adjAmp          = (amp - minAmp) * inverseAmpRange;

       

        level = powf(adjAmp, 1.0f / root);

    }   

    NSLog(@"平均值 %f", level * 120);

}

 

 

返回目錄 

3. iOS 7中默認配置的變化

在iOS 6中,AVAudioRecorder的默認配置(通過其settings屬性)是:

{

    AVFormatIDKey = 1819304813;

    AVLinearPCMBitDepthKey = 16;

    AVLinearPCMIsBigEndianKey = 0;

    AVLinearPCMIsFloatKey = 0;

    AVLinearPCMIsNonInterleaved = 0;

    AVNumberOfChannelsKey = 1;

    AVSampleRateKey = 44100;

}

 

而在iOS 7中,默認配置是:

{

    AVFormatIDKey = 1819304813;

    AVLinearPCMBitDepthKey = 16;

    AVLinearPCMIsBigEndianKey = 0;

    AVLinearPCMIsFloatKey = 0;

    AVLinearPCMIsNonInterleaved = 0;

    AVNumberOfChannelsKey = 2;

    AVSampleRateKey = 44100;

}

 

變化是AVNumberOfChannelsKey從1變成了2,也就是支持兩個音道的錄制,顯然一個麥克風不需要,最好把AVNumberOfChannelsKey設置成1。

關於AVAudioRecorder的配置項,可以參考這個帖子

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM