00001
00002 #include "eChannelSDLMixer.h"
00003
00004
00005 #include "rSDL.h"
00006 #include "rScreen.h"
00007 #include "defs.h"
00008
00009 #include "tString.h"
00010 #include "tLinkedList.h"
00011 #include "tDirectories.h"
00012 #include "tConfiguration.h"
00013 #include "tConsole.h"
00014 #include "tError.h"
00015 #include "eGameObject.h"
00016 #include "eCoord.h"
00017
00018 #include "eSoundMixer.h"
00019
00020
00021 #include <math.h>
00022
00023
00024 #define SOUND_OFF 0
00025 #define SOUND_LOW 1
00026 #define SOUND_MED 2
00027 #define SOUND_HIGH 3
00028
00029
00030 #define PLAYLIST_INTERNAL 0
00031 #define PLAYLIST_CUSTOM 1
00032
00033
00034
00035
00036
00037
00038 eWavData::eWavData() :
00039 m_Volume(64), m_Playable(false)
00040 {
00041 #ifdef HAVE_LIBSDL_MIXER
00042
00043 m_WavData = NULL;
00044 #endif // DEDICATED
00045 }
00046
00047 eWavData::~eWavData() {
00048 #ifdef HAVE_LIBSDL_MIXER
00049 if(m_WavData != NULL) {
00050 Mix_FreeChunk(m_WavData);
00051 }
00052 #endif // DEDICATED
00053 }
00054
00055 eWavData::eWavData(const char* filename) {
00056 #ifdef HAVE_LIBSDL_MIXER
00057
00058 #endif // DEDICATED
00059 }
00060
00061 void eWavData::LoadWavFile(const char* filename) {
00062 #ifdef HAVE_LIBSDL_MIXER
00063 #ifdef MACOSX
00064
00065 return;
00066 #endif
00067
00068 m_WavData = Mix_LoadWAV(filename);
00069
00070 if(!m_WavData) {
00071 tERR_WARN("Couldn't load wav file\n");
00072 } else {
00073
00074 }
00075 #endif // DEDICATED
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 int eChannel::numChannels = 0;
00085
00086 eChannel::eChannel() : m_Delayed(false) {
00087 #ifdef HAVE_LIBSDL_MIXER
00088 m_ChannelID = numChannels;
00089 numChannels++;
00090 m_Volume = 50;
00091 m_isDirty = false;
00092 m_isPlaying = false;
00093 m_continuous = false;
00094 #endif // DEDICATED
00095 }
00096
00097 void eChannel::PlaySound(eWavData& sound) {
00098 #ifdef HAVE_LIBSDL_MIXER
00099 if(m_isPlaying) {
00100 Mix_HaltChannel(m_ChannelID);
00101
00102 }
00103 int theChannel;
00104 Mix_Volume(m_ChannelID, sound.GetVolume());
00105 theChannel = Mix_PlayChannel(m_ChannelID, sound.GetWavData(), 0);
00106
00107 if(theChannel != m_ChannelID) {
00108
00109
00110 } else {
00111 m_isPlaying = true;
00112 m_StartTime = SDL_GetTicks();
00113 }
00114 #endif // DEDICATED
00115 }
00116
00117 void eChannel::Set3d(eCoord home, eCoord soundPos, eCoord homeDirection) {
00118 #ifdef HAVE_LIBSDL_MIXER
00119
00120 eCoord soundPosRelative = (soundPos - home).Turn( homeDirection.Conj() );
00121
00122
00123 REAL distance = soundPosRelative.Norm();
00124
00125
00126 double bearing = atan2( -soundPosRelative.x, -soundPosRelative.y );
00127
00128
00129
00130
00131 int bearingInt = 180 + (int) (bearing * 180.0/M_PI);
00132
00133
00134
00135 const REAL microphoneSize = 3;
00136 int distanceInt = 255 - int( 255 * microphoneSize / ( sqrt(distance) + microphoneSize ) );
00137
00138 distanceInt = distanceInt > 255 ? 255 : distanceInt;
00139 distanceInt = distanceInt < 1 ? 1 : distanceInt;
00140
00141
00142 if ( distance < EPS * microphoneSize )
00143 bearingInt = 0;
00144
00145
00146 Mix_SetPosition(m_ChannelID, 0, 0);
00147
00148 Mix_SetPosition(m_ChannelID, bearingInt, distanceInt );
00149 #endif // DEDICATED
00150 }
00151
00152 void eChannel::Update() {
00153 #ifdef HAVE_LIBSDL_MIXER
00154 if(m_isDirty && !m_isPlaying) {
00155 Mix_UnregisterAllEffects(m_ChannelID);
00156 m_isDirty = false;
00157 }
00158
00159 if(m_continuous) {
00160 if(m_Delayed) {
00161 if(m_StartNow) {
00162 m_StartNow = false;
00163 m_Delayed = false;
00164 LoopSound(m_Sound);
00165 Set3d(m_Home->Position(), m_Owner->Position(), m_Home->Direction());
00166 std::cout << "Starting delayed effect\n";
00167 }
00168 } else {
00169 if(!m_Home || !m_Owner) {
00170 StopSound();
00171 return;
00172 }
00173 Set3d(m_Home->Position(), m_Owner->Position(), m_Home->Direction());
00174 }
00175 }
00176 #endif // DEDICATED
00177 }
00178
00179 void eChannel::UnplaySound() {
00180 #ifdef HAVE_LIBSDL_MIXER
00181 m_isDirty = true;
00182 m_isPlaying = false;
00183 #endif // DEDICATED
00184 }
00185
00186 void eChannel::SetOwner(eGameObject* owner) {
00187 #ifdef HAVE_LIBSDL_MIXER
00188 m_Owner = owner;
00189 #endif
00190 }
00191
00192 void eChannel::LoopSound(eWavData& sound) {
00193 #ifdef HAVE_LIBSDL_MIXER
00194
00195 if(m_isPlaying) {
00196 Mix_HaltChannel(m_ChannelID);
00197
00198 }
00199 m_continuous = true;
00200 m_Sound = sound;
00201
00202 if(m_Delayed) {
00203 return;
00204 }
00205 int theChannel;
00206 Mix_Volume(m_ChannelID, sound.GetVolume());
00207 theChannel = Mix_PlayChannel(m_ChannelID, m_Sound.GetWavData(), -1);
00208
00209
00210 if(theChannel < 0) {
00211
00212
00213 } else {
00214 m_isPlaying = true;
00215 }
00216 #endif
00217 }
00218