flt_vol: rename flt_volume_set_volume to set_gain, add getter for gain,

wildfire: refactor speaker decay code
This commit is contained in:
hap 2023-12-09 13:35:42 +01:00
parent 83abe16d5b
commit 3b2337cd9c
19 changed files with 75 additions and 86 deletions

View File

@ -15,7 +15,7 @@ filter_volume_device::filter_volume_device(const machine_config &mconfig, const
device_t(mconfig, FILTER_VOLUME, tag, owner, clock), device_t(mconfig, FILTER_VOLUME, tag, owner, clock),
device_sound_interface(mconfig, *this), device_sound_interface(mconfig, *this),
m_stream(nullptr), m_stream(nullptr),
m_gain(0) m_gain(1.0f)
{ {
} }
@ -26,9 +26,7 @@ filter_volume_device::filter_volume_device(const machine_config &mconfig, const
void filter_volume_device::device_start() void filter_volume_device::device_start()
{ {
m_gain = 1.0;
m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE);
save_item(NAME(m_gain)); save_item(NAME(m_gain));
} }
@ -44,8 +42,11 @@ void filter_volume_device::sound_stream_update(sound_stream &stream, std::vector
} }
void filter_volume_device::flt_volume_set_volume(float volume) filter_volume_device &filter_volume_device::set_gain(float gain)
{ {
if (m_stream)
m_stream->update(); m_stream->update();
m_gain = volume; m_gain = gain;
return *this;
} }

View File

@ -17,7 +17,8 @@ class filter_volume_device : public device_t, public device_sound_interface
public: public:
filter_volume_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); filter_volume_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
void flt_volume_set_volume(float volume); filter_volume_device &set_gain(float gain); // also may be used in mcfg to set initial value (default is 1.0)
float gain() { return m_gain; }
protected: protected:
// device-level overrides // device-level overrides

View File

@ -272,7 +272,7 @@ void advision_state::sound_g_w(u8 data)
void advision_state::sound_d_w(u8 data) void advision_state::sound_d_w(u8 data)
{ {
// D0: speaker volume // D0: speaker volume
m_volume->flt_volume_set_volume((data & 1) ? 0.5 : 1.0); m_volume->set_gain((data & 1) ? 0.5 : 1.0);
} }

View File

