mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
disound: Create m_specified_inputs_mask to track which inputs have been specified.
dac: Various improvements: - Default to output range -1..1, by far the most common case - Detect if inputs are specified and use those for output range leland: Update to leverage new DAC capabilities.
This commit is contained in:
parent
52c739b434
commit
eceffb4828
@ -91,8 +91,8 @@ dac_device_base::dac_device_base(const machine_config &mconfig, device_type type
|
||||
m_bits(bits),
|
||||
m_mapper(mapper),
|
||||
m_gain(gain),
|
||||
m_vref_base(0),
|
||||
m_vref_range(0)
|
||||
m_range_min(-1.0),
|
||||
m_range_max(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -108,12 +108,10 @@ void dac_device_base::device_start()
|
||||
m_value_map[code] = m_mapper(code, m_bits) * m_gain;
|
||||
|
||||
// determine the number of inputs
|
||||
int inputs = 0;
|
||||
if (m_vref_range == 0)
|
||||
inputs += 2;
|
||||
int inputs = (m_specified_inputs_mask == 0) ? 0 : 2;
|
||||
|
||||
// create the stream
|
||||
m_stream = stream_alloc(inputs, 1, 48000 * 4, STREAM_DISABLE_INPUT_RESAMPLING);
|
||||
m_stream = stream_alloc(inputs, 1, 48000 * 4);
|
||||
|
||||
// save data
|
||||
save_item(NAME(m_curval));
|
||||
@ -131,25 +129,31 @@ void dac_device_base::sound_stream_update(sound_stream &stream, std::vector<read
|
||||
// rails are constant
|
||||
if (inputs.size() == 0)
|
||||
{
|
||||
out.fill(m_vref_base + m_curval * m_vref_range);
|
||||
out.fill(m_range_min + m_curval * (m_range_max - m_range_min));
|
||||
return;
|
||||
}
|
||||
|
||||
auto &pos = inputs[DAC_VREF_POS_INPUT];
|
||||
auto &neg = inputs[DAC_VREF_NEG_INPUT];
|
||||
auto &hi = inputs[DAC_INPUT_RANGE_HI];
|
||||
auto &lo = inputs[DAC_INPUT_RANGE_LO];
|
||||
|
||||
// rails are streams but effectively constant
|
||||
if (pos.sample_rate() == SAMPLE_RATE_MINIMUM && neg.sample_rate() == SAMPLE_RATE_MINIMUM)
|
||||
out.fill(neg.get(0) + m_curval * (pos.get(0) - neg.get(0)));
|
||||
|
||||
// rails are streams matching our output rate
|
||||
else if (pos.sample_rate() == out.sample_rate() && neg.sample_rate() == out.sample_rate())
|
||||
// constant lo, streaming hi
|
||||
if (!BIT(m_specified_inputs_mask, DAC_INPUT_RANGE_LO))
|
||||
{
|
||||
for (int sampindex = 0; sampindex < out.samples(); sampindex++)
|
||||
out.put(sampindex, neg.get(sampindex) + m_curval * (pos.get(sampindex) - neg.get(sampindex)));
|
||||
out.put(sampindex, m_range_min + m_curval * (hi.get(sampindex) - m_range_min));
|
||||
}
|
||||
|
||||
// other cases not supported for now
|
||||
// constant hi, streaming lo
|
||||
else if (!BIT(m_specified_inputs_mask, DAC_INPUT_RANGE_HI))
|
||||
{
|
||||
for (int sampindex = 0; sampindex < out.samples(); sampindex++)
|
||||
out.put(sampindex, lo.get(sampindex) + m_curval * (m_range_max - lo.get(sampindex)));
|
||||
}
|
||||
|
||||
// both streams provided
|
||||
else
|
||||
throw emu_fatalerror("Unsupported case: DAC input rate does not match DAC output rate");
|
||||
{
|
||||
for (int sampindex = 0; sampindex < out.samples(); sampindex++)
|
||||
out.put(sampindex, lo.get(sampindex) + m_curval * (hi.get(sampindex) - lo.get(sampindex)));
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,11 @@
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define DAC_VREF_POS_INPUT (0)
|
||||
#define DAC_VREF_NEG_INPUT (1)
|
||||
#define DAC_INPUT_RANGE_HI (0)
|
||||
#define DAC_INPUT_RANGE_LO (1)
|
||||
|
||||
#define DAC_VREF_POS_INPUT (DAC_INPUT_RANGE_HI)
|
||||
#define DAC_VREF_NEG_INPUT (DAC_INPUT_RANGE_LO)
|
||||
|
||||
|
||||
|
||||
@ -100,14 +103,13 @@ protected:
|
||||
|
||||
public:
|
||||
// configuration
|
||||
dac_device_base &set_constant_vref(stream_buffer::sample_t vref1, stream_buffer::sample_t vref2)
|
||||
dac_device_base &set_output_range(stream_buffer::sample_t range_min, stream_buffer::sample_t range_max)
|
||||
{
|
||||
if (vref1 > vref2)
|
||||
std::swap(vref1, vref2);
|
||||
m_vref_base = vref1;
|
||||
m_vref_range = vref2 - vref1;
|
||||
m_range_min = range_min;
|
||||
m_range_max = range_max;
|
||||
return *this;
|
||||
}
|
||||
dac_device_base &set_output_range(stream_buffer::sample_t vref) { return set_output_range(-vref, vref); }
|
||||
|
||||
private:
|
||||
// internal state
|
||||
@ -119,8 +121,8 @@ private:
|
||||
u8 const m_bits;
|
||||
dac_mapper_callback const m_mapper;
|
||||
stream_buffer::sample_t const m_gain;
|
||||
stream_buffer::sample_t m_vref_base;
|
||||
stream_buffer::sample_t m_vref_range;
|
||||
stream_buffer::sample_t m_range_min;
|
||||
stream_buffer::sample_t m_range_max;
|
||||
};
|
||||
|
||||
|
||||
@ -128,11 +130,13 @@ private:
|
||||
|
||||
class dac_bit_device_base : public dac_device_base, public dac_bit_interface
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
dac_bit_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 bits, dac_mapper_callback mapper, stream_buffer::sample_t gain) :
|
||||
dac_device_base(mconfig, type, tag, owner, clock, bits, mapper, gain)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual WRITE_LINE_MEMBER(write) override { this->set_value(state); }
|
||||
virtual void data_w(u8 data) override { this->set_value(data); }
|
||||
};
|
||||
@ -142,11 +146,13 @@ public:
|
||||
|
||||
class dac_byte_device_base : public dac_device_base, public dac_byte_interface
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
dac_byte_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 bits, dac_mapper_callback mapper, stream_buffer::sample_t gain) :
|
||||
dac_device_base(mconfig, type, tag, owner, clock, bits, mapper, gain)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void write(u8 data) override { this->set_value(data); }
|
||||
virtual void data_w(u8 data) override { this->set_value(data); }
|
||||
};
|
||||
@ -156,11 +162,13 @@ public:
|
||||
|
||||
class dac_word_device_base : public dac_device_base, public dac_word_interface
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
dac_word_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 bits, dac_mapper_callback mapper, stream_buffer::sample_t gain) :
|
||||
dac_device_base(mconfig, type, tag, owner, clock, bits, mapper, gain)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void write(u16 data) override { this->set_value(data); }
|
||||
virtual void data_w(u16 data) override { this->set_value(data); }
|
||||
};
|
||||
|
@ -21,10 +21,11 @@
|
||||
// device_sound_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_sound_interface::device_sound_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_interface(device, "sound")
|
||||
, m_outputs(0)
|
||||
, m_auto_allocated_inputs(0)
|
||||
device_sound_interface::device_sound_interface(const machine_config &mconfig, device_t &device) :
|
||||
device_interface(device, "sound"),
|
||||
m_outputs(0),
|
||||
m_auto_allocated_inputs(0),
|
||||
m_specified_inputs_mask(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -292,10 +293,15 @@ void device_sound_interface::interface_pre_start()
|
||||
// scan each route on the device
|
||||
for (sound_route const &route : sound.routes())
|
||||
{
|
||||
// see if we are the target of this route; if we are, make sure the source device is started
|
||||
device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str());
|
||||
if ((target_device == &device()) && !sound.device().started())
|
||||
throw device_missing_dependencies();
|
||||
if (target_device == &device())
|
||||
{
|
||||
// see if we are the target of this route; if we are, make sure the source device is started
|
||||
if (!sound.device().started())
|
||||
throw device_missing_dependencies();
|
||||
if (route.m_input != AUTO_ALLOC_INPUT)
|
||||
m_specified_inputs_mask |= 1 << route.m_input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +314,7 @@ void device_sound_interface::interface_pre_start()
|
||||
{
|
||||
// see if we are the target of this route
|
||||
device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str());
|
||||
if ((target_device == &device()) && (route.m_input == AUTO_ALLOC_INPUT))
|
||||
if (target_device == &device() && route.m_input == AUTO_ALLOC_INPUT)
|
||||
{
|
||||
route.m_input = m_auto_allocated_inputs;
|
||||
m_auto_allocated_inputs += (route.m_output == ALL_OUTPUTS) ? sound.outputs() : 1;
|
||||
@ -339,7 +345,7 @@ void device_sound_interface::interface_post_start()
|
||||
int inputnum = route.m_input;
|
||||
int const numoutputs = sound.outputs();
|
||||
for (int outputnum = 0; outputnum < numoutputs; outputnum++)
|
||||
if ((route.m_output == outputnum) || (route.m_output == ALL_OUTPUTS))
|
||||
if (route.m_output == outputnum || route.m_output == ALL_OUTPUTS)
|
||||
{
|
||||
// find the output stream to connect from
|
||||
int streamoutputnum;
|
||||
@ -440,7 +446,7 @@ void device_mixer_interface::interface_pre_start()
|
||||
{
|
||||
// see if we are the target of this route
|
||||
device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str());
|
||||
if ((target_device == &device()) && (route.m_input < m_auto_allocated_inputs))
|
||||
if (target_device == &device() && route.m_input < m_auto_allocated_inputs)
|
||||
{
|
||||
int const count = (route.m_output == ALL_OUTPUTS) ? sound.outputs() : 1;
|
||||
for (int output = 0; output < count; output++)
|
||||
|
@ -109,6 +109,7 @@ protected:
|
||||
std::vector<sound_route> m_route_list; // list of sound routes
|
||||
int m_outputs; // number of outputs from this instance
|
||||
int m_auto_allocated_inputs; // number of auto-allocated inputs targeting us
|
||||
u32 m_specified_inputs_mask; // mask of inputs explicitly specified (not counting auto-allocated)
|
||||
};
|
||||
|
||||
// iterator
|
||||
|
@ -145,20 +145,15 @@ void leland_80186_sound_device::device_add_mconfig(machine_config &config)
|
||||
m_audiocpu->tmrout0_handler().set(FUNC(leland_80186_sound_device::i80186_tmr0_w));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
AD7524(config, m_dac[i], 0).add_route(ALL_OUTPUTS, "speaker", 0.2); // 74hc374.u31..6 + ad7524.u46..51
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0); // 74hc374.u17..22 + rX2-rX9 (24k,12k,6.2k,3k,1.5k,750,360,160) where X is 0..5
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, m_dacvol[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0).set_output_range(0, 1); // 74hc374.u17..22 + rX2-rX9 (24k,12k,6.2k,3k,1.5k,750,360,160) where X is 0..5
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_INPUT_RANGE_HI);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_INPUT_RANGE_LO);
|
||||
}
|
||||
AD7533(config, "dac9", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // ad7533.u64
|
||||
|
||||
vref.add_route(0, "dac9", 1.0, DAC_VREF_POS_INPUT);
|
||||
vref.add_route(0, "dac9", -1.0, DAC_VREF_NEG_INPUT);
|
||||
|
||||
PIT8254(config, m_pit[0], 0);
|
||||
m_pit[0]->set_clk<0>(4000000);
|
||||
m_pit[0]->out_handler<0>().set(m_audiocpu, FUNC(i80186_cpu_device::drq0_w));
|
||||
@ -186,14 +181,12 @@ void redline_80186_sound_device::device_add_mconfig(machine_config &config)
|
||||
m_audiocpu->chip_select_callback().set(FUNC(leland_80186_sound_device::peripheral_ctrl));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
AD7524(config, m_dac[i], 0).add_route(ALL_OUTPUTS, "speaker", 0.2); // unknown DAC
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_VREF_NEG_INPUT); // unknown DAC
|
||||
vref.add_route(0, m_dacvol[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0).set_output_range(0, 1);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_INPUT_RANGE_HI);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_INPUT_RANGE_LO); // unknown DAC
|
||||
}
|
||||
|
||||
PIT8254(config, m_pit[0], 0);
|
||||
@ -229,20 +222,15 @@ void ataxx_80186_sound_device::device_add_mconfig(machine_config &config)
|
||||
m_audiocpu->tmrout0_handler().set(FUNC(leland_80186_sound_device::i80186_tmr0_w));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
AD7524(config, m_dac[i], 0).add_route(ALL_OUTPUTS, "speaker", 0.2); // unknown DAC
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0); // unknown DAC
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, m_dacvol[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0).set_output_range(0, 1); // unknown DAC
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_INPUT_RANGE_HI);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_INPUT_RANGE_LO);
|
||||
}
|
||||
AD7533(config, "dac9", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC
|
||||
|
||||
vref.add_route(0, "dac9", 1.0, DAC_VREF_POS_INPUT);
|
||||
vref.add_route(0, "dac9", -1.0, DAC_VREF_NEG_INPUT);
|
||||
|
||||
PIT8254(config, m_pit[0], 0);
|
||||
m_pit[0]->set_clk<0>(4000000);
|
||||
m_pit[0]->out_handler<0>().set(m_audiocpu, FUNC(i80186_cpu_device::drq0_w));
|
||||
@ -264,18 +252,14 @@ void wsf_80186_sound_device::device_add_mconfig(machine_config &config)
|
||||
m_audiocpu->tmrout1_handler().set(FUNC(leland_80186_sound_device::i80186_tmr1_w));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
AD7524(config, m_dac[i], 0).add_route(ALL_OUTPUTS, "speaker", 0.2); // unknown DAC
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0); // unknown DAC
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_VREF_NEG_INPUT); // unknown DAC
|
||||
vref.add_route(0, m_dacvol[i], 1.0, DAC_VREF_POS_INPUT);
|
||||
DAC_8BIT_BINARY_WEIGHTED(config, m_dacvol[i], 0).set_output_range(0, 1); // unknown DAC
|
||||
m_dacvol[i]->add_route(0, m_dac[i], 1.0, DAC_INPUT_RANGE_HI);
|
||||
m_dacvol[i]->add_route(0, m_dac[i], -1.0, DAC_INPUT_RANGE_LO); // unknown DAC
|
||||
}
|
||||
AD7533(config, "dac9", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC
|
||||
vref.add_route(0, "dac9", 1.0, DAC_VREF_POS_INPUT);
|
||||
vref.add_route(0, "dac9", -1.0, DAC_VREF_NEG_INPUT);
|
||||
|
||||
/* sound hardware */
|
||||
YM2151(config, m_ymsnd, 4000000);
|
||||
|
@ -1560,7 +1560,7 @@ void williams_state::williams_base(machine_config &config)
|
||||
|
||||
// sound hardware
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
MC1408(config, "dac", 0).set_constant_vref(-1.0, 1.0).add_route(ALL_OUTPUTS, "speaker", 0.25); // mc1408.ic6
|
||||
MC1408(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25); // mc1408.ic6
|
||||
|
||||
// pia
|
||||
INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
|
||||
@ -1768,8 +1768,8 @@ void blaster_state::blaster(machine_config &config)
|
||||
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
MC1408(config, "ldac", 0).set_constant_vref(-1.0, 1.0).add_route(ALL_OUTPUTS, "lspeaker", 0.25); // unknown DAC
|
||||
MC1408(config, "rdac", 0).set_constant_vref(-1.0, 1.0).add_route(ALL_OUTPUTS, "rspeaker", 0.25); // unknown DAC
|
||||
MC1408(config, "ldac", 0).add_route(ALL_OUTPUTS, "lspeaker", 0.25); // unknown DAC
|
||||
MC1408(config, "rdac", 0).add_route(ALL_OUTPUTS, "rspeaker", 0.25); // unknown DAC
|
||||
}
|
||||
|
||||
|
||||
@ -1804,7 +1804,7 @@ void williams2_state::williams2_base(machine_config &config)
|
||||
|
||||
// sound hardware
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
MC1408(config, "dac", 0).set_constant_vref(-1.0, 1.0).add_route(ALL_OUTPUTS, "speaker", 0.5); // unknown DAC
|
||||
MC1408(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.5); // unknown DAC
|
||||
|
||||
INPUT_MERGER_ANY_HIGH(config, "mainirq").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE);
|
||||
INPUT_MERGER_ANY_HIGH(config, "soundirq").output_handler().set_inputline(m_soundcpu, M6808_IRQ_LINE);
|
||||
|
Loading…
Reference in New Issue
Block a user