I am using an AVAudioRecorder to check the volume level and accordingly update a UIImageView. However, when I hold the home button down for Siri or when the device receives a phone call, the UIImageView is not updated anymore. This is my current code with this imported in the .h:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
I then used this code to create the recorder and update the UIImageView in the .m:
@interface MyViewController ()
@property NSTimer *checkDecibelLevelsTimer;
@property (strong, nonatomic) IBOutlet UIImageView *visualizer;
@property AVAudioRecorder *recorder;
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
[audioSession setActive:YES error:nil];
NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey,
nil];
NSError *error;
self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (self.recorder) {
[self.recorder prepareToRecord];
self.recorder.meteringEnabled = YES;
[self.recorder record];
} else {
NSLog(@"%@", [error description]);
}
self.checkDecibelLevelsTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03
target: self
selector: @selector(checkDecibelLevelsCallback:)
userInfo: nil
repeats: YES];
}
-(void)checkDecibelLevelsCallback:(NSTimer *)timer {
[self.recorder updateMeters];
if ([self.recorder averagePowerForChannel:0] < -40) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer1"];
} else if ([self.recorder averagePowerForChannel:0] < -35) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer2"];
} else if ([self.recorder averagePowerForChannel:0] < -30) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer3"];
} else if ([self.recorder averagePowerForChannel:0] < -25) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer4"];
} else if ([self.recorder averagePowerForChannel:0] < -20) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer5"];
} else if ([self.recorder averagePowerForChannel:0] < -15) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer6"];
} else if ([self.recorder averagePowerForChannel:0] < -10) {
self.visualizer.image = [UIImage imageNamed:@"Visualizer7"];
} else {
self.visualizer.image = [UIImage imageNamed:@"Visualizer8"];
}
}
I tried to handle interruptions by implementing this code in the .m:
- (void)beginInterruption {
NSLog(@"begin interruption");
[self.recorder pause];
}
- (void)endInterruption {
NSLog(@"end interruption");
[self.recorder record];
}
and adding @interface MyViewController : UIViewController <AVAudioSessionDelegate>
in the .h. I noticed that the NSLog returns nothing and the UIImageView still is not updated. How can I fix this?
Alright, I figured out a solution. I put this in the viewDidLoad method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignInactive) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
and added the following methods:
- (void)willResignInactive {
[self.recorder stop];
}
- (void)didBecomeActive {
[self.recorder record];
}