audio/phoenix.c:

* fixed sound issue related to (auto) save states
This commit is contained in:
Couriersud 2008-01-18 17:57:37 +00:00
parent c60ef331ab
commit 6f3bf9f10f

View File

@ -48,15 +48,30 @@
#define VMIN 0 #define VMIN 0
#define VMAX 32767 #define VMAX 32767
static UINT8 sound_latch_a; struct c_state
{
INT32 counter;
INT32 level;
};
static sound_stream * channel; struct n_state
{
INT32 counter;
INT32 polyoffs;
INT32 polybit;
INT32 lowpass_counter;
INT32 lowpass_polybit;
};
static UINT32 *poly18 = NULL; static struct c_state c24_state;
static struct c_state c25_state;
static struct n_state noise_state;
static UINT8 sound_latch_a;
static sound_stream * channel;
static UINT32 * poly18;
INLINE int update_c24(int samplerate) INLINE int update_c24(int samplerate)
{ {
static int counter, level;
/* /*
* Noise frequency control (Port B): * Noise frequency control (Port B):
* Bit 6 lo charges C24 (6.8u) via R51 (330) and when * Bit 6 lo charges C24 (6.8u) via R51 (330) and when
@ -69,38 +84,37 @@ INLINE int update_c24(int samplerate)
#define R52 20000 #define R52 20000
if( sound_latch_a & 0x40 ) if( sound_latch_a & 0x40 )
{ {
if (level > VMIN) if (c24_state.level > VMIN)
{ {
counter -= (int)((level - VMIN) / (R52 * C24)); c24_state.counter -= (int)((c24_state.level - VMIN) / (R52 * C24));
if( counter <= 0 ) if( c24_state.counter <= 0 )
{ {
int n = -counter / samplerate + 1; int n = -c24_state.counter / samplerate + 1;
counter += n * samplerate; c24_state.counter += n * samplerate;
if( (level -= n) < VMIN) if( (c24_state.level -= n) < VMIN)
level = VMIN; c24_state.level = VMIN;
} }
} }
} }
else else
{ {
if (level < VMAX) if (c24_state.level < VMAX)
{ {
counter -= (int)((VMAX - level) / ((R51+R49) * C24)); c24_state.counter -= (int)((VMAX - c24_state.level) / ((R51+R49) * C24));
if( counter <= 0 ) if( c24_state.counter <= 0 )
{ {
int n = -counter / samplerate + 1; int n = -c24_state.counter / samplerate + 1;
counter += n * samplerate; c24_state.counter += n * samplerate;
if( (level += n) > VMAX) if( (c24_state.level += n) > VMAX)
level = VMAX; c24_state.level = VMAX;
} }
} }
} }
return VMAX - level; return VMAX - c24_state.level;
} }
INLINE int update_c25(int samplerate) INLINE int update_c25(int samplerate)
{ {
static int counter, level;
/* /*
* Bit 7 hi charges C25 (6.8u) over a R50 (1k) and R53 (330) and when * Bit 7 hi charges C25 (6.8u) over a R50 (1k) and R53 (330) and when
* bit 7 is lo, C25 is discharged through R54 (47k) * bit 7 is lo, C25 is discharged through R54 (47k)
@ -113,39 +127,38 @@ INLINE int update_c25(int samplerate)
if( sound_latch_a & 0x80 ) if( sound_latch_a & 0x80 )
{ {
if (level < VMAX) if (c25_state.level < VMAX)
{ {
counter -= (int)((VMAX - level) / ((R50+R53) * C25)); c25_state.counter -= (int)((VMAX - c25_state.level) / ((R50+R53) * C25));
if( counter <= 0 ) if( c25_state.counter <= 0 )
{ {
int n = -counter / samplerate + 1; int n = -c25_state.counter / samplerate + 1;
counter += n * samplerate; c25_state.counter += n * samplerate;
if( (level += n) > VMAX ) if( (c25_state.level += n) > VMAX )
level = VMAX; c25_state.level = VMAX;
} }
} }
} }
else else
{ {
if (level > VMIN) if (c25_state.level > VMIN)
{ {
counter -= (int)((level - VMIN) / (R54 * C25)); c25_state.counter -= (int)((c25_state.level - VMIN) / (R54 * C25));
if( counter <= 0 ) if( c25_state.counter <= 0 )
{ {
int n = -counter / samplerate + 1; int n = -c25_state.counter / samplerate + 1;
counter += n * samplerate; c25_state.counter += n * samplerate;
if( (level -= n) < VMIN ) if( (c25_state.level -= n) < VMIN )
level = VMIN; c25_state.level = VMIN;
} }
} }
} }
return level; return c25_state.level;
} }
INLINE int noise(int samplerate) INLINE int noise(int samplerate)
{ {
static int counter, polyoffs, polybit, lowpass_counter, lowpass_polybit;
int vc24 = update_c24(samplerate); int vc24 = update_c24(samplerate);
int vc25 = update_c25(samplerate); int vc25 = update_c25(samplerate);
int sum = 0, level, frequency; int sum = 0, level, frequency;
@ -168,25 +181,25 @@ INLINE int noise(int samplerate)
* R71 (2700 Ohms) parallel to R73 (47k Ohms) = approx. 2553 Ohms * R71 (2700 Ohms) parallel to R73 (47k Ohms) = approx. 2553 Ohms
* maxfreq = 1.44 / ((2553+2*1000) * 0.05e-6) = approx. 6325 Hz * maxfreq = 1.44 / ((2553+2*1000) * 0.05e-6) = approx. 6325 Hz
*/ */
counter -= frequency; noise_state.counter -= frequency;
if( counter <= 0 ) if( noise_state.counter <= 0 )
{ {
int n = (-counter / samplerate) + 1; int n = (-noise_state.counter / samplerate) + 1;
counter += n * samplerate; noise_state.counter += n * samplerate;
polyoffs = (polyoffs + n) & 0x3ffff; noise_state.polyoffs = (noise_state.polyoffs + n) & 0x3ffff;
polybit = (poly18[polyoffs>>5] >> (polyoffs & 31)) & 1; noise_state.polybit = (poly18[noise_state.polyoffs>>5] >> (noise_state.polyoffs & 31)) & 1;
} }
if (!polybit) if (!noise_state.polybit)
sum += vc24; sum += vc24;
/* 400Hz crude low pass filter: this is only a guess!! */ /* 400Hz crude low pass filter: this is only a guess!! */
lowpass_counter -= 400; noise_state.lowpass_counter -= 400;
if( lowpass_counter <= 0 ) if( noise_state.lowpass_counter <= 0 )
{ {
lowpass_counter += samplerate; noise_state.lowpass_counter += samplerate;
lowpass_polybit = polybit; noise_state.lowpass_polybit = noise_state.polybit;
} }
if (!lowpass_polybit) if (!noise_state.lowpass_polybit)
sum += vc25; sum += vc25;
return sum; return sum;
@ -374,9 +387,6 @@ DISCRETE_SOUND_END
WRITE8_HANDLER( phoenix_sound_control_a_w ) WRITE8_HANDLER( phoenix_sound_control_a_w )
{ {
if( data == sound_latch_a )
return;
discrete_sound_w(PHOENIX_EFFECT_2_DATA, data & 0x0f); discrete_sound_w(PHOENIX_EFFECT_2_DATA, data & 0x0f);
discrete_sound_w(PHOENIX_EFFECT_2_FREQ, (data & 0x30) >> 4); discrete_sound_w(PHOENIX_EFFECT_2_FREQ, (data & 0x30) >> 4);
// discrete_sound_w(PHOENIX_EFFECT_3_EN , data & 0x40); // discrete_sound_w(PHOENIX_EFFECT_3_EN , data & 0x40);
@ -388,7 +398,22 @@ WRITE8_HANDLER( phoenix_sound_control_a_w )
SOUND_START( phoenix) SOUND_START( phoenix)
{ {
sound_latch_a = 0;
memset(&c24_state, 0, sizeof(c24_state));
memset(&c25_state, 0, sizeof(c25_state));
memset(&noise_state, 0, sizeof(noise_state));
state_save_register_global(sound_latch_a); state_save_register_global(sound_latch_a);
state_save_register_global(c24_state.counter);
state_save_register_global(c24_state.level);
state_save_register_global(c25_state.counter);
state_save_register_global(c25_state.level);
state_save_register_global(noise_state.counter);
state_save_register_global(noise_state.polybit);
state_save_register_global(noise_state.polyoffs);
state_save_register_global(noise_state.lowpass_counter);
state_save_register_global(noise_state.lowpass_polybit);
} }
WRITE8_HANDLER( phoenix_sound_control_b_w ) WRITE8_HANDLER( phoenix_sound_control_b_w )