在iOS里,录音、播放最简单的方法,就是使用AVAudioRecorder和AVAudioPlayer。这两个类也可以轻松得到当前音量:
在init时:
recorder.meteringEnabled = YES
在录音、播放时:
[recorder updateMeters];
[recorder averagePowerForChannel:0];
然而这两个类层级太高,我们只能用苹果开放给我们的接口;对于一些更底层的东西,比如拿到声音的samples,一边录音一边播放等,都无法搞定。这时候,可以使用AudioQueue,AudioUnit等,配合AVAudioSession等使用,此处不表。下面专讲用AudioQueue方法拿到声音数据之后,如何将这些samples转化成音量。
使用AudioQueue录音时,回调方法中可以得到一个AudioBufferList类型的数据,每个frame里有inNumberFrames个数据,有inNumberChannels个channel。inNumberFrames*inNumberChannels的结果,就是AudioBufferList其中一个buffer里的数据量。
AudioBufferList里的buffer里面的数据,根据设置不同,有可能是0-1的float类型,也有可能是int类型,如果是int类型,需要转化为0-1的float类型。
根据这些数据计算音量,需要用到vDSP库,这个库已经封装了很多快速计算的方法,不需要我们自己去实现。计算代码如下:
float* data = (float)malloc(inputBuffer->mBuffers[0].mDataByteSizesizeof(float));
(memcpy(data, (float *)inputBuffer->mBuffers[0].mData, inputBuffer->mBuffers[0].mDataByteSize);)//初始化data
vDSP_vsq(data, 1, data, 1, numFrames*numChannels);
float meanVal = 0.0;
vDSP_meanv(data, 1, &meanVal, numFrames*numChannels);
float one = 1.0;
vDSP_vdbcon(&meanVal, 1, &one, &meanVal, 1, 1, 0);
float decibel = meanVal;
这里,decibel就是音量。音量大小以0为最大,-60为最小。
各vDSP方法代表的含义,可以查询苹果官方文档:https://developer.apple.com/library/mac/documentation/Accelerate/Reference/vDSPRef/index.html