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.c | 652 +++++++++++++++++++++++-------------------- 1 file changed, 342 insertions(+), 310 deletions(-) (limited to 'apps/plugins/mikmod/virtch.c') diff --git a/apps/plugins/mikmod/virtch.c b/apps/plugins/mikmod/virtch.c index 6e8174016c..f2fd528b00 100644 --- a/apps/plugins/mikmod/virtch.c +++ b/apps/plugins/mikmod/virtch.c @@ -6,12 +6,12 @@ it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - + You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -20,7 +20,7 @@ /*============================================================================== - $Id: virtch.c,v 1.4 2005/05/18 13:42:23 raphassenat Exp $ + $Id$ Sample mixing routines, using a 32 bits mixing buffer. @@ -33,28 +33,23 @@ (b) Interpolation of sample data during mixing (c) Dolby Surround Sound */ -#if 0 -#include -#endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include #ifdef HAVE_MEMORY_H #include #endif #include #include "mikmod_internals.h" -#include "mikmod.h" /* Constant definitions ==================== - BITSHIFT + BITSHIFT Controls the maximum volume of the sound output. All data is shifted right by BITSHIFT after being mixed. Higher values result in quieter sound and less chance of distortion. @@ -130,164 +125,176 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL, #else #define NATIVE SLONG #endif + #if defined HAVE_SSE2 || defined HAVE_ALTIVEC -static size_t MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,size_t index, size_t increment,size_t todo) +# if !defined(NATIVE_64BIT_INT) +static SINTPTR_T MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo) { - // TODO: + /* TODO: */ SWORD sample; SLONG lvolsel = vnf->lvolsel; while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel * sample; } - return index; + return idx; } +# endif /* !NATIVE_64BIT_INT */ -static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index, size_t increment,size_t todo) -{ +static SINTPTR_T MixSIMDStereoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo) +{ SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel}; SWORD sample; SLONG remain = todo; - // Dest can be misaligned ... + /* Dest can be misaligned */ while(!IS_ALIGNED_16(dest)) { - sample=srce[(index += increment) >> FRACBITS]; + sample=srce[idx >> FRACBITS]; + idx += increment; *dest++ += vol[0] * sample; *dest++ += vol[1] * sample; todo--; + if(!todo) return idx; } - // Srce is always aligned ... + /* Srce is always aligned */ #if defined HAVE_SSE2 - remain = todo&3; + remain = todo&3; { - __m128i v0 = _mm_set_epi16(0, vol[1], - 0, vol[0], - 0, vol[1], - 0, vol[0]); + __m128i v0 = _mm_set_epi16(0, vol[1], + 0, vol[0], + 0, vol[1], + 0, vol[0]); for(todo>>=2;todo; todo--) { - SWORD s0 = srce[(index += increment) >> FRACBITS]; - SWORD s1 = srce[(index += increment) >> FRACBITS]; - SWORD s2 = srce[(index += increment) >> FRACBITS]; - SWORD s3 = srce[(index += increment) >> FRACBITS]; + SWORD s0 = srce[idx >> FRACBITS]; + SWORD s1 = srce[(idx += increment) >> FRACBITS]; + SWORD s2 = srce[(idx += increment) >> FRACBITS]; + SWORD s3 = srce[(idx += increment) >> FRACBITS]; __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0); __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2); __m128i v3 = _mm_load_si128((__m128i*)(dest+0)); __m128i v4 = _mm_load_si128((__m128i*)(dest+4)); _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1))); _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2))); - dest+=8; + dest+=8; + idx += increment; } } #elif defined HAVE_ALTIVEC remain = todo&3; { - vector signed short r0 = vec_ld(0, vol); - vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, // l - 0, 1, // l - 2, 3, // r - 2, 1, // r - 0, 1, // l - 0, 1, // l - 2, 3, // r - 2, 3 // r - )); SWORD s[8]; - + vector signed short r0 = vec_ld(0, vol); + vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */ + 0, 1, /* l */ + 2, 3, /* r */ + 2, 1, /* r */ + 0, 1, /* l */ + 0, 1, /* l */ + 2, 3, /* r */ + 2, 3 /* r */ + )); + for(todo>>=2;todo; todo--) { - // Load constants - s[0] = srce[(index += increment) >> FRACBITS]; - s[1] = srce[(index += increment) >> FRACBITS]; - s[2] = srce[(index += increment) >> FRACBITS]; - s[3] = srce[(index += increment) >> FRACBITS]; + vector short int r1; + vector signed short v1, v2; + vector signed int v3, v4, v5, v6; + + /* Load constants */ + s[0] = srce[idx >> FRACBITS]; + s[1] = srce[(idx += increment) >> FRACBITS]; + s[2] = srce[(idx += increment) >> FRACBITS]; + s[3] = srce[(idx += increment) >> FRACBITS]; s[4] = 0; - - vector short int r1 = vec_ld(0, s); - vector signed short v1 = vec_perm(r1, r1, (vector unsigned char)(0*2, 0*2+1, // s0 - 4*2, 4*2+1, // 0 - 0*2, 0*2+1, // s0 - 4*2, 4*2+1, // 0 - 1*2, 1*2+1, // s1 - 4*2, 4*2+1, // 0 - 1*2, 1*2+1, // s1 - 4*2, 4*2+1 // 0 - )); - - vector signed short v2 = vec_perm(r1, r1, (vector unsigned char)(2*2, 2*2+1, // s2 - 4*2, 4*2+1, // 0 - 2*2, 2*2+1, // s2 - 4*2, 4*2+1, // 0 - 3*2, 3*2+1, // s3 - 4*2, 4*2+1, // 0 - 3*2, 3*2+1, // s3 - 4*2, 4*2+1 // 0 - )); - vector signed int v3 = vec_ld(0, dest); - vector signed int v4 = vec_ld(0, dest + 4); - vector signed int v5 = vec_mule(v0, v1); - vector signed int v6 = vec_mule(v0, v2); - - vec_st(vec_add(v3, v5), 0, dest); + + r1 = vec_ld(0, s); + v1 = vec_perm(r1, r1, (vector unsigned char) + (0*2, 0*2+1, /* s0 */ + 4*2, 4*2+1, /* 0 */ + 0*2, 0*2+1, /* s0 */ + 4*2, 4*2+1, /* 0 */ + 1*2, 1*2+1, /* s1 */ + 4*2, 4*2+1, /* 0 */ + 1*2, 1*2+1, /* s1 */ + 4*2, 4*2+1 /* 0 */ + ) ); + v2 = vec_perm(r1, r1, (vector unsigned char) + (2*2, 2*2+1, /* s2 */ + 4*2, 4*2+1, /* 0 */ + 2*2, 2*2+1, /* s2 */ + 4*2, 4*2+1, /* 0 */ + 3*2, 3*2+1, /* s3 */ + 4*2, 4*2+1, /* 0 */ + 3*2, 3*2+1, /* s3 */ + 4*2, 4*2+1 /* 0 */ + ) ); + + v3 = vec_ld(0, dest); + v4 = vec_ld(0, dest + 4); + v5 = vec_mule(v0, v1); + v6 = vec_mule(v0, v2); + + vec_st(vec_add(v3, v5), 0, dest); vec_st(vec_add(v4, v6), 0x10, dest); dest+=8; + idx += increment; } } -#endif // HAVE_ALTIVEC +#endif /* HAVE_ALTIVEC */ - // Remaining bits ... + /* Remaining bits */ while(remain--) { - sample=srce[(index += increment) >> FRACBITS]; + sample=srce[idx >> FRACBITS]; + idx += increment; *dest++ += vol[0] * sample; *dest++ += vol[1] * sample; } - return index; + return idx; } #endif /*========== 32 bit sample mixers - only for 32 bit platforms */ #ifndef NATIVE_64BIT_INT -static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { #if defined HAVE_ALTIVEC || defined HAVE_SSE2 - if (md_mode & DMODE_SIMDMIXER) - { - return MixSIMDMonoNormal(srce, dest, index, increment, todo); + if (md_mode & DMODE_SIMDMIXER) { + return MixSIMDMonoNormal(srce, dest, idx, increment, todo); } else #endif { SWORD sample; SLONG lvolsel = vnf->lvolsel; - + while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - + sample = srce[idx >> FRACBITS]; + idx += increment; + *dest++ += lvolsel * sample; } } - return index; + return idx; } -// FIXME: This mixer should works also on 64-bit platform -// Hint : changes SLONG / SLONGLONG mess with size_t -static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +/* FIXME: This mixer should works also on 64-bit platform */ +/* Hint : changes SLONG / SLONGLONG mess with intptr */ +static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { #if defined HAVE_ALTIVEC || defined HAVE_SSE2 - if (md_mode & DMODE_SIMDMIXER) - { - return MixSIMDStereoNormal(srce, dest, index, increment, todo); + if (md_mode & DMODE_SIMDMIXER) { + return MixSIMDStereoNormal(srce, dest, idx, increment, todo); } else #endif @@ -297,17 +304,17 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i SLONG rvolsel = vnf->rvolsel; while(todo--) { - sample=srce[(index += increment) >> FRACBITS]; + sample=srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel * sample; *dest++ += rvolsel * sample; } } - return index; + return idx; } - -static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { SWORD sample; SLONG lvolsel = vnf->lvolsel; @@ -315,25 +322,26 @@ static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG if (lvolsel>=rvolsel) { while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel*sample; *dest++ -= lvolsel*sample; } - } else { + } + else { while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ -= rvolsel*sample; *dest++ += rvolsel*sample; } } - return index; + return idx; } -static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -342,33 +350,33 @@ static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc if (rampvol) { SLONG oldlvol = vnf->oldlvol - lvolsel; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; + * sample >> CLICK_SHIFT; if (!--rampvol) break; } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += lvolsel * sample; } - return index; + return idx; } -static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -379,13 +387,13 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i SLONG oldlvol = vnf->oldlvol - lvolsel; SLONG oldrvol = vnf->oldrvol - rvolsel; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; + * sample >> CLICK_SHIFT; *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) * sample >> CLICK_SHIFT; if (!--rampvol) @@ -393,22 +401,22 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += lvolsel * sample; *dest++ += rvolsel * sample; } - return index; + return idx; } -static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) +static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -427,13 +435,13 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG if (rampvol) { oldvol -= vol; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; sample=((vol << CLICK_SHIFT) + oldvol * rampvol) - * sample >> CLICK_SHIFT; + * sample >> CLICK_SHIFT; *dest++ += sample; *dest++ -= sample; @@ -442,55 +450,55 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += vol*sample; *dest++ -= vol*sample; } - return index; + return idx; } #endif /*========== 64 bit sample mixers - all platforms */ -static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SWORD sample; SLONG lvolsel = vnf->lvolsel; while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel * sample; } - return index; + return idx; } -static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SWORD sample; SLONG lvolsel = vnf->lvolsel; SLONG rvolsel = vnf->rvolsel; while(todo--) { - sample=srce[index >> FRACBITS]; - index += increment; + sample=srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel * sample; *dest++ += rvolsel * sample; } - return index; + return idx; } -static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SWORD sample; SLONG lvolsel = vnf->lvolsel; @@ -498,25 +506,26 @@ static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index if(vnf->lvolsel>=vnf->rvolsel) { while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ += lvolsel*sample; *dest++ -= lvolsel*sample; } - } else { + } + else { while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; + sample = srce[idx >> FRACBITS]; + idx += increment; *dest++ -= rvolsel*sample; *dest++ += rvolsel*sample; } } - return index; + return idx; } -static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -525,10 +534,10 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO if (rampvol) { SLONG oldlvol = vnf->oldlvol - lvolsel; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) * sample >> CLICK_SHIFT; @@ -537,21 +546,21 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += lvolsel * sample; } - return index; + return idx; } -static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -562,10 +571,10 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S SLONG oldlvol = vnf->oldlvol - lvolsel; SLONG oldrvol = vnf->oldrvol - rvolsel; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) * sample >> CLICK_SHIFT; @@ -576,22 +585,22 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += lvolsel * sample; *dest++ += rvolsel * sample; } - return index; + return idx; } -static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) +static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) { SLONG sample; SLONG lvolsel = vnf->lvolsel; @@ -610,13 +619,13 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index if (rampvol) { oldvol -= vol; while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; sample=((vol << CLICK_SHIFT) + oldvol * rampvol) - * sample >> CLICK_SHIFT; + * sample >> CLICK_SHIFT; *dest++ += sample; *dest++ -= sample; if (!--rampvol) @@ -624,19 +633,19 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index } vnf->rampvol = rampvol; if (todo < 0) - return index; + return idx; } while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; + sample=(SLONG)srce[idx>>FRACBITS]+ + ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) + *(idx&FRACMASK)>>FRACBITS); + idx += increment; *dest++ += vol*sample; *dest++ -= vol*sample; } - return index; + return idx; } static void (*MixReverb)(SLONG* srce,NATIVE count); @@ -673,7 +682,7 @@ static void MixReverb_Normal(SLONG* srce,NATIVE count) /* left channel */ *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; + RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; } } @@ -710,10 +719,10 @@ static void MixReverb_Stereo(SLONG* srce,NATIVE count) /* left channel then right channel */ *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; + RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ - RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; + RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; } } @@ -839,58 +848,56 @@ static void Mix32To8(SBYTE* dste,const SLONG *srce,NATIVE count) #if defined HAVE_ALTIVEC || defined HAVE_SSE2 -// Mix 32bit input to floating point. 32 samples per iteration -// PC: ?, Mac OK -static void Mix32ToFP_SIMD(float* dste,SLONG* srce,NATIVE count) +/* Mix 32bit input to floating point. 32 samples per iteration */ +/* PC: ?, Mac OK */ +static void Mix32ToFP_SIMD(float* dste,const SLONG* srce,NATIVE count) { - int remain=count; + const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT)); + int remain=count; + simd_m128 x1, x2, xk; while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) { - float x1; - EXTRACT_SAMPLE_FP(x1,FP_SHIFT); - CHECK_SAMPLE_FP(x1,1.0f); - PUT_SAMPLE_FP(x1); + float xf; + EXTRACT_SAMPLE_FP(xf,FP_SHIFT); + CHECK_SAMPLE_FP(xf,1.0f); + PUT_SAMPLE_FP(xf); count--; - if (!count) - { - return; - } + if (!count) return; } - remain = count&7; - - const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT)); - simd_m128 x1, x2; - simd_m128 xk = LOAD_PS1_SIMD(&k); // Scale factor + remain = count&7; + + xk = LOAD_PS1_SIMD(&k); /* Scale factor */ for(count>>=3;count;count--) { - EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples - EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); // Load 4 samples - PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples - PUT_SAMPLE_SIMD_F(dste+4, x2); // Store 4 samples - srce+=8; - dste+=8; - } + EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */ + EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); /* Load 4 samples */ + PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */ + PUT_SAMPLE_SIMD_F(dste+4, x2); /* Store 4 samples */ + srce+=8; + dste+=8; + } if (remain&4) { - EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples - PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples - srce+=4; - dste+=4; - remain &= 3; - } + EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */ + PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */ + srce+=4; + dste+=4; + remain &= 3; + } while(remain--) { - float x1; - EXTRACT_SAMPLE_FP(x1,FP_SHIFT); - CHECK_SAMPLE_FP(x1,1.0f); - PUT_SAMPLE_FP(x1); + float xf; + EXTRACT_SAMPLE_FP(xf,FP_SHIFT); + CHECK_SAMPLE_FP(xf,1.0f); + PUT_SAMPLE_FP(xf); } } -// PC: Ok, Mac Ok -static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) -{ + +/* PC: Ok, Mac Ok */ +static void Mix32To16_SIMD(SWORD* dste,const SLONG* srce,NATIVE count) +{ int remain = count; while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) @@ -900,34 +907,31 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) CHECK_SAMPLE(x1,32768); PUT_SAMPLE(x1); count--; - if (!count) - { - return; - } + if (!count) return; } remain = count&7; - for(count>>=3;count;count--) + for(count>>=3;count;count--) { simd_m128i x1,x2; - EXTRACT_SAMPLE_SIMD_16(srce, x1); // Load 4 samples - EXTRACT_SAMPLE_SIMD_16(srce+4, x2); // Load 4 samples - PUT_SAMPLE_SIMD_W(dste, x1, x2); // Store 8 samples + EXTRACT_SAMPLE_SIMD_16(srce, x1); /* Load 4 samples */ + EXTRACT_SAMPLE_SIMD_16(srce+4, x2); /* Load 4 samples */ + PUT_SAMPLE_SIMD_W(dste, x1, x2); /* Store 8 samples */ srce+=8; dste+=8; } if (remain) - Mix32To16(dste, srce, remain); + Mix32To16(dste, srce, remain); } -// Mix 32bit input to 8bit. 128 samples per iteration -// PC:OK, Mac: Ok -static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) -{ +/* Mix 32bit input to 8bit. 128 samples per iteration */ +/* PC:OK, Mac: Ok */ +static void Mix32To8_SIMD(SBYTE* dste,const SLONG* srce,NATIVE count) +{ int remain=count; - + while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) { SWORD x1; @@ -935,32 +939,29 @@ static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) CHECK_SAMPLE(x1,128); PUT_SAMPLE(x1+128); count--; - if (!count) - { - return; - } + if (!count) return; } - + remain = count&15; for(count>>=4;count;count--) { - simd_m128i x1,x2,x3,x4; - EXTRACT_SAMPLE_SIMD_8(srce, x1); // Load 4 samples - EXTRACT_SAMPLE_SIMD_8(srce+4, x2); // Load 4 samples - EXTRACT_SAMPLE_SIMD_8(srce+8, x3); // Load 4 samples - EXTRACT_SAMPLE_SIMD_8(srce+12, x4); // Load 4 samples - PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); // Store 16 samples - srce+=16; - dste+=16; + simd_m128i x1,x2,x3,x4; + EXTRACT_SAMPLE_SIMD_8(srce, x1); /* Load 4 samples */ + EXTRACT_SAMPLE_SIMD_8(srce+4, x2); /* Load 4 samples */ + EXTRACT_SAMPLE_SIMD_8(srce+8, x3); /* Load 4 samples */ + EXTRACT_SAMPLE_SIMD_8(srce+12, x4); /* Load 4 samples */ + PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); /* Store 16 samples */ + srce+=16; + dste+=16; } + if (remain) - Mix32To8(dste, srce, remain); + Mix32To8(dste, srce, remain); } #endif - static void AddChannel(SLONG* ptr,NATIVE todo) { SLONGLONG end,done; @@ -1050,65 +1051,64 @@ static void AddChannel(SLONG* ptr,NATIVE todo) if(vc_mode & DMODE_STEREO) { if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) vnf->current=Mix32SurroundInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); else vnf->current=Mix32StereoInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } else vnf->current=Mix32MonoInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } else if(vc_mode & DMODE_STEREO) { if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) vnf->current=Mix32SurroundNormal - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); else { #if defined HAVE_ALTIVEC || defined HAVE_SSE2 - if (md_mode & DMODE_SIMDMIXER) + if (md_mode & DMODE_SIMDMIXER) vnf->current=MixSIMDStereoNormal - (s,ptr,vnf->current,vnf->increment,done); - - else + (s,ptr,vnf->current,vnf->increment,done); + else #endif vnf->current=Mix32StereoNormal - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } } else vnf->current=Mix32MonoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else + (s,ptr,vnf->current,vnf->increment,done); + } + else #endif - { + { if((md_mode & DMODE_INTERP)) { if(vc_mode & DMODE_STEREO) { if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) vnf->current=MixSurroundInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); else vnf->current=MixStereoInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } else vnf->current=MixMonoInterp - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } else if(vc_mode & DMODE_STEREO) { if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) vnf->current=MixSurroundNormal - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); else { #if defined HAVE_ALTIVEC || defined HAVE_SSE2 - if (md_mode & DMODE_SIMDMIXER) + if (md_mode & DMODE_SIMDMIXER) vnf->current=MixSIMDStereoNormal - (s,ptr,vnf->current,vnf->increment,done); - - else + (s,ptr,vnf->current,vnf->increment,done); + else #endif vnf->current=MixStereoNormal - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } } else vnf->current=MixMonoNormal - (s,ptr,vnf->current,vnf->increment,done); + (s,ptr,vnf->current,vnf->increment,done); } } else /* update sample position */ @@ -1119,6 +1119,33 @@ static void AddChannel(SLONG* ptr,NATIVE todo) } } +#ifdef NO_HQMIXER +#define VC_SetupPointers() do{}while(0) +#define VC1_Init VC_Init +#define VC1_Exit VC_Exit +#define VC1_PlayStart VC_PlayStart +#define VC1_PlayStop VC_PlayStop +#define VC1_SampleLength VC_SampleLength +#define VC1_SampleSpace VC_SampleSpace +#define VC1_SampleLoad VC_SampleLoad +#define VC1_SampleUnload VC_SampleUnload +#define VC1_SetNumVoices VC_SetNumVoices +#define VC1_SilenceBytes VC_SilenceBytes +#define VC1_VoicePlay VC_VoicePlay +#define VC1_VoiceStop VC_VoiceStop +#define VC1_VoiceGetFrequency VC_VoiceGetFrequency +#define VC1_VoiceGetPanning VC_VoiceGetPanning +#define VC1_VoiceGetPosition VC_VoiceGetPosition +#define VC1_VoiceGetVolume VC_VoiceGetVolume +#define VC1_VoiceRealVolume VC_VoiceRealVolume +#define VC1_VoiceSetFrequency VC_VoiceSetFrequency +#define VC1_VoiceSetPanning VC_VoiceSetPanning +#define VC1_VoiceSetVolume VC_VoiceSetVolume +#define VC1_VoiceStopped VC_VoiceStopped +#define VC1_WriteBytes VC_WriteBytes +#define VC1_WriteSamples VC_WriteSamples +#endif + #define _IN_VIRTCH_ #include "virtch_common.c" #undef _IN_VIRTCH_ @@ -1190,7 +1217,6 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo) vc_callback((unsigned char*)vc_tickbuf, portion); } - #if defined HAVE_ALTIVEC || defined HAVE_SSE2 if (md_mode & DMODE_SIMDMIXER) { @@ -1219,20 +1245,23 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo) int VC1_Init(void) { +#ifndef NO_HQMIXER VC_SetupPointers(); - - //if (md_mode&DMODE_HQMIXER) - // return VC2_Init(); - if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { + if (md_mode&DMODE_HQMIXER) + return VC2_Init(); +#endif + + if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) { _mm_errno = MMERR_INITIALIZING_MIXER; return 1; } - if(!vc_tickbuf) - if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { + if(!vc_tickbuf) { + if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) { _mm_errno = MMERR_INITIALIZING_MIXER; return 1; } + } MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal; MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal; @@ -1264,14 +1293,17 @@ int VC1_PlayStart(void) if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; - if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; - if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; - if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; - if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; - if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; - if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; - if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; - if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; + /* allocate reverb buffers for the right channel if in stereo mode only. */ + if (vc_mode & DMODE_STEREO) { + if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; + if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; + if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; + if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; + if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; + if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; + if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; + if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; + } RVRindex = 0; return 0; @@ -1279,23 +1311,23 @@ int VC1_PlayStart(void) void VC1_PlayStop(void) { - if(RVbufL1) MikMod_free(RVbufL1); - if(RVbufL2) MikMod_free(RVbufL2); - if(RVbufL3) MikMod_free(RVbufL3); - if(RVbufL4) MikMod_free(RVbufL4); - if(RVbufL5) MikMod_free(RVbufL5); - if(RVbufL6) MikMod_free(RVbufL6); - if(RVbufL7) MikMod_free(RVbufL7); - if(RVbufL8) MikMod_free(RVbufL8); + MikMod_free(RVbufL1); + MikMod_free(RVbufL2); + MikMod_free(RVbufL3); + MikMod_free(RVbufL4); + MikMod_free(RVbufL5); + MikMod_free(RVbufL6); + MikMod_free(RVbufL7); + MikMod_free(RVbufL8); RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; - if(RVbufR1) MikMod_free(RVbufR1); - if(RVbufR2) MikMod_free(RVbufR2); - if(RVbufR3) MikMod_free(RVbufR3); - if(RVbufR4) MikMod_free(RVbufR4); - if(RVbufR5) MikMod_free(RVbufR5); - if(RVbufR6) MikMod_free(RVbufR6); - if(RVbufR7) MikMod_free(RVbufR7); - if(RVbufR8) MikMod_free(RVbufR8); + MikMod_free(RVbufR1); + MikMod_free(RVbufR2); + MikMod_free(RVbufR3); + MikMod_free(RVbufR4); + MikMod_free(RVbufR5); + MikMod_free(RVbufR6); + MikMod_free(RVbufR7); + MikMod_free(RVbufR8); RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; } @@ -1305,8 +1337,8 @@ int VC1_SetNumVoices(void) if(!(vc_softchn=md_softchn)) return 0; - if(vinf) MikMod_free(vinf); - if(!(vinf= MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1; + MikMod_free(vinf); + if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1; for(t=0;t