diff options
Diffstat (limited to 'src/chips/dosbox')
| -rw-r--r-- | src/chips/dosbox/dbopl.cpp | 143 | ||||
| -rw-r--r-- | src/chips/dosbox/dbopl.h | 6 | 
2 files changed, 115 insertions, 34 deletions
| diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 4eb79f8..2d31708 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -37,6 +37,7 @@  #include <math.h>  #include <stdlib.h>  #include <string.h> +#include <vector>  #include "dbopl.h"  #if defined(__GNUC__) && __GNUC__ > 3 @@ -70,6 +71,36 @@  #define PI 3.14159265358979323846  #endif +struct NoCopy { +	NoCopy() {} +private: +	NoCopy(const NoCopy &); +	NoCopy &operator=(const NoCopy &); +}; +#if !defined(_WIN32) +#include <pthread.h> +struct Mutex : NoCopy { +	Mutex() : m(PTHREAD_MUTEX_INITIALIZER) {} +	void lock() { pthread_mutex_lock(&m); } +	void unlock() { pthread_mutex_unlock(&m); } +	pthread_mutex_t m; +}; +#else +#include <windows.h> +struct Mutex : NoCopy { +	Mutex() { InitializeCriticalSection(&m); } +	~Mutex() { DeleteCriticalSection(&m); } +	void lock() { EnterCriticalSection(&m); } +	void unlock() { LeaveCriticalSection(&m); } +	CRITICAL_SECTION m; +}; +#endif +struct MutexHolder : NoCopy { +	explicit MutexHolder(Mutex &m) : m(m) { m.lock(); } +	~MutexHolder() { m.unlock(); } +	Mutex &m; +}; +  namespace DBOPL {  #define OPLRATE		((double)(14318180.0 / 288.0)) @@ -222,24 +253,24 @@ static const Bit8u KslShiftTable[4] = {  // Pan law table  static const Bit16u PanLawTable[] =  { -    65535, 65529, 65514, 65489, 65454, 65409, 65354, 65289, -    65214, 65129, 65034, 64929, 64814, 64689, 64554, 64410, -    64255, 64091, 63917, 63733, 63540, 63336, 63123, 62901, -    62668, 62426, 62175, 61914, 61644, 61364, 61075, 60776, -    60468, 60151, 59825, 59489, 59145, 58791, 58428, 58057, -    57676, 57287, 56889, 56482, 56067, 55643, 55211, 54770, -    54320, 53863, 53397, 52923, 52441, 51951, 51453, 50947, -    50433, 49912, 49383, 48846, 48302, 47750, 47191, -    46340, /* Center left */ -    46340, /* Center right */ -    45472, 44885, 44291, 43690, 43083, 42469, 41848, 41221, -    40588, 39948, 39303, 38651, 37994, 37330, 36661, 35986, -    35306, 34621, 33930, 33234, 32533, 31827, 31116, 30400, -    29680, 28955, 28225, 27492, 26754, 26012, 25266, 24516, -    23762, 23005, 22244, 21480, 20713, 19942, 19169, 18392, -    17613, 16831, 16046, 15259, 14469, 13678, 12884, 12088, -    11291, 10492, 9691, 8888, 8085, 7280, 6473, 5666, -    4858, 4050, 3240, 2431, 1620, 810, 0 +	65535, 65529, 65514, 65489, 65454, 65409, 65354, 65289, +	65214, 65129, 65034, 64929, 64814, 64689, 64554, 64410, +	64255, 64091, 63917, 63733, 63540, 63336, 63123, 62901, +	62668, 62426, 62175, 61914, 61644, 61364, 61075, 60776, +	60468, 60151, 59825, 59489, 59145, 58791, 58428, 58057, +	57676, 57287, 56889, 56482, 56067, 55643, 55211, 54770, +	54320, 53863, 53397, 52923, 52441, 51951, 51453, 50947, +	50433, 49912, 49383, 48846, 48302, 47750, 47191, +	46340, /* Center left */ +	46340, /* Center right */ +	45472, 44885, 44291, 43690, 43083, 42469, 41848, 41221, +	40588, 39948, 39303, 38651, 37994, 37330, 36661, 35986, +	35306, 34621, 33930, 33234, 32533, 31827, 31116, 30400, +	29680, 28955, 28225, 27492, 26754, 26012, 25266, 24516, +	23762, 23005, 22244, 21480, 20713, 19942, 19169, 18392, +	17613, 16831, 16046, 15259, 14469, 13678, 12884, 12088, +	11291, 10492, 9691, 8888, 8085, 7280, 6473, 5666, +	4858, 4050, 3240, 2431, 1620, 810, 0  };  //Generate a table index and table shift value using input value from a selected rate @@ -465,7 +496,7 @@ Bits Operator::TemplateVolume(  ) {  			return vol;  		}  		//In sustain phase, but not sustaining, do regular release -                /* fall through */ +				/* fall through */  	case RELEASE:  		vol += RateForward( releaseAdd );;  		if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { @@ -1294,21 +1325,40 @@ void Chip::GenerateBlock3_Mix( Bitu total, Bit32s* output  ) {  	}  } -void Chip::Setup( Bit32u rate ) { +struct CacheEntry { +	Bit32u rate; +	Bit32u freqMul[16]; +	Bit32u linearRates[76]; +	Bit32u attackRates[76]; +}; +static std::vector<CacheEntry> cache; +static Mutex cacheMutex; + +static const CacheEntry *CacheLookupRateDependent( Bit32u rate ) +{ +	for ( size_t i = 0, n = cache.size(); i < n; ++i ) { +		if (cache[i].rate == rate) +			return &cache[i]; +	} +	return NULL; +} + +static const CacheEntry &ComputeRateDependent( Bit32u rate ) +{ +	{ +		MutexHolder lock( cacheMutex ); +		if (const CacheEntry *entry = CacheLookupRateDependent( rate )) +			return *entry; +	} +  	double original = OPLRATE; -//	double original = rate;  	double scale = original / (double)rate; -	//Noise counter is run at the same precision as general waves -	noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); -	noiseCounter = 0; -	noiseValue = 1;	//Make sure it triggers the noise xor the first time -	//The low frequency oscillation counter -	//Every time his overflows vibrato and tremoloindex are increased -	lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); -	lfoCounter = 0; -	vibratoIndex = 0; -	tremoloIndex = 0; +	CacheEntry entry; +	entry.rate = rate; +	Bit32u *freqMul = entry.freqMul; +	Bit32u *linearRates = entry.linearRates; +	Bit32u *attackRates = entry.attackRates;  	//With higher octave this gets shifted up  	//-1 since the freqCreateTable = *2 @@ -1330,6 +1380,7 @@ void Chip::Setup( Bit32u rate ) {  		EnvelopeSelect( i, index, shift );  		linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));  	} +  //	Bit32s attackDiffs[62];  	//Generate the best matching attack rate  	for ( Bit8u i = 0; i < 62; i++ ) { @@ -1382,6 +1433,36 @@ void Chip::Setup( Bit32u rate ) {  		//This should provide instant volume maximizing  		attackRates[i] = 8 << RATE_SH;  	} + +	MutexHolder lock( cacheMutex ); +	if (const CacheEntry *entry = CacheLookupRateDependent( rate )) +		return *entry; + +	cache.push_back(entry); +	return cache.back(); +} + +void Chip::Setup( Bit32u rate ) { +	double original = OPLRATE; +//	double original = rate; +	double scale = original / (double)rate; + +	//Noise counter is run at the same precision as general waves +	noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); +	noiseCounter = 0; +	noiseValue = 1;	//Make sure it triggers the noise xor the first time +	//The low frequency oscillation counter +	//Every time his overflows vibrato and tremoloindex are increased +	lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); +	lfoCounter = 0; +	vibratoIndex = 0; +	tremoloIndex = 0; + +	const CacheEntry &entry = ComputeRateDependent( rate ); +	freqMul = entry.freqMul; +	linearRates = entry.linearRates; +	attackRates = entry.attackRates; +  	//Setup the channels with the correct four op flags  	//Channels are accessed through a table so they appear linear here  	chan[ 0].fourMask = 0x00 | ( 1 << 0 ); diff --git a/src/chips/dosbox/dbopl.h b/src/chips/dosbox/dbopl.h index 429735f..89d2019 100644 --- a/src/chips/dosbox/dbopl.h +++ b/src/chips/dosbox/dbopl.h @@ -227,11 +227,11 @@ struct Chip {  	Bit32u noiseValue;  	//Frequency scales for the different multiplications -	Bit32u freqMul[16]; +	const Bit32u *freqMul/*[16]*/;  	//Rates for decay and release for rate of this chip -	Bit32u linearRates[76]; +	const Bit32u *linearRates/*[76]*/;  	//Best match attack rates for the rate of this chip -	Bit32u attackRates[76]; +	const Bit32u *attackRates/*[76]*/;  	//18 channels with 2 operators each  	Channel chan[18]; |