API 0.9.5
AppKit/CPSound.j
Go to the documentation of this file.
00001 /*
00002  * CPSound.j
00003  * AppKit
00004  *
00005  * Created by Antoine Mercadal
00006  * Copyright 2010, Antoine Mercadal
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 CPSoundLoadStateEmpty       = 0;
00025 CPSoundLoadStateLoading     = 1;
00026 CPSoundLoadStateCanBePlayed = 2;
00027 CPSoundLoadStateError       = 3;
00028 
00029 CPSoundPlayBackStatePlay    = 0;
00030 CPSoundPlayBackStateStop    = 1;
00031 CPSoundPlayBackStatePause   = 2;
00032 
00033 
00042 @implementation CPSound : CPObject
00043 {
00044     CPString            _name;
00045     id                  _delegate;
00046 
00047     BOOL                _playRequestBeforeLoad;
00048     HTMLAudioElement    _audioTag;
00049     int                 _loadStatus;
00050     int                 _playBackStatus;
00051 }
00052 
00053 #pragma mark -
00054 #pragma mark Initialization
00055 
00056 - (id)init
00057 {
00058     if (self = [super init])
00059     {
00060         _loadStatus = CPSoundLoadStateEmpty;
00061         _loops = NO;
00062         _audioTag = document.createElement("audio");
00063         _audioTag.preload = YES;
00064         _playRequestBeforeLoad = NO;
00065 
00066         _audioTag.addEventListener("canplay", function()
00067         {
00068             [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00069             [self _soundDidload];
00070         }, true);
00071 
00072         _audioTag.addEventListener("ended", function()
00073         {
00074             [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00075             [self _soundDidEnd];
00076         }, true);
00077 
00078         _audioTag.addEventListener("error", function()
00079         {
00080             [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00081             [self _soundError];
00082         }, true);
00083     }
00084 
00085     return self;
00086 }
00087 
00094 - (id)initWithContentsOfFile:(CPString)aFile byReference:(BOOL)byRef
00095 {
00096     if (self = [self init])
00097     {
00098         _loadStatus = CPSoundLoadStateLoading;
00099         _audioTag.src = aFile;
00100     }
00101 
00102     return self;
00103 }
00104 
00111 - (id)initWithContentsOfURL:(CPURL)aURL byReference:(BOOL)byRef
00112 {
00113     return [self initWithContentsOfFile:[aURL absoluteString] byReference:NO];
00114 }
00115 
00122 - (id)initWithData:(CPData)someData
00123 {
00124     if (self = [self init])
00125     {
00126         _loadStatus = CPSoundLoadStateLoading;
00127         _audioTag.src = [someData rawString];
00128     }
00129 
00130     return self;
00131 }
00132 
00133 
00134 #pragma mark -
00135 #pragma mark Events listener
00136 
00139 - (void)_soundDidload
00140 {
00141     _loadStatus = CPSoundLoadStateCanBePlayed;
00142 
00143     if (_playRequestBeforeLoad)
00144     {
00145         _playRequestBeforeLoad = NO;
00146         [self play];
00147     }
00148 }
00149 
00152 - (void)_soundDidEnd
00153 {
00154     if (![self loops])
00155         [self stop];
00156 }
00157 
00160 - (void)_soundError
00161 {
00162     _loadStatus = CPSoundLoadStateError;
00163     CPLog.error("Cannot load sound. Maybe the format of your sound is not compatible with your browser.");
00164 }
00165 
00166 
00167 #pragma mark -
00168 #pragma mark Media controls
00169 
00175 - (BOOL)play
00176 {
00177     if (_loadStatus === CPSoundLoadStateLoading)
00178     {
00179         _playRequestBeforeLoad = YES;
00180         return YES;
00181     }
00182 
00183     if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
00184         || (_playBackStatus === CPSoundPlayBackStatePlay))
00185         return NO;
00186 
00187     _audioTag.play();
00188     _playBackStatus = CPSoundPlayBackStatePlay;
00189 
00190     return YES;
00191 }
00192 
00198 - (BOOL)stop
00199 {
00200     if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
00201         || (_playBackStatus === CPSoundPlayBackStateStop))
00202         return NO;
00203 
00204     _audioTag.pause();
00205     _audioTag.currentTime = 0.0;
00206     _playBackStatus = CPSoundPlayBackStateStop;
00207 
00208     if (_delegate && [_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
00209         [_delegate sound:self didFinishPlaying:YES];
00210 
00211     return YES;
00212 }
00213 
00219 - (BOOL)pause
00220 {
00221     if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
00222         || (_playBackStatus === CPSoundPlayBackStatePause))
00223         return NO;
00224 
00225     _audioTag.pause();
00226     _playBackStatus = CPSoundPlayBackStatePause;
00227 
00228     return YES;
00229 }
00230 
00236 - (BOOL)resume
00237 {
00238     if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
00239         || (_playBackStatus !== CPSoundPlayBackStatePause))
00240         return NO;
00241 
00242     _audioTag.play();
00243     _playBackStatus = CPSoundPlayBackStatePlay;
00244 
00245     return YES;
00246 }
00247 
00253 - (BOOL)loops
00254 {
00255     return _audioTag.loop;
00256 }
00257 
00263 - (void)setLoops:(BOOL)shouldLoop
00264 {
00265     _audioTag.loop = shouldLoop;
00266 }
00267 
00273 - (double)volume
00274 {
00275     return _audioTag.volume;
00276 }
00277 
00283 - (void)setVolume:(double)aVolume
00284 {
00285     if (aVolume > 1.0)
00286         aVolume = 1.0;
00287     else if (aVolume < 0.0)
00288         aVolume = 0.0;
00289 
00290     _audioTag.volume = aVolume;
00291 }
00292 
00293 #pragma mark -
00294 #pragma mark Accessors
00295 
00301 - (double)duration
00302 {
00303     return _audioTag.duration;
00304 }
00305 
00311 - (BOOL)isPlaying
00312 {
00313     return (_playBackStatus === CPSoundPlayBackStatePlay);
00314 }
00315 
00316 @end
00317 
00318 @implementation CPSound (CPSynthesizedAccessors)
00319 
00323 - (CPString)name
00324 {
00325     return _name;
00326 }
00327 
00331 - (void)setName:(CPString)aValue
00332 {
00333     _name = aValue;
00334 }
00335 
00339 - (id)delegate
00340 {
00341     return _delegate;
00342 }
00343 
00347 - (void)setDelegate:(id)aValue
00348 {
00349     _delegate = aValue;
00350 }
00351 
00352 @end
 All Classes Files Functions Variables Defines