我已经为录音应用程序构建了一个模拟的模拟 VU 表,并且所有内容都正确连接并按照我期望的方式工作,除了一个方面。如果您观看这个 13 秒的 VU 表运行视频,您会看到指针到处弹跳,这并不是真正的 VU 表中会发生的情况。有关我正在寻找的示例,请试用 Apple“语音备忘录”应用程序并查看。
到目前为止,我的逻辑很简单:
#define VU_METER_FREQUENCY 1.0/5.0
- (void)someMethod {
_updateTimer = [NSTimer
scheduledTimerWithTimeInterval:VU_METER_FREQUENCY
target:self
selector:@selector(_refresh)
userInfo:nil
repeats:YES];
}
- (void)_refresh {
// if we have no queue, but still have levels, gradually bring them down
if (_delegate == nil) {
CFAbsoluteTime thisFire = CFAbsoluteTimeGetCurrent();
// calculate how much time passed since the last draw
CFAbsoluteTime timePassed = thisFire - _peakFalloffLastFire;
needleValue = needleValue - timePassed * VU_METER_LEVEL_FALL_OFF_PER_SECOND;
if (needleValue < VU_METER_MIN_DB) {
needleValue = VU_METER_MIN_DB;
TT_INVALIDATE_TIMER(_updateTimer);
}
_peakFalloffLastFire = thisFire;
} else {
prevNeedleValue = needleValue;
needleValue = [_delegate currentDB];
}
[self updateNeedle];
}
- (void)updateNeedle {
[UIView beginAnimations:nil context:NULL]; // arguments are optional
[UIView setAnimationDuration:VU_METER_FREQUENCY];
[UIView setAnimationCurve:(needleValue > prevNeedleValue ? UIViewAnimationCurveEaseOut : UIViewAnimationCurveEaseIn)];
CGFloat radAngle = [self radianAngleForValue:needleValue];
self.needle.transform = CGAffineTransformMakeRotation(radAngle);
[UIView commitAnimations];
}
基本上,我设置了一个计时器来运行VU_METER_FREQUENCY
并使用带有缓动的 UIView 动画更新指针旋转,该动画优先保持指针更高。我正在寻找一种方法来调整它以提供更平滑的指针,我的基准尽可能接近 Apple 的模拟 VU Meter。为了得到needleValue
,我使用AudioQueue
'smAveragePower
并在每次currentDB
调用时查询它。我怎样才能平滑这个?