home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / audio / audio.cpp next >
Encoding:
C/C++ Source or Header  |  2008-08-25  |  17.4 KB  |  941 lines

  1. /***************************************************************************
  2.  * audio.cpp  -  Audio Engine
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../audio/audio.h"
  17. #include "../audio/sound_manager.h"
  18. #include "../core/game_core.h"
  19. #include "../level/level.h"
  20. #include "../overworld/overworld.h"
  21. #include "../user/preferences.h"
  22. #include "../core/i18n.h"
  23.  
  24. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  25.  
  26. void Finished_Sound( int channel )
  27. {
  28.     // find the finished sound and free the data
  29.     for( AudioSoundList::iterator itr = pAudio->sounds.begin(), itr_end = pAudio->sounds.end(); itr != itr_end; ++itr )
  30.     {
  31.         cAudio_Sound *obj = (*itr);
  32.  
  33.         if( obj->m_channel == channel )
  34.         {
  35.             obj->Finished();
  36.         }
  37.     }
  38. }
  39.  
  40. /* *** *** *** *** *** *** *** *** Audio Sound *** *** *** *** *** *** *** *** *** */
  41.  
  42. cAudio_Sound :: cAudio_Sound( void )
  43. {
  44.     m_data = NULL;
  45.     m_channel = -1;
  46.     m_resource_id = -1;
  47. }
  48.  
  49. cAudio_Sound :: ~cAudio_Sound( void )
  50. {
  51.     Free();
  52. }
  53.  
  54. void cAudio_Sound :: Load( cSound *data )
  55. {
  56.     Free();
  57.     
  58.     m_data = data;
  59. }
  60.  
  61. void cAudio_Sound :: Free( void )
  62. {
  63.     Stop();
  64.  
  65.     if( m_data )
  66.     {
  67.         m_data = NULL;
  68.     }
  69.     
  70.     m_channel = -1;
  71.     m_resource_id = -1;
  72. }
  73.  
  74. void cAudio_Sound :: Finished( void )
  75. {
  76.     m_channel = -1;
  77. }
  78.  
  79. int cAudio_Sound :: Play( int use_res_id /* = -1 */, int loops /* = 0 */ )
  80. {
  81.     if( !m_data || !m_data->m_chunk )
  82.     {
  83.         return 0;
  84.     }
  85.  
  86.     if( use_res_id >= 0 )
  87.     {
  88.         for( AudioSoundList::iterator itr = pAudio->sounds.begin(), itr_end = pAudio->sounds.end(); itr != itr_end; ++itr )
  89.         {
  90.             // get object pointer
  91.             cAudio_Sound *obj = (*itr);
  92.  
  93.             // skip self
  94.             if( !obj || obj->m_channel == m_channel )
  95.             {
  96.                 continue;
  97.             }
  98.  
  99.             // stop Sounds using the given resource id
  100.             if( obj->m_resource_id == use_res_id )
  101.             {
  102.                 obj->Stop();
  103.             }
  104.         }
  105.     }
  106.  
  107.     m_resource_id = use_res_id;
  108.     // play sound
  109.     m_channel = Mix_PlayChannel( -1, m_data->m_chunk, loops );
  110.     // add callback if sound finished playing
  111.     Mix_ChannelFinished( &Finished_Sound );
  112.  
  113.     return m_channel;
  114. }
  115.  
  116. void cAudio_Sound :: Stop( void )
  117. {
  118.     // if not loaded or not playing
  119.     if( !m_data || m_channel < 0 )
  120.     {
  121.         return;
  122.     }
  123.     
  124.     Mix_HaltChannel( m_channel );
  125.     m_channel = -1;
  126. }
  127.  
  128. /* *** *** *** *** *** *** *** *** Audio *** *** *** *** *** *** *** *** *** */
  129.  
  130. cAudio :: cAudio( void )
  131. {
  132.     initialised = 0;
  133.     sound_enabled = 0;
  134.     music_enabled = 0;
  135.  
  136.     debug = 0;
  137.  
  138.     sound_volume = 100;
  139.     music_volume = 80;
  140.  
  141.     music = NULL;
  142.     music_old = NULL;
  143.  
  144.     max_sounds = 0;
  145.     sound_count = 0;
  146.  
  147.     audio_buffer = 4096; // below 2000 can be choppy
  148.     audio_channels = MIX_DEFAULT_CHANNELS; // 1 = Mono, 2 = Stereo
  149.  
  150.     sounds_played = 0;
  151.     music_played = 0;
  152. }
  153.  
  154. cAudio :: ~cAudio( void )
  155. {
  156.     Close();
  157. }
  158.  
  159. bool cAudio :: Init( void )
  160. {
  161.     // Get current device parameters
  162.     int dev_frequency = 0;
  163.     Uint16 dev_format = 0;
  164.     int dev_channels = 0;
  165.     Mix_QuerySpec( &dev_frequency, &dev_format, &dev_channels );
  166.  
  167.     bool sound = pPreferences->audio_sound;
  168.     bool music = pPreferences->audio_music;
  169.  
  170.     // if no change
  171.     if( music_enabled == music && sound_enabled == sound && dev_frequency == pPreferences->audio_hz )
  172.     {
  173.         return 1;
  174.     }
  175.  
  176.     Close();
  177.  
  178.     // if no audio
  179.     if( !music && !sound )
  180.     {
  181.         return 1;
  182.     }
  183.  
  184.     // if audio system is not initialised
  185.     if( !initialised )
  186.     {
  187.         if( debug )
  188.         {
  189.             printf( "Initializing Audio System - Buffer %i, Frequency %i, Speaker Channels %i\n", audio_buffer, pPreferences->audio_hz, audio_channels );
  190.         }
  191.  
  192.         /*    Initializing preferred Audio System specs with Mixer Standard format (Stereo)
  193.         *
  194.         *    frequency    : Output sampling frequency in samples per second (Hz).
  195.         *    format        : Output sample format.
  196.         *    channels    : Number of sound channels in output. 2 for stereo and 1 for mono.
  197.         *    chunk size    : Bytes used per output sample.
  198.         */
  199.  
  200.         if( Mix_OpenAudio( pPreferences->audio_hz, MIX_DEFAULT_FORMAT, audio_channels, audio_buffer ) < 0 ) 
  201.         {
  202.             printf( "Warning : Could not init 16-bit Audio\n- Reason : %s\n", SDL_GetError() );
  203.             return 0;
  204.         }
  205.  
  206.         initialised = 1;
  207.     }
  208.  
  209.  
  210.     if( debug )
  211.     {
  212.         printf( "Audio Sound Channels available : %d\n", Mix_AllocateChannels( -1 ) );
  213.     }
  214.  
  215.     // music initialization
  216.     if( music && !music_enabled )
  217.     {
  218.         music_enabled = 1;
  219.  
  220.         // set music volume
  221.         Set_Music_Volume( music_volume );
  222.     }
  223.     // music de-initialization
  224.     else if( !music && music_enabled )
  225.     {
  226.         Halt_Music();
  227.  
  228.         music_enabled = 0;
  229.     }
  230.  
  231.     // sound initialization
  232.     if( sound && !sound_enabled )
  233.     {
  234.         sound_enabled = 1;
  235.  
  236.         // create sound array
  237.         Set_Max_Sounds();
  238.         // set sound volume
  239.         Set_Sound_Volume( sound_volume );
  240.     }
  241.     // sound de-initialization
  242.     else if( !sound && sound_enabled )
  243.     {
  244.         Stop_Sounds();
  245.  
  246.         sound_enabled = 0;
  247.     }
  248.  
  249.     return 1;
  250. }
  251.  
  252. void cAudio :: Close( void )
  253. {
  254.     if( initialised )
  255.     {
  256.         if( debug )
  257.         {
  258.             printf( "Closing Audio System\n" );
  259.         }
  260.  
  261.         if( sound_enabled )
  262.         {
  263.             Stop_Sounds();
  264.  
  265.             // clear sounds
  266.             for( AudioSoundList::iterator itr = sounds.begin(), itr_end = sounds.end(); itr != itr_end; ++itr )
  267.             {
  268.                 delete *itr;
  269.             }
  270.  
  271.             sounds.clear();
  272.  
  273.             Mix_AllocateChannels( 0 );
  274.             max_sounds = 0;
  275.             sound_enabled = 0;
  276.         }
  277.  
  278.         if( music_enabled )
  279.         {
  280.             Halt_Music();
  281.  
  282.             if( music )
  283.             {
  284.                 Mix_FreeMusic( music );
  285.                 music = NULL;
  286.             }
  287.  
  288.             if( music_old )
  289.             {
  290.                 Mix_FreeMusic( music_old );
  291.                 music_old = NULL;
  292.             }
  293.  
  294.             music_enabled = 0;
  295.         }
  296.  
  297.         Mix_CloseAudio();
  298.  
  299.         initialised = 0;
  300.     }
  301. }
  302.  
  303. void cAudio :: Set_Max_Sounds( unsigned int limit /* = 10 */ )
  304. {
  305.     if( !initialised || !sound_enabled )
  306.     {
  307.         return;
  308.     }
  309.  
  310.     // if limit is too small set it to the minimum
  311.     if( limit < 5 )
  312.     {
  313.         limit = 5;
  314.     }
  315.  
  316.     max_sounds = limit;
  317.  
  318.     // remove exceeding sounds
  319.     while( sounds.size() > max_sounds )
  320.     {
  321.         delete *sounds.end();
  322.         sounds.erase( sounds.end() );
  323.     }
  324.  
  325.     // change channels managed by the mixer
  326.     Mix_AllocateChannels( max_sounds );
  327.  
  328.     if( debug )
  329.     {
  330.         printf( "Audio Sound Channels changed : %d\n", Mix_AllocateChannels( -1 ) );
  331.     }
  332. }
  333.  
  334. cSound *cAudio :: Get_Sound_File( string filename )
  335. {
  336.     if( !initialised || !sound_enabled )
  337.     {
  338.         return NULL;
  339.     }
  340.  
  341.     // not available
  342.     if( !File_Exists( filename ) )
  343.     {
  344.         // add sound directory
  345.         if( filename.find( DATA_DIR "/" GAME_SOUNDS_DIR "/" ) == string::npos )
  346.         {
  347.             filename.insert( 0, DATA_DIR "/" GAME_SOUNDS_DIR "/" );
  348.         }
  349.     }
  350.  
  351.     cSound *sound = pSound_Manager->Get_Pointer( filename );
  352.  
  353.     // if not already cached
  354.     if( !sound )
  355.     {
  356.         sound = new cSound();
  357.  
  358.         // loaded sound
  359.         if( sound->Load( filename ) )
  360.         {
  361.             pSound_Manager->Add( sound );
  362.  
  363.             if( debug )
  364.             {
  365.                 printf( "Loaded sound file : %s\n", filename.c_str() );
  366.             }
  367.         }
  368.         // failed loading
  369.         else
  370.         {
  371.             printf( "Could not load sound file : %s \nReason : %s\n", filename.c_str(), SDL_GetError() );
  372.             
  373.             delete sound;
  374.             return NULL;
  375.         }
  376.     }
  377.  
  378.     return sound;
  379. }
  380.  
  381. bool cAudio :: Play_Sound( string filename, int res_id /* = -1 */, int volume /* = -1 */, int loops /* = 0 */ )
  382. {
  383.     if( !initialised || !sound_enabled )
  384.     {
  385.         return 0;
  386.     }
  387.  
  388.     // not available
  389.     if( !File_Exists( filename ) )
  390.     {
  391.         // add sound directory
  392.         if( filename.find( DATA_DIR "/" GAME_SOUNDS_DIR "/" ) == string::npos )
  393.         {
  394.             filename.insert( 0, DATA_DIR "/" GAME_SOUNDS_DIR "/" );
  395.         }
  396.  
  397.         // not found
  398.         if( !File_Exists( filename ) )
  399.         {
  400.             printf( "Could not find sound file : %s\n", filename.c_str() );
  401.             return 0;
  402.         }
  403.     }
  404.  
  405.     cSound *sound_data = Get_Sound_File( filename );
  406.  
  407.     // failed loading
  408.     if( !sound_data )
  409.     {
  410.         printf( "Warning : Could not load sound file : %s\n", filename.c_str() );
  411.         return 0;
  412.     }
  413.  
  414.     // create channel
  415.     cAudio_Sound *sound = Create_Sound_Channel();
  416.  
  417.     if( !sound )
  418.     {
  419.         // no free channel available
  420.         return 0;
  421.     }
  422.  
  423.     // load data
  424.     sound->Load( sound_data );
  425.     // play
  426.     sound->Play( res_id, loops );
  427.  
  428.     // failed to play
  429.     if( sound->m_channel < 0 )
  430.     {
  431.         if( debug )
  432.         {
  433.             printf( "Could not play sound file : %s\n", filename.c_str() );
  434.         }
  435.  
  436.         return 0;
  437.     }
  438.     // playing successfully
  439.     else
  440.     {
  441.         sounds_played++;
  442.  
  443.         // volume is out of range
  444.         if( volume > MIX_MAX_VOLUME )
  445.         {
  446.             printf( "PlaySound Volume is out of range : %d\n", volume );
  447.             volume = sound_volume;
  448.         }
  449.         // no volume is given
  450.         else if( volume < 0 )
  451.         {
  452.             volume = sound_volume;
  453.         }
  454.  
  455.         // set volume
  456.         Mix_Volume( sound->m_channel, volume );
  457.     }
  458.  
  459.     return 1;
  460. }
  461.  
  462. bool cAudio :: Play_Music( string filename, int loops /* = 0 */, bool force /* = 1 */, unsigned int fadein_ms /* = 0 */ )
  463. {
  464.     if( !music_enabled || !initialised )
  465.     {
  466.         return 0;
  467.     }
  468.  
  469.     if( filename.find( DATA_DIR "/" GAME_MUSIC_DIR "/" ) == string::npos )
  470.     {
  471.         filename.insert( 0, DATA_DIR "/" GAME_MUSIC_DIR "/" );
  472.     }
  473.  
  474.     // no valid file
  475.     if( !File_Exists( filename ) )
  476.     {
  477.         printf( "Couldn't find music file : %s\n", filename.c_str() );
  478.         return 0;
  479.     }
  480.  
  481.     // if music is stopped resume it
  482.     Resume_Music();
  483.  
  484.     // if no music is playing or force to play the given music
  485.     if( !Is_Music_Playing() || force ) 
  486.     {
  487.         // stop and free current music
  488.         if( music )
  489.         {
  490.             Halt_Music();
  491.             Mix_FreeMusic( music );
  492.         }
  493.         // free old music
  494.         if( music_old )
  495.         {
  496.             Mix_FreeMusic( music_old );
  497.             music_old = NULL;
  498.         }
  499.  
  500.         // load the given music
  501.         music = Mix_LoadMUS( filename.c_str() );
  502.  
  503.         // loaded
  504.         if( music )
  505.         {
  506.             // count success
  507.             music_played++;
  508.  
  509.             // no fade in
  510.             if( !fadein_ms )
  511.             {
  512.                 Mix_PlayMusic( music, loops );
  513.             }
  514.             // fade in
  515.             else
  516.             {
  517.                 Mix_FadeInMusic( music, loops, fadein_ms );
  518.             }
  519.         }
  520.         // not loaded
  521.         else 
  522.         {
  523.             if( debug )
  524.             {
  525.                 printf( "Couldn't load music file : %s\n", filename.c_str() );
  526.             }
  527.  
  528.             // failed to play
  529.             return 0;
  530.         }
  531.     }
  532.     // music is playing and is not forced
  533.     else
  534.     {
  535.         // if music is loaded
  536.         if( music )
  537.         {
  538.             // if old music is loaded free the wanted next playing music data
  539.             if( music_old )
  540.             {
  541.                 Mix_FreeMusic( music );
  542.                 music = NULL;
  543.             }
  544.             // if no old music move current to old music
  545.             else
  546.             {
  547.                 music_old = music;
  548.                 music = NULL;
  549.             }
  550.         }
  551.  
  552.         // load the wanted next playing music
  553.         music = Mix_LoadMUS( filename.c_str() );
  554.     }
  555.     
  556.     return 1;
  557. }
  558.  
  559. cAudio_Sound *cAudio :: Get_Playing_Sound( string filename )
  560. {
  561.     if( !sound_enabled || !initialised )
  562.     {
  563.         return NULL;
  564.     }
  565.  
  566.     // add sound directory
  567.     if( filename.find( DATA_DIR "/" GAME_SOUNDS_DIR "/" ) == string::npos )
  568.     {
  569.         filename.insert( 0, DATA_DIR "/" GAME_SOUNDS_DIR "/" );
  570.     }
  571.  
  572.     // get all sounds
  573.     for( AudioSoundList::iterator itr = sounds.begin(), itr_end = sounds.end(); itr != itr_end; ++itr )
  574.     {
  575.         // get object pointer
  576.         cAudio_Sound *obj = (*itr);
  577.  
  578.         // if not playing
  579.         if( obj->m_channel < 0 )
  580.         {
  581.             continue;
  582.         }
  583.  
  584.         // found it
  585.         if( obj->m_data->m_filename.compare( filename ) == 0 )
  586.         {
  587.             // return first found
  588.             return obj;
  589.         }
  590.     }
  591.  
  592.     // not found
  593.     return NULL;
  594. }
  595.  
  596. cAudio_Sound *cAudio :: Create_Sound_Channel( void )
  597. {
  598.     // get all sounds
  599.     for( AudioSoundList::iterator itr = sounds.begin(), itr_end = sounds.end(); itr != itr_end; ++itr )
  600.     {
  601.         // get object pointer
  602.         cAudio_Sound *obj = (*itr);
  603.  
  604.         // if not playing
  605.         if( obj->m_channel < 0 )
  606.         {
  607.             // found a free channel
  608.             obj->Free();
  609.             return obj;
  610.         }
  611.     }
  612.  
  613.     // if not maximum sounds
  614.     if( sounds.size() < max_sounds )
  615.     {
  616.         cAudio_Sound *sound = new cAudio_Sound();
  617.         sounds.push_back( sound );
  618.         return sound;
  619.     }
  620.  
  621.     // none found
  622.     return NULL;
  623. }
  624.  
  625. void cAudio :: Toggle_Music( void )
  626. {
  627.     pPreferences->audio_music = !pPreferences->audio_music;
  628.     Init();
  629.  
  630.     // play music
  631.     if( music_enabled )
  632.     {
  633.         // valid level music available
  634.         if( pActive_Level->valid_music )
  635.         {
  636.             Play_Music( pActive_Level->musicfile, -1, 1, 2000 );
  637.         }
  638.         // in overworld
  639.         else if( Game_Mode == MODE_OVERWORLD )
  640.         {
  641.             Play_Music( pActive_Overworld->musicfile, -1, 1, 2000 );
  642.         }
  643.         // in menu
  644.         else
  645.         {
  646.             Play_Music( "game/menu.ogg", -1, 1, 2000 );
  647.         }
  648.  
  649.         // Warning if no music pack is installed and music got enabled
  650.         if( !File_Exists( DATA_DIR "/" GAME_MUSIC_DIR "/game/menu.ogg" ) && !File_Exists( DATA_DIR "/" GAME_MUSIC_DIR "/land/land_1.ogg" ) )
  651.         {
  652.             Draw_Static_Text( _("Warning : No music addon detected"), &orange );
  653.         }
  654.     }
  655. }
  656.  
  657. void cAudio :: Toggle_Sounds( void )
  658. {
  659.     pPreferences->audio_sound = !pPreferences->audio_sound;
  660.     Init();
  661.  
  662.     // play a test sound
  663.     if( sound_enabled )
  664.     {
  665.         Play_Sound( "audio_on.ogg" );
  666.     }
  667. }
  668.  
  669. void cAudio :: Pause_Music( void )
  670. {
  671.     if( !music_enabled || !initialised )
  672.     {
  673.         return;
  674.     }
  675.  
  676.     // Check if music is currently playing
  677.     if( Mix_PlayingMusic() )
  678.     {
  679.         Mix_PauseMusic();
  680.     }
  681. }
  682.  
  683. void cAudio :: Resume_Sound( int channel /* = -1 */ )
  684. {
  685.     if( !sound_enabled || !initialised )
  686.     {
  687.         return;
  688.     }
  689.  
  690.     // resume playback on all previously active channels
  691.     Mix_Resume( channel );
  692. }
  693.  
  694. void cAudio :: Resume_Music( void )
  695. {
  696.     if( !music_enabled || !initialised )
  697.     {
  698.         return;
  699.     }
  700.  
  701.     // Check if music is currently paused
  702.     if( Mix_PausedMusic() )
  703.     {
  704.         Mix_ResumeMusic();
  705.     }
  706. }
  707.  
  708. void cAudio :: Fadeout_Sounds( unsigned int ms /* = 200 */, int channel /* = -1 */, bool overwrite_fading /* = 0 */ )
  709. {
  710.     if( !sound_enabled || !initialised )
  711.     {
  712.         return;
  713.     }
  714.  
  715.     // Check the Channels
  716.     if( Mix_Playing( channel ) )
  717.     {
  718.         // Do not fade out the sound again
  719.         if( !overwrite_fading && Is_Sound_Fading( -1 ) == MIX_FADING_OUT )
  720.         {
  721.             return;
  722.         }
  723.  
  724.         Mix_FadeOutChannel( channel, ms );
  725.     }
  726. }
  727.  
  728. void cAudio :: Fadeout_Sounds( unsigned int ms, string filename, bool overwrite_fading /* = 0 */ )
  729. {
  730.     if( !sound_enabled || !initialised )
  731.     {
  732.         return;
  733.     }
  734.  
  735.     // add sound directory
  736.     if( filename.find( DATA_DIR "/" GAME_SOUNDS_DIR "/" ) == string::npos )
  737.     {
  738.         filename.insert( 0, DATA_DIR "/" GAME_SOUNDS_DIR "/" );
  739.     }
  740.  
  741.     // get all sounds
  742.     for( AudioSoundList::iterator itr = sounds.begin(), itr_end = sounds.end(); itr != itr_end; ++itr )
  743.     {
  744.         // get object pointer
  745.         cAudio_Sound *obj = (*itr);
  746.  
  747.         // filename does not match
  748.         if( obj->m_data->m_filename.compare( filename ) != 0 )
  749.         {
  750.             continue;
  751.         }
  752.  
  753.         // Do not fade out the sound again
  754.         if( !overwrite_fading && Is_Sound_Fading( obj->m_channel ) == MIX_FADING_OUT )
  755.         {
  756.             continue;
  757.         }
  758.  
  759.         Mix_FadeOutChannel( obj->m_channel, ms );
  760.     }
  761. }
  762.  
  763. void cAudio :: Fadeout_Music( unsigned int ms /* = 500 */, bool overwrite_fading /* = 0 */ )
  764. {
  765.     if( !music_enabled || !initialised )
  766.     {
  767.         return;
  768.     }
  769.  
  770.     // if music is currently playing
  771.     if( Mix_PlayingMusic() )
  772.     {
  773.         Mix_Fading status = Is_Music_Fading();
  774.  
  775.         // don't fade the music out again
  776.         if( !overwrite_fading && status == MIX_FADING_OUT )
  777.         {
  778.             return;
  779.         } 
  780.         // Can't stop fade in with SDL_Mixer and fade out is ignored when fading in
  781.         else if( status == MIX_FADING_IN )
  782.         {
  783.             Halt_Music();
  784.         }
  785.  
  786.         Mix_FadeOutMusic( ms );
  787.     }
  788. }
  789.  
  790. void cAudio :: Set_Music_Position( float position )
  791. {
  792.     if( !music_enabled || !initialised || Is_Music_Fading() == MIX_FADING_OUT )
  793.     {
  794.         return;
  795.     }
  796.  
  797.     Mix_SetMusicPosition( position );
  798. }
  799.  
  800. Mix_Fading cAudio :: Is_Music_Fading( void )
  801. {
  802.     if( !music_enabled || !initialised )
  803.     {
  804.         return MIX_NO_FADING;
  805.     }
  806.  
  807.     return Mix_FadingMusic();
  808. }
  809.  
  810. Mix_Fading cAudio :: Is_Sound_Fading( int sound_channel )
  811. {
  812.     if( !sound_enabled || !initialised )
  813.     {
  814.         return MIX_NO_FADING;
  815.     }
  816.  
  817.      return Mix_FadingChannel( sound_channel );
  818. }
  819.  
  820. bool cAudio :: Is_Music_Paused( void )
  821. {
  822.     if( !music_enabled || !initialised )
  823.     {
  824.         return 0;
  825.     }
  826.     
  827.     if( Mix_PausedMusic() )
  828.     {
  829.         return 1;
  830.     }
  831.     
  832.     return 0;
  833. }
  834.  
  835. bool cAudio :: Is_Music_Playing( void )
  836. {
  837.     if( !music_enabled || !initialised )
  838.     {
  839.         return 0;
  840.     }
  841.     
  842.     if( Mix_PlayingMusic() )
  843.     {
  844.         return 1;
  845.     }
  846.     
  847.     return 0;
  848. }
  849.  
  850. void cAudio :: Halt_Sounds( int channel /* = -1 */ )
  851. {
  852.     if( !sound_enabled || !initialised )
  853.     {
  854.         return;
  855.     }
  856.  
  857.     // Check all Channels
  858.     if( Mix_Playing( channel ) )
  859.     {
  860.         Mix_HaltChannel( channel );
  861.     }
  862. }
  863.  
  864. void cAudio :: Halt_Music( void )
  865. {
  866.     if( !initialised )
  867.     {
  868.         return;
  869.     }
  870.  
  871.     // Checks if music is playing
  872.     if( Mix_PlayingMusic() )
  873.     {
  874.         Mix_HaltMusic();
  875.     }
  876. }
  877.  
  878. void cAudio :: Stop_Sounds( void )
  879. {
  880.     if( !initialised )
  881.     {
  882.         return;
  883.     }
  884.  
  885.     // Stop all channels
  886.     if( Mix_Playing( -1 ) )
  887.     {
  888.         Mix_HaltChannel( -1 );
  889.     }
  890. }
  891.  
  892. void cAudio :: Set_Sound_Volume( Uint8 volume, int channel /* = -1 */ )
  893. {
  894.     if( volume > MIX_MAX_VOLUME || !initialised )
  895.     {
  896.         return;
  897.     }
  898.  
  899.     Mix_Volume( channel, volume );
  900. }
  901.  
  902. void cAudio :: Set_Music_Volume( Uint8 volume )
  903. {
  904.     if( volume > MIX_MAX_VOLUME || !initialised )
  905.     {
  906.         return;
  907.     }
  908.  
  909.     Mix_VolumeMusic( volume );
  910. }
  911.  
  912. void cAudio :: Update( void )
  913. {
  914.     if( !initialised )
  915.     {
  916.         return;
  917.     }
  918.  
  919.     // if music is enabled
  920.     if( music_enabled )
  921.     {
  922.         // if no music is playing
  923.         if( !Mix_PlayingMusic() && music ) 
  924.         {
  925.             Mix_PlayMusic( music, 0 );
  926.             music_played++;
  927.  
  928.             // delete old music if available
  929.             if( music_old )
  930.             {
  931.                 Mix_FreeMusic( music_old );
  932.                 music_old = NULL;
  933.             }
  934.         }
  935.     }
  936. }
  937.  
  938. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  939.  
  940. cAudio *pAudio = NULL;
  941.