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, 2005 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 MikMod sound library internal definitions
24
25 ==============================================================================*/
26
27#ifndef _MIKMOD_INTERNALS_H
28#define _MIKMOD_INTERNALS_H
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34#include <stdarg.h>
35
36#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H)
37#define inline __inline
38#endif
39
40#include "mikmod.h"
41
42#ifndef MIKMOD_UNIX
43#if (defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) && \
44 !(defined(_MIKMOD_WIN32) || defined(_MIKMOD_OS2) || defined(_MIKMOD_DOS) || defined(_MIKMOD_AMIGA) || defined(macintosh))
45#define MIKMOD_UNIX 1
46#else
47#define MIKMOD_UNIX 0
48#endif
49#endif /* MIKMOD_UNIX */
50
51/*========== More type definitions */
52
53/* SLONGLONG: 64bit, signed */
54#if !defined(_WIN32) && \
55 (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
56typedef long SLONGLONG;
57#define NATIVE_64BIT_INT
58#elif defined(_WIN64) /* win64 is LLP64, not LP64 */
59#define NATIVE_64BIT_INT
60typedef long long SLONGLONG;
61#elif defined(__WATCOMC__)
62typedef __int64 SLONGLONG;
63#elif defined(_WIN32) && !defined(__MWERKS__)
64typedef LONGLONG SLONGLONG;
65#elif defined(macintosh) && !TYPE_LONGLONG
66#include <Types.h>
67typedef SInt64 SLONGLONG;
68#else
69typedef long long SLONGLONG;
70#endif
71typedef int __s64_typetest [(sizeof(SLONGLONG)==8) * 2 - 1];
72
73/* signed size type (ssize_t) */
74#if !defined(_WIN32) /* Win32 SDK has SSIZE_T */
75typedef long SSIZE_T;
76#endif
77typedef int __ssize_typetest [(sizeof(SSIZE_T)==sizeof(size_t)) * 2 - 1];
78
79/*========== Error handling */
80
81#define _mm_errno MikMod_errno
82#define _mm_critical MikMod_critical
83extern MikMod_handler_t _mm_errorhandler;
84
85/*========== MT stuff */
86
87#ifdef HAVE_PTHREAD
88#include <pthread.h>
89#define DECLARE_MUTEX(name) \
90 extern pthread_mutex_t _mm_mutex_##name
91#define MUTEX_LOCK(name) \
92 pthread_mutex_lock(&_mm_mutex_##name)
93#define MUTEX_UNLOCK(name) \
94 pthread_mutex_unlock(&_mm_mutex_##name)
95
96#elif defined(__OS2__)||defined(__EMX__)
97#define DECLARE_MUTEX(name) \
98 extern HMTX _mm_mutex_##name
99#define MUTEX_LOCK(name) \
100 if(_mm_mutex_##name)\
101 DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT)
102#define MUTEX_UNLOCK(name) \
103 if(_mm_mutex_##name)\
104 DosReleaseMutexSem(_mm_mutex_##name)
105
106#elif defined(_WIN32)||defined(__CYGWIN__)
107#include <windows.h>
108#define DECLARE_MUTEX(name) \
109 extern HANDLE _mm_mutex_##name
110#define MUTEX_LOCK(name) \
111 if(_mm_mutex_##name)\
112 WaitForSingleObject(_mm_mutex_##name,INFINITE)
113#define MUTEX_UNLOCK(name) \
114 if(_mm_mutex_##name)\
115 ReleaseMutex(_mm_mutex_##name)
116
117#else
118#define DECLARE_MUTEX(name) \
119 extern void *_mm_mutex_##name
120#define MUTEX_LOCK(name)
121#define MUTEX_UNLOCK(name)
122#endif
123
124DECLARE_MUTEX(lists);
125DECLARE_MUTEX(vars);
126
127/*========== Replacement funcs */
128
129//extern int strcasecmp (const char *__s1, const char *__s2);
130
131/*========== Portable file I/O */
132
133extern MREADER* _mm_new_mem_reader(const void *buffer, long len);
134extern void _mm_delete_mem_reader(MREADER *reader);
135
136extern MREADER* _mm_new_file_reader(int fp);
137extern void _mm_delete_file_reader(MREADER*);
138
139extern MWRITER* _mm_new_file_writer(int fp);
140extern void _mm_delete_file_writer(MWRITER*);
141
142extern int _mm_FileExists(const CHAR *fname);
143
144#define _mm_write_SBYTE(x,y) y->Put(y,(int)x)
145#define _mm_write_UBYTE(x,y) y->Put(y,(int)x)
146
147#define _mm_read_SBYTE(x) (SBYTE)x->Get(x)
148#define _mm_read_UBYTE(x) (UBYTE)x->Get(x)
149#define _mm_skip_BYTE(x) (void)x->Get(x)
150
151#define _mm_write_SBYTES(x,y,z) z->Write(z,(const void *)x,y)
152#define _mm_write_UBYTES(x,y,z) z->Write(z,(const void *)x,y)
153#define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y)
154#define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y)
155
156#define _mm_fseek(x,y,z) x->Seek(x,y,z)
157#define _mm_ftell(x) x->Tell(x)
158#define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET)
159
160#define _mm_eof(x) x->Eof(x)
161
162extern void _mm_iobase_setcur(MREADER*);
163extern void _mm_iobase_revert(MREADER*);
164extern int _mm_fopen(const CHAR *, const CHAR *);
165extern int _mm_fclose(int);
166extern void _mm_write_string(const CHAR*,MWRITER*);
167extern int _mm_read_string (CHAR*,int,MREADER*);
168
169extern SWORD _mm_read_M_SWORD(MREADER*);
170extern SWORD _mm_read_I_SWORD(MREADER*);
171extern UWORD _mm_read_M_UWORD(MREADER*);
172extern UWORD _mm_read_I_UWORD(MREADER*);
173
174extern SLONG _mm_read_M_SLONG(MREADER*);
175extern SLONG _mm_read_I_SLONG(MREADER*);
176extern ULONG _mm_read_M_ULONG(MREADER*);
177extern ULONG _mm_read_I_ULONG(MREADER*);
178
179extern int _mm_read_M_SWORDS(SWORD*,int,MREADER*);
180extern int _mm_read_I_SWORDS(SWORD*,int,MREADER*);
181extern int _mm_read_M_UWORDS(UWORD*,int,MREADER*);
182extern int _mm_read_I_UWORDS(UWORD*,int,MREADER*);
183
184extern int _mm_read_M_SLONGS(SLONG*,int,MREADER*);
185extern int _mm_read_I_SLONGS(SLONG*,int,MREADER*);
186extern int _mm_read_M_ULONGS(ULONG*,int,MREADER*);
187extern int _mm_read_I_ULONGS(ULONG*,int,MREADER*);
188
189extern void _mm_write_M_SWORD(SWORD,MWRITER*);
190extern void _mm_write_I_SWORD(SWORD,MWRITER*);
191extern void _mm_write_M_UWORD(UWORD,MWRITER*);
192extern void _mm_write_I_UWORD(UWORD,MWRITER*);
193
194extern void _mm_write_M_SLONG(SLONG,MWRITER*);
195extern void _mm_write_I_SLONG(SLONG,MWRITER*);
196extern void _mm_write_M_ULONG(ULONG,MWRITER*);
197extern void _mm_write_I_ULONG(ULONG,MWRITER*);
198
199extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*);
200extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*);
201extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*);
202extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*);
203
204extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*);
205extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*);
206extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*);
207extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
208
209/*========== Samples */
210
211#define MAX_SAMPLE_SIZE 0x10000000 /* a sane value guaranteed to not overflow an SLONG */
212
213/* This is a handle of sorts attached to any sample registered with
214 SL_RegisterSample. Generally, this only need be used or changed by the
215 loaders and drivers of mikmod. */
216typedef struct SAMPLOAD {
217 struct SAMPLOAD *next;
218
219 ULONG length; /* length of sample (in samples!) */
220 ULONG loopstart; /* repeat position (relative to start, in samples) */
221 ULONG loopend; /* repeat end */
222 UWORD infmt,outfmt;
223 int scalefactor;
224 SAMPLE* sample;
225 MREADER* reader;
226} SAMPLOAD;
227
228/*========== Sample and waves loading interface */
229
230extern void SL_HalveSample(SAMPLOAD*,int);
231extern void SL_Sample8to16(SAMPLOAD*);
232extern void SL_Sample16to8(SAMPLOAD*);
233extern void SL_SampleSigned(SAMPLOAD*);
234extern void SL_SampleUnsigned(SAMPLOAD*);
235extern int SL_LoadSamples(void);
236extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
237extern int SL_Load(void*,SAMPLOAD*,ULONG);
238extern int SL_Init(SAMPLOAD*);
239extern void SL_Exit(SAMPLOAD*);
240
241/*========== Internal module representation (UniMod) interface */
242
243/* number of notes in an octave */
244#define OCTAVE 12
245
246extern void UniSetRow(UBYTE*);
247extern UBYTE UniGetByte(void);
248extern UWORD UniGetWord(void);
249extern UBYTE* UniFindRow(UBYTE*,UWORD);
250extern void UniSkipOpcode(void);
251extern void UniReset(void);
252extern void UniWriteByte(UBYTE);
253extern void UniWriteWord(UWORD);
254extern void UniNewline(void);
255extern UBYTE* UniDup(void);
256extern int UniInit(void);
257extern void UniCleanup(void);
258extern void UniEffect(UWORD,UWORD);
259#define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x)
260#define UniNote(x) UniEffect(UNI_NOTE,x)
261extern void UniPTEffect(UBYTE,UBYTE);
262extern void UniVolEffect(UWORD,UBYTE);
263
264/*========== Module Commands */
265
266enum {
267 /* Simple note */
268 UNI_NOTE = 1,
269 /* Instrument change */
270 UNI_INSTRUMENT,
271 /* Protracker effects */
272 UNI_PTEFFECT0, /* arpeggio */
273 UNI_PTEFFECT1, /* porta up */
274 UNI_PTEFFECT2, /* porta down */
275 UNI_PTEFFECT3, /* porta to note */
276 UNI_PTEFFECT4, /* vibrato */
277 UNI_PTEFFECT5, /* dual effect 3+A */
278 UNI_PTEFFECT6, /* dual effect 4+A */
279 UNI_PTEFFECT7, /* tremolo */
280 UNI_PTEFFECT8, /* pan */
281 UNI_PTEFFECT9, /* sample offset */
282 UNI_PTEFFECTA, /* volume slide */
283 UNI_PTEFFECTB, /* pattern jump */
284 UNI_PTEFFECTC, /* set volume */
285 UNI_PTEFFECTD, /* pattern break */
286 UNI_PTEFFECTE, /* extended effects */
287 UNI_PTEFFECTF, /* set speed */
288 /* Scream Tracker effects */
289 UNI_S3MEFFECTA, /* set speed */
290 UNI_S3MEFFECTD, /* volume slide */
291 UNI_S3MEFFECTE, /* porta down */
292 UNI_S3MEFFECTF, /* porta up */
293 UNI_S3MEFFECTI, /* tremor */
294 UNI_S3MEFFECTQ, /* retrig */
295 UNI_S3MEFFECTR, /* tremolo */
296 UNI_S3MEFFECTT, /* set tempo */
297 UNI_S3MEFFECTU, /* fine vibrato */
298 UNI_KEYOFF, /* note off */
299 /* Fast Tracker effects */
300 UNI_KEYFADE, /* note fade */
301 UNI_VOLEFFECTS, /* volume column effects */
302 UNI_XMEFFECT4, /* vibrato */
303 UNI_XMEFFECT6, /* dual effect 4+A */
304 UNI_XMEFFECTA, /* volume slide */
305 UNI_XMEFFECTE1, /* fine porta up */
306 UNI_XMEFFECTE2, /* fine porta down */
307 UNI_XMEFFECTEA, /* fine volume slide up */
308 UNI_XMEFFECTEB, /* fine volume slide down */
309 UNI_XMEFFECTG, /* set global volume */
310 UNI_XMEFFECTH, /* global volume slide */
311 UNI_XMEFFECTL, /* set envelope position */
312 UNI_XMEFFECTP, /* pan slide */
313 UNI_XMEFFECTX1, /* extra fine porta up */
314 UNI_XMEFFECTX2, /* extra fine porta down */
315 /* Impulse Tracker effects */
316 UNI_ITEFFECTG, /* porta to note */
317 UNI_ITEFFECTH, /* vibrato */
318 UNI_ITEFFECTI, /* tremor (xy not incremented) */
319 UNI_ITEFFECTM, /* set channel volume */
320 UNI_ITEFFECTN, /* slide / fineslide channel volume */
321 UNI_ITEFFECTP, /* slide / fineslide channel panning */
322 UNI_ITEFFECTT, /* slide tempo */
323 UNI_ITEFFECTU, /* fine vibrato */
324 UNI_ITEFFECTW, /* slide / fineslide global volume */
325 UNI_ITEFFECTY, /* panbrello */
326 UNI_ITEFFECTZ, /* resonant filters */
327 UNI_ITEFFECTS0,
328 /* UltraTracker effects */
329 UNI_ULTEFFECT9, /* Sample fine offset */
330 /* OctaMED effects */
331 UNI_MEDSPEED,
332 UNI_MEDEFFECTF1,/* play note twice */
333 UNI_MEDEFFECTF2,/* delay note */
334 UNI_MEDEFFECTF3,/* play note three times */
335 /* Oktalyzer effects */
336 UNI_OKTARP, /* arpeggio */
337
338 /* Last effect supported by old modules in the UNI format. */
339 UNI_FORMAT_LAST,
340
341 /* Scream Tracker effects */
342 UNI_S3MEFFECTH, /* vibrato */
343 /* Impulse Tracker effects */
344 UNI_ITEFFECTH_OLD, /* vibrato (old) */
345 UNI_ITEFFECTU_OLD, /* fine vibrato (old) */
346 /* GDM effects. */
347 UNI_GDMEFFECT4, /* vibrato */
348 UNI_GDMEFFECT7, /* tremolo */
349 UNI_GDMEFFECT14, /* fine vibrato */
350 /* OctaMED effects. */
351 UNI_MEDEFFECT_VIB, /* MED vibrato */
352 UNI_MEDEFFECT_FD, /* set pitch */
353 UNI_MEDEFFECT_16, /* loop */
354 UNI_MEDEFFECT_18, /* stop note */
355 UNI_MEDEFFECT_1E, /* pattern delay */
356 UNI_MEDEFFECT_1F, /* note delay and retrigger */
357 /* Farandole effects. */
358 UNI_FAREFFECT1, /* Porta up */
359 UNI_FAREFFECT2, /* Porta down */
360 UNI_FAREFFECT3, /* Porta to note */
361 UNI_FAREFFECT4, /* Retrigger */
362 UNI_FAREFFECT6, /* Vibrato */
363 UNI_FAREFFECTD, /* Fine tempo down */
364 UNI_FAREFFECTE, /* Fine tempo up */
365 UNI_FAREFFECTF, /* Set tempo */
366
367 UNI_LAST
368};
369
370extern const UWORD unioperands[UNI_LAST];
371
372/* IT / S3M Extended SS effects: */
373enum {
374 SS_GLISSANDO = 1,
375 SS_FINETUNE,
376 SS_VIBWAVE,
377 SS_TREMWAVE,
378 SS_PANWAVE,
379 SS_FRAMEDELAY,
380 SS_S7EFFECTS,
381 SS_PANNING,
382 SS_SURROUND,
383 SS_HIOFFSET,
384 SS_PATLOOP,
385 SS_NOTECUT,
386 SS_NOTEDELAY,
387 SS_PATDELAY
388};
389
390/* IT Volume column effects */
391enum {
392 VOL_VOLUME = 1,
393 VOL_PANNING,
394 VOL_VOLSLIDE,
395 VOL_PITCHSLIDEDN,
396 VOL_PITCHSLIDEUP,
397 VOL_PORTAMENTO,
398 VOL_VIBRATO
399};
400
401/* IT resonant filter information */
402
403#define UF_MAXMACRO 0x10
404#define UF_MAXFILTER 0x100
405
406#define FILT_CUT 0x80
407#define FILT_RESONANT 0x81
408
409typedef struct FILTER {
410 UBYTE filter,inf;
411} FILTER;
412
413/*========== Instruments */
414
415/* Instrument format flags */
416#define IF_OWNPAN 1
417#define IF_PITCHPAN 2
418
419/* Envelope flags: */
420#define EF_ON 1
421#define EF_SUSTAIN 2
422#define EF_LOOP 4
423#define EF_VOLENV 8
424
425/* New Note Action Flags */
426#define NNA_CUT 0
427#define NNA_CONTINUE 1
428#define NNA_OFF 2
429#define NNA_FADE 3
430
431#define NNA_MASK 3
432
433#define DCT_OFF 0
434#define DCT_NOTE 1
435#define DCT_SAMPLE 2
436#define DCT_INST 3
437
438#define DCA_CUT 0
439#define DCA_OFF 1
440#define DCA_FADE 2
441
442#define KEY_KICK 0
443#define KEY_OFF 1
444#define KEY_FADE 2
445#define KEY_KILL (KEY_OFF|KEY_FADE)
446
447#define KICK_ABSENT 0
448#define KICK_NOTE 1
449#define KICK_KEYOFF 2
450#define KICK_ENV 4
451
452#define AV_IT 1 /* IT vs. XM vibrato info */
453
454/*========== Playing */
455
456#define POS_NONE (-2) /* no loop position defined */
457
458#define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */
459
460typedef struct ENVPR {
461 UBYTE flg; /* envelope flag */
462 UBYTE pts; /* number of envelope points */
463 UBYTE susbeg; /* envelope sustain index begin */
464 UBYTE susend; /* envelope sustain index end */
465 UBYTE beg; /* envelope loop begin */
466 UBYTE end; /* envelope loop end */
467 SWORD p; /* current envelope counter */
468 UWORD a; /* envelope index a */
469 UWORD b; /* envelope index b */
470 ENVPT* env; /* envelope points */
471} ENVPR;
472
473typedef struct MP_CHANNEL {
474 INSTRUMENT* i;
475 SAMPLE *s;
476 UBYTE sample; /* which sample number */
477 UBYTE note; /* the audible note as heard, direct rep of period */
478 SWORD outvolume; /* output volume (vol + sampcol + instvol) */
479 SBYTE chanvol; /* channel's "global" volume */
480 UWORD fadevol; /* fading volume rate */
481 SWORD panning; /* panning position */
482 UBYTE kick; /* if true = sample has to be restarted */
483 UBYTE kick_flag; /* kick has been true */
484 UWORD period; /* period to play the sample at */
485 UBYTE nna; /* New note action type + master/slave flags */
486
487 UBYTE volflg; /* volume envelope settings */
488 UBYTE panflg; /* panning envelope settings */
489 UBYTE pitflg; /* pitch envelope settings */
490
491 UBYTE keyoff; /* if true = fade out and stuff */
492 SWORD handle; /* which sample-handle */
493 UBYTE notedelay; /* (used for note delay) */
494 SLONG start; /* The starting byte index in the sample */
495} MP_CHANNEL;
496
497typedef struct MP_CONTROL {
498 struct MP_CHANNEL main;
499
500 struct MP_VOICE* slave; /* Audio Slave of current effects control channel */
501
502 UBYTE slavechn; /* Audio Slave of current effects control channel */
503 UBYTE muted; /* if set, channel not played */
504 UWORD ultoffset; /* fine sample offset memory */
505 UBYTE anote; /* the note that indexes the audible */
506 UBYTE oldnote;
507 SWORD ownper;
508 SWORD ownvol;
509 UBYTE dca; /* duplicate check action */
510 UBYTE dct; /* duplicate check type */
511 UBYTE* row; /* row currently playing on this channel */
512 SBYTE retrig; /* retrig value (0 means don't retrig) */
513 ULONG speed; /* what finetune to use */
514 SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */
515
516 SWORD tmpvolume; /* tmp volume */
517 UWORD tmpperiod; /* tmp period */
518 UWORD wantedperiod;/* period to slide to (with effect 3 or 5) */
519
520 UBYTE arpmem; /* arpeggio command memory */
521 UBYTE pansspd; /* panslide speed */
522 UWORD slidespeed;
523 UWORD portspeed; /* noteslide speed (toneportamento) */
524
525 UBYTE s3mtremor; /* s3m tremor (effect I) counter */
526 UBYTE s3mtronof; /* s3m tremor ontime/offtime */
527 UBYTE s3mvolslide;/* last used volslide */
528 SBYTE sliding;
529 UBYTE s3mrtgspeed;/* last used retrig speed */
530 UBYTE s3mrtgslide;/* last used retrig slide */
531
532 UBYTE fartoneportarunning; /* FAR tone porta (effect 3) is a little bit different than other effects. It should keep running when the effect has first started, even if it is not given on subsequently rows */
533 SLONG fartoneportaspeed; /* FAR tone porta increment value */
534 SLONG farcurrentvalue; /* Because we're using fixing points as speed and the current period is an integer, we need to store the current value here for next round */
535 UBYTE farretrigcount; /* Number of retrigs to do */
536
537 /* These variables are only stored on the first control instance and therefore used globally.
538 The reason they are stored here is to minimize the number of global variables. */
539 UBYTE farcurtempo; /* Farandole current speed */
540 SWORD fartempobend; /* Used by the Farandole fine tempo effects and store the current bend value */
541
542 UBYTE glissando; /* glissando (0 means off) */
543 UBYTE wavecontrol;
544
545 SBYTE vibpos; /* current vibrato position */
546 UBYTE vibspd; /* "" speed */
547 UBYTE vibdepth; /* "" depth */
548
549 SBYTE trmpos; /* current tremolo position */
550 UBYTE trmspd; /* "" speed */
551 UBYTE trmdepth; /* "" depth */
552
553 UBYTE fslideupspd;
554 UBYTE fslidednspd;
555 UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */
556 UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */
557 UBYTE ffportupspd;/* fx X1 (extra fine portamento up) data */
558 UBYTE ffportdnspd;/* fx X2 (extra fine portamento dn) data */
559
560 ULONG hioffset; /* last used high order of sample offset */
561 UWORD soffset; /* last used low order of sample-offset (effect 9) */
562
563 UBYTE sseffect; /* last used Sxx effect */
564 UBYTE ssdata; /* last used Sxx data info */
565 UBYTE chanvolslide;/* last used channel volume slide */
566
567 UBYTE panbwave; /* current panbrello waveform */
568 UBYTE panbpos; /* current panbrello position */
569 SBYTE panbspd; /* "" speed */
570 UBYTE panbdepth; /* "" depth */
571
572 UBYTE newnote; /* set to 1 if the current row contains a note */
573 UBYTE newsamp; /* set to 1 upon a sample / inst change */
574 UBYTE voleffect; /* Volume Column Effect Memory as used by IT */
575 UBYTE voldata; /* Volume Column Data Memory */
576
577 SWORD pat_reppos; /* patternloop position */
578 UWORD pat_repcnt; /* times to loop */
579} MP_CONTROL;
580
581/* Used by NNA only player (audio control. AUDTMP is used for full effects
582 control). */
583typedef struct MP_VOICE {
584 struct MP_CHANNEL main;
585
586 ENVPR venv;
587 ENVPR penv;
588 ENVPR cenv;
589
590 UWORD avibpos; /* autovibrato pos */
591 UWORD aswppos; /* autovibrato sweep pos */
592
593 ULONG totalvol; /* total volume of channel (before global mixings) */
594
595 int mflag;
596 SWORD masterchn;
597 UWORD masterperiod;
598
599 MP_CONTROL* master; /* index of "master" effects channel */
600} MP_VOICE;
601
602/*========== Loaders */
603
604typedef struct MLOADER {
605 struct MLOADER* next;
606 const CHAR* type;
607 const CHAR* version;
608 int (*Init)(void);
609 int (*Test)(void);
610 int (*Load)(int);
611 void (*Cleanup)(void);
612 CHAR* (*LoadTitle)(void);
613} MLOADER;
614
615/* internal loader variables */
616extern MREADER* modreader;
617extern MODULE of; /* static unimod loading space */
618extern const UWORD finetune[16];
619extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */
620
621extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
622extern UBYTE* poslookup; /* lookup table for pattern jumps after
623 blank pattern removal */
624extern UWORD poslookupcnt;
625extern UWORD* origpositions;
626
627extern int filters; /* resonant filters in use */
628extern UBYTE activemacro; /* active midi macro number for Sxx */
629extern UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */
630extern FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
631
632extern int* noteindex;
633
634/*========== Internal loader interface */
635
636extern int ReadComment(UWORD);
637extern int ReadLinedComment(UWORD,UWORD);
638extern int AllocPositions(int);
639extern int AllocPatterns(void);
640extern int AllocTracks(void);
641extern int AllocInstruments(void);
642extern int AllocSamples(void);
643extern CHAR* DupStr(const CHAR*, UWORD, int);
644
645/* loader utility functions */
646extern int* AllocLinear(void);
647extern void FreeLinear(void);
648extern int speed_to_finetune(ULONG,int);
649extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
650extern void S3MIT_CreateOrders(int);
651
652/* flags for S3MIT_ProcessCmd */
653#define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */
654#define S3MIT_IT 2 /* behave as impulse tracker */
655#define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */
656
657/* used to convert c4spd to linear XM periods (IT and IMF loaders). */
658extern UWORD getlinearperiod(UWORD,ULONG);
659extern ULONG getfrequency(UWORD,ULONG);
660
661/* loader shared data */
662#define STM_NTRACKERS 3
663extern const CHAR *STM_Signatures[STM_NTRACKERS];
664
665/*========== Player interface */
666
667extern int Player_Init(MODULE*);
668extern void Player_Exit(MODULE*);
669extern void Player_HandleTick(void);
670
671/*========== UnPackers */
672
673typedef int (*MUNPACKER) (struct MREADER*,
674 void** /* unpacked data out */ ,
675 long* /* unpacked data size */ );
676extern int PP20_Unpack(MREADER*, void**, long*);
677extern int MMCMP_Unpack(MREADER*, void**, long*);
678extern int XPK_Unpack(MREADER*, void**, long*);
679extern int S404_Unpack(MREADER*, void**, long*);
680
681/*========== Drivers */
682
683/* max. number of handles a driver has to provide. (not strict) */
684#define MAXSAMPLEHANDLES 384
685
686/* These variables can be changed at ANY time and results will be immediate */
687extern UWORD md_bpm; /* current song / hardware BPM rate */
688
689/* Variables below can be changed via MD_SetNumVoices at any time. However, a
690 call to MD_SetNumVoicess while the driver is active will cause the sound to
691 skip slightly. */
692extern UBYTE md_numchn; /* number of song + sound effects voices */
693extern UBYTE md_sngchn; /* number of song voices */
694extern UBYTE md_sfxchn; /* number of sound effects voices */
695extern UBYTE md_hardchn; /* number of hardware mixed voices */
696extern UBYTE md_softchn; /* number of software mixed voices */
697
698/* This is for use by the hardware drivers only. It points to the registered
699 tickhandler function. */
700extern MikMod_player_t md_player;
701
702extern SWORD MD_SampleLoad(SAMPLOAD*,int);
703extern void MD_SampleUnload(SWORD);
704extern ULONG MD_SampleSpace(int);
705extern ULONG MD_SampleLength(int,SAMPLE*);
706
707/* uLaw conversion */
708extern void unsignedtoulaw(char *,int);
709
710/* Parameter extraction helper */
711extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, int);
712
713/* Internal software mixer stuff */
714extern void VC_SetupPointers(void);
715extern int VC1_Init(void);
716extern int VC2_Init(void);
717
718#if (MIKMOD_UNIX)
719/* POSIX helper functions */
720extern int MD_Access(const CHAR *);
721extern int MD_DropPrivileges(void);
722#endif
723
724/* Macro to define a missing driver, yet allowing binaries to dynamically link
725 with the library without missing symbol errors */
726#define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 }
727
728/*========== Prototypes for non-MT safe versions of some public functions */
729
730extern void _mm_registerdriver(struct MDRIVER*);
731extern void _mm_registerloader(struct MLOADER*);
732extern int MikMod_Active_internal(void);
733extern void MikMod_DisableOutput_internal(void);
734extern int MikMod_EnableOutput_internal(void);
735extern void MikMod_Exit_internal(void);
736extern int MikMod_SetNumVoices_internal(int,int);
737extern void Player_Exit_internal(MODULE*);
738extern void Player_Stop_internal(void);
739extern int Player_Paused_internal(void);
740extern void Sample_Free_internal(SAMPLE*);
741extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG);
742extern void Voice_SetFrequency_internal(SBYTE,ULONG);
743extern void Voice_SetPanning_internal(SBYTE,ULONG);
744extern void Voice_SetVolume_internal(SBYTE,UWORD);
745extern void Voice_Stop_internal(SBYTE);
746extern int Voice_Stopped_internal(SBYTE);
747
748extern int VC1_PlayStart(void);
749extern int VC2_PlayStart(void);
750extern void VC1_PlayStop(void);
751extern void VC2_PlayStop(void);
752extern int VC1_SetNumVoices(void);
753extern int VC2_SetNumVoices(void);
754
755extern MikMod_callback_t vc_callback;
756
757#ifdef __cplusplus
758}
759#endif
760
761/*========== SIMD mixing routines */
762#undef HAVE_ALTIVEC
763#undef HAVE_SSE2
764#if defined(MIKMOD_SIMD)
765
766#if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3))
767#define HAVE_ALTIVEC
768
769#elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */
770#define HAVE_SSE2
771
772#elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64))
773/* FIXME: emmintrin.h requires VC6 processor pack or VC2003+ */
774#define HAVE_SSE2
775/* avoid some warnings */
776#pragma warning(disable:4761)
777#pragma warning(disable:4391)
778#pragma warning(disable:4244)
779
780#endif /* AltiVec/SSE2 */
781#endif /* MIKMOD_SIMD */
782
783/*========== SIMD mixing helper functions =============*/
784
785#if defined(_WIN64)
786# if defined(_MSC_VER)
787# define IS_ALIGNED_16(ptr) (!((__int64)(ptr) & 15i64))
788# else /* GCC, etc. */
789# define IS_ALIGNED_16(ptr) (!((long long)(ptr) & 15LL))
790# endif
791#else /* long cast should be OK for all else */
792#define IS_ALIGNED_16(ptr) (!((long)(ptr) & 15L))
793#endif
794
795/* Altivec helper function */
796#if defined HAVE_ALTIVEC
797
798#define simd_m128i vector signed int
799#define simd_m128 vector float
800
801#ifdef __GNUC__
802#include <ppc_intrinsics.h>
803#endif
804
805/* Helper functions */
806
807/* Set single float across the four values */
808static inline vector float vec_mul(const vector float a, const vector float b) {
809 return vec_madd(a, b, (const vector float)(0.f));
810}
811
812/* Set single float across the four values */
813static inline vector float vec_load_ps1(const float *pF) {
814 vector float data = vec_lde(0, pF);
815 return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0);
816}
817
818/* Set vector to 0 */
819static inline vector float vec_setzero() {
820 return (vector float) (0.);
821}
822
823static inline vector signed char vec_set1_8(unsigned char splatchar) {
824 vector unsigned char splatmap = vec_lvsl(0, &splatchar);
825 vector unsigned char result = vec_lde(0, &splatchar);
826 splatmap = vec_splat(splatmap, 0);
827 return (vector signed char)vec_perm(result, result, splatmap);
828}
829
830#define PERM_A0 0x00,0x01,0x02,0x03
831#define PERM_A1 0x04,0x05,0x06,0x07
832#define PERM_A2 0x08,0x09,0x0A,0x0B
833#define PERM_A3 0x0C,0x0D,0x0E,0x0F
834#define PERM_B0 0x10,0x11,0x12,0x13
835#define PERM_B1 0x14,0x15,0x16,0x17
836#define PERM_B2 0x18,0x19,0x1A,0x1B
837#define PERM_B3 0x1C,0x1D,0x1E,0x1F
838
839/* Equivalent to _mm_unpacklo_epi32 */
840static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) {
841 return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1));
842}
843
844/* Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). */
845static inline vector signed int vec_hiqq(vector signed int a) {
846 vector signed int b = vec_splat_s32(0);
847 return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3));
848}
849
850/* vec_sra is max +15. We have to do in two times ... */
851#define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul);
852#define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0));
853#define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8));
854#define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16));
855#define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste);
856#define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) vec_st(vec_add(vec_packs((vector signed short)vec_packs(v1, v2), (vector signed short)vec_packs(v3, v4)), vec_set1_8(128)), 0, dste);
857#define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste);
858#define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
859
860#elif defined HAVE_SSE2
861
862#include <emmintrin.h>
863
864/* SSE2 helper function */
865
866static __inline __m128i mm_hiqq(const __m128i a) {
867 return _mm_srli_si128(a, 8); /* get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). */
868}
869
870/* 128-bit mixing macros */
871#define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT+16-size);
872#define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT-size)), mul);
873#define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
874#define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
875#define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
876#define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
877#define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) _mm_store_si128((__m128i*)(dste), _mm_add_epi8(_mm_packs_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)), _mm_set1_epi8(128)));
878#define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1);
879#define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
880#define simd_m128i __m128i
881#define simd_m128 __m128
882
883#endif
884
885#if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
886/* MikMod_amalloc() returns a 16 byte aligned zero-filled
887 memory in SIMD-enabled builds.
888 - the returned memory can be freed with MikMod_afree()
889 - the returned memory CAN NOT be realloc()'ed safely. */
890#ifdef __cplusplus
891extern "C" {
892#endif
893void* MikMod_amalloc(size_t);
894void MikMod_afree(void *); /* frees if ptr != NULL */
895#ifdef __cplusplus
896}
897#endif
898
899#else /* NO SIMD */
900#define MikMod_amalloc(s) MikMod_calloc(1,(s))
901#define MikMod_afree MikMod_free
902#endif
903
904#endif /* _MIKMOD_INTERNALS_H */
905
906/* ex:set ts=4: */