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
+37 -9
View File
@@ -9,25 +9,35 @@ libmikmod main authors
maintained MikMod version 3 until it was discontinued. He still works
on the WinAmp module plugin, roughly based on MikMod.
* 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.
* 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
-------------------------
* Steve McIntyre <steven@chiark.greenend.org.uk>
* Steve McIntyre <steve@einval.com>
maintained MikMod'Unix version 2. Used to maintain the Debian package
for MikMod.
* Peter Amstutz <tetron@student.umass.edu>
maintained MikMod'Unix version 3 up to version 3.0.3.
General contributors
--------------------
* Arne de Bruijn <arne@knoware.nl>
wrote the compressed IT sample support.
* Shlomi Fish <shlomif@vipe.technion.ac.il>
wrote the Java port, bug fixes.
* Shlomi Fish <shlomif@shlomifish.org>
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>
overall bug fixes.
* Claudio Matsuoka <claudio@helllabs.org>
@@ -48,6 +58,9 @@ General contributors
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>
ported MikMod to FreeBSD.
* Chris Conn <cconn@tohs.abacom.com>
@@ -84,6 +97,22 @@ Contributors on the Windows side
created the DirectSound driver.
* Bjornar Henden <bhenden@online.no>
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
----------------------------
@@ -108,7 +137,7 @@ Contributors on the Macintosh side
Contributors on the OS/2 side
-----------------------------
* Stefan Tibus <Stefan_Tibus@ThePentagon.com>
* Stefan Tibus <sjti@gmx.net>
ported libmikmod to OS/2.
* Andrew Zabolotny <bit@eltech.ru>
improved the existing OS/2 drivers.
@@ -119,6 +148,5 @@ Contributors on the BeOS side
* Thomas Neumann <tneumann@polycode.dk>
integrated libmikmod into his BeOS APlayer, and contributed many bug fixes.
--
If your name is missing, don't hesitate to remind me at
<miod@mikmod.org>
--
If your name is missing, don't hesitate to remind the current maintainer.
+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
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
mwav.c npertab.c sloader.c virtch.c virtch2.c virtch_common.c"
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.
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.
+5 -5
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -51,7 +51,7 @@ static BOOL NS_IsThere(void)
return 1;
}
static BOOL NS_Init(void)
static int NS_Init(void)
{
zerobuf=(SBYTE*)MikMod_malloc(ZEROLEN);
return VC_Init();
@@ -61,6 +61,7 @@ static void NS_Exit(void)
{
VC_Exit();
MikMod_free(zerobuf);
zerobuf=NULL;
}
static void NS_Update(void)
@@ -75,7 +76,7 @@ MIKMODAPI MDRIVER drv_nos={
"Nosound Driver v3.0",
255,255,
"nosound",
NULL,
NULL,
NS_IsThere,
VC_SampleLoad,
@@ -103,5 +104,4 @@ MIKMODAPI MDRIVER drv_nos={
VC_VoiceRealVolume
};
/* ex:set ts=4: */
+106 -76
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -34,7 +34,6 @@
#include <unistd.h>
#endif
#include <ctype.h>
#include <stdio.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -42,10 +41,10 @@
#include <string.h>
#include "mikmod_internals.h"
#include "mikmod_ctype.h"
#ifdef SUNOS
extern int fprintf(FILE *, const char *, ...);
extern int toupper(int);
#endif
/*========== Module structure */
@@ -67,7 +66,7 @@ typedef struct ITHEADER {
UBYTE initspeed;
UBYTE inittempo;
UBYTE pansep; /* panning separation between channels */
UBYTE zerobyte;
UBYTE zerobyte;
UWORD msglength;
ULONG msgoffset;
UBYTE blank02[4];
@@ -107,19 +106,19 @@ typedef struct ITINSTHEADER {
CHAR filename[12]; /* (char) Instrument filename */
UBYTE zerobyte; /* (byte) Instrument type (always 0) */
UBYTE volflg;
UBYTE volpts;
UBYTE volpts;
UBYTE volbeg; /* (byte) Volume loop start (node) */
UBYTE volend; /* (byte) Volume loop end (node) */
UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */
UBYTE volsusend; /* (byte) Volume Sustain end (node) */
UBYTE panflg;
UBYTE panpts;
UBYTE panpts;
UBYTE panbeg; /* (byte) channel loop start (node) */
UBYTE panend; /* (byte) channel loop end (node) */
UBYTE pansusbeg; /* (byte) channel sustain begin (node) */
UBYTE pansusend; /* (byte) channel Sustain end (node) */
UBYTE pitflg;
UBYTE pitpts;
UBYTE pitpts;
UBYTE pitbeg; /* (byte) pitch loop start (node) */
UBYTE pitend; /* (byte) pitch loop end (node) */
UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */
@@ -149,7 +148,7 @@ typedef struct ITINSTHEADER {
UWORD pantick[ITENVCNT]; /* tick value of panning nodes */
SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */
UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */
} ITINSTHEADER;
} ITINSTHEADER;
/* unpacked note */
@@ -166,8 +165,8 @@ static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */
static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
static int numtrk=0;
static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
static CHAR* IT_Version[]={
static const CHAR* IT_Version[]={
"ImpulseTracker . ",
"Compressed ImpulseTracker . ",
"ImpulseTracker 2.14p3",
@@ -177,11 +176,11 @@ static CHAR* IT_Version[]={
};
/* table for porta-to-note command within volume/panning column */
static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
static const UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
/*========== Loader code */
BOOL IT_Test(void)
static BOOL IT_Test(void)
{
UBYTE id[4];
@@ -190,7 +189,7 @@ BOOL IT_Test(void)
return 0;
}
BOOL IT_Init(void)
static BOOL IT_Init(void)
{
if(!(mh=(ITHEADER*)MikMod_malloc(sizeof(ITHEADER)))) return 0;
if(!(poslookup=(UBYTE*)MikMod_malloc(256*sizeof(UBYTE)))) return 0;
@@ -201,7 +200,7 @@ BOOL IT_Init(void)
return 1;
}
void IT_Cleanup(void)
static void IT_Cleanup(void)
{
FreeLinear();
@@ -212,40 +211,48 @@ void IT_Cleanup(void)
MikMod_free(last);
MikMod_free(paraptr);
MikMod_free(origpositions);
mh=NULL;
poslookup=NULL;
itpat=NULL;
mask=NULL;
last=NULL;
paraptr=NULL;
origpositions=NULL;
}
/* Because so many IT files have 64 channels as the set number used, but really
only use far less (usually from 8 to 24 still), I had to make this function,
which determines the number of channels that are actually USED by a pattern.
NOTE: You must first seek to the file location of the pattern before calling
this procedure.
Returns 1 on error
NOTE: You must first seek to the file location of the pattern before calling
this procedure.
Returns 0 on error
*/
static BOOL IT_GetNumChannels(UWORD patrows)
{
int row=0,flag,ch;
do {
if((flag=_mm_read_UBYTE(modreader))==EOF) {
if(_mm_eof(modreader)) {
_mm_errno=MMERR_LOADING_PATTERN;
return 1;
return 0;
}
flag=_mm_read_UBYTE(modreader);
if(!flag)
row++;
else {
ch=(flag-1)&63;
remap[ch]=0;
if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
if(mask[ch]&1) _mm_read_UBYTE(modreader);
if(mask[ch]&2) _mm_read_UBYTE(modreader);
if(mask[ch]&4) _mm_read_UBYTE(modreader);
if(mask[ch]&8) { _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); }
if(mask[ch]&1) _mm_skip_BYTE(modreader);
if(mask[ch]&2) _mm_skip_BYTE(modreader);
if(mask[ch]&4) _mm_skip_BYTE(modreader);
if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); }
}
} while(row<patrows);
return 0;
return 1;
}
static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
@@ -282,7 +289,7 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
/* process volume / panning column
volume / panning effects do NOT all share the same memory address
yet. */
if(volpan<=64)
if(volpan<=64)
UniVolEffect(VOL_VOLUME,volpan);
else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
UniVolEffect(VOL_VOLSLIDE,0);
@@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
static 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 *ite=&itpat[200*64 -1];
UBYTE *m;
memset(itt,255,200*64*sizeof(ITNOTE));
do {
if((flag=_mm_read_UBYTE(modreader))==EOF) {
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN;
return 0;
}
flag=_mm_read_UBYTE(modreader);
if(!flag) {
itt=&itt[of.numchn];
row++;
@@ -342,29 +353,38 @@ static BOOL IT_ReadPattern(UWORD patrows)
if(ch!=-1) {
n=&itt[ch];
l=&last[ch];
} else
m=&mask[ch];
if(n > ite) { /* malformed file */
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
} else
{
n=l=&dummy;
blah = 0;
m=(UBYTE*)&blah;
}
if(flag&128) mask[ch]=_mm_read_UBYTE(modreader);
if(mask[ch]&1)
if(flag&128) *m=_mm_read_UBYTE(modreader);
if(*m&1)
/* convert IT note off to internal note off */
if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
l->note=n->note=253;
if(mask[ch]&2)
if(*m&2)
l->ins=n->ins=_mm_read_UBYTE(modreader);
if(mask[ch]&4)
if(*m&4)
l->volpan=n->volpan=_mm_read_UBYTE(modreader);
if(mask[ch]&8) {
if(*m&8) {
l->cmd=n->cmd=_mm_read_UBYTE(modreader);
l->inf=n->inf=_mm_read_UBYTE(modreader);
}
if(mask[ch]&16)
if(*m&16)
n->note=l->note;
if(mask[ch]&32)
if(*m&32)
n->ins=l->ins;
if(mask[ch]&64)
if(*m&64)
n->volpan=l->volpan;
if(mask[ch]&128) {
if(*m&128) {
n->cmd=l->cmd;
n->inf=l->inf;
}
@@ -379,38 +399,38 @@ static BOOL IT_ReadPattern(UWORD patrows)
return 1;
}
static void LoadMidiString(MREADER* modreader,CHAR* dest)
static void LoadMidiString(MREADER* r,CHAR* dest)
{
CHAR *cur,*last;
CHAR *curp,*lastp;
_mm_read_UBYTES(dest,32,modreader);
cur=last=dest;
_mm_read_UBYTES(dest,32,r);
curp=lastp=dest;
/* remove blanks and uppercase all */
while(*last) {
if(isalnum((int)*last)) *(cur++)=toupper((int)*last);
last++;
while(*lastp) {
if(mik_isalnum((int)*lastp)) *(curp++)=mik_toupper((int)*lastp);
lastp++;
}
*cur=0;
*curp=0;
}
/* Load embedded midi information for resonant filters */
static void IT_LoadMidiConfiguration(MREADER* modreader)
static void IT_LoadMidiConfiguration(MREADER* r)
{
int i;
memset(filtermacros,0,sizeof(filtermacros));
memset(filtersettings,0,sizeof(filtersettings));
if (modreader) { /* information is embedded in file */
if (r) { /* information is embedded in file */
UWORD dat;
CHAR midiline[33];
dat=_mm_read_I_UWORD(modreader);
_mm_fseek(modreader,8*dat+0x120,SEEK_CUR);
dat=_mm_read_I_UWORD(r);
_mm_fseek(r,8*dat+0x120,SEEK_CUR);
/* read midi macros */
for(i=0;i<UF_MAXMACRO;i++) {
LoadMidiString(modreader,midiline);
LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1')))
filtermacros[i]=(midiline[5]-'0')|0x80;
@@ -418,7 +438,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
/* read standalone filters */
for(i=0x80;i<0x100;i++) {
LoadMidiString(modreader,midiline);
LoadMidiString(r,midiline);
if((!strncmp(midiline,"F0F00",5))&&
((midiline[5]=='0')||(midiline[5]=='1'))) {
filtersettings[i].filter=(midiline[5]-'0')|0x80;
@@ -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;
INSTRUMENT *d;
SAMPLE *q;
BOOL compressed=0;
/*BOOL compressed=0;*/
numtrk=0;
filters=0;
@@ -479,6 +499,10 @@ BOOL IT_Load(BOOL curious)
_mm_errno=MMERR_LOADING_HEADER;
return 0;
}
if(mh->ordnum > 256 || mh->insnum > 255 || mh->smpnum > 255 || mh->patnum > 255) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
/* set module variables */
of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
@@ -506,11 +530,11 @@ BOOL IT_Load(BOOL curious)
/* 2.16 : IT 2.14p3 with resonant filters */
/* 2.15 : IT 2.14p3 (improved compression) */
if((mh->cwt<=0x219)&&(mh->cwt>=0x217))
of.modtype=strdup(IT_Version[mh->cmwt<0x214?4:5]);
of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?4:5]);
else if (mh->cwt>=0x215)
of.modtype=strdup(IT_Version[mh->cmwt<0x214?2:3]);
of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?2:3]);
else {
of.modtype = strdup(IT_Version[mh->cmwt<0x214?0:1]);
of.modtype = MikMod_strdup(IT_Version[mh->cmwt<0x214?0:1]);
of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0';
of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
@@ -550,7 +574,7 @@ BOOL IT_Load(BOOL curious)
/* read the order data */
if(!AllocPositions(mh->ordnum)) return 0;
if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
for(t=0;t<mh->ordnum;t++) {
origpositions[t]=_mm_read_UBYTE(modreader);
@@ -672,14 +696,14 @@ BOOL IT_Load(BOOL curious)
if(s.flag&2) q->flags|=SF_16BITS;
if((s.flag&8)&&(mh->cwt>=0x214)) {
q->flags|=SF_ITPACKED;
compressed=1;
/*compressed=1;*/
}
if(s.flag&16) q->flags|=SF_LOOP;
if(s.flag&64) q->flags|=SF_BIDI;
if(mh->cwt>=0x200) {
if(s.convert&1) q->flags|=SF_SIGNED;
if(s.convert&4) q->flags|=SF_DELTA;
if(s.convert&4) q->flags|=SF_DELTA;
}
q++;
}
@@ -726,7 +750,7 @@ BOOL IT_Load(BOOL curious)
ih.trkvers = _mm_read_I_UWORD(modreader);
ih.numsmp = _mm_read_UBYTE(modreader);
_mm_read_UBYTE(modreader);
_mm_skip_BYTE(modreader);
_mm_read_string(ih.name,26,modreader);
_mm_read_UBYTES(ih.blank01,6,modreader);
_mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
@@ -736,13 +760,15 @@ BOOL IT_Load(BOOL curious)
for(lp=0;lp<ITENVCNT;lp++) {
ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
ih.volnode[lp] = _mm_read_UBYTE(modreader);
}
}
} else {
/* load IT 2xx volume, pan and pitch envelopes */
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
#define IT_LoadEnvelope(name,type) \
ih. name##flg =_mm_read_UBYTE(modreader); \
ih. name##pts =_mm_read_UBYTE(modreader); \
if (ih. name##pts > ITENVCNT) \
ih. name##pts = ITENVCNT; \
ih. name##beg =_mm_read_UBYTE(modreader); \
ih. name##end =_mm_read_UBYTE(modreader); \
ih. name##susbeg=_mm_read_UBYTE(modreader); \
@@ -751,11 +777,13 @@ BOOL IT_Load(BOOL curious)
ih. name##node[lp]=_mm_read_##type (modreader); \
ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
} \
_mm_read_UBYTE(modreader)
_mm_skip_BYTE(modreader)
#else
#define IT_LoadEnvelope(name,type) \
ih. name/**/flg =_mm_read_UBYTE(modreader); \
ih. name/**/pts =_mm_read_UBYTE(modreader); \
if (ih. name/**/pts > ITENVCNT) \
ih. name/**/pts = ITENVCNT; \
ih. name/**/beg =_mm_read_UBYTE(modreader); \
ih. name/**/end =_mm_read_UBYTE(modreader); \
ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
@@ -764,7 +792,7 @@ BOOL IT_Load(BOOL curious)
ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
} \
_mm_read_UBYTE(modreader)
_mm_skip_BYTE(modreader)
#endif
IT_LoadEnvelope(vol,UBYTE);
@@ -772,7 +800,7 @@ BOOL IT_Load(BOOL curious)
IT_LoadEnvelope(pit,SBYTE);
#undef IT_LoadEnvelope
}
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
@@ -791,10 +819,10 @@ BOOL IT_Load(BOOL curious)
if(ih.volflg&1) d->volflg|=EF_ON;
if(ih.volflg&2) d->volflg|=EF_LOOP;
if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
/* XM conversion of IT envelope Array */
d->volbeg = ih.volbeg;
d->volbeg = ih.volbeg;
d->volend = ih.volend;
d->volsusbeg = ih.volsusbeg;
d->volsusend = ih.volsusend;
@@ -807,7 +835,7 @@ BOOL IT_Load(BOOL curious)
d->volpts++;
} else
break;
}
}
} else {
d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2;
if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN;
@@ -862,6 +890,7 @@ BOOL IT_Load(BOOL curious)
#endif
IT_ProcessEnvelope(vol);
for(u=0;u<ih.volpts;u++)
d->volenv[u].val=(ih.volnode[u]<<2);
@@ -882,7 +911,7 @@ BOOL IT_Load(BOOL curious)
#ifdef MIKMOD_DEBUG
{
static int warn=0;
if(!warn)
fprintf(stderr, "\rFilter envelopes not supported yet\n");
warn=1;
@@ -903,7 +932,7 @@ BOOL IT_Load(BOOL curious)
}
}
d++;
d++;
}
} else if(of.flags & UF_LINEAR) {
if(!AllocInstruments()) return 0;
@@ -941,12 +970,12 @@ BOOL IT_Load(BOOL curious)
return 0;
}
_mm_read_I_ULONG(modreader);
if(IT_GetNumChannels(packlen)) return 0;
if(!IT_GetNumChannels(packlen)) return 0;
}
}
/* give each of them a different number */
for(t=0;t<UF_MAXCHAN;t++)
for(t=0;t<UF_MAXCHAN;t++)
if(!remap[t])
remap[t]=of.numchn++;
@@ -973,6 +1002,7 @@ BOOL IT_Load(BOOL curious)
} else {
_mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
packlen=_mm_read_I_UWORD(modreader);
(void)packlen; /* unused */
of.pattrows[t]=_mm_read_I_UWORD(modreader);
_mm_read_I_ULONG(modreader);
if(!IT_ReadPattern(of.pattrows[t])) return 0;
@@ -982,13 +1012,13 @@ BOOL IT_Load(BOOL curious)
return 1;
}
CHAR *IT_LoadTitle(void)
static CHAR *IT_LoadTitle(void)
{
CHAR s[26];
_mm_fseek(modreader,4,SEEK_SET);
if(!_mm_read_UBYTES(s,26,modreader)) return NULL;
return(DupStr(s,26,0));
}
+19 -17
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -34,7 +34,6 @@
#include <unistd.h>
#endif
#include <ctype.h>
#include <stdio.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -42,6 +41,7 @@
#include <string.h>
#include "mikmod_internals.h"
#include "mikmod_ctype.h"
#ifdef SUNOS
extern int fprintf(FILE *, const char *, ...);
@@ -108,10 +108,10 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
*numchn = 4;
return 1;
}
/* Star Tracker */
if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
(isdigit(id[3]))) {
(mik_isdigit(id[3]))) {
*descr = startrekker;
modtype = trekker = 1;
*numchn = id[3] - '0';
@@ -141,7 +141,7 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
}
/* Fasttracker */
if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) {
if ((!memcmp(id + 1, "CHN", 3)) && (mik_isdigit(id[0]))) {
*descr = fasttracker;
modtype = 1;
*numchn = id[0] - '0';
@@ -149,7 +149,7 @@ static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
}
/* Fasttracker or Taketracker */
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') {
*descr = fasttracker;
modtype = 2; /* this can also be Imago Orpheus */
@@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
mh=NULL;
patbuf=NULL;
}
/*
@@ -277,7 +279,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
/* Handle ``heavy'' volumes correctly */
if ((effect == 0xc) && (effdat > 0x40))
effdat = 0x40;
/* An isolated 100, 200 or 300 effect should be ignored (no
"standalone" porta memory in mod files). However, a sequence such
as 1XX, 100, 100, 100 is fine. */
@@ -288,7 +290,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
UniPTEffect(effect, effdat);
if (effect == 8)
of.flags |= UF_PANNING;
return effect;
}
@@ -315,7 +317,7 @@ static BOOL ML_LoadPatterns(void)
return 0;
if (!AllocTracks())
return 0;
/* Allocate temporary buffer for loading and converting the patterns */
if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
return 0;
@@ -323,7 +325,7 @@ static BOOL ML_LoadPatterns(void)
if (trekker && of.numchn == 8) {
/* Startrekker module dual pattern */
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].b = _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++)
if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4)))
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].b = _mm_read_UBYTE(modreader);
patbuf[s].c = _mm_read_UBYTE(modreader);
@@ -346,7 +348,7 @@ static BOOL ML_LoadPatterns(void)
/* Generic module pattern */
for (t = 0; t < of.numpat; t++) {
/* 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].b = _mm_read_UBYTE(modreader);
patbuf[s].c = _mm_read_UBYTE(modreader);
@@ -384,10 +386,10 @@ static BOOL MOD_Load(BOOL curious)
mh->songlength = _mm_read_UBYTE(modreader);
/* this fixes mods which declare more than 128 positions.
/* this fixes mods which declare more than 128 positions.
* eg: beatwave.mod */
if (mh->songlength > 128) { mh->songlength = 128; }
mh->magic1 = _mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->positions, 128, modreader);
_mm_read_UBYTES(mh->magic2, 4, modreader);
@@ -476,11 +478,11 @@ static BOOL MOD_Load(BOOL curious)
q++;
}
of.modtype = strdup(descr);
of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns())
return 0;
return 1;
}
+34 -24
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -104,7 +104,7 @@ static unsigned int tracker; /* tracker id */
/* tracker identifiers */
#define NUMTRACKERS 4
static CHAR* S3M_Version[] = {
static const CHAR * S3M_Version[] = {
"Screamtracker x.xx",
"Imago Orpheus x.xx (S3M format)",
"Impulse Tracker x.xx (S3M format)",
@@ -113,11 +113,11 @@ static CHAR* S3M_Version[] = {
"Impulse Tracker 2.14p4 (S3M format)"
};
/* version number position in above array */
static int numeric[NUMTRACKERS]={14,14,16,16};
static const int numeric[NUMTRACKERS]={14,14,16,16};
/*========== Loader code */
BOOL S3M_Test(void)
static BOOL S3M_Test(void)
{
UBYTE id[4];
@@ -127,7 +127,7 @@ BOOL S3M_Test(void)
return 0;
}
BOOL S3M_Init(void)
static BOOL S3M_Init(void)
{
if(!(s3mbuf=(S3MNOTE*)MikMod_malloc(32*64*sizeof(S3MNOTE)))) return 0;
if(!(mh=(S3MHEADER*)MikMod_malloc(sizeof(S3MHEADER)))) return 0;
@@ -137,13 +137,18 @@ BOOL S3M_Init(void)
return 1;
}
void S3M_Cleanup(void)
static void S3M_Cleanup(void)
{
MikMod_free(s3mbuf);
MikMod_free(paraptr);
MikMod_free(poslookup);
MikMod_free(mh);
MikMod_free(origpositions);
s3mbuf=NULL;
paraptr=NULL;
poslookup=NULL;
mh=NULL;
origpositions=NULL;
}
/* Because so many s3m files have 16 channels as the set number used, but really
@@ -154,9 +159,9 @@ void S3M_Cleanup(void)
global variable 'remap'
NOTE: You must first seek to the file location of the pattern before calling
this procedure.
this procedure.
Returns 1 on fail. */
Returns 0 on fail. */
static BOOL S3M_GetNumChannels(void)
{
int row=0,flag,ch;
@@ -166,19 +171,19 @@ static BOOL S3M_GetNumChannels(void)
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_PATTERN;
return 1;
return 0;
}
if(flag) {
ch=flag&31;
if(mh->channels[ch]<32) remap[ch] = 0;
if(flag&32) {_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);}
if(flag&64) _mm_read_UBYTE(modreader);
if(flag&128){_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);}
if(flag&32) {_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
if(flag&64) _mm_skip_BYTE(modreader);
if(flag&128){_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
} else row++;
}
return 0;
}
return 1;
}
static BOOL S3M_ReadPattern(void)
{
@@ -250,7 +255,7 @@ static UBYTE* S3M_ConvertTrack(S3MNOTE* tr)
return UniDup();
}
BOOL S3M_Load(BOOL curious)
static BOOL S3M_Load(BOOL curious)
{
int t,u,track = 0;
SAMPLE *q;
@@ -282,6 +287,10 @@ BOOL S3M_Load(BOOL curious)
_mm_errno = MMERR_LOADING_HEADER;
return 0;
}
if(mh->ordnum > 255 || mh->insnum > 255 || mh->patnum > 255) {
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
/* then we can decide the module type */
tracker=mh->tracker>>12;
@@ -294,7 +303,7 @@ BOOL S3M_Load(BOOL curious)
tracker=NUMTRACKERS; /* IT 2.14p3 */
else tracker--;
}
of.modtype = strdup(S3M_Version[tracker]);
of.modtype = MikMod_strdup(S3M_Version[tracker]);
if(tracker<NUMTRACKERS) {
of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0';
of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0';
@@ -315,7 +324,7 @@ BOOL S3M_Load(BOOL curious)
/* read the order data */
if(!AllocPositions(mh->ordnum)) return 0;
if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
for(t=0;t<mh->ordnum;t++) {
origpositions[t]=_mm_read_UBYTE(modreader);
@@ -374,7 +383,8 @@ BOOL S3M_Load(BOOL curious)
_mm_read_string(s.scrs,4,modreader);
/* ScreamTracker imposes a 64000 bytes (not 64k !) limit */
if (s.length > 64000)
/* enforce it, if we'll use S3MIT_SCREAM in S3M_ConvertTrack() */
if (s.length > 64000 && tracker == 1)
s.length = 64000;
if(_mm_eof(modreader)) {
@@ -388,7 +398,7 @@ BOOL S3M_Load(BOOL curious)
q->loopstart = s.loopbeg;
q->loopend = s.loopend;
q->volume = s.volume;
q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4;
q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4;
if(s.flags&1) q->flags |= SF_LOOP;
if(s.flags&4) q->flags |= SF_16BITS;
@@ -406,16 +416,16 @@ BOOL S3M_Load(BOOL curious)
for(t=0;t<of.numpat;t++) {
/* seek to pattern position (+2 skip pattern length) */
_mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET);
if(S3M_GetNumChannels()) return 0;
if(!S3M_GetNumChannels()) return 0;
}
/* build the remap array */
for(t=0;t<32;t++)
if(!remap[t])
if(!remap[t])
remap[t]=of.numchn++;
/* set panning positions after building remap chart! */
for(t=0;t<32;t++)
for(t=0;t<32;t++)
if((mh->channels[t]<32)&&(remap[t]!=-1)) {
if(mh->channels[t]<8)
of.panning[remap[t]]=0x30;
@@ -444,7 +454,7 @@ BOOL S3M_Load(BOOL curious)
return 1;
}
CHAR *S3M_LoadTitle(void)
static CHAR *S3M_LoadTitle(void)
{
CHAR s[28];
+24 -18
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -74,7 +74,7 @@ typedef struct STMHEADER {
UBYTE ver_minor;
UBYTE inittempo; /* initspeed= stm inittempo>>4 */
UBYTE numpat; /* number of patterns */
UBYTE globalvol;
UBYTE globalvol;
UBYTE reserved[13];
STMSAMPLE sample[31]; /* STM sample data */
UBYTE patorder[128]; /* Docs say 64 - actually 128 */
@@ -90,7 +90,7 @@ static STMNOTE *stmbuf = NULL;
static STMHEADER *mh = NULL;
/* tracker identifiers */
static CHAR* STM_Version[STM_NTRACKERS] = {
static const CHAR * STM_Version[STM_NTRACKERS] = {
"Screamtracker 2",
"Converted by MOD2STM (STM format)",
"Wuzamod (STM format)"
@@ -98,7 +98,7 @@ static CHAR* STM_Version[STM_NTRACKERS] = {
/*========== Loader code */
BOOL STM_Test(void)
static BOOL STM_Test(void)
{
UBYTE str[44];
int t;
@@ -110,7 +110,7 @@ BOOL STM_Test(void)
/* Prevent false positives for S3M files */
if(!memcmp(str+40,"SCRM",4))
return 0;
for (t=0;t<STM_NTRACKERS;t++)
if(!memcmp(str,STM_Signatures[t],8))
return 1;
@@ -118,7 +118,7 @@ BOOL STM_Test(void)
return 0;
}
BOOL STM_Init(void)
static BOOL STM_Init(void)
{
if(!(mh=(STMHEADER*)MikMod_malloc(sizeof(STMHEADER)))) 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(stmbuf);
mh=NULL;
stmbuf=NULL;
}
static void STM_ConvertNote(STMNOTE *n)
@@ -145,7 +147,7 @@ static void STM_ConvertNote(STMNOTE *n)
if((ins)&&(ins<32)) UniInstrument(ins-1);
/* special values of [SBYTE0] are handled here
/* special values of [SBYTE0] are handled here
we have no idea if these strange values will ever be encountered.
but it appears as those stms sound correct. */
if((note==254)||(note==252)) {
@@ -231,7 +233,7 @@ static BOOL STM_LoadPatterns(void)
/* Allocate temporary buffer for loading and converting the patterns */
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].insvol = _mm_read_UBYTE(modreader);
stmbuf[s].volcmd = _mm_read_UBYTE(modreader);
@@ -249,14 +251,12 @@ static BOOL STM_LoadPatterns(void)
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 */
SAMPLE *q;
(void)curious; /* unused arg */
/* try to read stm header */
_mm_read_string(mh->songname,20,modreader);
_mm_read_string(mh->trackername,8,modreader);
@@ -272,6 +272,10 @@ BOOL STM_Load(BOOL curious)
mh->numpat =_mm_read_UBYTE(modreader);
mh->globalvol =_mm_read_UBYTE(modreader);
_mm_read_UBYTES(mh->reserved,13,modreader);
if(mh->numpat > 128) {
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
for(t=0;t<31;t++) {
STMSAMPLE *s=&mh->sample[t]; /* STM sample data */
@@ -299,7 +303,7 @@ BOOL STM_Load(BOOL curious)
/* set module variables */
for(t=0;t<STM_NTRACKERS;t++)
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.numpat = mh->numpat;
of.inittempo = 125; /* mh->inittempo+0x1c; */
@@ -314,7 +318,10 @@ BOOL STM_Load(BOOL curious)
/* 99 terminates the patorder list */
while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) {
of.positions[t]=mh->patorder[t];
t++;
if(++t == 0x80) {
_mm_errno = MMERR_NOT_A_MODULE;
return 0;
}
}
if(mh->patorder[t]<=99) t++;
of.numpos=t;
@@ -332,7 +339,7 @@ BOOL STM_Load(BOOL curious)
q->speed = (mh->sample[t].c2spd * 8363) / 8448;
q->volume = mh->sample[t].volume;
q->length = mh->sample[t].length;
if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0;
if (/*!mh->sample[t].volume || */q->length==1) q->length=0;
q->loopstart = mh->sample[t].loopbeg;
q->loopend = mh->sample[t].loopend;
q->seekpos = MikMod_ISA;
@@ -349,7 +356,7 @@ BOOL STM_Load(BOOL curious)
return 1;
}
CHAR *STM_LoadTitle(void)
static CHAR *STM_LoadTitle(void)
{
CHAR s[20];
@@ -372,5 +379,4 @@ MIKMODAPI MLOADER load_stm={
STM_LoadTitle
};
/* ex:set ts=4: */
+76 -53
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -59,7 +59,7 @@ typedef struct XMHEADER {
UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */
UWORD numpat; /* Number of patterns (max 256) */
UWORD numins; /* Number of instruments (max 128) */
UWORD flags;
UWORD flags;
UWORD tempo; /* Default tempo */
UWORD bpm; /* Default BPM */
UBYTE orders[256]; /* Pattern order table */
@@ -136,7 +136,7 @@ static XMWAVHEADER *wh=NULL,*s=NULL;
/*========== Loader code */
BOOL XM_Test(void)
static BOOL XM_Test(void)
{
UBYTE id[38];
@@ -146,15 +146,16 @@ BOOL XM_Test(void)
return 0;
}
BOOL XM_Init(void)
static BOOL XM_Init(void)
{
if(!(mh=(XMHEADER *)MikMod_malloc(sizeof(XMHEADER)))) return 0;
return 1;
}
void XM_Cleanup(void)
static void XM_Cleanup(void)
{
MikMod_free(mh);
mh=NULL;
}
static int XM_ReadNote(XMNOTE* n)
@@ -359,8 +360,8 @@ static BOOL LoadPatterns(BOOL dummypat)
return 0;
/* when packsize is 0, don't try to load a pattern.. it's empty. */
if(ph.packsize)
for(u=0;u<ph.numrows;u++)
if(ph.packsize)
for(u=0;u<ph.numrows;u++)
for(v=0;v<of.numchn;v++) {
if(!ph.packsize) break;
@@ -443,11 +444,17 @@ static void FixEnvelope(ENVPT *cur, int pts)
static BOOL LoadInstruments(void)
{
long filend,ck;
int t,u;
INSTRUMENT *d;
ULONG next=0;
UWORD wavcnt=0;
ck = _mm_ftell(modreader);
_mm_fseek(modreader,0,SEEK_END);
filend = _mm_ftell(modreader);
_mm_fseek(modreader,ck,SEEK_SET);
if(!AllocInstruments()) return 0;
d=of.instruments;
for(t=0;t<of.numins;t++,d++) {
@@ -460,6 +467,10 @@ static BOOL LoadInstruments(void)
headend = _mm_ftell(modreader);
ih.size = _mm_read_I_ULONG(modreader);
headend += ih.size;
ck = _mm_ftell(modreader);
if ((headend<0) || (filend<headend) || (headend<ck)) {
break;
}
_mm_read_string(ih.name, 22, modreader);
ih.type = _mm_read_UBYTE(modreader);
ih.numsmp = _mm_read_I_UWORD(modreader);
@@ -493,7 +504,11 @@ static BOOL LoadInstruments(void)
/* read the remainder of the header
(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
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((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
if(wh) { MikMod_free(wh);wh=NULL; }
MikMod_free(nextwav);nextwav=NULL;
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@@ -553,7 +568,7 @@ static BOOL LoadInstruments(void)
\
if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
d-> name/**/flg&=~EF_ON
#endif
#endif
XM_ProcessEnvelope(vol);
XM_ProcessEnvelope(pan);
@@ -570,15 +585,23 @@ static BOOL LoadInstruments(void)
everything over */
if(mh->version>0x0103) next = 0;
for(u=0;u<ih.numsmp;u++,s++) {
/* XM sample header is 40 bytes: make sure we won't hit EOF */
/* Note: last instrument is at the end of file in version 0x0104 */
if(_mm_ftell(modreader)+40>filend) {
MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
/* Allocate more room for sample information if necessary */
if(of.numsmp+u==wavcnt) {
wavcnt+=XM_SMPINCR;
if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
if(wh) { MikMod_free(wh);wh=NULL; }
if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY;
return 0;
}
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
MikMod_free(nextwav);nextwav=NULL;
_mm_errno = MMERR_OUT_OF_MEMORY;
return 0;
@@ -603,13 +626,6 @@ static BOOL LoadInstruments(void)
nextwav[of.numsmp+u]=next;
next+=s->length;
if(_mm_eof(modreader)) {
MikMod_free(nextwav);MikMod_free(wh);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
}
if(mh->version>0x0103) {
@@ -620,9 +636,16 @@ static BOOL LoadInstruments(void)
of.numsmp+=ih.numsmp;
} else {
/* 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);
nextwav=NULL;wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
@@ -634,8 +657,8 @@ static BOOL LoadInstruments(void)
/* sanity check */
if(!of.numsmp) {
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
if(wh) { MikMod_free(wh);wh=NULL; }
MikMod_free(nextwav);nextwav=NULL;
MikMod_free(wh);wh=NULL;
_mm_errno = MMERR_LOADING_SAMPLEINFO;
return 0;
}
@@ -643,7 +666,7 @@ static BOOL LoadInstruments(void)
return 1;
}
BOOL XM_Load(BOOL curious)
static BOOL XM_Load(BOOL curious)
{
INSTRUMENT *d;
SAMPLE *q;
@@ -651,17 +674,13 @@ BOOL XM_Load(BOOL curious)
BOOL dummypat=0;
char tracker[21],modtype[60];
(void)curious; /* unused arg */
/* try to read module header */
_mm_read_string(mh->id,17,modreader);
_mm_read_string(mh->songname,21,modreader);
_mm_read_string(mh->trackername,20,modreader);
mh->version =_mm_read_I_UWORD(modreader);
if((mh->version<0x102)||(mh->version>0x104)) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
if(mh->version < 0x102 || mh->version > 0x104)
goto bad_xm;
mh->headersize =_mm_read_I_ULONG(modreader);
mh->songlength =_mm_read_I_UWORD(modreader);
mh->restart =_mm_read_I_UWORD(modreader);
@@ -671,23 +690,25 @@ BOOL XM_Load(BOOL curious)
mh->flags =_mm_read_I_UWORD(modreader);
mh->tempo =_mm_read_I_UWORD(modreader);
mh->bpm =_mm_read_I_UWORD(modreader);
if(!mh->bpm) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
_mm_read_UBYTES(mh->orders,256,modreader);
if(_mm_eof(modreader)) {
_mm_errno = MMERR_LOADING_HEADER;
return 0;
}
if(mh->numchn > 64) goto bad_xm;
if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255)
goto bad_xm;
if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256)
goto bad_xm;
if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255)
goto bad_xm;
/* _mm_read_UBYTES(mh->orders,256,modreader);*/
/* _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/
_mm_read_UBYTES(mh->orders,mh->songlength,modreader);
if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader))
goto bad_hdr;
/* set module variables */
of.initspeed = mh->tempo;
of.initspeed = mh->tempo;
of.inittempo = mh->bpm;
strncpy(tracker,mh->trackername,20);tracker[20]=0;
for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0;
for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0;
/* some modules have the tracker name empty */
if (!tracker[0])
strcpy(tracker,"Unknown tracker");
@@ -699,7 +720,7 @@ BOOL XM_Load(BOOL curious)
sprintf(modtype,"%s (XM format %d.%02d)",
tracker,mh->version>>8,mh->version&0xff);
#endif
of.modtype = strdup(modtype);
of.modtype = MikMod_strdup(modtype);
of.numchn = mh->numchn;
of.numpat = mh->numpat;
of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */
@@ -707,8 +728,7 @@ BOOL XM_Load(BOOL curious)
of.numpos = mh->songlength; /* copy the songlength */
of.reppos = mh->restart<mh->songlength?mh->restart:0;
of.numins = mh->numins;
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS |
UF_PANNING;
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING;
if(mh->flags&1) of.flags |= UF_LINEAR;
of.bpmlimit = 32;
@@ -789,16 +809,19 @@ BOOL XM_Load(BOOL curious)
MikMod_free(wh);MikMod_free(nextwav);
wh=NULL;nextwav=NULL;
return 1;
bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0;
bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0;
}
CHAR *XM_LoadTitle(void)
static CHAR *XM_LoadTitle(void)
{
CHAR s[21];
CHAR str[21];
_mm_fseek(modreader,17,SEEK_SET);
if(!_mm_read_UBYTES(s,21,modreader)) return NULL;
if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
return(DupStr(s,21,1));
return(DupStr(str,21,1));
}
/*========== Loader information */
+6 -10
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -20,24 +20,20 @@
/*==============================================================================
$Id$
Routine for registering all drivers in libmikmod for the current platform.
==============================================================================*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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);
}
void MikMod_RegisterAllDrivers(void)
MIKMODAPI void MikMod_RegisterAllDrivers(void)
{
MUTEX_LOCK(lists);
_mm_registeralldrivers();
+123 -87
View File
@@ -1,17 +1,17 @@
/* MikMod sound library
(c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
for complete list.
(c) 1998-2014 Miodrag Vallat and others - see file AUTHORS
for a complete list.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -20,8 +20,6 @@
/*==============================================================================
$Id$
These routines are used to access the available soundcard drivers.
==============================================================================*/
@@ -34,54 +32,62 @@
#include <unistd.h>
#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>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include "mikmod_internals.h"
#if (MIKMOD_UNIX)
#include <pwd.h>
#include <sys/stat.h>
#endif
#ifdef SUNOS
extern int fprintf(FILE *, const char *, ...);
#endif
static MDRIVER *firstdriver=NULL;
MIKMODAPI MDRIVER *md_driver=NULL;
/* UQM mod: include the UQM file that manages stricmp vs strcasecmp. */
#include "port.h"
extern MODULE *pf; /* modfile being played */
/* EXPORTED GLOBALS */
MIKMODAPI MDRIVER *md_driver = NULL;
/* Initial global settings */
MIKMODAPI UWORD md_device = 0; /* autodetect */
MIKMODAPI UWORD md_mixfreq = 44100;
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
DMODE_SURROUND |DMODE_SOFT_MUSIC |
DMODE_SOFT_SNDFX;
MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
UWORD md_bpm = 125; /* tempo */
MIKMODAPI UWORD md_device = 0; /* autodetect */
MIKMODAPI UWORD md_mixfreq = 44100;
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
DMODE_SURROUND |
DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
/* Do not modify the numchn variables yourself! use MD_SetVoices() */
UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0;
UBYTE md_hardchn=0,md_softchn=0;
/* INTERNAL GLOBALS */
UWORD md_bpm = 125; /* tempo */
void (*md_player)(void) = Player_HandleTick;
static BOOL isplaying=0, initialized = 0;
static UBYTE *sfxinfo;
static int sfxpool;
/* 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;
static SAMPLE **md_sample = NULL;
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;
static UBYTE *sfxinfo;
static int sfxpool;
static SAMPLE **md_sample = NULL;
/* Previous driver in use */
static SWORD olddevice = -1;
static SWORD olddevice = -1;
/* Limits the number of hardware voices to the specified amount.
This function should only be used by the low-level drivers. */
@@ -183,17 +189,18 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void)
MUTEX_LOCK(lists);
/* compute size of buffer */
for(l=firstdriver;l;l=l->next)
len+=4+(l->next?1:0)+strlen(l->Version);
for(l = firstdriver; l; l = l->next)
len += 4 + (l->next ? 1 : 0) + strlen(l->Version);
if(len)
if((list=MikMod_malloc(len*sizeof(CHAR)))) {
list[0]=0;
/* list all registered device drivers : */
for(t=1,l=firstdriver;l;l=l->next,t++)
sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s",
list,t,l->Version);
if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
CHAR *list_end = list;
list[0] = 0;
/* list all registered device drivers : */
for(t = 1, l = firstdriver; l; l = l->next, t++) {
list_end += sprintf(list_end, "%2d %s%s", t, l->Version, (l->next)? "\n" : "");
}
}
MUTEX_UNLOCK(lists);
return list;
}
@@ -205,10 +212,16 @@ void _mm_registerdriver(struct MDRIVER* drv)
/* don't register a MISSING() driver */
if ((drv->Name) && (drv->Version)) {
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;
} else
firstdriver = drv;
firstdriver = drv;
}
}
@@ -224,7 +237,7 @@ MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv)
MUTEX_UNLOCK(lists);
}
MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
MIKMODAPI int MikMod_DriverFromAlias(const CHAR *alias)
{
int rank=1;
MDRIVER *cruise;
@@ -244,6 +257,21 @@ MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
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 result;
@@ -474,7 +502,12 @@ MIKMODAPI ULONG Voice_RealVolume(SBYTE voice)
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;
@@ -532,9 +565,9 @@ static BOOL _mm_init(CHAR *cmdline)
return 0;
}
MIKMODAPI BOOL MikMod_Init(CHAR *cmdline)
MIKMODAPI int MikMod_Init(const CHAR *cmdline)
{
BOOL result;
int result;
MUTEX_LOCK(vars);
MUTEX_LOCK(lists);
@@ -552,8 +585,8 @@ void MikMod_Exit_internal(void)
md_numchn = md_sfxchn = md_sngchn = 0;
md_driver = &drv_nos;
if(sfxinfo) MikMod_free(sfxinfo);
if(md_sample) MikMod_free(md_sample);
MikMod_free(sfxinfo);
MikMod_free(md_sample);
md_sample = NULL;
sfxinfo = NULL;
@@ -569,14 +602,14 @@ MIKMODAPI void MikMod_Exit(void)
MUTEX_UNLOCK(vars);
}
/* Reset the driver using the new global variable settings.
/* Reset the driver using the new global variable settings.
If the driver has not been initialized, it will be now. */
static BOOL _mm_reset(CHAR *cmdline)
static int _mm_reset(const CHAR *cmdline)
{
BOOL wasplaying = 0;
if(!initialized) return _mm_init(cmdline);
if (isplaying) {
wasplaying = 1;
md_driver->PlayStop();
@@ -600,14 +633,14 @@ static BOOL _mm_reset(CHAR *cmdline)
return 1;
}
}
if (wasplaying) md_driver->PlayStart();
if (wasplaying) return md_driver->PlayStart();
return 0;
}
MIKMODAPI BOOL MikMod_Reset(CHAR *cmdline)
MIKMODAPI int MikMod_Reset(const CHAR *cmdline)
{
BOOL result;
int result;
MUTEX_LOCK(vars);
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. */
BOOL MikMod_SetNumVoices_internal(int music, int sfx)
int MikMod_SetNumVoices_internal(int music, int sfx)
{
BOOL resume = 0;
int t, oldchn = 0;
@@ -632,8 +665,8 @@ BOOL MikMod_SetNumVoices_internal(int music, int sfx)
resume = 1;
}
if(sfxinfo) MikMod_free(sfxinfo);
if(md_sample) MikMod_free(md_sample);
MikMod_free(sfxinfo);
MikMod_free(md_sample);
md_sample = NULL;
sfxinfo = NULL;
@@ -667,9 +700,9 @@ BOOL MikMod_SetNumVoices_internal(int music, int sfx)
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);
result=MikMod_SetNumVoices_internal(music,sfx);
@@ -678,7 +711,7 @@ MIKMODAPI BOOL MikMod_SetNumVoices(int music, int sfx)
return result;
}
BOOL MikMod_EnableOutput_internal(void)
int MikMod_EnableOutput_internal(void)
{
_mm_critical = 1;
if(!isplaying) {
@@ -689,9 +722,9 @@ BOOL MikMod_EnableOutput_internal(void)
return 0;
}
MIKMODAPI BOOL MikMod_EnableOutput(void)
MIKMODAPI int MikMod_EnableOutput(void)
{
BOOL result;
int result;
MUTEX_LOCK(vars);
result=MikMod_EnableOutput_internal();
@@ -735,8 +768,8 @@ MIKMODAPI BOOL MikMod_Active(void)
allocated for use as sound effects (loops through voices, skipping all active
criticals).
Returns the voice that the sound is being played on. */
SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags)
Returns the voice that the sound is being played on. */
static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags)
{
int orig=sfxpool;/* for cases where all channels are critical */
int c;
@@ -796,12 +829,15 @@ MIKMODAPI long MikMod_GetVersion(void)
#ifdef HAVE_PTHREAD
#define INIT_MUTEX(name) \
pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER
#elif defined(__OS2__)||defined(__EMX__)
#define INIT_MUTEX(name) \
HMTX _mm_mutex_##name
#elif defined(WIN32)
#elif defined(_WIN32)
#define INIT_MUTEX(name) \
HANDLE _mm_mutex_##name
#else
#define INIT_MUTEX(name) \
void *_mm_mutex_##name = NULL
@@ -813,8 +849,8 @@ INIT_MUTEX(lists);
MIKMODAPI BOOL MikMod_InitThreads(void)
{
static int firstcall=1;
static int result=0;
static BOOL result = 0;
if (firstcall) {
firstcall=0;
#ifdef HAVE_PTHREAD
@@ -826,9 +862,9 @@ MIKMODAPI BOOL MikMod_InitThreads(void)
result=0;
} else
result=1;
#elif defined(WIN32)
if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))||
(!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)"))))
#elif defined(_WIN32)
if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,TEXT("libmikmod(lists)"))))||
(!(_mm_mutex_vars=CreateMutex(NULL,FALSE,TEXT("libmikmod(vars)")))))
result=0;
else
result=1;
@@ -851,24 +887,24 @@ MIKMODAPI void MikMod_Lock(void)
/*========== 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;
if(cmdline) {
CHAR *buf=strstr(cmdline,atomname);
const CHAR *buf=strstr(cmdline,atomname);
if((buf)&&((buf==cmdline)||(*(buf-1)==','))) {
CHAR *ptr=buf+strlen(atomname);
const CHAR *ptr=buf+strlen(atomname);
if(*ptr=='=') {
for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++);
ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
if(ret)
strncpy(ret,buf,ptr-buf);
} else if((*ptr==',')||(!*ptr)) {
if(implicit) {
ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
if(ret)
strncpy(ret,buf,ptr-buf);
}
@@ -878,7 +914,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,BOOL implicit)
return ret;
}
#if defined unix || (defined __APPLE__ && defined __MACH__)
#if (MIKMOD_UNIX)
/*========== 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.
The goal is to prevent a setuid root libmikmod application from overriding
files like /etc/passwd with digital sound... */
BOOL MD_Access(CHAR *filename)
BOOL MD_Access(const CHAR * filename)
{
struct stat buf;
@@ -904,12 +940,12 @@ BOOL MD_Access(CHAR *filename)
} else
if(!(buf.st_mode&S_IWOTH)) return 0;
}
return 1;
}
/* Drop all root privileges we might have */
BOOL MD_DropPrivileges(void)
int MD_DropPrivileges(void)
{
if(!geteuid()) {
if(getuid()) {
@@ -932,4 +968,4 @@ BOOL MD_DropPrivileges(void)
#endif
/* ex:set ts=4: */
/* ex:set ts=8: */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+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 */
File diff suppressed because it is too large Load Diff
+174 -115
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -45,12 +45,16 @@
extern int fprintf(FILE *, const char *, ...);
#endif
MREADER *modreader;
MODULE of;
MREADER *modreader;
MODULE of;
static MLOADER *firstloader=NULL;
UWORD finetune[16]={
static MUNPACKER unpackers[] = {
NULL
};
const UWORD finetune[16] = {
8363,8413,8463,8529,8581,8651,8723,8757,
7895,7941,7985,8046,8107,8169,8232,8280
};
@@ -63,15 +67,18 @@ MIKMODAPI CHAR* MikMod_InfoLoader(void)
MUTEX_LOCK(lists);
/* compute size of buffer */
for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version);
for(l = firstloader; l; l = l->next)
len += 1 + (l->next ? 1 : 0) + strlen(l->version);
if(len)
if((list=MikMod_malloc(len*sizeof(CHAR)))) {
list[0]=0;
/* list all registered module loders */
for(l=firstloader;l;l=l->next)
sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version);
if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
CHAR *list_end = list;
list[0] = 0;
/* list all registered module loders */
for(l = firstloader; l; l = l->next) {
list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
}
}
MUTEX_UNLOCK(lists);
return list;
}
@@ -84,7 +91,7 @@ void _mm_registerloader(MLOADER* ldr)
while(cruise->next) cruise = cruise->next;
cruise->next=ldr;
} else
firstloader=ldr;
firstloader=ldr;
}
MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr)
@@ -106,7 +113,7 @@ BOOL ReadComment(UWORD len)
if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0;
_mm_read_UBYTES(of.comment,len,modreader);
/* translate IT linefeeds */
for(i=0;i<len;i++)
if(of.comment[i]=='\r') of.comment[i]='\n';
@@ -122,44 +129,44 @@ BOOL ReadComment(UWORD len)
BOOL ReadLinedComment(UWORD len,UWORD linelen)
{
CHAR *tempcomment,*line,*storage;
UWORD total=0,t,lines;
int i;
/* Adapted from the OpenMPT project, C'ified. */
CHAR *buf, *storage, *p;
size_t numlines, line, fpos, cpos, lpos, cnt;
lines = (len + linelen - 1) / linelen;
if (len) {
if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0;
if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) {
MikMod_free(tempcomment);
return 0;
}
memset(tempcomment, ' ', len);
_mm_read_UBYTES(tempcomment,len,modreader);
if (!linelen) return 0;
if (!len) return 1;
/* compute message length */
for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) {
for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0;
for(i=0;i<linelen;i++) if (!line[i]) break;
total+=1+i;
}
if (!(buf = (CHAR *) MikMod_malloc(len))) return 0;
numlines = (len + linelen - 1) / linelen;
cnt = (linelen + 1) * numlines;
if (!(storage = (CHAR *) MikMod_malloc(cnt + 1))) {
MikMod_free(buf);
return 0;
}
if(total>lines) {
if(!(of.comment=(CHAR*)MikMod_malloc(total+1))) {
MikMod_free(storage);
MikMod_free(tempcomment);
return 0;
_mm_read_UBYTES(buf,len,modreader);
storage[cnt] = 0;
for (line = 0, fpos = 0, cpos = 0; line < numlines; line++, fpos += linelen, cpos += (linelen + 1))
{
cnt = len - fpos;
if (cnt > linelen) cnt = linelen;
p = storage + cpos;
memcpy(p, buf + fpos, cnt);
p[cnt] = '\r';
/* fix weird chars */
for (lpos = 0; lpos < linelen; lpos++, p++) {
switch (*p) {
case '\0':
case '\n':
case '\r':
*p = ' ';
break;
}
/* convert message */
for(line=tempcomment,t=0;t<lines;t++,line+=linelen) {
for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break;
storage[i]=0; /* if (i==linelen) */
strcat(of.comment,storage);strcat(of.comment,"\r");
}
MikMod_free(storage);
MikMod_free(tempcomment);
}
}
of.comment = storage;
MikMod_free(buf);
return 1;
}
@@ -169,7 +176,7 @@ BOOL AllocPositions(int total)
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
}
if(!(of.positions=MikMod_calloc(total,sizeof(UWORD)))) return 0;
if(!(of.positions=(UWORD*)MikMod_calloc(total,sizeof(UWORD)))) return 0;
return 1;
}
@@ -207,7 +214,7 @@ BOOL AllocTracks(void)
BOOL AllocInstruments(void)
{
int t,n;
if(!of.numins) {
_mm_errno=MMERR_NOT_A_MODULE;
return 0;
@@ -216,11 +223,11 @@ BOOL AllocInstruments(void)
return 0;
for(t=0;t<of.numins;t++) {
for(n=0;n<INSTNOTES;n++) {
for(n=0;n<INSTNOTES;n++) {
/* Init note / sample lookup table */
of.instruments[t].samplenote[n] = n;
of.instruments[t].samplenumber[n] = t;
}
}
of.instruments[t].globvol = 64;
}
return 1;
@@ -257,8 +264,8 @@ static BOOL ML_LoadSamples(void)
}
/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any
terminating non-printing characters like 0, spaces etc. */
CHAR *DupStr(CHAR* s,UWORD len,BOOL strict)
terminating non-printing characters like 0, spaces etc. */
CHAR *DupStr(const CHAR* s, UWORD len, BOOL strict)
{
UWORD t;
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
buffer into that string, except for any control-chars */
if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1)))) {
if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1))) != NULL) {
for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t];
d[len]=0;
}
@@ -288,29 +295,31 @@ static void ML_XFreeSample(SAMPLE *s)
{
if(s->handle>=0)
MD_SampleUnload(s->handle);
if(s->samplename) MikMod_free(s->samplename);
/* moved samplename freeing to our caller ML_FreeEx(),
* because we are called conditionally. */
}
static void ML_XFreeInstrument(INSTRUMENT *i)
{
if(i->insname) MikMod_free(i->insname);
MikMod_free(i->insname);
}
static void ML_FreeEx(MODULE *mf)
{
UWORD t;
if(mf->songname) MikMod_free(mf->songname);
if(mf->comment) MikMod_free(mf->comment);
MikMod_free(mf->songname);
MikMod_free(mf->comment);
if(mf->modtype) MikMod_free(mf->modtype);
if(mf->positions) MikMod_free(mf->positions);
if(mf->patterns) MikMod_free(mf->patterns);
if(mf->pattrows) MikMod_free(mf->pattrows);
MikMod_free(mf->modtype);
MikMod_free(mf->positions);
MikMod_free(mf->patterns);
MikMod_free(mf->pattrows);
if(mf->tracks) {
for(t=0;t<mf->numtrk;t++)
if(mf->tracks[t]) MikMod_free(mf->tracks[t]);
MikMod_free(mf->tracks[t]);
MikMod_free(mf->tracks);
}
if(mf->instruments) {
@@ -319,8 +328,10 @@ static void ML_FreeEx(MODULE *mf)
MikMod_free(mf->instruments);
}
if(mf->samples) {
for(t=0;t<mf->numsmp;t++)
for(t=0;t<mf->numsmp;t++) {
MikMod_free(mf->samples[t].samplename);
if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]);
}
MikMod_free(mf->samples);
}
memset(mf,0,sizeof(MODULE));
@@ -329,12 +340,24 @@ static void ML_FreeEx(MODULE *mf)
static MODULE *ML_AllocUniMod(void)
{
MODULE *mf;
return (mf=MikMod_malloc(sizeof(MODULE)));
return (MODULE *) MikMod_malloc(sizeof(MODULE));
}
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) {
Player_Exit_internal(mf);
@@ -352,25 +375,44 @@ MIKMODAPI void Player_Free(MODULE *mf)
static CHAR* Player_LoadTitle_internal(MREADER *reader)
{
MLOADER *l;
CHAR *title;
void *unpk;
long newlen;
modreader=reader;
_mm_errno = 0;
_mm_critical = 0;
_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 */
for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader);
if(l->Test()) break;
}
if(!l) {
if(l) {
title = l->LoadTitle();
}
else {
_mm_errno = MMERR_NOT_A_MODULE;
if(_mm_errorhandler) _mm_errorhandler();
return NULL;
title = NULL;
}
return l->LoadTitle();
if (modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
return title;
}
MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp)
@@ -378,7 +420,7 @@ MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp)
CHAR* result=NULL;
MREADER* reader;
if(fp && (reader=_mm_new_file_reader(fp))) {
if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
@@ -392,22 +434,22 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
CHAR *result=NULL;
MREADER* reader;
if ((reader=_mm_new_mem_reader(buffer,len)))
if (!buffer || len <= 0) return NULL;
if ((reader=_mm_new_mem_reader(buffer,len)) != NULL)
{
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
_mm_delete_mem_reader(reader);
}
return result;
}
MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
{
{
CHAR *result=NULL;
if (reader) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
@@ -416,14 +458,14 @@ MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
return result;
}
MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename)
MIKMODAPI CHAR* Player_LoadTitle(const CHAR* filename)
{
CHAR* result=NULL;
FILE* fp;
MREADER* reader;
if((fp=_mm_fopen(filename,"rb"))) {
if((reader=_mm_new_file_reader(fp))) {
if((fp=_mm_fopen(filename,"rb")) != NULL) {
if((reader=_mm_new_file_reader(fp)) != NULL) {
MUTEX_LOCK(lists);
result=Player_LoadTitle_internal(reader);
MUTEX_UNLOCK(lists);
@@ -435,18 +477,28 @@ MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename)
}
/* 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;
MLOADER *l;
BOOL ok;
MODULE *mf;
void *unpk;
long newlen;
modreader = reader;
_mm_errno = 0;
_mm_critical = 0;
_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 */
for(l=firstloader;l;l=l->next) {
_mm_rewind(modreader);
@@ -455,15 +507,27 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if(!l) {
_mm_errno = MMERR_NOT_A_MODULE;
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL;
}
/* init unitrk routines */
if(!UniInit()) {
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL;
}
@@ -479,7 +543,7 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if (!l->Init || l->Init()) {
_mm_rewind(modreader);
ok = l->Load(curious);
if (ok) {
if (ok) {
/* propagate inflags=flags for in-module samples */
for (t = 0; t < of.numsmp; t++)
if (of.samples[t].inflags == 0)
@@ -492,27 +556,21 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if (l->Cleanup) l->Cleanup();
UniCleanup();
if(ok) ok = ML_LoadSamples();
if(ok) ok = ((mf=ML_AllocUniMod()) != NULL);
if(!ok) {
ML_FreeEx(&of);
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL;
}
if(!ML_LoadSamples()) {
ML_FreeEx(&of);
if(_mm_errorhandler) _mm_errorhandler();
_mm_rewind(modreader);_mm_iobase_revert(modreader);
return NULL;
}
if(!(mf=ML_AllocUniMod())) {
ML_FreeEx(&of);
_mm_rewind(modreader);_mm_iobase_revert(modreader);
if(_mm_errorhandler) _mm_errorhandler();
return NULL;
}
/* If the module doesn't have any specific panning, create a
MOD-like panning, with the channels half-separated. */
if (!(of.flags & UF_PANNING))
@@ -531,23 +589,23 @@ MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious)
if(maxchan<mf->numchn) mf->flags |= UF_NNA;
if(MikMod_SetNumVoices_internal(maxchan,-1)) {
_mm_iobase_revert(modreader);
Player_Free(mf);
return NULL;
}
ok = !MikMod_SetNumVoices_internal(maxchan,-1);
}
if(SL_LoadSamples()) {
_mm_iobase_revert(modreader);
if(ok) ok = !SL_LoadSamples();
if(ok) ok = !Player_Init(mf);
if(modreader!=reader) {
_mm_delete_mem_reader(modreader);
modreader=reader;
MikMod_free(unpk);
}
_mm_iobase_revert(modreader);
if(!ok) {
Player_Free_internal(mf);
return NULL;
}
if(Player_Init(mf)) {
_mm_iobase_revert(modreader);
Player_Free_internal(mf);
mf=NULL;
}
_mm_iobase_revert(modreader);
return mf;
}
@@ -569,7 +627,8 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,BOOL cur
MODULE* result=NULL;
MREADER* reader;
if ((reader=_mm_new_mem_reader(buffer, len))) {
if (!buffer || len <= 0) return NULL;
if ((reader=_mm_new_mem_reader(buffer, len)) != NULL) {
result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_mem_reader(reader);
}
@@ -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)
{
MODULE* result=NULL;
struct MREADER* reader=_mm_new_file_reader (fp);
struct MREADER* reader;
if (reader) {
if (fp && (reader=_mm_new_file_reader(fp)) != NULL) {
result=Player_LoadGeneric(reader,maxchan,curious);
_mm_delete_file_reader(reader);
}
@@ -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
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;
MODULE *mf=NULL;
if((fp=_mm_fopen(filename,"rb"))) {
if((fp=_mm_fopen(filename,"rb")) != NULL) {
mf=Player_LoadFP(fp,maxchan,curious);
_mm_fclose(fp);
}
+5 -4
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -32,8 +32,9 @@
#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_mod);
_mm_registerloader(&load_s3m);
@@ -41,7 +42,7 @@ void MikMod_RegisterAllLoaders_internal(void)
_mm_registerloader(&load_xm);
}
void MikMod_RegisterAllLoaders(void)
MIKMODAPI void MikMod_RegisterAllLoaders(void)
{
MUTEX_LOCK(lists);
MikMod_RegisterAllLoaders_internal();
+19 -26
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -43,13 +43,13 @@ extern int fprintf(FILE *, const char *, ...);
/*========== Shared tracker identifiers */
CHAR *STM_Signatures[STM_NTRACKERS] = {
const CHAR *STM_Signatures[STM_NTRACKERS] = {
"!Scream!",
"BMOD2STM",
"WUZAMOD!"
};
CHAR *STM_Version[STM_NTRACKERS] = {
const CHAR *STM_Version[STM_NTRACKERS] = {
"Screamtracker 2",
"Converted by MOD2STM (STM format)",
"Wuzamod (STM format)"
@@ -60,7 +60,7 @@ CHAR *STM_Version[STM_NTRACKERS] = {
SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
UBYTE* poslookup=NULL; /* lookup table for pattern jumps after blank
pattern removal */
UBYTE poslookupcnt;
UWORD poslookupcnt;
UWORD* origpositions=NULL;
BOOL filters; /* resonant filters in use */
@@ -71,30 +71,27 @@ FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
/*========== Linear periods stuff */
int* noteindex=NULL; /* remap value for linear period modules */
static int noteindexcount=0;
static unsigned noteindexcount=0;
int *AllocLinear(void)
{
if(of.numsmp>noteindexcount) {
noteindexcount=of.numsmp;
noteindex=realloc(noteindex,noteindexcount*sizeof(int));
noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int));
}
return noteindex;
}
void FreeLinear(void)
{
if(noteindex) {
MikMod_free(noteindex);
noteindex=NULL;
}
MikMod_free(noteindex);
noteindex=NULL;
noteindexcount=0;
}
int speed_to_finetune(ULONG speed,int sample)
{
int note=1,finetune=0;
ULONG ctmp=0,tmp;
int ctmp=0,tmp,note=1,ft=0;
speed>>=1;
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)<(speed-ctmp))
while(tmp>speed)
tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune));
tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft));
else {
note--;
while(ctmp<speed)
ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune));
ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft));
}
}
noteindex[sample]=note-4*OCTAVE;
return finetune;
return ft;
}
/*========== Order stuff */
@@ -142,13 +139,9 @@ void S3MIT_CreateOrders(BOOL curious)
/*========== Effect stuff */
/* handles S3M and IT effects */
void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags)
{
UBYTE hi,lo;
lo=inf&0xf;
hi=inf>>4;
UBYTE lo = inf&0xF;
/* process S3M / IT specific command structure */
if(cmd!=255) {
@@ -197,7 +190,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
case 9: /* Ixy tremor, ontime x, offtime y */
if (flags & S3MIT_OLDSTYLE)
UniEffect(UNI_S3MEFFECTI,inf);
else
else
UniEffect(UNI_ITEFFECTI,inf);
break;
case 0xa: /* Jxy arpeggio */
@@ -205,7 +198,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
break;
case 0xb: /* Kxy Dual command H00 & Dxy */
if (flags & S3MIT_OLDSTYLE)
UniPTEffect(0x4,0);
UniPTEffect(0x4,0);
else
UniEffect(UNI_ITEFFECTH,0);
UniEffect(UNI_S3MEFFECTD,inf);
@@ -219,7 +212,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
break;
case 0xd: /* Mxx Set Channel Volume */
UniEffect(UNI_ITEFFECTM,inf);
break;
break;
case 0xe: /* Nxy Slide Channel Volume */
UniEffect(UNI_ITEFFECTN,inf);
break;
@@ -234,7 +227,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
if(inf && !lo && !(flags & S3MIT_OLDSTYLE))
UniWriteByte(1);
else
UniWriteByte(inf);
UniWriteByte(inf);
break;
case 0x12: /* Rxy tremolo speed x, depth y */
UniEffect(UNI_S3MEFFECTR,inf);
+95 -26
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -30,44 +30,113 @@
#include "config.h"
#endif
#ifdef HAVE_POSIX_MEMALIGN
#define _XOPEN_SOURCE 600 /* for posix_memalign */
#endif
#include "string.h"
#include "mikmod_internals.h"
#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)
{
if (data)
return realloc(data, size);
else
return MikMod_malloc(size);
if (data) return realloc(data, size);
return calloc(1, size);
}
/* Same as malloc, but sets error variable _mm_error when fails */
void* MikMod_malloc(size_t size)
{
void *d;
if(!(d=calloc(1,size))) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
}
return d;
return MikMod_calloc(1, size);
}
/* Same as calloc, but sets error variable _mm_error when fails */
void* MikMod_calloc(size_t nitems,size_t size)
void* MikMod_calloc(size_t nitems, size_t size)
{
void *d;
if(!(d=calloc(nitems,size))) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
}
void *d = calloc(nitems, size);
if (d) return d;
_mm_errno = MMERR_OUT_OF_MEMORY;
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;
}
void MikMod_free(void *p)
{
if (p)
free(p);
}
/* ex:set ts=4: */
+140 -22
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -40,7 +40,9 @@
#include "mikmod_internals.h"
CHAR *_mm_errmsg[MMERR_MAX+1] =
#define _mmerr_invalid "Invalid error code"
static const char *_mm_errmsg[MMERR_MAX+1] =
{
/* No error */
@@ -82,62 +84,89 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Unable to set non-blocking mode for audio device",
/* AudioFile driver errors */
#ifdef DRV_AF
"Cannot find suitable AudioFile audio port",
#else
_mmerr_invalid,
#endif
/* AIX driver errors */
#ifdef DRV_AIX
"Configuration (init step) of audio device failed",
"Configuration (control step) of audio device failed",
"Configuration (start step) of audio device failed",
/* ALSA driver errors */
/* EsounD driver errors */
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* Ultrasound driver errors */
#ifdef DRV_ULTRA
"Ultrasound driver only works in 16 bit stereo 44 KHz",
"Ultrasound card could not be reset",
"Could not start Ultrasound timer",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* HP driver errors */
#ifdef DRV_HP
"Unable to select 16bit-linear sample format",
"Could not select requested sample-rate",
"Could not select requested number of channels",
"Unable to select audio output",
"Unable to get audio description",
"Could not set transmission buffer size",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* Open Sound System driver errors */
#ifdef DRV_OSS
"Could not set fragment size",
"Could not set sample size",
"Could not set mono/stereo setting",
"Could not set sample rate",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid,
#endif
/* SGI driver errors */
#ifdef DRV_SGI
"Unsupported sample rate",
"Hardware does not support 16 bit sound",
"Hardware does not support 8 bit sound",
"Hardware does not support stereo sound",
"Hardware does not support mono sound",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid,
#endif
/* Sun driver errors */
#ifdef DRV_SUN
"Sound device initialization failed",
#else
_mmerr_invalid,
#endif
/* OS/2 drivers errors */
#if defined(DRV_OS2) || defined(DRV_DART)
"Could not set mixing parameters",
#else
_mmerr_invalid,
#endif
#ifdef DRV_OS2
"Could not create playback semaphores",
"Could not create playback timer",
"Could not create playback thread",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
#endif
/* DirectSound driver errors */
#ifdef DRV_DS
"Could not set playback priority",
"Could not create playback buffers",
"Could not set playback format",
@@ -145,28 +174,117 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
"Could not register event",
"Could not create playback thread",
"Could not initialize playback thread",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid,
#endif
/* Windows Multimedia API driver errors */
#ifdef DRV_WIN
"Invalid device handle",
"The resource is already allocated",
"Invalid device identifier",
"Unsupported output format",
"Unknown error",
#else
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
_mmerr_invalid, _mmerr_invalid,
#endif
/* Macintosh driver errors */
#ifdef DRV_MAC
"Unsupported sample rate",
"Could not start playback",
#else
_mmerr_invalid, _mmerr_invalid,
#endif
/* MacOS X/Darwin driver errors */
#ifdef DRV_OSX
"Unknown device",
"Bad property",
"Could not set playback format",
"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 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];
}
@@ -175,7 +293,7 @@ MikMod_handler_t _mm_errorhandler = NULL;
MIKMODAPI int _mm_errno = 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;
+155 -117
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -43,18 +43,14 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <limits.h>
#include <stdio.h>
#include <string.h>
//#include "mikmod.h"
#include "mikmod_internals.h"
#ifdef SUNOS
@@ -66,17 +62,14 @@ extern int fseek(FILE *, long, int);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
#endif
#define COPY_BUFSIZE 1024
/* some prototypes */
static BOOL _mm_MemReader_Eof(MREADER* reader);
static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
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);
FILE* _mm_fopen(CHAR* fname,CHAR* attrib)
FILE* _mm_fopen(const CHAR* fname, const CHAR* attrib)
{
FILE *fp;
@@ -87,7 +80,7 @@ FILE* _mm_fopen(CHAR* fname,CHAR* attrib)
return fp;
}
BOOL _mm_FileExists(CHAR* fname)
BOOL _mm_FileExists(const CHAR* fname)
{
FILE *fp;
@@ -137,7 +130,7 @@ static int _mm_FileReader_Get(MREADER* reader)
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,
(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)
{
MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER));
MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER));
if (reader) {
reader->core.Eof =&_mm_FileReader_Eof;
reader->core.Read=&_mm_FileReader_Read;
@@ -164,7 +157,7 @@ MREADER *_mm_new_file_reader(FILE* fp)
void _mm_delete_file_reader (MREADER* reader)
{
if(reader) MikMod_free(reader);
MikMod_free(reader);
}
/*========== File Writer */
@@ -174,7 +167,7 @@ typedef struct MFILEWRITER {
FILE* file;
} 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);
}
@@ -184,19 +177,19 @@ static long _mm_FileWriter_Tell(MWRITER* writer)
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);
}
static BOOL _mm_FileWriter_Put(MWRITER* writer,int value)
static int _mm_FileWriter_Put(MWRITER* writer,int value)
{
return fputc(value,((MFILEWRITER*)writer)->file);
}
MWRITER *_mm_new_file_writer(FILE* fp)
{
MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER));
MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER));
if (writer) {
writer->core.Seek =&_mm_FileWriter_Seek;
writer->core.Tell =&_mm_FileWriter_Tell;
@@ -209,12 +202,11 @@ MWRITER *_mm_new_file_writer(FILE* fp)
void _mm_delete_file_writer (MWRITER* writer)
{
if(writer) MikMod_free (writer);
MikMod_free (writer);
}
/*========== Memory Reader */
typedef struct MMEMREADER {
MREADER core;
const void *buffer;
@@ -224,12 +216,12 @@ typedef struct MMEMREADER {
void _mm_delete_mem_reader(MREADER* reader)
{
if (reader) { MikMod_free(reader); }
MikMod_free(reader);
}
MREADER *_mm_new_mem_reader(const void *buffer, int len)
MREADER *_mm_new_mem_reader(const void *buffer, long len)
{
MMEMREADER* reader=(MMEMREADER*)MikMod_malloc(sizeof(MMEMREADER));
MMEMREADER* reader=(MMEMREADER*)MikMod_calloc(1,sizeof(MMEMREADER));
if (reader)
{
reader->core.Eof =&_mm_MemReader_Eof;
@@ -246,74 +238,86 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len)
static BOOL _mm_MemReader_Eof(MREADER* reader)
{
if (!reader) { return 1; }
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
return 1;
}
MMEMREADER* mr = (MMEMREADER*) reader;
if (!mr) return 1;
if (mr->pos >= mr->len) return 1;
return 0;
}
static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
{
unsigned char *d=ptr;
unsigned char *d;
const unsigned char *s;
if (!reader) { return 0; }
MMEMREADER* mr;
long siz;
BOOL ret;
if (reader->Eof(reader)) { return 0; }
if (!reader || !size || (size > (size_t) LONG_MAX))
return 0;
s = ((MMEMREADER*)reader)->buffer;
s += ((MMEMREADER*)reader)->pos;
if ( ((MMEMREADER*)reader)->pos + (long)size > ((MMEMREADER*)reader)->len)
{
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
return 0; /* not enough remaining bytes */
mr = (MMEMREADER*) reader;
siz = (long) size;
if (mr->pos >= mr->len) return 0; /* @ eof */
if (mr->pos + siz > mr->len) {
siz = mr->len - mr->pos;
ret = 0; /* not enough remaining bytes */
}
else {
ret = 1;
}
((MMEMREADER*)reader)->pos += (long)size;
s = (const unsigned char *) mr->buffer;
s += mr->pos;
mr->pos += siz;
d = (unsigned char *) ptr;
while (size--)
{
*d = *s;
s++;
d++;
while (siz) {
*d++ = *s++;
siz--;
}
return 1;
return ret;
}
static int _mm_MemReader_Get(MREADER* reader)
{
int pos;
MMEMREADER* mr;
int c;
if (reader->Eof(reader)) { return 0; }
pos = ((MMEMREADER*)reader)->pos;
((MMEMREADER*)reader)->pos++;
mr = (MMEMREADER*) reader;
if (mr->pos >= mr->len) return EOF;
c = ((const unsigned char*) mr->buffer)[mr->pos];
mr->pos++;
return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos];
return c;
}
static 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)
{
case SEEK_CUR:
((MMEMREADER*)reader)->pos += offset;
break;
case SEEK_SET:
((MMEMREADER*)reader)->pos = offset;
break;
case SEEK_END:
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1;
break;
case SEEK_CUR:
mr->pos += offset;
break;
case SEEK_SET:
mr->pos = reader->iobase + offset;
break;
case SEEK_END:
mr->pos = mr->len + offset;
break;
default: /* invalid */
return -1;
}
if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; }
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
if (mr->pos < reader->iobase) {
mr->pos = mr->core.iobase;
return -1;
}
if (mr->pos > mr->len) {
mr->pos = mr->len;
}
return 0;
}
@@ -321,14 +325,14 @@ static BOOL _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
static long _mm_MemReader_Tell(MREADER* reader)
{
if (reader) {
return ((MMEMREADER*)reader)->pos;
return ((MMEMREADER*)reader)->pos - reader->iobase;
}
return 0;
}
/*========== Write functions */
void _mm_write_string(CHAR* data,MWRITER* writer)
void _mm_write_string(const CHAR* data,MWRITER* writer)
{
if(data)
_mm_write_UBYTES(data,strlen(data),writer);
@@ -378,37 +382,51 @@ void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
_mm_write_I_ULONG((ULONG)data,writer);
}
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \
{ \
while(number-->0) \
_mm_write_##type_name(*(buffer++),writer); \
void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer);
}
#else
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \
{ \
while(number-->0) \
_mm_write_/**/type_name(*(buffer++),writer); \
void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer);
}
#endif
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)
DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)
DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)
void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
}
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)
DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)
DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)
void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
}
void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer);
}
void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer);
}
void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer);
}
void _mm_write_I_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
{
while(cnt-- > 0) _mm_write_I_ULONG(*(buffer++),writer);
}
/*========== Read functions */
int _mm_read_string(CHAR* buffer,int number,MREADER* reader)
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)
@@ -459,32 +477,52 @@ SLONG _mm_read_I_SLONG(MREADER* reader)
return((SLONG)_mm_read_I_ULONG(reader));
}
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \
{ \
while(number-->0) \
*(buffer++)=_mm_read_##type_name(reader); \
return !reader->Eof(reader); \
BOOL _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader);
return !reader->Eof(reader);
}
#else
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \
{ \
while(number-->0) \
*(buffer++)=_mm_read_/**/type_name(reader); \
return !reader->Eof(reader); \
BOOL _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader);
return !reader->Eof(reader);
}
#endif
DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)
DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)
DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)
DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)
BOOL _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
return !reader->Eof(reader);
}
DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)
DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)
DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)
DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)
BOOL _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
{
while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader);
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: */
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -37,7 +37,7 @@
/* Unibuffer chunk size */
#define BUFPAGE 128
UWORD unioperands[UNI_LAST]={
const UWORD unioperands[UNI_LAST] = {
0, /* not used */
1, /* UNI_NOTE */
1, /* UNI_INSTRUMENT */
@@ -209,12 +209,12 @@ static BOOL UniExpand(int wanted)
/* Expand the buffer by BUFPAGE bytes */
newbuf=(UBYTE*)MikMod_realloc(unibuf,(unimax+BUFPAGE)*sizeof(UBYTE));
/* Check if realloc succeeded */
/* Check if MikMod_realloc succeeded */
if(newbuf) {
unibuf = newbuf;
unimax+=BUFPAGE;
return 1;
} else
} else
return 0;
}
return 1;
@@ -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;
@@ -275,15 +275,15 @@ void UniNewline(void)
stream. */
UBYTE* UniDup(void)
{
UBYTE *d;
void *d;
if (!UniExpand(unitt-unipc)) return NULL;
if (!UniExpand(unipc-unitt)) return NULL;
unibuf[unitt] = 0;
if(!(d=(UBYTE *)MikMod_malloc(unipc))) return NULL;
if(!(d=MikMod_malloc(unipc))) return NULL;
memcpy(d,unibuf,unipc);
return d;
return (UBYTE *)d;
}
BOOL UniInit(void)
@@ -296,7 +296,7 @@ BOOL UniInit(void)
void UniCleanup(void)
{
if(unibuf) MikMod_free(unibuf);
MikMod_free(unibuf);
unibuf = NULL;
}
+193 -15
View File
@@ -1,4 +1,5 @@
/* MikMod sound library
(c) 2004, Raphael Assenat
(c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
for complete list.
@@ -6,12 +7,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -20,8 +21,6 @@
/*==============================================================================
$Id$
WAV sample loader
==============================================================================*/
@@ -46,6 +45,9 @@
extern int fprintf(FILE *, const char *, ...);
#endif
static void extract_channel(const char *src, char *dst, int num_chan, int num_samples, int samp_size, int channel);
typedef struct WAV {
CHAR rID[4];
ULONG rLen;
@@ -60,12 +62,32 @@ typedef struct WAV {
UWORD nFormatSpecific;
} 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;
WAV wh;
BOOL have_fmt=0;
_mm_fseek(reader, SEEK_SET, 0);
/* read wav header */
_mm_read_string(wh.rID,4,reader);
wh.rLen = _mm_read_I_ULONG(reader);
@@ -103,7 +125,7 @@ SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
#ifdef MIKMOD_DEBUG
fprintf(stderr,"\rwavloader : wFormatTag=%04x blockalign=%04x nFormatSpc=%04x\n",
wh.wFormatTag,wh.nBlockAlign,wh.nFormatSpecific);
wh.wFormatTag,wh.nBlockAlign,wh.nFormatSpecific);
#endif
if((have_fmt)||(wh.nChannels>1)) {
@@ -130,7 +152,7 @@ SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
si->inflags = si->flags;
SL_RegisterSample(si,MD_SNDFX,reader);
SL_LoadSamples();
/* skip any other remaining blocks - so in case of repeated sample
fragments, we'll return the first anyway instead of an error */
break;
@@ -144,23 +166,159 @@ SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
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;
MUTEX_LOCK(vars);
result=Sample_LoadGeneric_internal(reader);
result = Sample_LoadRawGeneric_internal(reader, rate, channel, flags);
MUTEX_UNLOCK(vars);
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;
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);
_mm_delete_mem_reader(reader);
}
@@ -172,20 +330,20 @@ MIKMODAPI SAMPLE* Sample_LoadFP(FILE *fp)
SAMPLE* result=NULL;
MREADER* reader;
if((reader=_mm_new_file_reader(fp))) {
if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
result=Sample_LoadGeneric(reader);
_mm_delete_file_reader(reader);
}
return result;
}
MIKMODAPI SAMPLE* Sample_Load(CHAR* filename)
MIKMODAPI SAMPLE* Sample_Load(const CHAR* filename)
{
FILE *fp;
SAMPLE *si=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);
_mm_fclose(fp);
}
@@ -195,6 +353,7 @@ MIKMODAPI SAMPLE* Sample_Load(CHAR* filename)
MIKMODAPI void Sample_Free(SAMPLE* si)
{
if(si) {
if (si->onfree) si->onfree(si->ctx);
MD_SampleUnload(si->handle);
MikMod_free(si);
}
@@ -207,4 +366,23 @@ void Sample_Free_internal(SAMPLE *si)
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: */
+3 -3
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -32,7 +32,7 @@
#include "mikmod_internals.h"
UWORD npertab[7 * OCTAVE] = {
const UWORD npertab[7 * OCTAVE] = {
/* Octaves 6 -> 0 */
/* C C# D D# E F F# G G# A A# B */
0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a,
+46 -35
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -56,7 +56,7 @@ typedef struct ITPACK {
BOOL SL_Init(SAMPLOAD* s)
{
if(!sl_buffer)
if(!(sl_buffer=MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
if(!(sl_buffer=(SWORD*)MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
sl_rlength = s->length;
if(s->infmt & SF_16BITS) sl_rlength>>=1;
@@ -68,16 +68,15 @@ BOOL SL_Init(SAMPLOAD* s)
void SL_Exit(SAMPLOAD *s)
{
if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
if(sl_buffer) {
MikMod_free(sl_buffer);
sl_buffer=NULL;
}
MikMod_free(sl_buffer);
sl_buffer=NULL;
}
/* unpack a 8bit IT packed sample */
static 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 bits = status->bits;
UWORD bufbits = status->bufbits;
@@ -145,13 +144,13 @@ static BOOL read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD
status->bufbits = bufbits;
status->last = last;
status->buf = buf;
return !!(dest-sl_buffer);
return (dest-out);
}
/* 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;
UWORD bits = status->bits;
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;
x|=(buf &((1<<y)-1))<<havebits;
buf>>=y;
bufbits-=y;
needbits-=y;
havebits+=y;
bufbits-=(UWORD)y;
needbits-=(UWORD)y;
havebits+=(UWORD)y;
}
if (new_count) {
new_count = 0;
if (++x >= bits)
x++;
bits = x;
bits = (UWORD)x;
continue;
}
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)>=bits)
x++;
bits = x;
bits = (UWORD)x;
continue;
}
}
else if (bits<18) {
if (x>=0x10000) {
bits=x-0x10000+1;
bits=(UWORD)(x-0x10000+1);
continue;
}
} else {
@@ -219,10 +218,10 @@ static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
status->bufbits = bufbits;
status->last = last;
status->buf = buf;
return !!(dest-sl_buffer);
return (dest-out);
}
static 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;
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 */
ITPACK status;
UWORD incnt;
UWORD incnt = 0;
status.buf = 0;
status.last = 0;
status.bufbits = 0;
status.bits = 0;
while(length) {
stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
@@ -258,6 +262,10 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
c_block -= stodo;
} else {
if(infmt&SF_16BITS) {
if(_mm_eof(reader)) {
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
return 1;
}
if(infmt&SF_BIG_ENDIAN)
_mm_read_M_SWORDS(sl_buffer,stodo,reader);
else
@@ -266,6 +274,10 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
SBYTE *src;
SWORD *dest;
if(_mm_eof(reader)) {
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
return 1;
}
reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
src = (SBYTE*)sl_buffer;
dest = sl_buffer;
@@ -285,7 +297,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
sl_old = sl_buffer[t];
}
if((infmt^outfmt) & SF_SIGNED)
if((infmt^outfmt) & SF_SIGNED)
for(t=0;t<stodo;t++)
sl_buffer[t]^= 0x8000;
@@ -299,7 +311,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
scaleval = 0;
for(u=scalefactor;u && t<stodo;u--,t++)
scaleval+=sl_buffer[t];
sl_buffer[idx++]=scaleval/(scalefactor-u);
sl_buffer[idx++]=(UWORD)(scaleval/(scalefactor-u));
length--;
}
stodo = idx;
@@ -316,7 +328,7 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
while(t<stodo && length) {
avgval=sl_buffer[t++];
avgval+=sl_buffer[t++];
sl_buffer[idx++]=avgval>>1;
sl_buffer[idx++]=(SWORD)(avgval>>1);
length-=2;
}
stodo = idx;
@@ -334,10 +346,10 @@ static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefacto
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,
length,smp->reader,0);
length,smp->reader,0);
}
/* Registers a sample for loading when SL_LoadSamples() is called. */
@@ -354,7 +366,7 @@ SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader)
cruise = sndfxlist;
} else
return NULL;
/* Allocate and add structure to the END of the list */
if(!(news=(SAMPLOAD*)MikMod_malloc(sizeof(SAMPLOAD)))) return NULL;
@@ -404,9 +416,9 @@ static ULONG SampleTotal(SAMPLOAD* samplist,int type)
static ULONG RealSpeed(SAMPLOAD *s)
{
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;
ULONG maxsize, speed;
@@ -414,7 +426,7 @@ static BOOL DitherSamples(SAMPLOAD* samplist,int type)
if(!samplist) return 0;
if((maxsize=MD_SampleSpace(type)*1024))
if((maxsize=MD_SampleSpace(type)*1024) != 0)
while(SampleTotal(samplist,type)>maxsize) {
/* First Pass - check for any 16 bit samples */
s = samplist;
@@ -468,17 +480,17 @@ static BOOL DitherSamples(SAMPLOAD* samplist,int type)
return 0;
}
BOOL SL_LoadSamples(void)
int SL_LoadSamples(void)
{
BOOL ok;
int rc;
_mm_critical = 0;
if((!musiclist)&&(!sndfxlist)) return 0;
ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
rc=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
musiclist=sndfxlist=NULL;
return ok;
return rc;
}
void SL_Sample16to8(SAMPLOAD* s)
@@ -515,5 +527,4 @@ void SL_HalveSample(SAMPLOAD* s,int factor)
s->sample->loopend = s->loopend / s->scalefactor;
}
/* ex:set ts=4: */
File diff suppressed because it is too large Load Diff
+586 -105
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -39,13 +39,15 @@
#include "config.h"
#endif
#ifndef NO_HQMIXER
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <string.h>
#include "mikmod_internals.h"
/*
Constant Definitions
====================
@@ -76,7 +78,8 @@
*/
#define MAXVOL_FACTOR (1<<9)
#define BITSHIFT 9
#define MAXVOL_FACTOR (1<<BITSHIFT)
#define REVERBERATION 11000L
#define SAMPLING_SHIFT 2
@@ -128,6 +131,11 @@ static SLONGLONG idxsize,idxlpos,idxlend;
static SLONG *vc_tickbuf=NULL;
static UWORD vc_mode;
#ifdef _MSC_VER
/* Weird bug in compiler */ /* FIXME is this still needed? */
typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
#endif
/* Reverb control variables */
static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8;
@@ -150,16 +158,16 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL,
/*========== 32 bit sample mixers - only for 32 bit platforms */
#ifndef NATIVE_64BIT_INT
static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo)
static SLONG Mix32MonoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
{
SWORD sample=0;
SLONG i,f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=(((SLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS);
index+=increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)( (((SLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS));
idx+=increment;
if(vnf->rampvol) {
*dest++ += (long)(
@@ -179,19 +187,19 @@ static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc
}
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;
SLONG i,f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1] * f)) >> FRACBITS);
index += increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1] * f)) >> FRACBITS));
idx += increment;
if(vnf->rampvol) {
*dest++ += (long)(
@@ -222,20 +230,20 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i
vnf->lastvalL=vnf->lvolsel*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;
long whoop;
SLONG i, f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS);
index+=increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONG)srce[i+1]*f)) >> FRACBITS));
idx+=increment;
if(vnf->rampvol) {
whoop=(long)(
@@ -262,22 +270,22 @@ static SLONG Mix32StereoSurround(const SWORD* srce,SLONG* dest,SLONG index,SLONG
vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->lvolsel*sample;
return index;
return idx;
}
#endif
/*========== 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;
SLONGLONG i,f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=(((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS);
index+=increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)((((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
idx+=increment;
if(vnf->rampvol) {
*dest++ += (long)(
@@ -297,19 +305,225 @@ static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO
}
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;
SLONGLONG i,f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS);
index += increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
idx += increment;
if(vnf->rampvol) {
*dest++ += (long)(
@@ -340,20 +554,22 @@ static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,S
vnf->lastvalL=vnf->lvolsel*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;
long whoop;
SLONGLONG i, f;
while(todo--) {
i=index>>FRACBITS,f=index&FRACMASK;
sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS);
index+=increment;
i=idx>>FRACBITS,f=idx&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1]*f)) >> FRACBITS));
idx+=increment;
if(vnf->rampvol) {
whoop=(long)(
@@ -380,19 +596,20 @@ static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG index
vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->lvolsel*sample;
return index;
return idx;
}
static void(*Mix32to16)(SWORD* dste,const SLONG* srce,NATIVE count);
static void(*Mix32to8)(SBYTE* dste,const SLONG* srce,NATIVE count);
static void(*MixReverb)(SLONG* srce,NATIVE count);
static void(*Mix32toFP)(float* dste,const SLONG *srce,NATIVE count);
static void(*Mix32to16)(SWORD* dste,const SLONG *srce,NATIVE count);
static void(*Mix32to8)(SBYTE* dste,const SLONG *srce,NATIVE count);
static void(*MixReverb)(SLONG *srce,NATIVE count);
/* Reverb macros */
#define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n
#define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7)
#define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7)
static void MixReverb_Normal(SLONG* srce,NATIVE count)
static void MixReverb_Normal(SLONG *srce,NATIVE count)
{
NATIVE speedup;
int ReverbPct;
@@ -418,7 +635,7 @@ static void MixReverb_Normal(SLONG* srce,NATIVE count)
/* left channel */
*srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
}
}
@@ -453,12 +670,96 @@ static void MixReverb_Stereo(SLONG *srce,NATIVE count)
COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8);
/* left channel */
*srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
*srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+
RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8];
/* right channel */
*srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+
RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8];
}
}
static void (*MixLowPass)(SLONG* srce,NATIVE count);
static int nLeftNR, nRightNR;
static void MixLowPass_Stereo(SLONG* srce,NATIVE count)
{
int n1 = nLeftNR, n2 = nRightNR;
SLONG *pnr = srce;
int nr=count;
for (; nr; nr--)
{
int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1;
n1 = vnr;
vnr = pnr[1] >> 1;
pnr[1] = vnr + n2;
n2 = vnr;
pnr += 2;
}
nLeftNR = n1;
nRightNR = n2;
}
static void MixLowPass_Normal(SLONG* srce,NATIVE count)
{
int n1 = nLeftNR;
SLONG *pnr = srce;
int nr=count;
for (; nr; nr--)
{
int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1;
n1 = vnr;
pnr ++;
}
nLeftNR = n1;
}
/* Mixing macros */
#define EXTRACT_SAMPLE_FP(var,attenuation) var=*srce++*((1.0f / 32768.0f) / (MAXVOL_FACTOR*attenuation))
#define CHECK_SAMPLE_FP(var,bound) var=(var>bound)?bound:(var<-bound)?-bound:var
static void Mix32ToFP_Normal(float* dste,const SLONG *srce,NATIVE count)
{
float x1,x2,tmpx;
int i;
for(count/=SAMPLING_FACTOR;count;count--) {
tmpx=0.0f;
for(i=SAMPLING_FACTOR/2;i;i--) {
EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
tmpx+=x1+x2;
}
*dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
}
}
static void Mix32ToFP_Stereo(float* dste,const SLONG *srce,NATIVE count)
{
float x1,x2,x3,x4,tmpx,tmpy;
int i;
for(count/=SAMPLING_FACTOR;count;count--) {
tmpx=tmpy=0.0f;
for(i=SAMPLING_FACTOR/2;i;i--) {
EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f);
EXTRACT_SAMPLE_FP(x3,1.0f); EXTRACT_SAMPLE_FP(x4,1.0f);
CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f);
CHECK_SAMPLE_FP(x3,1.0f); CHECK_SAMPLE_FP(x4,1.0f);
tmpx+=x1+x3;
tmpy+=x2+x4;
}
*dste++ =tmpx*(1.0f/SAMPLING_FACTOR);
*dste++ =tmpy*(1.0f/SAMPLING_FACTOR);
}
}
@@ -466,7 +767,7 @@ static void MixReverb_Stereo(SLONG *srce,NATIVE count)
#define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation)
#define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var
static void Mix32To16_Normal(SWORD* dste,const SLONG* srce,NATIVE count)
static void Mix32To16_Normal(SWORD* dste,const SLONG *srce,NATIVE count)
{
NATIVE x1,x2,tmpx;
int i;
@@ -481,11 +782,12 @@ static void Mix32To16_Normal(SWORD* dste,const SLONG* srce,NATIVE count)
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;
int i;
@@ -503,12 +805,12 @@ static void Mix32To16_Stereo(SWORD* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x3;
tmpy+=x2+x4;
}
*dste++ =tmpx/SAMPLING_FACTOR;
*dste++ =tmpy/SAMPLING_FACTOR;
*dste++ =(SWORD)(tmpx/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;
int i;
@@ -523,11 +825,11 @@ static void Mix32To8_Normal(SBYTE* dste,const SLONG* srce,NATIVE count)
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;
int i;
@@ -545,11 +847,163 @@ static void Mix32To8_Stereo(SBYTE* dste,const SLONG* srce,NATIVE count)
tmpx+=x1+x3;
tmpy+=x2+x4;
}
*dste++ =(tmpx/SAMPLING_FACTOR)+128;
*dste++ =(tmpy/SAMPLING_FACTOR)+128;
*dste++ =(SBYTE)((tmpx/SAMPLING_FACTOR)+128);
*dste++ =(SBYTE)((tmpy/SAMPLING_FACTOR)+128);
}
}
#if defined HAVE_SSE2
#define SHIFT_MIX_TO_16 (BITSHIFT + 16 - 16)
/* TEST: Ok */
static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
{
int remain = count;
/* Check unaligned dste buffer. srce is always aligned. */
while(!IS_ALIGNED_16(dste))
{
Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
dste+=2;
srce+=8;
count--;
if(!count) return;
}
/* dste and srce aligned. srce is always aligned. */
remain = count & 15;
/* count / 2 for 1 sample */
for(count>>=4;count;count--)
{
/* Load 32bit sample. 1st average */
__m128i v0 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+0)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+4)), SHIFT_MIX_TO_16)
); /* v0: s0.l+s2.l | s0.r+s2.r | s1.l+s3.l | s1.r+s3.r */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
__m128i v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
/* v1: s0.l+s2.l / 4 | s0.r+s2.r / 4 | s1.l+s3.l+s0.l+s2.l / 4 | s1.r+s3.r+s0.r+s2.r / 4 */
__m128i v2 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+8)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+12)), SHIFT_MIX_TO_16)
); /* v2: s4.l+s6.l | s4.r+s6.r | s5.l+s7.l | s5.r+s7.r */
__m128i v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
/* v3: s4.l+s6.l /4 | s4.r+s6.r / 4| s5.l+s7.l+s4.l+s6.l / 4 | s5.r+s7.r+s4.r+s6.l / 4 */
/* pack two stereo samples in one */
__m128i v4 = _mm_unpacklo_epi64(v1, v3); /* v4 = avg(s0,s1,s2,s3) | avg(s4,s5,s6,s7) */
__m128i v6;
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
v0 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+16)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+20)), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2);
v2 = _mm_add_epi32(
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+24)), SHIFT_MIX_TO_16),
_mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+28)), SHIFT_MIX_TO_16)
);
v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */
/* pack two stereo samples in one */
v6 = _mm_unpacklo_epi64(v1, v3); /* v6 = avg(s8,s9,s10,s11) | avg(s12,s13,s14,s15) */
_mm_store_si128((__m128i*)dste, _mm_packs_epi32(v4, v6)); /* 4 interpolated stereo sample 32bit to 4 */
dste+=8;
srce+=32; /* 32 = 4 * 8 */
}
/* FIXME: THIS PART WRITES PAST DST !! */
if (remain)
{
Mix32To16_Stereo(dste, srce, remain);
}
}
#elif defined HAVE_ALTIVEC
#define SHIFT_MIX_TO_16 vec_splat_u32(BITSHIFT + 16 - 16)
/* TEST: Ok */
static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count)
{
int remain = count;
/* Check unaligned dste buffer. srce is always aligned. */
while(!IS_ALIGNED_16(dste))
{
Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR);
dste+=2;
srce+=8;
count--;
if(!count) return;
}
/* dste and srce aligned. srce is always aligned. */
remain = count & 15;
for(count>>=4;count;count--)
{
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
vector signed int v0 = vec_add(
vec_sra(vec_ld(0, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
vec_sra(vec_ld(0x10, srce), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
vector signed int v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
vector signed int v2 = vec_add(
vec_sra(vec_ld(0x20, srce), SHIFT_MIX_TO_16),
vec_sra(vec_ld(0x30, srce), SHIFT_MIX_TO_16)
);
vector signed int v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
/* pack two stereo samples in one */
vector signed int v6, v4 = vec_unpacklo(v1, v3); /* v4 = lo64(v1) | lo64(v3) */
/* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */
v0 = vec_add(
vec_sra(vec_ld(0x40, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */
vec_sra(vec_ld(0x50, srce), SHIFT_MIX_TO_16)
); /* 128bit = 2 stereo samples */
/* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */
v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2));
v2 = vec_add(
vec_sra(vec_ld(0x60, srce), SHIFT_MIX_TO_16),
vec_sra(vec_ld(0x70, srce), SHIFT_MIX_TO_16)
);
v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */
/* pack two stereo samples in one */
v6 = vec_unpacklo(v1, v3);
vec_st(vec_packs(v4, v6), 0, dste); /* 4 interpolated stereo sample 32bit to 4 interpolated stereo sample 16bit + saturation */
dste+=8;
srce+=32; /* 32 = 4 * 8 */
}
if (remain)
{
Mix32To16_Stereo(dste, srce, remain);
}
}
#endif
static void AddChannel(SLONG* ptr,NATIVE todo)
{
SLONGLONG end,done;
@@ -638,27 +1092,28 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) {
if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND))
vnf->current=Mix32StereoSurround
(s,ptr,vnf->current,vnf->increment,done);
vnf->current=(SLONGLONG)Mix32StereoSurround
(s,ptr,vnf->current,vnf->increment,done);
else
vnf->current=Mix32StereoNormal
(s,ptr,vnf->current,vnf->increment,done);
(s,ptr,vnf->current,vnf->increment,done);
} else
vnf->current=Mix32MonoNormal
(s,ptr,vnf->current,vnf->increment,done);
} else
(s,ptr,vnf->current,vnf->increment,done);
}
else
#endif
{
{
if(vc_mode & DMODE_STEREO) {
if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND))
vnf->current=MixStereoSurround
(s,ptr,vnf->current,vnf->increment,done);
(s,ptr,vnf->current,vnf->increment,done);
else
vnf->current=MixStereoNormal
(s,ptr,vnf->current,vnf->increment,done);
(s,ptr,vnf->current,vnf->increment,done);
} else
vnf->current=MixMonoNormal
(s,ptr,vnf->current,vnf->increment,done);
(s,ptr,vnf->current,vnf->increment,done);
}
} else {
vnf->lastvalL = vnf->lastvalR = 0;
@@ -667,7 +1122,7 @@ static void AddChannel(SLONG* ptr,NATIVE todo)
}
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&=~(SAMPLING_FACTOR-1);
}
left = MIN(tickleft, (long)todo);
left = MIN(tickleft, todo);
buffer = buf;
tickleft -= 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>15) md_reverb=15;
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);
else
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();
if (!(md_mode&DMODE_HQMIXER))
return VC1_Init();
if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) {
if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) {
_mm_errno = MMERR_INITIALIZING_MIXER;
return 1;
}
if(!vc_tickbuf)
if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) {
if(!vc_tickbuf) {
if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) {
_mm_errno = MMERR_INITIALIZING_MIXER;
return 1;
}
}
if(md_mode & DMODE_STEREO) {
Mix32to16 = Mix32To16_Stereo;
Mix32toFP = Mix32ToFP_Stereo;
#if ((defined HAVE_ALTIVEC || defined HAVE_SSE2) && (SAMPLING_FACTOR == 4))
if (md_mode & DMODE_SIMDMIXER)
Mix32to16 = Mix32To16_Stereo_SIMD_4Tap;
else
#endif
Mix32to16 = Mix32To16_Stereo;
Mix32to8 = Mix32To8_Stereo;
MixReverb = MixReverb_Stereo;
MixLowPass = MixLowPass_Stereo;
} else {
Mix32toFP = Mix32ToFP_Normal;
Mix32to16 = Mix32To16_Normal;
Mix32to8 = Mix32To8_Normal;
MixReverb = MixReverb_Normal;
MixLowPass = MixLowPass_Normal;
}
md_mode |= DMODE_INTERP;
vc_mode = md_mode;
return 0;
}
BOOL VC2_PlayStart(void)
int VC2_PlayStart(void)
{
md_mode|=DMODE_INTERP;
@@ -829,14 +1305,17 @@ BOOL VC2_PlayStart(void)
if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
/* allocate reverb buffers for the right channel if in stereo mode only. */
if (vc_mode & DMODE_STEREO) {
if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1;
if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1;
if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1;
if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1;
if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1;
if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1;
if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1;
if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1;
}
RVRindex = 0;
return 0;
@@ -844,28 +1323,28 @@ BOOL VC2_PlayStart(void)
void VC2_PlayStop(void)
{
if(RVbufL1) MikMod_free(RVbufL1);
if(RVbufL2) MikMod_free(RVbufL2);
if(RVbufL3) MikMod_free(RVbufL3);
if(RVbufL4) MikMod_free(RVbufL4);
if(RVbufL5) MikMod_free(RVbufL5);
if(RVbufL6) MikMod_free(RVbufL6);
if(RVbufL7) MikMod_free(RVbufL7);
if(RVbufL8) MikMod_free(RVbufL8);
if(RVbufR1) MikMod_free(RVbufR1);
if(RVbufR2) MikMod_free(RVbufR2);
if(RVbufR3) MikMod_free(RVbufR3);
if(RVbufR4) MikMod_free(RVbufR4);
if(RVbufR5) MikMod_free(RVbufR5);
if(RVbufR6) MikMod_free(RVbufR6);
if(RVbufR7) MikMod_free(RVbufR7);
if(RVbufR8) MikMod_free(RVbufR8);
MikMod_free(RVbufL1);
MikMod_free(RVbufL2);
MikMod_free(RVbufL3);
MikMod_free(RVbufL4);
MikMod_free(RVbufL5);
MikMod_free(RVbufL6);
MikMod_free(RVbufL7);
MikMod_free(RVbufL8);
MikMod_free(RVbufR1);
MikMod_free(RVbufR2);
MikMod_free(RVbufR3);
MikMod_free(RVbufR4);
MikMod_free(RVbufR5);
MikMod_free(RVbufR6);
MikMod_free(RVbufR7);
MikMod_free(RVbufR8);
RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL;
RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL;
}
BOOL VC2_SetNumVoices(void)
int VC2_SetNumVoices(void)
{
int t;
@@ -873,8 +1352,8 @@ BOOL VC2_SetNumVoices(void)
if(!(vc_softchn=md_softchn)) return 0;
if(vinf) MikMod_free(vinf);
if(!(vinf=MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1;
MikMod_free(vinf);
if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1;
for(t=0;t<vc_softchn;t++) {
vinf[t].frq=10000;
@@ -884,4 +1363,6 @@ BOOL VC2_SetNumVoices(void)
return 0;
}
#endif /* ! NO_HQMIXER */
/* ex:set ts=4: */
+103 -87
View File
@@ -6,12 +6,12 @@
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -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"
extern BOOL VC1_Init(void);
extern BOOL VC2_Init(void);
static BOOL (*VC_Init_ptr)(void)=VC1_Init;
#ifndef NO_HQMIXER
extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
extern void VC1_Exit(void);
extern void VC2_Exit(void);
static void (*VC_Exit_ptr)(void)=VC1_Exit;
extern BOOL VC1_SetNumVoices(void);
extern BOOL VC2_SetNumVoices(void);
static BOOL (*VC_SetNumVoices_ptr)(void);
extern UWORD VC1_VoiceGetVolume(UBYTE);
extern UWORD VC2_VoiceGetVolume(UBYTE);
extern ULONG VC1_VoiceGetPanning(UBYTE);
extern ULONG VC2_VoiceGetPanning(UBYTE);
extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
extern ULONG VC1_VoiceGetFrequency(UBYTE);
extern ULONG VC2_VoiceGetFrequency(UBYTE);
extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
extern void VC1_VoiceStop(UBYTE);
extern void VC2_VoiceStop(UBYTE);
extern 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 VC2_SampleSpace(int);
static ULONG (*VC_SampleSpace_ptr)(int);
extern ULONG VC1_SampleLength(int,SAMPLE*);
extern ULONG VC2_SampleLength(int,SAMPLE*);
extern ULONG VC1_VoiceRealVolume(UBYTE);
extern ULONG VC2_VoiceRealVolume(UBYTE);
#endif
#ifndef _IN_VIRTCH_
#ifndef NO_HQMIXER
extern int VC1_Init(void);
extern int VC2_Init(void);
static int (*VC_Init_ptr)(void)=VC1_Init;
static void (*VC_Exit_ptr)(void)=VC1_Exit;
extern int VC1_SetNumVoices(void);
extern int VC2_SetNumVoices(void);
static int (*VC_SetNumVoices_ptr)(void);
static ULONG (*VC_SampleSpace_ptr)(int);
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
extern BOOL VC1_PlayStart(void);
extern BOOL VC2_PlayStart(void);
static BOOL (*VC_PlayStart_ptr)(void);
extern void VC1_PlayStop(void);
extern int VC2_PlayStart(void);
static int (*VC_PlayStart_ptr)(void);
extern void VC2_PlayStop(void);
static void (*VC_PlayStop_ptr)(void);
extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
extern void VC1_SampleUnload(SWORD);
extern void VC2_SampleUnload(SWORD);
static void (*VC_SampleUnload_ptr)(SWORD);
extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
extern void VC1_VoiceSetVolume(UBYTE,UWORD);
extern void VC2_VoiceSetVolume(UBYTE,UWORD);
static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
extern UWORD VC1_VoiceGetVolume(UBYTE);
extern UWORD VC2_VoiceGetVolume(UBYTE);
static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
extern ULONG VC1_VoiceGetFrequency(UBYTE);
extern ULONG VC2_VoiceGetFrequency(UBYTE);
static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
extern void VC1_VoiceSetPanning(UBYTE,ULONG);
extern void VC2_VoiceSetPanning(UBYTE,ULONG);
static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
extern ULONG VC1_VoiceGetPanning(UBYTE);
extern ULONG VC2_VoiceGetPanning(UBYTE);
static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
extern void VC1_VoiceStop(UBYTE);
extern void VC2_VoiceStop(UBYTE);
static void (*VC_VoiceStop_ptr)(UBYTE);
extern BOOL VC1_VoiceStopped(UBYTE);
extern BOOL VC2_VoiceStopped(UBYTE);
static BOOL (*VC_VoiceStopped_ptr)(UBYTE);
extern SLONG VC1_VoiceGetPosition(UBYTE);
extern SLONG VC2_VoiceGetPosition(UBYTE);
static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
extern ULONG VC1_VoiceRealVolume(UBYTE);
extern ULONG VC2_VoiceRealVolume(UBYTE);
static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
@@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
#define VC_FUNC2(suffix,ret,typ1,typ2) \
MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
#else
#define VC_PROC0(suffix) \
MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
@@ -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); }
#endif
VC_FUNC0(Init,BOOL)
VC_FUNC0(Init,int)
VC_PROC0(Exit)
VC_FUNC0(SetNumVoices,BOOL)
VC_FUNC0(SetNumVoices,int)
VC_FUNC1(SampleSpace,ULONG,int)
VC_FUNC2(SampleLength,ULONG,int,SAMPLE*)
VC_FUNC0(PlayStart,BOOL)
VC_FUNC0(PlayStart,int)
VC_PROC0(PlayStop)
VC_FUNC2(SampleLoad,SWORD,struct SAMPLOAD*,int)
VC_PROC1(SampleUnload,SWORD)
@@ -158,15 +166,16 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g)
{ VC_VoicePlay_ptr(a,b,c,d,e,f,g); }
void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) {
VC_VoicePlay_ptr(a,b,c,d,e,f,g);
}
VC_PROC1(VoiceStop,UBYTE)
VC_FUNC1(VoiceStopped,BOOL,UBYTE)
VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
void VC_SetupPointers(void)
{
if (md_mode&DMODE_HQMIXER) {
@@ -217,22 +226,25 @@ void VC_SetupPointers(void)
VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
}
}
#endif/* !NO_HQMIXER */
#else
#else /* _IN_VIRTCH_ */
#ifndef _VIRTCH_COMMON_
#define _VIRTCH_COMMON_
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;
return samples;
}
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;
return bytes;
}
@@ -244,7 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
todo=samples2bytes(bytes2samples(todo));
/* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
if(vc_mode & DMODE_16BITS)
if(vc_mode &(DMODE_16BITS|DMODE_FLOAT))
memset(buf,0,todo);
else
memset(buf,0x80,todo);
@@ -270,14 +282,14 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
void VC1_Exit(void)
{
if(vc_tickbuf) MikMod_free(vc_tickbuf);
if(vinf) MikMod_free(vinf);
if(Samples) MikMod_free(Samples);
MikMod_free(vinf);
MikMod_afree(vc_tickbuf);
MikMod_afree(Samples);
vc_tickbuf = NULL;
vinf = NULL;
Samples = NULL;
VC_SetupPointers();
}
@@ -303,19 +315,19 @@ ULONG VC1_VoiceGetFrequency(UBYTE voice)
void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
{
vinf[voice].flags = flags;
vinf[voice].handle = handle;
vinf[voice].start = start;
vinf[voice].size = size;
vinf[voice].reppos = reppos;
vinf[voice].repend = repend;
vinf[voice].kick = 1;
vinf[voice].flags = flags;
vinf[voice].handle = handle;
vinf[voice].start = start;
vinf[voice].size = size;
vinf[voice].reppos = reppos;
vinf[voice].repend = repend;
vinf[voice].kick = 1;
}
void VC1_VoiceStop(UBYTE voice)
{
vinf[voice].active = 0;
}
}
BOOL VC1_VoiceStopped(UBYTE voice)
{
@@ -324,11 +336,11 @@ BOOL VC1_VoiceStopped(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)
{
{
/* protect against clicks if volume variation is too high */
if(abs((int)vinf[voice].vol-(int)vol)>32)
vinf[voice].rampvol=CLICK_BUFFER;
@@ -347,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
void VC1_SampleUnload(SWORD handle)
{
if (handle<MAXSAMPLEHANDLES) {
if (Samples[handle])
MikMod_free(Samples[handle]);
if (Samples && (handle < MAXSAMPLEHANDLES)) {
MikMod_afree(Samples[handle]);
Samples[handle]=NULL;
}
}
@@ -358,10 +369,15 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
{
SAMPLE *s = sload->sample;
int handle;
ULONG t, length,loopstart,loopend;
ULONG t, length,loopstart,loopend,looplen;
if(type==MD_HARDWARE) return -1;
if(s->length > MAX_SAMPLE_SIZE) {
_mm_errno = MMERR_NOT_A_STREAM; /* better error? */
return -1;
}
/* Find empty slot to put sample address in */
for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
if(!Samples[handle]) break;
@@ -370,7 +386,7 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
_mm_errno = MMERR_OUT_OF_HANDLES;
return -1;
}
/* Reality check for loop settings */
if (s->loopend > s->length)
s->loopend = s->length;
@@ -384,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
SL_SampleSigned(sload);
SL_Sample8to16(sload);
if(!(Samples[handle]=(SWORD*)MikMod_malloc((length+20)<<1))) {
if(!(Samples[handle]=(SWORD*)MikMod_amalloc((length+20)<<1))) {
_mm_errno = MMERR_SAMPLE_TOO_BIG;
return -1;
}
/* read sample into buffer */
if (SL_Load(Samples[handle],sload,length))
if (SL_Load(Samples[handle],sload,length)) {
MikMod_afree(Samples[handle]);
Samples[handle]=NULL;
return -1;
}
/* Unclick sample */
if(s->flags & SF_LOOP) {
looplen = loopend - loopstart;/* handle short samples */
if(s->flags & SF_BIDI)
for(t=0;t<16;t++)
for(t=0;t<16 && t<looplen;t++)
Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
else
for(t=0;t<16;t++)
for(t=0;t<16 && t<looplen;t++)
Samples[handle][loopend+t]=Samples[handle][t+loopstart];
} else
for(t=0;t<16;t++)
@@ -410,15 +430,11 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
ULONG VC1_SampleSpace(int type)
{
(void)type; /* unused arg */
return vc_memory;
}
ULONG VC1_SampleLength(int type,SAMPLE* s)
{
(void)type; /* unused arg */
if (!s) return 0;
return (s->length*((s->flags&SF_16BITS)?2:1))+16;
@@ -431,7 +447,7 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
SWORD *smp;
SLONG t;
t = vinf[voice].current>>FRACBITS;
t = (SLONG)(vinf[voice].current>>FRACBITS);
if(!vinf[voice].active) return 0;
s = vinf[voice].handle;
@@ -452,8 +468,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
return abs(k-j);
}
#endif
#endif /* _VIRTCH_COMMON_ */
#endif
#endif /* _IN_VIRTCH_ */
/* ex:set ts=4: */