00001 00002 // Copyright (C) 2004-2007 by The Allacrost Project 00003 // All Rights Reserved 00004 // 00005 // This code is licensed under the GNU GPL version 2. It is free software 00006 // and you may modify it and/or redistribute it under the terms of this license. 00007 // See http://www.gnu.org/copyleft/gpl.html for details. 00009 00016 #include "audio_music.h" 00017 00018 using namespace std; 00019 using namespace hoa_utils; 00020 00021 namespace hoa_audio { 00022 00023 namespace private_audio { 00024 00025 // **************************************************************************** 00026 // ************************ MusicData Class Functions ************************* 00027 // **************************************************************************** 00028 00029 MusicData::MusicData(const std::string & fname) : 00030 filename(fname), 00031 playing(false) 00032 { 00033 music = Mix_LoadMUS(filename.c_str()); 00034 if (music == NULL) { 00035 cout << "AUDIO ERROR: Could not open music file " << filename << ": " << Mix_GetError() << endl; 00036 reference_count = 0; 00037 } 00038 else { 00039 reference_count = 1; 00040 } 00041 } 00042 00043 00044 MusicData::~MusicData() { 00045 if (reference_count > 0) { 00046 if (AUDIO_DEBUG) cerr << "AUDIO WARNING: freeing music data with a non-zero reference count" << endl; 00047 } 00048 00049 Mix_FreeMusic(music); 00050 music = NULL; 00051 } 00052 00053 00054 bool MusicData::IsValid() { 00055 if (music != NULL && reference_count > 0) { 00056 return true; 00057 } 00058 return false; 00059 } 00060 00061 00062 // Remove a reference to this buffer object and delete it if there are no more references. 00063 void MusicData::RemoveReference() { 00064 reference_count--; 00065 if (reference_count == 0) { 00066 // TODO: delete the class object and remove it from the music_data map, but be careful 00067 // delete this; 00068 } 00069 } 00070 00071 00072 void MusicData::DEBUG_PrintProperties() { 00073 if (IsValid() == false) { 00074 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00075 cerr << "ERROR: the data for the file " << filename << " is not valid" << endl; 00076 } 00077 else { 00078 cout << "--------------------------------------------------------------------------------" << endl; 00079 cout << "Filename: " << filename << endl; 00080 // These properties are not easily available with SDL_mixer 00081 // cout << "Frequency: " << property << " Hz" << endl; 00082 // cout << "Bit depth: " << property << endl; 00083 // cout << "Channels: " << property << endl; 00084 // cout << "Size: " << _chunk->alen << " bytes" << endl; 00085 cout << "--------------------------------------------------------------------------------" << endl; 00086 } 00087 } 00088 00089 00090 } // namespace private_audio 00091 00092 using namespace hoa_audio::private_audio; 00093 00094 // **************************************************************************** 00095 // ********************* MusicDescriptor Class Functions ********************** 00096 // **************************************************************************** 00097 00098 00099 MusicDescriptor::MusicDescriptor() : 00100 _data(NULL), 00101 _loop_count(-1), 00102 _fade_in_time(0), 00103 _fade_out_time(0), 00104 _play_timeout(-1) 00105 { 00106 } 00107 00108 00109 MusicDescriptor::~MusicDescriptor() { 00110 if (_data != NULL) { 00111 _data->RemoveReference(); 00112 _data = NULL; 00113 } 00114 } 00115 00116 00117 bool MusicDescriptor::LoadMusic(const std::string & fname) { 00118 // If the music descriptor is already using other audio data, remove a reference to that data 00119 if (_data != NULL) { 00120 _data->RemoveReference(); 00121 _data = NULL; 00122 } 00123 00124 _data = AudioManager->_AcquireMusicData(fname); 00125 if (_data == NULL) { 00126 return false; 00127 } 00128 else { 00129 return true; 00130 } 00131 } 00132 00133 void MusicDescriptor::FreeMusic() { 00134 if (_data != NULL) { 00135 _data->RemoveReference(); 00136 _data = NULL; 00137 } 00138 } 00139 00140 00141 void MusicDescriptor::PlayMusic() { 00142 if (_data == NULL) { 00143 return; 00144 } 00145 00146 if (GetMusicState() != AUDIO_STATE_STOPPED) { 00147 AudioManager->StopAllMusic(); 00148 } 00149 00150 if (Mix_FadeInMusic(_data->music, _loop_count, _fade_in_time) == -1) { 00151 cerr << "AUDIO ERROR: Could not play music" << endl; 00152 } 00153 00154 _data->playing = true; 00155 } 00156 00157 00158 void MusicDescriptor::PauseMusic() { 00159 if (_data == NULL) { 00160 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00161 return; 00162 } 00163 00164 Mix_PauseMusic(); 00165 00166 _data->playing = false; 00167 } 00168 00169 00170 void MusicDescriptor::ResumeMusic() { 00171 if (_data == NULL) { 00172 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00173 return; 00174 } 00175 00176 Mix_ResumeMusic(); 00177 00178 _data->playing = true; 00179 } 00180 00181 00182 void MusicDescriptor::StopMusic() { 00183 if (_data == NULL) { 00184 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00185 return; 00186 } 00187 00188 Mix_FadeOutMusic(_fade_out_time); 00189 00190 _data->playing = false; 00191 } 00192 00193 00194 void MusicDescriptor::RewindMusic() { 00195 if (_data == NULL) { 00196 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00197 return; 00198 } 00199 00200 Mix_RewindMusic(); 00201 } 00202 00203 00204 void MusicDescriptor::SeekMusic(float seconds) { 00205 if (_data == NULL) { 00206 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00207 return; 00208 } 00209 00210 Mix_SetMusicPosition(seconds); 00211 } 00212 00213 00214 uint8 MusicDescriptor::GetMusicState() { 00215 if (_data == NULL) { 00216 return AUDIO_STATE_UNLOADED; 00217 } 00218 00219 switch(Mix_FadingMusic()) { 00220 case MIX_FADING_IN: 00221 return AUDIO_STATE_FADING_IN; 00222 case MIX_FADING_OUT: 00223 return AUDIO_STATE_FADING_OUT; 00224 default: // MIX_NO_FADING 00225 break; 00226 } 00227 00228 if (Mix_PlayingMusic() != 0) { 00229 return AUDIO_STATE_PLAYING; 00230 } 00231 00232 if (Mix_PausedMusic() != 0) { 00233 return AUDIO_STATE_PAUSED; 00234 } 00235 00236 return AUDIO_STATE_STOPPED; 00237 } 00238 00239 00240 bool MusicDescriptor::IsPlaying() 00241 { 00242 if (_data != NULL) { 00243 return _data->playing; 00244 } 00245 else { 00246 return false; 00247 } 00248 } 00249 00250 00251 } // namespace hoa_audio
1.5.1