1 /* MikMod sound library
\r
2 (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
\r
5 This library is free software; you can redistribute it and/or modify
\r
6 it under the terms of the GNU Library General Public License as
\r
7 published by the Free Software Foundation; either version 2 of
\r
8 the License, or (at your option) any later version.
\r
10 This program is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 GNU Library General Public License for more details.
\r
15 You should have received a copy of the GNU Library General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
\r
21 /*==============================================================================
\r
23 $Id: sloader.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
\r
25 Routines for loading samples. The sample loader utilizes the routines
\r
26 provided by the "registered" sample loader.
\r
28 ==============================================================================*/
\r
30 #ifdef HAVE_CONFIG_H
\r
34 #ifdef HAVE_UNISTD_H
\r
38 #include "mikmod_internals.h"
\r
40 static int sl_rlength;
\r
41 static SWORD sl_old;
\r
42 static SWORD *sl_buffer=NULL;
\r
43 static SAMPLOAD *musiclist=NULL,*sndfxlist=NULL;
\r
45 /* size of the loader buffer in words */
\r
46 #define SLBUFSIZE 2048
\r
48 /* IT-Compressed status structure */
\r
49 typedef struct ITPACK {
\r
50 UWORD bits; /* current number of bits */
\r
51 UWORD bufbits; /* bits in buffer */
\r
52 SWORD last; /* last output */
\r
53 UBYTE buf; /* bit buffer */
\r
56 BOOL SL_Init(SAMPLOAD* s)
\r
59 if(!(sl_buffer=_mm_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
\r
61 sl_rlength = s->length;
\r
62 if(s->infmt & SF_16BITS) sl_rlength>>=1;
\r
68 void SL_Exit(SAMPLOAD *s)
\r
70 if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
\r
77 /* unpack a 8bit IT packed sample */
\r
78 static BOOL read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
\r
80 SWORD *dest=sl_buffer,*end=sl_buffer+count;
\r
81 UWORD x,y,needbits,havebits,new_count=0;
\r
82 UWORD bits = status->bits;
\r
83 UWORD bufbits = status->bufbits;
\r
84 SBYTE last = status->last;
\r
85 UBYTE buf = status->buf;
\r
88 needbits=new_count?3:bits;
\r
94 buf=_mm_read_UBYTE(reader);
\r
99 /* get as many bits as necessary */
\r
100 y = needbits<bufbits?needbits:bufbits;
\r
101 x|= (buf & ((1<<y)- 1))<<havebits;
\r
115 if (x==(1<<(bits-1))) {
\r
121 y = (0xff >> (9-bits)) - 4;
\r
122 if ((x>y)&&(x<=y+8)) {
\r
129 else if (bits<10) {
\r
135 /* error in compressed data... */
\r
136 _mm_errno=MMERR_ITPACK_INVALID_DATA;
\r
140 if (bits<8) /* extend sign */
\r
141 x = ((SBYTE)(x <<(8-bits))) >> (8-bits);
\r
142 *(dest++)= (last+=x) << 8; /* convert to 16 bit */
\r
144 status->bits = bits;
\r
145 status->bufbits = bufbits;
\r
146 status->last = last;
\r
148 return dest-sl_buffer;
\r
151 /* unpack a 16bit IT packed sample */
\r
152 static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
\r
154 SWORD *dest=sl_buffer,*end=sl_buffer+count;
\r
155 SLONG x,y,needbits,havebits,new_count=0;
\r
156 UWORD bits = status->bits;
\r
157 UWORD bufbits = status->bufbits;
\r
158 SWORD last = status->last;
\r
159 UBYTE buf = status->buf;
\r
162 needbits=new_count?4:bits;
\r
168 buf=_mm_read_UBYTE(reader);
\r
173 /* get as many bits as necessary */
\r
174 y=needbits<bufbits?needbits:bufbits;
\r
175 x|=(buf &((1<<y)-1))<<havebits;
\r
189 if (x==(1<<(bits-1))) {
\r
194 else if (bits<17) {
\r
195 y=(0xffff>>(17-bits))-8;
\r
196 if ((x>y)&&(x<=y+16)) {
\r
203 else if (bits<18) {
\r
209 /* error in compressed data... */
\r
210 _mm_errno=MMERR_ITPACK_INVALID_DATA;
\r
214 if (bits<16) /* extend sign */
\r
215 x = ((SWORD)(x<<(16-bits)))>>(16-bits);
\r
216 *(dest++)=(last+=x);
\r
218 status->bits = bits;
\r
219 status->bufbits = bufbits;
\r
220 status->last = last;
\r
222 return dest-sl_buffer;
\r
225 static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,BOOL dither)
\r
227 SBYTE *bptr = (SBYTE*)buffer;
\r
228 SWORD *wptr = (SWORD*)buffer;
\r
231 int result,c_block=0; /* compression bytes until next block */
\r
236 stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
\r
238 if(infmt&SF_ITPACKED) {
\r
241 status.bits = (infmt & SF_16BITS) ? 17 : 9;
\r
242 status.last = status.bufbits = 0;
\r
243 incnt=_mm_read_I_UWORD(reader);
\r
244 c_block = (infmt & SF_16BITS) ? 0x4000 : 0x8000;
\r
245 if(infmt&SF_DELTA) sl_old=0;
\r
247 if (infmt & SF_16BITS) {
\r
248 if(!(result=read_itcompr16(&status,reader,sl_buffer,stodo,&incnt)))
\r
251 if(!(result=read_itcompr8(&status,reader,sl_buffer,stodo,&incnt)))
\r
254 if(result!=stodo) {
\r
255 _mm_errno=MMERR_ITPACK_INVALID_DATA;
\r
260 if(infmt&SF_16BITS) {
\r
261 if(infmt&SF_BIG_ENDIAN)
\r
262 _mm_read_M_SWORDS(sl_buffer,stodo,reader);
\r
264 _mm_read_I_SWORDS(sl_buffer,stodo,reader);
\r
269 reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
\r
270 src = (SBYTE*)sl_buffer;
\r
272 src += stodo;dest += stodo;
\r
274 for(t=0;t<stodo;t++) {
\r
282 if(infmt & SF_DELTA)
\r
283 for(t=0;t<stodo;t++) {
\r
284 sl_buffer[t] += sl_old;
\r
285 sl_old = sl_buffer[t];
\r
288 if((infmt^outfmt) & SF_SIGNED)
\r
289 for(t=0;t<stodo;t++)
\r
290 sl_buffer[t]^= 0x8000;
\r
296 /* Sample Scaling... average values for better results. */
\r
298 while(t<stodo && length) {
\r
300 for(u=scalefactor;u && t<stodo;u--,t++)
\r
301 scaleval+=sl_buffer[t];
\r
302 sl_buffer[idx++]=scaleval/(scalefactor-u);
\r
310 if((infmt & SF_STEREO) && !(outfmt & SF_STEREO)) {
\r
311 /* dither stereo to mono, average together every two samples */
\r
316 while(t<stodo && length) {
\r
317 avgval=sl_buffer[t++];
\r
318 avgval+=sl_buffer[t++];
\r
319 sl_buffer[idx++]=avgval>>1;
\r
326 if(outfmt & SF_16BITS) {
\r
327 for(t=0;t<stodo;t++)
\r
328 *(wptr++)=sl_buffer[t];
\r
330 for(t=0;t<stodo;t++)
\r
331 *(bptr++)=sl_buffer[t]>>8;
\r
337 BOOL SL_Load(void* buffer,SAMPLOAD *smp,ULONG length)
\r
339 return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor,
\r
340 length,smp->reader,0);
\r
343 /* Registers a sample for loading when SL_LoadSamples() is called. */
\r
344 SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader)
\r
346 SAMPLOAD *news,**samplist,*cruise;
\r
348 if(type==MD_MUSIC) {
\r
349 samplist = &musiclist;
\r
350 cruise = musiclist;
\r
352 if (type==MD_SNDFX) {
\r
353 samplist = &sndfxlist;
\r
354 cruise = sndfxlist;
\r
358 /* Allocate and add structure to the END of the list */
\r
359 if(!(news=(SAMPLOAD*)_mm_malloc(sizeof(SAMPLOAD)))) return NULL;
\r
362 while(cruise->next) cruise=cruise->next;
\r
363 cruise->next = news;
\r
367 news->infmt = s->flags & SF_FORMATMASK;
\r
368 news->outfmt = news->infmt;
\r
369 news->reader = reader;
\r
371 news->length = s->length;
\r
372 news->loopstart = s->loopstart;
\r
373 news->loopend = s->loopend;
\r
378 static void FreeSampleList(SAMPLOAD* s)
\r
389 /* Returns the total amount of memory required by the samplelist queue. */
\r
390 static ULONG SampleTotal(SAMPLOAD* samplist,int type)
\r
395 samplist->sample->flags=
\r
396 (samplist->sample->flags&~SF_FORMATMASK)|samplist->outfmt;
\r
397 total += MD_SampleLength(type,samplist->sample);
\r
398 samplist=samplist->next;
\r
404 static ULONG RealSpeed(SAMPLOAD *s)
\r
406 return(s->sample->speed/(s->scalefactor?s->scalefactor:1));
\r
409 static BOOL DitherSamples(SAMPLOAD* samplist,int type)
\r
411 SAMPLOAD *c2smp=NULL;
\r
412 ULONG maxsize, speed;
\r
415 if(!samplist) return 0;
\r
417 if((maxsize=MD_SampleSpace(type)*1024))
\r
418 while(SampleTotal(samplist,type)>maxsize) {
\r
419 /* First Pass - check for any 16 bit samples */
\r
422 if(s->outfmt & SF_16BITS) {
\r
428 /* Second pass (if no 16bits found above) is to take the sample with
\r
429 the highest speed and dither it by half. */
\r
434 if((s->sample->length) && (RealSpeed(s)>speed)) {
\r
435 speed=RealSpeed(s);
\r
441 SL_HalveSample(c2smp,2);
\r
445 /* Samples dithered, now load them ! */
\r
448 /* sample has to be loaded ? -> increase number of samples, allocate
\r
449 memory and load sample. */
\r
450 if(s->sample->length) {
\r
451 if(s->sample->seekpos)
\r
452 _mm_fseek(s->reader, s->sample->seekpos, SEEK_SET);
\r
454 /* Call the sample load routine of the driver module. It has to
\r
455 return a 'handle' (>=0) that identifies the sample. */
\r
456 s->sample->handle = MD_SampleLoad(s, type);
\r
457 s->sample->flags = (s->sample->flags & ~SF_FORMATMASK) | s->outfmt;
\r
458 if(s->sample->handle<0) {
\r
459 FreeSampleList(samplist);
\r
460 if(_mm_errorhandler) _mm_errorhandler();
\r
467 FreeSampleList(samplist);
\r
471 BOOL SL_LoadSamples(void)
\r
477 if((!musiclist)&&(!sndfxlist)) return 0;
\r
478 ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
\r
479 musiclist=sndfxlist=NULL;
\r
484 void SL_Sample16to8(SAMPLOAD* s)
\r
486 s->outfmt &= ~SF_16BITS;
\r
487 s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
\r
490 void SL_Sample8to16(SAMPLOAD* s)
\r
492 s->outfmt |= SF_16BITS;
\r
493 s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
\r
496 void SL_SampleSigned(SAMPLOAD* s)
\r
498 s->outfmt |= SF_SIGNED;
\r
499 s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
\r
502 void SL_SampleUnsigned(SAMPLOAD* s)
\r
504 s->outfmt &= ~SF_SIGNED;
\r
505 s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt;
\r
508 void SL_HalveSample(SAMPLOAD* s,int factor)
\r
510 s->scalefactor=factor>0?factor:2;
\r
512 s->sample->divfactor = s->scalefactor;
\r
513 s->sample->length = s->length / s->scalefactor;
\r
514 s->sample->loopstart = s->loopstart / s->scalefactor;
\r
515 s->sample->loopend = s->loopend / s->scalefactor;
\r