基于音量级反馈的UIImageView动画

时间:2015-06-16 10:11:01

标签: ios objective-c uiimageview avaudioplayer avaudiorecorder

我需要使用自定义模式创建音频级别可视化工具。我将图像设置为png' s。 我目前的做法是这样的

1)获取麦克风的音频电平

2)根据音量级别将相关图像加载到UIImageView。

// audio level timer
self.levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.001 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];

ImageView的

- (void)levelTimerCallback:(NSTimer *)timer {
[self.audioRecorder updateMeters];
const double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0]));
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;

//NSLog(@"Average input: %f Peak input: %f Low pass results: %f", [self.audioRecorder averagePowerForChannel:0], [self.audioRecorder peakPowerForChannel:0], lowPassResults);

if (lowPassResults > 0.0 && lowPassResults <= 0.05){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim1"];
}
if (lowPassResults > 0.06 && lowPassResults <= 0.10){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim2"];
}
if (lowPassResults > 0.11 && lowPassResults <= 0.15){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim3"];
}
if (lowPassResults > 0.16 && lowPassResults <= 0.20){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim4"];
}
if (lowPassResults > 0.21 && lowPassResults <= 0.25){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim5"];
}
if (lowPassResults > 0.26 && lowPassResults <= 0.30){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim6"];
}
if (lowPassResults > 0.31 && lowPassResults <= 0.35){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim7"];
}
if (lowPassResults > 0.36 && lowPassResults <= 0.40){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim8"];
}
if (lowPassResults > 0.41 && lowPassResults <= 0.45){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim9"];
}
if (lowPassResults > 0.46 && lowPassResults <= 0.50){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim10"];
}
if (lowPassResults > 0.51 && lowPassResults <= 0.55){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim11"];
}
if (lowPassResults > 0.56 && lowPassResults <= 0.60){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim12"];
}
if (lowPassResults > 0.61 && lowPassResults <= 0.65){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim13"];
}
if (lowPassResults > 0.66 && lowPassResults <= 0.70){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim14"];
}
if (lowPassResults > 0.71 && lowPassResults <= 0.75){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim15"];
}
if (lowPassResults > 0.76 && lowPassResults <= 0.80){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim16"];
}
if (lowPassResults > 0.81 && lowPassResults <= 0.85){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim17"];
}
if (lowPassResults > 0.86 && lowPassResults <= 0.90){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim18"];
}
if (lowPassResults > 0.86){
    imgViewRecordAnimation.image = nil;
    imgViewRecordAnimation.image = [UIImage imageNamed:@"anim19"];
}

}

但是输出并不是一个真实的可视化动画。什么应该是最好的方法?分享那里有更好的方法来做到这一点。

几张图片

enter image description here

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

如果您觉得图像变化看起来不稳定,最好在它们上应用动画。顺便说一下,您不需要将nil设置为imgViewRecordAnimation.image,因为您在此之后始终设置正确的图像,这将引入不必要的延迟。你也可以将所有if语句都设置为else,否则每次都执行所有if语句。

来到解决方案,您只需按照@MileAtNobel发布的链接即可。或者,如果您不想进行太多代码更改,则可以在backgroundColor属性上应用简单动画。您也可以删除计时器,检查下面的代码,看看代码是否正常工作。我也试图以非常相似的方式优化代码,我希望这会提高性能。

BOOL flagToContinue ; //assign NO to this flag to stop updating the images

-(void)levelTimerCallback
{
    NSLog(@"Volume Logic Begins") ;//Volume level logic begins
    [self.audioRecorder updateMeters];
    const double ALPHA = 0.05;
    double peakPowerForChannel = pow(10, (0.05 * [self.audioRecorder peakPowerForChannel:0]));
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults ;
    NSLog(@"Volume Logic ends") ;//Volume level logic ends

    [UIView animateWithDuration:0.001f
              delay:0.0f
            options: UIViewAnimationOptionCurveLinear
         animations:^{
           mgViewRecordAnimation.backgroundColor = [UIColor colorWithPatternImage:[NSString stringWithFormat:@"anim%d", (int)ceil(lowPassResults * 20)]];
         }
         completion:^(BOOL finished) {
           if(finished && flagToContinue) [self levelTimerCallback];
    }];
}

答案 1 :(得分:2)

好的,我不会给你一个直接的解决方案,但会尝试建议一个你必须尝试的解决方案。 因此,不要更改imageView的图像,而是编写自定义控件。 创建视图的子类。覆盖drawrect方法。在这种情况下,您可以根据控制值绘制所需的图案,也可以绘制图像本身。但建议采用第一种方法。 与更改图像相比,自定义绘图是平滑的。 请试一试,让我知道这是有效的。