@ -2456,7 +2456,7 @@ void cdkong_state::speaker_update()
if (m_r[1] & 8) if (m_r[1] & 8)
m_speaker_volume = 1.0; m_speaker_volume = 1.0;
m_volume->flt_volume_set_volume(m_speaker_volume); m_volume->set_gain(m_speaker_volume);
} }
TIMER_DEVICE_CALLBACK_MEMBER(cdkong_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(cdkong_state::speaker_decay_sim)
@ -3598,7 +3598,7 @@ u8 estargte_state::cop_latch_ack_r()
void estargte_state::cop_vol_w(u8 data) void estargte_state::cop_vol_w(u8 data)
{ {
// G0-G2: speaker volume (not mute when 0) // G0-G2: speaker volume (not mute when 0)
m_volume->flt_volume_set_volume(((data & 7) | 8) / 15.0); m_volume->set_gain(((data & 7) | 8) / 15.0);
} }
// inputs // inputs

View File

@ -899,7 +899,7 @@ void flash_state::speaker_update()
m_speaker_volume = 50.0; m_speaker_volume = 50.0;
// it takes a bit before it actually starts fading // it takes a bit before it actually starts fading
m_volume->flt_volume_set_volume(std::min(m_speaker_volume, 1.0)); m_volume->set_gain(std::min(m_speaker_volume, 1.0));
} }
TIMER_DEVICE_CALLBACK_MEMBER(flash_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(flash_state::speaker_decay_sim)
@ -1342,7 +1342,7 @@ void leboom_state::speaker_update()
if (~m_c & 0x80) if (~m_c & 0x80)
m_speaker_volume = 1.0; m_speaker_volume = 1.0;
m_volume->flt_volume_set_volume(m_speaker_volume); m_volume->set_gain(m_speaker_volume);
} }
TIMER_DEVICE_CALLBACK_MEMBER(leboom_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(leboom_state::speaker_decay_sim)

View File

@ -1892,7 +1892,7 @@ void cchime_state::machine_start()
TIMER_DEVICE_CALLBACK_MEMBER(cchime_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(cchime_state::speaker_decay_sim)
{ {
m_volume->flt_volume_set_volume(m_speaker_volume); m_volume->set_gain(m_speaker_volume);
// volume decays when speaker is off, decay scale is determined by tone knob // volume decays when speaker is off, decay scale is determined by tone knob
const double step = (1.005 - 1.0005) / 100.0; // approximation const double step = (1.005 - 1.0005) / 100.0; // approximation
@ -1922,7 +1922,7 @@ void cchime_state::write_o(u16 data)
// O2: trigger speaker on // O2: trigger speaker on
if (~m_o & data & 4) if (~m_o & data & 4)
m_volume->flt_volume_set_volume(m_speaker_volume = 1.0); m_volume->set_gain(m_speaker_volume = 1.0);
m_o = data; m_o = data;
} }
@ -3491,7 +3491,7 @@ void litelrn_state::machine_start()
TIMER_DEVICE_CALLBACK_MEMBER(litelrn_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(litelrn_state::speaker_decay_sim)
{ {
m_volume->flt_volume_set_volume(m_speaker_volume); m_volume->set_gain(m_speaker_volume);
// volume decays when speaker is off, rate is determined by tone knob // volume decays when speaker is off, rate is determined by tone knob
const double div[3] = { 1.002, 1.004, 1.008 }; // approximation const double div[3] = { 1.002, 1.004, 1.008 }; // approximation
@ -3512,7 +3512,7 @@ void litelrn_state::write_o(u16 data)
{ {
// O0: trigger speaker on // O0: trigger speaker on
if (~data & m_o & 1) if (~data & m_o & 1)
m_volume->flt_volume_set_volume(m_speaker_volume = 1.0); m_volume->set_gain(m_speaker_volume = 1.0);
// O2: select mode switch // O2: select mode switch
// other: N/C // other: N/C
@ -6017,7 +6017,7 @@ void mmarvin_state::machine_start()
TIMER_DEVICE_CALLBACK_MEMBER(mmarvin_state::speaker_decay_sim) TIMER_DEVICE_CALLBACK_MEMBER(mmarvin_state::speaker_decay_sim)
{ {
m_volume->flt_volume_set_volume(m_speaker_volume); m_volume->set_gain(m_speaker_volume);
// volume decays when speaker is off, decay scale is determined by tone knob // volume decays when speaker is off, decay scale is determined by tone knob
const double step = (1.01 - 1.003) / 100.0; // approximation const double step = (1.01 - 1.003) / 100.0; // approximation
@ -6047,7 +6047,7 @@ void mmarvin_state::write_r(u32 data)
// R9: trigger speaker on // R9: trigger speaker on
if (m_r & ~data & 0x200) if (m_r & ~data & 0x200)
m_volume->flt_volume_set_volume(m_speaker_volume = 1.0); m_volume->set_gain(m_speaker_volume = 1.0);
// R0,R1: digit/led select // R0,R1: digit/led select
// R7: digit DP // R7: digit DP

View File

@ -39,7 +39,6 @@ TODO:
#include "emu.h" #include "emu.h"
#include "cpu/amis2000/amis2000.h" #include "cpu/amis2000/amis2000.h"
#include "machine/timer.h"
#include "sound/flt_vol.h" #include "sound/flt_vol.h"
#include "sound/spkrdev.h" #include "sound/spkrdev.h"
#include "video/pwm.h" #include "video/pwm.h"
@ -73,25 +72,21 @@ private:
required_device<speaker_sound_device> m_speaker; required_device<speaker_sound_device> m_speaker;
required_device<filter_volume_device> m_volume; required_device<filter_volume_device> m_volume;
u16 m_a = 0; emu_timer *m_decaytimer;
u8 m_d = 0; bool m_speaker_on = false;
double m_speaker_volume = 0.0;
void update_display();
void write_d(u8 data); void write_d(u8 data);
void write_a(u16 data); void write_a(u16 data);
void speaker_update(); TIMER_CALLBACK_MEMBER(speaker_decay_sim);
TIMER_DEVICE_CALLBACK_MEMBER(speaker_decay_sim);
}; };
void wildfire_state::machine_start() void wildfire_state::machine_start()
{ {
m_decaytimer = timer_alloc(FUNC(wildfire_state::speaker_decay_sim), this);
// register for savestates // register for savestates
save_item(NAME(m_a)); save_item(NAME(m_speaker_on));
save_item(NAME(m_d));
save_item(NAME(m_speaker_volume));
} }
@ -100,42 +95,36 @@ void wildfire_state::machine_start()
I/O I/O
*******************************************************************************/ *******************************************************************************/
void wildfire_state::speaker_update() TIMER_CALLBACK_MEMBER(wildfire_state::speaker_decay_sim)
{
if (~m_a & 0x1000)
m_speaker_volume = 1.0;
m_volume->flt_volume_set_volume(m_speaker_volume);
}
TIMER_DEVICE_CALLBACK_MEMBER(wildfire_state::speaker_decay_sim)
{ {
// volume decays when speaker is off (divisor and timer period determine duration) // volume decays when speaker is off (divisor and timer period determine duration)
speaker_update(); m_volume->set_gain(m_volume->gain() / 1.0025);
m_speaker_volume /= 1.0025; m_decaytimer->adjust(attotime::from_usec(100));
}
void wildfire_state::update_display()
{
m_display->matrix(~m_a, m_d);
} }
void wildfire_state::write_d(u8 data) void wildfire_state::write_d(u8 data)
{ {
// D0-D7: led/7seg data // D0-D7: led/7seg data
m_d = bitswap<8>(data,7,0,1,2,3,4,5,6); m_display->write_mx(bitswap<8>(data,7,0,1,2,3,4,5,6));
update_display();
} }
void wildfire_state::write_a(u16 data) void wildfire_state::write_a(u16 data)
{ {
// A0-A2: digit select // A0-A2: digit select
// A3-A11: led select // A3-A11: led select
m_a = data; m_display->write_my(~data);
update_display();
// A12: speaker on // A12: speaker on
speaker_update(); bool speaker_on = bool(~data & 0x1000);
if (speaker_on)
{
m_volume->set_gain(1.0);
m_decaytimer->adjust(attotime::never);
}
else if (m_speaker_on)
m_decaytimer->adjust(attotime::zero);
m_speaker_on = speaker_on;
} }
@ -183,10 +172,8 @@ void wildfire_state::wildfire(machine_config &config)
// sound hardware // sound hardware
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
FILTER_VOLUME(config, m_volume).set_gain(0.0).add_route(ALL_OUTPUTS, "mono", 1.0);
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "volume", 0.25); SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "volume", 0.25);
FILTER_VOLUME(config, m_volume).add_route(ALL_OUTPUTS, "mono", 1.0);
TIMER(config, "speaker_decay").configure_periodic(FUNC(wildfire_state::speaker_decay_sim), attotime::from_usec(100));
} }

View File

@ -499,8 +499,8 @@ K054539_CB_MEMBER(xexex_state::ym_set_mixing)
{ {
for (int out = 0; out < 2; out++) for (int out = 0; out < 2; out++)
{ {
m_filter_l[out]->flt_volume_set_volume((71.0 * left) / 55.0); m_filter_l[out]->set_gain((71.0 * left) / 55.0);
m_filter_r[out]->flt_volume_set_volume((71.0 * right) / 55.0); m_filter_r[out]->set_gain((71.0 * right) / 55.0);
} }
} }

View File

@ -89,7 +89,7 @@ void cclimber_audio_device::sample_rate_w(u8 data)
void cclimber_audio_device::sample_volume_w(u8 data) void cclimber_audio_device::sample_volume_w(u8 data)
{ {
m_volume->flt_volume_set_volume(double(data & 0x1f) / 31.0); // range 0-31 m_volume->set_gain(double(data & 0x1f) / 31.0); // range 0-31
} }
void cclimber_audio_device::sample_trigger(int state) void cclimber_audio_device::sample_trigger(int state)

View File

@ -346,8 +346,8 @@ void x68k_state::ppi_port_c_w(uint8_t data)
set_adpcm(); set_adpcm();
m_okim6258->set_divider(m_adpcm.rate); m_okim6258->set_divider(m_adpcm.rate);
m_adpcm_out[0]->flt_volume_set_volume((m_adpcm.pan & 1) ? 0.0f : 1.0f); m_adpcm_out[0]->set_gain((m_adpcm.pan & 1) ? 0.0f : 1.0f);
m_adpcm_out[1]->flt_volume_set_volume((m_adpcm.pan & 2) ? 0.0f : 1.0f); m_adpcm_out[1]->set_gain((m_adpcm.pan & 2) ? 0.0f : 1.0f);
} }
// Set joystick outputs // Set joystick outputs

View File

@ -602,7 +602,7 @@ void berzerk_state::audio_w(offs_t offset, uint8_t data)
case 1: case 1:
{ {
/* volume - 0 appears to be inaudible */ /* volume - 0 appears to be inaudible */
m_s14001a_volume->flt_volume_set_volume((data >> 3 & 7) / 7.0); m_s14001a_volume->set_gain((data >> 3 & 7) / 7.0);
/* clock control - the first LS161 divides the clock by 9 to 16, the 2nd by 8, /* clock control - the first LS161 divides the clock by 9 to 16, the 2nd by 8,
giving a final clock from 19.5kHz to 34.7kHz */ giving a final clock from 19.5kHz to 34.7kHz */

View File

@ -480,9 +480,9 @@ void darius_state::update_fm0()
const int right = ((0xff - m_pan[0]) * m_vol[6]) >> 8; const int right = ((0xff - m_pan[0]) * m_vol[6]) >> 8;
if (m_filter_l[0][3] != nullptr) if (m_filter_l[0][3] != nullptr)
m_filter_l[0][3]->flt_volume_set_volume(left / 100.0); m_filter_l[0][3]->set_gain(left / 100.0);
if (m_filter_r[0][3] != nullptr) if (m_filter_r[0][3] != nullptr)
m_filter_r[0][3]->flt_volume_set_volume(right / 100.0); /* FM #0 */ m_filter_r[0][3]->set_gain(right / 100.0); /* FM #0 */
} }
void darius_state::update_fm1() void darius_state::update_fm1()
@ -491,9 +491,9 @@ void darius_state::update_fm1()
const int right = ((0xff - m_pan[1]) * m_vol[7]) >> 8; const int right = ((0xff - m_pan[1]) * m_vol[7]) >> 8;
if (m_filter_l[1][3] != nullptr) if (m_filter_l[1][3] != nullptr)
m_filter_l[1][3]->flt_volume_set_volume(left / 100.0); m_filter_l[1][3]->set_gain(left / 100.0);
if (m_filter_r[1][3] != nullptr) if (m_filter_r[1][3] != nullptr)
m_filter_r[1][3]->flt_volume_set_volume(right / 100.0); /* FM #1 */ m_filter_r[1][3]->set_gain(right / 100.0); /* FM #1 */
} }
void darius_state::update_psg0(int port) void darius_state::update_psg0(int port)
@ -512,9 +512,9 @@ void darius_state::update_psg0(int port)
const int right = ((0xff - m_pan[2]) * m_vol[port]) >> 8; const int right = ((0xff - m_pan[2]) * m_vol[port]) >> 8;
if (lvol != nullptr) if (lvol != nullptr)
lvol->flt_volume_set_volume(left / 100.0); lvol->set_gain(left / 100.0);
if (rvol != nullptr) if (rvol != nullptr)
rvol->flt_volume_set_volume(right / 100.0); rvol->set_gain(right / 100.0);
} }
void darius_state::update_psg1(int port) void darius_state::update_psg1(int port)
@ -533,9 +533,9 @@ void darius_state::update_psg1(int port)
const int right = ((0xff - m_pan[3]) * m_vol[port + 3]) >> 8; const int right = ((0xff - m_pan[3]) * m_vol[port + 3]) >> 8;
if (lvol != nullptr) if (lvol != nullptr)
lvol->flt_volume_set_volume(left / 100.0); lvol->set_gain(left / 100.0);
if (rvol != nullptr) if (rvol != nullptr)
rvol->flt_volume_set_volume(right / 100.0); rvol->set_gain(right / 100.0);
} }
void darius_state::update_da() void darius_state::update_da()
@ -544,9 +544,9 @@ void darius_state::update_da()
const int right = m_def_vol[(m_pan[4] >> 4) & 0x0f]; const int right = m_def_vol[(m_pan[4] >> 4) & 0x0f];
if (m_msm5205_l != nullptr) if (m_msm5205_l != nullptr)
m_msm5205_l->flt_volume_set_volume(left / 100.0); m_msm5205_l->set_gain(left / 100.0);
if (m_msm5205_r != nullptr) if (m_msm5205_r != nullptr)
m_msm5205_r->flt_volume_set_volume(right / 100.0); m_msm5205_r->set_gain(right / 100.0);
} }
void darius_state::fm0_pan_w(u8 data) void darius_state::fm0_pan_w(u8 data)

