我正在尝试使用avaudiorecorder录制用户语音时创建音频表级别。在这方面有人可以帮助我吗?
答案 0 :(得分:16)
实际上,代码非常简单,因为AVAudioPlayer和AVAudioRecorder已经内置了方法来帮助您。我的方法是:
-updateMeters
和averagePowerForChannel:
& peakPowerForChannel:
方法并调用委托方法来通知控制对象示例:
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
NSInvocationOperation *operation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateMeter) object:nil];
[queue addOperation: operation];
和
-(void)updateMeter
{
do {
//don't forget:
[recorder updateMeters];
self.averagePower = [recorder averagePowerForChannel:0];
self.peakPower = [recorder peakPowerForChannel:0];
// we don't want to surprise a ViewController with a method call
// not in the main thread
[self.delegate performSelectorOnMainThread: @selector(meterLevelsDidUpdate:) withObject:self waitUntilDone:NO];
[NSThread sleepForTimeInterval:.05]; // 20 FPS
}while(someCondition);
}
如果您的View Controller实现了meterLevelsDidUpdate:
方法,您可以使用此方法更新您的水平仪。
答案 1 :(得分:7)
很简单,您可以使用NSTimer:
- (void)startAudioMetering {
self.meterTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateAudioMeter)userInfo:nil repeats:YES];
}
- (void)stopAudioMetering {
[self.meterTimer invalidate];
}
- (void)updateAudioMeter { //called by timer
// audioRecorder being your instance of AVAudioRecorder
[self.audioRecorder updateMeters];
self.dBLevel = [self.audioRecorder averagePowerForChannel:0];
}
警告:在创建AVAudioRecorder实例时,您必须在调用prepareToRecord或记录后调用meteringEnabled,否则它将不会更新计时器:
[self.audioRecorder prepareToRecord];
self.audioRecorder.meteringEnabled = YES;
答案 2 :(得分:2)
Swift 代码:
NSOperationQueue().addOperationWithBlock({[weak self] in
repeat {
self?.audioRecorder.updateMeters()
self?.averagePower = self?.audioRecorder.averagePowerForChannel(0)
self?.peakPower = self?.audioRecorder.peakPowerForChannel(0)
self?.performSelectorOnMainThread(#selector(DictaphoneViewController.updateMeter), withObject: self, waitUntilDone: false)
NSThread.sleepForTimeInterval(0.05)//20 FPS
}
while (someCondition)
})
在func updateMeter(){//UI stuff here}
答案 3 :(得分:0)
非常简单, 您在缓冲区中获得的值是正数和负数(这是波的工作方式),因此如果您执行该值的平均值,它将为您提供接近0的值。
所以你要做的就是把所有的值都放在正面(用Math.abs()函数),然后做avarage,它会返回你的声级。
希望这会有所帮助;)
答案 4 :(得分:0)
您还可以使用ReactiveCocoa并使用interval:onScheduler:
:
返回一个信号,该信号在调度程序上的每个间隔发送当前日期/时间。
使用单个音频通道:
@weakify(self)
RACDisposable *metersDisposable = [[RACSignal // make sure you dispose it eventually
interval:0.1
onScheduler:[RACScheduler scheduler]]
subscribeNext:^(NSDate *) {
@strongify(self)
[recorder updateMeters];
auto averagePower = [recorder averagePowerForChannel:0];
auto peakPower = [recorder peakPowerForChannel:0];
// Inform the delegate or make other use of averagePower and peakPower
}];
答案 5 :(得分:-5)