iPad上的AVAudioRecorder电表延迟

时间:2011-07-11 05:53:10

标签: iphone xcode ipad audio avaudiorecorder

我无法从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:)];

为什么会有这么长的延迟?

编辑:我尝试过使用平均峰值功率,这没有延迟。所以我可以用它作为一种解决方法。但是我宁愿不使用和平均峰值功率,也很好理解发生了什么。

3 个答案:

答案 0 :(得分:3)

我确信大多数人已经明白这一点,但如果你想减少你的计量延迟,你需要使用AudioQueue或RemoteIO。请在此处查看更好的解释:

Confusion with meters in AVAudioRecorder

答案 1 :(得分:2)

您可以通过将meteringEnabled属性重置为YES来解决此问题。

yourRecorderName.meteringEnabled = YES

每次希望级别重置为环境级别时调用此方法。这大约需要0.02秒,在此期间,电平将在重置为环境之前短暂下降至0或-120 dB。

或者,您可以使用:

[yourRecorderName stop]
[yourRecorderName record]

这大约需要0.05秒,但等待时间内的等级不会下降到0。事实上,什么都不会发生,因为在这种情况下,它实际上需要记录器对象0.05秒才能停止并再次开始记录。

答案 2 :(得分:1)

使用计时器怎么样?它会变得更快 之后

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);
}