View File

@ -642,7 +642,7 @@ void ninjaw_state::pancontrol_w(offs_t offset, u8 data)
m_pandata[offset] = (float)data * (100.f / 255.0f); m_pandata[offset] = (float)data * (100.f / 255.0f);
//popmessage(" pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3] ); //popmessage(" pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3] );
flt->flt_volume_set_volume(m_pandata[offset] / 100.0); flt->set_gain(m_pandata[offset] / 100.0);
} }

View File

@ -383,20 +383,20 @@ void othunder_state::tc0310fam_w(offs_t offset, u8 data)
because we are using the AY-3-8910 emulation. */ because we are using the AY-3-8910 emulation. */
volr = (m_pan[0] + m_pan[2]) * 100 / (2 * 0x1f); volr = (m_pan[0] + m_pan[2]) * 100 / (2 * 0x1f);
voll = (m_pan[1] + m_pan[3]) * 100 / (2 * 0x1f); voll = (m_pan[1] + m_pan[3]) * 100 / (2 * 0x1f);
m_2610_0l->flt_volume_set_volume(voll / 100.0); m_2610_0l->set_gain(voll / 100.0);
m_2610_0r->flt_volume_set_volume(volr / 100.0); m_2610_0r->set_gain(volr / 100.0);
/* CH1 */ /* CH1 */
volr = m_pan[0] * 100 / 0x1f; volr = m_pan[0] * 100 / 0x1f;
voll = m_pan[1] * 100 / 0x1f; voll = m_pan[1] * 100 / 0x1f;
m_2610_1l->flt_volume_set_volume(voll / 100.0); m_2610_1l->set_gain(voll / 100.0);
m_2610_1r->flt_volume_set_volume(volr / 100.0); m_2610_1r->set_gain(volr / 100.0);
/* CH2 */ /* CH2 */
volr = m_pan[2] * 100 / 0x1f; volr = m_pan[2] * 100 / 0x1f;
voll = m_pan[3] * 100 / 0x1f; voll = m_pan[3] * 100 / 0x1f;
m_2610_2l->flt_volume_set_volume(voll / 100.0); m_2610_2l->set_gain(voll / 100.0);
m_2610_2r->flt_volume_set_volume(volr / 100.0); m_2610_2r->set_gain(volr / 100.0);
} }

