mirror of
https://github.com/holub/mame
synced 2025-04-26 10:13:37 +03:00
sound/discrete.cpp: Fix more crashes, and modernise a little.
Reserve some space in another vector that it takes addresses to members of (fixes lack of sound in dkong and dkongjr). Removed dependence on auto_alloc and friends. There's one more problematic make_unique_clear now, but there are several fewer auto_alloc family calls.
This commit is contained in:
parent
cc8cd6c33b
commit
687dd20aeb
@ -90,7 +90,7 @@ DEFINE_DEVICE_TYPE(DISCRETE, discrete_sound_device, "discrete", "Discrete Sound"
|
|||||||
|
|
||||||
struct output_buffer
|
struct output_buffer
|
||||||
{
|
{
|
||||||
double *node_buf;
|
std::unique_ptr<double []> node_buf;
|
||||||
const double *source;
|
const double *source;
|
||||||
volatile double *ptr;
|
volatile double *ptr;
|
||||||
int node_num;
|
int node_num;
|
||||||
@ -107,15 +107,15 @@ class discrete_task
|
|||||||
{
|
{
|
||||||
friend class discrete_device;
|
friend class discrete_device;
|
||||||
public:
|
public:
|
||||||
virtual ~discrete_task(void) { }
|
virtual ~discrete_task() { }
|
||||||
|
|
||||||
inline void step_nodes(void);
|
inline void step_nodes();
|
||||||
inline bool lock_threadid(int32_t threadid)
|
inline bool lock_threadid(int32_t threadid)
|
||||||
{
|
{
|
||||||
int expected = -1;
|
int expected = -1;
|
||||||
return m_threadid.compare_exchange_weak(expected, threadid, std::memory_order_release,std::memory_order_relaxed);
|
return m_threadid.compare_exchange_weak(expected, threadid, std::memory_order_release,std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
inline void unlock(void) { m_threadid = -1; }
|
inline void unlock() { m_threadid = -1; }
|
||||||
|
|
||||||
//const linked_list_entry *list;
|
//const linked_list_entry *list;
|
||||||
node_step_list_t step_list;
|
node_step_list_t step_list;
|
||||||
@ -123,22 +123,20 @@ public:
|
|||||||
/* list of source nodes */
|
/* list of source nodes */
|
||||||
std::vector<input_buffer> source_list; /* discrete_source_node */
|
std::vector<input_buffer> source_list; /* discrete_source_node */
|
||||||
|
|
||||||
int task_group;
|
int task_group = 0;
|
||||||
|
|
||||||
|
|
||||||
discrete_task(discrete_device &pdev)
|
discrete_task(discrete_device &pdev) : m_device(pdev), m_threadid(-1)
|
||||||
: task_group(0), m_device(pdev), m_threadid(-1), m_samples(0)
|
{
|
||||||
{
|
// FIXME: the code expects to be able to take pointers to members of elements of this vector before it's filled
|
||||||
source_list.clear();
|
source_list.reserve(16);
|
||||||
step_list.clear();
|
|
||||||
m_buffers.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void *task_callback(void *param, int threadid);
|
static void *task_callback(void *param, int threadid);
|
||||||
inline bool process(void);
|
inline bool process();
|
||||||
|
|
||||||
void check(discrete_task *dest_task);
|
void check(discrete_task &dest_task);
|
||||||
void prepare_for_queue(int samples);
|
void prepare_for_queue(int samples);
|
||||||
|
|
||||||
std::vector<output_buffer> m_buffers;
|
std::vector<output_buffer> m_buffers;
|
||||||
@ -146,8 +144,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<int32_t> m_threadid;
|
std::atomic<int32_t> m_threadid;
|
||||||
volatile int m_samples;
|
volatile int m_samples = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +175,7 @@ private:
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
inline void discrete_task::step_nodes(void)
|
inline void discrete_task::step_nodes()
|
||||||
{
|
{
|
||||||
for (input_buffer &sn : source_list)
|
for (input_buffer &sn : source_list)
|
||||||
{
|
{
|
||||||
@ -216,7 +213,7 @@ void *discrete_task::task_callback(void *param, int threadid)
|
|||||||
task_list_t *list = (task_list_t *) param;
|
task_list_t *list = (task_list_t *) param;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for (discrete_task *task : *list)
|
for (const auto &task : *list)
|
||||||
{
|
{
|
||||||
/* try to lock */
|
/* try to lock */
|
||||||
if (task->lock_threadid(threadid))
|
if (task->lock_threadid(threadid))
|
||||||
@ -231,7 +228,7 @@ void *discrete_task::task_callback(void *param, int threadid)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool discrete_task::process(void)
|
bool discrete_task::process()
|
||||||
{
|
{
|
||||||
int samples = std::min(int(m_samples), MAX_SAMPLES_PER_TASK_SLICE);
|
int samples = std::min(int(m_samples), MAX_SAMPLES_PER_TASK_SLICE);
|
||||||
|
|
||||||
@ -267,16 +264,16 @@ void discrete_task::prepare_for_queue(int samples)
|
|||||||
m_samples = samples;
|
m_samples = samples;
|
||||||
/* set up task buffers */
|
/* set up task buffers */
|
||||||
for (output_buffer &ob : m_buffers)
|
for (output_buffer &ob : m_buffers)
|
||||||
ob.ptr = ob.node_buf;
|
ob.ptr = ob.node_buf.get();
|
||||||
|
|
||||||
/* initialize sources */
|
/* initialize sources */
|
||||||
for (input_buffer &sn : source_list)
|
for (input_buffer &sn : source_list)
|
||||||
{
|
{
|
||||||
sn.ptr = sn.linked_outbuf->node_buf;
|
sn.ptr = sn.linked_outbuf->node_buf.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void discrete_task::check(discrete_task *dest_task)
|
void discrete_task::check(discrete_task &dest_task)
|
||||||
{
|
{
|
||||||
// FIXME: this function takes addresses of elements of a vector that has items added later
|
// FIXME: this function takes addresses of elements of a vector that has items added later
|
||||||
// 16 is enough for the systems in MAME, but the code should be fixed properly
|
// 16 is enough for the systems in MAME, but the code should be fixed properly
|
||||||
@ -289,7 +286,7 @@ void discrete_task::check(discrete_task *dest_task)
|
|||||||
{
|
{
|
||||||
discrete_base_node *task_node = node_entry->self;
|
discrete_base_node *task_node = node_entry->self;
|
||||||
|
|
||||||
for (discrete_step_interface *step_entry : dest_task->step_list)
|
for (discrete_step_interface *step_entry : dest_task.step_list)
|
||||||
{
|
{
|
||||||
discrete_base_node *dest_node = step_entry->self;
|
discrete_base_node *dest_node = step_entry->self;
|
||||||
|
|
||||||
@ -302,7 +299,6 @@ void discrete_task::check(discrete_task *dest_task)
|
|||||||
/* Fixme: sub nodes ! */
|
/* Fixme: sub nodes ! */
|
||||||
if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode_num))
|
if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode_num))
|
||||||
{
|
{
|
||||||
input_buffer source;
|
|
||||||
int found = -1;
|
int found = -1;
|
||||||
output_buffer *pbuf = nullptr;
|
output_buffer *pbuf = nullptr;
|
||||||
|
|
||||||
@ -319,28 +315,20 @@ void discrete_task::check(discrete_task *dest_task)
|
|||||||
{
|
{
|
||||||
output_buffer buf;
|
output_buffer buf;
|
||||||
|
|
||||||
buf.node_buf = auto_alloc_array(m_device.machine(), double,
|
buf.node_buf = std::make_unique<double []>((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY);
|
||||||
((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY));
|
buf.ptr = buf.node_buf.get();
|
||||||
buf.ptr = buf.node_buf;
|
|
||||||
buf.source = dest_node->m_input[inputnum];
|
buf.source = dest_node->m_input[inputnum];
|
||||||
buf.node_num = inputnode_num;
|
buf.node_num = inputnode_num;
|
||||||
//buf.node = device->discrete_find_node(inputnode);
|
//buf.node = device->discrete_find_node(inputnode);
|
||||||
m_buffers.push_back(buf);
|
m_buffers.push_back(std::move(buf));
|
||||||
pbuf = &m_buffers.back();
|
pbuf = &m_buffers.back();
|
||||||
}
|
}
|
||||||
m_device.discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode_num), NODE_CHILD_NODE_NUM(inputnode_num), this, task_group, dest_node->index(), dest_task->task_group);
|
m_device.discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode_num), NODE_CHILD_NODE_NUM(inputnode_num), this, task_group, dest_node->index(), dest_task.task_group);
|
||||||
|
|
||||||
/* register into source list */
|
/* register into source list */
|
||||||
//source = auto_alloc(device->machine(), discrete_source_node);
|
dest_task.source_list.push_back(input_buffer{ nullptr, pbuf, 0.0 });
|
||||||
//source.task = this;
|
// FIXME: taking address of element of vector before it's filled
|
||||||
//source.output_node = i;
|
dest_node->m_input[inputnum] = &dest_task.source_list.back().buffer;
|
||||||
source.linked_outbuf = pbuf;
|
|
||||||
source.buffer = 0.0; /* please compiler */
|
|
||||||
source.ptr = nullptr;
|
|
||||||
dest_task->source_list.push_back(source);
|
|
||||||
|
|
||||||
/* point the input to a buffered location */
|
|
||||||
dest_node->m_input[inputnum] = &dest_task->source_list.back().buffer; // was copied! &source.buffer;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,7 +357,7 @@ discrete_base_node::discrete_base_node() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
discrete_base_node::~discrete_base_node(void)
|
discrete_base_node::~discrete_base_node()
|
||||||
{
|
{
|
||||||
/* currently noting */
|
/* currently noting */
|
||||||
}
|
}
|
||||||
@ -393,7 +381,7 @@ void discrete_base_node::init(discrete_device *pdev, const discrete_block *xbloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void discrete_base_node::save_state(void)
|
void discrete_base_node::save_state()
|
||||||
{
|
{
|
||||||
if (m_block->node != NODE_SPECIAL)
|
if (m_block->node != NODE_SPECIAL)
|
||||||
m_device->save_item(NAME(m_output), m_block->node);
|
m_device->save_item(NAME(m_output), m_block->node);
|
||||||
@ -405,7 +393,7 @@ discrete_base_node *discrete_device::discrete_find_node(int node)
|
|||||||
return m_indexed_node[NODE_INDEX(node)];
|
return m_indexed_node[NODE_INDEX(node)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void discrete_base_node::resolve_input_nodes(void)
|
void discrete_base_node::resolve_input_nodes()
|
||||||
{
|
{
|
||||||
int inputnum;
|
int inputnum;
|
||||||
|
|
||||||
@ -617,7 +605,7 @@ static uint64_t list_run_time(const node_list_t &list)
|
|||||||
{
|
{
|
||||||
uint64_t total = 0;
|
uint64_t total = 0;
|
||||||
|
|
||||||
for (discrete_base_node *node : list)
|
for (const auto &node : list)
|
||||||
{
|
{
|
||||||
discrete_step_interface *step;
|
discrete_step_interface *step;
|
||||||
if (node->interface(step))
|
if (node->interface(step))
|
||||||
@ -637,12 +625,11 @@ static uint64_t step_list_run_time(const node_step_list_t &list)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
void discrete_device::display_profiling(void)
|
void discrete_device::display_profiling()
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
uint64_t total;
|
uint64_t total;
|
||||||
uint64_t tresh;
|
uint64_t tresh;
|
||||||
double tt;
|
|
||||||
|
|
||||||
/* calculate total time */
|
/* calculate total time */
|
||||||
total = list_run_time(m_node_list);
|
total = list_run_time(m_node_list);
|
||||||
@ -651,7 +638,7 @@ void discrete_device::display_profiling(void)
|
|||||||
osd_printf_info("Total Samples : %16d\n", m_total_samples);
|
osd_printf_info("Total Samples : %16d\n", m_total_samples);
|
||||||
tresh = total / count;
|
tresh = total / count;
|
||||||
osd_printf_info("Threshold (mean): %16d\n", tresh / m_total_samples);
|
osd_printf_info("Threshold (mean): %16d\n", tresh / m_total_samples);
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
discrete_step_interface *step;
|
discrete_step_interface *step;
|
||||||
if (node->interface(step))
|
if (node->interface(step))
|
||||||
@ -660,9 +647,9 @@ void discrete_device::display_profiling(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Task information */
|
/* Task information */
|
||||||
for (discrete_task *task : task_list)
|
for (const auto &task : task_list)
|
||||||
{
|
{
|
||||||
tt = step_list_run_time(task->step_list);
|
double tt = step_list_run_time(task->step_list);
|
||||||
|
|
||||||
osd_printf_info("Task(%d): %8.2f %15.2f\n", task->task_group, tt / double(total) * 100.0, tt / double(m_total_samples));
|
osd_printf_info("Task(%d): %8.2f %15.2f\n", task->task_group, tt / double(total) * 100.0, tt / double(m_total_samples));
|
||||||
}
|
}
|
||||||
@ -682,15 +669,15 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list)
|
|||||||
{
|
{
|
||||||
discrete_task *task = nullptr;
|
discrete_task *task = nullptr;
|
||||||
/* list tail pointers */
|
/* list tail pointers */
|
||||||
int has_tasks = 0;
|
bool has_tasks = false;
|
||||||
|
|
||||||
/* check whether we have tasks ... */
|
/* check whether we have tasks ... */
|
||||||
if (USE_DISCRETE_TASKS)
|
if (USE_DISCRETE_TASKS)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < block_list.size(); i++)
|
for (int i = 0; !has_tasks && (i < block_list.size()); i++)
|
||||||
{
|
{
|
||||||
if (block_list[i]->type == DSO_TASK_START)
|
if (block_list[i]->type == DSO_TASK_START)
|
||||||
has_tasks = 1;
|
has_tasks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,21 +686,23 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list)
|
|||||||
/* make sure we have one simple task
|
/* make sure we have one simple task
|
||||||
* No need to create a node since there are no dependencies.
|
* No need to create a node since there are no dependencies.
|
||||||
*/
|
*/
|
||||||
task = auto_alloc_clear(machine(), <discrete_task>(*this));
|
task_list.push_back(std::make_unique<discrete_task>(*this));
|
||||||
task_list.push_back(task);
|
task = task_list.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loop over all nodes */
|
/* loop over all nodes */
|
||||||
for (int i = 0; i < block_list.size(); i++)
|
for (int i = 0; i < block_list.size(); i++)
|
||||||
{
|
{
|
||||||
const discrete_block *block = block_list[i];
|
const discrete_block &block = *block_list[i];
|
||||||
|
|
||||||
//discrete_base_node *node = block->factory->Create(this, block);
|
// add to node list
|
||||||
discrete_base_node *node = block->factory(this, block);
|
m_node_list.push_back(block.factory(*this, block));
|
||||||
/* keep track of special nodes */
|
discrete_base_node &node = *m_node_list.back();
|
||||||
if (block->node == NODE_SPECIAL)
|
|
||||||
|
if (block.node == NODE_SPECIAL)
|
||||||
{
|
{
|
||||||
switch(block->type)
|
// keep track of special nodes
|
||||||
|
switch (block.type)
|
||||||
{
|
{
|
||||||
/* Output Node */
|
/* Output Node */
|
||||||
case DSO_OUTPUT:
|
case DSO_OUTPUT:
|
||||||
@ -734,12 +723,12 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list)
|
|||||||
{
|
{
|
||||||
if (task != nullptr)
|
if (task != nullptr)
|
||||||
fatalerror("init_nodes() - Nested DISCRETE_START_TASK.\n");
|
fatalerror("init_nodes() - Nested DISCRETE_START_TASK.\n");
|
||||||
task = auto_alloc_clear(machine(), <discrete_task>(*this));
|
task_list.push_back(std::make_unique<discrete_task>(*this));
|
||||||
task->task_group = block->initial[0];
|
task = task_list.back().get();
|
||||||
|
task->task_group = block.initial[0];
|
||||||
if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS)
|
if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS)
|
||||||
fatalerror("discrete_dso_task: illegal task_group %d\n", task->task_group);
|
fatalerror("discrete_dso_task: illegal task_group %d\n", task->task_group);
|
||||||
//logerror("task group %d\n", task->task_group);
|
//logerror("task group %d\n", task->task_group);
|
||||||
task_list.push_back(task);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -755,37 +744,33 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list)
|
|||||||
fatalerror("init_nodes() - Failed, trying to create unknown special discrete node.\n");
|
fatalerror("init_nodes() - Failed, trying to create unknown special discrete node.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise, make sure we are not a duplicate, and put ourselves into the indexed list */
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_indexed_node[NODE_INDEX(block->node)])
|
// otherwise, make sure we are not a duplicate, and put ourselves into the indexed list
|
||||||
fatalerror("init_nodes() - Duplicate entries for NODE_%02d\n", NODE_INDEX(block->node));
|
if (m_indexed_node[NODE_INDEX(block.node)])
|
||||||
m_indexed_node[NODE_INDEX(block->node)] = node;
|
fatalerror("init_nodes() - Duplicate entries for NODE_%02d\n", NODE_INDEX(block.node));
|
||||||
|
m_indexed_node[NODE_INDEX(block.node)] = &node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to node list */
|
// our running order just follows the order specified
|
||||||
m_node_list.push_back(node);
|
// does the node step?
|
||||||
|
|
||||||
/* our running order just follows the order specified */
|
|
||||||
/* does the node step ? */
|
|
||||||
discrete_step_interface *step;
|
discrete_step_interface *step;
|
||||||
if (node->interface(step))
|
if (node.interface(step))
|
||||||
{
|
{
|
||||||
/* do we belong to a task? */
|
/* do we belong to a task? */
|
||||||
if (task == nullptr)
|
if (task == nullptr)
|
||||||
fatalerror("init_nodes() - found node outside of task: %s\n", node->module_name() );
|
fatalerror("init_nodes() - found node outside of task: %s\n", node.module_name());
|
||||||
else
|
else
|
||||||
task->step_list.push_back(step);
|
task->step_list.push_back(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USE_DISCRETE_TASKS && block->type == DSO_TASK_END)
|
if (USE_DISCRETE_TASKS && block.type == DSO_TASK_END)
|
||||||
{
|
{
|
||||||
task = nullptr;
|
task = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and register save state */
|
/* and register save state */
|
||||||
node->save_state();
|
node.save_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_tasks)
|
if (!has_tasks)
|
||||||
@ -805,9 +790,9 @@ int discrete_device::same_module_index(const discrete_base_node &node)
|
|||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (discrete_base_node *n : m_node_list)
|
for (const auto &n : m_node_list)
|
||||||
{
|
{
|
||||||
if (n == &node)
|
if (n.get() == &node)
|
||||||
return index;
|
return index;
|
||||||
if (n->module_type() == node.module_type())
|
if (n->module_type() == node.module_type())
|
||||||
index++;
|
index++;
|
||||||
@ -846,7 +831,7 @@ discrete_sound_device::discrete_sound_device(const machine_config &mconfig, cons
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
discrete_device::~discrete_device(void)
|
discrete_device::~discrete_device()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,13 +877,13 @@ void discrete_device::device_start()
|
|||||||
m_node_list.clear();
|
m_node_list.clear();
|
||||||
|
|
||||||
/* allocate memory to hold pointers to nodes by index */
|
/* allocate memory to hold pointers to nodes by index */
|
||||||
m_indexed_node = auto_alloc_array_clear(this->machine(), discrete_base_node *, DISCRETE_MAX_NODES);
|
m_indexed_node = make_unique_clear<discrete_base_node * []>(DISCRETE_MAX_NODES);
|
||||||
|
|
||||||
/* initialize the node data */
|
/* initialize the node data */
|
||||||
init_nodes(block_list);
|
init_nodes(block_list);
|
||||||
|
|
||||||
/* now go back and find pointers to all input nodes */
|
/* now go back and find pointers to all input nodes */
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
node->resolve_input_nodes();
|
node->resolve_input_nodes();
|
||||||
}
|
}
|
||||||
@ -907,18 +892,18 @@ void discrete_device::device_start()
|
|||||||
m_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
|
m_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
|
||||||
|
|
||||||
/* Process nodes which have a start func */
|
/* Process nodes which have a start func */
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
node->start();
|
node->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set up tasks */
|
/* Now set up tasks */
|
||||||
for (discrete_task *task : task_list)
|
for (const auto &task : task_list)
|
||||||
{
|
{
|
||||||
for (discrete_task *dest_task : task_list)
|
for (const auto &dest_task : task_list)
|
||||||
{
|
{
|
||||||
if (task->task_group > dest_task->task_group)
|
if (task->task_group > dest_task->task_group)
|
||||||
dest_task->check(task);
|
dest_task->check(*task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -937,7 +922,7 @@ void discrete_device::device_stop()
|
|||||||
|
|
||||||
/* Process nodes which have a stop func */
|
/* Process nodes which have a stop func */
|
||||||
|
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
node->stop();
|
node->stop();
|
||||||
}
|
}
|
||||||
@ -964,10 +949,10 @@ void discrete_sound_device::device_start()
|
|||||||
discrete_device::device_start();
|
discrete_device::device_start();
|
||||||
|
|
||||||
/* look for input stream nodes */
|
/* look for input stream nodes */
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
/* if we are an stream input node, track that */
|
/* if we are an stream input node, track that */
|
||||||
discrete_dss_input_stream_node *input_stream = dynamic_cast<discrete_dss_input_stream_node *>(node);
|
discrete_dss_input_stream_node *input_stream = dynamic_cast<discrete_dss_input_stream_node *>(node.get());
|
||||||
if (input_stream != nullptr)
|
if (input_stream != nullptr)
|
||||||
{
|
{
|
||||||
m_input_stream_list.push_back(input_stream);
|
m_input_stream_list.push_back(input_stream);
|
||||||
@ -1003,7 +988,7 @@ void discrete_device::device_reset()
|
|||||||
update_to_current_time();
|
update_to_current_time();
|
||||||
|
|
||||||
/* loop over all nodes */
|
/* loop over all nodes */
|
||||||
for (discrete_base_node *node : m_node_list)
|
for (const auto &node : m_node_list)
|
||||||
{
|
{
|
||||||
/* Fimxe : node_level */
|
/* Fimxe : node_level */
|
||||||
node->m_output[0] = 0;
|
node->m_output[0] = 0;
|
||||||
@ -1032,7 +1017,7 @@ void discrete_device::process(int samples)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Setup tasks */
|
/* Setup tasks */
|
||||||
for (discrete_task *task : task_list)
|
for (const auto &task : task_list)
|
||||||
{
|
{
|
||||||
/* unlock the thread */
|
/* unlock the thread */
|
||||||
task->unlock();
|
task->unlock();
|
||||||
@ -1040,11 +1025,11 @@ void discrete_device::process(int samples)
|
|||||||
task->prepare_for_queue(samples);
|
task->prepare_for_queue(samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (discrete_task *task : task_list)
|
for (const auto &task : task_list)
|
||||||
{
|
{
|
||||||
/* Fire a work item for each task */
|
/* Fire a work item for each task */
|
||||||
(void)task;
|
(void)task;
|
||||||
osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE);
|
osd_work_item_queue(m_queue, discrete_task::task_callback, (void *)&task_list, WORK_ITEM_FLAG_AUTO_RELEASE);
|
||||||
}
|
}
|
||||||
osd_work_queue_wait(m_queue, osd_ticks_per_second()*10);
|
osd_work_queue_wait(m_queue, osd_ticks_per_second()*10);
|
||||||
|
|
||||||
|
@ -4106,9 +4106,9 @@ class discrete_task;
|
|||||||
class discrete_base_node;
|
class discrete_base_node;
|
||||||
class discrete_dss_input_stream_node;
|
class discrete_dss_input_stream_node;
|
||||||
class discrete_device;
|
class discrete_device;
|
||||||
typedef std::vector<discrete_base_node *> node_list_t;
|
typedef std::vector<std::unique_ptr<discrete_base_node> > node_list_t;
|
||||||
typedef std::vector<discrete_dss_input_stream_node *> istream_node_list_t;
|
typedef std::vector<discrete_dss_input_stream_node *> istream_node_list_t;
|
||||||
typedef std::vector<discrete_task *> task_list_t;
|
typedef std::vector<std::unique_ptr<discrete_task> > task_list_t;
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
@ -4128,7 +4128,7 @@ typedef std::vector<discrete_task *> task_list_t;
|
|||||||
struct discrete_block
|
struct discrete_block
|
||||||
{
|
{
|
||||||
int node; /* Output node number */
|
int node; /* Output node number */
|
||||||
discrete_base_node *(*factory)(discrete_device * pdev, const discrete_block *block);
|
std::unique_ptr<discrete_base_node> (*factory)(discrete_device &pdev, const discrete_block &block);
|
||||||
int type; /* see defines below */
|
int type; /* see defines below */
|
||||||
int active_inputs; /* Number of active inputs on this node type */
|
int active_inputs; /* Number of active inputs on this node type */
|
||||||
int input_node[DISCRETE_MAX_INPUTS];/* input/control nodes */
|
int input_node[DISCRETE_MAX_INPUTS];/* input/control nodes */
|
||||||
@ -4150,7 +4150,7 @@ class discrete_step_interface
|
|||||||
public:
|
public:
|
||||||
virtual ~discrete_step_interface() { }
|
virtual ~discrete_step_interface() { }
|
||||||
|
|
||||||
virtual void step(void) = 0;
|
virtual void step() = 0;
|
||||||
osd_ticks_t run_time;
|
osd_ticks_t run_time;
|
||||||
discrete_base_node * self;
|
discrete_base_node * self;
|
||||||
};
|
};
|
||||||
@ -4196,7 +4196,7 @@ public:
|
|||||||
|
|
||||||
uint8_t read(offs_t offset);
|
uint8_t read(offs_t offset);
|
||||||
void write(offs_t offset, uint8_t data);
|
void write(offs_t offset, uint8_t data);
|
||||||
virtual ~discrete_device(void);
|
virtual ~discrete_device();
|
||||||
|
|
||||||
template<int DiscreteInput>
|
template<int DiscreteInput>
|
||||||
DECLARE_WRITE_LINE_MEMBER(write_line)
|
DECLARE_WRITE_LINE_MEMBER(write_line)
|
||||||
@ -4206,7 +4206,7 @@ public:
|
|||||||
|
|
||||||
/* --------------------------------- */
|
/* --------------------------------- */
|
||||||
|
|
||||||
virtual void update_to_current_time(void) const { }
|
virtual void update_to_current_time() const { }
|
||||||
|
|
||||||
/* process a number of samples */
|
/* process a number of samples */
|
||||||
void process(int samples);
|
void process(int samples);
|
||||||
@ -4224,10 +4224,10 @@ public:
|
|||||||
discrete_base_node *discrete_find_node(int node);
|
discrete_base_node *discrete_find_node(int node);
|
||||||
|
|
||||||
/* are we profiling */
|
/* are we profiling */
|
||||||
inline int profiling(void) { return m_profiling; }
|
inline int profiling() { return m_profiling; }
|
||||||
|
|
||||||
inline int sample_rate(void) { return m_sample_rate; }
|
inline int sample_rate() { return m_sample_rate; }
|
||||||
inline double sample_time(void) { return m_sample_time; }
|
inline double sample_time() { return m_sample_time; }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -4255,11 +4255,11 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void discrete_build_list(const discrete_block *intf, sound_block_list_t &block_list);
|
void discrete_build_list(const discrete_block *intf, sound_block_list_t &block_list);
|
||||||
void discrete_sanity_check(const sound_block_list_t &block_list);
|
void discrete_sanity_check(const sound_block_list_t &block_list);
|
||||||
void display_profiling(void);
|
void display_profiling();
|
||||||
void init_nodes(const sound_block_list_t &block_list);
|
void init_nodes(const sound_block_list_t &block_list);
|
||||||
|
|
||||||
/* internal node tracking */
|
/* internal node tracking */
|
||||||
discrete_base_node ** m_indexed_node;
|
std::unique_ptr<discrete_base_node * []> m_indexed_node;
|
||||||
|
|
||||||
/* tasks */
|
/* tasks */
|
||||||
task_list_t task_list; /* discrete_task_context * */
|
task_list_t task_list; /* discrete_task_context * */
|
||||||
@ -4294,13 +4294,13 @@ public:
|
|||||||
set_intf(intf);
|
set_intf(intf);
|
||||||
}
|
}
|
||||||
discrete_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
discrete_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||||
virtual ~discrete_sound_device(void) { };
|
virtual ~discrete_sound_device() { };
|
||||||
|
|
||||||
/* --------------------------------- */
|
/* --------------------------------- */
|
||||||
|
|
||||||
virtual void update_to_current_time(void) const override { m_stream->update(); }
|
virtual void update_to_current_time() const override { m_stream->update(); }
|
||||||
|
|
||||||
sound_stream *get_stream(void) { return m_stream; }
|
sound_stream *get_stream() { return m_stream; }
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
@ -4336,13 +4336,14 @@ class discrete_base_node
|
|||||||
friend class discrete_task;
|
friend class discrete_task;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~discrete_base_node();
|
||||||
|
|
||||||
virtual void reset(void) { }
|
virtual void reset() { }
|
||||||
virtual void start(void) { }
|
virtual void start() { }
|
||||||
virtual void stop(void) { }
|
virtual void stop() { }
|
||||||
virtual void save_state(void);
|
virtual void save_state();
|
||||||
|
|
||||||
virtual int max_output(void) { return 1; };
|
virtual int max_output() { return 1; };
|
||||||
|
|
||||||
inline bool interface(discrete_step_interface *&intf) const { intf = m_step_intf; return (intf != nullptr); }
|
inline bool interface(discrete_step_interface *&intf) const { intf = m_step_intf; return (intf != nullptr); }
|
||||||
inline bool interface(discrete_input_interface *&intf) const { intf = m_input_intf; return (intf != nullptr); }
|
inline bool interface(discrete_input_interface *&intf) const { intf = m_input_intf; return (intf != nullptr); }
|
||||||
@ -4355,36 +4356,35 @@ public:
|
|||||||
inline void set_output(int n, double val) { m_output[n] = val; }
|
inline void set_output(int n, double val) { m_output[n] = val; }
|
||||||
|
|
||||||
/* Return the node index, i.e. X from NODE(X) */
|
/* Return the node index, i.e. X from NODE(X) */
|
||||||
inline int index(void) { return NODE_INDEX(m_block->node); }
|
inline int index() { return NODE_INDEX(m_block->node); }
|
||||||
|
|
||||||
/* Return the node number, i.e. NODE(X) */
|
/* Return the node number, i.e. NODE(X) */
|
||||||
inline int block_node(void) const { return m_block->node; }
|
inline int block_node() const { return m_block->node; }
|
||||||
|
|
||||||
/* Custom function specific initialisation data */
|
/* Custom function specific initialisation data */
|
||||||
inline const void *custom_data(void) { return m_custom; }
|
inline const void *custom_data() { return m_custom; }
|
||||||
|
|
||||||
inline int input_node(int inputnum) { return m_block->input_node[inputnum]; }
|
inline int input_node(int inputnum) { return m_block->input_node[inputnum]; }
|
||||||
|
|
||||||
/* Number of active inputs on this node type */
|
/* Number of active inputs on this node type */
|
||||||
inline int active_inputs(void) { return m_active_inputs; }
|
inline int active_inputs() { return m_active_inputs; }
|
||||||
/* Bit Flags. 1 in bit location means input_is_node */
|
/* Bit Flags. 1 in bit location means input_is_node */
|
||||||
inline int input_is_node(void) { return m_input_is_node; }
|
inline int input_is_node() { return m_input_is_node; }
|
||||||
|
|
||||||
inline double sample_time(void) { return m_device->sample_time(); }
|
inline double sample_time() { return m_device->sample_time(); }
|
||||||
inline int sample_rate(void) { return m_device->sample_rate(); }
|
inline int sample_rate() { return m_device->sample_rate(); }
|
||||||
|
|
||||||
const char * module_name(void) { return m_block->mod_name; }
|
const char * module_name() { return m_block->mod_name; }
|
||||||
inline int module_type(void) const { return m_block->type; }
|
inline int module_type() const { return m_block->type; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
discrete_base_node();
|
discrete_base_node();
|
||||||
virtual ~discrete_base_node();
|
|
||||||
|
|
||||||
/* finish node setup after allocation is complete */
|
/* finish node setup after allocation is complete */
|
||||||
void init(discrete_device * pdev, const discrete_block *block);
|
void init(discrete_device * pdev, const discrete_block *block);
|
||||||
|
|
||||||
void resolve_input_nodes(void);
|
void resolve_input_nodes();
|
||||||
|
|
||||||
double m_output[DISCRETE_MAX_OUTPUTS]; /* The node's last output value */
|
double m_output[DISCRETE_MAX_OUTPUTS]; /* The node's last output value */
|
||||||
const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */
|
const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */
|
||||||
@ -4406,7 +4406,7 @@ private:
|
|||||||
class discrete_node_base_factory
|
class discrete_node_base_factory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual discrete_base_node *Create(discrete_device * pdev, const discrete_block *block) = 0;
|
virtual std::unique_ptr<discrete_base_node> Create(discrete_device &pdev, const discrete_block &block) = 0;
|
||||||
virtual ~discrete_node_base_factory() {}
|
virtual ~discrete_node_base_factory() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4414,15 +4414,15 @@ template <class C>
|
|||||||
class discrete_node_factory : public discrete_node_base_factory
|
class discrete_node_factory : public discrete_node_base_factory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
discrete_base_node *Create(discrete_device * pdev, const discrete_block *block) override;
|
std::unique_ptr<discrete_base_node> Create(discrete_device &pdev, const discrete_block &block) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class C>
|
template <class C>
|
||||||
discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, const discrete_block *block)
|
std::unique_ptr<discrete_base_node> discrete_node_factory<C>::Create(discrete_device &pdev, const discrete_block &block)
|
||||||
{
|
{
|
||||||
discrete_base_node *r = auto_alloc_clear(pdev->machine(), <C>());
|
auto r = make_unique_clear<C>();
|
||||||
|
|
||||||
r->init(pdev, block);
|
r->init(&pdev, &block);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4442,9 +4442,9 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co
|
|||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
template <class C>
|
template <class C>
|
||||||
discrete_base_node *discrete_create_node(discrete_device * pdev, const discrete_block *block)
|
std::unique_ptr<discrete_base_node> discrete_create_node(discrete_device &pdev, const discrete_block &block)
|
||||||
{
|
{
|
||||||
return discrete_node_factory< C >().Create(pdev, block);
|
return discrete_node_factory<C>().Create(pdev, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DISCRETE_SOUND_EXTERN(name) extern const discrete_block name[]
|
#define DISCRETE_SOUND_EXTERN(name) extern const discrete_block name[]
|
||||||
|
Loading…
Reference in New Issue
Block a user