00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "OSDLAudioChannel.h"
00028
00029
00030 #include "OSDLAudio.h"
00031
00032
00033 #ifdef OSDL_USES_CONFIG_H
00034 #include "OSDLConfig.h"
00035 #endif // OSDL_USES_CONFIG_H
00036
00037 #if OSDL_ARCH_NINTENDO_DS
00038 #include "OSDLConfigForNintendoDS.h"
00039 #endif // OSDL_ARCH_NINTENDO_DS
00040
00041
00042 #if OSDL_USES_SDL
00043 #include "SDL.h"
00044 #endif // OSDL_USES_SDL
00045
00046 #if OSDL_USES_SDL_MIXER
00047 #include "SDL_mixer.h"
00048 #endif // OSDL_USES_SDL_MIXER
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 using std::string ;
00059
00060
00061
00062 using namespace Ceylan::Log ;
00063
00064 using namespace OSDL::Audio ;
00065
00066
00067
00068 AudioChannelException::AudioChannelException( const string & reason ) :
00069 AudioException( reason )
00070 {
00071
00072 }
00073
00074
00075
00076 AudioChannelException::~AudioChannelException() throw()
00077 {
00078
00079 }
00080
00081
00082
00083
00084 AudioChannel::AudioChannel( ChannelNumber channelNumber ) :
00085 Ceylan::TextDisplayable(),
00086 _channelNumber( channelNumber )
00087 {
00088
00089 #if OSDL_USES_SDL_MIXER
00090
00091
00092
00093 ::Mix_ChannelFinished( HandleFinishedPlaybackCallback ) ;
00094
00095 #else // OSDL_USES_SDL_MIXER
00096
00097 throw AudioChannelException( "AudioChannel constructor failed: "
00098 "no SDL_mixer support available." ) ;
00099
00100 #endif // OSDL_USES_SDL_MIXER
00101
00102 }
00103
00104
00105
00106 AudioChannel::~AudioChannel() throw()
00107 {
00108
00109
00110
00111 }
00112
00113
00114
00115 ChannelNumber AudioChannel::getNumber() const
00116 {
00117
00118 return _channelNumber ;
00119
00120 }
00121
00122
00123
00124 Volume AudioChannel::getVolume() const
00125 {
00126
00127 #if OSDL_USES_SDL_MIXER
00128
00129 return static_cast<Volume>( ::Mix_Volume( _channelNumber, -1 ) ) ;
00130
00131 #else // OSDL_USES_SDL_MIXER
00132
00133 throw AudioChannelException( "AudioChannel::getVolume failed: "
00134 "no SDL_mixer support available" ) ;
00135
00136 #endif // OSDL_USES_SDL_MIXER
00137
00138 }
00139
00140
00141
00142 void AudioChannel::setVolume( Volume newVolume )
00143 {
00144
00145 #if OSDL_USES_SDL_MIXER
00146
00147 ::Mix_Volume( _channelNumber, newVolume ) ;
00148
00149 #else // OSDL_USES_SDL_MIXER
00150
00151 throw AudioChannelException( "AudioChannel::setVolume failed: "
00152 "no SDL_mixer support available" ) ;
00153
00154 #endif // OSDL_USES_SDL_MIXER
00155
00156 }
00157
00158
00159
00160 void AudioChannel::setPanning( Ceylan::Maths::Percentage leftPercentage )
00161 {
00162
00163 #if OSDL_USES_SDL_MIXER
00164
00165 Ceylan::Uint8 left = static_cast<Ceylan::Uint8>(
00166 ( leftPercentage * 254 ) / 100 ) ;
00167
00168 if ( ::Mix_SetPanning( _channelNumber, left,
00169 254 - left ) == 0 )
00170 throw AudioChannelException( "AudioChannel::setPanning failed: "
00171 + string( ::Mix_GetError() ) ) ;
00172
00173 #else // OSDL_USES_SDL_MIXER
00174
00175 throw AudioChannelException( "AudioChannel::setPanning failed: "
00176 "no SDL_mixer support available" ) ;
00177
00178 #endif // OSDL_USES_SDL_MIXER
00179
00180 }
00181
00182
00183
00184 void AudioChannel::unsetPanning()
00185 {
00186
00187 #if OSDL_USES_SDL_MIXER
00188
00189 if ( ::Mix_SetPanning( _channelNumber, 255, 255 ) == 0 )
00190 throw AudioChannelException( "AudioChannel::unsetPanning failed: "
00191 + string( ::Mix_GetError() ) ) ;
00192
00193 #else // OSDL_USES_SDL_MIXER
00194
00195 throw AudioChannelException( "AudioChannel::unsetPanning failed: "
00196 "no SDL_mixer support available" ) ;
00197
00198 #endif // OSDL_USES_SDL_MIXER
00199
00200 }
00201
00202
00203
00204 void AudioChannel::setReverseStereo( bool reverse )
00205 {
00206
00207 #if OSDL_USES_SDL_MIXER
00208
00209 if ( ::Mix_SetReverseStereo( _channelNumber,
00210 ( ( reverse == true ) ? 1 : 0 ) ) == 0 )
00211 throw AudioException( "AudioChannel::setReverseStereo failed: "
00212 + string( ::Mix_GetError() ) ) ;
00213
00214 #else // OSDL_USES_SDL_MIXER
00215
00216 throw AudioChannelException( "AudioChannel::setReverseStereo failed: "
00217 "no SDL_mixer support available" ) ;
00218
00219 #endif // OSDL_USES_SDL_MIXER
00220
00221 }
00222
00223
00224
00225 void AudioChannel::setDistanceAttenuation( ListenerDistance distance )
00226 {
00227
00228 #if OSDL_USES_SDL_MIXER
00229
00230 if ( ::Mix_SetDistance( _channelNumber, distance ) == 0 )
00231 throw AudioChannelException(
00232 "AudioChannel::setDistanceAttenuation failed: "
00233 + string( ::Mix_GetError() ) ) ;
00234
00235 #else // OSDL_USES_SDL_MIXER
00236
00237 throw AudioChannelException( "AudioChannel::setDistanceAttenuation failed: "
00238 "no SDL_mixer support available" ) ;
00239
00240 #endif // OSDL_USES_SDL_MIXER
00241
00242 }
00243
00244
00245
00246 void AudioChannel::unsetDistanceAttenuation()
00247 {
00248
00249 #if OSDL_USES_SDL_MIXER
00250
00251 if ( ::Mix_SetDistance( _channelNumber, 0 ) == 0 )
00252 throw AudioChannelException(
00253 "AudioChannel::unsetDistanceAttenuation failed: "
00254 + string( ::Mix_GetError() ) ) ;
00255
00256 #else // OSDL_USES_SDL_MIXER
00257
00258 throw AudioChannelException(
00259 "AudioChannel::unsetDistanceAttenuation failed: "
00260 "no SDL_mixer support available" ) ;
00261
00262 #endif // OSDL_USES_SDL_MIXER
00263
00264 }
00265
00266
00267
00268 void AudioChannel::setPositionAttenuation( ListenerDistance distance,
00269 ListenerAngle angle )
00270 {
00271
00272 #if OSDL_USES_SDL_MIXER
00273
00274 if ( ::Mix_SetPosition( _channelNumber, distance, angle ) == 0 )
00275 throw AudioChannelException(
00276 "AudioChannel::setPositionAttenuation failed: "
00277 + string( ::Mix_GetError() ) ) ;
00278
00279 #else // OSDL_USES_SDL_MIXER
00280
00281 throw AudioChannelException( "AudioChannel::setPositionAttenuation failed: "
00282 "no SDL_mixer support available" ) ;
00283
00284 #endif // OSDL_USES_SDL_MIXER
00285
00286 }
00287
00288
00289
00290 void AudioChannel::unsetPositionAttenuation()
00291 {
00292
00293 #if OSDL_USES_SDL_MIXER
00294
00295 if ( ::Mix_SetPosition( _channelNumber, 0, 0 ) == 0 )
00296 throw AudioChannelException(
00297 "AudioChannel::unsetPositionAttenuation failed: "
00298 + string( ::Mix_GetError() ) ) ;
00299
00300 #else // OSDL_USES_SDL_MIXER
00301
00302 throw AudioChannelException(
00303 "AudioChannel::unsetPositionAttenuation failed: "
00304 "no SDL_mixer support available" ) ;
00305
00306 #endif // OSDL_USES_SDL_MIXER
00307
00308 }
00309
00310
00311
00312 bool AudioChannel::isPlaying() const
00313 {
00314
00315 #if OSDL_USES_SDL_MIXER
00316
00317 return ( ::Mix_Playing( _channelNumber ) != 0 ) ;
00318
00319 #else // OSDL_USES_SDL_MIXER
00320
00321 throw AudioChannelException( "AudioChannel::isPlaying failed: "
00322 "no SDL_mixer support available" ) ;
00323
00324 #endif // OSDL_USES_SDL_MIXER
00325
00326 }
00327
00328
00329
00330 bool AudioChannel::isPaused() const
00331 {
00332
00333 #if OSDL_USES_SDL_MIXER
00334
00335 return ( ::Mix_Paused( _channelNumber ) != 0 ) ;
00336
00337 #else // OSDL_USES_SDL_MIXER
00338
00339 throw AudioChannelException( "AudioChannel::isPaused failed: "
00340 "no SDL_mixer support available" ) ;
00341
00342 #endif // OSDL_USES_SDL_MIXER
00343
00344 }
00345
00346
00347
00348 FadingStatus AudioChannel::getFadingStatus() const
00349 {
00350
00351 #if OSDL_USES_SDL_MIXER
00352
00353 switch( ::Mix_FadingChannel( _channelNumber ) )
00354 {
00355
00356 case MIX_NO_FADING:
00357 return None ;
00358 break ;
00359
00360 case MIX_FADING_OUT:
00361 return Out ;
00362 break ;
00363
00364 case MIX_FADING_IN:
00365 return In ;
00366 break ;
00367
00368 default:
00369 LogPlug::error(
00370 "AudioChannel::getFadingStatus: unexpected status" ) ;
00371 return None ;
00372 break ;
00373
00374 }
00375
00376 #else // OSDL_USES_SDL_MIXER
00377
00378 throw AudioChannelException( "AudioChannel::isPaused failed: "
00379 "no SDL_mixer support available" ) ;
00380
00381 #endif // OSDL_USES_SDL_MIXER
00382
00383 }
00384
00385
00386
00387 void AudioChannel::pause()
00388 {
00389
00390 #if OSDL_USES_SDL_MIXER
00391
00392 ::Mix_Pause( _channelNumber ) ;
00393
00394 #else // OSDL_USES_SDL_MIXER
00395
00396 throw AudioChannelException( "AudioChannel::pause failed: "
00397 "no SDL_mixer support available" ) ;
00398
00399 #endif // OSDL_USES_SDL_MIXER
00400
00401 }
00402
00403
00404
00405 void AudioChannel::resume()
00406 {
00407
00408 #if OSDL_USES_SDL_MIXER
00409
00410 ::Mix_Resume( _channelNumber ) ;
00411
00412 #else // OSDL_USES_SDL_MIXER
00413
00414 throw AudioChannelException( "AudioChannel::resume failed: "
00415 "no SDL_mixer support available" ) ;
00416
00417 #endif // OSDL_USES_SDL_MIXER
00418
00419 }
00420
00421
00422
00423 void AudioChannel::waitEndOfPlayback() const
00424 {
00425
00426 while ( isPlaying() )
00427 Ceylan::System::atomicSleep() ;
00428
00429 }
00430
00431
00432
00433 void AudioChannel::halt()
00434 {
00435
00436 #if OSDL_USES_SDL_MIXER
00437
00438 ::Mix_HaltChannel( _channelNumber ) ;
00439
00440 #else // OSDL_USES_SDL_MIXER
00441
00442 throw AudioChannelException( "AudioChannel::halt failed: "
00443 "no SDL_mixer support available" ) ;
00444
00445 #endif // OSDL_USES_SDL_MIXER
00446
00447 }
00448
00449
00450
00451 void AudioChannel::expireIn( Ceylan::System::Millisecond expireDuration )
00452 {
00453
00454 #if OSDL_USES_SDL_MIXER
00455
00456 if ( ::Mix_ExpireChannel( _channelNumber, expireDuration ) != 1 )
00457 throw AudioChannelException( "AudioChannel::expireIn failed: "
00458 + string( ::Mix_GetError() ) ) ;
00459
00460 #else // OSDL_USES_SDL_MIXER
00461
00462 throw AudioChannelException( "AudioChannel::expireIn failed: "
00463 "no SDL_mixer support available" ) ;
00464
00465 #endif // OSDL_USES_SDL_MIXER
00466
00467 }
00468
00469
00470
00471 void AudioChannel::fadeOutDuring( Ceylan::System::Millisecond fadeOutDuration )
00472 {
00473
00474 #if OSDL_USES_SDL_MIXER
00475
00476 if ( ::Mix_FadeOutChannel( _channelNumber, fadeOutDuration ) != 1 )
00477 throw AudioChannelException( "AudioChannel::fadeOutDuring failed: "
00478 + string( ::Mix_GetError() ) ) ;
00479
00480
00481 #else // OSDL_USES_SDL_MIXER
00482
00483 throw AudioChannelException( "AudioChannel::fadeOutDuring failed: "
00484 "no SDL_mixer support available" ) ;
00485
00486 #endif // OSDL_USES_SDL_MIXER
00487
00488 }
00489
00490
00491
00492 void AudioChannel::onPlaybackFinished()
00493 {
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504
00505
00506
00507 const string AudioChannel::toString( Ceylan::VerbosityLevels level ) const
00508 {
00509
00510 return "Mixing channel #" + Ceylan::toString( _channelNumber ) ;
00511
00512 }
00513
00514
00515
00516
00517
00518
00519 void AudioChannel::HandleFinishedPlaybackCallback( int channelNumber )
00520 {
00521
00522 try
00523 {
00524
00525 OSDL::Audio::getExistingAudioModule().getMixingChannelAt(
00526 static_cast<ChannelNumber>( channelNumber ) ).onPlaybackFinished() ;
00527
00528 }
00529 catch( const AudioException & e )
00530 {
00531
00532 LogPlug::error( "AudioChannel::HandleFinishedPlaybackCallback failed: "
00533 + e.toString() ) ;
00534
00535 }
00536
00537 }
00538