~ubuntu-branches/ubuntu/karmic/frozen-bubble/karmic

« back to all changes in this revision

Viewing changes to SDL_mixer_patched/mikmod/sloader.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2002-04-17 09:21:51 UTC
  • Revision ID: james.westby@ubuntu.com-20020417092151-7ye6ril7bgg9g0he
Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      MikMod sound library
 
2
        (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
 
3
        complete list.
 
4
 
 
5
        This library is free software; you can redistribute it and/or modify
 
6
        it under the terms of the GNU Library General Public License as
 
7
        published by the Free Software Foundation; either version 2 of
 
8
        the License, or (at your option) any later version.
 
9
 
 
10
        This program is distributed in the hope that it will be useful,
 
11
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
        GNU Library General Public License for more details.
 
14
 
 
15
        You should have received a copy of the GNU Library General Public
 
16
        License along with this library; if not, write to the Free Software
 
17
        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
18
        02111-1307, USA.
 
19
*/
 
20
 
 
21
/*==============================================================================
 
22
 
 
23
  $Id: sloader.c,v 1.3 1999/12/28 18:51:11 hercules Exp $
 
24
 
 
25
  Routines for loading samples. The sample loader utilizes the routines
 
26
  provided by the "registered" sample loader.
 
27
 
 
28
==============================================================================*/
 
29
 
 
30
#ifdef HAVE_CONFIG_H
 
31
#include "config.h"
 
32
#endif
 
33
 
 
34
#include <mikmod_internals.h>
 
35
 
 
36
static  int sl_rlength;
 
37
static  SWORD sl_old;
 
38
static  SWORD *sl_buffer=NULL;
 
39
static  SAMPLOAD *musiclist=NULL,*sndfxlist=NULL;
 
40
 
 
41
/* size of the loader buffer in words */
 
42
#define SLBUFSIZE 2048
 
43
 
 
44
/* IT-Compressed status structure */
 
45
typedef struct ITPACK {
 
46
        UWORD bits;    /* current number of bits */
 
47
        UWORD bufbits; /* bits in buffer */
 
48
        SWORD last;    /* last output */
 
49
        UBYTE buf;     /* bit buffer */
 
50
} ITPACK;
 
51
 
 
52
BOOL SL_Init(SAMPLOAD* s)
 
53
{
 
54
        if(!sl_buffer)
 
55
                if(!(sl_buffer=_mm_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
 
56
 
 
57
        sl_rlength = s->length;
 
58
        if(s->infmt & SF_16BITS) sl_rlength>>=1;
 
59
        sl_old = 0;
 
60
 
 
61
        return 1;
 
62
}
 
63
 
 
64
void SL_Exit(SAMPLOAD *s)
 
65
{
 
66
        if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
 
67
        if(sl_buffer) {
 
68
                free(sl_buffer);
 
69
                sl_buffer=NULL;
 
70
        }
 
71
}
 
72
 
 
73
/* unpack a 8bit IT packed sample */
 
74
static BOOL read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
 
75
{
 
76
        SWORD *dest=sl_buffer,*end=sl_buffer+count;
 
77
        UWORD x,y,needbits,havebits,new_count=0;
 
78
        UWORD bits = status->bits;
 
79
        UWORD bufbits = status->bufbits;
 
80
        SBYTE last = status->last;
 
81
        UBYTE buf = status->buf;
 
82
 
 
83
        while (dest<end) {
 
84
                needbits=new_count?3:bits;
 
85
                x=havebits=0;
 
86
                while (needbits) {
 
87
                        /* feed buffer */
 
88
                        if (!bufbits) {
 
89
                                if((*incnt)--)
 
90
                                        buf=_mm_read_UBYTE(reader);
 
91
                                else
 
92
                                        buf=0;
 
93
                                bufbits=8;
 
94
                        }
 
95
                        /* get as many bits as necessary */
 
96
                        y = needbits<bufbits?needbits:bufbits;
 
97
                        x|= (buf & ((1<<y)- 1))<<havebits;
 
98
                        buf>>=y;
 
99
                        bufbits-=y;
 
100
                        needbits-=y;
 
101
                        havebits+=y;
 
102
                }
 
103
                if (new_count) {
 
104
                        new_count = 0;
 
105
                        if (++x >= bits)
 
106
                                x++;
 
107
                        bits = x;
 
108
                        continue;
 
109
                }
 
110
                if (bits<7) {
 
111
                        if (x==(1<<(bits-1))) {
 
112
                                new_count = 1;
 
113
                                continue;
 
114
                        }
 
115
                }
 
116
                else if (bits<9) {
 
117
                        y = (0xff >> (9-bits)) - 4;
 
118
                        if ((x>y)&&(x<=y+8)) {
 
119
                                if ((x-=y)>=bits)
 
120
                                        x++;
 
121
                                bits = x;
 
122
                                continue;
 
123
                        }
 
124
                }
 
125
                else if (bits<10) {
 
126
                        if (x>=0x100) {
 
127
                                bits=x-0x100+1;
 
128
                                continue;
 
129
                        }
 
130
                } else {
 
131
                        /* error in compressed data... */
 
132
                        _mm_errno=MMERR_ITPACK_INVALID_DATA;
 
133
                        return 0;
 
134
                }
 
135
 
 
136
                if (bits<8) /* extend sign */
 
137
                        x = ((SBYTE)(x <<(8-bits))) >> (8-bits);
 
138
                *(dest++)= (last+=x) << 8; /* convert to 16 bit */
 
139
        }
 
140
        status->bits = bits;
 
141
        status->bufbits = bufbits;
 
142
        status->last = last;
 
143
        status->buf = buf;
 
144
        return dest-sl_buffer;
 
145
}
 
146
 
 
147
/* unpack a 16bit IT packed sample */
 
148
static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
 
149
{
 
150
        SWORD *dest=sl_buffer,*end=sl_buffer+count;
 
151
        SLONG x,y,needbits,havebits,new_count=0;
 
152
        UWORD bits = status->bits;
 
153
        UWORD bufbits = status->bufbits;
 
154
        SWORD last = status->last;
 
155
        UBYTE buf = status->buf;
 
156
 
 
157
        while (dest<end) {
 
158
                needbits=new_count?4:bits;
 
159
                x=havebits=0;
 
160
                while (needbits) {
 
161
                        /* feed buffer */
 
162
                        if (!bufbits) {
 
163
                                if((*incnt)--)
 
164
                                        buf=_mm_read_UBYTE(reader);
 
165
                                else
 
166
                                        buf=0;
 
167
                                bufbits=8;
 
168
                        }
 
169
                        /* get as many bits as necessary */
 
170
                        y=needbits<bufbits?needbits:bufbits;
 
171
                        x|=(buf &((1<<y)-1))<<havebits;
 
172
                        buf>>=y;
 
173
                        bufbits-=y;
 
174
                        needbits-=y;
 
175
                        havebits+=y;
 
176
                }
 
177
                if (new_count) {
 
178
                        new_count = 0;
 
179
                        if (++x >= bits)
 
180
                                x++;
 
181
                        bits = x;
 
182
                        continue;
 
183
                }
 
184
                if (bits<7) {
 
185
                        if (x==(1<<(bits-1))) {
 
186
                                new_count=1;
 
187
                                continue;
 
188
                        }
 
189
                }
 
190
                else if (bits<17) {
 
191
                        y=(0xffff>>(17-bits))-8;
 
192
                        if ((x>y)&&(x<=y+16)) {
 
193
                                if ((x-=y)>=bits)
 
194
                                        x++;
 
195
                                bits = x;
 
196
                                continue;
 
197
                        }
 
198
                }
 
199
                else if (bits<18) {
 
200
                        if (x>=0x10000) {
 
201
                                bits=x-0x10000+1;
 
202
                                continue;
 
203
                        }
 
204
                } else {
 
205
                         /* error in compressed data... */
 
206
                        _mm_errno=MMERR_ITPACK_INVALID_DATA;
 
207
                        return 0;
 
208
                }
 
209
 
 
210
                if (bits<16) /* extend sign */
 
211
                        x = ((SWORD)(x<<(16-bits)))>>(16-bits);
 
212
                *(dest++)=(last+=x);
 
213
        }
 
214
        status->bits = bits;
 
215
        status->bufbits = bufbits;
 
216
        status->last = last;
 
217
        status->buf = buf;
 
218
        return dest-sl_buffer;
 
219
}
 
220
 
 
221
static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,BOOL dither)
 
222
{
 
223
        SBYTE *bptr = (SBYTE*)buffer;
 
224
        SWORD *wptr = (SWORD*)buffer;
 
225
        int stodo,t,u;
 
226
 
 
227
        int result,c_block=0;   /* compression bytes until next block */
 
228
        ITPACK status;
 
229
        UWORD incnt;
 
230
 
 
231
        while(length) {
 
232
                stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
 
233
 
 
234
                if(infmt&SF_ITPACKED) {
 
235
                        sl_rlength=0;
 
236
                        if (!c_block) {
 
237
                                status.bits = (infmt & SF_16BITS) ? 17 : 9;
 
238
                                status.last = status.bufbits = 0;
 
239
                                incnt=_mm_read_I_UWORD(reader);
 
240
                                c_block = (infmt & SF_16BITS) ? 0x4000 : 0x8000;
 
241
                                if(infmt&SF_DELTA) sl_old=0;
 
242
                        }
 
243
                        if (infmt & SF_16BITS) {
 
244
                                if(!(result=read_itcompr16(&status,reader,sl_buffer,stodo,&incnt)))
 
245
                                        return 1;
 
246
                        } else {
 
247
                                if(!(result=read_itcompr8(&status,reader,sl_buffer,stodo,&incnt)))
 
248
                                        return 1;
 
249
                        }
 
250
                        if(result!=stodo) {
 
251
                                _mm_errno=MMERR_ITPACK_INVALID_DATA;
 
252
                                return 1;
 
253
                        }
 
254
                        c_block -= stodo;
 
255
                } else {
 
256
                        if(infmt&SF_16BITS) {
 
257
                                if(infmt&SF_BIG_ENDIAN)
 
258
                                        _mm_read_M_SWORDS(sl_buffer,stodo,reader);
 
259
                                else
 
260
                                        _mm_read_I_SWORDS(sl_buffer,stodo,reader);
 
261
                        } else {
 
262
                                SBYTE *src;
 
263
                                SWORD *dest;
 
264
 
 
265
                                reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
 
266
                                src = (SBYTE*)sl_buffer;
 
267
                                dest  = sl_buffer;
 
268
                                src += stodo;dest += stodo;
 
269
 
 
270
                                for(t=0;t<stodo;t++) {
 
271
                                        src--;dest--;
 
272
                                        *dest = (*src)<<8;
 
273
                                }
 
274
                        }
 
275
                        sl_rlength-=stodo;
 
276
                }
 
277
 
 
278
                if(infmt & SF_DELTA)
 
279
                        for(t=0;t<stodo;t++) {
 
280
                                sl_buffer[t] += sl_old;
 
281
                                sl_old = sl_buffer[t];
 
282
                        }
 
283
 
 
284
                if((infmt^outfmt) & SF_SIGNED)
 
285
                        for(t=0;t<stodo;t++)
 
286
                                sl_buffer[t]^= 0x8000;
 
287
 
 
288
                if(scalefactor) {
 
289
                        int idx = 0;
 
290
                        SLONG scaleval;
 
291
 
 
292
                        /* Sample Scaling... average values for better results. */
 
293
                        t= 0;
 
294
                        while(t<stodo && length) {
 
295
                                scaleval = 0;
 
296
                                for(u=scalefactor;u && t<stodo;u--,t++)
 
297
                                        scaleval+=sl_buffer[t];
 
298
                                sl_buffer[idx++]=scaleval/(scalefactor-u);
 
299
                                length--;
 
300
                        }
 
301
                        stodo = idx;
 
302
                } else
 
303
                        length -= stodo;
 
304
 
 
305
                if (dither) {
 
306
                        if((infmt & SF_STEREO) && !(outfmt & SF_STEREO)) {
 
307
                                /* dither stereo to mono, average together every two samples */
 
308
                                SLONG avgval;
 
309
                                int idx = 0;
 
310
 
 
311
                                t=0;
 
312
                                while(t<stodo && length) {
 
313
                                        avgval=sl_buffer[t++];
 
314
                                        avgval+=sl_buffer[t++];
 
315
                                        sl_buffer[idx++]=avgval>>1;
 
316
                                        length-=2;
 
317
                                }
 
318
                                stodo = idx;
 
319
                        }
 
320
                }
 
321
 
 
322
                if(outfmt & SF_16BITS) {
 
323
                        for(t=0;t<stodo;t++)
 
324
                                *(wptr++)=sl_buffer[t];
 
325
                } else {
 
326
                        for(t=0;t<stodo;t++)
 
327
                                *(bptr++)=sl_buffer[t]>>8;
 
328
                }
 
329
        }
 
330
        return 0;
 
331
}
 
332
 
 
333
BOOL SL_Load(void* buffer,SAMPLOAD *smp,ULONG length)
 
334
{
 
335
        return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor,
 
336
                               length,smp->reader,0);
 
337
}
 
338
 
 
339
/* Registers a sample for loading when SL_LoadSamples() is called. */
 
340
SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader)
 
