- Vereinfache Code

- Reformatiere
This commit is contained in:
Yamagi Burmeister 2010-10-14 06:14:35 +00:00
parent 2b405405dc
commit a8a61f0234
1 changed files with 287 additions and 283 deletions

View File

@ -20,8 +20,8 @@
* ======================================================================= * =======================================================================
* *
* This code mixes two or more sound samples into one. It also * This code mixes two or more sound samples into one. It also
* implements sample rate changing and per channel extraction. It's * implements the calls to sample rate changing and per channel extraction.
* called by the upper level sound framework, snd_dma.c * It's called by the upper level sound framework, snd_dma.c
* *
* ======================================================================= * =======================================================================
*/ */
@ -31,69 +31,14 @@
#define PAINTBUFFER_SIZE 2048 #define PAINTBUFFER_SIZE 2048
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE]; portable_samplepair_t paintbuffer [ PAINTBUFFER_SIZE ];
int snd_scaletable[32][256]; int snd_scaletable [ 32 ] [ 256 ];
int *snd_p, snd_linear_count, snd_vol; int *snd_p, snd_linear_count, snd_vol;
short *snd_out; short *snd_out;
void S_WriteLinearBlastStereo16 (void) { void
int i; S_TransferPaintBuffer ( int endtime )
int val; {
for (i=0 ; i<snd_linear_count ; i+=2) {
val = snd_p[i]>>8;
if (val > 0x7fff)
snd_out[i] = 0x7fff;
else if (val < (short)0x8000)
snd_out[i] = (short)0x8000;
else
snd_out[i] = val;
val = snd_p[i+1]>>8;
if (val > 0x7fff)
snd_out[i+1] = 0x7fff;
else if (val < (short)0x8000)
snd_out[i+1] = (short)0x8000;
else
snd_out[i+1] = val;
}
}
void S_TransferStereo16 (unsigned long *pbuf, int endtime) {
int lpos;
int lpaintedtime;
snd_p = (int *) paintbuffer;
lpaintedtime = paintedtime;
while (lpaintedtime < endtime) {
/* handle recirculating buffer issues */
lpos = lpaintedtime & ((dma.samples>>1)-1);
snd_out = (short *) pbuf + (lpos<<1);
snd_linear_count = (dma.samples>>1) - lpos;
if (lpaintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - lpaintedtime;
snd_linear_count <<= 1;
/* write a linear blast of samples */
S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count;
lpaintedtime += (snd_linear_count>>1);
}
}
void S_TransferPaintBuffer(int endtime) {
int out_idx; int out_idx;
int count; int count;
int out_mask; int out_mask;
@ -102,241 +47,114 @@ void S_TransferPaintBuffer(int endtime) {
int val; int val;
unsigned long *pbuf; unsigned long *pbuf;
pbuf = (unsigned long *)dma.buffer; pbuf = (unsigned long *) dma.buffer;
if (s_testsound->value) { if ( s_testsound->value )
{
int i; int i;
int count; int count;
// write a fixed sine wave /* write a fixed sine wave */
count = (endtime - paintedtime); count = ( endtime - paintedtime );
for (i=0 ; i<count ; i++)
paintbuffer[i].left = paintbuffer[i].right = (int)((float)sin((paintedtime+i)*0.1f)*20000*256);
for ( i = 0; i < count; i++ )
{
paintbuffer [ i ].left = paintbuffer [ i ].right = (int) ( (float) sin( ( paintedtime + i ) * 0.1f ) * 20000 * 256 );
}
} }
if (dma.samplebits == 16 && dma.channels == 2) {
/* optimized case */
S_TransferStereo16 (pbuf, endtime);
} else {
/* general case */
p = (int *) paintbuffer; p = (int *) paintbuffer;
count = (endtime - paintedtime) * dma.channels; count = ( endtime - paintedtime ) * dma.channels;
out_mask = dma.samples - 1; out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask; out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels; step = 3 - dma.channels;
if (dma.samplebits == 16) { if ( dma.samplebits == 16 )
{
short *out = (short *) pbuf; short *out = (short *) pbuf;
while (count--) { while ( count-- )
{
val = *p >> 8; val = *p >> 8;
p+= step; p += step;
if (val > 0x7fff) if ( val > 0x7fff )
{
val = 0x7fff; val = 0x7fff;
else if (val < (short)0x8000)
val = (short)0x8000;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
} }
} else if (dma.samplebits == 8) { else if ( val < (short) 0x8000 )
{
val = (short) 0x8000;
}
out [ out_idx ] = val;
out_idx = ( out_idx + 1 ) & out_mask;
}
}
else if ( dma.samplebits == 8 )
{
unsigned char *out = (unsigned char *) pbuf; unsigned char *out = (unsigned char *) pbuf;
while (count--) { while ( count-- )
{
val = *p >> 8; val = *p >> 8;
p+= step; p += step;
if (val > 0x7fff) if ( val > 0x7fff )
{
val = 0x7fff; val = 0x7fff;
else if (val < (short)0x8000)
val = (short)0x8000;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
} }
}
}
}
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset); else if ( val < (short) 0x8000 )
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
void S_PaintChannels(int endtime) {
int i;
int end;
channel_t *ch;
sfxcache_t *sc;
int ltime, count;
playsound_t *ps;
snd_vol = (int)(s_volume->value*256);
while (paintedtime < endtime) {
/* if paintbuffer is smaller than DMA buffer */
end = endtime;
if (endtime - paintedtime > PAINTBUFFER_SIZE)
end = paintedtime + PAINTBUFFER_SIZE;
/* start any playsounds */
if (endtime - paintedtime > PAINTBUFFER_SIZE)
end = paintedtime + PAINTBUFFER_SIZE;
// start any playsounds
for (;;)
{ {
ps = s_pendingplays.next; val = (short) 0x8000;
if (ps == NULL)
break;
if (ps == &s_pendingplays)
break; // no more pending sounds
if (ps->begin <= paintedtime)
{
S_IssuePlaysound (ps);
continue;
} }
if (ps->begin < end) out [ out_idx ] = ( val >> 8 ) + 128;
end = ps->begin; // stop here out_idx = ( out_idx + 1 ) & out_mask;
break;
} }
/* clear the paint buffer */
if (s_rawend < paintedtime) {
memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
} else {
/* copy from the streaming sound source */
int s;
int stop;
stop = (end < s_rawend) ? end : s_rawend;
for (i=paintedtime ; i<stop ; i++) {
s = i&(MAX_RAW_SAMPLES-1);
paintbuffer[i-paintedtime] = s_rawsamples[s];
}
for ( ; i<end ; i++) {
paintbuffer[i-paintedtime].left = paintbuffer[i-paintedtime].right = 0;
}
}
/* paint in the channels. */
ch = channels;
for (i=0; i<MAX_CHANNELS ; i++, ch++) {
ltime = paintedtime;
while (ltime < end) {
if (!ch->sfx || (!ch->leftvol && !ch->rightvol) )
break;
/* max painting is to the end of the buffer */
count = end - ltime;
/* might be stopped by running out of data */
if (ch->end - ltime < count)
count = ch->end - ltime;
sc = S_LoadSound (ch->sfx);
if (!sc)
break;
if (count > 0 && ch->sfx) {
if (sc->width == 1)
S_PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
else
S_PaintChannelFrom16(ch, sc, count, ltime - paintedtime);
ltime += count;
}
/* if at end of loop, restart */
if (ltime >= ch->end) {
if (ch->autosound) {
/* autolooping sounds always go back to start */
ch->pos = 0;
ch->end = ltime + sc->length;
} else if (sc->loopstart >= 0) {
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
} else {
/* channel just stopped */
ch->sfx = NULL;
}
}
}
}
/* transfer out according to DMA format */
S_TransferPaintBuffer(end);
paintedtime = end;
} }
} }
void S_InitScaletable (void) { void
int i, j; S_PaintChannelFrom8 ( channel_t *ch, sfxcache_t *sc, int count, int offset )
int scale; {
if (s_volume->value > 2.0f)
Cvar_Set ("s_volume", "2");
else if (s_volume->value < 0)
Cvar_Set ("s_volume", "0");
s_volume->modified = false;
for (i=0 ; i<32 ; i++) {
scale = (int)(i * 8 * 256 * s_volume->value);
for (j=0 ; j<256 ; j++)
snd_scaletable[i][j] = ((signed char)j) * scale;
}
}
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset) {
int data; int data;
int *lscale, *rscale; int *lscale, *rscale;
unsigned char *sfx; unsigned char *sfx;
int i; int i;
portable_samplepair_t *samp; portable_samplepair_t *samp;
if (ch->leftvol > 255) if ( ch->leftvol > 255 )
{
ch->leftvol = 255; ch->leftvol = 255;
}
if (ch->rightvol > 255) if ( ch->rightvol > 255 )
{
ch->rightvol = 255; ch->rightvol = 255;
}
lscale = snd_scaletable[ ch->leftvol >> 3]; lscale = snd_scaletable [ ch->leftvol >> 3 ];
rscale = snd_scaletable[ ch->rightvol >> 3]; rscale = snd_scaletable [ ch->rightvol >> 3 ];
sfx = sc->data + ch->pos; sfx = sc->data + ch->pos;
samp = &paintbuffer[offset]; samp = &paintbuffer [ offset ];
for (i=0 ; i<count ; i++, samp++) { for ( i = 0; i < count; i++, samp++ )
data = sfx[i]; {
samp->left += lscale[data]; data = sfx [ i ];
samp->right += rscale[data]; samp->left += lscale [ data ];
samp->right += rscale [ data ];
} }
ch->pos += count; ch->pos += count;
} }
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset) { void
S_PaintChannelFrom16 ( channel_t *ch, sfxcache_t *sc, int count, int offset )
{
int data; int data;
int left, right; int left, right;
int leftvol, rightvol; int leftvol, rightvol;
@ -344,16 +162,17 @@ void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
int i; int i;
portable_samplepair_t *samp; portable_samplepair_t *samp;
leftvol = ch->leftvol*snd_vol; leftvol = ch->leftvol * snd_vol;
rightvol = ch->rightvol*snd_vol; rightvol = ch->rightvol * snd_vol;
sfx = (signed short *)sc->data + ch->pos; sfx = (signed short *) sc->data + ch->pos;
samp = &paintbuffer[offset]; samp = &paintbuffer [ offset ];
for (i=0 ; i<count ; i++, samp++) { for ( i = 0; i < count; i++, samp++ )
data = sfx[i]; {
left = (data * leftvol)>>8; data = sfx [ i ];
right = (data * rightvol)>>8; left = ( data * leftvol ) >> 8;
right = ( data * rightvol ) >> 8;
samp->left += left; samp->left += left;
samp->right += right; samp->right += right;
} }
@ -361,3 +180,188 @@ void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
ch->pos += count; ch->pos += count;
} }
void
S_PaintChannels ( int endtime )
{
int i;
int end;
channel_t *ch;
sfxcache_t *sc;
int ltime, count;
playsound_t *ps;
snd_vol = (int) ( s_volume->value * 256 );
while ( paintedtime < endtime )
{
/* if paintbuffer is smaller than DMA buffer */
end = endtime;
if ( endtime - paintedtime > PAINTBUFFER_SIZE )
{
end = paintedtime + PAINTBUFFER_SIZE;
}
/* start any playsounds */
if ( endtime - paintedtime > PAINTBUFFER_SIZE )
{
end = paintedtime + PAINTBUFFER_SIZE;
}
/* start any playsounds */
for ( ; ; )
{
ps = s_pendingplays.next;
if ( ps == NULL )
{
break;
}
if ( ps == &s_pendingplays )
{
break; /* no more pending sounds */
}
if ( ps->begin <= paintedtime )
{
S_IssuePlaysound( ps );
continue;
}
if ( ps->begin < end )
{
end = ps->begin; /* stop here */
}
break;
}
/* clear the paint buffer */
if ( s_rawend < paintedtime )
{
memset( paintbuffer, 0, ( end - paintedtime ) * sizeof ( portable_samplepair_t ) );
}
else
{
/* copy from the streaming sound source */
int s;
int stop;
stop = ( end < s_rawend ) ? end : s_rawend;
for ( i = paintedtime; i < stop; i++ )
{
s = i & ( MAX_RAW_SAMPLES - 1 );
paintbuffer [ i - paintedtime ] = s_rawsamples [ s ];
}
for ( ; i < end; i++ )
{
paintbuffer [ i - paintedtime ].left = paintbuffer [ i - paintedtime ].right = 0;
}
}
/* paint in the channels. */
ch = channels;
for ( i = 0; i < MAX_CHANNELS; i++, ch++ )
{
ltime = paintedtime;
while ( ltime < end )
{
if ( !ch->sfx || ( !ch->leftvol && !ch->rightvol ) )
{
break;
}
/* max painting is to the end of the buffer */
count = end - ltime;
/* might be stopped by running out of data */
if ( ch->end - ltime < count )
{
count = ch->end - ltime;
}
sc = S_LoadSound( ch->sfx );
if ( !sc )
{
break;
}
if ( ( count > 0 ) && ch->sfx )
{
if ( sc->width == 1 )
{
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
}
else
{
S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
}
ltime += count;
}
/* if at end of loop, restart */
if ( ltime >= ch->end )
{
if ( ch->autosound )
{
/* autolooping sounds always go back to start */
ch->pos = 0;
ch->end = ltime + sc->length;
}
else if ( sc->loopstart >= 0 )
{
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
}
else
{
/* channel just stopped */
ch->sfx = NULL;
}
}
}
}
/* transfer out according to DMA format */
S_TransferPaintBuffer( end );
paintedtime = end;
}
}
/* This is called from snd_dma.c */
void
S_InitScaletable ( void )
{
int i, j;
int scale;
if ( s_volume->value > 2.0f )
{
Cvar_Set( "s_volume", "2" );
}
else if ( s_volume->value < 0 )
{
Cvar_Set( "s_volume", "0" );
}
s_volume->modified = false;
for ( i = 0; i < 32; i++ )
{
scale = (int) ( i * 8 * 256 * s_volume->value );
for ( j = 0; j < 256; j++ )
{
snd_scaletable [ i ] [ j ] = ( (signed char) j ) * scale;
}
}
}