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/load_it.c | 184 ++++++++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 78 deletions(-) (limited to 'apps/plugins/mikmod/load_it.c') diff --git a/apps/plugins/mikmod/load_it.c b/apps/plugins/mikmod/load_it.c index c48d126f77..c1e257fd97 100644 --- a/apps/plugins/mikmod/load_it.c +++ b/apps/plugins/mikmod/load_it.c @@ -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_it.c,v 1.4 2010/01/12 03:30:32 realtech Exp $ + $Id$ Impulse tracker (IT) module loader @@ -45,7 +45,6 @@ #ifdef SUNOS extern int fprintf(FILE *, const char *, ...); -extern int toupper(int); #endif /*========== Module structure */ @@ -67,7 +66,7 @@ typedef struct ITHEADER { UBYTE initspeed; UBYTE inittempo; UBYTE pansep; /* panning separation between channels */ - UBYTE zerobyte; + UBYTE zerobyte; UWORD msglength; ULONG msgoffset; UBYTE blank02[4]; @@ -107,19 +106,19 @@ typedef struct ITINSTHEADER { CHAR filename[12]; /* (char) Instrument filename */ UBYTE zerobyte; /* (byte) Instrument type (always 0) */ UBYTE volflg; - UBYTE volpts; + UBYTE volpts; UBYTE volbeg; /* (byte) Volume loop start (node) */ UBYTE volend; /* (byte) Volume loop end (node) */ UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */ UBYTE volsusend; /* (byte) Volume Sustain end (node) */ UBYTE panflg; - UBYTE panpts; + UBYTE panpts; UBYTE panbeg; /* (byte) channel loop start (node) */ UBYTE panend; /* (byte) channel loop end (node) */ UBYTE pansusbeg; /* (byte) channel sustain begin (node) */ UBYTE pansusend; /* (byte) channel Sustain end (node) */ UBYTE pitflg; - UBYTE pitpts; + UBYTE pitpts; UBYTE pitbeg; /* (byte) pitch loop start (node) */ UBYTE pitend; /* (byte) pitch loop end (node) */ UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */ @@ -149,7 +148,7 @@ typedef struct ITINSTHEADER { UWORD pantick[ITENVCNT]; /* tick value of panning nodes */ SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */ UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */ -} ITINSTHEADER; +} ITINSTHEADER; /* unpacked note */ @@ -166,8 +165,8 @@ static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */ static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ static int numtrk=0; static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ - -static CHAR* IT_Version[]={ + +static const CHAR* IT_Version[]={ "ImpulseTracker . ", "Compressed ImpulseTracker . ", "ImpulseTracker 2.14p3", @@ -177,7 +176,7 @@ static CHAR* IT_Version[]={ }; /* table for porta-to-note command within volume/panning column */ -static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; +static const UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; /*========== Loader code */ @@ -212,40 +211,48 @@ static void IT_Cleanup(void) MikMod_free(last); MikMod_free(paraptr); MikMod_free(origpositions); + mh=NULL; + poslookup=NULL; + itpat=NULL; + mask=NULL; + last=NULL; + paraptr=NULL; + origpositions=NULL; } /* Because so many IT files have 64 channels as the set number used, but really only use far less (usually from 8 to 24 still), I had to make this function, which determines the number of channels that are actually USED by a pattern. - + NOTE: You must first seek to the file location of the pattern before calling - this procedure. + this procedure. - Returns 1 on error + Returns 0 on error */ static int IT_GetNumChannels(UWORD patrows) { int row=0,flag,ch; do { - if((flag=_mm_read_UBYTE(modreader))==EOF) { + if(_mm_eof(modreader)) { _mm_errno=MMERR_LOADING_PATTERN; - return 1; + return 0; } + flag=_mm_read_UBYTE(modreader); if(!flag) row++; else { ch=(flag-1)&63; remap[ch]=0; if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); - if(mask[ch]&1) (void)_mm_read_UBYTE(modreader); - if(mask[ch]&2) (void)_mm_read_UBYTE(modreader); - if(mask[ch]&4) (void)_mm_read_UBYTE(modreader); - if(mask[ch]&8) { (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); } + if(mask[ch]&1) _mm_skip_BYTE(modreader); + if(mask[ch]&2) _mm_skip_BYTE(modreader); + if(mask[ch]&4) _mm_skip_BYTE(modreader); + if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); } } } while(row ite) { /* malformed file */ + _mm_errno = MMERR_NOT_A_MODULE; + return 0; + } + } else + { n=l=&dummy; + blah = 0; + m=(UBYTE*)&blah; + } - if(flag&128) mask[ch]=_mm_read_UBYTE(modreader); - if(mask[ch]&1) + if(flag&128) *m=_mm_read_UBYTE(modreader); + if(*m&1) /* convert IT note off to internal note off */ - if((l->note=n->note=_mm_read_UBYTE(modreader))==255) + if((l->note=n->note=_mm_read_UBYTE(modreader))==255) l->note=n->note=253; - if(mask[ch]&2) + if(*m&2) l->ins=n->ins=_mm_read_UBYTE(modreader); - if(mask[ch]&4) + if(*m&4) l->volpan=n->volpan=_mm_read_UBYTE(modreader); - if(mask[ch]&8) { + if(*m&8) { l->cmd=n->cmd=_mm_read_UBYTE(modreader); l->inf=n->inf=_mm_read_UBYTE(modreader); } - if(mask[ch]&16) + if(*m&16) n->note=l->note; - if(mask[ch]&32) + if(*m&32) n->ins=l->ins; - if(mask[ch]&64) + if(*m&64) n->volpan=l->volpan; - if(mask[ch]&128) { + if(*m&128) { n->cmd=l->cmd; n->inf=l->inf; } @@ -379,38 +399,39 @@ static int IT_ReadPattern(UWORD patrows) return 1; } -static void LoadMidiString(MREADER* modreader,CHAR* dest) +static void LoadMidiString(MREADER* r,CHAR* dest) { - CHAR *cur,*last; + CHAR *curp,*lastp; - _mm_read_UBYTES(dest,32,modreader); - cur=last=dest; + memset(dest,0,33*sizeof(CHAR));/* caller sends midiline[33] */ + _mm_read_UBYTES(dest,32,r); + curp=lastp=dest; /* remove blanks and uppercase all */ - while(*last) { - if(isalnum((int)*last)) *(cur++)=toupper((int)*last); - last++; + while(*lastp) { + if(isalnum((int)*lastp)) *(curp++)=toupper((int)*lastp); + lastp++; } - *cur=0; + *curp=0; } /* Load embedded midi information for resonant filters */ -static void IT_LoadMidiConfiguration(MREADER* modreader) +static void IT_LoadMidiConfiguration(MREADER* r) { int i; memset(filtermacros,0,sizeof(filtermacros)); memset(filtersettings,0,sizeof(filtersettings)); - if (modreader) { /* information is embedded in file */ + if (r) { /* information is embedded in file */ UWORD dat; CHAR midiline[33]; - dat=_mm_read_I_UWORD(modreader); - _mm_fseek(modreader,8*dat+0x120,SEEK_CUR); + dat=_mm_read_I_UWORD(r); + _mm_fseek(r,8*dat+0x120,SEEK_CUR); /* read midi macros */ for(i=0;iordnum > 256 || mh->insnum > 255 || mh->smpnum > 255 || mh->patnum > 255) { + _mm_errno=MMERR_NOT_A_MODULE; + return 0; + } /* set module variables */ of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ @@ -506,11 +531,11 @@ static int IT_Load(int curious) /* 2.16 : IT 2.14p3 with resonant filters */ /* 2.15 : IT 2.14p3 (improved compression) */ if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) - of.modtype=StrDup(IT_Version[mh->cmwt<0x214?4:5]); + of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?4:5]); else if (mh->cwt>=0x215) - of.modtype=StrDup(IT_Version[mh->cmwt<0x214?2:3]); + of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?2:3]); else { - of.modtype = StrDup(IT_Version[mh->cmwt<0x214?0:1]); + of.modtype = MikMod_strdup(IT_Version[mh->cmwt<0x214?0:1]); of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0'; of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; @@ -550,7 +575,7 @@ static int IT_Load(int curious) /* read the order data */ if(!AllocPositions(mh->ordnum)) return 0; - if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; + if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; for(t=0;tordnum;t++) { origpositions[t]=_mm_read_UBYTE(modreader); @@ -672,14 +697,14 @@ static int IT_Load(int curious) if(s.flag&2) q->flags|=SF_16BITS; if((s.flag&8)&&(mh->cwt>=0x214)) { q->flags|=SF_ITPACKED; - /* compressed=1; */ + /*compressed=1;*/ } if(s.flag&16) q->flags|=SF_LOOP; if(s.flag&64) q->flags|=SF_BIDI; if(mh->cwt>=0x200) { if(s.convert&1) q->flags|=SF_SIGNED; - if(s.convert&4) q->flags|=SF_DELTA; + if(s.convert&4) q->flags|=SF_DELTA; } q++; } @@ -726,7 +751,7 @@ static int IT_Load(int curious) ih.trkvers = _mm_read_I_UWORD(modreader); ih.numsmp = _mm_read_UBYTE(modreader); - (void)_mm_read_UBYTE(modreader); + _mm_skip_BYTE(modreader); _mm_read_string(ih.name,26,modreader); _mm_read_UBYTES(ih.blank01,6,modreader); _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); @@ -736,13 +761,15 @@ static int IT_Load(int curious) for(lp=0;lp ITENVCNT) \ + ih. name##pts = ITENVCNT; \ ih. name##beg =_mm_read_UBYTE(modreader); \ ih. name##end =_mm_read_UBYTE(modreader); \ ih. name##susbeg=_mm_read_UBYTE(modreader); \ @@ -751,11 +778,13 @@ static int IT_Load(int curious) ih. name##node[lp]=_mm_read_##type (modreader); \ ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \ } \ - (void)_mm_read_UBYTE(modreader) + _mm_skip_BYTE(modreader) #else #define IT_LoadEnvelope(name,type) \ ih. name/**/flg =_mm_read_UBYTE(modreader); \ ih. name/**/pts =_mm_read_UBYTE(modreader); \ + if (ih. name/**/pts > ITENVCNT) \ + ih. name/**/pts = ITENVCNT; \ ih. name/**/beg =_mm_read_UBYTE(modreader); \ ih. name/**/end =_mm_read_UBYTE(modreader); \ ih. name/**/susbeg=_mm_read_UBYTE(modreader); \ @@ -764,7 +793,7 @@ static int IT_Load(int curious) ih. name/**/node[lp]=_mm_read_/**/type (modreader); \ ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \ } \ - (void)_mm_read_UBYTE(modreader) + _mm_skip_BYTE(modreader) #endif IT_LoadEnvelope(vol,UBYTE); @@ -772,7 +801,7 @@ static int IT_Load(int curious) IT_LoadEnvelope(pit,SBYTE); #undef IT_LoadEnvelope } - + if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; @@ -791,10 +820,10 @@ static int IT_Load(int curious) if(ih.volflg&1) d->volflg|=EF_ON; if(ih.volflg&2) d->volflg|=EF_LOOP; - if(ih.volflg&4) d->volflg|=EF_SUSTAIN; + if(ih.volflg&4) d->volflg|=EF_SUSTAIN; /* XM conversion of IT envelope Array */ - d->volbeg = ih.volbeg; + d->volbeg = ih.volbeg; d->volend = ih.volend; d->volsusbeg = ih.volsusbeg; d->volsusend = ih.volsusend; @@ -807,7 +836,7 @@ static int IT_Load(int curious) d->volpts++; } else break; - } + } } else { d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2; if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN; @@ -827,7 +856,7 @@ static int IT_Load(int curious) d->rpanvar = ih.rpanvar; } -#if defined __STDC__ || defined _MSC_VER || defined MPW_C +#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C #define IT_ProcessEnvelope(name) \ if(ih. name##flg&1) d-> name##flg|=EF_ON; \ if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \ @@ -862,11 +891,7 @@ static int IT_Load(int curious) #endif IT_ProcessEnvelope(vol); - - // Secunia SA37775 - if (ih.volpts>= ENVPOINTS) - ih.volpts = ENVPOINTS-1; - + for(u=0;uvolenv[u].val=(ih.volnode[u]<<2); @@ -887,7 +912,7 @@ static int IT_Load(int curious) #ifdef MIKMOD_DEBUG { static int warn=0; - + if(!warn) fprintf(stderr, "\rFilter envelopes not supported yet\n"); warn=1; @@ -908,7 +933,7 @@ static int IT_Load(int curious) } } - d++; + d++; } } else if(of.flags & UF_LINEAR) { if(!AllocInstruments()) return 0; @@ -946,12 +971,12 @@ static int IT_Load(int curious) return 0; } _mm_read_I_ULONG(modreader); - if(IT_GetNumChannels(packlen)) return 0; + if(!IT_GetNumChannels(packlen)) return 0; } } /* give each of them a different number */ - for(t=0;tinsnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */ of.pattrows[t]=64; @@ -975,7 +1002,8 @@ static int IT_Load(int curious) } } else { _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET); - (void)_mm_read_I_UWORD(modreader); + packlen=_mm_read_I_UWORD(modreader); + (void)packlen; /* unused */ of.pattrows[t]=_mm_read_I_UWORD(modreader); _mm_read_I_ULONG(modreader); if(!IT_ReadPattern(of.pattrows[t])) return 0; @@ -991,7 +1019,7 @@ static CHAR *IT_LoadTitle(void) _mm_fseek(modreader,4,SEEK_SET); if(!_mm_read_UBYTES(s,26,modreader)) return NULL; - + return(DupStr(s,26,0)); } -- cgit v1.2.3