1
0
Fork 0
forked from len0rd/rockbox

mikmod: Upgrade mikmod core from v3.2.0 to v3.3.11

* Get rid of the non-functional GT2 loader
 * Add the UMX loader
 * Add HQ mixer routines (and make it configurable)
 * Allow samplerate to be configured at run/playtime
 * Support >64KHz mixing/playback
 * Correctly restore non-boost status

(The diff to upstream is much smaller now too!)

Change-Id: Iaa4ac901ba9cd4123bb225656976e78271353a72
This commit is contained in:
Solomon Peachy 2020-08-08 21:56:15 -04:00
parent 8c7780bafc
commit b4e70422a3
43 changed files with 5072 additions and 2802 deletions

View file

@ -15351,6 +15351,46 @@
swcodec: "Surround"
</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

View file

@ -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

View file

@ -20,7 +20,7 @@
/*==============================================================================
$Id: load_669.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
$Id: $
Composer 669 module loader
@ -53,7 +53,7 @@ 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)
@ -256,7 +258,7 @@ static int S69_Load(int curious)
_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;

View file

@ -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,14 +124,14 @@ 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))
@ -337,7 +337,7 @@ static int AMF_Load(int curious)
AMFSAMPLE s;
SAMPLE *q;
UWORD *track_remap;
ULONG samplepos;
ULONG samplepos, fileend;
int channel_remap[16];
(void)curious;
@ -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)
@ -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 {
@ -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,6 +508,11 @@ 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;
@ -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)

View file

@ -20,7 +20,7 @@
/*==============================================================================
$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>,
@ -77,7 +77,8 @@ 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,
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,
@ -140,9 +141,11 @@ 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;
@ -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;
@ -280,15 +291,15 @@ static int ASY_Load(int curious)
ULONG seekpos;
(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*/
@ -302,7 +313,7 @@ static int ASY_Load(int curious)
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 */
@ -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 */

View file

@ -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)
@ -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++;
}

View file

@ -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)
@ -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 */
@ -315,7 +325,7 @@ 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);
q->samplename = MikMod_strdup("");
q++;
}
return 1;

View file

@ -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) {
@ -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';

View file

@ -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
};

View file

@ -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,13 +127,37 @@ 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;
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)
@ -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);
@ -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);

View file

@ -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 */
@ -167,7 +166,7 @@ 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,6 +211,13 @@ 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
@ -221,31 +227,32 @@ static void IT_Cleanup(void)
NOTE: You must first seek to the file location of the pattern before calling
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)
@ -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];
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)
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;
@ -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);
@ -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);
@ -739,10 +764,12 @@ static int IT_Load(int curious)
}
} 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);
@ -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; \
@ -863,10 +892,6 @@ static int IT_Load(int curious)
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);
@ -946,7 +971,7 @@ 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;
}
}
@ -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;

View file

@ -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,19 +121,19 @@ 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));
}
@ -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,45 +175,46 @@ 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;
}
@ -223,9 +222,9 @@ static int M15_Test(void)
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;
}
/*
@ -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,9 +410,9 @@ 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;

View file

@ -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);
@ -694,7 +734,7 @@ static CHAR *MED_LoadTitle(void)
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);

View file

@ -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)
@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
mh=NULL;
patbuf=NULL;
}
/*
@ -309,8 +311,7 @@ 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;
@ -477,7 +478,7 @@ static int MOD_Load(int curious)
q++;
}
of.modtype = StrDup(descr);
of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns())
return 0;

View file

@ -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)
@ -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 */
@ -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)) {

View file

@ -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;
}
@ -334,9 +335,9 @@ static int OKT_Load(int 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 */
@ -442,7 +443,7 @@ static int OKT_Load(int curious)
static CHAR *OKT_LoadTitle(void)
{
return StrDup("");
return MikMod_strdup("");
}
/*========== Loader information */

View file

@ -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
@ -156,7 +161,7 @@ static void S3M_Cleanup(void)
NOTE: You must first seek to the file location of the pattern before calling
this procedure.
Returns 1 on fail. */
Returns 0 on fail. */
static int S3M_GetNumChannels(void)
{
int row=0,flag,ch;
@ -166,18 +171,18 @@ 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,7 +416,7 @@ 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 */

View file

@ -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
@ -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 */
@ -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)
@ -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;
@ -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: */

View file

@ -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,6 +114,7 @@ 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;
@ -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 */
@ -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;

View file

@ -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,7 +130,7 @@ static int ULT_Load(int curious)
SAMPLE *q;
ULTSAMPLE s;
ULTHEADER mh;
UBYTE nos,noc,rbnop;
UBYTE nos,noc,RBnop;
(void)curious;
/* try to read module header */
@ -207,26 +207,34 @@ 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;

View file

@ -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: */

View file

@ -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
@ -96,16 +96,16 @@ static UNISMP05 *wh=NULL,*s=NULL;
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);
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);
s->samplename=readstring();
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;
}
@ -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);
@ -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;

