From b4e70422a3455e327433a7471c929ef100ef3b10 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 8 Aug 2020 21:56:15 -0400 Subject: mikmod: Upgrade mikmod core from v3.2.0 to v3.3.11 * Get rid of the non-functional GT2 loader * Add the UMX loader * Add HQ mixer routines (and make it configurable) * Allow samplerate to be configured at run/playtime * Support >64KHz mixing/playback * Correctly restore non-boost status (The diff to upstream is much smaller now too!) Change-Id: Iaa4ac901ba9cd4123bb225656976e78271353a72 --- apps/plugins/mikmod/mikmod_internals.h | 789 ++++++++++++++++++--------------- 1 file changed, 425 insertions(+), 364 deletions(-) (limited to 'apps/plugins/mikmod/mikmod_internals.h') diff --git a/apps/plugins/mikmod/mikmod_internals.h b/apps/plugins/mikmod/mikmod_internals.h index 78d7b52045..e6ba1875c0 100644 --- a/apps/plugins/mikmod/mikmod_internals.h +++ b/apps/plugins/mikmod/mikmod_internals.h @@ -20,11 +20,9 @@ /*============================================================================== - $Id: mikmod_internals.h,v 1.7 2010/01/12 03:30:31 realtech Exp $ - MikMod sound library internal definitions -==============================================================================*/ + ==============================================================================*/ #ifndef _MIKMOD_INTERNALS_H #define _MIKMOD_INTERNALS_H @@ -34,32 +32,52 @@ extern "C" { #endif #include -#if 0 -#if defined(__OS2__)||defined(__EMX__)||defined(WIN32) -#define strcasecmp(s,t) stricmp(s,t) -#endif + +#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H) +#define inline __inline #endif #include "mikmod.h" +#ifndef MIKMOD_UNIX +#if (defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) && \ + !(defined(_MIKMOD_WIN32) || defined(_MIKMOD_OS2) || defined(_MIKMOD_DOS) || defined(_MIKMOD_AMIGA) || defined(macintosh)) +#define MIKMOD_UNIX 1 +#else +#define MIKMOD_UNIX 0 +#endif +#endif /* MIKMOD_UNIX */ + /*========== More type definitions */ /* SLONGLONG: 64bit, signed */ -#if defined (__arch64__) || defined(__alpha) || defined (__x64_64) || defined (_LP64) || defined (__powerpc64__) -typedef long SLONGLONG; +#if !defined(_WIN32) && \ + (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__)) +typedef long SLONGLONG; +#define NATIVE_64BIT_INT +#elif defined(_WIN64) /* win64 is LLP64, not LP64 */ #define NATIVE_64BIT_INT -#if 0 +typedef long long SLONGLONG; #elif defined(__WATCOMC__) -typedef __int64 SLONGLONG; -#elif defined(WIN32) && !defined(__MWERKS__) -typedef LONGLONG SLONGLONG; -#elif macintosh && !TYPE_LONGLONG +typedef __int64 SLONGLONG; +#elif defined(_WIN32) && !defined(__MWERKS__) +typedef LONGLONG SLONGLONG; +#elif defined(macintosh) && !TYPE_LONGLONG #include -typedef SInt64 SLONGLONG; +typedef SInt64 SLONGLONG; +#else +typedef long long SLONGLONG; #endif +typedef int __s64_typetest [(sizeof(SLONGLONG)==8) * 2 - 1]; + +/* pointer-sized signed int (ssize_t/intptr_t) : */ +#if defined(_WIN64) /* win64 is LLP64, not LP64 */ +typedef long long SINTPTR_T; #else -typedef long long SLONGLONG; +/* long should be pointer-sized for all others : */ +typedef long SINTPTR_T; #endif +typedef int __iptr_typetest [(sizeof(SINTPTR_T)==sizeof(void*)) * 2 - 1]; /*========== Error handling */ @@ -72,33 +90,36 @@ extern MikMod_handler_t _mm_errorhandler; #ifdef HAVE_PTHREAD #include #define DECLARE_MUTEX(name) \ - extern pthread_mutex_t _mm_mutex_##name -#define MUTEX_LOCK(name) \ - pthread_mutex_lock(&_mm_mutex_##name) -#define MUTEX_UNLOCK(name) \ - pthread_mutex_unlock(&_mm_mutex_##name) + extern pthread_mutex_t _mm_mutex_##name +#define MUTEX_LOCK(name) \ + pthread_mutex_lock(&_mm_mutex_##name) +#define MUTEX_UNLOCK(name) \ + pthread_mutex_unlock(&_mm_mutex_##name) + #elif defined(__OS2__)||defined(__EMX__) -#define DECLARE_MUTEX(name) \ - extern HMTX _mm_mutex_##name -#define MUTEX_LOCK(name) \ - if(_mm_mutex_##name) \ - DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) -#define MUTEX_UNLOCK(name) \ - if(_mm_mutex_##name) \ - DosReleaseMutexSem(_mm_mutex_##name) -#elif defined(WIN32) +#define DECLARE_MUTEX(name) \ + extern HMTX _mm_mutex_##name +#define MUTEX_LOCK(name) \ + if(_mm_mutex_##name)\ + DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) +#define MUTEX_UNLOCK(name) \ + if(_mm_mutex_##name)\ + DosReleaseMutexSem(_mm_mutex_##name) + +#elif defined(_WIN32) #include -#define DECLARE_MUTEX(name) \ - extern HANDLE _mm_mutex_##name -#define MUTEX_LOCK(name) \ - if(_mm_mutex_##name) \ - WaitForSingleObject(_mm_mutex_##name,INFINITE) -#define MUTEX_UNLOCK(name) \ - if(_mm_mutex_##name) \ - ReleaseMutex(_mm_mutex_##name) +#define DECLARE_MUTEX(name) \ + extern HANDLE _mm_mutex_##name +#define MUTEX_LOCK(name) \ + if(_mm_mutex_##name)\ + WaitForSingleObject(_mm_mutex_##name,INFINITE) +#define MUTEX_UNLOCK(name) \ + if(_mm_mutex_##name)\ + ReleaseMutex(_mm_mutex_##name) + #else -#define DECLARE_MUTEX(name) \ - extern void *_mm_mutex_##name +#define DECLARE_MUTEX(name) \ + extern void *_mm_mutex_##name #define MUTEX_LOCK(name) #define MUTEX_UNLOCK(name) #endif @@ -106,9 +127,13 @@ extern MikMod_handler_t _mm_errorhandler; DECLARE_MUTEX(lists); DECLARE_MUTEX(vars); +/*========== Replacement funcs */ + +//extern int strcasecmp (const char *__s1, const char *__s2); + /*========== Portable file I/O */ -extern MREADER* _mm_new_mem_reader(const void *buffer, int len); +extern MREADER* _mm_new_mem_reader(const void *buffer, long len); extern void _mm_delete_mem_reader(MREADER *reader); extern MREADER* _mm_new_file_reader(int fp); @@ -117,33 +142,32 @@ extern void _mm_delete_file_reader(MREADER*); extern MWRITER* _mm_new_file_writer(int fp); extern void _mm_delete_file_writer(MWRITER*); -extern int _mm_FileExists(CHAR *fname); +extern int _mm_FileExists(const CHAR *fname); -#define _mm_write_SBYTE(x,y) y->Put(y,(int)x) -#define _mm_write_UBYTE(x,y) y->Put(y,(int)x) +#define _mm_write_SBYTE(x,y) y->Put(y,(int)x) +#define _mm_write_UBYTE(x,y) y->Put(y,(int)x) -#define _mm_read_SBYTE(x) (SBYTE)x->Get(x) -#define _mm_read_UBYTE(x) (UBYTE)x->Get(x) +#define _mm_read_SBYTE(x) (SBYTE)x->Get(x) +#define _mm_read_UBYTE(x) (UBYTE)x->Get(x) +#define _mm_skip_BYTE(x) (void)x->Get(x) -#define _mm_write_SBYTES(x,y,z) z->Write(z,(void *)x,y) -#define _mm_write_UBYTES(x,y,z) z->Write(z,(void *)x,y) +#define _mm_write_SBYTES(x,y,z) z->Write(z,(const void *)x,y) +#define _mm_write_UBYTES(x,y,z) z->Write(z,(const void *)x,y) #define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y) #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y) -#define _mm_fseek(x,y,z) x->Seek(x,y,z) -#define _mm_ftell(x) x->Tell(x) -#define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET) +#define _mm_fseek(x,y,z) x->Seek(x,y,z) +#define _mm_ftell(x) x->Tell(x) +#define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET) -#define _mm_eof(x) x->Eof(x) +#define _mm_eof(x) x->Eof(x) extern void _mm_iobase_setcur(MREADER*); extern void _mm_iobase_revert(MREADER*); -extern int _mm_fopen(CHAR*,CHAR*); -extern int _mm_fclose(int); -#if !defined(ROCKBOX) -extern void _mm_write_string(CHAR*,MWRITER*); -#endif -extern int _mm_read_string (CHAR*,int,MREADER*); +extern int _mm_fopen(const CHAR *, const CHAR *); +extern int _mm_fclose(int); +extern void _mm_write_string(const CHAR*,MWRITER*); +extern int _mm_read_string (CHAR*,int,MREADER*); extern SWORD _mm_read_M_SWORD(MREADER*); extern SWORD _mm_read_I_SWORD(MREADER*); @@ -187,19 +211,21 @@ extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*); /*========== Samples */ +#define MAX_SAMPLE_SIZE 0x10000000 /* a sane value guaranteed to not overflow an SLONG */ + /* This is a handle of sorts attached to any sample registered with SL_RegisterSample. Generally, this only need be used or changed by the loaders and drivers of mikmod. */ typedef struct SAMPLOAD { - struct SAMPLOAD *next; - - ULONG length; /* length of sample (in samples!) */ - ULONG loopstart; /* repeat position (relative to start, in samples) */ - ULONG loopend; /* repeat end */ - UWORD infmt,outfmt; - int scalefactor; - SAMPLE* sample; - MREADER* reader; + struct SAMPLOAD *next; + + ULONG length; /* length of sample (in samples!) */ + ULONG loopstart; /* repeat position (relative to start, in samples) */ + ULONG loopend; /* repeat end */ + UWORD infmt,outfmt; + int scalefactor; + SAMPLE* sample; + MREADER* reader; } SAMPLOAD; /*========== Sample and waves loading interface */ @@ -209,9 +235,9 @@ extern void SL_Sample8to16(SAMPLOAD*); extern void SL_Sample16to8(SAMPLOAD*); extern void SL_SampleSigned(SAMPLOAD*); extern void SL_SampleUnsigned(SAMPLOAD*); -extern int SL_LoadSamples(void); +extern int SL_LoadSamples(void); extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); -extern int SL_Load(void*,SAMPLOAD*,ULONG); +extern int SL_Load(void*,SAMPLOAD*,ULONG); extern int SL_Init(SAMPLOAD*); extern void SL_Exit(SAMPLOAD*); @@ -233,126 +259,126 @@ extern UBYTE* UniDup(void); extern int UniInit(void); extern void UniCleanup(void); extern void UniEffect(UWORD,UWORD); -#define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x) -#define UniNote(x) UniEffect(UNI_NOTE,x) +#define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x) +#define UniNote(x) UniEffect(UNI_NOTE,x) extern void UniPTEffect(UBYTE,UBYTE); extern void UniVolEffect(UWORD,UBYTE); /*========== Module Commands */ enum { - /* Simple note */ - UNI_NOTE = 1, - /* Instrument change */ - UNI_INSTRUMENT, - /* Protracker effects */ - UNI_PTEFFECT0, /* arpeggio */ - UNI_PTEFFECT1, /* porta up */ - UNI_PTEFFECT2, /* porta down */ - UNI_PTEFFECT3, /* porta to note */ - UNI_PTEFFECT4, /* vibrato */ - UNI_PTEFFECT5, /* dual effect 3+A */ - UNI_PTEFFECT6, /* dual effect 4+A */ - UNI_PTEFFECT7, /* tremolo */ - UNI_PTEFFECT8, /* pan */ - UNI_PTEFFECT9, /* sample offset */ - UNI_PTEFFECTA, /* volume slide */ - UNI_PTEFFECTB, /* pattern jump */ - UNI_PTEFFECTC, /* set volume */ - UNI_PTEFFECTD, /* pattern break */ - UNI_PTEFFECTE, /* extended effects */ - UNI_PTEFFECTF, /* set speed */ - /* Scream Tracker effects */ - UNI_S3MEFFECTA, /* set speed */ - UNI_S3MEFFECTD, /* volume slide */ - UNI_S3MEFFECTE, /* porta down */ - UNI_S3MEFFECTF, /* porta up */ - UNI_S3MEFFECTI, /* tremor */ - UNI_S3MEFFECTQ, /* retrig */ - UNI_S3MEFFECTR, /* tremolo */ - UNI_S3MEFFECTT, /* set tempo */ - UNI_S3MEFFECTU, /* fine vibrato */ - UNI_KEYOFF, /* note off */ - /* Fast Tracker effects */ - UNI_KEYFADE, /* note fade */ - UNI_VOLEFFECTS, /* volume column effects */ - UNI_XMEFFECT4, /* vibrato */ - UNI_XMEFFECT6, /* dual effect 4+A */ - UNI_XMEFFECTA, /* volume slide */ - UNI_XMEFFECTE1, /* fine porta up */ - UNI_XMEFFECTE2, /* fine porta down */ - UNI_XMEFFECTEA, /* fine volume slide up */ - UNI_XMEFFECTEB, /* fine volume slide down */ - UNI_XMEFFECTG, /* set global volume */ - UNI_XMEFFECTH, /* global volume slide */ - UNI_XMEFFECTL, /* set envelope position */ - UNI_XMEFFECTP, /* pan slide */ - UNI_XMEFFECTX1, /* extra fine porta up */ - UNI_XMEFFECTX2, /* extra fine porta down */ - /* Impulse Tracker effects */ - UNI_ITEFFECTG, /* porta to note */ - UNI_ITEFFECTH, /* vibrato */ - UNI_ITEFFECTI, /* tremor (xy not incremented) */ - UNI_ITEFFECTM, /* set channel volume */ - UNI_ITEFFECTN, /* slide / fineslide channel volume */ - UNI_ITEFFECTP, /* slide / fineslide channel panning */ - UNI_ITEFFECTT, /* slide tempo */ - UNI_ITEFFECTU, /* fine vibrato */ - UNI_ITEFFECTW, /* slide / fineslide global volume */ - UNI_ITEFFECTY, /* panbrello */ - UNI_ITEFFECTZ, /* resonant filters */ - UNI_ITEFFECTS0, - /* UltraTracker effects */ - UNI_ULTEFFECT9, /* Sample fine offset */ - /* OctaMED effects */ - UNI_MEDSPEED, - UNI_MEDEFFECTF1, /* play note twice */ - UNI_MEDEFFECTF2, /* delay note */ - UNI_MEDEFFECTF3, /* play note three times */ - /* Oktalyzer effects */ - UNI_OKTARP, /* arpeggio */ - - UNI_LAST + /* Simple note */ + UNI_NOTE = 1, + /* Instrument change */ + UNI_INSTRUMENT, + /* Protracker effects */ + UNI_PTEFFECT0, /* arpeggio */ + UNI_PTEFFECT1, /* porta up */ + UNI_PTEFFECT2, /* porta down */ + UNI_PTEFFECT3, /* porta to note */ + UNI_PTEFFECT4, /* vibrato */ + UNI_PTEFFECT5, /* dual effect 3+A */ + UNI_PTEFFECT6, /* dual effect 4+A */ + UNI_PTEFFECT7, /* tremolo */ + UNI_PTEFFECT8, /* pan */ + UNI_PTEFFECT9, /* sample offset */ + UNI_PTEFFECTA, /* volume slide */ + UNI_PTEFFECTB, /* pattern jump */ + UNI_PTEFFECTC, /* set volume */ + UNI_PTEFFECTD, /* pattern break */ + UNI_PTEFFECTE, /* extended effects */ + UNI_PTEFFECTF, /* set speed */ + /* Scream Tracker effects */ + UNI_S3MEFFECTA, /* set speed */ + UNI_S3MEFFECTD, /* volume slide */ + UNI_S3MEFFECTE, /* porta down */ + UNI_S3MEFFECTF, /* porta up */ + UNI_S3MEFFECTI, /* tremor */ + UNI_S3MEFFECTQ, /* retrig */ + UNI_S3MEFFECTR, /* tremolo */ + UNI_S3MEFFECTT, /* set tempo */ + UNI_S3MEFFECTU, /* fine vibrato */ + UNI_KEYOFF, /* note off */ + /* Fast Tracker effects */ + UNI_KEYFADE, /* note fade */ + UNI_VOLEFFECTS, /* volume column effects */ + UNI_XMEFFECT4, /* vibrato */ + UNI_XMEFFECT6, /* dual effect 4+A */ + UNI_XMEFFECTA, /* volume slide */ + UNI_XMEFFECTE1, /* fine porta up */ + UNI_XMEFFECTE2, /* fine porta down */ + UNI_XMEFFECTEA, /* fine volume slide up */ + UNI_XMEFFECTEB, /* fine volume slide down */ + UNI_XMEFFECTG, /* set global volume */ + UNI_XMEFFECTH, /* global volume slide */ + UNI_XMEFFECTL, /* set envelope position */ + UNI_XMEFFECTP, /* pan slide */ + UNI_XMEFFECTX1, /* extra fine porta up */ + UNI_XMEFFECTX2, /* extra fine porta down */ + /* Impulse Tracker effects */ + UNI_ITEFFECTG, /* porta to note */ + UNI_ITEFFECTH, /* vibrato */ + UNI_ITEFFECTI, /* tremor (xy not incremented) */ + UNI_ITEFFECTM, /* set channel volume */ + UNI_ITEFFECTN, /* slide / fineslide channel volume */ + UNI_ITEFFECTP, /* slide / fineslide channel panning */ + UNI_ITEFFECTT, /* slide tempo */ + UNI_ITEFFECTU, /* fine vibrato */ + UNI_ITEFFECTW, /* slide / fineslide global volume */ + UNI_ITEFFECTY, /* panbrello */ + UNI_ITEFFECTZ, /* resonant filters */ + UNI_ITEFFECTS0, + /* UltraTracker effects */ + UNI_ULTEFFECT9, /* Sample fine offset */ + /* OctaMED effects */ + UNI_MEDSPEED, + UNI_MEDEFFECTF1,/* play note twice */ + UNI_MEDEFFECTF2,/* delay note */ + UNI_MEDEFFECTF3,/* play note three times */ + /* Oktalyzer effects */ + UNI_OKTARP, /* arpeggio */ + + UNI_LAST }; -extern UWORD unioperands[UNI_LAST]; +extern const UWORD unioperands[UNI_LAST]; /* IT / S3M Extended SS effects: */ enum { - SS_GLISSANDO = 1, - SS_FINETUNE, - SS_VIBWAVE, - SS_TREMWAVE, - SS_PANWAVE, - SS_FRAMEDELAY, - SS_S7EFFECTS, - SS_PANNING, - SS_SURROUND, - SS_HIOFFSET, - SS_PATLOOP, - SS_NOTECUT, - SS_NOTEDELAY, - SS_PATDELAY + SS_GLISSANDO = 1, + SS_FINETUNE, + SS_VIBWAVE, + SS_TREMWAVE, + SS_PANWAVE, + SS_FRAMEDELAY, + SS_S7EFFECTS, + SS_PANNING, + SS_SURROUND, + SS_HIOFFSET, + SS_PATLOOP, + SS_NOTECUT, + SS_NOTEDELAY, + SS_PATDELAY }; /* IT Volume column effects */ enum { - VOL_VOLUME = 1, - VOL_PANNING, - VOL_VOLSLIDE, - VOL_PITCHSLIDEDN, - VOL_PITCHSLIDEUP, - VOL_PORTAMENTO, - VOL_VIBRATO + VOL_VOLUME = 1, + VOL_PANNING, + VOL_VOLSLIDE, + VOL_PITCHSLIDEDN, + VOL_PITCHSLIDEUP, + VOL_PORTAMENTO, + VOL_VIBRATO }; /* IT resonant filter information */ -#define UF_MAXMACRO 0x10 -#define UF_MAXFILTER 0x100 +#define UF_MAXMACRO 0x10 +#define UF_MAXFILTER 0x100 -#define FILT_CUT 0x80 -#define FILT_RESONANT 0x81 +#define FILT_CUT 0x80 +#define FILT_RESONANT 0x81 typedef struct FILTER { UBYTE filter,inf; @@ -401,163 +427,163 @@ typedef struct FILTER { /*========== Playing */ -#define POS_NONE (-2) /* no loop position defined */ +#define POS_NONE (-2) /* no loop position defined */ -#define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */ +#define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */ typedef struct ENVPR { - UBYTE flg; /* envelope flag */ - UBYTE pts; /* number of envelope points */ - UBYTE susbeg; /* envelope sustain index begin */ - UBYTE susend; /* envelope sustain index end */ - UBYTE beg; /* envelope loop begin */ - UBYTE end; /* envelope loop end */ - SWORD p; /* current envelope counter */ - UWORD a; /* envelope index a */ - UWORD b; /* envelope index b */ - ENVPT* env; /* envelope points */ + UBYTE flg; /* envelope flag */ + UBYTE pts; /* number of envelope points */ + UBYTE susbeg; /* envelope sustain index begin */ + UBYTE susend; /* envelope sustain index end */ + UBYTE beg; /* envelope loop begin */ + UBYTE end; /* envelope loop end */ + SWORD p; /* current envelope counter */ + UWORD a; /* envelope index a */ + UWORD b; /* envelope index b */ + ENVPT* env; /* envelope points */ } ENVPR; typedef struct MP_CHANNEL { - INSTRUMENT* i; - SAMPLE* s; - UBYTE sample; /* which sample number */ - UBYTE note; /* the audible note as heard, direct rep of period */ - SWORD outvolume; /* output volume (vol + sampcol + instvol) */ - SBYTE chanvol; /* channel's "global" volume */ - UWORD fadevol; /* fading volume rate */ - SWORD panning; /* panning position */ - UBYTE kick; /* if true = sample has to be restarted */ - UBYTE kick_flag; /* kick has been true */ - UWORD period; /* period to play the sample at */ - UBYTE nna; /* New note action type + master/slave flags */ - - UBYTE volflg; /* volume envelope settings */ - UBYTE panflg; /* panning envelope settings */ - UBYTE pitflg; /* pitch envelope settings */ - - UBYTE keyoff; /* if true = fade out and stuff */ - SWORD handle; /* which sample-handle */ - UBYTE notedelay; /* (used for note delay) */ - SLONG start; /* The starting byte index in the sample */ + INSTRUMENT* i; + SAMPLE *s; + UBYTE sample; /* which sample number */ + UBYTE note; /* the audible note as heard, direct rep of period */ + SWORD outvolume; /* output volume (vol + sampcol + instvol) */ + SBYTE chanvol; /* channel's "global" volume */ + UWORD fadevol; /* fading volume rate */ + SWORD panning; /* panning position */ + UBYTE kick; /* if true = sample has to be restarted */ + UBYTE kick_flag; /* kick has been true */ + UWORD period; /* period to play the sample at */ + UBYTE nna; /* New note action type + master/slave flags */ + + UBYTE volflg; /* volume envelope settings */ + UBYTE panflg; /* panning envelope settings */ + UBYTE pitflg; /* pitch envelope settings */ + + UBYTE keyoff; /* if true = fade out and stuff */ + SWORD handle; /* which sample-handle */ + UBYTE notedelay; /* (used for note delay) */ + SLONG start; /* The starting byte index in the sample */ } MP_CHANNEL; typedef struct MP_CONTROL { - struct MP_CHANNEL main; - - struct MP_VOICE *slave; /* Audio Slave of current effects control channel */ - - UBYTE slavechn; /* Audio Slave of current effects control channel */ - UBYTE muted; /* if set, channel not played */ - UWORD ultoffset; /* fine sample offset memory */ - UBYTE anote; /* the note that indexes the audible */ - UBYTE oldnote; - SWORD ownper; - SWORD ownvol; - UBYTE dca; /* duplicate check action */ - UBYTE dct; /* duplicate check type */ - UBYTE* row; /* row currently playing on this channel */ - SBYTE retrig; /* retrig value (0 means don't retrig) */ - ULONG speed; /* what finetune to use */ - SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */ - - SWORD tmpvolume; /* tmp volume */ - UWORD tmpperiod; /* tmp period */ - UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */ - - UBYTE arpmem; /* arpeggio command memory */ - UBYTE pansspd; /* panslide speed */ - UWORD slidespeed; - UWORD portspeed; /* noteslide speed (toneportamento) */ - - UBYTE s3mtremor; /* s3m tremor (effect I) counter */ - UBYTE s3mtronof; /* s3m tremor ontime/offtime */ - UBYTE s3mvolslide; /* last used volslide */ - SBYTE sliding; - UBYTE s3mrtgspeed; /* last used retrig speed */ - UBYTE s3mrtgslide; /* last used retrig slide */ - - UBYTE glissando; /* glissando (0 means off) */ - UBYTE wavecontrol; - - SBYTE vibpos; /* current vibrato position */ - UBYTE vibspd; /* "" speed */ - UBYTE vibdepth; /* "" depth */ - - SBYTE trmpos; /* current tremolo position */ - UBYTE trmspd; /* "" speed */ - UBYTE trmdepth; /* "" depth */ - - UBYTE fslideupspd; - UBYTE fslidednspd; - UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ - UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ - UBYTE ffportupspd; /* fx X1 (extra fine portamento up) data */ - UBYTE ffportdnspd; /* fx X2 (extra fine portamento dn) data */ - - ULONG hioffset; /* last used high order of sample offset */ - UWORD soffset; /* last used low order of sample-offset (effect 9) */ - - UBYTE sseffect; /* last used Sxx effect */ - UBYTE ssdata; /* last used Sxx data info */ - UBYTE chanvolslide; /* last used channel volume slide */ - - UBYTE panbwave; /* current panbrello waveform */ - UBYTE panbpos; /* current panbrello position */ - SBYTE panbspd; /* "" speed */ - UBYTE panbdepth; /* "" depth */ - - UWORD newsamp; /* set to 1 upon a sample / inst change */ - UBYTE voleffect; /* Volume Column Effect Memory as used by IT */ - UBYTE voldata; /* Volume Column Data Memory */ - - SWORD pat_reppos; /* patternloop position */ - UWORD pat_repcnt; /* times to loop */ + struct MP_CHANNEL main; + + struct MP_VOICE* slave; /* Audio Slave of current effects control channel */ + + UBYTE slavechn; /* Audio Slave of current effects control channel */ + UBYTE muted; /* if set, channel not played */ + UWORD ultoffset; /* fine sample offset memory */ + UBYTE anote; /* the note that indexes the audible */ + UBYTE oldnote; + SWORD ownper; + SWORD ownvol; + UBYTE dca; /* duplicate check action */ + UBYTE dct; /* duplicate check type */ + UBYTE* row; /* row currently playing on this channel */ + SBYTE retrig; /* retrig value (0 means don't retrig) */ + ULONG speed; /* what finetune to use */ + SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */ + + SWORD tmpvolume; /* tmp volume */ + UWORD tmpperiod; /* tmp period */ + UWORD wantedperiod;/* period to slide to (with effect 3 or 5) */ + + UBYTE arpmem; /* arpeggio command memory */ + UBYTE pansspd; /* panslide speed */ + UWORD slidespeed; + UWORD portspeed; /* noteslide speed (toneportamento) */ + + UBYTE s3mtremor; /* s3m tremor (effect I) counter */ + UBYTE s3mtronof; /* s3m tremor ontime/offtime */ + UBYTE s3mvolslide;/* last used volslide */ + SBYTE sliding; + UBYTE s3mrtgspeed;/* last used retrig speed */ + UBYTE s3mrtgslide;/* last used retrig slide */ + + UBYTE glissando; /* glissando (0 means off) */ + UBYTE wavecontrol; + + SBYTE vibpos; /* current vibrato position */ + UBYTE vibspd; /* "" speed */ + UBYTE vibdepth; /* "" depth */ + + SBYTE trmpos; /* current tremolo position */ + UBYTE trmspd; /* "" speed */ + UBYTE trmdepth; /* "" depth */ + + UBYTE fslideupspd; + UBYTE fslidednspd; + UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ + UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ + UBYTE ffportupspd;/* fx X1 (extra fine portamento up) data */ + UBYTE ffportdnspd;/* fx X2 (extra fine portamento dn) data */ + + ULONG hioffset; /* last used high order of sample offset */ + UWORD soffset; /* last used low order of sample-offset (effect 9) */ + + UBYTE sseffect; /* last used Sxx effect */ + UBYTE ssdata; /* last used Sxx data info */ + UBYTE chanvolslide;/* last used channel volume slide */ + + UBYTE panbwave; /* current panbrello waveform */ + UBYTE panbpos; /* current panbrello position */ + SBYTE panbspd; /* "" speed */ + UBYTE panbdepth; /* "" depth */ + + UWORD newsamp; /* set to 1 upon a sample / inst change */ + UBYTE voleffect; /* Volume Column Effect Memory as used by IT */ + UBYTE voldata; /* Volume Column Data Memory */ + + SWORD pat_reppos; /* patternloop position */ + UWORD pat_repcnt; /* times to loop */ } MP_CONTROL; /* Used by NNA only player (audio control. AUDTMP is used for full effects control). */ typedef struct MP_VOICE { - struct MP_CHANNEL main; + struct MP_CHANNEL main; - ENVPR venv; - ENVPR penv; - ENVPR cenv; + ENVPR venv; + ENVPR penv; + ENVPR cenv; - UWORD avibpos; /* autovibrato pos */ - UWORD aswppos; /* autovibrato sweep pos */ + UWORD avibpos; /* autovibrato pos */ + UWORD aswppos; /* autovibrato sweep pos */ - ULONG totalvol; /* total volume of channel (before global mixings) */ + ULONG totalvol; /* total volume of channel (before global mixings) */ - int mflag; - SWORD masterchn; - UWORD masterperiod; + int mflag; + SWORD masterchn; + UWORD masterperiod; - MP_CONTROL* master; /* index of "master" effects channel */ + MP_CONTROL* master; /* index of "master" effects channel */ } MP_VOICE; /*========== Loaders */ typedef struct MLOADER { -struct MLOADER* next; - CHAR* type; - CHAR* version; - int (*Init)(void); - int (*Test)(void); - int (*Load)(int); - void (*Cleanup)(void); - CHAR* (*LoadTitle)(void); + struct MLOADER* next; + const CHAR* type; + const CHAR* version; + int (*Init)(void); + int (*Test)(void); + int (*Load)(int); + void (*Cleanup)(void); + CHAR* (*LoadTitle)(void); } MLOADER; /* internal loader variables */ extern MREADER* modreader; -extern UWORD finetune[16]; extern MODULE of; /* static unimod loading space */ -extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */ +extern const UWORD finetune[16]; +extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */ extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ extern UBYTE* poslookup; /* lookup table for pattern jumps after - blank pattern removal */ + blank pattern removal */ extern UWORD poslookupcnt; extern UWORD* origpositions; @@ -577,8 +603,7 @@ extern int AllocPatterns(void); extern int AllocTracks(void); extern int AllocInstruments(void); extern int AllocSamples(void); -extern CHAR* DupStr(CHAR*,UWORD,int); -extern CHAR* StrDup(CHAR *s); +extern CHAR* DupStr(const CHAR*, UWORD, int); /* loader utility functions */ extern int* AllocLinear(void); @@ -588,28 +613,38 @@ extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int); extern void S3MIT_CreateOrders(int); /* flags for S3MIT_ProcessCmd */ -#define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */ -#define S3MIT_IT 2 /* behave as impulse tracker */ -#define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */ +#define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */ +#define S3MIT_IT 2 /* behave as impulse tracker */ +#define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */ /* used to convert c4spd to linear XM periods (IT and IMF loaders). */ extern UWORD getlinearperiod(UWORD,ULONG); extern ULONG getfrequency(UWORD,ULONG); /* loader shared data */ -#define STM_NTRACKERS 3 -extern CHAR *STM_Signatures[STM_NTRACKERS]; +#define STM_NTRACKERS 3 +extern const CHAR *STM_Signatures[STM_NTRACKERS]; /*========== Player interface */ -extern int Player_Init(MODULE*); +extern int Player_Init(MODULE*); extern void Player_Exit(MODULE*); extern void Player_HandleTick(void); +/*========== UnPackers */ + +typedef int (*MUNPACKER) (struct MREADER*, + void** /* unpacked data out */ , + long* /* unpacked data size */ ); +extern int PP20_Unpack(MREADER*, void**, long*); +extern int MMCMP_Unpack(MREADER*, void**, long*); +extern int XPK_Unpack(MREADER*, void**, long*); +extern int S404_Unpack(MREADER*, void**, long*); + /*========== Drivers */ /* max. number of handles a driver has to provide. (not strict) */ -#define MAXSAMPLEHANDLES 384 +#define MAXSAMPLEHANDLES 384 /* These variables can be changed at ANY time and results will be immediate */ extern UWORD md_bpm; /* current song / hardware BPM rate */ @@ -625,7 +660,7 @@ extern UBYTE md_softchn; /* number of software mixed voices */ /* This is for use by the hardware drivers only. It points to the registered tickhandler function. */ -extern void (*md_player)(void); +extern MikMod_player_t md_player; extern SWORD MD_SampleLoad(SAMPLOAD*,int); extern void MD_SampleUnload(SWORD); @@ -636,17 +671,17 @@ extern ULONG MD_SampleLength(int,SAMPLE*); extern void unsignedtoulaw(char *,int); /* Parameter extraction helper */ -extern CHAR *MD_GetAtom(CHAR*,CHAR*,int); +extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, int); /* Internal software mixer stuff */ extern void VC_SetupPointers(void); -extern int VC1_Init(void); -extern int VC2_Init(void); +extern int VC1_Init(void); +extern int VC2_Init(void); -#if defined(unix) || defined(__APPLE__) && defined(__MACH__) +#if (MIKMOD_UNIX) /* POSIX helper functions */ -extern int MD_Access(CHAR *); -extern int MD_DropPrivileges(void); +extern int MD_Access(const CHAR *); +extern int MD_DropPrivileges(void); #endif /* Macro to define a missing driver, yet allowing binaries to dynamically link @@ -659,9 +694,9 @@ extern void _mm_registerdriver(struct MDRIVER*); extern void _mm_registerloader(struct MLOADER*); extern int MikMod_Active_internal(void); extern void MikMod_DisableOutput_internal(void); -extern int MikMod_EnableOutput_internal(void); +extern int MikMod_EnableOutput_internal(void); extern void MikMod_Exit_internal(void); -extern int MikMod_SetNumVoices_internal(int,int); +extern int MikMod_SetNumVoices_internal(int,int); extern void Player_Exit_internal(MODULE*); extern void Player_Stop_internal(void); extern int Player_Paused_internal(void); @@ -673,6 +708,15 @@ extern void Voice_SetVolume_internal(SBYTE,UWORD); extern void Voice_Stop_internal(SBYTE); extern int Voice_Stopped_internal(SBYTE); +extern int VC1_PlayStart(void); +extern int VC2_PlayStart(void); +extern void VC1_PlayStop(void); +extern void VC2_PlayStop(void); +extern int VC1_SetNumVoices(void); +extern int VC2_SetNumVoices(void); + +extern MikMod_callback_t vc_callback; + #ifdef __cplusplus } #endif @@ -680,30 +724,36 @@ extern int Voice_Stopped_internal(SBYTE); /*========== SIMD mixing routines */ #undef HAVE_ALTIVEC #undef HAVE_SSE2 +#if defined(MIKMOD_SIMD) -#if defined(__APPLE__) && !defined (__i386__) - -#if defined __VEC__ && !(defined(__GNUC__) && (__GNUC__ < 3)) +#if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3)) #define HAVE_ALTIVEC -#endif // __VEC__ -#elif defined WIN32 || defined __WIN64 || (defined __APPLE__ && defined (__i386__) && defined __VEC__) - -// FIXME: emmintrin.h requires VC6 processor pack or VC2003+ +#elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */ #define HAVE_SSE2 -/* Fixes couples warnings */ -#ifdef _MSC_VER +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64)) +/* FIXME: emmintrin.h requires VC6 processor pack or VC2003+ */ +#define HAVE_SSE2 +/* avoid some warnings */ #pragma warning(disable:4761) #pragma warning(disable:4391) #pragma warning(disable:4244) -#endif -#endif -// TODO: Test for GCC Linux + +#endif /* AltiVec/SSE2 */ +#endif /* MIKMOD_SIMD */ /*========== SIMD mixing helper functions =============*/ -#define IS_ALIGNED_16(ptr) (!(((intptr_t)(ptr)) & 15)) +#if defined(_WIN64) +# if defined(_MSC_VER) +# define IS_ALIGNED_16(ptr) (!((__int64)(ptr) & 15i64)) +# else /* GCC, LCC, .. */ +# define IS_ALIGNED_16(ptr) (!((long long)(ptr) & 15LL)) +# endif +#else /* long cast should be OK for all else */ +#define IS_ALIGNED_16(ptr) (!((long)(ptr) & 15L)) +#endif /* Altivec helper function */ #if defined HAVE_ALTIVEC @@ -715,33 +765,29 @@ extern int Voice_Stopped_internal(SBYTE); #include #endif -// Helper functions +/* Helper functions */ -// Set single float across the four values -static inline vector float vec_mul( const vector float a, const vector float b) -{ +/* Set single float across the four values */ +static inline vector float vec_mul(const vector float a, const vector float b) { return vec_madd(a, b, (const vector float)(0.f)); } -// Set single float across the four values -static inline vector float vec_load_ps1(const float *pF ) -{ +/* Set single float across the four values */ +static inline vector float vec_load_ps1(const float *pF) { vector float data = vec_lde(0, pF); return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0); } -// Set vector to 0 -static inline const vector float vec_setzero() -{ - return (const vector float) (0.); +/* Set vector to 0 */ +static inline vector float vec_setzero() { + return (vector float) (0.); } -static inline vector signed char vec_set1_8(unsigned char splatchar) -{ - vector unsigned char splatmap = vec_lvsl(0, &splatchar); - vector unsigned char result = vec_lde(0, &splatchar); - splatmap = vec_splat(splatmap, 0); - return (vector signed char)vec_perm(result, result, splatmap); +static inline vector signed char vec_set1_8(unsigned char splatchar) { + vector unsigned char splatmap = vec_lvsl(0, &splatchar); + vector unsigned char result = vec_lde(0, &splatchar); + splatmap = vec_splat(splatmap, 0); + return (vector signed char)vec_perm(result, result, splatmap); } #define PERM_A0 0x00,0x01,0x02,0x03 @@ -753,48 +799,45 @@ static inline vector signed char vec_set1_8(unsigned char splatchar) #define PERM_B2 0x18,0x19,0x1A,0x1B #define PERM_B3 0x1C,0x1D,0x1E,0x1F -// Equivalent to _mm_unpacklo_epi32 -static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) -{ +/* Equivalent to _mm_unpacklo_epi32 */ +static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) { return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1)); } -// Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). -static inline vector signed int vec_hiqq(vector signed int a) -{ +/* Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). */ +static inline vector signed int vec_hiqq(vector signed int a) { vector signed int b = vec_splat_s32(0); return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3)); } -// vec_sra is max +15. We have to do in two times ... -#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); -#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)); -#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)); -#define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT+16-16)); -#define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste); -#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); +/* vec_sra is max +15. We have to do in two times ... */ +#define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul); +#define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0)); +#define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8)); +#define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16)); +#define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste); +#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); #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste); #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr) #elif defined HAVE_SSE2 -/* SSE2 helper function */ - #include -static __inline __m128i mm_hiqq(const __m128i a) -{ - return _mm_srli_si128(a, 8); // get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). +/* SSE2 helper function */ + +static __inline __m128i mm_hiqq(const __m128i a) { + return _mm_srli_si128(a, 8); /* get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). */ } /* 128-bit mixing macros */ -#define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT+16-size); -#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); +#define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT+16-size); +#define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT-size)), mul); #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0) #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8) #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16) -#define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2)); -#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))); +#define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2)); +#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))); #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1); #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr) #define simd_m128i __m128i @@ -802,7 +845,25 @@ static __inline __m128i mm_hiqq(const __m128i a) #endif +#if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC) +/* MikMod_amalloc() returns a 16 byte aligned zero-filled + memory in SIMD-enabled builds. + - the returned memory can be freed with MikMod_afree() + - the returned memory CAN NOT be realloc()'ed safely. */ +#ifdef __cplusplus +extern "C" { +#endif +void* MikMod_amalloc(size_t); +void MikMod_afree(void *); /* frees if ptr != NULL */ +#ifdef __cplusplus +} +#endif +#else /* NO SIMD */ +#define MikMod_amalloc MikMod_malloc +#define MikMod_afree MikMod_free #endif +#endif /* _MIKMOD_INTERNALS_H */ + /* ex:set ts=4: */ -- cgit v1.2.3