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 $Id: mikmod_internals.h,v 1.7 2010/01/12 03:30:31 realtech Exp $
25 MikMod sound library internal definitions
27 ==============================================================================*/
29 #ifndef _MIKMOD_INTERNALS_H
30 #define _MIKMOD_INTERNALS_H
38 #if defined(__OS2__)||defined(__EMX__)||defined(WIN32)
39 #define strcasecmp(s,t) stricmp(s,t)
45 /*========== More type definitions */
47 /* SLONGLONG: 64bit, signed */
48 #if defined (__arch64__) || defined(__alpha) || defined (__x64_64) || defined (_LP64) || defined (__powerpc64__)
49 typedef long SLONGLONG
;
50 #define NATIVE_64BIT_INT
52 #elif defined(__WATCOMC__)
53 typedef __int64 SLONGLONG
;
54 #elif defined(WIN32) && !defined(__MWERKS__)
55 typedef LONGLONG SLONGLONG
;
56 #elif macintosh && !TYPE_LONGLONG
58 typedef SInt64 SLONGLONG
;
61 typedef long long SLONGLONG
;
64 /*========== Error handling */
66 #define _mm_errno MikMod_errno
67 #define _mm_critical MikMod_critical
68 extern MikMod_handler_t _mm_errorhandler
;
70 /*========== MT stuff */
74 #define DECLARE_MUTEX(name) \
75 extern pthread_mutex_t _mm_mutex_##name
76 #define MUTEX_LOCK(name) \
77 pthread_mutex_lock(&_mm_mutex_##name)
78 #define MUTEX_UNLOCK(name) \
79 pthread_mutex_unlock(&_mm_mutex_##name)
80 #elif defined(__OS2__)||defined(__EMX__)
81 #define DECLARE_MUTEX(name) \
82 extern HMTX _mm_mutex_##name
83 #define MUTEX_LOCK(name) \
84 if(_mm_mutex_##name) \
85 DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT)
86 #define MUTEX_UNLOCK(name) \
87 if(_mm_mutex_##name) \
88 DosReleaseMutexSem(_mm_mutex_##name)
91 #define DECLARE_MUTEX(name) \
92 extern HANDLE _mm_mutex_##name
93 #define MUTEX_LOCK(name) \
94 if(_mm_mutex_##name) \
95 WaitForSingleObject(_mm_mutex_##name,INFINITE)
96 #define MUTEX_UNLOCK(name) \
97 if(_mm_mutex_##name) \
98 ReleaseMutex(_mm_mutex_##name)
100 #define DECLARE_MUTEX(name) \
101 extern void *_mm_mutex_##name
102 #define MUTEX_LOCK(name)
103 #define MUTEX_UNLOCK(name)
106 DECLARE_MUTEX(lists
);
109 /*========== Portable file I/O */
111 extern MREADER
* _mm_new_mem_reader(const void *buffer
, int len
);
112 extern void _mm_delete_mem_reader(MREADER
*reader
);
114 extern MREADER
* _mm_new_file_reader(int fp
);
115 extern void _mm_delete_file_reader(MREADER
*);
117 extern MWRITER
* _mm_new_file_writer(int fp
);
118 extern void _mm_delete_file_writer(MWRITER
*);
120 extern int _mm_FileExists(CHAR
*fname
);
122 #define _mm_write_SBYTE(x,y) y->Put(y,(int)x)
123 #define _mm_write_UBYTE(x,y) y->Put(y,(int)x)
125 #define _mm_read_SBYTE(x) (SBYTE)x->Get(x)
126 #define _mm_read_UBYTE(x) (UBYTE)x->Get(x)
128 #define _mm_write_SBYTES(x,y,z) z->Write(z,(void *)x,y)
129 #define _mm_write_UBYTES(x,y,z) z->Write(z,(void *)x,y)
130 #define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y)
131 #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y)
133 #define _mm_fseek(x,y,z) x->Seek(x,y,z)
134 #define _mm_ftell(x) x->Tell(x)
135 #define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET)
137 #define _mm_eof(x) x->Eof(x)
139 extern void _mm_iobase_setcur(MREADER
*);
140 extern void _mm_iobase_revert(MREADER
*);
141 extern int _mm_fopen(CHAR
*,CHAR
*);
142 extern int _mm_fclose(int);
143 extern void _mm_write_string(CHAR
*,MWRITER
*);
144 extern int _mm_read_string (CHAR
*,int,MREADER
*);
146 extern SWORD
_mm_read_M_SWORD(MREADER
*);
147 extern SWORD
_mm_read_I_SWORD(MREADER
*);
148 extern UWORD
_mm_read_M_UWORD(MREADER
*);
149 extern UWORD
_mm_read_I_UWORD(MREADER
*);
151 extern SLONG
_mm_read_M_SLONG(MREADER
*);
152 extern SLONG
_mm_read_I_SLONG(MREADER
*);
153 extern ULONG
_mm_read_M_ULONG(MREADER
*);
154 extern ULONG
_mm_read_I_ULONG(MREADER
*);
156 extern int _mm_read_M_SWORDS(SWORD
*,int,MREADER
*);
157 extern int _mm_read_I_SWORDS(SWORD
*,int,MREADER
*);
158 extern int _mm_read_M_UWORDS(UWORD
*,int,MREADER
*);
159 extern int _mm_read_I_UWORDS(UWORD
*,int,MREADER
*);
161 extern int _mm_read_M_SLONGS(SLONG
*,int,MREADER
*);
162 extern int _mm_read_I_SLONGS(SLONG
*,int,MREADER
*);
163 extern int _mm_read_M_ULONGS(ULONG
*,int,MREADER
*);
164 extern int _mm_read_I_ULONGS(ULONG
*,int,MREADER
*);
166 extern void _mm_write_M_SWORD(SWORD
,MWRITER
*);
167 extern void _mm_write_I_SWORD(SWORD
,MWRITER
*);
168 extern void _mm_write_M_UWORD(UWORD
,MWRITER
*);
169 extern void _mm_write_I_UWORD(UWORD
,MWRITER
*);
171 extern void _mm_write_M_SLONG(SLONG
,MWRITER
*);
172 extern void _mm_write_I_SLONG(SLONG
,MWRITER
*);
173 extern void _mm_write_M_ULONG(ULONG
,MWRITER
*);
174 extern void _mm_write_I_ULONG(ULONG
,MWRITER
*);
176 extern void _mm_write_M_SWORDS(SWORD
*,int,MWRITER
*);
177 extern void _mm_write_I_SWORDS(SWORD
*,int,MWRITER
*);
178 extern void _mm_write_M_UWORDS(UWORD
*,int,MWRITER
*);
179 extern void _mm_write_I_UWORDS(UWORD
*,int,MWRITER
*);
181 extern void _mm_write_M_SLONGS(SLONG
*,int,MWRITER
*);
182 extern void _mm_write_I_SLONGS(SLONG
*,int,MWRITER
*);
183 extern void _mm_write_M_ULONGS(ULONG
*,int,MWRITER
*);
184 extern void _mm_write_I_ULONGS(ULONG
*,int,MWRITER
*);
186 /*========== Samples */
188 /* This is a handle of sorts attached to any sample registered with
189 SL_RegisterSample. Generally, this only need be used or changed by the
190 loaders and drivers of mikmod. */
191 typedef struct SAMPLOAD
{
192 struct SAMPLOAD
*next
;
194 ULONG length
; /* length of sample (in samples!) */
195 ULONG loopstart
; /* repeat position (relative to start, in samples) */
196 ULONG loopend
; /* repeat end */
203 /*========== Sample and waves loading interface */
205 extern void SL_HalveSample(SAMPLOAD
*,int);
206 extern void SL_Sample8to16(SAMPLOAD
*);
207 extern void SL_Sample16to8(SAMPLOAD
*);
208 extern void SL_SampleSigned(SAMPLOAD
*);
209 extern void SL_SampleUnsigned(SAMPLOAD
*);
210 extern int SL_LoadSamples(void);
211 extern SAMPLOAD
* SL_RegisterSample(SAMPLE
*,int,MREADER
*);
212 extern int SL_Load(void*,SAMPLOAD
*,ULONG
);
213 extern int SL_Init(SAMPLOAD
*);
214 extern void SL_Exit(SAMPLOAD
*);
216 /*========== Internal module representation (UniMod) interface */
218 /* number of notes in an octave */
221 extern void UniSetRow(UBYTE
*);
222 extern UBYTE
UniGetByte(void);
223 extern UWORD
UniGetWord(void);
224 extern UBYTE
* UniFindRow(UBYTE
*,UWORD
);
225 extern void UniSkipOpcode(void);
226 extern void UniReset(void);
227 extern void UniWriteByte(UBYTE
);
228 extern void UniWriteWord(UWORD
);
229 extern void UniNewline(void);
230 extern UBYTE
* UniDup(void);
231 extern int UniInit(void);
232 extern void UniCleanup(void);
233 extern void UniEffect(UWORD
,UWORD
);
234 #define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x)
235 #define UniNote(x) UniEffect(UNI_NOTE,x)
236 extern void UniPTEffect(UBYTE
,UBYTE
);
237 extern void UniVolEffect(UWORD
,UBYTE
);
239 /*========== Module Commands */
244 /* Instrument change */
246 /* Protracker effects */
247 UNI_PTEFFECT0
, /* arpeggio */
248 UNI_PTEFFECT1
, /* porta up */
249 UNI_PTEFFECT2
, /* porta down */
250 UNI_PTEFFECT3
, /* porta to note */
251 UNI_PTEFFECT4
, /* vibrato */
252 UNI_PTEFFECT5
, /* dual effect 3+A */
253 UNI_PTEFFECT6
, /* dual effect 4+A */
254 UNI_PTEFFECT7
, /* tremolo */
255 UNI_PTEFFECT8
, /* pan */
256 UNI_PTEFFECT9
, /* sample offset */
257 UNI_PTEFFECTA
, /* volume slide */
258 UNI_PTEFFECTB
, /* pattern jump */
259 UNI_PTEFFECTC
, /* set volume */
260 UNI_PTEFFECTD
, /* pattern break */
261 UNI_PTEFFECTE
, /* extended effects */
262 UNI_PTEFFECTF
, /* set speed */
263 /* Scream Tracker effects */
264 UNI_S3MEFFECTA
, /* set speed */
265 UNI_S3MEFFECTD
, /* volume slide */
266 UNI_S3MEFFECTE
, /* porta down */
267 UNI_S3MEFFECTF
, /* porta up */
268 UNI_S3MEFFECTI
, /* tremor */
269 UNI_S3MEFFECTQ
, /* retrig */
270 UNI_S3MEFFECTR
, /* tremolo */
271 UNI_S3MEFFECTT
, /* set tempo */
272 UNI_S3MEFFECTU
, /* fine vibrato */
273 UNI_KEYOFF
, /* note off */
274 /* Fast Tracker effects */
275 UNI_KEYFADE
, /* note fade */
276 UNI_VOLEFFECTS
, /* volume column effects */
277 UNI_XMEFFECT4
, /* vibrato */
278 UNI_XMEFFECT6
, /* dual effect 4+A */
279 UNI_XMEFFECTA
, /* volume slide */
280 UNI_XMEFFECTE1
, /* fine porta up */
281 UNI_XMEFFECTE2
, /* fine porta down */
282 UNI_XMEFFECTEA
, /* fine volume slide up */
283 UNI_XMEFFECTEB
, /* fine volume slide down */
284 UNI_XMEFFECTG
, /* set global volume */
285 UNI_XMEFFECTH
, /* global volume slide */
286 UNI_XMEFFECTL
, /* set envelope position */
287 UNI_XMEFFECTP
, /* pan slide */
288 UNI_XMEFFECTX1
, /* extra fine porta up */
289 UNI_XMEFFECTX2
, /* extra fine porta down */
290 /* Impulse Tracker effects */
291 UNI_ITEFFECTG
, /* porta to note */
292 UNI_ITEFFECTH
, /* vibrato */
293 UNI_ITEFFECTI
, /* tremor (xy not incremented) */
294 UNI_ITEFFECTM
, /* set channel volume */
295 UNI_ITEFFECTN
, /* slide / fineslide channel volume */
296 UNI_ITEFFECTP
, /* slide / fineslide channel panning */
297 UNI_ITEFFECTT
, /* slide tempo */
298 UNI_ITEFFECTU
, /* fine vibrato */
299 UNI_ITEFFECTW
, /* slide / fineslide global volume */
300 UNI_ITEFFECTY
, /* panbrello */
301 UNI_ITEFFECTZ
, /* resonant filters */
303 /* UltraTracker effects */
304 UNI_ULTEFFECT9
, /* Sample fine offset */
305 /* OctaMED effects */
307 UNI_MEDEFFECTF1
, /* play note twice */
308 UNI_MEDEFFECTF2
, /* delay note */
309 UNI_MEDEFFECTF3
, /* play note three times */
310 /* Oktalyzer effects */
311 UNI_OKTARP
, /* arpeggio */
316 extern UWORD unioperands
[UNI_LAST
];
318 /* IT / S3M Extended SS effects: */
336 /* IT Volume column effects */
347 /* IT resonant filter information */
349 #define UF_MAXMACRO 0x10
350 #define UF_MAXFILTER 0x100
352 #define FILT_CUT 0x80
353 #define FILT_RESONANT 0x81
355 typedef struct FILTER
{
359 /*========== Instruments */
361 /* Instrument format flags */
363 #define IF_PITCHPAN 2
365 /* Envelope flags: */
371 /* New Note Action Flags */
373 #define NNA_CONTINUE 1
391 #define KEY_KILL (KEY_OFF|KEY_FADE)
393 #define KICK_ABSENT 0
395 #define KICK_KEYOFF 2
398 #define AV_IT 1 /* IT vs. XM vibrato info */
400 /*========== Playing */
402 #define POS_NONE (-2) /* no loop position defined */
404 #define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */
406 typedef struct ENVPR
{
407 UBYTE flg
; /* envelope flag */
408 UBYTE pts
; /* number of envelope points */
409 UBYTE susbeg
; /* envelope sustain index begin */
410 UBYTE susend
; /* envelope sustain index end */
411 UBYTE beg
; /* envelope loop begin */
412 UBYTE end
; /* envelope loop end */
413 SWORD p
; /* current envelope counter */
414 UWORD a
; /* envelope index a */
415 UWORD b
; /* envelope index b */
416 ENVPT
* env
; /* envelope points */
419 typedef struct MP_CHANNEL
{
422 UBYTE sample
; /* which sample number */
423 UBYTE note
; /* the audible note as heard, direct rep of period */
424 SWORD outvolume
; /* output volume (vol + sampcol + instvol) */
425 SBYTE chanvol
; /* channel's "global" volume */
426 UWORD fadevol
; /* fading volume rate */
427 SWORD panning
; /* panning position */
428 UBYTE kick
; /* if true = sample has to be restarted */
429 UBYTE kick_flag
; /* kick has been true */
430 UWORD period
; /* period to play the sample at */
431 UBYTE nna
; /* New note action type + master/slave flags */
433 UBYTE volflg
; /* volume envelope settings */
434 UBYTE panflg
; /* panning envelope settings */
435 UBYTE pitflg
; /* pitch envelope settings */
437 UBYTE keyoff
; /* if true = fade out and stuff */
438 SWORD handle
; /* which sample-handle */
439 UBYTE notedelay
; /* (used for note delay) */
440 SLONG start
; /* The starting byte index in the sample */
443 typedef struct MP_CONTROL
{
444 struct MP_CHANNEL main
;
446 struct MP_VOICE
*slave
; /* Audio Slave of current effects control channel */
448 UBYTE slavechn
; /* Audio Slave of current effects control channel */
449 UBYTE muted
; /* if set, channel not played */
450 UWORD ultoffset
; /* fine sample offset memory */
451 UBYTE anote
; /* the note that indexes the audible */
455 UBYTE dca
; /* duplicate check action */
456 UBYTE dct
; /* duplicate check type */
457 UBYTE
* row
; /* row currently playing on this channel */
458 SBYTE retrig
; /* retrig value (0 means don't retrig) */
459 ULONG speed
; /* what finetune to use */
460 SWORD volume
; /* amiga volume (0 t/m 64) to play the sample at */
462 SWORD tmpvolume
; /* tmp volume */
463 UWORD tmpperiod
; /* tmp period */
464 UWORD wantedperiod
; /* period to slide to (with effect 3 or 5) */
466 UBYTE arpmem
; /* arpeggio command memory */
467 UBYTE pansspd
; /* panslide speed */
469 UWORD portspeed
; /* noteslide speed (toneportamento) */
471 UBYTE s3mtremor
; /* s3m tremor (effect I) counter */
472 UBYTE s3mtronof
; /* s3m tremor ontime/offtime */
473 UBYTE s3mvolslide
; /* last used volslide */
475 UBYTE s3mrtgspeed
; /* last used retrig speed */
476 UBYTE s3mrtgslide
; /* last used retrig slide */
478 UBYTE glissando
; /* glissando (0 means off) */
481 SBYTE vibpos
; /* current vibrato position */
482 UBYTE vibspd
; /* "" speed */
483 UBYTE vibdepth
; /* "" depth */
485 SBYTE trmpos
; /* current tremolo position */
486 UBYTE trmspd
; /* "" speed */
487 UBYTE trmdepth
; /* "" depth */
491 UBYTE fportupspd
; /* fx E1 (extra fine portamento up) data */
492 UBYTE fportdnspd
; /* fx E2 (extra fine portamento dn) data */
493 UBYTE ffportupspd
; /* fx X1 (extra fine portamento up) data */
494 UBYTE ffportdnspd
; /* fx X2 (extra fine portamento dn) data */
496 ULONG hioffset
; /* last used high order of sample offset */
497 UWORD soffset
; /* last used low order of sample-offset (effect 9) */
499 UBYTE sseffect
; /* last used Sxx effect */
500 UBYTE ssdata
; /* last used Sxx data info */
501 UBYTE chanvolslide
; /* last used channel volume slide */
503 UBYTE panbwave
; /* current panbrello waveform */
504 UBYTE panbpos
; /* current panbrello position */
505 SBYTE panbspd
; /* "" speed */
506 UBYTE panbdepth
; /* "" depth */
508 UWORD newsamp
; /* set to 1 upon a sample / inst change */
509 UBYTE voleffect
; /* Volume Column Effect Memory as used by IT */
510 UBYTE voldata
; /* Volume Column Data Memory */
512 SWORD pat_reppos
; /* patternloop position */
513 UWORD pat_repcnt
; /* times to loop */
516 /* Used by NNA only player (audio control. AUDTMP is used for full effects
518 typedef struct MP_VOICE
{
519 struct MP_CHANNEL main
;
525 UWORD avibpos
; /* autovibrato pos */
526 UWORD aswppos
; /* autovibrato sweep pos */
528 ULONG totalvol
; /* total volume of channel (before global mixings) */
534 MP_CONTROL
* master
; /* index of "master" effects channel */
537 /*========== Loaders */
539 typedef struct MLOADER
{
540 struct MLOADER
* next
;
546 void (*Cleanup
)(void);
547 CHAR
* (*LoadTitle
)(void);
550 /* internal loader variables */
551 extern MREADER
* modreader
;
552 extern UWORD finetune
[16];
553 extern MODULE of
; /* static unimod loading space */
554 extern UWORD npertab
[7*OCTAVE
]; /* used by the original MOD loaders */
556 extern SBYTE remap
[UF_MAXCHAN
]; /* for removing empty channels */
557 extern UBYTE
* poslookup
; /* lookup table for pattern jumps after
558 blank pattern removal */
559 extern UWORD poslookupcnt
;
560 extern UWORD
* origpositions
;
562 extern int filters
; /* resonant filters in use */
563 extern UBYTE activemacro
; /* active midi macro number for Sxx */
564 extern UBYTE filtermacros
[UF_MAXMACRO
]; /* midi macro settings */
565 extern FILTER filtersettings
[UF_MAXFILTER
]; /* computed filter settings */
567 extern int* noteindex
;
569 /*========== Internal loader interface */
571 extern int ReadComment(UWORD
);
572 extern int ReadLinedComment(UWORD
,UWORD
);
573 extern int AllocPositions(int);
574 extern int AllocPatterns(void);
575 extern int AllocTracks(void);
576 extern int AllocInstruments(void);
577 extern int AllocSamples(void);
578 extern CHAR
* DupStr(CHAR
*,UWORD
,int);
579 extern CHAR
* StrDup(CHAR
*s
);
581 /* loader utility functions */
582 extern int* AllocLinear(void);
583 extern void FreeLinear(void);
584 extern int speed_to_finetune(ULONG
,int);
585 extern void S3MIT_ProcessCmd(UBYTE
,UBYTE
,unsigned int);
586 extern void S3MIT_CreateOrders(int);
588 /* flags for S3MIT_ProcessCmd */
589 #define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */
590 #define S3MIT_IT 2 /* behave as impulse tracker */
591 #define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */
593 /* used to convert c4spd to linear XM periods (IT and IMF loaders). */
594 extern UWORD
getlinearperiod(UWORD
,ULONG
);
595 extern ULONG
getfrequency(UWORD
,ULONG
);
597 /* loader shared data */
598 #define STM_NTRACKERS 3
599 extern CHAR
*STM_Signatures
[STM_NTRACKERS
];
601 /*========== Player interface */
603 extern int Player_Init(MODULE
*);
604 extern void Player_Exit(MODULE
*);
605 extern void Player_HandleTick(void);
607 /*========== Drivers */
609 /* max. number of handles a driver has to provide. (not strict) */
610 #define MAXSAMPLEHANDLES 384
612 /* These variables can be changed at ANY time and results will be immediate */
613 extern UWORD md_bpm
; /* current song / hardware BPM rate */
615 /* Variables below can be changed via MD_SetNumVoices at any time. However, a
616 call to MD_SetNumVoicess while the driver is active will cause the sound to
618 extern UBYTE md_numchn
; /* number of song + sound effects voices */
619 extern UBYTE md_sngchn
; /* number of song voices */
620 extern UBYTE md_sfxchn
; /* number of sound effects voices */
621 extern UBYTE md_hardchn
; /* number of hardware mixed voices */
622 extern UBYTE md_softchn
; /* number of software mixed voices */
624 /* This is for use by the hardware drivers only. It points to the registered
625 tickhandler function. */
626 extern void (*md_player
)(void);
628 extern SWORD
MD_SampleLoad(SAMPLOAD
*,int);
629 extern void MD_SampleUnload(SWORD
);
630 extern ULONG
MD_SampleSpace(int);
631 extern ULONG
MD_SampleLength(int,SAMPLE
*);
633 /* uLaw conversion */
634 extern void unsignedtoulaw(char *,int);
636 /* Parameter extraction helper */
637 extern CHAR
*MD_GetAtom(CHAR
*,CHAR
*,int);
639 /* Internal software mixer stuff */
640 extern void VC_SetupPointers(void);
641 extern int VC1_Init(void);
642 extern int VC2_Init(void);
644 #if defined(unix) || defined(__APPLE__) && defined(__MACH__)
645 /* POSIX helper functions */
646 extern int MD_Access(CHAR
*);
647 extern int MD_DropPrivileges(void);
650 /* Macro to define a missing driver, yet allowing binaries to dynamically link
651 with the library without missing symbol errors */
652 #define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 }
654 /*========== Prototypes for non-MT safe versions of some public functions */
656 extern void _mm_registerdriver(struct MDRIVER
*);
657 extern void _mm_registerloader(struct MLOADER
*);
658 extern int MikMod_Active_internal(void);
659 extern void MikMod_DisableOutput_internal(void);
660 extern int MikMod_EnableOutput_internal(void);
661 extern void MikMod_Exit_internal(void);
662 extern int MikMod_SetNumVoices_internal(int,int);
663 extern void Player_Exit_internal(MODULE
*);
664 extern void Player_Stop_internal(void);
665 extern int Player_Paused_internal(void);
666 extern void Sample_Free_internal(SAMPLE
*);
667 extern void Voice_Play_internal(SBYTE
,SAMPLE
*,ULONG
);
668 extern void Voice_SetFrequency_internal(SBYTE
,ULONG
);
669 extern void Voice_SetPanning_internal(SBYTE
,ULONG
);
670 extern void Voice_SetVolume_internal(SBYTE
,UWORD
);
671 extern void Voice_Stop_internal(SBYTE
);
672 extern int Voice_Stopped_internal(SBYTE
);
678 /*========== SIMD mixing routines */
682 #if defined(__APPLE__) && !defined (__i386__)
684 #if defined __VEC__ && !(defined(__GNUC__) && (__GNUC__ < 3))
688 #elif defined WIN32 || defined __WIN64 || (defined __APPLE__ && defined (__i386__) && defined __VEC__)
690 // FIXME: emmintrin.h requires VC6 processor pack or VC2003+
693 /* Fixes couples warnings */
695 #pragma warning(disable:4761)
696 #pragma warning(disable:4391)
697 #pragma warning(disable:4244)
700 // TODO: Test for GCC Linux
702 /*========== SIMD mixing helper functions =============*/
704 #define IS_ALIGNED_16(ptr) (!(((int)(ptr)) & 15))
706 /* Altivec helper function */
707 #if defined HAVE_ALTIVEC
709 #define simd_m128i vector signed int
710 #define simd_m128 vector float
713 #include <ppc_intrinsics.h>
718 // Set single float across the four values
719 static inline vector
float vec_mul( const vector
float a
, const vector
float b
)
721 return vec_madd(a
, b
, (const vector
float)(0.f
));
724 // Set single float across the four values
725 static inline vector
float vec_load_ps1(const float *pF
)
727 vector
float data
= vec_lde(0, pF
);
728 return vec_splat(vec_perm(data
, data
, vec_lvsl(0, pF
)), 0);
732 static inline const vector
float vec_setzero()
734 return (const vector
float) (0.);
737 static inline vector
signed char vec_set1_8(unsigned char splatchar
)
739 vector
unsigned char splatmap
= vec_lvsl(0, &splatchar
);
740 vector
unsigned char result
= vec_lde(0, &splatchar
);
741 splatmap
= vec_splat(splatmap
, 0);
742 return (vector
signed char)vec_perm(result
, result
, splatmap
);
745 #define PERM_A0 0x00,0x01,0x02,0x03
746 #define PERM_A1 0x04,0x05,0x06,0x07
747 #define PERM_A2 0x08,0x09,0x0A,0x0B
748 #define PERM_A3 0x0C,0x0D,0x0E,0x0F
749 #define PERM_B0 0x10,0x11,0x12,0x13
750 #define PERM_B1 0x14,0x15,0x16,0x17
751 #define PERM_B2 0x18,0x19,0x1A,0x1B
752 #define PERM_B3 0x1C,0x1D,0x1E,0x1F
754 // Equivalent to _mm_unpacklo_epi32
755 static inline vector
signed int vec_unpacklo(vector
signed int a
, vector
signed int b
)
757 return vec_perm(a
, b
, (vector
unsigned char)(PERM_A0
,PERM_A1
,PERM_B0
,PERM_B1
));
760 // Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part).
761 static inline vector
signed int vec_hiqq(vector
signed int a
)
763 vector
signed int b
= vec_splat_s32(0);
764 return vec_perm(a
, b
, (vector
unsigned char)(PERM_A2
,PERM_A3
,PERM_B2
,PERM_B3
));
767 // vec_sra is max +15. We have to do in two times ...
768 #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul);
769 #define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0));
770 #define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8));
771 #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT+16-16));
772 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste);
773 #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);
774 #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste);
775 #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
777 #elif defined HAVE_SSE2
779 /* SSE2 helper function */
781 #include <emmintrin.h>
783 static __inline __m128i
mm_hiqq(const __m128i a
)
785 return _mm_srli_si128(a
, 8); // get the 64bit upper part. new 64bit upper is undefined (zeroed is fine).
788 /* 128-bit mixing macros */
789 #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT+16-size);
790 #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT-size)), mul);
791 #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
792 #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
793 #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
794 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
795 #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)));
796 #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1);
797 #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
798 #define simd_m128i __m128i
799 #define simd_m128 __m128