comparison playercode/sloader.c @ 6:d14fd386d182

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:09 +0000
parents
children
comparison
equal deleted inserted replaced
5:42e11dc15457 6:d14fd386d182
1 /*
2 --> Sample Loaders and Sample Processing
3
4 Name: sloader.c
5
6 Description:
7 Routines for loading samples. The sample loader utilizes the routines
8 provided by the "registered" sample loader. See SAMPLELOADER in
9 MIKMOD.H for the sample loader structure.
10
11 Portability:
12 All systems - all compilers
13
14 */
15
16 #include "mikmod.h"
17
18
19 static int sl_rlength;
20 static SWORD sl_old;
21 static SWORD *sl_buffer = NULL;
22 static SAMPLOAD *musiclist = NULL,
23 *sndfxlist = NULL;
24
25
26
27 BOOL SL_Init(SAMPLOAD *s) // returns 0 on error!
28 {
29 if(sl_buffer==NULL)
30 if((sl_buffer=_mm_malloc(4100)) == NULL) return 0;
31
32 sl_rlength = s->length;
33 if(s->infmt & SF_16BITS) sl_rlength>>=1;
34 sl_old = 0;
35
36 return 1;
37 }
38
39
40 void SL_Exit(SAMPLOAD *s)
41 {
42 if(sl_rlength > 0) _mm_fseek(s->fp,sl_rlength,SEEK_CUR);
43 }
44
45
46 void SL_Reset(void)
47 {
48 sl_old = 0;
49 }
50
51
52 void SL_Load(void *buffer, SAMPLOAD *smp, int length)
53 {
54 UWORD infmt = smp->infmt, outfmt = smp->outfmt;
55 SBYTE *bptr = (SBYTE *)buffer;
56 SWORD *wptr = (SWORD *)buffer;
57 int stodo;
58 int t, u;
59
60 while(length)
61 { stodo = (length<2048) ? length : 2048;
62
63 if(infmt & SF_16BITS)
64 { if(infmt & SF_BIG_ENDIAN)
65 _mm_read_M_SWORDS(sl_buffer,stodo,smp->fp);
66 else
67 _mm_read_I_SWORDS(sl_buffer,stodo,smp->fp);
68 } else
69 { SBYTE *s;
70 SWORD *d;
71
72 fread(sl_buffer,sizeof(SBYTE),stodo,smp->fp);
73
74 s = (SBYTE *)sl_buffer;
75 d = sl_buffer;
76 s += stodo;
77 d += stodo;
78
79 for(t=0; t<stodo; t++)
80 { s--;
81 d--;
82 *d = (*s)<<8;
83 }
84 }
85
86 if(infmt & SF_DELTA)
87 { for(t=0; t<stodo; t++)
88 { sl_buffer[t] += sl_old;
89 sl_old = sl_buffer[t];
90 }
91 }
92
93 if((infmt^outfmt) & SF_SIGNED)
94 { for(t=0; t<stodo; t++)
95 sl_buffer[t] ^= 0x8000;
96 }
97
98 if(smp->scalefactor)
99 { int idx = 0;
100 SLONG scaleval;
101
102 // Sample Scaling... average values for better results.
103 t = 0;
104 while(t<stodo && length)
105 { scaleval = 0;
106 for(u=smp->scalefactor; u && t<stodo; u--, t++)
107 scaleval += sl_buffer[t];
108 sl_buffer[idx++] = scaleval / (smp->scalefactor-u);
109 length--;
110 }
111 sl_rlength -= stodo;
112 stodo = idx;
113 } else
114 { length -= stodo;
115 sl_rlength -= stodo;
116 }
117
118 if(outfmt & SF_16BITS)
119 { for(t=0; t<stodo; t++) *(wptr++) = sl_buffer[t];
120 } else
121 { for(t=0; t<stodo; t++) *(bptr++) = sl_buffer[t]>>8;
122 }
123 }
124 }
125
126
127 void SL_LoadStream(void *buffer, UWORD infmt, UWORD outfmt, int length, FILE *fp)
128
129 // This is like SL_Load, but does not perform sample scaling, and does not
130 // require calls to SL_Init / SL_Exit.
131
132 {
133 SBYTE *bptr = (SBYTE *)buffer;
134 SWORD *wptr = (SWORD *)buffer;
135 int stodo;
136 int t;
137
138 // compute number of samples to load
139
140 if(sl_buffer==NULL)
141 if((sl_buffer=_mm_malloc(4100)) == NULL) return;
142
143 while(length)
144 { stodo = (length<2048) ? length : 2048;
145
146 if(infmt & SF_16BITS)
147 { if(infmt & SF_BIG_ENDIAN)
148 _mm_read_M_SWORDS(sl_buffer,stodo,fp);
149 else
150 _mm_read_I_SWORDS(sl_buffer,stodo,fp);
151 } else
152 { SBYTE *s;
153 SWORD *d;
154
155 fread(sl_buffer,sizeof(SBYTE),stodo,fp);
156
157 s = (SBYTE *)sl_buffer;
158 d = sl_buffer;
159 s += stodo;
160 d += stodo;
161
162 for(t=0; t<stodo; t++)
163 { s--;
164 d--;
165 *d = (*s)<<8;
166 }
167 }
168
169 if(infmt & SF_DELTA)
170 { for(t=0; t<stodo; t++)
171 { sl_buffer[t] += sl_old;
172 sl_old = sl_buffer[t];
173 }
174 }
175
176 if((infmt^outfmt) & SF_SIGNED)
177 { for(t=0; t<stodo; t++)
178 sl_buffer[t] ^= 0x8000;
179 }
180
181 length -= stodo;
182
183 if((infmt & SF_STEREO) && !(outfmt & SF_STEREO))
184 { // Dither stereo to mono .. average together every two samples
185 SLONG avgval;
186 int idx = 0;
187
188 t = 0;
189 while(t<stodo && length)
190 { avgval = sl_buffer[t++];
191 avgval += sl_buffer[t++];
192 sl_buffer[idx++] = avgval >> 1;
193 length-=2;
194 }
195 stodo = idx;
196 }
197
198 if(outfmt & SF_16BITS)
199 { for(t=0; t<stodo; t++) *(wptr++) = sl_buffer[t];
200 } else
201 { for(t=0; t<stodo; t++) *(bptr++) = sl_buffer[t]>>8;
202 }
203 }
204 }
205
206
207 SAMPLOAD *SL_RegisterSample(SAMPLE *s, int type, FILE *fp) // Returns 1 on error!
208
209 // Registers a sample for loading when SL_LoadSamples() is called.
210 // type - type of sample to be loaded ..
211 // MD_MUSIC, MD_SNDFX
212
213 {
214 SAMPLOAD *news, **samplist, *cruise;
215
216 if(type==MD_MUSIC)
217 { samplist = & musiclist;
218 cruise = musiclist;
219 } else
220 { samplist = &sndfxlist;
221 cruise = sndfxlist;
222 }
223
224 // Allocate and add structure to the END of the list
225
226 if((news=(SAMPLOAD *)_mm_calloc(1,sizeof(SAMPLOAD))) == NULL) return NULL;
227
228 if(cruise!=NULL)
229 { while(cruise->next!=NULL) cruise = cruise->next;
230 cruise->next = news;
231 } else
232 *samplist = news;
233
234 news->infmt = s->flags & 31;
235 news->outfmt = news->infmt;
236 news->fp = fp;
237 news->sample = s;
238 news->length = s->length;
239 news->loopstart = s->loopstart;
240 news->loopend = s->loopend;
241
242 return news;
243 }
244
245
246 static void FreeSampleList(SAMPLOAD *s)
247 {
248 SAMPLOAD *old;
249
250 while(s!=NULL)
251 { old = s;
252 s = s->next;
253 free(old);
254 }
255 }
256
257
258 static ULONG SampleTotal(SAMPLOAD *samplist, int type)
259 // Returns the total amount of memory required by the samplelist queue.
260 {
261 int total = 0;
262
263 while(samplist!=NULL)
264 { samplist->sample->flags = (samplist->sample->flags&~31) | samplist->outfmt;
265 total += MD_SampleLength(type,samplist->sample);
266 samplist = samplist->next;
267 }
268
269 return total;
270 }
271
272
273 static ULONG RealSpeed(SAMPLOAD *s)
274 {
275 return(s->sample->speed / ((s->scalefactor==0) ? 1 : s->scalefactor));
276 }
277
278
279 static BOOL DitherSamples(SAMPLOAD *samplist, int type)
280 {
281 SAMPLOAD *c2smp;
282 ULONG maxsize, speed;
283 SAMPLOAD *s;
284
285 if(samplist==NULL) return 0;
286
287 // make sure the samples will fit inside available RAM
288 if((maxsize = MD_SampleSpace(type)*1024) != 0)
289 { while(SampleTotal(samplist, type) > maxsize)
290 { // First Pass - check for any 16 bit samples
291 s = samplist;
292 while(s!=NULL)
293 { if(s->outfmt & SF_16BITS)
294 { SL_Sample16to8(s);
295 break;
296 }
297 s = s->next;
298 }
299
300 // Second pass (if no 16bits found above) is to take the sample
301 // with the highest speed and dither it by half.
302 if(s==NULL)
303 { s = samplist;
304 speed = 0;
305 while(s!=NULL)
306 { if((s->sample->length) && (RealSpeed(s) > speed))
307 { speed = RealSpeed(s);
308 c2smp = s;
309 }
310 s = s->next;
311 }
312 SL_HalveSample(c2smp);
313 }
314 }
315 }
316
317
318 // Samples dithered, now load them!
319 // ================================
320
321 s = samplist;
322 while(s != NULL)
323 { // sample has to be loaded ? -> increase number of
324 // samples, allocate memory and load sample.
325
326 if(s->sample->length)
327 { if(s->sample->seekpos)
328 _mm_fseek(s->fp, s->sample->seekpos, SEEK_SET);
329
330 // Call the sample load routine of the driver module.
331 // It has to return a 'handle' (>=0) that identifies
332 // the sample.
333
334 s->sample->handle = MD_SampleLoad(s, type, s->fp);
335 s->sample->flags = (s->sample->flags & ~31) | s->outfmt;
336 if(s->sample->handle < 0)
337 { FreeSampleList(samplist);
338 if(_mm_errorhandler!=NULL) _mm_errorhandler();
339 return 1;
340 }
341 }
342 s = s->next;
343 }
344
345 FreeSampleList(samplist);
346 return 0;
347 }
348
349
350 BOOL SL_LoadSamples(void) // Returns 1 on error!
351 {
352 BOOL ok;
353
354 _mm_critical = 0;
355
356 if((musiclist==NULL) && (sndfxlist==NULL)) return 0;
357 // MikMod_Exit();
358 // exit(1);
359 ok = DitherSamples(musiclist,MD_MUSIC) || DitherSamples(sndfxlist,MD_SNDFX);
360
361 musiclist = sndfxlist = NULL;
362
363 return ok;
364 }
365
366
367 void SL_Sample16to8(SAMPLOAD *s)
368 {
369 s->outfmt &= ~SF_16BITS;
370 s->sample->flags = (s->sample->flags&~31) | s->outfmt;
371 }
372
373
374 void SL_Sample8to16(SAMPLOAD *s)
375 {
376 s->outfmt |= SF_16BITS;
377 s->sample->flags = (s->sample->flags&~31) | s->outfmt;
378 }
379
380
381 void SL_SampleSigned(SAMPLOAD *s)
382 {
383 s->outfmt |= SF_SIGNED;
384 s->sample->flags = (s->sample->flags&~31) | s->outfmt;
385 }
386
387
388 void SL_SampleUnsigned(SAMPLOAD *s)
389 {
390 s->outfmt &= ~SF_SIGNED;
391 s->sample->flags = (s->sample->flags&~31) | s->outfmt;
392 }
393
394
395 void SL_HalveSample(SAMPLOAD *s)
396 {
397 if(s->scalefactor)
398 s->scalefactor++;
399 else
400 s->scalefactor = 2;
401
402 s->sample->divfactor = s->scalefactor;
403 s->sample->length = s->length / s->scalefactor;
404 s->sample->loopstart = s->loopstart / s->scalefactor;
405 s->sample->loopend = s->loopend / s->scalefactor;
406 }
407