View file

@ -20,7 +20,7 @@
/*==============================================================================
$Id: load_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $
$Id$
Fasttracker (XM) module loader
@ -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)
@ -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]; \
@ -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;
}
@ -671,10 +680,8 @@ static int XM_Load(int curious)
_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,22 +691,24 @@ 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.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])
@ -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 */

View file

@ -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,13 +108,24 @@ 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
#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 */
/* 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
@ -103,25 +133,29 @@ static void _mm_registeralldrivers(void)
#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();

View file

@ -1,6 +1,6 @@
/* 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
@ -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,47 +32,52 @@
#include <unistd.h>
#endif
#if 0
#if defined unix || (defined __APPLE__ && defined __MACH__)
#include <string.h>
#include "mikmod_internals.h"
#if (MIKMOD_UNIX)
#include <pwd.h>
#include <sys/stat.h>
#endif
#endif
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include "mikmod_internals.h"
#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 ULONG md_mixfreq = 44100;
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
DMODE_SURROUND |DMODE_SOFT_MUSIC |
DMODE_SOFT_SNDFX;
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 MD_SetVoices() */
/* 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;
void (*md_player)(void) = Player_HandleTick;
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;
@ -187,12 +190,13 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void)
len += 4 + (l->next ? 1 : 0) + strlen(l->Version);
if(len)
if((list=MikMod_malloc(len*sizeof(CHAR)))) {
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++)
sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s",
list,t,l->Version);
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;
@ -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;
@ -255,8 +259,7 @@ MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal)
MDRIVER *cruise;
/* Allow only driver ordinals > 0 */
if (!ordinal)
return 0;
if (!ordinal) return NULL;
MUTEX_LOCK(lists);
cruise = firstdriver;
@ -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;
@ -600,7 +601,7 @@ MIKMODAPI void MikMod_Exit(void)
/* 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;
@ -630,11 +631,11 @@ static int _mm_reset(CHAR *cmdline)
}
}
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;
@ -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
@ -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;
@ -961,5 +964,5 @@ int MD_DropPrivileges(void)
}
#endif
#endif
/* ex:set ts=4: */
/* ex:set ts=8: */

View file

@ -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
@ -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,8 +733,7 @@ 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);
@ -850,7 +907,6 @@ static int playfile(char* filename)
rb->queue_delete(&thread_q);
#endif
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if ( settings.boost )
rb->cpu_boost(false);
#endif
@ -891,7 +947,6 @@ 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);
@ -908,11 +963,24 @@ enum plugin_status plugin_start(const void* parameter)
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,7 +1002,6 @@ 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,

View file

@ -1,5 +1,5 @@
/* MikMod sound library
(c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS
(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
@ -20,8 +20,6 @@
/*==============================================================================
$Id: mikmod.h.in,v 1.3 2005/03/30 19:09:21 realtech Exp $
MikMod sound library include file
==============================================================================*/
@ -40,14 +38,34 @@ 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
#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 __declspec(dllimport)
# 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
#endif
@ -57,8 +75,8 @@ extern "C" {
*/
#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)| \
@ -68,52 +86,90 @@ extern "C" {
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__)
#define INCL_DOSSEMAPHORES
#include <os2.h>
#else
#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
/* 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
typedef char CHAR;
/* 1 byte, signed and unsigned: */
typedef signed char SBYTE;
#ifndef _MIKMOD_AMIGA
typedef unsigned char UBYTE;
#endif
/* 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
#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__)
/* 64 bit architectures */
/* 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
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 */
#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
*/
@ -210,6 +266,33 @@ enum {
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
};
@ -222,7 +305,7 @@ 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);
@ -236,12 +319,12 @@ 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_Reset(const CHAR*);
MIKMODAPI extern int MikMod_SetNumVoices(int,int);
MIKMODAPI extern int MikMod_Active(void);
MIKMODAPI extern int MikMod_EnableOutput(void);
@ -253,9 +336,10 @@ 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
@ -274,7 +358,7 @@ typedef struct MREADER {
typedef struct MWRITER {
int (*Seek)(struct MWRITER*, long, int);
long (*Tell)(struct MWRITER*);
int (*Write)(struct MWRITER*,void*,size_t);
int (*Write)(struct MWRITER*, const void*, size_t);
int (*Put)(struct MWRITER*, int);
} MWRITER;
@ -351,12 +435,12 @@ typedef struct 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*);
@ -481,8 +565,10 @@ typedef struct MODULE {
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) */
@ -572,6 +658,7 @@ 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) */
@ -579,11 +666,11 @@ MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */
* ========== 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*);
@ -649,19 +736,21 @@ enum {
#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;
const CHAR* Name;
const CHAR* Version;
UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */
UBYTE SoftVoiceLimit; /* Limit of software mixer voices */
CHAR *Alias;
CHAR *CmdLineHelp;
const CHAR* Alias;
const CHAR* CmdLineHelp;
void (*CommandLine) (CHAR*);
void (*CommandLine) (const CHAR*);
int (*IsPresent) (void);
SWORD (*SampleLoad) (struct SAMPLOAD*,int);
void (*SampleUnload) (SWORD);
@ -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 */
@ -720,29 +808,40 @@ MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound 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_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_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);

View file

@ -20,8 +20,6 @@
/*==============================================================================
$Id: mikmod_internals.h,v 1.7 2010/01/12 03:30:31 realtech Exp $
MikMod sound library internal definitions
==============================================================================*/
@ -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__)
#if !defined(_WIN32) && \
(defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
typedef long SLONGLONG;
#define NATIVE_64BIT_INT
#if 0
#elif defined(_WIN64) /* win64 is LLP64, not LP64 */
#define NATIVE_64BIT_INT
typedef long long SLONGLONG;
#elif defined(__WATCOMC__)
typedef __int64 SLONGLONG;
#elif defined(WIN32) && !defined(__MWERKS__)
#elif defined(_WIN32) && !defined(__MWERKS__)
typedef LONGLONG SLONGLONG;
#elif macintosh && !TYPE_LONGLONG
#elif defined(macintosh) && !TYPE_LONGLONG
#include <Types.h>
typedef SInt64 SLONGLONG;
#endif
#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
/* 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 */
@ -77,6 +95,7 @@ extern MikMod_handler_t _mm_errorhandler;
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
@ -86,7 +105,8 @@ extern MikMod_handler_t _mm_errorhandler;
#define MUTEX_UNLOCK(name) \
if(_mm_mutex_##name)\
DosReleaseMutexSem(_mm_mutex_##name)
#elif defined(WIN32)
#elif defined(_WIN32)
#include <windows.h>
#define DECLARE_MUTEX(name) \
extern HANDLE _mm_mutex_##name
@ -96,6 +116,7 @@ extern MikMod_handler_t _mm_errorhandler;
#define MUTEX_UNLOCK(name) \
if(_mm_mutex_##name)\
ReleaseMutex(_mm_mutex_##name)
#else
#define DECLARE_MUTEX(name) \
extern void *_mm_mutex_##name
@ -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,16 +142,17 @@ 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_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)
@ -138,11 +164,9 @@ extern int _mm_FileExists(CHAR *fname);
extern void _mm_iobase_setcur(MREADER*);
extern void _mm_iobase_revert(MREADER*);
extern int _mm_fopen(CHAR*,CHAR*);
extern int _mm_fopen(const CHAR *, const CHAR *);
extern int _mm_fclose(int);
#if !defined(ROCKBOX)
extern void _mm_write_string(CHAR*,MWRITER*);
#endif
extern void _mm_write_string(const CHAR*,MWRITER*);
extern int _mm_read_string (CHAR*,int,MREADER*);
extern SWORD _mm_read_M_SWORD(MREADER*);
@ -187,6 +211,8 @@ 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. */
@ -315,7 +341,7 @@ enum {
UNI_LAST
};
extern UWORD unioperands[UNI_LAST];
extern const UWORD unioperands[UNI_LAST];
/* IT / S3M Extended SS effects: */
enum {
@ -540,8 +566,8 @@ typedef struct MP_VOICE {
typedef struct MLOADER {
struct MLOADER* next;
CHAR* type;
CHAR* version;
const CHAR* type;
const CHAR* version;
int (*Init)(void);
int (*Test)(void);
int (*Load)(int);
@ -551,9 +577,9 @@ struct MLOADER* next;
/* 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
@ -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);
@ -598,7 +623,7 @@ extern ULONG getfrequency(UWORD,ULONG);
/* loader shared data */
#define STM_NTRACKERS 3
extern CHAR *STM_Signatures[STM_NTRACKERS];
extern const CHAR *STM_Signatures[STM_NTRACKERS];
/*========== Player interface */
@ -606,6 +631,16 @@ 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) */
@ -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,16 +671,16 @@ 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);
#if defined(unix) || defined(__APPLE__) && defined(__MACH__)
#if (MIKMOD_UNIX)
/* POSIX helper functions */
extern int MD_Access(CHAR *);
extern int MD_Access(const CHAR *);
extern int MD_DropPrivileges(void);
#endif
@ -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,29 +765,25 @@ 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)
{
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);
@ -753,24 +799,22 @@ 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));
/* 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);
@ -778,18 +822,17 @@ static inline vector signed int vec_hiqq(vector signed int a)
#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)
@ -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: */

View file

@ -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__)

View file

@ -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,14 +73,17 @@ 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)))) {
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)
sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version);
for(l = firstloader; l; l = l->next) {
list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
}
}
MUTEX_UNLOCK(lists);
return list;
@ -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;
/* Adapted from the OpenMPT project, C'ified. */
CHAR *buf, *storage, *p;
size_t numlines, line, fpos, cpos, lpos, cnt;
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);
if (!linelen) return 0;
if (!len) return 1;
/* 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);
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");
}
MikMod_free(storage);
MikMod_free(tempcomment);
_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;
}
}
}
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;
}
@ -258,7 +271,7 @@ 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)
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,11 +346,25 @@ static void ML_FreeEx(MODULE *mf)
static MODULE *ML_AllocUniMod(void)
{
MODULE *mf;
return (mf=MikMod_malloc(sizeof(MODULE)));
return (MODULE *) MikMod_malloc(sizeof(MODULE));
}
#ifndef NO_DEPACKERS
static int ML_TryUnpack(MREADER *reader,void **out,long *outlen)
{
int i;
*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)
{
if(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,7 +448,8 @@ 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);
@ -408,7 +457,6 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
_mm_delete_mem_reader(reader);
}
return result;
}
@ -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;
}
@ -500,24 +578,20 @@ 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);
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
return NULL;
#ifndef NO_DEPACKERS
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(!ML_LoadSamples()) {
ML_FreeEx(&of);
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
return NULL;
}
if(!(mf=ML_AllocUniMod())) {
ML_FreeEx(&of);
_mm_rewind(modreader);_mm_iobase_revert(modreader);
#endif
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL;
}
@ -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(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(SL_LoadSamples()) {
#endif
_mm_iobase_revert(modreader);
if(!ok) {
Player_Free_internal(mf);
return NULL;
}
if(Player_Init(mf)) {
_mm_iobase_revert(modreader);
Player_Free_internal(mf);
mf=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);
}

View file

@ -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();

View file

@ -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;
}
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 */
@ -143,11 +141,7 @@ void S3MIT_CreateOrders(int curious)
/* handles S3M and IT effects */
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) {

View file

@ -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
#ifdef HAVE_POSIX_MEMALIGN
#define _XOPEN_SOURCE 600 /* for posix_memalign */
#endif
#include "string.h"
#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;
}
static void *get_pointer(void *data)
{
unsigned char *_pptr = (unsigned char*)data - sizeof(void*);
size_t _ptr = *(size_t*)_pptr;
return (void*)_ptr;
}
*/
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
}
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*));
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;
}
#endif
if(!d) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
return NULL;
}
return align_pointer(d, ALIGN_STRIDE);
#endif
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 *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) return d;
if(!d) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
}
return align_pointer(d, ALIGN_STRIDE);
#endif
#endif
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
if (data) free(data);
}
#endif
/* 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: */

View file

@ -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];
}

View file

@ -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,13 +75,10 @@ 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;
//if(!(fp=fopen(fname,attrib))) {
// _mm_errno = MMERR_OPENING_FILE;
// if(_mm_errorhandler) _mm_errorhandler();
@ -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;
@ -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)
@ -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,7 +184,7 @@ MREADER *_mm_new_file_reader(int fp)
void _mm_delete_file_reader (MREADER* reader)
{
if(reader) MikMod_free(reader);
MikMod_free(reader);
}
/*========== File Writer */
@ -209,10 +206,9 @@ 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;
@ -229,7 +225,7 @@ static int _mm_FileWriter_Put(MWRITER* writer,int value)
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;
MMEMREADER* mr;
long siz;
int ret;
if (!reader) { return 0; }
if (!reader || !size || (size > (size_t) LONG_MAX))
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 */
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; }
mr = (MMEMREADER*) reader;
if (mr->pos >= mr->len) return EOF;
c = ((const unsigned char*) mr->buffer)[mr->pos];
mr->pos++;
pos = ((MMEMREADER*)reader)->pos;
((MMEMREADER*)reader)->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;
mr->pos += offset;
break;
case SEEK_SET:
((MMEMREADER*)reader)->pos = offset;
mr->pos = reader->iobase + offset;
break;
case SEEK_END:
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1;
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);
}
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_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);
}
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: */

