diff options
author | 2020-09-30 23:40:06 +1000 | |
---|---|---|
committer | 2020-09-30 23:40:06 +1000 | |
commit | 687dd20aebdd0efe97a7ae54faf3a7badffc6473 (patch) | |
tree | 8d5d95ccaea760b9f96922abc697cb12e2f28e80 /src/devices/sound | |
parent | cc8cd6c33bd2e7fb261db2309f3561d64c0cab5a (diff) |
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.
Diffstat (limited to 'src/devices/sound')
-rw-r--r-- | src/devices/sound/discrete.cpp | 167 | ||||
-rw-r--r-- | src/devices/sound/discrete.h | 74 |
2 files changed, 113 insertions, 128 deletions
diff --git a/src/devices/sound/discrete.cpp b/src/devices/sound/discrete.cpp index 41ac932ef04..82dc5e8c9e4 100644 --- a/src/devices/sound/discrete.cpp +++ b/src/devices/sound/discrete.cpp @@ -90,7 +90,7 @@ DEFINE_DEVICE_TYPE(DISCRETE, discrete_sound_device, "discrete", "Discrete Sound" struct output_buffer { - double *node_buf; + std::unique_ptr<double []> node_buf; const double *source; volatile double *ptr; int node_num; @@ -107,15 +107,15 @@ class discrete_task { friend class discrete_device; public: - virtual ~discrete_task(void) { } + virtual ~discrete_task() { } - inline void step_nodes(void); + inline void step_nodes(); inline bool lock_threadid(int32_t threadid) { int expected = -1; 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; node_step_list_t step_list; @@ -123,22 +123,20 @@ public: /* list of source nodes */ std::vector<input_buffer> source_list; /* discrete_source_node */ - int task_group; + int task_group = 0; - discrete_task(discrete_device &pdev) - : task_group(0), m_device(pdev), m_threadid(-1), m_samples(0) -{ - source_list.clear(); - step_list.clear(); - m_buffers.clear(); + discrete_task(discrete_device &pdev) : m_device(pdev), m_threadid(-1) + { + // FIXME: the code expects to be able to take pointers to members of elements of this vector before it's filled + source_list.reserve(16); } protected: 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); std::vector<output_buffer> m_buffers; @@ -146,8 +144,7 @@ protected: private: 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) { @@ -216,7 +213,7 @@ void *discrete_task::task_callback(void *param, int threadid) task_list_t *list = (task_list_t *) param; do { - for (discrete_task *task : *list) + for (const auto &task : *list) { /* try to lock */ if (task->lock_threadid(threadid)) @@ -231,7 +228,7 @@ void *discrete_task::task_callback(void *param, int threadid) return nullptr; } -bool discrete_task::process(void) +bool discrete_task::process() { 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; /* set up task buffers */ for (output_buffer &ob : m_buffers) - ob.ptr = ob.node_buf; + ob.ptr = ob.node_buf.get(); /* initialize sources */ 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 // 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; - 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; @@ -302,7 +299,6 @@ void discrete_task::check(discrete_task *dest_task) /* Fixme: sub nodes ! */ if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode_num)) { - input_buffer source; int found = -1; output_buffer *pbuf = nullptr; @@ -319,28 +315,20 @@ void discrete_task::check(discrete_task *dest_task) { output_buffer buf; - buf.node_buf = auto_alloc_array(m_device.machine(), double, - ((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY)); - buf.ptr = buf.node_buf; + buf.node_buf = std::make_unique<double []>((task_node->sample_rate() + sound_manager::STREAMS_UPDATE_FREQUENCY) / sound_manager::STREAMS_UPDATE_FREQUENCY); + buf.ptr = buf.node_buf.get(); buf.source = dest_node->m_input[inputnum]; buf.node_num = inputnode_num; //buf.node = device->discrete_find_node(inputnode); - m_buffers.push_back(buf); + m_buffers.push_back(std::move(buf)); 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 */ - //source = auto_alloc(device->machine(), discrete_source_node); - //source.task = this; - //source.output_node = i; - 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; + dest_task.source_list.push_back(input_buffer{ nullptr, pbuf, 0.0 }); + // FIXME: taking address of element of vector before it's filled + dest_node->m_input[inputnum] = &dest_task.source_list.back().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 */ } @@ -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) 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)]; } -void discrete_base_node::resolve_input_nodes(void) +void discrete_base_node::resolve_input_nodes() { int inputnum; @@ -617,7 +605,7 @@ static uint64_t list_run_time(const node_list_t &list) { uint64_t total = 0; - for (discrete_base_node *node : list) + for (const auto &node : list) { discrete_step_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; } -void discrete_device::display_profiling(void) +void discrete_device::display_profiling() { int count; uint64_t total; uint64_t tresh; - double tt; /* calculate total time */ 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); tresh = total / count; 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; if (node->interface(step)) @@ -660,9 +647,9 @@ void discrete_device::display_profiling(void) } /* 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)); } @@ -682,15 +669,15 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) { discrete_task *task = nullptr; /* list tail pointers */ - int has_tasks = 0; + bool has_tasks = false; /* check whether we have 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) - 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 * No need to create a node since there are no dependencies. */ - task = auto_alloc_clear(machine(), <discrete_task>(*this)); - task_list.push_back(task); + task_list.push_back(std::make_unique<discrete_task>(*this)); + task = task_list.back().get(); } /* loop over all nodes */ 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); - discrete_base_node *node = block->factory(this, block); - /* keep track of special nodes */ - if (block->node == NODE_SPECIAL) + // add to node list + m_node_list.push_back(block.factory(*this, block)); + discrete_base_node &node = *m_node_list.back(); + + if (block.node == NODE_SPECIAL) { - switch(block->type) + // keep track of special nodes + switch (block.type) { /* Output Node */ case DSO_OUTPUT: @@ -734,12 +723,12 @@ void discrete_device::init_nodes(const sound_block_list_t &block_list) { if (task != nullptr) fatalerror("init_nodes() - Nested DISCRETE_START_TASK.\n"); - task = auto_alloc_clear(machine(), <discrete_task>(*this)); - task->task_group = block->initial[0]; + task_list.push_back(std::make_unique<discrete_task>(*this)); + task = task_list.back().get(); + task->task_group = block.initial[0]; if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS) fatalerror("discrete_dso_task: illegal task_group %d\n", task->task_group); //logerror("task group %d\n", task->task_group); - task_list.push_back(task); } 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"); } } - - /* otherwise, make sure we are not a duplicate, and put ourselves into the indexed list */ else { - if (m_indexed_node[NODE_INDEX(block->node)]) - fatalerror("init_nodes() - Duplicate entries for NODE_%02d\n", NODE_INDEX(block->node)); - m_indexed_node[NODE_INDEX(block->node)] = node; + // otherwise, make sure we are not a duplicate, and put ourselves into the indexed list + if (m_indexed_node[NODE_INDEX(block.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 */ - m_node_list.push_back(node); - - /* our running order just follows the order specified */ - /* does the node step ? */ + // our running order just follows the order specified + // does the node step? discrete_step_interface *step; - if (node->interface(step)) + if (node.interface(step)) { /* do we belong to a task? */ 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 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; } /* and register save state */ - node->save_state(); + node.save_state(); } if (!has_tasks) @@ -805,9 +790,9 @@ int discrete_device::same_module_index(const discrete_base_node &node) { 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; if (n->module_type() == node.module_type()) 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(); /* 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 */ init_nodes(block_list); /* 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(); } @@ -907,18 +892,18 @@ void discrete_device::device_start() m_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ); /* Process nodes which have a start func */ - for (discrete_base_node *node : m_node_list) + for (const auto &node : m_node_list) { node->start(); } /* 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) - dest_task->check(task); + dest_task->check(*task); } } } @@ -937,7 +922,7 @@ void discrete_device::device_stop() /* Process nodes which have a stop func */ - for (discrete_base_node *node : m_node_list) + for (const auto &node : m_node_list) { node->stop(); } @@ -964,10 +949,10 @@ void discrete_sound_device::device_start() discrete_device::device_start(); /* 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 */ - 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) { m_input_stream_list.push_back(input_stream); @@ -1003,7 +988,7 @@ void discrete_device::device_reset() update_to_current_time(); /* loop over all nodes */ - for (discrete_base_node *node : m_node_list) + for (const auto &node : m_node_list) { /* Fimxe : node_level */ node->m_output[0] = 0; @@ -1032,7 +1017,7 @@ void discrete_device::process(int samples) return; /* Setup tasks */ - for (discrete_task *task : task_list) + for (const auto &task : task_list) { /* unlock the thread */ task->unlock(); @@ -1040,11 +1025,11 @@ void discrete_device::process(int 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 */ (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); diff --git a/src/devices/sound/discrete.h b/src/devices/sound/discrete.h index ae7102b5799..87014470bbc 100644 --- a/src/devices/sound/discrete.h +++ b/src/devices/sound/discrete.h @@ -4106,9 +4106,9 @@ class discrete_task; class discrete_base_node; class discrete_dss_input_stream_node; 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_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 { 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 active_inputs; /* Number of active inputs on this node type */ int input_node[DISCRETE_MAX_INPUTS];/* input/control nodes */ @@ -4150,7 +4150,7 @@ class discrete_step_interface public: virtual ~discrete_step_interface() { } - virtual void step(void) = 0; + virtual void step() = 0; osd_ticks_t run_time; discrete_base_node * self; }; @@ -4196,7 +4196,7 @@ public: uint8_t read(offs_t offset); void write(offs_t offset, uint8_t data); - virtual ~discrete_device(void); + virtual ~discrete_device(); template<int DiscreteInput> 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 */ void process(int samples); @@ -4224,10 +4224,10 @@ public: discrete_base_node *discrete_find_node(int node); /* 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 double sample_time(void) { return m_sample_time; } + inline int sample_rate() { return m_sample_rate; } + inline double sample_time() { return m_sample_time; } protected: @@ -4255,11 +4255,11 @@ protected: private: 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 display_profiling(void); + void display_profiling(); void init_nodes(const sound_block_list_t &block_list); /* internal node tracking */ - discrete_base_node ** m_indexed_node; + std::unique_ptr<discrete_base_node * []> m_indexed_node; /* tasks */ task_list_t task_list; /* discrete_task_context * */ @@ -4294,13 +4294,13 @@ public: set_intf(intf); } 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: // device-level overrides @@ -4336,13 +4336,14 @@ class discrete_base_node friend class discrete_task; public: + virtual ~discrete_base_node(); - virtual void reset(void) { } - virtual void start(void) { } - virtual void stop(void) { } - virtual void save_state(void); + virtual void reset() { } + virtual void start() { } + virtual void stop() { } + 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_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; } /* 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) */ - inline int block_node(void) const { return m_block->node; } + inline int block_node() const { return m_block->node; } /* 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]; } /* 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 */ - 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 int sample_rate(void) { return m_device->sample_rate(); } + inline double sample_time() { return m_device->sample_time(); } + inline int sample_rate() { return m_device->sample_rate(); } - const char * module_name(void) { return m_block->mod_name; } - inline int module_type(void) const { return m_block->type; } + const char * module_name() { return m_block->mod_name; } + inline int module_type() const { return m_block->type; } protected: discrete_base_node(); - virtual ~discrete_base_node(); /* finish node setup after allocation is complete */ 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 */ const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ @@ -4406,7 +4406,7 @@ private: class discrete_node_base_factory { 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() {} }; @@ -4414,15 +4414,15 @@ template <class C> class discrete_node_factory : public discrete_node_base_factory { 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> -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; } @@ -4442,9 +4442,9 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co *************************************/ 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[] |