Skip to content

Commit

Permalink
Updated virtch2. Fixed mmio.c
Browse files Browse the repository at this point in the history
  • Loading branch information
realtech committed Mar 30, 2005
1 parent db71aa3 commit b081973
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 58 deletions.
15 changes: 8 additions & 7 deletions mmio/mmio.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


/*============================================================================== /*==============================================================================
$Id: mmio.c,v 1.1 2005/03/30 01:31:01 raphassenat Exp $ $Id: mmio.c,v 1.2 2005/03/30 17:42:34 realtech Exp $
Portable file I/O routines Portable file I/O routines
Expand Down Expand Up @@ -245,33 +245,34 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len)
return (MREADER*)reader; return (MREADER*)reader;
} }



static BOOL _mm_MemReader_Eof(MREADER* reader) static BOOL _mm_MemReader_Eof(MREADER* reader)
{ {
if (!reader) { return 1; } if (!reader) { return 1; }
if ( ((MMEMREADER*)reader)->pos >= ((MMEMREADER*)reader)->len ) { if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
return 1; return 1;
} }
return 0; return 0;
} }


static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) static BOOL _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
{ {
unsigned char *d=ptr; unsigned char *d=ptr, *s;
const unsigned char *s;

if (!reader) { return 0; } if (!reader) { return 0; }


if (reader->Eof(reader)) { return 0; } if (reader->Eof(reader)) { return 0; }


s = ((MMEMREADER*)reader)->buffer; s = ((MMEMREADER*)reader)->buffer;
s += ((MMEMREADER*)reader)->pos; s += ((MMEMREADER*)reader)->pos;


if ( ((MMEMREADER*)reader)->pos + size >= ((MMEMREADER*)reader)->len - 1) if ( ((MMEMREADER*)reader)->pos + size > ((MMEMREADER*)reader)->len)
{ {
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
return 0; /* not enough remaining bytes */ return 0; /* not enough remaining bytes */
} }


((MMEMREADER*)reader)->pos += (long)size; ((MMEMREADER*)reader)->pos += size;


