Upgrade internal libmikmod to 3.3.11.1.

This should fix music playback corruption issues reported on
64-bit ARM architectures.
This commit is contained in:
Michael Martin
2021-07-24 18:53:43 -07:00
parent 199e3748cc
commit 4f5cbef324
30 changed files with 5962 additions and 2063 deletions
+3
View File
@@ -1,3 +1,6 @@
Progress to next release:
- Upgrade internal libmikmod to 3.3.11.1, for Aarch64 support - McMartin
0.8: 0.8:
- Grouping ship properties together at the top of the ship .c files, from - Grouping ship properties together at the top of the ship .c files, from
oldlaptop. oldlaptop.
+35 -7
View File
@@ -9,13 +9,21 @@ libmikmod main authors
maintained MikMod version 3 until it was discontinued. He still works maintained MikMod version 3 until it was discontinued. He still works
on the WinAmp module plugin, roughly based on MikMod. on the WinAmp module plugin, roughly based on MikMod.
* Miod Vallat <miod@mikmod.org> * Miod Vallat <miod@mikmod.org>
current overbooked libmikmod maintainer (since version 3.0.4), made [email doesn't work anymore...]
maintainer MikMod'Unix (since version 3.0.4), made
an audit of the code resulting in many bugs fixed. an audit of the code resulting in many bugs fixed.
* Raphael Assenat <raph@raphnet.net>
Revived the project after many years of inactivity, in 2004. Former
maintainer.
* Shlomi Fish <shlomif@shlomifish.org> ( http://www.shlomifish.org/ ).
Took over maintenance after many years of inactivity, in 2012.
* Ozkan Sezer <sezero@users.sourceforge.net>
Took over maintenance in 2013. (current maintainer.)
Previous Unix maintainers Previous Unix maintainers
------------------------- -------------------------
* Steve McIntyre <steven@chiark.greenend.org.uk> * Steve McIntyre <steve@einval.com>
maintained MikMod'Unix version 2. Used to maintain the Debian package maintained MikMod'Unix version 2. Used to maintain the Debian package
for MikMod. for MikMod.
* Peter Amstutz <tetron@student.umass.edu> * Peter Amstutz <tetron@student.umass.edu>
@@ -26,8 +34,10 @@ General contributors
* Arne de Bruijn <arne@knoware.nl> * Arne de Bruijn <arne@knoware.nl>
wrote the compressed IT sample support. wrote the compressed IT sample support.
* Shlomi Fish <shlomif@vipe.technion.ac.il> * Shlomi Fish <shlomif@shlomifish.org>
wrote the Java port, bug fixes. wrote the Java port, bug fixes, CMake build system.
* Ozkan Sezer <sezero@users.sourceforge.net>
overall bug fixes, configury updates.
* Juan Linietsky <coding@reduz.com.ar> * Juan Linietsky <coding@reduz.com.ar>
overall bug fixes. overall bug fixes.
* Claudio Matsuoka <claudio@helllabs.org> * Claudio Matsuoka <claudio@helllabs.org>
@@ -48,6 +58,9 @@ General contributors
Contributors on the Unix side Contributors on the Unix side
----------------------------- -----------------------------
* Axel "awe" Wefers <awe@fruitz-of-dojo.de>
wrote the OSX CoreAudio driver, the AIFF driver and
updated the Mac Audio Carbon driver
* Douglas Carmichael <dcarmich@mcs.com> * Douglas Carmichael <dcarmich@mcs.com>
ported MikMod to FreeBSD. ported MikMod to FreeBSD.
* Chris Conn <cconn@tohs.abacom.com> * Chris Conn <cconn@tohs.abacom.com>
@@ -84,6 +97,22 @@ Contributors on the Windows side
created the DirectSound driver. created the DirectSound driver.
* Bjornar Henden <bhenden@online.no> * Bjornar Henden <bhenden@online.no>
created the Multimedia API windows driver. created the Multimedia API windows driver.
* Paul Spark <sparkynz74@gmail.com>
created the SDL windows driver and made changes to build with MSVC++ 6.
Contributors on the Android side
--------------------------------
* Radovan Cervenka <radovan.cervenka@gmail.com>
provided the Android building artifacts and ported the old OpenSL ES
driver from the old http://github.com/0xD34D/libmikmod-android project
to libmikmod-3.
Contributors on the Amiga side
------------------------------
* Szilárd Biró <col.lawrence@gmail.com>
provided the AHI driver.
Contributors on the Dos side Contributors on the Dos side
---------------------------- ----------------------------
@@ -108,7 +137,7 @@ Contributors on the Macintosh side
Contributors on the OS/2 side Contributors on the OS/2 side
----------------------------- -----------------------------
* Stefan Tibus <Stefan_Tibus@ThePentagon.com> * Stefan Tibus <sjti@gmx.net>
ported libmikmod to OS/2. ported libmikmod to OS/2.
* Andrew Zabolotny <bit@eltech.ru> * Andrew Zabolotny <bit@eltech.ru>
improved the existing OS/2 drivers. improved the existing OS/2 drivers.
@@ -120,5 +149,4 @@ Contributors on the BeOS side
integrated libmikmod into his BeOS APlayer, and contributed many bug fixes. integrated libmikmod into his BeOS APlayer, and contributed many bug fixes.
-- --
If your name is missing, don't hesitate to remind me at If your name is missing, don't hesitate to remind the current maintainer.
<miod@mikmod.org>
+1 -1
View File
@@ -1,5 +1,5 @@
uqm_CFILES="drv_nos.c load_it.c load_mod.c load_s3m.c load_stm.c load_xm.c uqm_CFILES="drv_nos.c load_it.c load_mod.c load_s3m.c load_stm.c load_xm.c
mdreg.c mdriver.c mloader.c mdreg.c mdriver.c mdulaw.c mloader.c
mlreg.c mlutil.c mmalloc.c mmerror.c mmio.c mplayer.c munitrk.c mlreg.c mlutil.c mmalloc.c mmerror.c mmio.c mplayer.c munitrk.c
mwav.c npertab.c sloader.c virtch.c virtch2.c virtch_common.c" mwav.c npertab.c sloader.c virtch.c virtch2.c virtch_common.c"
uqm_HFILES="mikmod_build.h mikmod.h mikmod_internals.h" uqm_HFILES="mikmod_build.h mikmod.h mikmod_internals.h"
+7 -1
View File
@@ -1,5 +1,11 @@
NOTE by UQM developers: this is a modified version of libmikmod. NOTE by UQM developers: this is a modified version of libmikmod.
This version of the library is based on the official libmikmod library This version of the library is based on the official libmikmod library
version 3.1.11a with some internal and API changes backported from v3.2.2. version 3.3.11.1. Alterations have been marked with comments that
begin with the text UQM MOD, along with brief descriptions. The
changes are largely limited to removal of unused-by-UQM formats and
drivers, hardcoding static-library behavior for the remainder, and
reliance on UQM's own configuration files for cross-compatibility
defines.
The official library is found at http://sourceforge.net/projects/mikmod. The official library is found at http://sourceforge.net/projects/mikmod.
+3 -3
View File
@@ -51,7 +51,7 @@ static BOOL NS_IsThere(void)
return 1; return 1;
} }
static BOOL NS_Init(void) static int NS_Init(void)
{ {
zerobuf=(SBYTE*)MikMod_malloc(ZEROLEN); zerobuf=(SBYTE*)MikMod_malloc(ZEROLEN);
return VC_Init(); return VC_Init();
@@ -61,6 +61,7 @@ static void NS_Exit(void)
{ {
VC_Exit(); VC_Exit();
MikMod_free(zerobuf); MikMod_free(zerobuf);
zerobuf=NULL;
} }
static void NS_Update(void) static void NS_Update(void)
@@ -75,7 +76,7 @@ MIKMODAPI MDRIVER drv_nos={
"Nosound Driver v3.0", "Nosound Driver v3.0",
255,255, 255,255,
"nosound", "nosound",
NULL,
NULL, NULL,
NS_IsThere, NS_IsThere,
VC_SampleLoad, VC_SampleLoad,
@@ -103,5 +104,4 @@ MIKMODAPI MDRIVER drv_nos={
VC_VoiceRealVolume VC_VoiceRealVolume
}; };
/* ex:set ts=4: */ /* ex:set ts=4: */
+82 -52
View File
@@ -34,7 +34,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
@@ -42,10 +41,10 @@
#include <string.h> #include <string.h>
#include "mikmod_internals.h" #include "mikmod_internals.h"
#include "mikmod_ctype.h"
#ifdef SUNOS #ifdef SUNOS
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
extern int toupper(int);
#endif #endif
/*========== Module structure */ /*========== Module structure */
@@ -167,7 +166,7 @@ static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
static int numtrk=0; static int numtrk=0;
static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
static CHAR* IT_Version[]={ static const CHAR* IT_Version[]={
"ImpulseTracker . ", "ImpulseTracker . ",
"Compressed ImpulseTracker . ", "Compressed ImpulseTracker . ",
"ImpulseTracker 2.14p3", "ImpulseTracker 2.14p3",
@@ -177,11 +176,11 @@ static CHAR* IT_Version[]={
}; };
/* table for porta-to-note command within volume/panning column */ /* 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 */ /*========== Loader code */
BOOL IT_Test(void) static BOOL IT_Test(void)
{ {
UBYTE id[4]; UBYTE id[4];
@@ -190,7 +189,7 @@ BOOL IT_Test(void)
return 0; return 0;
} }
BOOL IT_Init(void) static BOOL IT_Init(void)
{ {
if(!(mh=(ITHEADER*)MikMod_malloc(sizeof(ITHEADER)))) return 0; if(!(mh=(ITHEADER*)MikMod_malloc(sizeof(ITHEADER)))) return 0;
if(!(poslookup=(UBYTE*)MikMod_malloc(256*sizeof(UBYTE)))) return 0; if(!(poslookup=(UBYTE*)MikMod_malloc(256*sizeof(UBYTE)))) return 0;
@@ -201,7 +200,7 @@ BOOL IT_Init(void)
return 1; return 1;
} }
void IT_Cleanup(void) static void IT_Cleanup(void)
{ {
FreeLinear(); FreeLinear();
@@ -212,6 +211,13 @@ void IT_Cleanup(void)
MikMod_free(last); MikMod_free(last);
MikMod_free(paraptr); MikMod_free(paraptr);
MikMod_free(origpositions); 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 /* Because so many IT files have 64 channels as the set number used, but really
@@ -221,31 +227,32 @@ void IT_Cleanup(void)
NOTE: You must first seek to the file location of the pattern before calling NOTE: You must first seek to the file location of the pattern before calling
this procedure. this procedure.
Returns 1 on error Returns 0 on error
*/ */
static BOOL IT_GetNumChannels(UWORD patrows) static BOOL IT_GetNumChannels(UWORD patrows)
{ {
int row=0,flag,ch; int row=0,flag,ch;
do { do {
if((flag=_mm_read_UBYTE(modreader))==EOF) { if(_mm_eof(modreader)) {
_mm_errno=MMERR_LOADING_PATTERN; _mm_errno=MMERR_LOADING_PATTERN;
return 1; return 0;
} }
flag=_mm_read_UBYTE(modreader);
if(!flag) if(!flag)
row++; row++;
else { else {
ch=(flag-1)&63; ch=(flag-1)&63;
remap[ch]=0; remap[ch]=0;
if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
if(mask[ch]&1) _mm_read_UBYTE(modreader); if(mask[ch]&1) _mm_skip_BYTE(modreader);
if(mask[ch]&2) _mm_read_UBYTE(modreader); if(mask[ch]&2) _mm_skip_BYTE(modreader);
if(mask[ch]&4) _mm_read_UBYTE(modreader); if(mask[ch]&4) _mm_skip_BYTE(modreader);
if(mask[ch]&8) { _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); } if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); }
} }
} while(row<patrows); } while(row<patrows);
return 0; return 1;
} }
static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows) static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
@@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
static BOOL IT_ReadPattern(UWORD patrows) static BOOL 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 *itt=itpat,dummy,*n,*l;
ITNOTE *ite=&itpat[200*64 -1];
UBYTE *m;
memset(itt,255,200*64*sizeof(ITNOTE)); memset(itt,255,200*64*sizeof(ITNOTE));
do { do {
if((flag=_mm_read_UBYTE(modreader))==EOF) { if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN; _mm_errno = MMERR_LOADING_PATTERN;
return 0; return 0;
} }
flag=_mm_read_UBYTE(modreader);
if(!flag) { if(!flag) {
itt=&itt[of.numchn]; itt=&itt[of.numchn];
row++; row++;
@@ -342,29 +353,38 @@ static BOOL IT_ReadPattern(UWORD patrows)
if(ch!=-1) { if(ch!=-1) {
n=&itt[ch]; n=&itt[ch];
l=&last[ch]; l=&last[ch];
m=&mask[ch];
if(n > ite) { /* malformed file */
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
} else } else
{
n=l=&dummy; n=l=&dummy;
blah = 0;
m=(UBYTE*)&blah;
}
if(flag&128) mask[ch]=_mm_read_UBYTE(modreader); if(flag&128) *m=_mm_read_UBYTE(modreader);
if(mask[ch]&1) if(*m&1)
/* convert IT note off to internal note off */ /* convert IT note off to internal note off */
if((l->note=n->note=_mm_read_UBYTE(modreader))==255) if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
l->note=n->note=253; l->note=n->note=253;
if(mask[ch]&2) if(*m&2)
l->ins=n->ins=_mm_read_UBYTE(modreader); l->ins=n->ins=_mm_read_UBYTE(modreader);
if(mask[ch]&4) if(*m&4)
l->volpan=n->volpan=_mm_read_UBYTE(modreader); l->volpan=n->volpan=_mm_read_UBYTE(modreader);
if(mask[ch]&8) { if(*m&8) {
l->cmd=n->cmd=_mm_read_UBYTE(modreader); l->cmd=n->cmd=_mm_read_UBYTE(modreader);
l->inf=n->inf=_mm_read_UBYTE(modreader); l->inf=n->inf=_mm_read_UBYTE(modreader);
} }
if(mask[ch]&16) if(*m&16)
n->note=l->note; n->note=l->note;
if(mask[ch]&32) if(*m&32)
n->ins=l->ins; n->ins=l->ins;
if(mask[ch]&64) if(*m&64)
n->volpan=l->volpan; n->volpan=l->volpan;
if(mask[ch]&128) { if(*m&128) {
n->cmd=l->cmd; n->cmd=l->cmd;
n->inf=l->inf; n->inf=l->inf;
} }
@@ -379,38 +399,38 @@ static BOOL IT_ReadPattern(UWORD patrows)
return 1; 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); _mm_read_UBYTES(dest,32,r);
cur=last=dest; curp=lastp=dest;
/* remove blanks and uppercase all */ /* remove blanks and uppercase all */
while(*last) { while(*lastp) {
if(isalnum((int)*last)) *(cur++)=toupper((int)*last); if(mik_isalnum((int)*lastp)) *(curp++)=mik_toupper((int)*lastp);
last++; lastp++;
} }
*cur=0; *curp=0;
} }
/* Load embedded midi information for resonant filters */ /* Load embedded midi information for resonant filters */
static void IT_LoadMidiConfiguration(MREADER* modreader) static void IT_LoadMidiConfiguration(MREADER* r)
{ {
int i; int i;
memset(filtermacros,0,sizeof(filtermacros)); memset(filtermacros,0,sizeof(filtermacros));
memset(filtersettings,0,sizeof(filtersettings)); memset(filtersettings,0,sizeof(filtersettings));
if (modreader) { /* information is embedded in file */ if (r) { /* information is embedded in file */
UWORD dat; UWORD dat;
CHAR midiline[33]; CHAR midiline[33];
dat=_mm_read_I_UWORD(modreader); dat=_mm_read_I_UWORD(r);
_mm_fseek(modreader,8*dat+0x120,SEEK_CUR); _mm_fseek(r,8*dat+0x120,SEEK_CUR);
/* read midi macros */ /* read midi macros */
for(i=0;i<UF_MAXMACRO;i++) { for(i=0;i<UF_MAXMACRO;i++) {
LoadMidiString(modreader,midiline); LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&& if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1'))) ((midiline[5]=='0')||(midiline[5]=='1')))
filtermacros[i]=(midiline[5]-'0')|0x80; filtermacros[i]=(midiline[5]-'0')|0x80;
@@ -418,7 +438,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
/* read standalone filters */ /* read standalone filters */
for(i=0x80;i<0x100;i++) { for(i=0x80;i<0x100;i++) {
LoadMidiString(modreader,midiline); LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&& if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1'))) { ((midiline[5]=='0')||(midiline[5]=='1'))) {
filtersettings[i].filter=(midiline[5]-'0')|0x80; filtersettings[i].filter=(midiline[5]-'0')|0x80;
@@ -441,12 +461,12 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
} }
} }
BOOL IT_Load(BOOL curious) static BOOL IT_Load(BOOL curious)
{ {
int t,u,lp; int t,u,lp;
INSTRUMENT *d; INSTRUMENT *d;
SAMPLE *q; SAMPLE *q;
BOOL compressed=0; /*BOOL compressed=0;*/
numtrk=0; numtrk=0;
filters=0; filters=0;
@@ -479,6 +499,10 @@ BOOL IT_Load(BOOL curious)
_mm_errno=MMERR_LOADING_HEADER; _mm_errno=MMERR_LOADING_HEADER;
return 0; 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 */ /* set module variables */
of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
@@ -506,11 +530,11 @@ BOOL IT_Load(BOOL curious)
/* 2.16 : IT 2.14p3 with resonant filters */ /* 2.16 : IT 2.14p3 with resonant filters */
/* 2.15 : IT 2.14p3 (improved compression) */ /* 2.15 : IT 2.14p3 (improved compression) */
if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) 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) 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 { 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?15:26] = (mh->cwt>>8)+'0';
of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
@@ -550,7 +574,7 @@ BOOL IT_Load(BOOL curious)
/* read the order data */ /* read the order data */
if(!AllocPositions(mh->ordnum)) return 0; 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++) { for(t=0;t<mh->ordnum;t++) {
origpositions[t]=_mm_read_UBYTE(modreader); origpositions[t]=_mm_read_UBYTE(modreader);
@@ -672,7 +696,7 @@ BOOL IT_Load(BOOL curious)
if(s.flag&2) q->flags|=SF_16BITS; if(s.flag&2) q->flags|=SF_16BITS;
if((s.flag&8)&&(mh->cwt>=0x214)) { if((s.flag&8)&&(mh->cwt>=0x214)) {
q->flags|=SF_ITPACKED; q->flags|=SF_ITPACKED;
compressed=1; /*compressed=1;*/
} }
if(s.flag&16) q->flags|=SF_LOOP; if(s.flag&16) q->flags|=SF_LOOP;
if(s.flag&64) q->flags|=SF_BIDI; if(s.flag&64) q->flags|=SF_BIDI;
@@ -726,7 +750,7 @@ BOOL IT_Load(BOOL curious)
ih.trkvers = _mm_read_I_UWORD(modreader); ih.trkvers = _mm_read_I_UWORD(modreader);
ih.numsmp = _mm_read_UBYTE(modreader); ih.numsmp = _mm_read_UBYTE(modreader);
_mm_read_UBYTE(modreader); _mm_skip_BYTE(modreader);
_mm_read_string(ih.name,26,modreader); _mm_read_string(ih.name,26,modreader);
_mm_read_UBYTES(ih.blank01,6,modreader); _mm_read_UBYTES(ih.blank01,6,modreader);
_mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
@@ -743,6 +767,8 @@ BOOL IT_Load(BOOL curious)
#define IT_LoadEnvelope(name,type) \ #define IT_LoadEnvelope(name,type) \
ih. name##flg =_mm_read_UBYTE(modreader); \ ih. name##flg =_mm_read_UBYTE(modreader); \
ih. name##pts =_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##beg =_mm_read_UBYTE(modreader); \
ih. name##end =_mm_read_UBYTE(modreader); \ ih. name##end =_mm_read_UBYTE(modreader); \
ih. name##susbeg=_mm_read_UBYTE(modreader); \ ih. name##susbeg=_mm_read_UBYTE(modreader); \
@@ -751,11 +777,13 @@ BOOL IT_Load(BOOL curious)
ih. name##node[lp]=_mm_read_##type (modreader); \ ih. name##node[lp]=_mm_read_##type (modreader); \
ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \ ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
} \ } \
_mm_read_UBYTE(modreader) _mm_skip_BYTE(modreader)
#else #else
#define IT_LoadEnvelope(name,type) \ #define IT_LoadEnvelope(name,type) \
ih. name/**/flg =_mm_read_UBYTE(modreader); \ ih. name/**/flg =_mm_read_UBYTE(modreader); \
ih. name/**/pts =_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/**/beg =_mm_read_UBYTE(modreader); \
ih. name/**/end =_mm_read_UBYTE(modreader); \ ih. name/**/end =_mm_read_UBYTE(modreader); \
ih. name/**/susbeg=_mm_read_UBYTE(modreader); \ ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
@@ -764,7 +792,7 @@ BOOL IT_Load(BOOL curious)
ih. name/**/node[lp]=_mm_read_/**/type (modreader); \ ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \ ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
} \ } \
_mm_read_UBYTE(modreader) _mm_skip_BYTE(modreader)
#endif #endif
IT_LoadEnvelope(vol,UBYTE); IT_LoadEnvelope(vol,UBYTE);
@@ -862,6 +890,7 @@ BOOL IT_Load(BOOL curious)
#endif #endif
IT_ProcessEnvelope(vol); IT_ProcessEnvelope(vol);
for(u=0;u<ih.volpts;u++) for(u=0;u<ih.volpts;u++)
d->volenv[u].val=(ih.volnode[u]<<2); d->volenv[u].val=(ih.volnode[u]<<2);
@@ -941,7 +970,7 @@ BOOL IT_Load(BOOL curious)
return 0; return 0;
} }
_mm_read_I_ULONG(modreader); _mm_read_I_ULONG(modreader);
if(IT_GetNumChannels(packlen)) return 0; if(!IT_GetNumChannels(packlen)) return 0;
} }
} }
@@ -973,6 +1002,7 @@ BOOL IT_Load(BOOL curious)
} else { } else {
_mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET); _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
packlen=_mm_read_I_UWORD(modreader); packlen=_mm_read_I_UWORD(modreader);
(void)packlen; /* unused */
of.pattrows[t]=_mm_read_I_UWORD(modreader); of.pattrows[t]=_mm_read_I_UWORD(modreader);
_mm_read_I_ULONG(modreader); _mm_read_I_ULONG(modreader);
if(!IT_ReadPattern(of.pattrows[t])) return 0; if(!IT_ReadPattern(of.pattrows[t])) return 0;
@@ -982,7 +1012,7 @@ BOOL IT_Load(BOOL curious)
return 1; return 1;
} }
CHAR *IT_LoadTitle(void) static CHAR *IT_LoadTitle(void)
{ {
CHAR s[26]; CHAR s[26];
+10 -8
View File
@@ -34,7 +34,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
@@ -42,6 +41,7 @@
#include <string.h> #include <string.h>
#include "mikmod_internals.h" #include "mikmod_internals.h"
#include "mikmod_ctype.h"
#ifdef SUNOS #ifdef SUNOS
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
@@ -111,7 +111,7 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
/* Star Tracker */ /* Star Tracker */
if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) && if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
(isdigit(id[3]))) { (mik_isdigit(id[3]))) {
*descr = startrekker; *descr = startrekker;
modtype = trekker = 1; modtype = trekker = 1;
*numchn = id[3] - '0'; *numchn = id[3] - '0';
@@ -141,7 +141,7 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
} }
/* Fasttracker */ /* Fasttracker */
if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) { if ((!memcmp(id + 1, "CHN", 3)) && (mik_isdigit(id[0]))) {
*descr = fasttracker; *descr = fasttracker;
modtype = 1; modtype = 1;
*numchn = id[0] - '0'; *numchn = id[0] - '0';
@@ -149,7 +149,7 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
} }
/* Fasttracker or Taketracker */ /* Fasttracker or Taketracker */
if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2))) if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2)))
&& (isdigit(id[0])) && (isdigit(id[1]))) { && (mik_isdigit(id[0])) && (mik_isdigit(id[1]))) {
if (id[3] == 'H') { if (id[3] == 'H') {
*descr = fasttracker; *descr = fasttracker;
modtype = 2; /* this can also be Imago Orpheus */ modtype = 2; /* this can also be Imago Orpheus */
@@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
{ {
MikMod_free(mh); MikMod_free(mh);
MikMod_free(patbuf); MikMod_free(patbuf);
mh=NULL;
patbuf=NULL;
} }
/* /*
@@ -323,7 +325,7 @@ static BOOL ML_LoadPatterns(void)
if (trekker && of.numchn == 8) { if (trekker && of.numchn == 8) {
/* Startrekker module dual pattern */ /* Startrekker module dual pattern */
for (t = 0; t < of.numpat; t++) { for (t = 0; t < of.numpat; t++) {
for (s = 0; s < (64 * 4); s++) { for (s = 0; s < (64U * 4); s++) {
patbuf[s].a = _mm_read_UBYTE(modreader); patbuf[s].a = _mm_read_UBYTE(modreader);
patbuf[s].b = _mm_read_UBYTE(modreader); patbuf[s].b = _mm_read_UBYTE(modreader);
patbuf[s].c = _mm_read_UBYTE(modreader); patbuf[s].c = _mm_read_UBYTE(modreader);
@@ -332,7 +334,7 @@ static BOOL ML_LoadPatterns(void)
for (s = 0; s < 4; s++) for (s = 0; s < 4; s++)
if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4))) if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
return 0; return 0;
for (s = 0; s < (64 * 4); s++) { for (s = 0; s < (64U * 4); s++) {
patbuf[s].a = _mm_read_UBYTE(modreader); patbuf[s].a = _mm_read_UBYTE(modreader);
patbuf[s].b = _mm_read_UBYTE(modreader); patbuf[s].b = _mm_read_UBYTE(modreader);
patbuf[s].c = _mm_read_UBYTE(modreader); patbuf[s].c = _mm_read_UBYTE(modreader);
@@ -346,7 +348,7 @@ static BOOL ML_LoadPatterns(void)
/* Generic module pattern */ /* Generic module pattern */
for (t = 0; t < of.numpat; t++) { for (t = 0; t < of.numpat; t++) {
/* Load the pattern into the temp buffer and convert it */ /* Load the pattern into the temp buffer and convert it */
for (s = 0; s < (64 * of.numchn); s++) { for (s = 0; s < (64U * of.numchn); s++) {
patbuf[s].a = _mm_read_UBYTE(modreader); patbuf[s].a = _mm_read_UBYTE(modreader);
patbuf[s].b = _mm_read_UBYTE(modreader); patbuf[s].b = _mm_read_UBYTE(modreader);
patbuf[s].c = _mm_read_UBYTE(modreader); patbuf[s].c = _mm_read_UBYTE(modreader);
@@ -476,7 +478,7 @@ static BOOL MOD_Load(BOOL curious)
q++; q++;
} }
of.modtype = strdup(descr); of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns()) if (!ML_LoadPatterns())
return 0; return 0;
+28 -18
View File
@@ -104,7 +104,7 @@ static unsigned int tracker; /* tracker id */
/* tracker identifiers */ /* tracker identifiers */
#define NUMTRACKERS 4 #define NUMTRACKERS 4
static CHAR* S3M_Version[] = { static const CHAR * S3M_Version[] = {
"Screamtracker x.xx", "Screamtracker x.xx",
"Imago Orpheus x.xx (S3M format)", "Imago Orpheus x.xx (S3M format)",
"Impulse Tracker x.xx (S3M format)", "Impulse Tracker x.xx (S3M format)",
@@ -113,11 +113,11 @@ static CHAR* S3M_Version[] = {
"Impulse Tracker 2.14p4 (S3M format)" "Impulse Tracker 2.14p4 (S3M format)"
}; };
/* version number position in above array */ /* 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 */ /*========== Loader code */
BOOL S3M_Test(void) static BOOL S3M_Test(void)
{ {
UBYTE id[4]; UBYTE id[4];
@@ -127,7 +127,7 @@ BOOL S3M_Test(void)
return 0; return 0;
} }
BOOL S3M_Init(void) static BOOL S3M_Init(void)
{ {
if(!(s3mbuf=(S3MNOTE*)MikMod_malloc(32*64*sizeof(S3MNOTE)))) return 0; if(!(s3mbuf=(S3MNOTE*)MikMod_malloc(32*64*sizeof(S3MNOTE)))) return 0;
if(!(mh=(S3MHEADER*)MikMod_malloc(sizeof(S3MHEADER)))) return 0; if(!(mh=(S3MHEADER*)MikMod_malloc(sizeof(S3MHEADER)))) return 0;
@@ -137,13 +137,18 @@ BOOL S3M_Init(void)
return 1; return 1;
} }
void S3M_Cleanup(void) static void S3M_Cleanup(void)
{ {
MikMod_free(s3mbuf); MikMod_free(s3mbuf);
MikMod_free(paraptr); MikMod_free(paraptr);
MikMod_free(poslookup); MikMod_free(poslookup);
MikMod_free(mh); MikMod_free(mh);
MikMod_free(origpositions); 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 /* Because so many s3m files have 16 channels as the set number used, but really
@@ -156,7 +161,7 @@ void S3M_Cleanup(void)
NOTE: You must first seek to the file location of the pattern before calling NOTE: You must first seek to the file location of the pattern before calling
this procedure. this procedure.
Returns 1 on fail. */ Returns 0 on fail. */
static BOOL S3M_GetNumChannels(void) static BOOL S3M_GetNumChannels(void)
{ {
int row=0,flag,ch; int row=0,flag,ch;
@@ -166,18 +171,18 @@ static BOOL S3M_GetNumChannels(void)
if(_mm_eof(modreader)) { if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN; _mm_errno = MMERR_LOADING_PATTERN;
return 1; return 0;
} }
if(flag) { if(flag) {
ch=flag&31; ch=flag&31;
if(mh->channels[ch]<32) remap[ch] = 0; if(mh->channels[ch]<32) remap[ch] = 0;
if(flag&32) {_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} if(flag&32) {_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
if(flag&64) _mm_read_UBYTE(modreader); if(flag&64) _mm_skip_BYTE(modreader);
if(flag&128){_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} if(flag&128){_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
} else row++; } else row++;
} }
return 0; return 1;
} }
static BOOL S3M_ReadPattern(void) static BOOL S3M_ReadPattern(void)
@@ -250,7 +255,7 @@ static UBYTE* S3M_ConvertTrack(S3MNOTE* tr)
return UniDup(); return UniDup();
} }
BOOL S3M_Load(BOOL curious) static BOOL S3M_Load(BOOL curious)
{ {
int t,u,track = 0; int t,u,track = 0;
SAMPLE *q; SAMPLE *q;
@@ -282,6 +287,10 @@ BOOL S3M_Load(BOOL curious)
_mm_errno = MMERR_LOADING_HEADER; _mm_errno = MMERR_LOADING_HEADER;
return 0; 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 */ /* then we can decide the module type */
tracker=mh->tracker>>12; tracker=mh->tracker>>12;
@@ -294,7 +303,7 @@ BOOL S3M_Load(BOOL curious)
tracker=NUMTRACKERS; /* IT 2.14p3 */ tracker=NUMTRACKERS; /* IT 2.14p3 */
else tracker--; else tracker--;
} }
of.modtype = strdup(S3M_Version[tracker]); of.modtype = MikMod_strdup(S3M_Version[tracker]);
if(tracker<NUMTRACKERS) { if(tracker<NUMTRACKERS) {
of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0'; of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0';
of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0'; of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0';
@@ -315,7 +324,7 @@ BOOL S3M_Load(BOOL curious)
/* read the order data */ /* read the order data */
if(!AllocPositions(mh->ordnum)) return 0; 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++) { for(t=0;t<mh->ordnum;t++) {
origpositions[t]=_mm_read_UBYTE(modreader); origpositions[t]=_mm_read_UBYTE(modreader);
@@ -374,7 +383,8 @@ BOOL S3M_Load(BOOL curious)
_mm_read_string(s.scrs,4,modreader); _mm_read_string(s.scrs,4,modreader);
/* ScreamTracker imposes a 64000 bytes (not 64k !) limit */ /* 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; s.length = 64000;
if(_mm_eof(modreader)) { if(_mm_eof(modreader)) {
@@ -388,7 +398,7 @@ BOOL S3M_Load(BOOL curious)
q->loopstart = s.loopbeg; q->loopstart = s.loopbeg;
q->loopend = s.loopend; q->loopend = s.loopend;
q->volume = s.volume; 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&1) q->flags |= SF_LOOP;
if(s.flags&4) q->flags |= SF_16BITS; if(s.flags&4) q->flags |= SF_16BITS;
@@ -406,7 +416,7 @@ BOOL S3M_Load(BOOL curious)
for(t=0;t<of.numpat;t++) { for(t=0;t<of.numpat;t++) {
/* seek to pattern position (+2 skip pattern length) */ /* seek to pattern position (+2 skip pattern length) */
_mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET); _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 */ /* build the remap array */
@@ -444,7 +454,7 @@ BOOL S3M_Load(BOOL curious)
return 1; return 1;
} }
CHAR *S3M_LoadTitle(void) static CHAR *S3M_LoadTitle(void)
{ {
CHAR s[28]; CHAR s[28];
+18 -12
View File
@@ -90,7 +90,7 @@ static STMNOTE *stmbuf = NULL;
static STMHEADER *mh = NULL; static STMHEADER *mh = NULL;
/* tracker identifiers */ /* tracker identifiers */
static CHAR* STM_Version[STM_NTRACKERS] = { static const CHAR * STM_Version[STM_NTRACKERS] = {
"Screamtracker 2", "Screamtracker 2",
"Converted by MOD2STM (STM format)", "Converted by MOD2STM (STM format)",
"Wuzamod (STM format)" "Wuzamod (STM format)"
@@ -98,7 +98,7 @@ static CHAR* STM_Version[STM_NTRACKERS] = {
/*========== Loader code */ /*========== Loader code */
BOOL STM_Test(void) static BOOL STM_Test(void)
{ {
UBYTE str[44]; UBYTE str[44];
int t; int t;
@@ -118,7 +118,7 @@ BOOL STM_Test(void)
return 0; return 0;
} }
BOOL STM_Init(void) static BOOL STM_Init(void)
{ {
if(!(mh=(STMHEADER*)MikMod_malloc(sizeof(STMHEADER)))) return 0; if(!(mh=(STMHEADER*)MikMod_malloc(sizeof(STMHEADER)))) return 0;
if(!(stmbuf=(STMNOTE*)MikMod_calloc(64U*4,sizeof(STMNOTE)))) return 0; if(!(stmbuf=(STMNOTE*)MikMod_calloc(64U*4,sizeof(STMNOTE)))) return 0;
@@ -130,6 +130,8 @@ static void STM_Cleanup(void)
{ {
MikMod_free(mh); MikMod_free(mh);
MikMod_free(stmbuf); MikMod_free(stmbuf);
mh=NULL;
stmbuf=NULL;
} }
static void STM_ConvertNote(STMNOTE *n) static void STM_ConvertNote(STMNOTE *n)
@@ -231,7 +233,7 @@ static BOOL STM_LoadPatterns(void)
/* Allocate temporary buffer for loading and converting the patterns */ /* Allocate temporary buffer for loading and converting the patterns */
for(t=0;t<of.numpat;t++) { for(t=0;t<of.numpat;t++) {
for(s=0;s<(64*of.numchn);s++) { for(s=0;s<(64U*of.numchn);s++) {
stmbuf[s].note = _mm_read_UBYTE(modreader); stmbuf[s].note = _mm_read_UBYTE(modreader);
stmbuf[s].insvol = _mm_read_UBYTE(modreader); stmbuf[s].insvol = _mm_read_UBYTE(modreader);
stmbuf[s].volcmd = _mm_read_UBYTE(modreader); stmbuf[s].volcmd = _mm_read_UBYTE(modreader);
@@ -249,14 +251,12 @@ static BOOL STM_LoadPatterns(void)
return 1; return 1;
} }
BOOL STM_Load(BOOL curious) static BOOL STM_Load(BOOL curious)
{ {
int t; int t;
ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */ ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */
SAMPLE *q; SAMPLE *q;
(void)curious; /* unused arg */
/* try to read stm header */ /* try to read stm header */
_mm_read_string(mh->songname,20,modreader); _mm_read_string(mh->songname,20,modreader);
_mm_read_string(mh->trackername,8,modreader); _mm_read_string(mh->trackername,8,modreader);
@@ -272,6 +272,10 @@ BOOL STM_Load(BOOL curious)
mh->numpat =_mm_read_UBYTE(modreader); mh->numpat =_mm_read_UBYTE(modreader);
mh->globalvol =_mm_read_UBYTE(modreader); mh->globalvol =_mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->reserved,13,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++) { for(t=0;t<31;t++) {
STMSAMPLE *s=&mh->sample[t]; /* STM sample data */ STMSAMPLE *s=&mh->sample[t]; /* STM sample data */
@@ -299,7 +303,7 @@ BOOL STM_Load(BOOL curious)
/* set module variables */ /* set module variables */
for(t=0;t<STM_NTRACKERS;t++) for(t=0;t<STM_NTRACKERS;t++)
if(!memcmp(mh->trackername,STM_Signatures[t],8)) break; if(!memcmp(mh->trackername,STM_Signatures[t],8)) break;
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.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */
of.numpat = mh->numpat; of.numpat = mh->numpat;
of.inittempo = 125; /* mh->inittempo+0x1c; */ of.inittempo = 125; /* mh->inittempo+0x1c; */
@@ -314,7 +318,10 @@ BOOL STM_Load(BOOL curious)
/* 99 terminates the patorder list */ /* 99 terminates the patorder list */
while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) { while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) {
of.positions[t]=mh->patorder[t]; of.positions[t]=mh->patorder[t];
t++; if(++t == 0x80) {
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
} }
if(mh->patorder[t]<=99) t++; if(mh->patorder[t]<=99) t++;
of.numpos=t; of.numpos=t;
@@ -332,7 +339,7 @@ BOOL STM_Load(BOOL curious)
q->speed = (mh->sample[t].c2spd * 8363) / 8448; q->speed = (mh->sample[t].c2spd * 8363) / 8448;
q->volume = mh->sample[t].volume; q->volume = mh->sample[t].volume;
q->length = mh->sample[t].length; 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->loopstart = mh->sample[t].loopbeg;
q->loopend = mh->sample[t].loopend; q->loopend = mh->sample[t].loopend;
q->seekpos = MikMod_ISA; q->seekpos = MikMod_ISA;
@@ -349,7 +356,7 @@ BOOL STM_Load(BOOL curious)
return 1; return 1;
} }
CHAR *STM_LoadTitle(void) static CHAR *STM_LoadTitle(void)
{ {
CHAR s[20]; CHAR s[20];
@@ -372,5 +379,4 @@ MIKMODAPI MLOADER load_stm={
STM_LoadTitle STM_LoadTitle
}; };
/* ex:set ts=4: */ /* ex:set ts=4: */
+68 -45
View File
@@ -136,7 +136,7 @@ static XMWAVHEADER *wh=NULL,*s=NULL;
/*========== Loader code */ /*========== Loader code */
BOOL XM_Test(void) static BOOL XM_Test(void)
{ {
UBYTE id[38]; UBYTE id[38];
@@ -146,15 +146,16 @@ BOOL XM_Test(void)
return 0; return 0;
} }
BOOL XM_Init(void) static BOOL XM_Init(void)
{ {
if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0; if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0;
return 1; return 1;
} }
void XM_Cleanup(void) static void XM_Cleanup(void)
{ {
MikMod_free(mh); MikMod_free(mh);
mh=NULL;
} }
static int XM_ReadNote(XMNOTE* n) static int XM_ReadNote(XMNOTE* n)
@@ -443,11 +444,17 @@ static void FixEnvelope(ENVPT *cur, int pts)
static BOOL LoadInstruments(void) static BOOL LoadInstruments(void)
{ {
long filend,ck;
int t,u; int t,u;
INSTRUMENT *d; INSTRUMENT *d;
ULONG next=0; ULONG next=0;
UWORD wavcnt=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; if(!AllocInstruments()) return 0;
d=of.instruments; d=of.instruments;
for(t=0;t<of.numins;t++,d++) { for(t=0;t<of.numins;t++,d++) {
@@ -460,6 +467,10 @@ static BOOL LoadInstruments(void)
headend = _mm_ftell(modreader); headend = _mm_ftell(modreader);
ih.size = _mm_read_I_ULONG(modreader); ih.size = _mm_read_I_ULONG(modreader);
headend += ih.size; headend += ih.size;
ck = _mm_ftell(modreader);
if ((headend<0) || (filend<headend) || (headend<ck)) {
break;
}
_mm_read_string(ih.name, 22, modreader); _mm_read_string(ih.name, 22, modreader);
ih.type = _mm_read_UBYTE(modreader); ih.type = _mm_read_UBYTE(modreader);
ih.numsmp = _mm_read_I_UWORD(modreader); ih.numsmp = _mm_read_I_UWORD(modreader);
@@ -493,7 +504,11 @@ static BOOL LoadInstruments(void)
/* read the remainder of the header /* read the remainder of the header
(2 bytes for 1.03, 22 for 1.04) */ (2 bytes for 1.03, 22 for 1.04) */
for(u=headend-_mm_ftell(modreader);u;u--) _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 /* we can't trust the envelope point count here, as some
modules have incorrect values (K_OSPACE.XM reports 32 volume modules have incorrect values (K_OSPACE.XM reports 32 volume
@@ -502,8 +517,8 @@ static BOOL LoadInstruments(void)
if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2; if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
if((_mm_eof(modreader))||(pth.volpts>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; } MikMod_free(nextwav);nextwav=NULL;
if(wh) { MikMod_free(wh);wh=NULL; } MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO; _mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0; return 0;
} }
@@ -570,15 +585,23 @@ static BOOL LoadInstruments(void)
everything over */ everything over */
if(mh->version>0x0103) next = 0; if(mh->version>0x0103) next = 0;
for(u=0;u<ih.numsmp;u++,s++) { 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 */ /* Allocate more room for sample information if necessary */
if(of.numsmp+u==wavcnt) { if(of.numsmp+u==wavcnt) {
wavcnt+=XM_SMPINCR; wavcnt+=XM_SMPINCR;
if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){ if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
if(wh) { MikMod_free(wh);wh=NULL; } MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY; _mm_errno = MMERR_OUT_OF_MEMORY;
return 0; return 0;
} }
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) { if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
MikMod_free(nextwav);nextwav=NULL; MikMod_free(nextwav);nextwav=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY; _mm_errno = MMERR_OUT_OF_MEMORY;
return 0; return 0;
@@ -603,13 +626,6 @@ static BOOL LoadInstruments(void)
nextwav[of.numsmp+u]=next; nextwav[of.numsmp+u]=next;
next+=s->length; 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) { if(mh->version>0x0103) {
@@ -620,9 +636,16 @@ static BOOL LoadInstruments(void)
of.numsmp+=ih.numsmp; of.numsmp+=ih.numsmp;
} else { } else {
/* read the remainder of the header */ /* read the remainder of the header */
for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader); ck = _mm_ftell(modreader);
if ((headend<0) || (filend<headend) || (headend<ck)) {
break;
}
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); MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL; nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO; _mm_errno = MMERR_LOADING_SAMPLEINFO;
@@ -634,8 +657,8 @@ static BOOL LoadInstruments(void)
/* sanity check */ /* sanity check */
if(!of.numsmp) { if(!of.numsmp) {
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; } MikMod_free(nextwav);nextwav=NULL;
if(wh) { MikMod_free(wh);wh=NULL; } MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO; _mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0; return 0;
} }
@@ -643,7 +666,7 @@ static BOOL LoadInstruments(void)
return 1; return 1;
} }
BOOL XM_Load(BOOL curious) static BOOL XM_Load(BOOL curious)
{ {
INSTRUMENT *d; INSTRUMENT *d;
SAMPLE *q; SAMPLE *q;
@@ -651,17 +674,13 @@ BOOL XM_Load(BOOL curious)
BOOL dummypat=0; BOOL dummypat=0;
char tracker[21],modtype[60]; char tracker[21],modtype[60];
(void)curious; /* unused arg */
/* try to read module header */ /* try to read module header */
_mm_read_string(mh->id,17,modreader); _mm_read_string(mh->id,17,modreader);
_mm_read_string(mh->songname,21,modreader); _mm_read_string(mh->songname,21,modreader);
_mm_read_string(mh->trackername,20,modreader); _mm_read_string(mh->trackername,20,modreader);
mh->version =_mm_read_I_UWORD(modreader); mh->version =_mm_read_I_UWORD(modreader);
if((mh->version<0x102)||(mh->version>0x104)) { if(mh->version < 0x102 || mh->version > 0x104)
_mm_errno=MMERR_NOT_A_MODULE; goto bad_xm;
return 0;
}
mh->headersize =_mm_read_I_ULONG(modreader); mh->headersize =_mm_read_I_ULONG(modreader);
mh->songlength =_mm_read_I_UWORD(modreader); mh->songlength =_mm_read_I_UWORD(modreader);
mh->restart =_mm_read_I_UWORD(modreader); mh->restart =_mm_read_I_UWORD(modreader);
@@ -671,22 +690,24 @@ BOOL XM_Load(BOOL curious)
mh->flags =_mm_read_I_UWORD(modreader); mh->flags =_mm_read_I_UWORD(modreader);
mh->tempo =_mm_read_I_UWORD(modreader); mh->tempo =_mm_read_I_UWORD(modreader);
mh->bpm =_mm_read_I_UWORD(modreader); mh->bpm =_mm_read_I_UWORD(modreader);
if(!mh->bpm) { if(mh->numchn > 64) goto bad_xm;
_mm_errno=MMERR_NOT_A_MODULE; if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255)
return 0; goto bad_xm;
} if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256)
_mm_read_UBYTES(mh->orders,256,modreader); goto bad_xm;
if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255)
if(_mm_eof(modreader)) { goto bad_xm;
_mm_errno = MMERR_LOADING_HEADER; /* _mm_read_UBYTES(mh->orders,256,modreader);*/
return 0; /* _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 */ /* set module variables */
of.initspeed = mh->tempo; of.initspeed = mh->tempo;
of.inittempo = mh->bpm; of.inittempo = mh->bpm;
strncpy(tracker,mh->trackername,20);tracker[20]=0; 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 */ /* some modules have the tracker name empty */
if (!tracker[0]) if (!tracker[0])
@@ -699,7 +720,7 @@ BOOL XM_Load(BOOL curious)
sprintf(modtype,"%s (XM format %d.%02d)", sprintf(modtype,"%s (XM format %d.%02d)",
tracker,mh->version>>8,mh->version&0xff); tracker,mh->version>>8,mh->version&0xff);
#endif #endif
of.modtype = strdup(modtype); of.modtype = MikMod_strdup(modtype);
of.numchn = mh->numchn; of.numchn = mh->numchn;
of.numpat = mh->numpat; of.numpat = mh->numpat;
of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */ of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */
@@ -707,8 +728,7 @@ BOOL XM_Load(BOOL curious)
of.numpos = mh->songlength; /* copy the songlength */ of.numpos = mh->songlength; /* copy the songlength */
of.reppos = mh->restart<mh->songlength?mh->restart:0; of.reppos = mh->restart<mh->songlength?mh->restart:0;
of.numins = mh->numins; of.numins = mh->numins;
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING;
UF_PANNING;
if(mh->flags&1) of.flags |= UF_LINEAR; if(mh->flags&1) of.flags |= UF_LINEAR;
of.bpmlimit = 32; of.bpmlimit = 32;
@@ -789,16 +809,19 @@ BOOL XM_Load(BOOL curious)
MikMod_free(wh);MikMod_free(nextwav); MikMod_free(wh);MikMod_free(nextwav);
wh=NULL;nextwav=NULL; wh=NULL;nextwav=NULL;
return 1; return 1;
bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0;
bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0;
} }
CHAR *XM_LoadTitle(void) static CHAR *XM_LoadTitle(void)
{ {
CHAR s[21]; CHAR str[21];
_mm_fseek(modreader,17,SEEK_SET); _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 */ /*========== Loader information */
+4 -8
View File
@@ -20,24 +20,20 @@
/*============================================================================== /*==============================================================================
$Id$
Routine for registering all drivers in libmikmod for the current platform. Routine for registering all drivers in libmikmod for the current platform.
==============================================================================*/ ==============================================================================*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "mikmod_internals.h" #include "mikmod_internals.h"
void _mm_registeralldrivers(void) static void _mm_registeralldrivers(void)
{ {
/* UQM Edit: cut down driver list to our one driver */
/* Register 'nosound' driver */
_mm_registerdriver(&drv_nos); _mm_registerdriver(&drv_nos);
} }
void MikMod_RegisterAllDrivers(void) MIKMODAPI void MikMod_RegisterAllDrivers(void)
{ {
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
_mm_registeralldrivers(); _mm_registeralldrivers();
+101 -65
View File
@@ -1,6 +1,6 @@
/* MikMod sound library /* MikMod sound library
(c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS (c) 1998-2014 Miodrag Vallat and others - see file AUTHORS
for complete list. for a complete list.
This library is free software; you can redistribute it and/or modify This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as it under the terms of the GNU Library General Public License as
@@ -20,8 +20,6 @@
/*============================================================================== /*==============================================================================
$Id$
These routines are used to access the available soundcard drivers. These routines are used to access the available soundcard drivers.
==============================================================================*/ ==============================================================================*/
@@ -34,47 +32,55 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if defined unix || (defined __APPLE__ && defined __MACH__)
#include <pwd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include <string.h> #include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include "mikmod_internals.h" #include "mikmod_internals.h"
#if (MIKMOD_UNIX)
#include <pwd.h>
#include <sys/stat.h>
#endif
#ifdef SUNOS #ifdef SUNOS
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
#endif #endif
static MDRIVER *firstdriver=NULL; /* UQM mod: include the UQM file that manages stricmp vs strcasecmp. */
MIKMODAPI MDRIVER *md_driver=NULL; #include "port.h"
extern MODULE *pf; /* modfile being played */ extern MODULE *pf; /* modfile being played */
/* EXPORTED GLOBALS */
MIKMODAPI MDRIVER *md_driver = NULL;
/* Initial global settings */ /* Initial global settings */
MIKMODAPI UWORD md_device = 0; /* autodetect */ MIKMODAPI UWORD md_device = 0; /* autodetect */
MIKMODAPI UWORD md_mixfreq = 44100; MIKMODAPI UWORD md_mixfreq = 44100;
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS | MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
DMODE_SURROUND |DMODE_SOFT_MUSIC | DMODE_SURROUND |
DMODE_SOFT_SNDFX; DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
MIKMODAPI UBYTE md_reverb = 0; /* no reverb */ MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */ MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */ MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */ MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
UWORD md_bpm = 125; /* tempo */
/* Do not modify the numchn variables yourself! use MD_SetVoices() */ /* INTERNAL GLOBALS */
UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0; UWORD md_bpm = 125; /* tempo */
UBYTE md_hardchn=0,md_softchn=0;
/* 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_callback_t vc_callback = NULL;
/* PRIVATE VARS */
static MDRIVER *firstdriver = NULL;
static volatile BOOL isplaying = 0, initialized = 0;
void (*md_player)(void) = Player_HandleTick;
static BOOL isplaying=0, initialized = 0;
static UBYTE *sfxinfo; static UBYTE *sfxinfo;
static int sfxpool; static int sfxpool;
@@ -183,16 +189,17 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void)
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
/* compute size of buffer */ /* compute size of buffer */
for(l=firstdriver;l;l=l->next) for(l = firstdriver; l; l = l->next)
len+=4+(l->next?1:0)+strlen(l->Version); len += 4 + (l->next ? 1 : 0) + strlen(l->Version);
if(len) if(len)
if((list=MikMod_malloc(len*sizeof(CHAR)))) { if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
list[0]=0; CHAR *list_end = list;
list[0] = 0;
/* list all registered device drivers : */ /* list all registered device drivers : */
for(t=1,l=firstdriver;l;l=l->next,t++) for(t = 1, l = firstdriver; l; l = l->next, t++) {
sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s", list_end += sprintf(list_end, "%2d %s%s", t, l->Version, (l->next)? "\n" : "");
list,t,l->Version); }
} }
MUTEX_UNLOCK(lists); MUTEX_UNLOCK(lists);
return list; return list;
@@ -205,7 +212,13 @@ void _mm_registerdriver(struct MDRIVER* drv)
/* don't register a MISSING() driver */ /* don't register a MISSING() driver */
if ((drv->Name) && (drv->Version)) { if ((drv->Name) && (drv->Version)) {
if (cruise) { if (cruise) {
while (cruise->next) cruise = cruise->next; if ( cruise == drv )
return;
while(cruise->next) {
cruise = cruise->next;
if ( cruise == drv )
return;
}
cruise->next = drv; cruise->next = drv;
} else } else
firstdriver = drv; firstdriver = drv;
@@ -224,7 +237,7 @@ MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv)
MUTEX_UNLOCK(lists); MUTEX_UNLOCK(lists);
} }
MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias) MIKMODAPI int MikMod_DriverFromAlias(const CHAR *alias)
{ {
int rank=1; int rank=1;
MDRIVER *cruise; MDRIVER *cruise;
@@ -244,6 +257,21 @@ MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
return rank; return rank;
} }
MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal)
{
MDRIVER *cruise;
/* Allow only driver ordinals > 0 */
if (!ordinal) return NULL;
MUTEX_LOCK(lists);
cruise = firstdriver;
while (cruise && --ordinal)
cruise = cruise->next;
MUTEX_UNLOCK(lists);
return cruise;
}
SWORD MD_SampleLoad(SAMPLOAD* s, int type) SWORD MD_SampleLoad(SAMPLOAD* s, int type)
{ {
SWORD result; SWORD result;
@@ -474,7 +502,12 @@ MIKMODAPI ULONG Voice_RealVolume(SBYTE voice)
return result; return result;
} }
static BOOL _mm_init(CHAR *cmdline) MIKMODAPI void VC_SetCallback(MikMod_callback_t callback)
{
vc_callback = callback;
}
static int _mm_init(const CHAR *cmdline)
{ {
UWORD t; UWORD t;
@@ -532,9 +565,9 @@ static BOOL _mm_init(CHAR *cmdline)
return 0; return 0;
} }
MIKMODAPI BOOL MikMod_Init(CHAR *cmdline) MIKMODAPI int MikMod_Init(const CHAR *cmdline)
{ {
BOOL result; int result;
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
@@ -552,8 +585,8 @@ void MikMod_Exit_internal(void)
md_numchn = md_sfxchn = md_sngchn = 0; md_numchn = md_sfxchn = md_sngchn = 0;
md_driver = &drv_nos; md_driver = &drv_nos;
if(sfxinfo) MikMod_free(sfxinfo); MikMod_free(sfxinfo);
if(md_sample) MikMod_free(md_sample); MikMod_free(md_sample);
md_sample = NULL; md_sample = NULL;
sfxinfo = NULL; sfxinfo = NULL;
@@ -571,7 +604,7 @@ MIKMODAPI void MikMod_Exit(void)
/* Reset the driver using the new global variable settings. /* Reset the driver using the new global variable settings.
If the driver has not been initialized, it will be now. */ If the driver has not been initialized, it will be now. */
static BOOL _mm_reset(CHAR *cmdline) static int _mm_reset(const CHAR *cmdline)
{ {
BOOL wasplaying = 0; BOOL wasplaying = 0;
@@ -601,13 +634,13 @@ static BOOL _mm_reset(CHAR *cmdline)
} }
} }
if (wasplaying) md_driver->PlayStart(); if (wasplaying) return md_driver->PlayStart();
return 0; return 0;
} }
MIKMODAPI BOOL MikMod_Reset(CHAR *cmdline) MIKMODAPI int MikMod_Reset(const CHAR *cmdline)
{ {
BOOL result; int result;
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
@@ -619,7 +652,7 @@ MIKMODAPI BOOL MikMod_Reset(CHAR *cmdline)
} }
/* If either parameter is -1, the current set value will be retained. */ /* If either parameter is -1, the current set value will be retained. */
BOOL MikMod_SetNumVoices_internal(int music, int sfx) int MikMod_SetNumVoices_internal(int music, int sfx)
{ {
BOOL resume = 0; BOOL resume = 0;
int t, oldchn = 0; int t, oldchn = 0;
@@ -632,8 +665,8 @@ BOOL MikMod_SetNumVoices_internal(int music, int sfx)
resume = 1; resume = 1;
} }
if(sfxinfo) MikMod_free(sfxinfo); MikMod_free(sfxinfo);
if(md_sample) MikMod_free(md_sample); MikMod_free(md_sample);
md_sample = NULL; md_sample = NULL;
sfxinfo = NULL; sfxinfo = NULL;
@@ -667,9 +700,9 @@ BOOL MikMod_SetNumVoices_internal(int music, int sfx)
return 0; return 0;
} }
MIKMODAPI BOOL MikMod_SetNumVoices(int music, int sfx) MIKMODAPI int MikMod_SetNumVoices(int music, int sfx)
{ {
BOOL result; int result;
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
result=MikMod_SetNumVoices_internal(music,sfx); result=MikMod_SetNumVoices_internal(music,sfx);
@@ -678,7 +711,7 @@ MIKMODAPI BOOL MikMod_SetNumVoices(int music, int sfx)
return result; return result;
} }
BOOL MikMod_EnableOutput_internal(void) int MikMod_EnableOutput_internal(void)
{ {
_mm_critical = 1; _mm_critical = 1;
if(!isplaying) { if(!isplaying) {
@@ -689,9 +722,9 @@ BOOL MikMod_EnableOutput_internal(void)
return 0; return 0;
} }
MIKMODAPI BOOL MikMod_EnableOutput(void) MIKMODAPI int MikMod_EnableOutput(void)
{ {
BOOL result; int result;
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
result=MikMod_EnableOutput_internal(); result=MikMod_EnableOutput_internal();
@@ -736,7 +769,7 @@ MIKMODAPI BOOL MikMod_Active(void)
criticals). criticals).
Returns the voice that the sound is being played on. */ Returns the voice that the sound is being played on. */
SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags) static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags)
{ {
int orig=sfxpool;/* for cases where all channels are critical */ int orig=sfxpool;/* for cases where all channels are critical */
int c; int c;
@@ -796,12 +829,15 @@ MIKMODAPI long MikMod_GetVersion(void)
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
#define INIT_MUTEX(name) \ #define INIT_MUTEX(name) \
pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER
#elif defined(__OS2__)||defined(__EMX__) #elif defined(__OS2__)||defined(__EMX__)
#define INIT_MUTEX(name) \ #define INIT_MUTEX(name) \
HMTX _mm_mutex_##name HMTX _mm_mutex_##name
#elif defined(WIN32)
#elif defined(_WIN32)
#define INIT_MUTEX(name) \ #define INIT_MUTEX(name) \
HANDLE _mm_mutex_##name HANDLE _mm_mutex_##name
#else #else
#define INIT_MUTEX(name) \ #define INIT_MUTEX(name) \
void *_mm_mutex_##name = NULL void *_mm_mutex_##name = NULL
@@ -813,7 +849,7 @@ INIT_MUTEX(lists);
MIKMODAPI BOOL MikMod_InitThreads(void) MIKMODAPI BOOL MikMod_InitThreads(void)
{ {
static int firstcall=1; static int firstcall=1;
static int result=0; static BOOL result = 0;
if (firstcall) { if (firstcall) {
firstcall=0; firstcall=0;
@@ -826,9 +862,9 @@ MIKMODAPI BOOL MikMod_InitThreads(void)
result=0; result=0;
} else } else
result=1; result=1;
#elif defined(WIN32) #elif defined(_WIN32)
if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))|| if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,TEXT("libmikmod(lists)"))))||
(!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)")))) (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,TEXT("libmikmod(vars)")))))
result=0; result=0;
else else
result=1; result=1;
@@ -851,24 +887,24 @@ MIKMODAPI void MikMod_Lock(void)
/*========== Parameter extraction helper */ /*========== Parameter extraction helper */
CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,BOOL implicit) CHAR *MD_GetAtom(const CHAR *atomname, const CHAR *cmdline, BOOL implicit)
{ {
CHAR *ret=NULL; CHAR *ret=NULL;
if(cmdline) { if(cmdline) {
CHAR *buf=strstr(cmdline,atomname); const CHAR *buf=strstr(cmdline,atomname);
if((buf)&&((buf==cmdline)||(*(buf-1)==','))) { if((buf)&&((buf==cmdline)||(*(buf-1)==','))) {
CHAR *ptr=buf+strlen(atomname); const CHAR *ptr=buf+strlen(atomname);
if(*ptr=='=') { if(*ptr=='=') {
for(buf=++ptr;(*ptr)&&((*ptr)!=',');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) if(ret)
strncpy(ret,buf,ptr-buf); strncpy(ret,buf,ptr-buf);
} else if((*ptr==',')||(!*ptr)) { } else if((*ptr==',')||(!*ptr)) {
if(implicit) { if(implicit) {
ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR)); ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
if(ret) if(ret)
strncpy(ret,buf,ptr-buf); strncpy(ret,buf,ptr-buf);
} }
@@ -878,7 +914,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,BOOL implicit)
return ret; return ret;
} }
#if defined unix || (defined __APPLE__ && defined __MACH__) #if (MIKMOD_UNIX)
/*========== Posix helper functions */ /*========== Posix helper functions */
@@ -887,7 +923,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,BOOL implicit)
reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise. 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 The goal is to prevent a setuid root libmikmod application from overriding
files like /etc/passwd with digital sound... */ files like /etc/passwd with digital sound... */
BOOL MD_Access(CHAR *filename) BOOL MD_Access(const CHAR * filename)
{ {
struct stat buf; struct stat buf;
@@ -909,7 +945,7 @@ BOOL MD_Access(CHAR *filename)
} }
/* Drop all root privileges we might have */ /* Drop all root privileges we might have */
BOOL MD_DropPrivileges(void) int MD_DropPrivileges(void)
{ {
if(!geteuid()) { if(!geteuid()) {
if(getuid()) { if(getuid()) {
@@ -932,4 +968,4 @@ BOOL MD_DropPrivileges(void)
#endif #endif
/* ex:set ts=4: */ /* ex:set ts=8: */
File diff suppressed because it is too large Load Diff
+197 -79
View File
@@ -1,5 +1,5 @@
/* MikMod sound library /* 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. for complete list.
This library is free software; you can redistribute it and/or modify This library is free software; you can redistribute it and/or modify
@@ -20,14 +20,12 @@
/*============================================================================== /*==============================================================================
$Id$
MikMod sound library include file MikMod sound library include file
==============================================================================*/ ==============================================================================*/
#ifndef LIBS_MIKMOD_MIKMOD_H_ #ifndef _MIKMOD_H_
#define LIBS_MIKMOD_MIKMOD_H_ #define _MIKMOD_H_
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -36,27 +34,16 @@
extern "C" { extern "C" {
#endif #endif
/* /* UQM MOD: Internal mikmod never has to worry about shared library symbol visibility. */
* ========== Compiler magic for shared libraries
*/
#if defined(LIBMIKMOD_DLL)
#if defined(DLL_EXPORTS)
#define MIKMODAPI __declspec(dllexport)
#else
#define MIKMODAPI __declspec(dllimport)
#endif
#else
#define MIKMODAPI #define MIKMODAPI
#endif
/* /*
* ========== Library version * ========== Library version
*/ */
#define LIBMIKMOD_VERSION_MAJOR 3L #define LIBMIKMOD_VERSION_MAJOR 3L
#define LIBMIKMOD_VERSION_MINOR 1L #define LIBMIKMOD_VERSION_MINOR 3L
#define LIBMIKMOD_REVISION 12L #define LIBMIKMOD_REVISION 11L
#define LIBMIKMOD_VERSION \ #define LIBMIKMOD_VERSION \
((LIBMIKMOD_VERSION_MAJOR<<16)| \ ((LIBMIKMOD_VERSION_MAJOR<<16)| \
@@ -66,51 +53,90 @@ extern "C" {
MIKMODAPI extern long MikMod_GetVersion(void); MIKMODAPI extern long MikMod_GetVersion(void);
/* /*
* ========== Platform independent-type definitions * ========== Dependency platform headers
*/ */
#if defined(WIN32)||defined(WIN64) #ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h> #include <windows.h>
#include <io.h> #include <io.h>
#include <mmsystem.h> #include <mmsystem.h>
#define _MIKMOD_WIN32
#endif #endif
#if defined(__OS2__)||defined(__EMX__) #if defined(__DJGPP__) || defined(MSDOS) || defined(__MSDOS__) || defined(__DOS__)
#define _MIKMOD_DOS
#endif
#if defined(__OS2__) || defined(__EMX__)
#define INCL_DOSSEMAPHORES #define INCL_DOSSEMAPHORES
#include <os2.h> #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; typedef char CHAR;
#endif #endif
/* BOOL: 0=false, <>0 true -- 16 bits on Amiga, int-wide on others. */
#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA))
typedef int BOOL;
#endif
/* 1 byte, signed and unsigned: */
typedef signed char SBYTE;
#ifndef _MIKMOD_AMIGA
typedef unsigned char UBYTE;
#endif
#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) \ /* 2 bytes, signed and unsigned: */
|| defined(__powerpc64__) || defined(_M_IA64) || defined(_M_AMD64) #ifndef __LCC__
/* 64 bit architectures */ typedef signed short int SWORD;
#endif
#if !(defined(__LCC__) || defined(_MIKMOD_AMIGA))
typedef unsigned short int UWORD;
#endif
typedef signed char SBYTE; /* 1 byte, signed */ /* 4 bytes, signed and unsigned: */
typedef unsigned char UBYTE; /* 1 byte, unsigned */ #if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__)
typedef signed short SWORD; /* 2 bytes, signed */ /* 64 bit architectures: */
typedef unsigned short UWORD; /* 2 bytes, unsigned */ typedef signed int SLONG;
typedef signed int SLONG; /* 4 bytes, signed */ #if !(defined(_WIN32) || defined(_MIKMOD_AMIGA))
typedef unsigned int ULONG; /* 4 bytes, unsigned */ typedef unsigned int ULONG;
typedef int BOOL; /* 0=false, <>0 true */ #endif
#else #else /* 32 bit architectures: */
/* 32 bit architectures */ typedef signed long int SLONG;
#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA))
typedef signed char SBYTE; /* 1 byte, signed */ typedef unsigned long int ULONG;
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 */
#endif #endif
#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(BOOL) == sizeof(int))
#endif
&& (sizeof(CHAR) == sizeof(char))
) * 2 - 1 ];
/* /*
* ========== Error codes * ========== Error codes
*/ */
@@ -195,6 +221,45 @@ enum {
MMERR_MAC_SPEED, MMERR_MAC_SPEED,
MMERR_MAC_START, MMERR_MAC_START,
MMERR_OSX_UNKNOWN_DEVICE,
MMERR_OSX_BAD_PROPERTY,
MMERR_OSX_UNSUPPORTED_FORMAT,
MMERR_OSX_SET_STEREO,
MMERR_OSX_BUFFER_ALLOC,
MMERR_OSX_ADD_IO_PROC,
MMERR_OSX_DEVICE_START,
MMERR_OSX_PTHREAD,
MMERR_DOSWSS_STARTDMA,
MMERR_DOSSB_STARTDMA,
MMERR_NO_FLOAT32,/* should actually be after MMERR_ULAW or something */
MMERR_OPENAL_CREATECTX,
MMERR_OPENAL_CTXCURRENT,
MMERR_OPENAL_GENBUFFERS,
MMERR_OPENAL_GENSOURCES,
MMERR_OPENAL_SOURCE,
MMERR_OPENAL_QUEUEBUFFERS,
MMERR_OPENAL_UNQUEUEBUFFERS,
MMERR_OPENAL_BUFFERDATA,
MMERR_OPENAL_GETSOURCE,
MMERR_OPENAL_SOURCEPLAY,
MMERR_OPENAL_SOURCESTOP,
MMERR_ALSA_NOCONFIG,
MMERR_ALSA_SETPARAMS,
MMERR_ALSA_SETFORMAT,
MMERR_ALSA_SETRATE,
MMERR_ALSA_SETCHANNELS,
MMERR_ALSA_BUFFERSIZE,
MMERR_ALSA_PCM_START,
MMERR_ALSA_PCM_WRITE,
MMERR_ALSA_PCM_RECOVER,
MMERR_SNDIO_SETPARAMS,
MMERR_SNDIO_BADPARAMS,
MMERR_MAX MMERR_MAX
}; };
@@ -207,7 +272,7 @@ typedef MikMod_handler *MikMod_handler_t;
MIKMODAPI extern int MikMod_errno; MIKMODAPI extern int MikMod_errno;
MIKMODAPI extern BOOL MikMod_critical; MIKMODAPI extern BOOL 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); MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t);
@@ -221,14 +286,15 @@ MIKMODAPI extern void MikMod_RegisterAllDrivers(void);
MIKMODAPI extern CHAR* MikMod_InfoDriver(void); MIKMODAPI extern CHAR* MikMod_InfoDriver(void);
MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); 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 BOOL MikMod_Init(CHAR*); MIKMODAPI extern int MikMod_Init(const CHAR*);
MIKMODAPI extern void MikMod_Exit(void); MIKMODAPI extern void MikMod_Exit(void);
MIKMODAPI extern BOOL MikMod_Reset(CHAR*); MIKMODAPI extern int MikMod_Reset(const CHAR*);
MIKMODAPI extern BOOL MikMod_SetNumVoices(int,int); MIKMODAPI extern int MikMod_SetNumVoices(int,int);
MIKMODAPI extern BOOL MikMod_Active(void); MIKMODAPI extern BOOL MikMod_Active(void);
MIKMODAPI extern BOOL MikMod_EnableOutput(void); MIKMODAPI extern int MikMod_EnableOutput(void);
MIKMODAPI extern void MikMod_DisableOutput(void); MIKMODAPI extern void MikMod_DisableOutput(void);
MIKMODAPI extern void MikMod_Update(void); MIKMODAPI extern void MikMod_Update(void);
@@ -237,16 +303,17 @@ MIKMODAPI extern void MikMod_Lock(void);
MIKMODAPI extern void MikMod_Unlock(void); MIKMODAPI extern void MikMod_Unlock(void);
MIKMODAPI extern void* MikMod_malloc(size_t); 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_calloc(size_t,size_t);
MIKMODAPI extern void MikMod_free(void *); MIKMODAPI extern void* MikMod_realloc(void*,size_t);
MIKMODAPI extern CHAR* MikMod_strdup(const CHAR*);
MIKMODAPI extern void MikMod_free(void*); /* frees if ptr != NULL */
/* /*
* ========== Reader, Writer * ========== Reader, Writer
*/ */
typedef struct MREADER { typedef struct MREADER {
BOOL (*Seek)(struct MREADER*,long,int); int (*Seek)(struct MREADER*,long,int);
long (*Tell)(struct MREADER*); long (*Tell)(struct MREADER*);
BOOL (*Read)(struct MREADER*,void*,size_t); BOOL (*Read)(struct MREADER*,void*,size_t);
int (*Get)(struct MREADER*); int (*Get)(struct MREADER*);
@@ -256,10 +323,10 @@ typedef struct MREADER {
} MREADER; } MREADER;
typedef struct MWRITER { typedef struct MWRITER {
BOOL (*Seek)(struct MWRITER*,long,int); int (*Seek)(struct MWRITER*, long, int);
long (*Tell)(struct MWRITER*); long (*Tell)(struct MWRITER*);
BOOL (*Write)(struct MWRITER*,void*,size_t); BOOL (*Write)(struct MWRITER*, const void*, size_t);
BOOL (*Put)(struct MWRITER*,int); int (*Put)(struct MWRITER*, int);
} MWRITER; } MWRITER;
/* /*
@@ -329,11 +396,18 @@ typedef struct SAMPLE {
UBYTE divfactor; /* for sample scaling, maintains proper period slides */ UBYTE divfactor; /* for sample scaling, maintains proper period slides */
ULONG seekpos; /* seek position in file */ ULONG seekpos; /* seek position in file */
SWORD handle; /* sample handle used by individual drivers */ SWORD handle; /* sample handle used by individual drivers */
void (*onfree)(void *ctx); /* called from Sample_Free if not NULL */
void *ctx; /* context passed to previous function*/
} SAMPLE; } SAMPLE;
/* Sample functions */ /* Sample functions */
MIKMODAPI extern SAMPLE *Sample_Load(CHAR*); MIKMODAPI extern SAMPLE *Sample_LoadRaw(const CHAR *,ULONG rate, ULONG channel, ULONG flags);
MIKMODAPI extern SAMPLE *Sample_LoadRawFP(FILE *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(const CHAR*);
MIKMODAPI extern SAMPLE *Sample_LoadFP(FILE*); MIKMODAPI extern SAMPLE *Sample_LoadFP(FILE*);
MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len); MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len);
MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*);
@@ -458,8 +532,10 @@ typedef struct MODULE {
UWORD numpat; /* number of patterns in this song */ UWORD numpat; /* number of patterns in this song */
UWORD numins; /* number of instruments */ UWORD numins; /* number of instruments */
UWORD numsmp; /* number of samples */ UWORD numsmp; /* number of samples */
struct INSTRUMENT* instruments; /* all instruments */
struct SAMPLE* samples; /* all samples */ struct INSTRUMENT* instruments; /* all instruments */
struct SAMPLE* samples; /* all samples */
UBYTE realchn; /* real number of channels used */ UBYTE realchn; /* real number of channels used */
UBYTE totalchn; /* total number of channels used (incl NNAs) */ UBYTE totalchn; /* total number of channels used (incl NNAs) */
@@ -498,8 +574,8 @@ struct SAMPLE* samples; /* all samples */
UWORD vbtick; /* tick counter (counts from 0 to sngspd) */ UWORD vbtick; /* tick counter (counts from 0 to sngspd) */
UWORD sngremainder;/* used for song time computation */ UWORD sngremainder;/* used for song time computation */
struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */
struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */ struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */
UBYTE globalslide; /* global volume slide rate */ UBYTE globalslide; /* global volume slide rate */
UBYTE pat_repcrazy;/* module has just looped to position -1 */ UBYTE pat_repcrazy;/* module has just looped to position -1 */
@@ -510,6 +586,17 @@ struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */
UWORD bpmlimit; /* threshold to detect bpm or speed values */ UWORD bpmlimit; /* threshold to detect bpm or speed values */
} MODULE; } MODULE;
/* This structure is used to query current playing voices status */
typedef struct VOICEINFO {
INSTRUMENT* i; /* Current channel instrument */
SAMPLE* s; /* Current channel sample */
SWORD panning; /* panning position */
SBYTE volume; /* channel's "global" volume (0..64) */
UWORD period; /* period to play the sample at */
UBYTE kick; /* if true = sample has been restarted */
} VOICEINFO;
/* /*
* ========== Module loaders * ========== Module loaders
*/ */
@@ -522,9 +609,11 @@ MIKMODAPI extern void MikMod_RegisterLoader(struct MLOADER*);
MIKMODAPI extern struct MLOADER load_669; /* 669 and Extended-669 (by Tran/Renaissance) */ MIKMODAPI extern struct MLOADER load_669; /* 669 and Extended-669 (by Tran/Renaissance) */
MIKMODAPI extern struct MLOADER load_amf; /* DMP Advanced Module Format (by Otto Chrons) */ MIKMODAPI extern struct MLOADER load_amf; /* DMP Advanced Module Format (by Otto Chrons) */
MIKMODAPI extern struct MLOADER load_asy; /* ASYLUM Music Format 1.0 */
MIKMODAPI extern struct MLOADER load_dsm; /* DSIK internal module format */ MIKMODAPI extern struct MLOADER load_dsm; /* DSIK internal module format */
MIKMODAPI extern struct MLOADER load_far; /* Farandole Composer (by Daniel Potter) */ MIKMODAPI extern struct MLOADER load_far; /* Farandole Composer (by Daniel Potter) */
MIKMODAPI extern struct MLOADER load_gdm; /* General DigiMusic (by Edward Schlunder) */ MIKMODAPI extern struct MLOADER load_gdm; /* General DigiMusic (by Edward Schlunder) */
MIKMODAPI extern struct MLOADER load_gt2; /* Graoumf tracker */
MIKMODAPI extern struct MLOADER load_it; /* Impulse Tracker (by Jeffrey Lim) */ MIKMODAPI extern struct MLOADER load_it; /* Impulse Tracker (by Jeffrey Lim) */
MIKMODAPI extern struct MLOADER load_imf; /* Imago Orpheus (by Lutz Roeder) */ MIKMODAPI extern struct MLOADER load_imf; /* Imago Orpheus (by Lutz Roeder) */
MIKMODAPI extern struct MLOADER load_med; /* Amiga MED modules (by Teijo Kinnunen) */ MIKMODAPI extern struct MLOADER load_med; /* Amiga MED modules (by Teijo Kinnunen) */
@@ -536,6 +625,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_stx; /* STMIK 0.2 (by Future Crew) */
MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (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_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_uni; /* MikMod and APlayer internal module format */
MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */
@@ -543,11 +633,11 @@ MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */
* ========== Module player * ========== Module player
*/ */
MIKMODAPI extern MODULE* Player_Load(CHAR*,int,BOOL); MIKMODAPI extern MODULE* Player_Load(const CHAR*,int,BOOL);
MIKMODAPI extern MODULE* Player_LoadFP(FILE*,int,BOOL); MIKMODAPI extern MODULE* Player_LoadFP(FILE*,int,BOOL);
MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,BOOL curious); MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,BOOL curious);
MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,BOOL); MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,BOOL);
MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*); MIKMODAPI extern CHAR* Player_LoadTitle(const CHAR*);
MIKMODAPI extern CHAR* Player_LoadTitleFP(FILE*); MIKMODAPI extern CHAR* Player_LoadTitleFP(FILE*);
MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len); MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len);
MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*); MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*);
@@ -571,9 +661,12 @@ MIKMODAPI extern void Player_Mute(SLONG,...);
MIKMODAPI extern void Player_ToggleMute(SLONG,...); MIKMODAPI extern void Player_ToggleMute(SLONG,...);
MIKMODAPI extern int Player_GetChannelVoice(UBYTE); MIKMODAPI extern int Player_GetChannelVoice(UBYTE);
MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE);
MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo);
MIKMODAPI extern int Player_GetRow(void);
MIKMODAPI extern int Player_GetOrder(void);
typedef void (MikMod_player)(void); typedef void (*MikMod_player_t)(void);
typedef MikMod_player *MikMod_player_t; typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t); MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t);
@@ -602,33 +695,39 @@ enum {
#define DMODE_SOFT_SNDFX 0x0004 /* Process sound effects via software mixer */ #define DMODE_SOFT_SNDFX 0x0004 /* Process sound effects via software mixer */
#define DMODE_SOFT_MUSIC 0x0008 /* Process music via software mixer */ #define DMODE_SOFT_MUSIC 0x0008 /* Process music via software mixer */
#define DMODE_HQMIXER 0x0010 /* Use high-quality (slower) software mixer */ #define DMODE_HQMIXER 0x0010 /* Use high-quality (slower) software mixer */
#define DMODE_FLOAT 0x0020 /* enable float output */
/* These take effect immediately. */ /* These take effect immediately. */
#define DMODE_SURROUND 0x0100 /* enable surround sound */ #define DMODE_SURROUND 0x0100 /* enable surround sound */
#define DMODE_INTERP 0x0200 /* enable interpolation */ #define DMODE_INTERP 0x0200 /* enable interpolation */
#define DMODE_REVERSE 0x0400 /* reverse stereo */ #define DMODE_REVERSE 0x0400 /* reverse stereo */
#define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */
#define DMODE_NOISEREDUCTION 0x1000 /* Low pass filtering */
struct SAMPLOAD; struct SAMPLOAD;
typedef struct MDRIVER { typedef struct MDRIVER {
struct MDRIVER* next; struct MDRIVER* next;
CHAR* Name; const CHAR* Name;
CHAR* Version; const CHAR* Version;
UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */ UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */
UBYTE SoftVoiceLimit; /* Limit of software mixer voices */ UBYTE SoftVoiceLimit; /* Limit of software mixer voices */
CHAR* Alias; const CHAR* Alias;
const CHAR* CmdLineHelp;
void (*CommandLine) (CHAR*); void (*CommandLine) (const CHAR*);
BOOL (*IsPresent) (void); BOOL (*IsPresent) (void);
SWORD (*SampleLoad) (struct SAMPLOAD*,int); SWORD (*SampleLoad) (struct SAMPLOAD*,int);
void (*SampleUnload) (SWORD); void (*SampleUnload) (SWORD);
ULONG (*FreeSampleSpace) (int); ULONG (*FreeSampleSpace) (int);
ULONG (*RealSampleLength) (int,struct SAMPLE*); ULONG (*RealSampleLength) (int,struct SAMPLE*);
BOOL (*Init) (void); int (*Init) (void);
void (*Exit) (void); void (*Exit) (void);
BOOL (*Reset) (void); int (*Reset) (void);
BOOL (*SetNumVoices) (void); int (*SetNumVoices) (void);
BOOL (*PlayStart) (void); int (*PlayStart) (void);
void (*PlayStop) (void); void (*PlayStop) (void);
void (*Update) (void); void (*Update) (void);
void (*Pause) (void); void (*Pause) (void);
@@ -670,36 +769,55 @@ 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_raw; /* raw file disk writer [music.raw] */
MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */
MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music.wav] */ MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music.wav] */
MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */
MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */
MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */ MIKMODAPI extern struct MDRIVER drv_sam9407;/* Linux sam9407 driver */
MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ MIKMODAPI extern struct MDRIVER drv_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_aix; /* AIX audio device */
MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ 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_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_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_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_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_sun; /* Sun/NetBSD/OpenBSD audio device */
MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ 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_os2; /* OS/2 MMPM/2 */
MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ 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_win; /* Win32 multimedia API driver */
MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager 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_wss; /* DOS WSS driver */
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) */ /*========== Virtual channel mixer interface (for user-supplied drivers only) */
MIKMODAPI extern BOOL VC_Init(void); MIKMODAPI extern int VC_Init(void);
MIKMODAPI extern void VC_Exit(void); MIKMODAPI extern void VC_Exit(void);
MIKMODAPI extern BOOL VC_SetNumVoices(void); MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback);
MIKMODAPI extern int VC_SetNumVoices(void);
MIKMODAPI extern ULONG VC_SampleSpace(int); MIKMODAPI extern ULONG VC_SampleSpace(int);
MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*);
MIKMODAPI extern BOOL VC_PlayStart(void); MIKMODAPI extern int VC_PlayStart(void);
MIKMODAPI extern void VC_PlayStop(void); MIKMODAPI extern void VC_PlayStop(void);
MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int);
+84
View File
@@ -0,0 +1,84 @@
/* Locale insensitive ctype.h functions taken from the RPM library.
* RPM is Copyright (c) 1998 by Red Hat Software, Inc.
*
* 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.
*/
#ifndef MIKMOD_CTYPE_H
#define MIKMOD_CTYPE_H
static inline int mik_isascii(int c) {
return ((c & ~0x7f) == 0);
}
static inline int mik_islower(int c) {
return (c >= 'a' && c <= 'z');
}
static inline int mik_isupper(int c) {
return (c >= 'A' && c <= 'Z');
}
static inline int mik_isalpha(int c) {
return (mik_islower(c) || mik_isupper(c));
}
static inline int mik_isdigit(int c) {
return (c >= '0' && c <= '9');
}
static inline int mik_isxdigit(int c) {
return (mik_isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
static inline int mik_isalnum(int c) {
return (mik_isalpha(c) || mik_isdigit(c));
}
static inline int mik_isblank(int c) {
return (c == ' ' || c == '\t');
}
static inline int mik_isspace(int c) {
switch (c) {
case ' ': case '\t':
case '\n': case '\r':
case '\f': case '\v': return 1;
}
return 0;
}
static inline int mik_isgraph(int c) {
return (c > 0x20 && c <= 0x7e);
}
static inline int mik_isprint(int c) {
return (c >= 0x20 && c <= 0x7e);
}
static inline int mik_toascii(int c) {
return (c & 0x7f);
}
static inline int mik_tolower(int c) {
return ((mik_isupper(c)) ? (c | ('a' - 'A')) : c);
}
static inline int mik_toupper(int c) {
return ((mik_islower(c)) ? (c & ~('a' - 'A')) : c);
}
#endif /* MIKMOD_CTYPE_H */
+258 -68
View File
@@ -1,5 +1,5 @@
/* MikMod sound library /* MikMod sound library
(c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for (c) 1998, 1999, 2005 Miodrag Vallat and others - see file AUTHORS for
complete list. complete list.
This library is free software; you can redistribute it and/or modify This library is free software; you can redistribute it and/or modify
@@ -20,47 +20,64 @@
/*============================================================================== /*==============================================================================
$Id$
MikMod sound library internal definitions MikMod sound library internal definitions
==============================================================================*/ ==============================================================================*/
#ifndef LIBS_MIKMOD_MIKMOD_INTERNALS_H_ #ifndef _MIKMOD_INTERNALS_H
#define LIBS_MIKMOD_MIKMOD_INTERNALS_H_ #define _MIKMOD_INTERNALS_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdarg.h> #include <stdarg.h>
#if defined(__OS2__)||defined(__EMX__)||defined(WIN32)||defined(WIN64)
#define strcasecmp(s,t) stricmp(s,t) #if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H)
#define inline __inline
#endif #endif
#define MIKMOD_INTERNAL #include "mikmod.h"
#include "mikmod_build.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 */ /*========== More type definitions */
/* SLONGLONG: 64bit, signed */ /* SLONGLONG: 64bit, signed */
#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) \ #if !defined(_WIN32) && \
|| defined(_M_IA64) || defined(_M_AMD64) (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
typedef long SLONGLONG; typedef long SLONGLONG;
#define NATIVE_64BIT_INT #define NATIVE_64BIT_INT
#elif defined(__powerpc64__) #elif defined(_WIN64) /* win64 is LLP64, not LP64 */
typedef long long SLONGLONG;
#define NATIVE_64BIT_INT #define NATIVE_64BIT_INT
typedef long long SLONGLONG;
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
typedef __int64 SLONGLONG; typedef __int64 SLONGLONG;
#elif defined(WIN32) && !defined(__MWERKS__) #elif defined(_WIN32) && !defined(__MWERKS__)
typedef LONGLONG SLONGLONG; typedef LONGLONG SLONGLONG;
#elif macintosh && !TYPE_LONGLONG #elif defined(macintosh) && !TYPE_LONGLONG
#include <Types.h> #include <Types.h>
typedef SInt64 SLONGLONG; typedef SInt64 SLONGLONG;
#else #else
typedef long long SLONGLONG; typedef long long SLONGLONG;
#endif #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 */ /*========== Error handling */
@@ -78,25 +95,28 @@ extern MikMod_handler_t _mm_errorhandler;
pthread_mutex_lock(&_mm_mutex_##name) pthread_mutex_lock(&_mm_mutex_##name)
#define MUTEX_UNLOCK(name) \ #define MUTEX_UNLOCK(name) \
pthread_mutex_unlock(&_mm_mutex_##name) pthread_mutex_unlock(&_mm_mutex_##name)
#elif defined(__OS2__)||defined(__EMX__) #elif defined(__OS2__)||defined(__EMX__)
#define DECLARE_MUTEX(name) \ #define DECLARE_MUTEX(name) \
extern HMTX _mm_mutex_##name extern HMTX _mm_mutex_##name
#define MUTEX_LOCK(name) \ #define MUTEX_LOCK(name) \
if(_mm_mutex_##name) \ if(_mm_mutex_##name)\
DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT)
#define MUTEX_UNLOCK(name) \ #define MUTEX_UNLOCK(name) \
if(_mm_mutex_##name) \ if(_mm_mutex_##name)\
DosReleaseMutexSem(_mm_mutex_##name) DosReleaseMutexSem(_mm_mutex_##name)
#elif defined(WIN32) || defined(WIN64)
#elif defined(_WIN32)
#include <windows.h> #include <windows.h>
#define DECLARE_MUTEX(name) \ #define DECLARE_MUTEX(name) \
extern HANDLE _mm_mutex_##name extern HANDLE _mm_mutex_##name
#define MUTEX_LOCK(name) \ #define MUTEX_LOCK(name) \
if(_mm_mutex_##name) \ if(_mm_mutex_##name)\
WaitForSingleObject(_mm_mutex_##name,INFINITE) WaitForSingleObject(_mm_mutex_##name,INFINITE)
#define MUTEX_UNLOCK(name) \ #define MUTEX_UNLOCK(name) \
if(_mm_mutex_##name) \ if(_mm_mutex_##name)\
ReleaseMutex(_mm_mutex_##name) ReleaseMutex(_mm_mutex_##name)
#else #else
#define DECLARE_MUTEX(name) \ #define DECLARE_MUTEX(name) \
extern void *_mm_mutex_##name extern void *_mm_mutex_##name
@@ -107,9 +127,13 @@ extern MikMod_handler_t _mm_errorhandler;
DECLARE_MUTEX(lists); DECLARE_MUTEX(lists);
DECLARE_MUTEX(vars); DECLARE_MUTEX(vars);
/*========== Replacement funcs */
extern int _mm_strcasecmp (const char *__s1, const char *__s2);
/*========== Portable file I/O */ /*========== 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 void _mm_delete_mem_reader(MREADER *reader);
extern MREADER* _mm_new_file_reader(FILE* fp); extern MREADER* _mm_new_file_reader(FILE* fp);
@@ -118,16 +142,17 @@ extern void _mm_delete_file_reader(MREADER*);
extern MWRITER* _mm_new_file_writer(FILE *fp); extern MWRITER* _mm_new_file_writer(FILE *fp);
extern void _mm_delete_file_writer(MWRITER*); extern void _mm_delete_file_writer(MWRITER*);
extern BOOL _mm_FileExists(CHAR *fname); extern BOOL _mm_FileExists(const CHAR *fname);
#define _mm_write_SBYTE(x,y) y->Put(y,(int)x) #define _mm_write_SBYTE(x,y) y->Put(y,(int)x)
#define _mm_write_UBYTE(x,y) y->Put(y,(int)x) #define _mm_write_UBYTE(x,y) y->Put(y,(int)x)
#define _mm_read_SBYTE(x) (SBYTE)x->Get(x) #define _mm_read_SBYTE(x) (SBYTE)x->Get(x)
#define _mm_read_UBYTE(x) (UBYTE)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_SBYTES(x,y,z) z->Write(z,(const void *)x,y)
#define _mm_write_UBYTES(x,y,z) z->Write(z,(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_SBYTES(x,y,z) z->Read(z,(void *)x,y)
#define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y) #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y)
@@ -139,10 +164,10 @@ extern BOOL _mm_FileExists(CHAR *fname);
extern void _mm_iobase_setcur(MREADER*); extern void _mm_iobase_setcur(MREADER*);
extern void _mm_iobase_revert(MREADER*); extern void _mm_iobase_revert(MREADER*);
extern FILE *_mm_fopen(CHAR*,CHAR*); extern FILE* _mm_fopen(const CHAR *, const CHAR *);
extern int _mm_fclose(FILE *); extern int _mm_fclose(FILE *);
extern void _mm_write_string(CHAR*,MWRITER*); extern void _mm_write_string(const CHAR*,MWRITER*);
extern int _mm_read_string (CHAR*,int,MREADER*); extern BOOL _mm_read_string (CHAR*,int,MREADER*);
extern SWORD _mm_read_M_SWORD(MREADER*); extern SWORD _mm_read_M_SWORD(MREADER*);
extern SWORD _mm_read_I_SWORD(MREADER*); extern SWORD _mm_read_I_SWORD(MREADER*);
@@ -154,15 +179,15 @@ extern SLONG _mm_read_I_SLONG(MREADER*);
extern ULONG _mm_read_M_ULONG(MREADER*); extern ULONG _mm_read_M_ULONG(MREADER*);
extern ULONG _mm_read_I_ULONG(MREADER*); extern ULONG _mm_read_I_ULONG(MREADER*);
extern int _mm_read_M_SWORDS(SWORD*,int,MREADER*); extern BOOL _mm_read_M_SWORDS(SWORD*,int,MREADER*);
extern int _mm_read_I_SWORDS(SWORD*,int,MREADER*); extern BOOL _mm_read_I_SWORDS(SWORD*,int,MREADER*);
extern int _mm_read_M_UWORDS(UWORD*,int,MREADER*); extern BOOL _mm_read_M_UWORDS(UWORD*,int,MREADER*);
extern int _mm_read_I_UWORDS(UWORD*,int,MREADER*); extern BOOL _mm_read_I_UWORDS(UWORD*,int,MREADER*);
extern int _mm_read_M_SLONGS(SLONG*,int,MREADER*); extern BOOL _mm_read_M_SLONGS(SLONG*,int,MREADER*);
extern int _mm_read_I_SLONGS(SLONG*,int,MREADER*); extern BOOL _mm_read_I_SLONGS(SLONG*,int,MREADER*);
extern int _mm_read_M_ULONGS(ULONG*,int,MREADER*); extern BOOL _mm_read_M_ULONGS(ULONG*,int,MREADER*);
extern int _mm_read_I_ULONGS(ULONG*,int,MREADER*); extern BOOL _mm_read_I_ULONGS(ULONG*,int,MREADER*);
extern void _mm_write_M_SWORD(SWORD,MWRITER*); extern void _mm_write_M_SWORD(SWORD,MWRITER*);
extern void _mm_write_I_SWORD(SWORD,MWRITER*); extern void _mm_write_I_SWORD(SWORD,MWRITER*);
@@ -186,6 +211,8 @@ extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
/*========== Samples */ /*========== 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 /* This is a handle of sorts attached to any sample registered with
SL_RegisterSample. Generally, this only need be used or changed by the SL_RegisterSample. Generally, this only need be used or changed by the
loaders and drivers of mikmod. */ loaders and drivers of mikmod. */
@@ -208,9 +235,9 @@ extern void SL_Sample8to16(SAMPLOAD*);
extern void SL_Sample16to8(SAMPLOAD*); extern void SL_Sample16to8(SAMPLOAD*);
extern void SL_SampleSigned(SAMPLOAD*); extern void SL_SampleSigned(SAMPLOAD*);
extern void SL_SampleUnsigned(SAMPLOAD*); extern void SL_SampleUnsigned(SAMPLOAD*);
extern BOOL SL_LoadSamples(void); extern int SL_LoadSamples(void);
extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
extern BOOL SL_Load(void*,SAMPLOAD*,ULONG); extern int SL_Load(void*,SAMPLOAD*,ULONG);
extern BOOL SL_Init(SAMPLOAD*); extern BOOL SL_Init(SAMPLOAD*);
extern void SL_Exit(SAMPLOAD*); extern void SL_Exit(SAMPLOAD*);
@@ -305,16 +332,16 @@ enum {
UNI_ULTEFFECT9, /* Sample fine offset */ UNI_ULTEFFECT9, /* Sample fine offset */
/* OctaMED effects */ /* OctaMED effects */
UNI_MEDSPEED, UNI_MEDSPEED,
UNI_MEDEFFECTF1, /* play note twice */ UNI_MEDEFFECTF1,/* play note twice */
UNI_MEDEFFECTF2, /* delay note */ UNI_MEDEFFECTF2,/* delay note */
UNI_MEDEFFECTF3, /* play note three times */ UNI_MEDEFFECTF3,/* play note three times */
/* Oktalyzer effects */ /* Oktalyzer effects */
UNI_OKTARP, /* arpeggio */ UNI_OKTARP, /* arpeggio */
UNI_LAST UNI_LAST
}; };
extern UWORD unioperands[UNI_LAST]; extern const UWORD unioperands[UNI_LAST];
/* IT / S3M Extended SS effects: */ /* IT / S3M Extended SS effects: */
enum { enum {
@@ -419,7 +446,7 @@ typedef struct ENVPR {
typedef struct MP_CHANNEL { typedef struct MP_CHANNEL {
INSTRUMENT* i; INSTRUMENT* i;
SAMPLE* s; SAMPLE *s;
UBYTE sample; /* which sample number */ UBYTE sample; /* which sample number */
UBYTE note; /* the audible note as heard, direct rep of period */ UBYTE note; /* the audible note as heard, direct rep of period */
SWORD outvolume; /* output volume (vol + sampcol + instvol) */ SWORD outvolume; /* output volume (vol + sampcol + instvol) */
@@ -427,6 +454,7 @@ typedef struct MP_CHANNEL {
UWORD fadevol; /* fading volume rate */ UWORD fadevol; /* fading volume rate */
SWORD panning; /* panning position */ SWORD panning; /* panning position */
UBYTE kick; /* if true = sample has to be restarted */ UBYTE kick; /* if true = sample has to be restarted */
UBYTE kick_flag; /* kick has been true */
UWORD period; /* period to play the sample at */ UWORD period; /* period to play the sample at */
UBYTE nna; /* New note action type + master/slave flags */ UBYTE nna; /* New note action type + master/slave flags */
@@ -443,7 +471,7 @@ typedef struct MP_CHANNEL {
typedef struct MP_CONTROL { typedef struct MP_CONTROL {
struct MP_CHANNEL main; struct MP_CHANNEL main;
struct MP_VOICE *slave; /* Audio Slave of current effects control channel */ struct MP_VOICE* slave; /* Audio Slave of current effects control channel */
UBYTE slavechn; /* Audio Slave of current effects control channel */ UBYTE slavechn; /* Audio Slave of current effects control channel */
UBYTE muted; /* if set, channel not played */ UBYTE muted; /* if set, channel not played */
@@ -461,7 +489,7 @@ typedef struct MP_CONTROL {
SWORD tmpvolume; /* tmp volume */ SWORD tmpvolume; /* tmp volume */
UWORD tmpperiod; /* tmp period */ UWORD tmpperiod; /* tmp period */
UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */ UWORD wantedperiod;/* period to slide to (with effect 3 or 5) */
UBYTE arpmem; /* arpeggio command memory */ UBYTE arpmem; /* arpeggio command memory */
UBYTE pansspd; /* panslide speed */ UBYTE pansspd; /* panslide speed */
@@ -470,10 +498,10 @@ typedef struct MP_CONTROL {
UBYTE s3mtremor; /* s3m tremor (effect I) counter */ UBYTE s3mtremor; /* s3m tremor (effect I) counter */
UBYTE s3mtronof; /* s3m tremor ontime/offtime */ UBYTE s3mtronof; /* s3m tremor ontime/offtime */
UBYTE s3mvolslide; /* last used volslide */ UBYTE s3mvolslide;/* last used volslide */
SBYTE sliding; SBYTE sliding;
UBYTE s3mrtgspeed; /* last used retrig speed */ UBYTE s3mrtgspeed;/* last used retrig speed */
UBYTE s3mrtgslide; /* last used retrig slide */ UBYTE s3mrtgslide;/* last used retrig slide */
UBYTE glissando; /* glissando (0 means off) */ UBYTE glissando; /* glissando (0 means off) */
UBYTE wavecontrol; UBYTE wavecontrol;
@@ -490,15 +518,15 @@ typedef struct MP_CONTROL {
UBYTE fslidednspd; UBYTE fslidednspd;
UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */
UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */
UBYTE ffportupspd; /* fx X1 (extra fine portamento up) data */ UBYTE ffportupspd;/* fx X1 (extra fine portamento up) data */
UBYTE ffportdnspd; /* fx X2 (extra fine portamento dn) data */ UBYTE ffportdnspd;/* fx X2 (extra fine portamento dn) data */
ULONG hioffset; /* last used high order of sample offset */ ULONG hioffset; /* last used high order of sample offset */
UWORD soffset; /* last used low order of sample-offset (effect 9) */ UWORD soffset; /* last used low order of sample-offset (effect 9) */
UBYTE sseffect; /* last used Sxx effect */ UBYTE sseffect; /* last used Sxx effect */
UBYTE ssdata; /* last used Sxx data info */ UBYTE ssdata; /* last used Sxx data info */
UBYTE chanvolslide; /* last used channel volume slide */ UBYTE chanvolslide;/* last used channel volume slide */
UBYTE panbwave; /* current panbrello waveform */ UBYTE panbwave; /* current panbrello waveform */
UBYTE panbpos; /* current panbrello position */ UBYTE panbpos; /* current panbrello position */
@@ -537,9 +565,9 @@ typedef struct MP_VOICE {
/*========== Loaders */ /*========== Loaders */
typedef struct MLOADER { typedef struct MLOADER {
struct MLOADER* next; struct MLOADER* next;
CHAR* type; const CHAR* type;
CHAR* version; const CHAR* version;
BOOL (*Init)(void); BOOL (*Init)(void);
BOOL (*Test)(void); BOOL (*Test)(void);
BOOL (*Load)(BOOL); BOOL (*Load)(BOOL);
@@ -549,14 +577,14 @@ struct MLOADER* next;
/* internal loader variables */ /* internal loader variables */
extern MREADER* modreader; extern MREADER* modreader;
extern UWORD finetune[16];
extern MODULE of; /* static unimod loading space */ 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 SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
extern UBYTE* poslookup; /* lookup table for pattern jumps after extern UBYTE* poslookup; /* lookup table for pattern jumps after
blank pattern removal */ blank pattern removal */
extern UBYTE poslookupcnt; extern UWORD poslookupcnt;
extern UWORD* origpositions; extern UWORD* origpositions;
extern BOOL filters; /* resonant filters in use */ extern BOOL filters; /* resonant filters in use */
@@ -575,7 +603,7 @@ extern BOOL AllocPatterns(void);
extern BOOL AllocTracks(void); extern BOOL AllocTracks(void);
extern BOOL AllocInstruments(void); extern BOOL AllocInstruments(void);
extern BOOL AllocSamples(void); extern BOOL AllocSamples(void);
extern CHAR* DupStr(CHAR*,UWORD,BOOL); extern CHAR* DupStr(const CHAR*, UWORD, BOOL);
/* loader utility functions */ /* loader utility functions */
extern int* AllocLinear(void); extern int* AllocLinear(void);
@@ -595,14 +623,24 @@ extern ULONG getfrequency(UWORD,ULONG);
/* loader shared data */ /* loader shared data */
#define STM_NTRACKERS 3 #define STM_NTRACKERS 3
extern CHAR *STM_Signatures[STM_NTRACKERS]; extern const CHAR *STM_Signatures[STM_NTRACKERS];
/*========== Player interface */ /*========== Player interface */
extern BOOL Player_Init(MODULE*); extern int Player_Init(MODULE*);
extern void Player_Exit(MODULE*); extern void Player_Exit(MODULE*);
extern void Player_HandleTick(void); extern void Player_HandleTick(void);
/*========== UnPackers */
typedef BOOL (*MUNPACKER) (struct MREADER*,
void** /* unpacked data out */ ,
long* /* unpacked data size */ );
extern BOOL PP20_Unpack(MREADER*, void**, long*);
extern BOOL MMCMP_Unpack(MREADER*, void**, long*);
extern BOOL XPK_Unpack(MREADER*, void**, long*);
extern BOOL S404_Unpack(MREADER*, void**, long*);
/*========== Drivers */ /*========== Drivers */
/* max. number of handles a driver has to provide. (not strict) */ /* max. number of handles a driver has to provide. (not strict) */
@@ -633,17 +671,17 @@ extern ULONG MD_SampleLength(int,SAMPLE*);
extern void unsignedtoulaw(char *,int); extern void unsignedtoulaw(char *,int);
/* Parameter extraction helper */ /* Parameter extraction helper */
extern CHAR *MD_GetAtom(CHAR*,CHAR*,BOOL); extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, BOOL);
/* Internal software mixer stuff */ /* Internal software mixer stuff */
extern void VC_SetupPointers(void); extern void VC_SetupPointers(void);
extern BOOL VC1_Init(void); extern int VC1_Init(void);
extern BOOL VC2_Init(void); extern int VC2_Init(void);
#if defined(unix) || defined(__APPLE__) && defined(__MACH__) #if (MIKMOD_UNIX)
/* POSIX helper functions */ /* POSIX helper functions */
extern BOOL MD_Access(CHAR *); extern BOOL MD_Access(const CHAR *);
extern BOOL MD_DropPrivileges(void); extern int MD_DropPrivileges(void);
#endif #endif
/* Macro to define a missing driver, yet allowing binaries to dynamically link /* Macro to define a missing driver, yet allowing binaries to dynamically link
@@ -656,9 +694,9 @@ extern void _mm_registerdriver(struct MDRIVER*);
extern void _mm_registerloader(struct MLOADER*); extern void _mm_registerloader(struct MLOADER*);
extern BOOL MikMod_Active_internal(void); extern BOOL MikMod_Active_internal(void);
extern void MikMod_DisableOutput_internal(void); extern void MikMod_DisableOutput_internal(void);
extern BOOL MikMod_EnableOutput_internal(void); extern int MikMod_EnableOutput_internal(void);
extern void MikMod_Exit_internal(void); extern void MikMod_Exit_internal(void);
extern BOOL MikMod_SetNumVoices_internal(int,int); extern int MikMod_SetNumVoices_internal(int,int);
extern void Player_Exit_internal(MODULE*); extern void Player_Exit_internal(MODULE*);
extern void Player_Stop_internal(void); extern void Player_Stop_internal(void);
extern BOOL Player_Paused_internal(void); extern BOOL Player_Paused_internal(void);
@@ -670,10 +708,162 @@ extern void Voice_SetVolume_internal(SBYTE,UWORD);
extern void Voice_Stop_internal(SBYTE); extern void Voice_Stop_internal(SBYTE);
extern BOOL Voice_Stopped_internal(SBYTE); extern BOOL 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 #ifdef __cplusplus
} }
#endif #endif
/*========== SIMD mixing routines */
#undef HAVE_ALTIVEC
#undef HAVE_SSE2
#if defined(MIKMOD_SIMD)
#if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3))
#define HAVE_ALTIVEC
#elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */
#define HAVE_SSE2
#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 /* AltiVec/SSE2 */
#endif /* MIKMOD_SIMD */
/*========== SIMD mixing helper functions =============*/
#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 #endif
/* Altivec helper function */
#if defined HAVE_ALTIVEC
#define simd_m128i vector signed int
#define simd_m128 vector float
#ifdef __GNUC__
#include <ppc_intrinsics.h>
#endif
/* Helper functions */
/* 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) {
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 vector float vec_setzero() {
return (vector float) (0.);
}
static inline vector signed char vec_set1_8(unsigned char splatchar) {
vector unsigned char splatmap = vec_lvsl(0, &splatchar);
vector unsigned char result = vec_lde(0, &splatchar);
splatmap = vec_splat(splatmap, 0);
return (vector signed char)vec_perm(result, result, splatmap);
}
#define PERM_A0 0x00,0x01,0x02,0x03
#define PERM_A1 0x04,0x05,0x06,0x07
#define PERM_A2 0x08,0x09,0x0A,0x0B
#define PERM_A3 0x0C,0x0D,0x0E,0x0F
#define PERM_B0 0x10,0x11,0x12,0x13
#define PERM_B1 0x14,0x15,0x16,0x17
#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) {
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) {
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 const *)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul);
#define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0));
#define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8));
#define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16));
#define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste);
#define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) vec_st(vec_add(vec_packs((vector signed short)vec_packs(v1, v2), (vector signed short)vec_packs(v3, v4)), vec_set1_8(128)), 0, dste);
#define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste);
#define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
#elif defined HAVE_SSE2
#include <emmintrin.h>
/* 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 const *)(srce)), BITSHIFT+16-size);
#define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT-size)), mul);
#define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
#define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
#define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
#define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
#define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) _mm_store_si128((__m128i*)(dste), _mm_add_epi8(_mm_packs_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)), _mm_set1_epi8(128)));
#define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1);
#define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
#define simd_m128i __m128i
#define simd_m128 __m128
#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: */ /* ex:set ts=4: */
+157 -98
View File
@@ -45,12 +45,16 @@
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
#endif #endif
MREADER *modreader; MREADER *modreader;
MODULE of; MODULE of;
static MLOADER *firstloader=NULL; static MLOADER *firstloader=NULL;
UWORD finetune[16]={ static MUNPACKER unpackers[] = {
NULL
};
const UWORD finetune[16] = {
8363,8413,8463,8529,8581,8651,8723,8757, 8363,8413,8463,8529,8581,8651,8723,8757,
7895,7941,7985,8046,8107,8169,8232,8280 7895,7941,7985,8046,8107,8169,8232,8280
}; };
@@ -63,14 +67,17 @@ MIKMODAPI CHAR* MikMod_InfoLoader(void)
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
/* compute size of buffer */ /* 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(len)
if((list=MikMod_malloc(len*sizeof(CHAR)))) { if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
list[0]=0; CHAR *list_end = list;
list[0] = 0;
/* list all registered module loders */ /* list all registered module loders */
for(l=firstloader;l;l=l->next) for(l = firstloader; l; l = l->next) {
sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version); list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
}
} }
MUTEX_UNLOCK(lists); MUTEX_UNLOCK(lists);
return list; return list;
@@ -122,44 +129,44 @@ BOOL ReadComment(UWORD len)
BOOL ReadLinedComment(UWORD len,UWORD linelen) BOOL ReadLinedComment(UWORD len,UWORD linelen)
{ {
CHAR *tempcomment,*line,*storage; /* Adapted from the OpenMPT project, C'ified. */
UWORD total=0,t,lines; CHAR *buf, *storage, *p;
int i; size_t numlines, line, fpos, cpos, lpos, cnt;
lines = (len + linelen - 1) / linelen; if (!linelen) return 0;
if (len) { if (!len) return 1;
if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0;
if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) {
MikMod_free(tempcomment);
return 0;
}
memset(tempcomment, ' ', len);
_mm_read_UBYTES(tempcomment,len,modreader);
/* compute message length */ if (!(buf = (CHAR *) MikMod_malloc(len))) return 0;
for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) { numlines = (len + linelen - 1) / linelen;
for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0; cnt = (linelen + 1) * numlines;
for(i=0;i<linelen;i++) if (!line[i]) break; if (!(storage = (CHAR *) MikMod_malloc(cnt + 1))) {
total+=1+i; MikMod_free(buf);
}
if(total>lines) {
if(!(of.comment=(CHAR*)MikMod_malloc(total+1))) {
MikMod_free(storage);
MikMod_free(tempcomment);
return 0; return 0;
} }
/* convert message */ _mm_read_UBYTES(buf,len,modreader);
for(line=tempcomment,t=0;t<lines;t++,line+=linelen) { storage[cnt] = 0;
for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break; for (line = 0, fpos = 0, cpos = 0; line < numlines; line++, fpos += linelen, cpos += (linelen + 1))
storage[i]=0; /* if (i==linelen) */ {
strcat(of.comment,storage);strcat(of.comment,"\r"); cnt = len - fpos;
} if (cnt > linelen) cnt = linelen;
MikMod_free(storage); p = storage + cpos;
MikMod_free(tempcomment); 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; return 1;
} }
@@ -169,7 +176,7 @@ BOOL AllocPositions(int total)
_mm_errno=MMERR_NOT_A_MODULE; _mm_errno=MMERR_NOT_A_MODULE;
return 0; 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; return 1;
} }
@@ -258,7 +265,7 @@ static BOOL ML_LoadSamples(void)
/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any /* Creates a CSTR out of a character buffer of 'len' bytes, but strips any
terminating non-printing characters like 0, spaces etc. */ terminating non-printing characters like 0, spaces etc. */
CHAR *DupStr(CHAR* s,UWORD len,BOOL strict) CHAR *DupStr(const CHAR* s, UWORD len, BOOL strict)
{ {
UWORD t; UWORD t;
CHAR *d=NULL; CHAR *d=NULL;
@@ -277,7 +284,7 @@ CHAR *DupStr(CHAR* s,UWORD len,BOOL strict)
/* When the buffer wasn't completely empty, allocate a cstring and copy the /* When the buffer wasn't completely empty, allocate a cstring and copy the
buffer into that string, except for any control-chars */ 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]; for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t];
d[len]=0; d[len]=0;
} }
@@ -288,29 +295,31 @@ static void ML_XFreeSample(SAMPLE *s)
{ {
if(s->handle>=0) if(s->handle>=0)
MD_SampleUnload(s->handle); 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) static void ML_XFreeInstrument(INSTRUMENT *i)
{ {
if(i->insname) MikMod_free(i->insname); MikMod_free(i->insname);
} }
static void ML_FreeEx(MODULE *mf) static void ML_FreeEx(MODULE *mf)
{ {
UWORD t; UWORD t;
if(mf->songname) MikMod_free(mf->songname); MikMod_free(mf->songname);
if(mf->comment) MikMod_free(mf->comment); MikMod_free(mf->comment);
if(mf->modtype) MikMod_free(mf->modtype); MikMod_free(mf->modtype);
if(mf->positions) MikMod_free(mf->positions); MikMod_free(mf->positions);
if(mf->patterns) MikMod_free(mf->patterns); MikMod_free(mf->patterns);
if(mf->pattrows) MikMod_free(mf->pattrows); MikMod_free(mf->pattrows);
if(mf->tracks) { if(mf->tracks) {
for(t=0;t<mf->numtrk;t++) 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); MikMod_free(mf->tracks);
} }
if(mf->instruments) { if(mf->instruments) {
@@ -319,8 +328,10 @@ static void ML_FreeEx(MODULE *mf)
MikMod_free(mf->instruments); MikMod_free(mf->instruments);
} }
if(mf->samples) { 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]); if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]);
}
MikMod_free(mf->samples); MikMod_free(mf->samples);
} }
memset(mf,0,sizeof(MODULE)); memset(mf,0,sizeof(MODULE));
@@ -329,12 +340,24 @@ static void ML_FreeEx(MODULE *mf)
static MODULE *ML_AllocUniMod(void) static MODULE *ML_AllocUniMod(void)
{ {
MODULE *mf; return (MODULE *) MikMod_malloc(sizeof(MODULE));
return (mf=MikMod_malloc(sizeof(MODULE)));
} }
void Player_Free_internal(MODULE *mf) static BOOL 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;
}
static void Player_Free_internal(MODULE *mf)
{ {
if(mf) { if(mf) {
Player_Exit_internal(mf); Player_Exit_internal(mf);
@@ -352,25 +375,44 @@ MIKMODAPI void Player_Free(MODULE *mf)
static CHAR* Player_LoadTitle_internal(MREADER *reader) static CHAR* Player_LoadTitle_internal(MREADER *reader)
{ {
MLOADER *l; MLOADER *l;
CHAR *title;
void *unpk;
long newlen;
modreader=reader; modreader=reader;
_mm_errno = 0; _mm_errno = 0;
_mm_critical = 0; _mm_critical = 0;
_mm_iobase_setcur(modreader); _mm_iobase_setcur(modreader);
if(ML_TryUnpack(modreader,&unpk,&newlen)) {
if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
modreader=reader;
MikMod_free(unpk);
return NULL;
}
}
/* Try to find a loader that recognizes the module */ /* Try to find a loader that recognizes the module */
for(l=firstloader;l;l=l->next) { for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader); _mm_rewind(modreader);
if(l->Test()) break; if(l->Test()) break;
} }
if(!l) { if(l) {
title = l->LoadTitle();
}
else {
_mm_errno = MMERR_NOT_A_MODULE; _mm_errno = MMERR_NOT_A_MODULE;
if(_mm_errorhandler) _mm_errorhandler(); if(_mm_errorhandler) _mm_errorhandler();
return NULL; title = NULL;
} }
return l->LoadTitle(); if (modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
return title;
} }
MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp) MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp)
@@ -378,7 +420,7 @@ MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp)
CHAR* result=NULL; CHAR* result=NULL;
MREADER* reader; MREADER* reader;
if(fp && (reader=_mm_new_file_reader(fp))) { if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader); result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists); MUTEX_UNLOCK(lists);
@@ -392,7 +434,8 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
CHAR *result=NULL; CHAR *result=NULL;
MREADER* reader; 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); MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader); result=Player_LoadTitle_internal(reader);
@@ -400,7 +443,6 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
_mm_delete_mem_reader(reader); _mm_delete_mem_reader(reader);
} }
return result; return result;
} }
@@ -416,14 +458,14 @@ MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
return result; return result;
} }
MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) MIKMODAPI CHAR* Player_LoadTitle(const CHAR* filename)
{ {
CHAR* result=NULL; CHAR* result=NULL;
FILE* fp; FILE* fp;
MREADER* reader; MREADER* reader;
if((fp=_mm_fopen(filename,"rb"))) { if((fp=_mm_fopen(filename,"rb")) != NULL) {
if((reader=_mm_new_file_reader(fp))) { if((reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader); result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists); MUTEX_UNLOCK(lists);
@@ -435,18 +477,28 @@ MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename)
} }
/* Loads a module given an reader */ /* Loads a module given an reader */
MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious) static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
{ {
int t; int t;
MLOADER *l; MLOADER *l;
BOOL ok; BOOL ok;
MODULE *mf; MODULE *mf;
void *unpk;
long newlen;
modreader = reader; modreader = reader;
_mm_errno = 0; _mm_errno = 0;
_mm_critical = 0; _mm_critical = 0;
_mm_iobase_setcur(modreader); _mm_iobase_setcur(modreader);
if(ML_TryUnpack(modreader,&unpk,&newlen)) {
if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
modreader=reader;
MikMod_free(unpk);
return NULL;
}
}
/* Try to find a loader that recognizes the module */ /* Try to find a loader that recognizes the module */
for(l=firstloader;l;l=l->next) { for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader); _mm_rewind(modreader);
@@ -455,15 +507,27 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if(!l) { if(!l) {
_mm_errno = MMERR_NOT_A_MODULE; _mm_errno = MMERR_NOT_A_MODULE;
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(_mm_errorhandler) _mm_errorhandler(); if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader); _mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL; return NULL;
} }
/* init unitrk routines */ /* init unitrk routines */
if(!UniInit()) { if(!UniInit()) {
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(_mm_errorhandler) _mm_errorhandler(); if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader); _mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL; return NULL;
} }
@@ -492,24 +556,18 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if (l->Cleanup) l->Cleanup(); if (l->Cleanup) l->Cleanup();
UniCleanup(); UniCleanup();
if(ok) ok = ML_LoadSamples();
if(ok) ok = ((mf=ML_AllocUniMod()) != NULL);
if(!ok) { if(!ok) {
ML_FreeEx(&of); ML_FreeEx(&of);
if(_mm_errorhandler) _mm_errorhandler(); if(modreader!=reader) {
_mm_rewind(modreader);_mm_iobase_revert(modreader); _mm_delete_mem_reader(modreader);
return NULL; 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);
if(_mm_errorhandler) _mm_errorhandler(); if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL; return NULL;
} }
@@ -531,23 +589,23 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if(maxchan<mf->numchn) mf->flags |= UF_NNA; if(maxchan<mf->numchn) mf->flags |= UF_NNA;
if(MikMod_SetNumVoices_internal(maxchan,-1)) { ok = !MikMod_SetNumVoices_internal(maxchan,-1);
_mm_iobase_revert(modreader);
Player_Free(mf);
return NULL;
} }
if(ok) ok = !SL_LoadSamples();
if(ok) ok = !Player_Init(mf);
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
} }
if(SL_LoadSamples()) {
_mm_iobase_revert(modreader); _mm_iobase_revert(modreader);
if(!ok) {
Player_Free_internal(mf); Player_Free_internal(mf);
return NULL; return NULL;
} }
if(Player_Init(mf)) {
_mm_iobase_revert(modreader);
Player_Free_internal(mf);
mf=NULL;
}
_mm_iobase_revert(modreader);
return mf; return mf;
} }
@@ -569,7 +627,8 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,BOOL cur
MODULE* result=NULL; MODULE* result=NULL;
MREADER* reader; 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); result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_mem_reader(reader); _mm_delete_mem_reader(reader);
} }
@@ -581,9 +640,9 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,BOOL cur
MIKMODAPI MODULE* Player_LoadFP(FILE* fp,int maxchan,BOOL curious) MIKMODAPI MODULE* Player_LoadFP(FILE* fp,int maxchan,BOOL curious)
{ {
MODULE* result=NULL; 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); result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_file_reader(reader); _mm_delete_file_reader(reader);
} }
@@ -592,12 +651,12 @@ MIKMODAPI MODULE* Player_LoadFP(FILE* fp,int maxchan,BOOL curious)
/* Open a module via its filename. The loader will initialize the specified /* Open a module via its filename. The loader will initialize the specified
song-player 'player'. */ song-player 'player'. */
MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,BOOL curious) MIKMODAPI MODULE* Player_Load(const CHAR* filename,int maxchan,BOOL curious)
{ {
FILE *fp; FILE *fp;
MODULE *mf=NULL; MODULE *mf=NULL;
if((fp=_mm_fopen(filename,"rb"))) { if((fp=_mm_fopen(filename,"rb")) != NULL) {
mf=Player_LoadFP(fp,maxchan,curious); mf=Player_LoadFP(fp,maxchan,curious);
_mm_fclose(fp); _mm_fclose(fp);
} }
+3 -2
View File
@@ -32,8 +32,9 @@
#include "mikmod_internals.h" #include "mikmod_internals.h"
void MikMod_RegisterAllLoaders_internal(void) static void MikMod_RegisterAllLoaders_internal(void)
{ {
/* UQM edit: Cut down the loader list to those we support */
_mm_registerloader(&load_it); _mm_registerloader(&load_it);
_mm_registerloader(&load_mod); _mm_registerloader(&load_mod);
_mm_registerloader(&load_s3m); _mm_registerloader(&load_s3m);
@@ -41,7 +42,7 @@ void MikMod_RegisterAllLoaders_internal(void)
_mm_registerloader(&load_xm); _mm_registerloader(&load_xm);
} }
void MikMod_RegisterAllLoaders(void) MIKMODAPI void MikMod_RegisterAllLoaders(void)
{ {
MUTEX_LOCK(lists); MUTEX_LOCK(lists);
MikMod_RegisterAllLoaders_internal(); MikMod_RegisterAllLoaders_internal();
+11 -18
View File
@@ -43,13 +43,13 @@ extern int fprintf(FILE *, const char *, ...);
/*========== Shared tracker identifiers */ /*========== Shared tracker identifiers */
CHAR *STM_Signatures[STM_NTRACKERS] = { const CHAR *STM_Signatures[STM_NTRACKERS] = {
"!Scream!", "!Scream!",
"BMOD2STM", "BMOD2STM",
"WUZAMOD!" "WUZAMOD!"
}; };
CHAR *STM_Version[STM_NTRACKERS] = { const CHAR *STM_Version[STM_NTRACKERS] = {
"Screamtracker 2", "Screamtracker 2",
"Converted by MOD2STM (STM format)", "Converted by MOD2STM (STM format)",
"Wuzamod (STM format)" "Wuzamod (STM format)"
@@ -60,7 +60,7 @@ CHAR *STM_Version[STM_NTRACKERS] = {
SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
UBYTE* poslookup=NULL; /* lookup table for pattern jumps after blank UBYTE* poslookup=NULL; /* lookup table for pattern jumps after blank
pattern removal */ pattern removal */
UBYTE poslookupcnt; UWORD poslookupcnt;
UWORD* origpositions=NULL; UWORD* origpositions=NULL;
BOOL filters; /* resonant filters in use */ BOOL filters; /* resonant filters in use */
@@ -71,30 +71,27 @@ FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
/*========== Linear periods stuff */ /*========== Linear periods stuff */
int* noteindex=NULL; /* remap value for linear period modules */ int* noteindex=NULL; /* remap value for linear period modules */
static int noteindexcount=0; static unsigned noteindexcount=0;
int *AllocLinear(void) int *AllocLinear(void)
{ {
if(of.numsmp>noteindexcount) { if(of.numsmp>noteindexcount) {
noteindexcount=of.numsmp; noteindexcount=of.numsmp;
noteindex=realloc(noteindex,noteindexcount*sizeof(int)); noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int));
} }
return noteindex; return noteindex;
} }
void FreeLinear(void) void FreeLinear(void)
{ {
if(noteindex) {
MikMod_free(noteindex); MikMod_free(noteindex);
noteindex=NULL; noteindex=NULL;
}
noteindexcount=0; noteindexcount=0;
} }
int speed_to_finetune(ULONG speed,int sample) int speed_to_finetune(ULONG speed,int sample)
{ {
int note=1,finetune=0; int ctmp=0,tmp,note=1,ft=0;
ULONG ctmp=0,tmp;
speed>>=1; speed>>=1;
while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) { while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) {
@@ -105,16 +102,16 @@ int speed_to_finetune(ULONG speed,int sample)
if(tmp!=speed) { if(tmp!=speed) {
if((tmp-speed)<(speed-ctmp)) if((tmp-speed)<(speed-ctmp))
while(tmp>speed) while(tmp>speed)
tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune)); tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft));
else { else {
note--; note--;
while(ctmp<speed) while(ctmp<speed)
ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune)); ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft));
} }
} }
noteindex[sample]=note-4*OCTAVE; noteindex[sample]=note-4*OCTAVE;
return finetune; return ft;
} }
/*========== Order stuff */ /*========== Order stuff */
@@ -142,13 +139,9 @@ void S3MIT_CreateOrders(BOOL curious)
/*========== Effect stuff */ /*========== Effect stuff */
/* handles S3M and IT effects */ /* handles S3M and IT effects */
void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags)
{ {
UBYTE hi,lo; UBYTE lo = inf&0xF;
lo=inf&0xf;
hi=inf>>4;
/* process S3M / IT specific command structure */ /* process S3M / IT specific command structure */
if(cmd!=255) { if(cmd!=255) {
+90 -21
View File
@@ -30,44 +30,113 @@
#include "config.h" #include "config.h"
#endif #endif
#ifdef HAVE_POSIX_MEMALIGN
#define _XOPEN_SOURCE 600 /* for posix_memalign */
#endif
#include "string.h"
#include "mikmod_internals.h" #include "mikmod_internals.h"
#if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
#undef WIN32_ALIGNED_MALLOC
#if defined(_WIN32) && !defined(_WIN32_WCE)
# if defined(_WIN64) /* OK with MSVC and MinGW */
# define WIN32_ALIGNED_MALLOC
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
# define WIN32_ALIGNED_MALLOC
# elif defined(__MINGW32__)
/* no guarantees that msvcrt.dll will have it */
# endif
#endif
#define PTRSIZE (sizeof(void*))
/* return a 16 byte aligned address */
void* MikMod_amalloc(size_t size)
{
void *d;
#if defined(HAVE_POSIX_MEMALIGN)
if (!posix_memalign(&d, 16, size)) {
memset(d, 0, size);
return d;
}
#elif defined(WIN32_ALIGNED_MALLOC)
d = _aligned_malloc(size, 16);
if (d) {
ZeroMemory(d, size);
return d;
}
#else
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
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
return NULL;
}
void MikMod_afree(void *data)
{
if (!data) return;
#if defined(HAVE_POSIX_MEMALIGN)
free(data);
#elif defined(WIN32_ALIGNED_MALLOC)
_aligned_free(data);
#else
free((void *) *(size_t*)((unsigned char *)data - PTRSIZE));
#endif
}
#endif /* (HAVE_SSE2) || (HAVE_ALTIVEC) */
void* MikMod_realloc(void *data, size_t size) void* MikMod_realloc(void *data, size_t size)
{ {
if (data) if (data) return realloc(data, size);
return realloc(data, size); return calloc(1, size);
else
return MikMod_malloc(size);
} }
/* Same as malloc, but sets error variable _mm_error when fails */ /* Same as malloc, but sets error variable _mm_error when fails */
void* MikMod_malloc(size_t size) void* MikMod_malloc(size_t size)
{ {
void *d; return MikMod_calloc(1, size);
if(!(d=calloc(1,size))) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
}
return d;
} }
/* Same as calloc, but sets error variable _mm_error when fails */ /* Same as calloc, but sets error variable _mm_error when fails */
void* MikMod_calloc(size_t nitems,size_t size) void* MikMod_calloc(size_t nitems, size_t size)
{ {
void *d; void *d = calloc(nitems, size);
if (d) return d;
if(!(d=calloc(nitems,size))) {
_mm_errno = MMERR_OUT_OF_MEMORY; _mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler(); if(_mm_errorhandler) _mm_errorhandler();
} return NULL;
}
void MikMod_free(void *data)
{
if (data) free(data);
}
/* like strdup(), but the result must be freed using MikMod_free() */
CHAR *MikMod_strdup(const CHAR *s)
{
size_t l;
CHAR *d;
if (!s) return NULL;
l = strlen(s) + 1;
d = (CHAR *) MikMod_calloc(1, l * sizeof(CHAR));
if (d) strcpy(d, s);
return d; return d;
} }
void MikMod_free(void *p)
{
if (p)
free(p);
}
/* ex:set ts=4: */ /* ex:set ts=4: */
+138 -20
View File
@@ -40,7 +40,9 @@
#include "mikmod_internals.h" #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 */ /* No error */
@@ -82,62 +84,89 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Unable to set non-blocking mode for audio device", "Unable to set non-blocking mode for audio device",
/* AudioFile driver errors */ /* AudioFile driver errors */
#ifdef DRV_AF
"Cannot find suitable AudioFile audio port", "Cannot find suitable AudioFile audio port",
#else
_mmerr_invalid,
#endif
/* AIX driver errors */ /* AIX driver errors */
#ifdef DRV_AIX
"Configuration (init step) of audio device failed", "Configuration (init step) of audio device failed",
"Configuration (control step) of audio device failed", "Configuration (control step) of audio device failed",
"Configuration (start step) of audio device failed", "Configuration (start step) of audio device failed",
#else
/* ALSA driver errors */ _mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* EsounD driver errors */
/* Ultrasound driver errors */ /* Ultrasound driver errors */
#ifdef DRV_ULTRA
"Ultrasound driver only works in 16 bit stereo 44 KHz", "Ultrasound driver only works in 16 bit stereo 44 KHz",
"Ultrasound card could not be reset", "Ultrasound card could not be reset",
"Could not start Ultrasound timer", "Could not start Ultrasound timer",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* HP driver errors */ /* HP driver errors */
#ifdef DRV_HP
"Unable to select 16bit-linear sample format", "Unable to select 16bit-linear sample format",
"Could not select requested sample-rate", "Could not select requested sample-rate",
"Could not select requested number of channels", "Could not select requested number of channels",
"Unable to select audio output", "Unable to select audio output",
"Unable to get audio description", "Unable to get audio description",
"Could not set transmission buffer size", "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 */ /* Open Sound System driver errors */
#ifdef DRV_OSS
"Could not set fragment size", "Could not set fragment size",
"Could not set sample size", "Could not set sample size",
"Could not set mono/stereo setting", "Could not set mono/stereo setting",
"Could not set sample rate", "Could not set sample rate",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid,
#endif
/* SGI driver errors */ /* SGI driver errors */
#ifdef DRV_SGI
"Unsupported sample rate", "Unsupported sample rate",
"Hardware does not support 16 bit sound", "Hardware does not support 16 bit sound",
"Hardware does not support 8 bit sound", "Hardware does not support 8 bit sound",
"Hardware does not support stereo sound", "Hardware does not support stereo sound",
"Hardware does not support mono sound", "Hardware does not support mono sound",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid,
#endif
/* Sun driver errors */ /* Sun driver errors */
#ifdef DRV_SUN
"Sound device initialization failed", "Sound device initialization failed",
#else
_mmerr_invalid,
#endif
/* OS/2 drivers errors */ /* OS/2 drivers errors */
#if defined(DRV_OS2) || defined(DRV_DART)
"Could not set mixing parameters", "Could not set mixing parameters",
#else
_mmerr_invalid,
#endif
#ifdef DRV_OS2
"Could not create playback semaphores", "Could not create playback semaphores",
"Could not create playback timer", "Could not create playback timer",
"Could not create playback thread", "Could not create playback thread",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* DirectSound driver errors */ /* DirectSound driver errors */
#ifdef DRV_DS
"Could not set playback priority", "Could not set playback priority",
"Could not create playback buffers", "Could not create playback buffers",
"Could not set playback format", "Could not set playback format",
@@ -145,28 +174,117 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Could not register event", "Could not register event",
"Could not create playback thread", "Could not create playback thread",
"Could not initialize 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 */ /* Windows Multimedia API driver errors */
#ifdef DRV_WIN
"Invalid device handle", "Invalid device handle",
"The resource is already allocated", "The resource is already allocated",
"Invalid device identifier", "Invalid device identifier",
"Unsupported output format", "Unsupported output format",
"Unknown error", "Unknown error",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid,
#endif
/* Macintosh driver errors */ /* Macintosh driver errors */
#ifdef DRV_MAC
"Unsupported sample rate", "Unsupported sample rate",
"Could not start playback", "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",
"Could not set mono/stereo setting",
"Could not create playback buffers",
"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 */
"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]; return _mm_errmsg[code];
} }
@@ -175,7 +293,7 @@ MikMod_handler_t _mm_errorhandler = NULL;
MIKMODAPI int _mm_errno = 0; MIKMODAPI int _mm_errno = 0;
MIKMODAPI BOOL _mm_critical = 0; MIKMODAPI BOOL _mm_critical = 0;
MikMod_handler_t _mm_registererrorhandler(MikMod_handler_t proc) static MikMod_handler_t _mm_registererrorhandler(MikMod_handler_t proc)
{ {
MikMod_handler_t oldproc=_mm_errorhandler; MikMod_handler_t oldproc=_mm_errorhandler;
+145 -107
View File
@@ -43,18 +43,14 @@
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
//#include "mikmod.h"
#include "mikmod_internals.h" #include "mikmod_internals.h"
#ifdef SUNOS #ifdef SUNOS
@@ -66,17 +62,14 @@ extern int fseek(FILE *, long, int);
extern size_t fwrite(const void *, size_t, size_t, FILE *); extern size_t fwrite(const void *, size_t, size_t, FILE *);
#endif #endif
#define COPY_BUFSIZE 1024
/* some prototypes */ /* some prototypes */
static BOOL _mm_MemReader_Eof(MREADER* reader); static BOOL _mm_MemReader_Eof(MREADER* reader);
static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size); static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
static int _mm_MemReader_Get(MREADER* reader); static int _mm_MemReader_Get(MREADER* reader);
static BOOL _mm_MemReader_Seek(MREADER* reader,long offset,int whence); static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
static long _mm_MemReader_Tell(MREADER* reader); static long _mm_MemReader_Tell(MREADER* reader);
FILE* _mm_fopen(const CHAR* fname, const CHAR* attrib)
FILE* _mm_fopen(CHAR* fname,CHAR* attrib)
{ {
FILE *fp; FILE *fp;
@@ -87,7 +80,7 @@ FILE* _mm_fopen(CHAR* fname,CHAR* attrib)
return fp; return fp;
} }
BOOL _mm_FileExists(CHAR* fname) BOOL _mm_FileExists(const CHAR* fname)
{ {
FILE *fp; FILE *fp;
@@ -137,7 +130,7 @@ static int _mm_FileReader_Get(MREADER* reader)
return fgetc(((MFILEREADER*)reader)->file); return fgetc(((MFILEREADER*)reader)->file);
} }
static BOOL _mm_FileReader_Seek(MREADER* reader,long offset,int whence) static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence)
{ {
return fseek(((MFILEREADER*)reader)->file, return fseek(((MFILEREADER*)reader)->file,
(whence==SEEK_SET)?offset+reader->iobase:offset,whence); (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
@@ -150,7 +143,7 @@ static long _mm_FileReader_Tell(MREADER* reader)
MREADER *_mm_new_file_reader(FILE* fp) MREADER *_mm_new_file_reader(FILE* fp)
{ {
MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER)); MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER));
if (reader) { if (reader) {
reader->core.Eof =&_mm_FileReader_Eof; reader->core.Eof =&_mm_FileReader_Eof;
reader->core.Read=&_mm_FileReader_Read; reader->core.Read=&_mm_FileReader_Read;
@@ -164,7 +157,7 @@ MREADER *_mm_new_file_reader(FILE* fp)
void _mm_delete_file_reader (MREADER* reader) void _mm_delete_file_reader (MREADER* reader)
{ {
if(reader) MikMod_free(reader); MikMod_free(reader);
} }
/*========== File Writer */ /*========== File Writer */
@@ -174,7 +167,7 @@ typedef struct MFILEWRITER {
FILE* file; FILE* file;
} MFILEWRITER; } MFILEWRITER;
static BOOL _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)
{ {
return fseek(((MFILEWRITER*)writer)->file,offset,whence); return fseek(((MFILEWRITER*)writer)->file,offset,whence);
} }
@@ -184,19 +177,19 @@ static long _mm_FileWriter_Tell(MWRITER* writer)
return ftell(((MFILEWRITER*)writer)->file); return ftell(((MFILEWRITER*)writer)->file);
} }
static BOOL _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size) static BOOL _mm_FileWriter_Write(MWRITER* writer, const void* ptr, size_t size)
{ {
return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size); return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size);
} }
static BOOL _mm_FileWriter_Put(MWRITER* writer,int value) static int _mm_FileWriter_Put(MWRITER* writer,int value)
{ {
return fputc(value,((MFILEWRITER*)writer)->file); return fputc(value,((MFILEWRITER*)writer)->file);
} }
MWRITER *_mm_new_file_writer(FILE* fp) MWRITER *_mm_new_file_writer(FILE* fp)
{ {
MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER)); MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER));
if (writer) { if (writer) {
writer->core.Seek =&_mm_FileWriter_Seek; writer->core.Seek =&_mm_FileWriter_Seek;
writer->core.Tell =&_mm_FileWriter_Tell; writer->core.Tell =&_mm_FileWriter_Tell;
@@ -209,12 +202,11 @@ MWRITER *_mm_new_file_writer(FILE* fp)
void _mm_delete_file_writer (MWRITER* writer) void _mm_delete_file_writer (MWRITER* writer)
{ {
if(writer) MikMod_free (writer); MikMod_free (writer);
} }
/*========== Memory Reader */ /*========== Memory Reader */
typedef struct MMEMREADER { typedef struct MMEMREADER {
MREADER core; MREADER core;
const void *buffer; const void *buffer;
@@ -224,12 +216,12 @@ typedef struct MMEMREADER {
void _mm_delete_mem_reader(MREADER* reader) 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) if (reader)
{ {
reader->core.Eof =&_mm_MemReader_Eof; reader->core.Eof =&_mm_MemReader_Eof;
@@ -246,74 +238,86 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len)
static BOOL _mm_MemReader_Eof(MREADER* reader) static BOOL _mm_MemReader_Eof(MREADER* reader)
{ {
if (!reader) { return 1; } MMEMREADER* mr = (MMEMREADER*) reader;
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { if (!mr) return 1;
return 1; if (mr->pos >= mr->len) return 1;
}
return 0; return 0;
} }
static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
{ {
unsigned char *d=ptr; unsigned char *d;
const unsigned char *s; const unsigned char *s;
MMEMREADER* mr;
long siz;
BOOL ret;
if (!reader) { return 0; } if (!reader || !size || (size > (size_t) LONG_MAX))
return 0;
if (reader->Eof(reader)) { return 0; } mr = (MMEMREADER*) reader;
siz = (long) size;
s = ((MMEMREADER*)reader)->buffer; if (mr->pos >= mr->len) return 0; /* @ eof */
s += ((MMEMREADER*)reader)->pos; if (mr->pos + siz > mr->len) {
siz = mr->len - mr->pos;
if ( ((MMEMREADER*)reader)->pos + (long)size > ((MMEMREADER*)reader)->len) ret = 0; /* not enough remaining bytes */
{ }
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; else {
return 0; /* not enough remaining bytes */ 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--) while (siz) {
{ *d++ = *s++;
*d = *s; siz--;
s++;
d++;
} }
return 1; return ret;
} }
static int _mm_MemReader_Get(MREADER* reader) 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; return c;
((MMEMREADER*)reader)->pos++;
return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos];
} }
static BOOL _mm_MemReader_Seek(MREADER* reader,long offset,int whence) 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) switch(whence)
{ {
case SEEK_CUR: case SEEK_CUR:
((MMEMREADER*)reader)->pos += offset; mr->pos += offset;
break; break;
case SEEK_SET: case SEEK_SET:
((MMEMREADER*)reader)->pos = offset; mr->pos = reader->iobase + offset;
break; break;
case SEEK_END: case SEEK_END:
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1; mr->pos = mr->len + offset;
break; break;
default: /* invalid */
return -1;
} }
if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; } if (mr->pos < reader->iobase) {
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { mr->pos = mr->core.iobase;
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; return -1;
}
if (mr->pos > mr->len) {
mr->pos = mr->len;
} }
return 0; return 0;
} }
@@ -321,14 +325,14 @@ static BOOL _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
static long _mm_MemReader_Tell(MREADER* reader) static long _mm_MemReader_Tell(MREADER* reader)
{ {
if (reader) { if (reader) {
return ((MMEMREADER*)reader)->pos; return ((MMEMREADER*)reader)->pos - reader->iobase;
} }
return 0; return 0;
} }
/*========== Write functions */ /*========== Write functions */
void _mm_write_string(CHAR* data,MWRITER* writer) void _mm_write_string(const CHAR* data,MWRITER* writer)
{ {
if(data) if(data)
_mm_write_UBYTES(data,strlen(data),writer); _mm_write_UBYTES(data,strlen(data),writer);
@@ -378,37 +382,51 @@ void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
_mm_write_I_ULONG((ULONG)data,writer); _mm_write_I_ULONG((ULONG)data,writer);
} }
#if defined __STDC__ || defined _MSC_VER || defined MPW_C void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ {
void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \ while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer);
{ \
while(number-->0) \
_mm_write_##type_name(*(buffer++),writer); \
} }
#else
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \ {
{ \ while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer);
while(number-->0) \
_mm_write_/**/type_name(*(buffer++),writer); \
} }
#endif
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD) void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD) {
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD) while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD) }
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG) void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG) {
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG) while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG) }
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 */ /*========== Read functions */
int _mm_read_string(CHAR* buffer,int number,MREADER* reader) BOOL _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) UWORD _mm_read_M_UWORD(MREADER* reader)
@@ -459,32 +477,52 @@ SLONG _mm_read_I_SLONG(MREADER* reader)
return((SLONG)_mm_read_I_ULONG(reader)); return((SLONG)_mm_read_I_ULONG(reader));
} }
#if defined __STDC__ || defined _MSC_VER || defined MPW_C BOOL _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ {
int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \ while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader);
{ \ return !reader->Eof(reader);
while(number-->0) \
*(buffer++)=_mm_read_##type_name(reader); \
return !reader->Eof(reader); \
} }
#else
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ BOOL _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \ {
{ \ while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader);
while(number-->0) \ return !reader->Eof(reader);
*(buffer++)=_mm_read_/**/type_name(reader); \
return !reader->Eof(reader); \
} }
#endif
DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD) BOOL _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD) {
DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD) while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD) return !reader->Eof(reader);
}
DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG) BOOL _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG) {
DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG) while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader);
DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG) return !reader->Eof(reader);
}
BOOL _mm_read_M_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_M_SLONG(reader);
return !reader->Eof(reader);
}
BOOL _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader);
return !reader->Eof(reader);
}
BOOL _mm_read_I_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_I_SLONG(reader);
return !reader->Eof(reader);
}
BOOL _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: */ /* ex:set ts=4: */
+116 -248
View File
@@ -48,25 +48,25 @@ extern long int random(void);
#endif #endif
/* The currently playing module */ /* The currently playing module */
/* This variable should better be static, but it would break the ABI, so this MODULE *pf = NULL;
will wait */
/*static*/ MODULE *pf = NULL; #define NUMVOICES(mod) (md_sngchn < (mod)->numvoices ? md_sngchn : (mod)->numvoices)
#define HIGH_OCTAVE 2 /* number of above-range octaves */ #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, 0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80,
0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0, 0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0,
0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160, 0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160,
0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700 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, 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 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, 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, 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, 45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58,
@@ -78,7 +78,7 @@ static UBYTE avibtab[128]={
}; };
/* Triton's linear periods to frequency translation table (for XM modules) */ /* 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, 535232,534749,534266,533784,533303,532822,532341,531861,
531381,530902,530423,529944,529466,528988,528511,528034, 531381,530902,530423,529944,529466,528988,528511,528034,
527558,527082,526607,526131,525657,525183,524709,524236, 527558,527082,526607,526131,525657,525183,524709,524236,
@@ -178,7 +178,7 @@ static ULONG lintab[768]={
}; };
#define LOGFAC 2*16 #define LOGFAC 2*16
static UWORD logtab[104]={ static const UWORD logtab[104]={
LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887, LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887,
LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862, LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862,
LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838, LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838,
@@ -207,7 +207,7 @@ static UWORD logtab[104]={
LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431 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, 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, 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, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
@@ -227,12 +227,12 @@ static SBYTE PanbrelloTable[256]={
}; };
/* returns a random value between 0 and ceil-1, ceil must be a power of two */ /* 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 #if defined(HAVE_SRANDOM) && !defined(_MIKMOD_AMIGA)
return random()&(ceil-1); return random()&(ceilval-1);
#else #else
return (rand()*ceil)/(RAND_MAX+1.0); return (rand()*ceilval)/(RAND_MAX+1.0);
#endif #endif
} }
@@ -248,14 +248,14 @@ static int MP_FindEmptyChannel(MODULE *mod)
MP_VOICE *a; MP_VOICE *a;
ULONG t,k,tvol,pp; 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)|| if (((mod->voice[t].main.kick==KICK_ABSENT)||
(mod->voice[t].main.kick==KICK_ENV))&& (mod->voice[t].main.kick==KICK_ENV))&&
Voice_Stopped_internal(t)) Voice_Stopped_internal(t))
return t; return t;
tvol=0xffffffUL;t=-1;a=mod->voice; 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 */ /* allow us to take over a nonexisting sample */
if (!a->main.s) if (!a->main.s)
return k; return k;
@@ -363,7 +363,8 @@ static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susen
/* Imago Orpheus sometimes stores an extra initial point in the envelope */ /* Imago Orpheus sometimes stores an extra initial point in the envelope */
if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) { 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 */ /* Fit in the envelope, still */
@@ -549,9 +550,6 @@ static int DoPTEffect0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick) { if (!tick) {
if (!dat && (flags & UF_ARPMEM)) if (!dat && (flags & UF_ARPMEM))
@@ -569,10 +567,6 @@ static int DoPTEffect1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick && dat) if (!tick && dat)
a->slidespeed = (UWORD)dat << 2; a->slidespeed = (UWORD)dat << 2;
@@ -587,10 +581,6 @@ static int DoPTEffect2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick && dat) if (!tick && dat)
a->slidespeed = (UWORD)dat << 2; a->slidespeed = (UWORD)dat << 2;
@@ -635,10 +625,6 @@ static int DoPTEffect3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if ((!tick)&&(dat)) a->portspeed=(UWORD)dat<<2; if ((!tick)&&(dat)) a->portspeed=(UWORD)dat<<2;
if (a->main.period) if (a->main.period)
@@ -691,10 +677,6 @@ static int DoPTEffect4(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0x0f) a->vibdepth=dat&0xf;
@@ -723,10 +705,6 @@ static int DoPTEffect5(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (a->main.period) if (a->main.period)
DoToneSlide(tick, a); DoToneSlide(tick, a);
@@ -745,10 +723,6 @@ static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE q; UBYTE q;
UWORD temp = 0; /* silence warning */ UWORD temp = 0; /* silence warning */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
if (dat&0x0f) a->trmdepth=dat&0xf; if (dat&0x0f) a->trmdepth=dat&0xf;
@@ -796,9 +770,6 @@ static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)tick; /* unused arg */
(void)flags; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (mod->panflag) if (mod->panflag)
a->main.panning = mod->panning[channel] = dat; a->main.panning = mod->panning[channel] = dat;
@@ -810,10 +781,6 @@ static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
if (dat) a->soffset=(UWORD)dat<<8; if (dat) a->soffset=(UWORD)dat<<8;
@@ -831,10 +798,6 @@ static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (tick) if (tick)
DoVolSlide(a, dat); DoVolSlide(a, dat);
@@ -855,9 +818,6 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)a; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (tick || mod->patdly2) if (tick || mod->patdly2)
@@ -870,8 +830,8 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
if (!mod->loop && !mod->patbrk && if (!mod->loop && !mod->patbrk &&
(dat < mod->sngpos || (dat < mod->sngpos ||
(mod->sngpos == (mod->numpos - 1) && !mod->patbrk) || (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 /* if we don't loop, better not to skip the end of the
pattern, after all... so: pattern, after all... so:
mod->patbrk=0; */ mod->patbrk=0; */
@@ -883,6 +843,9 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
mod->sngpos=dat; mod->sngpos=dat;
mod->posjmp=2; mod->posjmp=2;
mod->patpos=0; 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; return 0;
@@ -892,10 +855,6 @@ static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (tick) return 0; if (tick) return 0;
if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */ if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
@@ -909,14 +868,12 @@ static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)a; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if ((tick)||(mod->patdly2)) return 0; if ((tick)||(mod->patdly2)) return 0;
if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&& 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]]; dat=mod->pattrows[mod->positions[mod->sngpos]];
}
mod->patbrk=dat; mod->patbrk=dat;
if (!mod->posjmp) { if (!mod->posjmp) {
/* don't ask me to explain this code - it makes /* don't ask me to explain this code - it makes
@@ -924,9 +881,8 @@ static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
correctly, among others. Take that for granted, or write correctly, among others. Take that for granted, or write
the page of comments yourself... you might need some the page of comments yourself... you might need some
aspirin - Miod */ aspirin - Miod */
if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)|| if ((mod->sngpos==mod->numpos-1)&&(dat)&&
(mod->positions[mod->sngpos]==(mod->numpat-1) ((mod->loop) || (mod->positions[mod->sngpos]==(mod->numpat-1) && !(flags&UF_NOWRAP)))) {
&& !(flags&UF_NOWRAP)))) {
mod->sngpos=0; mod->sngpos=0;
mod->posjmp=2; mod->posjmp=2;
} else } else
@@ -997,8 +953,13 @@ static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod,
} else } else
mod->patpos=a->pat_reppos; mod->patpos=a->pat_reppos;
} else a->pat_reppos=POS_NONE; } else a->pat_reppos=POS_NONE;
} else } else {
a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */ 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; break;
case 0x7: /* set tremolo waveform */ case 0x7: /* set tremolo waveform */
a->wavecontrol&=0x0f; a->wavecontrol&=0x0f;
@@ -1073,10 +1034,6 @@ static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (tick||mod->patdly2) return 0; if (tick||mod->patdly2) return 0;
if (mod->extspd&&(dat>=mod->bpmlimit)) if (mod->extspd&&(dat>=mod->bpmlimit))
@@ -1096,10 +1053,6 @@ static int DoS3MEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE speed; UBYTE speed;
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
speed = UniGetByte(); speed = UniGetByte();
if (tick || mod->patdly2) if (tick || mod->patdly2)
@@ -1149,9 +1102,6 @@ static void DoS3MVolSlide(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE inf)
static int DoS3MEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoS3MEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)mod; /* unused arg */
(void)channel; /* unused arg */
DoS3MVolSlide(tick, flags, a, UniGetByte()); DoS3MVolSlide(tick, flags, a, UniGetByte());
return 1; return 1;
@@ -1183,10 +1133,6 @@ static int DoS3MEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (a->main.period) if (a->main.period)
DoS3MSlideDn(tick, a,dat); DoS3MSlideDn(tick, a,dat);
@@ -1218,10 +1164,6 @@ static int DoS3MEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (a->main.period) if (a->main.period)
DoS3MSlideUp(tick, a,dat); DoS3MSlideUp(tick, a,dat);
@@ -1233,10 +1175,6 @@ static int DoS3MEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE inf, on, off; UBYTE inf, on, off;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
a->s3mtronof = inf; a->s3mtronof = inf;
@@ -1263,9 +1201,6 @@ static int DoS3MEffectQ(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE inf; UBYTE inf;
(void)mod; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (a->main.period) { if (a->main.period) {
if (inf) { if (inf) {
@@ -1328,10 +1263,6 @@ static int DoS3MEffectR(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
UBYTE dat, q; UBYTE dat, q;
UWORD temp=0; /* silence warning */ UWORD temp=0; /* silence warning */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick) { if (!tick) {
if (dat&0x0f) a->trmdepth=dat&0xf; if (dat&0x0f) a->trmdepth=dat&0xf;
@@ -1379,10 +1310,6 @@ static int DoS3MEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE tempo; UBYTE tempo;
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
tempo = UniGetByte(); tempo = UniGetByte();
if (tick || mod->patdly2) if (tick || mod->patdly2)
@@ -1398,10 +1325,6 @@ static int DoS3MEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
UBYTE dat, q; UBYTE dat, q;
UWORD temp = 0; /* silence warning */ UWORD temp = 0; /* silence warning */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick) { if (!tick) {
if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0x0f) a->vibdepth=dat&0xf;
@@ -1446,11 +1369,6 @@ static int DoS3MEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
static int DoKeyOff(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoKeyOff(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
a->main.keyoff|=KEY_OFF; a->main.keyoff|=KEY_OFF;
if ((!(a->main.volflg&EF_ON))||(a->main.volflg&EF_LOOP)) if ((!(a->main.volflg&EF_ON))||(a->main.volflg&EF_LOOP))
a->main.keyoff=KEY_KILL; a->main.keyoff=KEY_KILL;
@@ -1462,9 +1380,6 @@ static int DoKeyFade(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if ((tick>=dat)||(tick==mod->sngspd-1)) { if ((tick>=dat)||(tick==mod->sngspd-1)) {
a->main.keyoff=KEY_KILL; a->main.keyoff=KEY_KILL;
@@ -1483,10 +1398,6 @@ static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE inf, lo, hi; UBYTE inf, lo, hi;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
a->s3mvolslide = inf; a->s3mvolslide = inf;
@@ -1521,10 +1432,6 @@ static int DoXMEffectE1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
if (dat) a->fportupspd=dat; if (dat) a->fportupspd=dat;
@@ -1539,10 +1446,6 @@ static int DoXMEffectE2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
if (dat) a->fportdnspd=dat; if (dat) a->fportdnspd=dat;
@@ -1557,10 +1460,6 @@ static int DoXMEffectEA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) if (!tick)
if (dat) a->fslideupspd=dat; if (dat) a->fslideupspd=dat;
@@ -1574,10 +1473,6 @@ static int DoXMEffectEB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) if (!tick)
if (dat) a->fslidednspd=dat; if (dat) a->fslidednspd=dat;
@@ -1589,11 +1484,6 @@ static int DoXMEffectEB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
static int DoXMEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoXMEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
mod->volume=UniGetByte()<<1; mod->volume=UniGetByte()<<1;
if (mod->volume>128) mod->volume=128; if (mod->volume>128) mod->volume=128;
@@ -1604,10 +1494,6 @@ static int DoXMEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE inf; UBYTE inf;
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (tick) { if (tick) {
@@ -1629,17 +1515,13 @@ static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if ((!tick)&&(a->main.i)) { if ((!tick)&&(a->main.i)) {
UWORD points; UWORD points;
INSTRUMENT *i=a->main.i; INSTRUMENT *i=a->main.i;
MP_VOICE *aout; MP_VOICE *aout;
if ((aout=a->slave)) { if ((aout=a->slave) != NULL) {
if (aout->venv.env) { if (aout->venv.env) {
points=i->volenv[i->volpts-1].pos; points=i->volenv[i->volpts-1].pos;
aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos; aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos;
@@ -1659,9 +1541,6 @@ static int DoXMEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE inf, lo, hi; UBYTE inf, lo, hi;
SWORD pan; SWORD pan;
(void)flags; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (!mod->panflag) if (!mod->panflag)
return 0; return 0;
@@ -1690,10 +1569,6 @@ static int DoXMEffectX1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (dat) if (dat)
a->ffportupspd = dat; a->ffportupspd = dat;
@@ -1714,10 +1589,6 @@ static int DoXMEffectX2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE dat; UBYTE dat;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (dat) if (dat)
a->ffportdnspd=dat; a->ffportdnspd=dat;
@@ -1778,10 +1649,6 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
static int DoITEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoITEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
DoITToneSlide(tick, a, UniGetByte()); DoITToneSlide(tick, a, UniGetByte());
return 0; return 0;
@@ -1833,10 +1700,6 @@ static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat)
static int DoITEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoITEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
DoITVibrato(tick, a, UniGetByte()); DoITVibrato(tick, a, UniGetByte());
return 0; return 0;
@@ -1846,11 +1709,6 @@ static int DoITEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE inf, on, off; UBYTE inf, on, off;
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
a->s3mtronof = inf; a->s3mtronof = inf;
@@ -1873,11 +1731,6 @@ static int DoITEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
static int DoITEffectM(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoITEffectM(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
a->main.chanvol=UniGetByte(); a->main.chanvol=UniGetByte();
if (a->main.chanvol>64) if (a->main.chanvol>64)
a->main.chanvol=64; a->main.chanvol=64;
@@ -1891,10 +1744,6 @@ static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE inf, lo, hi; UBYTE inf, lo, hi;
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
@@ -1931,9 +1780,6 @@ static int DoITEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE inf, lo, hi; UBYTE inf, lo, hi;
SWORD pan; SWORD pan;
(void)flags; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
a->pansspd = inf; a->pansspd = inf;
@@ -1971,11 +1817,6 @@ static int DoITEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE tempo; UBYTE tempo;
SWORD temp; SWORD temp;
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
tempo = UniGetByte(); tempo = UniGetByte();
if (mod->patdly2) if (mod->patdly2)
@@ -1997,10 +1838,6 @@ static int DoITEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE dat, q; UBYTE dat, q;
UWORD temp = 0; /* silence warning */ UWORD temp = 0; /* silence warning */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat = UniGetByte(); dat = UniGetByte();
if (!tick) { if (!tick) {
if (dat&0x0f) a->vibdepth=dat&0xf; if (dat&0x0f) a->vibdepth=dat&0xf;
@@ -2045,10 +1882,6 @@ static int DoITEffectW(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
{ {
UBYTE inf, lo, hi; UBYTE inf, lo, hi;
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
inf = UniGetByte(); inf = UniGetByte();
if (inf) if (inf)
@@ -2085,7 +1918,6 @@ static int DoITEffectY(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
UBYTE dat, q; UBYTE dat, q;
SLONG temp = 0; /* silence warning */ SLONG temp = 0; /* silence warning */
(void)flags; /* unused arg */
dat=UniGetByte(); dat=UniGetByte();
if (!tick) { if (!tick) {
@@ -2210,8 +2042,6 @@ static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UBYTE c, inf; UBYTE c, inf;
(void)channel; /* unused arg */
c = UniGetByte(); c = UniGetByte();
inf = UniGetByte(); inf = UniGetByte();
@@ -2262,11 +2092,6 @@ static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
{ {
UWORD offset=UniGetWord(); UWORD offset=UniGetWord();
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
if (offset) if (offset)
a->ultoffset=offset; a->ultoffset=offset;
@@ -2284,11 +2109,6 @@ static int DoMEDSpeed(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD
{ {
UWORD speed=UniGetWord(); UWORD speed=UniGetWord();
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)channel; /* unused arg */
mod->bpm=speed; mod->bpm=speed;
return 0; return 0;
@@ -2321,9 +2141,6 @@ static int DoOktArp(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD c
{ {
UBYTE dat, dat2; UBYTE dat, dat2;
(void)mod; /* unused arg */
(void)channel; /* unused arg */
dat2 = UniGetByte(); /* arpeggio style */ dat2 = UniGetByte(); /* arpeggio style */
dat = UniGetByte(); dat = UniGetByte();
if (!tick) { if (!tick) {
@@ -2342,12 +2159,6 @@ static int DoOktArp(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD c
static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
{ {
(void)tick; /* unused arg */
(void)flags; /* unused arg */
(void)a; /* unused arg */
(void)mod; /* unused arg */
(void)channel; /* unused arg */
UniSkipOpcode(); UniSkipOpcode();
return 0; return 0;
@@ -2428,7 +2239,11 @@ static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
int explicitslides = 0; int explicitslides = 0;
effect_func f; 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]; f = effects[c];
if (f != DoNothing) if (f != DoNothing)
a->sliding = 0; a->sliding = 0;
@@ -2447,12 +2262,12 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
switch (dat) { switch (dat) {
case 0x0: /* past note cut */ 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) if (mod->voice[t].master==a)
mod->voice[t].main.fadevol=0; mod->voice[t].main.fadevol=0;
break; break;
case 0x1: /* past note off */ 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) { if (mod->voice[t].master==a) {
mod->voice[t].main.keyoff|=KEY_OFF; mod->voice[t].main.keyoff|=KEY_OFF;
if ((!(mod->voice[t].venv.flg & EF_ON))|| if ((!(mod->voice[t].venv.flg & EF_ON))||
@@ -2461,7 +2276,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
} }
break; break;
case 0x2: /* past note fade */ 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) if (mod->voice[t].master==a)
mod->voice[t].main.keyoff|=KEY_FADE; mod->voice[t].main.keyoff|=KEY_FADE;
break; break;
@@ -2504,7 +2319,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
} }
} }
void pt_UpdateVoices(MODULE *mod, int max_volume) static void pt_UpdateVoices(MODULE *mod, int max_volume)
{ {
SWORD envpan,envvol,envpit,channel; SWORD envpan,envvol,envpit,channel;
UWORD playperiod; UWORD playperiod;
@@ -2516,7 +2331,7 @@ void pt_UpdateVoices(MODULE *mod, int max_volume)
SAMPLE *s; SAMPLE *s;
mod->totalchn=mod->realchn=0; mod->totalchn=mod->realchn=0;
for (channel=0;channel<md_sngchn;channel++) { for (channel=0;channel<NUMVOICES(mod);channel++) {
aout=&mod->voice[channel]; aout=&mod->voice[channel];
i=aout->main.i; i=aout->main.i;
s=aout->main.s; s=aout->main.s;
@@ -2563,6 +2378,9 @@ void pt_UpdateVoices(MODULE *mod, int max_volume)
if (aout->main.pitflg & EF_ON) if (aout->main.pitflg & EF_ON)
envpit = ProcessEnvelope(aout,&aout->cenv,32); envpit = ProcessEnvelope(aout,&aout->cenv,32);
} }
if (aout->main.kick == KICK_NOTE) {
aout->main.kick_flag = 1;
}
aout->main.kick=KICK_ABSENT; aout->main.kick=KICK_ABSENT;
tmpvol = aout->main.fadevol; /* max 32768 */ tmpvol = aout->main.fadevol; /* max 32768 */
@@ -2704,7 +2522,7 @@ void pt_UpdateVoices(MODULE *mod, int max_volume)
} }
/* Handles new notes or instruments */ /* Handles new notes or instruments */
void pt_Notes(MODULE *mod) static void pt_Notes(MODULE *mod)
{ {
SWORD channel; SWORD channel;
MP_CONTROL *a; MP_CONTROL *a;
@@ -2730,7 +2548,7 @@ void pt_Notes(MODULE *mod)
UniSetRow(a->row); UniSetRow(a->row);
funky=0; funky=0;
while((c=UniGetByte())) while((c=UniGetByte()) != 0)
switch (c) { switch (c) {
case UNI_NOTE: case UNI_NOTE:
funky|=1; funky|=1;
@@ -2763,7 +2581,7 @@ void pt_Notes(MODULE *mod)
INSTRUMENT *i; INSTRUMENT *i;
SAMPLE *s; SAMPLE *s;
if ((i=a->main.i)) { if ((i=a->main.i) != NULL) {
if (i->samplenumber[a->anote] >= mod->numsmp) continue; if (i->samplenumber[a->anote] >= mod->numsmp) continue;
s=&mod->samples[i->samplenumber[a->anote]]; s=&mod->samples[i->samplenumber[a->anote]];
a->main.note=i->samplenote[a->anote]; a->main.note=i->samplenote[a->anote];
@@ -2842,7 +2660,7 @@ void pt_Notes(MODULE *mod)
} }
/* Handles effects */ /* Handles effects */
void pt_EffectsPass1(MODULE *mod) static void pt_EffectsPass1(MODULE *mod)
{ {
SWORD channel; SWORD channel;
MP_CONTROL *a; MP_CONTROL *a;
@@ -2852,7 +2670,7 @@ void pt_EffectsPass1(MODULE *mod)
for (channel=0;channel<mod->numchn;channel++) { for (channel=0;channel<mod->numchn;channel++) {
a=&mod->control[channel]; a=&mod->control[channel];
if ((aout=a->slave)) { if ((aout=a->slave) != NULL) {
a->main.fadevol=aout->main.fadevol; a->main.fadevol=aout->main.fadevol;
a->main.period=aout->main.period; a->main.period=aout->main.period;
if (a->main.kick==KICK_KEYOFF) if (a->main.kick==KICK_KEYOFF)
@@ -2893,7 +2711,7 @@ void pt_EffectsPass1(MODULE *mod)
} }
/* NNA management */ /* NNA management */
void pt_NNA(MODULE *mod) static void pt_NNA(MODULE *mod)
{ {
SWORD channel; SWORD channel;
MP_CONTROL *a; MP_CONTROL *a;
@@ -2934,7 +2752,7 @@ void pt_NNA(MODULE *mod)
if (a->dct!=DCT_OFF) { if (a->dct!=DCT_OFF) {
int t; int t;
for (t=0;t<md_sngchn;t++) for (t=0;t<NUMVOICES(mod);t++)
if ((!Voice_Stopped_internal(t))&& if ((!Voice_Stopped_internal(t))&&
(mod->voice[t].masterchn==channel)&& (mod->voice[t].masterchn==channel)&&
(a->main.sample==mod->voice[t].main.sample)) { (a->main.sample==mod->voice[t].main.sample)) {
@@ -2974,7 +2792,7 @@ void pt_NNA(MODULE *mod)
} }
/* Setup module and NNA voices */ /* Setup module and NNA voices */
void pt_SetupVoices(MODULE *mod) static void pt_SetupVoices(MODULE *mod)
{ {
SWORD channel; SWORD channel;
MP_CONTROL *a; MP_CONTROL *a;
@@ -2998,7 +2816,7 @@ void pt_SetupVoices(MODULE *mod)
a->slave=&mod->voice[a->slavechn=channel]; a->slave=&mod->voice[a->slavechn=channel];
/* assign parts of MP_VOICE only done for a KICK_NOTE */ /* 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; if (aout->mflag && aout->master) aout->master->slave=NULL;
aout->master=a; aout->master=a;
a->slave=aout; a->slave=aout;
@@ -3015,7 +2833,7 @@ void pt_SetupVoices(MODULE *mod)
} }
/* second effect pass */ /* second effect pass */
void pt_EffectsPass2(MODULE *mod) static void pt_EffectsPass2(MODULE *mod)
{ {
SWORD channel; SWORD channel;
MP_CONTROL *a; MP_CONTROL *a;
@@ -3027,7 +2845,7 @@ void pt_EffectsPass2(MODULE *mod)
if (!a->row) continue; if (!a->row) continue;
UniSetRow(a->row); UniSetRow(a->row);
while((c=UniGetByte())) while((c=UniGetByte()) != 0)
if (c==UNI_ITEFFECTS0) { if (c==UNI_ITEFFECTS0) {
c=UniGetByte(); c=UniGetByte();
if ((c>>4)==SS_S7EFFECTS) if ((c>>4)==SS_S7EFFECTS)
@@ -3089,6 +2907,9 @@ void Player_HandleTick(void)
pf->control[channel].pat_reppos=-1; pf->control[channel].pat_reppos=-1;
pf->patbrk=pf->posjmp=0; 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 /* handle the "---" (end of song) pattern since it can occur
*inside* the module in some formats */ *inside* the module in some formats */
if ((pf->sngpos>=pf->numpos)|| if ((pf->sngpos>=pf->numpos)||
@@ -3103,7 +2924,6 @@ void Player_HandleTick(void)
pf->bpm=pf->inittempo<32?32:pf->inittempo; pf->bpm=pf->inittempo<32?32:pf->inittempo;
} }
} }
if (pf->sngpos<0) pf->sngpos=pf->numpos-1;
} }
if (!pf->patdly2) if (!pf->patdly2)
@@ -3160,7 +2980,7 @@ static void Player_Init_internal(MODULE* mod)
mod->patbrk=0; mod->patbrk=0;
} }
BOOL Player_Init(MODULE* mod) int Player_Init(MODULE* mod)
{ {
mod->extspd=1; mod->extspd=1;
mod->panflag=1; mod->panflag=1;
@@ -3176,6 +2996,11 @@ BOOL Player_Init(MODULE* mod)
if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE)))) if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE))))
return 1; 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); Player_Init_internal(mod);
return 0; return 0;
} }
@@ -3191,9 +3016,7 @@ void Player_Exit_internal(MODULE* mod)
pf=NULL; pf=NULL;
} }
if (mod->control)
MikMod_free(mod->control); MikMod_free(mod->control);
if (mod->voice)
MikMod_free(mod->voice); MikMod_free(mod->voice);
mod->control=NULL; mod->control=NULL;
mod->voice=NULL; mod->voice=NULL;
@@ -3209,8 +3032,10 @@ void Player_Exit(MODULE* mod)
MIKMODAPI void Player_SetVolume(SWORD volume) MIKMODAPI void Player_SetVolume(SWORD volume)
{ {
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
if (pf) if (pf) {
pf->volume=(volume<0)?0:(volume>128)?128:volume; pf->volume=(volume<0)?0:(volume>128)?128:volume;
pf->initvolume=pf->volume;
}
MUTEX_UNLOCK(vars); MUTEX_UNLOCK(vars);
} }
@@ -3284,7 +3109,7 @@ MIKMODAPI void Player_NextPosition(void)
pf->patbrk=0; pf->patbrk=0;
pf->vbtick=pf->sngspd; pf->vbtick=pf->sngspd;
for (t=0;t<md_sngchn;t++) { for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t); Voice_Stop_internal(t);
pf->voice[t].main.i=NULL; pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL; pf->voice[t].main.s=NULL;
@@ -3309,7 +3134,7 @@ MIKMODAPI void Player_PrevPosition(void)
pf->patbrk=0; pf->patbrk=0;
pf->vbtick=pf->sngspd; pf->vbtick=pf->sngspd;
for (t=0;t<md_sngchn;t++) { for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t); Voice_Stop_internal(t);
pf->voice[t].main.i=NULL; pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL; pf->voice[t].main.s=NULL;
@@ -3336,7 +3161,7 @@ MIKMODAPI void Player_SetPosition(UWORD pos)
pf->sngpos=pos; pf->sngpos=pos;
pf->vbtick=pf->sngspd; pf->vbtick=pf->sngspd;
for (t=0;t<md_sngchn;t++) { for (t=0;t<NUMVOICES(pf);t++) {
Voice_Stop_internal(t); Voice_Stop_internal(t);
pf->voice[t].main.i=NULL; pf->voice[t].main.i=NULL;
pf->voice[t].main.s=NULL; pf->voice[t].main.s=NULL;
@@ -3439,7 +3264,7 @@ MIKMODAPI void Player_Mute(SLONG arg1,...)
static void Player_ToggleMute_internal(SLONG arg1,va_list ap) static void Player_ToggleMute_internal(SLONG arg1,va_list ap)
{ {
SLONG arg2,arg3=0; SLONG arg2,arg3=0;
SLONG t; ULONG t;
if (pf) { if (pf) {
switch (arg1) { switch (arg1) {
@@ -3558,4 +3383,47 @@ MIKMODAPI void Player_SetTempo(UWORD tempo)
MUTEX_UNLOCK(vars); MUTEX_UNLOCK(vars);
} }
MIKMODAPI int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo)
{
int i;
if (numvoices > md_sngchn)
numvoices = md_sngchn;
MUTEX_LOCK(vars);
if (pf)
for (i = 0; i < md_sngchn; i++) {
vinfo [i].i = pf->voice[i].main.i;
vinfo [i].s = pf->voice[i].main.s;
vinfo [i].panning = pf->voice [i].main.panning;
vinfo [i].volume = pf->voice [i].main.chanvol;
vinfo [i].period = pf->voice [i].main.period;
vinfo [i].kick = pf->voice [i].main.kick_flag;
pf->voice [i].main.kick_flag = 0;
}
MUTEX_UNLOCK(vars);
return numvoices;
}
/* 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; */
MUTEX_UNLOCK(vars);
return ret;
}
/* Get current module row */
MIKMODAPI int Player_GetRow(void)
{
int ret;
MUTEX_LOCK(vars);
ret = pf ? pf->patpos : 0;
MUTEX_UNLOCK(vars);
return ret;
}
/* ex:set ts=4: */ /* ex:set ts=4: */
+8 -8
View File
@@ -37,7 +37,7 @@
/* Unibuffer chunk size */ /* Unibuffer chunk size */
#define BUFPAGE 128 #define BUFPAGE 128
UWORD unioperands[UNI_LAST]={ const UWORD unioperands[UNI_LAST] = {
0, /* not used */ 0, /* not used */
1, /* UNI_NOTE */ 1, /* UNI_NOTE */
1, /* UNI_INSTRUMENT */ 1, /* UNI_INSTRUMENT */
@@ -209,7 +209,7 @@ static BOOL UniExpand(int wanted)
/* Expand the buffer by BUFPAGE bytes */ /* Expand the buffer by BUFPAGE bytes */
newbuf=(UBYTE*)MikMod_realloc(unibuf,(unimax+BUFPAGE)*sizeof(UBYTE)); newbuf=(UBYTE*)MikMod_realloc(unibuf,(unimax+BUFPAGE)*sizeof(UBYTE));
/* Check if realloc succeeded */ /* Check if MikMod_realloc succeeded */
if(newbuf) { if(newbuf) {
unibuf = newbuf; unibuf = newbuf;
unimax+=BUFPAGE; unimax+=BUFPAGE;
@@ -236,7 +236,7 @@ void UniWriteWord(UWORD data)
} }
} }
static BOOL MyCmp(UBYTE* a,UBYTE* b,UWORD l) static BOOL MyCmp(const UBYTE* a,const UBYTE* b,UWORD l)
{ {
UWORD t; UWORD t;
@@ -275,15 +275,15 @@ void UniNewline(void)
stream. */ stream. */
UBYTE* UniDup(void) UBYTE* UniDup(void)
{ {
UBYTE *d; void *d;
if (!UniExpand(unitt-unipc)) return NULL; if (!UniExpand(unipc-unitt)) return NULL;
unibuf[unitt] = 0; unibuf[unitt] = 0;
if(!(d=(UBYTE *)MikMod_malloc(unipc))) return NULL; if(!(d=MikMod_malloc(unipc))) return NULL;
memcpy(d,unibuf,unipc); memcpy(d,unibuf,unipc);
return d; return (UBYTE *)d;
} }
BOOL UniInit(void) BOOL UniInit(void)
@@ -296,7 +296,7 @@ BOOL UniInit(void)
void UniCleanup(void) void UniCleanup(void)
{ {
if(unibuf) MikMod_free(unibuf); MikMod_free(unibuf);
unibuf = NULL; unibuf = NULL;
} }
+189 -11
View File
@@ -1,4 +1,5 @@
/* MikMod sound library /* MikMod sound library
(c) 2004, Raphael Assenat
(c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
for complete list. for complete list.
@@ -20,8 +21,6 @@
/*============================================================================== /*==============================================================================
$Id$
WAV sample loader WAV sample loader
==============================================================================*/ ==============================================================================*/
@@ -46,6 +45,9 @@
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
#endif #endif
static void extract_channel(const char *src, char *dst, int num_chan, int num_samples, int samp_size, int channel);
typedef struct WAV { typedef struct WAV {
CHAR rID[4]; CHAR rID[4];
ULONG rLen; ULONG rLen;
@@ -60,12 +62,32 @@ typedef struct WAV {
UWORD nFormatSpecific; UWORD nFormatSpecific;
} WAV; } WAV;
SAMPLE* Sample_LoadGeneric_internal(MREADER* reader) static BOOL isWaveFile(MREADER* reader)
{
WAV wh;
_mm_fseek(reader, SEEK_SET, 0);
/* read wav header */
_mm_read_string(wh.rID,4,reader);
wh.rLen = _mm_read_I_ULONG(reader);
_mm_read_string(wh.wID,4,reader);
/* check for correct header */
if(_mm_eof(reader)|| memcmp(wh.rID,"RIFF",4) || memcmp(wh.wID,"WAVE",4)) {
return 0;
}
return 1;
}
static SAMPLE* Sample_LoadGeneric_internal_wav(MREADER* reader)
{ {
SAMPLE *si=NULL; SAMPLE *si=NULL;
WAV wh; WAV wh;
BOOL have_fmt=0; BOOL have_fmt=0;
_mm_fseek(reader, SEEK_SET, 0);
/* read wav header */ /* read wav header */
_mm_read_string(wh.rID,4,reader); _mm_read_string(wh.rID,4,reader);
wh.rLen = _mm_read_I_ULONG(reader); wh.rLen = _mm_read_I_ULONG(reader);
@@ -144,23 +166,159 @@ SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
return si; return si;
} }
MIKMODAPI SAMPLE* Sample_LoadGeneric(MREADER* reader) static SAMPLE* Sample_LoadRawGeneric_internal(MREADER* reader, ULONG rate, ULONG channel, ULONG flags)
{
SAMPLE *si;
long len;
int samp_size=1;
if(!(si=(SAMPLE*)MikMod_malloc(sizeof(SAMPLE)))) return NULL;
/* length */
_mm_fseek(reader, 0, SEEK_END);
len = _mm_ftell(reader);
si->panning = PAN_CENTER;
si->speed = rate/1;
si->volume = 64;
si->length = len;
si->loopstart=0;
si->loopend = len;
si->susbegin = 0;
si->susend = 0;
si->inflags = si->flags = flags;
if (si->flags & SF_16BITS) {
si->length >>= 1;
si->loopstart >>= 1;
si->loopend >>= 1;
samp_size = 2;
}
if (si->flags & SF_STEREO)
{
char *data, *channel_data;
int num_samp = si->length/samp_size/2;
MREADER *chn_reader;
data = (char*)MikMod_malloc(si->length);
if (!data) { MikMod_free(si); return NULL; }
channel_data = (char*)MikMod_malloc(si->length/2);
if (!channel_data) { MikMod_free(data); MikMod_free(si); return NULL; }
/* load the raw samples completely, and fully extract the
* requested channel. Create a memory reader pointing to
* the channel data. */
_mm_fseek(reader, 0, SEEK_SET);
reader->Read(reader, data, si->length);
extract_channel(data, channel_data, 2, num_samp, samp_size, channel);
chn_reader = _mm_new_mem_reader(channel_data, num_samp * samp_size);
if (!chn_reader) {
MikMod_free(channel_data);
MikMod_free(data);
MikMod_free(si);
return NULL;
}
/* half of the samples were in the other channel */
si->loopstart=0;
si->length=num_samp;
si->loopend=num_samp;
SL_RegisterSample(si, MD_SNDFX, chn_reader);
SL_LoadSamples();
_mm_delete_mem_reader(chn_reader);
MikMod_free(channel_data);
MikMod_free(data);
return si;
}
_mm_fseek(reader, 0, SEEK_SET);
SL_RegisterSample(si, MD_SNDFX, reader);
SL_LoadSamples();
return si;
}
static SAMPLE* Sample_LoadGeneric_internal(MREADER* reader, const char *options)
{
if (isWaveFile(reader)) {
return Sample_LoadGeneric_internal_wav(reader);
}
return NULL;
}
MIKMODAPI SAMPLE* Sample_LoadRawGeneric(MREADER* reader, ULONG rate, ULONG channel, ULONG flags)
{ {
SAMPLE* result; SAMPLE* result;
MUTEX_LOCK(vars); MUTEX_LOCK(vars);
result=Sample_LoadGeneric_internal(reader); result = Sample_LoadRawGeneric_internal(reader, rate, channel, flags);
MUTEX_UNLOCK(vars); MUTEX_UNLOCK(vars);
return result; return result;
} }
MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len) MIKMODAPI SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags)
{
SAMPLE *result=NULL;
MREADER *reader;
if (!buf || len <= 0) return NULL;
if ((reader=_mm_new_mem_reader(buf, len)) != NULL) {
result=Sample_LoadRawGeneric(reader, rate, channel, flags);
_mm_delete_mem_reader(reader);
}
return result;
}
MIKMODAPI SAMPLE* Sample_LoadRawFP(FILE *fp, ULONG rate, ULONG channel, ULONG flags)
{ {
SAMPLE* result=NULL; SAMPLE* result=NULL;
MREADER* reader; MREADER* reader;
if ((reader=_mm_new_mem_reader(buf, len))) { if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
result=Sample_LoadRawGeneric(reader, rate, channel, flags);
_mm_delete_file_reader(reader);
}
return result;
}
MIKMODAPI SAMPLE* Sample_LoadRaw(const CHAR* filename, ULONG rate, ULONG channel, ULONG flags)
{
FILE *fp;
SAMPLE *si=NULL;
if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL;
if((fp=_mm_fopen(filename,"rb")) != NULL) {
si = Sample_LoadRawFP(fp, rate, channel, flags);
_mm_fclose(fp);
}
return si;
}
MIKMODAPI SAMPLE* Sample_LoadGeneric(MREADER* reader)
{
SAMPLE* result;
MUTEX_LOCK(vars);
result=Sample_LoadGeneric_internal(reader, NULL);
MUTEX_UNLOCK(vars);
return result;
}
MIKMODAPI SAMPLE *Sample_LoadMem(const char *buf, int len)
{
SAMPLE* result=NULL;
MREADER* reader;
if (!buf || len <= 0) return NULL;
if ((reader=_mm_new_mem_reader(buf, len)) != NULL) {
result=Sample_LoadGeneric(reader); result=Sample_LoadGeneric(reader);
_mm_delete_mem_reader(reader); _mm_delete_mem_reader(reader);
} }
@@ -172,20 +330,20 @@ MIKMODAPI SAMPLE* Sample_LoadFP(FILE *fp)
SAMPLE* result=NULL; SAMPLE* result=NULL;
MREADER* reader; MREADER* reader;
if((reader=_mm_new_file_reader(fp))) { if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
result=Sample_LoadGeneric(reader); result=Sample_LoadGeneric(reader);
_mm_delete_file_reader(reader); _mm_delete_file_reader(reader);
} }
return result; return result;
} }
MIKMODAPI SAMPLE* Sample_Load(CHAR* filename) MIKMODAPI SAMPLE* Sample_Load(const CHAR* filename)
{ {
FILE *fp; FILE *fp;
SAMPLE *si=NULL; SAMPLE *si=NULL;
if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL; if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL;
if((fp=_mm_fopen(filename,"rb"))) { if((fp=_mm_fopen(filename,"rb")) != NULL) {
si = Sample_LoadFP(fp); si = Sample_LoadFP(fp);
_mm_fclose(fp); _mm_fclose(fp);
} }
@@ -195,6 +353,7 @@ MIKMODAPI SAMPLE* Sample_Load(CHAR* filename)
MIKMODAPI void Sample_Free(SAMPLE* si) MIKMODAPI void Sample_Free(SAMPLE* si)
{ {
if(si) { if(si) {
if (si->onfree) si->onfree(si->ctx);
MD_SampleUnload(si->handle); MD_SampleUnload(si->handle);
MikMod_free(si); MikMod_free(si);
} }
@@ -207,4 +366,23 @@ void Sample_Free_internal(SAMPLE *si)
MUTEX_UNLOCK(vars); MUTEX_UNLOCK(vars);
} }
/* ex:set ts=4: */ static void extract_channel(const char *src, char *dst, int num_chan, int num_samples, int samp_size, int channel)
{
int i;
#ifdef MIKMOD_DEBUG
fprintf(stderr,"Extract channel: %p %p, num_chan=%d, num_samples=%d, samp_size=%d, channel=%d\n",
src,dst,num_chan,num_samples,samp_size,channel);
#endif
src += channel * samp_size;
while (num_samples--)
{
for (i=0; i<samp_size; i++) {
dst[i] = src[i];
}
src += samp_size * num_chan;
dst += samp_size;
}
}
/* ex:set ts=8: */
+1 -1
View File
@@ -32,7 +32,7 @@
#include "mikmod_internals.h" #include "mikmod_internals.h"
UWORD npertab[7 * OCTAVE] = { const UWORD npertab[7 * OCTAVE] = {
/* Octaves 6 -> 0 */ /* Octaves 6 -> 0 */
/* C C# D D# E F F# G G# A A# B */ /* C C# D D# E F F# G G# A A# B */
0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a, 0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a,
+38 -27
View File
@@ -56,7 +56,7 @@ typedef struct ITPACK {
BOOL SL_Init(SAMPLOAD* s) BOOL SL_Init(SAMPLOAD* s)
{ {
if(!sl_buffer) 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; sl_rlength = s->length;
if(s->infmt & SF_16BITS) sl_rlength>>=1; if(s->infmt & SF_16BITS) sl_rlength>>=1;
@@ -68,16 +68,15 @@ BOOL SL_Init(SAMPLOAD* s)
void SL_Exit(SAMPLOAD *s) void SL_Exit(SAMPLOAD *s)
{ {
if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR); if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
if(sl_buffer) {
MikMod_free(sl_buffer); MikMod_free(sl_buffer);
sl_buffer=NULL; sl_buffer=NULL;
}
} }
/* unpack a 8bit IT packed sample */ /* unpack a 8bit IT packed sample */
static BOOL 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 x,y,needbits,havebits,new_count=0;
UWORD bits = status->bits; UWORD bits = status->bits;
UWORD bufbits = status->bufbits; UWORD bufbits = status->bufbits;
@@ -145,13 +144,13 @@ static BOOL read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD
status->bufbits = bufbits; status->bufbits = bufbits;
status->last = last; status->last = last;
status->buf = buf; status->buf = buf;
return !!(dest-sl_buffer); return (dest-out);
} }
/* unpack a 16bit IT packed sample */ /* unpack a 16bit IT packed sample */
static BOOL 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; SLONG x,y,needbits,havebits,new_count=0;
UWORD bits = status->bits; UWORD bits = status->bits;
UWORD bufbits = status->bufbits; UWORD bufbits = status->bufbits;
@@ -174,15 +173,15 @@ static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
y=needbits<bufbits?needbits:bufbits; y=needbits<bufbits?needbits:bufbits;
x|=(buf &((1<<y)-1))<<havebits; x|=(buf &((1<<y)-1))<<havebits;
buf>>=y; buf>>=y;
bufbits-=y; bufbits-=(UWORD)y;
needbits-=y; needbits-=(UWORD)y;
havebits+=y; havebits+=(UWORD)y;
} }
if (new_count) { if (new_count) {
new_count = 0; new_count = 0;
if (++x >= bits) if (++x >= bits)
x++; x++;
bits = x; bits = (UWORD)x;
continue; continue;
} }
if (bits<7) { if (bits<7) {
@@ -196,13 +195,13 @@ static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
if ((x>y)&&(x<=y+16)) { if ((x>y)&&(x<=y+16)) {
if ((x-=y)>=bits) if ((x-=y)>=bits)
x++; x++;
bits = x; bits = (UWORD)x;
continue; continue;
} }
} }
else if (bits<18) { else if (bits<18) {
if (x>=0x10000) { if (x>=0x10000) {
bits=x-0x10000+1; bits=(UWORD)(x-0x10000+1);
continue; continue;
} }
} else { } else {
@@ -219,10 +218,10 @@ static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
status->bufbits = bufbits; status->bufbits = bufbits;
status->last = last; status->last = last;
status->buf = buf; status->buf = buf;
return !!(dest-sl_buffer); return (dest-out);
} }
static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,BOOL dither) static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,BOOL dither)
{ {
SBYTE *bptr = (SBYTE*)buffer; SBYTE *bptr = (SBYTE*)buffer;
SWORD *wptr = (SWORD*)buffer; SWORD *wptr = (SWORD*)buffer;
@@ -230,7 +229,12 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
int result,c_block=0; /* compression bytes until next block */ int result,c_block=0; /* compression bytes until next block */
ITPACK status; ITPACK status;
UWORD incnt; UWORD incnt = 0;
status.buf = 0;
status.last = 0;
status.bufbits = 0;
status.bits = 0;
while(length) { while(length) {
stodo=(length<SLBUFSIZE)?length:SLBUFSIZE; stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
@@ -258,6 +262,10 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
c_block -= stodo; c_block -= stodo;
} else { } else {
if(infmt&SF_16BITS) { if(infmt&SF_16BITS) {
if(_mm_eof(reader)) {
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
return 1;
}
if(infmt&SF_BIG_ENDIAN) if(infmt&SF_BIG_ENDIAN)
_mm_read_M_SWORDS(sl_buffer,stodo,reader); _mm_read_M_SWORDS(sl_buffer,stodo,reader);
else else
@@ -266,6 +274,10 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
SBYTE *src; SBYTE *src;
SWORD *dest; SWORD *dest;
if(_mm_eof(reader)) {
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
return 1;
}
reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo); reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
src = (SBYTE*)sl_buffer; src = (SBYTE*)sl_buffer;
dest = sl_buffer; dest = sl_buffer;
@@ -299,7 +311,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
scaleval = 0; scaleval = 0;
for(u=scalefactor;u && t<stodo;u--,t++) for(u=scalefactor;u && t<stodo;u--,t++)
scaleval+=sl_buffer[t]; scaleval+=sl_buffer[t];
sl_buffer[idx++]=scaleval/(scalefactor-u); sl_buffer[idx++]=(UWORD)(scaleval/(scalefactor-u));
length--; length--;
} }
stodo = idx; stodo = idx;
@@ -316,7 +328,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
while(t<stodo && length) { while(t<stodo && length) {
avgval=sl_buffer[t++]; avgval=sl_buffer[t++];
avgval+=sl_buffer[t++]; avgval+=sl_buffer[t++];
sl_buffer[idx++]=avgval>>1; sl_buffer[idx++]=(SWORD)(avgval>>1);
length-=2; length-=2;
} }
stodo = idx; stodo = idx;
@@ -334,7 +346,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
return 0; return 0;
} }
BOOL SL_Load(void* buffer,SAMPLOAD *smp,ULONG length) int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length)
{ {
return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor, return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor,
length,smp->reader,0); length,smp->reader,0);
@@ -406,7 +418,7 @@ static ULONG RealSpeed(SAMPLOAD *s)
return(s->sample->speed/(s->scalefactor?s->scalefactor:1)); return(s->sample->speed/(s->scalefactor?s->scalefactor:1));
} }
static BOOL DitherSamples(SAMPLOAD* samplist,int type) static int DitherSamples(SAMPLOAD* samplist,int type)
{ {
SAMPLOAD *c2smp=NULL; SAMPLOAD *c2smp=NULL;
ULONG maxsize, speed; ULONG maxsize, speed;
@@ -414,7 +426,7 @@ static BOOL DitherSamples(SAMPLOAD* samplist,int type)
if(!samplist) return 0; if(!samplist) return 0;
if((maxsize=MD_SampleSpace(type)*1024)) if((maxsize=MD_SampleSpace(type)*1024) != 0)
while(SampleTotal(samplist,type)>maxsize) { while(SampleTotal(samplist,type)>maxsize) {
/* First Pass - check for any 16 bit samples */ /* First Pass - check for any 16 bit samples */
s = samplist; s = samplist;
@@ -468,17 +480,17 @@ static BOOL DitherSamples(SAMPLOAD* samplist,int type)
return 0; return 0;
} }
BOOL SL_LoadSamples(void) int SL_LoadSamples(void)
{ {
BOOL ok; int rc;
_mm_critical = 0; _mm_critical = 0;
if((!musiclist)&&(!sndfxlist)) return 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; musiclist=sndfxlist=NULL;
return ok; return rc;
} }
void SL_Sample16to8(SAMPLOAD* s) void SL_Sample16to8(SAMPLOAD* s)
@@ -515,5 +527,4 @@ void SL_HalveSample(SAMPLOAD* s,int factor)
s->sample->loopend = s->loopend / s->scalefactor; s->sample->loopend = s->loopend / s->scalefactor;
} }
/* ex:set ts=4: */ /* ex:set ts=4: */
File diff suppressed because it is too large Load Diff
+561 -80
View File
@@ -39,6 +39,8 @@
#include "config.h" #include "config.h"
#endif #endif
#ifndef NO_HQMIXER
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
#endif #endif
@@ -76,7 +78,8 @@
*/ */
#define MAXVOL_FACTOR (1<<9) #define BITSHIFT 9
#define MAXVOL_FACTOR (1<<BITSHIFT)
#define REVERBERATION 11000L #define REVERBERATION 11000L
#define SAMPLING_SHIFT 2 #define SAMPLING_SHIFT 2
@@ -128,6 +131,11 @@ static SLONGLONG idxsize,idxlpos,idxlend;
static SLONG *vc_tickbuf=NULL; static SLONG *vc_tickbuf=NULL;
static UWORD vc_mode; static UWORD vc_mode;
#ifdef _MSC_VER
/* Weird bug in compiler */ /* FIXME is this still needed? */
typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
#endif
/* Reverb control variables */ /* Reverb control variables */
static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8; static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8;
@@ -150,16 +158,16 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL,
/*========== 32 bit sample mixers - only for 32 bit platforms */ /*========== 32 bit sample mixers - only for 32 bit platforms */
#ifndef NATIVE_64BIT_INT #ifndef NATIVE_64BIT_INT
static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) static SLONG Mix32MonoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{ {
SWORD sample=0; SWORD sample=0;
SLONG i,f; SLONG i,f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(((SLONG)(srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)( (((SLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS); ((SLONG)srce[i+1]*f)) >> FRACBITS));
index+=increment; idx+=increment;
if(vnf->rampvol) { if(vnf->rampvol) {
*dest++ += (long)( *dest++ += (long)(
@@ -179,19 +187,19 @@ static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
} }
vnf->lastvalL=vnf->lvolsel * sample; vnf->lastvalL=vnf->lvolsel * sample;
return index; return idx;
} }
static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,ULONG todo) static SLONG Mix32StereoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo)
{ {
SWORD sample=0; SWORD sample=0;
SLONG i,f; SLONG i,f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1] * f)) >> FRACBITS); ((SLONG)srce[i+1] * f)) >> FRACBITS));
index += increment; idx += increment;
if(vnf->rampvol) { if(vnf->rampvol) {
*dest++ += (long)( *dest++ += (long)(
@@ -222,20 +230,20 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
vnf->lastvalL=vnf->lvolsel*sample; vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample; vnf->lastvalR=vnf->rvolsel*sample;
return index; return idx;
} }
static SLONG Mix32StereoSurround(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,ULONG todo) static SLONG Mix32StereoSurround(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo)
{ {
SWORD sample=0; SWORD sample=0;
long whoop; long whoop;
SLONG i, f; SLONG i, f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS); ((SLONG)srce[i+1]*f)) >> FRACBITS));
index+=increment; idx+=increment;
if(vnf->rampvol) { if(vnf->rampvol) {
whoop=(long)( whoop=(long)(
@@ -262,22 +270,22 @@ static SLONG Mix32StereoSurround(const SWORD* srce,SLONG* dest,SLONG index,SLONG
vnf->lastvalL=vnf->lvolsel*sample; vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->lvolsel*sample; vnf->lastvalR=vnf->lvolsel*sample;
return index; return idx;
} }
#endif #endif
/*========== 64 bit mixers */ /*========== 64 bit mixers */
static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) static SLONGLONG MixMonoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo)
{ {
SWORD sample=0; SWORD sample=0;
SLONGLONG i,f; SLONGLONG i,f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)((((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS); ((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
index+=increment; idx+=increment;
if(vnf->rampvol) { if(vnf->rampvol) {
*dest++ += (long)( *dest++ += (long)(
@@ -297,19 +305,225 @@ static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
} }
vnf->lastvalL=vnf->lvolsel * sample; vnf->lastvalL=vnf->lvolsel * sample;
return index; return idx;
} }
static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo) /* Slowest part... */
#if defined HAVE_SSE2 || defined HAVE_ALTIVEC
static __inline SWORD GetSample(const SWORD* const srce, SLONGLONG idx)
{
SLONGLONG i=idx>>FRACBITS;
SLONGLONG f=idx&FRACMASK;
return (SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
}
static SLONGLONG MixSIMDStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
{
SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel};
SWORD sample=0;
SLONG remain = todo;
/* Dest can be misaligned */
while(!IS_ALIGNED_16(dest)) {
sample=srce[idx >> FRACBITS];
idx += increment;
*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
todo--;
if(!todo) goto end;
}
/* Srce is always aligned */
#if defined HAVE_SSE2
remain = todo&3;
{
__m128i v0 = _mm_set_epi16(0, vol[1],
0, vol[0],
0, vol[1],
0, vol[0]);
for(todo>>=2;todo; todo--)
{
SWORD s0 = GetSample(srce, idx);
SWORD s1 = GetSample(srce, idx += increment);
SWORD s2 = GetSample(srce, idx += increment);
SWORD s3 = GetSample(srce, idx += increment);
__m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0);
__m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2);
__m128i v3 = _mm_load_si128((__m128i*)(dest+0));
__m128i v4 = _mm_load_si128((__m128i*)(dest+4));
_mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1)));
_mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2)));
dest+=8;
idx += increment;
}
}
#elif defined HAVE_ALTIVEC
remain = todo&3;
{
SWORD s[8];
vector signed short r0 = vec_ld(0, vol);
vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */
0, 1, /* l */
2, 3, /* r */
2, 1, /* r */
0, 1, /* l */
0, 1, /* l */
2, 3, /* r */
2, 3 /* r */
));
for(todo>>=2;todo; todo--)
{
vector short int r1;
vector signed short v1, v2;
vector signed int v3, v4, v5, v6;
/* Load constants */
s[0] = GetSample(srce, idx);
s[1] = GetSample(srce, idx += increment);
s[2] = GetSample(srce, idx += increment);
s[3] = GetSample(srce, idx += increment);
s[4] = 0;
r1 = vec_ld(0, s);
v1 = vec_perm(r1, r1, (vector unsigned char)
(0*2, 0*2+1, /* s0 */
4*2, 4*2+1, /* 0 */
0*2, 0*2+1, /* s0 */
4*2, 4*2+1, /* 0 */
1*2, 1*2+1, /* s1 */
4*2, 4*2+1, /* 0 */
1*2, 1*2+1, /* s1 */
4*2, 4*2+1 /* 0 */
) );
v2 = vec_perm(r1, r1, (vector unsigned char)
(2*2, 2*2+1, /* s2 */
4*2, 4*2+1, /* 0 */
2*2, 2*2+1, /* s2 */
4*2, 4*2+1, /* 0 */
3*2, 3*2+1, /* s3 */
4*2, 4*2+1, /* 0 */
3*2, 3*2+1, /* s3 */
4*2, 4*2+1 /* 0 */
) );
v3 = vec_ld(0, dest);
v4 = vec_ld(0x10, dest);
v5 = vec_mule(v0, v1);
v6 = vec_mule(v0, v2);
vec_st(vec_add(v3, v5), 0, dest);
vec_st(vec_add(v4, v6), 0x10, dest);
dest+=8;
idx += increment;
}
}
#endif /* HAVE_ALTIVEC */
/* Remaining bits */
while(remain--) {
sample=GetSample(srce, idx);
idx+= increment;
*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
}
end:
vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample;
return idx;
}
static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
{
SWORD sample=0;
SLONGLONG i,f;
if (vnf->rampvol)
while(todo) {
todo--;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
idx += increment;
*dest++ += (long)(
( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) +
(vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol))
) * (SLONGLONG)sample ) >> CLICK_SHIFT );
*dest++ += (long)(
( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) +
(vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol))
) * (SLONGLONG)sample ) >> CLICK_SHIFT );
vnf->rampvol--;
if (!vnf->rampvol)
break;
}
if (vnf->click)
while(todo) {
todo--;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
idx += increment;
*dest++ += (long)(
( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
(SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) )
>> CLICK_SHIFT );
*dest++ += (long)(
( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) *
(SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) )
>> CLICK_SHIFT );
vnf->click--;
if (!vnf->click)
break;
}
if (todo)
{
if (md_mode & DMODE_SIMDMIXER) {
return MixSIMDStereoNormal(srce, dest, idx, increment, todo);
}
while(todo)
{
i=idx>>FRACBITS,
f=idx&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
idx += increment;
*dest++ +=vnf->lvolsel*sample;
*dest++ +=vnf->rvolsel*sample;
todo--;
}
}
vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample;
return idx;
}
#else /* HAVE_SSE2 || HAVE_ALTIVEC */
static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
{ {
SWORD sample=0; SWORD sample=0;
SLONGLONG i,f; SLONGLONG i,f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS); ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
index += increment; idx += increment;
if(vnf->rampvol) { if(vnf->rampvol) {
*dest++ += (long)( *dest++ += (long)(
@@ -340,20 +554,22 @@ static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,S
vnf->lastvalL=vnf->lvolsel*sample; vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample; vnf->lastvalR=vnf->rvolsel*sample;
return index; return idx;
} }
#endif /* HAVE_SSE2 || HAVE_ALTIVEC */
static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo)
static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo)
{ {
SWORD sample=0; SWORD sample=0;
long whoop; long whoop;
SLONGLONG i, f; SLONGLONG i, f;
while(todo--) { while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK; i=idx>>FRACBITS,f=idx&FRACMASK;
sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS); ((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
index+=increment; idx+=increment;
if(vnf->rampvol) { if(vnf->rampvol) {
whoop=(long)( whoop=(long)(
@@ -380,19 +596,20 @@ static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG index
vnf->lastvalL=vnf->lvolsel*sample; vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->lvolsel*sample; vnf->lastvalR=vnf->lvolsel*sample;
return index; return idx;
} }
static void(*Mix32to16)(SWORD* dste,const SLONG* srce,NATIVE count); static void(*Mix32toFP)(float* dste,const SLONG *srce,NATIVE count);
static void(*Mix32to8)(SBYTE* dste,const SLONG* srce,NATIVE count); static void(*Mix32to16)(SWORD* dste,const SLONG *srce,NATIVE count);
static void(*MixReverb)(SLONG* srce,NATIVE count); static void(*Mix32to8)(SBYTE* dste,const SLONG *srce,NATIVE count);
static void(*MixReverb)(SLONG *srce,NATIVE count);
/* Reverb macros */ /* Reverb macros */
#define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n #define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n
#define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7) #define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7)
#define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7) #define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7)
static void MixReverb_Normal(SLONG* srce,NATIVE count) static void MixReverb_Normal(SLONG *srce,NATIVE count)
{ {
NATIVE speedup; NATIVE speedup;
int ReverbPct; int ReverbPct;
@@ -462,11 +679,95 @@ static void MixReverb_Stereo(SLONG *srce,NATIVE count)
} }
} }
static void (*MixLowPass)(SLONG* srce,NATIVE count);
static int nLeftNR, nRightNR;
static void MixLowPass_Stereo(SLONG* srce,NATIVE count)
{
int n1 = nLeftNR, n2 = nRightNR;
SLONG *pnr = srce;
int nr=count;
for (; nr; nr--)
{
int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1;
n1 = vnr;
vnr = pnr[1] >> 1;
pnr[1] = vnr + n2;
n2 = vnr;
pnr += 2;
}
nLeftNR = n1;
nRightNR = n2;
}
static void MixLowPass_Normal(SLONG* srce,NATIVE count)
{
int n1 = nLeftNR;
SLONG *pnr = srce;
int nr=count;
for (; nr; nr--)
{
int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1;
n1 = vnr;
pnr ++;
}
nLeftNR = n1;
}
/* Mixing macros */
#define EXTRACT_SAMPLE_FP(var,attenuation) var=*srce++*((1.0f / 32768.0f) / (MAXVOL_FACTOR*attenuation))
#define CHECK_SAMPLE_FP(var,bound) var=(var>bound)?bound:(var<-bound)?-bound:var
static void Mix32ToFP_Normal(float* dste,const SLONG *srce,NATIVE count)
{
float x1,x2,tmpx;
int i;
for(count/=SAMPLING_FACTOR;count;count--) {
tmpx=0.0f;
for(i=SAMPLING_FACTOR/2;i;i--) {
EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
tmpx+=x1+x2;
}
*dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
}
}
static void Mix32ToFP_Stereo(float* dste,const SLONG *srce,NATIVE count)
{
float x1,x2,x3,x4,tmpx,tmpy;
int i;
for(count/=SAMPLING_FACTOR;count;count--) {
tmpx=tmpy=0.0f;
for(i=SAMPLING_FACTOR/2;i;i--) {
EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
EXTRACT_SAMPLE_FP(x3,1.0f); EXTRACT_SAMPLE_FP(x4,1.0f);
CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
CHECK_SAMPLE_FP(x3,1.0f); CHECK_SAMPLE_FP(x4,1.0f);
tmpx+=x1+x3;
tmpy+=x2+x4;
}
*dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
*dste++ =tmpy*(1.0f/SAMPLING_FACTOR);
}
}
/* Mixing macros */ /* Mixing macros */
#define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation) #define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation)
#define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var #define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var
static void Mix32To16_Normal(SWORD* dste,const SLONG* srce,NATIVE count) static void Mix32To16_Normal(SWORD* dste,const SLONG *srce,NATIVE count)
{ {
NATIVE x1,x2,tmpx; NATIVE x1,x2,tmpx;
int i; int i;
@@ -481,11 +782,12 @@ static void Mix32To16_Normal(SWORD* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x2; tmpx+=x1+x2;
} }
*dste++ =tmpx/SAMPLING_FACTOR; *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR);
} }
} }
static void Mix32To16_Stereo(SWORD* dste,const SLONG* srce,NATIVE count)
static void Mix32To16_Stereo(SWORD* dste,const SLONG *srce,NATIVE count)
{ {
NATIVE x1,x2,x3,x4,tmpx,tmpy; NATIVE x1,x2,x3,x4,tmpx,tmpy;
int i; int i;
@@ -503,12 +805,12 @@ static void Mix32To16_Stereo(SWORD* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x3; tmpx+=x1+x3;
tmpy+=x2+x4; tmpy+=x2+x4;
} }
*dste++ =tmpx/SAMPLING_FACTOR; *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR);
*dste++ =tmpy/SAMPLING_FACTOR; *dste++ =(SWORD)(tmpy/SAMPLING_FACTOR);
} }
} }
static void Mix32To8_Normal(SBYTE* dste,const SLONG* srce,NATIVE count) static void Mix32To8_Normal(SBYTE* dste,const SLONG *srce,NATIVE count)
{ {
NATIVE x1,x2,tmpx; NATIVE x1,x2,tmpx;
int i; int i;
@@ -523,11 +825,11 @@ static void Mix32To8_Normal(SBYTE* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x2; tmpx+=x1+x2;
} }
*dste++ =(tmpx/SAMPLING_FACTOR)+128; *dste++ = (SBYTE)((tmpx/SAMPLING_FACTOR)+128);
} }
} }
static void Mix32To8_Stereo(SBYTE* dste,const SLONG* srce,NATIVE count) static void Mix32To8_Stereo(SBYTE* dste,const SLONG *srce,NATIVE count)
{ {
NATIVE x1,x2,x3,x4,tmpx,tmpy; NATIVE x1,x2,x3,x4,tmpx,tmpy;
int i; int i;
@@ -545,11 +847,163 @@ static void Mix32To8_Stereo(SBYTE* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x3; tmpx+=x1+x3;
tmpy+=x2+x4; tmpy+=x2+x4;
} }
*dste++ =(tmpx/SAMPLING_FACTOR)+128; *dste++ =(SBYTE)((tmpx/SAMPLING_FACTOR)+128);
*dste++ =(tmpy/SAMPLING_FACTOR)+128; *dste++ =(SBYTE)((tmpy/SAMPLING_FACTOR)+128);
} }
} }
#if defined HAVE_SSE2
#define SHIFT_MIX_TO_16 (BITSHIFT + 16 - 16)
/* TEST: Ok */
static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
{
int remain = count;
/* Check unaligned dste buffer. srce is always aligned. */
while(!IS_ALIGNED_16(dste))
{
Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
dste+=2;
srce+=8;
count--;
if(!count) return;
}
/* dste and srce aligned. srce is always aligned. */
remain = count & 15;
/* count / 2 for 1 sample */
for(count>>=4;count;count--)
{
/* Load 32bit sample. 1st average */
__m128i v0 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+0)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+4)), SHIFT_MIX_TO_16)
); /* v0: s0.l+s2.l | s0.r+s2.r | s1.l+s3.l | s1.r+s3.r */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
__m128i v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
/* v1: s0.l+s2.l / 4 | s0.r+s2.r / 4 | s1.l+s3.l+s0.l+s2.l / 4 | s1.r+s3.r+s0.r+s2.r / 4 */
__m128i v2 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+8)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+12)), SHIFT_MIX_TO_16)
); /* v2: s4.l+s6.l | s4.r+s6.r | s5.l+s7.l | s5.r+s7.r */
__m128i v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
/* v3: s4.l+s6.l /4 | s4.r+s6.r / 4| s5.l+s7.l+s4.l+s6.l / 4 | s5.r+s7.r+s4.r+s6.l / 4 */
/* pack two stereo samples in one */
__m128i v4 = _mm_unpacklo_epi64(v1, v3); /* v4 = avg(s0,s1,s2,s3) | avg(s4,s5,s6,s7) */
__m128i v6;
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
v0 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+16)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+20)), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
v2 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+24)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+28)), SHIFT_MIX_TO_16)
);
v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
/* pack two stereo samples in one */
v6 = _mm_unpacklo_epi64(v1, v3); /* v6 = avg(s8,s9,s10,s11) | avg(s12,s13,s14,s15) */
_mm_store_si128((__m128i*)dste, _mm_packs_epi32(v4, v6)); /* 4 interpolated stereo sample 32bit to 4 */
dste+=8;
srce+=32; /* 32 = 4 * 8 */
}
/* FIXME: THIS PART WRITES PAST DST !! */
if (remain)
{
Mix32To16_Stereo(dste, srce, remain);
}
}
#elif defined HAVE_ALTIVEC
#define SHIFT_MIX_TO_16 vec_splat_u32(BITSHIFT + 16 - 16)
/* TEST: Ok */
static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
{
int remain = count;
/* Check unaligned dste buffer. srce is always aligned. */
while(!IS_ALIGNED_16(dste))
{
Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
dste+=2;
srce+=8;
count--;
if(!count) return;
}
/* dste and srce aligned. srce is always aligned. */
remain = count & 15;
for(count>>=4;count;count--)
{
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
vector signed int v0 = vec_add(
vec_sra(vec_ld(0, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
vec_sra(vec_ld(0x10, srce), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
vector signed int v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
vector signed int v2 = vec_add(
vec_sra(vec_ld(0x20, srce), SHIFT_MIX_TO_16),
vec_sra(vec_ld(0x30, srce), SHIFT_MIX_TO_16)
);
vector signed int v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
/* pack two stereo samples in one */
vector signed int v6, v4 = vec_unpacklo(v1, v3); /* v4 = lo64(v1) | lo64(v3) */
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
v0 = vec_add(
vec_sra(vec_ld(0x40, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
vec_sra(vec_ld(0x50, srce), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
v2 = vec_add(
vec_sra(vec_ld(0x60, srce), SHIFT_MIX_TO_16),
vec_sra(vec_ld(0x70, srce), SHIFT_MIX_TO_16)
);
v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
/* pack two stereo samples in one */
v6 = vec_unpacklo(v1, v3);
vec_st(vec_packs(v4, v6), 0, dste); /* 4 interpolated stereo sample 32bit to 4 interpolated stereo sample 16bit + saturation */
dste+=8;
srce+=32; /* 32 = 4 * 8 */
}
if (remain)
{
Mix32To16_Stereo(dste, srce, remain);
}
}
#endif
static void AddChannel(SLONG* ptr,NATIVE todo) static void AddChannel(SLONG* ptr,NATIVE todo)
{ {
SLONGLONG end,done; SLONGLONG end,done;
@@ -638,7 +1092,7 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) { if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) {
if(vc_mode & DMODE_STEREO) { if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND)) if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND))
vnf->current=Mix32StereoSurround vnf->current=(SLONGLONG)Mix32StereoSurround
(s,ptr,vnf->current,vnf->increment,done); (s,ptr,vnf->current,vnf->increment,done);
else else
vnf->current=Mix32StereoNormal vnf->current=Mix32StereoNormal
@@ -646,7 +1100,8 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
} else } else
vnf->current=Mix32MonoNormal vnf->current=Mix32MonoNormal
(s,ptr,vnf->current,vnf->increment,done); (s,ptr,vnf->current,vnf->increment,done);
} else }
else
#endif #endif
{ {
if(vc_mode & DMODE_STEREO) { if(vc_mode & DMODE_STEREO) {
@@ -667,7 +1122,7 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
} }
todo -= done; todo -= done;
ptr +=(vc_mode & DMODE_STEREO)?(done<<1):done; ptr += (vc_mode & DMODE_STEREO)?(done<<1):done;
} }
} }
@@ -710,7 +1165,7 @@ void VC2_WriteSamples(SBYTE* buf,ULONG todo)
tickleft=(md_mixfreq*125L*SAMPLING_FACTOR)/(md_bpm*50L); tickleft=(md_mixfreq*125L*SAMPLING_FACTOR)/(md_bpm*50L);
tickleft&=~(SAMPLING_FACTOR-1); tickleft&=~(SAMPLING_FACTOR-1);
} }
left = MIN(tickleft, (long)todo); left = MIN(tickleft, todo);
buffer = buf; buffer = buf;
tickleft -= left; tickleft -= left;
todo -= left; todo -= left;
@@ -756,12 +1211,22 @@ void VC2_WriteSamples(SBYTE* buf,ULONG todo)
} }
} }
if(md_mode & DMODE_NOISEREDUCTION) {
MixLowPass(vc_tickbuf, portion);
}
if(md_reverb) { if(md_reverb) {
if(md_reverb>15) md_reverb=15; if(md_reverb>15) md_reverb=15;
MixReverb(vc_tickbuf,portion); MixReverb(vc_tickbuf,portion);
} }
if(vc_mode & DMODE_16BITS) if (vc_callback) {
vc_callback((unsigned char*)vc_tickbuf, portion);
}
if(vc_mode & DMODE_FLOAT)
Mix32toFP((float*)buffer,vc_tickbuf,portion);
else if(vc_mode & DMODE_16BITS)
Mix32to16((SWORD*)buffer,vc_tickbuf,portion); Mix32to16((SWORD*)buffer,vc_tickbuf,portion);
else else
Mix32to8((SBYTE*)buffer,vc_tickbuf,portion); Mix32to8((SBYTE*)buffer,vc_tickbuf,portion);
@@ -772,38 +1237,49 @@ void VC2_WriteSamples(SBYTE* buf,ULONG todo)
} }
} }
BOOL VC2_Init(void) int VC2_Init(void)
{ {
VC_SetupPointers(); VC_SetupPointers();
if (!(md_mode&DMODE_HQMIXER)) if (!(md_mode&DMODE_HQMIXER))
return VC1_Init(); return VC1_Init();
if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) {
_mm_errno = MMERR_INITIALIZING_MIXER; _mm_errno = MMERR_INITIALIZING_MIXER;
return 1; return 1;
} }
if(!vc_tickbuf) if(!vc_tickbuf) {
if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) {
_mm_errno = MMERR_INITIALIZING_MIXER; _mm_errno = MMERR_INITIALIZING_MIXER;
return 1; return 1;
} }
}
if(md_mode & DMODE_STEREO) { if(md_mode & DMODE_STEREO) {
Mix32toFP = Mix32ToFP_Stereo;
#if ((defined HAVE_ALTIVEC || defined HAVE_SSE2) && (SAMPLING_FACTOR == 4))
if (md_mode & DMODE_SIMDMIXER)
Mix32to16 = Mix32To16_Stereo_SIMD_4Tap;
else
#endif
Mix32to16 = Mix32To16_Stereo; Mix32to16 = Mix32To16_Stereo;
Mix32to8 = Mix32To8_Stereo; Mix32to8 = Mix32To8_Stereo;
MixReverb = MixReverb_Stereo; MixReverb = MixReverb_Stereo;
MixLowPass = MixLowPass_Stereo;
} else { } else {
Mix32toFP = Mix32ToFP_Normal;
Mix32to16 = Mix32To16_Normal; Mix32to16 = Mix32To16_Normal;
Mix32to8 = Mix32To8_Normal; Mix32to8 = Mix32To8_Normal;
MixReverb = MixReverb_Normal; MixReverb = MixReverb_Normal;
MixLowPass = MixLowPass_Normal;
} }
md_mode |= DMODE_INTERP; md_mode |= DMODE_INTERP;
vc_mode = md_mode; vc_mode = md_mode;
return 0; return 0;
} }
BOOL VC2_PlayStart(void) int VC2_PlayStart(void)
{ {
md_mode|=DMODE_INTERP; md_mode|=DMODE_INTERP;
@@ -829,6 +1305,8 @@ BOOL VC2_PlayStart(void)
if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; 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(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
@@ -837,6 +1315,7 @@ BOOL VC2_PlayStart(void)
if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
}
RVRindex = 0; RVRindex = 0;
return 0; return 0;
@@ -844,28 +1323,28 @@ BOOL VC2_PlayStart(void)
void VC2_PlayStop(void) void VC2_PlayStop(void)
{ {
if(RVbufL1) MikMod_free(RVbufL1); MikMod_free(RVbufL1);
if(RVbufL2) MikMod_free(RVbufL2); MikMod_free(RVbufL2);
if(RVbufL3) MikMod_free(RVbufL3); MikMod_free(RVbufL3);
if(RVbufL4) MikMod_free(RVbufL4); MikMod_free(RVbufL4);
if(RVbufL5) MikMod_free(RVbufL5); MikMod_free(RVbufL5);
if(RVbufL6) MikMod_free(RVbufL6); MikMod_free(RVbufL6);
if(RVbufL7) MikMod_free(RVbufL7); MikMod_free(RVbufL7);
if(RVbufL8) MikMod_free(RVbufL8); MikMod_free(RVbufL8);
if(RVbufR1) MikMod_free(RVbufR1); MikMod_free(RVbufR1);
if(RVbufR2) MikMod_free(RVbufR2); MikMod_free(RVbufR2);
if(RVbufR3) MikMod_free(RVbufR3); MikMod_free(RVbufR3);
if(RVbufR4) MikMod_free(RVbufR4); MikMod_free(RVbufR4);
if(RVbufR5) MikMod_free(RVbufR5); MikMod_free(RVbufR5);
if(RVbufR6) MikMod_free(RVbufR6); MikMod_free(RVbufR6);
if(RVbufR7) MikMod_free(RVbufR7); MikMod_free(RVbufR7);
if(RVbufR8) MikMod_free(RVbufR8); MikMod_free(RVbufR8);
RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL;
RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL;
} }
BOOL VC2_SetNumVoices(void) int VC2_SetNumVoices(void)
{ {
int t; int t;
@@ -873,8 +1352,8 @@ BOOL VC2_SetNumVoices(void)
if(!(vc_softchn=md_softchn)) return 0; if(!(vc_softchn=md_softchn)) return 0;
if(vinf) MikMod_free(vinf); MikMod_free(vinf);
if(!(vinf=MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1; if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1;
for(t=0;t<vc_softchn;t++) { for(t=0;t<vc_softchn;t++) {
vinf[t].frq=10000; vinf[t].frq=10000;
@@ -884,4 +1363,6 @@ BOOL VC2_SetNumVoices(void)
return 0; return 0;
} }
#endif /* ! NO_HQMIXER */
/* ex:set ts=4: */ /* ex:set ts=4: */
+88 -72
View File
@@ -27,80 +27,86 @@
==============================================================================*/ ==============================================================================*/
#ifndef _IN_VIRTCH_ #if defined(HAVE_CONFIG_H) && !defined(_IN_VIRTCH_) /* config.h isn't guarded */
#include "config.h"
#endif
#include "mikmod_internals.h" #include "mikmod_internals.h"
extern BOOL VC1_Init(void); #ifndef NO_HQMIXER
extern BOOL VC2_Init(void); extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
static BOOL (*VC_Init_ptr)(void)=VC1_Init; 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 VC1_Exit(void);
extern void VC2_Exit(void); extern void VC2_Exit(void);
static void (*VC_Exit_ptr)(void)=VC1_Exit; extern UWORD VC1_VoiceGetVolume(UBYTE);
extern BOOL VC1_SetNumVoices(void); extern UWORD VC2_VoiceGetVolume(UBYTE);
extern BOOL VC2_SetNumVoices(void); extern ULONG VC1_VoiceGetPanning(UBYTE);
static BOOL (*VC_SetNumVoices_ptr)(void); 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 BOOL VC1_VoiceStopped(UBYTE);
extern BOOL 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 VC1_SampleSpace(int);
extern ULONG VC2_SampleSpace(int); extern ULONG VC2_SampleSpace(int);
static ULONG (*VC_SampleSpace_ptr)(int);
extern ULONG VC1_SampleLength(int,SAMPLE*); extern ULONG VC1_SampleLength(int,SAMPLE*);
extern ULONG VC2_SampleLength(int,SAMPLE*); extern ULONG VC2_SampleLength(int,SAMPLE*);
extern ULONG VC1_VoiceRealVolume(UBYTE);
extern ULONG VC2_VoiceRealVolume(UBYTE);
#endif
#ifndef _IN_VIRTCH_
#ifndef NO_HQMIXER
extern int VC1_Init(void);
extern int VC2_Init(void);
static int (*VC_Init_ptr)(void)=VC1_Init;
static void (*VC_Exit_ptr)(void)=VC1_Exit;
extern int VC1_SetNumVoices(void);
extern int VC2_SetNumVoices(void);
static int (*VC_SetNumVoices_ptr)(void);
static ULONG (*VC_SampleSpace_ptr)(int);
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*); static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
extern BOOL VC1_PlayStart(void); extern int VC2_PlayStart(void);
extern BOOL VC2_PlayStart(void); static int (*VC_PlayStart_ptr)(void);
static BOOL (*VC_PlayStart_ptr)(void);
extern void VC1_PlayStop(void);
extern void VC2_PlayStop(void); extern void VC2_PlayStop(void);
static void (*VC_PlayStop_ptr)(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); static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
extern void VC1_SampleUnload(SWORD);
extern void VC2_SampleUnload(SWORD);
static void (*VC_SampleUnload_ptr)(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); 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); 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); static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
extern UWORD VC1_VoiceGetVolume(UBYTE);
extern UWORD VC2_VoiceGetVolume(UBYTE);
static UWORD (*VC_VoiceGetVolume_ptr)(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); static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
extern ULONG VC1_VoiceGetFrequency(UBYTE);
extern ULONG VC2_VoiceGetFrequency(UBYTE);
static ULONG (*VC_VoiceGetFrequency_ptr)(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); static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
extern ULONG VC1_VoiceGetPanning(UBYTE);
extern ULONG VC2_VoiceGetPanning(UBYTE);
static ULONG (*VC_VoiceGetPanning_ptr)(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); 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); static void (*VC_VoiceStop_ptr)(UBYTE);
extern BOOL VC1_VoiceStopped(UBYTE);
extern BOOL VC2_VoiceStopped(UBYTE);
static BOOL (*VC_VoiceStopped_ptr)(UBYTE); static BOOL (*VC_VoiceStopped_ptr)(UBYTE);
extern SLONG VC1_VoiceGetPosition(UBYTE);
extern SLONG VC2_VoiceGetPosition(UBYTE);
static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE); static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
extern ULONG VC1_VoiceRealVolume(UBYTE);
extern ULONG VC2_VoiceRealVolume(UBYTE);
static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE); static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
#if defined __STDC__ || defined _MSC_VER || defined MPW_C #if defined __STDC__ || defined _MSC_VER || defined MPW_C
@@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
#define VC_FUNC2(suffix,ret,typ1,typ2) \ #define VC_FUNC2(suffix,ret,typ1,typ2) \
MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); } MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
#else #else
#define VC_PROC0(suffix) \ #define VC_PROC0(suffix) \
MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); } MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
@@ -141,12 +149,12 @@ MIKMODAPI void VC_/**/suffix (typ1 a,typ2 b) { VC_/**/suffix/**/_ptr(a,b); }
MIKMODAPI ret VC_/**/suffix (typ1 a,typ2 b) { return VC_/**/suffix/**/_ptr(a,b); } MIKMODAPI ret VC_/**/suffix (typ1 a,typ2 b) { return VC_/**/suffix/**/_ptr(a,b); }
#endif #endif
VC_FUNC0(Init,BOOL) VC_FUNC0(Init,int)
VC_PROC0(Exit) VC_PROC0(Exit)
VC_FUNC0(SetNumVoices,BOOL) VC_FUNC0(SetNumVoices,int)
VC_FUNC1(SampleSpace,ULONG,int) VC_FUNC1(SampleSpace,ULONG,int)
VC_FUNC2(SampleLength,ULONG,int,SAMPLE*) VC_FUNC2(SampleLength,ULONG,int,SAMPLE*)
VC_FUNC0(PlayStart,BOOL) VC_FUNC0(PlayStart,int)
VC_PROC0(PlayStop) VC_PROC0(PlayStop)
VC_FUNC2(SampleLoad,SWORD,struct SAMPLOAD*,int) VC_FUNC2(SampleLoad,SWORD,struct SAMPLOAD*,int)
VC_PROC1(SampleUnload,SWORD) VC_PROC1(SampleUnload,SWORD)
@@ -159,8 +167,9 @@ VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
VC_PROC2(VoiceSetPanning,UBYTE,ULONG) VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
VC_FUNC1(VoiceGetPanning,ULONG,UBYTE) VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD 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_VoicePlay_ptr(a,b,c,d,e,f,g);
}
VC_PROC1(VoiceStop,UBYTE) VC_PROC1(VoiceStop,UBYTE)
VC_FUNC1(VoiceStopped,BOOL,UBYTE) VC_FUNC1(VoiceStopped,BOOL,UBYTE)
@@ -217,22 +226,25 @@ void VC_SetupPointers(void)
VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume; VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
} }
} }
#endif/* !NO_HQMIXER */
#else #else /* _IN_VIRTCH_ */
#ifndef _VIRTCH_COMMON_ #ifndef _VIRTCH_COMMON_
#define _VIRTCH_COMMON_ #define _VIRTCH_COMMON_
static ULONG samples2bytes(ULONG samples) static ULONG samples2bytes(ULONG samples)
{ {
if(vc_mode & DMODE_16BITS) samples <<= 1; if(vc_mode & DMODE_FLOAT) samples <<= 2;
else if(vc_mode & DMODE_16BITS) samples <<= 1;
if(vc_mode & DMODE_STEREO) samples <<= 1; if(vc_mode & DMODE_STEREO) samples <<= 1;
return samples; return samples;
} }
static ULONG bytes2samples(ULONG bytes) static ULONG bytes2samples(ULONG bytes)
{ {
if(vc_mode & DMODE_16BITS) bytes >>= 1; if(vc_mode & DMODE_FLOAT) bytes >>= 2;
else if(vc_mode & DMODE_16BITS) bytes >>= 1;
if(vc_mode & DMODE_STEREO) bytes >>= 1; if(vc_mode & DMODE_STEREO) bytes >>= 1;
return bytes; return bytes;
} }
@@ -244,7 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
todo=samples2bytes(bytes2samples(todo)); todo=samples2bytes(bytes2samples(todo));
/* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */ /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
if(vc_mode & DMODE_16BITS) if(vc_mode &(DMODE_16BITS|DMODE_FLOAT))
memset(buf,0,todo); memset(buf,0,todo);
else else
memset(buf,0x80,todo); memset(buf,0x80,todo);
@@ -270,9 +282,9 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
void VC1_Exit(void) void VC1_Exit(void)
{ {
if(vc_tickbuf) MikMod_free(vc_tickbuf); MikMod_free(vinf);
if(vinf) MikMod_free(vinf); MikMod_afree(vc_tickbuf);
if(Samples) MikMod_free(Samples); MikMod_afree(Samples);
vc_tickbuf = NULL; vc_tickbuf = NULL;
vinf = NULL; vinf = NULL;
@@ -324,7 +336,7 @@ BOOL VC1_VoiceStopped(UBYTE voice)
SLONG VC1_VoiceGetPosition(UBYTE voice) SLONG VC1_VoiceGetPosition(UBYTE voice)
{ {
return(vinf[voice].current>>FRACBITS); return (SLONG)(vinf[voice].current>>FRACBITS);
} }
void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) void VC1_VoiceSetVolume(UBYTE voice,UWORD vol)
@@ -347,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
void VC1_SampleUnload(SWORD handle) void VC1_SampleUnload(SWORD handle)
{ {
if (handle<MAXSAMPLEHANDLES) { if (Samples && (handle < MAXSAMPLEHANDLES)) {
if (Samples[handle]) MikMod_afree(Samples[handle]);
MikMod_free(Samples[handle]);
Samples[handle]=NULL; Samples[handle]=NULL;
} }
} }
@@ -358,10 +369,15 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
{ {
SAMPLE *s = sload->sample; SAMPLE *s = sload->sample;
int handle; int handle;
ULONG t, length,loopstart,loopend; ULONG t, length,loopstart,loopend,looplen;
if(type==MD_HARDWARE) return -1; 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 */ /* Find empty slot to put sample address in */
for(handle=0;handle<MAXSAMPLEHANDLES;handle++) for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
if(!Samples[handle]) break; if(!Samples[handle]) break;
@@ -384,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
SL_SampleSigned(sload); SL_SampleSigned(sload);
SL_Sample8to16(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; _mm_errno = MMERR_SAMPLE_TOO_BIG;
return -1; return -1;
} }
/* read sample into buffer */ /* 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; return -1;
}
/* Unclick sample */ /* Unclick sample */
if(s->flags & SF_LOOP) { if(s->flags & SF_LOOP) {
looplen = loopend - loopstart;/* handle short samples */
if(s->flags & SF_BIDI) 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]; Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
else else
for(t=0;t<16;t++) for(t=0;t<16 && t<looplen;t++)
Samples[handle][loopend+t]=Samples[handle][t+loopstart]; Samples[handle][loopend+t]=Samples[handle][t+loopstart];
} else } else
for(t=0;t<16;t++) for(t=0;t<16;t++)
@@ -410,15 +430,11 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
ULONG VC1_SampleSpace(int type) ULONG VC1_SampleSpace(int type)
{ {
(void)type; /* unused arg */
return vc_memory; return vc_memory;
} }
ULONG VC1_SampleLength(int type,SAMPLE* s) ULONG VC1_SampleLength(int type,SAMPLE* s)
{ {
(void)type; /* unused arg */
if (!s) return 0; if (!s) return 0;
return (s->length*((s->flags&SF_16BITS)?2:1))+16; return (s->length*((s->flags&SF_16BITS)?2:1))+16;
@@ -431,7 +447,7 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
SWORD *smp; SWORD *smp;
SLONG t; SLONG t;
t = vinf[voice].current>>FRACBITS; t = (SLONG)(vinf[voice].current>>FRACBITS);
if(!vinf[voice].active) return 0; if(!vinf[voice].active) return 0;
s = vinf[voice].handle; s = vinf[voice].handle;
@@ -452,8 +468,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
return abs(k-j); return abs(k-j);
} }
#endif #endif /* _VIRTCH_COMMON_ */
#endif #endif /* _IN_VIRTCH_ */
/* ex:set ts=4: */ /* ex:set ts=4: */