1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Solomon Peachy 2020-08-08 21:56:15 -04:00
parent 8c7780bafc
commit b4e70422a3
43 changed files with 5072 additions and 2802 deletions

View file

@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@ -20,7 +20,7 @@
/*==============================================================================
$Id: load_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $
$Id$
Fasttracker (XM) module loader
@ -59,7 +59,7 @@ typedef struct XMHEADER {
UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */
UWORD numpat; /* Number of patterns (max 256) */
UWORD numins; /* Number of instruments (max 128) */
UWORD flags;
UWORD flags;
UWORD tempo; /* Default tempo */
UWORD bpm; /* Default BPM */
UBYTE orders[256]; /* Pattern order table */
@ -129,7 +129,7 @@ typedef struct XMNOTE {
static XMNOTE *xmpat=NULL;
static XMHEADER *mh=NULL;
/* increment unit for sample array MikMod_reallocation */
/* increment unit for sample array reallocation */
#define XM_SMPINCR 64
static ULONG *nextwav=NULL;
static XMWAVHEADER *wh=NULL,*s=NULL;
@ -155,6 +155,7 @@ static int XM_Init(void)
static void XM_Cleanup(void)
{
MikMod_free(mh);
mh=NULL;
}
static int XM_ReadNote(XMNOTE* n)
@ -359,8 +360,8 @@ static int LoadPatterns(int dummypat)
return 0;
/* when packsize is 0, don't try to load a pattern.. it's empty. */
if(ph.packsize)
for(u=0;u<ph.numrows;u++)
if(ph.packsize)
for(u=0;u<ph.numrows;u++)
for(v=0;v<of.numchn;v++) {
if(!ph.packsize) break;
@ -443,11 +444,17 @@ static void FixEnvelope(ENVPT *cur, int pts)
static int LoadInstruments(void)
{
int t,u, ck;
long filend,ck;
int t,u;
INSTRUMENT *d;
ULONG next=0;
UWORD wavcnt=0;
ck = _mm_ftell(modreader);
_mm_fseek(modreader,0,SEEK_END);
filend = _mm_ftell(modreader);
_mm_fseek(modreader,ck,SEEK_SET);
if(!AllocInstruments()) return 0;
d=of.instruments;
for(t=0;t<of.numins;t++,d++) {
@ -461,12 +468,9 @@ static int LoadInstruments(void)
ih.size = _mm_read_I_ULONG(modreader);
headend += ih.size;
ck = _mm_ftell(modreader);
_mm_fseek(modreader,0,SEEK_END);
if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
_mm_fseek(modreader,ck,SEEK_SET);
if ((headend<0) || (filend<headend) || (headend<ck)) {
break;
}
_mm_fseek(modreader,ck,SEEK_SET);
_mm_read_string(ih.name, 22, modreader);
ih.type = _mm_read_UBYTE(modreader);
ih.numsmp = _mm_read_I_UWORD(modreader);
@ -500,7 +504,11 @@ static int LoadInstruments(void)
/* read the remainder of the header
(2 bytes for 1.03, 22 for 1.04) */
if (headend>=_mm_ftell(modreader)) for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader);
if (headend>=_mm_ftell(modreader)) {
for(u=headend-_mm_ftell(modreader);u;u--) {
_mm_skip_BYTE(modreader);
}
}
/* we can't trust the envelope point count here, as some
modules have incorrect values (K_OSPACE.XM reports 32 volume
@ -509,8 +517,8 @@ static int LoadInstruments(void)
if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
if(wh) { MikMod_free(wh);wh=NULL; }
MikMod_free(nextwav);nextwav=NULL;
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@ -519,7 +527,7 @@ static int LoadInstruments(void)
d->samplenumber[u]=pth.what[u]+of.numsmp;
d->volfade = pth.volfade;
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define XM_ProcessEnvelope(name) \
for (u = 0; u < (XMENVCNT >> 1); u++) { \
d-> name##env[u].pos = pth. name##env[u << 1]; \
@ -560,7 +568,7 @@ static int LoadInstruments(void)
\
if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
d-> name/**/flg&=~EF_ON
#endif
#endif
XM_ProcessEnvelope(vol);
XM_ProcessEnvelope(pan);
@ -577,15 +585,23 @@ static int LoadInstruments(void)
everything over */
if(mh->version>0x0103) next = 0;
for(u=0;u<ih.numsmp;u++,s++) {
/* XM sample header is 40 bytes: make sure we won't hit EOF */
/* Note: last instrument is at the end of file in version 0x0104 */
if(_mm_ftell(modreader)+40>filend) {
MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
/* Allocate more room for sample information if necessary */
if(of.numsmp+u==wavcnt) {
wavcnt+=XM_SMPINCR;
if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
if(wh) { MikMod_free(wh);wh=NULL; }
if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY;
return 0;
}
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
MikMod_free(nextwav);nextwav=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY;
return 0;
@ -610,13 +626,6 @@ static int LoadInstruments(void)
nextwav[of.numsmp+u]=next;
next+=s->length;
if(_mm_eof(modreader)) {
MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
}
if(mh->version>0x0103) {
@ -628,15 +637,15 @@ static int LoadInstruments(void)
} else {
/* read the remainder of the header */
ck = _mm_ftell(modreader);
_mm_fseek(modreader,0,SEEK_END);
if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
_mm_fseek(modreader,ck,SEEK_SET);
if ((headend<0) || (filend<headend) || (headend<ck)) {
break;
}
_mm_fseek(modreader,ck,SEEK_SET);
for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader);
for(u=headend-_mm_ftell(modreader);u;u--) {
_mm_skip_BYTE(modreader);
}
if(_mm_eof(modreader)) {
/* last instrument is at the end of file in version 0x0104 */
if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) {
MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
@ -648,8 +657,8 @@ static int LoadInstruments(void)
/* sanity check */
if(!of.numsmp) {
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
if(wh) { MikMod_free(wh);wh=NULL; }
MikMod_free(nextwav);nextwav=NULL;
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@ -664,17 +673,15 @@ static int XM_Load(int curious)
int t,u;
int dummypat=0;
char tracker[21],modtype[60];
(void)curious;
(void)curious;
/* try to read module header */
_mm_read_string(mh->id,17,modreader);
_mm_read_string(mh->songname,21,modreader);
_mm_read_string(mh->trackername,20,modreader);
mh->version =_mm_read_I_UWORD(modreader);
if((mh->version<0x102)||(mh->version>0x104)) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
if(mh->version < 0x102 || mh->version > 0x104)
goto bad_xm;
mh->headersize =_mm_read_I_ULONG(modreader);
mh->songlength =_mm_read_I_UWORD(modreader);
mh->restart =_mm_read_I_UWORD(modreader);
@ -684,23 +691,25 @@ static int XM_Load(int curious)
mh->flags =_mm_read_I_UWORD(modreader);
mh->tempo =_mm_read_I_UWORD(modreader);
mh->bpm =_mm_read_I_UWORD(modreader);
if(!mh->bpm) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
_mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_HEADER;
return 0;
}
if(mh->numchn > 64) goto bad_xm;
if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255)
goto bad_xm;
if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256)
goto bad_xm;
if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255)
goto bad_xm;
/* _mm_read_UBYTES(mh->orders,256,modreader);*/
/* _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/
_mm_read_UBYTES(mh->orders,mh->songlength,modreader);
if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader))
goto bad_hdr;
/* set module variables */
of.initspeed = mh->tempo;
of.initspeed = mh->tempo;
of.inittempo = mh->bpm;
strncpy(tracker,mh->trackername,20);tracker[20]=0;
for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0;
for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0;
/* some modules have the tracker name empty */
if (!tracker[0])
strcpy(tracker,"Unknown tracker");
@ -712,7 +721,7 @@ static int XM_Load(int curious)
sprintf(modtype,"%s (XM format %d.%02d)",
tracker,mh->version>>8,mh->version&0xff);
#endif
of.modtype = StrDup(modtype);
of.modtype = MikMod_strdup(modtype);
of.numchn = mh->numchn;
of.numpat = mh->numpat;
of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */
@ -720,8 +729,7 @@ static int XM_Load(int curious)
of.numpos = mh->songlength; /* copy the songlength */
of.reppos = mh->restart<mh->songlength?mh->restart:0;
of.numins = mh->numins;
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS |
UF_PANNING;
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING;
if(mh->flags&1) of.flags |= UF_LINEAR;
of.bpmlimit = 32;
@ -802,16 +810,19 @@ static int XM_Load(int curious)
MikMod_free(wh);MikMod_free(nextwav);
wh=NULL;nextwav=NULL;
return 1;
bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0;
bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0;
}
static CHAR *XM_LoadTitle(void)
{
CHAR s[21];
CHAR str[21];
_mm_fseek(modreader,17,SEEK_SET);
if(!_mm_read_UBYTES(s,21,modreader)) return NULL;
if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
return(DupStr(s,21,1));
return(DupStr(str,21,1));
}
/*========== Loader information */