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