forked from len0rd/rockbox
duke3d: rewrite sound mixing to use fixed-point
Gives significant performance improvement on ipod6g. Change-Id: I1e8462bec197acb10e770c796240b5001df52440
This commit is contained in:
parent
78db1d9502
commit
9f6ce046cb
10 changed files with 476 additions and 449 deletions
|
@ -195,4 +195,17 @@ void fatal(char *fmt, ...);
|
||||||
void rb_exit(int rc);
|
void rb_exit(int rc);
|
||||||
void rbsdl_atexit(void (*)(void));
|
void rbsdl_atexit(void (*)(void));
|
||||||
|
|
||||||
|
/* speed */
|
||||||
|
static inline uint16_t readLE16(void *addr)
|
||||||
|
{
|
||||||
|
uint8_t *ptr = addr;
|
||||||
|
return (*(ptr+1) << 8) | *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t readLE32(void *addr)
|
||||||
|
{
|
||||||
|
uint8_t *ptr = addr;
|
||||||
|
return (*(ptr+3) << 24) |(*(ptr+2) << 16) | (*(ptr+1) << 8) | *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _SDL_config_rockbox_h */
|
#endif /* _SDL_config_rockbox_h */
|
||||||
|
|
|
@ -39,6 +39,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../global.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "dpmi.h"
|
#include "dpmi.h"
|
||||||
#include "usrhooks.h"
|
#include "usrhooks.h"
|
||||||
|
@ -120,7 +122,8 @@ static int MV_FooMemory;
|
||||||
static int MV_BufferDescriptor;
|
static int MV_BufferDescriptor;
|
||||||
static int MV_BufferEmpty[ NumberOfBuffers ];
|
static int MV_BufferEmpty[ NumberOfBuffers ];
|
||||||
char *MV_MixBuffer[ NumberOfBuffers + 1 ];
|
char *MV_MixBuffer[ NumberOfBuffers + 1 ];
|
||||||
double *MV_FooBuffer = NULL;
|
/* fixed-point */
|
||||||
|
long *MV_FooBuffer = NULL;
|
||||||
|
|
||||||
static VoiceNode *MV_Voices = NULL;
|
static VoiceNode *MV_Voices = NULL;
|
||||||
|
|
||||||
|
@ -134,7 +137,7 @@ static void ( *MV_CallBackFunc )( unsigned long ) = NULL;
|
||||||
static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
|
static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
|
||||||
static void ( *MV_MixFunction )( VoiceNode *voice);
|
static void ( *MV_MixFunction )( VoiceNode *voice);
|
||||||
|
|
||||||
int MV_MaxVolume = 63;
|
const int MV_MaxVolume = 63;
|
||||||
|
|
||||||
int *MV_GLast, *MV_GPos, *MV_GVal;
|
int *MV_GLast, *MV_GPos, *MV_GVal;
|
||||||
|
|
||||||
|
@ -144,8 +147,8 @@ char *MV_MixDestination;
|
||||||
short *MV_LeftVolume;
|
short *MV_LeftVolume;
|
||||||
short *MV_RightVolume;
|
short *MV_RightVolume;
|
||||||
#else
|
#else
|
||||||
int MV_LeftVolume;
|
int MV_LeftVolume, MV_LeftScale;
|
||||||
int MV_RightVolume;
|
int MV_RightVolume, MV_RightScale;
|
||||||
#endif
|
#endif
|
||||||
int MV_SampleSize = 1;
|
int MV_SampleSize = 1;
|
||||||
int MV_RightChannelOffset;
|
int MV_RightChannelOffset;
|
||||||
|
@ -317,6 +320,9 @@ static void MV_Mix( VoiceNode *voice )
|
||||||
MV_MixDestination += 8;
|
MV_MixDestination += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MV_LeftScale = (MV_LeftVolume << FRACBITS) / MV_MaxVolume;
|
||||||
|
MV_RightScale = (MV_RightVolume << FRACBITS) / MV_MaxVolume;
|
||||||
|
|
||||||
// Add this voice to the mix
|
// Add this voice to the mix
|
||||||
while( length > 0 )
|
while( length > 0 )
|
||||||
{
|
{
|
||||||
|
@ -459,7 +465,7 @@ void MV_ServiceVoc
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ClearBuffer_DW( MV_FooBuffer, 0, sizeof(double) / 4 * MV_BufferSize / MV_SampleSize * MV_Channels);
|
ClearBuffer_DW( MV_FooBuffer, 0, sizeof(long) / 4 * MV_BufferSize / MV_SampleSize * MV_Channels);
|
||||||
MV_BufferEmpty[ MV_MixPage ] = TRUE;
|
MV_BufferEmpty[ MV_MixPage ] = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3109,7 +3115,7 @@ int MV_Init
|
||||||
MV_SetVolume( MV_MaxTotalVolume );
|
MV_SetVolume( MV_MaxTotalVolume );
|
||||||
|
|
||||||
|
|
||||||
MV_FooMemory = sizeof(double) * MixBufferSize * numchannels + 1024;
|
MV_FooMemory = sizeof(long) * MixBufferSize * numchannels + 1024;
|
||||||
status = USRHOOKS_GetMem( ( void ** )&ptr, MV_FooMemory);
|
status = USRHOOKS_GetMem( ( void ** )&ptr, MV_FooMemory);
|
||||||
if ( status != USRHOOKS_Ok )
|
if ( status != USRHOOKS_Ok )
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,12 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#ifndef __MULTIVOC_H
|
#ifndef __MULTIVOC_H
|
||||||
#define __MULTIVOC_H
|
#define __MULTIVOC_H
|
||||||
|
|
||||||
//#include <windows.h>
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
// forward declare
|
/* must 8 or less, otherwise sound will clip */
|
||||||
//struct SDL_mutex;
|
#define FRACBITS 8
|
||||||
|
|
||||||
|
|
||||||
#define MV_MinVoiceHandle 1
|
#define MV_MinVoiceHandle 1
|
||||||
|
|
||||||
|
@ -124,7 +122,6 @@ int MV_Shutdown( void );
|
||||||
void MV_UnlockMemory( void );
|
void MV_UnlockMemory( void );
|
||||||
int MV_LockMemory( void );
|
int MV_LockMemory( void );
|
||||||
|
|
||||||
//CRITICAL_SECTION reverbCS;
|
|
||||||
SDL_mutex* reverbMutex;
|
SDL_mutex* reverbMutex;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#include "multivoc.h"
|
#include "multivoc.h"
|
||||||
|
|
||||||
|
#include "fixedpoint.h"
|
||||||
|
|
||||||
#include "../global.h" /* for readLE16 */
|
#include "../global.h" /* for readLE16 */
|
||||||
|
|
||||||
extern char *MV_MixDestination;
|
extern char *MV_MixDestination;
|
||||||
extern uint32_t MV_MixPosition;
|
extern uint32_t MV_MixPosition;
|
||||||
extern int *MV_GLast, *MV_GPos, *MV_GVal;
|
extern int *MV_GLast, *MV_GPos, *MV_GVal;
|
||||||
|
|
||||||
extern int MV_LeftVolume;
|
extern int MV_LeftVolume, MV_LeftScale;
|
||||||
extern int MV_RightVolume;
|
extern int MV_RightVolume, MV_RightScale;
|
||||||
extern int MV_MaxVolume;
|
extern const int MV_MaxVolume;
|
||||||
|
|
||||||
// extern unsigned char *MV_HarshClipTable;
|
// extern unsigned char *MV_HarshClipTable;
|
||||||
|
|
||||||
|
@ -44,8 +46,8 @@ int MV_cubic(int position)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int MV_cubic8(const unsigned char *src, int position, int rate)
|
static int MV_cubic8(const unsigned char *src, int position, int rate)
|
||||||
{
|
{
|
||||||
int temp, hpos = position >> 16;
|
int temp, hpos = position >> 16;
|
||||||
|
|
||||||
if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
|
if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
|
||||||
|
@ -60,14 +62,15 @@ static int MV_cubic8(const unsigned char *src, int position, int rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
|
return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int MV_cubic16(const short *src, int position, int rate)
|
static int MV_cubic16(const short *src, int position, int rate)
|
||||||
{
|
{
|
||||||
int temp, hpos = position >> 16;
|
int temp, hpos = position >> 16;
|
||||||
|
|
||||||
if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
|
if (abs(hpos - *MV_GLast) > 3)
|
||||||
|
*MV_GLast = hpos;
|
||||||
|
|
||||||
temp = hpos;
|
temp = hpos;
|
||||||
|
|
||||||
|
@ -75,7 +78,8 @@ static int MV_cubic16(const short *src, int position, int rate)
|
||||||
{
|
{
|
||||||
/* readLE16 returns unsigned short, but it won't be casted
|
/* readLE16 returns unsigned short, but it won't be casted
|
||||||
* implicitly, since gval0 is of type int. */
|
* implicitly, since gval0 is of type int. */
|
||||||
gval0 = (short) readLE16(src + temp++);
|
gval0 = (short) readLE16(src + temp);
|
||||||
|
temp++;
|
||||||
|
|
||||||
*MV_GPos = (*MV_GPos + 1) & 3;
|
*MV_GPos = (*MV_GPos + 1) & 3;
|
||||||
(*MV_GLast)++;
|
(*MV_GLast)++;
|
||||||
|
@ -103,8 +107,8 @@ static int MV_cubic8to16(const unsigned char *src, int position, int rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int MV_cubic16to8(const short *src, int position, int rate)
|
static int MV_cubic16to8(const short *src, int position, int rate)
|
||||||
{
|
{
|
||||||
int temp, hpos = position >> 16;
|
int temp, hpos = position >> 16;
|
||||||
|
|
||||||
if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
|
if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
|
||||||
|
@ -119,9 +123,10 @@ static int MV_cubic16to8(const short *src, int position, int rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
|
return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
void MV_Mix8BitMono( uint32_t position, uint32_t rate,
|
void MV_Mix8BitMono( uint32_t position, uint32_t rate,
|
||||||
const char *start, uint32_t length )
|
const char *start, uint32_t length )
|
||||||
{
|
{
|
||||||
|
@ -369,23 +374,29 @@ void MV_Mix16BitStereo16( uint32_t position,
|
||||||
MV_MixPosition = position;
|
MV_MixPosition = position;
|
||||||
MV_MixDestination = (char *)dest;
|
MV_MixDestination = (char *)dest;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fp_calls[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
//static const double recip = 1/(double)(1<<FRACBITS);
|
||||||
|
|
||||||
|
/* #2 */
|
||||||
void MV_MixFPMono8( uint32_t position,
|
void MV_MixFPMono8( uint32_t position,
|
||||||
uint32_t rate, const char *start, uint32_t length )
|
uint32_t rate, const char *start, uint32_t length )
|
||||||
{
|
{
|
||||||
|
++fp_calls[0];
|
||||||
const unsigned char *src;
|
const unsigned char *src;
|
||||||
double *dest;
|
long *dest;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
src = (const unsigned char *)start;
|
src = (const unsigned char *)start;
|
||||||
dest = (double *)MV_MixDestination;
|
dest = (long *)MV_MixDestination;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
int s = MV_cubic8to16(src, position, rate);
|
int s = MV_cubic8to16(src, position, rate) << FRACBITS;
|
||||||
double out;
|
long out;
|
||||||
|
|
||||||
out = (double)s * (double)MV_LeftVolume / (double)MV_MaxVolume;
|
out = (s * MV_LeftScale) >> FRACBITS;
|
||||||
out = out / ((double)0x8000);
|
|
||||||
*dest += out;
|
*dest += out;
|
||||||
|
|
||||||
position += rate;
|
position += rate;
|
||||||
|
@ -396,24 +407,25 @@ void MV_MixFPMono8( uint32_t position,
|
||||||
MV_MixDestination = (char *)dest;
|
MV_MixDestination = (char *)dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #1 performance hog */
|
||||||
void MV_MixFPStereo8( uint32_t position,
|
void MV_MixFPStereo8( uint32_t position,
|
||||||
uint32_t rate, const char *start, uint32_t length )
|
uint32_t rate, const char *start, uint32_t length )
|
||||||
{
|
{
|
||||||
|
++fp_calls[1];
|
||||||
const unsigned char *src;
|
const unsigned char *src;
|
||||||
double *dest;
|
long *dest;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
src = (const unsigned char *)start;
|
src = (const unsigned char *)start;
|
||||||
dest = (double *)MV_MixDestination;
|
dest = (long *)MV_MixDestination;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
int s = MV_cubic8to16(src, position, rate);
|
int s = MV_cubic8to16(src, position, rate) << FRACBITS;
|
||||||
double left, right;
|
long left, right;
|
||||||
|
|
||||||
|
left = (s * MV_LeftScale) >> FRACBITS;
|
||||||
|
right = (s * MV_RightScale) >> FRACBITS;
|
||||||
|
|
||||||
left = (double)MV_LeftVolume * (double)s / (double)MV_MaxVolume;
|
|
||||||
left = left / ((double)0x8000);
|
|
||||||
right = (double)(MV_RightVolume * s) / MV_MaxVolume;
|
|
||||||
right = right / ((double)0x8000);
|
|
||||||
dest[0] += left;
|
dest[0] += left;
|
||||||
dest[1] += right;
|
dest[1] += right;
|
||||||
|
|
||||||
|
@ -426,22 +438,23 @@ void MV_MixFPStereo8( uint32_t position,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rarely called */
|
||||||
void MV_MixFPMono16( uint32_t position,
|
void MV_MixFPMono16( uint32_t position,
|
||||||
uint32_t rate, const char *start, uint32_t length )
|
uint32_t rate, const char *start, uint32_t length )
|
||||||
{
|
{
|
||||||
|
++fp_calls[2];
|
||||||
const short *src;
|
const short *src;
|
||||||
double *dest;
|
long *dest;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
src = (const short *)start;
|
src = (const short *)start;
|
||||||
dest = (double *)MV_MixDestination;
|
dest = (long *)MV_MixDestination;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
int s = MV_cubic16(src, position, rate);
|
int s = MV_cubic16(src, position, rate) << FRACBITS;
|
||||||
double out;
|
long out;
|
||||||
|
|
||||||
out = (double)s * (double)MV_LeftVolume / (double)MV_MaxVolume;
|
out = (s * MV_LeftScale) >> FRACBITS;
|
||||||
out = out / ((double)0x8000);
|
|
||||||
*dest += out;
|
*dest += out;
|
||||||
|
|
||||||
position += rate;
|
position += rate;
|
||||||
|
@ -452,24 +465,26 @@ void MV_MixFPMono16( uint32_t position,
|
||||||
MV_MixDestination = (char *)dest;
|
MV_MixDestination = (char *)dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #3 performance hog */
|
||||||
void MV_MixFPStereo16( uint32_t position,
|
void MV_MixFPStereo16( uint32_t position,
|
||||||
uint32_t rate, const char *start, uint32_t length )
|
uint32_t rate, const char *start, uint32_t length )
|
||||||
{
|
{
|
||||||
|
++fp_calls[3];
|
||||||
const short *src;
|
const short *src;
|
||||||
double *dest;
|
long *dest;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
src = (const short *)start;
|
src = (const short *)start;
|
||||||
dest = (double *)MV_MixDestination;
|
dest = (long *)MV_MixDestination;
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
int s = MV_cubic16(src, position, rate);
|
int s = MV_cubic16(src, position, rate) << FRACBITS;
|
||||||
double left, right;
|
|
||||||
|
long left, right;
|
||||||
|
|
||||||
|
left = (s * MV_LeftScale) >> FRACBITS;
|
||||||
|
right = (s * MV_RightScale) >> FRACBITS;
|
||||||
|
|
||||||
left = (double)MV_LeftVolume * (double)s / (double)MV_MaxVolume;
|
|
||||||
left = left / ((double)0x8000);
|
|
||||||
right = (double)(MV_RightVolume * s) / MV_MaxVolume;
|
|
||||||
right = right / ((double)0x8000);
|
|
||||||
dest[0] += left;
|
dest[0] += left;
|
||||||
dest[1] += right;
|
dest[1] += right;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#include "multivoc.h"
|
#include "multivoc.h"
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "fixedpoint.h"
|
||||||
|
|
||||||
extern double *MV_FooBuffer;
|
extern long *MV_FooBuffer;
|
||||||
extern int MV_BufferSize;
|
extern int MV_BufferSize;
|
||||||
extern int MV_SampleSize;
|
extern int MV_SampleSize;
|
||||||
extern int MV_MaxVolume;
|
extern const int MV_MaxVolume;
|
||||||
extern int MV_ReverbDelay;
|
extern int MV_ReverbDelay;
|
||||||
extern int MV_MixRate;
|
extern int MV_MixRate;
|
||||||
extern int MV_Channels;
|
extern int MV_Channels;
|
||||||
|
|
||||||
static double * reverbBuffer = 0;
|
static long * reverbBuffer = 0;
|
||||||
static int delay = 0, CurrAddr;
|
static int delay = 0, CurrAddr;
|
||||||
|
|
||||||
static int FB_SRC_A, FB_SRC_B, IIR_DEST_A0, IIR_DEST_A1, ACC_SRC_A0, ACC_SRC_A1, ACC_SRC_B0,
|
static int FB_SRC_A, FB_SRC_B, IIR_DEST_A0, IIR_DEST_A1, ACC_SRC_A0, ACC_SRC_A1, ACC_SRC_B0,
|
||||||
|
@ -17,10 +18,10 @@ static int FB_SRC_A, FB_SRC_B, IIR_DEST_A0, IIR_DEST_A1, ACC_SRC_A0, ACC_SRC_A1,
|
||||||
ACC_SRC_C1, ACC_SRC_D0, ACC_SRC_D1, IIR_SRC_B1, IIR_SRC_B0, MIX_DEST_A0,
|
ACC_SRC_C1, ACC_SRC_D0, ACC_SRC_D1, IIR_SRC_B1, IIR_SRC_B0, MIX_DEST_A0,
|
||||||
MIX_DEST_A1, MIX_DEST_B0, MIX_DEST_B1;
|
MIX_DEST_A1, MIX_DEST_B0, MIX_DEST_B1;
|
||||||
|
|
||||||
static double IIR_ALPHA, ACC_COEF_A, ACC_COEF_B, ACC_COEF_C, ACC_COEF_D, IIR_COEF, FB_ALPHA, FB_X,
|
static long IIR_ALPHA, ACC_COEF_A, ACC_COEF_B, ACC_COEF_C, ACC_COEF_D, IIR_COEF, FB_ALPHA, FB_X,
|
||||||
IN_COEF_L, IN_COEF_R;
|
IN_COEF_L, IN_COEF_R;
|
||||||
|
|
||||||
static double iRVBLeft, iRVBRight;
|
static long iRVBLeft, iRVBRight;
|
||||||
|
|
||||||
static int cnv_offset(int src)
|
static int cnv_offset(int src)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,8 @@ static int cnv_offset(int src)
|
||||||
|
|
||||||
// extern __stdcall OutputDebugStringA(char *);
|
// extern __stdcall OutputDebugStringA(char *);
|
||||||
|
|
||||||
|
static const double fp_scale = (double) (1 << FRACBITS);
|
||||||
|
|
||||||
static void check_buffer()
|
static void check_buffer()
|
||||||
{
|
{
|
||||||
int new_delay = cnv_offset(MV_ReverbDelay);
|
int new_delay = cnv_offset(MV_ReverbDelay);
|
||||||
|
@ -61,26 +64,26 @@ static void check_buffer()
|
||||||
MIX_DEST_A1 = cnv_offset(0x238);
|
MIX_DEST_A1 = cnv_offset(0x238);
|
||||||
MIX_DEST_B0 = cnv_offset(0x154);
|
MIX_DEST_B0 = cnv_offset(0x154);
|
||||||
MIX_DEST_B1 = cnv_offset(0xAA);
|
MIX_DEST_B1 = cnv_offset(0xAA);
|
||||||
IIR_ALPHA = 0.8701171875;
|
IIR_ALPHA = 0.8701171875 * fp_scale;
|
||||||
ACC_COEF_A = 0.622314453125;
|
ACC_COEF_A = 0.622314453125 * fp_scale;
|
||||||
ACC_COEF_B = -0.5244140625;
|
ACC_COEF_B = -0.5244140625 * fp_scale;
|
||||||
ACC_COEF_C = 0.53955078125;
|
ACC_COEF_C = 0.53955078125 * fp_scale;
|
||||||
ACC_COEF_D = -0.50830078125;
|
ACC_COEF_D = -0.50830078125 * fp_scale;
|
||||||
IIR_COEF = -0.69921875;
|
IIR_COEF = -0.69921875 * fp_scale;
|
||||||
FB_ALPHA = 0.67578125;
|
FB_ALPHA = 0.67578125 * fp_scale;
|
||||||
FB_X = 0.646484375;
|
FB_X = 0.646484375 * fp_scale;
|
||||||
IN_COEF_L = -2.;
|
IN_COEF_L = -2. * fp_scale;
|
||||||
IN_COEF_R = -2.;
|
IN_COEF_R = -2. * fp_scale;
|
||||||
if (reverbBuffer) reverbBuffer = (double*) realloc(reverbBuffer, new_delay * sizeof(double));
|
if (reverbBuffer) reverbBuffer = (long*) realloc(reverbBuffer, new_delay * sizeof(long));
|
||||||
else reverbBuffer = (double*) malloc(new_delay * sizeof(double));
|
else reverbBuffer = (long*) malloc(new_delay * sizeof(long));
|
||||||
memset(reverbBuffer, 0, new_delay * sizeof(double));
|
memset(reverbBuffer, 0, new_delay * sizeof(long));
|
||||||
delay = new_delay;
|
delay = new_delay;
|
||||||
CurrAddr = 0;
|
CurrAddr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double g_buffer(int iOff, double *ptr) // get_buffer content helper: takes care about wraps
|
long g_buffer(int iOff, long *ptr) // get_buffer content helper: takes care about wraps
|
||||||
{
|
{
|
||||||
int correctDelay = delay;
|
int correctDelay = delay;
|
||||||
if(!correctDelay)
|
if(!correctDelay)
|
||||||
|
@ -98,10 +101,10 @@ double g_buffer(int iOff, double *ptr) // get_buffer co
|
||||||
{
|
{
|
||||||
iOff=correctDelay-(0-iOff);
|
iOff=correctDelay-(0-iOff);
|
||||||
}
|
}
|
||||||
return (double)*(ptr+iOff);
|
return (long)*(ptr+iOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void s_buffer(int iOff,double iVal, double *ptr) // set_buffer content helper: takes care about wraps and clipping
|
void s_buffer(int iOff,long iVal, long *ptr) // set_buffer content helper: takes care about wraps and clipping
|
||||||
{
|
{
|
||||||
int correctDelay = delay;
|
int correctDelay = delay;
|
||||||
if(!correctDelay)
|
if(!correctDelay)
|
||||||
|
@ -122,7 +125,7 @@ void s_buffer(int iOff,double iVal, double *ptr) // set_buffer co
|
||||||
*(ptr+iOff)=iVal;
|
*(ptr+iOff)=iVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void s_buffer1(int iOff,double iVal, double *ptr) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
|
void s_buffer1(int iOff,long iVal, long *ptr) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
|
||||||
{
|
{
|
||||||
int correctDelay = delay;
|
int correctDelay = delay;
|
||||||
if(!correctDelay)
|
if(!correctDelay)
|
||||||
|
@ -143,61 +146,63 @@ void s_buffer1(int iOff,double iVal, double *ptr) // set_buffer (
|
||||||
*(ptr+iOff)=iVal;
|
*(ptr+iOff)=iVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
double MixREVERBLeft(double INPUT_SAMPLE_L, double INPUT_SAMPLE_R, double *ptr)
|
long MixREVERBLeft(long INPUT_SAMPLE_L, long INPUT_SAMPLE_R, long *ptr)
|
||||||
{
|
{
|
||||||
double ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
|
long ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
|
||||||
|
|
||||||
const double IIR_INPUT_A0 = (g_buffer(IIR_SRC_A0, ptr) * IIR_COEF) + (INPUT_SAMPLE_L * IN_COEF_L);
|
const long IIR_INPUT_A0 = (fp_mul(g_buffer(IIR_SRC_A0, ptr), IIR_COEF, FRACBITS) + fp_mul(INPUT_SAMPLE_L, IN_COEF_L, FRACBITS));
|
||||||
const double IIR_INPUT_A1 = (g_buffer(IIR_SRC_A1, ptr) * IIR_COEF) + (INPUT_SAMPLE_R * IN_COEF_R);
|
const long IIR_INPUT_A1 = (fp_mul(g_buffer(IIR_SRC_A1, ptr), IIR_COEF, FRACBITS) + fp_mul(INPUT_SAMPLE_R, IN_COEF_R, FRACBITS));
|
||||||
const double IIR_INPUT_B0 = (g_buffer(IIR_SRC_B0, ptr) * IIR_COEF) + (INPUT_SAMPLE_L * IN_COEF_L);
|
const long IIR_INPUT_B0 = (fp_mul(g_buffer(IIR_SRC_B0, ptr), IIR_COEF, FRACBITS) + fp_mul(INPUT_SAMPLE_L, IN_COEF_L, FRACBITS));
|
||||||
const double IIR_INPUT_B1 = (g_buffer(IIR_SRC_B1, ptr) * IIR_COEF) + (INPUT_SAMPLE_R * IN_COEF_R);
|
const long IIR_INPUT_B1 = (fp_mul(g_buffer(IIR_SRC_B1, ptr), IIR_COEF, FRACBITS) + fp_mul(INPUT_SAMPLE_R, IN_COEF_R, FRACBITS));
|
||||||
|
|
||||||
const double IIR_A0 = (IIR_INPUT_A0 * IIR_ALPHA) + (g_buffer(IIR_DEST_A0, ptr) * (1.f - IIR_ALPHA));
|
const long one = (1 << FRACBITS);
|
||||||
const double IIR_A1 = (IIR_INPUT_A1 * IIR_ALPHA) + (g_buffer(IIR_DEST_A1, ptr) * (1.f - IIR_ALPHA));
|
const long IIR_A0 = fp_mul(IIR_INPUT_A0, IIR_ALPHA, FRACBITS) + fp_mul(g_buffer(IIR_DEST_A0, ptr), (one - IIR_ALPHA), FRACBITS);
|
||||||
const double IIR_B0 = (IIR_INPUT_B0 * IIR_ALPHA) + (g_buffer(IIR_DEST_B0, ptr) * (1.f - IIR_ALPHA));
|
const long IIR_A1 = fp_mul(IIR_INPUT_A1, IIR_ALPHA, FRACBITS) + fp_mul(g_buffer(IIR_DEST_A1, ptr), (one - IIR_ALPHA), FRACBITS);
|
||||||
const double IIR_B1 = (IIR_INPUT_B1 * IIR_ALPHA) + (g_buffer(IIR_DEST_B1, ptr) * (1.f - IIR_ALPHA));
|
const long IIR_B0 = fp_mul(IIR_INPUT_B0, IIR_ALPHA, FRACBITS) + fp_mul(g_buffer(IIR_DEST_B0, ptr), (one - IIR_ALPHA), FRACBITS);
|
||||||
|
const long IIR_B1 = fp_mul(IIR_INPUT_B1, IIR_ALPHA, FRACBITS) + fp_mul(g_buffer(IIR_DEST_B1, ptr), (one - IIR_ALPHA), FRACBITS);
|
||||||
|
|
||||||
s_buffer1(IIR_DEST_A0, IIR_A0, ptr);
|
s_buffer1(IIR_DEST_A0, IIR_A0, ptr);
|
||||||
s_buffer1(IIR_DEST_A1, IIR_A1, ptr);
|
s_buffer1(IIR_DEST_A1, IIR_A1, ptr);
|
||||||
s_buffer1(IIR_DEST_B0, IIR_B0, ptr);
|
s_buffer1(IIR_DEST_B0, IIR_B0, ptr);
|
||||||
s_buffer1(IIR_DEST_B1, IIR_B1, ptr);
|
s_buffer1(IIR_DEST_B1, IIR_B1, ptr);
|
||||||
|
|
||||||
ACC0 = (g_buffer(ACC_SRC_A0, ptr) * ACC_COEF_A) +
|
ACC0 = (fp_mul(g_buffer(ACC_SRC_A0, ptr), ACC_COEF_A, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_B0, ptr) * ACC_COEF_B) +
|
fp_mul(g_buffer(ACC_SRC_B0, ptr), ACC_COEF_B, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_C0, ptr) * ACC_COEF_C) +
|
fp_mul(g_buffer(ACC_SRC_C0, ptr), ACC_COEF_C, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_D0, ptr) * ACC_COEF_D);
|
fp_mul(g_buffer(ACC_SRC_D0, ptr), ACC_COEF_D, FRACBITS));
|
||||||
ACC1 = (g_buffer(ACC_SRC_A1, ptr) * ACC_COEF_A) +
|
ACC1 = (fp_mul(g_buffer(ACC_SRC_A1, ptr), ACC_COEF_A, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_B1, ptr) * ACC_COEF_B) +
|
fp_mul(g_buffer(ACC_SRC_B1, ptr), ACC_COEF_B, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_C1, ptr) * ACC_COEF_C) +
|
fp_mul(g_buffer(ACC_SRC_C1, ptr), ACC_COEF_C, FRACBITS) +
|
||||||
(g_buffer(ACC_SRC_D1, ptr) * ACC_COEF_D);
|
fp_mul(g_buffer(ACC_SRC_D1, ptr), ACC_COEF_D, FRACBITS));
|
||||||
|
|
||||||
FB_A0 = g_buffer(MIX_DEST_A0 - FB_SRC_A, ptr);
|
FB_A0 = g_buffer(MIX_DEST_A0 - FB_SRC_A, ptr);
|
||||||
FB_A1 = g_buffer(MIX_DEST_A1 - FB_SRC_A, ptr);
|
FB_A1 = g_buffer(MIX_DEST_A1 - FB_SRC_A, ptr);
|
||||||
FB_B0 = g_buffer(MIX_DEST_B0 - FB_SRC_B, ptr);
|
FB_B0 = g_buffer(MIX_DEST_B0 - FB_SRC_B, ptr);
|
||||||
FB_B1 = g_buffer(MIX_DEST_B1 - FB_SRC_B, ptr);
|
FB_B1 = g_buffer(MIX_DEST_B1 - FB_SRC_B, ptr);
|
||||||
|
|
||||||
s_buffer(MIX_DEST_A0, ACC0 - (FB_A0 * FB_ALPHA), ptr);
|
s_buffer(MIX_DEST_A0, ACC0 - fp_mul(FB_A0 , FB_ALPHA, FRACBITS), ptr);
|
||||||
s_buffer(MIX_DEST_A1, ACC1 - (FB_A1 * FB_ALPHA), ptr);
|
s_buffer(MIX_DEST_A1, ACC1 - fp_mul(FB_A1 , FB_ALPHA, FRACBITS), ptr);
|
||||||
|
|
||||||
s_buffer(MIX_DEST_B0, (FB_ALPHA * ACC0) - (FB_A0 * (FB_ALPHA - 1.f)) - (FB_B0 * FB_X), ptr);
|
s_buffer(MIX_DEST_B0, fp_mul(FB_ALPHA , ACC0, FRACBITS) - fp_mul(FB_A0, (FB_ALPHA - one), FRACBITS) - fp_mul(FB_B0, FB_X, FRACBITS), ptr);
|
||||||
s_buffer(MIX_DEST_B1, (FB_ALPHA * ACC1) - (FB_A1 * (FB_ALPHA - 1.f)) - (FB_B1 * FB_X), ptr);
|
s_buffer(MIX_DEST_B1, fp_mul(FB_ALPHA , ACC1, FRACBITS) - fp_mul(FB_A1, (FB_ALPHA - one), FRACBITS) - fp_mul(FB_B1, FB_X, FRACBITS), ptr);
|
||||||
|
|
||||||
iRVBLeft = (g_buffer(MIX_DEST_A0, ptr)+g_buffer(MIX_DEST_B0, ptr))/3.f;
|
iRVBLeft = fp_div((g_buffer(MIX_DEST_A0, ptr)+g_buffer(MIX_DEST_B0, ptr)), 3 << FRACBITS, FRACBITS);
|
||||||
iRVBRight = (g_buffer(MIX_DEST_A1, ptr)+g_buffer(MIX_DEST_B1, ptr))/3.f;
|
iRVBRight = fp_div((g_buffer(MIX_DEST_A1, ptr)+g_buffer(MIX_DEST_B1, ptr)), 3 << FRACBITS, FRACBITS);
|
||||||
|
|
||||||
CurrAddr++;
|
CurrAddr++;
|
||||||
if(CurrAddr>delay-1) CurrAddr=0;
|
if(CurrAddr>delay-1) CurrAddr=0;
|
||||||
|
|
||||||
return (double)iRVBLeft;
|
return (long)iRVBLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
double MixREVERBRight(void)
|
long MixREVERBRight(void)
|
||||||
{
|
{
|
||||||
return (double)iRVBRight;
|
return (long)iRVBRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MV_FPReverb(int volume)
|
void MV_FPReverb(int volume)
|
||||||
{
|
{
|
||||||
|
//rb->splashf(HZ, "SLOW CODE!!!");
|
||||||
int i, count = MV_BufferSize / MV_SampleSize * MV_Channels;
|
int i, count = MV_BufferSize / MV_SampleSize * MV_Channels;
|
||||||
|
|
||||||
// sprintf(err, "count: %d, old_delay: %d", count, delay);
|
// sprintf(err, "count: %d, old_delay: %d", count, delay);
|
||||||
|
@ -216,24 +221,29 @@ void MV_FPReverb(int volume)
|
||||||
|
|
||||||
// OutputDebugStringA(err);
|
// OutputDebugStringA(err);
|
||||||
|
|
||||||
|
long scale = (volume << FRACBITS) / MV_MaxVolume;
|
||||||
|
|
||||||
if (MV_Channels == 1)
|
if (MV_Channels == 1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
double temp = MV_FooBuffer[i];
|
long temp = MV_FooBuffer[i];
|
||||||
MV_FooBuffer[i] += ((MixREVERBLeft(temp, temp, reverbBuffer) + MixREVERBRight()) * .5) * (double)volume / (double)MV_MaxVolume;
|
/* evaluation order matters */
|
||||||
|
long total = MixREVERBLeft(temp, temp, reverbBuffer);
|
||||||
|
total += MixREVERBRight();
|
||||||
|
total /= 2;
|
||||||
|
MV_FooBuffer[i] += (scale * total) >> FRACBITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
count >>= 1;
|
count /= 2;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
double left = MV_FooBuffer[i*2];
|
long left = MV_FooBuffer[i*2];
|
||||||
double right = MV_FooBuffer[i*2+1];
|
long right = MV_FooBuffer[i*2+1];
|
||||||
double scale = (double)volume / (double)MV_MaxVolume;
|
left += (scale * MixREVERBLeft(left, right, reverbBuffer)) >> FRACBITS;
|
||||||
left += MixREVERBLeft(left, right, reverbBuffer) * scale;
|
right += (scale * MixREVERBRight()) >> FRACBITS;
|
||||||
right += MixREVERBRight() * scale;
|
|
||||||
MV_FooBuffer[i*2] = left;
|
MV_FooBuffer[i*2] = left;
|
||||||
MV_FooBuffer[i*2+1] = right;
|
MV_FooBuffer[i*2+1] = right;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +275,7 @@ void MV_16BitDownmix(char *dest, int count)
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
int out = (int)((MV_FooBuffer[i] * (double)0x8000));
|
int out = MV_FooBuffer[i] >> FRACBITS;
|
||||||
if (out < -32768) pdest[i] = -32768;
|
if (out < -32768) pdest[i] = -32768;
|
||||||
else if (out > 32767) pdest[i] = 32767;
|
else if (out > 32767) pdest[i] = 32767;
|
||||||
else pdest[i] = out;
|
else pdest[i] = out;
|
||||||
|
@ -278,13 +288,14 @@ void MV_8BitDownmix(char *dest, int count)
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
int out = ((int)((MV_FooBuffer[i] * (double)0x80)));
|
int out = MV_FooBuffer[i] >> FRACBITS;
|
||||||
if (out < -128) dest[i] = 0;
|
if (out < -128) dest[i] = 0;
|
||||||
else if (out > 127) dest[i] = 255;
|
else if (out > 127) dest[i] = 255;
|
||||||
else dest[i] = out + 0x80;
|
else dest[i] = out + 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void MV_16BitReverbFast( const char *src, char *dest, int count, int shift )
|
void MV_16BitReverbFast( const char *src, char *dest, int count, int shift )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -310,3 +321,4 @@ void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, in
|
||||||
dest[i] = (signed char) (a + sh + c);
|
dest[i] = (signed char) (a + sh + c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -2227,8 +2227,9 @@ void duke_tics(short offx, short offy, short color)
|
||||||
else
|
else
|
||||||
savedFps = fpsAvg;
|
savedFps = fpsAvg;
|
||||||
|
|
||||||
extern int rbaud_underruns;
|
extern int rbaud_underruns, fp_calls[4];
|
||||||
sprintf(fps," %d %d", savedFps, rbaud_underruns);
|
sprintf(fps," %d %d %d %d %d %d", savedFps, rbaud_underruns, fp_calls[0],
|
||||||
|
fp_calls[1], fp_calls[2], fp_calls[3]);
|
||||||
strcat(text, fps);
|
strcat(text, fps);
|
||||||
|
|
||||||
minitext(offx,offy,text,color,2+8+16+128);
|
minitext(offx,offy,text,color,2+8+16+128);
|
||||||
|
|
|
@ -32,18 +32,6 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "duke3d.h"
|
#include "duke3d.h"
|
||||||
|
|
||||||
uint16_t readLE16(void *addr)
|
|
||||||
{
|
|
||||||
uint8_t *ptr = addr;
|
|
||||||
return (*(ptr+1) << 8) | *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t readLE32(void *addr)
|
|
||||||
{
|
|
||||||
uint8_t *ptr = addr;
|
|
||||||
return (*(ptr+3) << 24) |(*(ptr+2) << 16) | (*(ptr+1) << 8) | *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *mymembuf;
|
char *mymembuf;
|
||||||
uint8_t MusicPtr[72000];
|
uint8_t MusicPtr[72000];
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
#define open rb->open
|
#define open rb->open
|
||||||
uint16_t readLE16(void *addr);
|
|
||||||
uint32_t readLE32(void *addr);
|
|
||||||
|
|
||||||
void FixFilePath(char *filename);
|
void FixFilePath(char *filename);
|
||||||
int FindDistance3D(int ix, int iy, int iz);
|
int FindDistance3D(int ix, int iy, int iz);
|
||||||
|
|
|
@ -50,7 +50,7 @@ int32_t backflag,numenvsnds;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void SoundStartup( void )
|
void SoundStartup( void )
|
||||||
{
|
{
|
||||||
int32 status;
|
int32 status;
|
||||||
|
|
||||||
// if they chose None lets return
|
// if they chose None lets return
|
||||||
|
@ -107,7 +107,7 @@ void SoundStartup( void )
|
||||||
{
|
{
|
||||||
Error(EXIT_FAILURE, FX_ErrorString( FX_Error ));
|
Error(EXIT_FAILURE, FX_ErrorString( FX_Error ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================
|
===================
|
||||||
|
|
|
@ -66,9 +66,6 @@ int32_t Intelint32_t (int32_t l);
|
||||||
|
|
||||||
void HeapSort(uint8_t * base, int32 nel, int32 width, int32 (*compare)(), void (*switcher)());
|
void HeapSort(uint8_t * base, int32 nel, int32 width, int32 (*compare)(), void (*switcher)());
|
||||||
|
|
||||||
uint16_t readLE16(void *addr);
|
|
||||||
uint32_t readLE32(void *addr);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue