summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang40
-rw-r--r--apps/plugins/mikmod/SOURCES3
-rw-r--r--apps/plugins/mikmod/load_669.c30
-rw-r--r--apps/plugins/mikmod/load_amf.c72
-rw-r--r--apps/plugins/mikmod/load_asy.c91
-rw-r--r--apps/plugins/mikmod/load_dsm.c29
-rw-r--r--apps/plugins/mikmod/load_far.c38
-rw-r--r--apps/plugins/mikmod/load_gdm.c33
-rw-r--r--apps/plugins/mikmod/load_gt2.c375
-rw-r--r--apps/plugins/mikmod/load_imf.c71
-rw-r--r--apps/plugins/mikmod/load_it.c184
-rw-r--r--apps/plugins/mikmod/load_m15.c107
-rw-r--r--apps/plugins/mikmod/load_med.c74
-rw-r--r--apps/plugins/mikmod/load_mod.c27
-rw-r--r--apps/plugins/mikmod/load_mtm.c34
-rw-r--r--apps/plugins/mikmod/load_okt.c21
-rw-r--r--apps/plugins/mikmod/load_s3m.c50
-rw-r--r--apps/plugins/mikmod/load_stm.c40
-rw-r--r--apps/plugins/mikmod/load_stx.c26
-rw-r--r--apps/plugins/mikmod/load_ult.c40
-rw-r--r--apps/plugins/mikmod/load_umx.c476
-rw-r--r--apps/plugins/mikmod/load_uni.c163
-rw-r--r--apps/plugins/mikmod/load_xm.c129
-rw-r--r--apps/plugins/mikmod/mdreg.c66
-rw-r--r--apps/plugins/mikmod/mdriver.c189
-rw-r--r--apps/plugins/mikmod/mikmod.c133
-rw-r--r--apps/plugins/mikmod/mikmod.h895
-rw-r--r--apps/plugins/mikmod/mikmod_internals.h789
-rw-r--r--apps/plugins/mikmod/mikmod_supp.h3
-rw-r--r--apps/plugins/mikmod/mloader.c319
-rw-r--r--apps/plugins/mikmod/mlreg.c5
-rw-r--r--apps/plugins/mikmod/mlutil.c44
-rw-r--r--apps/plugins/mikmod/mmalloc.c207
-rw-r--r--apps/plugins/mikmod/mmerror.c150
-rw-r--r--apps/plugins/mikmod/mmio.c304
-rw-r--r--apps/plugins/mikmod/mplayer.c410
-rw-r--r--apps/plugins/mikmod/munitrk.c22
-rw-r--r--apps/plugins/mikmod/npertab.c8
-rw-r--r--apps/plugins/mikmod/sloader.c60
-rw-r--r--apps/plugins/mikmod/virtch.c652
-rw-r--r--apps/plugins/mikmod/virtch2.c1370
-rw-r--r--apps/plugins/mikmod/virtch_common.c193
-rw-r--r--apps/plugins/viewers.config2
43 files changed, 5122 insertions, 2852 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 8079884426..5937df64c0 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -15352,6 +15352,46 @@
</voice>
</phrase>
<phrase>
+ id: LANG_MIKMOD_HQMIXER
+ desc: in mikmod settings menu
+ user: core
+ <source>
+ *: none
+ lowmem: none
+ swcodec: "HQ Mixer"
+ </source>
+ <dest>
+ *: none
+ lowmem: none
+ swcodec: "HQ Mixer"
+ </dest>
+ <voice>
+ *: none
+ lowmem: none
+ swcodec: "High Quality Mixer"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_MIKMOD_SAMPLERATE
+ desc: in mikmod settings menu
+ user: core
+ <source>
+ *: none
+ lowmem: none
+ swcodec: "Sample Rate"
+ </source>
+ <dest>
+ *: none
+ lowmem: none
+ swcodec: "Sample Rate"
+ </dest>
+ <voice>
+ *: none
+ lowmem: none
+ swcodec: "Sample Rate"
+ </voice>
+</phrase>
+<phrase>
id: LANG_CPU_BOOST
desc: in mikmod settings menu
user: core
diff --git a/apps/plugins/mikmod/SOURCES b/apps/plugins/mikmod/SOURCES
index 1de5bb2149..bea10f9a29 100644
--- a/apps/plugins/mikmod/SOURCES
+++ b/apps/plugins/mikmod/SOURCES
@@ -5,7 +5,6 @@ load_asy.c
load_dsm.c
load_far.c
load_gdm.c
-load_gt2.c
load_imf.c
load_it.c
load_m15.c
@@ -17,6 +16,7 @@ load_s3m.c
load_stm.c
load_stx.c
load_ult.c
+load_umx.c
load_uni.c
load_xm.c
mdreg.c
@@ -34,6 +34,7 @@ sloader.c
strdup.c
strstr.c
virtch.c
+virtch2.c
virtch_common.c
mikmod.c
diff --git a/apps/plugins/mikmod/load_669.c b/apps/plugins/mikmod/load_669.c
index 000e51d985..0872043f65 100644
--- a/apps/plugins/mikmod/load_669.c
+++ b/apps/plugins/mikmod/load_669.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_669.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id: $
Composer 669 module loader
@@ -49,11 +49,11 @@ extern int fprintf(FILE *, const char *, ...);
/*========== Module structure */
/* header */
-typedef struct S69HEADER {
+typedef struct S69HEADER {
UBYTE marker[2];
CHAR message[108];
UBYTE nos;
- UBYTE rbnop;
+ UBYTE RBnop;
UBYTE looporder;
UBYTE orders[0x80];
UBYTE tempos[0x80];
@@ -81,7 +81,7 @@ static S69NOTE* s69pat=NULL;
static S69HEADER* mh=NULL;
/* file type identification */
-static CHAR* S69_Version[]={
+static const CHAR* S69_Version[]={
"Composer 669",
"Extended 669"
};
@@ -134,6 +134,8 @@ static void S69_Cleanup(void)
{
MikMod_free(s69pat);
MikMod_free(mh);
+ mh=NULL;
+ s69pat=NULL;
}
static int S69_LoadPatterns(void)
@@ -142,7 +144,7 @@ static int S69_LoadPatterns(void)
UBYTE note,inst,vol,effect,lastfx,lastval;
S69NOTE *cur;
int tracks=0;
-
+
if(!AllocPatterns()) return 0;
if(!AllocTracks()) return 0;
@@ -226,7 +228,7 @@ static int S69_LoadPatterns(void)
case 5: /* set speed */
if (effect)
UniPTEffect(0xf,effect);
- else
+ else
if(mh->marker[0]!=0x69) {
#ifdef MIKMOD_DEBUG
fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n",
@@ -250,13 +252,13 @@ static int S69_Load(int curious)
int i;
SAMPLE *current;
S69SAMPLE sample;
- (void)curious;
+ (void)curious;
/* module header */
_mm_read_UBYTES(mh->marker,2,modreader);
_mm_read_UBYTES(mh->message,108,modreader);
mh->nos=_mm_read_UBYTE(modreader);
- mh->rbnop=_mm_read_UBYTE(modreader);
+ mh->RBnop=_mm_read_UBYTE(modreader);
mh->looporder=_mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->orders,0x80,modreader);
for(i=0;i<0x80;i++)
@@ -281,9 +283,9 @@ static int S69_Load(int curious)
of.initspeed=4;
of.inittempo=78;
of.songname=DupStr(mh->message,36,1);
- of.modtype=StrDup(S69_Version[memcmp(mh->marker,"JN",2)==0]);
+ of.modtype=MikMod_strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]);
of.numchn=8;
- of.numpat=mh->rbnop;
+ of.numpat=mh->RBnop;
of.numins=of.numsmp=mh->nos;
of.numtrk=of.numchn*of.numpat;
of.flags=UF_XMPERIODS|UF_LINEAR;
@@ -292,7 +294,7 @@ static int S69_Load(int curious)
for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0;
for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0;
if((mh->message[0])||(mh->message[36])||(mh->message[72]))
- if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1))) {
+ if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1)) != NULL) {
strncpy(of.comment,mh->message,36);
strcat(of.comment,"\r");
if (mh->message[36]) strncat(of.comment,mh->message+36,36);
@@ -304,7 +306,7 @@ static int S69_Load(int curious)
if(!AllocPositions(0x80)) return 0;
for(i=0;i<0x80;i++) {
- if(mh->orders[i]>=mh->rbnop) break;
+ if(mh->orders[i]>=mh->RBnop) break;
of.positions[i]=mh->orders[i];
}
of.numpos=i;
diff --git a/apps/plugins/mikmod/load_amf.c b/apps/plugins/mikmod/load_amf.c
index 32067602f2..ba1f59a5be 100644
--- a/apps/plugins/mikmod/load_amf.c
+++ b/apps/plugins/mikmod/load_amf.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,8 +20,6 @@
/*==============================================================================
- $Id: load_amf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
-
DMP Advanced Module Format loader
==============================================================================*/
@@ -112,9 +110,11 @@ static void AMF_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(track);
+ mh=NULL;
+ track=NULL;
}
-static int AMF_UnpackTrack(MREADER* modreader)
+static int AMF_UnpackTrack(MREADER* r)
{
ULONG tracksize;
UBYTE row,cmd;
@@ -124,20 +124,20 @@ static int AMF_UnpackTrack(MREADER* modreader)
memset(track,0,64*sizeof(AMFNOTE));
/* read packed track */
- if (modreader) {
- tracksize=_mm_read_I_UWORD(modreader);
- tracksize+=((ULONG)_mm_read_UBYTE(modreader))<<16;
+ if (r) {
+ tracksize=_mm_read_I_UWORD(r);
+ tracksize+=((ULONG)_mm_read_UBYTE(r))<<16;
if (tracksize)
while(tracksize--) {
- row=_mm_read_UBYTE(modreader);
- cmd=_mm_read_UBYTE(modreader);
- arg=_mm_read_SBYTE(modreader);
+ row=_mm_read_UBYTE(r);
+ cmd=_mm_read_UBYTE(r);
+ arg=_mm_read_SBYTE(r);
/* unexpected end of track */
if(!tracksize) {
if((row==0xff)&&(cmd==0xff)&&(arg==-1))
break;
/* the last triplet should be FF FF FF, but this is not
- always the case... maybe a bug in m2amf ?
+ always the case... maybe a bug in m2amf ?
else
return 0;
*/
@@ -164,7 +164,7 @@ static int AMF_UnpackTrack(MREADER* modreader)
if (cmd==0x83) {
/* volume without note */
track[row].volume=(UBYTE)arg+1;
- } else
+ } else
if (cmd==0xff) {
/* apparently, some M2AMF version fail to estimate the
size of the compressed patterns correctly, and end
@@ -322,7 +322,7 @@ static UBYTE* AMF_ConvertTrack(void)
of.flags |= UF_PANNING;
break;
}
-
+
}
if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1);
UniNewline();
@@ -333,13 +333,13 @@ static UBYTE* AMF_ConvertTrack(void)
static int AMF_Load(int curious)
{
int u,defaultpanning;
- unsigned int t,realtrackcnt,realsmpcnt;
+ unsigned int t,realtrackcnt,realsmpcnt;
AMFSAMPLE s;
SAMPLE *q;
UWORD *track_remap;
- ULONG samplepos;
+ ULONG samplepos, fileend;
int channel_remap[16];
- (void)curious;
+ (void)curious;
/* try to read module header */
_mm_read_UBYTES(mh->id,3,modreader);
@@ -386,7 +386,7 @@ static int AMF_Load(int curious)
of.inittempo = mh->songbpm;
AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10);
AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10);
- of.modtype = StrDup(AMF_Version);
+ of.modtype = MikMod_strdup(AMF_Version);
of.numchn = mh->numchannels;
of.numtrk = mh->numorders*mh->numchannels;
if (mh->numtracks>of.numtrk)
@@ -400,7 +400,7 @@ static int AMF_Load(int curious)
/* XXX whenever possible, we should try to determine the original format.
Here we assume it was S3M-style wrt bpmlimit... */
of.bpmlimit = 32;
-
+
/*
* Play with the panning table. Although the AMF format embeds a
* panning table, if the module was a MOD or an S3M with default
@@ -466,7 +466,10 @@ static int AMF_Load(int curious)
s.c2spd =_mm_read_I_UWORD(modreader);
if(s.c2spd==8368) s.c2spd=8363;
s.volume =_mm_read_UBYTE(modreader);
- if(mh->version>=11) {
+ /* "the tribal zone.amf" and "the way its gonna b.amf" by Maelcum
+ * are the only version 10 files I can find, and they have 32 bit
+ * reppos and repend, not 16. */
+ if(mh->version>=10) {/* was 11 */
s.reppos =_mm_read_I_ULONG(modreader);
s.repend =_mm_read_I_ULONG(modreader);
} else {
@@ -475,7 +478,7 @@ static int AMF_Load(int curious)
}
if(_mm_eof(modreader)) {
- _mm_errno = MMERR_LOADING_SAMPLEINFO;
+ _mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@@ -493,7 +496,7 @@ static int AMF_Load(int curious)
}
/* read track table */
- if(!(track_remap=MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
+ if(!(track_remap=(UWORD*)MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
return 0;
_mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader);
if(_mm_eof(modreader)) {
@@ -505,9 +508,14 @@ static int AMF_Load(int curious)
for(realtrackcnt=t=0;t<=mh->numtracks;t++)
if (realtrackcnt<track_remap[t])
realtrackcnt=track_remap[t];
+ if (realtrackcnt > (int)mh->numtracks) {
+ MikMod_free(track_remap);
+ _mm_errno=MMERR_NOT_A_MODULE;
+ return 0;
+ }
for(t=0;t<of.numpat*of.numchn;t++)
of.patterns[t]=(of.patterns[t]<=mh->numtracks)?
- track_remap[of.patterns[t]]-1:(int)realtrackcnt;
+ track_remap[of.patterns[t]]-1:(int)realtrackcnt;
MikMod_free(track_remap);
@@ -531,18 +539,32 @@ static int AMF_Load(int curious)
for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL;
/* compute sample offsets */
+ if(_mm_eof(modreader)) goto fail;
samplepos=_mm_ftell(modreader);
+ _mm_fseek(modreader,0,SEEK_END);
+ fileend=_mm_ftell(modreader);
+ _mm_fseek(modreader,samplepos,SEEK_SET);
for(realsmpcnt=t=0;t<of.numsmp;t++)
if(realsmpcnt<of.samples[t].seekpos)
realsmpcnt=of.samples[t].seekpos;
for(t=1;t<=realsmpcnt;t++) {
q=of.samples;
- while(q->seekpos!=t) q++;
+ u=0;
+ while(q->seekpos!=t) {
+ if(++u==of.numsmp)
+ goto fail;
+ q++;
+ }
q->seekpos=samplepos;
samplepos+=q->length;
}
-
+ if(samplepos>fileend)
+ goto fail;
+
return 1;
+fail:
+ _mm_errno = MMERR_LOADING_SAMPLEINFO;
+ return 0;
}
static CHAR *AMF_LoadTitle(void)
diff --git a/apps/plugins/mikmod/load_asy.c b/apps/plugins/mikmod/load_asy.c
index 46e899f6bd..48d746c8e8 100644
--- a/apps/plugins/mikmod/load_asy.c
+++ b/apps/plugins/mikmod/load_asy.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,15 +20,15 @@
/*==============================================================================
- $Id: load_asy.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
ASYLUM Music Format v1.0 (.amf) loader
adapted from load_mod.c by Raphael Assenat <raph@raphnet.net>,
with the help of the AMF2MOD utility sourcecode,
written to convert crusader's amf files into 8
channels mod file in 1995 by Mr. P / Powersource
- mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca
-
+ mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca
+
==============================================================================*/
@@ -76,8 +76,9 @@ typedef struct MODNOTE {
/* This table is taken from AMF2MOD.C
* written in 1995 by Mr. P / Powersource
- * mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */
-UWORD periodtable[]={6848,6464,6096,5760,5424,5120,4832,4560,4304,
+ * mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */
+static const UWORD periodtable[] = {
+ 6848,6464,6096,5760,5424,5120,4832,4560,4304,
4064,3840,3628,3424,3232,3048,2880,2712,2560,
2416,2280,2152,2032,1920,1814,1712,1616,1524,
1440,1356,1280,1208,1140,1076,1016, 960, 907,
@@ -108,7 +109,7 @@ static int ASY_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
modtype = 1;
return 1;
}
-
+
return 0;
}
@@ -140,14 +141,16 @@ static void ASY_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
+ mh = NULL;
+ patbuf = NULL;
}
-static void ConvertNote(MODNOTE *n)
+static int ConvertNote(MODNOTE *n)
{
UBYTE instrument, effect, effdat, note;
UWORD period;
UBYTE lastnote = 0;
-
+
instrument = n->b&0x1f;
effect = n->c;
effdat = n->d;
@@ -158,10 +161,10 @@ static void ConvertNote(MODNOTE *n)
} else {
period = 0;
}
-
+
/* Convert the period to a note number */
note = 0;
- if (period)
+ if (period)
{
for (note = 0; note < 7 * OCTAVE; note++)
if (period >= npertab[note])
@@ -186,8 +189,8 @@ static void ConvertNote(MODNOTE *n)
UniInstrument(instrument - 1);
/* ...otherwise, only adjust volume... */
else {
- /* ...unless an effect was specified,
- * which forces a new note to be
+ /* ...unless an effect was specified,
+ * which forces a new note to be
* played */
if (effect || effdat) {
UniInstrument(instrument - 1);
@@ -218,7 +221,15 @@ static void ConvertNote(MODNOTE *n)
if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
effdat &= 0xf0;
+ if (effect == 0x1b) {
+ return 0; /* UniEffect(UNI_S3MEFFECTQ,dat) ? */
+ }
+ if (effect > 0xf) {
+ return 0; /* return -1 to fail? */
+ }
+
UniPTEffect(effect, effdat);
+ return 0;
}
static UBYTE *ConvertTrack(MODNOTE *n)
@@ -227,7 +238,8 @@ static UBYTE *ConvertTrack(MODNOTE *n)
UniReset();
for (t = 0; t < 64; t++) {
- ConvertNote(n);
+ if (ConvertNote(n) < 0)
+ return NULL;
UniNewline();
n += of.numchn;
}
@@ -237,8 +249,7 @@ static UBYTE *ConvertTrack(MODNOTE *n)
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
static int ML_LoadPatterns(void)
{
- int t, tracks = 0;
- unsigned int s;
+ unsigned int t, s, tracks = 0;
if (!AllocPatterns()) {
return 0;
@@ -246,7 +257,7 @@ static int ML_LoadPatterns(void)
if (!AllocTracks()) {
return 0;
}
-
+
/* Allocate temporary buffer for loading and converting the patterns */
if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
return 0;
@@ -278,31 +289,31 @@ static int ASY_Load(int curious)
MSAMPINFO *s;
CHAR *descr=asylum;
ULONG seekpos;
- (void)curious;
+ (void)curious;
- // no title in asylum amf files :(
- strcpy(mh->songname, "");
+ /* no title in asylum amf files :( */
+ mh->songname[0] = '\0';
_mm_fseek(modreader, 0x23, SEEK_SET);
mh->num_patterns = _mm_read_UBYTE(modreader);
mh->num_orders = _mm_read_UBYTE(modreader);
-
- // skip unknown byte
- (void)_mm_read_UBYTE(modreader);
+
+ /* skip unknown byte */
+ _mm_skip_BYTE(modreader);
_mm_read_UBYTES(mh->positions, 256, modreader);
-
+
/* read samples headers*/
for (t = 0; t < 64; t++) {
s = &mh->samples[t];
-
+
_mm_fseek(modreader, 0x126 + (t*37), SEEK_SET);
-
+
_mm_read_string(s->samplename, 22, modreader);
s->samplename[21] = 0; /* just in case */
-
+
s->finetune = _mm_read_UBYTE(modreader);
s->volume = _mm_read_UBYTE(modreader);
- (void)_mm_read_UBYTE(modreader); // skip unknown byte
+ _mm_skip_BYTE(modreader);/* skip unknown byte */
s->length = _mm_read_I_ULONG(modreader);
s->reppos = _mm_read_I_ULONG(modreader);
s->replen = _mm_read_I_ULONG(modreader);
@@ -324,12 +335,16 @@ static int ASY_Load(int curious)
of.numpat = mh->num_patterns;
of.numtrk = of.numpat * of.numchn;
-
/* Copy positions (orders) */
if (!AllocPositions(of.numpos))
return 0;
for (t = 0; t < of.numpos; t++) {
of.positions[t] = mh->positions[t];
+ if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
}
/* Finally, init the sampleinfo structures */
@@ -343,7 +358,7 @@ static int ASY_Load(int curious)
for (t = 0; t < of.numins; t++) {
/* convert the samplename */
q->samplename = DupStr(s->samplename, 23, 1);
-
+
/* init the sampleinfo variables */
q->speed = finetune[s->finetune & 0xf];
q->volume = s->volume & 0x7f;
@@ -351,16 +366,16 @@ static int ASY_Load(int curious)
q->loopstart = (ULONG)s->reppos;
q->loopend = (ULONG)q->loopstart + (s->replen);
q->length = (ULONG)s->length;
-
+
q->flags = SF_SIGNED;
-
+
q->seekpos = seekpos;
seekpos += q->length;
-
+
if ((s->replen) > 2) {
q->flags |= SF_LOOP;
}
-
+
/* fix replen if repend > length */
if (q->loopend > q->length)
q->loopend = q->length;
@@ -369,7 +384,7 @@ static int ASY_Load(int curious)
q++;
}
- of.modtype = StrDup(descr);
+ of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns())
return 0;
@@ -379,9 +394,7 @@ static int ASY_Load(int curious)
static CHAR *ASY_LoadTitle(void)
{
- CHAR *s = ""; // no titles
-
- return (DupStr(s, 21, 1));
+ return MikMod_strdup("");
}
/*========== Loader information */
diff --git a/apps/plugins/mikmod/load_dsm.c b/apps/plugins/mikmod/load_dsm.c
index 59abf0bcfe..e995f7dfad 100644
--- a/apps/plugins/mikmod/load_dsm.c
+++ b/apps/plugins/mikmod/load_dsm.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_dsm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
DSIK internal format (DSM) module loader
@@ -89,9 +89,9 @@ typedef struct DSMNOTE {
/*========== Loader variables */
-static CHAR* SONGID="SONG";
-static CHAR* INSTID="INST";
-static CHAR* PATTID="PATT";
+static const CHAR* SONGID="SONG";
+static const CHAR* INSTID="INST";
+static const CHAR* PATTID="PATT";
static UBYTE blockid[4];
static ULONG blockln;
@@ -101,7 +101,7 @@ static DSMNOTE* dsmbuf=NULL;
static CHAR DSM_Version[]="DSIK DSM-format";
-static unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'};
+static const unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'};
/*========== Loader code */
@@ -126,6 +126,8 @@ static void DSM_Cleanup(void)
{
MikMod_free(dsmbuf);
MikMod_free(mh);
+ dsmbuf = NULL;
+ mh = NULL;
}
static int GetBlockHeader(void)
@@ -133,7 +135,7 @@ static int GetBlockHeader(void)
/* make sure we're at the right position for reading the
next riff block, no matter how many bytes read */
_mm_fseek(modreader, blocklp+blockln, SEEK_SET);
-
+
while(1) {
_mm_read_UBYTES(blockid,4,modreader);
blockln=_mm_read_I_ULONG(modreader);
@@ -237,7 +239,7 @@ static int DSM_Load(int curious)
DSMINST s;
SAMPLE *q;
int cursmp=0,curpat=0,track=0;
- (void)curious;
+ (void)curious;
blocklp=0;
blockln=12;
@@ -266,7 +268,7 @@ static int DSM_Load(int curious)
/* set module variables */
of.initspeed=mh->speed;
of.inittempo=mh->bpm;
- of.modtype=StrDup(DSM_Version);
+ of.modtype=MikMod_strdup(DSM_Version);
of.numchn=mh->numtrk;
of.numpat=mh->numpat;
of.numtrk=of.numchn*of.numpat;
@@ -286,6 +288,11 @@ static int DSM_Load(int curious)
for(t=0;t<mh->numord;t++) {
int order=mh->orders[t];
if(order==255) order=LAST_PATTERN;
+ else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
of.positions[of.numpos]=order;
if(mh->orders[t]<254) of.numpos++;
}
@@ -344,7 +351,7 @@ static CHAR *DSM_LoadTitle(void)
_mm_fseek(modreader,12,SEEK_SET);
if(!_mm_read_UBYTES(s,28,modreader)) return NULL;
-
+
return(DupStr(s,28,1));
}
diff --git a/apps/plugins/mikmod/load_far.c b/apps/plugins/mikmod/load_far.c
index 2a1a44eda9..643cf15d49 100644
--- a/apps/plugins/mikmod/load_far.c
+++ b/apps/plugins/mikmod/load_far.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_far.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Farandole (FAR) module loader
@@ -92,7 +92,7 @@ static FARHEADER1 *mh1 = NULL;
static FARHEADER2 *mh2 = NULL;
static FARNOTE *pat = NULL;
-static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
+static const unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
/*========== Loader code */
@@ -119,6 +119,9 @@ static void FAR_Cleanup(void)
MikMod_free(mh1);
MikMod_free(mh2);
MikMod_free(pat);
+ mh1 = NULL;
+ mh2 = NULL;
+ pat = NULL;
}
static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows)
@@ -180,7 +183,7 @@ static int FAR_Load(int curious)
FARSAMPLE s;
FARNOTE *crow;
UBYTE smap[8];
- (void)curious;
+ (void)curious;
/* try to read module header (first part) */
_mm_read_UBYTES(mh1->id,4,modreader);
@@ -196,7 +199,7 @@ static int FAR_Load(int curious)
mh1->stlen = _mm_read_I_UWORD (modreader);
/* init modfile data */
- of.modtype = StrDup(FAR_Version);
+ of.modtype = MikMod_strdup(FAR_Version);
of.songname = DupStr(mh1->songname,40,1);
of.numchn = 16;
of.initspeed = mh1->speed;
@@ -207,7 +210,12 @@ static int FAR_Load(int curious)
/* read songtext into comment field */
if(mh1->stlen)
- if (!ReadLinedComment(mh1->stlen, 66)) return 0;
+ if (!ReadLinedComment(mh1->stlen, 132)) return 0;
+
+ if(_mm_eof(modreader)) {
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
/* try to read module header (second part) */
_mm_read_UBYTES(mh2->orders,256,modreader);
@@ -238,12 +246,14 @@ static int FAR_Load(int curious)
if(!AllocPatterns()) return 0;
for(t=0;t<of.numpat;t++) {
- UBYTE rows=0/* ,tempo */;
+ UBYTE rows=0;
+ UBYTE tempo;
memset(pat,0,256*16*4*sizeof(FARNOTE));
if(mh2->patsiz[t]) {
rows = _mm_read_UBYTE(modreader);
- /* tempo = */ (void)_mm_read_UBYTE(modreader);
+ tempo = _mm_read_UBYTE(modreader);
+ (void)tempo; /* unused */
crow = pat;
/* file often allocates 64 rows even if there are less in pattern */
@@ -284,7 +294,7 @@ static int FAR_Load(int curious)
of.numins = 0;
for(t=0;t<64;t++)
if(smap[t>>3]&(1<<(t&7))) of.numins=t+1;
- of.numsmp = of.numins;
+ of.numsmp = of.numins;
/* alloc sample structs */
if(!AllocSamples()) return 0;
@@ -314,8 +324,8 @@ static int FAR_Load(int curious)
q->seekpos = _mm_ftell(modreader);
_mm_fseek(modreader,q->length,SEEK_CUR);
- } else
- q->samplename = DupStr(NULL,0,0);
+ } else
+ q->samplename = MikMod_strdup("");
q++;
}
return 1;
@@ -327,8 +337,8 @@ static CHAR *FAR_LoadTitle(void)
_mm_fseek(modreader,4,SEEK_SET);
if(!_mm_read_UBYTES(s,40,modreader)) return NULL;
-
- return(DupStr(s,40,1));
+
+ return (DupStr(s,40,1));
}
/*========== Loader information */
diff --git a/apps/plugins/mikmod/load_gdm.c b/apps/plugins/mikmod/load_gdm.c
index 694d534236..5f06f9c70b 100644
--- a/apps/plugins/mikmod/load_gdm.c
+++ b/apps/plugins/mikmod/load_gdm.c
@@ -20,7 +20,7 @@
/*==============================================================================
- $Id: load_gdm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
General DigiMusic (GDM) module loader
@@ -114,7 +114,7 @@ typedef struct GDMSAMPLE {
static GDMHEADER *mh=NULL; /* pointer to GDM header */
static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */
-CHAR GDM_Version[]="General DigiMusic 1.xx";
+static CHAR GDM_Version[]="General DigiMusic 1.xx";
static int GDM_Test(void)
{
@@ -146,36 +146,45 @@ static void GDM_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(gdmbuf);
+ mh=NULL;
+ gdmbuf=NULL;
}
static int GDM_ReadPattern(void)
{
- int pos,flag,ch,i,maxch;
+ int pos,flag,ch,i;
GDMNOTE n;
- UWORD length,x=0;
+ SLONG length,x=0;
/* get pattern length */
- length=_mm_read_I_UWORD(modreader)-2;
+ length=(SLONG)_mm_read_I_UWORD(modreader);
+ length-=2;
/* clear pattern data */
memset(gdmbuf,255,32*64*sizeof(GDMNOTE));
pos=0;
- maxch=0;
while (x<length) {
memset(&n,255,sizeof(GDMNOTE));
flag=_mm_read_UBYTE(modreader);
x++;
- if (_mm_eof(modreader)) {
- _mm_errno=MMERR_LOADING_PATTERN;
+ if (_mm_eof(modreader))
return 0;
- }
ch=flag&31;
- if (ch>maxch) maxch=ch;
+ if (ch > of.numchn)
+ return 0;
+
if (!flag) {
pos++;
+ if (x==length) {
+ if (pos > 64)
+ return 0;
+ } else {
+ if (pos >= 64)
+ return 0;
+ }
continue;
}
if (flag&0x60) {
@@ -343,7 +352,7 @@ static int GDM_Load(int curious)
SAMPLE *q;
GDMSAMPLE s;
ULONG position;
- (void)curious;
+ (void)curious;
/* read header */
_mm_read_string(mh->id1,4,modreader);
@@ -390,7 +399,7 @@ static int GDM_Load(int curious)
}
/* now we fill */
- of.modtype=StrDup(GDM_Version);
+ of.modtype=MikMod_strdup(GDM_Version);
of.modtype[18]=mh->majorver+'0';
of.modtype[20]=mh->minorver/10+'0';
of.modtype[21]=mh->minorver%10+'0';
diff --git a/apps/plugins/mikmod/load_gt2.c b/apps/plugins/mikmod/load_gt2.c
deleted file mode 100644
index 26b4d1f59a..0000000000
--- a/apps/plugins/mikmod/load_gt2.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/* MikMod sound library
- (c) 2003-2004 Raphael Assenat and others - see file
- AUTHORS for complete list.
-
- This library is free software; you can redistribute it and/or modify
- 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
- 02111-1307, USA.
-*/
-
-/*==============================================================================
-
- $Id: load_gt2.c,v 1.2 2005/03/30 19:09:35 realtech Exp $
-
- Graoumf tracker format (.GT2)
-
-==============================================================================*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <string.h>
-
-#include "mikmod_internals.h"
-
-typedef struct GT_NOTE {
- UBYTE note; /* 24-127, 48 is middle C-2. 0 for no note */
- UBYTE inst; /* instrument, 1-255, 0 for none */
- UWORD effect; /* 0 for no FX */
- UBYTE vv; /* volume, 1-255, 0 for no volume */
-} GT_NOTE;
-
-/* general info chunk */
-typedef struct GT2_CHUNK {
- UBYTE magic[4]; /* must be 'GT2' */
- UBYTE version; /* 01 = v0.7, 02=v0.726, 03=v0.731 */
- ULONG chunk_size;
- CHAR module_name[33]; /* 32 bytes in file */
- CHAR comments_author[161]; /* 160 bytes in file */
- UBYTE date_day;
- UBYTE date_month;
- UWORD date_year;
- CHAR tracker_name[25]; /* 24 in file */
- UWORD initial_speed;
- UWORD initial_tempo;
- UWORD initial_master_volume; /* 000 - fff */
- UWORD num_voices; /* for the following panning section */
- UWORD *voice_pannings; /* 000 - 800 - fff */
-} GT2_CHUNK;
-
-/* track volume chunk */
-typedef struct TVOL_CHUNK {
- UBYTE id[4]; /* must be TVOL */
- ULONG chunk_size;
- UWORD num_tracks; /* for the following array */
- UWORD *track_volumes; /* 0000 - 1000 - FFFF */
-} TVOL_CHUNK;
-
-/* extra-comment chunk */
-typedef struct XCOM_CHUNK {
- UBYTE id[4]; /* must be XCOM */
- ULONG chunk_size;
- ULONG comment_len;
- CHAR *comment; /* comment_len + 1 allocated */
-} XCOM_CHUNK;
-
-/* song chunk */
-typedef struct SONG_CHUNK {
- UBYTE id[4]; /* must be SONG */
- ULONG chunk_size;
- UWORD song_length;
- UWORD song_repeat_point;
- UWORD *patterns; /* pattern numbers */
-} SONG_CHUNK;
-
-/* pattern set chunk */
-typedef struct PATS_CHUNK {
- UBYTE id[4]; /* must be PATS */
- ULONG chunk_size;
- UWORD num_tracks; /* total number of tracks for the song */
- UWORD num_patterns; /* number of patterns saved */
-} PATS_CHUNK;
-
-/* pattern chunk */
-typedef struct PATD_CHUNK {
- UBYTE id[4]; /* must be PATD */
- ULONG chunk_size;
- UWORD pattern_number;
- CHAR pattern_name[17]; /* 16 in file */
- UWORD codage_version; /* only 0 expected for now */
- /* version 0 (full pattern) */
- UWORD num_lines;
- UWORD num_tracks;
- GT_NOTE *notes; /* sizeof(GT_NOTE) * num_lines * num_tracks */
-} PATD_CHUNK;
-
-/* instrument set chunk */
-typedef struct ORCH_CHUNK {
- UBYTE id[4]; /* must be ORCH */
- ULONG chunk_size;
- UWORD num_instruments; /* number of instruments saved */
-} ORCH_CHUNK;
-
-typedef struct INST_NOTE {
- UBYTE samp_number;/* sample number for midi note */
- CHAR tranp; /* transposition for note */
-} INST_NOTE;
-
-/* instrument chunk */
-typedef struct INST_CHUNK {
- UBYTE id[4]; /* must be INST */
- ULONG chunk_size;
- UWORD instrument_number;
- CHAR name[29]; /* 28 in file */
- UWORD type; /* 0 = sample */
- UWORD volume; /* volume, 0-255 */
- UWORD auto_panning; /* autopanning, 000 - 800 - fff, -1 no autopanning */
- UWORD volume_enveloppe_number;
- UWORD tone_enveloppe_number;
- UWORD pan_enveloppe_number;
- UBYTE reserved[10];
- INST_NOTE note[128];
-} INST_CHUNK;
-
-typedef struct SAMP_CHUNK {
- UBYTE id[4]; /* must be SAMP */
- ULONG chunk_size;
- UWORD sample_number;
- CHAR name[29]; /* 28 in file */
- UWORD flags; /* bit0: 0 = mono, 1 = stereo bit1: 0 normal loop, bit2: ping pong loop */
- UWORD autopanning; /* 000 - 800 - fff */
- UWORD num_bits; /* 8 or 16 */
- UWORD rate; /* between 2000 and 65000 */
- ULONG length; /* bytes */
- ULONG loop_start; /* bytes */
- ULONG loop_len; /* bytes */
- UWORD volume; /* 0 - 255 */
- UWORD finetune; /* (-8..+7 -> -1..+7/8 halftone) */
- UWORD codage; /* 0 */
- UBYTE *data;
-} SAMP_CHUNK;
-
-typedef struct xENV_CHUNK {
- UBYTE id[4]; /* must be VENV, TENV or PENV */
- ULONG chunk_size;
- UWORD envelope_number;
- CHAR name[21]; /* 20 in file */
- UWORD keyoff_offset;
- UBYTE *data;
-} xENV_CHUNK;
-
-typedef struct ENDC_CHUNK {
- UBYTE id[4]; /* must be ENDC */
- ULONG chunk_size;
- ULONG total_module_size;
-} ENDC_CHUNK;
-
-
-typedef union GT_CHUNK
-{
- UBYTE id[4]; /* must be TVOL */
- GT2_CHUNK gt2;
- TVOL_CHUNK tvol;
- XCOM_CHUNK xcom;
- SONG_CHUNK song;
- PATS_CHUNK pats;
- PATD_CHUNK patd;
- ORCH_CHUNK orch;
- INST_CHUNK inst;
- SAMP_CHUNK samp;
- xENV_CHUNK xenv;
- ENDC_CHUNK endc;
-} GT_CHUNK;
-
-static GT_CHUNK *loadChunk(void)
-{
- GT_CHUNK *new_chunk = MikMod_malloc(sizeof(GT_CHUNK));
-
- /* the file chunk id only use 3 bytes, others 4 */
- _mm_read_UBYTES(new_chunk->id, 3, modreader);
- if (! (new_chunk->id[0]=='G' &&
- new_chunk->id[1]=='T' &&
- new_chunk->id[2]=='2')
- )
- {
- _mm_read_UBYTES(&new_chunk->id[3], 1, modreader);
- }
- else
- {
- new_chunk->id[3] = ' ';
- }
-
- printf(">> %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]);
-
- if (!memcmp(new_chunk, "GT2", 3)) {
- _mm_read_UBYTES(&new_chunk->gt2.version, 1, modreader);
- _mm_read_M_ULONGS(&new_chunk->gt2.chunk_size, 1, modreader);
- new_chunk->gt2.module_name[32] = 0;
- _mm_read_UBYTES(&new_chunk->gt2.module_name, 32, modreader);
- new_chunk->gt2.comments_author[160] = 0;
- _mm_read_UBYTES(&new_chunk->gt2.comments_author, 160, modreader);
- _mm_read_UBYTES(&new_chunk->gt2.date_day, 1, modreader);
- _mm_read_UBYTES(&new_chunk->gt2.date_month, 1, modreader);
- _mm_read_M_UWORDS(&new_chunk->gt2.date_year, 1, modreader);
- new_chunk->gt2.tracker_name[24] = 0;
- _mm_read_UBYTES(&new_chunk->gt2.tracker_name, 24, modreader);
- _mm_read_M_UWORDS(&new_chunk->gt2.initial_speed, 1, modreader);
- _mm_read_M_UWORDS(&new_chunk->gt2.initial_tempo, 1, modreader);
- _mm_read_M_UWORDS(&new_chunk->gt2.initial_master_volume, 1, modreader);
- _mm_read_M_UWORDS(&new_chunk->gt2.num_voices, 1, modreader);
- new_chunk->gt2.voice_pannings = MikMod_malloc(2*new_chunk->gt2.num_voices);
- _mm_read_M_UWORDS(new_chunk->gt2.voice_pannings, new_chunk->gt2.num_voices, modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "TVOL", 4)) {
- new_chunk->tvol.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->tvol.num_tracks = _mm_read_M_UWORD(modreader);
- new_chunk->tvol.track_volumes = MikMod_malloc(new_chunk->tvol.num_tracks * 2);
- _mm_read_M_UWORDS(new_chunk->tvol.track_volumes, new_chunk->tvol.num_tracks, modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "XCOM", 4)) {
- new_chunk->xcom.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->xcom.comment_len = _mm_read_M_ULONG(modreader);
- new_chunk->xcom.comment = MikMod_malloc(new_chunk->xcom.comment_len + 1);
- _mm_read_UBYTES(new_chunk->xcom.comment, new_chunk->xcom.comment_len, modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "SONG", 4)) {
- new_chunk->song.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->song.song_length = _mm_read_M_UWORD(modreader);
- new_chunk->song.song_repeat_point = _mm_read_M_UWORD(modreader);
- new_chunk->song.patterns = MikMod_malloc(2*new_chunk->song.song_length);
- _mm_read_M_UWORDS(new_chunk->song.patterns, new_chunk->song.song_length, modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "PATS", 4)) {
- new_chunk->pats.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->pats.num_tracks = _mm_read_M_UWORD(modreader);
- new_chunk->pats.num_patterns = _mm_read_M_UWORD(modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "PATD", 4)) {
- new_chunk->patd.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->patd.pattern_number = _mm_read_M_UWORD(modreader);
- new_chunk->patd.pattern_name[16] = 0;
- _mm_read_UBYTES(new_chunk->patd.pattern_name, 16, modreader);
- new_chunk->patd.codage_version = _mm_read_M_UWORD(modreader);
- new_chunk->patd.num_lines = _mm_read_M_UWORD(modreader);
- new_chunk->patd.num_tracks = _mm_read_M_UWORD(modreader);
- new_chunk->patd.notes = MikMod_malloc(5 *
- new_chunk->patd.num_lines *
- new_chunk->patd.num_tracks);
- _mm_read_UBYTES(new_chunk->patd.notes,
- new_chunk->patd.num_lines * new_chunk->patd.num_tracks * 5,
- modreader);
- return new_chunk;
- }
-
- if (!memcmp(new_chunk, "ORCH", 4)) {
- new_chunk->orch.chunk_size = _mm_read_M_ULONG(modreader);
- new_chunk->orch.num_instruments = _mm_read_M_UWORD(modreader);
- return new_chunk;
- }
- if (!memcmp(new_chunk, "INST", 4)) {
- return new_chunk;
- }
- if (!memcmp(new_chunk, "SAMP", 4)) {
- return new_chunk;
- }
- if (!memcmp(new_chunk, "VENV", 4)) {
- return new_chunk;
- }
- if (!memcmp(new_chunk, "TENV", 4)) {
- return new_chunk;
- }
- if (!memcmp(new_chunk, "PENV", 4)) {
- return new_chunk;
- }
- if (!memcmp(new_chunk, "ENDC", 4)) {
- return new_chunk;
- }
-
- printf("?? %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]);
-
- MikMod_free(new_chunk);
- return NULL; // unknown chunk
-}
-
-static int GT2_Init(void)
-{
- return 1;
-}
-
-static int GT2_Test(void)
-{
- UBYTE magic[3];
- _mm_fseek(modreader, 0, SEEK_SET);
-
- _mm_read_UBYTES(magic, 3, modreader);
-
- if (magic[0] == 'G' && magic[1] == 'T' && magic[2] == '2') { return 1; }
-
- return 0;
-}
-
-static int GT2_Load(int curious)
-{
- GT_CHUNK *tmp;
- (void)curious;
-
- _mm_fseek(modreader, 0, SEEK_SET);
- while ( (tmp = loadChunk() ))
- {
- printf("%c%c%c%c\n", tmp->id[0], tmp->id[1], tmp->id[2], tmp->id[3]);
-
- }
-
- return 0;
-}
-
-static void GT2_Cleanup(void)
-{
-}
-
-static CHAR *GT2_LoadTitle(void)
-{
- CHAR title[33];
- _mm_fseek(modreader, 8, SEEK_SET);
-
- _mm_read_UBYTES(title, 32, modreader);
- title[32]=0;
-
- return (DupStr(title, 32, 1));
-}
-
-
-MIKMODAPI MLOADER load_gt2 = {
- NULL,
- "Graoumf Tracker 2 module",
- "Graoumf Tracker 2",
- GT2_Init,
- GT2_Test,
- GT2_Load,
- GT2_Cleanup,
- GT2_LoadTitle
-};
-
-
-
diff --git a/apps/plugins/mikmod/load_imf.c b/apps/plugins/mikmod/load_imf.c
index 9c93d97e23..39cdf5464d 100644
--- a/apps/plugins/mikmod/load_imf.c
+++ b/apps/plugins/mikmod/load_imf.c
@@ -20,7 +20,7 @@
/*==============================================================================
- $Id: load_imf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Imago Orpheus (IMF) module loader
@@ -127,12 +127,36 @@ static IMFHEADER *mh=NULL;
static int IMF_Test(void)
{
- UBYTE id[4];
+ UBYTE buf[512], *p;
+ int t, chn;
_mm_fseek(modreader,0x3c,SEEK_SET);
- if(!_mm_read_UBYTES(id,4,modreader)) return 0;
- if(!memcmp(id,"IM10",4)) return 1;
- return 0;
+ if (!_mm_read_UBYTES(buf,4,modreader)) return 0;
+ if (memcmp(buf,"IM10",4) != 0) return 0; /* no magic */
+
+ _mm_fseek(modreader,32,SEEK_SET);
+ if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad ordnum */
+ if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad patnum */
+ if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad insnum */
+
+ _mm_fseek(modreader,64,SEEK_SET);
+ if(!_mm_read_UBYTES(buf,512,modreader)) return 0;
+ /* verify channel status */
+ for (t = 0, chn = 0, p = &buf[15]; t < 512; t += 16, p += 16) {
+ switch (*p) {
+ case 0: /* channel enabled */
+ case 1: /* channel muted */
+ chn++;
+ break;
+ case 2: /* channel disabled */
+ break;
+ default: /* bad status value */
+ return 0;
+ }
+ }
+ if(!chn) return 0; /* no channels found */
+
+ return 1;
}
static int IMF_Init(void)
@@ -149,6 +173,8 @@ static void IMF_Cleanup(void)
MikMod_free(imfpat);
MikMod_free(mh);
+ imfpat=NULL;
+ mh=NULL;
}
static int IMF_ReadPattern(SLONG size,UWORD rows)
@@ -388,7 +414,7 @@ static int IMF_Load(int curious)
ULONG *nextwav=NULL;
UWORD wavcnt=0;
UBYTE id[4];
- (void)curious;
+ (void)curious;
/* try to read the module header */
_mm_read_string(mh->songname,32,modreader);
@@ -410,7 +436,7 @@ static int IMF_Load(int curious)
/* set module variables */
of.songname=DupStr(mh->songname,31,1);
- of.modtype=StrDup(IMF_Version);
+ of.modtype=MikMod_strdup(IMF_Version);
of.numpat=mh->patnum;
of.numins=mh->insnum;
of.reppos=0;
@@ -467,6 +493,13 @@ static int IMF_Load(int curious)
if(!AllocPositions(of.numpos)) return 0;
for(t=u=0;t<mh->ordnum;t++)
if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t];
+ for(t=0;t<of.numpos;t++) {
+ if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
+ }
/* load pattern info */
of.numtrk=of.numpat*of.numchn;
@@ -509,16 +542,16 @@ static int IMF_Load(int curious)
_mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader);
_mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader);
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define IMF_FinishLoadingEnvelope(name) \
ih. name##pts=_mm_read_UBYTE(modreader); \
ih. name##sus=_mm_read_UBYTE(modreader); \
ih. name##beg=_mm_read_UBYTE(modreader); \
ih. name##end=_mm_read_UBYTE(modreader); \
ih. name##flg=_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader)
+ _mm_skip_BYTE(modreader); \
+ _mm_skip_BYTE(modreader); \
+ _mm_skip_BYTE(modreader)
#else
#define IMF_FinishLoadingEnvelope(name) \
ih. name/**/pts=_mm_read_UBYTE(modreader); \
@@ -526,9 +559,9 @@ static int IMF_Load(int curious)
ih. name/**/beg=_mm_read_UBYTE(modreader); \
ih. name/**/end=_mm_read_UBYTE(modreader); \
ih. name/**/flg=_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader); \
- (void)_mm_read_UBYTE(modreader)
+ _mm_skip_BYTE(modreader); \
+ _mm_skip_BYTE(modreader); \
+ _mm_skip_BYTE(modreader)
#endif
IMF_FinishLoadingEnvelope(vol);
@@ -541,7 +574,7 @@ static int IMF_Load(int curious)
_mm_read_UBYTES(id,4,modreader);
/* Looks like Imago Orpheus forgets the signature for empty
instruments following a multi-sample instrument... */
- if(memcmp(id,"II10",4) &&
+ if(memcmp(id,"II10",4) &&
(oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) {
if(nextwav) MikMod_free(nextwav);
if(wh) MikMod_free(wh);
@@ -562,7 +595,7 @@ static int IMF_Load(int curious)
d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp;
d->volfade=ih.volfade;
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define IMF_ProcessEnvelope(name) \
for (u = 0; u < (IMFENVCNT >> 1); u++) { \
d-> name##env[u].pos = ih. name##env[u << 1]; \
@@ -613,12 +646,12 @@ static int IMF_Load(int curious)
/* allocate more room for sample information if necessary */
if(of.numsmp+u==wavcnt) {
wavcnt+=IMF_SMPINCR;
- if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) {
+ if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) {
if(wh) MikMod_free(wh);
_mm_errno=MMERR_OUT_OF_MEMORY;
return 0;
}
- if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
+ if(!(wh=(IMFWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
MikMod_free(nextwav);
_mm_errno=MMERR_OUT_OF_MEMORY;
return 0;
@@ -627,7 +660,7 @@ static int IMF_Load(int curious)
}
_mm_read_string(s->samplename,13,modreader);
- (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);
+ _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);
s->length =_mm_read_I_ULONG(modreader);
s->loopstart =_mm_read_I_ULONG(modreader);
s->loopend =_mm_read_I_ULONG(modreader);
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<patrows);
- return 0;
+ return 1;
}
static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
@@ -282,7 +289,7 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
/* process volume / panning column
volume / panning effects do NOT all share the same memory address
yet. */
- if(volpan<=64)
+ if(volpan<=64)
UniVolEffect(VOL_VOLUME,volpan);
else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
UniVolEffect(VOL_VOLSLIDE,0);
@@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
static int IT_ReadPattern(UWORD patrows)
{
- int row=0,flag,ch,blah;
+ int row=0,flag,ch;
+ unsigned int blah;
ITNOTE *itt=itpat,dummy,*n,*l;
+ ITNOTE *ite=&itpat[200*64 -1];
+ UBYTE *m;
memset(itt,255,200*64*sizeof(ITNOTE));
do {
- if((flag=_mm_read_UBYTE(modreader))==EOF) {
+ if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN;
return 0;
}
+ flag=_mm_read_UBYTE(modreader);
if(!flag) {
itt=&itt[of.numchn];
row++;
@@ -342,29 +353,38 @@ static int IT_ReadPattern(UWORD patrows)
if(ch!=-1) {
n=&itt[ch];
l=&last[ch];
- } else
+ m=&mask[ch];
+ if(n > 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;i<UF_MAXMACRO;i++) {
- LoadMidiString(modreader,midiline);
+ LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1')))
filtermacros[i]=(midiline[5]-'0')|0x80;
@@ -418,7 +439,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
/* read standalone filters */
for(i=0x80;i<0x100;i++) {
- LoadMidiString(modreader,midiline);
+ LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1'))) {
filtersettings[i].filter=(midiline[5]-'0')|0x80;
@@ -446,7 +467,7 @@ static int IT_Load(int curious)
int t,u,lp;
INSTRUMENT *d;
SAMPLE *q;
- /* int compressed=0; */
+ /*int compressed=0;*/
numtrk=0;
filters=0;
@@ -479,6 +500,10 @@ static int IT_Load(int curious)
_mm_errno=MMERR_LOADING_HEADER;
return 0;
}
+ if(mh->ordnum > 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;t<mh->ordnum;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;lp++) {
ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
ih.volnode[lp] = _mm_read_UBYTE(modreader);
- }
+ }
} else {
/* load IT 2xx volume, pan and pitch envelopes */
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#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); \
@@ -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;u<ih.volpts;u++)
d->volenv[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;t<UF_MAXCHAN;t++)
+ for(t=0;t<UF_MAXCHAN;t++)
if(!remap[t])
remap[t]=of.numchn++;
@@ -963,6 +988,8 @@ static int IT_Load(int curious)
if(!AllocTracks()) return 0;
for(t=0;t<of.numpat;t++) {
+ UWORD packlen;
+
/* seek to pattern position */
if(!paraptr[mh->insnum+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));
}
diff --git a/apps/plugins/mikmod/load_m15.c b/apps/plugins/mikmod/load_m15.c
index b5d5329bf0..2359175bb3 100644
--- a/apps/plugins/mikmod/load_m15.c
+++ b/apps/plugins/mikmod/load_m15.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_m15.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
15 instrument MOD loader
Also supports Ultimate Sound Tracker (old M15 format)
@@ -79,33 +79,31 @@ static int ust_loader = 0; /* if TRUE, load as an ust module. */
/* known file formats which can confuse the loader */
#define REJECT 2
-static char *signatures[REJECT]={
+static const char *signatures[REJECT]={
"CAKEWALK", /* cakewalk midi files */
"SZDD" /* Microsoft compressed files */
};
-static int siglen[REJECT]={8,4};
+static const int siglen[REJECT]={8,4};
/*========== Loader code */
-static int LoadModuleHeader(MODULEHEADER *mh)
+static int LoadModuleHeader(MODULEHEADER *h)
{
int t,u;
- _mm_read_string(mh->songname,20,modreader);
- mh->songname[20]=0; /* just in case */
+ _mm_read_string(h->songname,20,modreader);
/* sanity check : title should contain printable characters and a bunch
of null chars */
for(t=0;t<20;t++)
- if((mh->songname[t])&&(mh->songname[t]<32)) return 0;
- for(t=0;(mh->songname[t])&&(t<20);t++);
- if(t<20) for(;t<20;t++) if(mh->songname[t]) return 0;
+ if((h->songname[t])&&(h->songname[t]<32)) return 0;
+ for(t=0;(h->songname[t])&&(t<20);t++);
+ if(t<20) for(;t<20;t++) if(h->songname[t]) return 0;
for(t=0;t<15;t++) {
- MSAMPINFO *s=&mh->samples[t];
+ MSAMPINFO *s=&h->samples[t];
_mm_read_string(s->samplename,22,modreader);
- s->samplename[22]=0; /* just in case */
s->length =_mm_read_M_UWORD(modreader);
s->finetune =_mm_read_UBYTE(modreader);
s->volume =_mm_read_UBYTE(modreader);
@@ -123,26 +121,26 @@ static int LoadModuleHeader(MODULEHEADER *mh)
if(s->finetune>>4) return 0;
}
- mh->songlength =_mm_read_UBYTE(modreader);
- mh->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */
+ h->songlength =_mm_read_UBYTE(modreader);
+ h->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */
/* sanity check : no more than 128 positions, restart position in range */
- if((!mh->songlength)||(mh->songlength>128)) return 0;
+ if((!h->songlength)||(h->songlength>128)) return 0;
/* values encountered so far are 0x6a and 0x78 */
- if(((mh->magic1&0xf8)!=0x78)&&(mh->magic1!=0x6a)&&(mh->magic1>mh->songlength)) return 0;
+ if(((h->magic1&0xf8)!=0x78)&&(h->magic1!=0x6a)&&(h->magic1>h->songlength)) return 0;
- _mm_read_UBYTES(mh->positions,128,modreader);
+ _mm_read_UBYTES(h->positions,128,modreader);
/* sanity check : pattern range is 0..63 */
for(t=0;t<128;t++)
- if(mh->positions[t]>63) return 0;
+ if(h->positions[t]>63) return 0;
return(!_mm_eof(modreader));
}
/* Checks the patterns in the modfile for UST / 15-inst indications.
- For example, if an effect 3xx is found, it is assumed that the song
- is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST.
+ For example, if an effect 3xx is found, it is assumed that the song
+ is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST.
Returns: 0 indecisive; 1 = UST; 2 = 15-inst */
static int CheckPatternType(int numpat)
@@ -152,7 +150,7 @@ static int CheckPatternType(int numpat)
for(t=0;t<numpat*(64U*4);t++) {
/* Load the pattern into the temp buffer and scan it */
- (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);
+ _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);
eff = _mm_read_UBYTE(modreader);
dat = _mm_read_UBYTE(modreader);
@@ -177,55 +175,56 @@ static int CheckPatternType(int numpat)
static int M15_Test(void)
{
int t, numpat;
- MODULEHEADER mh;
+ MODULEHEADER h;
ust_loader = 0;
- if(!LoadModuleHeader(&mh)) return 0;
+ memset(&h, 0, sizeof(MODULEHEADER));
+ if(!LoadModuleHeader(&h)) return 0;
/* reject other file types */
for(t=0;t<REJECT;t++)
- if(!memcmp(mh.songname,signatures[t],siglen[t])) return 0;
+ if(!memcmp(h.songname,signatures[t],siglen[t])) return 0;
- if(mh.magic1>127) return 0;
- if((!mh.songlength)||(mh.songlength>mh.magic1)) return 0;
+ if(h.magic1>127) return 0;
+ if((!h.songlength)||(h.songlength>h.magic1)) return 0;
for(t=0;t<15;t++) {
/* all finetunes should be zero */
- if(mh.samples[t].finetune) return 0;
+ if(h.samples[t].finetune) return 0;
/* all volumes should be <= 64 */
- if(mh.samples[t].volume>64) return 0;
+ if(h.samples[t].volume>64) return 0;
/* all instrument names should begin with s, st-, or a number */
- if((mh.samples[t].samplename[0]=='s')||
- (mh.samples[t].samplename[0]=='S')) {
- if((memcmp(mh.samples[t].samplename,"st-",3)) &&
- (memcmp(mh.samples[t].samplename,"ST-",3)) &&
- (*mh.samples[t].samplename))
+ if((h.samples[t].samplename[0]=='s')||
+ (h.samples[t].samplename[0]=='S')) {
+ if((memcmp(h.samples[t].samplename,"st-",3)) &&
+ (memcmp(h.samples[t].samplename,"ST-",3)) &&
+ (*h.samples[t].samplename))
ust_loader = 1;
} else
- if(!isdigit((int)mh.samples[t].samplename[0]))
+ if(!isdigit((int)h.samples[t].samplename[0]))
ust_loader = 1;
- if(mh.samples[t].length>4999||mh.samples[t].reppos>9999) {
+ if(h.samples[t].length>4999||h.samples[t].reppos>9999) {
ust_loader = 0;
- if(mh.samples[t].length>32768) return 0;
+ if(h.samples[t].length>32768) return 0;
}
/* if loop information is incorrect as words, but correct as bytes,
this is likely to be an ust-style module */
- if((mh.samples[t].reppos+mh.samples[t].replen>mh.samples[t].length)&&
- (mh.samples[t].reppos+mh.samples[t].replen<(mh.samples[t].length<<1))){
+ if((h.samples[t].reppos+h.samples[t].replen>h.samples[t].length)&&
+ (h.samples[t].reppos+h.samples[t].replen<(h.samples[t].length<<1))) {
ust_loader = 1;
return 1;
}
- if(!ust_loader) return 1;
+ if(!ust_loader) return 1;
}
- for(numpat=0,t=0;t<mh.songlength;t++)
- if(mh.positions[t]>numpat)
- numpat = mh.positions[t];
+ for(numpat=0,t=0;t<h.songlength;t++)
+ if(h.positions[t]>numpat)
+ numpat = h.positions[t];
numpat++;
switch(CheckPatternType(numpat)) {
case 0: /* indecisive, so check more clues... */
@@ -242,7 +241,7 @@ static int M15_Test(void)
static int M15_Init(void)
{
- if(!(mh=(MODULEHEADER*)MikMod_malloc(sizeof(MODULEHEADER)))) return 0;
+ if(!(mh=(MODULEHEADER*)MikMod_calloc(1,sizeof(MODULEHEADER)))) return 0;
return 1;
}
@@ -250,6 +249,8 @@ static void M15_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
+ mh=NULL;
+ patbuf=NULL;
}
/*
@@ -331,7 +332,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect)
case 1:
UniPTEffect(0,effdat);
break;
- case 2:
+ case 2:
if(effdat&0xf) UniPTEffect(1,effdat&0xf);
else if(effdat>>2) UniPTEffect(2,effdat>>2);
break;
@@ -351,7 +352,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect)
}
if (effect == 8)
of.flags |= UF_PANNING;
-
+
return effect;
}
@@ -372,8 +373,7 @@ static UBYTE *M15_ConvertTrack(MODNOTE* n)
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
static int M15_LoadPatterns(void)
{
- int t,tracks=0;
- unsigned int s;
+ unsigned int t,s,tracks=0;
if(!AllocPatterns()) return 0;
if(!AllocTracks()) return 0;
@@ -398,9 +398,10 @@ static int M15_LoadPatterns(void)
static int M15_Load(int curious)
{
- int t,scan;
+ unsigned int t,scan;
SAMPLE *q;
MSAMPINFO *s;
+ (void)curious;
/* try to read module header */
if(!LoadModuleHeader(mh)) {
@@ -409,14 +410,14 @@ static int M15_Load(int curious)
}
if(ust_loader)
- of.modtype = StrDup("Ultimate Soundtracker");
+ of.modtype = MikMod_strdup("Ultimate Soundtracker");
else
- of.modtype = StrDup("Soundtracker");
+ of.modtype = MikMod_strdup("Soundtracker");
/* set module variables */
of.initspeed = 6;
of.inittempo = 125;
- of.numchn = 4;
+ of.numchn = 4;
of.songname = DupStr(mh->songname,21,1);
of.numpos = mh->songlength;
of.reppos = 0;
@@ -467,7 +468,7 @@ static int M15_Load(int curious)
q->length = s->length<<1;
q->flags = SF_SIGNED;
- if(ust_loader) q->flags |= SF_UST_LOOP;
+ if(ust_loader) q->flags |= SF_UST_LOOP;
if(s->replen>2) q->flags |= SF_LOOP;
s++;
diff --git a/apps/plugins/mikmod/load_med.c b/apps/plugins/mikmod/load_med.c
index aafb6602a6..a6af8c06cb 100644
--- a/apps/plugins/mikmod/load_med.c
+++ b/apps/plugins/mikmod/load_med.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_med.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Amiga MED module loader
@@ -189,6 +189,12 @@ static void MED_Cleanup(void)
MikMod_free(ba);
MikMod_free(mmd0pat);
MikMod_free(mmd1pat);
+ me = NULL;
+ mh = NULL;
+ ms = NULL;
+ ba = NULL;
+ mmd0pat = NULL;
+ mmd1pat = NULL;
}
static void EffectCvt(UBYTE eff, UBYTE dat)
@@ -338,7 +344,13 @@ static int LoadMEDPatterns(void)
of.numchn = numtracks;
if (numlines > maxlines)
maxlines = numlines;
+ /* sanity check */
+ if (numtracks > 64)
+ return 0;
}
+ /* sanity check */
+ if (! of.numchn) /* docs say 4, 8, 12 or 16 */
+ return 0;
of.numtrk = of.numpat * of.numchn;
if (!AllocTracks())
@@ -346,10 +358,8 @@ static int LoadMEDPatterns(void)
if (!AllocPatterns())
return 0;
- if (!
- (mmd0pat =
- (MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1),
- sizeof(MMD0NOTE)))) return 0;
+ if (!(mmd0pat = (MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD0NOTE))))
+ return 0;
/* second read: read and convert patterns */
for (t = 0; t < of.numpat; t++) {
@@ -388,7 +398,15 @@ static int LoadMMD1Patterns(void)
of.numchn = numtracks;
if (numlines > maxlines)
maxlines = numlines;
+ /* sanity check */
+ if (numtracks > 64)
+ return 0;
+ if (numlines >= 3200) /* per docs */
+ return 0;
}
+ /* sanity check */
+ if (! of.numchn) /* docs say 4, 8, 12 or 16 */
+ return 0;
of.numtrk = of.numpat * of.numchn;
if (!AllocTracks())
@@ -396,10 +414,8 @@ static int LoadMMD1Patterns(void)
if (!AllocPatterns())
return 0;
- if (!
- (mmd1pat =
- (MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1),
- sizeof(MMD1NOTE)))) return 0;
+ if (!(mmd1pat = (MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD1NOTE))))
+ return 0;
/* second read: really read and convert patterns */
for (t = 0; t < of.numpat; t++) {
@@ -471,6 +487,11 @@ static int MED_Load(int curious)
ms->numblocks = _mm_read_M_UWORD(modreader);
ms->songlen = _mm_read_M_UWORD(modreader);
_mm_read_UBYTES(ms->playseq, 256, modreader);
+ /* sanity check */
+ if (ms->numblocks > 255 || ms->songlen > 256) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
ms->deftempo = _mm_read_M_UWORD(modreader);
ms->playtransp = _mm_read_SBYTE(modreader);
ms->flags = _mm_read_UBYTE(modreader);
@@ -479,6 +500,11 @@ static int MED_Load(int curious)
_mm_read_UBYTES(ms->trkvol, 16, modreader);
ms->mastervol = _mm_read_UBYTE(modreader);
ms->numsamples = _mm_read_UBYTE(modreader);
+ /* sanity check */
+ if (ms->numsamples > 64) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
/* check for a bad header */
if (_mm_eof(modreader)) {
@@ -505,6 +531,14 @@ static int MED_Load(int curious)
me->songname = _mm_read_M_ULONG(modreader);
me->songnamelen = _mm_read_M_ULONG(modreader);
me->dumps = _mm_read_M_ULONG(modreader);
+ /* sanity check */
+ if (me->annolen > 0xffff) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
+ /* truncate insane songnamelen (fail instead??) */
+ if (me->songnamelen > 256)
+ me->songnamelen = 256;
}
/* seek to and read the samplepointer array */
@@ -526,8 +560,14 @@ static int MED_Load(int curious)
/* copy song positions */
if (!AllocPositions(ms->songlen))
return 0;
- for (t = 0; t < ms->songlen; t++)
+ for (t = 0; t < ms->songlen; t++) {
of.positions[t] = ms->playseq[t];
+ if (of.positions[t]>ms->numblocks) { /* SANITIY CHECK */
+ /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],ms->numblocks);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
+ }
decimalvolumes = (ms->flags & 0x10) ? 0 : 1;
bpmtempos = (ms->flags2 & 0x20) ? 1 : 0;
@@ -571,7 +611,7 @@ static int MED_Load(int curious)
of.flags |= UF_HIGHBPM;
}
MED_Version[12] = mh->id;
- of.modtype = StrDup(MED_Version);
+ of.modtype = MikMod_strdup(MED_Version);
of.numchn = 0; /* will be counted later */
of.numpat = ms->numblocks;
of.numpos = ms->songlen;
@@ -582,7 +622,7 @@ static int MED_Load(int curious)
char *name;
_mm_fseek(modreader, me->songname, SEEK_SET);
- name = MikMod_malloc(me->songnamelen);
+ name = (char *) MikMod_malloc(me->songnamelen);
_mm_read_UBYTES(name, me->songnamelen, modreader);
of.songname = DupStr(name, me->songnamelen, 1);
MikMod_free(name);
@@ -684,17 +724,17 @@ static CHAR *MED_LoadTitle(void)
{
ULONG posit, namelen;
CHAR *name, *retvalue = NULL;
-
+
_mm_fseek(modreader, 0x20, SEEK_SET);
posit = _mm_read_M_ULONG(modreader);
-
+
if (posit) {
_mm_fseek(modreader, posit + 0x2C, SEEK_SET);
posit = _mm_read_M_ULONG(modreader);
namelen = _mm_read_M_ULONG(modreader);
_mm_fseek(modreader, posit, SEEK_SET);
- name = MikMod_malloc(namelen);
+ name = (CHAR*) MikMod_malloc(namelen);
_mm_read_UBYTES(name, namelen, modreader);
retvalue = DupStr(name, namelen, 1);
MikMod_free(name);
diff --git a/apps/plugins/mikmod/load_mod.c b/apps/plugins/mikmod/load_mod.c
index 6075e9c7e1..0fe0dcd595 100644
--- a/apps/plugins/mikmod/load_mod.c
+++ b/apps/plugins/mikmod/load_mod.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_mod.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Generic MOD loader (Protracker, StarTracker, FastTracker, etc)
@@ -108,7 +108,7 @@ static int MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
*numchn = 4;
return 1;
}
-
+
/* Star Tracker */
if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
(isdigit(id[3]))) {
@@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
+ mh=NULL;
+ patbuf=NULL;
}
/*
@@ -277,7 +279,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
/* Handle ``heavy'' volumes correctly */
if ((effect == 0xc) && (effdat > 0x40))
effdat = 0x40;
-
+
/* An isolated 100, 200 or 300 effect should be ignored (no
"standalone" porta memory in mod files). However, a sequence such
as 1XX, 100, 100, 100 is fine. */
@@ -288,7 +290,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
UniPTEffect(effect, effdat);
if (effect == 8)
of.flags |= UF_PANNING;
-
+
return effect;
}
@@ -309,14 +311,13 @@ static UBYTE *ConvertTrack(MODNOTE *n, int numchn)
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
static int ML_LoadPatterns(void)
{
- int t, tracks = 0;
- unsigned int s;
+ unsigned int t, s, tracks = 0;
if (!AllocPatterns())
return 0;
if (!AllocTracks())
return 0;
-
+
/* Allocate temporary buffer for loading and converting the patterns */
if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
return 0;
@@ -385,10 +386,10 @@ static int MOD_Load(int curious)
mh->songlength = _mm_read_UBYTE(modreader);
- /* this fixes mods which declare more than 128 positions.
+ /* this fixes mods which declare more than 128 positions.
* eg: beatwave.mod */
if (mh->songlength > 128) { mh->songlength = 128; }
-
+
mh->magic1 = _mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->positions, 128, modreader);
_mm_read_UBYTES(mh->magic2, 4, modreader);
@@ -477,11 +478,11 @@ static int MOD_Load(int curious)
q++;
}
- of.modtype = StrDup(descr);
+ of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns())
return 0;
-
+
return 1;
}
diff --git a/apps/plugins/mikmod/load_mtm.c b/apps/plugins/mikmod/load_mtm.c
index 6c9fb30846..5620575a10 100644
--- a/apps/plugins/mikmod/load_mtm.c
+++ b/apps/plugins/mikmod/load_mtm.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_mtm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
MTM module loader
@@ -108,6 +108,8 @@ static void MTM_Cleanup(void)
{
MikMod_free(mtmtrk);
MikMod_free(mh);
+ mtmtrk=NULL;
+ mh=NULL;
}
static UBYTE* MTM_Convert(void)
@@ -145,7 +147,7 @@ static int MTM_Load(int curious)
int t,u;
MTMSAMPLE s;
SAMPLE *q;
- (void)curious;
+ (void)curious;
/* try to read module header */
_mm_read_UBYTES(mh->id,3,modreader);
@@ -169,7 +171,7 @@ static int MTM_Load(int curious)
/* set module variables */
of.initspeed = 6;
of.inittempo = 125;
- of.modtype = StrDup(MTM_Version);
+ of.modtype = MikMod_strdup(MTM_Version);
of.numchn = mh->numchannels;
of.numtrk = mh->numtracks+1; /* get number of channels */
of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */
@@ -193,7 +195,7 @@ static int MTM_Load(int curious)
s.attribute =_mm_read_UBYTE(modreader);
if(_mm_eof(modreader)) {
- _mm_errno = MMERR_LOADING_SAMPLEINFO;
+ _mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@@ -218,9 +220,15 @@ static int MTM_Load(int curious)
}
if(!AllocPositions(of.numpos)) return 0;
- for(t=0;t<of.numpos;t++)
+ for(t=0;t<of.numpos;t++) {
of.positions[t]=_mm_read_UBYTE(modreader);
- for(;t<128;t++) (void)_mm_read_UBYTE(modreader);
+ if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
+ }
+ for(;t<128;t++) _mm_skip_BYTE(modreader);
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_HEADER;
return 0;
@@ -231,12 +239,12 @@ static int MTM_Load(int curious)
of.tracks[0]=MTM_Convert(); /* track 0 is empty */
for(t=1;t<of.numtrk;t++) {
- int s;
+ int s_idx;
- for(s=0;s<64;s++) {
- mtmtrk[s].a=_mm_read_UBYTE(modreader);
- mtmtrk[s].b=_mm_read_UBYTE(modreader);
- mtmtrk[s].c=_mm_read_UBYTE(modreader);
+ for(s_idx=0;s_idx<64;s_idx++) {
+ mtmtrk[s_idx].a=_mm_read_UBYTE(modreader);
+ mtmtrk[s_idx].b=_mm_read_UBYTE(modreader);
+ mtmtrk[s_idx].c=_mm_read_UBYTE(modreader);
}
if(_mm_eof(modreader)) {
diff --git a/apps/plugins/mikmod/load_okt.c b/apps/plugins/mikmod/load_okt.c
index 6a40b5fe03..a0eee7f56e 100644
--- a/apps/plugins/mikmod/load_okt.c
+++ b/apps/plugins/mikmod/load_okt.c
@@ -20,7 +20,7 @@
/*==============================================================================
- $Id: load_okt.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Oktalyzer (OKT) module loader
@@ -203,7 +203,7 @@ static int OKT_doSAMP(int len)
s.len = _mm_read_M_ULONG(modreader);
s.loopbeg = _mm_read_M_UWORD(modreader) * 2;
s.looplen = _mm_read_M_UWORD(modreader) * 2;
- (void)_mm_read_UBYTE(modreader);
+ _mm_skip_BYTE(modreader);
s.volume = _mm_read_UBYTE(modreader);
_mm_read_M_UWORD(modreader);
@@ -314,6 +314,7 @@ static int OKT_doPBOD(int patnum)
}
MikMod_free(patbuf);
MikMod_free(okttrk);
+ okttrk = NULL;
return 1;
}
@@ -330,28 +331,28 @@ static int OKT_Load(int curious)
int seen_cmod = 0, seen_samp = 0, seen_slen = 0, seen_plen = 0, seen_patt
= 0, seen_spee = 0;
int patnum = 0, insnum = 0;
- (void)curious;
+ (void)curious;
/* skip OKTALYZER header */
_mm_fseek(modreader, 8, SEEK_SET);
- of.songname = StrDup("");
+ of.songname = MikMod_strdup("");
- of.modtype = StrDup("Amiga Oktalyzer");
+ of.modtype = MikMod_strdup("Amiga Oktalyzer");
of.numpos = of.reppos = 0;
-
+
/* default values */
of.initspeed = 6;
of.inittempo = 125;
-
+
while (1) {
/* read block header */
_mm_read_UBYTES(id, 4, modreader);
len = _mm_read_M_ULONG(modreader);
-
+
if (_mm_eof(modreader))
break;
fp = _mm_ftell(modreader);
-
+
if (!memcmp(id, "CMOD", 4)) {
if (!seen_cmod) {
OKT_doCMOD();
@@ -442,7 +443,7 @@ static int OKT_Load(int curious)
static CHAR *OKT_LoadTitle(void)
{
- return StrDup("");
+ return MikMod_strdup("");
}
/*========== Loader information */
diff --git a/apps/plugins/mikmod/load_s3m.c b/apps/plugins/mikmod/load_s3m.c
index e162388f15..076159afc5 100644
--- a/apps/plugins/mikmod/load_s3m.c
+++ b/apps/plugins/mikmod/load_s3m.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_s3m.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Screamtracker (S3M) module loader
@@ -104,7 +104,7 @@ static unsigned int tracker; /* tracker id */
/* tracker identifiers */
#define NUMTRACKERS 4
-static CHAR* S3M_Version[] = {
+static const CHAR * S3M_Version[] = {
"Screamtracker x.xx",
"Imago Orpheus x.xx (S3M format)",
"Impulse Tracker x.xx (S3M format)",
@@ -113,7 +113,7 @@ static CHAR* S3M_Version[] = {
"Impulse Tracker 2.14p4 (S3M format)"
};
/* version number position in above array */
-static int numeric[NUMTRACKERS]={14,14,16,16};
+static const int numeric[NUMTRACKERS]={14,14,16,16};
/*========== Loader code */
@@ -144,6 +144,11 @@ static void S3M_Cleanup(void)
MikMod_free(poslookup);
MikMod_free(mh);
MikMod_free(origpositions);
+ s3mbuf=NULL;
+ paraptr=NULL;
+ poslookup=NULL;
+ mh=NULL;
+ origpositions=NULL;
}
/* Because so many s3m files have 16 channels as the set number used, but really
@@ -154,9 +159,9 @@ static void S3M_Cleanup(void)
global variable 'remap'
NOTE: You must first seek to the file location of the pattern before calling
- this procedure.
+ this procedure.
- Returns 1 on fail. */
+ Returns 0 on fail. */
static int S3M_GetNumChannels(void)
{
int row=0,flag,ch;
@@ -166,19 +171,19 @@ static int S3M_GetNumChannels(void)
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN;
- return 1;
+ return 0;
}
if(flag) {
ch=flag&31;
if(mh->channels[ch]<32) remap[ch] = 0;
- if(flag&32) {(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);}
- if(flag&64) (void)_mm_read_UBYTE(modreader);
- if(flag&128){(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);}
+ if(flag&32) {_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
+ if(flag&64) _mm_skip_BYTE(modreader);
+ if(flag&128){_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
} else row++;
}
- return 0;
-}
+ return 1;
+}
static int S3M_ReadPattern(void)
{
@@ -282,6 +287,10 @@ static int S3M_Load(int curious)
_mm_errno = MMERR_LOADING_HEADER;
return 0;
}
+ if(mh->ordnum > 255 || mh->insnum > 255 || mh->patnum > 255) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
/* then we can decide the module type */
tracker=mh->tracker>>12;
@@ -294,7 +303,7 @@ static int S3M_Load(int curious)
tracker=NUMTRACKERS; /* IT 2.14p3 */
else tracker--;
}
- of.modtype = StrDup(S3M_Version[tracker]);
+ of.modtype = MikMod_strdup(S3M_Version[tracker]);
if(tracker<NUMTRACKERS) {
of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0';
of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0';
@@ -315,7 +324,7 @@ static int S3M_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;t<mh->ordnum;t++) {
origpositions[t]=_mm_read_UBYTE(modreader);
@@ -374,7 +383,8 @@ static int S3M_Load(int curious)
_mm_read_string(s.scrs,4,modreader);
/* ScreamTracker imposes a 64000 bytes (not 64k !) limit */
- if (s.length > 64000)
+ /* enforce it, if we'll use S3MIT_SCREAM in S3M_ConvertTrack() */
+ if (s.length > 64000 && tracker == 1)
s.length = 64000;
if(_mm_eof(modreader)) {
@@ -388,7 +398,7 @@ static int S3M_Load(int curious)
q->loopstart = s.loopbeg;
q->loopend = s.loopend;
q->volume = s.volume;
- q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4;
+ q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4;
if(s.flags&1) q->flags |= SF_LOOP;
if(s.flags&4) q->flags |= SF_16BITS;
@@ -406,16 +416,16 @@ static int S3M_Load(int curious)
for(t=0;t<of.numpat;t++) {
/* seek to pattern position (+2 skip pattern length) */
_mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET);
- if(S3M_GetNumChannels()) return 0;
+ if(!S3M_GetNumChannels()) return 0;
}
/* build the remap array */
for(t=0;t<32;t++)
- if(!remap[t])
+ if(!remap[t])
remap[t]=of.numchn++;
/* set panning positions after building remap chart! */
- for(t=0;t<32;t++)
+ for(t=0;t<32;t++)
if((mh->channels[t]<32)&&(remap[t]!=-1)) {
if(mh->channels[t]<8)
of.panning[remap[t]]=0x30;
diff --git a/apps/plugins/mikmod/load_stm.c b/apps/plugins/mikmod/load_stm.c
index 994b0e5355..c62a6d7f36 100644
--- a/apps/plugins/mikmod/load_stm.c
+++ b/apps/plugins/mikmod/load_stm.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_stm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
Screamtracker 2 (STM) module loader
@@ -74,7 +74,7 @@ typedef struct STMHEADER {
UBYTE ver_minor;
UBYTE inittempo; /* initspeed= stm inittempo>>4 */
UBYTE numpat; /* number of patterns */
- UBYTE globalvol;
+ UBYTE globalvol;
UBYTE reserved[13];
STMSAMPLE sample[31]; /* STM sample data */
UBYTE patorder[128]; /* Docs say 64 - actually 128 */
@@ -90,7 +90,7 @@ static STMNOTE *stmbuf = NULL;
static STMHEADER *mh = NULL;
/* tracker identifiers */
-static CHAR* STM_Version[STM_NTRACKERS] = {
+static const CHAR * STM_Version[STM_NTRACKERS] = {
"Screamtracker 2",
"Converted by MOD2STM (STM format)",
"Wuzamod (STM format)"
@@ -103,6 +103,7 @@ static int STM_Test(void)
UBYTE str[44];
int t;
+ memset(str,0,44);
_mm_fseek(modreader,20,SEEK_SET);
_mm_read_UBYTES(str,44,modreader);
if(str[9]!=2) return 0; /* STM Module = filetype 2 */
@@ -110,7 +111,7 @@ static int STM_Test(void)
/* Prevent false positives for S3M files */
if(!memcmp(str+40,"SCRM",4))
return 0;
-
+
for (t=0;t<STM_NTRACKERS;t++)
if(!memcmp(str,STM_Signatures[t],8))
return 1;
@@ -130,6 +131,8 @@ static void STM_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(stmbuf);
+ mh=NULL;
+ stmbuf=NULL;
}
static void STM_ConvertNote(STMNOTE *n)
@@ -145,7 +148,7 @@ static void STM_ConvertNote(STMNOTE *n)
if((ins)&&(ins<32)) UniInstrument(ins-1);
- /* special values of [SBYTE0] are handled here
+ /* special values of [SBYTE0] are handled here
we have no idea if these strange values will ever be encountered.
but it appears as those stms sound correct. */
if((note==254)||(note==252)) {
@@ -224,8 +227,7 @@ static UBYTE *STM_ConvertTrack(STMNOTE *n)
static int STM_LoadPatterns(void)
{
- int t,tracks=0;
- unsigned int s;
+ unsigned int t,s,tracks=0;
if(!AllocPatterns()) return 0;
if(!AllocTracks()) return 0;
@@ -252,10 +254,10 @@ static int STM_LoadPatterns(void)
static int STM_Load(int curious)
{
- int t;
+ int t;
ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */
SAMPLE *q;
- (void)curious;
+ (void)curious;
/* try to read stm header */
_mm_read_string(mh->songname,20,modreader);
@@ -272,6 +274,10 @@ static int STM_Load(int curious)
mh->numpat =_mm_read_UBYTE(modreader);
mh->globalvol =_mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->reserved,13,modreader);
+ if(mh->numpat > 128) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
for(t=0;t<31;t++) {
STMSAMPLE *s=&mh->sample[t]; /* STM sample data */
@@ -299,9 +305,7 @@ static int STM_Load(int curious)
/* set module variables */
for(t=0;t<STM_NTRACKERS;t++)
if(!memcmp(mh->trackername,STM_Signatures[t],8)) break;
- if(t == STM_NTRACKERS)
- return 0;
- of.modtype = StrDup(STM_Version[t]);
+ of.modtype = MikMod_strdup(STM_Version[t]);
of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */
of.numpat = mh->numpat;
of.inittempo = 125; /* mh->inittempo+0x1c; */
@@ -316,7 +320,10 @@ static int STM_Load(int curious)
/* 99 terminates the patorder list */
while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) {
of.positions[t]=mh->patorder[t];
- t++;
+ if(++t == 0x80) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
}
if(mh->patorder[t]<=99) t++;
of.numpos=t;
@@ -334,7 +341,7 @@ static int STM_Load(int curious)
q->speed = (mh->sample[t].c2spd * 8363) / 8448;
q->volume = mh->sample[t].volume;
q->length = mh->sample[t].length;
- if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0;
+ if (/*!mh->sample[t].volume || */q->length==1) q->length=0;
q->loopstart = mh->sample[t].loopbeg;
q->loopend = mh->sample[t].loopend;
q->seekpos = MikMod_ISA;
@@ -374,5 +381,4 @@ MIKMODAPI MLOADER load_stm={
STM_LoadTitle
};
-
/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/load_stx.c b/apps/plugins/mikmod/load_stx.c
index ac6e51f4c7..db25813342 100644
--- a/apps/plugins/mikmod/load_stx.c
+++ b/apps/plugins/mikmod/load_stx.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_stx.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
STMIK 0.2 (STX) module loader
@@ -114,13 +114,14 @@ static int STX_Test(void)
UBYTE id[8];
int t;
+ memset(id,0,8);
_mm_fseek(modreader,0x3C,SEEK_SET);
if(!_mm_read_UBYTES(id,4,modreader)) return 0;
if(memcmp(id,"SCRM",4)) return 0;
_mm_fseek(modreader,0x14,SEEK_SET);
if(!_mm_read_UBYTES(id,8,modreader)) return 0;
-
+
for(t=0;t<STM_NTRACKERS;t++)
if(!memcmp(id,STM_Signatures[t],8)) return 1;
@@ -143,6 +144,10 @@ static void STX_Cleanup(void)
MikMod_free(paraptr);
MikMod_free(poslookup);
MikMod_free(mh);
+ stxbuf=NULL;
+ paraptr=NULL;
+ poslookup=NULL;
+ mh=NULL;
}
static int STX_ReadPattern(void)
@@ -297,6 +302,11 @@ static int STX_Load(int curious)
_mm_errno = MMERR_LOADING_HEADER;
return 0;
}
+ if(mh->ordnum > 256 || !mh->insnum || mh->insnum > 256 ||
+ mh->patnum > 254 || !mh->patnum) {
+ _mm_errno = MMERR_NOT_A_MODULE;
+ return 0;
+ }
/* set module variables */
of.songname = DupStr(mh->songname,20,1);
@@ -323,10 +333,10 @@ static int STX_Load(int curious)
version=_mm_read_I_UWORD(modreader);
if(version==mh->patsize) {
version = 0x10;
- of.modtype = StrDup("STMIK 0.2 (STM2STX 1.0)");
+ of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.0)");
} else {
version = 0x11;
- of.modtype = StrDup("STMIK 0.2 (STM2STX 1.1)");
+ of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.1)");
}
/* read the order data */
@@ -343,7 +353,7 @@ static int STX_Load(int curious)
if(order==255) order=LAST_PATTERN;
of.positions[of.numpos]=order;
poslookup[t]=of.numpos; /* bug fix for freaky S3Ms */
- if(of.positions[t]<254) of.numpos++;
+ if(of.positions[t]<254) of.numpos++;
else
/* special end of song pattern */
if((order==LAST_PATTERN)&&(!curious)) break;
@@ -389,7 +399,7 @@ static int STX_Load(int curious)
q->loopstart = s.loopbeg;
q->loopend = s.loopend;
q->volume = s.volume;
- q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4;
+ q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4;
q->flags |= SF_SIGNED;
if(s.flags&1) q->flags |= SF_LOOP;
diff --git a/apps/plugins/mikmod/load_ult.c b/apps/plugins/mikmod/load_ult.c
index f56c2df06b..1d4e5cf72b 100644
--- a/apps/plugins/mikmod/load_ult.c
+++ b/apps/plugins/mikmod/load_ult.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_ult.c,v 1.3 2010/01/12 03:30:32 realtech Exp $
+ $Id$
Ultratracker (ULT) module loader
@@ -80,7 +80,7 @@ typedef struct ULTEVENT {
#define ULTS_REVERSE 16
#define ULT_VERSION_LEN 18
-static CHAR ULT_Version[ULT_VERSION_LEN]="Ultra Tracker v1.x";
+static CHAR ULT_Version[ULT_VERSION_LEN+1]="Ultra Tracker v1.x";
static ULTEVENT ev;
@@ -130,8 +130,8 @@ static int ULT_Load(int curious)
SAMPLE *q;
ULTSAMPLE s;
ULTHEADER mh;
- UBYTE nos,noc,rbnop;
- (void)curious;
+ UBYTE nos,noc,RBnop;
+ (void)curious;
/* try to read module header */
_mm_read_string(mh.id,15,modreader);
@@ -207,29 +207,37 @@ static int ULT_Load(int curious)
if(!AllocPositions(256)) return 0;
for(t=0;t<256;t++)
of.positions[t]=_mm_read_UBYTE(modreader);
- for(t=0;t<256;t++)
+
+ noc=_mm_read_UBYTE(modreader);
+ RBnop=_mm_read_UBYTE(modreader);
+
+ of.numchn=++noc;
+ of.numpat=++RBnop;
+ of.numtrk=of.numchn*of.numpat;
+
+ for(t=0;t<256;t++) {
if(of.positions[t]==255) {
of.positions[t]=LAST_PATTERN;
break;
}
+ if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
+ }
of.numpos=t;
- noc=_mm_read_UBYTE(modreader);
- rbnop=_mm_read_UBYTE(modreader);
-
- of.numchn=++noc;
- of.numpat=++rbnop;
- of.numtrk=of.numchn*of.numpat;
if(!AllocTracks()) return 0;
if(!AllocPatterns()) return 0;
for(u=0;u<of.numchn;u++)
for(t=0;t<of.numpat;t++)
of.patterns[(t*of.numchn)+u]=tracks++;
- // SA37775
+ /* Secunia SA37775 / CVE-2009-3996 */
if (of.numchn>=UF_MAXCHAN)
of.numchn=UF_MAXCHAN - 1;
-
+
/* read pan position table for v1.5 and higher */
if(mh.id[14]>='3') {
for(t=0;t<of.numchn;t++) of.panning[t]=_mm_read_UBYTE(modreader)<<4;
@@ -313,7 +321,7 @@ static int ULT_Load(int curious)
return 1;
}
-static CHAR *ULT_LoadTitle(void)
+static CHAR * ULT_LoadTitle(void)
{
CHAR s[32];
diff --git a/apps/plugins/mikmod/load_umx.c b/apps/plugins/mikmod/load_umx.c
new file mode 100644
index 0000000000..1a0535affd
--- /dev/null
+++ b/apps/plugins/mikmod/load_umx.c
@@ -0,0 +1,476 @@
+/* MikMod sound library
+ * (c) 2003-2004 Raphael Assenat and others - see file
+ * AUTHORS for complete list.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * 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
+ * 02111-1307, USA.
+ */
+
+/* Epic Games Unreal UMX container loading for libmikmod
+ * Written by O. Sezer <sezero@users.sourceforge.net>
+ *
+ * Records data type/offset info in its Test() function, then acts
+ * as a middle-man, forwarding calls to the real loader units. It
+ * requires that the MREADER implementation in use always respects
+ * its iobase fields. Like all other libmikmod loaders, this code
+ * is not reentrant yet.
+ *
+ * UPKG parsing partially based on Unreal Media Ripper (UMR) v0.3
+ * by Andy Ward <wardwh@swbell.net>, with additional updates
+ * by O. Sezer - see git repo at https://github.com/sezero/umr/
+ *
+ * The cheaper way, i.e. linear search of music object like libxmp
+ * and libmodplug does, is possible. With this however we're using
+ * the embedded offset, size and object type directly from the umx
+ * file, and I feel safer with it.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mikmod_internals.h"
+
+
+/*========== upkg defs */
+
+typedef SLONG fci_t; /* FCompactIndex */
+
+#define UPKG_HDR_TAG 0x9e2a83c1
+
+struct _genhist { /* for upkg versions >= 68 */
+ SLONG export_count;
+ SLONG name_count;
+};
+
+struct upkg_hdr {
+ ULONG tag; /* UPKG_HDR_TAG */
+ SLONG file_version;
+ ULONG pkg_flags;
+ SLONG name_count; /* number of names in name table (>= 0) */
+ SLONG name_offset; /* offset to name table (>= 0) */
+ SLONG export_count; /* num. exports in export table (>= 0) */
+ SLONG export_offset; /* offset to export table (>= 0) */
+ SLONG import_count; /* num. imports in export table (>= 0) */
+ SLONG import_offset; /* offset to import table (>= 0) */
+
+ /* number of GUIDs in heritage table (>= 1) and table's offset:
+ * only with versions < 68. */
+ SLONG heritage_count;
+ SLONG heritage_offset;
+ /* with versions >= 68: a GUID, a dword for generation count
+ * and export_count and name_count dwords for each generation: */
+ ULONG guid[4];
+ SLONG generation_count;
+#define UPKG_HDR_SIZE 64 /* 64 bytes up until here */
+ /*struct _genhist *gen;*/
+};
+/* compile time assert for upkg_hdr size */
+/*typedef int _check_hdrsize[2 * (offsetof(struct upkg_hdr, gen) == UPKG_HDR_SIZE) - 1];*/
+typedef int _check_hdrsize[2 * (sizeof(struct upkg_hdr) == UPKG_HDR_SIZE) - 1];
+
+/*========== Supported content types */
+
+#define UMUSIC_IT 0
+#define UMUSIC_S3M 1
+#define UMUSIC_XM 2
+#define UMUSIC_MOD 3
+
+static const char *mustype[] = {
+ "IT", "S3M", "XM", "MOD",
+ NULL
+};
+
+/*========== UPKG parsing */
+
+/* decode an FCompactIndex.
+ * original documentation by Tim Sweeney was at
+ * http://unreal.epicgames.com/Packages.htm
+ * also see Unreal Wiki:
+ * http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details
+ */
+static fci_t get_fci (const char *in, int *pos)
+{
+ SLONG a;
+ int size;
+
+ size = 1;
+ a = in[0] & 0x3f;
+
+ if (in[0] & 0x40) {
+ size++;
+ a |= (in[1] & 0x7f) << 6;
+
+ if (in[1] & 0x80) {
+ size++;
+ a |= (in[2] & 0x7f) << 13;
+
+ if (in[2] & 0x80) {
+ size++;
+ a |= (in[3] & 0x7f) << 20;
+
+ if (in[3] & 0x80) {
+ size++;
+ a |= (in[4] & 0x3f) << 27;
+ }
+ }
+ }
+ }
+
+ if (in[0] & 0x80)
+ a = -a;
+
+ *pos += size;
+
+ return a;
+}
+
+static int get_objtype (SLONG ofs, int type)
+{
+ char sig[16];
+_retry:
+ _mm_fseek(modreader, ofs, SEEK_SET);
+ _mm_read_UBYTES(sig, 16, modreader);
+ if (type == UMUSIC_IT) {
+ if (memcmp(sig, "IMPM", 4) == 0)
+ return UMUSIC_IT;
+ return -1;
+ }
+ if (type == UMUSIC_XM) {
+ if (memcmp(sig, "Extended Module:", 16) != 0)
+ return -1;
+ _mm_read_UBYTES(sig, 16, modreader);
+ if (sig[0] != ' ') return -1;
+ _mm_read_UBYTES(sig, 16, modreader);
+ if (sig[5] != 0x1a) return -1;
+ return UMUSIC_XM;
+ }
+
+ _mm_fseek(modreader, ofs + 44, SEEK_SET);
+ _mm_read_UBYTES(sig, 4, modreader);
+ if (type == UMUSIC_S3M) {
+ if (memcmp(sig, "SCRM", 4) == 0)
+ return UMUSIC_S3M;
+ /*return -1;*/
+ /* SpaceMarines.umx and Starseek.umx from Return to NaPali
+ * report as "s3m" whereas the actual music format is "it" */
+ type = UMUSIC_IT;
+ goto _retry;
+ }
+
+ _mm_fseek(modreader, ofs + 1080, SEEK_SET);
+ _mm_read_UBYTES(sig, 4, modreader);
+ if (type == UMUSIC_MOD) {
+ if (memcmp(sig, "M.K.", 4) == 0 || memcmp(sig, "M!K!", 4) == 0)
+ return UMUSIC_MOD;
+ return -1;
+ }
+
+ return -1;
+}
+
+static int read_export (const struct upkg_hdr *hdr,
+ SLONG *ofs, SLONG *objsize)
+{
+ char buf[40];
+ int idx = 0, t;
+
+ _mm_fseek(modreader, *ofs, SEEK_SET);
+ if (!_mm_read_UBYTES(buf, 40, modreader))
+ return -1;
+
+ if (hdr->file_version < 40) idx += 8; /* 00 00 00 00 00 00 00 00 */
+ if (hdr->file_version < 60) idx += 16; /* 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 */
+ get_fci(&buf[idx], &idx); /* skip junk */
+ t = get_fci(&buf[idx], &idx); /* type_name */
+ if (hdr->file_version > 61) idx += 4; /* skip export size */
+ *objsize = get_fci(&buf[idx], &idx);
+ *ofs += idx; /* offset for real data */
+
+ return t; /* return type_name index */
+}
+
+static int read_typname(const struct upkg_hdr *hdr,
+ int idx, char *out)
+{
+ int i, s;
+ long l;
+ char buf[64];
+
+ if (idx >= hdr->name_count) return -1;
+ buf[63] = '\0';
+ for (i = 0, l = 0; i <= idx; i++) {
+ _mm_fseek(modreader, hdr->name_offset + l, SEEK_SET);
+ _mm_read_UBYTES(buf, 63, modreader);
+ if (hdr->file_version >= 64) {
+ s = *(signed char *)buf; /* numchars *including* terminator */
+ if (s <= 0 || s > 64) return -1;
+ l += s + 5; /* 1 for buf[0], 4 for int32_t name_flags */
+ } else {
+ l += (long)strlen(buf);
+ l += 5; /* 1 for terminator, 4 for int32_t name_flags */
+ }
+ }
+
+ strcpy(out, (hdr->file_version >= 64)? &buf[1] : buf);
+ return 0;
+}
+
+static int probe_umx (const struct upkg_hdr *hdr,
+ SLONG *ofs, SLONG *objsize)
+{
+ int i, idx, t;
+ SLONG s, pos;
+ long fsiz;
+ char buf[64];
+
+ idx = 0;
+ _mm_fseek(modreader, 0, SEEK_END);
+ fsiz = _mm_ftell(modreader);
+
+ /* Find the offset and size of the first IT, S3M or XM
+ * by parsing the exports table. The umx files should
+ * have only one export. Kran32.umx from Unreal has two,
+ * but both pointing to the same music. */
+ if (hdr->export_offset >= fsiz) return -1;
+ memset(buf, 0, 64);
+ _mm_fseek(modreader, hdr->export_offset, SEEK_SET);
+ _mm_read_UBYTES(buf, 64, modreader);
+
+ get_fci(&buf[idx], &idx); /* skip class_index */
+ get_fci(&buf[idx], &idx); /* skip super_index */
+ if (hdr->file_version >= 60) idx += 4; /* skip int32 package_index */
+ get_fci(&buf[idx], &idx); /* skip object_name */
+ idx += 4; /* skip int32 object_flags */
+
+ s = get_fci(&buf[idx], &idx); /* get serial_size */
+ if (s <= 0) return -1;
+ pos = get_fci(&buf[idx],&idx); /* get serial_offset */
+ if (pos < 0 || pos > fsiz - 40) return -1;
+
+ if ((t = read_export(hdr, &pos, &s)) < 0) return -1;
+ if (s <= 0 || s > fsiz - pos) return -1;
+
+ if (read_typname(hdr, t, buf) < 0) return -1;
+ for (i = 0; mustype[i] != NULL; i++) {
+ if (!strcasecmp(buf, mustype[i])) {
+ t = i;
+ break;
+ }
+ }
+ if (mustype[i] == NULL) return -1;
+ if ((t = get_objtype(pos, t)) < 0) return -1;
+
+ *ofs = pos;
+ *objsize = s;
+ return t;
+}
+
+static SLONG probe_header (void *header)
+{
+ struct upkg_hdr *hdr;
+ unsigned char *p;
+ ULONG *swp;
+ int i;
+
+ /* byte swap the header - all members are 32 bit LE values */
+ p = (unsigned char *) header;
+ swp = (ULONG *) header;
+ for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) {
+ swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+ }
+
+ hdr = (struct upkg_hdr *) header;
+ if (hdr->tag != UPKG_HDR_TAG) {
+ return -1;
+ }
+ if (hdr->name_count < 0 ||
+ hdr->name_offset < 0 ||
+ hdr->export_count < 0 ||
+ hdr->export_offset < 0 ||
+ hdr->import_count < 0 ||
+ hdr->import_offset < 0 ) {
+ return -1;
+ }
+
+ switch (hdr->file_version) {
+ case 35: case 37: /* Unreal beta - */
+ case 40: case 41: /* 1998 */
+ case 61:/* Unreal */
+ case 62:/* Unreal Tournament */
+ case 63:/* Return to NaPali */
+ case 64:/* Unreal Tournament */
+ case 66:/* Unreal Tournament */
+ case 68:/* Unreal Tournament */
+ case 69:/* Tactical Ops */
+ case 83:/* Mobile Forces */
+ return 0;
+ }
+
+ return -1;
+}
+
+static int process_upkg (SLONG *ofs, SLONG *objsize)
+{
+ char header[UPKG_HDR_SIZE];
+
+ if (!_mm_read_UBYTES(header, UPKG_HDR_SIZE, modreader))
+ return -1;
+ if (probe_header(header) < 0)
+ return -1;
+
+ return probe_umx((struct upkg_hdr *)header, ofs, objsize);
+}
+
+/*========== Loader vars */
+
+typedef struct _umx_info {
+ int type;
+ SLONG ofs, size;
+ MLOADER* loader;
+} umx_info;
+
+static umx_info *umx_data = NULL;
+
+/*========== Loader code */
+
+/* Without Test() being called first, Load[Title] is never called.
+ * A Test() is always followed by either a Load() or a LoadTitle().
+ * A Load() is always followed by Cleanup() regardless of success.
+ *
+ * Therefore, in between Test() and LoadTitle() or Load()/Cleanup(),
+ * we must remember the type and the offset of the umx music data,
+ * and always clear it when returning from LoadTitle() or Cleanup().
+ */
+
+static int UMX_Test(void)
+{
+ int type;
+ SLONG ofs = 0, size = 0;
+
+ if (umx_data) {
+#ifdef MIKMOD_DEBUG
+ fprintf(stderr, "UMX_Test called while a previous instance is active\n");
+#endif
+ MikMod_free(umx_data);
+ umx_data = NULL;
+ }
+
+ _mm_fseek(modreader, 0, SEEK_SET);
+ type = process_upkg(&ofs, &size);
+ if (type < 0 || type > UMUSIC_MOD)
+ return 0;
+
+ umx_data = (umx_info*) MikMod_calloc(1, sizeof(umx_info));
+ if (!umx_data) return 0;
+
+ umx_data->type = type;
+ umx_data->ofs = ofs;
+ umx_data->size = size;
+ switch (type) {
+ case UMUSIC_IT:
+ umx_data->loader = &load_it;
+ break;
+ case UMUSIC_S3M:
+ umx_data->loader = &load_s3m;
+ break;
+ case UMUSIC_XM:
+ umx_data->loader = &load_xm;
+ break;
+ case UMUSIC_MOD:
+ umx_data->loader = &load_mod;
+ break;
+ }
+
+ return 1;
+}
+
+static int UMX_Init(void)
+{
+ if (!umx_data || !umx_data->loader)
+ return 0;
+
+ if (umx_data->loader->Init)
+ return umx_data->loader->Init();
+
+ return 1;
+}
+
+static void UMX_Cleanup(void)
+{
+ if (!umx_data) return;
+
+ if (umx_data->loader && umx_data->loader->Cleanup)
+ umx_data->loader->Cleanup();
+
+ MikMod_free(umx_data);
+ umx_data = NULL;
+}
+
+static int UMX_Load(int curious)
+{
+ if (!umx_data || !umx_data->loader)
+ return 0;
+
+ _mm_fseek(modreader, umx_data->ofs, SEEK_SET);
+ /* set reader iobase to the umx object offset */
+ _mm_iobase_revert(modreader);
+ _mm_iobase_setcur(modreader);
+
+ return umx_data->loader->Load(curious);
+}
+
+static CHAR *UMX_LoadTitle(void)
+{
+ CHAR *title;
+
+ if (!umx_data) return NULL;
+
+ if (!umx_data->loader) {
+ title = NULL;
+ }
+ else {
+ _mm_fseek(modreader, umx_data->ofs, SEEK_SET);
+ /* set reader iobase to the umx object offset */
+ _mm_iobase_revert(modreader);
+ _mm_iobase_setcur(modreader);
+
+ title = umx_data->loader->LoadTitle();
+ }
+
+ MikMod_free(umx_data);
+ umx_data = NULL;
+
+ return title;
+}
+
+/*========== Loader information */
+
+MIKMODAPI MLOADER load_umx = {
+ NULL,
+ "UMX",
+ "UMX (Unreal UMX container)",
+ UMX_Init,
+ UMX_Test,
+ UMX_Load,
+ UMX_Cleanup,
+ UMX_LoadTitle
+};
+
+/* ex:set ts=8: */
diff --git a/apps/plugins/mikmod/load_uni.c b/apps/plugins/mikmod/load_uni.c
index 7bedd8f16c..834fd3a85a 100644
--- a/apps/plugins/mikmod/load_uni.c
+++ b/apps/plugins/mikmod/load_uni.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_uni.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
+ $Id$
UNIMOD (libmikmod's and APlayer's internal module format) loader
@@ -94,18 +94,18 @@ static UNISMP05 *wh=NULL,*s=NULL;
/*========== Loader code */
-static char* readstring(void)
+static char * readstring(void)
{
- char *s=NULL;
+ char *str=NULL;
UWORD len;
-
+
len=_mm_read_I_UWORD(modreader);
if(len) {
- s=MikMod_malloc(len+1);
- _mm_read_UBYTES(s,len,modreader);
- s[len]=0;
+ str=(char *) MikMod_malloc(len+1);
+ _mm_read_UBYTES(str,len,modreader);
+ str[len]=0;
}
- return s;
+ return str;
}
static int UNI_Test(void)
@@ -133,7 +133,7 @@ static int UNI_Init(void)
static void UNI_Cleanup(void)
{
MikMod_free(wh);
- s=NULL;
+ wh = s = NULL;
}
static UBYTE* readtrack(void)
@@ -148,7 +148,7 @@ static UBYTE* readtrack(void)
len=_mm_read_I_UWORD(modreader);
if(!len) return NULL;
- if(!(t=MikMod_malloc(len))) return NULL;
+ if(!(t=(UBYTE*)MikMod_malloc(len))) return NULL;
_mm_read_UBYTES(t,len,modreader);
/* Check if the track is correct */
@@ -221,65 +221,65 @@ static UBYTE* readtrack(void)
static int loadsmp6(void)
{
int t;
- SAMPLE *s;
+ SAMPLE *sptr;
- s=of.samples;
- for(t=0;t<of.numsmp;t++,s++) {
+ sptr=of.samples;
+ for(t=0;t<of.numsmp;t++,sptr++) {
int flags;
flags = _mm_read_M_UWORD(modreader);
- s->flags=0;
- if(flags&0x0004) s->flags|=SF_STEREO;
- if(flags&0x0002) s->flags|=SF_SIGNED;
- if(flags&0x0001) s->flags|=SF_16BITS;
+ sptr->flags=0;
+ if(flags&0x0004) sptr->flags|=SF_STEREO;
+ if(flags&0x0002) sptr->flags|=SF_SIGNED;
+ if(flags&0x0001) sptr->flags|=SF_16BITS;
/* convert flags */
if(universion>=0x104) {
- if(flags&0x2000) s->flags|=SF_UST_LOOP;
- if(flags&0x1000) s->flags|=SF_OWNPAN;
- if(flags&0x0800) s->flags|=SF_SUSTAIN;
- if(flags&0x0400) s->flags|=SF_REVERSE;
- if(flags&0x0200) s->flags|=SF_BIDI;
- if(flags&0x0100) s->flags|=SF_LOOP;
- if(flags&0x0020) s->flags|=SF_ITPACKED;
- if(flags&0x0010) s->flags|=SF_DELTA;
- if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
+ if(flags&0x2000) sptr->flags|=SF_UST_LOOP;
+ if(flags&0x1000) sptr->flags|=SF_OWNPAN;
+ if(flags&0x0800) sptr->flags|=SF_SUSTAIN;
+ if(flags&0x0400) sptr->flags|=SF_REVERSE;
+ if(flags&0x0200) sptr->flags|=SF_BIDI;
+ if(flags&0x0100) sptr->flags|=SF_LOOP;
+ if(flags&0x0020) sptr->flags|=SF_ITPACKED;
+ if(flags&0x0010) sptr->flags|=SF_DELTA;
+ if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN;
} else if(universion>=0x102) {
- if(flags&0x0800) s->flags|=SF_UST_LOOP;
- if(flags&0x0400) s->flags|=SF_OWNPAN;
- if(flags&0x0200) s->flags|=SF_SUSTAIN;
- if(flags&0x0100) s->flags|=SF_REVERSE;
- if(flags&0x0080) s->flags|=SF_BIDI;
- if(flags&0x0040) s->flags|=SF_LOOP;
- if(flags&0x0020) s->flags|=SF_ITPACKED;
- if(flags&0x0010) s->flags|=SF_DELTA;
- if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
+ if(flags&0x0800) sptr->flags|=SF_UST_LOOP;
+ if(flags&0x0400) sptr->flags|=SF_OWNPAN;
+ if(flags&0x0200) sptr->flags|=SF_SUSTAIN;
+ if(flags&0x0100) sptr->flags|=SF_REVERSE;
+ if(flags&0x0080) sptr->flags|=SF_BIDI;
+ if(flags&0x0040) sptr->flags|=SF_LOOP;
+ if(flags&0x0020) sptr->flags|=SF_ITPACKED;
+ if(flags&0x0010) sptr->flags|=SF_DELTA;
+ if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN;
} else {
- if(flags&0x400) s->flags|=SF_UST_LOOP;
- if(flags&0x200) s->flags|=SF_OWNPAN;
- if(flags&0x100) s->flags|=SF_REVERSE;
- if(flags&0x080) s->flags|=SF_SUSTAIN;
- if(flags&0x040) s->flags|=SF_BIDI;
- if(flags&0x020) s->flags|=SF_LOOP;
- if(flags&0x010) s->flags|=SF_BIG_ENDIAN;
- if(flags&0x008) s->flags|=SF_DELTA;
+ if(flags&0x400) sptr->flags|=SF_UST_LOOP;
+ if(flags&0x200) sptr->flags|=SF_OWNPAN;
+ if(flags&0x100) sptr->flags|=SF_REVERSE;
+ if(flags&0x080) sptr->flags|=SF_SUSTAIN;
+ if(flags&0x040) sptr->flags|=SF_BIDI;
+ if(flags&0x020) sptr->flags|=SF_LOOP;
+ if(flags&0x010) sptr->flags|=SF_BIG_ENDIAN;
+ if(flags&0x008) sptr->flags|=SF_DELTA;
}
- s->speed = _mm_read_M_ULONG(modreader);
- s->volume = _mm_read_UBYTE(modreader);
- s->panning = _mm_read_M_UWORD(modreader);
- s->length = _mm_read_M_ULONG(modreader);
- s->loopstart = _mm_read_M_ULONG(modreader);
- s->loopend = _mm_read_M_ULONG(modreader);
- s->susbegin = _mm_read_M_ULONG(modreader);
- s->susend = _mm_read_M_ULONG(modreader);
- s->globvol = _mm_read_UBYTE(modreader);
- s->vibflags = _mm_read_UBYTE(modreader);
- s->vibtype = _mm_read_UBYTE(modreader);
- s->vibsweep = _mm_read_UBYTE(modreader);
- s->vibdepth = _mm_read_UBYTE(modreader);
- s->vibrate = _mm_read_UBYTE(modreader);
-
- s->samplename=readstring();
+ sptr->speed = _mm_read_M_ULONG(modreader);
+ sptr->volume = _mm_read_UBYTE(modreader);
+ sptr->panning = _mm_read_M_UWORD(modreader);
+ sptr->length = _mm_read_M_ULONG(modreader);
+ sptr->loopstart = _mm_read_M_ULONG(modreader);
+ sptr->loopend = _mm_read_M_ULONG(modreader);
+ sptr->susbegin = _mm_read_M_ULONG(modreader);
+ sptr->susend = _mm_read_M_ULONG(modreader);
+ sptr->globvol = _mm_read_UBYTE(modreader);
+ sptr->vibflags = _mm_read_UBYTE(modreader);
+ sptr->vibtype = _mm_read_UBYTE(modreader);
+ sptr->vibsweep = _mm_read_UBYTE(modreader);
+ sptr->vibdepth = _mm_read_UBYTE(modreader);
+ sptr->vibrate = _mm_read_UBYTE(modreader);
+
+ sptr->samplename=readstring();
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_SAMPLEINFO;
@@ -308,7 +308,7 @@ static int loadinstr6(void)
i->rpanvar = _mm_read_UBYTE(modreader);
i->volfade = _mm_read_M_UWORD(modreader);
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define UNI_LoadEnvelope6(name) \
i-> name##flg=_mm_read_UBYTE(modreader); \
i-> name##pts=_mm_read_UBYTE(modreader); \
@@ -373,7 +373,7 @@ static int loadinstr5(void)
for(u=0;u<96;u++)
i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader);
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define UNI_LoadEnvelope5(name) \
i-> name##flg=_mm_read_UBYTE(modreader); \
i-> name##pts=_mm_read_UBYTE(modreader); \
@@ -415,7 +415,7 @@ static int loadinstr5(void)
/* Allocate more room for sample information if necessary */
if(of.numsmp+u==wavcnt) {
wavcnt+=UNI_SMPINCR;
- if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) {
+ if(!(wh=(UNISMP05*)MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) {
_mm_errno=MMERR_OUT_OF_MEMORY;
return 0;
}
@@ -447,7 +447,7 @@ static int loadinstr5(void)
/* sanity check */
if(!of.numsmp) {
- if(wh) { MikMod_free(wh);wh=NULL; }
+ MikMod_free(wh);wh=NULL;
_mm_errno=MMERR_LOADING_SAMPLEINFO;
return 0;
}
@@ -504,8 +504,8 @@ static int UNI_Load(int curious)
char *modtype,*oldtype=NULL;
INSTRUMENT *d;
SAMPLE *q;
- (void)curious;
-
+ (void)curious;
+
/* read module header */
_mm_read_UBYTES(mh.id,4,modreader);
if(mh.id[3]!='N')
@@ -514,11 +514,11 @@ static int UNI_Load(int curious)
universion=0x100;
if(universion>=6) {
- if (universion==6)
- (void)_mm_read_UBYTE(modreader);
- else
+ if (universion==6) {
+ _mm_skip_BYTE(modreader);
+ } else {
universion=_mm_read_M_UWORD(modreader);
-
+ }
mh.flags =_mm_read_M_UWORD(modreader);
mh.numchn =_mm_read_UBYTE(modreader);
mh.numvoices =_mm_read_UBYTE(modreader);
@@ -556,7 +556,7 @@ static int UNI_Load(int curious)
mh.flags &= UF_XMPERIODS | UF_LINEAR;
mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING;
}
-
+
/* set module parameters */
of.flags =mh.flags;
of.numchn =mh.numchn;
@@ -578,21 +578,21 @@ static int UNI_Load(int curious)
oldtype=readstring();
if(oldtype) {
size_t len=strlen(oldtype)+20;
- if(!(modtype=MikMod_malloc(len))) return 0;
+ if(!(modtype=(char*)MikMod_malloc(len))) return 0;
#ifdef HAVE_SNPRINTF
snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
#else
sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
#endif
} else {
- if(!(modtype=MikMod_malloc(10))) return 0;
+ if(!(modtype=(char*)MikMod_malloc(10))) return 0;
#ifdef HAVE_SNPRINTF
snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
#else
sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
#endif
}
- of.modtype=StrDup(modtype);
+ of.modtype=MikMod_strdup(modtype);
MikMod_free(modtype);MikMod_free(oldtype);
of.comment=readstring();
@@ -624,9 +624,14 @@ static int UNI_Load(int curious)
for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t];
}
/* convert the ``end of song'' pattern code if necessary */
- if(universion<0x106)
- for(t=0;t<of.numpos;t++)
- if(of.positions[t]==255) of.positions[t]=LAST_PATTERN;
+ for(t=0;t<of.numpos;t++) {
+ if(universion<0x106 && of.positions[t]==255) of.positions[t]=LAST_PATTERN;
+ else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
+ /* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
+ _mm_errno = MMERR_LOADING_HEADER;
+ return 0;
+ }
+ }
/* instruments and samples */
if(universion>=6) {
@@ -642,7 +647,7 @@ static int UNI_Load(int curious)
if(!AllocInstruments()) return 0;
if(!loadinstr5()) return 0;
if(!AllocSamples()) {
- if(wh) { MikMod_free(wh);wh=NULL; }
+ MikMod_free(wh);wh=NULL;
return 0;
}
if(!loadsmp5()) return 0;
diff --git a/apps/plugins/mikmod/load_xm.c b/apps/plugins/mikmod/load_xm.c
index ffbd6dff4d..3eb0803668 100644
--- a/apps/plugins/mikmod/load_xm.c
+++ b/apps/plugins/mikmod/load_xm.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_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 */
diff --git a/apps/plugins/mikmod/mdreg.c b/apps/plugins/mikmod/mdreg.c
index 6cbaad2932..ff5d803000 100644
--- a/apps/plugins/mikmod/mdreg.c
+++ b/apps/plugins/mikmod/mdreg.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,8 +20,6 @@
/*==============================================================================
- $Id: mdreg.c,v 1.2 2005/03/30 19:11:13 realtech Exp $
-
Routine for registering all drivers in libmikmod for the current platform.
==============================================================================*/
@@ -34,12 +32,13 @@
static void _mm_registeralldrivers(void)
{
-#if 0
-
/* Register network drivers */
#ifdef DRV_AF
_mm_registerdriver(&drv_AF);
#endif
+#ifdef DRV_PULSEAUDIO
+ _mm_registerdriver(&drv_pulseaudio);
+#endif
#ifdef DRV_ESD
_mm_registerdriver(&drv_esd);
#endif
@@ -51,8 +50,22 @@ static void _mm_registeralldrivers(void)
#ifdef DRV_ULTRA
_mm_registerdriver(&drv_ultra);
#endif
+#ifdef DRV_SAM9407
+ _mm_registerdriver(&drv_sam9407);
+#endif
- /* Register hardware drivers - software mixing */
+ /* Register multi-platform drivers -- software mixing */
+#ifdef DRV_SDL
+ _mm_registerdriver(&drv_sdl);
+#endif
+#ifdef DRV_OPENAL
+ _mm_registerdriver(&drv_openal);
+#endif
+
+ /* Register OS-specific hardware drivers - software mixing */
+#ifdef DRV_AHI
+ _mm_registerdriver(&drv_ahi);
+#endif
#ifdef DRV_AIX
_mm_registerdriver(&drv_aix);
#endif
@@ -62,6 +75,9 @@ static void _mm_registeralldrivers(void)
#ifdef DRV_HP
_mm_registerdriver(&drv_hp);
#endif
+#ifdef DRV_SNDIO
+ _mm_registerdriver(&drv_sndio);
+#endif
#ifdef DRV_OSS
_mm_registerdriver(&drv_oss);
#endif
@@ -77,6 +93,9 @@ static void _mm_registeralldrivers(void)
#ifdef DRV_OS2
_mm_registerdriver(&drv_os2);
#endif
+#ifdef DRV_XAUDIO2
+ _mm_registerdriver(&drv_xaudio2);
+#endif
#ifdef DRV_DS
_mm_registerdriver(&drv_ds);
#endif
@@ -89,39 +108,54 @@ static void _mm_registeralldrivers(void)
#ifdef DRV_OSX
_mm_registerdriver(&drv_osx);
#endif
+#ifdef DRV_DC
+ _mm_registerdriver(&drv_dc);
+#endif
#ifdef DRV_GP32
_mm_registerdriver(&drv_gp32);
#endif
-
- /* dos drivers */
+#ifdef DRV_PSP
+ _mm_registerdriver(&drv_psp);
+#endif
+#ifdef DRV_OSLES
+ _mm_registerdriver(&drv_osles);
+#endif
+#ifdef DRV_N64
+ _mm_registerdriver(&drv_n64);
+#endif
+
+ /* dos drivers - wss first, since some cards emulate sb */
#ifdef DRV_WSS
- /* wss first, since some cards emulate sb */
_mm_registerdriver(&drv_wss);
#endif
#ifdef DRV_SB
_mm_registerdriver(&drv_sb);
#endif
-
+
/* Register disk writers */
- _mm_registerdriver(&drv_raw);
+#ifdef DRV_WAV
_mm_registerdriver(&drv_wav);
+#endif
#ifdef DRV_AIFF
_mm_registerdriver(&drv_aiff);
#endif
-
+#ifdef DRV_RAW
+ _mm_registerdriver(&drv_raw);
+#endif
+
/* Register other drivers */
#ifdef DRV_PIPE
_mm_registerdriver(&drv_pipe);
#endif
-#ifndef macintosh
+#if defined(DRV_STDOUT) && !defined(macintosh)
_mm_registerdriver(&drv_stdout);
#endif
-#endif
+ /* Register 'nosound' driver */
_mm_registerdriver(&drv_nos);
}
-void MikMod_RegisterAllDrivers(void)
+MIKMODAPI void MikMod_RegisterAllDrivers(void)
{
MUTEX_LOCK(lists);
_mm_registeralldrivers();
diff --git a/apps/plugins/mikmod/mdriver.c b/apps/plugins/mikmod/mdriver.c
index 2e8e9b5e41..2e1f8063b9 100644
--- a/apps/plugins/mikmod/mdriver.c
+++ b/apps/plugins/mikmod/mdriver.c
@@ -1,17 +1,17 @@
/* MikMod sound library
- (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
- for complete list.
+ (c) 1998-2014 Miodrag Vallat and others - see file AUTHORS
+ for a complete list.
This library is free software; you can redistribute it and/or modify
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,8 +20,6 @@
/*==============================================================================
- $Id: mdriver.c,v 1.4 2007/12/03 20:59:05 denis111 Exp $
-
These routines are used to access the available soundcard drivers.
==============================================================================*/
@@ -34,54 +32,59 @@
#include <unistd.h>
#endif
-#if 0
-#if defined unix || (defined __APPLE__ && defined __MACH__)
-#include <pwd.h>
-#include <sys/stat.h>
-#endif
-#endif
-
#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
#include "mikmod_internals.h"
+#if (MIKMOD_UNIX)
+#include <pwd.h>
+#include <sys/stat.h>
+#endif
+
#ifdef SUNOS
extern int fprintf(FILE *, const char *, ...);
#endif
-static MDRIVER *firstdriver=NULL;
-MIKMODAPI MDRIVER *md_driver=NULL;
extern MODULE *pf; /* modfile being played */
+/* EXPORTED GLOBALS */
+MIKMODAPI MDRIVER *md_driver = NULL;
+
/* Initial global settings */
-MIKMODAPI UWORD md_device = 0; /* autodetect */
-MIKMODAPI UWORD md_mixfreq = 44100;
-MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
- DMODE_SURROUND |DMODE_SOFT_MUSIC |
- DMODE_SOFT_SNDFX;
-MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
-MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
-MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
-MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
-MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
- UWORD md_bpm = 125; /* tempo */
-
-/* Do not modify the numchn variables yourself! use MD_SetVoices() */
- UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0;
- UBYTE md_hardchn=0,md_softchn=0;
-
- void (*md_player)(void) = Player_HandleTick;
-static volatile int isplaying=0, initialized = 0;
-static UBYTE *sfxinfo;
-static int sfxpool;
-
-static SAMPLE **md_sample = NULL;
+MIKMODAPI UWORD md_device = 0; /* autodetect */
+MIKMODAPI ULONG md_mixfreq = 44100;
+MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
+ DMODE_SURROUND |
+ DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
+MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
+MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
+MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
+MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
+MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
+
+/* INTERNAL GLOBALS */
+UWORD md_bpm = 125; /* tempo */
+
+/* Do not modify the numchn variables yourself! use MikMod_SetNumVoices() */
+UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0;
+UBYTE md_hardchn = 0, md_softchn= 0;
+
+MikMod_player_t md_player = Player_HandleTick;
+
+MikMod_callback_t vc_callback = NULL;
+
+/* PRIVATE VARS */
+static MDRIVER *firstdriver = NULL;
+
+static volatile int isplaying = 0, initialized = 0;
+
+static UBYTE *sfxinfo;
+static int sfxpool;
+
+static SAMPLE **md_sample = NULL;
/* Previous driver in use */
-static SWORD olddevice = -1;
+static SWORD olddevice = -1;
/* Limits the number of hardware voices to the specified amount.
This function should only be used by the low-level drivers. */
@@ -183,17 +186,18 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void)
MUTEX_LOCK(lists);
/* compute size of buffer */
- for(l=firstdriver;l;l=l->next)
- len+=4+(l->next?1:0)+strlen(l->Version);
+ for(l = firstdriver; l; l = l->next)
+ len += 4 + (l->next ? 1 : 0) + strlen(l->Version);
if(len)
- if((list=MikMod_malloc(len*sizeof(CHAR)))) {
- list[0]=0;
- /* list all registered device drivers : */
- for(t=1,l=firstdriver;l;l=l->next,t++)
- sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s",
- list,t,l->Version);
+ if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
+ CHAR *list_end = list;
+ list[0] = 0;
+ /* list all registered device drivers : */
+ for(t = 1, l = firstdriver; l; l = l->next, t++) {
+ list_end += sprintf(list_end, "%2d %s%s", t, l->Version, (l->next)? "\n" : "");
}
+ }
MUTEX_UNLOCK(lists);
return list;
}
@@ -214,7 +218,7 @@ void _mm_registerdriver(struct MDRIVER* drv)
}
cruise->next = drv;
} else
- firstdriver = drv;
+ firstdriver = drv;
}
}
@@ -230,7 +234,7 @@ MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv)
MUTEX_UNLOCK(lists);
}
-MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
+MIKMODAPI int MikMod_DriverFromAlias(const CHAR *alias)
{
int rank=1;
MDRIVER *cruise;
@@ -252,18 +256,17 @@ MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal)
{
- MDRIVER *cruise;
+ MDRIVER *cruise;
- /* Allow only driver ordinals > 0 */
- if (!ordinal)
- return 0;
+ /* Allow only driver ordinals > 0 */
+ if (!ordinal) return NULL;
- MUTEX_LOCK(lists);
- cruise = firstdriver;
- while (cruise && --ordinal)
- cruise = cruise->next;
- MUTEX_UNLOCK(lists);
- return cruise;
+ MUTEX_LOCK(lists);
+ cruise = firstdriver;
+ while (cruise && --ordinal)
+ cruise = cruise->next;
+ MUTEX_UNLOCK(lists);
+ return cruise;
}
SWORD MD_SampleLoad(SAMPLOAD* s, int type)
@@ -496,14 +499,12 @@ MIKMODAPI ULONG Voice_RealVolume(SBYTE voice)
return result;
}
-extern MikMod_callback_t vc_callback;
-
MIKMODAPI void VC_SetCallback(MikMod_callback_t callback)
{
vc_callback = callback;
}
-static int _mm_init(CHAR *cmdline)
+static int _mm_init(const CHAR *cmdline)
{
UWORD t;
@@ -561,7 +562,7 @@ static int _mm_init(CHAR *cmdline)
return 0;
}
-MIKMODAPI int MikMod_Init(CHAR *cmdline)
+MIKMODAPI int MikMod_Init(const CHAR *cmdline)
{
int result;
@@ -581,8 +582,8 @@ void MikMod_Exit_internal(void)
md_numchn = md_sfxchn = md_sngchn = 0;
md_driver = &drv_nos;
- if(sfxinfo) MikMod_free(sfxinfo);
- if(md_sample) MikMod_free(md_sample);
+ MikMod_free(sfxinfo);
+ MikMod_free(md_sample);
md_sample = NULL;
sfxinfo = NULL;
@@ -598,14 +599,14 @@ MIKMODAPI void MikMod_Exit(void)
MUTEX_UNLOCK(vars);
}
-/* Reset the driver using the new global variable settings.
+/* Reset the driver using the new global variable settings.
If the driver has not been initialized, it will be now. */
-static int _mm_reset(CHAR *cmdline)
+static int _mm_reset(const CHAR *cmdline)
{
int wasplaying = 0;
if(!initialized) return _mm_init(cmdline);
-
+
if (isplaying) {
wasplaying = 1;
md_driver->PlayStop();
@@ -629,12 +630,12 @@ static int _mm_reset(CHAR *cmdline)
return 1;
}
}
-
- if (wasplaying) md_driver->PlayStart();
+
+ if (wasplaying) return md_driver->PlayStart();
return 0;
}
-MIKMODAPI int MikMod_Reset(CHAR *cmdline)
+MIKMODAPI int MikMod_Reset(const CHAR *cmdline)
{
int result;
@@ -661,8 +662,8 @@ int MikMod_SetNumVoices_internal(int music, int sfx)
resume = 1;
}
- if(sfxinfo) MikMod_free(sfxinfo);
- if(md_sample) MikMod_free(md_sample);
+ MikMod_free(sfxinfo);
+ MikMod_free(md_sample);
md_sample = NULL;
sfxinfo = NULL;
@@ -764,7 +765,7 @@ MIKMODAPI int MikMod_Active(void)
allocated for use as sound effects (loops through voices, skipping all active
criticals).
- Returns the voice that the sound is being played on. */
+ Returns the voice that the sound is being played on. */
static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags)
{
int orig=sfxpool;/* for cases where all channels are critical */
@@ -825,12 +826,15 @@ MIKMODAPI long MikMod_GetVersion(void)
#ifdef HAVE_PTHREAD
#define INIT_MUTEX(name) \
pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER
+
#elif defined(__OS2__)||defined(__EMX__)
#define INIT_MUTEX(name) \
HMTX _mm_mutex_##name
-#elif defined(WIN32)
+
+#elif defined(_WIN32)
#define INIT_MUTEX(name) \
HANDLE _mm_mutex_##name
+
#else
#define INIT_MUTEX(name) \
void *_mm_mutex_##name = NULL
@@ -842,8 +846,8 @@ INIT_MUTEX(lists);
MIKMODAPI int MikMod_InitThreads(void)
{
static int firstcall=1;
- static int result=0;
-
+ static int result = 0;
+
if (firstcall) {
firstcall=0;
#ifdef HAVE_PTHREAD
@@ -855,9 +859,9 @@ MIKMODAPI int MikMod_InitThreads(void)
result=0;
} else
result=1;
-#elif defined(WIN32)
- if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))||
- (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)"))))
+#elif defined(_WIN32)
+ if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,TEXT("libmikmod(lists)"))))||
+ (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,TEXT("libmikmod(vars)")))))
result=0;
else
result=1;
@@ -880,24 +884,24 @@ MIKMODAPI void MikMod_Lock(void)
/*========== Parameter extraction helper */
-CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
+CHAR *MD_GetAtom(const CHAR *atomname, const CHAR *cmdline, int implicit)
{
CHAR *ret=NULL;
if(cmdline) {
- CHAR *buf=strstr(cmdline,atomname);
+ const CHAR *buf=strstr(cmdline,atomname);
if((buf)&&((buf==cmdline)||(*(buf-1)==','))) {
- CHAR *ptr=buf+strlen(atomname);
+ const CHAR *ptr=buf+strlen(atomname);
if(*ptr=='=') {
for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++);
- ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
+ ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
if(ret)
strncpy(ret,buf,ptr-buf);
} else if((*ptr==',')||(!*ptr)) {
if(implicit) {
- ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
+ ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
if(ret)
strncpy(ret,buf,ptr-buf);
}
@@ -907,8 +911,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
return ret;
}
-#if 0
-#if defined unix || (defined __APPLE__ && defined __MACH__)
+#if (MIKMOD_UNIX)
/*========== Posix helper functions */
@@ -917,7 +920,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise.
The goal is to prevent a setuid root libmikmod application from overriding
files like /etc/passwd with digital sound... */
-int MD_Access(CHAR *filename)
+int MD_Access(const CHAR * filename)
{
struct stat buf;
@@ -934,7 +937,7 @@ int MD_Access(CHAR *filename)
} else
if(!(buf.st_mode&S_IWOTH)) return 0;
}
-
+
return 1;
}
@@ -961,5 +964,5 @@ int MD_DropPrivileges(void)
}
#endif
-#endif
-/* ex:set ts=4: */
+
+/* ex:set ts=8: */
diff --git a/apps/plugins/mikmod/mikmod.c b/apps/plugins/mikmod/mikmod.c
index 688baed56c..0eba320f18 100644
--- a/apps/plugins/mikmod/mikmod.c
+++ b/apps/plugins/mikmod/mikmod.c
@@ -25,7 +25,7 @@
/* Persistent configuration */
#define MIKMOD_CONFIGFILE "mikmod.cfg"
#define MIKMOD_SETTINGS_MINVERSION 1
-#define MIKMOD_SETTINGS_VERSION 1
+#define MIKMOD_SETTINGS_VERSION 2
#ifdef USETHREADS
#define EV_EXIT 9999
@@ -161,7 +161,6 @@ static bool mod_ext(const char ext[])
!rb->strcasecmp(ext,".dsm") ||
!rb->strcasecmp(ext,".far") ||
!rb->strcasecmp(ext,".gdm") ||
- !rb->strcasecmp(ext,".gt2") ||
!rb->strcasecmp(ext,".imf") ||
!rb->strcasecmp(ext,".it") ||
!rb->strcasecmp(ext,".m15") ||
@@ -174,6 +173,7 @@ static bool mod_ext(const char ext[])
!rb->strcasecmp(ext,".stx") ||
!rb->strcasecmp(ext,".ult") ||
!rb->strcasecmp(ext,".uni") ||
+ !rb->strcasecmp(ext,".umx") ||
!rb->strcasecmp(ext,".xm") )
return true;
else
@@ -305,7 +305,7 @@ static void showinfo(void)
rb->lcd_putsxy(1, 1, statustext);
sprintf(statustext, "Type: %s", module->modtype);
rb->lcd_putsxy(1, 11, statustext);
-
+
sprintf(statustext, "Samples: %d", module->numsmp);
rb->lcd_putsxy(1, 21, statustext);
@@ -315,25 +315,25 @@ static void showinfo(void)
rb->lcd_putsxy(1, 31, statustext);
}
- sprintf(statustext, "pat: %03d/%03d %2.2X",
+ sprintf(statustext, "pat: %03d/%03d %2.2X",
module->sngpos, module->numpos - 1, module->patpos);
rb->lcd_putsxy(1, 51, statustext);
- sprintf(statustext, "spd: %d/%d",
+ sprintf(statustext, "spd: %d/%d",
module->sngspd, module->bpm);
rb->lcd_putsxy(1, 61, statustext);
sprintf(statustext, "vol: %ddB", rb->global_settings->volume);
rb->lcd_putsxy(1, 71, statustext);
- sprintf(statustext, "time: %d:%02d",
+ sprintf(statustext, "time: %d:%02d",
(playingtime / 60) % 60, playingtime % 60);
rb->lcd_putsxy(1, 81, statustext);
if (module->flags & UF_NNA)
{
sprintf(statustext, "chn: %d/%d+%d->%d",
- module->realchn, module->numchn,
+ module->realchn, module->numchn,
module->totalchn - module->realchn,
module->totalchn);
}
@@ -465,32 +465,44 @@ struct mikmod_settings
{
int pansep;
int reverb;
+ int sample_rate;
bool interp;
bool reverse;
bool surround;
+ bool hqmixer;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
bool boost;
+#endif
};
static struct mikmod_settings settings =
{
- 128,
- 0,
- 0,
- 0,
- 1,
- 1
+ .pansep = 128,
+ .reverb = 0,
+ .sample_rate = -1,
+ .interp = 0,
+ .reverse = 0,
+ .surround = 1,
+ .hqmixer = 0,
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ .boost = 1,
+#endif
};
static struct mikmod_settings old_settings;
-static struct configdata config[] =
+static const struct configdata config[] =
{
{ TYPE_INT, 0, 128, { .int_p = &settings.pansep }, "Panning Separation", NULL},
{ TYPE_INT, 0, 15, { .int_p = &settings.reverb }, "Reverberation", NULL},
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.interp }, "Interpolation", NULL},
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.reverse }, "Reverse Channels", NULL},
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.surround }, "Surround", NULL},
+ { TYPE_BOOL, 0, 1, { .bool_p = &settings.hqmixer }, "HQ Mixer", NULL},
+ { TYPE_INT, 0, HW_NUM_FREQ-1, { .int_p = &settings.sample_rate }, "Sample Rate", NULL},
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.boost }, "CPU Boost", NULL},
+#endif
};
static void applysettings(void)
@@ -498,6 +510,7 @@ static void applysettings(void)
md_pansep = settings.pansep;
md_reverb = settings.reverb;
md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
+
if ( settings.interp )
{
md_mode |= DMODE_INTERP;
@@ -510,6 +523,21 @@ static void applysettings(void)
{
md_mode |= DMODE_SURROUND;
}
+#ifndef NO_HQMIXER
+ if ( settings.hqmixer )
+ {
+ md_mode |= DMODE_HQMIXER;
+ }
+#endif
+
+ if (md_mixfreq != rb->hw_freq_sampr[settings.sample_rate]) {
+ md_mixfreq = rb->hw_freq_sampr[settings.sample_rate];
+// MikMod_Reset(""); BROKEN!
+ rb->pcm_play_stop();
+ rb->mixer_set_frequency(md_mixfreq);
+ rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
+ }
+
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if ( Player_Active() )
{
@@ -518,6 +546,21 @@ static void applysettings(void)
#endif
}
+static const struct opt_items sr_names[HW_NUM_FREQ] = {
+ HW_HAVE_96_([HW_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },)
+ HW_HAVE_88_([HW_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },)
+ HW_HAVE_64_([HW_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },)
+ HW_HAVE_48_([HW_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },)
+ HW_HAVE_44_([HW_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },)
+ HW_HAVE_32_([HW_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },)
+ HW_HAVE_24_([HW_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },)
+ HW_HAVE_22_([HW_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },)
+ HW_HAVE_16_([HW_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },)
+ HW_HAVE_12_([HW_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },)
+ HW_HAVE_11_([HW_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },)
+ HW_HAVE_8_( [HW_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },)
+};
+
/**
Shows the settings menu
*/
@@ -531,6 +574,8 @@ static int settings_menu(void)
ID2P(LANG_INTERPOLATION),
ID2P(LANG_SWAP_CHANNELS),
ID2P(LANG_MIKMOD_SURROUND),
+ ID2P(LANG_MIKMOD_HQMIXER),
+ ID2P(LANG_MIKMOD_SAMPLERATE),
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ID2P(LANG_CPU_BOOST)
#endif
@@ -571,9 +616,22 @@ static int settings_menu(void)
break;
case 5:
+ rb->set_bool(rb->str(LANG_MIKMOD_HQMIXER), &(settings.hqmixer));
+ applysettings();
+ break;
+
+ case 6:
+ rb->set_option(rb->str(LANG_MIKMOD_SAMPLERATE), &(settings.sample_rate), INT, sr_names,
+ HW_NUM_FREQ, NULL);
+ applysettings();
+ break;
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ case 7:
rb->set_bool(rb->str(LANG_CPU_BOOST), &(settings.boost));
applysettings();
break;
+#endif
case MENU_ATTACHED_USB:
return PLUGIN_USB_CONNECTED;
@@ -675,13 +733,12 @@ static int playfile(char* filename)
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- if ( settings.boost )
- rb->cpu_boost(true);
+ rb->cpu_boost(settings.boost);
#endif
#ifdef USETHREADS
rb->queue_init(&thread_q, true);
if ((thread_id = rb->create_thread(thread, thread_stack,
- sizeof(thread_stack), 0, "render buffering thread"
+ sizeof(thread_stack), 0, "render buffering thread"
IF_PRIO(, PRIORITY_PLAYBACK)
IF_COP(, CPU))) == 0)
{
@@ -830,11 +887,11 @@ static int playfile(char* filename)
rb->lcd_setfont(FONT_SYSFIXED);
screenupdated = false;
break;
-
+
case ACTION_WPS_STOP:
quit = true;
break;
-
+
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
{
@@ -850,20 +907,19 @@ static int playfile(char* filename)
rb->queue_delete(&thread_q);
#endif
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- if ( settings.boost )
- rb->cpu_boost(false);
+ rb->cpu_boost(false);
#endif
Player_Stop();
Player_Free(module);
-
+
memset(gmbuf, '\0', sizeof(gmbuf));
-
+
if ( retval == PLUGIN_OK && entries > 1 && !quit )
{
retval = change_filename(DIR_NEXT);
}
-
+
return retval;
}
@@ -891,10 +947,9 @@ enum plugin_status plugin_start(const void* parameter)
rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
#endif
- rb->mixer_set_frequency(SAMPLE_RATE);
audio_buffer = rb->plugin_get_audio_buffer((size_t *)&audio_buffer_free);
-
+
rb->strcpy(np_file, parameter);
get_mod_list();
if(!entries) {
@@ -903,16 +958,29 @@ enum plugin_status plugin_start(const void* parameter)
//add_pool(audio_buffer, audio_buffer_free);
init_memory_pool(audio_buffer_free, audio_buffer);
-
+
MikMod_RegisterDriver(&drv_nos);
MikMod_RegisterAllLoaders();
MikMod_RegisterErrorHandler(mm_errorhandler);
- md_mixfreq = SAMPLE_RATE;
-
configfile_load(MIKMOD_CONFIGFILE, config,
ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
rb->memcpy(&old_settings, &settings, sizeof (settings));
+
+ /* If there's no configured rate, use the default */
+ if (settings.sample_rate == -1) {
+ int i;
+ for (i = 0 ; i < HW_NUM_FREQ ; i++) {
+ if (rb->hw_freq_sampr[i] == SAMPLE_RATE) {
+ settings.sample_rate = i;
+ break;
+ }
+ }
+ if (settings.sample_rate == -1) {
+ settings.sample_rate = HW_NUM_FREQ -1;
+ }
+ }
+
applysettings();
if (MikMod_Init(""))
@@ -934,14 +1002,13 @@ enum plugin_status plugin_start(const void* parameter)
if (retval == PLUGIN_OK)
{
- rb->splash(0, "Saving Settings");
if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
{
- configfile_save(MIKMOD_CONFIGFILE, config,
- ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
+ configfile_save(MIKMOD_CONFIGFILE, config,
+ ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
}
}
-
+
destroy_memory_pool(audio_buffer);
return retval;
diff --git a/apps/plugins/mikmod/mikmod.h b/apps/plugins/mikmod/mikmod.h
index a1c201f6d2..8256299451 100644
--- a/apps/plugins/mikmod/mikmod.h
+++ b/apps/plugins/mikmod/mikmod.h
@@ -1,30 +1,28 @@
-/* MikMod sound library
- (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS
- for complete list.
-
- This library is free software; you can redistribute it and/or modify
- 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
- 02111-1307, USA.
+/* MikMod sound library
+ (c) 1998-2014 Miodrag Vallat and others - see the AUTHORS file
+ for complete list.
+
+ This library is free software; you can redistribute it and/or modify
+ 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
+ 02111-1307, USA.
*/
/*==============================================================================
- $Id: mikmod.h.in,v 1.3 2005/03/30 19:09:21 realtech Exp $
-
MikMod sound library include file
-==============================================================================*/
+ ==============================================================================*/
#ifndef _MIKMOD_H_
#define _MIKMOD_H_
@@ -40,163 +38,221 @@ extern "C" {
/*
* ========== Compiler magic for shared libraries
+ *
+ * ========== NOTE TO WINDOWS DEVELOPERS:
+ * If you are compiling for Windows and will link to the static library
+ * (libmikmod.a with MinGW, or mikmod_static.lib with MSVC or LCC, etc),
+ * you must define MIKMOD_STATIC in your project. Otherwise, dllimport
+ * will be assumed.
*/
-
-#if defined WIN32 && defined _DLL
-#ifdef DLL_EXPORTS
-#define MIKMODAPI __declspec(dllexport)
-#else
-#define MIKMODAPI __declspec(dllimport)
-#endif
+#if defined(_WIN32) || defined(__CYGWIN__)
+# if defined(MIKMOD_BUILD) && defined(DLL_EXPORT) /* building libmikmod as a dll for windows */
+# define MIKMODAPI __declspec(dllexport)
+# elif defined(MIKMOD_BUILD) || defined(MIKMOD_STATIC) /* building or using static libmikmod for windows */
+# define MIKMODAPI
+# else
+# define MIKMODAPI __declspec(dllimport) /* using libmikmod dll for windows */
+# endif
+#elif defined(__OS2__) && defined(__WATCOMC__)
+# if defined(MIKMOD_BUILD) && defined(__SW_BD) /* building libmikmod as a dll for os/2 */
+# define MIKMODAPI __declspec(dllexport)
+# else
+# define MIKMODAPI /* using dll or static libmikmod for os/2 */
+# endif
+/* SYM_VISIBILITY should be defined if both the compiler
+ * and the target support the visibility attributes. the
+ * configury does that automatically. for the standalone
+ * makefiles, etc, the developer should add the required
+ * flags, i.e.: -DSYM_VISIBILITY -fvisibility=hidden */
+#elif defined(MIKMOD_BUILD) && defined(SYM_VISIBILITY)
+# define MIKMODAPI __attribute__((visibility("default")))
#else
-#define MIKMODAPI
+# define MIKMODAPI
#endif
/*
- * ========== Library version
+ * ========== Library version
*/
#define LIBMIKMOD_VERSION_MAJOR 3L
-#define LIBMIKMOD_VERSION_MINOR 2L
-#define LIBMIKMOD_REVISION 0L
+#define LIBMIKMOD_VERSION_MINOR 3L
+#define LIBMIKMOD_REVISION 11L
#define LIBMIKMOD_VERSION \
- ((LIBMIKMOD_VERSION_MAJOR<<16)| \
- (LIBMIKMOD_VERSION_MINOR<< 8)| \
- (LIBMIKMOD_REVISION))
+ ((LIBMIKMOD_VERSION_MAJOR<<16)| \
+ (LIBMIKMOD_VERSION_MINOR<< 8)| \
+ (LIBMIKMOD_REVISION))
MIKMODAPI extern long MikMod_GetVersion(void);
/*
- * ========== Platform independent-type definitions
+ * ========== Dependency platform headers
*/
-#if 0
-#ifdef WIN32
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
+#endif
#include <windows.h>
#include <io.h>
#include <mmsystem.h>
+#define _MIKMOD_WIN32
+#endif
+
+#if defined(__DJGPP__) || defined(MSDOS) || defined(__MSDOS__) || defined(__DOS__)
+#define _MIKMOD_DOS
#endif
-#if defined(__OS2__)||defined(__EMX__)
+#if defined(__OS2__) || defined(__EMX__)
#define INCL_DOSSEMAPHORES
#include <os2.h>
-#else
-typedef char CHAR;
+#include <io.h>
+#define _MIKMOD_OS2
+#endif
+
+#if defined(__MORPHOS__) || defined(__AROS__) || defined(_AMIGA) || defined(__AMIGA__) || defined(__amigaos__) || defined(AMIGAOS)
+#include <exec/types.h>
+#define _MIKMOD_AMIGA
#endif
+
+/*
+ * ========== Platform independent-type definitions
+ * (pain when it comes to cross-platform maintenance..)
+ */
+
+#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32))
+typedef char CHAR;
#endif
-typedef char CHAR;
+/* int: 0=false, <>0 true -- 16 bits on Amiga, int-wide on others. */
+#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA))
+//typedef int int;
+#endif
+/* 1 byte, signed and unsigned: */
+typedef signed char SBYTE;
+#ifndef _MIKMOD_AMIGA
+typedef unsigned char UBYTE;
+#endif
-#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__)
-/* 64 bit architectures */
+/* 2 bytes, signed and unsigned: */
+#if !(defined __LCC__ && defined _WIN32)
+typedef signed short int SWORD;
+#endif
+#if !((defined __LCC__ && defined _WIN32) || defined(_MIKMOD_AMIGA))
+typedef unsigned short int UWORD;
+#endif
-typedef signed char SBYTE; /* 1 byte, signed */
-typedef unsigned char UBYTE; /* 1 byte, unsigned */
-typedef signed short SWORD; /* 2 bytes, signed */
-typedef unsigned short UWORD; /* 2 bytes, unsigned */
-typedef signed int SLONG; /* 4 bytes, signed */
-typedef unsigned int ULONG; /* 4 bytes, unsigned */
-//typedef int BOOL; /* 0=false, <>0 true */
+/* 4 bytes, signed and unsigned: */
+#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__)
+ /* 64 bit architectures: */
+typedef signed int SLONG;
+#if !(defined(_WIN32) || defined(_MIKMOD_AMIGA))
+typedef unsigned int ULONG;
+#endif
-#else
-/* 32 bit architectures */
-
-typedef signed char SBYTE; /* 1 byte, signed */
-typedef unsigned char UBYTE; /* 1 byte, unsigned */
-typedef signed short SWORD; /* 2 bytes, signed */
-typedef unsigned short UWORD; /* 2 bytes, unsigned */
-typedef signed long SLONG; /* 4 bytes, signed */
-#if !defined(__OS2__)&&!defined(__EMX__)&&!defined(WIN32)
-typedef unsigned long ULONG; /* 4 bytes, unsigned */
-//typedef int BOOL; /* 0=false, <>0 true */
+#else /* 32 bit architectures: */
+typedef signed long int SLONG;
+#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA))
+typedef unsigned long int ULONG;
#endif
#endif
+/* make sure types are of correct sizes: */
+typedef int __mikmod_typetest [
+ (
+ (sizeof(SBYTE)==1) && (sizeof(UBYTE)==1)
+ && (sizeof(SWORD)==2) && (sizeof(UWORD)==2)
+ && (sizeof(SLONG)==4) && (sizeof(ULONG)==4)
+#ifndef _MIKMOD_AMIGA
+ && (sizeof(int) == sizeof(int))
+#endif
+ && (sizeof(CHAR) == sizeof(char))
+ ) * 2 - 1 ];
+
/*
- * ========== Error codes
+ * ========== Error codes
*/
enum {
- MMERR_OPENING_FILE = 1,
- MMERR_OUT_OF_MEMORY,
- MMERR_DYNAMIC_LINKING,
-
- MMERR_SAMPLE_TOO_BIG,
- MMERR_OUT_OF_HANDLES,
- MMERR_UNKNOWN_WAVE_TYPE,
-
- MMERR_LOADING_PATTERN,
- MMERR_LOADING_TRACK,
- MMERR_LOADING_HEADER,
- MMERR_LOADING_SAMPLEINFO,
- MMERR_NOT_A_MODULE,
- MMERR_NOT_A_STREAM,
- MMERR_MED_SYNTHSAMPLES,
- MMERR_ITPACK_INVALID_DATA,
-
- MMERR_DETECTING_DEVICE,
- MMERR_INVALID_DEVICE,
- MMERR_INITIALIZING_MIXER,
- MMERR_OPENING_AUDIO,
- MMERR_8BIT_ONLY,
- MMERR_16BIT_ONLY,
- MMERR_STEREO_ONLY,
- MMERR_ULAW,
- MMERR_NON_BLOCK,
-
- MMERR_AF_AUDIO_PORT,
-
- MMERR_AIX_CONFIG_INIT,
- MMERR_AIX_CONFIG_CONTROL,
- MMERR_AIX_CONFIG_START,
-
- MMERR_GUS_SETTINGS,
- MMERR_GUS_RESET,
- MMERR_GUS_TIMER,
-
- MMERR_HP_SETSAMPLESIZE,
- MMERR_HP_SETSPEED,
- MMERR_HP_CHANNELS,
- MMERR_HP_AUDIO_OUTPUT,
- MMERR_HP_AUDIO_DESC,
- MMERR_HP_BUFFERSIZE,
-
- MMERR_OSS_SETFRAGMENT,
- MMERR_OSS_SETSAMPLESIZE,
- MMERR_OSS_SETSTEREO,
- MMERR_OSS_SETSPEED,
-
- MMERR_SGI_SPEED,
- MMERR_SGI_16BIT,
- MMERR_SGI_8BIT,
- MMERR_SGI_STEREO,
- MMERR_SGI_MONO,
-
- MMERR_SUN_INIT,
-
- MMERR_OS2_MIXSETUP,
- MMERR_OS2_SEMAPHORE,
- MMERR_OS2_TIMER,
- MMERR_OS2_THREAD,
-
- MMERR_DS_PRIORITY,
- MMERR_DS_BUFFER,
- MMERR_DS_FORMAT,
- MMERR_DS_NOTIFY,
- MMERR_DS_EVENT,
- MMERR_DS_THREAD,
- MMERR_DS_UPDATE,
-
- MMERR_WINMM_HANDLE,
- MMERR_WINMM_ALLOCATED,
- MMERR_WINMM_DEVICEID,
- MMERR_WINMM_FORMAT,
- MMERR_WINMM_UNKNOWN,
-
- MMERR_MAC_SPEED,
- MMERR_MAC_START,
+ MMERR_OPENING_FILE = 1,
+ MMERR_OUT_OF_MEMORY,
+ MMERR_DYNAMIC_LINKING,
+
+ MMERR_SAMPLE_TOO_BIG,
+ MMERR_OUT_OF_HANDLES,
+ MMERR_UNKNOWN_WAVE_TYPE,
+
+ MMERR_LOADING_PATTERN,
+ MMERR_LOADING_TRACK,
+ MMERR_LOADING_HEADER,
+ MMERR_LOADING_SAMPLEINFO,
+ MMERR_NOT_A_MODULE,
+ MMERR_NOT_A_STREAM,
+ MMERR_MED_SYNTHSAMPLES,
+ MMERR_ITPACK_INVALID_DATA,
+
+ MMERR_DETECTING_DEVICE,
+ MMERR_INVALID_DEVICE,
+ MMERR_INITIALIZING_MIXER,
+ MMERR_OPENING_AUDIO,
+ MMERR_8BIT_ONLY,
+ MMERR_16BIT_ONLY,
+ MMERR_STEREO_ONLY,
+ MMERR_ULAW,
+ MMERR_NON_BLOCK,
+
+ MMERR_AF_AUDIO_PORT,
+
+ MMERR_AIX_CONFIG_INIT,
+ MMERR_AIX_CONFIG_CONTROL,
+ MMERR_AIX_CONFIG_START,
+
+ MMERR_GUS_SETTINGS,
+ MMERR_GUS_RESET,
+ MMERR_GUS_TIMER,
+
+ MMERR_HP_SETSAMPLESIZE,
+ MMERR_HP_SETSPEED,
+ MMERR_HP_CHANNELS,
+ MMERR_HP_AUDIO_OUTPUT,
+ MMERR_HP_AUDIO_DESC,
+ MMERR_HP_BUFFERSIZE,
+
+ MMERR_OSS_SETFRAGMENT,
+ MMERR_OSS_SETSAMPLESIZE,
+ MMERR_OSS_SETSTEREO,
+ MMERR_OSS_SETSPEED,
+
+ MMERR_SGI_SPEED,
+ MMERR_SGI_16BIT,
+ MMERR_SGI_8BIT,
+ MMERR_SGI_STEREO,
+ MMERR_SGI_MONO,
+
+ MMERR_SUN_INIT,
+
+ MMERR_OS2_MIXSETUP,
+ MMERR_OS2_SEMAPHORE,
+ MMERR_OS2_TIMER,
+ MMERR_OS2_THREAD,
+
+ MMERR_DS_PRIORITY,
+ MMERR_DS_BUFFER,
+ MMERR_DS_FORMAT,
+ MMERR_DS_NOTIFY,
+ MMERR_DS_EVENT,
+ MMERR_DS_THREAD,
+ MMERR_DS_UPDATE,
+
+ MMERR_WINMM_HANDLE,
+ MMERR_WINMM_ALLOCATED,
+ MMERR_WINMM_DEVICEID,
+ MMERR_WINMM_FORMAT,
+ MMERR_WINMM_UNKNOWN,
+
+ MMERR_MAC_SPEED,
+ MMERR_MAC_START,
MMERR_OSX_UNKNOWN_DEVICE,
MMERR_OSX_BAD_PROPERTY,
@@ -205,16 +261,43 @@ enum {
MMERR_OSX_BUFFER_ALLOC,
MMERR_OSX_ADD_IO_PROC,
MMERR_OSX_DEVICE_START,
- MMERR_OSX_PTHREAD,
-
- MMERR_DOSWSS_STARTDMA,
- MMERR_DOSSB_STARTDMA,
-
- MMERR_MAX
+ MMERR_OSX_PTHREAD,
+
+ MMERR_DOSWSS_STARTDMA,
+ MMERR_DOSSB_STARTDMA,
+
+ MMERR_NO_FLOAT32,/* should actually be after MMERR_ULAW or something */
+
+ MMERR_OPENAL_CREATECTX,
+ MMERR_OPENAL_CTXCURRENT,
+ MMERR_OPENAL_GENBUFFERS,
+ MMERR_OPENAL_GENSOURCES,
+ MMERR_OPENAL_SOURCE,
+ MMERR_OPENAL_QUEUEBUFFERS,
+ MMERR_OPENAL_UNQUEUEBUFFERS,
+ MMERR_OPENAL_BUFFERDATA,
+ MMERR_OPENAL_GETSOURCE,
+ MMERR_OPENAL_SOURCEPLAY,
+ MMERR_OPENAL_SOURCESTOP,
+
+ MMERR_ALSA_NOCONFIG,
+ MMERR_ALSA_SETPARAMS,
+ MMERR_ALSA_SETFORMAT,
+ MMERR_ALSA_SETRATE,
+ MMERR_ALSA_SETCHANNELS,
+ MMERR_ALSA_BUFFERSIZE,
+ MMERR_ALSA_PCM_START,
+ MMERR_ALSA_PCM_WRITE,
+ MMERR_ALSA_PCM_RECOVER,
+
+ MMERR_SNDIO_SETPARAMS,
+ MMERR_SNDIO_BADPARAMS,
+
+ MMERR_MAX
};
/*
- * ========== Error handling
+ * ========== Error handling
*/
typedef void (MikMod_handler)(void);
@@ -222,12 +305,12 @@ typedef MikMod_handler *MikMod_handler_t;
MIKMODAPI extern int MikMod_errno;
MIKMODAPI extern int MikMod_critical;
-MIKMODAPI extern char *MikMod_strerror(int);
+MIKMODAPI extern const char *MikMod_strerror(int);
MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t);
/*
- * ========== Library initialization and core functions
+ * ========== Library initialization and core functions
*/
struct MDRIVER;
@@ -236,15 +319,15 @@ MIKMODAPI extern void MikMod_RegisterAllDrivers(void);
MIKMODAPI extern CHAR* MikMod_InfoDriver(void);
MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*);
-MIKMODAPI extern int MikMod_DriverFromAlias(CHAR*);
+MIKMODAPI extern int MikMod_DriverFromAlias(const CHAR*);
MIKMODAPI extern struct MDRIVER *MikMod_DriverByOrdinal(int);
-MIKMODAPI extern int MikMod_Init(CHAR*);
+MIKMODAPI extern int MikMod_Init(const CHAR*);
MIKMODAPI extern void MikMod_Exit(void);
-MIKMODAPI extern int MikMod_Reset(CHAR*);
-MIKMODAPI extern int MikMod_SetNumVoices(int,int);
+MIKMODAPI extern int MikMod_Reset(const CHAR*);
+MIKMODAPI extern int MikMod_SetNumVoices(int,int);
MIKMODAPI extern int MikMod_Active(void);
-MIKMODAPI extern int MikMod_EnableOutput(void);
+MIKMODAPI extern int MikMod_EnableOutput(void);
MIKMODAPI extern void MikMod_DisableOutput(void);
MIKMODAPI extern void MikMod_Update(void);
@@ -253,33 +336,34 @@ MIKMODAPI extern void MikMod_Lock(void);
MIKMODAPI extern void MikMod_Unlock(void);
MIKMODAPI extern void* MikMod_malloc(size_t);
-MIKMODAPI extern void* MikMod_realloc(void *, size_t);
MIKMODAPI extern void* MikMod_calloc(size_t,size_t);
-MIKMODAPI extern void MikMod_free(void*);
+MIKMODAPI extern void* MikMod_realloc(void*,size_t);
+MIKMODAPI extern CHAR* MikMod_strdup(const CHAR*);
+MIKMODAPI extern void MikMod_free(void*); /* frees if ptr != NULL */
/*
- * ========== Reader, Writer
+ * ========== Reader, Writer
*/
typedef struct MREADER {
- int (*Seek)(struct MREADER*,long,int);
- long (*Tell)(struct MREADER*);
- int (*Read)(struct MREADER*,void*,size_t);
- int (*Get)(struct MREADER*);
- int (*Eof)(struct MREADER*);
- long iobase;
- long prev_iobase;
+ int (*Seek)(struct MREADER*,long,int);
+ long (*Tell)(struct MREADER*);
+ int (*Read)(struct MREADER*,void*,size_t);
+ int (*Get)(struct MREADER*);
+ int (*Eof)(struct MREADER*);
+ long iobase;
+ long prev_iobase;
} MREADER;
typedef struct MWRITER {
- int (*Seek)(struct MWRITER*,long,int);
- long (*Tell)(struct MWRITER*);
- int (*Write)(struct MWRITER*,void*,size_t);
- int (*Put)(struct MWRITER*,int);
+ int (*Seek)(struct MWRITER*, long, int);
+ long (*Tell)(struct MWRITER*);
+ int (*Write)(struct MWRITER*, const void*, size_t);
+ int (*Put)(struct MWRITER*, int);
} MWRITER;
/*
- * ========== Samples
+ * ========== Samples
*/
/* Sample playback should not be interrupted */
@@ -291,9 +375,9 @@ typedef struct MWRITER {
#define SF_SIGNED 0x0004
#define SF_BIG_ENDIAN 0x0008
#define SF_DELTA 0x0010
-#define SF_ITPACKED 0x0020
+#define SF_ITPACKED 0x0020
-#define SF_FORMATMASK 0x003F
+#define SF_FORMATMASK 0x003F
/* General Playback flags */
@@ -302,61 +386,61 @@ typedef struct MWRITER {
#define SF_REVERSE 0x0400
#define SF_SUSTAIN 0x0800
-#define SF_PLAYBACKMASK 0x0C00
+#define SF_PLAYBACKMASK 0x0C00
/* Module-only Playback Flags */
-#define SF_OWNPAN 0x1000
+#define SF_OWNPAN 0x1000
#define SF_UST_LOOP 0x2000
-#define SF_EXTRAPLAYBACKMASK 0x3000
+#define SF_EXTRAPLAYBACKMASK 0x3000
/* Panning constants */
-#define PAN_LEFT 0
-#define PAN_HALFLEFT 64
-#define PAN_CENTER 128
-#define PAN_HALFRIGHT 192
-#define PAN_RIGHT 255
-#define PAN_SURROUND 512 /* panning value for Dolby Surround */
+#define PAN_LEFT 0
+#define PAN_HALFLEFT 64
+#define PAN_CENTER 128
+#define PAN_HALFRIGHT 192
+#define PAN_RIGHT 255
+#define PAN_SURROUND 512 /* panning value for Dolby Surround */
typedef struct SAMPLE {
- SWORD panning; /* panning (0-255 or PAN_SURROUND) */
- ULONG speed; /* Base playing speed/frequency of note */
- UBYTE volume; /* volume 0-64 */
- UWORD inflags; /* sample format on disk */
- UWORD flags; /* sample format in memory */
- ULONG length; /* length of sample (in samples!) */
- ULONG loopstart; /* repeat position (relative to start, in samples) */
- ULONG loopend; /* repeat end */
- ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */
- ULONG susend; /* sustain loop end / Yet! */
-
- /* Variables used by the module player only! (ignored for sound effects) */
- UBYTE globvol; /* global volume */
- UBYTE vibflags; /* autovibrato flag stuffs */
- UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */
- UBYTE vibsweep;
- UBYTE vibdepth;
- UBYTE vibrate;
- CHAR* samplename; /* name of the sample */
-
- /* Values used internally only */
- UWORD avibpos; /* autovibrato pos [player use] */
- UBYTE divfactor; /* for sample scaling, maintains proper period slides */
- ULONG seekpos; /* seek position in file */
- SWORD handle; /* sample handle used by individual drivers */
- void (*onfree)(void *ctx); /* called from Sample_Free if not NULL */
- void *ctx; /* context passed to previous function*/
+ SWORD panning; /* panning (0-255 or PAN_SURROUND) */
+ ULONG speed; /* Base playing speed/frequency of note */
+ UBYTE volume; /* volume 0-64 */
+ UWORD inflags; /* sample format on disk */
+ UWORD flags; /* sample format in memory */
+ ULONG length; /* length of sample (in samples!) */
+ ULONG loopstart; /* repeat position (relative to start, in samples) */
+ ULONG loopend; /* repeat end */
+ ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */
+ ULONG susend; /* sustain loop end / Yet! */
+
+ /* Variables used by the module player only! (ignored for sound effects) */
+ UBYTE globvol; /* global volume */
+ UBYTE vibflags; /* autovibrato flag stuffs */
+ UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */
+ UBYTE vibsweep;
+ UBYTE vibdepth;
+ UBYTE vibrate;
+ CHAR* samplename; /* name of the sample */
+
+ /* Values used internally only */
+ UWORD avibpos; /* autovibrato pos [player use] */
+ UBYTE divfactor; /* for sample scaling, maintains proper period slides */
+ ULONG seekpos; /* seek position in file */
+ SWORD handle; /* sample handle used by individual drivers */
+ void (*onfree)(void *ctx); /* called from Sample_Free if not NULL */
+ void *ctx; /* context passed to previous function*/
} SAMPLE;
/* Sample functions */
-MIKMODAPI extern SAMPLE *Sample_LoadRaw(CHAR *,ULONG rate, ULONG channel, ULONG flags);
+MIKMODAPI extern SAMPLE *Sample_LoadRaw(const CHAR *,ULONG rate, ULONG channel, ULONG flags);
MIKMODAPI extern SAMPLE *Sample_LoadRawFP(int fp,ULONG rate,ULONG channel, ULONG flags);
MIKMODAPI extern SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags);
MIKMODAPI extern SAMPLE *Sample_LoadRawGeneric(MREADER*reader,ULONG rate, ULONG channel, ULONG flags);
-MIKMODAPI extern SAMPLE *Sample_Load(CHAR*);
+MIKMODAPI extern SAMPLE *Sample_Load(const CHAR*);
MIKMODAPI extern SAMPLE *Sample_LoadFP(int);
MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len);
MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*);
@@ -376,12 +460,12 @@ MIKMODAPI extern SLONG Voice_GetPosition(SBYTE);
MIKMODAPI extern ULONG Voice_RealVolume(SBYTE);
/*
- * ========== Internal module representation (UniMod)
+ * ========== Internal module representation (UniMod)
*/
/*
- Instrument definition - for information only, the only field which may be
- of use in user programs is the name field
+ Instrument definition - for information only, the only field which may be
+ of use in user programs is the name field
*/
/* Instrument note count */
@@ -389,8 +473,8 @@ MIKMODAPI extern ULONG Voice_RealVolume(SBYTE);
/* Envelope point */
typedef struct ENVPT {
- SWORD pos;
- SWORD val;
+ SWORD pos;
+ SWORD val;
} ENVPT;
/* Envelope point count */
@@ -398,154 +482,156 @@ typedef struct ENVPT {
/* Instrument structure */
typedef struct INSTRUMENT {
- CHAR* insname;
-
- UBYTE flags;
- UWORD samplenumber[INSTNOTES];
- UBYTE samplenote[INSTNOTES];
-
- UBYTE nnatype;
- UBYTE dca; /* duplicate check action */
- UBYTE dct; /* duplicate check type */
- UBYTE globvol;
- UWORD volfade;
- SWORD panning; /* instrument-based panning var */
-
- UBYTE pitpansep; /* pitch pan separation (0 to 255) */
- UBYTE pitpancenter; /* pitch pan center (0 to 119) */
- UBYTE rvolvar; /* random volume varations (0 - 100%) */
- UBYTE rpanvar; /* random panning varations (0 - 100%) */
-
- /* volume envelope */
- UBYTE volflg; /* bit 0: on 1: sustain 2: loop */
- UBYTE volpts;
- UBYTE volsusbeg;
- UBYTE volsusend;
- UBYTE volbeg;
- UBYTE volend;
- ENVPT volenv[ENVPOINTS];
- /* panning envelope */
- UBYTE panflg; /* bit 0: on 1: sustain 2: loop */
- UBYTE panpts;
- UBYTE pansusbeg;
- UBYTE pansusend;
- UBYTE panbeg;
- UBYTE panend;
- ENVPT panenv[ENVPOINTS];
- /* pitch envelope */
- UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */
- UBYTE pitpts;
- UBYTE pitsusbeg;
- UBYTE pitsusend;
- UBYTE pitbeg;
- UBYTE pitend;
- ENVPT pitenv[ENVPOINTS];
+ CHAR* insname;
+
+ UBYTE flags;
+ UWORD samplenumber[INSTNOTES];
+ UBYTE samplenote[INSTNOTES];
+
+ UBYTE nnatype;
+ UBYTE dca; /* duplicate check action */
+ UBYTE dct; /* duplicate check type */
+ UBYTE globvol;
+ UWORD volfade;
+ SWORD panning; /* instrument-based panning var */
+
+ UBYTE pitpansep; /* pitch pan separation (0 to 255) */
+ UBYTE pitpancenter; /* pitch pan center (0 to 119) */
+ UBYTE rvolvar; /* random volume varations (0 - 100%) */
+ UBYTE rpanvar; /* random panning varations (0 - 100%) */
+
+ /* volume envelope */
+ UBYTE volflg; /* bit 0: on 1: sustain 2: loop */
+ UBYTE volpts;
+ UBYTE volsusbeg;
+ UBYTE volsusend;
+ UBYTE volbeg;
+ UBYTE volend;
+ ENVPT volenv[ENVPOINTS];
+ /* panning envelope */
+ UBYTE panflg; /* bit 0: on 1: sustain 2: loop */
+ UBYTE panpts;
+ UBYTE pansusbeg;
+ UBYTE pansusend;
+ UBYTE panbeg;
+ UBYTE panend;
+ ENVPT panenv[ENVPOINTS];
+ /* pitch envelope */
+ UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */
+ UBYTE pitpts;
+ UBYTE pitsusbeg;
+ UBYTE pitsusend;
+ UBYTE pitbeg;
+ UBYTE pitend;
+ ENVPT pitenv[ENVPOINTS];
} INSTRUMENT;
struct MP_CONTROL;
struct MP_VOICE;
/*
- Module definition
+ Module definition
*/
/* maximum master channels supported */
-#define UF_MAXCHAN 64
+#define UF_MAXCHAN 64
/* Module flags */
-#define UF_XMPERIODS 0x0001 /* XM periods / finetuning */
-#define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */
-#define UF_INST 0x0004 /* Instruments are used */
-#define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather
- than numchn */
-#define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */
-#define UF_BGSLIDES 0x0020 /* continue volume slides in the background */
-#define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */
-#define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break
- semantics */
-#define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */
-#define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */
-#define UF_PANNING 0x0400 /* module uses panning effects or have
- non-tracker default initial panning */
+#define UF_XMPERIODS 0x0001 /* XM periods / finetuning */
+#define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */
+#define UF_INST 0x0004 /* Instruments are used */
+#define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather
+ than numchn */
+#define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */
+#define UF_BGSLIDES 0x0020 /* continue volume slides in the background */
+#define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */
+#define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break
+ semantics */
+#define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */
+#define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */
+#define UF_PANNING 0x0400 /* module uses panning effects or have
+ non-tracker default initial panning */
typedef struct MODULE {
- /* general module information */
- CHAR* songname; /* name of the song */
- CHAR* modtype; /* string type of module loaded */
- CHAR* comment; /* module comments */
-
- UWORD flags; /* See module flags above */
- UBYTE numchn; /* number of module channels */
- UBYTE numvoices; /* max # voices used for full NNA playback */
- UWORD numpos; /* number of positions in this song */
- UWORD numpat; /* number of patterns in this song */
- UWORD numins; /* number of instruments */
- UWORD numsmp; /* number of samples */
-struct INSTRUMENT* instruments; /* all instruments */
-struct SAMPLE* samples; /* all samples */
- UBYTE realchn; /* real number of channels used */
- UBYTE totalchn; /* total number of channels used (incl NNAs) */
-
- /* playback settings */
- UWORD reppos; /* restart position */
- UBYTE initspeed; /* initial song speed */
- UWORD inittempo; /* initial song tempo */
- UBYTE initvolume; /* initial global volume (0 - 128) */
- UWORD panning[UF_MAXCHAN]; /* panning positions */
- UBYTE chanvol[UF_MAXCHAN]; /* channel positions */
- UWORD bpm; /* current beats-per-minute speed */
- UWORD sngspd; /* current song speed */
- SWORD volume; /* song volume (0-128) (or user volume) */
-
- int extspd; /* extended speed flag (default enabled) */
- int panflag; /* panning flag (default enabled) */
- int wrap; /* wrap module ? (default disabled) */
- int loop; /* allow module to loop ? (default enabled) */
- int fadeout; /* volume fade out during last pattern */
-
- UWORD patpos; /* current row number */
- SWORD sngpos; /* current song position */
- ULONG sngtime; /* current song time in 2^-10 seconds */
-
- SWORD relspd; /* relative speed factor */
-
- /* internal module representation */
- UWORD numtrk; /* number of tracks */
- UBYTE** tracks; /* array of numtrk pointers to tracks */
- UWORD* patterns; /* array of Patterns */
- UWORD* pattrows; /* array of number of rows for each pattern */
- UWORD* positions; /* all positions */
-
- int forbid; /* if true, no player update! */
- UWORD numrow; /* number of rows on current pattern */
- UWORD vbtick; /* tick counter (counts from 0 to sngspd) */
- UWORD sngremainder;/* used for song time computation */
-
-struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */
-struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */
-
- UBYTE globalslide; /* global volume slide rate */
- UBYTE pat_repcrazy;/* module has just looped to position -1 */
- UWORD patbrk; /* position where to start a new pattern */
- UBYTE patdly; /* patterndelay counter (command memory) */
- UBYTE patdly2; /* patterndelay counter (real one) */
- SWORD posjmp; /* flag to indicate a jump is needed... */
- UWORD bpmlimit; /* threshold to detect bpm or speed values */
+ /* general module information */
+ CHAR* songname; /* name of the song */
+ CHAR* modtype; /* string type of module loaded */
+ CHAR* comment; /* module comments */
+
+ UWORD flags; /* See module flags above */
+ UBYTE numchn; /* number of module channels */
+ UBYTE numvoices; /* max # voices used for full NNA playback */
+ UWORD numpos; /* number of positions in this song */
+ UWORD numpat; /* number of patterns in this song */
+ UWORD numins; /* number of instruments */
+ UWORD numsmp; /* number of samples */
+
+ struct INSTRUMENT* instruments; /* all instruments */
+ struct SAMPLE* samples; /* all samples */
+
+ UBYTE realchn; /* real number of channels used */
+ UBYTE totalchn; /* total number of channels used (incl NNAs) */
+
+ /* playback settings */
+ UWORD reppos; /* restart position */
+ UBYTE initspeed; /* initial song speed */
+ UWORD inittempo; /* initial song tempo */
+ UBYTE initvolume; /* initial global volume (0 - 128) */
+ UWORD panning[UF_MAXCHAN]; /* panning positions */
+ UBYTE chanvol[UF_MAXCHAN]; /* channel positions */
+ UWORD bpm; /* current beats-per-minute speed */
+ UWORD sngspd; /* current song speed */
+ SWORD volume; /* song volume (0-128) (or user volume) */
+
+ int extspd; /* extended speed flag (default enabled) */
+ int panflag; /* panning flag (default enabled) */
+ int wrap; /* wrap module ? (default disabled) */
+ int loop; /* allow module to loop ? (default enabled) */
+ int fadeout; /* volume fade out during last pattern */
+
+ UWORD patpos; /* current row number */
+ SWORD sngpos; /* current song position */
+ ULONG sngtime; /* current song time in 2^-10 seconds */
+
+ SWORD relspd; /* relative speed factor */
+
+ /* internal module representation */
+ UWORD numtrk; /* number of tracks */
+ UBYTE** tracks; /* array of numtrk pointers to tracks */
+ UWORD* patterns; /* array of Patterns */
+ UWORD* pattrows; /* array of number of rows for each pattern */
+ UWORD* positions; /* all positions */
+
+ int forbid; /* if true, no player update! */
+ UWORD numrow; /* number of rows on current pattern */
+ UWORD vbtick; /* tick counter (counts from 0 to sngspd) */
+ UWORD sngremainder;/* used for song time computation */
+
+ struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */
+ struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */
+
+ UBYTE globalslide; /* global volume slide rate */
+ UBYTE pat_repcrazy;/* module has just looped to position -1 */
+ UWORD patbrk; /* position where to start a new pattern */
+ UBYTE patdly; /* patterndelay counter (command memory) */
+ UBYTE patdly2; /* patterndelay counter (real one) */
+ SWORD posjmp; /* flag to indicate a jump is needed... */
+ UWORD bpmlimit; /* threshold to detect bpm or speed values */
} MODULE;
/* This structure is used to query current playing voices status */
typedef struct VOICEINFO {
- INSTRUMENT* i; /* Current channel instrument */
- SAMPLE* s; /* Current channel sample */
- SWORD panning; /* panning position */
- SBYTE volume; /* channel's "global" volume (0..64) */
- UWORD period; /* period to play the sample at */
- UBYTE kick; /* if true = sample has been restarted */
+ INSTRUMENT* i; /* Current channel instrument */
+ SAMPLE* s; /* Current channel sample */
+ SWORD panning; /* panning position */
+ SBYTE volume; /* channel's "global" volume (0..64) */
+ UWORD period; /* period to play the sample at */
+ UBYTE kick; /* if true = sample has been restarted */
} VOICEINFO;
/*
- * ========== Module loaders
+ * ========== Module loaders
*/
struct MLOADER;
@@ -572,18 +658,19 @@ MIKMODAPI extern struct MLOADER load_stm; /* ScreamTracker 2 (by Future Crew) */
MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */
MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */
MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */
+MIKMODAPI extern struct MLOADER load_umx; /* Unreal UMX container of Epic Games */
MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */
MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */
/*
- * ========== Module player
+ * ========== Module player
*/
-MIKMODAPI extern MODULE* Player_Load(CHAR*,int,int);
+MIKMODAPI extern MODULE* Player_Load(const CHAR*,int,int);
MIKMODAPI extern MODULE* Player_LoadFP(int,int,int);
MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious);
MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,int);
-MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*);
+MIKMODAPI extern CHAR* Player_LoadTitle(const CHAR*);
MIKMODAPI extern CHAR* Player_LoadTitleFP(int);
MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len);
MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*);
@@ -607,9 +694,9 @@ MIKMODAPI extern void Player_Mute(SLONG,...);
MIKMODAPI extern void Player_ToggleMute(SLONG,...);
MIKMODAPI extern int Player_GetChannelVoice(UBYTE);
MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE);
-MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo);
+MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo);
MIKMODAPI extern int Player_GetRow(void);
-MIKMODAPI extern int Player_GetOrder(void);
+MIKMODAPI extern int Player_GetOrder(void);
typedef void (*MikMod_player_t)(void);
typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
@@ -620,17 +707,17 @@ MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t);
#define MUTE_INCLUSIVE 32001
/*
- * ========== Drivers
+ * ========== Drivers
*/
enum {
- MD_MUSIC = 0,
- MD_SNDFX
+ MD_MUSIC = 0,
+ MD_SNDFX
};
enum {
- MD_HARDWARE = 0,
- MD_SOFTWARE
+ MD_HARDWARE = 0,
+ MD_SOFTWARE
};
/* Mixing flags */
@@ -646,46 +733,48 @@ enum {
#define DMODE_SURROUND 0x0100 /* enable surround sound */
#define DMODE_INTERP 0x0200 /* enable interpolation */
#define DMODE_REVERSE 0x0400 /* reverse stereo */
-#define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */
+#define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */
#define DMODE_NOISEREDUCTION 0x1000 /* Low pass filtering */
+
struct SAMPLOAD;
+
typedef struct MDRIVER {
-struct MDRIVER* next;
- CHAR* Name;
- CHAR* Version;
-
- UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */
- UBYTE SoftVoiceLimit; /* Limit of software mixer voices */
-
- CHAR *Alias;
- CHAR *CmdLineHelp;
-
- void (*CommandLine) (CHAR*);
- int (*IsPresent) (void);
- SWORD (*SampleLoad) (struct SAMPLOAD*,int);
- void (*SampleUnload) (SWORD);
- ULONG (*FreeSampleSpace) (int);
- ULONG (*RealSampleLength) (int,struct SAMPLE*);
- int (*Init) (void);
- void (*Exit) (void);
- int (*Reset) (void);
- int (*SetNumVoices) (void);
- int (*PlayStart) (void);
- void (*PlayStop) (void);
- void (*Update) (void);
- void (*Pause) (void);
- void (*VoiceSetVolume) (UBYTE,UWORD);
- UWORD (*VoiceGetVolume) (UBYTE);
- void (*VoiceSetFrequency)(UBYTE,ULONG);
- ULONG (*VoiceGetFrequency)(UBYTE);
- void (*VoiceSetPanning) (UBYTE,ULONG);
- ULONG (*VoiceGetPanning) (UBYTE);
- void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
- void (*VoiceStop) (UBYTE);
- int (*VoiceStopped) (UBYTE);
- SLONG (*VoiceGetPosition) (UBYTE);
- ULONG (*VoiceRealVolume) (UBYTE);
+ struct MDRIVER* next;
+ const CHAR* Name;
+ const CHAR* Version;
+
+ UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */
+ UBYTE SoftVoiceLimit; /* Limit of software mixer voices */
+
+ const CHAR* Alias;
+ const CHAR* CmdLineHelp;
+
+ void (*CommandLine) (const CHAR*);
+ int (*IsPresent) (void);
+ SWORD (*SampleLoad) (struct SAMPLOAD*,int);
+ void (*SampleUnload) (SWORD);
+ ULONG (*FreeSampleSpace) (int);
+ ULONG (*RealSampleLength) (int,struct SAMPLE*);
+ int (*Init) (void);
+ void (*Exit) (void);
+ int (*Reset) (void);
+ int (*SetNumVoices) (void);
+ int (*PlayStart) (void);
+ void (*PlayStop) (void);
+ void (*Update) (void);
+ void (*Pause) (void);
+ void (*VoiceSetVolume) (UBYTE,UWORD);
+ UWORD (*VoiceGetVolume) (UBYTE);
+ void (*VoiceSetFrequency)(UBYTE,ULONG);
+ ULONG (*VoiceGetFrequency)(UBYTE);
+ void (*VoiceSetPanning) (UBYTE,ULONG);
+ ULONG (*VoiceGetPanning) (UBYTE);
+ void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
+ void (*VoiceStop) (UBYTE);
+ int (*VoiceStopped) (UBYTE);
+ SLONG (*VoiceGetPosition) (UBYTE);
+ ULONG (*VoiceRealVolume) (UBYTE);
} MDRIVER;
/* These variables can be changed at ANY time and results will be immediate */
@@ -700,7 +789,7 @@ MIKMODAPI extern UBYTE md_pansep; /* 0 = mono; 128 == 100% (full left/righ
in a skip or pop in audio (depending on the soundcard driver and the settings
changed). */
MIKMODAPI extern UWORD md_device; /* device */
-MIKMODAPI extern UWORD md_mixfreq; /* mixing frequency */
+MIKMODAPI extern ULONG md_mixfreq; /* mixing frequency */
MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */
/* The following variable should not be changed! */
@@ -709,7 +798,6 @@ MIKMODAPI extern MDRIVER* md_driver; /* Current driver in use. */
/* Known drivers list */
MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */
-#if 0
MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */
MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */
MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */
@@ -717,42 +805,53 @@ MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music
MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */
MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */
-MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */
+MIKMODAPI extern struct MDRIVER drv_sam9407;/* Linux sam9407 driver */
MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */
+MIKMODAPI extern struct MDRIVER drv_ahi; /* Amiga AHI */
MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */
MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */
MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */
+MIKMODAPI extern struct MDRIVER drv_pulseaudio; /* PulseAudio */
MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */
-MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */
+MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */
MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */
+MIKMODAPI extern struct MDRIVER drv_openal; /* OpenAL driver */
+MIKMODAPI extern struct MDRIVER drv_sdl; /* SDL audio driver */
MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */
+MIKMODAPI extern struct MDRIVER drv_sndio; /* OpenBSD sndio */
MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */
MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */
MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */
MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */
+MIKMODAPI extern struct MDRIVER drv_xaudio2;/* Win32 XAudio2 driver */
MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */
MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */
-MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */
+MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */
+MIKMODAPI extern struct MDRIVER drv_dc; /* Dreamcast driver */
MIKMODAPI extern struct MDRIVER drv_gp32; /* GP32 Sound driver */
+MIKMODAPI extern struct MDRIVER drv_psp; /* PlayStation Portable driver */
+MIKMODAPI extern struct MDRIVER drv_n64; /* Nintendo64 driver */
MIKMODAPI extern struct MDRIVER drv_wss; /* DOS WSS driver */
-MIKMODAPI extern struct MDRIVER drv_sb; /* DOS SB driver */
-#endif
+MIKMODAPI extern struct MDRIVER drv_sb; /* DOS S/B driver */
+
+MIKMODAPI extern struct MDRIVER drv_osles; /* OpenSL ES driver for android */
+
/*========== Virtual channel mixer interface (for user-supplied drivers only) */
-MIKMODAPI extern int VC_Init(void);
+MIKMODAPI extern int VC_Init(void);
MIKMODAPI extern void VC_Exit(void);
MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback);
-MIKMODAPI extern int VC_SetNumVoices(void);
+MIKMODAPI extern int VC_SetNumVoices(void);
MIKMODAPI extern ULONG VC_SampleSpace(int);
MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*);
-MIKMODAPI extern int VC_PlayStart(void);
+MIKMODAPI extern int VC_PlayStart(void);
MIKMODAPI extern void VC_PlayStop(void);
MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int);
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 <stdarg.h>
-#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 <Types.h>
-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 <pthread.h>
#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 <windows.h>
-#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 <ppc_intrinsics.h>
#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 <emmintrin.h>
-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: */
diff --git a/apps/plugins/mikmod/mikmod_supp.h b/apps/plugins/mikmod/mikmod_supp.h
index c1a8681720..fdd9d8f24f 100644
--- a/apps/plugins/mikmod/mikmod_supp.h
+++ b/apps/plugins/mikmod/mikmod_supp.h
@@ -8,6 +8,9 @@
#undef WIN32
+#define NO_DEPACKERS // We don't support these
+//#define NO_HQMIXER // We don't have the oomph
+
#ifndef NO_MMSUPP_DEFINES
#define snprintf(...) rb->snprintf(__VA_ARGS__)
#define fdprintf(...) rb->fdprintf(__VA_ARGS__)
diff --git a/apps/plugins/mikmod/mloader.c b/apps/plugins/mikmod/mloader.c
index 5f58d8102f..9ea9489272 100644
--- a/apps/plugins/mikmod/mloader.c
+++ b/apps/plugins/mikmod/mloader.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: mloader.c,v 1.3 2005/04/07 19:57:39 realtech Exp $
+ $Id$
These routines are used to access the available module loaders
@@ -50,7 +50,17 @@ MODULE of;
static MLOADER *firstloader=NULL;
-UWORD finetune[16]={
+#ifndef NO_DEPACKERS
+static MUNPACKER unpackers[] = {
+ PP20_Unpack,
+ MMCMP_Unpack,
+ XPK_Unpack,
+ S404_Unpack,
+ NULL
+};
+#endif
+
+const UWORD finetune[16] = {
8363,8413,8463,8529,8581,8651,8723,8757,
7895,7941,7985,8046,8107,8169,8232,8280
};
@@ -63,15 +73,18 @@ MIKMODAPI CHAR* MikMod_InfoLoader(void)
MUTEX_LOCK(lists);
/* compute size of buffer */
- for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version);
+ for(l = firstloader; l; l = l->next)
+ len += 1 + (l->next ? 1 : 0) + strlen(l->version);
if(len)
- if((list=MikMod_malloc(len*sizeof(CHAR)))) {
- list[0]=0;
- /* list all registered module loders */
- for(l=firstloader;l;l=l->next)
- sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version);
+ if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
+ CHAR *list_end = list;
+ list[0] = 0;
+ /* list all registered module loders */
+ for(l = firstloader; l; l = l->next) {
+ list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
}
+ }
MUTEX_UNLOCK(lists);
return list;
}
@@ -84,7 +97,7 @@ void _mm_registerloader(MLOADER* ldr)
while(cruise->next) cruise = cruise->next;
cruise->next=ldr;
} else
- firstloader=ldr;
+ firstloader=ldr;
}
MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr)
@@ -106,7 +119,7 @@ int ReadComment(UWORD len)
if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0;
_mm_read_UBYTES(of.comment,len,modreader);
-
+
/* translate IT linefeeds */
for(i=0;i<len;i++)
if(of.comment[i]=='\r') of.comment[i]='\n';
@@ -122,44 +135,44 @@ int ReadComment(UWORD len)
int ReadLinedComment(UWORD len,UWORD linelen)
{
- CHAR *tempcomment,*line,*storage;
- UWORD total=0,t,lines;
- int i;
-
- lines = (len + linelen - 1) / linelen;
- if (len) {
- if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0;
- if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) {
- MikMod_free(tempcomment);
- return 0;
- }
- memset(tempcomment, ' ', len);
- _mm_read_UBYTES(tempcomment,len,modreader);
-
- /* compute message length */
- for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) {
- for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0;
- for(i=0;i<linelen;i++) if (!line[i]) break;
- total+=1+i;
- }
-
- if(total>lines) {
- if(!(of.comment=(CHAR*)MikMod_malloc(total+1))) {
- MikMod_free(storage);
- MikMod_free(tempcomment);
- return 0;
- }
+ /* Adapted from the OpenMPT project, C'ified. */
+ CHAR *buf, *storage, *p;
+ size_t numlines, line, fpos, cpos, lpos, cnt;
+
+ if (!linelen) return 0;
+ if (!len) return 1;
+
+ if (!(buf = (CHAR *) MikMod_malloc(len))) return 0;
+ numlines = (len + linelen - 1) / linelen;
+ cnt = (linelen + 1) * numlines;
+ if (!(storage = (CHAR *) MikMod_malloc(cnt + 1))) {
+ MikMod_free(buf);
+ return 0;
+ }
- /* convert message */
- for(line=tempcomment,t=0;t<lines;t++,line+=linelen) {
- for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break;
- storage[i]=0; /* if (i==linelen) */
- strcat(of.comment,storage);strcat(of.comment,"\r");
+ _mm_read_UBYTES(buf,len,modreader);
+ storage[cnt] = 0;
+ for (line = 0, fpos = 0, cpos = 0; line < numlines; line++, fpos += linelen, cpos += (linelen + 1))
+ {
+ cnt = len - fpos;
+ if (cnt > linelen) cnt = linelen;
+ p = storage + cpos;
+ memcpy(p, buf + fpos, cnt);
+ p[cnt] = '\r';
+ /* fix weird chars */
+ for (lpos = 0; lpos < linelen; lpos++, p++) {
+ switch (*p) {
+ case '\0':
+ case '\n':
+ case '\r':
+ *p = ' ';
+ break;
}
- MikMod_free(storage);
- MikMod_free(tempcomment);
}
}
+
+ of.comment = storage;
+ MikMod_free(buf);
return 1;
}
@@ -169,7 +182,7 @@ int AllocPositions(int total)
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
- if(!(of.positions=MikMod_calloc(total,sizeof(UWORD)))) return 0;
+ if(!(of.positions=(UWORD*)MikMod_calloc(total,sizeof(UWORD)))) return 0;
return 1;
}
@@ -207,7 +220,7 @@ int AllocTracks(void)
int AllocInstruments(void)
{
int t,n;
-
+
if(!of.numins) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
@@ -216,11 +229,11 @@ int AllocInstruments(void)
return 0;
for(t=0;t<of.numins;t++) {
- for(n=0;n<INSTNOTES;n++) {
+ for(n=0;n<INSTNOTES;n++) {
/* Init note / sample lookup table */
of.instruments[t].samplenote[n] = n;
of.instruments[t].samplenumber[n] = t;
- }
+ }
of.instruments[t].globvol = 64;
}
return 1;
@@ -257,8 +270,8 @@ static int ML_LoadSamples(void)
}
/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any
- terminating non-printing characters like 0, spaces etc. */
-CHAR *DupStr(CHAR* s,UWORD len,int strict)
+ terminating non-printing characters like 0, spaces etc. */
+CHAR *DupStr(const CHAR* s, UWORD len, int strict)
{
UWORD t;
CHAR *d=NULL;
@@ -277,48 +290,42 @@ CHAR *DupStr(CHAR* s,UWORD len,int strict)
/* When the buffer wasn't completely empty, allocate a cstring and copy the
buffer into that string, except for any control-chars */
- if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1)))) {
+ if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1))) != NULL) {
for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t];
d[len]=0;
}
return d;
}
-CHAR *StrDup(CHAR *s)
-{
- size_t l = strlen(s) + 1;
- CHAR *d = MikMod_malloc(l);
- strcpy(d, s);
- return d;
-}
-
static void ML_XFreeSample(SAMPLE *s)
{
if(s->handle>=0)
MD_SampleUnload(s->handle);
- if(s->samplename) MikMod_free(s->samplename);
+
+/* moved samplename freeing to our caller ML_FreeEx(),
+ * because we are called conditionally. */
}
static void ML_XFreeInstrument(INSTRUMENT *i)
{
- if(i->insname) MikMod_free(i->insname);
+ MikMod_free(i->insname);
}
static void ML_FreeEx(MODULE *mf)
{
UWORD t;
- if(mf->songname) MikMod_free(mf->songname);
- if(mf->comment) MikMod_free(mf->comment);
+ MikMod_free(mf->songname);
+ MikMod_free(mf->comment);
- if(mf->modtype) MikMod_free(mf->modtype);
- if(mf->positions) MikMod_free(mf->positions);
- if(mf->patterns) MikMod_free(mf->patterns);
- if(mf->pattrows) MikMod_free(mf->pattrows);
+ MikMod_free(mf->modtype);
+ MikMod_free(mf->positions);
+ MikMod_free(mf->patterns);
+ MikMod_free(mf->pattrows);
if(mf->tracks) {
for(t=0;t<mf->numtrk;t++)
- if(mf->tracks[t]) MikMod_free(mf->tracks[t]);
+ MikMod_free(mf->tracks[t]);
MikMod_free(mf->tracks);
}
if(mf->instruments) {
@@ -327,8 +334,10 @@ static void ML_FreeEx(MODULE *mf)
MikMod_free(mf->instruments);
}
if(mf->samples) {
- for(t=0;t<mf->numsmp;t++)
+ for(t=0;t<mf->numsmp;t++) {
+ MikMod_free(mf->samples[t].samplename);
if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]);
+ }
MikMod_free(mf->samples);
}
memset(mf,0,sizeof(MODULE));
@@ -337,10 +346,24 @@ static void ML_FreeEx(MODULE *mf)
static MODULE *ML_AllocUniMod(void)
{
- MODULE *mf;
+ return (MODULE *) MikMod_malloc(sizeof(MODULE));
+}
+
+#ifndef NO_DEPACKERS
+static int ML_TryUnpack(MREADER *reader,void **out,long *outlen)
+{
+ int i;
- return (mf=MikMod_malloc(sizeof(MODULE)));
+ *out = NULL;
+ *outlen = 0;
+
+ for(i=0;unpackers[i]!=NULL;++i) {
+ _mm_rewind(reader);
+ if(unpackers[i](reader,out,outlen)) return 1;
+ }
+ return 0;
}
+#endif
static void Player_Free_internal(MODULE *mf)
{
@@ -360,25 +383,50 @@ MIKMODAPI void Player_Free(MODULE *mf)
static CHAR* Player_LoadTitle_internal(MREADER *reader)
{
MLOADER *l;
+ CHAR *title;
+ #ifndef NO_DEPACKERS
+ void *unpk;
+ long newlen;
+ #endif
modreader=reader;
_mm_errno = 0;
_mm_critical = 0;
_mm_iobase_setcur(modreader);
+ #ifndef NO_DEPACKERS
+ if(ML_TryUnpack(modreader,&unpk,&newlen)) {
+ if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
+ modreader=reader;
+ MikMod_free(unpk);
+ return NULL;
+ }
+ }
+ #endif
+
/* Try to find a loader that recognizes the module */
for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader);
if(l->Test()) break;
}
- if(!l) {
+ if(l) {
+ title = l->LoadTitle();
+ }
+ else {
_mm_errno = MMERR_NOT_A_MODULE;
if(_mm_errorhandler) _mm_errorhandler();
- return NULL;
+ title = NULL;
}
- return l->LoadTitle();
+ #ifndef NO_DEPACKERS
+ if (modreader!=reader) {
+ _mm_delete_mem_reader(modreader);
+ modreader=reader;
+ MikMod_free(unpk);
+ }
+ #endif
+ return title;
}
MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
@@ -386,7 +434,7 @@ MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
CHAR* result=NULL;
MREADER* reader;
- if(fp && (reader=_mm_new_file_reader(fp))) {
+ if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
@@ -400,22 +448,22 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
CHAR *result=NULL;
MREADER* reader;
- if ((reader=_mm_new_mem_reader(buffer,len)))
+ if (!buffer || len <= 0) return NULL;
+ if ((reader=_mm_new_mem_reader(buffer,len)) != NULL)
{
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
_mm_delete_mem_reader(reader);
}
-
-
+
return result;
}
MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
-{
+{
CHAR *result=NULL;
-
+
if (reader) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
@@ -424,14 +472,14 @@ MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
return result;
}
-MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename)
+MIKMODAPI CHAR* Player_LoadTitle(const CHAR* filename)
{
CHAR* result=NULL;
int fp;
MREADER* reader;
- if((fp=_mm_fopen(filename,"rb"))) {
- if((reader=_mm_new_file_reader(fp))) {
+ if((fp=_mm_fopen(filename,"rb")) >= 0) {
+ if((reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
@@ -449,12 +497,26 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
MLOADER *l;
int ok;
MODULE *mf;
+ #ifndef NO_DEPACKERS
+ void *unpk;
+ long newlen;
+ #endif
modreader = reader;
_mm_errno = 0;
_mm_critical = 0;
_mm_iobase_setcur(modreader);
+ #ifndef NO_DEPACKERS
+ if(ML_TryUnpack(modreader,&unpk,&newlen)) {
+ if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
+ modreader=reader;
+ MikMod_free(unpk);
+ return NULL;
+ }
+ }
+ #endif
+
/* Try to find a loader that recognizes the module */
for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader);
@@ -463,15 +525,31 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
if(!l) {
_mm_errno = MMERR_NOT_A_MODULE;
+ #ifndef NO_DEPACKERS
+ if(modreader!=reader) {
+ _mm_delete_mem_reader(modreader);
+ modreader=reader;
+ MikMod_free(unpk);
+ }
+ #endif
if(_mm_errorhandler) _mm_errorhandler();
- _mm_rewind(modreader);_mm_iobase_revert(modreader);
+ _mm_rewind(modreader);
+ _mm_iobase_revert(modreader);
return NULL;
}
/* init unitrk routines */
if(!UniInit()) {
+ #ifndef NO_DEPACKERS
+ if(modreader!=reader) {
+ _mm_delete_mem_reader(modreader);
+ modreader=reader;
+ MikMod_free(unpk);
+ }
+ #endif
if(_mm_errorhandler) _mm_errorhandler();
- _mm_rewind(modreader);_mm_iobase_revert(modreader);
+ _mm_rewind(modreader);
+ _mm_iobase_revert(modreader);
return NULL;
}
@@ -487,7 +565,7 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
if (!l->Init || l->Init()) {
_mm_rewind(modreader);
ok = l->Load(curious);
- if (ok) {
+ if (ok) {
/* propagate inflags=flags for in-module samples */
for (t = 0; t < of.numsmp; t++)
if (of.samples[t].inflags == 0)
@@ -500,27 +578,23 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
if (l->Cleanup) l->Cleanup();
UniCleanup();
+ if(ok) ok = ML_LoadSamples();
+ if(ok) ok = ((mf=ML_AllocUniMod()) != NULL);
if(!ok) {
ML_FreeEx(&of);
+ #ifndef NO_DEPACKERS
+ if(modreader!=reader) {
+ _mm_delete_mem_reader(modreader);
+ modreader=reader;
+ MikMod_free(unpk);
+ }
+ #endif
if(_mm_errorhandler) _mm_errorhandler();
- _mm_rewind(modreader);_mm_iobase_revert(modreader);
- return NULL;
- }
-
- if(!ML_LoadSamples()) {
- ML_FreeEx(&of);
- if(_mm_errorhandler) _mm_errorhandler();
- _mm_rewind(modreader);_mm_iobase_revert(modreader);
+ _mm_rewind(modreader);
+ _mm_iobase_revert(modreader);
return NULL;
}
- if(!(mf=ML_AllocUniMod())) {
- ML_FreeEx(&of);
- _mm_rewind(modreader);_mm_iobase_revert(modreader);
- if(_mm_errorhandler) _mm_errorhandler();
- return NULL;
- }
-
/* If the module doesn't have any specific panning, create a
MOD-like panning, with the channels half-separated. */
if (!(of.flags & UF_PANNING))
@@ -539,23 +613,25 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
if(maxchan<mf->numchn) mf->flags |= UF_NNA;
- if(MikMod_SetNumVoices_internal(maxchan,-1)) {
- _mm_iobase_revert(modreader);
- Player_Free(mf);
- return NULL;
- }
+ ok = !MikMod_SetNumVoices_internal(maxchan,-1);
}
- if(SL_LoadSamples()) {
- _mm_iobase_revert(modreader);
- Player_Free_internal(mf);
- return NULL;
+
+ if(ok) ok = !SL_LoadSamples();
+ if(ok) ok = !Player_Init(mf);
+
+ #ifndef NO_DEPACKERS
+ if(modreader!=reader) {
+ _mm_delete_mem_reader(modreader);
+ modreader=reader;
+ MikMod_free(unpk);
}
- if(Player_Init(mf)) {
- _mm_iobase_revert(modreader);
+ #endif
+ _mm_iobase_revert(modreader);
+
+ if(!ok) {
Player_Free_internal(mf);
- mf=NULL;
+ return NULL;
}
- _mm_iobase_revert(modreader);
return mf;
}
@@ -577,7 +653,8 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
MODULE* result=NULL;
MREADER* reader;
- if ((reader=_mm_new_mem_reader(buffer, len))) {
+ if (!buffer || len <= 0) return NULL;
+ if ((reader=_mm_new_mem_reader(buffer, len)) != NULL) {
result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_mem_reader(reader);
}
@@ -589,9 +666,9 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
{
MODULE* result=NULL;
- struct MREADER* reader=_mm_new_file_reader (fp);
+ struct MREADER* reader;
- if (reader) {
+ if (fp && (reader=_mm_new_file_reader(fp)) != NULL) {
result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_file_reader(reader);
}
@@ -600,12 +677,12 @@ MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
/* Open a module via its filename. The loader will initialize the specified
song-player 'player'. */
-MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious)
+MIKMODAPI MODULE* Player_Load(const CHAR* filename,int maxchan,int curious)
{
int fp;
MODULE *mf=NULL;
- if((fp=_mm_fopen(filename,"rb"))) {
+ if((fp=_mm_fopen(filename,"rb")) >= 0) {
mf=Player_LoadFP(fp,maxchan,curious);
_mm_fclose(fp);
}
diff --git a/apps/plugins/mikmod/mlreg.c b/apps/plugins/mikmod/mlreg.c
index c8850fb62f..10095d8157 100644
--- a/apps/plugins/mikmod/mlreg.c
+++ b/apps/plugins/mikmod/mlreg.c
@@ -40,7 +40,7 @@ static void MikMod_RegisterAllLoaders_internal(void)
_mm_registerloader(&load_dsm);
_mm_registerloader(&load_far);
_mm_registerloader(&load_gdm);
- _mm_registerloader(&load_gt2);
+/* _mm_registerloader(&load_gt2);*/ /* load_gt2 isn't complete */
_mm_registerloader(&load_it);
_mm_registerloader(&load_imf);
_mm_registerloader(&load_mod);
@@ -51,13 +51,14 @@ static void MikMod_RegisterAllLoaders_internal(void)
_mm_registerloader(&load_stm);
_mm_registerloader(&load_stx);
_mm_registerloader(&load_ult);
+ _mm_registerloader(&load_umx);
_mm_registerloader(&load_uni);
_mm_registerloader(&load_xm);
_mm_registerloader(&load_m15);
}
-void MikMod_RegisterAllLoaders(void)
+MIKMODAPI void MikMod_RegisterAllLoaders(void)
{
MUTEX_LOCK(lists);
MikMod_RegisterAllLoaders_internal();
diff --git a/apps/plugins/mikmod/mlutil.c b/apps/plugins/mikmod/mlutil.c
index ddaddc7871..328b1d4089 100644
--- a/apps/plugins/mikmod/mlutil.c
+++ b/apps/plugins/mikmod/mlutil.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: mlutil.c,v 1.3 2007/12/06 17:43:10 denis111 Exp $
+ $Id$
Utility functions for the module loader
@@ -43,13 +43,13 @@ extern int fprintf(FILE *, const char *, ...);
/*========== Shared tracker identifiers */
-CHAR *STM_Signatures[STM_NTRACKERS] = {
+const CHAR *STM_Signatures[STM_NTRACKERS] = {
"!Scream!",
"BMOD2STM",
"WUZAMOD!"
};
-CHAR *STM_Version[STM_NTRACKERS] = {
+const CHAR *STM_Version[STM_NTRACKERS] = {
"Screamtracker 2",
"Converted by MOD2STM (STM format)",
"Wuzamod (STM format)"
@@ -71,29 +71,27 @@ FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
/*========== Linear periods stuff */
int* noteindex=NULL; /* remap value for linear period modules */
-static int noteindexcount=0;
+static unsigned noteindexcount=0;
int *AllocLinear(void)
{
if(of.numsmp>noteindexcount) {
noteindexcount=of.numsmp;
- noteindex=MikMod_realloc(noteindex,noteindexcount*sizeof(int));
+ noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int));
}
return noteindex;
}
void FreeLinear(void)
{
- if(noteindex) {
- MikMod_free(noteindex);
- noteindex=NULL;
- }
+ MikMod_free(noteindex);
+ noteindex=NULL;
noteindexcount=0;
}
int speed_to_finetune(ULONG speed,int sample)
{
- ULONG ctmp=0,tmp,note=1,finetune=0;
+ ULONG ctmp=0,tmp,note=1,ft=0;
speed>>=1;
while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) {
@@ -104,16 +102,16 @@ int speed_to_finetune(ULONG speed,int sample)
if(tmp!=speed) {
if((tmp-speed)<(speed-ctmp))
while(tmp>speed)
- tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune));
+ tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft));
else {
note--;
while(ctmp<speed)
- ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune));
+ ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft));
}
}
noteindex[sample]=note-4*OCTAVE;
- return finetune;
+ return ft;
}
/*========== Order stuff */
@@ -141,13 +139,9 @@ void S3MIT_CreateOrders(int curious)
/*========== Effect stuff */
/* handles S3M and IT effects */
-void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
+void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags)
{
- UBYTE /* hi,*/ lo;
-
- lo=inf&0xf;
- /* hi=inf>>4; */
-
+ UBYTE lo = inf&0xF;
/* process S3M / IT specific command structure */
if(cmd!=255) {
@@ -196,7 +190,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
case 9: /* Ixy tremor, ontime x, offtime y */
if (flags & S3MIT_OLDSTYLE)
UniEffect(UNI_S3MEFFECTI,inf);
- else
+ else
UniEffect(UNI_ITEFFECTI,inf);
break;
case 0xa: /* Jxy arpeggio */
@@ -204,7 +198,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
break;
case 0xb: /* Kxy Dual command H00 & Dxy */
if (flags & S3MIT_OLDSTYLE)
- UniPTEffect(0x4,0);
+ UniPTEffect(0x4,0);
else
UniEffect(UNI_ITEFFECTH,0);
UniEffect(UNI_S3MEFFECTD,inf);
@@ -218,7 +212,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
break;
case 0xd: /* Mxx Set Channel Volume */
UniEffect(UNI_ITEFFECTM,inf);
- break;
+ break;
case 0xe: /* Nxy Slide Channel Volume */
UniEffect(UNI_ITEFFECTN,inf);
break;
@@ -233,7 +227,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
if(inf && !lo && !(flags & S3MIT_OLDSTYLE))
UniWriteByte(1);
else
- UniWriteByte(inf);
+ UniWriteByte(inf);
break;
case 0x12: /* Rxy tremolo speed x, depth y */
UniEffect(UNI_S3MEFFECTR,inf);
diff --git a/apps/plugins/mikmod/mmalloc.c b/apps/plugins/mikmod/mmalloc.c
index 2797def57d..ed5fd4684c 100644
--- a/apps/plugins/mikmod/mmalloc.c
+++ b/apps/plugins/mikmod/mmalloc.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: mmalloc.c,v 1.3 2007/12/03 20:42:58 denis111 Exp $
+ $Id$
Dynamic memory routines
@@ -30,150 +30,113 @@
#include "config.h"
#endif
-#include "mikmod_internals.h"
-
-#define ALIGN_STRIDE 16
-/* not used
-static void * align_pointer(char *ptr, size_t stride)
-{
- char *pptr = ptr + sizeof(void*);
- char *fptr;
- size_t err = ((size_t)pptr)&(stride-1);
- if (err)
- fptr = pptr + (stride - err);
- else
- fptr = pptr;
- *(size_t*)(fptr - sizeof(void*)) = (size_t)ptr;
- return fptr;
-}
+#ifdef HAVE_POSIX_MEMALIGN
+#define _XOPEN_SOURCE 600 /* for posix_memalign */
+#endif
-static void *get_pointer(void *data)
-{
- unsigned char *_pptr = (unsigned char*)data - sizeof(void*);
- size_t _ptr = *(size_t*)_pptr;
- return (void*)_ptr;
-}
-*/
+#include "string.h"
+#include "mikmod_internals.h"
-void* MikMod_realloc(void *data, size_t size)
-{
- return realloc(data, size);
-
-#if 0
- if (data)
- {
-#if defined __MACH__
- void *d = realloc(data, size);
- if (d)
- {
- return d;
- }
- return 0;
-#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
- return _aligned_realloc(data, size, ALIGN_STRIDE);
-#else
- unsigned char *newPtr = (unsigned char *)realloc(get_pointer(data), size + ALIGN_STRIDE + sizeof(void*));
- return align_pointer(newPtr, ALIGN_STRIDE);
+#if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
+#undef WIN32_ALIGNED_MALLOC
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+# if defined(_WIN64) /* OK with MSVC and MinGW */
+# define WIN32_ALIGNED_MALLOC
+# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define WIN32_ALIGNED_MALLOC
+# elif defined(__MINGW32__)
+ /* no guarantees that msvcrt.dll will have it */
+# endif
#endif
- }
- return MikMod_malloc(size);
-#endif
-}
+#define PTRSIZE (sizeof(void*))
-/* Same as malloc, but sets error variable _mm_error when fails. Returns a 16-byte aligned pointer */
-void* MikMod_malloc(size_t size)
+/* return a 16 byte aligned address */
+void* MikMod_amalloc(size_t size)
{
void *d;
- if(!(d=calloc(1,size))) {
- _mm_errno = MMERR_OUT_OF_MEMORY;
- if(_mm_errorhandler) _mm_errorhandler();
- }
- return d;
-
-#if 0
-#if defined __MACH__
- void *d = calloc(1, size);
- if (d)
- {
+#if defined(HAVE_POSIX_MEMALIGN)
+ if (!posix_memalign(&d, 16, size)) {
+ memset(d, 0, size);
return d;
}
- return 0;
-#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
- void * d = _aligned_malloc(size, ALIGN_STRIDE);
- if (d)
- {
+#elif defined(WIN32_ALIGNED_MALLOC)
+ d = _aligned_malloc(size, 16);
+ if (d) {
ZeroMemory(d, size);
return d;
}
- return 0;
#else
- void *d = calloc(1, size + ALIGN_STRIDE + sizeof(void*));
-
- if(!d) {
- _mm_errno = MMERR_OUT_OF_MEMORY;
- if(_mm_errorhandler) _mm_errorhandler();
+ size_t s = (size)? ((size + (PTRSIZE-1)) & ~(PTRSIZE-1)) : PTRSIZE;
+ s += PTRSIZE + 16;
+ d = calloc(1, s);
+ if (d) {
+ char *pptr = (char *)d + PTRSIZE;
+ size_t err = ((size_t)pptr) & 15;
+ char *fptr = pptr + (16 - err);
+ *(size_t*)(fptr - PTRSIZE) = (size_t)d;
+ return fptr;
}
- return align_pointer(d, ALIGN_STRIDE);
#endif
+
+ _mm_errno = MMERR_OUT_OF_MEMORY;
+ if(_mm_errorhandler) _mm_errorhandler();
+ return NULL;
+}
+
+void MikMod_afree(void *data)
+{
+ if (!data) return;
+#if defined(HAVE_POSIX_MEMALIGN)
+ free(data);
+#elif defined(WIN32_ALIGNED_MALLOC)
+ _aligned_free(data);
+#else
+ free((void *) *(size_t*)((unsigned char *)data - PTRSIZE));
#endif
}
+#endif /* (HAVE_SSE2) || (HAVE_ALTIVEC) */
+
+void* MikMod_realloc(void *data, size_t size)
+{
+ if (data) return realloc(data, size);
+ return calloc(1, size);
+}
+
+/* Same as malloc, but sets error variable _mm_error when fails */
+void* MikMod_malloc(size_t size)
+{
+ return MikMod_calloc(1, size);
+}
/* Same as calloc, but sets error variable _mm_error when fails */
-void* MikMod_calloc(size_t nitems,size_t size)
+void* MikMod_calloc(size_t nitems, size_t size)
{
- void *d;
-
- if(!(d=calloc(nitems,size))) {
- _mm_errno = MMERR_OUT_OF_MEMORY;
- if(_mm_errorhandler) _mm_errorhandler();
- }
- return d;
-
-#if 0
-#if defined __MACH__
void *d = calloc(nitems, size);
- if (d)
- {
- return d;
- }
- return 0;
-#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
- void * d = _aligned_malloc(size * nitems, ALIGN_STRIDE);
- if (d)
- {
- ZeroMemory(d, size * nitems);
- return d;
- }
- return 0;
-#else
- void *d = calloc(nitems, size + ALIGN_STRIDE + sizeof(void*));
-
- if(!d) {
- _mm_errno = MMERR_OUT_OF_MEMORY;
- if(_mm_errorhandler) _mm_errorhandler();
- }
- return align_pointer(d, ALIGN_STRIDE);
-#endif
-#endif
+ if (d) return d;
+
+ _mm_errno = MMERR_OUT_OF_MEMORY;
+ if(_mm_errorhandler) _mm_errorhandler();
+ return NULL;
}
void MikMod_free(void *data)
{
- free(data);
-
-#if 0
- if (data)
- {
-#if defined __MACH__
- free(data);
-#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
- _aligned_free(data);
-#else
- free(get_pointer(data));
-#endif
- }
-#endif
+ if (data) free(data);
+}
+
+/* like strdup(), but the result must be freed using MikMod_free() */
+CHAR *MikMod_strdup(const CHAR *s)
+{
+ size_t l;
+ CHAR *d;
+
+ if (!s) return NULL;
+
+ l = strlen(s) + 1;
+ d = (CHAR *) MikMod_calloc(1, l * sizeof(CHAR));
+ if (d) strcpy(d, s);
+ return d;
}
/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/mmerror.c b/apps/plugins/mikmod/mmerror.c
index ed7c66a10f..4d7949890e 100644
--- a/apps/plugins/mikmod/mmerror.c
+++ b/apps/plugins/mikmod/mmerror.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: mmerror.c,v 1.2 2005/03/30 19:10:41 realtech Exp $
+ $Id$
Error handling functions.
Register an error handler with _mm_RegisterErrorHandler() and you're all set.
@@ -40,7 +40,9 @@
#include "mikmod_internals.h"
-CHAR *_mm_errmsg[MMERR_MAX+1] =
+#define _mmerr_invalid "Invalid error code"
+
+static const char *_mm_errmsg[MMERR_MAX+1] =
{
/* No error */
@@ -82,62 +84,89 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Unable to set non-blocking mode for audio device",
/* AudioFile driver errors */
-
+#ifdef DRV_AF
"Cannot find suitable AudioFile audio port",
+#else
+ _mmerr_invalid,
+#endif
/* AIX driver errors */
-
+#ifdef DRV_AIX
"Configuration (init step) of audio device failed",
"Configuration (control step) of audio device failed",
"Configuration (start step) of audio device failed",
-
-/* ALSA driver errors */
-
-/* EsounD driver errors */
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+#endif
/* Ultrasound driver errors */
-
+#ifdef DRV_ULTRA
"Ultrasound driver only works in 16 bit stereo 44 KHz",
"Ultrasound card could not be reset",
"Could not start Ultrasound timer",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+#endif
/* HP driver errors */
-
+#ifdef DRV_HP
"Unable to select 16bit-linear sample format",
"Could not select requested sample-rate",
"Could not select requested number of channels",
"Unable to select audio output",
"Unable to get audio description",
"Could not set transmission buffer size",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+#endif
/* Open Sound System driver errors */
-
+#ifdef DRV_OSS
"Could not set fragment size",
"Could not set sample size",
"Could not set mono/stereo setting",
"Could not set sample rate",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid,
+#endif
/* SGI driver errors */
-
+#ifdef DRV_SGI
"Unsupported sample rate",
"Hardware does not support 16 bit sound",
"Hardware does not support 8 bit sound",
"Hardware does not support stereo sound",
"Hardware does not support mono sound",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid,
+#endif
/* Sun driver errors */
-
+#ifdef DRV_SUN
"Sound device initialization failed",
+#else
+ _mmerr_invalid,
+#endif
/* OS/2 drivers errors */
-
+#if defined(DRV_OS2) || defined(DRV_DART)
"Could not set mixing parameters",
+#else
+ _mmerr_invalid,
+#endif
+#ifdef DRV_OS2
"Could not create playback semaphores",
"Could not create playback timer",
"Could not create playback thread",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+#endif
/* DirectSound driver errors */
-
+#ifdef DRV_DS
"Could not set playback priority",
"Could not create playback buffers",
"Could not set playback format",
@@ -145,22 +174,34 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Could not register event",
"Could not create playback thread",
"Could not initialize playback thread",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid,
+#endif
/* Windows Multimedia API driver errors */
-
+#ifdef DRV_WIN
"Invalid device handle",
"The resource is already allocated",
"Invalid device identifier",
"Unsupported output format",
"Unknown error",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid,
+#endif
/* Macintosh driver errors */
-
+#ifdef DRV_MAC
"Unsupported sample rate",
"Could not start playback",
+#else
+ _mmerr_invalid, _mmerr_invalid,
+#endif
/* MacOS X/Darwin driver errors */
-
+#ifdef DRV_OSX
"Unknown device",
"Bad property",
"Could not set playback format",
@@ -169,20 +210,81 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Could not create playback thread",
"Could not start audio device",
"Could not create buffer thread",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid,
+#endif
/* DOS driver errors */
-
+#ifdef DRV_WSS
"WSS_STARTDMA",
+#else
+ _mmerr_invalid,
+#endif
+#ifdef DRV_SB
"SB_STARTDMA",
+#else
+ _mmerr_invalid,
+#endif
+
+/* float32 output */
+
+ "This driver doesn't support 32 bit float output",
+
+/* OpenAL driver errors */
+#ifdef DRV_OPENAL
+ "Could not create context",
+ "Could not make context current",
+ "Could not create buffers",
+ "Could not create sources",
+ "Could not change source parameters",
+ "Could not queue buffers",
+ "Could not unqueue buffers",
+ "Could not copy buffer data",
+ "Could not get source parameters",
+ "Could not play source",
+ "Could not stop source",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid,
+#endif
+
+/* ALSA driver errors */
+#ifdef DRV_ALSA
+ "No ALSA configurations available",
+ "Could not set ALSA output params",
+ "Could not set playback format",
+ "Could not set sample rate",
+ "Could not set mono/stereo setting",
+ "Could not get buffer size from ALSA",
+ "ALSA PCM start error",
+ "ALSA PCM write error",
+ "ALSA PCM recovery failure",
+#else
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
+#endif
+
+/* Sndio errors */
+#ifdef DRV_SNDIO
+ "Could not set SNDIO output params",
+ "Unsupported SNDIO output params",
+#else
+ _mmerr_invalid, _mmerr_invalid,
+#endif
/* Invalid error */
- "Invalid error code"
+ _mmerr_invalid
};
-MIKMODAPI char *MikMod_strerror(int code)
+MIKMODAPI const char *MikMod_strerror(int code)
{
- if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX+1;
+ if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX;
return _mm_errmsg[code];
}
diff --git a/apps/plugins/mikmod/mmio.c b/apps/plugins/mikmod/mmio.c
index 0ffecffd2f..023c56baef 100644
--- a/apps/plugins/mikmod/mmio.c
+++ b/apps/plugins/mikmod/mmio.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,8 +20,6 @@
/*==============================================================================
- $Id: mmio.c,v 1.3 2005/03/30 19:10:58 realtech Exp $
-
Portable file I/O routines
==============================================================================*/
@@ -51,10 +49,14 @@
#include <unistd.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
#include <stdio.h>
#include <string.h>
+#include <limits.h>
-#include "mikmod.h"
#include "mikmod_internals.h"
#ifdef SUNOS
@@ -66,8 +68,6 @@ extern int fseek(FILE *, long, int);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
#endif
-#define COPY_BUFSIZE 1024
-
/* some prototypes */
static int _mm_MemReader_Eof(MREADER* reader);
static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
@@ -75,16 +75,13 @@ static int _mm_MemReader_Get(MREADER* reader);
static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
static long _mm_MemReader_Tell(MREADER* reader);
-//static long _mm_iobase=0,temp_iobase=0;
-
-int _mm_fopen(CHAR* fname,CHAR* attrib)
+int _mm_fopen(const CHAR* fname, const CHAR* attrib)
{
int fp;
- (void)attrib;
-
+ (void)attrib;
//if(!(fp=fopen(fname,attrib))) {
- // _mm_errno = MMERR_OPENING_FILE;
- // if(_mm_errorhandler) _mm_errorhandler();
+ // _mm_errno = MMERR_OPENING_FILE;
+ // if(_mm_errorhandler) _mm_errorhandler();
//}
fp = open(fname, O_RDONLY);
if( fp < 0 ) {
@@ -94,7 +91,7 @@ int _mm_fopen(CHAR* fname,CHAR* attrib)
return fp;
}
-int _mm_FileExists(CHAR* fname)
+int _mm_FileExists(const CHAR* fname)
{
int fp;
@@ -103,7 +100,7 @@ int _mm_FileExists(CHAR* fname)
fp = open(fname, O_RDONLY);
if ( fp < 0 ) return 0;
close(fp);
-
+
return 1;
}
@@ -130,12 +127,12 @@ void _mm_iobase_revert(MREADER* reader)
typedef struct MFILEREADER {
MREADER core;
- int file;
+ int file;
} MFILEREADER;
static int _mm_FileReader_Eof(MREADER* reader)
{
- //return feof(((MFILEREADER*)reader)->file);
+ //return feof(((MFILEREADER*)reader)->file);
int size = filesize(((MFILEREADER*)reader)->file);
int offset = lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR);
return (size <= 0 || offset < 0 || offset >= size) ? 1 : 0;
@@ -143,8 +140,8 @@ static int _mm_FileReader_Eof(MREADER* reader)
static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size)
{
- //return !!fread(ptr,size,1,((MFILEREADER*)reader)->file);
return read(((MFILEREADER*)reader)->file, ptr, size);
+ //return !!fread(ptr,size,1,((MFILEREADER*)reader)->file);
}
static int _mm_FileReader_Get(MREADER* reader)
@@ -160,7 +157,7 @@ static int _mm_FileReader_Get(MREADER* reader)
static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence)
{
//return fseek(((MFILEREADER*)reader)->file,
- // (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
+ // (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
return lseek(((MFILEREADER*)reader)->file,
(whence==SEEK_SET)?offset+reader->iobase:offset,whence);
}
@@ -173,7 +170,7 @@ static long _mm_FileReader_Tell(MREADER* reader)
MREADER *_mm_new_file_reader(int fp)
{
- MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER));
+ MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER));
if (reader) {
reader->core.Eof =&_mm_FileReader_Eof;
reader->core.Read=&_mm_FileReader_Read;
@@ -187,14 +184,14 @@ MREADER *_mm_new_file_reader(int fp)
void _mm_delete_file_reader (MREADER* reader)
{
- if(reader) MikMod_free(reader);
+ MikMod_free(reader);
}
/*========== File Writer */
typedef struct MFILEWRITER {
MWRITER core;
- int file;
+ int file;
} MFILEWRITER;
static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)
@@ -209,27 +206,26 @@ static long _mm_FileWriter_Tell(MWRITER* writer)
return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR);
}
-static int _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size)
+static int _mm_FileWriter_Write(MWRITER* writer, const void* ptr, size_t size)
{
//return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size);
- //return (write(ptr,size,((MFILEWRITER*)writer)->file)==(int)size);
- (void)writer;
- (void)ptr;
- (void)size;
- return 0;
+ (void)writer;
+ (void)ptr;
+ (void)size;
+ return 0;
}
static int _mm_FileWriter_Put(MWRITER* writer,int value)
{
- (void)writer;
- (void)value;
+ (void)writer;
+ (void)value;
//return fputc(value,((MFILEWRITER*)writer)->file);
- return 1; // TODO
+ return 1; // TODO
}
MWRITER *_mm_new_file_writer(int fp)
{
- MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER));
+ MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER));
if (writer) {
writer->core.Seek =&_mm_FileWriter_Seek;
writer->core.Tell =&_mm_FileWriter_Tell;
@@ -242,12 +238,11 @@ MWRITER *_mm_new_file_writer(int fp)
void _mm_delete_file_writer (MWRITER* writer)
{
- if(writer) MikMod_free (writer);
+ MikMod_free (writer);
}
/*========== Memory Reader */
-
typedef struct MMEMREADER {
MREADER core;
const void *buffer;
@@ -257,12 +252,12 @@ typedef struct MMEMREADER {
void _mm_delete_mem_reader(MREADER* reader)
{
- if (reader) { MikMod_free(reader); }
+ MikMod_free(reader);
}
-MREADER *_mm_new_mem_reader(const void *buffer, int len)
+MREADER *_mm_new_mem_reader(const void *buffer, long len)
{
- MMEMREADER* reader=(MMEMREADER*)MikMod_malloc(sizeof(MMEMREADER));
+ MMEMREADER* reader=(MMEMREADER*)MikMod_calloc(1,sizeof(MMEMREADER));
if (reader)
{
reader->core.Eof =&_mm_MemReader_Eof;
@@ -279,74 +274,86 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len)
static int _mm_MemReader_Eof(MREADER* reader)
{
- if (!reader) { return 1; }
- if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
- return 1;
- }
+ MMEMREADER* mr = (MMEMREADER*) reader;
+ if (!mr) return 1;
+ if (mr->pos >= mr->len) return 1;
return 0;
}
static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
{
- unsigned char *d=ptr;
+ unsigned char *d;
const unsigned char *s;
-
- if (!reader) { return 0; }
-
- if (reader->Eof(reader)) { return 0; }
-
- s = ((MMEMREADER*)reader)->buffer;
- s += ((MMEMREADER*)reader)->pos;
-
- if ( ((MMEMREADER*)reader)->pos + (long)size > ((MMEMREADER*)reader)->len)
- {
- ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
- return 0; /* not enough remaining bytes */
+ MMEMREADER* mr;
+ long siz;
+ int ret;
+
+ if (!reader || !size || (size > (size_t) LONG_MAX))
+ return 0;
+
+ mr = (MMEMREADER*) reader;
+ siz = (long) size;
+ if (mr->pos >= mr->len) return 0; /* @ eof */
+ if (mr->pos + siz > mr->len) {
+ siz = mr->len - mr->pos;
+ ret = 0; /* not enough remaining bytes */
+ }
+ else {
+ ret = 1;
}
- ((MMEMREADER*)reader)->pos += (long)size;
+ s = (const unsigned char *) mr->buffer;
+ s += mr->pos;
+ mr->pos += siz;
+ d = (unsigned char *) ptr;
- while (size--)
- {
- *d = *s;
- s++;
- d++;
+ while (siz) {
+ *d++ = *s++;
+ siz--;
}
-
- return 1;
+
+ return ret;
}
static int _mm_MemReader_Get(MREADER* reader)
{
- int pos;
+ MMEMREADER* mr;
+ int c;
- if (reader->Eof(reader)) { return 0; }
-
- pos = ((MMEMREADER*)reader)->pos;
- ((MMEMREADER*)reader)->pos++;
+ mr = (MMEMREADER*) reader;
+ if (mr->pos >= mr->len) return EOF;
+ c = ((const unsigned char*) mr->buffer)[mr->pos];
+ mr->pos++;
- return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos];
+ return c;
}
static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
{
- if (!reader) { return -1; }
-
+ MMEMREADER* mr;
+
+ if (!reader) return -1;
+ mr = (MMEMREADER*) reader;
switch(whence)
{
- case SEEK_CUR:
- ((MMEMREADER*)reader)->pos += offset;
- break;
- case SEEK_SET:
- ((MMEMREADER*)reader)->pos = offset;
- break;
- case SEEK_END:
- ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1;
- break;
+ case SEEK_CUR:
+ mr->pos += offset;
+ break;
+ case SEEK_SET:
+ mr->pos = reader->iobase + offset;
+ break;
+ case SEEK_END:
+ mr->pos = mr->len + offset;
+ break;
+ default: /* invalid */
+ return -1;
}
- if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; }
- if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
- ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
+ if (mr->pos < reader->iobase) {
+ mr->pos = mr->core.iobase;
+ return -1;
+ }
+ if (mr->pos > mr->len) {
+ mr->pos = mr->len;
}
return 0;
}
@@ -354,13 +361,14 @@ static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
static long _mm_MemReader_Tell(MREADER* reader)
{
if (reader) {
- return ((MMEMREADER*)reader)->pos;
+ return ((MMEMREADER*)reader)->pos - reader->iobase;
}
return 0;
}
/*========== Write functions */
-void _mm_write_string(CHAR* data,MWRITER* writer)
+
+void _mm_write_string(const CHAR* data,MWRITER* writer)
{
if(data)
_mm_write_UBYTES(data,strlen(data),writer);
@@ -410,37 +418,51 @@ void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
_mm_write_I_ULONG((ULONG)data,writer);
}
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
-#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
-void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \
-{ \
- while(number-->0) \
- _mm_write_##type_name(*(buffer++),writer); \
+void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer);
}
-#else
-#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
-void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \
-{ \
- while(number-->0) \
- _mm_write_/**/type_name(*(buffer++),writer); \
+
+void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer);
}
-#endif
-DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)
-DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)
-DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)
-DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)
+void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
+}
-DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)
-DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)
-DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)
-DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)
+void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
+}
+
+void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer);
+}
+
+void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer);
+}
+
+void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer);
+}
+
+void _mm_write_I_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
+{
+ while(cnt-- > 0) _mm_write_I_ULONG(*(buffer++),writer);
+}
/*========== Read functions */
-int _mm_read_string(CHAR* buffer,int number,MREADER* reader)
+int _mm_read_string(CHAR* buffer,int cnt,MREADER* reader)
{
- return reader->Read(reader,buffer,number);
+ return reader->Read(reader,buffer,cnt);
}
UWORD _mm_read_M_UWORD(MREADER* reader)
@@ -491,32 +513,52 @@ SLONG _mm_read_I_SLONG(MREADER* reader)
return((SLONG)_mm_read_I_ULONG(reader));
}
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
-#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
-int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \
-{ \
- while(number-->0) \
- *(buffer++)=_mm_read_##type_name(reader); \
- return !reader->Eof(reader); \
+int _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader);
+ return !reader->Eof(reader);
}
-#else
-#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
-int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \
-{ \
- while(number-->0) \
- *(buffer++)=_mm_read_/**/type_name(reader); \
- return !reader->Eof(reader); \
+
+int _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader);
+ return !reader->Eof(reader);
}
-#endif
-DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)
-DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)
-DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)
-DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)
+int _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
+ return !reader->Eof(reader);
+}
+
+int _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader);
+ return !reader->Eof(reader);
+}
+
+int _mm_read_M_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_M_SLONG(reader);
+ return !reader->Eof(reader);
+}
-DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)
-DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)
-DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)
-DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)
+int _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader);
+ return !reader->Eof(reader);
+}
+
+int _mm_read_I_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_I_SLONG(reader);
+ return !reader->Eof(reader);
+}
+
+int _mm_read_I_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
+{
+ while(cnt-- > 0) *(buffer++)=_mm_read_I_ULONG(reader);
+ return !reader->Eof(reader);
+}
/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/mplayer.c b/apps/plugins/mikmod/mplayer.c
index 88d6a81af4..ee5c2d187e 100644
--- a/apps/plugins/mikmod/mplayer.c
+++ b/apps/plugins/mikmod/mplayer.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: mplayer.c,v 1.4 2006/08/08 00:06:31 realtech Exp $
+ $Id$
The Protracker Player Driver
@@ -40,31 +40,35 @@
#include <stdlib.h>
#endif
+#include <limits.h>
+
#include "mikmod_internals.h"
#ifdef SUNOS
-extern int fprintf(FILE *, const char *, ...);
+extern int fprintf(int, const char *, ...);
extern long int random(void);
#endif
/* The currently playing module */
MODULE *pf = NULL;
+#define NUMVOICES(mod) (md_sngchn < (mod)->numvoices ? md_sngchn : (mod)->numvoices)
+
#define HIGH_OCTAVE 2 /* number of above-range octaves */
-static UWORD oldperiods[OCTAVE*2]={
+static const UWORD oldperiods[OCTAVE*2]={
0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80,
0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0,
0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160,
0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700
};
-static UBYTE VibratoTable[32]={
+static const UBYTE VibratoTable[32]={
0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253,
255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24
};
-static UBYTE avibtab[128]={
+static const UBYTE avibtab[128]={
0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23,
24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44,
45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58,
@@ -76,7 +80,7 @@ static UBYTE avibtab[128]={
};
/* Triton's linear periods to frequency translation table (for XM modules) */
-static ULONG lintab[768]={
+static const ULONG lintab[768]={
535232,534749,534266,533784,533303,532822,532341,531861,
531381,530902,530423,529944,529466,528988,528511,528034,
527558,527082,526607,526131,525657,525183,524709,524236,
@@ -176,7 +180,7 @@ static ULONG lintab[768]={
};
#define LOGFAC 2*16
-static UWORD logtab[104]={
+static const UWORD logtab[104]={
LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887,
LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862,
LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838,
@@ -205,7 +209,7 @@ static UWORD logtab[104]={
LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431
};
-static SBYTE PanbrelloTable[256]={
+static const SBYTE PanbrelloTable[256]={
0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
@@ -225,12 +229,12 @@ static SBYTE PanbrelloTable[256]={
};
/* returns a random value between 0 and ceil-1, ceil must be a power of two */
-static int getrandom(int ceil)
+static int getrandom(int ceilval)
{
-#ifdef HAVE_SRANDOM
- return random()&(ceil-1);
+#if defined(HAVE_SRANDOM) && !defined(_MIKMOD_AMIGA)
+ return random()&(ceilval-1);
#else
- return (rand()*ceil)/(RAND_MAX+1.0);
+ return (rand()*ceilval)/(RAND_MAX+1.0);
#endif
}
@@ -246,14 +250,14 @@ static int MP_FindEmptyChannel(MODULE *mod)
MP_VOICE *a;
ULONG t,k,tvol,pp;
- for (t=0;t<md_sngchn;t++)
+ for (t=0;t<NUMVOICES(mod);t++)
if (((mod->voice[t].main.kick==KICK_ABSENT)||
(mod->voice[t].main.kick==KICK_ENV))&&
Voice_Stopped_internal(t))
return t;
tvol=0xffffffUL;t=-1;a=mod->voice;
- for (k=0;k<md_sngchn;k++,a++) {
+ for (k=0;k<NUMVOICES(mod);k++,a++) {
/* allow us to take over a nonexisting sample */
if (!a->main.s)
return k;
@@ -325,9 +329,9 @@ static UWORD GetPeriod(UWORD flags, UWORD note, ULONG speed)
{
if (flags & UF_XMPERIODS) {
if (flags & UF_LINEAR)
- return getlinearperiod(note, speed);
+ return getlinearperiod(note, speed);
else
- return getlogperiod(note, speed);
+ return getlogperiod(note, speed);
} else
return getoldperiod(note, speed);
}
@@ -359,9 +363,15 @@ static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susen
t->a=0;
t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1;
+ if (!t->pts) { /* FIXME: bad/crafted file. better/more general solution? */
+ t->b=0;
+ return t->env[0].val;
+ }
+
/* Imago Orpheus sometimes stores an extra initial point in the envelope */
if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) {
- t->a++;t->b++;
+ t->a++;
+ t->b++;
}
/* Fit in the envelope, still */
@@ -615,10 +625,10 @@ static void DoToneSlide(UWORD tick, MP_CONTROL *a)
/* ...make tmpperiod equal tperiod */
a->tmpperiod=a->main.period=a->wantedperiod;
else if (dist>0) {
- a->tmpperiod-=a->portspeed;
+ a->tmpperiod-=a->portspeed;
a->main.period-=a->portspeed; /* dist>0, slide up */
} else {
- a->tmpperiod+=a->portspeed;
+ a->tmpperiod+=a->portspeed;
a->main.period+=a->portspeed; /* dist<0, slide down */
}
} else
@@ -786,8 +796,8 @@ static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)tick;
- (void)flags;
+ (void)tick;
+ (void)flags;
dat = UniGetByte();
if (mod->panflag)
@@ -799,16 +809,16 @@ static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)flags;
- (void)mod;
- (void)channel;
+ (void)flags;
+ (void)mod;
+ (void)channel;
dat=UniGetByte();
if (!tick) {
if (dat) a->soffset=(UWORD)dat<<8;
a->main.start=a->hioffset|a->soffset;
- if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
+ if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
a->main.s->loopstart:a->main.s->length;
}
@@ -819,9 +829,9 @@ static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)flags;
- (void)mod;
- (void)channel;
+ (void)flags;
+ (void)mod;
+ (void)channel;
dat=UniGetByte();
if (tick)
@@ -842,14 +852,19 @@ static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)a;
- (void)channel;
+ (void)a;
+ (void)channel;
dat=UniGetByte();
if (tick || mod->patdly2)
return 0;
+ if (dat >= mod->numpos) { /* crafted file? */
+ /* fprintf(stderr,"DoPTEffectB: numpos=%d, dat=%d -> %d\n",mod->numpos,dat,mod->numpos-1);*/
+ dat=mod->numpos-1;
+ }
+
/* Vincent Voois uses a nasty trick in "Universal Bolero" */
if (dat == mod->sngpos && mod->patbrk == mod->patpos)
return 0;
@@ -857,8 +872,8 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
if (!mod->loop && !mod->patbrk &&
(dat < mod->sngpos ||
(mod->sngpos == (mod->numpos - 1) && !mod->patbrk) ||
- (dat == mod->sngpos && (flags & UF_NOWRAP))
- )) {
+ (dat == mod->sngpos && (flags & UF_NOWRAP)) ) )
+ {
/* if we don't loop, better not to skip the end of the
pattern, after all... so:
mod->patbrk=0; */
@@ -870,6 +885,9 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
mod->sngpos=dat;
mod->posjmp=2;
mod->patpos=0;
+ /* cancel the FT2 pattern loop (E60) bug.
+ * also see DoEEffects() below for it. */
+ if (flags & UF_FT2QUIRKS) mod->patbrk=0;
}
return 0;
@@ -878,15 +896,15 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)flags;
- (void)mod;
- (void)channel;
+ (void)flags;
+ (void)mod;
+ (void)channel;
- dat=UniGetByte();
- if (tick) return 0;
- if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
- else if (dat>64) dat=64;
- a->tmpvolume=dat;
+ dat=UniGetByte();
+ if (tick) return 0;
+ if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
+ else if (dat>64) dat=64;
+ a->tmpvolume=dat;
return 0;
}
@@ -894,29 +912,33 @@ static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE dat;
- (void)a;
- (void)channel;
+ (void)a;
+ (void)channel;
- dat=UniGetByte();
- if ((tick)||(mod->patdly2)) return 0;
- if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&&
- (dat>mod->pattrows[mod->positions[mod->sngpos]]))
- dat=mod->pattrows[mod->positions[mod->sngpos]];
- mod->patbrk=dat;
- if (!mod->posjmp) {
- /* don't ask me to explain this code - it makes
- backwards.s3m and children.xm (heretic's version) play
- correctly, among others. Take that for granted, or write
- the page of comments yourself... you might need some
- aspirin - Miod */
- if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)||
- (mod->positions[mod->sngpos]==(mod->numpat-1)
- && !(flags&UF_NOWRAP)))) {
- mod->sngpos=0;
- mod->posjmp=2;
- } else
- mod->posjmp=3;
- }
+ dat=UniGetByte();
+ if ((tick)||(mod->patdly2)) return 0;
+ if (dat && dat >= mod->numrow) { /* crafted file? */
+ /* fprintf(stderr,"DoPTEffectD: numrow=%d, dat=%d -> 0\n",mod->numrow,dat);*/
+ dat=0;
+ }
+ if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&&
+ (dat>mod->pattrows[mod->positions[mod->sngpos]])) {
+ dat=mod->pattrows[mod->positions[mod->sngpos]];
+ }
+ mod->patbrk=dat;
+ if (!mod->posjmp) {
+ /* don't ask me to explain this code - it makes
+ backwards.s3m and children.xm (heretic's version) play
+ correctly, among others. Take that for granted, or write
+ the page of comments yourself... you might need some
+ aspirin - Miod */
+ if ((mod->sngpos==mod->numpos-1)&&(dat)&&
+ ((mod->loop) || (mod->positions[mod->sngpos]==(mod->numpat-1) && !(flags&UF_NOWRAP)))) {
+ mod->sngpos=0;
+ mod->posjmp=2;
+ } else
+ mod->posjmp=3;
+ }
return 0;
}
@@ -982,8 +1004,13 @@ static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod,
} else
mod->patpos=a->pat_reppos;
} else a->pat_reppos=POS_NONE;
- } else
+ } else {
a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */
+ /* emulate the FT2 pattern loop (E60) bug:
+ * http://milkytracker.org/docs/MilkyTracker.html#fxE6x
+ * roadblas.xm plays correctly with this. */
+ if (flags & UF_FT2QUIRKS) mod->patbrk=mod->patpos;
+ }
break;
case 0x7: /* set tremolo waveform */
a->wavecontrol&=0x0f;
@@ -1065,7 +1092,7 @@ static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
if (tick||mod->patdly2) return 0;
if (mod->extspd&&(dat>=mod->bpmlimit))
mod->bpm=dat;
- else
+ else
if (dat) {
mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat;
mod->vbtick=0;
@@ -1465,7 +1492,7 @@ static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
a->s3mvolslide = inf;
else
inf = a->s3mvolslide;
-
+
if (tick) {
lo=inf&0xf;
hi=inf>>4;
@@ -1608,7 +1635,7 @@ static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
INSTRUMENT *i=a->main.i;
MP_VOICE *aout;
- if ((aout=a->slave)) {
+ if ((aout=a->slave) != NULL) {
if (aout->venv.env) {
points=i->volenv[i->volpts-1].pos;
aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos;
@@ -1710,7 +1737,7 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
/* if we don't come from another note, ignore the slide and play the note
as is */
if (!a->oldnote || !a->main.period)
- return;
+ return;
if ((!tick)&&(a->newsamp)){
a->main.kick=KICK_NOTE;
@@ -1725,15 +1752,15 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
difference between those two values */
dist=a->main.period-a->wantedperiod;
- /* if they are equal or if portamentospeed is too big... */
+ /* if they are equal or if portamentospeed is too big... */
if ((!dist)||((a->portspeed<<2)>abs(dist)))
/* ... make tmpperiod equal tperiod */
a->tmpperiod=a->main.period=a->wantedperiod;
else
- if (dist>0) {
+ if (dist>0) {
a->tmpperiod-=a->portspeed<<2;
a->main.period-=a->portspeed<<2; /* dist>0 slide up */
- } else {
+ } else {
a->tmpperiod+=a->portspeed<<2;
a->main.period+=a->portspeed<<2; /* dist<0 slide down */
}
@@ -1762,7 +1789,7 @@ static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat)
if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
}
if (!a->main.period)
- return;
+ return;
q=(a->vibpos>>2)&0x1f;
@@ -1867,7 +1894,7 @@ static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
lo=inf&0xf;
hi=inf>>4;
- if (!hi)
+ if (!hi)
a->main.chanvol-=lo;
else
if (!lo) {
@@ -2105,13 +2132,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
switch (c) {
case SS_GLISSANDO: /* S1x set glissando voice */
DoEEffects(tick, flags, a, mod, channel, 0x30|inf);
- break;
+ break;
case SS_FINETUNE: /* S2x set finetune */
DoEEffects(tick, flags, a, mod, channel, 0x50|inf);
break;
case SS_VIBWAVE: /* S3x set vibrato waveform */
DoEEffects(tick, flags, a, mod, channel, 0x40|inf);
- break;
+ break;
case SS_TREMWAVE: /* S4x set tremolo waveform */
DoEEffects(tick, flags, a, mod, channel, 0x70|inf);
break;
@@ -2130,13 +2157,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
case SS_SURROUND: /* S9x set surround sound */
if (mod->panflag)
a->main.panning = mod->panning[channel] = PAN_SURROUND;
- break;
+ break;
case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */
if (!tick) {
a->hioffset=inf<<16;
a->main.start=a->hioffset|a->soffset;
- if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
+ if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
a->main.s->loopstart:a->main.s->length;
}
@@ -2168,10 +2195,10 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UBYTE c, inf;
- (void)channel;
-
- c = UniGetByte();
- inf = UniGetByte();
+ (void)channel;
+
+ c = UniGetByte();
+ inf = UniGetByte();
if ((!c)&&(!inf)) {
c=a->voleffect;
@@ -2219,16 +2246,16 @@ static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{
UWORD offset=UniGetWord();
- (void)tick;
- (void)flags;
- (void)mod;
- (void)channel;
+ (void)tick;
+ (void)flags;
+ (void)mod;
+ (void)channel;
if (offset)
a->ultoffset=offset;
a->main.start=a->ultoffset<<2;
- if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
+ if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
a->main.s->loopstart:a->main.s->length;
@@ -2310,68 +2337,68 @@ static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD
typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD);
static effect_func effects[UNI_LAST] = {
- DoNothing, /* 0 */
- DoNothing, /* UNI_NOTE */
- DoNothing, /* UNI_INSTRUMENT */
- DoPTEffect0, /* UNI_PTEFFECT0 */
- DoPTEffect1, /* UNI_PTEFFECT1 */
- DoPTEffect2, /* UNI_PTEFFECT2 */
- DoPTEffect3, /* UNI_PTEFFECT3 */
- DoPTEffect4, /* UNI_PTEFFECT4 */
- DoPTEffect5, /* UNI_PTEFFECT5 */
- DoPTEffect6, /* UNI_PTEFFECT6 */
- DoPTEffect7, /* UNI_PTEFFECT7 */
- DoPTEffect8, /* UNI_PTEFFECT8 */
- DoPTEffect9, /* UNI_PTEFFECT9 */
- DoPTEffectA, /* UNI_PTEFFECTA */
- DoPTEffectB, /* UNI_PTEFFECTB */
- DoPTEffectC, /* UNI_PTEFFECTC */
- DoPTEffectD, /* UNI_PTEFFECTD */
- DoPTEffectE, /* UNI_PTEFFECTE */
- DoPTEffectF, /* UNI_PTEFFECTF */
- DoS3MEffectA, /* UNI_S3MEFFECTA */
- DoS3MEffectD, /* UNI_S3MEFFECTD */
- DoS3MEffectE, /* UNI_S3MEFFECTE */
- DoS3MEffectF, /* UNI_S3MEFFECTF */
- DoS3MEffectI, /* UNI_S3MEFFECTI */
- DoS3MEffectQ, /* UNI_S3MEFFECTQ */
- DoS3MEffectR, /* UNI_S3MEFFECTR */
- DoS3MEffectT, /* UNI_S3MEFFECTT */
- DoS3MEffectU, /* UNI_S3MEFFECTU */
- DoKeyOff, /* UNI_KEYOFF */
- DoKeyFade, /* UNI_KEYFADE */
- DoVolEffects, /* UNI_VOLEFFECTS */
- DoPTEffect4, /* UNI_XMEFFECT4 */
- DoXMEffect6, /* UNI_XMEFFECT6 */
- DoXMEffectA, /* UNI_XMEFFECTA */
- DoXMEffectE1, /* UNI_XMEFFECTE1 */
- DoXMEffectE2, /* UNI_XMEFFECTE2 */
- DoXMEffectEA, /* UNI_XMEFFECTEA */
- DoXMEffectEB, /* UNI_XMEFFECTEB */
- DoXMEffectG, /* UNI_XMEFFECTG */
- DoXMEffectH, /* UNI_XMEFFECTH */
- DoXMEffectL, /* UNI_XMEFFECTL */
- DoXMEffectP, /* UNI_XMEFFECTP */
- DoXMEffectX1, /* UNI_XMEFFECTX1 */
- DoXMEffectX2, /* UNI_XMEFFECTX2 */
- DoITEffectG, /* UNI_ITEFFECTG */
- DoITEffectH, /* UNI_ITEFFECTH */
- DoITEffectI, /* UNI_ITEFFECTI */
- DoITEffectM, /* UNI_ITEFFECTM */
- DoITEffectN, /* UNI_ITEFFECTN */
- DoITEffectP, /* UNI_ITEFFECTP */
- DoITEffectT, /* UNI_ITEFFECTT */
- DoITEffectU, /* UNI_ITEFFECTU */
- DoITEffectW, /* UNI_ITEFFECTW */
- DoITEffectY, /* UNI_ITEFFECTY */
- DoNothing, /* UNI_ITEFFECTZ */
- DoITEffectS0, /* UNI_ITEFFECTS0 */
- DoULTEffect9, /* UNI_ULTEFFECT9 */
- DoMEDSpeed, /* UNI_MEDSPEED */
- DoMEDEffectF1, /* UNI_MEDEFFECTF1 */
- DoMEDEffectF2, /* UNI_MEDEFFECTF2 */
- DoMEDEffectF3, /* UNI_MEDEFFECTF3 */
- DoOktArp, /* UNI_OKTARP */
+ DoNothing, /* 0 */
+ DoNothing, /* UNI_NOTE */
+ DoNothing, /* UNI_INSTRUMENT */
+ DoPTEffect0, /* UNI_PTEFFECT0 */
+ DoPTEffect1, /* UNI_PTEFFECT1 */
+ DoPTEffect2, /* UNI_PTEFFECT2 */
+ DoPTEffect3, /* UNI_PTEFFECT3 */
+ DoPTEffect4, /* UNI_PTEFFECT4 */
+ DoPTEffect5, /* UNI_PTEFFECT5 */
+ DoPTEffect6, /* UNI_PTEFFECT6 */
+ DoPTEffect7, /* UNI_PTEFFECT7 */
+ DoPTEffect8, /* UNI_PTEFFECT8 */
+ DoPTEffect9, /* UNI_PTEFFECT9 */
+ DoPTEffectA, /* UNI_PTEFFECTA */
+ DoPTEffectB, /* UNI_PTEFFECTB */
+ DoPTEffectC, /* UNI_PTEFFECTC */
+ DoPTEffectD, /* UNI_PTEFFECTD */
+ DoPTEffectE, /* UNI_PTEFFECTE */
+ DoPTEffectF, /* UNI_PTEFFECTF */
+ DoS3MEffectA, /* UNI_S3MEFFECTA */
+ DoS3MEffectD, /* UNI_S3MEFFECTD */
+ DoS3MEffectE, /* UNI_S3MEFFECTE */
+ DoS3MEffectF, /* UNI_S3MEFFECTF */
+ DoS3MEffectI, /* UNI_S3MEFFECTI */
+ DoS3MEffectQ, /* UNI_S3MEFFECTQ */
+ DoS3MEffectR, /* UNI_S3MEFFECTR */
+ DoS3MEffectT, /* UNI_S3MEFFECTT */
+ DoS3MEffectU, /* UNI_S3MEFFECTU */
+ DoKeyOff, /* UNI_KEYOFF */
+ DoKeyFade, /* UNI_KEYFADE */
+ DoVolEffects, /* UNI_VOLEFFECTS */
+ DoPTEffect4, /* UNI_XMEFFECT4 */
+ DoXMEffect6, /* UNI_XMEFFECT6 */
+ DoXMEffectA, /* UNI_XMEFFECTA */
+ DoXMEffectE1, /* UNI_XMEFFECTE1 */
+ DoXMEffectE2, /* UNI_XMEFFECTE2 */
+ DoXMEffectEA, /* UNI_XMEFFECTEA */
+ DoXMEffectEB, /* UNI_XMEFFECTEB */
+ DoXMEffectG, /* UNI_XMEFFECTG */
+ DoXMEffectH, /* UNI_XMEFFECTH */
+ DoXMEffectL, /* UNI_XMEFFECTL */
+ DoXMEffectP, /* UNI_XMEFFECTP */
+ DoXMEffectX1, /* UNI_XMEFFECTX1 */
+ DoXMEffectX2, /* UNI_XMEFFECTX2 */
+ DoITEffectG, /* UNI_ITEFFECTG */
+ DoITEffectH, /* UNI_ITEFFECTH */
+ DoITEffectI, /* UNI_ITEFFECTI */
+ DoITEffectM, /* UNI_ITEFFECTM */
+ DoITEffectN, /* UNI_ITEFFECTN */
+ DoITEffectP, /* UNI_ITEFFECTP */
+ DoITEffectT, /* UNI_ITEFFECTT */
+ DoITEffectU, /* UNI_ITEFFECTU */
+ DoITEffectW, /* UNI_ITEFFECTW */
+ DoITEffectY, /* UNI_ITEFFECTY */
+ DoNothing, /* UNI_ITEFFECTZ */
+ DoITEffectS0, /* UNI_ITEFFECTS0 */
+ DoULTEffect9, /* UNI_ULTEFFECT9 */
+ DoMEDSpeed, /* UNI_MEDSPEED */
+ DoMEDEffectF1, /* UNI_MEDEFFECTF1 */
+ DoMEDEffectF2, /* UNI_MEDEFFECTF2 */
+ DoMEDEffectF3, /* UNI_MEDEFFECTF3 */
+ DoOktArp, /* UNI_OKTARP */
};
static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
@@ -2382,10 +2409,14 @@ static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
int explicitslides = 0;
effect_func f;
- while((c=UniGetByte())) {
+ while((c=UniGetByte()) != 0) {
+#if 0 /* this doesn't normally happen unless things go fubar elsewhere */
+ if (c >= UNI_LAST)
+ fprintf(stderr,"fubar'ed opcode %u\n",c);
+#endif
f = effects[c];
if (f != DoNothing)
- a->sliding = 0;
+ a->sliding = 0;
explicitslides |= f(tick, flags, a, mod, channel);
}
return explicitslides;
@@ -2396,17 +2427,17 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
int t;
MP_VOICE *aout;
- dat&=0xf;
+ dat&=0xf;
aout=(a->slave)?a->slave:NULL;
switch (dat) {
case 0x0: /* past note cut */
- for (t=0;t<md_sngchn;t++)
+ for (t=0;t<NUMVOICES(mod);t++)
if (mod->voice[t].master==a)
mod->voice[t].main.fadevol=0;
break;
case 0x1: /* past note off */
- for (t=0;t<md_sngchn;t++)
+ for (t=0;t<NUMVOICES(mod);t++)
if (mod->voice[t].master==a) {
mod->voice[t].main.keyoff|=KEY_OFF;
if ((!(mod->voice[t].venv.flg & EF_ON))||
@@ -2415,7 +2446,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
}
break;
case 0x2: /* past note fade */
- for (t=0;t<md_sngchn;t++)
+ for (t=0;t<NUMVOICES(mod);t++)
if (mod->voice[t].master==a)
mod->voice[t].main.keyoff|=KEY_FADE;
break;
@@ -2427,7 +2458,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
break;
case 0x5: /* set NNA note off */
a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF;
- break;
+ break;
case 0x6: /* set NNA note fade */
a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE;
break;
@@ -2442,7 +2473,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
case 0x9: /* disable panning envelope */
if (aout)
aout->main.panflg&=~EF_ON;
- break;
+ break;
case 0xa: /* enable panning envelope */
if (aout)
aout->main.panflg|=EF_ON;
@@ -2470,7 +2501,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume)
SAMPLE *s;
mod->totalchn=mod->realchn=0;
- for (channel=0;channel<md_sngchn;channel++) {
+ for (channel=0;channel<NUMVOICES(mod);channel++) {
aout=&mod->voice[channel];
i=aout->main.i;
s=aout->main.s;
@@ -2484,7 +2515,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume)
if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) {
Voice_Play_internal(channel,s,(aout->main.start==-1)?
- ((s->flags&SF_UST_LOOP) ? (SLONG)s->loopstart : 0) : aout->main.start);
+ ((s->flags&SF_UST_LOOP)?(SLONG)s->loopstart:0):aout->main.start);
aout->main.fadevol=32768;
aout->aswppos=0;
}
@@ -2687,7 +2718,7 @@ static void pt_Notes(MODULE *mod)
UniSetRow(a->row);
funky=0;
- while((c=UniGetByte()))
+ while((c=UniGetByte()) != 0)
switch (c) {
case UNI_NOTE:
funky|=1;
@@ -2720,7 +2751,7 @@ static void pt_Notes(MODULE *mod)
INSTRUMENT *i;
SAMPLE *s;
- if ((i=a->main.i)) {
+ if ((i=a->main.i) != NULL) {
if (i->samplenumber[a->anote] >= mod->numsmp) continue;
s=&mod->samples[i->samplenumber[a->anote]];
a->main.note=i->samplenote[a->anote];
@@ -2809,7 +2840,7 @@ static void pt_EffectsPass1(MODULE *mod)
for (channel=0;channel<mod->numchn;channel++) {
a=&mod->control[channel];
- if ((aout=a->slave)) {
+ if ((aout=a->slave) != NULL) {
a->main.fadevol=aout->main.fadevol;
a->main.period=aout->main.period;
if (a->main.kick==KICK_KEYOFF)
@@ -2891,7 +2922,7 @@ static void pt_NNA(MODULE *mod)
if (a->dct!=DCT_OFF) {
int t;
- for (t=0;t<md_sngchn;t++)
+ for (t=0;t<NUMVOICES(mod);t++)
if ((!Voice_Stopped_internal(t))&&
(mod->voice[t].masterchn==channel)&&
(a->main.sample==mod->voice[t].main.sample)) {
@@ -2951,11 +2982,11 @@ static void pt_SetupVoices(MODULE *mod)
if ((newchn=MP_FindEmptyChannel(mod))!=-1)
a->slave=&mod->voice[a->slavechn=newchn];
}
- } else
+ } else
a->slave=&mod->voice[a->slavechn=channel];
/* assign parts of MP_VOICE only done for a KICK_NOTE */
- if ((aout=a->slave)) {
+ if ((aout=a->slave) != NULL) {
if (aout->mflag && aout->master) aout->master->slave=NULL;
aout->master=a;
a->slave=aout;
@@ -2984,7 +3015,7 @@ static void pt_EffectsPass2(MODULE *mod)
if (!a->row) continue;
UniSetRow(a->row);
- while((c=UniGetByte()))
+ while((c=UniGetByte()) != 0)
if (c==UNI_ITEFFECTS0) {
c=UniGetByte();
if ((c>>4)==SS_S7EFFECTS)
@@ -3016,7 +3047,7 @@ void Player_HandleTick(void)
pf->sngremainder%=pf->bpm;
if (++pf->vbtick>=pf->sngspd) {
- if (pf->pat_repcrazy)
+ if (pf->pat_repcrazy)
pf->pat_repcrazy=0; /* play 2 times row 0 */
else
pf->patpos++;
@@ -3046,6 +3077,9 @@ void Player_HandleTick(void)
pf->control[channel].pat_reppos=-1;
pf->patbrk=pf->posjmp=0;
+
+ if (pf->sngpos<0) pf->sngpos=(SWORD)(pf->numpos-1);
+
/* handle the "---" (end of song) pattern since it can occur
*inside* the module in some formats */
if ((pf->sngpos>=pf->numpos)||
@@ -3060,7 +3094,6 @@ void Player_HandleTick(void)
pf->bpm=pf->inittempo<32?32:pf->inittempo;
}
}
- if (pf->sngpos<0) pf->sngpos=pf->numpos-1;
}
if (!pf->patdly2)
@@ -3093,7 +3126,7 @@ static void Player_Init_internal(MODULE* mod)
mod->control[t].main.chanvol=mod->chanvol[t];
mod->control[t].main.panning=mod->panning[t];
}
-
+
mod->sngtime=0;
mod->sngremainder=0;
@@ -3133,6 +3166,11 @@ int Player_Init(MODULE* mod)
if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE))))
return 1;
+ /* mod->numvoices was used during loading to clamp md_sngchn.
+ After loading it's used to remember how big mod->voice is.
+ */
+ mod->numvoices = md_sngchn;
+
Player_Init_internal(mod);
return 0;
}
@@ -3148,10 +3186,8 @@ void Player_Exit_internal(MODULE* mod)
pf=NULL;
}
- if (mod->control)
- MikMod_free(mod->control);
- if (mod->voice)
- MikMod_free(mod->voice);
+ MikMod_free(mod->control);
+ MikMod_free(mod->voice);
mod->control=NULL;
mod->voice=NULL;
}
@@ -3166,8 +3202,10 @@ void Player_Exit(MODULE* mod)
MIKMODAPI void Player_SetVolume(SWORD volume)
{
MUTEX_LOCK(vars);
- if (pf)
+ if (pf) {
pf->volume=(volume<0)?0:(volume>128)?128:volume;
+ pf->initvolume=pf->volume;
+ }
MUTEX_UNLOCK(vars);
}
@@ -3241,7 +3279,7 @@ MIKMODAPI void Player_NextPosition(void)
pf->patbrk=0;
pf->vbtick=pf->sngspd;
- for (t=0;t<md_sngchn;t++) {
+ for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t);
pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL;
@@ -3266,7 +3304,7 @@ MIKMODAPI void Player_PrevPosition(void)
pf->patbrk=0;
pf->vbtick=pf->sngspd;
- for (t=0;t<md_sngchn;t++) {
+ for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t);
pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL;
@@ -3293,7 +3331,7 @@ MIKMODAPI void Player_SetPosition(UWORD pos)
pf->sngpos=pos;
pf->vbtick=pf->sngspd;
- for (t=0;t<md_sngchn;t++) {
+ for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t);
pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL;
@@ -3303,12 +3341,12 @@ MIKMODAPI void Player_SetPosition(UWORD pos)
pf->control[t].main.s=NULL;
}
pf->forbid=0;
-
+
if (!pos)
Player_Init_internal(pf);
}
MUTEX_UNLOCK(vars);
-}
+}
static void Player_Unmute_internal(SLONG arg1,va_list ap)
{
@@ -3418,7 +3456,7 @@ static void Player_ToggleMute_internal(SLONG arg1,va_list ap)
}
break;
default:
- if (arg1<pf->numchn)
+ if (arg1<pf->numchn)
pf->control[arg1].muted=1-pf->control[arg1].muted;
break;
}
@@ -3465,7 +3503,7 @@ MIKMODAPI UWORD Player_GetChannelPeriod(UBYTE chan)
UWORD result=0;
MUTEX_LOCK(vars);
- if (pf)
+ if (pf)
result=(chan<pf->numchn)?pf->control[chan].main.period:0;
MUTEX_UNLOCK(vars);
@@ -3499,7 +3537,7 @@ MIKMODAPI void Player_TogglePause(void)
MIKMODAPI void Player_SetSpeed(UWORD speed)
{
MUTEX_LOCK(vars);
- if (pf)
+ if (pf)
pf->sngspd=speed?(speed<32?speed:32):1;
MUTEX_UNLOCK(vars);
}
@@ -3538,18 +3576,17 @@ MIKMODAPI int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo)
return numvoices;
}
-
-// Get current module order
+/* Get current module order */
MIKMODAPI int Player_GetOrder(void)
{
int ret;
MUTEX_LOCK(vars);
- ret = pf ? pf->sngpos :0; // pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0;
+ ret = pf ? pf->sngpos :0; /* pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0; */
MUTEX_UNLOCK(vars);
return ret;
}
-// Get current module row
+/* Get current module row */
MIKMODAPI int Player_GetRow(void)
{
int ret;
@@ -3559,5 +3596,4 @@ MIKMODAPI int Player_GetRow(void)
return ret;
}
-
/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/munitrk.c b/apps/plugins/mikmod/munitrk.c
index f0a8f58af7..72e7de4e7e 100644
--- a/apps/plugins/mikmod/munitrk.c
+++ b/apps/plugins/mikmod/munitrk.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: munitrk.c,v 1.2 2005/03/30 19:11:46 realtech Exp $
+ $Id$
All routines dealing with the manipulation of UNITRK streams
@@ -37,7 +37,7 @@
/* Unibuffer chunk size */
#define BUFPAGE 128
-UWORD unioperands[UNI_LAST]={
+const UWORD unioperands[UNI_LAST] = {
0, /* not used */
1, /* UNI_NOTE */
1, /* UNI_INSTRUMENT */
@@ -214,7 +214,7 @@ static int UniExpand(int wanted)
unibuf = newbuf;
unimax+=BUFPAGE;
return 1;
- } else
+ } else
return 0;
}
return 1;
@@ -236,7 +236,7 @@ void UniWriteWord(UWORD data)
}
}
-static int MyCmp(UBYTE* a,UBYTE* b,UWORD l)
+static int MyCmp(const UBYTE* a,const UBYTE* b,UWORD l)
{
UWORD t;
@@ -275,15 +275,15 @@ void UniNewline(void)
stream. */
UBYTE* UniDup(void)
{
- UBYTE *d;
+ void *d;
- if (!UniExpand(unitt-unipc)) return NULL;
+ if (!UniExpand(unipc-unitt)) return NULL;
unibuf[unitt] = 0;
- if(!(d=(UBYTE *)MikMod_malloc(unipc))) return NULL;
+ if(!(d=MikMod_malloc(unipc))) return NULL;
memcpy(d,unibuf,unipc);
- return d;
+ return (UBYTE *)d;
}
int UniInit(void)
@@ -296,7 +296,7 @@ int UniInit(void)
void UniCleanup(void)
{
- if(unibuf) MikMod_free(unibuf);
+ MikMod_free(unibuf);
unibuf = NULL;
}
diff --git a/apps/plugins/mikmod/npertab.c b/apps/plugins/mikmod/npertab.c
index 4aa5ef9a17..b106b2adf8 100644
--- a/apps/plugins/mikmod/npertab.c
+++ b/apps/plugins/mikmod/npertab.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: npertab.c,v 1.2 2005/03/30 19:11:47 realtech Exp $
+ $Id$
MOD format period table. Used by both the MOD and M15 (15-inst mod) Loaders.
@@ -32,7 +32,7 @@
#include "mikmod_internals.h"
-UWORD npertab[7 * OCTAVE] = {
+const UWORD npertab[7 * OCTAVE] = {
/* Octaves 6 -> 0 */
/* C C# D D# E F F# G G# A A# B */
0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a,
diff --git a/apps/plugins/mikmod/sloader.c b/apps/plugins/mikmod/sloader.c
index 8c1070cba1..af7f623799 100644
--- a/apps/plugins/mikmod/sloader.c
+++ b/apps/plugins/mikmod/sloader.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: sloader.c,v 1.3 2007/12/06 17:46:08 denis111 Exp $
+ $Id$
Routines for loading samples. The sample loader utilizes the routines
provided by the "registered" sample loader.
@@ -56,7 +56,7 @@ typedef struct ITPACK {
int SL_Init(SAMPLOAD* s)
{
if(!sl_buffer)
- if(!(sl_buffer=MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
+ if(!(sl_buffer=(SWORD*)MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
sl_rlength = s->length;
if(s->infmt & SF_16BITS) sl_rlength>>=1;
@@ -68,16 +68,15 @@ int SL_Init(SAMPLOAD* s)
void SL_Exit(SAMPLOAD *s)
{
if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
- if(sl_buffer) {
- MikMod_free(sl_buffer);
- sl_buffer=NULL;
- }
+
+ MikMod_free(sl_buffer);
+ sl_buffer=NULL;
}
/* unpack a 8bit IT packed sample */
-static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
+static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt)
{
- SWORD *dest=sl_buffer,*end=sl_buffer+count;
+ SWORD *dest=out,*end=out+count;
UWORD x,y,needbits,havebits,new_count=0;
UWORD bits = status->bits;
UWORD bufbits = status->bufbits;
@@ -145,13 +144,13 @@ static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD c
status->bufbits = bufbits;
status->last = last;
status->buf = buf;
- return (dest-sl_buffer);
+ return (dest-out);
}
/* unpack a 16bit IT packed sample */
-static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
+static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt)
{
- SWORD *dest=sl_buffer,*end=sl_buffer+count;
+ SWORD *dest=out,*end=out+count;
SLONG x,y,needbits,havebits,new_count=0;
UWORD bits = status->bits;
UWORD bufbits = status->bufbits;
@@ -219,7 +218,7 @@ static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
status->bufbits = bufbits;
status->last = last;
status->buf = buf;
- return (dest-sl_buffer);
+ return (dest-out);
}
static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,int dither)
@@ -231,9 +230,11 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
int result,c_block=0; /* compression bytes until next block */
ITPACK status;
UWORD incnt = 0;
-
- memset(&status, 0, sizeof(status)); /* initialize status */
-
+
+ status.buf = 0;
+ status.last = 0;
+ status.bufbits = 0;
+ status.bits = 0;
while(length) {
stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
@@ -261,6 +262,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
c_block -= stodo;
} else {
if(infmt&SF_16BITS) {
+ if(_mm_eof(reader)) {
+ _mm_errno=MMERR_NOT_A_STREAM;/* better error? */
+ return 1;
+ }
if(infmt&SF_BIG_ENDIAN)
_mm_read_M_SWORDS(sl_buffer,stodo,reader);
else
@@ -269,6 +274,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
SBYTE *src;
SWORD *dest;
+ if(_mm_eof(reader)) {
+ _mm_errno=MMERR_NOT_A_STREAM;/* better error? */
+ return 1;
+ }
reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
src = (SBYTE*)sl_buffer;
dest = sl_buffer;
@@ -288,7 +297,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
sl_old = sl_buffer[t];
}
- if((infmt^outfmt) & SF_SIGNED)
+ if((infmt^outfmt) & SF_SIGNED)
for(t=0;t<stodo;t++)
sl_buffer[t]^= 0x8000;
@@ -340,7 +349,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length)
{
return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor,
- length,smp->reader,0);
+ length,smp->reader,0);
}
/* Registers a sample for loading when SL_LoadSamples() is called. */
@@ -357,7 +366,7 @@ SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader)
cruise = sndfxlist;
} else
return NULL;
-
+
/* Allocate and add structure to the END of the list */
if(!(news=(SAMPLOAD*)MikMod_malloc(sizeof(SAMPLOAD)))) return NULL;
@@ -407,7 +416,7 @@ static ULONG SampleTotal(SAMPLOAD* samplist,int type)
static ULONG RealSpeed(SAMPLOAD *s)
{
return(s->sample->speed/(s->scalefactor?s->scalefactor:1));
-}
+}
static int DitherSamples(SAMPLOAD* samplist,int type)
{
@@ -417,7 +426,7 @@ static int DitherSamples(SAMPLOAD* samplist,int type)
if(!samplist) return 0;
- if((maxsize=MD_SampleSpace(type)*1024))
+ if((maxsize=MD_SampleSpace(type)*1024) != 0)
while(SampleTotal(samplist,type)>maxsize) {
/* First Pass - check for any 16 bit samples */
s = samplist;
@@ -473,15 +482,15 @@ static int DitherSamples(SAMPLOAD* samplist,int type)
int SL_LoadSamples(void)
{
- int ok;
+ int rc;
_mm_critical = 0;
if((!musiclist)&&(!sndfxlist)) return 0;
- ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
+ rc=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
musiclist=sndfxlist=NULL;
- return ok;
+ return rc;
}
void SL_Sample16to8(SAMPLOAD* s)
@@ -518,5 +527,4 @@ void SL_HalveSample(SAMPLOAD* s,int factor)
s->sample->loopend = s->loopend / s->scalefactor;
}
-
/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/virtch.c b/apps/plugins/mikmod/virtch.c
index 6e8174016c..f2fd528b00 100644
--- a/apps/plugins/mikmod/virtch.c
+++ b/apps/plugins/mikmod/virtch.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: virtch.c,v 1.4 2005/05/18 13:42:23 raphassenat Exp $
+ $Id$
Sample mixing routines, using a 32 bits mixing buffer.
@@ -33,28 +33,23 @@
(b) Interpolation of sample data during mixing
(c) Dolby Surround Sound
*/
-#if 0
-#include <assert.h>
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <stddef.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <string.h>
#include "mikmod_internals.h"
-#include "mikmod.h"
/*
Constant definitions
====================
- BITSHIFT
+ BITSHIFT
Controls the maximum volume of the sound output. All data is shifted
right by BITSHIFT after being mixed. Higher values result in quieter
sound and less chance of distortion.
@@ -130,164 +125,176 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL,
#else
#define NATIVE SLONG
#endif
+
#if defined HAVE_SSE2 || defined HAVE_ALTIVEC
-static size_t MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,size_t index, size_t increment,size_t todo)
+# if !defined(NATIVE_64BIT_INT)
+static SINTPTR_T MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo)
{
- // TODO:
+ /* TODO: */
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel * sample;
}
- return index;
+ return idx;
}
+# endif /* !NATIVE_64BIT_INT */
-static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index, size_t increment,size_t todo)
-{
+static SINTPTR_T MixSIMDStereoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo)
+{
SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel};
SWORD sample;
SLONG remain = todo;
- // Dest can be misaligned ...
+ /* Dest can be misaligned */
while(!IS_ALIGNED_16(dest)) {
- sample=srce[(index += increment) >> FRACBITS];
+ sample=srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
todo--;
+ if(!todo) return idx;
}
- // Srce is always aligned ...
+ /* Srce is always aligned */
#if defined HAVE_SSE2
- remain = todo&3;
+ remain = todo&3;
{
- __m128i v0 = _mm_set_epi16(0, vol[1],
- 0, vol[0],
- 0, vol[1],
- 0, vol[0]);
+ __m128i v0 = _mm_set_epi16(0, vol[1],
+ 0, vol[0],
+ 0, vol[1],
+ 0, vol[0]);
for(todo>>=2;todo; todo--)
{
- SWORD s0 = srce[(index += increment) >> FRACBITS];
- SWORD s1 = srce[(index += increment) >> FRACBITS];
- SWORD s2 = srce[(index += increment) >> FRACBITS];
- SWORD s3 = srce[(index += increment) >> FRACBITS];
+ SWORD s0 = srce[idx >> FRACBITS];
+ SWORD s1 = srce[(idx += increment) >> FRACBITS];
+ SWORD s2 = srce[(idx += increment) >> FRACBITS];
+ SWORD s3 = srce[(idx += increment) >> FRACBITS];
__m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0);
__m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2);
__m128i v3 = _mm_load_si128((__m128i*)(dest+0));
__m128i v4 = _mm_load_si128((__m128i*)(dest+4));
_mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1)));
_mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2)));
- dest+=8;
+ dest+=8;
+ idx += increment;
}
}
#elif defined HAVE_ALTIVEC
remain = todo&3;
{
- vector signed short r0 = vec_ld(0, vol);
- vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, // l
- 0, 1, // l
- 2, 3, // r
- 2, 1, // r
- 0, 1, // l
- 0, 1, // l
- 2, 3, // r
- 2, 3 // r
- ));
SWORD s[8];
-
+ vector signed short r0 = vec_ld(0, vol);
+ vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */
+ 0, 1, /* l */
+ 2, 3, /* r */
+ 2, 1, /* r */
+ 0, 1, /* l */
+ 0, 1, /* l */
+ 2, 3, /* r */
+ 2, 3 /* r */
+ ));
+
for(todo>>=2;todo; todo--)
{
- // Load constants
- s[0] = srce[(index += increment) >> FRACBITS];
- s[1] = srce[(index += increment) >> FRACBITS];
- s[2] = srce[(index += increment) >> FRACBITS];
- s[3] = srce[(index += increment) >> FRACBITS];
+ vector short int r1;
+ vector signed short v1, v2;
+ vector signed int v3, v4, v5, v6;
+
+ /* Load constants */
+ s[0] = srce[idx >> FRACBITS];
+ s[1] = srce[(idx += increment) >> FRACBITS];
+ s[2] = srce[(idx += increment) >> FRACBITS];
+ s[3] = srce[(idx += increment) >> FRACBITS];
s[4] = 0;
-
- vector short int r1 = vec_ld(0, s);
- vector signed short v1 = vec_perm(r1, r1, (vector unsigned char)(0*2, 0*2+1, // s0
- 4*2, 4*2+1, // 0
- 0*2, 0*2+1, // s0
- 4*2, 4*2+1, // 0
- 1*2, 1*2+1, // s1
- 4*2, 4*2+1, // 0
- 1*2, 1*2+1, // s1
- 4*2, 4*2+1 // 0
- ));
-
- vector signed short v2 = vec_perm(r1, r1, (vector unsigned char)(2*2, 2*2+1, // s2
- 4*2, 4*2+1, // 0
- 2*2, 2*2+1, // s2
- 4*2, 4*2+1, // 0
- 3*2, 3*2+1, // s3
- 4*2, 4*2+1, // 0
- 3*2, 3*2+1, // s3
- 4*2, 4*2+1 // 0
- ));
- vector signed int v3 = vec_ld(0, dest);
- vector signed int v4 = vec_ld(0, dest + 4);
- vector signed int v5 = vec_mule(v0, v1);
- vector signed int v6 = vec_mule(v0, v2);
-
- vec_st(vec_add(v3, v5), 0, dest);
+
+ r1 = vec_ld(0, s);
+ v1 = vec_perm(r1, r1, (vector unsigned char)
+ (0*2, 0*2+1, /* s0 */
+ 4*2, 4*2+1, /* 0 */
+ 0*2, 0*2+1, /* s0 */
+ 4*2, 4*2+1, /* 0 */
+ 1*2, 1*2+1, /* s1 */
+ 4*2, 4*2+1, /* 0 */
+ 1*2, 1*2+1, /* s1 */
+ 4*2, 4*2+1 /* 0 */
+ ) );
+ v2 = vec_perm(r1, r1, (vector unsigned char)
+ (2*2, 2*2+1, /* s2 */
+ 4*2, 4*2+1, /* 0 */
+ 2*2, 2*2+1, /* s2 */
+ 4*2, 4*2+1, /* 0 */
+ 3*2, 3*2+1, /* s3 */
+ 4*2, 4*2+1, /* 0 */
+ 3*2, 3*2+1, /* s3 */
+ 4*2, 4*2+1 /* 0 */
+ ) );
+
+ v3 = vec_ld(0, dest);
+ v4 = vec_ld(0, dest + 4);
+ v5 = vec_mule(v0, v1);
+ v6 = vec_mule(v0, v2);
+
+ vec_st(vec_add(v3, v5), 0, dest);
vec_st(vec_add(v4, v6), 0x10, dest);
dest+=8;
+ idx += increment;
}
}
-#endif // HAVE_ALTIVEC
+#endif /* HAVE_ALTIVEC */
- // Remaining bits ...
+ /* Remaining bits */
while(remain--) {
- sample=srce[(index += increment) >> FRACBITS];
+ sample=srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
}
- return index;
+ return idx;
}
#endif
/*========== 32 bit sample mixers - only for 32 bit platforms */
#ifndef NATIVE_64BIT_INT
-static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
- if (md_mode & DMODE_SIMDMIXER)
- {
- return MixSIMDMonoNormal(srce, dest, index, increment, todo);
+ if (md_mode & DMODE_SIMDMIXER) {
+ return MixSIMDMonoNormal(srce, dest, idx, increment, todo);
}
else
#endif
{
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
-
+
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
-
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
+
*dest++ += lvolsel * sample;
}
}
- return index;
+ return idx;
}
-// FIXME: This mixer should works also on 64-bit platform
-// Hint : changes SLONG / SLONGLONG mess with size_t
-static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+/* FIXME: This mixer should works also on 64-bit platform */
+/* Hint : changes SLONG / SLONGLONG mess with intptr */
+static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
- if (md_mode & DMODE_SIMDMIXER)
- {
- return MixSIMDStereoNormal(srce, dest, index, increment, todo);
+ if (md_mode & DMODE_SIMDMIXER) {
+ return MixSIMDStereoNormal(srce, dest, idx, increment, todo);
}
else
#endif
@@ -297,17 +304,17 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
SLONG rvolsel = vnf->rvolsel;
while(todo--) {
- sample=srce[(index += increment) >> FRACBITS];
+ sample=srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel * sample;
*dest++ += rvolsel * sample;
}
}
- return index;
+ return idx;
}
-
-static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
@@ -315,25 +322,26 @@ static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG
if (lvolsel>=rvolsel) {
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel*sample;
*dest++ -= lvolsel*sample;
}
- } else {
+ }
+ else {
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ -= rvolsel*sample;
*dest++ += rvolsel*sample;
}
}
- return index;
+ return idx;
}
-static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -342,33 +350,33 @@ static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
if (rampvol) {
SLONG oldlvol = vnf->oldlvol - lvolsel;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
- * sample >> CLICK_SHIFT;
+ * sample >> CLICK_SHIFT;
if (!--rampvol)
break;
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += lvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -379,13 +387,13 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
SLONG oldlvol = vnf->oldlvol - lvolsel;
SLONG oldrvol = vnf->oldrvol - rvolsel;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
- * sample >> CLICK_SHIFT;
+ * sample >> CLICK_SHIFT;
*dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol)
* sample >> CLICK_SHIFT;
if (!--rampvol)
@@ -393,22 +401,22 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += lvolsel * sample;
*dest++ += rvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
+static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -427,13 +435,13 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG
if (rampvol) {
oldvol -= vol;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
sample=((vol << CLICK_SHIFT) + oldvol * rampvol)
- * sample >> CLICK_SHIFT;
+ * sample >> CLICK_SHIFT;
*dest++ += sample;
*dest++ -= sample;
@@ -442,55 +450,55 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += vol*sample;
*dest++ -= vol*sample;
}
- return index;
+ return idx;
}
#endif
/*========== 64 bit sample mixers - all platforms */
-static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
SLONG rvolsel = vnf->rvolsel;
while(todo--) {
- sample=srce[index >> FRACBITS];
- index += increment;
+ sample=srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel * sample;
*dest++ += rvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SWORD sample;
SLONG lvolsel = vnf->lvolsel;
@@ -498,25 +506,26 @@ static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index
if(vnf->lvolsel>=vnf->rvolsel) {
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ += lvolsel*sample;
*dest++ -= lvolsel*sample;
}
- } else {
+ }
+ else {
while(todo--) {
- sample = srce[index >> FRACBITS];
- index += increment;
+ sample = srce[idx >> FRACBITS];
+ idx += increment;
*dest++ -= rvolsel*sample;
*dest++ += rvolsel*sample;
}
}
- return index;
+ return idx;
}
-static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -525,10 +534,10 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
if (rampvol) {
SLONG oldlvol = vnf->oldlvol - lvolsel;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
* sample >> CLICK_SHIFT;
@@ -537,21 +546,21 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += lvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -562,10 +571,10 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S
SLONG oldlvol = vnf->oldlvol - lvolsel;
SLONG oldrvol = vnf->oldrvol - rvolsel;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol)
* sample >> CLICK_SHIFT;
@@ -576,22 +585,22 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += lvolsel * sample;
*dest++ += rvolsel * sample;
}
- return index;
+ return idx;
}
-static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo)
+static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{
SLONG sample;
SLONG lvolsel = vnf->lvolsel;
@@ -610,13 +619,13 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index
if (rampvol) {
oldvol -= vol;
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
sample=((vol << CLICK_SHIFT) + oldvol * rampvol)
- * sample >> CLICK_SHIFT;
+ * sample >> CLICK_SHIFT;
*dest++ += sample;
*dest++ -= sample;
if (!--rampvol)
@@ -624,19 +633,19 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index
}
vnf->rampvol = rampvol;
if (todo < 0)
- return index;
+ return idx;
}
while(todo--) {
- sample=(SLONG)srce[index>>FRACBITS]+
- ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS])
- *(index&FRACMASK)>>FRACBITS);
- index += increment;
+ sample=(SLONG)srce[idx>>FRACBITS]+
+ ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS])
+ *(idx&FRACMASK)>>FRACBITS);
+ idx += increment;
*dest++ += vol*sample;
*dest++ -= vol*sample;
}
- return index;
+ return idx;
}
static void (*MixReverb)(SLONG* srce,NATIVE count);
@@ -673,7 +682,7 @@ static void MixReverb_Normal(SLONG* srce,NATIVE count)
/* left channel */
*srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
- RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
+ RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
}
}
@@ -710,10 +719,10 @@ static void MixReverb_Stereo(SLONG* srce,NATIVE count)
/* left channel then right channel */
*srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
- RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
+ RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
*srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+
- RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
+ RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
}
}
@@ -839,58 +848,56 @@ static void Mix32To8(SBYTE* dste,const SLONG *srce,NATIVE count)
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
-// Mix 32bit input to floating point. 32 samples per iteration
-// PC: ?, Mac OK
-static void Mix32ToFP_SIMD(float* dste,SLONG* srce,NATIVE count)
+/* Mix 32bit input to floating point. 32 samples per iteration */
+/* PC: ?, Mac OK */
+static void Mix32ToFP_SIMD(float* dste,const SLONG* srce,NATIVE count)
{
- int remain=count;
+ const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT));
+ int remain=count;
+ simd_m128 x1, x2, xk;
while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
{
- float x1;
- EXTRACT_SAMPLE_FP(x1,FP_SHIFT);
- CHECK_SAMPLE_FP(x1,1.0f);
- PUT_SAMPLE_FP(x1);
+ float xf;
+ EXTRACT_SAMPLE_FP(xf,FP_SHIFT);
+ CHECK_SAMPLE_FP(xf,1.0f);
+ PUT_SAMPLE_FP(xf);
count--;
- if (!count)
- {
- return;
- }
+ if (!count) return;
}
- remain = count&7;
-
- const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT));
- simd_m128 x1, x2;
- simd_m128 xk = LOAD_PS1_SIMD(&k); // Scale factor
+ remain = count&7;
+
+ xk = LOAD_PS1_SIMD(&k); /* Scale factor */
for(count>>=3;count;count--) {
- EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples
- EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); // Load 4 samples
- PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples
- PUT_SAMPLE_SIMD_F(dste+4, x2); // Store 4 samples
- srce+=8;
- dste+=8;
- }
+ EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */
+ EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); /* Load 4 samples */
+ PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */
+ PUT_SAMPLE_SIMD_F(dste+4, x2); /* Store 4 samples */
+ srce+=8;
+ dste+=8;
+ }
if (remain&4) {
- EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples
- PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples
- srce+=4;
- dste+=4;
- remain &= 3;
- }
+ EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */
+ PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */
+ srce+=4;
+ dste+=4;
+ remain &= 3;
+ }
while(remain--) {
- float x1;
- EXTRACT_SAMPLE_FP(x1,FP_SHIFT);
- CHECK_SAMPLE_FP(x1,1.0f);
- PUT_SAMPLE_FP(x1);
+ float xf;
+ EXTRACT_SAMPLE_FP(xf,FP_SHIFT);
+ CHECK_SAMPLE_FP(xf,1.0f);
+ PUT_SAMPLE_FP(xf);
}
}
-// PC: Ok, Mac Ok
-static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count)
-{
+
+/* PC: Ok, Mac Ok */
+static void Mix32To16_SIMD(SWORD* dste,const SLONG* srce,NATIVE count)
+{
int remain = count;
while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
@@ -900,34 +907,31 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count)
CHECK_SAMPLE(x1,32768);
PUT_SAMPLE(x1);
count--;
- if (!count)
- {
- return;
- }
+ if (!count) return;
}
remain = count&7;
- for(count>>=3;count;count--)
+ for(count>>=3;count;count--)
{
simd_m128i x1,x2;
- EXTRACT_SAMPLE_SIMD_16(srce, x1); // Load 4 samples
- EXTRACT_SAMPLE_SIMD_16(srce+4, x2); // Load 4 samples
- PUT_SAMPLE_SIMD_W(dste, x1, x2); // Store 8 samples
+ EXTRACT_SAMPLE_SIMD_16(srce, x1); /* Load 4 samples */
+ EXTRACT_SAMPLE_SIMD_16(srce+4, x2); /* Load 4 samples */
+ PUT_SAMPLE_SIMD_W(dste, x1, x2); /* Store 8 samples */
srce+=8;
dste+=8;
}
if (remain)
- Mix32To16(dste, srce, remain);
+ Mix32To16(dste, srce, remain);
}
-// Mix 32bit input to 8bit. 128 samples per iteration
-// PC:OK, Mac: Ok
-static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count)
-{
+/* Mix 32bit input to 8bit. 128 samples per iteration */
+/* PC:OK, Mac: Ok */
+static void Mix32To8_SIMD(SBYTE* dste,const SLONG* srce,NATIVE count)
+{
int remain=count;
-
+
while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce))
{
SWORD x1;
@@ -935,32 +939,29 @@ static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count)
CHECK_SAMPLE(x1,128);
PUT_SAMPLE(x1+128);
count--;
- if (!count)
- {
- return;
- }
+ if (!count) return;
}
-
+
remain = count&15;
for(count>>=4;count;count--) {
- simd_m128i x1,x2,x3,x4;
- EXTRACT_SAMPLE_SIMD_8(srce, x1); // Load 4 samples
- EXTRACT_SAMPLE_SIMD_8(srce+4, x2); // Load 4 samples
- EXTRACT_SAMPLE_SIMD_8(srce+8, x3); // Load 4 samples
- EXTRACT_SAMPLE_SIMD_8(srce+12, x4); // Load 4 samples
- PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); // Store 16 samples
- srce+=16;
- dste+=16;
+ simd_m128i x1,x2,x3,x4;
+ EXTRACT_SAMPLE_SIMD_8(srce, x1); /* Load 4 samples */
+ EXTRACT_SAMPLE_SIMD_8(srce+4, x2); /* Load 4 samples */
+ EXTRACT_SAMPLE_SIMD_8(srce+8, x3); /* Load 4 samples */
+ EXTRACT_SAMPLE_SIMD_8(srce+12, x4); /* Load 4 samples */
+ PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); /* Store 16 samples */
+ srce+=16;
+ dste+=16;
}
+
if (remain)
- Mix32To8(dste, srce, remain);
+ Mix32To8(dste, srce, remain);
}
#endif
-
static void AddChannel(SLONG* ptr,NATIVE todo)
{
SLONGLONG end,done;
@@ -1050,65 +1051,64 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
vnf->current=Mix32SurroundInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
else
vnf->current=Mix32StereoInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
} else
vnf->current=Mix32MonoInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
} else if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
vnf->current=Mix32SurroundNormal
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
else
{
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
- if (md_mode & DMODE_SIMDMIXER)
+ if (md_mode & DMODE_SIMDMIXER)
vnf->current=MixSIMDStereoNormal
- (s,ptr,vnf->current,vnf->increment,done);
-
- else
+ (s,ptr,vnf->current,vnf->increment,done);
+ else
#endif
vnf->current=Mix32StereoNormal
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
}
} else
vnf->current=Mix32MonoNormal
- (s,ptr,vnf->current,vnf->increment,done);
- } else
+ (s,ptr,vnf->current,vnf->increment,done);
+ }
+ else
#endif
- {
+ {
if((md_mode & DMODE_INTERP)) {
if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
vnf->current=MixSurroundInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
else
vnf->current=MixStereoInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
} else
vnf->current=MixMonoInterp
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
} else if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND))
vnf->current=MixSurroundNormal
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
else
{
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
- if (md_mode & DMODE_SIMDMIXER)
+ if (md_mode & DMODE_SIMDMIXER)
vnf->current=MixSIMDStereoNormal
- (s,ptr,vnf->current,vnf->increment,done);
-
- else
+ (s,ptr,vnf->current,vnf->increment,done);
+ else
#endif
vnf->current=MixStereoNormal
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
}
} else
vnf->current=MixMonoNormal
- (s,ptr,vnf->current,vnf->increment,done);
+ (s,ptr,vnf->current,vnf->increment,done);
}
} else
/* update sample position */
@@ -1119,6 +1119,33 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
}
}
+#ifdef NO_HQMIXER
+#define VC_SetupPointers() do{}while(0)
+#define VC1_Init VC_Init
+#define VC1_Exit VC_Exit
+#define VC1_PlayStart VC_PlayStart
+#define VC1_PlayStop VC_PlayStop
+#define VC1_SampleLength VC_SampleLength
+#define VC1_SampleSpace VC_SampleSpace
+#define VC1_SampleLoad VC_SampleLoad
+#define VC1_SampleUnload VC_SampleUnload
+#define VC1_SetNumVoices VC_SetNumVoices
+#define VC1_SilenceBytes VC_SilenceBytes
+#define VC1_VoicePlay VC_VoicePlay
+#define VC1_VoiceStop VC_VoiceStop
+#define VC1_VoiceGetFrequency VC_VoiceGetFrequency
+#define VC1_VoiceGetPanning VC_VoiceGetPanning
+#define VC1_VoiceGetPosition VC_VoiceGetPosition
+#define VC1_VoiceGetVolume VC_VoiceGetVolume
+#define VC1_VoiceRealVolume VC_VoiceRealVolume
+#define VC1_VoiceSetFrequency VC_VoiceSetFrequency
+#define VC1_VoiceSetPanning VC_VoiceSetPanning
+#define VC1_VoiceSetVolume VC_VoiceSetVolume
+#define VC1_VoiceStopped VC_VoiceStopped
+#define VC1_WriteBytes VC_WriteBytes
+#define VC1_WriteSamples VC_WriteSamples
+#endif
+
#define _IN_VIRTCH_
#include "virtch_common.c"
#undef _IN_VIRTCH_
@@ -1190,7 +1217,6 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo)
vc_callback((unsigned char*)vc_tickbuf, portion);
}
-
#if defined HAVE_ALTIVEC || defined HAVE_SSE2
if (md_mode & DMODE_SIMDMIXER)
{
@@ -1219,20 +1245,23 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo)
int VC1_Init(void)
{
+#ifndef NO_HQMIXER
VC_SetupPointers();
-
- //if (md_mode&DMODE_HQMIXER)
- // return VC2_Init();
- if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) {
+ if (md_mode&DMODE_HQMIXER)
+ return VC2_Init();
+#endif
+
+ if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) {
_mm_errno = MMERR_INITIALIZING_MIXER;
return 1;
}
- if(!vc_tickbuf)
- if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) {
+ if(!vc_tickbuf) {
+ if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) {
_mm_errno = MMERR_INITIALIZING_MIXER;
return 1;
}
+ }
MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal;
MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal;
@@ -1264,14 +1293,17 @@ int VC1_PlayStart(void)
if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
- if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
+ /* allocate reverb buffers for the right channel if in stereo mode only. */
+ if (vc_mode & DMODE_STEREO) {
+ if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
+ }
RVRindex = 0;
return 0;
@@ -1279,23 +1311,23 @@ int VC1_PlayStart(void)
void VC1_PlayStop(void)
{
- if(RVbufL1) MikMod_free(RVbufL1);
- if(RVbufL2) MikMod_free(RVbufL2);
- if(RVbufL3) MikMod_free(RVbufL3);
- if(RVbufL4) MikMod_free(RVbufL4);
- if(RVbufL5) MikMod_free(RVbufL5);
- if(RVbufL6) MikMod_free(RVbufL6);
- if(RVbufL7) MikMod_free(RVbufL7);
- if(RVbufL8) MikMod_free(RVbufL8);
+ MikMod_free(RVbufL1);
+ MikMod_free(RVbufL2);
+ MikMod_free(RVbufL3);
+ MikMod_free(RVbufL4);
+ MikMod_free(RVbufL5);
+ MikMod_free(RVbufL6);
+ MikMod_free(RVbufL7);
+ MikMod_free(RVbufL8);
RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL;
- if(RVbufR1) MikMod_free(RVbufR1);
- if(RVbufR2) MikMod_free(RVbufR2);
- if(RVbufR3) MikMod_free(RVbufR3);
- if(RVbufR4) MikMod_free(RVbufR4);
- if(RVbufR5) MikMod_free(RVbufR5);
- if(RVbufR6) MikMod_free(RVbufR6);
- if(RVbufR7) MikMod_free(RVbufR7);
- if(RVbufR8) MikMod_free(RVbufR8);
+ MikMod_free(RVbufR1);
+ MikMod_free(RVbufR2);
+ MikMod_free(RVbufR3);
+ MikMod_free(RVbufR4);
+ MikMod_free(RVbufR5);
+ MikMod_free(RVbufR6);
+ MikMod_free(RVbufR7);
+ MikMod_free(RVbufR8);
RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL;
}
@@ -1305,8 +1337,8 @@ int VC1_SetNumVoices(void)
if(!(vc_softchn=md_softchn)) return 0;
- if(vinf) MikMod_free(vinf);
- if(!(vinf= MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1;
+ MikMod_free(vinf);
+ if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1;
for(t=0;t<vc_softchn;t++) {
vinf[t].frq=10000;
diff --git a/apps/plugins/mikmod/virtch2.c b/apps/plugins/mikmod/virtch2.c
new file mode 100644
index 0000000000..d512833bbe
--- /dev/null
+++ b/apps/plugins/mikmod/virtch2.c
@@ -0,0 +1,1370 @@
+/* MikMod sound library
+ (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
+ complete list.
+
+ This library is free software; you can redistribute it and/or modify
+ 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
+ 02111-1307, USA.
+*/
+
+/*==============================================================================
+
+ $Id$
+
+ High-quality sample mixing routines, using a 32 bits mixing buffer,
+ interpolation, and sample smoothing to improve sound quality and remove
+ clicks.
+
+==============================================================================*/
+
+/*
+
+ Future Additions:
+ Low-Pass filter to remove annoying staticy buzz.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mikmod.h"
+
+#ifndef NO_HQMIXER
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <string.h>
+
+#include "mikmod_internals.h"
+
+/*
+ Constant Definitions
+ ====================
+
+ MAXVOL_FACTOR (was BITSHIFT in virtch.c)
+ Controls the maximum volume of the output data. All mixed data is
+ divided by this number after mixing, so larger numbers result in
+ quieter mixing. Smaller numbers will increase the likeliness of
+ distortion on loud modules.
+
+ REVERBERATION
+ Larger numbers result in shorter reverb duration. Longer reverb
+ durations can cause unwanted static and make the reverb sound more
+ like a crappy echo.
+
+ SAMPLING_SHIFT
+ Specified the shift multiplier which controls by how much the mixing
+ rate is multiplied while mixing. Higher values can improve quality by
+ smoothing the sound and reducing pops and clicks. Note, this is a shift
+ value, so a value of 2 becomes a mixing-rate multiplier of 4, and a
+ value of 3 = 8, etc.
+
+ FRACBITS
+ The number of bits per integer devoted to the fractional part of the
+ number. Generally, this number should not be changed for any reason.
+
+ !!! IMPORTANT !!! All values below MUST ALWAYS be greater than 0
+
+*/
+
+#define BITSHIFT 9
+#define MAXVOL_FACTOR (1<<BITSHIFT)
+#define REVERBERATION 11000L
+
+#define SAMPLING_SHIFT 2
+#define SAMPLING_FACTOR (1UL<<SAMPLING_SHIFT)
+
+#define FRACBITS 28
+#define FRACMASK ((1UL<<FRACBITS)-1UL)
+
+#define TICKLSIZE 8192
+#define TICKWSIZE (TICKLSIZE * 2)
+#define TICKBSIZE (TICKWSIZE * 2)
+
+#define CLICK_SHIFT_BASE 6
+#define CLICK_SHIFT (CLICK_SHIFT_BASE + SAMPLING_SHIFT)
+#define CLICK_BUFFER (1L << CLICK_SHIFT)
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b)) ? (a) : (b))
+#endif
+
+typedef struct VINFO {
+ UBYTE kick; /* =1 -> sample has to be restarted */
+ UBYTE active; /* =1 -> sample is playing */
+ UWORD flags; /* 16/8 bits looping/one-shot */
+ SWORD handle; /* identifies the sample */
+ ULONG start; /* start index */
+ ULONG size; /* samplesize */
+ ULONG reppos; /* loop start */
+ ULONG repend; /* loop end */
+ ULONG frq; /* current frequency */
+ int vol; /* current volume */
+ int pan; /* current panning position */
+
+ int click;
+ int rampvol;
+ SLONG lastvalL,lastvalR;
+ int lvolsel,rvolsel; /* Volume factor in range 0-255 */
+ int oldlvol,oldrvol;
+
+ SLONGLONG current; /* current index in the sample */
+ SLONGLONG increment; /* increment value */
+} VINFO;
+
+static SWORD **Samples;
+static VINFO *vinf=NULL,*vnf;
+static long tickleft,samplesthatfit,vc_memory=0;
+static int vc_softchn;
+static SLONGLONG idxsize,idxlpos,idxlend;
+static SLONG *vc_tickbuf=NULL;
+static UWORD vc_mode;
+
+#ifdef _MSC_VER
+/* Weird bug in compiler */ /* FIXME is this still needed? */
+typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
+#endif
+
+/* Reverb control variables */
+
+static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8;
+static ULONG RVRindex;
+
+/* For Mono or Left Channel */
+static SLONG *RVbufL1=NULL,*RVbufL2=NULL,*RVbufL3=NULL,*RVbufL4=NULL,
+ *RVbufL5=NULL,*RVbufL6=NULL,*RVbufL7=NULL,*RVbufL8=NULL;
+
+/* For Stereo only (Right Channel) */
+static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL,
+ *RVbufR5=NULL,*RVbufR6=NULL,*RVbufR7=NULL,*RVbufR8=NULL;
+
+#ifdef NATIVE_64BIT_INT
+#define NATIVE SLONGLONG
+#else
+#define NATIVE SLONG
+#endif
+
+/*========== 32 bit sample mixers - only for 32 bit platforms */
+#ifndef NATIVE_64BIT_INT
+
+static SLONG Mix32MonoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
+{
+ SWORD sample=0;
+ SLONG i,f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)( (((SLONG)(srce[i]*(FRACMASK+1L-f)) +
+ ((SLONG)srce[i+1]*f)) >> FRACBITS));
+ idx+=increment;
+
+ if(vnf->rampvol) {
+ *dest++ += (long)(
+ ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) *
+ (SLONG)sample ) >> CLICK_SHIFT );
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ *dest++ += (long)(
+ ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONG)sample ) +
+ (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT );
+ vnf->click--;
+ } else
+ *dest++ +=vnf->lvolsel*sample;
+ }
+ vnf->lastvalL=vnf->lvolsel * sample;
+
+ return idx;
+}
+
+static SLONG Mix32StereoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo)
+{
+ SWORD sample=0;
+ SLONG i,f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONG)srce[i+1] * f)) >> FRACBITS));
+ idx += increment;
+
+ if(vnf->rampvol) {
+ *dest++ += (long)(
+ ( ( ((SLONG)vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONG)sample ) >> CLICK_SHIFT );
+ *dest++ += (long)(
+ ( ( ((SLONG)vnf->oldrvol*vnf->rampvol) +
+ (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONG)sample ) >> CLICK_SHIFT );
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ *dest++ += (long)(
+ ( ( (SLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONG)sample ) + (vnf->lastvalL * vnf->click) )
+ >> CLICK_SHIFT );
+ *dest++ += (long)(
+ ( ( ((SLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONG)sample ) + (vnf->lastvalR * vnf->click) )
+ >> CLICK_SHIFT );
+ vnf->click--;
+ } else {
+ *dest++ +=vnf->lvolsel*sample;
+ *dest++ +=vnf->rvolsel*sample;
+ }
+ }
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->rvolsel*sample;
+
+ return idx;
+}
+
+static SLONG Mix32StereoSurround(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo)
+{
+ SWORD sample=0;
+ long whoop;
+ SLONG i, f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONG)srce[i+1]*f)) >> FRACBITS));
+ idx+=increment;
+
+ if(vnf->rampvol) {
+ whoop=(long)(
+ ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) *
+ (SLONG)sample) >> CLICK_SHIFT );
+ *dest++ +=whoop;
+ *dest++ -=whoop;
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ whoop = (long)(
+ ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONG)sample) +
+ (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT );
+ *dest++ +=whoop;
+ *dest++ -=whoop;
+ vnf->click--;
+ } else {
+ *dest++ +=vnf->lvolsel*sample;
+ *dest++ -=vnf->lvolsel*sample;
+ }
+ }
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->lvolsel*sample;
+
+ return idx;
+}
+#endif
+
+/*========== 64 bit mixers */
+
+static SLONGLONG MixMonoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
+{
+ SWORD sample=0;
+ SLONGLONG i,f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)((((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
+ idx+=increment;
+
+ if(vnf->rampvol) {
+ *dest++ += (long)(
+ ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) *
+ (SLONGLONG)sample ) >> CLICK_SHIFT );
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample ) +
+ (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT );
+ vnf->click--;
+ } else
+ *dest++ +=vnf->lvolsel*sample;
+ }
+ vnf->lastvalL=vnf->lvolsel * sample;
+
+ return idx;
+}
+
+/* Slowest part... */
+
+#if defined HAVE_SSE2 || defined HAVE_ALTIVEC
+
+static __inline SWORD GetSample(const SWORD* const srce, SLONGLONG idx)
+{
+ SLONGLONG i=idx>>FRACBITS;
+ SLONGLONG f=idx&FRACMASK;
+ return (SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
+}
+
+static SLONGLONG MixSIMDStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
+{
+ SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel};
+ SWORD sample=0;
+ SLONG remain = todo;
+
+ /* Dest can be misaligned */
+ while(!IS_ALIGNED_16(dest)) {
+ sample=srce[idx >> FRACBITS];
+ idx += increment;
+ *dest++ += vol[0] * sample;
+ *dest++ += vol[1] * sample;
+ todo--;
+ if(!todo) goto end;
+ }
+
+ /* Srce is always aligned */
+
+#if defined HAVE_SSE2
+ remain = todo&3;
+ {
+ __m128i v0 = _mm_set_epi16(0, vol[1],
+ 0, vol[0],
+ 0, vol[1],
+ 0, vol[0]);
+ for(todo>>=2;todo; todo--)
+ {
+ SWORD s0 = GetSample(srce, idx);
+ SWORD s1 = GetSample(srce, idx += increment);
+ SWORD s2 = GetSample(srce, idx += increment);
+ SWORD s3 = GetSample(srce, idx += increment);
+ __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0);
+ __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2);
+ __m128i v3 = _mm_load_si128((__m128i*)(dest+0));
+ __m128i v4 = _mm_load_si128((__m128i*)(dest+4));
+ _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1)));
+ _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2)));
+ dest+=8;
+ idx += increment;
+ }
+ }
+
+#elif defined HAVE_ALTIVEC
+ remain = todo&3;
+ {
+ SWORD s[8];
+ vector signed short r0 = vec_ld(0, vol);
+ vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */
+ 0, 1, /* l */
+ 2, 3, /* r */
+ 2, 1, /* r */
+ 0, 1, /* l */
+ 0, 1, /* l */
+ 2, 3, /* r */
+ 2, 3 /* r */
+ ));
+
+ for(todo>>=2;todo; todo--)
+ {
+ vector short int r1;
+ vector signed short v1, v2;
+ vector signed int v3, v4, v5, v6;
+
+ /* Load constants */
+ s[0] = GetSample(srce, idx);
+ s[1] = GetSample(srce, idx += increment);
+ s[2] = GetSample(srce, idx += increment);
+ s[3] = GetSample(srce, idx += increment);
+ s[4] = 0;
+
+ r1 = vec_ld(0, s);
+ v1 = vec_perm(r1, r1, (vector unsigned char)
+ (0*2, 0*2+1, /* s0 */
+ 4*2, 4*2+1, /* 0 */
+ 0*2, 0*2+1, /* s0 */
+ 4*2, 4*2+1, /* 0 */
+ 1*2, 1*2+1, /* s1 */
+ 4*2, 4*2+1, /* 0 */
+ 1*2, 1*2+1, /* s1 */
+ 4*2, 4*2+1 /* 0 */
+ ) );
+ v2 = vec_perm(r1, r1, (vector unsigned char)
+ (2*2, 2*2+1, /* s2 */
+ 4*2, 4*2+1, /* 0 */
+ 2*2, 2*2+1, /* s2 */
+ 4*2, 4*2+1, /* 0 */
+ 3*2, 3*2+1, /* s3 */
+ 4*2, 4*2+1, /* 0 */
+ 3*2, 3*2+1, /* s3 */
+ 4*2, 4*2+1 /* 0 */
+ ) );
+
+ v3 = vec_ld(0, dest);
+ v4 = vec_ld(0x10, dest);
+ v5 = vec_mule(v0, v1);
+ v6 = vec_mule(v0, v2);
+
+ vec_st(vec_add(v3, v5), 0, dest);
+ vec_st(vec_add(v4, v6), 0x10, dest);
+
+ dest+=8;
+ idx += increment;
+ }
+ }
+#endif /* HAVE_ALTIVEC */
+
+ /* Remaining bits */
+ while(remain--) {
+ sample=GetSample(srce, idx);
+ idx+= increment;
+ *dest++ += vol[0] * sample;
+ *dest++ += vol[1] * sample;
+ }
+end:
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->rvolsel*sample;
+ return idx;
+}
+
+static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
+{
+ SWORD sample=0;
+ SLONGLONG i,f;
+
+ if (vnf->rampvol)
+ while(todo) {
+ todo--;
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
+ idx += increment;
+
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONGLONG)sample ) >> CLICK_SHIFT );
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) +
+ (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONGLONG)sample ) >> CLICK_SHIFT );
+ vnf->rampvol--;
+
+ if (!vnf->rampvol)
+ break;
+ }
+
+ if (vnf->click)
+ while(todo) {
+ todo--;
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
+ idx += increment;
+
+ *dest++ += (long)(
+ ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) )
+ >> CLICK_SHIFT );
+
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) )
+ >> CLICK_SHIFT );
+ vnf->click--;
+
+ if (!vnf->click)
+ break;
+ }
+
+ if (todo)
+ {
+ if (md_mode & DMODE_SIMDMIXER) {
+ return MixSIMDStereoNormal(srce, dest, idx, increment, todo);
+ }
+ while(todo)
+ {
+ i=idx>>FRACBITS,
+ f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
+ idx += increment;
+
+ *dest++ +=vnf->lvolsel*sample;
+ *dest++ +=vnf->rvolsel*sample;
+ todo--;
+ }
+ }
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->rvolsel*sample;
+
+ return idx;
+}
+
+#else /* HAVE_SSE2 || HAVE_ALTIVEC */
+static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
+{
+ SWORD sample=0;
+ SLONGLONG i,f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
+ idx += increment;
+
+ if(vnf->rampvol) {
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONGLONG)sample ) >> CLICK_SHIFT );
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) +
+ (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol))
+ ) * (SLONGLONG)sample ) >> CLICK_SHIFT );
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ *dest++ += (long)(
+ ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) )
+ >> CLICK_SHIFT );
+ *dest++ += (long)(
+ ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) )
+ >> CLICK_SHIFT );
+ vnf->click--;
+ } else {
+ *dest++ +=vnf->lvolsel*sample;
+ *dest++ +=vnf->rvolsel*sample;
+ }
+ }
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->rvolsel*sample;
+
+ return idx;
+}
+#endif /* HAVE_SSE2 || HAVE_ALTIVEC */
+
+
+static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
+{
+ SWORD sample=0;
+ long whoop;
+ SLONGLONG i, f;
+
+ while(todo--) {
+ i=idx>>FRACBITS,f=idx&FRACMASK;
+ sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
+ ((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
+ idx+=increment;
+
+ if(vnf->rampvol) {
+ whoop=(long)(
+ ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) +
+ (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) *
+ (SLONGLONG)sample) >> CLICK_SHIFT );
+ *dest++ +=whoop;
+ *dest++ -=whoop;
+ vnf->rampvol--;
+ } else
+ if(vnf->click) {
+ whoop = (long)(
+ ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
+ (SLONGLONG)sample) +
+ (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT );
+ *dest++ +=whoop;
+ *dest++ -=whoop;
+ vnf->click--;
+ } else {
+ *dest++ +=vnf->lvolsel*sample;
+ *dest++ -=vnf->lvolsel*sample;
+ }
+ }
+ vnf->lastvalL=vnf->lvolsel*sample;
+ vnf->lastvalR=vnf->lvolsel*sample;
+
+ return idx;
+}
+
+static void(*Mix32toFP)(float* dste,const SLONG *srce,NATIVE count);
+static void(*Mix32to16)(SWORD* dste,const SLONG *srce,NATIVE count);
+static void(*Mix32to8)(SBYTE* dste,const SLONG *srce,NATIVE count);
+static void(*MixReverb)(SLONG *srce,NATIVE count);
+
+/* Reverb macros */
+#define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n
+#define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7)
+#define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7)
+
+static void MixReverb_Normal(SLONG *srce,NATIVE count)
+{
+ NATIVE speedup;
+ int ReverbPct;
+ unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8;
+
+ ReverbPct=58+(md_reverb*4);
+
+ COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4);
+ COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8);
+
+ while(count--) {
+ /* Compute the left channel echo buffers */
+ speedup = *srce >> 3;
+
+ COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4);
+ COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8);
+
+ /* Prepare to compute actual finalized data */
+ RVRindex++;
+
+ COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4);
+ COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8);
+
+ /* left channel */
+ *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
+ RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
+ }
+}
+
+static void MixReverb_Stereo(SLONG *srce,NATIVE count)
+{
+ NATIVE speedup;
+ int ReverbPct;
+ unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8;
+
+ ReverbPct=58+(md_reverb*4);
+
+ COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4);
+ COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8);
+
+ while(count--) {
+ /* Compute the left channel echo buffers */
+ speedup = *srce >> 3;
+
+ COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4);
+ COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8);
+
+ /* Compute the right channel echo buffers */
+ speedup = srce[1] >> 3;
+
+ COMPUTE_RECHO(1); COMPUTE_RECHO(2); COMPUTE_RECHO(3); COMPUTE_RECHO(4);
+ COMPUTE_RECHO(5); COMPUTE_RECHO(6); COMPUTE_RECHO(7); COMPUTE_RECHO(8);
+
+ /* Prepare to compute actual finalized data */
+ RVRindex++;
+
+ COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4);
+ COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8);
+
+ /* left channel */
+ *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
+ RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
+
+ /* right channel */
+ *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+
+ RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
+ }
+}
+
+static void (*MixLowPass)(SLONG* srce,NATIVE count);
+
+static int nLeftNR, nRightNR;
+
+static void MixLowPass_Stereo(SLONG* srce,NATIVE count)
+{
+ int n1 = nLeftNR, n2 = nRightNR;
+ SLONG *pnr = srce;
+ int nr=count;
+ for (; nr; nr--)
+ {
+ int vnr = pnr[0] >> 1;
+ pnr[0] = vnr + n1;
+ n1 = vnr;
+ vnr = pnr[1] >> 1;
+ pnr[1] = vnr + n2;
+ n2 = vnr;
+ pnr += 2;
+ }
+ nLeftNR = n1;
+ nRightNR = n2;
+}
+
+static void MixLowPass_Normal(SLONG* srce,NATIVE count)
+{
+ int n1 = nLeftNR;
+ SLONG *pnr = srce;
+ int nr=count;
+ for (; nr; nr--)
+ {
+ int vnr = pnr[0] >> 1;
+ pnr[0] = vnr + n1;
+ n1 = vnr;
+ pnr ++;
+ }
+ nLeftNR = n1;
+}
+
+/* Mixing macros */
+#define EXTRACT_SAMPLE_FP(var,attenuation) var=*srce++*((1.0f / 32768.0f) / (MAXVOL_FACTOR*attenuation))
+#define CHECK_SAMPLE_FP(var,bound) var=(var>bound)?bound:(var<-bound)?-bound:var
+
+static void Mix32ToFP_Normal(float* dste,const SLONG *srce,NATIVE count)
+{
+ float x1,x2,tmpx;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx=0.0f;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
+
+ CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
+
+ tmpx+=x1+x2;
+ }
+ *dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
+ }
+}
+
+static void Mix32ToFP_Stereo(float* dste,const SLONG *srce,NATIVE count)
+{
+ float x1,x2,x3,x4,tmpx,tmpy;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx=tmpy=0.0f;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
+ EXTRACT_SAMPLE_FP(x3,1.0f); EXTRACT_SAMPLE_FP(x4,1.0f);
+
+ CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
+ CHECK_SAMPLE_FP(x3,1.0f); CHECK_SAMPLE_FP(x4,1.0f);
+
+ tmpx+=x1+x3;
+ tmpy+=x2+x4;
+ }
+ *dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
+ *dste++ =tmpy*(1.0f/SAMPLING_FACTOR);
+ }
+}
+
+/* Mixing macros */
+#define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation)
+#define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var
+
+static void Mix32To16_Normal(SWORD* dste,const SLONG *srce,NATIVE count)
+{
+ NATIVE x1,x2,tmpx;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx=0;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1);
+
+ CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768);
+
+ tmpx+=x1+x2;
+ }
+ *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR);
+ }
+}
+
+
+static void Mix32To16_Stereo(SWORD* dste,const SLONG *srce,NATIVE count)
+{
+ NATIVE x1,x2,x3,x4,tmpx,tmpy;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx=tmpy=0;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1);
+ EXTRACT_SAMPLE(x3,1); EXTRACT_SAMPLE(x4,1);
+
+ CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768);
+ CHECK_SAMPLE(x3,32768); CHECK_SAMPLE(x4,32768);
+
+ tmpx+=x1+x3;
+ tmpy+=x2+x4;
+ }
+ *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR);
+ *dste++ =(SWORD)(tmpy/SAMPLING_FACTOR);
+ }
+}
+
+static void Mix32To8_Normal(SBYTE* dste,const SLONG *srce,NATIVE count)
+{
+ NATIVE x1,x2,tmpx;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx = 0;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256);
+
+ CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128);
+
+ tmpx+=x1+x2;
+ }
+ *dste++ = (SBYTE)((tmpx/SAMPLING_FACTOR)+128);
+ }
+}
+
+static void Mix32To8_Stereo(SBYTE* dste,const SLONG *srce,NATIVE count)
+{
+ NATIVE x1,x2,x3,x4,tmpx,tmpy;
+ int i;
+
+ for(count/=SAMPLING_FACTOR;count;count--) {
+ tmpx=tmpy=0;
+
+ for(i=SAMPLING_FACTOR/2;i;i--) {
+ EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256);
+ EXTRACT_SAMPLE(x3,256); EXTRACT_SAMPLE(x4,256);
+
+ CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128);
+ CHECK_SAMPLE(x3,128); CHECK_SAMPLE(x4,128);
+
+ tmpx+=x1+x3;
+ tmpy+=x2+x4;
+ }
+ *dste++ =(SBYTE)((tmpx/SAMPLING_FACTOR)+128);
+ *dste++ =(SBYTE)((tmpy/SAMPLING_FACTOR)+128);
+ }
+}
+
+#if defined HAVE_SSE2
+#define SHIFT_MIX_TO_16 (BITSHIFT + 16 - 16)
+/* TEST: Ok */
+static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
+{
+ int remain = count;
+
+ /* Check unaligned dste buffer. srce is always aligned. */
+ while(!IS_ALIGNED_16(dste))
+ {
+ Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
+ dste+=2;
+ srce+=8;
+ count--;
+ if(!count) return;
+ }
+
+ /* dste and srce aligned. srce is always aligned. */
+ remain = count & 15;
+ /* count / 2 for 1 sample */
+
+ for(count>>=4;count;count--)
+ {
+ /* Load 32bit sample. 1st average */
+ __m128i v0 = _mm_add_epi32(
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+0)), SHIFT_MIX_TO_16),
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+4)), SHIFT_MIX_TO_16)
+ ); /* v0: s0.l+s2.l | s0.r+s2.r | s1.l+s3.l | s1.r+s3.r */
+
+ /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
+ __m128i v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
+ /* v1: s0.l+s2.l / 4 | s0.r+s2.r / 4 | s1.l+s3.l+s0.l+s2.l / 4 | s1.r+s3.r+s0.r+s2.r / 4 */
+
+ __m128i v2 = _mm_add_epi32(
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+8)), SHIFT_MIX_TO_16),
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+12)), SHIFT_MIX_TO_16)
+ ); /* v2: s4.l+s6.l | s4.r+s6.r | s5.l+s7.l | s5.r+s7.r */
+
+ __m128i v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
+ /* v3: s4.l+s6.l /4 | s4.r+s6.r / 4| s5.l+s7.l+s4.l+s6.l / 4 | s5.r+s7.r+s4.r+s6.l / 4 */
+
+ /* pack two stereo samples in one */
+ __m128i v4 = _mm_unpacklo_epi64(v1, v3); /* v4 = avg(s0,s1,s2,s3) | avg(s4,s5,s6,s7) */
+
+ __m128i v6;
+
+ /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
+ v0 = _mm_add_epi32(
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+16)), SHIFT_MIX_TO_16),
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+20)), SHIFT_MIX_TO_16)
+ ); /* 128bit = 2 stereo samples */
+
+ /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
+ v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
+
+ v2 = _mm_add_epi32(
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+24)), SHIFT_MIX_TO_16),
+ _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+28)), SHIFT_MIX_TO_16)
+ );
+
+ v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
+
+ /* pack two stereo samples in one */
+ v6 = _mm_unpacklo_epi64(v1, v3); /* v6 = avg(s8,s9,s10,s11) | avg(s12,s13,s14,s15) */
+
+ _mm_store_si128((__m128i*)dste, _mm_packs_epi32(v4, v6)); /* 4 interpolated stereo sample 32bit to 4 */
+
+ dste+=8;
+ srce+=32; /* 32 = 4 * 8 */
+ }
+
+ /* FIXME: THIS PART WRITES PAST DST !! */
+ if (remain)
+ {
+ Mix32To16_Stereo(dste, srce, remain);
+ }
+}
+
+#elif defined HAVE_ALTIVEC
+#define SHIFT_MIX_TO_16 vec_splat_u32(BITSHIFT + 16 - 16)
+/* TEST: Ok */
+static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
+{
+ int remain = count;
+
+ /* Check unaligned dste buffer. srce is always aligned. */
+ while(!IS_ALIGNED_16(dste))
+ {
+ Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
+ dste+=2;
+ srce+=8;
+ count--;
+ if(!count) return;
+ }
+
+ /* dste and srce aligned. srce is always aligned. */
+ remain = count & 15;
+ for(count>>=4;count;count--)
+ {
+ /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
+ vector signed int v0 = vec_add(
+ vec_sra(vec_ld(0, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
+ vec_sra(vec_ld(0x10, srce), SHIFT_MIX_TO_16)
+ ); /* 128bit = 2 stereo samples */
+
+ /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
+ vector signed int v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
+
+ vector signed int v2 = vec_add(
+ vec_sra(vec_ld(0x20, srce), SHIFT_MIX_TO_16),
+ vec_sra(vec_ld(0x30, srce), SHIFT_MIX_TO_16)
+ );
+
+ vector signed int v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
+
+ /* pack two stereo samples in one */
+ vector signed int v6, v4 = vec_unpacklo(v1, v3); /* v4 = lo64(v1) | lo64(v3) */
+
+ /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
+ v0 = vec_add(
+ vec_sra(vec_ld(0x40, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
+ vec_sra(vec_ld(0x50, srce), SHIFT_MIX_TO_16)
+ ); /* 128bit = 2 stereo samples */
+
+ /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
+ v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
+
+ v2 = vec_add(
+ vec_sra(vec_ld(0x60, srce), SHIFT_MIX_TO_16),
+ vec_sra(vec_ld(0x70, srce), SHIFT_MIX_TO_16)
+ );
+
+ v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
+
+ /* pack two stereo samples in one */
+ v6 = vec_unpacklo(v1, v3);
+
+ vec_st(vec_packs(v4, v6), 0, dste); /* 4 interpolated stereo sample 32bit to 4 interpolated stereo sample 16bit + saturation */
+
+ dste+=8;
+ srce+=32; /* 32 = 4 * 8 */
+ }
+
+ if (remain)
+ {
+ Mix32To16_Stereo(dste, srce, remain);
+ }
+}
+
+#endif
+
+
+static void AddChannel(SLONG* ptr,NATIVE todo)
+{
+ SLONGLONG end,done;
+ SWORD *s;
+
+ if(!(s=Samples[vnf->handle])) {
+ vnf->current = vnf->active = 0;
+ vnf->lastvalL = vnf->lastvalR = 0;
+ return;
+ }
+
+ /* update the 'current' index so the sample loops, or stops playing if it
+ reached the end of the sample */
+ while(todo>0) {
+ SLONGLONG endpos;
+
+ if(vnf->flags & SF_REVERSE) {
+ /* The sample is playing in reverse */
+ if((vnf->flags&SF_LOOP)&&(vnf->current<idxlpos)) {
+ /* the sample is looping and has reached the loopstart index */
+ if(vnf->flags & SF_BIDI) {
+ /* sample is doing bidirectional loops, so 'bounce' the
+ current index against the idxlpos */
+ vnf->current = idxlpos+(idxlpos-vnf->current);
+ vnf->flags &= ~SF_REVERSE;
+ vnf->increment = -vnf->increment;
+ } else
+ /* normal backwards looping, so set the current position to
+ loopend index */
+ vnf->current=idxlend-(idxlpos-vnf->current);
+ } else {
+ /* the sample is not looping, so check if it reached index 0 */
+ if(vnf->current < 0) {
+ /* playing index reached 0, so stop playing this sample */
+ vnf->current = vnf->active = 0;
+ break;
+ }
+ }
+ } else {
+ /* The sample is playing forward */
+ if((vnf->flags & SF_LOOP) &&
+ (vnf->current >= idxlend)) {
+ /* the sample is looping, check the loopend index */
+ if(vnf->flags & SF_BIDI) {
+ /* sample is doing bidirectional loops, so 'bounce' the
+ current index against the idxlend */
+ vnf->flags |= SF_REVERSE;
+ vnf->increment = -vnf->increment;
+ vnf->current = idxlend-(vnf->current-idxlend);
+ } else
+ /* normal backwards looping, so set the current position
+ to loopend index */
+ vnf->current=idxlpos+(vnf->current-idxlend);
+ } else {
+ /* sample is not looping, so check if it reached the last
+ position */
+ if(vnf->current >= idxsize) {
+ /* yes, so stop playing this sample */
+ vnf->current = vnf->active = 0;
+ break;
+ }
+ }
+ }
+
+ end=(vnf->flags&SF_REVERSE)?(vnf->flags&SF_LOOP)?idxlpos:0:
+ (vnf->flags&SF_LOOP)?idxlend:idxsize;
+
+ /* if the sample is not blocked... */
+ if((end==vnf->current)||(!vnf->increment))
+ done=0;
+ else {
+ done=MIN((end-vnf->current)/vnf->increment+1,todo);
+ if(done<0) done=0;
+ }
+
+ if(!done) {
+ vnf->active = 0;
+ break;
+ }
+
+ endpos=vnf->current+done*vnf->increment;
+
+ if(vnf->vol || vnf->rampvol) {
+#ifndef NATIVE_64BIT_INT
+ /* use the 32 bit mixers as often as we can (they're much faster) */
+ if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) {
+ if(vc_mode & DMODE_STEREO) {
+ if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND))
+ vnf->current=(SLONGLONG)Mix32StereoSurround
+ (s,ptr,vnf->current,vnf->increment,done);
+ else
+ vnf->current=Mix32StereoNormal
+ (s,ptr,vnf->current,vnf->increment,done);
+ } else
+ vnf->current=Mix32MonoNormal
+ (s,ptr,vnf->current,vnf->increment,done);
+ }
+ else
+#endif
+ {
+ if(vc_mode & DMODE_STEREO) {
+ if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND))
+ vnf->current=MixStereoSurround
+ (s,ptr,vnf->current,vnf->increment,done);
+ else
+ vnf->current=MixStereoNormal
+ (s,ptr,vnf->current,vnf->increment,done);
+ } else
+ vnf->current=MixMonoNormal
+ (s,ptr,vnf->current,vnf->increment,done);
+ }
+ } else {
+ vnf->lastvalL = vnf->lastvalR = 0;
+ /* update sample position */
+ vnf->current=endpos;
+ }
+
+ todo -= done;
+ ptr += (vc_mode & DMODE_STEREO)?(done<<1):done;
+ }
+}
+
+#define _IN_VIRTCH_
+
+#define VC1_SilenceBytes VC2_SilenceBytes
+#define VC1_WriteSamples VC2_WriteSamples
+#define VC1_WriteBytes VC2_WriteBytes
+#define VC1_Exit VC2_Exit
+#define VC1_VoiceSetVolume VC2_VoiceSetVolume
+#define VC1_VoiceGetVolume VC2_VoiceGetVolume
+#define VC1_VoiceSetPanning VC2_VoiceSetPanning
+#define VC1_VoiceGetPanning VC2_VoiceGetPanning
+#define VC1_VoiceSetFrequency VC2_VoiceSetFrequency
+#define VC1_VoiceGetFrequency VC2_VoiceGetFrequency
+#define VC1_VoicePlay VC2_VoicePlay
+#define VC1_VoiceStop VC2_VoiceStop
+#define VC1_VoiceStopped VC2_VoiceStopped
+#define VC1_VoiceGetPosition VC2_VoiceGetPosition
+#define VC1_SampleUnload VC2_SampleUnload
+#define VC1_SampleLoad VC2_SampleLoad
+#define VC1_SampleSpace VC2_SampleSpace
+#define VC1_SampleLength VC2_SampleLength
+#define VC1_VoiceRealVolume VC2_VoiceRealVolume
+
+#include "virtch_common.c"
+#undef _IN_VIRTCH_
+
+void VC2_WriteSamples(SBYTE* buf,ULONG todo)
+{
+ int left,portion=0;
+ SBYTE *buffer;
+ int t,pan,vol;
+
+ todo*=SAMPLING_FACTOR;
+
+ while(todo) {
+ if(!tickleft) {
+ if(vc_mode & DMODE_SOFT_MUSIC) md_player();
+ tickleft=(md_mixfreq*125L*SAMPLING_FACTOR)/(md_bpm*50L);
+ tickleft&=~(SAMPLING_FACTOR-1);
+ }
+ left = MIN(tickleft, (int)todo);
+ buffer = buf;
+ tickleft -= left;
+ todo -= left;
+ buf += samples2bytes(left)/SAMPLING_FACTOR;
+
+ while(left) {
+ portion = MIN(left, samplesthatfit);
+ memset(vc_tickbuf,0,portion<<((vc_mode&DMODE_STEREO)?3:2));
+ for(t=0;t<vc_softchn;t++) {
+ vnf = &vinf[t];
+
+ if(vnf->kick) {
+ vnf->current=((SLONGLONG)(vnf->start))<<FRACBITS;
+ vnf->kick = 0;
+ vnf->active = 1;
+ vnf->click = CLICK_BUFFER;
+ vnf->rampvol = 0;
+ }
+
+ if(!vnf->frq) vnf->active = 0;
+
+ if(vnf->active) {
+ vnf->increment=((SLONGLONG)(vnf->frq)<<(FRACBITS-SAMPLING_SHIFT))
+ /md_mixfreq;
+ if(vnf->flags&SF_REVERSE) vnf->increment=-vnf->increment;
+ vol = vnf->vol; pan = vnf->pan;
+
+ vnf->oldlvol=vnf->lvolsel;vnf->oldrvol=vnf->rvolsel;
+ if(vc_mode & DMODE_STEREO) {
+ if(pan!=PAN_SURROUND) {
+ vnf->lvolsel=(vol*(PAN_RIGHT-pan))>>8;
+ vnf->rvolsel=(vol*pan)>>8;
+ } else {
+ vnf->lvolsel=vnf->rvolsel=(vol * 256L) / 480;
+ }
+ } else
+ vnf->lvolsel=vol;
+
+ idxsize=(vnf->size)?((SLONGLONG)(vnf->size)<<FRACBITS)-1:0;
+ idxlend=(vnf->repend)?((SLONGLONG)(vnf->repend)<<FRACBITS)-1:0;
+ idxlpos=(SLONGLONG)(vnf->reppos)<<FRACBITS;
+ AddChannel(vc_tickbuf,portion);
+ }
+ }
+
+ if(md_mode & DMODE_NOISEREDUCTION) {
+ MixLowPass(vc_tickbuf, portion);
+ }
+
+ if(md_reverb) {
+ if(md_reverb>15) md_reverb=15;
+ MixReverb(vc_tickbuf,portion);
+ }
+
+ if (vc_callback) {
+ vc_callback((unsigned char*)vc_tickbuf, portion);
+ }
+
+ if(vc_mode & DMODE_FLOAT)
+ Mix32toFP((float*)buffer,vc_tickbuf,portion);
+ else if(vc_mode & DMODE_16BITS)
+ Mix32to16((SWORD*)buffer,vc_tickbuf,portion);
+ else
+ Mix32to8((SBYTE*)buffer,vc_tickbuf,portion);
+
+ buffer += samples2bytes(portion) / SAMPLING_FACTOR;
+ left -= portion;
+ }
+ }
+}
+
+int VC2_Init(void)
+{
+ VC_SetupPointers();
+
+ if (!(md_mode&DMODE_HQMIXER))
+ return VC1_Init();
+
+ if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) {
+ _mm_errno = MMERR_INITIALIZING_MIXER;
+ return 1;
+ }
+ if(!vc_tickbuf) {
+ if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) {
+ _mm_errno = MMERR_INITIALIZING_MIXER;
+ return 1;
+ }
+ }
+
+ if(md_mode & DMODE_STEREO) {
+ Mix32toFP = Mix32ToFP_Stereo;
+#if ((defined HAVE_ALTIVEC || defined HAVE_SSE2) && (SAMPLING_FACTOR == 4))
+ if (md_mode & DMODE_SIMDMIXER)
+ Mix32to16 = Mix32To16_Stereo_SIMD_4Tap;
+ else
+#endif
+ Mix32to16 = Mix32To16_Stereo;
+ Mix32to8 = Mix32To8_Stereo;
+ MixReverb = MixReverb_Stereo;
+ MixLowPass = MixLowPass_Stereo;
+ } else {
+ Mix32toFP = Mix32ToFP_Normal;
+ Mix32to16 = Mix32To16_Normal;
+ Mix32to8 = Mix32To8_Normal;
+ MixReverb = MixReverb_Normal;
+ MixLowPass = MixLowPass_Normal;
+ }
+
+ md_mode |= DMODE_INTERP;
+ vc_mode = md_mode;
+ return 0;
+}
+
+int VC2_PlayStart(void)
+{
+ md_mode|=DMODE_INTERP;
+
+ samplesthatfit = TICKLSIZE;
+ if(vc_mode & DMODE_STEREO) samplesthatfit >>= 1;
+ tickleft = 0;
+
+ RVc1 = (5000L * md_mixfreq) / (REVERBERATION * 10);
+ RVc2 = (5078L * md_mixfreq) / (REVERBERATION * 10);
+ RVc3 = (5313L * md_mixfreq) / (REVERBERATION * 10);
+ RVc4 = (5703L * md_mixfreq) / (REVERBERATION * 10);
+ RVc5 = (6250L * md_mixfreq) / (REVERBERATION * 10);
+ RVc6 = (6953L * md_mixfreq) / (REVERBERATION * 10);
+ RVc7 = (7813L * md_mixfreq) / (REVERBERATION * 10);
+ RVc8 = (8828L * md_mixfreq) / (REVERBERATION * 10);
+
+ if(!(RVbufL1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
+
+ /* allocate reverb buffers for the right channel if in stereo mode only. */
+ if (vc_mode & DMODE_STEREO) {
+ if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
+ if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
+ }
+
+ RVRindex = 0;
+ return 0;
+}
+
+void VC2_PlayStop(void)
+{
+ MikMod_free(RVbufL1);
+ MikMod_free(RVbufL2);
+ MikMod_free(RVbufL3);
+ MikMod_free(RVbufL4);
+ MikMod_free(RVbufL5);
+ MikMod_free(RVbufL6);
+ MikMod_free(RVbufL7);
+ MikMod_free(RVbufL8);
+ MikMod_free(RVbufR1);
+ MikMod_free(RVbufR2);
+ MikMod_free(RVbufR3);
+ MikMod_free(RVbufR4);
+ MikMod_free(RVbufR5);
+ MikMod_free(RVbufR6);
+ MikMod_free(RVbufR7);
+ MikMod_free(RVbufR8);
+
+ RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL;
+ RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL;
+}
+
+int VC2_SetNumVoices(void)
+{
+ int t;
+
+ md_mode|=DMODE_INTERP;
+
+ if(!(vc_softchn=md_softchn)) return 0;
+
+ MikMod_free(vinf);
+ if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1;
+
+ for(t=0;t<vc_softchn;t++) {
+ vinf[t].frq=10000;
+ vinf[t].pan=(t&1)?PAN_LEFT:PAN_RIGHT;
+ }
+
+ return 0;
+}
+
+#endif /* ! NO_HQMIXER */
+
+/* ex:set ts=4: */
diff --git a/apps/plugins/mikmod/virtch_common.c b/apps/plugins/mikmod/virtch_common.c
index e13f6d1c51..3395120a47 100644
--- a/apps/plugins/mikmod/virtch_common.c
+++ b/apps/plugins/mikmod/virtch_common.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,90 +20,96 @@
/*==============================================================================
- $Id: virtch_common.c,v 1.2 2005/03/30 19:11:50 realtech Exp $
+ $Id$
Common source parts between the two software mixers.
This file is probably the ugliest part of libmikmod...
==============================================================================*/
-#ifndef _IN_VIRTCH_
-
+#if defined(HAVE_CONFIG_H) && !defined(_IN_VIRTCH_) /* config.h isn't guarded */
+#include "config.h"
+#endif
#include "mikmod_internals.h"
-extern int VC1_Init(void);
-//extern int VC2_Init(void);
-static int (*VC_Init_ptr)(void)=VC1_Init;
+#ifndef NO_HQMIXER
+extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
+extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
+extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
+extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
extern void VC1_Exit(void);
-//extern void VC2_Exit(void);
-static void (*VC_Exit_ptr)(void)=VC1_Exit;
-extern int VC1_SetNumVoices(void);
-//extern int VC2_SetNumVoices(void);
-static int (*VC_SetNumVoices_ptr)(void);
+extern void VC2_Exit(void);
+extern UWORD VC1_VoiceGetVolume(UBYTE);
+extern UWORD VC2_VoiceGetVolume(UBYTE);
+extern ULONG VC1_VoiceGetPanning(UBYTE);
+extern ULONG VC2_VoiceGetPanning(UBYTE);
+extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
+extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
+extern ULONG VC1_VoiceGetFrequency(UBYTE);
+extern ULONG VC2_VoiceGetFrequency(UBYTE);
+extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
+extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
+extern void VC1_VoiceStop(UBYTE);
+extern void VC2_VoiceStop(UBYTE);
+extern int VC1_VoiceStopped(UBYTE);
+extern int VC2_VoiceStopped(UBYTE);
+extern SLONG VC1_VoiceGetPosition(UBYTE);
+extern SLONG VC2_VoiceGetPosition(UBYTE);
+extern void VC1_VoiceSetVolume(UBYTE,UWORD);
+extern void VC2_VoiceSetVolume(UBYTE,UWORD);
+extern void VC1_VoiceSetPanning(UBYTE,ULONG);
+extern void VC2_VoiceSetPanning(UBYTE,ULONG);
+extern void VC1_SampleUnload(SWORD);
+extern void VC2_SampleUnload(SWORD);
+extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
+extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
extern ULONG VC1_SampleSpace(int);
-//extern ULONG VC2_SampleSpace(int);
-static ULONG (*VC_SampleSpace_ptr)(int);
+extern ULONG VC2_SampleSpace(int);
extern ULONG VC1_SampleLength(int,SAMPLE*);
-//extern ULONG VC2_SampleLength(int,SAMPLE*);
+extern ULONG VC2_SampleLength(int,SAMPLE*);
+extern ULONG VC1_VoiceRealVolume(UBYTE);
+extern ULONG VC2_VoiceRealVolume(UBYTE);
+#endif
+
+
+#ifndef _IN_VIRTCH_
+
+#ifndef NO_HQMIXER
+extern int VC1_Init(void);
+extern int VC2_Init(void);
+static int (*VC_Init_ptr)(void)=VC1_Init;
+static void (*VC_Exit_ptr)(void)=VC1_Exit;
+extern int VC1_SetNumVoices(void);
+extern int VC2_SetNumVoices(void);
+static int (*VC_SetNumVoices_ptr)(void);
+static ULONG (*VC_SampleSpace_ptr)(int);
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
-extern int VC1_PlayStart(void);
-//extern int VC2_PlayStart(void);
-static int (*VC_PlayStart_ptr)(void);
-extern void VC1_PlayStop(void);
+extern int VC2_PlayStart(void);
+static int (*VC_PlayStart_ptr)(void);
extern void VC2_PlayStop(void);
static void (*VC_PlayStop_ptr)(void);
-extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
-//extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
-extern void VC1_SampleUnload(SWORD);
-//extern void VC2_SampleUnload(SWORD);
static void (*VC_SampleUnload_ptr)(SWORD);
-extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
-//extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
-extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
-//extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
-extern void VC1_VoiceSetVolume(UBYTE,UWORD);
-//extern void VC2_VoiceSetVolume(UBYTE,UWORD);
static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
-extern UWORD VC1_VoiceGetVolume(UBYTE);
-//extern UWORD VC2_VoiceGetVolume(UBYTE);
static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
-extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
-//extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
-extern ULONG VC1_VoiceGetFrequency(UBYTE);
-//extern ULONG VC2_VoiceGetFrequency(UBYTE);
static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
-extern void VC1_VoiceSetPanning(UBYTE,ULONG);
-//extern void VC2_VoiceSetPanning(UBYTE,ULONG);
static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
-extern ULONG VC1_VoiceGetPanning(UBYTE);
-//extern ULONG VC2_VoiceGetPanning(UBYTE);
static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
-extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
-//extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
-extern void VC1_VoiceStop(UBYTE);
-//extern void VC2_VoiceStop(UBYTE);
static void (*VC_VoiceStop_ptr)(UBYTE);
-extern int VC1_VoiceStopped(UBYTE);
-//extern int VC2_VoiceStopped(UBYTE);
static int (*VC_VoiceStopped_ptr)(UBYTE);
-extern SLONG VC1_VoiceGetPosition(UBYTE);
-//extern SLONG VC2_VoiceGetPosition(UBYTE);
static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
-extern ULONG VC1_VoiceRealVolume(UBYTE);
-//extern ULONG VC2_VoiceRealVolume(UBYTE);
static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
-#if defined __STDC__ || defined _MSC_VER || defined MPW_C
+#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
#define VC_PROC0(suffix) \
MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); }
@@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
#define VC_FUNC2(suffix,ret,typ1,typ2) \
MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
+
#else
+
#define VC_PROC0(suffix) \
MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
@@ -158,18 +166,18 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
-
-void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g)
-{ VC_VoicePlay_ptr(a,b,c,d,e,f,g); }
+
+void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) {
+ VC_VoicePlay_ptr(a,b,c,d,e,f,g);
+}
VC_PROC1(VoiceStop,UBYTE)
VC_FUNC1(VoiceStopped,int,UBYTE)
VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
-
+
void VC_SetupPointers(void)
{
- /*
if (md_mode&DMODE_HQMIXER) {
VC_Init_ptr=VC2_Init;
VC_Exit_ptr=VC2_Exit;
@@ -194,7 +202,6 @@ void VC_SetupPointers(void)
VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition;
VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume;
} else {
- */
VC_Init_ptr=VC1_Init;
VC_Exit_ptr=VC1_Exit;
VC_SetNumVoices_ptr=VC1_SetNumVoices;
@@ -217,10 +224,11 @@ void VC_SetupPointers(void)
VC_VoiceStopped_ptr=VC1_VoiceStopped;
VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition;
VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
- //}
+ }
}
+#endif/* !NO_HQMIXER */
-#else
+#else /* _IN_VIRTCH_ */
#ifndef _VIRTCH_COMMON_
#define _VIRTCH_COMMON_
@@ -248,9 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
todo=samples2bytes(bytes2samples(todo));
/* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
- if(vc_mode & DMODE_FLOAT)
- memset(buf,0,todo);
- else if(vc_mode & DMODE_16BITS)
+ if(vc_mode &(DMODE_16BITS|DMODE_FLOAT))
memset(buf,0,todo);
else
memset(buf,0x80,todo);
@@ -276,14 +282,14 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
void VC1_Exit(void)
{
- if(vc_tickbuf) MikMod_free(vc_tickbuf);
- if(vinf) MikMod_free(vinf);
- if(Samples) MikMod_free(Samples);
+ MikMod_free(vinf);
+ MikMod_afree(vc_tickbuf);
+ MikMod_afree(Samples);
vc_tickbuf = NULL;
vinf = NULL;
Samples = NULL;
-
+
VC_SetupPointers();
}
@@ -309,19 +315,19 @@ ULONG VC1_VoiceGetFrequency(UBYTE voice)
void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
{
- vinf[voice].flags = flags;
- vinf[voice].handle = handle;
- vinf[voice].start = start;
- vinf[voice].size = size;
- vinf[voice].reppos = reppos;
- vinf[voice].repend = repend;
- vinf[voice].kick = 1;
+ vinf[voice].flags = flags;
+ vinf[voice].handle = handle;
+ vinf[voice].start = start;
+ vinf[voice].size = size;
+ vinf[voice].reppos = reppos;
+ vinf[voice].repend = repend;
+ vinf[voice].kick = 1;
}
void VC1_VoiceStop(UBYTE voice)
{
vinf[voice].active = 0;
-}
+}
int VC1_VoiceStopped(UBYTE voice)
{
@@ -334,7 +340,7 @@ SLONG VC1_VoiceGetPosition(UBYTE voice)
}
void VC1_VoiceSetVolume(UBYTE voice,UWORD vol)
-{
+{
/* protect against clicks if volume variation is too high */
if(abs((int)vinf[voice].vol-(int)vol)>32)
vinf[voice].rampvol=CLICK_BUFFER;
@@ -353,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
void VC1_SampleUnload(SWORD handle)
{
- if (handle<MAXSAMPLEHANDLES) {
- if (Samples[handle])
- MikMod_free(Samples[handle]);
+ if (Samples && (handle < MAXSAMPLEHANDLES)) {
+ MikMod_afree(Samples[handle]);
Samples[handle]=NULL;
}
}
@@ -364,10 +369,15 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
{
SAMPLE *s = sload->sample;
int handle;
- ULONG t, length,loopstart,loopend;
+ ULONG t, length,loopstart,loopend,looplen;
if(type==MD_HARDWARE) return -1;
+ if(s->length > MAX_SAMPLE_SIZE) {
+ _mm_errno = MMERR_NOT_A_STREAM; /* better error? */
+ return -1;
+ }
+
/* Find empty slot to put sample address in */
for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
if(!Samples[handle]) break;
@@ -376,7 +386,7 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
_mm_errno = MMERR_OUT_OF_HANDLES;
return -1;
}
-
+
/* Reality check for loop settings */
if (s->loopend > s->length)
s->loopend = s->length;
@@ -390,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
SL_SampleSigned(sload);
SL_Sample8to16(sload);
- if(!(Samples[handle]=(SWORD*)MikMod_malloc((length+20)<<1))) {
+ if(!(Samples[handle]=(SWORD*)MikMod_amalloc((length+20)<<1))) {
_mm_errno = MMERR_SAMPLE_TOO_BIG;
return -1;
}
/* read sample into buffer */
- if (SL_Load(Samples[handle],sload,length))
+ if (SL_Load(Samples[handle],sload,length)) {
+ MikMod_afree(Samples[handle]);
+ Samples[handle]=NULL;
return -1;
+ }
/* Unclick sample */
if(s->flags & SF_LOOP) {
+ looplen = loopend - loopstart;/* handle short samples */
if(s->flags & SF_BIDI)
- for(t=0;t<16;t++)
+ for(t=0;t<16 && t<looplen;t++)
Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
else
- for(t=0;t<16;t++)
+ for(t=0;t<16 && t<looplen;t++)
Samples[handle][loopend+t]=Samples[handle][t+loopstart];
} else
for(t=0;t<16;t++)
@@ -416,13 +430,13 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
ULONG VC1_SampleSpace(int type)
{
- (void)type;
+ (void)type;
return vc_memory;
}
ULONG VC1_SampleLength(int type,SAMPLE* s)
{
- (void)type;
+ (void)type;
if (!s) return 0;
return (s->length*((s->flags&SF_16BITS)?2:1))+16;
@@ -456,11 +470,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
return abs(k-j);
}
+#endif /* _VIRTCH_COMMON_ */
-#endif
-
-MikMod_callback_t vc_callback;
-
-#endif
+#endif /* _IN_VIRTCH_ */
/* ex:set ts=4: */
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 96228085c9..84f096a409 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -44,7 +44,6 @@ asy,viewers/mikmod,7
dsm,viewers/mikmod,7
far,viewers/mikmod,7
gdm,viewers/mikmod,7
-gt2,viewers/mikmod,7
imf,viewers/mikmod,7
it,viewers/mikmod,7
m15,viewers/mikmod,7
@@ -57,6 +56,7 @@ stm,viewers/mikmod,7
stx,viewers/mikmod,7
ult,viewers/mikmod,7
uni,viewers/mikmod,7
+umx,viewers/mikmod,7
xm,viewers/mikmod,7
pd,viewers/pdbox,2
rsp,viewers/searchengine,8