View File

@ -1585,7 +1585,7 @@ void taitoz_z80_sound_state::sound_bankswitch_w(u8 data)
/**** sound pan control ****/ /**** sound pan control ****/
void taitoz_state::pancontrol_w(offs_t offset, u8 data) void taitoz_state::pancontrol_w(offs_t offset, u8 data)
{ {
m_filter[offset & 3]->flt_volume_set_volume(data / 255.0f); m_filter[offset & 3]->set_gain(data / 255.0f);
} }

View File

@ -719,7 +719,7 @@ void topspeed_state::volume_w(offs_t offset, u8 data)
case 0x600: filter = m_filter1r; break; // YM-2151 R case 0x600: filter = m_filter1r; break; // YM-2151 R
} }
filter->flt_volume_set_volume(data / 255.0f); filter->set_gain(data / 255.0f);
} }
void topspeed_state::z80ctc_to0(int state) void topspeed_state::z80ctc_to0(int state)

View File

@ -375,7 +375,7 @@ void warriorb_state::pancontrol_w(offs_t offset, u8 data)
m_pandata[offset] = (data << 1) + data; // original volume * 3 m_pandata[offset] = (data << 1) + data; // original volume * 3
LOGPANDATA("pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3]); LOGPANDATA("pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3]);
flt->flt_volume_set_volume(m_pandata[offset] / 100.0); flt->set_gain(m_pandata[offset] / 100.0);
} }

