iOS: 使用AVAudioRecorder中遇到的问题

此博客解决了我在开发时所遇到的问题

转载与此处:http://www.cnblogs.com/mgen/p/3374987.html


目录

  • 1. 关于录音和Audio Session Categories
  • 2. 分贝数据的处理
  • 3. iOS 7中默认配置的变化

 

返回目录

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]

                setCategoryAVAudioSessionCategoryRecord

                //或者AVAudioSessionCategoryPlayAndRecord

                error: &setCategoryError];

 

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

//或者使用kAudioSessionCategory_PlayAndRecord

UInt32 sessionCategory = kAudioSessionCategory_RecordAudio;

OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategorysizeof(sessionCategory), &sessionCategory);

 

返回目录

2. 分贝数据的处理

根据Apple文档,AVAudioRecorder的averagePowerForChannel和peakPowerForChannel方法返回的是分贝数据,数值在-160 - 0之间(可能会返回大于0的值如果超出了极限)。在实际测试中,比如我在办公室(不算吵也不算特别安静的环境下)我测试averagePowerForChannel的返回值平均在-35左右徘徊。

有很多方法可以把这个原始的分贝数据转化成更可读或者更可用的形式。如Apple SpeakHere Sample。

或者自己手动设置一个分贝的范围,然后根据比例输出自己需要的分贝范围:比如下段代码:

//用于监控AVAudioRecorder数据的Timer回调方法。

//注意设置AVAudioRecordermeteringEnabled属性为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回调方法。

//注意设置AVAudioRecordermeteringEnabled属性为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.0f0.05f * minDecibels);

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

        float   amp             = powf(10.0f0.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的配置项,可以参考这个帖子。


你可能感兴趣的:(iOS: 使用AVAudioRecorder中遇到的问题)