// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
disound.h
Device sound interfaces.
***************************************************************************/
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef MAME_EMU_DISOUND_H
#define MAME_EMU_DISOUND_H
#include <functional>
#include <utility>
//**************************************************************************
// CONSTANTS
//**************************************************************************
constexpr int ALL_OUTPUTS = 65535; // special value indicating all outputs for the current chip
constexpr int AUTO_ALLOC_INPUT = 65535;
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class read_stream_view;
class write_stream_view;
enum sound_stream_flags : u32;
// ======================> device_sound_interface
class device_sound_interface : public device_interface
{
public:
class sound_route
{
public:
u32 m_output; // output index, or ALL_OUTPUTS
u32 m_input; // target input index
u32 m_mixoutput; // target mixer output
float m_gain; // gain
std::reference_wrapper<device_t> m_base; // target search base
std::string m_target; // target tag
};
// construction/destruction
device_sound_interface(const machine_config &mconfig, device_t &device);
virtual ~device_sound_interface();
virtual bool issound() { return true; } /// HACK: allow devices to hide from the ui
// configuration access
std::vector<sound_route> const &routes() const { return m_route_list; }
// configuration helpers
template <typename T, bool R>
device_sound_interface &add_route(u32 output, const device_finder<T, R> &target, double gain, u32 input = AUTO_ALLOC_INPUT, u32 mixoutput = 0)
{
const std::pair<device_t &, const char *> ft(target.finder_target());
return add_route(output, ft.first, ft.second, gain, input, mixoutput);
}
device_sound_interface &add_route(u32 output, const char *target, double gain, u32 input = AUTO_ALLOC_INPUT, u32 mixoutput = 0);
device_sound_interface &add_route(u32 output, device_sound_interface &target, double gain, u32 input = AUTO_ALLOC_INPUT, u32 mixoutput = 0);
device_sound_interface &add_route(u32 output, speaker_device &target, double gain, u32 input = AUTO_ALLOC_INPUT, u32 mixoutput = 0);
device_sound_interface &reset_routes() { m_route_list.clear(); return *this; }
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs);
// stream creation
sound_stream *stream_alloc(int inputs, int outputs, int sample_rate);
sound_stream *stream_alloc(int inputs, int outputs, int sample_rate, sound_stream_flags flags);
// helpers
int inputs() const;
int outputs() const;
sound_stream *input_to_stream_input(int inputnum, int &stream_inputnum) const;
sound_stream *output_to_stream_output(int outputnum, int &stream_outputnum) const;
float input_gain(int inputnum) const;
float output_gain(int outputnum) const;
void set_input_gain(int inputnum, float gain);
void set_output_gain(int outputnum, float gain);
int inputnum_from_device(device_t &device, int outputnum = 0) const;
protected:
// configuration access
std::vector<sound_route> &routes() { return m_route_list; }
device_sound_interface &add_route(u32 output, device_t &base, const char *tag, double gain, u32 input, u32 mixoutput);
// optional operation overrides
virtual void interface_validity_check(validity_checker &valid) const override;
virtual void interface_pre_start() override;
virtual void interface_post_start() override;
virtual void interface_pre_reset() override;
// internal state
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
typedef device_interface_enumerator<device_sound_interface> sound_interface_enumerator;
// ======================> device_mixer_interface
class device_mixer_interface : public device_sound_interface
{
public:
// construction/destruction
device_mixer_interface(const machine_config &mconfig, device_t &device, int outputs = 1);
virtual ~device_mixer_interface();
protected:
// optional operation overrides
virtual void interface_pre_start() override;
virtual void interface_post_load() override;
// sound interface overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
// internal state
u8 m_outputs; // number of outputs
std::vector<u8> m_outputmap; // map of inputs to outputs
std::vector<bool> m_output_clear; // flag for tracking cleared buffers
sound_stream *m_mixer_stream; // mixing stream
};
// iterator
typedef device_interface_enumerator<device_mixer_interface> mixer_interface_enumerator;
#endif // MAME_EMU_DISOUND_H