diff options
Diffstat (limited to 'apps/plugins/mikmod/mikmod_internals.h')
-rw-r--r-- | apps/plugins/mikmod/mikmod_internals.h | 806 |
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 | ||
33 | extern "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__) | ||
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 | ||
63 | |||
64 | /*========== Error handling */ | ||
65 | |||
66 | #define _mm_errno MikMod_errno | ||
67 | #define _mm_critical MikMod_critical | ||
68 | extern 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 | |||
106 | DECLARE_MUTEX(lists); | ||
107 | DECLARE_MUTEX(vars); | ||
108 | |||
109 | /*========== Portable file I/O */ | ||
110 | |||
111 | extern MREADER* _mm_new_mem_reader(const void *buffer, int len); | ||
112 | extern void _mm_delete_mem_reader(MREADER *reader); | ||
113 | |||
114 | extern MREADER* _mm_new_file_reader(int fp); | ||
115 | extern void _mm_delete_file_reader(MREADER*); | ||
116 | |||
117 | extern MWRITER* _mm_new_file_writer(int fp); | ||
118 | extern void _mm_delete_file_writer(MWRITER*); | ||
119 | |||
120 | extern 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 | |||
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*); | ||
145 | |||
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*); | ||
150 | |||
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*); | ||
155 | |||
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*); | ||
160 | |||
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*); | ||
165 | |||
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*); | ||
170 | |||
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*); | ||
175 | |||
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*); | ||
180 | |||
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*); | ||
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. */ | ||
191 | typedef 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 | |||
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*); | ||
215 | |||
216 | /*========== Internal module representation (UniMod) interface */ | ||
217 | |||
218 | /* number of notes in an octave */ | ||
219 | #define OCTAVE 12 | ||
220 | |||
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); | ||
238 | |||
239 | /*========== Module Commands */ | ||
240 | |||
241 | enum { | ||
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 | |||
316 | extern UWORD unioperands[UNI_LAST]; | ||
317 | |||
318 | /* IT / S3M Extended SS effects: */ | ||
319 | enum { | ||
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 */ | ||
337 | enum { | ||
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 | |||
355 | typedef 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 | |||
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 */ | ||
417 | } ENVPR; | ||
418 | |||
419 | typedef 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 | |||
443 | typedef 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). */ | ||
518 | typedef 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 | |||
539 | typedef struct MLOADER { | ||
540 | struct 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 */ | ||
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 */ | ||
555 | |||
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; | ||
561 | |||
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 */ | ||
566 | |||
567 | extern int* noteindex; | ||
568 | |||
569 | /*========== Internal loader interface */ | ||
570 | |||
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); | ||
580 | |||
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); | ||
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). */ | ||
594 | extern UWORD getlinearperiod(UWORD,ULONG); | ||
595 | extern ULONG getfrequency(UWORD,ULONG); | ||
596 | |||
597 | /* loader shared data */ | ||
598 | #define STM_NTRACKERS 3 | ||
599 | extern CHAR *STM_Signatures[STM_NTRACKERS]; | ||
600 | |||
601 | /*========== Player interface */ | ||
602 | |||
603 | extern int Player_Init(MODULE*); | ||
604 | extern void Player_Exit(MODULE*); | ||
605 | extern 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 */ | ||
613 | extern 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. */ | ||
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 */ | ||
623 | |||
624 | /* This is for use by the hardware drivers only. It points to the registered | ||
625 | tickhandler function. */ | ||
626 | extern void (*md_player)(void); | ||
627 | |||
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*); | ||
632 | |||
633 | /* uLaw conversion */ | ||
634 | extern void unsignedtoulaw(char *,int); | ||
635 | |||
636 | /* Parameter extraction helper */ | ||
637 | extern CHAR *MD_GetAtom(CHAR*,CHAR*,int); | ||
638 | |||
639 | /* Internal software mixer stuff */ | ||
640 | extern void VC_SetupPointers(void); | ||
641 | extern int VC1_Init(void); | ||
642 | extern int VC2_Init(void); | ||
643 | |||
644 | #if defined(unix) || defined(__APPLE__) && defined(__MACH__) | ||
645 | /* POSIX helper functions */ | ||
646 | extern int MD_Access(CHAR *); | ||
647 | extern 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 | |||
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); | ||
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 | ||
719 | static 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 | ||
725 | static 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 | ||
732 | static inline const vector float vec_setzero() | ||
733 | { | ||
734 | return (const vector float) (0.); | ||
735 | } | ||
736 | |||
737 | static 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 | ||
755 | static 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). | ||
761 | static 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 | |||
783 | static __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: */ | ||