AVAudioRecorder averagePowerForChannel всегда возвращает -120.0 - PullRequest
9 голосов
/ 17 февраля 2011

Я пытаюсь использовать метод AveragePowerForChannel AVAudioRecorder для мониторинга уровней входного сигнала на микрофоне для приложения для iPad / iPhone.У меня есть обратный вызов, который опрашивает средний уровень в цикле - на iPhone он работает нормально и возвращает разумные уровни, но по какой-то причине на iPad он всегда возвращает -120.0.

Вот некоторые из моих кодов установки:

- (void) setupMic {
if (micInput) {
    [micInput release];
    micInput = nil;
}
NSURL *newURL = [[NSURL alloc] initFileURLWithPath:@"/dev/null"];

NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];

[recordSettings setObject:[NSNumber numberWithInt:kAudioFormatAppleLossless] forKey: AVFormatIDKey];
[recordSettings setObject:[NSNumber numberWithFloat:22050.0] forKey: AVSampleRateKey];
//  [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSettings setObject:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
[recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSettings setObject:[NSNumber numberWithInt: AVAudioQualityLow] forKey: AVEncoderAudioQualityKey];

micInput = [[AVAudioRecorder alloc] initWithURL:newURL settings:recordSettings error:nil];
//  [micInput setMeteringEnabled:YES];

[newURL release];
[recordSettings removeAllObjects];
[recordSettings release];
}

, а также мой метод начала записи:

- (void) startRecording {
NSLog(@"startRecording!");
[micInput pause];
[micInput prepareToRecord];
micInput.meteringEnabled = YES;
[micInput record];
[micInput updateMeters];
levelTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.0] interval:0.03 target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:levelTimer forMode:NSDefaultRunLoopMode];
}

и немного обратного вызова levelTimer:

- (void)levelTimerCallback:(NSTimer *)timer {
[micInput updateMeters];
double avgPowerForChannel = pow(10, (0.05 * [micInput averagePowerForChannel:0]));
[micSprite receiveInput:avgPowerForChannel];

NSLog(@"Avg. Power: %f", [micInput averagePowerForChannel:0]);

 ...

}

Где на iPhone оператор NSLog будет возвращать разумные значения, а iPad всегда будет возвращать -120.0.

Примечание: я использую это внутри приложения cocos2d.По какой-то причине, если я перезапущу текущую сцену на iPad, уровни микрофонов вернут правильные значения.

У кого-нибудь есть какие-либо предложения?Я серьезно в растерянности здесь.Спасибо!

Ответы [ 5 ]

19 голосов
/ 04 апреля 2011

У меня была такая же проблема. Я обнаружил, что установка категории в AVAudioSessionCategoryPlayAndRecord исправляет это:

NSError *error;
[[AVAudioSession sharedInstance] 
    setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];

if (error) {
    NSLog(@"Error setting category: %@", [error description]);
}
1 голос
/ 11 февраля 2012

Да, я тоже. Существует только один общий AVAudioSession. Установка его категории влияет на все рекордеры и проигрыватели, поэтому установка категории на AVAudioSessionCategoryPlay в одной области приложения, например, отключает рекордеры в других областях.

0 голосов
/ 15 апреля 2017

Вам нужно запустить AVAudioSession (это следует сделать методом didMoveToview, это может быть причиной проблемы)

let session = AVAudioSession.sharedInstance()
    try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
    try session.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
    try session.setActive(true)
try recorder = AVAudioRecorder(url: getDocumentsDirectory(), settings: settings)

и запустить регистратор

func start() {
    recorder?.record()
    recorder?.updateMeters()
}

и получитьдецибелы, вызывая

let decibels = recorder.averagePower(forChannel: 0)

от -120 (минимальное значение) до 0. Уровень шума в некоторых кафе, например, -20

, вот более подробный пример http://www.mikitamanko.com/blog/2017/04/15/swift-how-to-get-decibels/ Примечание: используйте также метод обновления.

0 голосов
/ 10 декабря 2015

1) Убедитесь, что у вас есть разрешение:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    if([[AVAudioSession sharedInstance] respondsToSelector:@selector(requestRecordPermission:)])
    {
        [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
            NSLog(@"permission : %d", granted);
            if(granted)[self setupMic];// record ...
        }];
    }
}

2) Убедитесь, что ваш путь допустим (/ dev / null ok ??):

NSString* dir=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSArray *pathComponents = [NSArray arrayWithObjects:dir,fileName,nil];
recordedAudioURL = [NSURL fileURLWithPathComponents:pathComponents];

3)активировать audioSession

 [audioSession setActive:YES error:&error];

4) Проверить все ошибки и вернуть значения, включая

BOOL ok=[micInput prepareToRecord];
ok=ok &&[micInput record];
0 голосов
/ 07 июля 2012

Другая возможная причина этого действительно проста, убедитесь, что вы звоните [запись рекордера];

Эта строка была случайно удалена, и нам потребовалось некоторое время, чтобы признать это как причину -120значения, возвращаемые на счетчик.

HTH

...