View file

@ -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;
@ -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 */
@ -850,6 +860,11 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
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;
@ -899,9 +917,14 @@ static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
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]])) {
dat=mod->pattrows[mod->positions[mod->sngpos]];
}
mod->patbrk=dat;
if (!mod->posjmp) {
/* don't ask me to explain this code - it makes
@ -909,9 +932,8 @@ static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
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)))) {
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
@ -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;
@ -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;
@ -2382,7 +2409,11 @@ 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;
@ -2401,12 +2432,12 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
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;
@ -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;
@ -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)) {
@ -2955,7 +2986,7 @@ static void pt_SetupVoices(MODULE *mod)
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)
@ -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)
@ -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,9 +3186,7 @@ void Player_Exit_internal(MODULE* mod)
pf=NULL;
}
if (mod->control)
MikMod_free(mod->control);
if (mod->voice)
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;
@ -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: */

View file

@ -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 */
@ -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;
}

View file

@ -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,

View file

@ -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;
}
}
/* 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)
@ -232,8 +231,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
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;
@ -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: */

View file

@ -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,22 +33,17 @@
(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
@ -130,38 +125,43 @@ 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;
@ -172,10 +172,10 @@ static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index,
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));
@ -183,86 +183,94 @@ static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index,
_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;
{
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
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 */
) );
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);
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
@ -271,23 +279,22 @@ static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
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,10 +350,10 @@ 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;
@ -354,21 +362,21 @@ static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
}
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,10 +387,10 @@ 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;
@ -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,10 +435,10 @@ 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;
@ -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,10 +619,10 @@ 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;
@ -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);
@ -839,57 +848,55 @@ 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)
{
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
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
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
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;
@ -900,10 +907,7 @@ 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;
@ -911,9 +915,9 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE 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;
}
@ -922,9 +926,9 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count)
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;
@ -935,24 +939,22 @@ 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
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);
}
@ -960,7 +962,6 @@ static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count)
#endif
static void AddChannel(SLONG* ptr,NATIVE todo)
{
SLONGLONG end,done;
@ -1067,7 +1068,6 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
if (md_mode & DMODE_SIMDMIXER)
vnf->current=MixSIMDStereoNormal
(s,ptr,vnf->current,vnf->increment,done);
else
#endif
vnf->current=Mix32StereoNormal
@ -1076,7 +1076,8 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
} else
vnf->current=Mix32MonoNormal
(s,ptr,vnf->current,vnf->increment,done);
} else
}
else
#endif
{
if((md_mode & DMODE_INTERP)) {
@ -1100,7 +1101,6 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
if (md_mode & DMODE_SIMDMIXER)
vnf->current=MixSIMDStereoNormal
(s,ptr,vnf->current,vnf->increment,done);
else
#endif
vnf->current=MixStereoNormal
@ -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 (md_mode&DMODE_HQMIXER)
return VC2_Init();
#endif
if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) {
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,6 +1293,8 @@ 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;
/* 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;
@ -1272,6 +1303,7 @@ int VC1_PlayStart(void)
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;

File diff suppressed because it is too large Load diff

View file

@ -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);
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);
extern ULONG VC1_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);
extern int VC2_SetNumVoices(void);
static int (*VC_SetNumVoices_ptr)(void);
extern ULONG VC1_SampleSpace(int);
//extern ULONG VC2_SampleSpace(int);
static ULONG (*VC_SampleSpace_ptr)(int);
extern ULONG VC1_SampleLength(int,SAMPLE*);
//extern ULONG VC2_SampleLength(int,SAMPLE*);
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
extern int VC1_PlayStart(void);
//extern int VC2_PlayStart(void);
extern int VC2_PlayStart(void);
static int (*VC_PlayStart_ptr)(void);
extern void VC1_PlayStop(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(); }
@ -159,8 +167,9 @@ 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)
@ -169,7 +178,6 @@ 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,9 +282,9 @@ 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;
@ -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;
@ -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++)
@ -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: */

View file

@ -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