View File

@ -390,13 +390,13 @@ void lockon_state::sound_vol(uint8_t data)
double lgain = gains[data & 0xf]; double lgain = gains[data & 0xf];
double rgain = gains[data >> 4]; double rgain = gains[data >> 4];
m_f2203_1l->flt_volume_set_volume(lgain); m_f2203_1l->set_gain(lgain);
m_f2203_2l->flt_volume_set_volume(lgain); m_f2203_2l->set_gain(lgain);
m_f2203_3l->flt_volume_set_volume(lgain); m_f2203_3l->set_gain(lgain);
m_f2203_1r->flt_volume_set_volume(rgain); m_f2203_1r->set_gain(rgain);
m_f2203_2r->flt_volume_set_volume(rgain); m_f2203_2r->set_gain(rgain);
m_f2203_3r->flt_volume_set_volume(rgain); m_f2203_3r->set_gain(rgain);
} }
void lockon_state::ym2203_irq(int state) void lockon_state::ym2203_irq(int state)

View File

@ -114,7 +114,7 @@ void senjyo_state::dac_clock_w(int state)
void senjyo_state::dac_volume_w(uint8_t data) void senjyo_state::dac_volume_w(uint8_t data)
{ {
m_volume->flt_volume_set_volume((data & 0xf) / 15.0); m_volume->set_gain((data & 0xf) / 15.0);
} }
void senjyo_state::dac_enable_w(uint8_t data) void senjyo_state::dac_enable_w(uint8_t data)