while (size--) while (size--)
{ {
Expand Down
264 changes: 213 additions & 51 deletions playercode/virtch2.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


/*============================================================================== /*==============================================================================
$Id: virtch2.c,v 1.1 2005/03/30 01:31:05 raphassenat Exp $ $Id: virtch2.c,v 1.2 2005/03/30 17:42:36 realtech Exp $
High-quality sample mixing routines, using a 32 bits mixing buffer, High-quality sample mixing routines, using a 32 bits mixing buffer,
interpolation, and sample smoothing to improve sound quality and remove interpolation, and sample smoothing to improve sound quality and remove
Expand Down Expand Up @@ -308,46 +308,208 @@ static SLONGLONG MixMonoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG ind
} }


// Slowest part... // Slowest part...

#if defined HAVE_SSE2 || defined HAVE_ALTIVEC

static __inline SWORD GetSample(const SWORD* const srce, SLONGLONG index)
{
SLONGLONG i=index>>FRACBITS;
SLONGLONG f=index&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 index,SLONGLONG increment,ULONG todo)
{
SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel};
SWORD s[8];
SWORD sample=0;
SLONG remain = todo;

// Dest can be misaligned ...
while(!IS_ALIGNED_16(dest)) {
sample=srce[(index += increment) >> FRACBITS];
*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
todo--;
}

// 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, index += increment);
SWORD s1 = GetSample(srce, index += increment);
SWORD s2 = GetSample(srce, index += increment);
SWORD s3 = GetSample(srce, index += 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;
}
}

#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
));


for(todo>>=2;todo; todo--)
{
// Load constants
s[0] = GetSample(srce, index += increment);
s[1] = GetSample(srce, index += increment);
s[2] = GetSample(srce, index += increment);
s[3] = GetSample(srce, index += increment);
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);
vec_st(vec_add(v4, v6), 0, dest + 4);

dest+=8;
}
}
#endif // HAVE_ALTIVEC

// Remaining bits ...
while(remain--) {
sample=GetSample(srce, index+= increment);

*dest++ += vol[0] * sample;
*dest++ += vol[1] * sample;
}


vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample;
return index;
}

#endif


static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo) static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo)
{ {
SWORD sample=0; SWORD sample=0;
SLONGLONG i,f; SLONGLONG i,f;


while(todo--) { if (vnf->rampvol)
while(todo) {
todo--;
i=index>>FRACBITS,f=index&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
index += 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=index>>FRACBITS,f=index&FRACMASK; i=index>>FRACBITS,f=index&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); ((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
index += increment; index += increment;


if(vnf->rampvol) { *dest++ += (long)(
*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--;
} else
if(vnf->click) {
*dest++ += (long)(
( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) *
(SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) ) (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) )
>> CLICK_SHIFT ); >> CLICK_SHIFT );
*dest++ += (long)(
*dest++ += (long)(
( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) *
(SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) ) (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) )
>> CLICK_SHIFT ); >> CLICK_SHIFT );
vnf->click--; vnf->click--;
} else {
*dest++ +=vnf->lvolsel*sample; if (!vnf->click)
*dest++ +=vnf->rvolsel*sample; break;
}


if (todo)
{
#if defined HAVE_SSE2 || defined HAVE_ALTIVEC
if (md_mode & DMODE_SIMDMIXER)
{
index = MixSIMDStereoNormal(srce, dest, index, increment, todo);
} }
else
#endif
{

while(todo)
{
i=index>>FRACBITS,
f=index&FRACMASK;
sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) +
((SLONGLONG)srce[i+1] * f)) >> FRACBITS));
index += increment;

*dest++ +=vnf->lvolsel*sample;
*dest++ +=vnf->rvolsel*sample;
todo--;
}
}
} }
vnf->lastvalL=vnf->lvolsel*sample;
vnf->lastvalR=vnf->rvolsel*sample;

return index; return index;
} }


Expand Down Expand Up @@ -476,37 +638,37 @@ static void (*MixLowPass)(SLONG* srce,NATIVE count);
static int nLeftNR, nRightNR; static int nLeftNR, nRightNR;


static void MixLowPass_Stereo(SLONG* srce,NATIVE count) static void MixLowPass_Stereo(SLONG* srce,NATIVE count)
{ {
int n1 = nLeftNR, n2 = nRightNR; int n1 = nLeftNR, n2 = nRightNR;
SLONG *pnr = srce; SLONG *pnr = srce;
int nr=count; int nr=count;
for (; nr; nr--) for (; nr; nr--)
{ {
int vnr = pnr[0] >> 1; int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1; pnr[0] = vnr + n1;
n1 = vnr; n1 = vnr;
vnr = pnr[1] >> 1; vnr = pnr[1] >> 1;
pnr[1] = vnr + n2; pnr[1] = vnr + n2;
n2 = vnr; n2 = vnr;
pnr += 2; pnr += 2;
} }
nLeftNR = n1; nLeftNR = n1;
nRightNR = n2; nRightNR = n2;
} }


static void MixLowPass_Normal(SLONG* srce,NATIVE count) static void MixLowPass_Normal(SLONG* srce,NATIVE count)
{ {
int n1 = nLeftNR; int n1 = nLeftNR;
SLONG *pnr = srce; SLONG *pnr = srce;
int nr=count; int nr=count;
for (; nr; nr--) for (; nr; nr--)
{ {
int vnr = pnr[0] >> 1; int vnr = pnr[0] >> 1;
pnr[0] = vnr + n1; pnr[0] = vnr + n1;
n1 = vnr; n1 = vnr;
pnr ++; pnr ++;
} }
nLeftNR = n1; nLeftNR = n1;
} }


/* Mixing macros */ /* Mixing macros */
Expand Down Expand Up @@ -1157,4 +1319,4 @@ BOOL VC2_SetNumVoices(void)
return 0; return 0;
} }


/* ex:set ts=4: */ /* ex:set ts=4: */

0 comments on commit b081973

Please sign in to comment.