00001 #include "sound.h"
00002 #include "tll.h"
00003 #include "camera.h"
00004 #include "resource.rh"
00005 #include "mmgr.h"
00006
00007 extern int device;
00008 extern BOOL lowqual;
00009 extern int SphereSector;
00010 extern VECTOR SpherePosition;
00011 extern int numSamples;
00012 extern int numChannels;
00013 extern LinkedList<SOUND_SAMPLE> SampleList;
00014 extern LinkedList<SOUND_CHANNEL> ChannelList;
00015 extern HWND hWnd;
00016 extern CAMERA* camera;
00017 extern CAMERA LastCam;
00018 extern int currentCamera;
00019
00020 int SOUND_SAMPLE::Compare(const SOUND_SAMPLE& Sample)
00021 {
00022 if (linkPosition < Sample.linkPosition)
00023 return smaller;
00024 if (linkPosition > Sample.linkPosition)
00025 return bigger;
00026 else
00027 return same;
00028 }
00029
00030 int SOUND_CHANNEL::Compare(const SOUND_CHANNEL& Channel)
00031 {
00032 if (linkPosition < Channel.linkPosition)
00033 return smaller;
00034 if (linkPosition > Channel.linkPosition)
00035 return bigger;
00036 else
00037 return same;
00038 }
00039
00040 void InitializeBASS()
00041 {
00042
00043 if (BASS_GetVersion() != MAKELONG(1, 4))
00044 MessageBox(0, "BASS version 1.4 was not loaded", "Incorrect BASS.DLL", 0);
00045
00046
00047 if (!BASS_Init(device, lowqual?22050:44100, BASS_DEVICE_3D, hWnd))
00048 MessageBox(0, "Could not initialize output device", "Error", 0);
00049
00050
00051 BASS_Set3DFactors(1.0, 1.0, 1.0);
00052
00053
00054 BASS_SetEAXParameters(-1, 0.0, -1.0, -1.0);
00055
00056 BASS_Start();
00057 }
00058
00059
00060 void LoadSample(SOUND_SAMPLE* Sample)
00061 {
00062
00063 Sample->hSample = BASS_SampleLoad(FALSE, Sample->name, 0, 0, Sample->max, Sample->flags);
00064 if (Sample->hSample)
00065 {
00066 BASS_SAMPLE sampleInfo;
00067 BASS_SampleGetInfo(Sample->hSample, &sampleInfo);
00068
00069 sampleInfo.volume = Sample->volume;
00070 sampleInfo.mindist = Sample->mindist;
00071 sampleInfo.maxdist = Sample->maxdist;
00072 BASS_SampleSetInfo(Sample->hSample, &sampleInfo);
00073
00074 Sample->linkPosition = ++numSamples;
00075 SampleList.Insert(Sample);
00076 }
00077 else
00078 MessageBox(NULL,"Could not load sound sample","Error",MB_OK|MB_ICONERROR);
00079 }
00080
00081 void CreateChannel(int SampleNumber)
00082 {
00083 SOUND_SAMPLE* Sample = SampleList.Get(SampleNumber);
00084 SOUND_CHANNEL* Channel = new SOUND_CHANNEL;
00085 Channel->hSample = Sample->hSample;
00086 Channel->linkPosition = ++numChannels;
00087 ChannelList.Insert(Channel);
00088 }
00089
00090 void UpdateListener()
00091 {
00092 BASS_3DVECTOR Player;
00093 BASS_3DVECTOR Bass_Front;
00094 BASS_3DVECTOR Bass_Top;
00095 BASS_3DVECTOR Bass_Velocity;
00096
00097 Player.x = camera[currentCamera].Position.x;
00098 Player.y = camera[currentCamera].Position.y;
00099 Player.z = camera[currentCamera].Position.z;
00100 VECTOR Front = camera[currentCamera].GetZUnit();
00101 VECTOR Top = camera[currentCamera].GetYUnit();
00102 Bass_Front.x = -Front.x;
00103 Bass_Front.y = -Front.y;
00104 Bass_Front.z = -Front.z;
00105 Bass_Top.x = Top.x;
00106 Bass_Top.y = Top.y;
00107 Bass_Top.z = Top.z;
00108 Bass_Velocity.x = camera[currentCamera].Position.x - LastCam.Position.x;
00109 Bass_Velocity.y = camera[currentCamera].Position.y - LastCam.Position.y;
00110 Bass_Velocity.z = camera[currentCamera].Position.z - LastCam.Position.z;
00111
00112 BASS_Set3DPosition(&Player, &Bass_Velocity, &Bass_Front, &Bass_Top);
00113
00114
00115 BASS_Apply3D();
00116 }
00117
00118 void UpdateChannel(int ChannelNumber, VECTOR* Position, VECTOR* Orientation, VECTOR* Velocity)
00119 {
00120 SOUND_CHANNEL* Channel = ChannelList.Get(ChannelNumber);
00121
00122 if (Position)
00123 {
00124 Channel->position.x = Position->x;
00125 Channel->position.y = Position->y;
00126 Channel->position.z = Position->z;
00127 }
00128 if (Orientation)
00129 {
00130 Channel->orientation.x = Orientation->x;
00131 Channel->orientation.y = Orientation->y;
00132 Channel->orientation.z = Orientation->z;
00133 }
00134 if (Velocity)
00135 {
00136 Channel->velocity.x = Velocity->x;
00137 Channel->velocity.y = Velocity->y;
00138 Channel->velocity.z = Velocity->z;
00139 }
00140
00141
00142 if (BASS_ChannelIsActive(Channel->hChannel))
00143 BASS_ChannelSet3DPosition(Channel->hChannel, &Channel->position, NULL, &Channel->velocity);
00144
00145
00146 BASS_Apply3D();
00147 }
00148
00149 void PlayChannel(int ChannelNumber)
00150 {
00151 SOUND_CHANNEL* Channel = ChannelList.Get(ChannelNumber);
00152 Channel->hChannel = BASS_SamplePlay3D(Channel->hSample, &Channel->position, NULL, &Channel->velocity);
00153
00154 char temp[256];
00155 int result = BASS_ErrorGetCode();
00156 if (result)
00157 {
00158 sprintf(temp, "BASS error code No. %d", result);
00159 MessageBox(NULL, temp, "Error", MB_OK|MB_ICONERROR);
00160 }
00161 }
00162
00163 VOID CALLBACK SoundTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
00164 {
00165 SOUND_CHANNEL* Channel = ChannelList.Get((int)idEvent);
00166 PlayChannel((int)idEvent);
00167 if ((Channel->looped && !Channel->intermittent) || !Channel->looped)
00168 KillTimer(hWnd, idEvent);
00169 if (Channel->looped && Channel->intermittent && Channel->random)
00170 {
00171 int randomtime = (rand()%(Channel->upperrand - Channel->lowerrand)) + Channel->lowerrand;
00172 SetTimer(hWnd, idEvent, randomtime, (TIMERPROC)SoundTimerProc);
00173 }
00174 }
00175
00176 void CreateSounds()
00177 {
00178 SOUND_SAMPLE* Sample;
00179 SOUND_CHANNEL* Channel;
00180 VECTOR Position;
00181
00182
00183 Sample = new SOUND_SAMPLE;
00184 sprintf(Sample->name, "%s", "engine.wav");
00185 Sample->max = 10;
00186 Sample->volume = 100;
00187 Sample->mindist = 10.0;
00188 Sample->maxdist = 1000.0;
00189 Sample->flags = BASS_SAMPLE_OVER_DIST | BASS_SAMPLE_LOOP | BASS_SAMPLE_3D | BASS_SAMPLE_VAM;
00190 LoadSample(Sample);
00191
00192 CreateChannel(sample_engine);
00193 Channel = ChannelList.Get(channel_engine);
00194 Channel->looped = true;
00195 Channel->intermittent = false;
00196 Channel->random = false;
00197 Channel->interval = 2000;
00198 Channel->idEvent = (unsigned int)channel_engine;
00199 SetTimer(hWnd, Channel->idEvent, Channel->interval, (TIMERPROC)SoundTimerProc);
00200
00201
00202 Sample = new SOUND_SAMPLE;
00203 sprintf(Sample->name, "%s", "waterdrop.wav");
00204 Sample->max = 10;
00205 Sample->volume = 20;
00206 Sample->mindist = 12.0;
00207 Sample->maxdist = 100.0;
00208 Sample->flags = BASS_SAMPLE_OVER_DIST | BASS_SAMPLE_MUTEMAX | BASS_SAMPLE_3D | BASS_SAMPLE_VAM;
00209 LoadSample(Sample);
00210
00211
00212 CreateChannel(sample_drip);
00213 Channel = ChannelList.Get(channel_drip1);
00214 Channel->looped = true;
00215 Channel->intermittent = true;
00216 Channel->random = false;
00217 Channel->interval = 1000;
00218 Channel->idEvent = (unsigned int)channel_drip1;
00219 SetTimer(hWnd, Channel->idEvent, Channel->interval, (TIMERPROC)SoundTimerProc);
00220 Position.x = 150.0;
00221 Position.y = -10.0;
00222 Position.z = -30.0;
00223 UpdateChannel(channel_drip1, &Position, NULL, NULL);
00224
00225
00226 CreateChannel(sample_drip);
00227 Channel = ChannelList.Get(channel_drip2);
00228 Channel->looped = true;
00229 Channel->intermittent = true;
00230 Channel->random = true;
00231 Channel->lowerrand = 800;
00232 Channel->upperrand = 8000;
00233 Channel->interval = 1000;
00234 Channel->idEvent = (unsigned int)channel_drip2;
00235 SetTimer(hWnd, Channel->idEvent, Channel->interval, (TIMERPROC)SoundTimerProc);
00236 Position.x = 150.0;
00237 Position.y = -10.0;
00238 Position.z = -30.0;
00239 UpdateChannel(channel_drip2, &Position, NULL, NULL);
00240
00241
00242 Sample = new SOUND_SAMPLE;
00243 sprintf(Sample->name, "%s", "bird.wav");
00244 Sample->max = 10;
00245 Sample->volume = 50;
00246 Sample->mindist = 10.0;
00247 Sample->maxdist = 100.0;
00248 Sample->flags = BASS_SAMPLE_OVER_DIST | BASS_SAMPLE_MUTEMAX | BASS_SAMPLE_3D | BASS_SAMPLE_VAM;
00249 LoadSample(Sample);
00250
00251 CreateChannel(sample_bird);
00252 Channel = ChannelList.Get(channel_bird);
00253 Channel->looped = true;
00254 Channel->intermittent = true;
00255 Channel->random = true;
00256 Channel->lowerrand = 2000;
00257 Channel->upperrand = 25000;
00258 Channel->interval = 5000;
00259 Channel->idEvent = (unsigned int)channel_bird;
00260 SetTimer(hWnd, Channel->idEvent, Channel->interval, (TIMERPROC)SoundTimerProc);
00261 Position.x = 110.0;
00262 Position.y = 0.0;
00263 Position.z = 120.0;
00264 UpdateChannel(channel_bird, &Position, NULL, NULL);
00265
00266
00267 Sample = new SOUND_SAMPLE;
00268 sprintf(Sample->name, "%s", "carhorn.wav");
00269 Sample->max = 10;
00270 Sample->volume = 100;
00271 Sample->mindist = 10.0;
00272 Sample->maxdist = 1000.0;
00273 Sample->flags = BASS_SAMPLE_OVER_DIST | BASS_SAMPLE_3D | BASS_SAMPLE_VAM;
00274 LoadSample(Sample);
00275
00276 CreateChannel(sample_carhorn);
00277 }
00278
00279
00280
00281 BOOL CALLBACK devicedialogproc(HWND h,UINT m,WPARAM w,LPARAM l)
00282 {
00283 switch (m) {
00284 case WM_COMMAND:
00285 switch (LOWORD(w)) {
00286 case ID_DEVLIST:
00287 if (HIWORD(w)==LBN_SELCHANGE)
00288 device=SendMessage((HWND)l,LB_GETCURSEL,0,0);
00289 else if (HIWORD(w)==LBN_DBLCLK)
00290 EndDialog(h,0);
00291 break;
00292 case ID_LOWQUAL:
00293 lowqual=SendDlgItemMessage(h,ID_LOWQUAL,BM_GETCHECK,0,0);
00294 break;
00295 case IDOK:
00296 EndDialog(h,0);
00297 return 1;
00298 }
00299 break;
00300
00301 case WM_INITDIALOG:
00302 {
00303 char text[100],*d;
00304 int c;
00305 for (c=0;BASS_GetDeviceDescription(c,&d);c++) {
00306 strcpy(text,d);
00307
00308 if (!BASS_Init(c,44100,BASS_DEVICE_3D|BASS_DEVICE_NOSYNC|BASS_DEVICE_NOTHREAD,h))
00309 continue;
00310 if (BASS_GetEAXParameters(NULL,NULL,NULL,NULL))
00311 strcat(text," [EAX]");
00312 BASS_Free();
00313 SendDlgItemMessage(h,ID_DEVLIST,LB_ADDSTRING,0,(LONG)text);
00314 }
00315 SendDlgItemMessage(h,ID_DEVLIST,LB_SETCURSEL,0,0);
00316 }
00317 device=lowqual=0;
00318 return 1;
00319 }
00320 return 0;
00321 }
00322