Как сделать уровень аудиометра с помощью avaudiorecorder

Я пытаюсь создать уровень аудиометра, когда я записываю голос пользователя, используя avaudiorecorder. Может ли кто-нибудь помочь мне в этом отношении?

Ответ 1

На самом деле, код довольно прост, так как 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:, вы можете использовать этот метод для обновления своего измерителя уровня.

  • создать подкласс UIView с подвью, который изменяет его высоту в соответствии со средним или максимальным значением (значениями). Отрегулируйте вкус.

Ответ 2

Легко, вы можете использовать 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 вы должны вызвать meteringEnabled ПОСЛЕ того, как вы вызываете prepareToRecord или запись, иначе он не будет обновлятьMeters:

[self.audioRecorder prepareToRecord];
self.audioRecorder.meteringEnabled = YES;

Ответ 3

Быстрое код, основанный на ответе Тома:

 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}

Ответ 4

Его довольно простой, Значения, которые вы получаете в буфере, являются положительными и отрицательными (так работают волны), поэтому, если вы делаете среднее значение этих значений, оно даст вам значение около 0.

Итак, что вам нужно сделать, просто положите все значения положительными (с помощью функции Math.abs()), а затем сделайте avarage, он вернет вам уровень звука.

Надеюсь, что это поможет;)

Ответ 5

Вы также можете использовать 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
      }];

Ответ 6

Я нашел ответ в следующей ссылке.

AVMeter для AVPlayer

Хотя для этого требуется множество настроек, но я чувствую, что смогу это сделать.