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 00010 /*!**************************************************************************** 00011 * \file audio_sound.cpp 00012 * \author Tyler Olsen, roots@allacrost.org 00013 * \brief Sound file for sound-related code in the audio engine. 00014 *****************************************************************************/ 00015 00016 #include "audio_sound.h" 00017 00018 using namespace std; 00019 using namespace hoa_utils; 00020 00021 namespace hoa_audio { 00022 00023 namespace private_audio { 00024 00025 // **************************************************************************** 00026 // ************************ SoundData Class Functions ************************* 00027 // **************************************************************************** 00028 00029 // Creates a new buffer for the filename and loads the WAV data. 00030 00031 SoundData::SoundData(string fname) { 00032 filename = fname; 00033 00034 sound = Mix_LoadWAV(filename.c_str()); 00035 if (sound == NULL) { 00036 cout << "AUDIO ERROR: Could not open sound file " << filename << ": " << Mix_GetError() << endl; 00037 reference_count = 0; 00038 } 00039 else { 00040 reference_count = 1; 00041 } 00042 } 00043 00044 SoundData::~SoundData() { 00045 if (reference_count > 0) { 00046 cerr << "AUDIO WARNING: Audio engine is attempting to delete buffer " << filename << 00047 ", which still has " << static_cast<int32>(reference_count) << " refereces to it\n"; 00048 } 00049 00050 Mix_FreeChunk(sound); 00051 sound = NULL; 00052 } 00053 00054 00055 void SoundData::RemoveReference() { 00056 reference_count--; 00057 if (reference_count == 0) { 00058 // TODO: delete the class object and remove it from the sound_data map, but be careful 00059 // delete this; 00060 } 00061 } 00062 00063 00064 bool SoundData::IsValid() { 00065 if (sound != NULL && reference_count > 0) { 00066 return true; 00067 } 00068 return false; 00069 } 00070 00071 00072 void SoundData::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: " << sound->alen << " bytes" << endl; 00085 cout << "--------------------------------------------------------------------------------" << endl; 00086 } 00087 } 00088 00089 } // namespace private_audio 00090 00091 using namespace hoa_audio::private_audio; 00092 00093 // **************************************************************************** 00094 // ***** SoundDescriptor Class Functions 00095 // **************************************************************************** 00096 00097 // The constructor does not attempt to retrieve any resources. 00098 SoundDescriptor::SoundDescriptor() { 00099 _data = NULL; 00100 _loop_count = 0; 00101 _fade_in_time = 0; 00102 _fade_out_time = 0; 00103 _play_timeout = -1; 00104 } 00105 00106 00107 // The destructor will call the AudioManager singleton to manage the buffer and source that the class was using. 00108 SoundDescriptor::~SoundDescriptor() { 00109 if (_data != NULL) { 00110 _data->RemoveReference(); 00111 _data = NULL; 00112 } 00113 } 00114 00115 00116 // This constructor will load the sound from memory, if it isn't loaded already. 00117 bool SoundDescriptor::LoadSound(string fname) { 00118 if (fname == "") { 00119 cerr << "AUDIO WARNING: Bad filename passed in LoadSound (empty string)." << endl; 00120 return false; 00121 } 00122 00123 _data = AudioManager->_AcquireSoundData(fname); 00124 if (_data == NULL) { 00125 cerr << "AUDIO ERROR: Failed to get a buffer for sound file " << fname << endl; 00126 return false; 00127 } 00128 return true; 00129 } 00130 00131 00132 void SoundDescriptor::FreeSound() { 00133 if (_data != NULL) { 00134 _data->RemoveReference(); 00135 _data = NULL; 00136 } 00137 } 00138 00139 00140 // Retrieve the state of the audio 00141 uint8 SoundDescriptor::GetSoundState() { 00142 if (_data == NULL) { 00143 return AUDIO_STATE_UNLOADED; 00144 } 00145 00146 // This is needed because there is currently no guarantee if the _channel is still playing the chunk... 00147 if (Mix_GetChunk(_channel) != _data->sound) { 00148 return AUDIO_STATE_STOPPED; 00149 } 00150 00151 switch(Mix_FadingChannel(_channel)) { 00152 case MIX_FADING_IN: 00153 return AUDIO_STATE_FADING_IN; 00154 case MIX_FADING_OUT: 00155 return AUDIO_STATE_FADING_OUT; 00156 default: // MIX_NO_FADING 00157 break; 00158 } 00159 00160 if (Mix_Playing(_channel) != 0) { 00161 return AUDIO_STATE_PLAYING; 00162 } 00163 00164 if (Mix_Paused(_channel) != 0) { 00165 return AUDIO_STATE_PAUSED; 00166 } 00167 00168 return AUDIO_STATE_STOPPED; 00169 } 00170 00171 00172 void SoundDescriptor::PlaySound() { 00173 if (_data == NULL) { 00174 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00175 return; 00176 } 00177 00178 if (_fade_in_time != 0) { 00179 _channel = Mix_FadeInChannelTimed(ANY_CHANNEL, _data->sound, _loop_count, _fade_in_time, _play_timeout); 00180 } 00181 else { 00182 _channel = Mix_PlayChannelTimed(ANY_CHANNEL, _data->sound, _loop_count, _play_timeout); 00183 } 00184 00185 if (_channel == -1) { 00186 AudioManager->_audio_errors |= AUDIO_ERROR_PLAY_FAILURE; 00187 } 00188 } 00189 00190 00191 void SoundDescriptor::PauseSound() { 00192 if (_data == NULL) { 00193 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00194 return; 00195 } 00196 00197 Mix_Pause(_channel); 00198 } 00199 00200 00201 void SoundDescriptor::ResumeSound() { 00202 if (_data == NULL) { 00203 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00204 return; 00205 } 00206 00207 Mix_Resume(_channel); 00208 } 00209 00210 00211 void SoundDescriptor::StopSound() { 00212 if (_data == NULL) { 00213 AudioManager->_audio_errors |= AUDIO_ERROR_NO_DATA; 00214 return; 00215 } 00216 00217 if (_fade_out_time != 0) { 00218 Mix_FadeOutChannel(_channel, _fade_out_time); 00219 } 00220 else { 00221 Mix_HaltChannel(_channel); 00222 } 00223 } 00224 00225 00226 // void SoundDescriptor::RewindSound() {} 00227 00228 // void SoundDescriptor::FreeSound() {} 00229 00230 00231 } // namespace hoa_audio
1.5.1