1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 
6 #if EMSCRIPTEN
7 #include <AL/al.h>
8 #include <AL/alc.h>
9 #else
10 #include "al.h"
11 #include "alc.h"
12 #endif
13 
14 #include "fixer.h"
15 
16 #include "3dc.h"
17 #include "platform.h"
18 #include "inline.h"
19 #include "psndplat.h"
20 #include "gamedef.h"
21 #include "avpview.h"
22 #include "ffstdio.h"
23 #include "dynamics.h"
24 #include "dynblock.h"
25 #include "stratdef.h"
26 
27 #if defined( _MSC_VERx )
28 #include <AL/eax.h>
29 #endif
30 
31 #if 0
32 #define OPENAL_DEBUG
33 #endif
34 
35 ACTIVESOUNDSAMPLE ActiveSounds[SOUND_MAXACTIVE];
36 ACTIVESOUNDSAMPLE BlankActiveSound = {SID_NOSOUND,ASP_Minimum,0,0,NULL,0,0,0,0,0, { {0,0,0},{0,0,0},0,0 }, 0, 0, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, NULL, NULL, NULL};
37 SOUNDSAMPLEDATA BlankGameSound = {0,0,0,0,0,NULL,0,0,NULL,0};
38 SOUNDSAMPLEDATA GameSounds[SID_MAXIMUM];
39 
40 static ALCdevice *AvpSoundDevice;
41 static ALvoid *AvpSoundContext;
42 static int AvpFrequency = 44100;
43 
44 extern int WantSound;
45 
46 static int SoundActivated = 0;
47 
48 static struct {
49 	unsigned int flags;
50 	BOOL reverb_changed;
51 	float reverb_mix;
52 	unsigned int env_index;
53 } SoundConfig;
54 
55 #if defined(_MSC_VERx)
56 // EAX1.0
57 #define EAX_REVERBMIX_USEDISTANCE -1.0F
58 
59 // EAX1.0
60 #define EAX_ENVIRONMENT_DEFAULT EAX_ENVIRONMENT_PLAIN
61 
62 EAXSet EAX_pfPropSet;
63 EAXGet EAX_pfPropGet;
64 #endif
65 
66 /* start simplistic riff wave parsing */
67 #define lsb8 (buf, x)  (((unsigned int)buf[(x)+0] <<  0))
68 #define lsb16(buf, x)  (((unsigned int)buf[(x)+0] <<  0) | ((unsigned int)buf[(x)+1] <<  8))
69 #define lsb32(buf, x)  (((unsigned int)buf[(x)+0] <<  0) | ((unsigned int)buf[(x)+1] <<  8) | ((unsigned int)buf[(x)+2] << 16) | ((unsigned int)buf[(x)+3] << 24))
70 
71 typedef struct FormatChunk {
72   short          wFormatTag;
73   unsigned short wChannels;
74   unsigned long  dwSamplesPerSec;
75   unsigned long  dwAvgBytesPerSec;
76   unsigned short wBlockAlign;
77   unsigned short wBitsPerSample;
78 } FormatChunk;
79 
80 typedef struct DataChunk {
81   unsigned char* pData;
82   unsigned int   dwLength;
83 } DataChunk;
84 
ParseWAV(const unsigned char * data,unsigned char ** pFmtPtr,unsigned char ** pDataPtr)85 static int ParseWAV( const unsigned char* data, unsigned char** pFmtPtr, unsigned char** pDataPtr )
86 {
87   unsigned char* pData;
88   unsigned char* pDataEnd;
89   unsigned char* fmtPtr;
90   int riffLength;
91   int chunkLength;
92 
93   if( data == NULL || pFmtPtr == NULL || pDataPtr == NULL ) {
94     return 0;
95   }
96 
97   /* assuming input data is complete and not corrupt... */
98 
99   pData = (unsigned char*) data;
100 
101   /* bytes 0-3 are the RIFF groupId */
102   if( pData[ 0 ] != 'R' || pData[ 1 ] != 'I' || pData[ 2 ] != 'F' || pData[ 3 ] != 'F' ) {
103     /* bad group id */
104     return 0;
105   }
106 
107   /* bytes 4-7 are the RIFF length. */
108   riffLength = lsb32( pData, 4 );
109 
110   pDataEnd = pData + 8 + riffLength;
111 
112   if( pData[ 8 ] != 'W' || pData[ 9 ] != 'A' || pData[ 10 ] != 'V' || pData[ 11 ] != 'E' ) {
113     /* bad riff type */
114     return 0;
115   }
116 
117   /* all valid wave files have the 'fmt ' chunk before the 'data' chunk. */
118 
119   /* skip passed the initial header. */
120   pData += 12;
121 
122   /* look for the 'fmt ' and 'data' chunks. */
123   fmtPtr = NULL;
124 
125   while( pData+8 < pDataEnd ) {
126 
127     chunkLength = lsb32( pData, 4 );
128 
129     if( fmtPtr == NULL && pData[ 0 ] == 'f' && pData[ 1 ] == 'm' && pData[ 2 ] == 't' && pData[ 3 ] == ' ' ) {
130       fmtPtr = pData;
131     } else if( fmtPtr != NULL && pData[ 0 ] == 'd' && pData[ 1 ] == 'a' && pData[ 2 ] == 't' && pData[ 3 ] == 'a' ) {
132 
133       *pFmtPtr  = fmtPtr;
134       *pDataPtr = pData;
135 
136       return 1;
137     }
138 
139     pData += 8 + chunkLength;
140   }
141 
142   return 0;
143 }
144 
SimpleLoadWAV(const unsigned char * data,FormatChunk * pFmtChunk,DataChunk * pDataChunk)145 static int SimpleLoadWAV( const unsigned char* data, FormatChunk* pFmtChunk, DataChunk* pDataChunk)
146 {
147   unsigned char* fmtPtr;
148   unsigned char* dataPtr;
149 
150   if( data == NULL || pFmtChunk == NULL || pDataChunk == NULL ) {
151   	return 0;
152   }
153 
154   if( !ParseWAV( data, &fmtPtr, &dataPtr ) ) {
155   	return 0;
156   }
157 
158   pFmtChunk->wFormatTag       = lsb16( fmtPtr, 8  );
159   pFmtChunk->wChannels        = lsb16( fmtPtr, 10 );
160   pFmtChunk->dwSamplesPerSec  = lsb32( fmtPtr, 12 );
161   pFmtChunk->dwAvgBytesPerSec = lsb32( fmtPtr, 16 );
162   pFmtChunk->wBlockAlign      = lsb16( fmtPtr, 20 );
163   pFmtChunk->wBitsPerSample   = lsb16( fmtPtr, 22 );
164 
165   pDataChunk->pData    = &dataPtr[ 8 ];
166   pDataChunk->dwLength = lsb32( dataPtr, 4 );
167 
168   return 1;
169 }
170 /* end simplistic riff wave parsing */
171 
172 /*
173 openal.c TODO:
174 1. There is no EAX/Reverb.  But there's probably not much I can do...
175 2. Restarting sound system may or may not work.
176 3. Better Error Handling (device not avail, etc).
177 4. Implement sample offsets in psnd.c using AL_SAMPLE_OFFSET (add api here)
178 */
PlatStartSoundSys()179 int PlatStartSoundSys()
180 {
181 	int initSources;
182 	int i;
183 	ALfloat pos[] = { 0.0, 0.0, 0.0 };
184 	ALfloat vel[] = { 0.0, 0.0, 0.0 };
185 	ALfloat or[]  = { 0.0, 0.0, 1.0, 0.0, -1.0, 0.0 };
186 
187 	int attrlist[6];
188 
189 	/* Set the globals. */
190 	SoundConfig.flags = 0;
191 	SoundConfig.reverb_changed = TRUE;
192 	SoundConfig.reverb_mix = 0.0f;
193 	SoundConfig.env_index = 1000;
194 
195 	SoundActivated = 0;
196 	if (WantSound == 0) {
197 		return 0;
198 	}
199 
200 	attrlist[0] = ALC_FREQUENCY;
201 	attrlist[1] = AvpFrequency;
202 	attrlist[2] = ALC_SYNC;
203 	attrlist[3] = AL_FALSE;
204 	attrlist[4] = 0;
205 
206 	AvpSoundDevice = alcOpenDevice(NULL);
207 	if (AvpSoundDevice == NULL) {
208 		return 0;
209 	}
210 
211 	AvpSoundContext = alcCreateContext(AvpSoundDevice, attrlist);
212 	if (AvpSoundContext == NULL) {
213 		/* TODO: destroy sound device */
214 		return 0;
215 	}
216 
217 	alcMakeContextCurrent(AvpSoundContext);
218 
219 	alListenerf(AL_GAIN, 1.0);
220 	alListenerfv(AL_POSITION, pos);
221 	alListenerfv(AL_VELOCITY, vel);
222 	alListenerfv(AL_ORIENTATION, or);
223 
224 	alDistanceModel(AL_NONE);
225 
226 	if (alGetError() != AL_NO_ERROR) {
227 		// TODO: this shouldn't exit abruptly..
228 		// TODO: better error handling throughout
229 		fprintf(stderr, "alListenerfv() error = ...\n");
230 		exit(1);
231 	}
232 
233 #if defined(_MSC_VERx)
234 	EAX_pfPropSet = NULL;
235 	EAX_pfPropGet = NULL;
236 
237 	if( alIsExtensionPresent( (ALubyte*) "EAX" ) == AL_TRUE ) {
238 		EAX_pfPropSet = alGetProcAddress( (ALubyte*) "EAXSet" );
239 		EAX_pfPropGet = alGetProcAddress( (ALubyte*) "EAXGet" );
240 	}
241 
242 	// Set a default environment value.
243 	PlatSetEnviroment(EAX_ENVIRONMENT_DEFAULT, EAX_REVERBMIX_USEDISTANCE);
244 #endif
245 
246 	initSources = 1;
247 
248 	for (i = 0; i < SOUND_MAXACTIVE; i++) {
249 		ALuint p;
250 
251 		if( initSources ) {
252 			alGenSources (1, &p);
253 			if (alGetError () != AL_NO_ERROR) {
254 				// TODO - need to figure out how many sources we are allowed to make
255 				//fprintf (stderr, "alGenSources () error = ...");
256 				//return -1;
257 				initSources = 0;
258 				p = 0;
259 			}
260 		} else {
261 			p = 0;
262 		}
263 
264 		// TODO: remove the incorrectly named PropSetP variables
265 
266 		ActiveSounds[i].ds3DBufferP = p;
267 
268 		ActiveSounds[i].PropSetP_pos[0] = 0.0;
269 		ActiveSounds[i].PropSetP_pos[1] = 0.0;
270 		ActiveSounds[i].PropSetP_pos[2] = 0.0;
271 		ActiveSounds[i].PropSetP_vel[0] = 0.0;
272 		ActiveSounds[i].PropSetP_vel[1] = 0.0;
273 		ActiveSounds[i].PropSetP_vel[2] = 0.0;
274 
275 		if( initSources ) {
276 			alSourcef(p, AL_PITCH, 1.0f);
277 			alSourcef(p, AL_GAIN, 1.0f);
278 			alSourcefv(p, AL_POSITION, ActiveSounds[i].PropSetP_pos);
279 			alSourcefv(p, AL_VELOCITY, ActiveSounds[i].PropSetP_vel);
280 
281 			alSourcef(p, AL_ROLLOFF_FACTOR, 0.01f);
282 			alSourcef(p, AL_REFERENCE_DISTANCE, 1.0f);
283 		}
284 	}
285 
286 	SoundActivated = 1;
287 
288 	return 1;
289 }
290 
PlatEndSoundSys()291 void PlatEndSoundSys()
292 {
293 /* TODO - free everything */
294 	fprintf(stderr, "OPENAL: PlatEndSoundSys()\n");
295 }
296 
297 // this table plots the frequency change for
298 // 128/ths of a semitone for one octave (0-1535),
299 // divide or multiply by 2 to subtract or add an octave
300 static const float pitch_to_frequency_mult_table [] =
301 {
302 	1.0F,		1.00045137F,	1.000902943F,	1.00135472F,	1.001806701F,	1.002258886F,	1.002711275F,	1.003163868F,
303 	1.003616666F,	1.004069668F,	1.004522874F,	1.004976285F,	1.005429901F,	1.005883722F,	1.006337747F,	1.006791977F,
304 	1.007246412F,	1.007701053F,	1.008155898F,	1.008610949F,	1.009066205F,	1.009521667F,	1.009977334F,	1.010433207F,
305 	1.010889286F,	1.011345571F,	1.011802061F,	1.012258758F,	1.012715661F,	1.01317277F,	1.013630085F,	1.014087607F,
306 	1.014545335F,	1.01500327F,	1.015461411F,	1.01591976F,	1.016378315F,	1.016837077F,	1.017296046F,	1.017755223F,
307 	1.018214607F,	1.018674198F,	1.019133996F,	1.019594002F,	1.020054216F,	1.020514637F,	1.020975266F,	1.021436104F,
308 	1.021897149F,	1.022358402F,	1.022819863F,	1.023281533F,	1.023743411F,	1.024205498F,	1.024667793F,	1.025130297F,
309 	1.025593009F,	1.026055931F,	1.026519061F,	1.026982401F,	1.027445949F,	1.027909707F,	1.028373674F,	1.028837851F,
310 	1.029302237F,	1.029766832F,	1.030231638F,	1.030696653F,	1.031161878F,	1.031627313F,	1.032092958F,	1.032558813F,
311 	1.033024879F,	1.033491155F,	1.033957641F,	1.034424338F,	1.034891246F,	1.035358364F,	1.035825694F,	1.036293234F,
312 	1.036760985F,	1.037228947F,	1.037697121F,	1.038165506F,	1.038634102F,	1.03910291F,	1.039571929F,	1.04004116F,
313 	1.040510603F,	1.040980258F,	1.041450125F,	1.041920204F,	1.042390495F,	1.042860998F,	1.043331714F,	1.043802642F,
314 	1.044273782F,	1.044745136F,	1.045216702F,	1.045688481F,	1.046160473F,	1.046632678F,	1.047105096F,	1.047577727F,
315 	1.048050572F,	1.04852363F,	1.048996902F,	1.049470387F,	1.049944086F,	1.050417999F,	1.050892125F,	1.051366466F,
316 	1.051841021F,	1.05231579F,	1.052790773F,	1.053265971F,	1.053741383F,	1.05421701F,	1.054692851F,	1.055168907F,
317 	1.055645178F,	1.056121664F,	1.056598366F,	1.057075282F,	1.057552413F,	1.05802976F,	1.058507323F,	1.058985101F,
318 	1.059463094F,	1.059941304F,	1.060419729F,	1.06089837F,	1.061377227F,	1.061856301F,	1.06233559F,	1.062815096F,
319 	1.063294818F,	1.063774757F,	1.064254913F,	1.064735285F,	1.065215874F,	1.06569668F,	1.066177703F,	1.066658943F,
320 	1.067140401F,	1.067622075F,	1.068103967F,	1.068586077F,	1.069068404F,	1.069550949F,	1.070033712F,	1.070516692F,
321 	1.070999891F,	1.071483308F,	1.071966943F,	1.072450796F,	1.072934868F,	1.073419158F,	1.073903666F,	1.074388394F,
322 	1.07487334F,	1.075358505F,	1.075843889F,	1.076329492F,	1.076815315F,	1.077301356F,	1.077787617F,	1.078274098F,
323 	1.078760798F,	1.079247718F,	1.079734857F,	1.080222216F,	1.080709796F,	1.081197595F,	1.081685615F,	1.082173855F,
324 	1.082662315F,	1.083150996F,	1.083639897F,	1.084129019F,	1.084618362F,	1.085107926F,	1.085597711F,	1.086087716F,
325 	1.086577943F,	1.087068391F,	1.087559061F,	1.088049952F,	1.088541065F,	1.089032399F,	1.089523955F,	1.090015733F,
326 	1.090507733F,	1.090999955F,	1.091492399F,	1.091985065F,	1.092477954F,	1.092971065F,	1.093464399F,	1.093957956F,
327 	1.094451735F,	1.094945737F,	1.095439962F,	1.09593441F,	1.096429082F,	1.096923976F,	1.097419095F,	1.097914436F,
328 	1.098410001F,	1.09890579F,	1.099401803F,	1.099898039F,	1.1003945F,	1.100891184F,	1.101388093F,	1.101885226F,
329 	1.102382583F,	1.102880165F,	1.103377972F,	1.103876003F,	1.104374259F,	1.10487274F,	1.105371446F,	1.105870377F,
330 	1.106369533F,	1.106868914F,	1.107368521F,	1.107868354F,	1.108368412F,	1.108868695F,	1.109369205F,	1.10986994F,
331 	1.110370902F,	1.11087209F,	1.111373503F,	1.111875143F,	1.11237701F,	1.112879103F,	1.113381423F,	1.113883969F,
332 	1.114386743F,	1.114889743F,	1.11539297F,	1.115896424F,	1.116400106F,	1.116904015F,	1.117408152F,	1.117912516F,
333 	1.118417107F,	1.118921927F,	1.119426974F,	1.119932249F,	1.120437752F,	1.120943484F,	1.121449444F,	1.121955632F,
334 	1.122462048F,	1.122968693F,	1.123475567F,	1.12398267F,	1.124490002F,	1.124997562F,	1.125505352F,	1.12601337F,
335 	1.126521619F,	1.127030096F,	1.127538803F,	1.12804774F,	1.128556906F,	1.129066302F,	1.129575929F,	1.130085785F,
336 	1.130595871F,	1.131106188F,	1.131616734F,	1.132127512F,	1.13263852F,	1.133149758F,	1.133661227F,	1.134172928F,
337 	1.134684859F,	1.135197021F,	1.135709414F,	1.136222039F,	1.136734895F,	1.137247982F,	1.137761301F,	1.138274852F,
338 	1.138788635F,	1.139302649F,	1.139816896F,	1.140331374F,	1.140846085F,	1.141361028F,	1.141876204F,	1.142391612F,
339 	1.142907253F,	1.143423126F,	1.143939233F,	1.144455572F,	1.144972144F,	1.14548895F,	1.146005989F,	1.146523261F,
340 	1.147040767F,	1.147558506F,	1.148076479F,	1.148594686F,	1.149113126F,	1.149631801F,	1.15015071F,	1.150669853F,
341 	1.15118923F,	1.151708842F,	1.152228688F,	1.152748769F,	1.153269085F,	1.153789635F,	1.154310421F,	1.154831441F,
342 	1.155352697F,	1.155874188F,	1.156395914F,	1.156917876F,	1.157440074F,	1.157962507F,	1.158485176F,	1.159008081F,
343 	1.159531222F,	1.160054599F,	1.160578212F,	1.161102062F,	1.161626148F,	1.16215047F,	1.16267503F,	1.163199826F,
344 	1.163724859F,	1.164250129F,	1.164775636F,	1.16530138F,	1.165827362F,	1.16635358F,	1.166880037F,	1.167406731F,
345 	1.167933663F,	1.168460833F,	1.16898824F,	1.169515886F,	1.17004377F,	1.170571892F,	1.171100252F,	1.171628851F,
346 	1.172157689F,	1.172686765F,	1.17321608F,	1.173745634F,	1.174275427F,	1.174805459F,	1.175335731F,	1.175866241F,
347 	1.176396992F,	1.176927981F,	1.177459211F,	1.17799068F,	1.178522389F,	1.179054338F,	1.179586527F,	1.180118957F,
348 	1.180651627F,	1.181184537F,	1.181717688F,	1.182251079F,	1.182784711F,	1.183318584F,	1.183852698F,	1.184387053F,
349 	1.184921649F,	1.185456487F,	1.185991566F,	1.186526886F,	1.187062448F,	1.187598252F,	1.188134298F,	1.188670585F,
350 	1.189207115F,	1.189743887F,	1.190280901F,	1.190818158F,	1.191355657F,	1.191893398F,	1.192431383F,	1.19296961F,
351 	1.19350808F,	1.194046793F,	1.194585749F,	1.195124949F,	1.195664392F,	1.196204079F,	1.196744009F,	1.197284182F,
352 	1.1978246F,	1.198365262F,	1.198906167F,	1.199447317F,	1.199988711F,	1.200530349F,	1.201072232F,	1.201614359F,
353 	1.202156731F,	1.202699348F,	1.20324221F,	1.203785317F,	1.204328669F,	1.204872266F,	1.205416109F,	1.205960197F,
354 	1.206504531F,	1.20704911F,	1.207593935F,	1.208139006F,	1.208684324F,	1.209229887F,	1.209775696F,	1.210321752F,
355 	1.210868055F,	1.211414604F,	1.211961399F,	1.212508442F,	1.213055731F,	1.213603267F,	1.214151051F,	1.214699082F,
356 	1.21524736F,	1.215795886F,	1.216344659F,	1.21689368F,	1.217442948F,	1.217992465F,	1.21854223F,	1.219092243F,
357 	1.219642504F,	1.220193013F,	1.220743771F,	1.221294778F,	1.221846033F,	1.222397537F,	1.22294929F,	1.223501292F,
358 	1.224053543F,	1.224606044F,	1.225158794F,	1.225711793F,	1.226265042F,	1.226818541F,	1.227372289F,	1.227926288F,
359 	1.228480536F,	1.229035035F,	1.229589784F,	1.230144783F,	1.230700033F,	1.231255533F,	1.231811285F,	1.232367287F,
360 	1.23292354F,	1.233480044F,	1.234036799F,	1.234593806F,	1.235151064F,	1.235708573F,	1.236266335F,	1.236824348F,
361 	1.237382612F,	1.237941129F,	1.238499898F,	1.239058919F,	1.239618193F,	1.240177719F,	1.240737497F,	1.241297528F,
362 	1.241857812F,	1.242418349F,	1.242979139F,	1.243540182F,	1.244101478F,	1.244663027F,	1.24522483F,	1.245786887F,
363 	1.246349197F,	1.246911761F,	1.247474579F,	1.248037651F,	1.248600977F,	1.249164558F,	1.249728392F,	1.250292482F,
364 	1.250856826F,	1.251421424F,	1.251986278F,	1.252551386F,	1.25311675F,	1.253682369F,	1.254248243F,	1.254814372F,
365 	1.255380757F,	1.255947398F,	1.256514294F,	1.257081446F,	1.257648855F,	1.258216519F,	1.25878444F,	1.259352616F,
366 	1.25992105F,	1.26048974F,	1.261058687F,	1.26162789F,	1.26219735F,	1.262767068F,	1.263337042F,	1.263907274F,
367 	1.264477763F,	1.26504851F,	1.265619515F,	1.266190777F,	1.266762297F,	1.267334075F,	1.26790611F,	1.268478405F,
368 	1.269050957F,	1.269623768F,	1.270196838F,	1.270770166F,	1.271343753F,	1.271917599F,	1.272491703F,	1.273066067F,
369 	1.273640691F,	1.274215573F,	1.274790715F,	1.275366117F,	1.275941778F,	1.2765177F,	1.277093881F,	1.277670322F,
370 	1.278247024F,	1.278823985F,	1.279401208F,	1.27997869F,	1.280556434F,	1.281134438F,	1.281712703F,	1.282291229F,
371 	1.282870016F,	1.283449065F,	1.284028374F,	1.284607946F,	1.285187778F,	1.285767873F,	1.28634823F,	1.286928848F,
372 	1.287509728F,	1.288090871F,	1.288672276F,	1.289253943F,	1.289835873F,	1.290418066F,	1.291000521F,	1.29158324F,
373 	1.292166221F,	1.292749466F,	1.293332973F,	1.293916744F,	1.294500779F,	1.295085077F,	1.295669639F,	1.296254465F,
374 	1.296839555F,	1.297424909F,	1.298010527F,	1.298596409F,	1.299182556F,	1.299768967F,	1.300355643F,	1.300942584F,
375 	1.30152979F,	1.302117261F,	1.302704997F,	1.303292998F,	1.303881265F,	1.304469797F,	1.305058595F,	1.305647659F,
376 	1.306236989F,	1.306826584F,	1.307416446F,	1.308006574F,	1.308596968F,	1.309187629F,	1.309778556F,	1.310369751F,
377 	1.310961212F,	1.311552939F,	1.312144935F,	1.312737197F,	1.313329726F,	1.313922523F,	1.314515588F,	1.31510892F,
378 	1.31570252F,	1.316296388F,	1.316890524F,	1.317484929F,	1.318079601F,	1.318674542F,	1.319269752F,	1.31986523F,
379 	1.320460977F,	1.321056993F,	1.321653278F,	1.322249832F,	1.322846655F,	1.323443748F,	1.32404111F,	1.324638742F,
380 	1.325236643F,	1.325834815F,	1.326433256F,	1.327031968F,	1.327630949F,	1.328230202F,	1.328829724F,	1.329429517F,
381 	1.330029581F,	1.330629916F,	1.331230522F,	1.331831399F,	1.332432547F,	1.333033967F,	1.333635657F,	1.33423762F,
382 	1.334839854F,	1.33544236F,	1.336045138F,	1.336648188F,	1.337251511F,	1.337855105F,	1.338458972F,	1.339063112F,
383 	1.339667524F,	1.340272209F,	1.340877167F,	1.341482398F,	1.342087903F,	1.34269368F,	1.343299731F,	1.343906056F,
384 	1.344512654F,	1.345119526F,	1.345726672F,	1.346334092F,	1.346941786F,	1.347549755F,	1.348157998F,	1.348766515F,
385 	1.349375307F,	1.349984374F,	1.350593716F,	1.351203333F,	1.351813225F,	1.352423392F,	1.353033835F,	1.353644553F,
386 	1.354255547F,	1.354866817F,	1.355478362F,	1.356090184F,	1.356702282F,	1.357314656F,	1.357927306F,	1.358540233F,
387 	1.359153437F,	1.359766917F,	1.360380675F,	1.360994709F,	1.361609021F,	1.362223609F,	1.362838476F,	1.363453619F,
388 	1.364069041F,	1.36468474F,	1.365300717F,	1.365916972F,	1.366533506F,	1.367150317F,	1.367767407F,	1.368384776F,
389 	1.369002423F,	1.369620349F,	1.370238554F,	1.370857038F,	1.371475801F,	1.372094843F,	1.372714165F,	1.373333766F,
390 	1.373953647F,	1.374573808F,	1.375194249F,	1.37581497F,	1.376435971F,	1.377057252F,	1.377678814F,	1.378300656F,
391 	1.378922779F,	1.379545183F,	1.380167867F,	1.380790833F,	1.38141408F,	1.382037608F,	1.382661418F,	1.383285509F,
392 	1.383909882F,	1.384534537F,	1.385159473F,	1.385784692F,	1.386410193F,	1.387035977F,	1.387662042F,	1.388288391F,
393 	1.388915022F,	1.389541936F,	1.390169133F,	1.390796613F,	1.391424376F,	1.392052422F,	1.392680752F,	1.393309366F,
394 	1.393938263F,	1.394567445F,	1.39519691F,	1.395826659F,	1.396456693F,	1.397087011F,	1.397717613F,	1.398348501F,
395 	1.398979673F,	1.399611129F,	1.400242871F,	1.400874898F,	1.40150721F,	1.402139808F,	1.402772691F,	1.40340586F,
396 	1.404039315F,	1.404673055F,	1.405307082F,	1.405941395F,	1.406575994F,	1.407210879F,	1.407846051F,	1.40848151F,
397 	1.409117256F,	1.409753289F,	1.410389608F,	1.411026215F,	1.411663109F,	1.412300291F,	1.41293776F,	1.413575517F,
398 	1.414213562F,	1.414851895F,	1.415490516F,	1.416129426F,	1.416768623F,	1.417408109F,	1.418047884F,	1.418687948F,
399 	1.4193283F,	1.419968942F,	1.420609873F,	1.421251093F,	1.421892602F,	1.422534401F,	1.42317649F,	1.423818868F,
400 	1.424461537F,	1.425104495F,	1.425747744F,	1.426391283F,	1.427035113F,	1.427679233F,	1.428323644F,	1.428968346F,
401 	1.429613338F,	1.430258622F,	1.430904197F,	1.431550064F,	1.432196222F,	1.432842672F,	1.433489413F,	1.434136447F,
402 	1.434783772F,	1.43543139F,	1.4360793F,	1.436727502F,	1.437375997F,	1.438024785F,	1.438673866F,	1.439323239F,
403 	1.439972906F,	1.440622866F,	1.441273119F,	1.441923666F,	1.442574506F,	1.44322564F,	1.443877069F,	1.444528791F,
404 	1.445180807F,	1.445833118F,	1.446485723F,	1.447138622F,	1.447791816F,	1.448445306F,	1.44909909F,	1.449753169F,
405 	1.450407543F,	1.451062213F,	1.451717178F,	1.452372439F,	1.453027996F,	1.453683848F,	1.454339997F,	1.454996442F,
406 	1.455653183F,	1.45631022F,	1.456967554F,	1.457625185F,	1.458283113F,	1.458941337F,	1.459599859F,	1.460258678F,
407 	1.460917794F,	1.461577208F,	1.462236919F,	1.462896929F,	1.463557236F,	1.464217841F,	1.464878744F,	1.465539946F,
408 	1.466201446F,	1.466863245F,	1.467525342F,	1.468187738F,	1.468850433F,	1.469513428F,	1.470176721F,	1.470840314F,
409 	1.471504207F,	1.472168399F,	1.472832891F,	1.473497683F,	1.474162775F,	1.474828167F,	1.475493859F,	1.476159852F,
410 	1.476826146F,	1.47749274F,	1.478159635F,	1.478826832F,	1.479494329F,	1.480162128F,	1.480830228F,	1.481498629F,
411 	1.482167333F,	1.482836338F,	1.483505645F,	1.484175254F,	1.484845166F,	1.48551538F,	1.486185896F,	1.486856715F,
412 	1.487527837F,	1.488199262F,	1.48887099F,	1.489543021F,	1.490215355F,	1.490887993F,	1.491560934F,	1.492234179F,
413 	1.492907728F,	1.493581581F,	1.494255739F,	1.4949302F,	1.495604966F,	1.496280037F,	1.496955412F,	1.497631092F,
414 	1.498307077F,	1.498983367F,	1.499659962F,	1.500336863F,	1.50101407F,	1.501691582F,	1.502369399F,	1.503047523F,
415 	1.503725953F,	1.504404689F,	1.505083732F,	1.505763081F,	1.506442736F,	1.507122698F,	1.507802968F,	1.508483544F,
416 	1.509164428F,	1.509845618F,	1.510527117F,	1.511208923F,	1.511891036F,	1.512573458F,	1.513256187F,	1.513939225F,
417 	1.514622571F,	1.515306226F,	1.515990189F,	1.516674461F,	1.517359041F,	1.518043931F,	1.51872913F,	1.519414638F,
418 	1.520100455F,	1.520786582F,	1.521473019F,	1.522159765F,	1.522846822F,	1.523534189F,	1.524221866F,	1.524909853F,
419 	1.525598151F,	1.526286759F,	1.526975679F,	1.527664909F,	1.52835445F,	1.529044303F,	1.529734467F,	1.530424942F,
420 	1.53111573F,	1.531806829F,	1.53249824F,	1.533189963F,	1.533881998F,	1.534574345F,	1.535267006F,	1.535959978F,
421 	1.536653264F,	1.537346862F,	1.538040774F,	1.538734999F,	1.539429537F,	1.540124388F,	1.540819553F,	1.541515032F,
422 	1.542210825F,	1.542906932F,	1.543603354F,	1.544300089F,	1.544997139F,	1.545694504F,	1.546392183F,	1.547090177F,
423 	1.547788487F,	1.548487111F,	1.549186051F,	1.549885307F,	1.550584878F,	1.551284764F,	1.551984967F,	1.552685486F,
424 	1.553386321F,	1.554087472F,	1.55478894F,	1.555490724F,	1.556192825F,	1.556895243F,	1.557597978F,	1.558301031F,
425 	1.5590044F,	1.559708087F,	1.560412092F,	1.561116415F,	1.561821055F,	1.562526013F,	1.56323129F,	1.563936885F,
426 	1.564642798F,	1.56534903F,	1.566055581F,	1.566762451F,	1.56746964F,	1.568177148F,	1.568884975F,	1.569593122F,
427 	1.570301589F,	1.571010375F,	1.571719481F,	1.572428908F,	1.573138654F,	1.573848721F,	1.574559108F,	1.575269816F,
428 	1.575980845F,	1.576692195F,	1.577403866F,	1.578115858F,	1.578828171F,	1.579540806F,	1.580253763F,	1.580967041F,
429 	1.581680641F,	1.582394564F,	1.583108809F,	1.583823376F,	1.584538265F,	1.585253478F,	1.585969013F,	1.586684871F,
430 	1.587401052F,	1.588117556F,	1.588834384F,	1.589551536F,	1.590269011F,	1.59098681F,	1.591704933F,	1.59242338F,
431 	1.593142151F,	1.593861247F,	1.594580668F,	1.595300413F,	1.596020483F,	1.596740878F,	1.597461598F,	1.598182643F,
432 	1.598904014F,	1.599625711F,	1.600347733F,	1.601070081F,	1.601792756F,	1.602515756F,	1.603239083F,	1.603962736F,
433 	1.604686716F,	1.605411023F,	1.606135656F,	1.606860617F,	1.607585905F,	1.60831152F,	1.609037463F,	1.609763734F,
434 	1.610490332F,	1.611217258F,	1.611944513F,	1.612672095F,	1.613400006F,	1.614128246F,	1.614856814F,	1.615585711F,
435 	1.616314938F,	1.617044493F,	1.617774377F,	1.618504592F,	1.619235135F,	1.619966009F,	1.620697212F,	1.621428745F,
436 	1.622160609F,	1.622892803F,	1.623625327F,	1.624358182F,	1.625091368F,	1.625824885F,	1.626558732F,	1.627292911F,
437 	1.628027422F,	1.628762264F,	1.629497437F,	1.630232943F,	1.63096878F,	1.63170495F,	1.632441452F,	1.633178286F,
438 	1.633915453F,	1.634652953F,	1.635390785F,	1.636128951F,	1.63686745F,	1.637606282F,	1.638345447F,	1.639084947F,
439 	1.63982478F,	1.640564947F,	1.641305448F,	1.642046283F,	1.642787453F,	1.643528957F,	1.644270796F,	1.645012969F,
440 	1.645755478F,	1.646498322F,	1.647241501F,	1.647985016F,	1.648728866F,	1.649473052F,	1.650217574F,	1.650962432F,
441 	1.651707626F,	1.652453156F,	1.653199024F,	1.653945227F,	1.654691768F,	1.655438645F,	1.65618586F,	1.656933412F,
442 	1.657681301F,	1.658429528F,	1.659178092F,	1.659926995F,	1.660676235F,	1.661425814F,	1.662175731F,	1.662925986F,
443 	1.66367658F,	1.664427513F,	1.665178785F,	1.665930396F,	1.666682346F,	1.667434636F,	1.668187265F,	1.668940234F,
444 	1.669693543F,	1.670447192F,	1.671201181F,	1.67195551F,	1.67271018F,	1.67346519F,	1.674220541F,	1.674976233F,
445 	1.675732267F,	1.676488641F,	1.677245357F,	1.678002414F,	1.678759814F,	1.679517555F,	1.680275638F,	1.681034063F,
446 	1.681792831F,	1.682551941F,	1.683311393F,	1.684071189F,	1.684831327F,	1.685591809F,	1.686352633F,	1.687113802F,
447 	1.687875313F,	1.688637169F,	1.689399368F,	1.690161912F,	1.690924799F,	1.691688031F,	1.692451608F,	1.693215529F,
448 	1.693979795F,	1.694744405F,	1.695509361F,	1.696274663F,	1.697040309F,	1.697806302F,	1.69857264F,	1.699339324F,
449 	1.700106354F,	1.70087373F,	1.701641453F,	1.702409522F,	1.703177937F,	1.7039467F,	1.70471581F,	1.705485266F,
450 	1.706255071F,	1.707025222F,	1.707795721F,	1.708566568F,	1.709337763F,	1.710109306F,	1.710881197F,	1.711653437F,
451 	1.712426025F,	1.713198962F,	1.713972248F,	1.714745883F,	1.715519867F,	1.7162942F,	1.717068883F,	1.717843916F,
452 	1.718619298F,	1.719395031F,	1.720171113F,	1.720947546F,	1.721724329F,	1.722501463F,	1.723278948F,	1.724056783F,
453 	1.72483497F,	1.725613508F,	1.726392397F,	1.727171638F,	1.727951231F,	1.728731176F,	1.729511472F,	1.730292121F,
454 	1.731073122F,	1.731854476F,	1.732636182F,	1.733418241F,	1.734200653F,	1.734983419F,	1.735766537F,	1.73655001F,
455 	1.737333835F,	1.738118015F,	1.738902548F,	1.739687436F,	1.740472678F,	1.741258274F,	1.742044225F,	1.742830531F,
456 	1.743617191F,	1.744404207F,	1.745191578F,	1.745979304F,	1.746767386F,	1.747555824F,	1.748344617F,	1.749133767F,
457 	1.749923272F,	1.750713134F,	1.751503353F,	1.752293928F,	1.75308486F,	1.753876149F,	1.754667796F,	1.755459799F,
458 	1.75625216F,	1.757044879F,	1.757837956F,	1.75863139F,	1.759425183F,	1.760219334F,	1.761013843F,	1.761808711F,
459 	1.762603938F,	1.763399524F,	1.764195468F,	1.764991772F,	1.765788436F,	1.766585459F,	1.767382842F,	1.768180585F,
460 	1.768978687F,	1.769777151F,	1.770575974F,	1.771375158F,	1.772174703F,	1.772974609F,	1.773774875F,	1.774575503F,
461 	1.775376493F,	1.776177843F,	1.776979556F,	1.77778163F,	1.778584067F,	1.779386865F,	1.780190027F,	1.78099355F,
462 	1.781797436F,	1.782601685F,	1.783406297F,	1.784211273F,	1.785016611F,	1.785822313F,	1.786628379F,	1.787434809F,
463 	1.788241602F,	1.78904876F,	1.789856282F,	1.790664169F,	1.79147242F,	1.792281036F,	1.793090017F,	1.793899363F,
464 	1.794709075F,	1.795519152F,	1.796329595F,	1.797140403F,	1.797951578F,	1.798763118F,	1.799575025F,	1.800387298F,
465 	1.801199938F,	1.802012945F,	1.802826319F,	1.80364006F,	1.804454168F,	1.805268643F,	1.806083487F,	1.806898698F,
466 	1.807714277F,	1.808530224F,	1.809346539F,	1.810163223F,	1.810980276F,	1.811797697F,	1.812615487F,	1.813433647F,
467 	1.814252176F,	1.815071074F,	1.815890341F,	1.816709979F,	1.817529987F,	1.818350364F,	1.819171112F,	1.819992231F,
468 	1.82081372F,	1.821635579F,	1.82245781F,	1.823280412F,	1.824103385F,	1.82492673F,	1.825750446F,	1.826574535F,
469 	1.827398995F,	1.828223827F,	1.829049031F,	1.829874608F,	1.830700558F,	1.831526881F,	1.832353576F,	1.833180645F,
470 	1.834008086F,	1.834835902F,	1.835664091F,	1.836492654F,	1.83732159F,	1.838150901F,	1.838980587F,	1.839810647F,
471 	1.840641081F,	1.84147189F,	1.842303075F,	1.843134634F,	1.843966569F,	1.844798879F,	1.845631565F,	1.846464627F,
472 	1.847298065F,	1.848131879F,	1.84896607F,	1.849800636F,	1.85063558F,	1.851470901F,	1.852306598F,	1.853142673F,
473 	1.853979125F,	1.854815955F,	1.855653162F,	1.856490747F,	1.857328711F,	1.858167052F,	1.859005772F,	1.859844871F,
474 	1.860684348F,	1.861524205F,	1.86236444F,	1.863205054F,	1.864046048F,	1.864887422F,	1.865729175F,	1.866571309F,
475 	1.867413822F,	1.868256716F,	1.86909999F,	1.869943645F,	1.87078768F,	1.871632097F,	1.872476895F,	1.873322074F,
476 	1.874167634F,	1.875013576F,	1.8758599F,	1.876706606F,	1.877553694F,	1.878401165F,	1.879249018F,	1.880097254F,
477 	1.880945872F,	1.881794874F,	1.882644259F,	1.883494027F,	1.884344179F,	1.885194715F,	1.886045634F,	1.886896938F,
478 	1.887748625F,	1.888600698F,	1.889453154F,	1.890305996F,	1.891159223F,	1.892012834F,	1.892866831F,	1.893721214F,
479 	1.894575982F,	1.895431135F,	1.896286675F,	1.897142601F,	1.897998914F,	1.898855613F,	1.899712698F,	1.900570171F,
480 	1.90142803F,	1.902286277F,	1.903144911F,	1.904003932F,	1.904863342F,	1.905723139F,	1.906583324F,	1.907443898F,
481 	1.90830486F,	1.909166211F,	1.91002795F,	1.910890079F,	1.911752596F,	1.912615503F,	1.913478799F,	1.914342486F,
482 	1.915206561F,	1.916071027F,	1.916935883F,	1.91780113F,	1.918666767F,	1.919532795F,	1.920399213F,	1.921266023F,
483 	1.922133224F,	1.923000816F,	1.9238688F,	1.924737176F,	1.925605944F,	1.926475103F,	1.927344656F,	1.9282146F,
484 	1.929084938F,	1.929955668F,	1.930826791F,	1.931698307F,	1.932570217F,	1.93344252F,	1.934315217F,	1.935188308F,
485 	1.936061793F,	1.936935673F,	1.937809947F,	1.938684615F,	1.939559678F,	1.940435136F,	1.94131099F,	1.942187238F,
486 	1.943063882F,	1.943940922F,	1.944818358F,	1.94569619F,	1.946574418F,	1.947453042F,	1.948332063F,	1.949211481F,
487 	1.950091295F,	1.950971507F,	1.951852116F,	1.952733123F,	1.953614527F,	1.954496329F,	1.955378529F,	1.956261128F,
488 	1.957144124F,	1.958027519F,	1.958911313F,	1.959795506F,	1.960680098F,	1.961565089F,	1.96245048F,	1.963336271F,
489 	1.964222461F,	1.965109051F,	1.965996041F,	1.966883432F,	1.967771223F,	1.968659415F,	1.969548008F,	1.970437002F,
490 	1.971326397F,	1.972216194F,	1.973106392F,	1.973996992F,	1.974887994F,	1.975779399F,	1.976671205F,	1.977563415F,
491 	1.978456026F,	1.979349041F,	1.980242459F,	1.98113628F,	1.982030505F,	1.982925133F,	1.983820165F,	1.984715601F,
492 	1.985611441F,	1.986507685F,	1.987404335F,	1.988301388F,	1.989198847F,	1.990096711F,	1.99099498F,	1.991893654F,
493 	1.992792734F,	1.99369222F,	1.994592112F,	1.99549241F,	1.996393115F,	1.997294226F,	1.998195744F,	1.999097668F,
494 
495 };
496 
ToneToFrequency(int currentFrequency,int currentPitch,int newPitch)497 static int ToneToFrequency(int currentFrequency, int currentPitch, int newPitch)
498 {
499 	int newFrequency = currentFrequency;
500 
501 	if (!((currentPitch>=PITCH_MINPLAT)&&(currentPitch<=PITCH_MAXPLAT)))
502 		return 0;
503 
504 	if (!((currentFrequency>=FREQUENCY_MINPLAT)&&(currentPitch<=FREQUENCY_MAXPLAT)))
505 		return 0;
506 
507 	/* limit pitch */
508 	if(newPitch>PITCH_MAXPLAT) newPitch=PITCH_MAXPLAT;
509 	if(newPitch<PITCH_MINPLAT) newPitch=PITCH_MINPLAT;
510 
511 	if(newPitch>currentPitch)
512 	{
513 		/* scale up */
514 		int numOctaves, numTones;
515   	 	numOctaves = (newPitch-currentPitch)/1536;
516 		numTones = (newPitch-currentPitch)%1536;
517 
518 		newFrequency<<=numOctaves;
519 		if(newFrequency>FREQUENCY_MAXPLAT) newFrequency=FREQUENCY_MAXPLAT;
520 
521 		if(numTones>0) newFrequency = (int)((float)(newFrequency)*pitch_to_frequency_mult_table[numTones]);
522 		if(newFrequency>FREQUENCY_MAXPLAT) newFrequency=FREQUENCY_MAXPLAT;
523 	}
524 	else
525 	{
526 		/* scale down */
527 		int numOctaves, numTones;
528   	 	numOctaves = (currentPitch-newPitch)/1536;
529 		numTones = (currentPitch-newPitch)%1536;
530 
531 		newFrequency>>=numOctaves;
532 	 	if(newFrequency<FREQUENCY_MINPLAT) newFrequency=FREQUENCY_MINPLAT;
533 
534 		if(numTones>0) newFrequency = (int)((float)(newFrequency)/pitch_to_frequency_mult_table[numTones]);
535 		if(newFrequency<FREQUENCY_MINPLAT) newFrequency=FREQUENCY_MINPLAT;
536 	}
537 	return newFrequency;
538 }
539 
PlatPlaySound(int activeIndex)540 int PlatPlaySound(int activeIndex)
541 {
542 	int si;
543 
544 	if (!SoundActivated) {
545 		return 0;
546 	}
547 
548 	if ((activeIndex < 0) || (activeIndex >= SOUND_MAXACTIVE)) {
549 		return 0;
550 	}
551 
552 	si = ActiveSounds[activeIndex].soundIndex;
553 	if ((si < 0) || (si >= SID_MAXIMUM)) {
554 		return 0;
555 	}
556 	if (!GameSounds[si].loaded) {
557 		return 0;
558 	}
559 
560 	alSourceStop(ActiveSounds[activeIndex].ds3DBufferP);
561 
562 	alSourcei(ActiveSounds[activeIndex].ds3DBufferP, AL_BUFFER,
563 		   GameSounds[si].dsBufferP);
564 
565 	alSourcei(ActiveSounds[activeIndex].ds3DBufferP, AL_LOOPING,
566 		ActiveSounds[activeIndex].loop ? AL_TRUE : AL_FALSE);
567 
568 	/* may need to initialise pitch before playing */
569 	if (1 || ActiveSounds[activeIndex].pitch != GameSounds[si].pitch) {
570 		PlatChangeSoundPitch(activeIndex, ActiveSounds[activeIndex].pitch);
571 	}
572 
573 	if (ActiveSounds[activeIndex].threedee) {
574 		alSourcei(ActiveSounds[activeIndex].ds3DBufferP, AL_SOURCE_RELATIVE, AL_FALSE);
575 		alSourcef(ActiveSounds[activeIndex].ds3DBufferP, AL_REFERENCE_DISTANCE, ActiveSounds[activeIndex].threedeedata.inner_range);
576 
577 		// TODO: min distance ActiveSounds[activeIndex].threedeedata.inner_range?
578 		// TODO: max distance DS3D_DEFAULTMAXDISTANCE?
579 		PlatDo3dSound(activeIndex);
580 	} else {
581 		ALfloat zero[3] = { 0.0f, 0.0f, 0.0f };
582 		int newVolume;
583 
584 		alSourcei(ActiveSounds[activeIndex].ds3DBufferP, AL_SOURCE_RELATIVE, AL_TRUE);
585 		alSourcefv(ActiveSounds[activeIndex].ds3DBufferP, AL_POSITION, zero);
586 		alSourcefv(ActiveSounds[activeIndex].ds3DBufferP, AL_VELOCITY, zero);
587 
588 		newVolume = ActiveSounds[activeIndex].volume;
589 		newVolume = (newVolume * VOLUME_PLAT2DSCALE) >> 7;
590 		ActiveSounds[activeIndex].volume = newVolume;
591 
592 		PlatChangeSoundVolume (activeIndex, ActiveSounds[activeIndex].volume);
593 	}
594 
595 	if (!ActiveSounds[activeIndex].reverb_off) {
596 		// TODO: DSPROPERTY_EAXBUFFER_REVERBMIX set to &SoundConfig.reverb_mix
597 	} else {
598 		// TODO: DSPROPERTY_EAXBUFFER_REVERBMIX set to 0
599 	}
600 
601 	if (!ActiveSounds[activeIndex].paused) {
602 		alSourcePlay (ActiveSounds[activeIndex].ds3DBufferP);
603 
604 #ifdef OPENAL_DEBUG
605 		if (ActiveSounds[activeIndex].loop) {
606 			fprintf(stderr, "OPENAL: Playing sound %i %s looping in slot %i\n",
607 				si, GameSounds[si].wavName, activeIndex);
608 		} else {
609 			fprintf(stderr, "OPENAL: Playing sound %i %s once in slot %i\n",
610 				si, GameSounds[si].wavName, activeIndex);
611 		}
612 #endif
613 	}
614 
615 	return 1;
616 }
617 
PlatStopSound(int activeIndex)618 void PlatStopSound(int activeIndex)
619 {
620 #ifdef OPENAL_DEBUG
621 	fprintf(stderr, "OPENAL: PlatStopSound(%d)\n", activeIndex);
622 #endif
623 	if (!SoundActivated) {
624 		return;
625 	}
626 
627 	// TODO: should be able to release data here
628 	alSourceStop(ActiveSounds[activeIndex].ds3DBufferP);
629 }
630 
631 /* table generated by:
632    vol_to_gain_table[volume] = (float) pow(10.0, (double) vol_to_atten_table[volume] / 2000.0);
633 */
634 static const float vol_to_gain_table[] = {
635 0.000010f, 0.000011f, 0.000056f, 0.000146f, 0.000287f, 0.000486f, 0.000748f, 0.001076f,
636 0.001474f, 0.001945f, 0.002495f, 0.003122f, 0.003837f, 0.004629f, 0.005514f, 0.006494f,
637 0.007560f, 0.008720f, 0.009977f, 0.011337f, 0.012794f, 0.014355f, 0.016014f, 0.017783f,
638 0.019656f, 0.021652f, 0.023741f, 0.025942f, 0.028281f, 0.030726f, 0.033266f, 0.035934f,
639 0.038726f, 0.041639f, 0.044668f, 0.047863f, 0.051168f, 0.054576f, 0.058076f, 0.061731f,
640 0.065539f, 0.069502f, 0.073536f, 0.077714f, 0.082130f, 0.086596f, 0.091201f, 0.095940f,
641 0.100809f, 0.105803f, 0.110917f, 0.116279f, 0.121759f, 0.127350f, 0.133045f, 0.138995f,
642 0.144877f, 0.151182f, 0.157398f, 0.163870f, 0.170608f, 0.177419f, 0.184289f, 0.191426f,
643 0.198609f, 0.206063f, 0.213550f, 0.221309f, 0.229087f, 0.237137f, 0.245188f, 0.253805f,
644 0.262120f, 0.270707f, 0.279576f, 0.288735f, 0.297852f, 0.307256f, 0.316592f, 0.326212f,
645 0.336124f, 0.345939f, 0.356451f, 0.366438f, 0.377138f, 0.387704f, 0.398566f, 0.409732f,
646 0.420727f, 0.432016f, 0.443609f, 0.455512f, 0.467197f, 0.479181f, 0.491473f, 0.504081f,
647 0.516416f, 0.529663f, 0.542625f, 0.555265f, 0.568853f, 0.582103f, 0.596348f, 0.610239f,
648 0.623735f, 0.638263f, 0.652379f, 0.667575f, 0.682339f, 0.696626f, 0.712033f, 0.727780f,
649 0.743019f, 0.758578f, 0.774462f, 0.790679f, 0.807235f, 0.824138f, 0.840427f, 0.857038f,
650 0.873977f, 0.891251f, 0.908866f, 0.926830f, 0.945148f, 0.962720f, 0.980618f, 1.000000f
651 };
652 
PlatChangeGlobalVolume(int volume)653 int PlatChangeGlobalVolume(int volume)
654 {
655 	if (!SoundActivated) {
656 		return 0;
657 	}
658 
659 	alListenerf(AL_GAIN, vol_to_gain_table[volume]);
660 
661 	return 1;
662 }
663 
PlatChangeSoundVolume(int activeIndex,int volume)664 int PlatChangeSoundVolume(int activeIndex, int volume)
665 {
666 	if (!SoundActivated) {
667 		return 0;
668 	}
669 
670 	alSourcef(ActiveSounds[activeIndex].ds3DBufferP,
671 		AL_GAIN, vol_to_gain_table[volume]);
672 
673 	return 1;
674 }
675 
PlatChangeSoundPitch(int activeIndex,int pitch)676 int PlatChangeSoundPitch(int activeIndex, int pitch)
677 {
678 	float frequency;
679 
680 	SOUNDINDEX gsi = ActiveSounds[activeIndex].soundIndex;
681 
682 	if (!SoundActivated) {
683 		return 0;
684 	}
685 
686 	if ((pitch < PITCH_MIN) || (pitch >= PITCH_MAX)) {
687 		return 0;
688 	}
689 
690 	if (pitch == PITCH_DEFAULTPLAT) {
691 		frequency = GameSounds[gsi].dsFrequency;
692 	} else {
693 		frequency = ToneToFrequency (GameSounds[gsi].dsFrequency,
694 			GameSounds[gsi].pitch, pitch);
695 	}
696 
697 	frequency = frequency / (float)GameSounds[gsi].dsFrequency;
698 	if (frequency > 2.0) {
699 #ifdef OPENAL_DEBUG
700 	fprintf(stderr, "OPENAL: freq clamp = %f\n", frequency);
701 #endif
702 
703 		alSourceStop(ActiveSounds[activeIndex].ds3DBufferP);
704 		return 0;
705 	}
706 
707 	alSourcef(ActiveSounds[activeIndex].ds3DBufferP, AL_PITCH, frequency);
708 
709 #ifdef OPENAL_DEBUG
710 	fprintf(stderr, "OPENAL: freq change = %f\n", frequency);
711 #endif
712 
713 	ActiveSounds[activeIndex].pitch = pitch;
714 
715 #ifdef OPENAL_DEBUG
716 	fprintf(stderr, "OPENAL: PlatChangeSoundPitch(%d, %d) = %f\n", activeIndex, pitch, (double)frequency);
717 #endif
718 	return 1;
719 }
720 
PlatSoundHasStopped(int activeIndex)721 int PlatSoundHasStopped(int activeIndex)
722 {
723 	ALint val;
724 
725 #ifdef OPENAL_DEBUG
726 	fprintf(stderr, "PlatSoundHasStopped(%d)\n", activeIndex);
727 #endif
728 
729 	if (!SoundActivated) {
730 		return 0;
731 	}
732 
733 	alGetSourceiv (ActiveSounds[activeIndex].ds3DBufferP,
734 			AL_SOURCE_STATE, &val);
735 
736 	if (alGetError () != AL_NO_ERROR) {
737 		return SOUND_PLATFORMERROR;
738 	}
739 
740 	if ((val != AL_PLAYING) && (val != AL_PAUSED)) {
741 		return 1;
742 	}
743 
744 	return 0;
745 }
746 
PlatDo3dSound(int activeIndex)747 int PlatDo3dSound(int activeIndex)
748 {
749 	int distance;
750 	VECTORCH relativePosn;
751 	int newVolume;
752 
753 	if (!SoundActivated) {
754 		return 0;
755 	}
756 
757 	relativePosn.vx = ActiveSounds[activeIndex].threedeedata.position.vx -
758 			Global_VDB_Ptr->VDB_World.vx;
759 	relativePosn.vy = ActiveSounds[activeIndex].threedeedata.position.vy -
760 			Global_VDB_Ptr->VDB_World.vy;
761 	relativePosn.vz = ActiveSounds[activeIndex].threedeedata.position.vz -
762 			Global_VDB_Ptr->VDB_World.vz;
763 
764 	distance = Magnitude(&relativePosn);
765 
766 	/* Deal with paused looping sounds. */
767 	if (ActiveSounds[activeIndex].paused) {
768 		if (distance < (ActiveSounds[activeIndex].threedeedata.outer_range + SOUND_DEACTIVATERANGE)) {
769 
770 			alSourcei(ActiveSounds[activeIndex].ds3DBufferP, AL_LOOPING,
771 				ActiveSounds[activeIndex].loop ? AL_TRUE : AL_FALSE);
772 
773 			alSourcePlay (ActiveSounds[activeIndex].ds3DBufferP);
774 			newVolume = 0;
775 			ActiveSounds[activeIndex].paused = 0;
776 		} else {
777 			return 1;
778 		}
779 	}
780 
781 	if (distance < ActiveSounds[activeIndex].threedeedata.inner_range) {
782 		newVolume = ActiveSounds[activeIndex].volume;
783 	} else {
784 		/* Use proper 3D, but our own attenuation. */
785 		if (distance < ActiveSounds[activeIndex].threedeedata.outer_range) {
786 			float in_to_dis_to_out = ActiveSounds[activeIndex].threedeedata.outer_range - distance;
787 			float in_to_out = ActiveSounds[activeIndex].threedeedata.outer_range - ActiveSounds[activeIndex].threedeedata.inner_range;
788 
789 			if (in_to_out > 0.0) {
790 				newVolume = (int)((float)ActiveSounds[activeIndex].volume * (in_to_dis_to_out / in_to_out));
791 			} else {
792 				newVolume = 0;
793 			}
794 		} else {
795 			newVolume = 0;
796 
797 			/* Deal with looping sounds. */
798 			if ((distance < (ActiveSounds[activeIndex].threedeedata.outer_range + SOUND_DEACTIVATERANGE)) &&
799 			   ActiveSounds[activeIndex].loop) {
800 
801 			   	alSourcePause(ActiveSounds[activeIndex].ds3DBufferP);
802 				ActiveSounds[activeIndex].paused = 1;
803 			}
804 		}
805 	}
806 
807 	if (newVolume > VOLUME_MAX) {
808 		newVolume = VOLUME_MAX;
809 	}
810 	if (newVolume < VOLUME_MIN) {
811 		newVolume = VOLUME_MIN;
812 	}
813 
814 #ifdef OPENAL_DEBUG
815 	fprintf(stderr, "OPENAL: PlatDo3dSound: idx = %d, volume = %d, distance = %d\n", activeIndex, newVolume, distance);
816 #endif
817 
818 	if (PlatChangeSoundVolume (activeIndex, newVolume) == SOUND_PLATFORMERROR) {
819 		return SOUND_PLATFORMERROR;
820 	}
821 
822 	if (distance < ActiveSounds[activeIndex].threedeedata.outer_range) {
823 		ActiveSounds[activeIndex].PropSetP_pos[0] = (ALfloat)relativePosn.vx;
824 		ActiveSounds[activeIndex].PropSetP_pos[1] = (ALfloat)relativePosn.vy;
825 		ActiveSounds[activeIndex].PropSetP_pos[2] = (ALfloat)relativePosn.vz;
826 
827 		alSourcefv (ActiveSounds[activeIndex].ds3DBufferP, AL_POSITION, ActiveSounds[activeIndex].PropSetP_pos);
828 
829 #ifdef OPENAL_DEBUG
830 fprintf(stderr, "OPENAL: Sound : (%f, %f, %f) [%d] [%d,%d]\n", ActiveSounds[activeIndex].PropSetP_pos[0], ActiveSounds[activeIndex].PropSetP_pos[1], ActiveSounds[activeIndex].PropSetP_pos[2], activeIndex, ActiveSounds[activeIndex].threedeedata.inner_range, ActiveSounds[activeIndex].threedeedata.outer_range);
831 #endif
832 
833 // No doppler for now.
834 //		ActiveSounds[activeIndex].PropSetP_vel[0] =
835 //			ActiveSounds[activeIndex].threedeedata.velocity.vx;
836 //		ActiveSounds[activeIndex].PropSetP_vel[1] =
837 //			ActiveSounds[activeIndex].threedeedata.velocity.vy;
838 //		ActiveSounds[activeIndex].PropSetP_vel[2] =
839 //			ActiveSounds[activeIndex].threedeedata.velocity.vz;
840 //		alSourcefv (ActiveSounds[activeIndex].ds3DBufferP,
841 //			    AL_VELOCITY, ActiveSounds[activeIndex].PropSetP_vel);
842 
843 		// TODO: fake 3d support ?
844 	}
845 
846 	return 1;
847 }
848 
849 
PlatUpdatePlayer()850 void PlatUpdatePlayer()
851 {
852 	ALfloat vel[3], or[6], pos[3];
853 
854 	if (!SoundActivated) {
855 		return;
856 	}
857 
858 	if (Global_VDB_Ptr != NULL) {
859 		extern int NormalFrameTime;
860 		extern int DopplerShiftIsOn;
861 
862 		if (AvP.PlayerType != I_Alien) {
863 			or[0] = (float) ((Global_VDB_Ptr->VDB_Mat.mat13) / 65536.0F);
864 			or[1] = 0.0;
865 			or[2] = (float) ((Global_VDB_Ptr->VDB_Mat.mat33) / 65536.0F);
866 			or[3] = 0.0;
867 			or[4] = -1.0; /* negated for openal */
868 			or[5] = 0.0;
869 		} else {
870 			or[0] = (float) ((Global_VDB_Ptr->VDB_Mat.mat13) / 65536.0F);
871 			or[1] = (float) ((Global_VDB_Ptr->VDB_Mat.mat23) / 65536.0F);
872 			or[2] = (float) ((Global_VDB_Ptr->VDB_Mat.mat33) / 65536.0F);
873 			or[3] = -(float) ((Global_VDB_Ptr->VDB_Mat.mat12) / 65536.0F);
874 			or[4] = -(float) ((Global_VDB_Ptr->VDB_Mat.mat22) / 65536.0F); /* negated for openal */
875 			or[5] = -(float) ((Global_VDB_Ptr->VDB_Mat.mat32) / 65536.0F);
876 		}
877 
878 #pragma message ("VELOCITY AND/OR OPENAL SETUP IS IN WRONG UNITS")
879 		static int useVel = 0;
880 		if (useVel!=0&&(AvP.PlayerType == I_Alien && DopplerShiftIsOn && NormalFrameTime)) {
881 			DYNAMICSBLOCK *dynPtr = Player->ObStrategyBlock->DynPtr;
882 			float invFrameTime = 100000.0f/(float)NormalFrameTime;
883 
884 			vel[0] = (float)(dynPtr->Position.vx - dynPtr->PrevPosition.vx) * invFrameTime;
885 			vel[1] = (float)(dynPtr->Position.vy - dynPtr->PrevPosition.vy) * invFrameTime;
886 			vel[2] = (float)(dynPtr->Position.vz - dynPtr->PrevPosition.vz) * invFrameTime;
887 		} else {
888 			vel[0] = 0.0;
889 			vel[1] = 0.0;
890 			vel[2] = 0.0;
891 		}
892 
893 		pos[0] = Global_VDB_Ptr->VDB_World.vx; // 10000.0;
894 		pos[1] = Global_VDB_Ptr->VDB_World.vy; // 10000.0;
895 		pos[2] = Global_VDB_Ptr->VDB_World.vz; // 10000.0;
896 
897 #ifdef OPENAL_DEBUG
898 		fprintf(stderr, "OPENAL: Player: (%f, %f, %f) (%f, %f, %f %f, %f, %f) (%f, %f, %f)\n", pos[0], pos[1], pos[2], or[0], or[1], or[2], or[3], or[4], or[5], vel[0], vel[1], vel[2]);
899 #endif
900 
901 		pos[0] = 0.0f;
902 		pos[1] = 0.0f;
903 		pos[2] = 0.0f;
904 
905 		alListenerfv (AL_ORIENTATION, or);
906 		alListenerfv (AL_VELOCITY, vel);
907 		alListenerfv (AL_POSITION, pos);
908 	}
909 
910 #if defined( _MSC_VERx )
911 	if( SoundConfig.reverb_changed ) {
912 		// TODO: reverb handling
913 	}
914 #endif
915 }
916 
PlatSetEnviroment(unsigned int env_index,float reverb_mix)917 void PlatSetEnviroment(unsigned int env_index, float reverb_mix)
918 {
919 #ifdef OPENAL_DEBUG
920 	fprintf(stderr, "OPENAL: PlatSetEnvironment(%d, %f)\n", env_index, reverb_mix);
921 #endif
922 
923 #if defined( _MSC_VERx )
924 	if( SoundConfig.env_index != env_index ) {
925 
926 		// TODO: support the custom plain reverb
927 		if( env_index >= EAX_ENVIRONMENT_COUNT ) {
928 			env_index = EAX_ENVIRONMENT_DEFAULT;
929 		}
930 
931 		if( EAX_pfPropSet != NULL ) {
932 			ALuint ulEAXVal = env_index;
933 
934 			EAX_pfPropSet(&DSPROPSETID_EAX20_ListenerProperties,
935 				DSPROPERTY_EAXLISTENER_ENVIRONMENT, 0, &ulEAXVal, sizeof( ulEAXVal ) );
936 
937 			// how to set all parameters:
938 			// EAXLISTENERPROPERTIES mystruct = { ... };
939 			// EAX_pfPropSet(&DSPROPSETID_EAX_ListenerProperites,
940 			//	DSPROPERTY_EAXLISTENER_ALL, 0, &mystruct, sizeof(EAXLISTENERPROPERTIES));
941 		}
942 
943 		SoundConfig.env_index = env_index;
944 	}
945 
946 	if( reverb_mix == SoundConfig.reverb_mix ) {
947 		return;
948 	}
949 
950 	// EAX2.0: EAX_REVERBMIX_USEDISTANCE is DSPPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR?
951 	// But I don't think AvP even set this in the final version.
952 
953 	if( (reverb_mix < 0.0f) || (reverb_mix > 1.0f) ) {
954 		// TODO: handle EAX_REVERBMIX_USEDISTANCE
955 		SoundConfig.reverb_mix = EAX_REVERBMIX_USEDISTANCE;
956 	} else {
957 		SoundConfig.reverb_mix = reverb_mix;
958 	}
959 
960 	SoundConfig.reverb_changed = TRUE;
961 #endif
962 }
963 
PlatEndGameSound(SOUNDINDEX index)964 void PlatEndGameSound(SOUNDINDEX index)
965 {
966 	int i;
967 
968 	GameSounds[index].loaded = 0;
969 	GameSounds[index].dsFrequency = 0;
970 
971 	if (GameSounds[index].wavName != NULL) {
972 		DeallocateMem(GameSounds[index].wavName);
973 		GameSounds[index].wavName = NULL;
974 	}
975 
976 	if (!SoundActivated) {
977 		return;
978 	}
979 
980 	if((index<0)||(index>=SID_MAXIMUM)) return; /* no such sound */
981 
982 	for (i = 0; i < SOUND_MAXACTIVE; i++) {
983 		if (ActiveSounds[i].soundIndex == index) {
984 			PlatStopSound(i);
985 
986 			alSourcei(i, AL_BUFFER, 0);
987 		}
988 	}
989 
990 	if (GameSounds[index].dsBufferP) {
991 		alDeleteBuffers(1, &(GameSounds[index].dsBufferP));
992 		GameSounds[index].dsBufferP = 0;
993 	}
994 }
995 
PlatMaxHWSounds()996 unsigned int PlatMaxHWSounds()
997 {
998 #ifdef OPENAL_DEBUG
999 	fprintf(stderr, "OPENAL: PlatMaxHWSounds()\n");
1000 #endif
1001 	// TODO - need to implement this for real?
1002 	return 0;
1003 }
1004 
InitialiseBaseFrequency(SOUNDINDEX soundNum)1005 void InitialiseBaseFrequency(SOUNDINDEX soundNum)
1006 {
1007 	int frequency;
1008 
1009 #ifdef OPENAL_DEBUG
1010 	fprintf(stderr, "OPENAL: InitialiseBaseFrequency(%d) [%d] pitch = %d\n", soundNum, GameSounds[soundNum].pitch==PITCH_DEFAULTPLAT, GameSounds[soundNum].pitch);
1011 #endif
1012 	if(GameSounds[soundNum].pitch>PITCH_MAXPLAT) GameSounds[soundNum].pitch=PITCH_MAXPLAT;
1013 	if(GameSounds[soundNum].pitch<PITCH_MINPLAT) GameSounds[soundNum].pitch=PITCH_MINPLAT;
1014 
1015 	if(GameSounds[soundNum].pitch==PITCH_DEFAULTPLAT) return;
1016 
1017 	frequency = ToneToFrequency(GameSounds[soundNum].dsFrequency,
1018 		PITCH_DEFAULTPLAT, GameSounds[soundNum].pitch);
1019 
1020 #ifdef OPENAL_DEBUG
1021 	fprintf(stderr, "OPENAL: old=%d,new=%d\n", GameSounds[soundNum].dsFrequency, frequency);
1022 #endif
1023 
1024 	GameSounds[soundNum].dsFrequency = frequency;
1025 }
1026 
UpdateSoundFrequencies()1027 void UpdateSoundFrequencies()
1028 {
1029 	extern int SoundSwitchedOn;
1030 	extern int TimeScale;
1031 	int i;
1032 
1033 #ifdef OPENAL_DEBUG
1034 	fprintf(stderr, "OPENAL: UpdateSoundFreqncies()\n");
1035 #endif
1036 
1037 	if (!SoundActivated) {
1038 		return;
1039 	}
1040 
1041 	if (!SoundSwitchedOn) {
1042 		return;
1043 	}
1044 
1045 	for (i = 0; i < SOUND_MAXACTIVE; i++) {
1046 		int gameIndex = ActiveSounds[i].soundIndex;
1047 
1048 		if (gameIndex == SID_NOSOUND) {
1049 			continue;
1050 		}
1051 
1052 		if (TimeScale != ONE_FIXED) {
1053 #ifdef OPENAL_DEBUG
1054  			fprintf(stderr, "OPENAL: UpdateSoundFreqncies %d, f = %d\n", i, MUL_FIXED(GameSounds[gameIndex].dsFrequency,TimeScale));
1055 #endif
1056 		}
1057 
1058 		if (ActiveSounds[i].pitch != GameSounds[gameIndex].pitch) {
1059 			PlatChangeSoundPitch(i,ActiveSounds[i].pitch);
1060 		}
1061 	}
1062 }
1063 
LoadWAV(ALvoid * data,ALvoid ** bufferPtr,ALushort * format,ALushort * freq,int * len,int * seclen)1064 static int LoadWAV( ALvoid* data, ALvoid** bufferPtr, ALushort* format, ALushort* freq, int* len, int* seclen )
1065 {
1066 	FormatChunk fmtChunk;
1067 	DataChunk   dataChunk;
1068 
1069 	if( !SimpleLoadWAV( (unsigned char*)data, &fmtChunk, &dataChunk ) ) {
1070 printf("WAV DEBUG: file didn't parse\n");
1071 		return 0;
1072 	}
1073 
1074 	if( fmtChunk.wFormatTag != 1 ) {
1075 printf("WAV DEBUG: got format tag %d\n", fmtChunk.wFormatTag );
1076 		return 0;
1077 	}
1078 
1079 	if( fmtChunk.wBitsPerSample == 8 ) {
1080 		if( fmtChunk.wChannels == 1 ) {
1081 			*format = AL_FORMAT_MONO8;
1082 		} else if( fmtChunk.wChannels == 2 ) {
1083 			*format = AL_FORMAT_STEREO8;
1084 		} else {
1085 printf("WAV DEBUG: too many channels\n" );
1086 			return 0;
1087 		}
1088 	} else if( fmtChunk.wBitsPerSample == 16 ) {
1089 		if( fmtChunk.wChannels == 1 ) {
1090 			*format = AL_FORMAT_MONO16;
1091 		} else if( fmtChunk.wChannels == 2 ) {
1092 			*format = AL_FORMAT_STEREO16;
1093 		} else {
1094 printf("WAV DEBUG: too many channels\n" );
1095 			return 0;
1096 		}
1097 	} else {
1098 printf("WAV DEBUG: bad bit setup\n");
1099 		return 0;
1100 	}
1101 
1102 	*freq      = fmtChunk.dwSamplesPerSec;
1103 	*len       = dataChunk.dwLength;
1104 	*bufferPtr = dataChunk.pData;
1105 
1106 	*seclen = DIV_FIXED( dataChunk.dwLength, fmtChunk.dwAvgBytesPerSec );
1107 
1108 	return 1;
1109 }
1110 
1111 
LoadWavFile(int soundNum,char * wavFileName)1112 int LoadWavFile(int soundNum, char * wavFileName)
1113 {
1114 	ALushort freq, format;
1115 	ALvoid *data, *bufferPtr;
1116 	int len, seclen;
1117 	FILE *fp;
1118 	const char* wavname;
1119 
1120 #ifdef OPENAL_DEBUG
1121 	fprintf(stderr, "LoadWavFile(%d, %s) - sound\n", soundNum, wavFileName);
1122 #endif
1123 
1124 	if (!SoundActivated) {
1125 		return 0;
1126 	}
1127 
1128 	/* TODO: Perm for now, until custom rifs can be loaded in ~/.avp */
1129 	fp = OpenGameFile(wavFileName, FILEMODE_READONLY, FILETYPE_PERM);
1130 	if (fp == NULL) {
1131 		return 0;
1132 	}
1133 
1134 	fseek(fp, 0, SEEK_END);
1135 	len = ftell(fp);
1136 	rewind(fp);
1137 
1138 	data = (ALvoid*) malloc(len);
1139 	if( data == NULL ) {
1140 		fclose(fp);
1141 		return 0;
1142 	}
1143 
1144 	fread(data, 1, len, fp);
1145 	fclose(fp);
1146 
1147 	if( !LoadWAV( data, &bufferPtr, &format, &freq, &len, &seclen ) ) {
1148 		free( data );
1149 		return 0;
1150 	}
1151 
1152 	alGenBuffers(1, &(GameSounds[soundNum].dsBufferP));
1153 	alBufferData(GameSounds[soundNum].dsBufferP, format, bufferPtr, len, freq);
1154 
1155 	// get the basename of the filename
1156 	wavname = strrchr(wavFileName, '\\');
1157 	if (wavname != NULL) {
1158 		wavname++;
1159 	} else {
1160 		wavname = wavFileName;
1161 	}
1162 
1163 	GameSounds[soundNum].wavName = (char *)AllocateMem(strlen(wavname) + 1);
1164 	strcpy(GameSounds[soundNum].wavName, wavname);
1165 
1166 	GameSounds[soundNum].flags = SAMPLE_IN_HW;
1167 	GameSounds[soundNum].length = (seclen != 0) ? seclen : 1;
1168 	GameSounds[soundNum].dsFrequency = freq;
1169 
1170 	free(data);
1171 
1172 	return 1;
1173 }
1174 
ExtractWavFile(int soundIndex,unsigned char * bufferPtr)1175 unsigned char *ExtractWavFile(int soundIndex, unsigned char *bufferPtr)
1176 {
1177 	ALint len, seclen;
1178 	void *udata;
1179 	ALushort rfmt, rfreq;
1180 	size_t slen;
1181 
1182 #ifdef OPENAL_DEBUG
1183 fprintf(stderr, "OPENAL: ExtractWavFile(%d, %p)\n", soundIndex, bufferPtr);
1184 #endif
1185 
1186 	if (!SoundActivated) {
1187 		return 0;
1188 	}
1189 
1190 	slen = strlen (bufferPtr) + 1;
1191 	GameSounds[soundIndex].wavName = (char *)AllocateMem (slen);
1192 	strcpy (GameSounds[soundIndex].wavName, bufferPtr);
1193 
1194 	bufferPtr += slen;
1195 
1196 #ifdef OPENAL_DEBUG
1197 fprintf(stderr, "OPENAL: Loaded %s\n", GameSounds[soundIndex].wavName);
1198 #endif
1199 
1200 	if( LoadWAV( bufferPtr, &udata, &rfmt, &rfreq, &len, &seclen ) ) {
1201 
1202 		alGenBuffers(1, &(GameSounds[soundIndex].dsBufferP));
1203 		alBufferData (GameSounds[soundIndex].dsBufferP, rfmt, udata, len, rfreq);
1204 
1205 		//GameSounds[soundIndex].loaded = 1;
1206 		GameSounds[soundIndex].flags = SAMPLE_IN_HW;
1207 		GameSounds[soundIndex].length = (seclen != 0) ? seclen : 1;
1208 		GameSounds[soundIndex].dsFrequency = rfreq;
1209 		//GameSounds[soundIndex].pitch = PITCH_DEFAULTPLAT;
1210 	}
1211 
1212 	/* read RIFF chunk length and jump past it */
1213 	return bufferPtr + 8 +
1214 		((bufferPtr[4] <<  0) | (bufferPtr[5] << 8) |
1215 		 (bufferPtr[6] << 16) | (bufferPtr[7] << 24));
1216 }
1217 
LoadWavFromFastFile(int soundNum,char * wavFileName)1218 int LoadWavFromFastFile(int soundNum, char * wavFileName)
1219 {
1220 	FFILE *fp;
1221 	unsigned char *buf;
1222 	size_t len;
1223 	int ok = 0;
1224 
1225 #ifdef OPENAL_DEBUG
1226 	fprintf(stderr, "OPENAL: LoadWavFromFastFile(%d, %s)\n", soundNum, wavFileName);
1227 #endif
1228 
1229 	if ((fp = ffopen (wavFileName, "rb")) != NULL) {
1230 		ffseek (fp, 0, SEEK_END);
1231 		len = fftell (fp);
1232 		ffseek (fp, 0, SEEK_SET);
1233 		buf = (unsigned char *) malloc (len + strlen (wavFileName) + 1);
1234 		strcpy (buf, wavFileName);
1235 		ffread (&buf[strlen(wavFileName)+1], len, 1, fp);
1236 		ffclose (fp);
1237 		ok = ( ExtractWavFile (soundNum, buf) != NULL );
1238 		free (buf);
1239 	}
1240 
1241 	return ok;
1242 }
1243