6
|
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
|