Задержка счетчика AVAudioRecorder на iPad - PullRequest
4 голосов
/ 11 июля 2011

У меня проблемы с получением точного показания счетчика от AVAudioRecorder (тестирование на iPad).

Кажется, что работает нормально, когда громкость растет, однако задержка происходит, когда громкость падает.Например: я говорю в микрофон и медленно повышаю голос.Показания увеличиваются с -35,567 до -34,678 до -10,579, как я и надеялся, но когда я перестаю говорить, происходит задержка в 1 - 2 секунды, прежде чем он снова падает до -35,567 (или что бы то ни было).NSLog продолжает обновляться из цикла, но номер счетчика остается неизменным во время задержки, даже если звук давно закончился.

Я добавил суть кода ниже и был бы рад предоставить полный код, еслинеобходимо.

Я инициализирую рекордер следующим образом:

AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: &error];
[audioSession setActive:YES error: &error];

NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory()  stringByAppendingPathComponent: [NSString stringWithString: @"Recording.caf"]]];

recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder setMeteringEnabled:YES];

[recorder record];

и обновляю счетчик в цикле:

-(void) loop:(ccTime)dt 
{
    if(isRecording == YES)
    {        
        //get volume levels
        [recorder updateMeters];
        float level = [recorder peakPowerForChannel:0];
        NSLog(@"Vol: %f", level);
    }
}

отредактировано: Я должен также упомянуть, что я использую расписание Cocos2d для цикла:

[self schedule:@selector(loop:)];

Есть идеи, почему будет такая большая задержка?

отредактировано: Iпытался использовать среднюю пиковую мощность, и это не имеет задержки.Так что я мог бы использовать это как обходной путь.Однако я бы не стал использовать усредненную пиковую мощность, и было бы неплохо понять, что происходит.

Ответы [ 3 ]

3 голосов
/ 13 сентября 2011

Я уверен, что большинство уже поняли это, но если вы хотите меньше задержек при измерении, вам нужно использовать AudioQueue или RemoteIO. Смотри лучшее объяснение здесь:

Путаница со счетчиками в AVAudioRecorder

2 голосов
/ 28 июня 2013

Это можно исправить, сбросив свойство meteringEnabled на YES.

yourRecorderName.meteringEnabled = YES

Вызывайте это каждый раз, когда вы хотите, чтобы уровни сбрасывались до уровней окружающей среды. Это займет около 0,02 секунды, и за это время уровни кратковременно упадут до 0 или -120 дБ, прежде чем вернуться в состояние окружающей среды.

В качестве альтернативы вы можете использовать:

[yourRecorderName stop]
[yourRecorderName record]

Это займет около 0,05 секунды, но уровни не упадут до 0 во время ожидания. Фактически, ничего не произойдет, потому что в этом случае объекту записи фактически требуется 0,05 секунды, чтобы остановить и снова начать запись.

1 голос
/ 14 июля 2011

Как насчет использования таймера? это было бы намного быстрее после

NSError* error
        if (recorder) {
            recorder.meteringEnabled = YES;
            [recorder record];
            levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
    } else
            NSLog(@" error %@",[error description]);
        }

Где levelTimer - это NStimer, который вызывает функцию, которая делает то, что вы хотите (levelTimerCallback :), обновляет счетчики и т. Д.

   -(IBAction)levelTimerCallback:(NSTimer*)timer
{
     [recorder updateMeters];
        float level = [recorder peakPowerForChannel:0];
        NSLog(@"Vol: %f", level);
}
...