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