From b4e70422a3455e327433a7471c929ef100ef3b10 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 8 Aug 2020 21:56:15 -0400 Subject: mikmod: Upgrade mikmod core from v3.2.0 to v3.3.11 * Get rid of the non-functional GT2 loader * Add the UMX loader * Add HQ mixer routines (and make it configurable) * Allow samplerate to be configured at run/playtime * Support >64KHz mixing/playback * Correctly restore non-boost status (The diff to upstream is much smaller now too!) Change-Id: Iaa4ac901ba9cd4123bb225656976e78271353a72 --- apps/plugins/mikmod/virtch_common.c | 193 +++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 91 deletions(-) (limited to 'apps/plugins/mikmod/virtch_common.c') diff --git a/apps/plugins/mikmod/virtch_common.c b/apps/plugins/mikmod/virtch_common.c index e13f6d1c51..3395120a47 100644 --- a/apps/plugins/mikmod/virtch_common.c +++ b/apps/plugins/mikmod/virtch_common.c @@ -6,12 +6,12 @@ it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - + You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -20,90 +20,96 @@ /*============================================================================== - $Id: virtch_common.c,v 1.2 2005/03/30 19:11:50 realtech Exp $ + $Id$ Common source parts between the two software mixers. This file is probably the ugliest part of libmikmod... ==============================================================================*/ -#ifndef _IN_VIRTCH_ - +#if defined(HAVE_CONFIG_H) && !defined(_IN_VIRTCH_) /* config.h isn't guarded */ +#include "config.h" +#endif #include "mikmod_internals.h" -extern int VC1_Init(void); -//extern int VC2_Init(void); -static int (*VC_Init_ptr)(void)=VC1_Init; +#ifndef NO_HQMIXER +extern ULONG VC1_SilenceBytes(SBYTE*,ULONG); +extern ULONG VC2_SilenceBytes(SBYTE*,ULONG); +extern ULONG VC1_WriteBytes(SBYTE*,ULONG); +extern ULONG VC2_WriteBytes(SBYTE*,ULONG); extern void VC1_Exit(void); -//extern void VC2_Exit(void); -static void (*VC_Exit_ptr)(void)=VC1_Exit; -extern int VC1_SetNumVoices(void); -//extern int VC2_SetNumVoices(void); -static int (*VC_SetNumVoices_ptr)(void); +extern void VC2_Exit(void); +extern UWORD VC1_VoiceGetVolume(UBYTE); +extern UWORD VC2_VoiceGetVolume(UBYTE); +extern ULONG VC1_VoiceGetPanning(UBYTE); +extern ULONG VC2_VoiceGetPanning(UBYTE); +extern void VC1_VoiceSetFrequency(UBYTE,ULONG); +extern void VC2_VoiceSetFrequency(UBYTE,ULONG); +extern ULONG VC1_VoiceGetFrequency(UBYTE); +extern ULONG VC2_VoiceGetFrequency(UBYTE); +extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); +extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); +extern void VC1_VoiceStop(UBYTE); +extern void VC2_VoiceStop(UBYTE); +extern int VC1_VoiceStopped(UBYTE); +extern int VC2_VoiceStopped(UBYTE); +extern SLONG VC1_VoiceGetPosition(UBYTE); +extern SLONG VC2_VoiceGetPosition(UBYTE); +extern void VC1_VoiceSetVolume(UBYTE,UWORD); +extern void VC2_VoiceSetVolume(UBYTE,UWORD); +extern void VC1_VoiceSetPanning(UBYTE,ULONG); +extern void VC2_VoiceSetPanning(UBYTE,ULONG); +extern void VC1_SampleUnload(SWORD); +extern void VC2_SampleUnload(SWORD); +extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int); +extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int); extern ULONG VC1_SampleSpace(int); -//extern ULONG VC2_SampleSpace(int); -static ULONG (*VC_SampleSpace_ptr)(int); +extern ULONG VC2_SampleSpace(int); extern ULONG VC1_SampleLength(int,SAMPLE*); -//extern ULONG VC2_SampleLength(int,SAMPLE*); +extern ULONG VC2_SampleLength(int,SAMPLE*); +extern ULONG VC1_VoiceRealVolume(UBYTE); +extern ULONG VC2_VoiceRealVolume(UBYTE); +#endif + + +#ifndef _IN_VIRTCH_ + +#ifndef NO_HQMIXER +extern int VC1_Init(void); +extern int VC2_Init(void); +static int (*VC_Init_ptr)(void)=VC1_Init; +static void (*VC_Exit_ptr)(void)=VC1_Exit; +extern int VC1_SetNumVoices(void); +extern int VC2_SetNumVoices(void); +static int (*VC_SetNumVoices_ptr)(void); +static ULONG (*VC_SampleSpace_ptr)(int); static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*); -extern int VC1_PlayStart(void); -//extern int VC2_PlayStart(void); -static int (*VC_PlayStart_ptr)(void); -extern void VC1_PlayStop(void); +extern int VC2_PlayStart(void); +static int (*VC_PlayStart_ptr)(void); extern void VC2_PlayStop(void); static void (*VC_PlayStop_ptr)(void); -extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int); -//extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int); static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int); -extern void VC1_SampleUnload(SWORD); -//extern void VC2_SampleUnload(SWORD); static void (*VC_SampleUnload_ptr)(SWORD); -extern ULONG VC1_WriteBytes(SBYTE*,ULONG); -//extern ULONG VC2_WriteBytes(SBYTE*,ULONG); static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG); -extern ULONG VC1_SilenceBytes(SBYTE*,ULONG); -//extern ULONG VC2_SilenceBytes(SBYTE*,ULONG); static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG); -extern void VC1_VoiceSetVolume(UBYTE,UWORD); -//extern void VC2_VoiceSetVolume(UBYTE,UWORD); static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD); -extern UWORD VC1_VoiceGetVolume(UBYTE); -//extern UWORD VC2_VoiceGetVolume(UBYTE); static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE); -extern void VC1_VoiceSetFrequency(UBYTE,ULONG); -//extern void VC2_VoiceSetFrequency(UBYTE,ULONG); static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG); -extern ULONG VC1_VoiceGetFrequency(UBYTE); -//extern ULONG VC2_VoiceGetFrequency(UBYTE); static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE); -extern void VC1_VoiceSetPanning(UBYTE,ULONG); -//extern void VC2_VoiceSetPanning(UBYTE,ULONG); static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG); -extern ULONG VC1_VoiceGetPanning(UBYTE); -//extern ULONG VC2_VoiceGetPanning(UBYTE); static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE); -extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); -//extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); -extern void VC1_VoiceStop(UBYTE); -//extern void VC2_VoiceStop(UBYTE); static void (*VC_VoiceStop_ptr)(UBYTE); -extern int VC1_VoiceStopped(UBYTE); -//extern int VC2_VoiceStopped(UBYTE); static int (*VC_VoiceStopped_ptr)(UBYTE); -extern SLONG VC1_VoiceGetPosition(UBYTE); -//extern SLONG VC2_VoiceGetPosition(UBYTE); static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE); -extern ULONG VC1_VoiceRealVolume(UBYTE); -//extern ULONG VC2_VoiceRealVolume(UBYTE); static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE); -#if defined __STDC__ || defined _MSC_VER || defined MPW_C +#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C #define VC_PROC0(suffix) \ MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); } @@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); } #define VC_FUNC2(suffix,ret,typ1,typ2) \ MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); } + #else + #define VC_PROC0(suffix) \ MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); } @@ -158,18 +166,18 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG) VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE) VC_PROC2(VoiceSetPanning,UBYTE,ULONG) VC_FUNC1(VoiceGetPanning,ULONG,UBYTE) - -void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) -{ VC_VoicePlay_ptr(a,b,c,d,e,f,g); } + +void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) { + VC_VoicePlay_ptr(a,b,c,d,e,f,g); +} VC_PROC1(VoiceStop,UBYTE) VC_FUNC1(VoiceStopped,int,UBYTE) VC_FUNC1(VoiceGetPosition,SLONG,UBYTE) VC_FUNC1(VoiceRealVolume,ULONG,UBYTE) - + void VC_SetupPointers(void) { - /* if (md_mode&DMODE_HQMIXER) { VC_Init_ptr=VC2_Init; VC_Exit_ptr=VC2_Exit; @@ -194,7 +202,6 @@ void VC_SetupPointers(void) VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition; VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume; } else { - */ VC_Init_ptr=VC1_Init; VC_Exit_ptr=VC1_Exit; VC_SetNumVoices_ptr=VC1_SetNumVoices; @@ -217,10 +224,11 @@ void VC_SetupPointers(void) VC_VoiceStopped_ptr=VC1_VoiceStopped; VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition; VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume; - //} + } } +#endif/* !NO_HQMIXER */ -#else +#else /* _IN_VIRTCH_ */ #ifndef _VIRTCH_COMMON_ #define _VIRTCH_COMMON_ @@ -248,9 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo) todo=samples2bytes(bytes2samples(todo)); /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */ - if(vc_mode & DMODE_FLOAT) - memset(buf,0,todo); - else if(vc_mode & DMODE_16BITS) + if(vc_mode &(DMODE_16BITS|DMODE_FLOAT)) memset(buf,0,todo); else memset(buf,0x80,todo); @@ -276,14 +282,14 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo) void VC1_Exit(void) { - if(vc_tickbuf) MikMod_free(vc_tickbuf); - if(vinf) MikMod_free(vinf); - if(Samples) MikMod_free(Samples); + MikMod_free(vinf); + MikMod_afree(vc_tickbuf); + MikMod_afree(Samples); vc_tickbuf = NULL; vinf = NULL; Samples = NULL; - + VC_SetupPointers(); } @@ -309,19 +315,19 @@ ULONG VC1_VoiceGetFrequency(UBYTE voice) void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) { - vinf[voice].flags = flags; - vinf[voice].handle = handle; - vinf[voice].start = start; - vinf[voice].size = size; - vinf[voice].reppos = reppos; - vinf[voice].repend = repend; - vinf[voice].kick = 1; + vinf[voice].flags = flags; + vinf[voice].handle = handle; + vinf[voice].start = start; + vinf[voice].size = size; + vinf[voice].reppos = reppos; + vinf[voice].repend = repend; + vinf[voice].kick = 1; } void VC1_VoiceStop(UBYTE voice) { vinf[voice].active = 0; -} +} int VC1_VoiceStopped(UBYTE voice) { @@ -334,7 +340,7 @@ SLONG VC1_VoiceGetPosition(UBYTE voice) } void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) -{ +{ /* protect against clicks if volume variation is too high */ if(abs((int)vinf[voice].vol-(int)vol)>32) vinf[voice].rampvol=CLICK_BUFFER; @@ -353,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan) void VC1_SampleUnload(SWORD handle) { - if (handlesample; 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;handleloopend > s->length) s->loopend = s->length; @@ -390,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type) SL_SampleSigned(sload); SL_Sample8to16(sload); - if(!(Samples[handle]=(SWORD*)MikMod_malloc((length+20)<<1))) { + if(!(Samples[handle]=(SWORD*)MikMod_amalloc((length+20)<<1))) { _mm_errno = MMERR_SAMPLE_TOO_BIG; return -1; } /* read sample into buffer */ - if (SL_Load(Samples[handle],sload,length)) + if (SL_Load(Samples[handle],sload,length)) { + MikMod_afree(Samples[handle]); + Samples[handle]=NULL; return -1; + } /* Unclick sample */ if(s->flags & SF_LOOP) { + looplen = loopend - loopstart;/* handle short samples */ if(s->flags & SF_BIDI) - for(t=0;t<16;t++) + for(t=0;t<16 && tlength*((s->flags&SF_16BITS)?2:1))+16; @@ -456,11 +470,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice) return abs(k-j); } +#endif /* _VIRTCH_COMMON_ */ -#endif - -MikMod_callback_t vc_callback; - -#endif +#endif /* _IN_VIRTCH_ */ /* ex:set ts=4: */ -- cgit v1.2.3