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_sound_interface(mconfig, *this),
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()
{
m_gain = 1.0;
m_stream = stream_alloc(1, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE);
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)
{
m_stream->update();
m_gain = volume;
if (m_stream)
m_stream->update();
m_gain = gain;
return *this;
}

View File

@ -17,7 +17,8 @@ class filter_volume_device : public device_t, public device_sound_interface
public:
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:
// 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)
{
// 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)
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)
@ -3598,7 +3598,7 @@ u8 estargte_state::cop_latch_ack_r()
void estargte_state::cop_vol_w(u8 data)
{
// 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

View File

@ -899,7 +899,7 @@ void flash_state::speaker_update()
m_speaker_volume = 50.0;
// 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)
@ -1342,7 +1342,7 @@ void leboom_state::speaker_update()
if (~m_c & 0x80)
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)

View File

@ -1892,7 +1892,7 @@ void cchime_state::machine_start()
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
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
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;
}
@ -3491,7 +3491,7 @@ void litelrn_state::machine_start()
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
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
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
// other: N/C
@ -6017,7 +6017,7 @@ void mmarvin_state::machine_start()
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
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
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
// R7: digit DP

View File

@ -39,7 +39,6 @@ TODO:
#include "emu.h"
#include "cpu/amis2000/amis2000.h"
#include "machine/timer.h"
#include "sound/flt_vol.h"
#include "sound/spkrdev.h"
#include "video/pwm.h"
@ -73,25 +72,21 @@ private:
required_device<speaker_sound_device> m_speaker;
required_device<filter_volume_device> m_volume;
u16 m_a = 0;
u8 m_d = 0;
emu_timer *m_decaytimer;
bool m_speaker_on = false;
double m_speaker_volume = 0.0;
void update_display();
void write_d(u8 data);
void write_a(u16 data);
void speaker_update();
TIMER_DEVICE_CALLBACK_MEMBER(speaker_decay_sim);
TIMER_CALLBACK_MEMBER(speaker_decay_sim);
};
void wildfire_state::machine_start()
{
m_decaytimer = timer_alloc(FUNC(wildfire_state::speaker_decay_sim), this);
// register for savestates
save_item(NAME(m_a));
save_item(NAME(m_d));
save_item(NAME(m_speaker_volume));
save_item(NAME(m_speaker_on));
}
@ -100,42 +95,36 @@ void wildfire_state::machine_start()
I/O
*******************************************************************************/
void wildfire_state::speaker_update()
{
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)
TIMER_CALLBACK_MEMBER(wildfire_state::speaker_decay_sim)
{
// volume decays when speaker is off (divisor and timer period determine duration)
speaker_update();
m_speaker_volume /= 1.0025;
}
void wildfire_state::update_display()
{
m_display->matrix(~m_a, m_d);
m_volume->set_gain(m_volume->gain() / 1.0025);
m_decaytimer->adjust(attotime::from_usec(100));
}
void wildfire_state::write_d(u8 data)
{
// D0-D7: led/7seg data
m_d = bitswap<8>(data,7,0,1,2,3,4,5,6);
update_display();
m_display->write_mx(bitswap<8>(data,7,0,1,2,3,4,5,6));
}
void wildfire_state::write_a(u16 data)
{
// A0-A2: digit select
// A3-A11: led select
m_a = data;
update_display();
m_display->write_my(~data);
// 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
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);
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++)
{
m_filter_l[out]->flt_volume_set_volume((71.0 * left) / 55.0);
m_filter_r[out]->flt_volume_set_volume((71.0 * right) / 55.0);
m_filter_l[out]->set_gain((71.0 * left) / 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)
{
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)

View File

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

View File

@ -602,7 +602,7 @@ void berzerk_state::audio_w(offs_t offset, uint8_t data)
case 1:
{
/* 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,
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;
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)
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()
@ -491,9 +491,9 @@ void darius_state::update_fm1()
const int right = ((0xff - m_pan[1]) * m_vol[7]) >> 8;
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)
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)
@ -512,9 +512,9 @@ void darius_state::update_psg0(int port)
const int right = ((0xff - m_pan[2]) * m_vol[port]) >> 8;
if (lvol != nullptr)
lvol->flt_volume_set_volume(left / 100.0);
lvol->set_gain(left / 100.0);
if (rvol != nullptr)
rvol->flt_volume_set_volume(right / 100.0);
rvol->set_gain(right / 100.0);
}
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;
if (lvol != nullptr)
lvol->flt_volume_set_volume(left / 100.0);
lvol->set_gain(left / 100.0);
if (rvol != nullptr)
rvol->flt_volume_set_volume(right / 100.0);
rvol->set_gain(right / 100.0);
}
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];
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)
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)

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);
//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. */
volr = (m_pan[0] + m_pan[2]) * 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_0r->flt_volume_set_volume(volr / 100.0);
m_2610_0l->set_gain(voll / 100.0);
m_2610_0r->set_gain(volr / 100.0);
/* CH1 */
volr = m_pan[0] * 100 / 0x1f;
voll = m_pan[1] * 100 / 0x1f;
m_2610_1l->flt_volume_set_volume(voll / 100.0);
m_2610_1r->flt_volume_set_volume(volr / 100.0);
m_2610_1l->set_gain(voll / 100.0);
m_2610_1r->set_gain(volr / 100.0);
/* CH2 */
volr = m_pan[2] * 100 / 0x1f;
voll = m_pan[3] * 100 / 0x1f;
m_2610_2l->flt_volume_set_volume(voll / 100.0);
m_2610_2r->flt_volume_set_volume(volr / 100.0);
m_2610_2l->set_gain(voll / 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 ****/
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
}
filter->flt_volume_set_volume(data / 255.0f);
filter->set_gain(data / 255.0f);
}
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
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 rgain = gains[data >> 4];
m_f2203_1l->flt_volume_set_volume(lgain);
m_f2203_2l->flt_volume_set_volume(lgain);
m_f2203_3l->flt_volume_set_volume(lgain);
m_f2203_1l->set_gain(lgain);
m_f2203_2l->set_gain(lgain);
m_f2203_3l->set_gain(lgain);
m_f2203_1r->flt_volume_set_volume(rgain);
m_f2203_2r->flt_volume_set_volume(rgain);
m_f2203_3r->flt_volume_set_volume(rgain);
m_f2203_1r->set_gain(rgain);
m_f2203_2r->set_gain(rgain);
m_f2203_3r->set_gain(rgain);
}
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)
{
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)