Added route-inputs to netlist sound device. Currently this is WIP and needs some polishing, however proof-of-concept exists now.

Example usage can be enabled in pong by uncommenting TEST_SOUND
This commit is contained in:
Couriersud 2014-02-02 15:59:41 +00:00
parent e39a886110
commit a1cf018fe5
5 changed files with 133 additions and 10 deletions

View File

@ -451,18 +451,22 @@ void netlist_mame_sound_device_t::device_start()
LOG_DEV_CALLS(("device_start %s\n", tag()));
netlist_list_t<nld_sound *> outdevs = netlist().get_device_list<nld_sound *>();
// Configure outputs
netlist_list_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out *>();
if (outdevs.count() == 0)
fatalerror("No output devices");
m_num_outputs = outdevs.count();
m_num_inputs = 0;
/* resort channels */
for (int i=0; i < MAX_OUT; i++) m_out[i] = NULL;
for (int i=0; i < m_num_outputs; i++)
{
int chan = outdevs[i]->m_channel.Value();
netlist().log("Output %d on channel %d", i, chan);
if (chan < 0 || chan >= MAX_OUT || chan >= outdevs.count())
fatalerror("illegal channel number");
m_out[chan] = outdevs[i];
@ -470,6 +474,21 @@ void netlist_mame_sound_device_t::device_start()
m_out[chan]->m_buffer = NULL;
}
// Configure inputs
m_num_inputs = 0;
m_in = NULL;
netlist_list_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in *>();
if (indevs.count() > 1)
fatalerror("A maximum of one input device is allowed!");
if (indevs.count() == 1)
{
m_in = indevs[0];
m_num_inputs = m_in->resolve();
m_in->m_inc = netlist_time::from_hz(clock());
}
/* initialize the stream(s) */
m_stream = machine().sound().stream_alloc(*this, m_num_inputs, m_num_outputs, clock());
@ -477,7 +496,8 @@ void netlist_mame_sound_device_t::device_start()
void netlist_mame_sound_device_t::nl_register_devices()
{
setup().factory().register_device<nld_sound>( "NETDEV_SOUND_OUT", "nld_sound", "+CHAN");
setup().factory().register_device<nld_sound_out>("NETDEV_SOUND_OUT", "nld_sound_out", "+CHAN");
setup().factory().register_device<nld_sound_in>("NETDEV_SOUND_IN", "nld_sound_in", "-");
}
@ -488,6 +508,14 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre
m_out[i]->m_buffer = outputs[i];
}
if (m_num_inputs)
m_in->buffer_reset();
for (int i=0; i < m_num_inputs; i++)
{
m_in->m_buffer[i] = inputs[i];
}
netlist_time cur = netlist().time();
//printf("current time %f\n", netlist().time().as_double());

View File

