1 /* MikMod sound library
2 (c) 1998, 1999, 2005 Miodrag Vallat and others - see file AUTHORS for
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.
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.
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
21 /*==============================================================================
23 MikMod sound library internal definitions
25 ==============================================================================*/
27 #ifndef _MIKMOD_INTERNALS_H
28 #define _MIKMOD_INTERNALS_H
36 #if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H)
37 #define inline __inline
41 #if (defined(unix) || defined(__unix__) || defined(__unix) || \
42 (defined(__APPLE__) && defined(__MACH__))) && \
43 !(defined(__DJGPP__) || defined(_WIN32) || defined(__OS2__) || defined(__EMX__))
46 #endif /* MIKMOD_UNIX */
50 /*========== More type definitions */
52 /* SLONGLONG: 64bit, signed */
53 #if !defined(_WIN32) && \
54 (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
55 typedef long SLONGLONG;
56 #define NATIVE_64BIT_INT
57 #elif defined(_WIN64) /* win64 is LLP64, not LP64 */
58 #define NATIVE_64BIT_INT
59 typedef long long SLONGLONG;
60 #elif defined(__WATCOMC__)
61 typedef __int64 SLONGLONG;
62 #elif defined(_WIN32) && !defined(__MWERKS__)
63 typedef LONGLONG SLONGLONG;
64 #elif defined(macintosh) && !TYPE_LONGLONG
66 typedef SInt64 SLONGLONG;
68 typedef long long SLONGLONG;
70 typedef int __s64_typetest [(sizeof(SLONGLONG)==8) * 2 - 1];
72 /* pointer-sized signed int (ssize_t/intptr_t) : */
73 #if defined(_WIN64) /* win64 is LLP64, not LP64 */
74 typedef long long SINTPTR_T;
76 /* long should be pointer-sized for all others : */
77 typedef long SINTPTR_T;
79 typedef int __iptr_typetest [(sizeof(SINTPTR_T)==sizeof(void*)) * 2 - 1];
81 /*========== Error handling */
83 #define _mm_errno MikMod_errno
84 #define _mm_critical MikMod_critical
85 extern MikMod_handler_t _mm_errorhandler;
87 /*========== MT stuff */
91 #define DECLARE_MUTEX(name) \
92 extern pthread_mutex_t _mm_mutex_##name
93 #define MUTEX_LOCK(name) \
94 pthread_mutex_lock(&_mm_mutex_##name)
95 #define MUTEX_UNLOCK(name) \
96 pthread_mutex_unlock(&_mm_mutex_##name)
98 #elif defined(__OS2__)||defined(__EMX__)
99 #define DECLARE_MUTEX(name) \
100 extern HMTX _mm_mutex_##name
101 #define MUTEX_LOCK(name) \
102 if(_mm_mutex_##name)\
103 DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT)
104 #define MUTEX_UNLOCK(name) \
105 if(_mm_mutex_##name)\
106 DosReleaseMutexSem(_mm_mutex_##name)
108 #elif defined(_WIN32)
110 #define DECLARE_MUTEX(name) \
111 extern HANDLE _mm_mutex_##name
112 #define MUTEX_LOCK(name) \
113 if(_mm_mutex_##name)\
114 WaitForSingleObject(_mm_mutex_##name,INFINITE)
115 #define MUTEX_UNLOCK(name) \
116 if(_mm_mutex_##name)\
117 ReleaseMutex(_mm_mutex_##name)
120 #define DECLARE_MUTEX(name) \
121 extern void *_mm_mutex_##name
122 #define MUTEX_LOCK(name)
123 #define MUTEX_UNLOCK(name)
126 DECLARE_MUTEX(lists);
129 /*========== Replacement funcs */
131 extern int _mm_strcasecmp (const char *__s1, const char *__s2);
133 /*========== Portable file I/O */
135 extern MREADER* _mm_new_mem_reader(const void *buffer, long len);
136 extern void _mm_delete_mem_reader(MREADER *reader);
138 extern MREADER* _mm_new_file_reader(FILE* fp);
139 extern void _mm_delete_file_reader(MREADER*);
141 extern MWRITER* _mm_new_file_writer(FILE *fp);
142 extern void _mm_delete_file_writer(MWRITER*);
144 extern BOOL _mm_FileExists(const CHAR *fname);
146 #define _mm_write_SBYTE(x,y) y->Put(y,(int)x)
147 #define _mm_write_UBYTE(x,y) y->Put(y,(int)x)
149 #define _mm_read_SBYTE(x) (SBYTE)x->Get(x)
150 #define _mm_read_UBYTE(x) (UBYTE)x->Get(x)
151 #define _mm_skip_BYTE(x) (void)x->Get(x)
153 #define _mm_write_SBYTES(x,y,z) z->Write(z,(const void *)x,y)
154 #define _mm_write_UBYTES(x,y,z) z->Write(z,(const void *)x,y)
155 #define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y)
156 #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y)
158 #define _mm_fseek(x,y,z) x->Seek(x,y,z)
159 #define _mm_ftell(x) x->Tell(x)
160 #define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET)
162 #define _mm_eof(x) x->Eof(x)
164 extern void _mm_iobase_setcur(MREADER*);
165 extern void _mm_iobase_revert(MREADER*);
166 extern FILE* _mm_fopen(const CHAR *, const CHAR *);
167 extern int _mm_fclose(FILE *);
168 extern void _mm_write_string(const CHAR*,MWRITER*);
169 extern BOOL _mm_read_string (CHAR*,int,MREADER*);
171 extern SWORD _mm_read_M_SWORD(MREADER*);
172 extern SWORD _mm_read_I_SWORD(MREADER*);
173 extern UWORD _mm_read_M_UWORD(MREADER*);
174 extern UWORD _mm_read_I_UWORD(MREADER*);
176 extern SLONG _mm_read_M_SLONG(MREADER*);
177 extern SLONG _mm_read_I_SLONG(MREADER*);
178 extern ULONG _mm_read_M_ULONG(MREADER*);
179 extern ULONG _mm_read_I_ULONG(MREADER*);
181 extern BOOL _mm_read_M_SWORDS(SWORD*,int,MREADER*);
182 extern BOOL _mm_read_I_SWORDS(SWORD*,int,MREADER*);
183 extern BOOL _mm_read_M_UWORDS(UWORD*,int,MREADER*);
184 extern BOOL _mm_read_I_UWORDS(UWORD*,int,MREADER*);
186 extern BOOL _mm_read_M_SLONGS(SLONG*,int,MREADER*);
187 extern BOOL _mm_read_I_SLONGS(SLONG*,int,MREADER*);
188 extern BOOL _mm_read_M_ULONGS(ULONG*,int,MREADER*);
189 extern BOOL _mm_read_I_ULONGS(ULONG*,int,MREADER*);
191 extern void _mm_write_M_SWORD(SWORD,MWRITER*);
192 extern void _mm_write_I_SWORD(SWORD,MWRITER*);
193 extern void _mm_write_M_UWORD(UWORD,MWRITER*);
194 extern void _mm_write_I_UWORD(UWORD,MWRITER*);
196 extern void _mm_write_M_SLONG(SLONG,MWRITER*);
197 extern void _mm_write_I_SLONG(SLONG,MWRITER*);
198 extern void _mm_write_M_ULONG(ULONG,MWRITER*);
199 extern void _mm_write_I_ULONG(ULONG,MWRITER*);
201 extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*);
202 extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*);
203 extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*);
204 extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*);
206 extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*);
207 extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*);
208 extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*);
209 extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
211 /*========== Samples */
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. */
216 typedef struct SAMPLOAD {
217 struct SAMPLOAD *next;
219 ULONG length; /* length of sample (in samples!) */
220 ULONG loopstart; /* repeat position (relative to start, in samples) */
221 ULONG loopend; /* repeat end */
228 /*========== Sample and waves loading interface */
230 extern void SL_HalveSample(SAMPLOAD*,int);
231 extern void SL_Sample8to16(SAMPLOAD*);
232 extern void SL_Sample16to8(SAMPLOAD*);
233 extern void SL_SampleSigned(SAMPLOAD*);
234 extern void SL_SampleUnsigned(SAMPLOAD*);
235 extern int SL_LoadSamples(void);
236 extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
237 extern int SL_Load(void*,SAMPLOAD*,ULONG);
238 extern BOOL SL_Init(SAMPLOAD*);
239 extern void SL_Exit(SAMPLOAD*);
241 /*========== Internal module representation (UniMod) interface */
243 /* number of notes in an octave */
246 extern void UniSetRow(UBYTE*);
247 extern UBYTE UniGetByte(void);
248 extern UWORD UniGetWord(void);
249 extern UBYTE* UniFindRow(UBYTE*,UWORD);
250 extern void UniSkipOpcode(void);
251 extern void UniReset(void);
252 extern void UniWriteByte(UBYTE);
253 extern void UniWriteWord(UWORD);
254 extern void UniNewline(void);
255 extern UBYTE* UniDup(void);
256 extern BOOL UniInit(void);
257 extern void UniCleanup(void);
258 extern void UniEffect(UWORD,UWORD);
259 #define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x)
260 #define UniNote(x) UniEffect(UNI_NOTE,x)
261 extern void UniPTEffect(UBYTE,UBYTE);
262 extern void UniVolEffect(UWORD,UBYTE);
264 /*========== Module Commands */
269 /* Instrument change */
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 */
328 /* UltraTracker effects */
329 UNI_ULTEFFECT9, /* Sample fine offset */
330 /* OctaMED effects */
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 */
341 extern const UWORD unioperands[UNI_LAST];
343 /* IT / S3M Extended SS effects: */
361 /* IT Volume column effects */
372 /* IT resonant filter information */
374 #define UF_MAXMACRO 0x10
375 #define UF_MAXFILTER 0x100
377 #define FILT_CUT 0x80
378 #define FILT_RESONANT 0x81
380 typedef struct FILTER {
384 /*========== Instruments */
386 /* Instrument format flags */
388 #define IF_PITCHPAN 2
390 /* Envelope flags: */
396 /* New Note Action Flags */
398 #define NNA_CONTINUE 1
416 #define KEY_KILL (KEY_OFF|KEY_FADE)
418 #define KICK_ABSENT 0
420 #define KICK_KEYOFF 2
423 #define AV_IT 1 /* IT vs. XM vibrato info */
425 /*========== Playing */
427 #define POS_NONE (-2) /* no loop position defined */
429 #define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */
431 typedef struct ENVPR {
432 UBYTE flg; /* envelope flag */
433 UBYTE pts; /* number of envelope points */
434 UBYTE susbeg; /* envelope sustain index begin */
435 UBYTE susend; /* envelope sustain index end */
436 UBYTE beg; /* envelope loop begin */
437 UBYTE end; /* envelope loop end */
438 SWORD p; /* current envelope counter */
439 UWORD a; /* envelope index a */
440 UWORD b; /* envelope index b */
441 ENVPT* env; /* envelope points */
444 typedef struct MP_CHANNEL {
447 UBYTE sample; /* which sample number */
448 UBYTE note; /* the audible note as heard, direct rep of period */
449 SWORD outvolume; /* output volume (vol + sampcol + instvol) */
450 SBYTE chanvol; /* channel's "global" volume */
451 UWORD fadevol; /* fading volume rate */
452 SWORD panning; /* panning position */
453 UBYTE kick; /* if true = sample has to be restarted */
454 UBYTE kick_flag; /* kick has been true */
455 UWORD period; /* period to play the sample at */
456 UBYTE nna; /* New note action type + master/slave flags */
458 UBYTE volflg; /* volume envelope settings */
459 UBYTE panflg; /* panning envelope settings */
460 UBYTE pitflg; /* pitch envelope settings */
462 UBYTE keyoff; /* if true = fade out and stuff */
463 SWORD handle; /* which sample-handle */
464 UBYTE notedelay; /* (used for note delay) */
465 SLONG start; /* The starting byte index in the sample */
468 typedef struct MP_CONTROL {
469 struct MP_CHANNEL main;
471 struct MP_VOICE* slave; /* Audio Slave of current effects control channel */
473 UBYTE slavechn; /* Audio Slave of current effects control channel */
474 UBYTE muted; /* if set, channel not played */
475 UWORD ultoffset; /* fine sample offset memory */
476 UBYTE anote; /* the note that indexes the audible */
480 UBYTE dca; /* duplicate check action */
481 UBYTE dct; /* duplicate check type */
482 UBYTE* row; /* row currently playing on this channel */
483 SBYTE retrig; /* retrig value (0 means don't retrig) */
484 ULONG speed; /* what finetune to use */
485 SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */
487 SWORD tmpvolume; /* tmp volume */
488 UWORD tmpperiod; /* tmp period */
489 UWORD wantedperiod;/* period to slide to (with effect 3 or 5) */
491 UBYTE arpmem; /* arpeggio command memory */
492 UBYTE pansspd; /* panslide speed */
494 UWORD portspeed; /* noteslide speed (toneportamento) */
496 UBYTE s3mtremor; /* s3m tremor (effect I) counter */
497 UBYTE s3mtronof; /* s3m tremor ontime/offtime */
498 UBYTE s3mvolslide;/* last used volslide */
500 UBYTE s3mrtgspeed;/* last used retrig speed */
501 UBYTE s3mrtgslide;/* last used retrig slide */
503 UBYTE glissando; /* glissando (0 means off) */
506 SBYTE vibpos; /* current vibrato position */
507 UBYTE vibspd; /* "" speed */
508 UBYTE vibdepth; /* "" depth */
510 SBYTE trmpos; /* current tremolo position */
511 UBYTE trmspd; /* "" speed */
512 UBYTE trmdepth; /* "" depth */
516 UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */
517 UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */
518 UBYTE ffportupspd;/* fx X1 (extra fine portamento up) data */
519 UBYTE ffportdnspd;/* fx X2 (extra fine portamento dn) data */
521 ULONG hioffset; /* last used high order of sample offset */
522 UWORD soffset; /* last used low order of sample-offset (effect 9) */
524 UBYTE sseffect; /* last used Sxx effect */
525 UBYTE ssdata; /* last used Sxx data info */
526 UBYTE chanvolslide;/* last used channel volume slide */
528 UBYTE panbwave; /* current panbrello waveform */
529 UBYTE panbpos; /* current panbrello position */
530 SBYTE panbspd; /* "" speed */
531 UBYTE panbdepth; /* "" depth */
533 UWORD newsamp; /* set to 1 upon a sample / inst change */
534 UBYTE voleffect; /* Volume Column Effect Memory as used by IT */
535 UBYTE voldata; /* Volume Column Data Memory */
537 SWORD pat_reppos; /* patternloop position */
538 UWORD pat_repcnt; /* times to loop */
541 /* Used by NNA only player (audio control. AUDTMP is used for full effects
543 typedef struct MP_VOICE {
544 struct MP_CHANNEL main;
550 UWORD avibpos; /* autovibrato pos */
551 UWORD aswppos; /* autovibrato sweep pos */
553 ULONG totalvol; /* total volume of channel (before global mixings) */
559 MP_CONTROL* master; /* index of "master" effects channel */
562 /*========== Loaders */
564 typedef struct MLOADER {
565 struct MLOADER* next;
571 void (*Cleanup)(void);
572 CHAR* (*LoadTitle)(void);
575 /* internal loader variables */
576 extern MREADER* modreader;
577 extern MODULE of; /* static unimod loading space */
578 extern const UWORD finetune[16];
579 extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */
581 extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
582 extern UBYTE* poslookup; /* lookup table for pattern jumps after
583 blank pattern removal */
584 extern UWORD poslookupcnt;
585 extern UWORD* origpositions;
587 extern BOOL filters; /* resonant filters in use */
588 extern UBYTE activemacro; /* active midi macro number for Sxx */
589 extern UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */
590 extern FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
592 extern int* noteindex;
594 /*========== Internal loader interface */
596 extern BOOL ReadComment(UWORD);
597 extern BOOL ReadLinedComment(UWORD,UWORD);
598 extern BOOL AllocPositions(int);
599 extern BOOL AllocPatterns(void);
600 extern BOOL AllocTracks(void);
601 extern BOOL AllocInstruments(void);
602 extern BOOL AllocSamples(void);
603 extern CHAR* DupStr(const CHAR*, UWORD, BOOL);
605 /* loader utility functions */
606 extern int* AllocLinear(void);
607 extern void FreeLinear(void);
608 extern int speed_to_finetune(ULONG,int);
609 extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
610 extern void S3MIT_CreateOrders(BOOL);
612 /* flags for S3MIT_ProcessCmd */
613 #define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */
614 #define S3MIT_IT 2 /* behave as impulse tracker */
615 #define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */
617 /* used to convert c4spd to linear XM periods (IT and IMF loaders). */
618 extern UWORD getlinearperiod(UWORD,ULONG);
619 extern ULONG getfrequency(UWORD,ULONG);
621 /* loader shared data */
622 #define STM_NTRACKERS 3
623 extern const CHAR *STM_Signatures[STM_NTRACKERS];
625 /*========== Player interface */
627 extern int Player_Init(MODULE*);
628 extern void Player_Exit(MODULE*);
629 extern void Player_HandleTick(void);
631 /*========== UnPackers */
633 typedef BOOL (*MUNPACKER) (struct MREADER*,
634 void** /* unpacked data out */ ,
635 long* /* unpacked data size */ );
636 extern BOOL PP20_Unpack(MREADER*, void**, long*);
637 extern BOOL MMCMP_Unpack(MREADER*, void**, long*);
638 extern BOOL XPK_Unpack(MREADER*, void**, long*);
639 extern BOOL S404_Unpack(MREADER*, void**, long*);
641 /*========== Drivers */
643 /* max. number of handles a driver has to provide. (not strict) */
644 #define MAXSAMPLEHANDLES 384
646 /* These variables can be changed at ANY time and results will be immediate */
647 extern UWORD md_bpm; /* current song / hardware BPM rate */
649 /* Variables below can be changed via MD_SetNumVoices at any time. However, a
650 call to MD_SetNumVoicess while the driver is active will cause the sound to
652 extern UBYTE md_numchn; /* number of song + sound effects voices */
653 extern UBYTE md_sngchn; /* number of song voices */
654 extern UBYTE md_sfxchn; /* number of sound effects voices */
655 extern UBYTE md_hardchn; /* number of hardware mixed voices */
656 extern UBYTE md_softchn; /* number of software mixed voices */
658 /* This is for use by the hardware drivers only. It points to the registered
659 tickhandler function. */
660 extern void (*md_player)(void);
662 extern SWORD MD_SampleLoad(SAMPLOAD*,int);
663 extern void MD_SampleUnload(SWORD);
664 extern ULONG MD_SampleSpace(int);
665 extern ULONG MD_SampleLength(int,SAMPLE*);
667 /* uLaw conversion */
668 extern void unsignedtoulaw(char *,int);
670 /* Parameter extraction helper */
671 extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, BOOL);
673 /* Internal software mixer stuff */
674 extern void VC_SetupPointers(void);
675 extern int VC1_Init(void);
676 extern int VC2_Init(void);
679 /* POSIX helper functions */
680 extern BOOL MD_Access(const CHAR *);
681 extern int MD_DropPrivileges(void);
684 /* Macro to define a missing driver, yet allowing binaries to dynamically link
685 with the library without missing symbol errors */
686 #define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 }
688 /*========== Prototypes for non-MT safe versions of some public functions */
690 extern void _mm_registerdriver(struct MDRIVER*);
691 extern void _mm_registerloader(struct MLOADER*);
692 extern BOOL MikMod_Active_internal(void);
693 extern void MikMod_DisableOutput_internal(void);
694 extern int MikMod_EnableOutput_internal(void);
695 extern void MikMod_Exit_internal(void);
696 extern int MikMod_SetNumVoices_internal(int,int);
697 extern void Player_Exit_internal(MODULE*);
698 extern void Player_Stop_internal(void);
699 extern BOOL Player_Paused_internal(void);
700 extern void Sample_Free_internal(SAMPLE*);
701 extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG);
702 extern void Voice_SetFrequency_internal(SBYTE,ULONG);
703 extern void Voice_SetPanning_internal(SBYTE,ULONG);
704 extern void Voice_SetVolume_internal(SBYTE,UWORD);
705 extern void Voice_Stop_internal(SBYTE);
706 extern BOOL Voice_Stopped_internal(SBYTE);
708 extern int VC1_PlayStart(void);
709 extern int VC2_PlayStart(void);
710 extern void VC1_PlayStop(void);
711 extern void VC2_PlayStop(void);
712 extern int VC1_SetNumVoices(void);
713 extern int VC2_SetNumVoices(void);
715 extern MikMod_callback_t vc_callback;
721 /*========== SIMD mixing routines */
724 #if defined(MIKMOD_SIMD)
726 #if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3))
729 #elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */
732 #elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64))
733 /* FIXME: emmintrin.h requires VC6 processor pack or VC2003+ */
735 /* avoid some warnings */
736 #pragma warning(disable:4761)
737 #pragma warning(disable:4391)
738 #pragma warning(disable:4244)
740 #endif /* AltiVec/SSE2 */
741 #endif /* MIKMOD_SIMD */
743 /*========== SIMD mixing helper functions =============*/
746 # if defined(_MSC_VER)
747 # define IS_ALIGNED_16(ptr) (!((__int64)(ptr) & 15i64))
748 # else /* GCC, LCC, .. */
749 # define IS_ALIGNED_16(ptr) (!((long long)(ptr) & 15LL))
751 #else /* long cast should be OK for all else */
752 #define IS_ALIGNED_16(ptr) (!((long)(ptr) & 15L))
755 /* Altivec helper function */
756 #if defined HAVE_ALTIVEC
758 #define simd_m128i vector signed int
759 #define simd_m128 vector float
762 #include <ppc_intrinsics.h>
765 /* Helper functions */
767 /* Set single float across the four values */
768 static inline vector float vec_mul(const vector float a, const vector float b) {
769 return vec_madd(a, b, (const vector float)(0.f));
772 /* Set single float across the four values */
773 static inline vector float vec_load_ps1(const float *pF) {
774 vector float data = vec_lde(0, pF);
775 return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0);
778 /* Set vector to 0 */
779 static inline vector float vec_setzero() {
780 return (vector float) (0.);
783 static inline vector signed char vec_set1_8(unsigned char splatchar) {
784 vector unsigned char splatmap = vec_lvsl(0, &splatchar);
785 vector unsigned char result = vec_lde(0, &splatchar);
786 splatmap = vec_splat(splatmap, 0);
787 return (vector signed char)vec_perm(result, result, splatmap);
790 #define PERM_A0 0x00,0x01,0x02,0x03
791 #define PERM_A1 0x04,0x05,0x06,0x07
792 #define PERM_A2 0x08,0x09,0x0A,0x0B
793 #define PERM_A3 0x0C,0x0D,0x0E,0x0F
794 #define PERM_B0 0x10,0x11,0x12,0x13
795 #define PERM_B1 0x14,0x15,0x16,0x17
796 #define PERM_B2 0x18,0x19,0x1A,0x1B
797 #define PERM_B3 0x1C,0x1D,0x1E,0x1F
799 /* Equivalent to _mm_unpacklo_epi32 */
800 static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) {
801 return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1));
804 /* Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). */
805 static inline vector signed int vec_hiqq(vector signed int a) {
806 vector signed int b = vec_splat_s32(0);
807 return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3));
810 /* vec_sra is max +15. We have to do in two times ... */
811 #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);
812 #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));
813 #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));
814 #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16));
815 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste);
816 #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);
817 #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste);
818 #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
820 #elif defined HAVE_SSE2
822 #include <emmintrin.h>
824 /* SSE2 helper function */
826 static __inline __m128i mm_hiqq(const __m128i a) {
827 return _mm_srli_si128(a, 8); /* get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). */
830 /* 128-bit mixing macros */
831 #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT+16-size);
832 #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);
833 #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
834 #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
835 #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
836 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
837 #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)));
838 #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1);
839 #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
840 #define simd_m128i __m128i
841 #define simd_m128 __m128
845 #if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
846 /* MikMod_amalloc() returns a 16 byte aligned zero-filled
847 memory in SIMD-enabled builds.
848 - the returned memory can be freed with MikMod_afree()
849 - the returned memory CAN NOT be realloc()'ed safely. */
853 void* MikMod_amalloc(size_t);
854 void MikMod_afree(void *); /* frees if ptr != NULL */
860 #define MikMod_amalloc MikMod_malloc
861 #define MikMod_afree MikMod_free
864 #endif /* _MIKMOD_INTERNALS_H */