diff -r 1edd500b2471 -r 6aeaba3ee584 project_files/HedgewarsMobile/MXAudioPlayerFadeOperation.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/HedgewarsMobile/MXAudioPlayerFadeOperation.m Thu Feb 09 17:28:05 2012 +0100 @@ -0,0 +1,133 @@ +// MXAudioPlayerFadeOperation.m +// +// Created by Andrew Mackenzie-Ross on 30/11/10. +// mackross.net. +// + +#import "MXAudioPlayerFadeOperation.h" +#import + +#define SKVolumeChangesPerSecond 15 + +@interface MXAudioPlayerFadeOperation () +@property (nonatomic, retain, readwrite) AVAudioPlayer *audioPlayer; +- (void)beginFadeOperation; +- (void)finishFadeOperation; +@end + +@implementation MXAudioPlayerFadeOperation +#pragma mark - +#pragma mark Properties +@synthesize audioPlayer = _audioPlayer; +@synthesize fadeDuration = _fadeDuration; +@synthesize finishVolume = _finishVolume; +@synthesize playBeforeFade = _playBeforeFade; +@synthesize pauseAfterFade = _pauseAfterFade; +@synthesize stopAfterFade = _stopAfterFade; +@synthesize delay = _delay; + +#pragma mark - +#pragma mark Accessors +- (AVAudioPlayer *)audioPlayer { + AVAudioPlayer *result; + @synchronized(self) { + result = [_audioPlayer retain]; + } + return [result autorelease]; +} + +- (void)setAudioPlayer:(AVAudioPlayer *)anAudioPlayer { + @synchronized(self) { + if (_audioPlayer != anAudioPlayer) { + [_audioPlayer release]; + _audioPlayer = [anAudioPlayer retain]; + } + } +} + +#pragma mark - +#pragma mark NSOperation +-(id) initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay { + if (self = [super init]) { + self.audioPlayer = player; + [player prepareToPlay]; + _fadeDuration = duration; + _finishVolume = volume; + _playBeforeFade = YES; + _stopAfterFade = NO; + _pauseAfterFade = (volume == 0.0) ? YES : NO; + _delay = timeDelay; + } + return self; +} + +- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration { + return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:duration withDelay:0.0]; +} + +- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume { + return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:1.0]; +} + +- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player { + return [self initFadeWithAudioPlayer:player toVolume:0.0]; +} + +- (id) init { + ALog(@"Failed to init class (%@) with AVAudioPlayer instance, use initFadeWithAudioPlayer:",[self class]); + return nil; +} + +- (void)main { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [NSThread sleepForTimeInterval:_delay]; + if ([self.audioPlayer isKindOfClass:[AVAudioPlayer class]]) { + [self beginFadeOperation]; + } + else { + ALog(@"AudioPlayerFadeOperation began with invalid AVAudioPlayer"); + } + + [pool release]; +} + +- (void)beginFadeOperation { + if (![self.audioPlayer isPlaying] && _playBeforeFade) [self.audioPlayer play]; + + if (_fadeDuration != 0.0) { + + NSTimeInterval sleepInterval = (1.0 / SKVolumeChangesPerSecond); + NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate]; + NSTimeInterval now = startTime; + + float startVolume = [self.audioPlayer volume]; + + while (now < (startTime + _fadeDuration)) { + float ratioOfFadeCompleted = (now - startTime)/_fadeDuration; + float volume = (_finishVolume * ratioOfFadeCompleted) + (startVolume * (1-ratioOfFadeCompleted)); + [self.audioPlayer setVolume:volume]; + [NSThread sleepForTimeInterval:sleepInterval]; + now = [[NSDate date] timeIntervalSinceReferenceDate]; + } + + [self.audioPlayer setVolume:_finishVolume]; + [self finishFadeOperation]; + } + else { + [self.audioPlayer setVolume:_finishVolume]; + [self finishFadeOperation]; + } +} + +- (void)finishFadeOperation { + if ([self.audioPlayer isPlaying] && _pauseAfterFade) [self.audioPlayer pause]; + if ([self.audioPlayer isPlaying] && _stopAfterFade) [self.audioPlayer stop]; +} + +- (void)dealloc { + releaseAndNil(_audioPlayer); + [super dealloc]; +} + +@end +