如何使用avaudiorecorder制作音频表级别

时间:2011-03-22 07:32:25

标签: iphone

我正在尝试使用av​​audiorecorder录制用户语音时创建音频表级别。在这方面有人可以帮助我吗?

6 个答案:

答案 0 :(得分:16)

实际上,代码非常简单,因为AVAudioPlayer和AVAudioRecorder已经内置了方法来帮助您。我的方法是:

  • 重复拨打-updateMetersaveragePowerForChannel:& 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:方法,您可以使用此方法更新您的水平仪。

  • 创建一个UIView子类,其子视图根据平均值或峰值更改其高度。调整味道。

答案 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)

根据Tom的回答

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}

中填写米尺UI

答案 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)

我在以下链接中找到了答案。

AVMeter for AVPlayer

虽然它需要很多自定义,但我觉得我能够做到。