@ -96,9 +96,11 @@
void _name(const double data, const attotime &time)
#define NETDEV_SOUND_OUT(_name, _v) \
NET_REGISTER_DEV(sound, _name) \
NET_REGISTER_DEV(sound_out, _name) \
PARAM(_name.CHAN, _v)
#define NETDEV_SOUND_IN(_name) \
NET_REGISTER_DEV(sound_in, _name)
class netlist_mame_device_t;
@ -261,7 +263,8 @@ private:
};
class nld_sound;
class nld_sound_out;
class nld_sound_in;
// ----------------------------------------------------------------------------------------
// netlist_mame_sound_device_t
@ -299,7 +302,8 @@ protected:
private:
static const int MAX_OUT = 10;
nld_sound *m_out[MAX_OUT];
nld_sound_out *m_out[MAX_OUT];
nld_sound_in *m_in;
sound_stream *m_stream;
int m_num_inputs;
int m_num_outputs;
@ -443,10 +447,10 @@ private:
netlist_mame_cpu_device_t *m_cpu_device;
};
class NETLIB_NAME(sound) : public netlist_device_t
class NETLIB_NAME(sound_out) : public netlist_device_t
{
public:
NETLIB_NAME(sound)()
NETLIB_NAME(sound_out)()
: netlist_device_t() { }
static const int BUFSIZE = 2048;
@ -500,6 +504,82 @@ private:
netlist_time m_last_buffer;
};
class NETLIB_NAME(sound_in) : public netlist_device_t
{
public:
NETLIB_NAME(sound_in)()
: netlist_device_t() { }
static const int BUFSIZE = 2048;
ATTR_COLD void start()
{
// clock part
register_output("Q", m_Q);
register_input("FB", m_feedback);
connect(m_feedback, m_Q);
m_inc = netlist_time::from_nsec(1);
for (int i=0; i<10; i++)
register_param(pstring::sprintf("CHAN%d", i), m_param_name[i], "");
m_num_channel = 0;
}
ATTR_COLD void reset()
{
m_pos = 0;
for (int i=0; i<10; i++)
m_buffer[i] = NULL;
}
ATTR_COLD int resolve()
{
m_pos = 0;
for (int i=0; i<10; i++)
{
if (m_param_name[i].Value() != "")
{
if (i != m_num_channel)
netlist().error("sound input numbering has to be sequential!");
m_num_channel++;
m_param[i] = dynamic_cast<netlist_param_double_t *>(setup().find_param(m_param_name[i].Value(), true));
}
}
return m_num_channel;
}
ATTR_HOT void update()
{
for (int i=0; i<m_num_channel; i++)
{
if (m_buffer[i] == NULL)
break; // stop, called outside of stream_update
double v = m_buffer[i][m_pos];
m_param[i]->setTo(v / 1000.0);
}
m_pos++;
OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
}
ATTR_HOT void buffer_reset()
{
m_pos = 0;
}
netlist_param_str_t m_param_name[10];
netlist_param_double_t *m_param[10];
stream_sample_t *m_buffer[10];
netlist_time m_inc;
private:
netlist_ttl_input_t m_feedback;
netlist_ttl_output_t m_Q;
int m_pos;
int m_num_channel;
};
// device type definition
extern const device_type NETLIST_CORE;

View File

@ -56,6 +56,7 @@ NETLIB_UPDATE(ttl_input)
NETLIB_UPDATE_PARAM(ttl_input)
{
update();
}
// ----------------------------------------------------------------------------------------
@ -79,4 +80,5 @@ NETLIB_UPDATE(analog_input)
NETLIB_UPDATE_PARAM(analog_input)
{
update();
}

View File

@ -653,6 +653,7 @@ void netlist_setup_t::start_devices()
for (int i=0; i < ll.count(); i++)
{
NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr()));
printf("%d: <%s>\n",i, ll[i].cstr());
netlist_device_t *nc = factory().new_device_by_classname("nld_log", *this);
pstring name = "log_" + ll[i];
register_dev(nc, name);

View File

@ -766,6 +766,11 @@ static NETLIST_START(test)
SOLVER(Solver)
PARAM(Solver.FREQ, 48000)
NETDEV_SOUND_IN(SND_IN)
PARAM(SND_IN.CHAN0, "tin.IN")
ANALOG_INPUT(tin, 0)
// astable NAND Multivibrator
RES(R1, 1000)
CAP(C1, 1e-6)
@ -778,6 +783,9 @@ static NETLIST_START(test)
NETDEV_SOUND_OUT(CH0, 0)
NET_C(CH0.IN, n2.Q)
NETDEV_SOUND_OUT(CH1, 1)
NET_C(CH1.IN, tin.Q)
NETLIST_END()
#endif
@ -887,10 +895,14 @@ static MACHINE_CONFIG_START( pong, pong_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("dac", DAC, 48000)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
#ifdef TEST_SOUND
MCFG_SOUND_ROUTE_EX(0, "snd_test", 1.0, 0)
#else
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
#endif
#ifdef TEST_SOUND
MCFG_SOUND_ADD("snd_test", NETLIST_SOUND, 24000)
MCFG_SOUND_ADD("snd_test", NETLIST_SOUND, 48000)
MCFG_NETLIST_SETUP(test)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
#endif