project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m
changeset 6659 a6030b32b222
parent 6656 6aeaba3ee584
child 6908 896ed2afcfb8
equal deleted inserted replaced
6658:2cccf6b2b89d 6659:a6030b32b222
       
     1 //  MXAudioPlayerFadeOperation.m
       
     2 //
       
     3 //  Created by Andrew Mackenzie-Ross on 30/11/10.
       
     4 //  mackross.net.
       
     5 //
       
     6 
       
     7 #import "MXAudioPlayerFadeOperation.h"
       
     8 #import <AVFoundation/AVFoundation.h>
       
     9 
       
    10 #define SKVolumeChangesPerSecond 15
       
    11 
       
    12 @interface MXAudioPlayerFadeOperation ()
       
    13 @property (nonatomic, retain, readwrite) AVAudioPlayer *audioPlayer; 
       
    14 - (void)beginFadeOperation;
       
    15 - (void)finishFadeOperation;
       
    16 @end
       
    17 
       
    18 @implementation MXAudioPlayerFadeOperation
       
    19 #pragma mark -
       
    20 #pragma mark Properties
       
    21 @synthesize audioPlayer = _audioPlayer;
       
    22 @synthesize fadeDuration = _fadeDuration;
       
    23 @synthesize finishVolume = _finishVolume;
       
    24 @synthesize playBeforeFade = _playBeforeFade;
       
    25 @synthesize pauseAfterFade = _pauseAfterFade;
       
    26 @synthesize stopAfterFade = _stopAfterFade;
       
    27 @synthesize delay = _delay;
       
    28 
       
    29 #pragma mark -
       
    30 #pragma mark Accessors
       
    31 - (AVAudioPlayer *)audioPlayer {
       
    32   AVAudioPlayer *result;
       
    33   @synchronized(self) {
       
    34     result = [_audioPlayer retain];
       
    35   }
       
    36   return [result autorelease];
       
    37 }
       
    38 
       
    39 - (void)setAudioPlayer:(AVAudioPlayer *)anAudioPlayer {
       
    40   @synchronized(self) {
       
    41     if (_audioPlayer != anAudioPlayer) {
       
    42       [_audioPlayer release];
       
    43       _audioPlayer = [anAudioPlayer retain];
       
    44     }
       
    45   }
       
    46 }
       
    47 
       
    48 #pragma mark -
       
    49 #pragma mark NSOperation
       
    50 -(id) initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay {
       
    51   if (self = [super init]) {
       
    52     self.audioPlayer = player;
       
    53     [player prepareToPlay];
       
    54     _fadeDuration = duration;
       
    55     _finishVolume = volume;
       
    56     _playBeforeFade = YES;
       
    57     _stopAfterFade = NO;
       
    58     _pauseAfterFade = (volume == 0.0) ? YES : NO;
       
    59     _delay = timeDelay;
       
    60   }
       
    61   return self;
       
    62 }
       
    63 
       
    64 - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration {
       
    65   return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:duration withDelay:0.0];
       
    66 }
       
    67 
       
    68 - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume {
       
    69   return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:1.0];
       
    70 }
       
    71 
       
    72 - (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player {
       
    73   return [self initFadeWithAudioPlayer:player toVolume:0.0];
       
    74 }
       
    75 
       
    76 - (id) init {
       
    77   ALog(@"Failed to init class (%@) with AVAudioPlayer instance, use initFadeWithAudioPlayer:",[self class]);
       
    78   return nil;
       
    79 }
       
    80 
       
    81 - (void)main {
       
    82   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
    83   [NSThread sleepForTimeInterval:_delay];
       
    84   if ([self.audioPlayer isKindOfClass:[AVAudioPlayer class]]) {
       
    85     [self beginFadeOperation];
       
    86   }
       
    87   else {
       
    88     ALog(@"AudioPlayerFadeOperation began with invalid AVAudioPlayer");
       
    89   }
       
    90   
       
    91   [pool release];
       
    92 }
       
    93 
       
    94 - (void)beginFadeOperation {
       
    95   if (![self.audioPlayer isPlaying] && _playBeforeFade) [self.audioPlayer play];
       
    96   
       
    97   if (_fadeDuration != 0.0) {
       
    98     
       
    99     NSTimeInterval sleepInterval = (1.0 / SKVolumeChangesPerSecond);
       
   100     NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];
       
   101     NSTimeInterval now = startTime;
       
   102     
       
   103     float startVolume = [self.audioPlayer volume];
       
   104     
       
   105     while (now < (startTime + _fadeDuration)) {
       
   106       float ratioOfFadeCompleted = (now - startTime)/_fadeDuration;
       
   107       float volume = (_finishVolume * ratioOfFadeCompleted) + (startVolume * (1-ratioOfFadeCompleted));
       
   108       [self.audioPlayer setVolume:volume];
       
   109       [NSThread sleepForTimeInterval:sleepInterval];
       
   110       now = [[NSDate date] timeIntervalSinceReferenceDate];
       
   111     }
       
   112     
       
   113     [self.audioPlayer setVolume:_finishVolume];
       
   114     [self finishFadeOperation];
       
   115   }
       
   116   else {
       
   117     [self.audioPlayer setVolume:_finishVolume];
       
   118     [self finishFadeOperation];
       
   119   }
       
   120 }
       
   121 
       
   122 - (void)finishFadeOperation {
       
   123   if ([self.audioPlayer isPlaying] && _pauseAfterFade) [self.audioPlayer pause];
       
   124   if ([self.audioPlayer isPlaying] && _stopAfterFade) [self.audioPlayer stop];
       
   125 }
       
   126 
       
   127 - (void)dealloc {
       
   128   releaseAndNil(_audioPlayer);
       
   129   [super dealloc];
       
   130 }
       
   131 
       
   132 @end
       
   133