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