summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/mikmod_internals.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/mikmod_internals.h')
-rw-r--r--apps/plugins/mikmod/mikmod_internals.h806
1 files changed, 806 insertions, 0 deletions
diff --git a/apps/plugins/mikmod/mikmod_internals.h b/apps/plugins/mikmod/mikmod_internals.h
new file mode 100644
index 0000000000..284dd85936
--- /dev/null
+++ b/apps/plugins/mikmod/mikmod_internals.h
@@ -0,0 +1,806 @@
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 $Id: mikmod_internals.h,v 1.7 2010/01/12 03:30:31 realtech Exp $
24
25 MikMod sound library internal definitions
26
27==============================================================================*/
28
29#ifndef _MIKMOD_INTERNALS_H
30#define _MIKMOD_INTERNALS_H
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
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
42
43#include "mikmod.h"
44
45/*========== More type definitions */
46
47/* SLONGLONG: 64bit, signed */
48#if defined (__arch64__) || defined(__alpha) || defined (__x64_64) || defined (_LP64) || defined (__powerpc64__)
49typedef long SLONGLONG;
50#define NATIVE_64BIT_INT
51#if 0
52#elif defined(__WATCOMC__)
53typedef __int64 SLONGLONG;
54#elif defined(WIN32) && !defined(__MWERKS__)
55typedef LONGLONG SLONGLONG;
56#elif macintosh && !TYPE_LONGLONG
57#include <Types.h>
58typedef SInt64 SLONGLONG;
59#endif
60#else
61typedef long long SLONGLONG;
62#endif
63
64/*========== Error handling */
65
66#define _mm_errno MikMod_errno
67#define _mm_critical MikMod_critical
68extern MikMod_handler_t _mm_errorhandler;
69
70/*========== MT stuff */
71
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
105
106DECLARE_MUTEX(lists);
107DECLARE_MUTEX(vars);
108
109/*========== Portable file I/O */
110
111extern MREADER* _mm_new_mem_reader(const void *buffer, int len);
112extern void _mm_delete_mem_reader(MREADER *reader);
113
114extern MREADER* _mm_new_file_reader(int fp);
115extern void _mm_delete_file_reader(MREADER*);
116
117extern MWRITER* _mm_new_file_writer(int fp);
118extern void _mm_delete_file_writer(MWRITER*);
119
120extern int _mm_FileExists(CHAR *fname);
121
122#define _mm_write_SBYTE(x,y) y->Put(y,(int)x)
123#define _mm_write_UBYTE(x,y) y->Put(y,(int)x)
124
125#define _mm_read_SBYTE(x) (SBYTE)x->Get(x)
126#define _mm_read_UBYTE(x) (UBYTE)x->Get(x)
127
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)
132
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)
136
137#define _mm_eof(x) x->Eof(x)
138
139extern void _mm_iobase_setcur(MREADER*);
140extern void _mm_iobase_revert(MREADER*);
141extern int _mm_fopen(CHAR*,CHAR*);
142extern int _mm_fclose(int);
143extern void _mm_write_string(CHAR*,MWRITER*);
144extern int _mm_read_string (CHAR*,int,MREADER*);
145
146extern SWORD _mm_read_M_SWORD(MREADER*);
147extern SWORD _mm_read_I_SWORD(MREADER*);
148extern UWORD _mm_read_M_UWORD(MREADER*);
149extern UWORD _mm_read_I_UWORD(MREADER*);
150
151extern SLONG _mm_read_M_SLONG(MREADER*);
152extern SLONG _mm_read_I_SLONG(MREADER*);
153extern ULONG _mm_read_M_ULONG(MREADER*);
154extern ULONG _mm_read_I_ULONG(MREADER*);
155
156extern int _mm_read_M_SWORDS(SWORD*,int,MREADER*);
157extern int _mm_read_I_SWORDS(SWORD*,int,MREADER*);
158extern int _mm_read_M_UWORDS(UWORD*,int,MREADER*);
159extern int _mm_read_I_UWORDS(UWORD*,int,MREADER*);
160
161extern int _mm_read_M_SLONGS(SLONG*,int,MREADER*);
162extern int _mm_read_I_SLONGS(SLONG*,int,MREADER*);
163extern int _mm_read_M_ULONGS(ULONG*,int,MREADER*);
164extern int _mm_read_I_ULONGS(ULONG*,int,MREADER*);
165
166extern void _mm_write_M_SWORD(SWORD,MWRITER*);
167extern void _mm_write_I_SWORD(SWORD,MWRITER*);
168extern void _mm_write_M_UWORD(UWORD,MWRITER*);
169extern void _mm_write_I_UWORD(UWORD,MWRITER*);
170
171extern void _mm_write_M_SLONG(SLONG,MWRITER*);
172extern void _mm_write_I_SLONG(SLONG,MWRITER*);
173extern void _mm_write_M_ULONG(ULONG,MWRITER*);
174extern void _mm_write_I_ULONG(ULONG,MWRITER*);
175
176extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*);
177extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*);
178extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*);
179extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*);
180
181extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*);
182extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*);
183extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*);
184extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
185
186/*========== Samples */
187
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. */
191typedef struct SAMPLOAD {
192 struct SAMPLOAD *next;
193
194 ULONG length; /* length of sample (in samples!) */
195 ULONG loopstart; /* repeat position (relative to start, in samples) */
196 ULONG loopend; /* repeat end */
197 UWORD infmt,outfmt;
198 int scalefactor;
199 SAMPLE* sample;
200 MREADER* reader;
201} SAMPLOAD;
202
203/*========== Sample and waves loading interface */
204
205extern void SL_HalveSample(SAMPLOAD*,int);
206extern void SL_Sample8to16(SAMPLOAD*);
207extern void SL_Sample16to8(SAMPLOAD*);
208extern void SL_SampleSigned(SAMPLOAD*);
209extern void SL_SampleUnsigned(SAMPLOAD*);
210extern int SL_LoadSamples(void);
211extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
212extern int SL_Load(void*,SAMPLOAD*,ULONG);
213extern int SL_Init(SAMPLOAD*);
214extern void SL_Exit(SAMPLOAD*);
215
216/*========== Internal module representation (UniMod) interface */
217
218/* number of notes in an octave */
219#define OCTAVE 12
220
221extern void UniSetRow(UBYTE*);
222extern UBYTE UniGetByte(void);
223extern UWORD UniGetWord(void);
224extern UBYTE* UniFindRow(UBYTE*,UWORD);
225extern void UniSkipOpcode(void);
226extern void UniReset(void);
227extern void UniWriteByte(UBYTE);
228extern void UniWriteWord(UWORD);
229extern void UniNewline(void);
230extern UBYTE* UniDup(void);
231extern int UniInit(void);
232extern void UniCleanup(void);
233extern void UniEffect(UWORD,UWORD);
234#define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x)
235#define UniNote(x) UniEffect(UNI_NOTE,x)
236extern void UniPTEffect(UBYTE,UBYTE);
237extern void UniVolEffect(UWORD,UBYTE);
238
239/*========== Module Commands */
240
241enum {
242 /* Simple note */
243 UNI_NOTE = 1,
244 /* Instrument change */
245 UNI_INSTRUMENT,
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 */
302 UNI_ITEFFECTS0,
303 /* UltraTracker effects */
304 UNI_ULTEFFECT9, /* Sample fine offset */
305 /* OctaMED effects */
306 UNI_MEDSPEED,
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 */
312
313 UNI_LAST
314};
315
316extern UWORD unioperands[UNI_LAST];
317
318/* IT / S3M Extended SS effects: */
319enum {
320 SS_GLISSANDO = 1,
321 SS_FINETUNE,
322 SS_VIBWAVE,
323 SS_TREMWAVE,
324 SS_PANWAVE,
325 SS_FRAMEDELAY,
326 SS_S7EFFECTS,
327 SS_PANNING,
328 SS_SURROUND,
329 SS_HIOFFSET,
330 SS_PATLOOP,
331 SS_NOTECUT,
332 SS_NOTEDELAY,
333 SS_PATDELAY
334};
335
336/* IT Volume column effects */
337enum {
338 VOL_VOLUME = 1,
339 VOL_PANNING,
340 VOL_VOLSLIDE,
341 VOL_PITCHSLIDEDN,
342 VOL_PITCHSLIDEUP,
343 VOL_PORTAMENTO,
344 VOL_VIBRATO
345};
346
347/* IT resonant filter information */
348
349#define UF_MAXMACRO 0x10
350#define UF_MAXFILTER 0x100
351
352#define FILT_CUT 0x80
353#define FILT_RESONANT 0x81
354
355typedef struct FILTER {
356 UBYTE filter,inf;
357} FILTER;
358
359/*========== Instruments */
360
361/* Instrument format flags */
362#define IF_OWNPAN 1
363#define IF_PITCHPAN 2
364
365/* Envelope flags: */
366#define EF_ON 1
367#define EF_SUSTAIN 2
368#define EF_LOOP 4
369#define EF_VOLENV 8
370
371/* New Note Action Flags */
372#define NNA_CUT 0
373#define NNA_CONTINUE 1
374#define NNA_OFF 2
375#define NNA_FADE 3
376
377#define NNA_MASK 3
378
379#define DCT_OFF 0
380#define DCT_NOTE 1
381#define DCT_SAMPLE 2
382#define DCT_INST 3
383
384#define DCA_CUT 0
385#define DCA_OFF 1
386#define DCA_FADE 2
387
388#define KEY_KICK 0
389#define KEY_OFF 1
390#define KEY_FADE 2
391#define KEY_KILL (KEY_OFF|KEY_FADE)
392
393#define KICK_ABSENT 0
394#define KICK_NOTE 1
395#define KICK_KEYOFF 2
396#define KICK_ENV 4
397
398#define AV_IT 1 /* IT vs. XM vibrato info */
399
400/*========== Playing */
401
402#define POS_NONE (-2) /* no loop position defined */
403
404#define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */
405
406typedef 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 */
417} ENVPR;
418
419typedef struct MP_CHANNEL {
420 INSTRUMENT* i;
421 SAMPLE* s;
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 */
432
433 UBYTE volflg; /* volume envelope settings */
434 UBYTE panflg; /* panning envelope settings */
435 UBYTE pitflg; /* pitch envelope settings */
436
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 */
441} MP_CHANNEL;
442
443typedef struct MP_CONTROL {
444 struct MP_CHANNEL main;
445
446 struct MP_VOICE *slave; /* Audio Slave of current effects control channel */
447
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 */
452 UBYTE oldnote;
453 SWORD ownper;
454 SWORD ownvol;
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 */
461
462 SWORD tmpvolume; /* tmp volume */
463 UWORD tmpperiod; /* tmp period */
464 UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */
465
466 UBYTE arpmem; /* arpeggio command memory */
467 UBYTE pansspd; /* panslide speed */
468 UWORD slidespeed;
469 UWORD portspeed; /* noteslide speed (toneportamento) */
470
471 UBYTE s3mtremor; /* s3m tremor (effect I) counter */
472 UBYTE s3mtronof; /* s3m tremor ontime/offtime */
473 UBYTE s3mvolslide; /* last used volslide */
474 SBYTE sliding;
475 UBYTE s3mrtgspeed; /* last used retrig speed */
476 UBYTE s3mrtgslide; /* last used retrig slide */
477
478 UBYTE glissando; /* glissando (0 means off) */
479 UBYTE wavecontrol;
480
481 SBYTE vibpos; /* current vibrato position */
482 UBYTE vibspd; /* "" speed */
483 UBYTE vibdepth; /* "" depth */
484
485 SBYTE trmpos; /* current tremolo position */
486 UBYTE trmspd; /* "" speed */
487 UBYTE trmdepth; /* "" depth */
488
489 UBYTE fslideupspd;
490 UBYTE fslidednspd;
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 */
495
496 ULONG hioffset; /* last used high order of sample offset */
497 UWORD soffset; /* last used low order of sample-offset (effect 9) */
498
499 UBYTE sseffect; /* last used Sxx effect */
500 UBYTE ssdata; /* last used Sxx data info */
501 UBYTE chanvolslide; /* last used channel volume slide */
502
503 UBYTE panbwave; /* current panbrello waveform */
504 UBYTE panbpos; /* current panbrello position */
505 SBYTE panbspd; /* "" speed */
506 UBYTE panbdepth; /* "" depth */
507
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 */
511
512 SWORD pat_reppos; /* patternloop position */
513 UWORD pat_repcnt; /* times to loop */
514} MP_CONTROL;
515
516/* Used by NNA only player (audio control. AUDTMP is used for full effects
517 control). */
518typedef struct MP_VOICE {
519 struct MP_CHANNEL main;
520
521 ENVPR venv;
522 ENVPR penv;
523 ENVPR cenv;
524
525 UWORD avibpos; /* autovibrato pos */
526 UWORD aswppos; /* autovibrato sweep pos */
527
528 ULONG totalvol; /* total volume of channel (before global mixings) */
529
530 int mflag;
531 SWORD masterchn;
532 UWORD masterperiod;
533
534 MP_CONTROL* master; /* index of "master" effects channel */
535} MP_VOICE;
536
537/*========== Loaders */
538
539typedef struct MLOADER {
540struct MLOADER* next;
541 CHAR* type;
542 CHAR* version;
543 int (*Init)(void);
544 int (*Test)(void);
545 int (*Load)(int);
546 void (*Cleanup)(void);
547 CHAR* (*LoadTitle)(void);
548} MLOADER;
549
550/* internal loader variables */
551extern MREADER* modreader;
552extern UWORD finetune[16];
553extern MODULE of; /* static unimod loading space */
554extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */
555
556extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
557extern UBYTE* poslookup; /* lookup table for pattern jumps after
558 blank pattern removal */
559extern UWORD poslookupcnt;
560extern UWORD* origpositions;
561
562extern int filters; /* resonant filters in use */
563extern UBYTE activemacro; /* active midi macro number for Sxx */
564extern UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */
565extern FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
566
567extern int* noteindex;
568
569/*========== Internal loader interface */
570
571extern int ReadComment(UWORD);
572extern int ReadLinedComment(UWORD,UWORD);
573extern int AllocPositions(int);
574extern int AllocPatterns(void);
575extern int AllocTracks(void);
576extern int AllocInstruments(void);
577extern int AllocSamples(void);
578extern CHAR* DupStr(CHAR*,UWORD,int);
579extern CHAR* StrDup(CHAR *s);
580
581/* loader utility functions */
582extern int* AllocLinear(void);
583extern void FreeLinear(void);
584extern int speed_to_finetune(ULONG,int);
585extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
586extern void S3MIT_CreateOrders(int);
587
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 */
592
593/* used to convert c4spd to linear XM periods (IT and IMF loaders). */
594extern UWORD getlinearperiod(UWORD,ULONG);
595extern ULONG getfrequency(UWORD,ULONG);
596
597/* loader shared data */
598#define STM_NTRACKERS 3
599extern CHAR *STM_Signatures[STM_NTRACKERS];
600
601/*========== Player interface */
602
603extern int Player_Init(MODULE*);
604extern void Player_Exit(MODULE*);
605extern void Player_HandleTick(void);
606
607/*========== Drivers */
608
609/* max. number of handles a driver has to provide. (not strict) */
610#define MAXSAMPLEHANDLES 384
611
612/* These variables can be changed at ANY time and results will be immediate */
613extern UWORD md_bpm; /* current song / hardware BPM rate */
614
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
617 skip slightly. */
618extern UBYTE md_numchn; /* number of song + sound effects voices */
619extern UBYTE md_sngchn; /* number of song voices */
620extern UBYTE md_sfxchn; /* number of sound effects voices */
621extern UBYTE md_hardchn; /* number of hardware mixed voices */
622extern UBYTE md_softchn; /* number of software mixed voices */
623
624/* This is for use by the hardware drivers only. It points to the registered
625 tickhandler function. */
626extern void (*md_player)(void);
627
628extern SWORD MD_SampleLoad(SAMPLOAD*,int);
629extern void MD_SampleUnload(SWORD);
630extern ULONG MD_SampleSpace(int);
631extern ULONG MD_SampleLength(int,SAMPLE*);
632
633/* uLaw conversion */
634extern void unsignedtoulaw(char *,int);
635
636/* Parameter extraction helper */
637extern CHAR *MD_GetAtom(CHAR*,CHAR*,int);
638
639/* Internal software mixer stuff */
640extern void VC_SetupPointers(void);
641extern int VC1_Init(void);
642extern int VC2_Init(void);
643
644#if defined(unix) || defined(__APPLE__) && defined(__MACH__)
645/* POSIX helper functions */
646extern int MD_Access(CHAR *);
647extern int MD_DropPrivileges(void);
648#endif
649
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 }
653
654/*========== Prototypes for non-MT safe versions of some public functions */
655
656extern void _mm_registerdriver(struct MDRIVER*);
657extern void _mm_registerloader(struct MLOADER*);
658extern int MikMod_Active_internal(void);
659extern void MikMod_DisableOutput_internal(void);
660extern int MikMod_EnableOutput_internal(void);
661extern void MikMod_Exit_internal(void);
662extern int MikMod_SetNumVoices_internal(int,int);
663extern void Player_Exit_internal(MODULE*);
664extern void Player_Stop_internal(void);
665extern int Player_Paused_internal(void);
666extern void Sample_Free_internal(SAMPLE*);
667extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG);
668extern void Voice_SetFrequency_internal(SBYTE,ULONG);
669extern void Voice_SetPanning_internal(SBYTE,ULONG);
670extern void Voice_SetVolume_internal(SBYTE,UWORD);
671extern void Voice_Stop_internal(SBYTE);
672extern int Voice_Stopped_internal(SBYTE);
673
674#ifdef __cplusplus
675}
676#endif
677
678/*========== SIMD mixing routines */
679#undef HAVE_ALTIVEC
680#undef HAVE_SSE2
681
682#if defined(__APPLE__) && !defined (__i386__)
683
684#if defined __VEC__ && !(defined(__GNUC__) && (__GNUC__ < 3))
685#define HAVE_ALTIVEC
686#endif // __VEC__
687
688#elif defined WIN32 || defined __WIN64 || (defined __APPLE__ && defined (__i386__) && defined __VEC__)
689
690// FIXME: emmintrin.h requires VC6 processor pack or VC2003+
691#define HAVE_SSE2
692
693/* Fixes couples warnings */
694#ifdef _MSC_VER
695#pragma warning(disable:4761)
696#pragma warning(disable:4391)
697#pragma warning(disable:4244)
698#endif
699#endif
700// TODO: Test for GCC Linux
701
702/*========== SIMD mixing helper functions =============*/
703
704#define IS_ALIGNED_16(ptr) (!(((int)(ptr)) & 15))
705
706/* Altivec helper function */
707#if defined HAVE_ALTIVEC
708
709#define simd_m128i vector signed int
710#define simd_m128 vector float
711
712#ifdef __GNUC__
713#include <ppc_intrinsics.h>
714#endif
715
716// Helper functions
717
718// Set single float across the four values
719static inline vector float vec_mul( const vector float a, const vector float b)
720{
721 return vec_madd(a, b, (const vector float)(0.f));
722}
723
724// Set single float across the four values
725static inline vector float vec_load_ps1(const float *pF )
726{
727 vector float data = vec_lde(0, pF);
728 return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0);
729}
730
731// Set vector to 0
732static inline const vector float vec_setzero()
733{
734 return (const vector float) (0.);
735}
736
737static inline vector signed char vec_set1_8(unsigned char splatchar)
738{
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);
743}
744
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
753
754// Equivalent to _mm_unpacklo_epi32
755static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b)
756{
757 return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1));
758}
759
760// Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part).
761static inline vector signed int vec_hiqq(vector signed int a)
762{
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));
765}
766
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)
776
777#elif defined HAVE_SSE2
778
779/* SSE2 helper function */
780
781#include <emmintrin.h>
782
783static __inline __m128i mm_hiqq(const __m128i a)
784{
785 return _mm_srli_si128(a, 8); // get the 64bit upper part. new 64bit upper is undefined (zeroed is fine).
786}
787
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
800
801#endif
802
803
804#endif
805
806/* ex:set ts=4: */