341
{
 
342
        SAMPLOAD *news,**samplist,*cruise;
 
343
 
 
344
        if(type==MD_MUSIC) {
 
345
                samplist = &musiclist;
 
346
                cruise = musiclist;
 
347
        } else
 
348
          if (type==MD_SNDFX) {
 
349
                samplist = &sndfxlist;
 
350
                cruise = sndfxlist;
 
351
        } else
 
352
                return NULL;
 
353
 
 
354
        /* Allocate and add structure to the END of the list */
 
355
        if(!(news=(SAMPLOAD*)_mm_malloc(sizeof(SAMPLOAD)))) return NULL;
 
356
 
 
357
        if(cruise) {
 
358
                while(cruise->next) cruise=cruise->next;
 
359
                cruise->next = news;
 
360
        } else
 
361
                *samplist = news;
 
362
 
 
363
        news->infmt     = s->flags & SF_FORMATMASK;
 
364
        news->outfmt    = news->infmt;
 
365
        news->reader    = reader;
 
366
        news->sample    = s;
 
367
        news->length    = s->length;
 
368
        news->loopstart = s->loopstart;
 
369
        news->loopend   = s->loopend;
 
370
 
 
371
        return news;
 
372
}
 
373
 
 
374
static void FreeSampleList(SAMPLOAD* s)
 
