Bump version numbers for 3.13
[maemo-rb.git] / apps / plugins / mikmod / mikmod_internals.h
blobacd514ad390b8e82ae9312245a15a3ed0ee39ab2
1 /* MikMod sound library
2 (c) 1998, 1999, 2005 Miodrag Vallat and others - see file AUTHORS for
3 complete list.
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
18 02111-1307, USA.
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
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 #include <stdarg.h>
37 #if 0
38 #if defined(__OS2__)||defined(__EMX__)||defined(WIN32)
39 #define strcasecmp(s,t) stricmp(s,t)
40 #endif
41 #endif
43 #include "mikmod.h"
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
51 #if 0
52 #elif defined(__WATCOMC__)
53 typedef __int64 SLONGLONG;
54 #elif defined(WIN32) && !defined(__MWERKS__)
55 typedef LONGLONG SLONGLONG;
56 #elif macintosh && !TYPE_LONGLONG
57 #include <Types.h>
58 typedef SInt64 SLONGLONG;
59 #endif
60 #else
61 typedef long long SLONGLONG;
62 #endif
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 */
72 #ifdef HAVE_PTHREAD
73 #include <pthread.h>
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)
89 #elif defined(WIN32)
90 #include <windows.h>
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)
99 #else
100 #define DECLARE_MUTEX(name) \
101 extern void *_mm_mutex_##name
102 #define MUTEX_LOCK(name)
103 #define MUTEX_UNLOCK(name)
104 #endif
106 DECLARE_MUTEX(lists);
107 DECLARE_MUTEX(vars);
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 #if !defined(ROCKBOX)
144 extern void _mm_write_string(CHAR*,MWRITER*);
145 #endif
146 extern int _mm_read_string (CHAR*,int,MREADER*);
148 extern SWORD _mm_read_M_SWORD(MREADER*);
149 extern SWORD _mm_read_I_SWORD(MREADER*);
150 extern UWORD _mm_read_M_UWORD(MREADER*);
151 extern UWORD _mm_read_I_UWORD(MREADER*);
153 extern SLONG _mm_read_M_SLONG(MREADER*);
154 extern SLONG _mm_read_I_SLONG(MREADER*);
155 extern ULONG _mm_read_M_ULONG(MREADER*);
156 extern ULONG _mm_read_I_ULONG(MREADER*);
158 extern int _mm_read_M_SWORDS(SWORD*,int,MREADER*);
159 extern int _mm_read_I_SWORDS(SWORD*,int,MREADER*);
160 extern int _mm_read_M_UWORDS(UWORD*,int,MREADER*);
161 extern int _mm_read_I_UWORDS(UWORD*,int,MREADER*);
163 extern int _mm_read_M_SLONGS(SLONG*,int,MREADER*);
164 extern int _mm_read_I_SLONGS(SLONG*,int,MREADER*);
165 extern int _mm_read_M_ULONGS(ULONG*,int,MREADER*);
166 extern int _mm_read_I_ULONGS(ULONG*,int,MREADER*);
168 extern void _mm_write_M_SWORD(SWORD,MWRITER*);
169 extern void _mm_write_I_SWORD(SWORD,MWRITER*);
170 extern void _mm_write_M_UWORD(UWORD,MWRITER*);
171 extern void _mm_write_I_UWORD(UWORD,MWRITER*);
173 extern void _mm_write_M_SLONG(SLONG,MWRITER*);
174 extern void _mm_write_I_SLONG(SLONG,MWRITER*);
175 extern void _mm_write_M_ULONG(ULONG,MWRITER*);
176 extern void _mm_write_I_ULONG(ULONG,MWRITER*);
178 extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*);
179 extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*);
180 extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*);
181 extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*);
183 extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*);
184 extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*);
185 extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*);
186 extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
188 /*========== Samples */
190 /* This is a handle of sorts attached to any sample registered with
191 SL_RegisterSample. Generally, this only need be used or changed by the
192 loaders and drivers of mikmod. */
193 typedef struct SAMPLOAD {
194 struct SAMPLOAD *next;
196 ULONG length; /* length of sample (in samples!) */
197 ULONG loopstart; /* repeat position (relative to start, in samples) */
198 ULONG loopend; /* repeat end */
199 UWORD infmt,outfmt;
200 int scalefactor;
201 SAMPLE* sample;
202 MREADER* reader;
203 } SAMPLOAD;
205 /*========== Sample and waves loading interface */
207 extern void SL_HalveSample(SAMPLOAD*,int);
208 extern void SL_Sample8to16(SAMPLOAD*);
209 extern void SL_Sample16to8(SAMPLOAD*);
210 extern void SL_SampleSigned(SAMPLOAD*);
211 extern void SL_SampleUnsigned(SAMPLOAD*);
212 extern int SL_LoadSamples(void);
213 extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
214 extern int SL_Load(void*,SAMPLOAD*,ULONG);
215 extern int SL_Init(SAMPLOAD*);
216 extern void SL_Exit(SAMPLOAD*);
218 /*========== Internal module representation (UniMod) interface */
220 /* number of notes in an octave */
221 #define OCTAVE 12
223 extern void UniSetRow(UBYTE*);
224 extern UBYTE UniGetByte(void);
225 extern UWORD UniGetWord(void);
226 extern UBYTE* UniFindRow(UBYTE*,UWORD);
227 extern void UniSkipOpcode(void);
228 extern void UniReset(void);
229 extern void UniWriteByte(UBYTE);
230 extern void UniWriteWord(UWORD);
231 extern void UniNewline(void);
232 extern UBYTE* UniDup(void);
233 extern int UniInit(void);
234 extern void UniCleanup(void);
235 extern void UniEffect(UWORD,UWORD);
236 #define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x)
237 #define UniNote(x) UniEffect(UNI_NOTE,x)
238 extern void UniPTEffect(UBYTE,UBYTE);
239 extern void UniVolEffect(UWORD,UBYTE);
241 /*========== Module Commands */
243 enum {
244 /* Simple note */
245 UNI_NOTE = 1,
246 /* Instrument change */
247 UNI_INSTRUMENT,
248 /* Protracker effects */
249 UNI_PTEFFECT0, /* arpeggio */
250 UNI_PTEFFECT1, /* porta up */
251 UNI_PTEFFECT2, /* porta down */
252 UNI_PTEFFECT3, /* porta to note */
253 UNI_PTEFFECT4, /* vibrato */
254 UNI_PTEFFECT5, /* dual effect 3+A */
255 UNI_PTEFFECT6, /* dual effect 4+A */
256 UNI_PTEFFECT7, /* tremolo */
257 UNI_PTEFFECT8, /* pan */
258 UNI_PTEFFECT9, /* sample offset */
259 UNI_PTEFFECTA, /* volume slide */
260 UNI_PTEFFECTB, /* pattern jump */
261 UNI_PTEFFECTC, /* set volume */
262 UNI_PTEFFECTD, /* pattern break */
263 UNI_PTEFFECTE, /* extended effects */
264 UNI_PTEFFECTF, /* set speed */
265 /* Scream Tracker effects */
266 UNI_S3MEFFECTA, /* set speed */
267 UNI_S3MEFFECTD, /* volume slide */
268 UNI_S3MEFFECTE, /* porta down */
269 UNI_S3MEFFECTF, /* porta up */
270 UNI_S3MEFFECTI, /* tremor */
271 UNI_S3MEFFECTQ, /* retrig */
272 UNI_S3MEFFECTR, /* tremolo */
273 UNI_S3MEFFECTT, /* set tempo */
274 UNI_S3MEFFECTU, /* fine vibrato */
275 UNI_KEYOFF, /* note off */
276 /* Fast Tracker effects */
277 UNI_KEYFADE, /* note fade */
278 UNI_VOLEFFECTS, /* volume column effects */
279 UNI_XMEFFECT4, /* vibrato */
280 UNI_XMEFFECT6, /* dual effect 4+A */
281 UNI_XMEFFECTA, /* volume slide */
282 UNI_XMEFFECTE1, /* fine porta up */
283 UNI_XMEFFECTE2, /* fine porta down */
284 UNI_XMEFFECTEA, /* fine volume slide up */
285 UNI_XMEFFECTEB, /* fine volume slide down */
286 UNI_XMEFFECTG, /* set global volume */
287 UNI_XMEFFECTH, /* global volume slide */
288 UNI_XMEFFECTL, /* set envelope position */
289 UNI_XMEFFECTP, /* pan slide */
290 UNI_XMEFFECTX1, /* extra fine porta up */
291 UNI_XMEFFECTX2, /* extra fine porta down */
292 /* Impulse Tracker effects */
293 UNI_ITEFFECTG, /* porta to note */
294 UNI_ITEFFECTH, /* vibrato */
295 UNI_ITEFFECTI, /* tremor (xy not incremented) */
296 UNI_ITEFFECTM, /* set channel volume */
297 UNI_ITEFFECTN, /* slide / fineslide channel volume */
298 UNI_ITEFFECTP, /* slide / fineslide channel panning */
299 UNI_ITEFFECTT, /* slide tempo */
300 UNI_ITEFFECTU, /* fine vibrato */
301 UNI_ITEFFECTW, /* slide / fineslide global volume */
302 UNI_ITEFFECTY, /* panbrello */
303 UNI_ITEFFECTZ, /* resonant filters */
304 UNI_ITEFFECTS0,
305 /* UltraTracker effects */
306 UNI_ULTEFFECT9, /* Sample fine offset */
307 /* OctaMED effects */
308 UNI_MEDSPEED,
309 UNI_MEDEFFECTF1, /* play note twice */
310 UNI_MEDEFFECTF2, /* delay note */
311 UNI_MEDEFFECTF3, /* play note three times */
312 /* Oktalyzer effects */
313 UNI_OKTARP, /* arpeggio */
315 UNI_LAST
318 extern UWORD unioperands[UNI_LAST];
320 /* IT / S3M Extended SS effects: */
321 enum {
322 SS_GLISSANDO = 1,
323 SS_FINETUNE,
324 SS_VIBWAVE,
325 SS_TREMWAVE,
326 SS_PANWAVE,
327 SS_FRAMEDELAY,
328 SS_S7EFFECTS,
329 SS_PANNING,
330 SS_SURROUND,
331 SS_HIOFFSET,
332 SS_PATLOOP,
333 SS_NOTECUT,
334 SS_NOTEDELAY,
335 SS_PATDELAY
338 /* IT Volume column effects */
339 enum {
340 VOL_VOLUME = 1,
341 VOL_PANNING,
342 VOL_VOLSLIDE,
343 VOL_PITCHSLIDEDN,
344 VOL_PITCHSLIDEUP,
345 VOL_PORTAMENTO,
346 VOL_VIBRATO
349 /* IT resonant filter information */
351 #define UF_MAXMACRO 0x10
352 #define UF_MAXFILTER 0x100
354 #define FILT_CUT 0x80
355 #define FILT_RESONANT 0x81
357 typedef struct FILTER {
358 UBYTE filter,inf;
359 } FILTER;
361 /*========== Instruments */
363 /* Instrument format flags */
364 #define IF_OWNPAN 1
365 #define IF_PITCHPAN 2
367 /* Envelope flags: */
368 #define EF_ON 1
369 #define EF_SUSTAIN 2
370 #define EF_LOOP 4
371 #define EF_VOLENV 8
373 /* New Note Action Flags */
374 #define NNA_CUT 0
375 #define NNA_CONTINUE 1
376 #define NNA_OFF 2
377 #define NNA_FADE 3
379 #define NNA_MASK 3
381 #define DCT_OFF 0
382 #define DCT_NOTE 1
383 #define DCT_SAMPLE 2
384 #define DCT_INST 3
386 #define DCA_CUT 0
387 #define DCA_OFF 1
388 #define DCA_FADE 2
390 #define KEY_KICK 0
391 #define KEY_OFF 1
392 #define KEY_FADE 2
393 #define KEY_KILL (KEY_OFF|KEY_FADE)
395 #define KICK_ABSENT 0
396 #define KICK_NOTE 1
397 #define KICK_KEYOFF 2
398 #define KICK_ENV 4
400 #define AV_IT 1 /* IT vs. XM vibrato info */
402 /*========== Playing */
404 #define POS_NONE (-2) /* no loop position defined */
406 #define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */
408 typedef struct ENVPR {
409 UBYTE flg; /* envelope flag */
410 UBYTE pts; /* number of envelope points */
411 UBYTE susbeg; /* envelope sustain index begin */
412 UBYTE susend; /* envelope sustain index end */
413 UBYTE beg; /* envelope loop begin */
414 UBYTE end; /* envelope loop end */
415 SWORD p; /* current envelope counter */
416 UWORD a; /* envelope index a */
417 UWORD b; /* envelope index b */
418 ENVPT* env; /* envelope points */
419 } ENVPR;
421 typedef struct MP_CHANNEL {
422 INSTRUMENT* i;
423 SAMPLE* s;
424 UBYTE sample; /* which sample number */
425 UBYTE note; /* the audible note as heard, direct rep of period */
426 SWORD outvolume; /* output volume (vol + sampcol + instvol) */
427 SBYTE chanvol; /* channel's "global" volume */
428 UWORD fadevol; /* fading volume rate */
429 SWORD panning; /* panning position */
430 UBYTE kick; /* if true = sample has to be restarted */
431 UBYTE kick_flag; /* kick has been true */
432 UWORD period; /* period to play the sample at */
433 UBYTE nna; /* New note action type + master/slave flags */
435 UBYTE volflg; /* volume envelope settings */
436 UBYTE panflg; /* panning envelope settings */
437 UBYTE pitflg; /* pitch envelope settings */
439 UBYTE keyoff; /* if true = fade out and stuff */
440 SWORD handle; /* which sample-handle */
441 UBYTE notedelay; /* (used for note delay) */
442 SLONG start; /* The starting byte index in the sample */
443 } MP_CHANNEL;
445 typedef struct MP_CONTROL {
446 struct MP_CHANNEL main;
448 struct MP_VOICE *slave; /* Audio Slave of current effects control channel */
450 UBYTE slavechn; /* Audio Slave of current effects control channel */
451 UBYTE muted; /* if set, channel not played */
452 UWORD ultoffset; /* fine sample offset memory */
453 UBYTE anote; /* the note that indexes the audible */
454 UBYTE oldnote;
455 SWORD ownper;
456 SWORD ownvol;
457 UBYTE dca; /* duplicate check action */
458 UBYTE dct; /* duplicate check type */
459 UBYTE* row; /* row currently playing on this channel */
460 SBYTE retrig; /* retrig value (0 means don't retrig) */
461 ULONG speed; /* what finetune to use */
462 SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */
464 SWORD tmpvolume; /* tmp volume */
465 UWORD tmpperiod; /* tmp period */
466 UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */
468 UBYTE arpmem; /* arpeggio command memory */
469 UBYTE pansspd; /* panslide speed */
470 UWORD slidespeed;
471 UWORD portspeed; /* noteslide speed (toneportamento) */
473 UBYTE s3mtremor; /* s3m tremor (effect I) counter */
474 UBYTE s3mtronof; /* s3m tremor ontime/offtime */
475 UBYTE s3mvolslide; /* last used volslide */
476 SBYTE sliding;
477 UBYTE s3mrtgspeed; /* last used retrig speed */
478 UBYTE s3mrtgslide; /* last used retrig slide */
480 UBYTE glissando; /* glissando (0 means off) */
481 UBYTE wavecontrol;
483 SBYTE vibpos; /* current vibrato position */
484 UBYTE vibspd; /* "" speed */
485 UBYTE vibdepth; /* "" depth */
487 SBYTE trmpos; /* current tremolo position */
488 UBYTE trmspd; /* "" speed */
489 UBYTE trmdepth; /* "" depth */
491 UBYTE fslideupspd;
492 UBYTE fslidednspd;
493 UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */
494 UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */
495 UBYTE ffportupspd; /* fx X1 (extra fine portamento up) data */
496 UBYTE ffportdnspd; /* fx X2 (extra fine portamento dn) data */
498 ULONG hioffset; /* last used high order of sample offset */
499 UWORD soffset; /* last used low order of sample-offset (effect 9) */
501 UBYTE sseffect; /* last used Sxx effect */
502 UBYTE ssdata; /* last used Sxx data info */
503 UBYTE chanvolslide; /* last used channel volume slide */
505 UBYTE panbwave; /* current panbrello waveform */
506 UBYTE panbpos; /* current panbrello position */
507 SBYTE panbspd; /* "" speed */
508 UBYTE panbdepth; /* "" depth */
510 UWORD newsamp; /* set to 1 upon a sample / inst change */
511 UBYTE voleffect; /* Volume Column Effect Memory as used by IT */
512 UBYTE voldata; /* Volume Column Data Memory */
514 SWORD pat_reppos; /* patternloop position */
515 UWORD pat_repcnt; /* times to loop */
516 } MP_CONTROL;
518 /* Used by NNA only player (audio control. AUDTMP is used for full effects
519 control). */
520 typedef struct MP_VOICE {
521 struct MP_CHANNEL main;
523 ENVPR venv;
524 ENVPR penv;
525 ENVPR cenv;
527 UWORD avibpos; /* autovibrato pos */
528 UWORD aswppos; /* autovibrato sweep pos */
530 ULONG totalvol; /* total volume of channel (before global mixings) */
532 int mflag;
533 SWORD masterchn;
534 UWORD masterperiod;
536 MP_CONTROL* master; /* index of "master" effects channel */
537 } MP_VOICE;
539 /*========== Loaders */
541 typedef struct MLOADER {
542 struct MLOADER* next;
543 CHAR* type;
544 CHAR* version;
545 int (*Init)(void);
546 int (*Test)(void);
547 int (*Load)(int);
548 void (*Cleanup)(void);
549 CHAR* (*LoadTitle)(void);
550 } MLOADER;
552 /* internal loader variables */
553 extern MREADER* modreader;
554 extern UWORD finetune[16];
555 extern MODULE of; /* static unimod loading space */
556 extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */
558 extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
559 extern UBYTE* poslookup; /* lookup table for pattern jumps after
560 blank pattern removal */
561 extern UWORD poslookupcnt;
562 extern UWORD* origpositions;
564 extern int filters; /* resonant filters in use */
565 extern UBYTE activemacro; /* active midi macro number for Sxx */
566 extern UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */
567 extern FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
569 extern int* noteindex;
571 /*========== Internal loader interface */
573 extern int ReadComment(UWORD);
574 extern int ReadLinedComment(UWORD,UWORD);
575 extern int AllocPositions(int);
576 extern int AllocPatterns(void);
577 extern int AllocTracks(void);
578 extern int AllocInstruments(void);
579 extern int AllocSamples(void);
580 extern CHAR* DupStr(CHAR*,UWORD,int);
581 extern CHAR* StrDup(CHAR *s);
583 /* loader utility functions */
584 extern int* AllocLinear(void);
585 extern void FreeLinear(void);
586 extern int speed_to_finetune(ULONG,int);
587 extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
588 extern void S3MIT_CreateOrders(int);
590 /* flags for S3MIT_ProcessCmd */
591 #define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */
592 #define S3MIT_IT 2 /* behave as impulse tracker */
593 #define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */
595 /* used to convert c4spd to linear XM periods (IT and IMF loaders). */
596 extern UWORD getlinearperiod(UWORD,ULONG);
597 extern ULONG getfrequency(UWORD,ULONG);
599 /* loader shared data */
600 #define STM_NTRACKERS 3
601 extern CHAR *STM_Signatures[STM_NTRACKERS];
603 /*========== Player interface */
605 extern int Player_Init(MODULE*);
606 extern void Player_Exit(MODULE*);
607 extern void Player_HandleTick(void);
609 /*========== Drivers */
611 /* max. number of handles a driver has to provide. (not strict) */
612 #define MAXSAMPLEHANDLES 384
614 /* These variables can be changed at ANY time and results will be immediate */
615 extern UWORD md_bpm; /* current song / hardware BPM rate */
617 /* Variables below can be changed via MD_SetNumVoices at any time. However, a
618 call to MD_SetNumVoicess while the driver is active will cause the sound to
619 skip slightly. */
620 extern UBYTE md_numchn; /* number of song + sound effects voices */
621 extern UBYTE md_sngchn; /* number of song voices */
622 extern UBYTE md_sfxchn; /* number of sound effects voices */
623 extern UBYTE md_hardchn; /* number of hardware mixed voices */
624 extern UBYTE md_softchn; /* number of software mixed voices */
626 /* This is for use by the hardware drivers only. It points to the registered
627 tickhandler function. */
628 extern void (*md_player)(void);
630 extern SWORD MD_SampleLoad(SAMPLOAD*,int);
631 extern void MD_SampleUnload(SWORD);
632 extern ULONG MD_SampleSpace(int);
633 extern ULONG MD_SampleLength(int,SAMPLE*);
635 /* uLaw conversion */
636 extern void unsignedtoulaw(char *,int);
638 /* Parameter extraction helper */
639 extern CHAR *MD_GetAtom(CHAR*,CHAR*,int);
641 /* Internal software mixer stuff */
642 extern void VC_SetupPointers(void);
643 extern int VC1_Init(void);
644 extern int VC2_Init(void);
646 #if defined(unix) || defined(__APPLE__) && defined(__MACH__)
647 /* POSIX helper functions */
648 extern int MD_Access(CHAR *);
649 extern int MD_DropPrivileges(void);
650 #endif
652 /* Macro to define a missing driver, yet allowing binaries to dynamically link
653 with the library without missing symbol errors */
654 #define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 }
656 /*========== Prototypes for non-MT safe versions of some public functions */
658 extern void _mm_registerdriver(struct MDRIVER*);
659 extern void _mm_registerloader(struct MLOADER*);
660 extern int MikMod_Active_internal(void);
661 extern void MikMod_DisableOutput_internal(void);
662 extern int MikMod_EnableOutput_internal(void);
663 extern void MikMod_Exit_internal(void);
664 extern int MikMod_SetNumVoices_internal(int,int);
665 extern void Player_Exit_internal(MODULE*);
666 extern void Player_Stop_internal(void);
667 extern int Player_Paused_internal(void);
668 extern void Sample_Free_internal(SAMPLE*);
669 extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG);
670 extern void Voice_SetFrequency_internal(SBYTE,ULONG);
671 extern void Voice_SetPanning_internal(SBYTE,ULONG);
672 extern void Voice_SetVolume_internal(SBYTE,UWORD);
673 extern void Voice_Stop_internal(SBYTE);
674 extern int Voice_Stopped_internal(SBYTE);
676 #ifdef __cplusplus
678 #endif
680 /*========== SIMD mixing routines */
681 #undef HAVE_ALTIVEC
682 #undef HAVE_SSE2
684 #if defined(__APPLE__) && !defined (__i386__)
686 #if defined __VEC__ && !(defined(__GNUC__) && (__GNUC__ < 3))
687 #define HAVE_ALTIVEC
688 #endif // __VEC__
690 #elif defined WIN32 || defined __WIN64 || (defined __APPLE__ && defined (__i386__) && defined __VEC__)
692 // FIXME: emmintrin.h requires VC6 processor pack or VC2003+
693 #define HAVE_SSE2
695 /* Fixes couples warnings */
696 #ifdef _MSC_VER
697 #pragma warning(disable:4761)
698 #pragma warning(disable:4391)
699 #pragma warning(disable:4244)
700 #endif
701 #endif
702 // TODO: Test for GCC Linux
704 /*========== SIMD mixing helper functions =============*/
706 #define IS_ALIGNED_16(ptr) (!(((int)(ptr)) & 15))
708 /* Altivec helper function */
709 #if defined HAVE_ALTIVEC
711 #define simd_m128i vector signed int
712 #define simd_m128 vector float
714 #ifdef __GNUC__
715 #include <ppc_intrinsics.h>
716 #endif
718 // Helper functions
720 // Set single float across the four values
721 static inline vector float vec_mul( const vector float a, const vector float b)
723 return vec_madd(a, b, (const vector float)(0.f));
726 // Set single float across the four values
727 static inline vector float vec_load_ps1(const float *pF )
729 vector float data = vec_lde(0, pF);
730 return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0);
733 // Set vector to 0
734 static inline const vector float vec_setzero()
736 return (const vector float) (0.);
739 static inline vector signed char vec_set1_8(unsigned char splatchar)
741 vector unsigned char splatmap = vec_lvsl(0, &splatchar);
742 vector unsigned char result = vec_lde(0, &splatchar);
743 splatmap = vec_splat(splatmap, 0);
744 return (vector signed char)vec_perm(result, result, splatmap);
747 #define PERM_A0 0x00,0x01,0x02,0x03
748 #define PERM_A1 0x04,0x05,0x06,0x07
749 #define PERM_A2 0x08,0x09,0x0A,0x0B
750 #define PERM_A3 0x0C,0x0D,0x0E,0x0F
751 #define PERM_B0 0x10,0x11,0x12,0x13
752 #define PERM_B1 0x14,0x15,0x16,0x17
753 #define PERM_B2 0x18,0x19,0x1A,0x1B
754 #define PERM_B3 0x1C,0x1D,0x1E,0x1F
756 // Equivalent to _mm_unpacklo_epi32
757 static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b)
759 return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1));
762 // Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part).
763 static inline vector signed int vec_hiqq(vector signed int a)
765 vector signed int b = vec_splat_s32(0);
766 return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3));
769 // vec_sra is max +15. We have to do in two times ...
770 #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);
771 #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));
772 #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));
773 #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT+16-16));
774 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste);
775 #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);
776 #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste);
777 #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
779 #elif defined HAVE_SSE2
781 /* SSE2 helper function */
783 #include <emmintrin.h>
785 static __inline __m128i mm_hiqq(const __m128i a)
787 return _mm_srli_si128(a, 8); // get the 64bit upper part. new 64bit upper is undefined (zeroed is fine).
790 /* 128-bit mixing macros */
791 #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT+16-size);
792 #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);
793 #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
794 #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
795 #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
796 #define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
797 #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)));
798 #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1);
799 #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
800 #define simd_m128i __m128i
801 #define simd_m128 __m128
803 #endif
806 #endif
808 /* ex:set ts=4: */