375
{
 
376
        SAMPLOAD *old;
 
377
 
 
378
        while(s) {
 
379
                old = s;
 
380
                s = s->next;
 
381
                free(old);
 
382
        }
 
383
}
 
384
 
 
385
/* Returns the total amount of memory required by the samplelist queue. */
 
386
static ULONG SampleTotal(SAMPLOAD* samplist,int type)
 
387
{
 
388
        int total = 0;
 
389
 
 
390
        while(samplist) {
 
391
                samplist->sample->flags=
 
392
                  (samplist->sample->flags&~SF_FORMATMASK)|samplist->outfmt;
 
393
                total += MD_SampleLength(type,samplist->sample);
 
394
                samplist=samplist->next;
 
395
        }
 
396
 
 
397
        return total;
 
398
}
 
399
 
 
400
static ULONG RealSpeed(SAMPLOAD *s)
 
401
{
 
402
        return(s->sample->speed/(s->scalefactor?s->scalefactor:1));
 
403
}
 
404
 
 
405
static BOOL DitherSamples(SAMPLOAD* samplist,int type)
 
406
{
 
407
        SAMPLOAD *c2smp=NULL;
 
408
        ULONG maxsize, speed;
 
409
        SAMPLOAD *s;
 
410
 
 
411
        if(!samplist) return 0;
 
412
 
 
413
        if((maxsize=MD_SampleSpace(type)*1024))
 
414
                while(SampleTotal(samplist,type)>maxsize) {
 
415
                        /* First Pass - check for any 16 bit samples */
 
416
                        s = samplist;
 
417
                        while(s) {
 
418
                                if(s->outfmt & SF_16BITS) {
 
419
                                        SL_Sample16to8(s);
 
420
                                        break;
 
421
                                }
 
422
                                s=s->next;
 
423
                        }
 
424
                        /* Second pass (if no 16bits found above) is to take the sample with
 
425
                           the highest speed and dither it by half. */
 
426
                        if(!s) {
 
427
                                s = samplist;
 
428
                                speed = 0;
 
429
                                while(s) {
 
430
                                        if((s->sample->length) && (RealSpeed(s)>speed)) {
 
431
                                                speed=RealSpeed(s);
 
432
                                                c2smp=s;
 
433
                                        }
 
434
                                        s=s->next;
 
435
                                }
 
436
                                if (c2smp)
 
437
                                        SL_HalveSample(c2smp,2);
 
438
                        }
 
439
                }
 
440
 
 
441
        /* Samples dithered, now load them ! */
 
442
        s = samplist;
 
443
        while(s) {
 
444
                /* sample has to be loaded ? -> increase number of samples, allocate
 
445
                   memory and load sample. */
 
446
                if(s->sample->length) {
 
447
                        if(s->sample->seekpos)
 
448
                                _mm_fseek(s->reader, s->sample->seekpos, SEEK_SET);
 
449
 
 
450
                        /* Call the sample load routine of the driver module. It has to
 
451
                           return a 'handle' (>=0) that identifies the sample. */
 
452
                        s->sample->handle = MD_SampleLoad(s, type);
 
453
                        s->sample->flags  = (s->sample->flags & ~SF_FORMATMASK) | s->outfmt;
 
454
                        if(s->sample->handle<0) {
 
455
                                FreeSampleList(samplist);
 
456
                                if(_mm_errorhandler) _mm_errorhandler();
 
457
                                return 1;
 
458
                        }
 
459
                }
 
460
                s = s->next;
 
461
        }
 
462
 
 
463
        FreeSampleList(samplist);
 
464
        return 0;
 
465
}
 
466
 
 
467
BOOL SL_LoadSamples(void)
 
468
{
 
469
        BOOL ok;
 
470
 
 
471
        _mm_critical = 0;
 
472
 
 
473
        if((!musiclist)&&(!sndfxlist)) return 0;
 
474
        ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
 
475
        musiclist=sndfxlist=NULL;
 
476
 
 
477
        return ok;
 
478
}
 
479
 
 
480
void SL_Sample16to8(SAMPLOAD* s)
 
481
{
 
482
        s->outfmt &= ~SF_16BITS;
 
483
        s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
 
484
}
 
485
 
 
486
void SL_Sample8to16(SAMPLOAD* s)
 
487
{
 
488
        s->outfmt |= SF_16BITS;
 
489
        s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
 
490
}
 
491
 
 
492
void SL_SampleSigned(SAMPLOAD* s)
 
493
{
 
494
        s->outfmt |= SF_SIGNED;
 
495
        s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
 
496
}
 
497
 
 
498
void SL_SampleUnsigned(SAMPLOAD* s)
 
499
{
 
500
        s->outfmt &= ~SF_SIGNED;
 
501
        s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
 
502
}
 
503
 
 
504
void SL_HalveSample(SAMPLOAD* s,int factor)
 
505
{
 
506
        s->scalefactor=factor>0?factor:2;
 
507
 
 
508
        s->sample->divfactor = s->scalefactor;
 
509
        s->sample->length    = s->length / s->scalefactor;
 
510
        s->sample->loopstart = s->loopstart / s->scalefactor;
 
511
        s->sample->loopend   = s->loopend / s->scalefactor;
 
512
}
 
513
 
 
514
 
 
515
/* ex:set ts=4: */