diff options
Diffstat (limited to 'src/devices')
298 files changed, 2400 insertions, 1739 deletions
diff --git a/src/devices/bus/a2bus/a2cffa.cpp b/src/devices/bus/a2bus/a2cffa.cpp index 7f6104310be..d08ac21f017 100644 --- a/src/devices/bus/a2bus/a2cffa.cpp +++ b/src/devices/bus/a2bus/a2cffa.cpp @@ -2,7 +2,7 @@ // copyright-holders:R. Belmont /********************************************************************* - a2cffa.c + a2cffa.cpp Implementation of Rich Dreher's IDE/CompactFlash card for the Apple II. @@ -16,18 +16,12 @@ #include "imagedev/harddriv.h" #include "softlist.h" -/*************************************************************************** - PARAMETERS -***************************************************************************/ - -#define LOG_A2CFFA 1 - //************************************************************************** // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE(A2BUS_CFFA2, a2bus_cffa2_device, "a2cffa2", "CFFA2000 Compact Flash (65C02 firmware, www.dreher.net)") -DEFINE_DEVICE_TYPE(A2BUS_CFFA2_6502, a2bus_cffa2_6502_device, "a2cffa02", "CFFA2000 Compact Flash (6502 firmware, www.dreher.net)") +DEFINE_DEVICE_TYPE(A2BUS_CFFA2, a2bus_cffa2_device, "a2cffa2", "CFFA 2.0 Compact Flash (65C02 firmware, www.dreher.net)") +DEFINE_DEVICE_TYPE(A2BUS_CFFA2_6502, a2bus_cffa2_6502_device, "a2cffa02", "CFFA 2.0 Compact Flash (6502 firmware, www.dreher.net)") #define CFFA2_ROM_REGION "cffa2_rom" #define CFFA2_ATA_TAG "cffa2_ata" diff --git a/src/devices/bus/a2bus/a2mcms.cpp b/src/devices/bus/a2bus/a2mcms.cpp index 7e2cab57b6b..f9de57897f8 100644 --- a/src/devices/bus/a2bus/a2mcms.cpp +++ b/src/devices/bus/a2bus/a2mcms.cpp @@ -206,7 +206,7 @@ mcms_device::mcms_device(const machine_config &mconfig, const char *tag, device_ void mcms_device::device_start() { m_write_irq.resolve(); - m_stream = machine().sound().stream_alloc(*this, 0, 2, 31250); + m_stream = stream_alloc_legacy(0, 2, 31250); m_timer = timer_alloc(0, nullptr); m_clrtimer = timer_alloc(1, nullptr); m_enabled = false; @@ -252,7 +252,7 @@ void mcms_device::device_timer(emu_timer &timer, device_timer_id tid, int param, } } -void mcms_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mcms_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *outL, *outR; int i, v; diff --git a/src/devices/bus/a2bus/a2mcms.h b/src/devices/bus/a2bus/a2mcms.h index 9a183a9313d..11e8b332ee0 100644 --- a/src/devices/bus/a2bus/a2mcms.h +++ b/src/devices/bus/a2bus/a2mcms.h @@ -42,7 +42,7 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream *m_stream; diff --git a/src/devices/bus/coco/coco_ssc.cpp b/src/devices/bus/coco/coco_ssc.cpp index 2f7a1793071..63f6e90fcc5 100644 --- a/src/devices/bus/coco/coco_ssc.cpp +++ b/src/devices/bus/coco/coco_ssc.cpp @@ -130,7 +130,7 @@ namespace virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream* m_stream; @@ -535,17 +535,17 @@ cocossc_sac_device::cocossc_sac_device(const machine_config &mconfig, const char void cocossc_sac_device::device_start() { - m_stream = stream_alloc(1, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void cocossc_sac_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cocossc_sac_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { - stream_sample_t *src = inputs[0]; + stream_sample_t const *src = inputs[0]; stream_sample_t *dst = outputs[0]; double n = samples; diff --git a/src/devices/bus/isa/gus.cpp b/src/devices/bus/isa/gus.cpp index 239b8a6d2d2..a1c3f39612e 100644 --- a/src/devices/bus/isa/gus.cpp +++ b/src/devices/bus/isa/gus.cpp @@ -243,7 +243,7 @@ void gf1_device::device_timer(emu_timer &timer, device_timer_id id, int param, v } } -void gf1_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void gf1_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int x,y; //uint32_t count; @@ -403,7 +403,7 @@ void gf1_device::device_start() m_wave_ram.resize(1024*1024); memset(&m_wave_ram[0], 0, 1024*1024); - m_stream = stream_alloc(0,2,clock() / (14 * 16)); + m_stream = stream_alloc_legacy(0,2,clock() / (14 * 16)); // init timers m_timer1 = timer_alloc(ADLIB_TIMER1); diff --git a/src/devices/bus/isa/gus.h b/src/devices/bus/isa/gus.h index ec2e4168142..3f637bee84d 100644 --- a/src/devices/bus/isa/gus.h +++ b/src/devices/bus/isa/gus.h @@ -123,7 +123,7 @@ public: // optional information overrides virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; protected: // voice-specific registers diff --git a/src/devices/bus/neogeo/prot_fatfury2.cpp b/src/devices/bus/neogeo/prot_fatfury2.cpp index bd7af9247db..c8e7151e6e8 100644 --- a/src/devices/bus/neogeo/prot_fatfury2.cpp +++ b/src/devices/bus/neogeo/prot_fatfury2.cpp @@ -11,14 +11,18 @@ DEFINE_DEVICE_TYPE(NG_FATFURY2_PROT, fatfury2_prot_device, "ng_fatfury_prot", "N fatfury2_prot_device::fatfury2_prot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, NG_FATFURY2_PROT, tag, owner, clock), - m_prot_data(0) + m_pro_ct0(*this, "pro_ct0") { } +void fatfury2_prot_device::device_add_mconfig(machine_config &config) +{ + ALPHA_8921(config, m_pro_ct0, 0); // PRO-CT0 or SNK-9201 +} + void fatfury2_prot_device::device_start() { - save_item(NAME(m_prot_data)); } void fatfury2_prot_device::device_reset() @@ -33,69 +37,27 @@ void fatfury2_prot_device::device_reset() /* 0x2xxxxx range. There are several checks all around the code. */ uint16_t fatfury2_prot_device::protection_r(offs_t offset) { - uint16_t res = m_prot_data >> 24; - - switch (offset) - { - case 0x55550/2: - case 0xffff0/2: - case 0x00000/2: - case 0xff000/2: - case 0x36000/2: - case 0x36008/2: - return res; - - case 0x36004/2: - case 0x3600c/2: - return ((res & 0xf0) >> 4) | ((res & 0x0f) << 4); - - default: - logerror("unknown protection read at %s, offset %08x\n", machine().describe_context(), offset << 1); - return 0; - } + m_pro_ct0->even_w(BIT(offset, 1)); + m_pro_ct0->h_w(BIT(offset, 2)); + u8 gad = m_pro_ct0->gad_r(); + u8 gbd = m_pro_ct0->gbd_r(); + return (BIT(gbd, 0, 2) << 6) | (BIT(gbd, 2, 2) << 4) | (BIT(gad, 0, 2) << 6) | (BIT(gad, 2, 2) << 4); } void fatfury2_prot_device::protection_w(offs_t offset, uint16_t data) { - switch (offset) - { - case 0x11112/2: /* data == 0x1111; expects 0xff000000 back */ - m_prot_data = 0xff000000; - break; - - case 0x33332/2: /* data == 0x3333; expects 0x0000ffff back */ - m_prot_data = 0x0000ffff; - break; - - case 0x44442/2: /* data == 0x4444; expects 0x00ff0000 back */ - m_prot_data = 0x00ff0000; - break; - - case 0x55552/2: /* data == 0x5555; read back from 55550, ffff0, 00000, ff000 */ - m_prot_data = 0xff00ff00; - break; - - case 0x56782/2: /* data == 0x1234; read back from 36000 *or* 36004 */ - m_prot_data = 0xf05a3601; - break; - - case 0x42812/2: /* data == 0x1824; read back from 36008 *or* 3600c */ - m_prot_data = 0x81422418; - break; - - case 0x55550/2: - case 0xffff0/2: - case 0xff000/2: - case 0x36000/2: - case 0x36004/2: - case 0x36008/2: - case 0x3600c/2: - m_prot_data <<= 8; - break; - - default: - logerror("unknown protection write at %s, offset %08x, data %02x\n", machine().describe_context(), offset, data); - break; - } + // /PORTOEL connected into PRO-CT0 CLK pin + m_pro_ct0->clk_w(true); + + m_pro_ct0->load_w(BIT(offset, 0)); // A1 + m_pro_ct0->even_w(BIT(offset, 1)); // A2 + m_pro_ct0->h_w(BIT(offset, 2)); // A3 + + // C16-31 = A4-A19, C0-C15 = D0-D15 + m_pro_ct0->c_w((u32(bitswap<16>(BIT(offset, 3, 16), 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0)) << 16) | + bitswap<16>(data, 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0)); + + // release /PORTOEL + m_pro_ct0->clk_w(false); } diff --git a/src/devices/bus/neogeo/prot_fatfury2.h b/src/devices/bus/neogeo/prot_fatfury2.h index 111b9f7388b..1cab87cb26a 100644 --- a/src/devices/bus/neogeo/prot_fatfury2.h +++ b/src/devices/bus/neogeo/prot_fatfury2.h @@ -6,6 +6,8 @@ #pragma once +#include "machine/alpha_8921.h" + DECLARE_DEVICE_TYPE(NG_FATFURY2_PROT, fatfury2_prot_device) @@ -19,10 +21,12 @@ public: void protection_w(offs_t offset, uint16_t data); protected: + virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; - uint32_t m_prot_data; +private: + required_device<alpha_8921_device> m_pro_ct0; // PRO-CT0 or SNK-9201 }; #endif // MAME_BUS_NEOGEO_PROT_FATFURY2_H diff --git a/src/devices/bus/uts_kbd/400kbd.cpp b/src/devices/bus/uts_kbd/400kbd.cpp index 38d35fda607..50e05d4eddf 100644 --- a/src/devices/bus/uts_kbd/400kbd.cpp +++ b/src/devices/bus/uts_kbd/400kbd.cpp @@ -112,7 +112,7 @@ static INPUT_PORTS_START(uts_400kbd) PORT_BIT(0x03, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE) PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('`') PORT_CHAR('@') PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('@') PORT_CHAR('`') PORT_CODE(KEYCODE_EQUALS) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('=') PORT_CODE(KEYCODE_MINUS) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('^') PORT_CHAR('~') PORT_CODE(KEYCODE_TILDE) diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp index f43e25e7986..58f3d31b150 100644 --- a/src/devices/cpu/mcs48/mcs48.cpp +++ b/src/devices/cpu/mcs48/mcs48.cpp @@ -889,10 +889,10 @@ OPHANDLER( stop_tcnt ) { burn_cycles(1); m_timecount_enabled = 0; } OPHANDLER( strt_t ) { burn_cycles(1); m_timecount_enabled = TIMER_ENABLED; m_prescaler = 0; } OPHANDLER( strt_cnt ) { + burn_cycles(1); if (!(m_timecount_enabled & COUNTER_ENABLED)) m_t1_history = test_r(1); - burn_cycles(1); m_timecount_enabled = COUNTER_ENABLED; } diff --git a/src/devices/cpu/pdp1/pdp1.cpp b/src/devices/cpu/pdp1/pdp1.cpp index a8704ad29d3..2d04709a4a9 100644 --- a/src/devices/cpu/pdp1/pdp1.cpp +++ b/src/devices/cpu/pdp1/pdp1.cpp @@ -348,8 +348,8 @@ #define LOG_EXTRA 0 #define LOG_IOT_EXTRA 0 -#define READ_PDP_18BIT(A) ((signed)m_program->read_dword((A)<<2)) -#define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A)<<2,(V))) +#define READ_PDP_18BIT(A) ((signed)m_program->read_dword(A)) +#define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A),(V))) #define PC m_pc @@ -378,12 +378,14 @@ #define PREVIOUS_PC ((PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK)) -DEFINE_DEVICE_TYPE(PDP1, pdp1_device, "pdp1_cpu", "DEC PDP1") +DEFINE_DEVICE_TYPE(PDP1, pdp1_device, "pdp1_cpu", "DEC PDP-1 Central Processor") pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, PDP1, tag, owner, clock) - , m_program_config("program", ENDIANNESS_BIG, 32, 18, 0) + , m_program_config("program", ENDIANNESS_BIG, 32, 18, -2) // data is actually 18 bits wide + , m_extern_iot(*this) + , m_io_sc_callback(*this) { m_program_config.m_is_octal = true; } @@ -405,16 +407,9 @@ void pdp1_device::device_config_complete() // or initialize to defaults if none provided else { - memset(&read_binary_word, 0, sizeof(read_binary_word)); - memset(&io_sc_callback, 0, sizeof(io_sc_callback)); extend_support = 0; hw_mul_div = 0; type_20_sbs = 0; - - for (auto & elem : extern_iot) - { - memset(&elem, 0, sizeof(elem)); - } } } @@ -495,34 +490,6 @@ void pdp1_device::execute_set_input(int irqline, int state) } -static void null_iot(device_t *device, int op2, int nac, int mb, int *io, int ac) -{ - pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device); - - pdp1->pdp1_null_iot(op2, nac, mb, io, ac); -} - -static void lem_eem_iot(device_t *device, int op2, int nac, int mb, int *io, int ac) -{ - pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device); - - pdp1->pdp1_lem_eem_iot(op2, nac, mb, io, ac); -} - -static void sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac) -{ - pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device); - - pdp1->pdp1_sbs_iot(op2, nac, mb, io, ac); -} - -static void type_20_sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac) -{ - pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device); - - pdp1->pdp1_type_20_sbs_iot(op2, nac, mb, io, ac); -} - void pdp1_device::device_start() { int i; @@ -569,12 +536,11 @@ void pdp1_device::device_start() /* set up params and callbacks */ for (i=0; i<64; i++) { - m_extern_iot[i] = (extern_iot[i]) - ? extern_iot[i] - : null_iot; + m_extern_iot[i].resolve(); + if (m_extern_iot[i].isnull()) + m_extern_iot[i] = iot_delegate(*this, FUNC(pdp1_device::null_iot)); } - m_read_binary_word = read_binary_word; - m_io_sc_callback = io_sc_callback; + m_io_sc_callback.resolve(); m_extend_support = extend_support; m_hw_mul_div = hw_mul_div; m_type_20_sbs = type_20_sbs; @@ -599,13 +565,13 @@ void pdp1_device::device_start() if (m_extend_support) { - m_extern_iot[074] = lem_eem_iot; + m_extern_iot[074] = iot_delegate(*this, FUNC(pdp1_device::lem_eem_iot)); } - m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = sbs_iot; + m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = iot_delegate(*this, FUNC(pdp1_device::sbs_iot)); if (m_type_20_sbs) { m_extern_iot[050] = m_extern_iot[051] = m_extern_iot[052] = m_extern_iot[053] - = type_20_sbs_iot; + = iot_delegate(*this, FUNC(pdp1_device::type_20_sbs_iot)); } state_add( PDP1_PC, "PC", m_pc).formatstr("%06O"); @@ -796,9 +762,6 @@ void pdp1_device::execute_run() { do { - debugger_instruction_hook(PC); - - /* ioh should be cleared at the end of the instruction cycle, and ios at the start of next instruction cycle, but who cares? */ if (m_ioh && m_ios) @@ -808,15 +771,19 @@ void pdp1_device::execute_run() if ((! m_run) && (! m_rim)) + { + debugger_instruction_hook(PC); m_icount = 0; /* if processor is stopped, just burn cycles */ + } else if (m_rim) { switch (m_rim_step) { case 0: /* read first word as instruction */ - if (m_read_binary_word) - (*m_read_binary_word)(this); /* data will be transferred to IO register */ + MB = 0; + /* data will be transferred to IO register in response to RPB */ + m_extern_iot[2](2, 0, 1, IO, AC); m_rim_step = 1; m_ios = 0; break; @@ -860,8 +827,9 @@ void pdp1_device::execute_run() case 2: /* read second word as data */ - if (m_read_binary_word) - (*m_read_binary_word)(this); /* data will be transferred to IO register */ + MB = 0; + /* data will be transferred to IO register in response to RPB */ + m_extern_iot[2](2, 0, 1, IO, AC); m_rim_step = 3; m_ios = 0; break; @@ -940,6 +908,7 @@ void pdp1_device::execute_run() if (! m_cycle) { /* no instruction in progress: time to fetch a new instruction, I guess */ + debugger_instruction_hook(PC); MB = READ_PDP_18BIT(MA = PC); INCREMENT_PC; IR = MB >> 13; /* basic opcode */ @@ -1564,7 +1533,7 @@ void pdp1_device::execute_instruction() { /* IOT with IO wait */ if (m_ioc) { /* the iot command line is pulsed only if ioc is asserted */ - (*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) == 0, MB, &IO, AC); + m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) == 0, MB, IO, AC); m_ioh = 1; /* enable io wait */ @@ -1587,7 +1556,7 @@ void pdp1_device::execute_instruction() } else { /* IOT with no IO wait */ - (*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) != 0, MB, &IO, AC); + m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) != 0, MB, IO, AC); } break; case OPR: /* Operate Instruction Group */ @@ -1639,7 +1608,7 @@ no_fetch: /* Handle unimplemented IOT */ -void pdp1_device::pdp1_null_iot(int op2, int nac, int mb, int *io, int ac) +void pdp1_device::null_iot(int op2, int nac, int mb, int &io, int ac) { /* Note that the dummy IOT 0 is used to wait for the completion pulse generated by the a pending IOT (IOT with completion pulse but no IO wait) */ @@ -1661,7 +1630,7 @@ void pdp1_device::pdp1_null_iot(int op2, int nac, int mb, int *io, int ac) IOT 74: LEM/EEM */ -void pdp1_device::pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac) +void pdp1_device::lem_eem_iot(int op2, int nac, int mb, int &io, int ac) { if (! m_extend_support) /* extend mode supported? */ { @@ -1684,7 +1653,7 @@ void pdp1_device::pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac) IOT 55: esm IOT 56: cbs */ -void pdp1_device::pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac) +void pdp1_device::sbs_iot(int op2, int nac, int mb, int &io, int ac) { switch (op2) { @@ -1727,7 +1696,7 @@ void pdp1_device::pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac) IOT 52: isb IOT 53: cac */ -void pdp1_device::pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac) +void pdp1_device::type_20_sbs_iot(int op2, int nac, int mb, int &io, int ac) { int channel, mask; if (! m_type_20_sbs) /* type 20 sequence break system supported? */ @@ -1820,6 +1789,6 @@ void pdp1_device::pulse_start_clear() field_interrupt(); /* now, we kindly ask IO devices to reset, too */ - if (m_io_sc_callback) - (*m_io_sc_callback)(this); + if (!m_io_sc_callback.isnull()) + m_io_sc_callback(); } diff --git a/src/devices/cpu/pdp1/pdp1.h b/src/devices/cpu/pdp1/pdp1.h index 1c2d5c7eea3..0a81c8177d4 100644 --- a/src/devices/cpu/pdp1/pdp1.h +++ b/src/devices/cpu/pdp1/pdp1.h @@ -20,20 +20,8 @@ enum }; -typedef void (*pdp1_extern_iot_func)(device_t *device, int op2, int nac, int mb, int *io, int ac); -typedef void (*pdp1_read_binary_word_func)(device_t *device); -typedef void (*pdp1_io_sc_func)(device_t *device); - - struct pdp1_reset_param_t { - /* callbacks for iot instructions (required for any I/O) */ - pdp1_extern_iot_func extern_iot[64]; - /* read a word from the perforated tape reader (required for read-in mode) */ - pdp1_read_binary_word_func read_binary_word; - /* callback called when sc is pulsed: IO devices should reset */ - pdp1_io_sc_func io_sc_callback; - /* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */ int extend_support; /* 1 to use hardware multiply/divide (MUL, DIV) instead of MUS, DIS */ @@ -49,6 +37,9 @@ class pdp1_device : public cpu_device , public pdp1_reset_param_t { public: + typedef device_delegate<void (int op2, int nac, int mb, int &io, int ac)> iot_delegate; + typedef device_delegate<void ()> io_sc_delegate; + enum opcode { AND = 001, @@ -83,14 +74,16 @@ public: // construction/destruction pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + template <int I, typename... T> void set_iot_callback(T &&... args) { m_extern_iot[I].set(std::forward<T>(args)...); } + template <typename... T> void set_io_sc_callback(T &&... args) { m_io_sc_callback.set(std::forward<T>(args)...); } void set_reset_param(const pdp1_reset_param_t *param) { m_reset_param = param; } void pulse_start_clear(); void io_complete() { m_ios = 1; } - void pdp1_null_iot(int op2, int nac, int mb, int *io, int ac); - void pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac); - void pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac); - void pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac); + void null_iot(int op2, int nac, int mb, int &io, int ac); + void lem_eem_iot(int op2, int nac, int mb, int &io, int ac); + void sbs_iot(int op2, int nac, int mb, int &io, int ac); + void type_20_sbs_iot(int op2, int nac, int mb, int &io, int ac); protected: // device-level overrides @@ -167,11 +160,9 @@ private: int m_no_sequence_break; /* disable sequence break recognition for one cycle */ /* callbacks for iot instructions (required for any I/O) */ - pdp1_extern_iot_func m_extern_iot[64]; - /* read a word from the perforated tape reader (required for read-in mode) */ - pdp1_read_binary_word_func m_read_binary_word; + iot_delegate::array<64> m_extern_iot; /* callback called when sc is pulsed: IO devices should reset */ - pdp1_io_sc_func m_io_sc_callback; + io_sc_delegate m_io_sc_callback; /* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */ int m_extend_support; diff --git a/src/devices/cpu/pdp1/pdp1dasm.cpp b/src/devices/cpu/pdp1/pdp1dasm.cpp index 9b04c91ec87..0c3286a9257 100644 --- a/src/devices/cpu/pdp1/pdp1dasm.cpp +++ b/src/devices/cpu/pdp1/pdp1dasm.cpp @@ -19,7 +19,7 @@ inline void pdp1_disassembler::ea() u32 pdp1_disassembler::opcode_alignment() const { - return 4; + return 1; } offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) @@ -290,5 +290,5 @@ offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat //etime = 5; break; } - return 4; + return 1; } diff --git a/src/devices/cpu/pdp1/tx0.cpp b/src/devices/cpu/pdp1/tx0.cpp index 99636fcb9c2..19ec75f223b 100644 --- a/src/devices/cpu/pdp1/tx0.cpp +++ b/src/devices/cpu/pdp1/tx0.cpp @@ -19,8 +19,8 @@ #define LOG_EXTRA 0 -#define READ_TX0_18BIT(A) ((signed)m_program->read_dword((A)<<2)) -#define WRITE_TX0_18BIT(A,V) (m_program->write_dword((A)<<2,(V))) +#define READ_TX0_18BIT(A) ((signed)m_program->read_dword(A)) +#define WRITE_TX0_18BIT(A,V) (m_program->write_dword((A),(V))) #define io_handler_rim 3 diff --git a/src/devices/cpu/pdp8/pdp8.cpp b/src/devices/cpu/pdp8/pdp8.cpp index 3084c1bb29d..e8090c8dfde 100644 --- a/src/devices/cpu/pdp8/pdp8.cpp +++ b/src/devices/cpu/pdp8/pdp8.cpp @@ -51,7 +51,7 @@ DEFINE_DEVICE_TYPE(PDP8, pdp8_device, "pdp8_cpu", "DEC PDP8") pdp8_device::pdp8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, PDP8, tag, owner, clock), - m_program_config("program", ENDIANNESS_BIG, 12, 12), + m_program_config("program", ENDIANNESS_BIG, 12, 12, -1), m_pc(0), m_ac(0), m_mb(0), diff --git a/src/devices/cpu/pdp8/pdp8dasm.cpp b/src/devices/cpu/pdp8/pdp8dasm.cpp index 389cf11fda7..8c2e57573b5 100644 --- a/src/devices/cpu/pdp8/pdp8dasm.cpp +++ b/src/devices/cpu/pdp8/pdp8dasm.cpp @@ -11,7 +11,7 @@ u32 pdp8_disassembler::opcode_alignment() const { - return 2; + return 1; } offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) @@ -164,5 +164,5 @@ offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat } } - return 2 | SUPPORTED; + return 1 | SUPPORTED | (opcode == 4 ? STEP_OVER : 0); } diff --git a/src/devices/cpu/tms57002/tms57002.cpp b/src/devices/cpu/tms57002/tms57002.cpp index 8464a10e2f0..c2cf28f3f92 100644 --- a/src/devices/cpu/tms57002/tms57002.cpp +++ b/src/devices/cpu/tms57002/tms57002.cpp @@ -918,28 +918,22 @@ void tms57002_device::execute_run() icount = 0; } -void tms57002_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tms57002_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - assert(samples == 1); + assert(inputs[0].samples() == 1); + assert(outputs[0].samples() == 1); - if (st0 & ST0_SIM) - { - si[0] = (inputs[0][0] << 8) & 0xffffff; - si[1] = (inputs[1][0] << 8) & 0xffffff; - si[2] = (inputs[2][0] << 8) & 0xffffff; - si[3] = (inputs[3][0] << 8) & 0xffffff; - } - else - { - si[0] = inputs[0][0] & 0xffffff; - si[1] = inputs[1][0] & 0xffffff; - si[2] = inputs[2][0] & 0xffffff; - si[3] = inputs[3][0] & 0xffffff; - } - outputs[0][0] = int16_t(so[0] >> 8); - outputs[1][0] = int16_t(so[1] >> 8); - outputs[2][0] = int16_t(so[2] >> 8); - outputs[3][0] = int16_t(so[3] >> 8); + stream_buffer::sample_t in_scale = 32768.0 * ((st0 & ST0_SIM) ? 256.0 : 1.0); + si[0] = s32(inputs[0].get(0) * in_scale) & 0xffffff; + si[1] = s32(inputs[1].get(0) * in_scale) & 0xffffff; + si[2] = s32(inputs[2].get(0) * in_scale) & 0xffffff; + si[3] = s32(inputs[3].get(0) * in_scale) & 0xffffff; + + stream_buffer::sample_t out_scale = 1.0 / (32768.0 * 65536.0); + outputs[0].put(0, stream_buffer::sample_t(s32(so[0] << 8)) * out_scale); + outputs[1].put(0, stream_buffer::sample_t(s32(so[1] << 8)) * out_scale); + outputs[2].put(0, stream_buffer::sample_t(s32(so[2] << 8)) * out_scale); + outputs[3].put(0, stream_buffer::sample_t(s32(so[3] << 8)) * out_scale); sync_w(1); } @@ -981,8 +975,7 @@ void tms57002_device::device_start() state_add(TMS57002_HOST3, "HOST3", host[3]); set_icountptr(icount); - - stream_alloc(4, 4, STREAM_SYNC); + stream_alloc(4, 4, SAMPLE_RATE_INPUT_ADAPTIVE, STREAM_SYNCHRONOUS); save_item(NAME(macc)); save_item(NAME(macc_read)); diff --git a/src/devices/cpu/tms57002/tms57002.h b/src/devices/cpu/tms57002/tms57002.h index b1a96823b06..12bcd732120 100644 --- a/src/devices/cpu/tms57002/tms57002.h +++ b/src/devices/cpu/tms57002/tms57002.h @@ -36,7 +36,7 @@ protected: virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual space_config_vector memory_space_config() const override; virtual u32 execute_min_cycles() const noexcept override; virtual u32 execute_max_cycles() const noexcept override; diff --git a/src/devices/cpu/z80/kc82.cpp b/src/devices/cpu/z80/kc82.cpp index dbea8fc70f5..bf0a26290c4 100644 --- a/src/devices/cpu/z80/kc82.cpp +++ b/src/devices/cpu/z80/kc82.cpp @@ -64,13 +64,11 @@ void kc82_device::device_start() for (int n = 1; n <= 4; n++) { - state_add<u8>(KC82_B1 + n - 1, string_format("B%d", n).c_str(), - [this, n]() { return m_mmu_b[n]; }, + state_add(KC82_B1 + n - 1, string_format("B%d", n).c_str(), m_mmu_b[n], [this, n](u8 data) { m_mmu_b[n] = data; mmu_remap_pages(); } ).mask(0x3f); if (n != 4) - state_add<u16>(KC82_A1 + n - 1, string_format("A%d", n).c_str(), - [this, n]() { return m_mmu_a[n]; }, + state_add(KC82_A1 + n - 1, string_format("A%d", n).c_str(), m_mmu_a[n], [this, n](u16 data) { m_mmu_a[n] = data; mmu_remap_pages(); } ).mask(0x3ff); } diff --git a/src/devices/cpu/z80/kl5c80a12.cpp b/src/devices/cpu/z80/kl5c80a12.cpp index dd7bd6060a6..7f79c37dec9 100644 --- a/src/devices/cpu/z80/kl5c80a12.cpp +++ b/src/devices/cpu/z80/kl5c80a12.cpp @@ -12,7 +12,7 @@ Important functional blocks: — MMU — USART (KP51) (unemulated) - — 16-bit timer/counters (KP64, KP63) (unemulated) + — 16-bit timer/counters (KP64, KP63) (KP64 unemulated) — 16-level interrupt controller (KP69) — Parallel ports (KP65, KP66) (unemulated) — 512-byte high-speed RAM @@ -22,6 +22,7 @@ #include "emu.h" #include "kl5c80a12.h" +#include "kp63.h" // device type definition DEFINE_DEVICE_TYPE(KL5C80A12, kl5c80a12_device, "kl5c80a12", "Kawasaki Steel KL5C80A12") @@ -59,6 +60,7 @@ void kl5c80a12_device::internal_ram(address_map &map) void kl5c80a12_device::internal_io(address_map &map) { map(0x00, 0x07).mirror(0xff00).rw(FUNC(kl5c80a12_device::mmu_r), FUNC(kl5c80a12_device::mmu_w)); + map(0x20, 0x25).mirror(0xff00).rw("timerb", FUNC(kp63_3channel_device::read), FUNC(kp63_3channel_device::write)); map(0x34, 0x34).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrl_r), FUNC(kp69_device::lerl_pgrl_w)); map(0x35, 0x35).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrh_r), FUNC(kp69_device::lerh_pgrh_w)); map(0x36, 0x36).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::imrl_r), FUNC(kp69_device::imrl_w)); @@ -97,6 +99,11 @@ void kl5c80a12_device::device_add_mconfig(machine_config &config) { KP69(config, m_kp69); m_kp69->int_callback().set_inputline(*this, INPUT_LINE_IRQ0); + + kp63_3channel_device &timerb(KP63_3CHANNEL(config, "timerb", DERIVED_CLOCK(1, 2))); + timerb.outs_callback<0>().set(m_kp69, FUNC(kp69_device::ir_w<13>)); + timerb.outs_callback<1>().set(m_kp69, FUNC(kp69_device::ir_w<14>)); + timerb.outs_callback<2>().set(m_kp69, FUNC(kp69_device::ir_w<15>)); } diff --git a/src/devices/cpu/z80/kl5c80a16.cpp b/src/devices/cpu/z80/kl5c80a16.cpp index 6328a7322f4..8fa31925366 100644 --- a/src/devices/cpu/z80/kl5c80a16.cpp +++ b/src/devices/cpu/z80/kl5c80a16.cpp @@ -9,7 +9,7 @@ — DMA controller (KP27) (unemulated) — UART (KP61) (unemulated) — Synchronous serial port (KP62) (unemulated) - — 16-bit timer/counters (KP63A) (unemulated) + — 16-bit timer/counters (KP63A) — 16-level interrupt controller (KP69) — Parallel ports (KP67) (unemulated) — External bus/DRAM interface unit (unemulated) @@ -18,6 +18,7 @@ #include "emu.h" #include "kl5c80a16.h" +#include "kp63.h" // device type definition DEFINE_DEVICE_TYPE(KL5C80A16, kl5c80a16_device, "kl5c80a16", "Kawasaki Steel KL5C80A16") @@ -45,6 +46,7 @@ kl5c80a16_device::kl5c80a16_device(const machine_config &mconfig, const char *ta void kl5c80a16_device::internal_io(address_map &map) { map(0x00, 0x07).mirror(0xff00).rw(FUNC(kl5c80a16_device::mmu_r), FUNC(kl5c80a16_device::mmu_w)); + map(0x20, 0x27).mirror(0xff00).rw("timer", FUNC(kp63a_device::read), FUNC(kp63a_device::write)); map(0x34, 0x34).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrl_r), FUNC(kp69_device::lerl_pgrl_w)); map(0x35, 0x35).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrh_r), FUNC(kp69_device::lerh_pgrh_w)); map(0x36, 0x36).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::imrl_r), FUNC(kp69_device::imrl_w)); @@ -83,6 +85,12 @@ void kl5c80a16_device::device_add_mconfig(machine_config &config) { KP69(config, m_kp69); m_kp69->int_callback().set_inputline(*this, INPUT_LINE_IRQ0); + + kp63a_device &timer(KP63A(config, "timer", DERIVED_CLOCK(1, 2))); + timer.outs_callback<0>().set(m_kp69, FUNC(kp69_device::ir_w<12>)); + timer.outs_callback<1>().set(m_kp69, FUNC(kp69_device::ir_w<13>)); + //timer.outs_callback<2>().set(m_kp69, FUNC(kp69_device::ir_w<0>)); // TODO: multiplexed with P20 input by SCR1 bit 4 + //timer.outs_callback<3>().set(m_kp69, FUNC(kp69_device::ir_w<1>)); // TODO: multiplexed with P21 input by SCR1 bit 5 (may also be NMI) } diff --git a/src/devices/cpu/z80/kp63.cpp b/src/devices/cpu/z80/kp63.cpp new file mode 100644 index 00000000000..a1a9e5913c8 --- /dev/null +++ b/src/devices/cpu/z80/kp63.cpp @@ -0,0 +1,477 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Kawasaki Steel (Kawatetsu) KP63(A) Timer/Counter + + These macro cells provide 4 independent 16-bit down counters (reduced + to 3 in some versions) driven by an 8-bit prescaler attached to the + system clock. This prescaler is not fully emulated here, since its + operations are mostly transparent, though a divide-by-4 clock output + (SYNC) may be selected to appear on a port pin. + + Each counter has a single and optional external input (GATEn), which + on the KP63 can only be used to gate a divide-by-4 count but can also + be configured as an input clock on the KP63A. + + Two outputs are generated for each counter. The pulse or toggle output + (OUTPn) has configurable polarity and can be used for 8-bit PWM. The + strobe output (OUTSn) goes active high for 4 clock cycles when the + counter underflows and is connected to the interrupt controller. + + Writing the initial count register (CR) and reading the current count + are two-step processes, effective at the second write or first read. + These must not be overlapped with each other since they share a + temporary register. + +***************************************************************************/ + +#include "emu.h" +#include "kp63.h" + +#define VERBOSE 1 +#include "logmacro.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definitions +DEFINE_DEVICE_TYPE(KP63_3CHANNEL, kp63_3channel_device, "kp63_3channel", "Kawasaki Steel KP63 Timer/Counter (3 channels)") +DEFINE_DEVICE_TYPE(KP63A, kp63a_device, "kp63a", "Kawasaki Steel KP63A Timer/Counter") + +const char *const kp63_device::s_count_modes[4] = +{ + "one-shot", + "continuous count", + "WDT", + "PWM" +}; + + +//************************************************************************** +// KP63 DEVICE +//************************************************************************** + +//------------------------------------------------- +// kp63_device - constructor +//------------------------------------------------- + +kp63_device::kp63_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 num_counters, u8 mode_mask) + : device_t(mconfig, type, tag, owner, clock) + , m_out_pulse_callback(*this) + , m_out_strobe_callback(*this) + , c_num_counters(num_counters) + , c_mode_mask(mode_mask) + , m_timer{0} + , m_strobe_timer{0} + , m_pwm_timer{0} + , m_cr{0} + , m_last_count{0} + , m_count_tmp{0} + , m_status{0} + , m_rw_seq(0) + , m_timer_started(0) + , m_gate_input(0xf) +{ +} + + +//------------------------------------------------- +// kp63_3channel_device - constructor +//------------------------------------------------- + +kp63_3channel_device::kp63_3channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : kp63_device(mconfig, KP63_3CHANNEL, tag, owner, clock, 3, 0x1f) +{ +} + + +//------------------------------------------------- +// kp63a_device - constructor +//------------------------------------------------- + +kp63a_device::kp63a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : kp63_device(mconfig, KP63A, tag, owner, clock, 4, 0x3f) +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void kp63_device::device_resolve_objects() +{ + // Resolve output callbacks + m_out_pulse_callback.resolve_all_safe(); + m_out_strobe_callback.resolve_all_safe(); +} + + +//------------------------------------------------- +// timer_expired - handle timed count underflow +//------------------------------------------------- + +template <int N> +TIMER_CALLBACK_MEMBER(kp63_device::timer_expired) +{ + timer_pulse(N); +} + + +//------------------------------------------------- +// strobe_off - handle end of strobe output +//------------------------------------------------- + +template <int N> +TIMER_CALLBACK_MEMBER(kp63_device::strobe_off) +{ + m_out_strobe_callback[N](0); +} + + +//------------------------------------------------- +// pwm_off - handle PWM phase change +//------------------------------------------------- + +template <int N> +TIMER_CALLBACK_MEMBER(kp63_device::pwm_off) +{ + m_status[N] &= 0x7f; + m_out_pulse_callback[N](BIT(m_status[N], 4) ? 1 : 0); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void kp63_device::device_start() +{ + // Setup timers + m_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<0>), this)); + m_strobe_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<0>), this)); + m_pwm_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<0>), this)); + m_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<1>), this)); + m_strobe_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<1>), this)); + m_pwm_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<1>), this)); + m_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<2>), this)); + m_strobe_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<2>), this)); + m_pwm_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<2>), this)); + if (c_num_counters > 3) + { + m_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<3>), this)); + m_strobe_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<3>), this)); + m_pwm_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<3>), this)); + } + + // Save state + save_item(NAME(m_cr)); + save_item(NAME(m_last_count)); + save_item(NAME(m_count_tmp)); + save_item(NAME(m_status)); + save_item(NAME(m_rw_seq)); + save_item(NAME(m_timer_started)); + save_item(NAME(m_gate_input)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void kp63_device::device_reset() +{ + for (unsigned n = 0; n < c_num_counters; n++) + { + // Turn off timers + m_timer[n]->adjust(attotime::never); + m_strobe_timer[n]->adjust(attotime::never); + m_pwm_timer[n]->adjust(attotime::never); + + // Reset status and count + m_status[n] = 0; + m_cr[n] = 0xffff; + m_last_count[n] = 0xffff; + + // Clear outputs + m_out_pulse_callback[n](0); + m_out_strobe_callback[n](0); + } + + // Clear read/write sequence for all counters + m_rw_seq = 0; + m_timer_started = 0; +} + + +//------------------------------------------------- +// timer_pulse - change outputs and stop or +// reload timer as count underflows +//------------------------------------------------- + +void kp63_device::timer_pulse(unsigned n) +{ + // Toggle pulse output + m_status[n] ^= 0x80; + m_out_pulse_callback[n](BIT(m_status[n], 7) != BIT(m_status[n], 4) ? 1 : 0); + + // Begin strobe output + m_out_strobe_callback[n](1); + m_strobe_timer[n]->adjust(clocks_to_attotime(4)); + + // Reload timer in continuous count and PWM modes + if (BIT(m_status[n], 2)) + timer_reload(n); + else + { + // Stop count at FFFF in one-shot and WDT modes + m_last_count[n] = 0xffff; + m_timer_started &= ~(1 << n); + } +} + + +//------------------------------------------------- +// timer_reload - reload timer from CR +//------------------------------------------------- + +void kp63_device::timer_reload(unsigned n) +{ + m_timer_started |= 1 << n; + + if (BIT(m_status[n], 5) || ((m_status[n] & 0x03) == 0x03 && !BIT(m_gate_input, n))) + m_last_count[n] = m_cr[n]; + else + { + unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256; + if ((m_status[n] & 0x0c) == 0x0c) + { + // PWM + m_timer[n]->adjust(clocks_to_attotime(prescale * ((m_cr[n] & 0x00ff) + 1))); + m_pwm_timer[n]->adjust(clocks_to_attotime(prescale * ((m_cr[n] >> 8) + 1))); + } + else + m_timer[n]->adjust(clocks_to_attotime(prescale * (u32(m_cr[n]) + 1))); + } +} + + +//------------------------------------------------- +// timer_resume_count - start counting again +//------------------------------------------------- + +void kp63_device::timer_resume_count(unsigned n) +{ + if (!BIT(m_status[n], 5) || ((m_status[n] & 0x03) != 0x03 || BIT(m_gate_input, n))) + { + unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256; + if ((m_status[n] & 0x0c) == 0x0c) + { + // PWM + m_timer[n]->adjust(clocks_to_attotime(prescale * ((m_last_count[n] & 0x00ff) + 1))); + m_pwm_timer[n]->adjust(clocks_to_attotime(prescale * ((m_last_count[n] >> 8) + 1))); + } + else + m_timer[n]->adjust(clocks_to_attotime(prescale * (u32(m_last_count[n]) + 1))); + } +} + + +//------------------------------------------------- +// timer_get_count - obtain the instant count in +// case of a readout or pause +//------------------------------------------------- + +u16 kp63_device::timer_get_count(unsigned n) const +{ + if (!BIT(m_timer_started, n) || BIT(m_status[n], 5) || ((m_status[n] & 0x03) == 0x03 && !BIT(m_gate_input, n))) + return m_last_count[n]; + else + { + unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256; + if ((m_status[n] & 0x0c) == 0x0c) + { + // PWM + u8 ticks = attotime_to_clocks(m_timer[n]->remaining()) / prescale; + return ticks | ((m_cr[n] - (u16(ticks) << 8)) & 0xff00); + } + else + return attotime_to_clocks(m_timer[n]->remaining()) / prescale; + } +} + + +//------------------------------------------------- +// read - read count or status register +//------------------------------------------------- + +u8 kp63_device::read(offs_t offset) +{ + const unsigned n = offset >> 1; + assert(n < c_num_counters); + + if (BIT(offset, 0)) + { + // Status read clears read/write sequence + if (!machine().side_effects_disabled()) + m_rw_seq &= ~(1 << n); + return m_status[n]; + } + else if (BIT(m_rw_seq, n)) + { + // Second step of counter readout + if (!machine().side_effects_disabled()) + m_rw_seq &= ~(1 << n); + return m_count_tmp[n]; + } + else + { + // First step of counter readout + u16 count = timer_get_count(n); + if (!machine().side_effects_disabled()) + { + // Latch high byte into TMP register + m_rw_seq |= 1 << n; + m_count_tmp[n] = count >> 8; + } + return count & 0x00ff; + } +} + +//------------------------------------------------- +// write - set CR or mode register +//------------------------------------------------- + +void kp63_device::write(offs_t offset, u8 data) +{ + const unsigned n = offset >> 1; + assert(n < c_num_counters); + + if (BIT(offset, 0)) + { + bool old_outp = BIT(m_status[n], 7) != BIT(m_status[n], 4); + + // Stop count before setting mode + if (BIT(m_timer_started, n)) + { + if (!BIT(m_status[n], 5) || ((m_status[n] & 0x03) != 0x03 || BIT(m_gate_input, n))) + { + m_last_count[n] = timer_get_count(n); + m_timer[n]->adjust(attotime::never); + m_pwm_timer[n]->adjust(attotime::never); + } + m_timer_started &= ~(1 << n); + } + + if (BIT(data & c_mode_mask, 5)) + LOG("%s: Timer #%d configured for %s mode, %s edges of GATE, initial output %c\n", + machine().describe_context(), + n, + s_count_modes[BIT(data, 2, 2)], + BIT(data, 1) ? "???" : BIT(data, 0) ? "falling" : "rising", + BIT(data, 4) ? 'H' : 'L'); + else + LOG("%s: Timer #%d configured for %s mode, 1/%d system clock (GATE %s), initial output %c\n", + machine().describe_context(), + n, + s_count_modes[BIT(data, 2, 2)], + BIT(data, 1) ? 4 : BIT(data, 0) ? 16 : 256, + (data & 0x03) == 0x03 ? "effective" : "ignored", + BIT(data, 4) ? 'H' : 'L'); + m_status[n] = data & c_mode_mask; + + // Update OUTP + if (old_outp != BIT(data, 4)) + m_out_pulse_callback[n](BIT(data, 4) ? 1 : 0); + } + else if ((m_status[n] & 0x0c) == 0x08) + { + // WDT retrigger (data ignored; initial count must be written using a different mode) + timer_reload(n); + } + else if (BIT(m_rw_seq, n)) + { + // Second step of initial count write + m_rw_seq &= ~(1 << n); + m_cr[n] = u16(data) << 8 | m_count_tmp[n]; + + LOG("%s: Timer #%d initial count = %d\n", machine().describe_context(), n, (m_status[n] == 0x0c) ? m_cr[n] & 0x00ff : m_cr[n]); + + // Automatic retrigger in one-shot and continuous modes + if (!BIT(m_status[n], 3) || !BIT(m_timer_started, n)) + { + if (!BIT(m_status[n], 7)) + { + // Toggle OUTP + m_status[n] |= 0x80; + m_out_pulse_callback[n](BIT(m_status[n], 4) ? 0 : 1); + } + timer_reload(n); + } + } + else + { + // First step of initial count write (held in TMP register) + m_rw_seq |= 1 << n; + m_count_tmp[n] = data; + } +} + +//------------------------------------------------- +// write_gate - handle gate inputs +//------------------------------------------------- + +void kp63_device::write_gate(unsigned n, bool state) +{ + assert(n < c_num_counters); + + if (BIT(m_gate_input, n) != state) + return; + + if (state) + m_gate_input |= 1 << n; + else + m_gate_input &= ~(1 << n); + + if (BIT(m_timer_started, n)) + { + if ((m_status[n] & 0x23) == 0x03) + { + // Timer gated on or off + if (state) + timer_resume_count(n); + else + { + m_last_count[n] = timer_get_count(n); + m_timer[n]->adjust(attotime::never); + } + } + else if ((m_status[n] & 0x23) == (state ? 0x21 : 0x20)) + { + // Count edges of gate input + if ((m_status[n] & 0x0c) == 0x0c) + { + // PWM: count is in lower 8 bits + if ((m_last_count[n] & 0x00ff) == 0) + timer_pulse(n); + else + { + // Decrement both halves and check for underflow in upper half + m_last_count[n] -= 0x0101; + if (m_last_count[n] >= 0xff00) + { + m_status[n] &= 0x7f; + m_out_pulse_callback[n](BIT(m_status[n], 4) ? 1 : 0); + } + } + } + else if (m_last_count[n]-- == 0) + timer_pulse(n); + } + } +} diff --git a/src/devices/cpu/z80/kp63.h b/src/devices/cpu/z80/kp63.h new file mode 100644 index 00000000000..73e269fb72b --- /dev/null +++ b/src/devices/cpu/z80/kp63.h @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Kawasaki Steel (Kawatetsu) KP63(A) Timer/Counter + +***************************************************************************/ + +#ifndef MAME_CPU_Z80_KP63_H +#define MAME_CPU_Z80_KP63_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class kp63_device : public device_t +{ +public: + // callback configuration + template <int N> auto outp_callback() { return m_out_pulse_callback[N].bind(); } + template <int N> auto outs_callback() { return m_out_strobe_callback[N].bind(); } + + // register interface + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + + // input line interface + template <int N> DECLARE_WRITE_LINE_MEMBER(gate_w) { write_gate(N, state); } + +protected: + // construction/destruction + kp63_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 num_counters, u8 mode_mask); + + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + static const char *const s_count_modes[4]; + + // timer callbacks + template <int N> TIMER_CALLBACK_MEMBER(timer_expired); + template <int N> TIMER_CALLBACK_MEMBER(strobe_off); + template <int N> TIMER_CALLBACK_MEMBER(pwm_off); + + // internal helpers + void timer_pulse(unsigned n); + void timer_reload(unsigned n); + void timer_resume_count(unsigned n); + u16 timer_get_count(unsigned n) const; + void write_gate(unsigned n, bool state); + + // callback objects + devcb_write_line::array<4> m_out_pulse_callback; + devcb_write_line::array<4> m_out_strobe_callback; + + // constant parameters + const u8 c_num_counters; + const u8 c_mode_mask; + + // internal timers + emu_timer *m_timer[4]; + emu_timer *m_strobe_timer[4]; + emu_timer *m_pwm_timer[4]; + + // internal state + u16 m_cr[4]; + u16 m_last_count[4]; + u8 m_count_tmp[4]; + u8 m_status[4]; + u8 m_rw_seq; + u8 m_timer_started; + u8 m_gate_input; +}; + +class kp63_3channel_device : public kp63_device +{ +public: + // device type constructor + kp63_3channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +class kp63a_device : public kp63_device +{ +public: + // device type constructor + kp63a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +// device type declarations +DECLARE_DEVICE_TYPE(KP63_3CHANNEL, kp63_3channel_device) +DECLARE_DEVICE_TYPE(KP63A, kp63a_device) + +#endif // MAME_CPU_Z80_KP63_H diff --git a/src/devices/cpu/z80/kp69.cpp b/src/devices/cpu/z80/kp69.cpp index dca74ff3b25..84be060c4c7 100644 --- a/src/devices/cpu/z80/kp69.cpp +++ b/src/devices/cpu/z80/kp69.cpp @@ -107,12 +107,12 @@ void kp69_device::device_start() void kp69_base_device::add_to_state(device_state_interface &state, int index) { - state.state_add<u16>(index, "IRR", [this]() { return m_irr; }, [this](u16 data) { set_irr(data); }); - state.state_add<u16>(index + 1, "ISR", [this]() { return m_isr; }, [this](u16 data) { set_isr(data); }); + state.state_add(index, "IRR", m_irr, [this](u16 data) { set_irr(data); }); + state.state_add(index + 1, "ISR", m_isr, [this](u16 data) { set_isr(data); }); state.state_add(index + 2, "IVR", m_ivr).mask(0xe0); - state.state_add<u16>(index + 3, "LER", [this]() { return m_ler; }, [this](u16 data) { set_ler(data); }); - state.state_add<u16>(index + 4, "PGR", [this]() { return m_pgr; }, [this](u16 data) { set_pgr(data); }); - state.state_add<u16>(index + 5, "IMR", [this]() { return m_imr; }, [this](u16 data) { set_imr(data); }); + state.state_add(index + 3, "LER", m_ler, [this](u16 data) { set_ler(data); }); + state.state_add(index + 4, "PGR", m_pgr, [this](u16 data) { set_pgr(data); }); + state.state_add(index + 5, "IMR", m_imr, [this](u16 data) { set_imr(data); }); } diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index 473dfe0ce7b..c6e20ba66dd 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -236,7 +236,7 @@ void cassette_image_device::device_start() m_state = m_default_state; m_value = 0; - machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), machine().sample_rate()); + stream_alloc_legacy(0, (m_stereo? 2:1), machine().sample_rate()); } image_init_result cassette_image_device::call_create(int format_type, util::option_resolution *format_options) @@ -404,7 +404,7 @@ std::string cassette_image_device::call_display() // Cassette sound //------------------------------------------------- -void cassette_image_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cassette_image_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *left_buffer = outputs[0]; stream_sample_t *right_buffer = nullptr; diff --git a/src/devices/imagedev/cassette.h b/src/devices/imagedev/cassette.h index 790b2e0d8c3..a661e8312a8 100644 --- a/src/devices/imagedev/cassette.h +++ b/src/devices/imagedev/cassette.h @@ -102,7 +102,7 @@ public: void seek(double time, int origin); // sound stream update overrides - void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; device_sound_interface& set_stereo() { m_stereo = true; return *this; } protected: diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index f725845fa0d..3dd96644f1a 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -1248,7 +1248,7 @@ void floppy_sound_device::device_start() // If we don't have all samples, don't allocate a stream or access sample data. if (m_loaded) { - m_sound = machine().sound().stream_alloc(*this, 0, 1, clock()); // per-floppy stream + m_sound = stream_alloc_legacy(0, 1, clock()); // per-floppy stream } register_for_save_states(); } @@ -1369,10 +1369,10 @@ void floppy_sound_device::step(int zone) } //------------------------------------------------- -// sound_stream_update - update the sound stream +// sound_stream_update_legacy - update the sound stream //------------------------------------------------- -void floppy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void floppy_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // We are using only one stream, unlike the parent class // Also, there is no need for interpolation, as we only expect diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h index 4fa16d3c338..d07a12c146c 100644 --- a/src/devices/imagedev/floppy.h +++ b/src/devices/imagedev/floppy.h @@ -294,7 +294,7 @@ protected: private: // device_sound_interface overrides - void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; sound_stream* m_sound; int m_step_base; diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp index 37c7237db52..06f557c4355 100644 --- a/src/devices/machine/6522via.cpp +++ b/src/devices/machine/6522via.cpp @@ -587,17 +587,6 @@ u8 via6522_device::read(offs_t offset) { LOGINT("PB INT "); CLR_PB_INT(); - - if (m_out_cb2 && (CB2_PULSE_OUTPUT(m_pcr) || CB2_AUTO_HS(m_pcr))) - { - m_out_cb2 = 0; - m_cb2_handler(m_out_cb2); - } - - if (CB2_PULSE_OUTPUT(m_pcr)) - { - m_cb2_timer->adjust(clocks_to_attotime(1)); - } } break; diff --git a/src/devices/machine/8364_paula.cpp b/src/devices/machine/8364_paula.cpp index a340b5a523c..1e10ca55b3e 100644 --- a/src/devices/machine/8364_paula.cpp +++ b/src/devices/machine/8364_paula.cpp @@ -58,7 +58,7 @@ void paula_8364_device::device_start() } // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 4, clock() / CLOCK_DIVIDER); + m_stream = stream_alloc_legacy(0, 4, clock() / CLOCK_DIVIDER); } //------------------------------------------------- @@ -159,10 +159,10 @@ void paula_8364_device::dma_reload(audio_channel *chan) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void paula_8364_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void paula_8364_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int channum, sampoffs = 0; diff --git a/src/devices/machine/8364_paula.h b/src/devices/machine/8364_paula.h index 0a7016c4496..a2ac2feab26 100644 --- a/src/devices/machine/8364_paula.h +++ b/src/devices/machine/8364_paula.h @@ -68,7 +68,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: enum diff --git a/src/devices/machine/acorn_vidc.cpp b/src/devices/machine/acorn_vidc.cpp index 65487e2b63a..36733555e7d 100644 --- a/src/devices/machine/acorn_vidc.cpp +++ b/src/devices/machine/acorn_vidc.cpp @@ -416,7 +416,7 @@ inline void acorn_vidc10_device::refresh_stereo_image(u8 channel) m_lspeaker->set_input_gain(channel,left_gain[m_stereo_image[channel]]*m_sound_input_gain); m_rspeaker->set_input_gain(channel,right_gain[m_stereo_image[channel]]*m_sound_input_gain); - //printf("%d %f %f\n",channel,m_lspeaker->input_gain(channel),m_rspeaker->input_gain(channel)); + //printf("%d %f %f\n",channel,m_lspeaker->input(channel).gain(),m_rspeaker->input(channel).gain()); } diff --git a/src/devices/machine/alpha_8921.cpp b/src/devices/machine/alpha_8921.cpp new file mode 100644 index 00000000000..bf57902b31e --- /dev/null +++ b/src/devices/machine/alpha_8921.cpp @@ -0,0 +1,212 @@ +// license:BSD-3-Clause +// copyright-holders:cam900 +/*************************************************************************** + + Alpha denshi ALPHA-8921 emulation + + Also known as + SNK PRO-CT0 + SNK-9201 + + This chip is sprite ROM data serializer, or optional security device. + used in some later 80s Alpha Denshi hardware(ex: Gang Wars), + Some early Neogeo MVS motherboards, AES cartridges. + also integrated in NEO-ZMC2, NEO-CMC. + + reference: https://wiki.neogeodev.org/index.php?title=PRO-CT0 + +***************************************************************************/ + +#include "emu.h" +#include "alpha_8921.h" +#include <algorithm> + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(ALPHA_8921, alpha_8921_device, "alpha_8921", "Alpha denshi ALPHA-8921") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// alpha_8921_device - constructor +//------------------------------------------------- + +alpha_8921_device::alpha_8921_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ALPHA_8921, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void alpha_8921_device::device_start() +{ + // save states + save_item(NAME(m_clk)); + save_item(NAME(m_load)); + save_item(NAME(m_even)); + save_item(NAME(m_h)); + save_item(NAME(m_c)); + save_item(NAME(m_gad)); + save_item(NAME(m_gbd)); + save_item(NAME(m_dota)); + save_item(NAME(m_dotb)); + save_item(NAME(m_sr)); + save_item(NAME(m_old_sr)); + save_item(NAME(m_old_even)); + save_item(NAME(m_old_h)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void alpha_8921_device::device_reset() +{ + // force update outputs + m_old_sr = ~m_sr; + m_old_even = !m_even; + m_old_h = !m_h; + update_output(); +} + + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +//------------------------------------------------- +// clk_w - Change clock pin status +//------------------------------------------------- + +WRITE_LINE_MEMBER(alpha_8921_device::clk_w) +{ + if (m_clk != state) + { + m_clk = state; + if (!m_clk) // falling edge + { + if (m_load) + m_sr = m_c; + else if (m_h) + m_sr = (BIT(m_sr, 24, 6) << 26) | (BIT(m_sr, 16, 6) << 18) | (BIT(m_sr, 8, 6) << 10) | (BIT(m_sr, 0, 6) << 2); + else + m_sr = ((BIT(m_sr, 26, 6)) << 24) | ((BIT(m_sr, 18, 6)) << 16) | ((BIT(m_sr, 10, 6)) << 8) | (BIT(m_sr, 2, 6)); + } + } +} + +//------------------------------------------------- +// load_w - Change LOAD pin status +//------------------------------------------------- + +WRITE_LINE_MEMBER(alpha_8921_device::load_w) +{ + m_load = state; +} + +//------------------------------------------------- +// even_w - Change EVEN pin status +//------------------------------------------------- + +WRITE_LINE_MEMBER(alpha_8921_device::even_w) +{ + m_even = state; +} + +//------------------------------------------------- +// h_w - Change H pin status +//------------------------------------------------- + +WRITE_LINE_MEMBER(alpha_8921_device::h_w) +{ + m_h = state; +} + +//------------------------------------------------- +// c_w - Change C data +//------------------------------------------------- + +void alpha_8921_device::c_w(u32 data) +{ + m_c = data; +} + +//------------------------------------------------- +// update_output - Update output results +//------------------------------------------------- + +void alpha_8921_device::update_output() +{ + if ((m_old_sr != m_sr) || (m_old_even != m_even) || (m_old_h != m_h)) + { + if (m_h) + { + m_gbd = bitswap<4>(m_sr, 30, 22, 14, 6); + m_gad = bitswap<4>(m_sr, 31, 23, 15, 7); + } + else + { + m_gbd = bitswap<4>(m_sr, 25, 17, 9, 1); + m_gad = bitswap<4>(m_sr, 24, 16, 8, 0); + } + if (m_even) + std::swap<u8>(m_gad, m_gbd); + + m_dota = m_gad ? true : false; + m_dotb = m_gbd ? true : false; + m_old_sr = m_sr; + m_old_even = m_even; + m_old_h = m_h; + } +} + +//------------------------------------------------- +// gad_r - Read GAD data +//------------------------------------------------- + +u8 alpha_8921_device::gad_r() +{ + update_output(); + return m_gad & 0xf; +} + +//------------------------------------------------- +// gbd_r - Read GBD data +//------------------------------------------------- + +u8 alpha_8921_device::gbd_r() +{ + update_output(); + return m_gbd & 0xf; +} + +//------------------------------------------------- +// dota_r - Read DOTA pin data (GAD isn't 0) +//------------------------------------------------- + +READ_LINE_MEMBER(alpha_8921_device::dota_r) +{ + update_output(); + return m_dota; +} + +//------------------------------------------------- +// dotb_r - Read DOTB pin data (GBD isn't 0) +//------------------------------------------------- + +READ_LINE_MEMBER(alpha_8921_device::dotb_r) +{ + update_output(); + return m_dotb; +} diff --git a/src/devices/machine/alpha_8921.h b/src/devices/machine/alpha_8921.h new file mode 100644 index 00000000000..88ecd850eb9 --- /dev/null +++ b/src/devices/machine/alpha_8921.h @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:cam900 +/*************************************************************************** + + Alpha denshi ALPHA-8921 emulation + +***************************************************************************/ + +#ifndef MAME_MACHINE_ALPHA_8921_H +#define MAME_MACHINE_ALPHA_8921_H + +#pragma once + + +// ======================> alpha_8921_device + +class alpha_8921_device : public device_t +{ +public: + // construction/destruction + alpha_8921_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // inputs + DECLARE_WRITE_LINE_MEMBER(clk_w); + DECLARE_WRITE_LINE_MEMBER(load_w); + DECLARE_WRITE_LINE_MEMBER(even_w); + DECLARE_WRITE_LINE_MEMBER(h_w); + void c_w(u32 data); + + // outputs + u8 gad_r(); + u8 gbd_r(); + DECLARE_READ_LINE_MEMBER(dota_r); + DECLARE_READ_LINE_MEMBER(dotb_r); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + // inputs + bool m_clk = false; // CLK pin + bool m_load = false; // LOAD pin + bool m_even = false; // EVEN pin + bool m_h = false; // H pin + u32 m_c = 0; // C data (32 bit) + + // outputs + u8 m_gad = 0; // GAD data (4 bit) + u8 m_gbd = 0; // GBD data (4 bit) + bool m_dota = false; // DOTA pin + bool m_dotb = false; // DOTB pin + + // internal status + u32 m_sr = 0; + u32 m_old_sr = ~0; + bool m_old_even = true; + bool m_old_h = true; + void update_output(); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(ALPHA_8921, alpha_8921_device) + +#endif // MAME_MACHINE_ALPHA_8921_H diff --git a/src/devices/machine/generalplus_gpl16250soc.cpp b/src/devices/machine/generalplus_gpl16250soc.cpp index ac0c99f480e..2548929027c 100644 --- a/src/devices/machine/generalplus_gpl16250soc.cpp +++ b/src/devices/machine/generalplus_gpl16250soc.cpp @@ -203,7 +203,7 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(int channel) // note, these patch the code copied to SRAM so the 'PROGRAM ROM' check fails (it passes otherwise) - //address_space& mem = this->space(AS_PROGRAM); + address_space& mem = this->space(AS_PROGRAM); //if (mem.read_word(0x4368c) == 0x4846) // mem.write_word(0x4368c, 0x4840); // cars 2 force service mode @@ -218,6 +218,13 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(int channel) //if (mem.read_word(0x4d8d4) == 0x4840) // mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack + //if (mem.read_word(0x3510f) == 0x4845) + // mem.write_word(0x3510f, 0x4840); // camp rock force service mode + + if (mem.read_word(0x4abe7) == 0x4840) + mem.write_word(0x4abe7, 0x4841); // camp rock IRQ? wait hack + + // clear params after operation m_dma_params[0][channel] = m_dma_params[0][channel] & 0x00f7; diff --git a/src/devices/machine/laserdsc.cpp b/src/devices/machine/laserdsc.cpp index 8176ac14f29..ef3df359859 100644 --- a/src/devices/machine/laserdsc.cpp +++ b/src/devices/machine/laserdsc.cpp @@ -308,11 +308,11 @@ void laserdisc_device::device_timer(emu_timer &timer, device_timer_id id, int pa //------------------------------------------------- -// sound_stream_update - audio streamer for +// sound_stream_update_legacy - audio streamer for // laserdiscs //------------------------------------------------- -void laserdisc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void laserdisc_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // compute AND values based on the squelch int16_t leftand = (m_audiosquelch & 1) ? 0x0000 : 0xffff; @@ -762,7 +762,7 @@ void laserdisc_device::init_audio() m_audio_callback.resolve(); // allocate a stream - m_stream = stream_alloc(0, 2, 48000); + m_stream = stream_alloc_legacy(0, 2, 48000); // allocate audio buffers m_audiomaxsamples = ((uint64_t)m_samplerate * 1000000 + m_fps_times_1million - 1) / m_fps_times_1million; diff --git a/src/devices/machine/laserdsc.h b/src/devices/machine/laserdsc.h index e2877a4a216..8ca3abad222 100644 --- a/src/devices/machine/laserdsc.h +++ b/src/devices/machine/laserdsc.h @@ -220,7 +220,7 @@ protected: virtual void device_validity_check(validity_checker &valid) const override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // subclass helpers void set_audio_squelch(bool squelchleft, bool squelchright) { m_stream->update(); m_audiosquelch = (squelchleft ? 1 : 0) | (squelchright ? 2 : 0); } diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 10208d8e357..988c21c33e1 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -263,7 +263,7 @@ plib::istream_uptr netlist_data_memregions_t::stream(const pstring &name) // sound_in // ---------------------------------------------------------------------------------------- -using sound_in_type = netlist::interface::NETLIB_NAME(buffered_param_setter)<stream_sample_t *>; +using sound_in_type = netlist::interface::NETLIB_NAME(buffered_param_setter)<netlist_mame_sound_input_buffer>; class NETLIB_NAME(sound_in) : public sound_in_type { @@ -820,17 +820,15 @@ void netlist_mame_stream_output_device::device_reset() #endif } -void netlist_mame_stream_output_device::sound_update_fill(std::size_t samples, stream_sample_t *target) +void netlist_mame_stream_output_device::sound_update_fill(write_stream_view &target) { - if (samples < m_buffer.size()) - osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), samples, m_buffer.size()); + if (target.samples() < m_buffer.size()) + osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), target.samples(), m_buffer.size()); - std::copy(m_buffer.begin(), m_buffer.end(), target); - std::size_t pos = m_buffer.size(); - while (pos < samples) - { - target[pos++] = m_cur; - } + int sampindex; + for (sampindex = 0; sampindex < m_buffer.size(); sampindex++) + target.put(sampindex, m_buffer[sampindex]); + target.fill(m_cur, sampindex); } @@ -868,19 +866,10 @@ void netlist_mame_stream_output_device::process(netlist::netlist_time_ext tim, n // throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize); while (m_buffer.size() < pos ) { - m_buffer.push_back(static_cast<stream_sample_t>(m_cur)); + m_buffer.push_back(static_cast<stream_buffer::sample_t>(m_cur)); } - // clamp to avoid spikes, but not too hard, as downstream processing, volume - // controls, etc may bring values above 32767 back down in range; some clamping - // is still useful, however, as the mixing is done with integral values - if (plib::abs(val) < 32767.0*256.0) - m_cur = val; - else if (val > 0.0) - m_cur = 32767.0*256.0; - else - m_cur = -32767.0*256.0; - + m_cur = val; } @@ -1409,8 +1398,10 @@ void netlist_mame_sound_device::device_start() if (e.first < 0 || e.first >= m_in.size()) fatalerror("illegal input channel number %d", e.first); } + m_inbuffer.resize(m_in.size()); + /* initialize the stream(s) */ - m_stream = machine().sound().stream_alloc(*this, m_in.size(), m_out.size(), m_sound_clock); + m_stream = stream_alloc(m_in.size(), m_out.size(), m_sound_clock, STREAM_DISABLE_INPUT_RESAMPLING); LOGDEVCALLS("sound device_start exit\n"); } @@ -1453,26 +1444,25 @@ void netlist_mame_sound_device::update_to_current_time() LOGTIMING("%s : %f us before machine time\n", this->name(), (cur - mtime).as_double() * 1000000.0); } -void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - const auto mtime = machine().time(); - if (mtime < m_last_update_to_current_time) - LOGTIMING("machine.time() decreased 1\n"); - m_last_update_to_current_time = mtime; - LOGDEBUG("samples %d\n", samples); - for (auto &e : m_in) { - auto sample_time = netlist::netlist_time::from_raw(static_cast<netlist::netlist_time::internal_type>(nltime_from_attotime(m_attotime_per_clock).as_raw())); - e.second->buffer_reset(sample_time, samples, &inputs[e.first]); + auto clock_period = inputs[e.first].sample_period(); + auto sample_time = netlist::netlist_time::from_raw(static_cast<netlist::netlist_time::internal_type>(nltime_from_attotime(clock_period).as_raw())); + m_inbuffer[e.first] = netlist_mame_sound_input_buffer(inputs[e.first]); + e.second->buffer_reset(sample_time, m_inbuffer[e.first].samples(), &m_inbuffer[e.first]); } - m_cur_time += (samples * m_attotime_per_clock); + int samples = outputs[0].samples(); + LOGDEBUG("samples %d\n", samples); - auto nl_target_time = std::min(nltime_from_attotime(mtime), nltime_from_attotime(m_cur_time)); + // end_time() is the time at the END of the last sample we're generating + // however, the sample value is the value at the START of that last sample, + // so subtract one sample period so that we only process up to the minimum + auto nl_target_time = nltime_from_attotime(outputs[0].end_time() - outputs[0].sample_period()); auto nltime(netlist().exec().time()); - if (nltime < nl_target_time) { netlist().exec().process_queue(nl_target_time - nltime); @@ -1480,7 +1470,7 @@ void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream for (auto &e : m_out) { - e.second->sound_update_fill(samples, outputs[e.first]); + e.second->sound_update_fill(outputs[e.first]); e.second->buffer_reset(nl_target_time); } diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index b7a78c0bd77..8b9e156adba 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -229,6 +229,22 @@ private: }; // ---------------------------------------------------------------------------------------- +// netlist_mame_sound_input_buffer +// ---------------------------------------------------------------------------------------- + +class netlist_mame_sound_input_buffer : public read_stream_view +{ +public: + netlist_mame_sound_input_buffer() : + read_stream_view() { } + + netlist_mame_sound_input_buffer(read_stream_view const &src) : + read_stream_view(src) { } + + stream_buffer::sample_t operator[](std::size_t index) { return get(index); } +}; + +// ---------------------------------------------------------------------------------------- // netlist_mame_sound_device // ---------------------------------------------------------------------------------------- @@ -266,13 +282,14 @@ protected: // device_t overrides virtual void device_start() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void device_validity_check(validity_checker &valid) const override; //virtual void device_reset() override; private: std::map<int, netlist_mame_stream_output_device *> m_out; std::map<std::size_t, nld_sound_in *> m_in; + std::vector<netlist_mame_sound_input_buffer> m_inbuffer; sound_stream *m_stream; attotime m_cur_time; uint32_t m_sound_clock; @@ -593,7 +610,7 @@ public: m_buffer.clear(); } - void sound_update_fill(std::size_t samples, stream_sample_t *target); + void sound_update_fill(write_stream_view &target); void set_sample_time(netlist::netlist_time t) { m_sample_time = t; } @@ -608,7 +625,7 @@ private: uint32_t m_channel; const char * m_out_name; - std::vector<stream_sample_t> m_buffer; + std::vector<stream_buffer::sample_t> m_buffer; double m_cur; netlist::netlist_time m_sample_time; diff --git a/src/devices/machine/s2636.cpp b/src/devices/machine/s2636.cpp index ddc46adf81c..bdf95dc69d0 100644 --- a/src/devices/machine/s2636.cpp +++ b/src/devices/machine/s2636.cpp @@ -203,7 +203,7 @@ void s2636_device::device_start() save_item(NAME(m_intreq)); save_item(NAME(m_intack)); - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); save_item(NAME(m_sample_cnt)); save_item(NAME(m_sound_lvl)); @@ -447,10 +447,10 @@ void s2636_device::write_intack(int state) //------------------------------------------------- -// sound_stream_update - generate audio output +// sound_stream_update_legacy - generate audio output //------------------------------------------------- -void s2636_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void s2636_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; while (samples--) diff --git a/src/devices/machine/s2636.h b/src/devices/machine/s2636.h index bc82ed68903..b5e41b83499 100644 --- a/src/devices/machine/s2636.h +++ b/src/devices/machine/s2636.h @@ -58,7 +58,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: enum diff --git a/src/devices/machine/sensorboard.cpp b/src/devices/machine/sensorboard.cpp index e3e168d6e16..0a5767aef3e 100644 --- a/src/devices/machine/sensorboard.cpp +++ b/src/devices/machine/sensorboard.cpp @@ -49,9 +49,10 @@ To prevent the possibility of a piece/sensor having opposite states (iow: piece selected but sensor deactivated, the button is not clicked when dropping a piece at the same position it was before. -Hold CTRL while clicking to activate the piece but ignore the sensor beneath it. -Hold SHIFT while clicking to activate the sensor but ignore the piece (sidenote: -it will invert the sensor state for magnet boards). +Hold CTRL while clicking to activate the piece but ignore the sensor beneath it, +on magnet boards this only applies during piece capture. Hold SHIFT while clicking +to activate the sensor but ignore the piece, on magnet boards it will invert the +sensor state instead. */ @@ -261,7 +262,7 @@ u8 sensorboard_device::read_sensor(u8 x, u8 y) if (m_magnets) { u8 piece = read_piece(x, y); - u8 state = (piece != 0 && pos != m_handpos && pos != m_droppos) ? 1 : 0; + u8 state = (piece != 0 && pos != m_handpos && (m_inp_ui->read() & 2 || pos != m_droppos)) ? 1 : 0; // piece recognition: return piece id if (m_inductive) diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp index f1ffd871f28..07d01e88be5 100644 --- a/src/devices/machine/spg2xx_audio.cpp +++ b/src/devices/machine/spg2xx_audio.cpp @@ -76,7 +76,7 @@ void spg2xx_audio_device::device_start() m_audio_beat = timer_alloc(TIMER_BEAT); m_audio_beat->adjust(attotime::never); - m_stream = stream_alloc(0, 2, 281250/4); + m_stream = stream_alloc_legacy(0, 2, 281250/4); m_channel_debug = -1; @@ -887,7 +887,7 @@ void spg2xx_audio_device::audio_w(offs_t offset, uint16_t data) } } -void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void spg2xx_audio_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *out_l = outputs[0]; stream_sample_t *out_r = outputs[1]; diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h index 30b001edfb2..59d7635198d 100644 --- a/src/devices/machine/spg2xx_audio.h +++ b/src/devices/machine/spg2xx_audio.h @@ -33,7 +33,7 @@ public: protected: // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; void audio_beat_tick(); void audio_rampdown_tick(const uint32_t channel); diff --git a/src/devices/sound/2203intf.cpp b/src/devices/sound/2203intf.cpp index 9b49479af97..6b579f486a3 100644 --- a/src/devices/sound/2203intf.cpp +++ b/src/devices/sound/2203intf.cpp @@ -54,11 +54,11 @@ void ym2203_device::timer_handler(int c, int count, int clock) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2203_device::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2203_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym2203_update_one(m_chip, outputs[0], samples); } @@ -108,7 +108,7 @@ void ym2203_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc(*this,0,1,rate, stream_update_delegate(&ym2203_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc_legacy(*this,0,1,rate, stream_update_legacy_delegate(&ym2203_device::stream_generate,this)); } //------------------------------------------------- diff --git a/src/devices/sound/2203intf.h b/src/devices/sound/2203intf.h index ff4af97c667..ccb5841cd82 100644 --- a/src/devices/sound/2203intf.h +++ b/src/devices/sound/2203intf.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); private: enum diff --git a/src/devices/sound/2608intf.cpp b/src/devices/sound/2608intf.cpp index 1bc634d34c2..4ca366fa117 100644 --- a/src/devices/sound/2608intf.cpp +++ b/src/devices/sound/2608intf.cpp @@ -63,10 +63,10 @@ void ym2608_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2608_device::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2608_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym2608_update_one(m_chip, outputs, samples); } @@ -93,7 +93,7 @@ void ym2608_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2608_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc_legacy(*this,0,2,rate, stream_update_legacy_delegate(&ym2608_device::stream_generate,this)); /* initialize YM2608 */ m_chip = ym2608_init(this,clock(),rate, diff --git a/src/devices/sound/2608intf.h b/src/devices/sound/2608intf.h index 97e488805c4..c6a3fec6fc9 100644 --- a/src/devices/sound/2608intf.h +++ b/src/devices/sound/2608intf.h @@ -39,7 +39,7 @@ protected: virtual void rom_bank_updated() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); private: void irq_handler(int irq); diff --git a/src/devices/sound/2610intf.cpp b/src/devices/sound/2610intf.cpp index 03c3fc218a2..2f6e3e08620 100644 --- a/src/devices/sound/2610intf.cpp +++ b/src/devices/sound/2610intf.cpp @@ -62,18 +62,18 @@ void ym2610_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2610_device::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2610_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym2610_update_one(m_chip, outputs, samples); } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2610b_device::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2610b_device::stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym2610b_update_one(m_chip, outputs, samples); } @@ -102,7 +102,7 @@ void ym2610_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2610_device::stream_generate,this)); + m_stream = machine().sound().stream_alloc_legacy(*this,0,2,rate, stream_update_legacy_delegate(&ym2610_device::stream_generate,this)); if (!has_configured_map(0) && !has_configured_map(1)) { diff --git a/src/devices/sound/2610intf.h b/src/devices/sound/2610intf.h index 91de98a41a4..a305f9d352d 100644 --- a/src/devices/sound/2610intf.h +++ b/src/devices/sound/2610intf.h @@ -40,7 +40,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + virtual void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples); void * m_chip; @@ -75,7 +75,7 @@ public: ym2610b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void stream_generate(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; }; diff --git a/src/devices/sound/2612intf.cpp b/src/devices/sound/2612intf.cpp index 4c09413339c..679333cdcf3 100644 --- a/src/devices/sound/2612intf.cpp +++ b/src/devices/sound/2612intf.cpp @@ -56,10 +56,10 @@ void ym2612_device::timer_handler(int c,int count,int clock) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2612_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2612_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym2612_update_one(m_chip, outputs, samples, m_output_bits); } @@ -87,7 +87,7 @@ void ym2612_device::device_start() m_timer[1] = timer_alloc(1); /* stream system initialize */ - m_stream = machine().sound().stream_alloc(*this,0,2,rate); + m_stream = stream_alloc_legacy(0,2,rate); /**** initialize YM2612 ****/ m_chip = ym2612_init(this,clock(),rate,&ym2612_device::static_timer_handler,&ym2612_device::static_irq_handler); @@ -108,7 +108,7 @@ void ym2612_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc(*this,0,2,rate); + m_stream = stream_alloc_legacy(0,2,rate); } //------------------------------------------------- diff --git a/src/devices/sound/2612intf.h b/src/devices/sound/2612intf.h index 1bbf9ea3bf9..f9447081d9b 100644 --- a/src/devices/sound/2612intf.h +++ b/src/devices/sound/2612intf.h @@ -33,7 +33,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; u8 m_output_bits; private: diff --git a/src/devices/sound/262intf.cpp b/src/devices/sound/262intf.cpp index f2aee977b30..0a76cdf6d2b 100644 --- a/src/devices/sound/262intf.cpp +++ b/src/devices/sound/262intf.cpp @@ -50,10 +50,10 @@ void ymf262_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ymf262_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymf262_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ymf262_update_one(m_chip, outputs, samples); } @@ -81,7 +81,7 @@ void ymf262_device::device_start() if (!m_chip) throw emu_fatalerror("ymf262_device(%s): Error creating YMF262 chip", tag()); - m_stream = machine().sound().stream_alloc(*this,0,4,rate); + m_stream = stream_alloc_legacy(0,4,rate); /* YMF262 setup */ ymf262_set_timer_handler (m_chip, &ymf262_device::static_timer_handler, this); diff --git a/src/devices/sound/262intf.h b/src/devices/sound/262intf.h index 816b2903831..09ae497748d 100644 --- a/src/devices/sound/262intf.h +++ b/src/devices/sound/262intf.h @@ -27,7 +27,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/3526intf.cpp b/src/devices/sound/3526intf.cpp index dd81b0d7eb0..dce29c78440 100644 --- a/src/devices/sound/3526intf.cpp +++ b/src/devices/sound/3526intf.cpp @@ -60,10 +60,10 @@ void ym3526_device::timer_handler(int c,const attotime &period) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym3526_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym3526_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym3526_update_one(m_chip, outputs[0], samples); } @@ -109,7 +109,7 @@ void ym3526_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc(*this,0,1,rate); + m_stream = stream_alloc_legacy(0,1,rate); } //------------------------------------------------- diff --git a/src/devices/sound/3526intf.h b/src/devices/sound/3526intf.h index 0e57a08e36d..5b425f41241 100644 --- a/src/devices/sound/3526intf.h +++ b/src/devices/sound/3526intf.h @@ -32,7 +32,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/3812intf.cpp b/src/devices/sound/3812intf.cpp index c5f5aeabb05..b9287f21d9e 100644 --- a/src/devices/sound/3812intf.cpp +++ b/src/devices/sound/3812intf.cpp @@ -62,10 +62,10 @@ void ym3812_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym3812_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym3812_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { ym3812_update_one(m_chip, outputs[0], samples); } @@ -110,7 +110,7 @@ void ym3812_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc(*this, 0, 1, rate); + m_stream = stream_alloc_legacy(0, 1, rate); } //------------------------------------------------- diff --git a/src/devices/sound/3812intf.h b/src/devices/sound/3812intf.h index 1bf4e536370..46266bbbca2 100644 --- a/src/devices/sound/3812intf.h +++ b/src/devices/sound/3812intf.h @@ -30,7 +30,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: enum diff --git a/src/devices/sound/8950intf.cpp b/src/devices/sound/8950intf.cpp index 3907daa4700..63056582a0e 100644 --- a/src/devices/sound/8950intf.cpp +++ b/src/devices/sound/8950intf.cpp @@ -56,10 +56,10 @@ void y8950_device::timer_handler(int c, const attotime &period) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void y8950_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void y8950_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { y8950_update_one(m_chip, outputs[0], samples); } @@ -87,7 +87,7 @@ void y8950_device::device_start() /* ADPCM ROM data */ y8950_set_delta_t_memory(m_chip, &y8950_device::static_read_byte, &y8950_device::static_write_byte); - m_stream = machine().sound().stream_alloc(*this,0,1,rate); + m_stream = stream_alloc_legacy(0,1,rate); /* port and keyboard handler */ y8950_set_port_handler(m_chip, &y8950_device::static_port_handler_w, &y8950_device::static_port_handler_r, this); y8950_set_keyboard_handler(m_chip, &y8950_device::static_keyboard_handler_w, &y8950_device::static_keyboard_handler_r, this); diff --git a/src/devices/sound/8950intf.h b/src/devices/sound/8950intf.h index 221c02bfb20..d1ba497c08d 100644 --- a/src/devices/sound/8950intf.h +++ b/src/devices/sound/8950intf.h @@ -41,7 +41,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void irq_handler(int irq); diff --git a/src/devices/sound/aica.cpp b/src/devices/sound/aica.cpp index f3ce7c337e0..7bedf5d660a 100644 --- a/src/devices/sound/aica.cpp +++ b/src/devices/sound/aica.cpp @@ -1229,17 +1229,12 @@ s32 aica_device::UpdateSlot(AICA_SLOT *slot) return sample; } -void aica_device::DoMasterSamples(int nsamples) +void aica_device::DoMasterSamples(std::vector<read_stream_view> const &inputs, write_stream_view &bufl, write_stream_view &bufr) { - stream_sample_t *exts[2]; int i; - stream_sample_t *bufr = m_bufferr; - stream_sample_t *bufl = m_bufferl; - exts[0] = m_exts0; - exts[1] = m_exts1; - - for (int s = 0; s < nsamples; ++s) + constexpr stream_buffer::sample_t sample_scale = 1.0 / stream_buffer::sample_t(32768 << SHIFT); + for (int s = 0; s < bufl.samples(); ++s) { s32 smpl = 0, smpr = 0; @@ -1280,7 +1275,7 @@ void aica_device::DoMasterSamples(int nsamples) { if (EFSDL(i + 16)) // 16,17 for EXTS { - m_DSP.EXTS[i] = exts[i][s]; + m_DSP.EXTS[i] = s16(inputs[i].get(s) * 32767.0); u32 Enc = ((EFPAN(i + 16)) << 0x8) | ((EFSDL(i + 16)) << 0xd); smpl += (m_DSP.EXTS[i] * m_LPANTABLE[Enc]) >> SHIFT; smpr += (m_DSP.EXTS[i] * m_RPANTABLE[Enc]) >> SHIFT; @@ -1298,8 +1293,8 @@ void aica_device::DoMasterSamples(int nsamples) smpr = clip16(smpr >> 3); } - *bufl++ = (smpl * m_LPANTABLE[MVOL() << 0xd]) >> SHIFT; - *bufr++ = (smpr * m_LPANTABLE[MVOL() << 0xd]) >> SHIFT; + bufl.put(s, stream_buffer::sample_t(smpl * m_LPANTABLE[MVOL() << 0xd]) * sample_scale); + bufr.put(s, stream_buffer::sample_t(smpr * m_LPANTABLE[MVOL() << 0xd]) * sample_scale); } } @@ -1393,13 +1388,9 @@ int aica_device::IRQCB(void *param) // sound_stream_update - handle a stream update //------------------------------------------------- -void aica_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void aica_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - m_bufferl = outputs[0]; - m_bufferr = outputs[1]; - m_exts0 = inputs[0]; - m_exts1 = inputs[1]; - DoMasterSamples(samples); + DoMasterSamples(inputs, outputs[0], outputs[1]); } //------------------------------------------------- @@ -1418,7 +1409,7 @@ void aica_device::device_start() m_irq_cb.resolve_safe(); m_main_irq_cb.resolve_safe(); - m_stream = machine().sound().stream_alloc(*this, 2, 2, (int)m_rate); + m_stream = stream_alloc(2, 2, (int)m_rate); // save state save_item(NAME(m_udata.data)); @@ -1568,10 +1559,6 @@ aica_device::aica_device(const machine_config &mconfig, const char *tag, device_ , m_MidiR(0) , m_mcieb(0) , m_mcipd(0) - , m_bufferl(nullptr) - , m_bufferr(nullptr) - , m_exts0(nullptr) - , m_exts1(nullptr) { memset(&m_udata.data, 0, sizeof(m_udata.data)); diff --git a/src/devices/sound/aica.h b/src/devices/sound/aica.h index 7c5597b5aa6..8509953a228 100644 --- a/src/devices/sound/aica.h +++ b/src/devices/sound/aica.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; @@ -124,7 +124,7 @@ private: void w16(u32 addr,u16 val); u16 r16(u32 addr); inline s32 UpdateSlot(AICA_SLOT *slot); - void DoMasterSamples(int nsamples); + void DoMasterSamples(std::vector<read_stream_view> const &inputs, write_stream_view &bufl, write_stream_view &bufr); void exec_dma(); @@ -184,11 +184,6 @@ private: AICADSP m_DSP; - stream_sample_t *m_bufferl; - stream_sample_t *m_bufferr; - stream_sample_t *m_exts0; - stream_sample_t *m_exts1; - s32 m_EG_TABLE[0x400]; int m_PLFO_TRI[256],m_PLFO_SQR[256],m_PLFO_SAW[256],m_PLFO_NOI[256]; int m_ALFO_TRI[256],m_ALFO_SQR[256],m_ALFO_SAW[256],m_ALFO_NOI[256]; diff --git a/src/devices/sound/asc.cpp b/src/devices/sound/asc.cpp index f007f4131fb..e03494040ab 100644 --- a/src/devices/sound/asc.cpp +++ b/src/devices/sound/asc.cpp @@ -62,7 +62,7 @@ asc_device::asc_device(const machine_config &mconfig, const char *tag, device_t void asc_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, 22257); + m_stream = stream_alloc(0, 2, 22257); memset(m_regs, 0, sizeof(m_regs)); @@ -117,22 +117,19 @@ void asc_device::device_timer(emu_timer &timer, device_timer_id tid, int param, // our sound stream //------------------------------------------------- -void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void asc_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; int i, ch; static uint32_t wtoffs[2] = { 0, 0x200 }; - outL = outputs[0]; - outR = outputs[1]; + auto &outL = outputs[0]; + auto &outR = outputs[1]; switch (m_regs[R_MODE-0x800] & 3) { case 0: // chip off - for (i = 0; i < samples; i++) - { - outL[i] = outR[i] = 0; - } + outL.fill(0); + outR.fill(0); // IIvx/IIvi bootrom indicates VASP updates this flag even when the chip is off if (m_chip_type == asc_type::VASP) @@ -140,12 +137,19 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp if (m_fifo_cap_a < 0x1ff) { m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A less than half full + + if (m_fifo_cap_a == 0) // fifo A fully empty + { + m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A empty + } } } break; case 1: // FIFO mode - for (i = 0; i < samples; i++) + { + constexpr stream_buffer::sample_t sample_scale = 64.0 / 32768.0; + for (i = 0; i < outL.samples(); i++) { int8_t smpll, smplr; @@ -230,13 +234,16 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp break; } - outL[i] = smpll * 64; - outR[i] = smplr * 64; + outL.put(i, stream_buffer::sample_t(smpll) * sample_scale); + outR.put(i, stream_buffer::sample_t(smplr) * sample_scale); } break; + } case 2: // wavetable mode - for (i = 0; i < samples; i++) + { + constexpr stream_buffer::sample_t sample_scale = 1.0 / (32768.0 * 4.0); + for (i = 0; i < outL.samples(); i++) { int32_t mixL, mixR; int8_t smpl; @@ -262,10 +269,11 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp mixR += smpl*256; } - outL[i] = mixL>>2; - outR[i] = mixR>>2; + outL.put(i, stream_buffer::sample_t(mixL) * sample_scale); + outR.put(i, stream_buffer::sample_t(mixR) * sample_scale); } break; + } } // printf("rdA %04x rdB %04x wrA %04x wrB %04x (capA %04x B %04x)\n", m_fifo_a_rdptr, m_fifo_b_rdptr, m_fifo_a_wrptr, m_fifo_b_wrptr, m_fifo_cap_a, m_fifo_cap_b); diff --git a/src/devices/sound/asc.h b/src/devices/sound/asc.h index e720aab4efa..f1dff62ffc2 100644 --- a/src/devices/sound/asc.h +++ b/src/devices/sound/asc.h @@ -76,7 +76,7 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; devcb_write_line write_irq; diff --git a/src/devices/sound/astrocde.cpp b/src/devices/sound/astrocde.cpp index 63f900b4806..17df6999989 100644 --- a/src/devices/sound/astrocde.cpp +++ b/src/devices/sound/astrocde.cpp @@ -126,12 +126,12 @@ void astrocade_io_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void astrocade_io_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void astrocade_io_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *dest = outputs[0]; + auto &dest = outputs[0]; uint16_t noise_state; uint8_t master_count; uint8_t noise_clock; @@ -142,17 +142,16 @@ void astrocade_io_device::sound_stream_update(sound_stream &stream, stream_sampl noise_state = m_noise_state; /* loop over samples */ - while (samples > 0) + int samples_this_time; + constexpr stream_buffer::sample_t sample_scale = 1.0f / 60.0f; + for (int sampindex = 0; sampindex < dest.samples(); sampindex += samples_this_time) { stream_sample_t cursample = 0; - int samples_this_time; - int samp; /* compute the number of cycles until the next master oscillator reset */ /* or until the next noise boundary */ - samples_this_time = std::min(samples, 256 - master_count); + samples_this_time = std::min<int>(dest.samples() - sampindex, 256 - master_count); samples_this_time = std::min(samples_this_time, 64 - noise_clock); - samples -= samples_this_time; /* sum the output of the tone generators */ if (m_a_state) @@ -167,9 +166,7 @@ void astrocade_io_device::sound_stream_update(sound_stream &stream, stream_sampl cursample += m_reg[7] >> 4; /* scale to max and output */ - cursample = cursample * 32767 / 60; - for (samp = 0; samp < samples_this_time; samp++) - *dest++ = cursample; + dest.fill(stream_buffer::sample_t(cursample) * sample_scale, sampindex, samples_this_time); /* clock the noise; a 2-bit counter clocks a 4-bit counter which clocks the LFSR */ noise_clock += samples_this_time; diff --git a/src/devices/sound/astrocde.h b/src/devices/sound/astrocde.h index 40bf8cc1448..387ef7f9ca3 100644 --- a/src/devices/sound/astrocde.h +++ b/src/devices/sound/astrocde.h @@ -58,7 +58,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; public: void write(offs_t offset, uint8_t data); diff --git a/src/devices/sound/awacs.cpp b/src/devices/sound/awacs.cpp index c03c2d9eb11..19f734cd468 100644 --- a/src/devices/sound/awacs.cpp +++ b/src/devices/sound/awacs.cpp @@ -42,7 +42,7 @@ awacs_device::awacs_device(const machine_config &mconfig, const char *tag, devic void awacs_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, 22050); + m_stream = stream_alloc(0, 2, 22050); memset(m_regs, 0, sizeof(m_regs)); @@ -86,20 +86,20 @@ void awacs_device::device_timer(emu_timer &timer, device_timer_id tid, int param // our sound stream //------------------------------------------------- -void awacs_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void awacs_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *outL, *outR; int offset = (m_buffer_num == 0) ? m_dma_offset_0 : m_dma_offset_1; - outL = outputs[0]; - outR = outputs[1]; + auto &outL = outputs[0]; + auto &outR = outputs[1]; + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; if (m_playback_enable) { - for (int i = 0; i < samples; i++) + for (int i = 0; i < outL.samples(); i++) { - outL[i] = (int16_t)m_dma_space->read_word(offset + m_play_ptr); - outR[i] = (int16_t)m_dma_space->read_word(offset + m_play_ptr + 2); + outL.put(i, stream_buffer::sample_t(s16(m_dma_space->read_word(offset + m_play_ptr))) * sample_scale); + outR.put(i, stream_buffer::sample_t(s16(m_dma_space->read_word(offset + m_play_ptr + 2))) * sample_scale); m_play_ptr += 4; } @@ -115,11 +115,8 @@ void awacs_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else { - for (int i = 0; i < samples; i++) - { - outL[i] = 0; - outR[i] = 0; - } + outL.fill(0); + outR.fill(0); } } diff --git a/src/devices/sound/awacs.h b/src/devices/sound/awacs.h index 4ef4a800a24..0840d21d0d9 100644 --- a/src/devices/sound/awacs.h +++ b/src/devices/sound/awacs.h @@ -36,7 +36,7 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; sound_stream *m_stream; diff --git a/src/devices/sound/ay8910.cpp b/src/devices/sound/ay8910.cpp index 1b1026b9e57..26e99cf1bc7 100644 --- a/src/devices/sound/ay8910.cpp +++ b/src/devices/sound/ay8910.cpp @@ -593,7 +593,7 @@ YM2203 Japanese datasheet contents, translated: http://www.larwe.com/technical/c #define ENABLE_REGISTER_TEST (0) /* Enable preprogrammed registers */ #define LOG_IGNORED_WRITES (0) -static constexpr int MAX_OUTPUT = 0x7fff; +static constexpr stream_buffer::sample_t MAX_OUTPUT = 1.0; /************************************* * @@ -770,7 +770,7 @@ static const ay8910_device::mosfet_param ay8910_mosfet_param = * *************************************/ -static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *par, const ay8910_device::ay_ym_param *par_env, int normalize, double factor, int zero_is_off, s32 *tab) +static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *par, const ay8910_device::ay_ym_param *par_env, int normalize, double factor, int zero_is_off, stream_buffer::sample_t *tab) { double min = 10.0, max = 0.0; @@ -829,7 +829,7 @@ static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *p /* for (e = 0;e<16;e++) printf("%d %d\n",e << 10, tab[e << 10]); */ } -static inline void build_single_table(double rl, const ay8910_device::ay_ym_param *par, int normalize, s32 *tab, int zero_is_off) +static inline void build_single_table(double rl, const ay8910_device::ay_ym_param *par, int normalize, stream_buffer::sample_t *tab, int zero_is_off) { double rt; double rw; @@ -867,7 +867,7 @@ static inline void build_single_table(double rl, const ay8910_device::ay_ym_para } -static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param &par, const double rd, s32 *tab) +static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param &par, const double rd, stream_buffer::sample_t *tab) { for (int j = 0; j < par.m_count; j++) { @@ -878,18 +878,14 @@ static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param const double Vs = p2 - sqrt(p2 * p2 - Vg * Vg); const double res = rd * (Vd / Vs - 1.0); - /* That's the biggest value we can stream on to netlist. */ - if (res > (1 << 28)) - tab[j] = (1 << 28); - else - tab[j] = res; + tab[j] = res; //printf("%d %f %10d\n", j, rd / (res + rd) * 5.0, tab[j]); } } -u16 ay8910_device::mix_3D() +stream_buffer::sample_t ay8910_device::mix_3D() { int indx = 0; @@ -1085,27 +1081,18 @@ void ay8910_device::ay8910_write_reg(int r, int v) // sound_stream_update - handle a stream update //------------------------------------------------- -void ay8910_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ay8910_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buf[NUM_CHANNELS]; tone_t *tone; envelope_t *envelope; - buf[0] = outputs[0]; - buf[1] = nullptr; - buf[2] = nullptr; - if (m_streams == NUM_CHANNELS) - { - buf[1] = outputs[1]; - buf[2] = outputs[2]; - } + int samples = outputs[0].samples(); /* hack to prevent us from hanging when starting filtered outputs */ if (!m_ready) { - for (int chan = 0; chan < NUM_CHANNELS; chan++) - if (buf[chan] != nullptr) - memset(buf[chan], 0, samples * sizeof(*buf[chan])); + for (int chan = 0; chan < m_streams; chan++) + outputs[chan].fill(0); } /* The 8910 has three outputs, each output is the mix of one of the three */ @@ -1116,7 +1103,7 @@ void ay8910_device::sound_stream_update(sound_stream &stream, stream_sample_t ** /* is 1, not 0, and can be modulated changing the volume. */ /* buffering loop */ - while (samples) + for (int sampindex = 0; sampindex < samples; sampindex++) { for (int chan = 0; chan < NUM_CHANNELS; chan++) { @@ -1212,40 +1199,39 @@ void ay8910_device::sound_stream_update(sound_stream &stream, stream_sample_t ** { env_volume >>= 1; if (m_feature & PSG_EXTENDED_ENVELOPE) // AY8914 Has a two bit tone_envelope field - *(buf[chan]++) = m_vol_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]; + outputs[chan].put(sampindex, m_vol_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]); else - *(buf[chan]++) = m_vol_table[chan][m_vol_enabled[chan] ? env_volume : 0]; + outputs[chan].put(sampindex, m_vol_table[chan][m_vol_enabled[chan] ? env_volume : 0]); } else { if (m_feature & PSG_EXTENDED_ENVELOPE) // AY8914 Has a two bit tone_envelope field - *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]; + outputs[chan].put(sampindex, m_env_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]); else - *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? env_volume : 0]; + outputs[chan].put(sampindex, m_env_table[chan][m_vol_enabled[chan] ? env_volume : 0]); } } else { if (m_feature & PSG_EXTENDED_ENVELOPE) // AY8914 Has a two bit tone_envelope field - *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]; + outputs[chan].put(sampindex, m_env_table[chan][m_vol_enabled[chan] ? env_volume >> (3-tone_envelope(tone)) : 0]); else - *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? env_volume : 0]; + outputs[chan].put(sampindex, m_env_table[chan][m_vol_enabled[chan] ? env_volume : 0]); } } else { if (is_expanded_mode()) - *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? tone_volume(tone) : 0]; + outputs[chan].put(sampindex, m_env_table[chan][m_vol_enabled[chan] ? tone_volume(tone) : 0]); else - *(buf[chan]++) = m_vol_table[chan][m_vol_enabled[chan] ? tone_volume(tone) : 0]; + outputs[chan].put(sampindex, m_vol_table[chan][m_vol_enabled[chan] ? tone_volume(tone) : 0]); } } } else { - *(buf[0]++) = mix_3D(); + outputs[0].put(sampindex, mix_3D()); } - samples--; } } @@ -1344,13 +1330,13 @@ void ay8910_device::device_start() m_streams = 1; } - m_vol3d_table = make_unique_clear<s32[]>(8*32*32*32); + m_vol3d_table = make_unique_clear<stream_buffer::sample_t[]>(8*32*32*32); build_mixer_table(); /* The envelope is pacing twice as fast for the YM2149 as for the AY-3-8910, */ /* This handled by the step parameter. Consequently we use a multipler of 2 here. */ - m_channel = machine().sound().stream_alloc(*this, 0, m_streams, (m_feature & PSG_HAS_EXPANDED_MODE) ? master_clock * 2 : master_clock / 8); + m_channel = stream_alloc(0, m_streams, (m_feature & PSG_HAS_EXPANDED_MODE) ? master_clock * 2 : master_clock / 8); ay_set_clock(master_clock); ay8910_statesave(); @@ -1396,7 +1382,7 @@ void ay8910_device::set_volume(int channel,int volume) { for (int ch = 0; ch < m_streams; ch++) if (channel == ch || m_streams == 1 || channel == ALL_8910_CHANNELS) - m_channel->set_output_gain(ch, volume / 100.0); + set_output_gain(ch, volume / 100.0); } void ay8910_device::ay_set_clock(int clock) diff --git a/src/devices/sound/ay8910.h b/src/devices/sound/ay8910.h index d9af1b6b86f..373a850b662 100644 --- a/src/devices/sound/ay8910.h +++ b/src/devices/sound/ay8910.h @@ -135,7 +135,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // trampolines for callbacks from fm.cpp static void psg_set_clock(device_t *device, int clock) { downcast<ay8910_device *>(device)->ay_set_clock(clock); } @@ -276,7 +276,7 @@ private: // internal helpers void set_type(psg_type_t psg_type); - inline u16 mix_3D(); + inline stream_buffer::sample_t mix_3D(); void ay8910_write_reg(int r, int v); void build_mixer_table(); void ay8910_statesave(); @@ -308,9 +308,9 @@ private: u8 m_vol_enabled[NUM_CHANNELS]; const ay_ym_param *m_par; const ay_ym_param *m_par_env; - s32 m_vol_table[NUM_CHANNELS][16]; - s32 m_env_table[NUM_CHANNELS][32]; - std::unique_ptr<s32[]> m_vol3d_table; + stream_buffer::sample_t m_vol_table[NUM_CHANNELS][16]; + stream_buffer::sample_t m_env_table[NUM_CHANNELS][32]; + std::unique_ptr<stream_buffer::sample_t[]> m_vol3d_table; int m_flags; /* Flags */ int m_feature; /* Chip specific features */ int m_res_load[3]; /* Load on channel in ohms */ diff --git a/src/devices/sound/beep.cpp b/src/devices/sound/beep.cpp index 8c5a404afd0..58096c4b561 100644 --- a/src/devices/sound/beep.cpp +++ b/src/devices/sound/beep.cpp @@ -49,7 +49,7 @@ void beep_device::device_start() { m_stream = stream_alloc(0, 1, BEEP_RATE); m_enable = 0; - m_signal = 0x07fff; + m_signal = 1.0; // register for savestates save_item(NAME(m_enable)); @@ -63,9 +63,9 @@ void beep_device::device_start() // sound_stream_update - handle a stream update //------------------------------------------------- -void beep_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void beep_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; int16_t signal = m_signal; int clock = 0, rate = BEEP_RATE / 2; @@ -78,14 +78,14 @@ void beep_device::sound_stream_update(sound_stream &stream, stream_sample_t **in /* if we're not enabled, just fill with 0 */ if ( !m_enable || clock == 0 ) { - memset( buffer, 0, samples * sizeof(*buffer) ); + buffer.fill(0); return; } /* fill in the sample */ - while( samples-- > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = signal; + buffer.put(sampindex, signal); incr -= clock; while( incr < 0 ) { @@ -116,7 +116,7 @@ WRITE_LINE_MEMBER(beep_device::set_state) /* restart wave from beginning */ m_incr = 0; - m_signal = 0x07fff; + m_signal = 1.0; } @@ -131,6 +131,6 @@ void beep_device::set_clock(uint32_t frequency) m_stream->update(); m_frequency = frequency; - m_signal = 0x07fff; + m_signal = 1.0; m_incr = 0; } diff --git a/src/devices/sound/beep.h b/src/devices/sound/beep.h index 388d0fa6261..6c5ef2ae65f 100644 --- a/src/devices/sound/beep.h +++ b/src/devices/sound/beep.h @@ -22,7 +22,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; public: DECLARE_WRITE_LINE_MEMBER(set_state); // enable/disable sound output @@ -33,7 +33,7 @@ private: int m_enable; /* enable beep */ int m_frequency; /* set frequency - this can be changed using the appropriate function */ int m_incr; /* initial wave state */ - int16_t m_signal; /* current signal */ + stream_buffer::sample_t m_signal; /* current signal */ }; DECLARE_DEVICE_TYPE(BEEP, beep_device) diff --git a/src/devices/sound/bsmt2000.cpp b/src/devices/sound/bsmt2000.cpp index 05ea982bb8e..09392661079 100644 --- a/src/devices/sound/bsmt2000.cpp +++ b/src/devices/sound/bsmt2000.cpp @@ -175,14 +175,12 @@ void bsmt2000_device::device_timer(emu_timer &timer, device_timer_id id, int par // for our sound stream //------------------------------------------------- -void bsmt2000_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void bsmt2000_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // just fill with current left/right values - for (int samp = 0; samp < samples; samp++) - { - outputs[0][samp] = m_left_data; - outputs[1][samp] = m_right_data; - } + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + outputs[0].fill(stream_buffer::sample_t(m_left_data) * sample_scale); + outputs[1].fill(stream_buffer::sample_t(m_right_data) * sample_scale); } diff --git a/src/devices/sound/bsmt2000.h b/src/devices/sound/bsmt2000.h index ef3c13e045f..289457cffd9 100644 --- a/src/devices/sound/bsmt2000.h +++ b/src/devices/sound/bsmt2000.h @@ -53,7 +53,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/c140.cpp b/src/devices/sound/c140.cpp index 7f3780c8ed3..0edb1920a8c 100644 --- a/src/devices/sound/c140.cpp +++ b/src/devices/sound/c140.cpp @@ -77,9 +77,9 @@ DEFINE_DEVICE_TYPE(C219, c219_device, "c219", "Namco C219") // LIVE DEVICE //************************************************************************** -static inline int limit(s32 in) +static inline stream_buffer::sample_t limit(stream_buffer::sample_t in) { - return std::max(-0x7fff, std::min(0x8000, in)); + return std::max(-1.0f, std::min(1.0f, in)); } @@ -220,7 +220,7 @@ void c140_device::rom_bank_updated() // sound_stream_update - handle a stream update //------------------------------------------------- -void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void c140_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { s32 dt; @@ -228,6 +228,7 @@ void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **in s16 *lmix, *rmix; + int samples = outputs[0].samples(); if (samples > m_sample_rate) samples = m_sample_rate; /* zap the contents of the mixer buffer */ @@ -323,21 +324,22 @@ void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **in lmix = m_mixer_buffer_left.get(); rmix = m_mixer_buffer_right.get(); { - stream_sample_t *dest1 = outputs[0]; - stream_sample_t *dest2 = outputs[1]; + auto &dest1 = outputs[0]; + auto &dest2 = outputs[1]; + constexpr stream_buffer::sample_t sample_scale = 8.0 / 32768.0; for (int i = 0; i < samples; i++) { - s32 val; + stream_buffer::sample_t val; - val = 8 * (*lmix++); - *dest1++ = limit(val); - val = 8 * (*rmix++); - *dest2++ = limit(val); + val = stream_buffer::sample_t(*lmix++) * sample_scale; + dest1.put(i, limit(val)); + val = stream_buffer::sample_t(*rmix++) * sample_scale; + dest2.put(i, limit(val)); } } } -void c219_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void c219_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { s32 dt; @@ -345,6 +347,7 @@ void c219_device::sound_stream_update(sound_stream &stream, stream_sample_t **in s16 *lmix, *rmix; + int samples = outputs[0].samples(); if (samples > m_sample_rate) samples = m_sample_rate; /* zap the contents of the mixer buffer */ @@ -460,16 +463,17 @@ void c219_device::sound_stream_update(sound_stream &stream, stream_sample_t **in lmix = m_mixer_buffer_left.get(); rmix = m_mixer_buffer_right.get(); { - stream_sample_t *dest1 = outputs[0]; - stream_sample_t *dest2 = outputs[1]; + auto &dest1 = outputs[0]; + auto &dest2 = outputs[1]; + constexpr stream_buffer::sample_t sample_scale = 8.0 / 32768.0; for (int i = 0; i < samples; i++) { - s32 val; + stream_buffer::sample_t val; - val = 8 * (*lmix++); - *dest1++ = limit(val); - val = 8 * (*rmix++); - *dest2++ = limit(val); + val = stream_buffer::sample_t(*lmix++) * sample_scale; + dest1.put(i, limit(val)); + val = stream_buffer::sample_t(*rmix++) * sample_scale; + dest2.put(i, limit(val)); } } } diff --git a/src/devices/sound/c140.h b/src/devices/sound/c140.h index 6f645a06d9e..3008d964a9d 100644 --- a/src/devices/sound/c140.h +++ b/src/devices/sound/c140.h @@ -44,7 +44,7 @@ protected: virtual void rom_bank_updated() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual int find_sample(int adrs, int bank, int voice); @@ -116,7 +116,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual int find_sample(int adrs, int bank, int voice) override; diff --git a/src/devices/sound/c352.cpp b/src/devices/sound/c352.cpp index 5038e0aaee2..826f194437a 100644 --- a/src/devices/sound/c352.cpp +++ b/src/devices/sound/c352.cpp @@ -122,14 +122,15 @@ void c352_device::ramp_volume(c352_voice_t &v, int ch, u8 val) v.curr_vol[ch] += (vol_delta > 0) ? -1 : 1; } -void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void c352_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer_fl = outputs[0]; - stream_sample_t *buffer_fr = outputs[1]; - stream_sample_t *buffer_rl = outputs[2]; - stream_sample_t *buffer_rr = outputs[3]; + auto &buffer_fl = outputs[0]; + auto &buffer_fr = outputs[1]; + auto &buffer_rl = outputs[2]; + auto &buffer_rr = outputs[3]; - for (int i = 0; i < samples; i++) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for (int i = 0; i < buffer_fl.samples(); i++) { int out[4] = { 0, 0, 0, 0 }; @@ -173,10 +174,10 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in out[3] += (((v.flags & C352_FLG_PHASEFR) ? -s : s) * v.curr_vol[3]) >> 8; } - *buffer_fl++ = (s16)(out[0] >> 3); - *buffer_fr++ = (s16)(out[1] >> 3); - *buffer_rl++ = (s16)(out[2] >> 3); - *buffer_rr++ = (s16)(out[3] >> 3); + buffer_fl.put(i, stream_buffer::sample_t(s16(out[0] >> 3)) * sample_scale); + buffer_fr.put(i, stream_buffer::sample_t(s16(out[1] >> 3)) * sample_scale); + buffer_rl.put(i, stream_buffer::sample_t(s16(out[2] >> 3)) * sample_scale); + buffer_rr.put(i, stream_buffer::sample_t(s16(out[3] >> 3)) * sample_scale); } } @@ -358,14 +359,14 @@ void c352_device::device_clock_changed() if (m_stream != nullptr) m_stream->set_sample_rate(m_sample_rate_base); else - m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base); + m_stream = stream_alloc(0, 4, m_sample_rate_base); } void c352_device::device_start() { m_sample_rate_base = clock() / m_divider; - m_stream = machine().sound().stream_alloc(*this, 0, 4, m_sample_rate_base); + m_stream = stream_alloc(0, 4, m_sample_rate_base); // generate mulaw table (Output similar to namco's VC emulator) int j = 0; diff --git a/src/devices/sound/c352.h b/src/devices/sound/c352.h index 2a8ea946c5b..d21ac96cd86 100644 --- a/src/devices/sound/c352.h +++ b/src/devices/sound/c352.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/c6280.cpp b/src/devices/sound/c6280.cpp index 0278620d943..d01dd74125a 100644 --- a/src/devices/sound/c6280.cpp +++ b/src/devices/sound/c6280.cpp @@ -42,15 +42,16 @@ #include <algorithm> -void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void c6280_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { const u8 lmal = (m_balance >> 4) & 0x0f; const u8 rmal = (m_balance >> 0) & 0x0f; /* Clear buffer */ - std::fill_n(&outputs[0][0], samples, 0); - std::fill_n(&outputs[1][0], samples, 0); + outputs[0].fill(0); + outputs[1].fill(0); + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int ch = 0; ch < 6; ch++) { channel *chan = &m_channel[ch]; @@ -76,7 +77,7 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i { /* Noise mode */ const u32 step = (chan->noise_control & 0x1f) ^ 0x1f; - for (int i = 0; i < samples; i += 1) + for (int i = 0; i < outputs[0].samples(); i += 1) { s16 data = BIT(chan->noise_seed, 0) ? 0x1f : 0; chan->noise_counter--; @@ -87,18 +88,18 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i // based on Charles MacDonald's research chan->noise_seed = (seed >> 1) | ((BIT(seed, 0) ^ BIT(seed, 1) ^ BIT(seed, 11) ^ BIT(seed, 12) ^ BIT(seed, 17)) << 17); } - outputs[0][i] += (s16)(vll * (data - 16)); - outputs[1][i] += (s16)(vlr * (data - 16)); + outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); + outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); } } else if (chan->control & 0x40) { /* DDA mode */ - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { - outputs[0][i] += (s16)(vll * (chan->dda - 16)); - outputs[1][i] += (s16)(vlr * (chan->dda - 16)); + outputs[0].add(i, stream_buffer::sample_t(s16(vll * (chan->dda - 16))) * sample_scale); + outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (chan->dda - 16))) * sample_scale); } } else @@ -111,7 +112,7 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i channel *lfo_srcchan = &m_channel[1]; channel *lfo_dstchan = &m_channel[0]; const u16 lfo_step = lfo_srcchan->frequency ? lfo_srcchan->frequency : 0x1000; - for (int i = 0; i < samples; i += 1) + for (int i = 0; i < outputs[0].samples(); i += 1) { s32 step = lfo_dstchan->frequency ? lfo_dstchan->frequency : 0x1000; if (m_lfo_control & 0x80) // reset LFO @@ -137,8 +138,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i lfo_dstchan->tick = step; lfo_dstchan->index = (lfo_dstchan->index + 1) & 0x1f; } - outputs[0][i] += (s16)(vll * (data - 16)); - outputs[1][i] += (s16)(vlr * (data - 16)); + outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); + outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); } } } @@ -146,7 +147,7 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i { /* Waveform mode */ const u32 step = chan->frequency ? chan->frequency : 0x1000; - for (int i = 0; i < samples; i += 1) + for (int i = 0; i < outputs[0].samples(); i += 1) { const s16 data = chan->waveform[chan->index]; chan->tick--; @@ -155,8 +156,8 @@ void c6280_device::sound_stream_update(sound_stream &stream, stream_sample_t **i chan->tick = step; chan->index = (chan->index + 1) & 0x1f; } - outputs[0][i] += (s16)(vll * (data - 16)); - outputs[1][i] += (s16)(vlr * (data - 16)); + outputs[0].add(i, stream_buffer::sample_t(s16(vll * (data - 16))) * sample_scale); + outputs[1].add(i, stream_buffer::sample_t(s16(vlr * (data - 16))) * sample_scale); } } } @@ -319,7 +320,7 @@ void c6280_device::device_start() m_lfo_control = 0; memset(m_channel, 0, sizeof(channel) * 8); - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()); + m_stream = stream_alloc(0, 2, clock()); /* Make volume table */ /* PSG has 48dB volume range spread over 32 steps */ diff --git a/src/devices/sound/c6280.h b/src/devices/sound/c6280.h index 9a778c31a9d..60ea993f71b 100644 --- a/src/devices/sound/c6280.h +++ b/src/devices/sound/c6280.h @@ -22,7 +22,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: struct channel { diff --git a/src/devices/sound/cdda.cpp b/src/devices/sound/cdda.cpp index 1b2d766493e..ca2bd280de8 100644 --- a/src/devices/sound/cdda.cpp +++ b/src/devices/sound/cdda.cpp @@ -15,11 +15,11 @@ // sound_stream_update - handle a stream update //------------------------------------------------- -void cdda_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cdda_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - get_audio_data(&outputs[0][0], &outputs[1][0], samples); - m_audio_volume[0] = int16_t(outputs[0][0]); - m_audio_volume[1] = int16_t(outputs[1][0]); + get_audio_data(outputs[0], outputs[1]); + m_audio_volume[0] = outputs[0].get(0); + m_audio_volume[1] = outputs[1].get(0); } //------------------------------------------------- @@ -31,7 +31,7 @@ void cdda_device::device_start() /* allocate an audio cache */ m_audio_cache = std::make_unique<uint8_t[]>(CD_MAX_SECTOR_DATA * MAX_SECTORS ); - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()); + m_stream = stream_alloc(0, 2, clock()); m_audio_playing = 0; m_audio_pause = 0; @@ -159,12 +159,13 @@ int cdda_device::audio_ended() converts it to 2 16-bit 44.1 kHz streams -------------------------------------------------*/ -void cdda_device::get_audio_data(stream_sample_t *bufL, stream_sample_t *bufR, uint32_t samples_wanted) +void cdda_device::get_audio_data(write_stream_view &bufL, write_stream_view &bufR) { int i; int16_t *audio_cache = (int16_t *) m_audio_cache.get(); - while (samples_wanted > 0) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for (int sampindex = 0; sampindex < bufL.samples(); ) { /* if no file, audio not playing, audio paused, or out of disc data, just zero fill */ @@ -176,12 +177,12 @@ void cdda_device::get_audio_data(stream_sample_t *bufL, stream_sample_t *bufR, u m_audio_ended_normally = true; } - memset(bufL, 0, sizeof(stream_sample_t)*samples_wanted); - memset(bufR, 0, sizeof(stream_sample_t)*samples_wanted); + bufL.fill(0, sampindex); + bufR.fill(0, sampindex); return; } - int samples = samples_wanted; + int samples = bufL.samples() - sampindex; if (samples > m_audio_samples) { samples = m_audio_samples; @@ -190,11 +191,11 @@ void cdda_device::get_audio_data(stream_sample_t *bufL, stream_sample_t *bufR, u for (i = 0; i < samples; i++) { /* CD-DA data on the disc is big-endian */ - *bufL++ = (int16_t) big_endianize_int16( audio_cache[ m_audio_bptr ] ); m_audio_bptr++; - *bufR++ = (int16_t) big_endianize_int16( audio_cache[ m_audio_bptr ] ); m_audio_bptr++; + bufL.put(sampindex + i, stream_buffer::sample_t(s16(big_endianize_int16( audio_cache[ m_audio_bptr ] ))) * sample_scale); m_audio_bptr++; + bufR.put(sampindex + i, stream_buffer::sample_t(s16(big_endianize_int16( audio_cache[ m_audio_bptr ] ))) * sample_scale); m_audio_bptr++; } - samples_wanted -= samples; + sampindex += samples; m_audio_samples -= samples; if (m_audio_samples == 0) diff --git a/src/devices/sound/cdda.h b/src/devices/sound/cdda.h index 73a1e1a237d..b0c7b7f81e8 100644 --- a/src/devices/sound/cdda.h +++ b/src/devices/sound/cdda.h @@ -30,10 +30,10 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: - void get_audio_data(stream_sample_t *bufL, stream_sample_t *bufR, uint32_t samples_wanted); + void get_audio_data(write_stream_view &bufL, write_stream_view &bufR); cdrom_file * m_disc; diff --git a/src/devices/sound/cdp1863.cpp b/src/devices/sound/cdp1863.cpp index 0f480f05bb6..984a306b28a 100644 --- a/src/devices/sound/cdp1863.cpp +++ b/src/devices/sound/cdp1863.cpp @@ -64,7 +64,7 @@ cdp1863_device::cdp1863_device(const machine_config &mconfig, const char *tag, d void cdp1863_device::device_start() { // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); // register for state saving save_item(NAME(m_clock1)); @@ -81,20 +81,15 @@ void cdp1863_device::device_start() // our sound stream //------------------------------------------------- -void cdp1863_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cdp1863_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - // reset the output stream - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - - int16_t signal = m_signal; - stream_sample_t *buffer = outputs[0]; - - memset( buffer, 0, samples * sizeof(*buffer) ); + stream_buffer::sample_t signal = m_signal; + auto &buffer = outputs[0]; if (m_oe) { double frequency; - int rate = machine().sample_rate() / 2; + int rate = buffer.sample_rate() / 2; // get progress through wave int incr = m_incr; @@ -112,16 +107,16 @@ void cdp1863_device::sound_stream_update(sound_stream &stream, stream_sample_t * if (signal < 0) { - signal = -0x7fff; + signal = -1.0; } else { - signal = 0x7fff; + signal = 1.0; } - while( samples-- > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = signal; + buffer.put(sampindex, signal); incr -= frequency; while( incr < 0 ) { @@ -134,6 +129,8 @@ void cdp1863_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_incr = incr; m_signal = signal; } + else + buffer.fill(0); } diff --git a/src/devices/sound/cdp1863.h b/src/devices/sound/cdp1863.h index e44b65a6f9d..ec0706e9a7c 100644 --- a/src/devices/sound/cdp1863.h +++ b/src/devices/sound/cdp1863.h @@ -54,7 +54,7 @@ protected: virtual void device_start() override; // internal callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream *m_stream; @@ -65,7 +65,7 @@ private: // sound state int m_oe; // output enable int m_latch; // sound latch - int16_t m_signal; // current signal + stream_buffer::sample_t m_signal;// current signal int m_incr; // initial wave state }; diff --git a/src/devices/sound/cdp1864.cpp b/src/devices/sound/cdp1864.cpp index ba026792c49..e8168004811 100644 --- a/src/devices/sound/cdp1864.cpp +++ b/src/devices/sound/cdp1864.cpp @@ -119,7 +119,7 @@ void cdp1864_device::device_start() initialize_palette(); // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); // allocate timers m_int_timer = timer_alloc(TIMER_INT); @@ -257,36 +257,31 @@ void cdp1864_device::device_timer(emu_timer &timer, device_timer_id id, int para // our sound stream //------------------------------------------------- -void cdp1864_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cdp1864_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - // reset the output stream - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - - int16_t signal = m_signal; - stream_sample_t *buffer = outputs[0]; - - memset( buffer, 0, samples * sizeof(*buffer) ); + stream_buffer::sample_t signal = m_signal; + auto &buffer = outputs[0]; if (m_aoe) { double frequency = unscaled_clock() / 8 / 4 / (m_latch + 1) / 2; - int rate = machine().sample_rate() / 2; + int rate = buffer.sample_rate() / 2; /* get progress through wave */ int incr = m_incr; if (signal < 0) { - signal = -0x7fff; + signal = -1.0; } else { - signal = 0x7fff; + signal = 1.0; } - while( samples-- > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = signal; + buffer.put(sampindex, signal); incr -= frequency; while( incr < 0 ) { @@ -299,6 +294,8 @@ void cdp1864_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_incr = incr; m_signal = signal; } + else + buffer.fill(0); } diff --git a/src/devices/sound/cdp1864.h b/src/devices/sound/cdp1864.h index 54c8f3b8ab2..6c589128ef7 100644 --- a/src/devices/sound/cdp1864.h +++ b/src/devices/sound/cdp1864.h @@ -115,7 +115,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // internal callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: enum @@ -157,7 +157,7 @@ private: // sound state int m_aoe; // audio on int m_latch; // sound latch - int16_t m_signal; // current signal + stream_buffer::sample_t m_signal; // current signal int m_incr; // initial wave state // timers diff --git a/src/devices/sound/cdp1869.cpp b/src/devices/sound/cdp1869.cpp index 02977b6d860..98580d7ae54 100644 --- a/src/devices/sound/cdp1869.cpp +++ b/src/devices/sound/cdp1869.cpp @@ -400,7 +400,7 @@ void cdp1869_device::device_start() m_bkg = 0; // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); // initialize other m_tonediv = 0; @@ -510,36 +510,33 @@ void cdp1869_device::cdp1869_palette(palette_device &palette) const // our sound stream //------------------------------------------------- -void cdp1869_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void cdp1869_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - // reset the output stream - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - - int16_t signal = m_signal; - stream_sample_t *buffer = outputs[0]; + stream_buffer::sample_t signal = m_signal; + auto &buffer = outputs[0]; if (!m_toneoff && m_toneamp) { double frequency = (clock() / 2) / (512 >> m_tonefreq) / (m_tonediv + 1); // double amplitude = m_toneamp * ((0.78*5) / 15); - int rate = machine().sample_rate() / 2; + int rate = buffer.sample_rate() / 2; /* get progress through wave */ int incr = m_incr; if (signal < 0) { - signal = -(m_toneamp * (0x07fff / 15)); + signal = -(stream_buffer::sample_t(m_toneamp) / 15.0); } else { - signal = m_toneamp * (0x07fff / 15); + signal = stream_buffer::sample_t(m_toneamp) / 15.0; } - while( samples-- > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ = signal; + buffer.put(sampindex, signal); incr -= frequency; while( incr < 0 ) { @@ -552,6 +549,8 @@ void cdp1869_device::sound_stream_update(sound_stream &stream, stream_sample_t * m_incr = incr; m_signal = signal; } + else + buffer.fill(0); /* if (!m_wnoff) { diff --git a/src/devices/sound/cdp1869.h b/src/devices/sound/cdp1869.h index be366a8d029..dc9c1501ea0 100644 --- a/src/devices/sound/cdp1869.h +++ b/src/devices/sound/cdp1869.h @@ -216,7 +216,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_sound_interface callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; inline bool is_ntsc(); inline uint8_t read_page_ram_byte(offs_t address); @@ -264,7 +264,7 @@ private: uint16_t m_hma; // home memory address // sound state - int16_t m_signal; // current signal + stream_buffer::sample_t m_signal; // current signal int m_incr; // initial wave state int m_toneoff; // tone off int m_wnoff; // white noise off diff --git a/src/devices/sound/cem3394.cpp b/src/devices/sound/cem3394.cpp index 60381d97723..5b288d2d700 100644 --- a/src/devices/sound/cem3394.cpp +++ b/src/devices/sound/cem3394.cpp @@ -19,23 +19,36 @@ #include <algorithm> -/* waveform generation parameters */ +// use 0.25 as the base volume for pulses +static constexpr double PULSE_VOLUME = 0.25; + +// sawtooth is 27% larger than pulses +static constexpr double SAWTOOTH_VOLUME = PULSE_VOLUME * 1.27f; + +// triangle is 27% larger than sawtooth +static constexpr double TRIANGLE_VOLUME = SAWTOOTH_VOLUME * 1.27f; + +// external input is unknown but let's make it the same as the pulse +static constexpr double EXTERNAL_VOLUME = PULSE_VOLUME; + + +// waveform generation parameters #define ENABLE_PULSE 1 #define ENABLE_TRIANGLE 1 #define ENABLE_SAWTOOTH 1 #define ENABLE_EXTERNAL 1 -/* pulse shaping parameters */ -/* examples: */ -/* hat trick - skidding ice sounds too loud if minimum width is too big */ -/* snake pit - melody during first level too soft if minimum width is too small */ -/* snake pit - bonus counter at the end of level */ -/* snacks'n jaxson - laugh at end of level is too soft if minimum width is too small */ +// pulse shaping parameters +// examples: +// hat trick - skidding ice sounds too loud if minimum width is too big +// snake pit - melody during first level too soft if minimum width is too small +// snake pit - bonus counter at the end of level +// snacks'n jaxson - laugh at end of level is too soft if minimum width is too small #define LIMIT_WIDTH 1 -#define MINIMUM_WIDTH 0.25 -#define MAXIMUM_WIDTH 0.75 +#define MINIMUM_WIDTH 0.2 +#define MAXIMUM_WIDTH 0.8 /******************************************************************************** @@ -97,13 +110,6 @@ #define WAVE_SAWTOOTH 2 #define WAVE_PULSE 4 -// keep lots of fractional bits -#define FRACTION_BITS 28 -#define FRACTION_ONE (1 << FRACTION_BITS) -#define FRACTION_ONE_D ((double)(1 << FRACTION_BITS)) -#define FRACTION_MASK (FRACTION_ONE - 1) -#define FRACTION_MULT(a,b) (((a) >> (FRACTION_BITS / 2)) * ((b) >> (FRACTION_BITS - FRACTION_BITS / 2))) - // device type definition DEFINE_DEVICE_TYPE(CEM3394, cem3394_device, "cem3394", "CEM3394 Synthesizer Voice") @@ -116,208 +122,143 @@ DEFINE_DEVICE_TYPE(CEM3394, cem3394_device, "cem3394", "CEM3394 Synthesizer Voic // cem3394_device - constructor //------------------------------------------------- -cem3394_device::cem3394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, CEM3394, tag, owner, clock), - device_sound_interface(mconfig, *this), - m_ext_cb(*this), - m_stream(nullptr), - m_vco_zero_freq(0.0), - m_filter_zero_freq(0.0), - m_wave_select(0), - m_volume(0), - m_mixer_internal(0), - m_mixer_external(0), - m_position(0), - m_step(0), - m_filter_position(0), - m_filter_step(0), - m_modulation_depth(0), - m_last_ext(0), - m_pulse_width(0), - m_inv_sample_rate(0.0), - m_sample_rate(0), - m_mixer_buffer(nullptr), - m_external_buffer(nullptr) +cem3394_device::cem3394_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, CEM3394, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(nullptr), + m_vco_zero_freq(500.0), + m_filter_zero_freq(1300.0), + m_values{0}, + m_wave_select(0), + m_volume(0), + m_mixer_internal(0), + m_mixer_external(0), + m_vco_position(0), + m_vco_step(0), + m_filter_frequency(1300), + m_filter_modulation(0), + m_filter_resonance(0), + m_filter_in{0}, + m_filter_out{0}, + m_pulse_width(0), + m_inv_sample_rate(1.0/48000.0) { - std::fill(std::begin(m_values), std::end(m_values), 0.0); } //------------------------------------------------- -// sound_stream_update - generate sound to the mix buffer in mono +// sound_stream_update - generate sound to the mix +// buffer in mono //------------------------------------------------- -void cem3394_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +double cem3394_device::filter(double input, double cutoff) { - int int_volume = (m_volume * m_mixer_internal) / 256; - int ext_volume = (m_volume * m_mixer_external) / 256; - uint32_t step = m_step, position, end_position = 0; - stream_sample_t *buffer = outputs[0]; - int16_t *mix, *ext; - int i; - - /* external volume is effectively 0 if no external function */ - if (m_ext_cb.isnull() || !ENABLE_EXTERNAL) - ext_volume = 0; - - /* adjust the volume for the filter */ - if (step > m_filter_step) - int_volume /= step - m_filter_step; - - /* bail if nothing's going on */ - if (int_volume == 0 && ext_volume == 0) + // clamp cutoff to useful range, 20Hz-20kHz + cutoff = std::max(std::min(cutoff, 20000.0), 20.0); + + // clamp resonance to 0.95 to prevent infinite gain + double r = 4.0 * std::min(m_filter_resonance, 0.95); + + double g = 2 * M_PI * cutoff; + double zc = g / tan(g/2 * m_inv_sample_rate); + + double gzc = zc / g; + double gzc2 = gzc * gzc; + double gzc3 = gzc2 * gzc; + double gzc4 = gzc3 * gzc; + double r1 = 1 + r; + + double a0 = r1; + double a1 = 4 * r1; + double a2 = 6 * r1; + double a3 = 4 * r1; + double a4 = r1; + + double b0 = r1 + 4 * gzc + 6 * gzc2 + 4 * gzc3 + gzc4; + double b1 = 4 * (r1 + 2 * gzc - 2 * gzc3 - gzc4); + double b2 = 6 * (r1 - 2 * gzc2 + gzc4); + double b3 = 4 * (r1 - 2 * gzc + 2 * gzc3 - gzc4); + double b4 = r1 - 4 * gzc + 6 * gzc2 - 4 * gzc3 + gzc4; + + double output = (input * a0 + + m_filter_in[0] * a1 + m_filter_in[1] * a2 + m_filter_in[2] * a3 + m_filter_in[3] * a4 + - m_filter_out[0] * b1 - m_filter_out[1] * b2 - m_filter_out[2] * b3 - m_filter_out[3] * b4) / b0; + +// sound_assert(!std::isnan(output)); +// sound_assert(output >= -1.5 && output <= 1.5); + if (output < -1.5 || output > 1.5 || std::isnan(output)) { - memset(buffer, 0, sizeof(*buffer) * samples); - return; + if (m_filter_out[0] > -1.5 && m_filter_out[0] < 1.5) + printf("cutoff: %6.0f res: %.5f output: %.5f\n", cutoff, m_filter_resonance, output); } + if (std::isnan(output)) output = 0; + + m_filter_in[3] = m_filter_in[2]; + m_filter_in[2] = m_filter_in[1]; + m_filter_in[1] = m_filter_in[0]; + m_filter_in[0] = input; + + m_filter_out[3] = m_filter_out[2]; + m_filter_out[2] = m_filter_out[1]; + m_filter_out[1] = m_filter_out[0]; + m_filter_out[0] = output; + + if (output < -1.0) + output = -1.0; + else if (output > 1.0) + output = 1.0; + return output; +} - /* if there's external stuff, fetch and process it now */ - if (ext_volume != 0) - { - uint32_t fposition = m_filter_position, fstep = m_filter_step, depth; - int16_t last_ext = m_last_ext; - - /* fetch the external data */ - m_ext_cb(samples, m_external_buffer.get()); - - /* compute the modulation depth, and adjust fstep to the maximum frequency */ - /* we lop off 13 bits of depth so that we can multiply by stepadjust, below, */ - /* which has 13 bits of precision */ - depth = FRACTION_MULT(fstep, m_modulation_depth); - fstep += depth; - depth >>= 13; - - /* "apply" the filter: note this is pretty cheesy; it basically just downsamples the - external sample to filter_freq by allowing only 2 transitions for every cycle */ - for (i = 0, ext = m_external_buffer.get(), position = m_position; i < samples; i++, ext++) - { - uint32_t newposition; - int32_t stepadjust; - - /* update the position and compute the adjustment from a triangle wave */ - if (position & (1 << (FRACTION_BITS - 1))) - stepadjust = 0x2000 - ((position >> (FRACTION_BITS - 14)) & 0x1fff); - else - stepadjust = (position >> (FRACTION_BITS - 14)) & 0x1fff; - position += step; - - /* if we cross a half-step boundary, allow the next byte of the external input */ - newposition = fposition + fstep - (stepadjust * depth); - if ((newposition ^ fposition) & ~(FRACTION_MASK >> 1)) - last_ext = *ext; - else - *ext = last_ext; - fposition = newposition & FRACTION_MASK; - } +void cem3394_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + auto &external = inputs[0]; + auto &buffer = outputs[0]; - /* update the final filter values */ - m_filter_position = fposition; - m_last_ext = last_ext; - } + if (m_wave_select == 0 && m_mixer_external == 0) + logerror("%f V didn't cut it\n", m_values[WAVE_SELECT]); - /* if there's internal stuff, generate it */ - if (int_volume != 0) + // loop over samples + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - if (m_wave_select == 0 && !ext_volume) - logerror("%f V didn't cut it\n", m_values[WAVE_SELECT]); - - /* handle the pulse component; it maxes out at 0x1932, which is 27% smaller than */ - /* the sawtooth (since the value is constant, this is the best place to have an */ - /* odd value for volume) */ - if (ENABLE_PULSE && (m_wave_select & WAVE_PULSE)) - { - uint32_t pulse_width = m_pulse_width; + // get the current VCO position and step it forward + double vco_position = m_vco_position; + m_vco_position += m_vco_step; - /* if the width is wider than the step, we're guaranteed to hit it once per cycle */ - if (pulse_width >= step) - { - for (i = 0, mix = m_mixer_buffer.get(), position = m_position; i < samples; i++, mix++) - { - if (position < pulse_width) - *mix = 0x1932; - else - *mix = 0x0000; - position = (position + step) & FRACTION_MASK; - } - } - - /* otherwise, we compute a volume and watch for cycle boundary crossings */ - else - { - int16_t volume = 0x1932 * pulse_width / step; - for (i = 0, mix = m_mixer_buffer.get(), position = m_position; i < samples; i++, mix++) - { - uint32_t newposition = position + step; - if ((newposition ^ position) & ~FRACTION_MASK) - *mix = volume; - else - *mix = 0x0000; - position = newposition & FRACTION_MASK; - } - } - end_position = position; - } + // clamp VCO position to a fraction + if (m_vco_position >= 1.0) + m_vco_position -= floor(m_vco_position); - /* otherwise, clear the mixing buffer */ - else - memset(m_mixer_buffer.get(), 0, sizeof(int16_t) * samples); + // handle the pulse component; might need some more thought here + double result = 0; + if (ENABLE_PULSE && (m_wave_select & WAVE_PULSE)) + if (vco_position < m_pulse_width) + result += PULSE_VOLUME * m_mixer_internal; - /* handle the sawtooth component; it maxes out at 0x2000, which is 27% larger */ - /* than the pulse */ + // handle the sawtooth component if (ENABLE_SAWTOOTH && (m_wave_select & WAVE_SAWTOOTH)) - { - for (i = 0, mix = m_mixer_buffer.get(), position = m_position; i < samples; i++, mix++) - { - *mix += ((position >> (FRACTION_BITS - 14)) & 0x3fff) - 0x2000; - position += step; - } - end_position = position & FRACTION_MASK; - } + result += SAWTOOTH_VOLUME * m_mixer_internal * vco_position; - /* handle the triangle component; it maxes out at 0x2800, which is 25% larger */ - /* than the sawtooth (should be 27% according to the specs, but 25% saves us */ - /* a multiplication) */ + // always compute the triangle waveform which is also used for filter modulation + double triangle = 2.0 * vco_position; + if (triangle > 1.0) + triangle = 2.0 - triangle; + + // handle the triangle component if (ENABLE_TRIANGLE && (m_wave_select & WAVE_TRIANGLE)) - { - for (i = 0, mix = m_mixer_buffer.get(), position = m_position; i < samples; i++, mix++) - { - int16_t value; - if (position & (1 << (FRACTION_BITS - 1))) - value = 0x2000 - ((position >> (FRACTION_BITS - 14)) & 0x1fff); - else - value = (position >> (FRACTION_BITS - 14)) & 0x1fff; - *mix += value + (value >> 2); - position += step; - } - end_position = position & FRACTION_MASK; - } + result += TRIANGLE_VOLUME * m_mixer_internal * triangle; - /* update the final position */ - m_position = end_position; - } + // compute extension input (for Bally/Sente this is the noise) + if (ENABLE_EXTERNAL) + result += EXTERNAL_VOLUME * m_mixer_external * external.get(sampindex); - /* mix it down */ - mix = m_mixer_buffer.get(); - ext = m_external_buffer.get(); - { - /* internal + external */ - if (ext_volume != 0 && int_volume != 0) - { - for (i = 0; i < samples; i++, mix++, ext++) - *buffer++ = (*mix * int_volume + *ext * ext_volume) / 128; - } - /* internal only */ - else if (int_volume != 0) - { - for (i = 0; i < samples; i++, mix++) - *buffer++ = *mix * int_volume / 128; - } - /* external only */ - else - { - for (i = 0; i < samples; i++, ext++) - *buffer++ = *ext * ext_volume / 128; - } + // compute the modulated filter frequency and apply the filter + // modulation tracks the VCO triangle + double filter_freq = m_filter_frequency * (1 + m_filter_modulation * (triangle - 0.5)); + result = filter(result, filter_freq); + + // write the sample + buffer.put(sampindex, result * m_volume); } } @@ -328,51 +269,49 @@ void cem3394_device::sound_stream_update(sound_stream &stream, stream_sample_t * void cem3394_device::device_start() { - /* copy global parameters */ - m_sample_rate = SAMPLE_RATE; - m_inv_sample_rate = 1.0 / (double)m_sample_rate; - - /* allocate stream channels, 1 per chip */ - m_stream = stream_alloc(0, 1, m_sample_rate); - - m_ext_cb.resolve(); + // compute a sample rate + // VCO can range up to pow(2, 4.0/.75) = ~40.3 * zero-voltage-freq (ZVF) + int sample_rate = m_vco_zero_freq * pow(2, 4.0 / 0.75) * 5; + m_inv_sample_rate = 1.0 / double(sample_rate); - /* allocate memory for a mixer buffer and external buffer (1 second should do it!) */ - m_mixer_buffer = std::make_unique<int16_t[]>(m_sample_rate); - m_external_buffer = std::make_unique<int16_t[]>(m_sample_rate); + // allocate stream channels, 1 per chip, with one external input + m_stream = stream_alloc(1, 1, sample_rate); save_item(NAME(m_values)); save_item(NAME(m_wave_select)); + save_item(NAME(m_volume)); save_item(NAME(m_mixer_internal)); save_item(NAME(m_mixer_external)); - save_item(NAME(m_position)); - save_item(NAME(m_step)); - save_item(NAME(m_filter_position)); - save_item(NAME(m_filter_step)); - save_item(NAME(m_modulation_depth)); - save_item(NAME(m_last_ext)); + + save_item(NAME(m_vco_position)); + save_item(NAME(m_vco_step)); + + save_item(NAME(m_filter_frequency)); + save_item(NAME(m_filter_modulation)); + save_item(NAME(m_filter_resonance)); + save_item(NAME(m_pulse_width)); } double cem3394_device::compute_db(double voltage) { - /* assumes 0.0 == full off, 4.0 == full on, with linear taper, as described in the datasheet */ + // assumes 0.0 == full off, 4.0 == full on, with linear taper, as described in the datasheet - /* above 4.0, maximum volume */ + // above 4.0, maximum volume if (voltage >= 4.0) return 0.0; - /* below 0.0, minimum volume */ + // below 0.0, minimum volume else if (voltage <= 0.0) return 90.0; - /* between 2.5 and 4.0, linear from 20dB to 0dB */ + // between 2.5 and 4.0, linear from 20dB to 0dB else if (voltage >= 2.5) return (4.0 - voltage) * (1.0 / 1.5) * 20.0; - /* between 0.0 and 2.5, exponential to 20dB */ + // between 0.0 and 2.5, exponential to 20dB else { double temp = 20.0 * pow(2.0, 2.5 - voltage); @@ -382,33 +321,33 @@ double cem3394_device::compute_db(double voltage) } -uint32_t cem3394_device::compute_db_volume(double voltage) +stream_buffer::sample_t cem3394_device::compute_db_volume(double voltage) { double temp; - /* assumes 0.0 == full off, 4.0 == full on, with linear taper, as described in the datasheet */ + // assumes 0.0 == full off, 4.0 == full on, with linear taper, as described in the datasheet - /* above 4.0, maximum volume */ + // above 4.0, maximum volume if (voltage >= 4.0) - return 256; + return 1.0; - /* below 0.0, minimum volume */ + // below 0.0, minimum volume else if (voltage <= 0.0) return 0; - /* between 2.5 and 4.0, linear from 20dB to 0dB */ + // between 2.5 and 4.0, linear from 20dB to 0dB else if (voltage >= 2.5) temp = (4.0 - voltage) * (1.0 / 1.5) * 20.0; - /* between 0.0 and 2.5, exponential to 20dB */ + // between 0.0 and 2.5, exponential to 20dB else { temp = 20.0 * pow(2.0, 2.5 - voltage); if (temp < 50.0) return 0; } - /* convert from dB to volume and return */ - return (uint32_t)(256.0 * pow(0.891251, temp)); + // convert from dB to volume and return + return powf(0.891251f, temp); } @@ -416,24 +355,24 @@ void cem3394_device::set_voltage(int input, double voltage) { double temp; - /* don't do anything if no change */ + // don't do anything if no change if (voltage == m_values[input]) return; m_values[input] = voltage; - /* update the stream first */ + // update the stream first m_stream->update(); - /* switch off the input */ + // switch off the input switch (input) { - /* frequency varies from -4.0 to +4.0, at 0.75V/octave */ + // frequency varies from -4.0 to +4.0, at 0.75V/octave case VCO_FREQUENCY: temp = m_vco_zero_freq * pow(2.0, -voltage * (1.0 / 0.75)); - m_step = (uint32_t)(temp * m_inv_sample_rate * FRACTION_ONE_D); + m_vco_step = temp * m_inv_sample_rate; break; - /* wave select determines triangle/sawtooth enable */ + // wave select determines triangle/sawtooth enable case WAVE_SELECT: m_wave_select &= ~(WAVE_TRIANGLE | WAVE_SAWTOOTH); if (voltage >= -0.5 && voltage <= -0.2) @@ -444,7 +383,7 @@ void cem3394_device::set_voltage(int input, double voltage) m_wave_select |= WAVE_SAWTOOTH; break; - /* pulse width determines duty cycle; 0.0 means 0%, 2.0 means 100% */ + // pulse width determines duty cycle; 0.0 means 0%, 2.0 means 100% case PULSE_WIDTH: if (voltage < 0.0) { @@ -453,21 +392,20 @@ void cem3394_device::set_voltage(int input, double voltage) } else { - temp = voltage * 0.5; + m_pulse_width = voltage * 0.5; if (LIMIT_WIDTH) - temp = MINIMUM_WIDTH + (MAXIMUM_WIDTH - MINIMUM_WIDTH) * temp; - m_pulse_width = (uint32_t)(temp * FRACTION_ONE_D); + m_pulse_width = MINIMUM_WIDTH + (MAXIMUM_WIDTH - MINIMUM_WIDTH) * m_pulse_width; m_wave_select |= WAVE_PULSE; } break; - /* final gain is pretty self-explanatory; 0.0 means ~90dB, 4.0 means 0dB */ + // final gain is pretty self-explanatory; 0.0 means ~90dB, 4.0 means 0dB case FINAL_GAIN: m_volume = compute_db_volume(voltage); break; - /* mixer balance is a pan between the external input and the internal input */ - /* 0.0 is equal parts of both; positive values favor external, negative favor internal */ + // mixer balance is a pan between the external input and the internal input + // 0.0 is equal parts of both; positive values favor external, negative favor internal case MIXER_BALANCE: if (voltage >= 0.0) { @@ -481,25 +419,29 @@ void cem3394_device::set_voltage(int input, double voltage) } break; - /* filter frequency varies from -4.0 to +4.0, at 0.375V/octave */ + // filter frequency varies from -3.0 to +4.0, at 0.375V/octave case FILTER_FREQENCY: - temp = m_filter_zero_freq * pow(2.0, -voltage * (1.0 / 0.375)); - m_filter_step = (uint32_t)(temp * m_inv_sample_rate * FRACTION_ONE_D); + m_filter_frequency = m_filter_zero_freq * pow(2.0, -voltage * (1.0 / 0.375)); break; - /* modulation depth is 0.01 at 0V and 2.0 at 3.5V; how it grows from one to the other */ - /* is still unclear at this point */ + // modulation depth is 0.01*freq at 0V and 2.0*freq at 3.5V case MODULATION_AMOUNT: if (voltage < 0.0) - m_modulation_depth = (uint32_t)(0.01 * FRACTION_ONE_D); + m_filter_modulation = 0.01; else if (voltage > 3.5) - m_modulation_depth = (uint32_t)(2.00 * FRACTION_ONE_D); + m_filter_modulation = 1.99; else - m_modulation_depth = (uint32_t)(((voltage * (1.0 / 3.5)) * 1.99 + 0.01) * FRACTION_ONE_D); + m_filter_modulation = (voltage * (1.0 / 3.5)) * 1.98 + 0.01; break; - /* this is not yet implemented */ + // this is not yet implemented case FILTER_RESONANCE: + if (voltage < 0.0) + m_filter_resonance = 0.0; + else if (voltage > 2.5) + m_filter_resonance = 1.0; + else + m_filter_resonance = voltage * (1.0 / 2.5); break; } } @@ -535,9 +477,9 @@ double cem3394_device::get_parameter(int input) if (voltage < 0.0) return 0.01; else if (voltage > 3.5) - return 2.0; + return 1.99; else - return (voltage * (1.0 / 3.5)) * 1.99 + 0.01; + return (voltage * (1.0 / 3.5)) * 1.98 + 0.01; case FILTER_RESONANCE: if (voltage < 0.0) diff --git a/src/devices/sound/cem3394.h b/src/devices/sound/cem3394.h index 40a6a2d0204..a3e5e3a85ea 100644 --- a/src/devices/sound/cem3394.h +++ b/src/devices/sound/cem3394.h @@ -5,14 +5,10 @@ #pragma once -#define CEM3394_EXT_INPUT(_name) void _name(int count, short *buffer) - class cem3394_device : public device_t, public device_sound_interface { public: - static constexpr unsigned SAMPLE_RATE = 44100*4; - // inputs enum { @@ -26,11 +22,8 @@ public: FINAL_GAIN }; - typedef device_delegate<void (int count, short *buffer)> ext_input_delegate; + cem3394_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - cem3394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - template <typename... T> void set_ext_input_callback(T &&... args) { m_ext_cb.set(std::forward<T>(args)...); } void set_vco_zero_freq(double freq) { m_vco_zero_freq = freq; } void set_filter_zero_freq(double freq) { m_filter_zero_freq = freq; } @@ -39,7 +32,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; public: // Set the voltage going to a particular parameter @@ -58,37 +51,34 @@ public: private: double compute_db(double voltage); - uint32_t compute_db_volume(double voltage); + stream_buffer::sample_t compute_db_volume(double voltage); private: - ext_input_delegate m_ext_cb; /* callback to generate external samples */ - - sound_stream *m_stream; /* our stream */ - double m_vco_zero_freq; /* frequency of VCO at 0.0V */ - double m_filter_zero_freq; /* frequency of filter at 0.0V */ + double filter(double input, double cutoff); - double m_values[8]; /* raw values of registers */ - uint8_t m_wave_select; /* flags which waveforms are enabled */ + sound_stream *m_stream; // our stream + double m_vco_zero_freq; // frequency of VCO at 0.0V + double m_filter_zero_freq; // frequency of filter at 0.0V - uint32_t m_volume; /* linear overall volume (0-256) */ - uint32_t m_mixer_internal; /* linear internal volume (0-256) */ - uint32_t m_mixer_external; /* linear external volume (0-256) */ + double m_values[8]; // raw values of registers + u8 m_wave_select; // flags which waveforms are enabled - uint32_t m_position; /* current VCO frequency position (0.FRACTION_BITS) */ - uint32_t m_step; /* per-sample VCO step (0.FRACTION_BITS) */ + double m_volume; // linear overall volume (0-1) + double m_mixer_internal; // linear internal volume (0-1) + double m_mixer_external; // linear external volume (0-1) - uint32_t m_filter_position; /* current filter frequency position (0.FRACTION_BITS) */ - uint32_t m_filter_step; /* per-sample filter step (0.FRACTION_BITS) */ - uint32_t m_modulation_depth; /* fraction of total by which we modulate (0.FRACTION_BITS) */ - int16_t m_last_ext; /* last external sample we read */ + double m_vco_position; // current VCO frequency position (always < 1.0) + double m_vco_step; // per-sample VCO step - uint32_t m_pulse_width; /* fractional pulse width (0.FRACTION_BITS) */ + double m_filter_frequency; // baseline filter frequency + double m_filter_modulation; // depth of modulation (up to 1.0) + double m_filter_resonance; // depth of modulation (up to 1.0) + double m_filter_in[4]; // filter input history + double m_filter_out[4]; // filter output history - double m_inv_sample_rate; - int m_sample_rate; + double m_pulse_width; // fractional pulse width - std::unique_ptr<int16_t[]> m_mixer_buffer; - std::unique_ptr<int16_t[]> m_external_buffer; + double m_inv_sample_rate; // 1/current sample rate }; DECLARE_DEVICE_TYPE(CEM3394, cem3394_device) diff --git a/src/devices/sound/dac.h b/src/devices/sound/dac.h index f1793b5f569..7a48ba80998 100644 --- a/src/devices/sound/dac.h +++ b/src/devices/sound/dac.h @@ -45,9 +45,10 @@ public: }; template <unsigned bits> -constexpr stream_sample_t dac_multiply(const double vref, const stream_sample_t code) +constexpr stream_buffer::sample_t dac_multiply(const double vref, const s32 code) { - return (bits > 1) ? ((vref * code) / (1 << (bits))) : (vref * code); + constexpr stream_buffer::sample_t scale = 1.0 / stream_buffer::sample_t((bits > 1) ? (1 << (bits)) : 1); + return vref * scale * stream_buffer::sample_t(code); } template <unsigned bits> @@ -62,12 +63,12 @@ protected: } sound_stream * m_stream; - stream_sample_t m_code; + s32 m_code; const double m_gain; - inline void setCode(stream_sample_t code) + inline void setCode(s32 code) { - code &= ~(~std::make_unsigned_t<stream_sample_t>(0) << bits); + code &= ~(~u32(0) << bits); if (m_code != code) { m_stream->update(); @@ -75,7 +76,7 @@ protected: } } - virtual void sound_stream_update_tag(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) = 0; + virtual void sound_stream_update_tag(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) = 0; }; template <unsigned bits> @@ -84,14 +85,14 @@ class dac_code_binary : protected dac_code<bits> protected: using dac_code<bits>::dac_code; - virtual void sound_stream_update_tag(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override + virtual void sound_stream_update_tag(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_pos = inputs[DAC_VREF_POS_INPUT][samp] * this->m_gain; - double const vref_neg = inputs[DAC_VREF_NEG_INPUT][samp] * this->m_gain; - stream_sample_t const vout = vref_neg + dac_multiply<bits>(vref_pos - vref_neg, this->m_code); - outputs[0][samp] = vout; + double const vref_pos = inputs[DAC_VREF_POS_INPUT].get(samp) * this->m_gain; + double const vref_neg = inputs[DAC_VREF_NEG_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = vref_neg + dac_multiply<bits>(vref_pos - vref_neg, this->m_code); + outputs[0].put(samp, vout); } } }; @@ -102,24 +103,24 @@ class dac_code_ones_complement : protected dac_code<bits> protected: using dac_code<bits>::dac_code; - virtual void sound_stream_update_tag(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override + virtual void sound_stream_update_tag(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override { if (this->m_code & (1 << (bits - 1))) { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_neg = inputs[DAC_VREF_NEG_INPUT][samp] * this->m_gain; - stream_sample_t const vout = dac_multiply<bits - 1>(vref_neg, this->m_code ^ ~(~0U << bits)); - outputs[0][samp] = vout; + double const vref_neg = inputs[DAC_VREF_NEG_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = dac_multiply<bits - 1>(vref_neg, this->m_code ^ ~(~0U << bits)); + outputs[0].put(samp, vout); } } else { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_pos = inputs[DAC_VREF_POS_INPUT][samp] * this->m_gain; - stream_sample_t const vout = dac_multiply<bits - 1>(vref_pos, this->m_code); - outputs[0][samp] = vout; + double const vref_pos = inputs[DAC_VREF_POS_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = dac_multiply<bits - 1>(vref_pos, this->m_code); + outputs[0].put(samp, vout); } } } @@ -131,14 +132,14 @@ class dac_code_twos_complement : protected dac_code<bits> protected: using dac_code<bits>::dac_code; - virtual void sound_stream_update_tag(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override + virtual void sound_stream_update_tag(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_pos = inputs[DAC_VREF_POS_INPUT][samp] * this->m_gain; - double const vref_neg = inputs[DAC_VREF_NEG_INPUT][samp] * this->m_gain; - stream_sample_t const vout = vref_neg + dac_multiply<bits>(vref_pos - vref_neg, this->m_code ^ (1 << (bits - 1))); - outputs[0][samp] = vout; + double const vref_pos = inputs[DAC_VREF_POS_INPUT].get(samp) * this->m_gain; + double const vref_neg = inputs[DAC_VREF_NEG_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = vref_neg + dac_multiply<bits>(vref_pos - vref_neg, this->m_code ^ (1 << (bits - 1))); + outputs[0].put(samp, vout); } } }; @@ -149,24 +150,24 @@ class dac_code_sign_magntitude : protected dac_code<bits> protected: using dac_code<bits>::dac_code; - virtual void sound_stream_update_tag(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override + virtual void sound_stream_update_tag(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override { if (this->m_code & (1 << (bits - 1))) { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_neg = inputs[DAC_VREF_NEG_INPUT][samp] * this->m_gain; - stream_sample_t const vout = dac_multiply<bits - 1>(vref_neg, this->m_code ^ (1 << (bits - 1))); - outputs[0][samp] = vout; + double const vref_neg = inputs[DAC_VREF_NEG_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = dac_multiply<bits - 1>(vref_neg, this->m_code ^ (1 << (bits - 1))); + outputs[0].put(samp, vout); } } else { - for (int samp = 0; samp < samples; samp++) + for (int samp = 0; samp < outputs[0].samples(); samp++) { - double const vref_pos = inputs[DAC_VREF_POS_INPUT][samp] * this->m_gain; - stream_sample_t const vout = dac_multiply<bits - 1>(vref_pos, this->m_code); - outputs[0][samp] = vout; + double const vref_pos = inputs[DAC_VREF_POS_INPUT].get(samp) * this->m_gain; + stream_buffer::sample_t const vout = dac_multiply<bits - 1>(vref_pos, this->m_code); + outputs[0].put(samp, vout); } } } @@ -193,9 +194,9 @@ protected: save_item(NAME(this->m_code)); } - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override { - _dac_code::sound_stream_update_tag(stream, inputs, outputs, samples); + _dac_code::sound_stream_update_tag(stream, inputs, outputs); } }; diff --git a/src/devices/sound/dac76.cpp b/src/devices/sound/dac76.cpp index 846ae2306bd..bbeb5728577 100644 --- a/src/devices/sound/dac76.cpp +++ b/src/devices/sound/dac76.cpp @@ -51,7 +51,7 @@ dac76_device::dac76_device(const machine_config &mconfig, const char *tag, devic void dac76_device::device_start() { // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate() * 8); + m_stream = stream_alloc(0, 1, machine().sample_rate() * 8); // register for save states save_item(NAME(m_chord)); @@ -75,7 +75,7 @@ void dac76_device::device_reset() // our sound stream //------------------------------------------------- -void dac76_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void dac76_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // get current output level int step_size = (2 << m_chord); @@ -84,9 +84,6 @@ void dac76_device::sound_stream_update(sound_stream &stream, stream_sample_t **i // apply sign bit vout *= (m_sb ? +1 : -1); - // range is 0-8031, normalize to about 0-32768 range - vout *= 4; - - for (int i = 0; i < samples; i++) - outputs[0][i] = vout; + // range is 0-8031, normalize to 0-1 range + outputs[0].fill(stream_buffer::sample_t(vout) * (1.0 / 8031.0)); } diff --git a/src/devices/sound/dac76.h b/src/devices/sound/dac76.h index f986b319917..74f51690082 100644 --- a/src/devices/sound/dac76.h +++ b/src/devices/sound/dac76.h @@ -57,7 +57,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: static constexpr int m_level[8] = { 0, 33, 99, 231, 495, 1023, 2079, 4191 }; diff --git a/src/devices/sound/dave.cpp b/src/devices/sound/dave.cpp index bac697ca619..f26ea891879 100644 --- a/src/devices/sound/dave.cpp +++ b/src/devices/sound/dave.cpp @@ -122,7 +122,7 @@ void dave_device::device_start() the volumes are mixed internally and output as left and right volume */ /* 3 tone channels + 1 noise channel */ - m_sound_stream_var = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate()); + m_sound_stream_var = stream_alloc(0, 2, machine().sample_rate()); } @@ -190,9 +190,8 @@ device_memory_interface::space_config_vector dave_device::memory_space_config() // sound_stream_update - handle a stream update //------------------------------------------------- -void dave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void dave_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer1, *buffer2; /* 0 = channel 0 left volume, 1 = channel 0 right volume, 2 = channel 1 left volume, 3 = channel 1 right volume, 4 = channel 2 left volume, 5 = channel 2 right volume @@ -203,10 +202,11 @@ void dave_device::sound_stream_update(sound_stream &stream, stream_sample_t **in //logerror("sound update!\n"); - buffer1 = outputs[0]; - buffer2 = outputs[1]; + auto &buffer1 = outputs[0]; + auto &buffer2 = outputs[1]; - while (samples) + constexpr stream_buffer::sample_t sample_scale = 1.0 / (4.0 * 32768.0); + for (int sampindex = 0; sampindex < buffer1.samples(); sampindex++) { int vol[4]; @@ -261,13 +261,11 @@ void dave_device::sound_stream_update(sound_stream &stream, stream_sample_t **in output_volumes[6] = ((m_level[3] & m_level_and[6]) | m_level_or[6]) & m_mame_volumes[3]; output_volumes[7] = ((m_level[3] & m_level_and[7]) | m_level_or[7]) & m_mame_volumes[7]; - left_volume = (output_volumes[0] + output_volumes[2] + output_volumes[4] + output_volumes[6])>>2; - right_volume = (output_volumes[1] + output_volumes[3] + output_volumes[5] + output_volumes[7])>>2; + left_volume = output_volumes[0] + output_volumes[2] + output_volumes[4] + output_volumes[6]; + right_volume = output_volumes[1] + output_volumes[3] + output_volumes[5] + output_volumes[7]; - *(buffer1++) = left_volume; - *(buffer2++) = right_volume; - - samples--; + buffer1.put(sampindex, stream_buffer::sample_t(left_volume) * sample_scale); + buffer2.put(sampindex, stream_buffer::sample_t(right_volume) * sample_scale); } } diff --git a/src/devices/sound/dave.h b/src/devices/sound/dave.h index bd5cb6a8445..7d2da120658 100644 --- a/src/devices/sound/dave.h +++ b/src/devices/sound/dave.h @@ -47,7 +47,7 @@ protected: virtual space_config_vector memory_space_config() const override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; uint8_t program_r(offs_t offset); void program_w(offs_t offset, uint8_t data); diff --git a/src/devices/sound/digitalk.cpp b/src/devices/sound/digitalk.cpp index 9992d6b160d..9ca0e6fa5f0 100644 --- a/src/devices/sound/digitalk.cpp +++ b/src/devices/sound/digitalk.cpp @@ -544,29 +544,29 @@ void digitalker_device::digitalker_step() // sound_stream_update - handle a stream update //------------------------------------------------- -void digitalker_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void digitalker_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *sout = outputs[0]; + auto &sout = outputs[0]; int cpos = 0; - while(cpos != samples) { + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + while(cpos != sout.samples()) { if(m_zero_count == 0 && m_dac_index == 128) digitalker_step(); if(m_zero_count) { - int n = samples - cpos; - int i; + int n = sout.samples() - cpos; if(n > m_zero_count) n = m_zero_count; - for(i=0; i != n; i++) - sout[cpos++] = 0; + sout.fill(0, cpos, n); + cpos += n; m_zero_count -= n; } else if(m_dac_index != 128) { - while(cpos != samples && m_dac_index != 128) { - short v = m_dac[m_dac_index]; + while(cpos != sout.samples() && m_dac_index != 128) { + stream_buffer::sample_t v = stream_buffer::sample_t(m_dac[m_dac_index]) * sample_scale; int pp = m_pitch_pos; - while(cpos != samples && pp != m_pitch) { - sout[cpos++] = v; + while(cpos != sout.samples() && pp != m_pitch) { + sout.put(cpos++, v); pp++; } if(pp == m_pitch) { @@ -577,8 +577,8 @@ void digitalker_device::sound_stream_update(sound_stream &stream, stream_sample_ } } else { - while(cpos != samples) - sout[cpos++] = 0; + sout.fill(0, cpos); + break; } } } diff --git a/src/devices/sound/digitalk.h b/src/devices/sound/digitalk.h index 44eff1e0343..18cc32fd3bd 100644 --- a/src/devices/sound/digitalk.h +++ b/src/devices/sound/digitalk.h @@ -29,7 +29,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: void digitalker_write(uint8_t *adr, uint8_t vol, int8_t dac); diff --git a/src/devices/sound/disc_cls.h b/src/devices/sound/disc_cls.h index 1855fbc5444..cb043557734 100644 --- a/src/devices/sound/disc_cls.h +++ b/src/devices/sound/disc_cls.h @@ -118,12 +118,13 @@ public: /* Add gain to the output and put into the buffers */ /* Clipping will be handled by the main sound system */ double val = DISCRETE_INPUT(0) * DISCRETE_INPUT(1); - *m_ptr++ = val; + m_outview->put(m_outview_sample++, val * (1.0 / 32768.0)); } virtual int max_output(void) override { return 0; } - virtual void set_output_ptr(stream_sample_t *ptr) override { m_ptr = ptr; } + virtual void set_output_ptr(write_stream_view &view) override { m_outview = &view; m_outview_sample = 0; } private: - stream_sample_t *m_ptr; + write_stream_view *m_outview; + u32 m_outview_sample; }; DISCRETE_CLASS(dso_csvlog, 0, @@ -230,9 +231,10 @@ public: //protected: uint32_t m_stream_in_number; - stream_sample_t *m_ptr; /* current in ptr for stream */ + read_stream_view const *m_inview; /* current in ptr for stream */ + uint32_t m_inview_sample; private: - void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + void stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs); double m_gain; /* node gain */ double m_offset; /* node offset */ diff --git a/src/devices/sound/disc_inp.hxx b/src/devices/sound/disc_inp.hxx index 2b39825f9f3..1c6c9a6dba5 100644 --- a/src/devices/sound/disc_inp.hxx +++ b/src/devices/sound/disc_inp.hxx @@ -242,21 +242,17 @@ void DISCRETE_CLASS_FUNC(dss_input_pulse, input_write)(int sub_node, uint8_t dat #define DSS_INPUT_STREAM__GAIN DISCRETE_INPUT(1) #define DSS_INPUT_STREAM__OFFSET DISCRETE_INPUT(2) -void discrete_dss_input_stream_node::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void discrete_dss_input_stream_node::stream_generate(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *ptr = outputs[0]; - int samplenum = samples; - - while (samplenum-- > 0) - *(ptr++) = m_data; + outputs[0].fill(m_data * (1.0 / 32768.0)); } DISCRETE_STEP(dss_input_stream) { /* the context pointer is set to point to the current input stream data in discrete_stream_update */ - if (EXPECTED(m_ptr)) + if (EXPECTED(m_inview)) { - set_output(0, (*m_ptr) * m_gain + m_offset); - m_ptr++; + set_output(0, m_inview->get(m_inview_sample) * 32768.0 * m_gain + m_offset); + m_inview_sample++; } else set_output(0, 0); @@ -264,7 +260,7 @@ DISCRETE_STEP(dss_input_stream) DISCRETE_RESET(dss_input_stream) { - m_ptr = nullptr; + m_inview = nullptr; m_data = 0; } @@ -304,7 +300,7 @@ DISCRETE_START(dss_input_stream) m_stream_in_number = DSS_INPUT_STREAM__STREAM; m_gain = DSS_INPUT_STREAM__GAIN; m_offset = DSS_INPUT_STREAM__OFFSET; - m_ptr = nullptr; + m_inview = nullptr; m_is_buffered = is_buffered(); m_buffer_stream = nullptr; @@ -318,7 +314,7 @@ void DISCRETE_CLASS_NAME(dss_input_stream)::stream_start(void) discrete_sound_device *snd_device = downcast<discrete_sound_device *>(m_device); //assert(DSS_INPUT_STREAM__STREAM < snd_device->m_input_stream_list.count()); - m_buffer_stream = m_device->machine().sound().stream_alloc(*snd_device, 0, 1, this->sample_rate(), stream_update_delegate(&discrete_dss_input_stream_node::stream_generate,this)); + m_buffer_stream = m_device->machine().sound().stream_alloc(*snd_device, 0, 1, this->sample_rate(), stream_update_delegate(&discrete_dss_input_stream_node::stream_generate,this), STREAM_DEFAULT_FLAGS); snd_device->get_stream()->set_input(m_stream_in_number, m_buffer_stream); } diff --git a/src/devices/sound/discrete.cpp b/src/devices/sound/discrete.cpp index 2e90311ac46..7d6a84a4fc7 100644 --- a/src/devices/sound/discrete.cpp +++ b/src/devices/sound/discrete.cpp @@ -862,7 +862,7 @@ discrete_device::~discrete_device(void) void discrete_device::device_start() { // create the stream - //m_stream = machine().sound().stream_alloc(*this, 0, 2, 22257); + //m_stream = stream_alloc_legacy(0, 2, 22257); const discrete_block *intf_start = m_intf; @@ -988,7 +988,7 @@ void discrete_sound_device::device_start() fatalerror("init_nodes() - Couldn't find an output node\n"); /* initialize the stream(s) */ - m_stream = machine().sound().stream_alloc(*this,m_input_stream_list.count(), m_output_list.count(), m_sample_rate); + m_stream = stream_alloc(m_input_stream_list.count(), m_output_list.count(), m_sample_rate); /* Finalize stream_input_nodes */ for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) @@ -1060,17 +1060,14 @@ void discrete_device::process(int samples) } //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void discrete_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void discrete_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int outputnum = 0; - if (samples == 0) - return; - /* Setup any output streams */ for_each(discrete_sound_output_interface **, node, &m_output_list) { @@ -1081,11 +1078,12 @@ void discrete_sound_device::sound_stream_update(sound_stream &stream, stream_sam /* Setup any input streams */ for_each(discrete_dss_input_stream_node **, node, &m_input_stream_list) { - (*node)->m_ptr = (stream_sample_t *) inputs[(*node)->m_stream_in_number]; + (*node)->m_inview = &inputs[(*node)->m_stream_in_number]; + (*node)->m_inview_sample = 0; } /* just process it */ - process(samples); + process(outputs[0].samples()); } //------------------------------------------------- diff --git a/src/devices/sound/discrete.h b/src/devices/sound/discrete.h index d06a18bf3a5..65879da211f 100644 --- a/src/devices/sound/discrete.h +++ b/src/devices/sound/discrete.h @@ -4248,7 +4248,7 @@ class discrete_sound_output_interface public: virtual ~discrete_sound_output_interface() { } - virtual void set_output_ptr(stream_sample_t *ptr) = 0; + virtual void set_output_ptr(write_stream_view &view) = 0; }; //************************************************************************** @@ -4387,7 +4387,7 @@ protected: virtual void device_reset() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: /* the output stream */ diff --git a/src/devices/sound/dmadac.cpp b/src/devices/sound/dmadac.cpp index 59fe5b15546..b3a7d84bbf5 100644 --- a/src/devices/sound/dmadac.cpp +++ b/src/devices/sound/dmadac.cpp @@ -21,7 +21,7 @@ * *************************************/ -#define DEFAULT_SAMPLE_RATE (44100) +#define DEFAULT_SAMPLE_RATE (48000) #define BUFFER_SIZE 32768 @@ -38,14 +38,11 @@ void dmadac_sound_device::device_start() { - /* allocate a clear a buffer */ - m_buffer = make_unique_clear<int16_t[]>(BUFFER_SIZE); - /* reset the state */ - m_volume = 0x100; + m_volume = 1.0; /* allocate a stream channel */ - m_channel = machine().sound().stream_alloc(*this, 0, 1, DEFAULT_SAMPLE_RATE); + m_channel = stream_alloc(0, 1, DEFAULT_SAMPLE_RATE); /* register with the save state system */ save_item(NAME(m_bufin)); @@ -53,7 +50,7 @@ void dmadac_sound_device::device_start() save_item(NAME(m_volume)); save_item(NAME(m_enabled)); save_item(NAME(m_frequency)); - save_pointer(NAME(m_buffer), BUFFER_SIZE); + save_item(NAME(m_buffer)); } @@ -91,6 +88,7 @@ void dmadac_sound_device::transfer(int channel, offs_t channel_spacing, offs_t f int j; /* loop over all channels and accumulate the data */ + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; if (m_enabled) { int maxin = (m_bufout + BUFFER_SIZE - 1) % BUFFER_SIZE; @@ -100,6 +98,35 @@ void dmadac_sound_device::transfer(int channel, offs_t channel_spacing, offs_t f /* copy the data */ for (j = 0; j < total_frames && curin != maxin; j++) { + m_buffer[curin] = stream_buffer::sample_t(*src) * sample_scale; + curin = (curin + 1) % BUFFER_SIZE; + src += frame_spacing; + } + m_bufin = curin; + + /* log overruns */ + if (j != total_frames) + logerror("dmadac_transfer: buffer overrun (short %d frames)\n", total_frames - j); + } + + // FIXME: this line has rotted and can no longer compile - it should be fixed and uncommented or removed + //LOG("dmadac_transfer - %d samples, %d effective, %d in buffer\n", total_frames, int(total_frames * double(DEFAULT_SAMPLE_RATE) / dmadac[first_channel].frequency), dmadac[first_channel].curinpos - dmadac[first_channel].curoutpos); +} + +void dmadac_sound_device::transfer(int channel, offs_t channel_spacing, offs_t frame_spacing, offs_t total_frames, stream_buffer::sample_t *data) +{ + int j; + + /* loop over all channels and accumulate the data */ + if (m_enabled) + { + int maxin = (m_bufout + BUFFER_SIZE - 1) % BUFFER_SIZE; + stream_buffer::sample_t *src = data + channel * channel_spacing; + int curin = m_bufin; + + /* copy the data */ + for (j = 0; j < total_frames && curin != maxin; j++) + { m_buffer[curin] = *src; curin = (curin + 1) % BUFFER_SIZE; src += frame_spacing; @@ -187,7 +214,7 @@ void dmadac_set_volume(dmadac_sound_device **devlist, uint8_t num_channels, uint void dmadac_sound_device::set_volume(uint16_t volume) { m_channel->update(); - m_volume = volume; + m_volume = stream_buffer::sample_t(volume) * (1.0 / 256.0); } DEFINE_DEVICE_TYPE(DMADAC, dmadac_sound_device, "dmadac", "DMA-driven DAC") @@ -195,7 +222,7 @@ DEFINE_DEVICE_TYPE(DMADAC, dmadac_sound_device, "dmadac", "DMA-driven DAC") dmadac_sound_device::dmadac_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, DMADAC, tag, owner, clock), device_sound_interface(mconfig, *this), - m_buffer(nullptr), + m_buffer(BUFFER_SIZE), m_bufin(0), m_bufout(0), m_volume(0), @@ -205,27 +232,25 @@ dmadac_sound_device::dmadac_sound_device(const machine_config &mconfig, const ch } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void dmadac_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void dmadac_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *output = outputs[0]; - int16_t *source = m_buffer.get(); + auto &output = outputs[0]; uint32_t curout = m_bufout; uint32_t curin = m_bufin; - int volume = m_volume; /* feed as much as we can */ - while (curout != curin && samples-- > 0) + int sampindex; + for (sampindex = 0; curout != curin && sampindex < output.samples(); sampindex++) { - *output++ = (source[curout] * volume) >> 8; + output.put(sampindex, stream_buffer::sample_t(m_buffer[curout]) * m_volume); curout = (curout + 1) % BUFFER_SIZE; } /* fill the rest with silence */ - while (samples-- > 0) - *output++ = 0; + output.fill(0, sampindex); /* save the new output pointer */ m_bufout = curout; diff --git a/src/devices/sound/dmadac.h b/src/devices/sound/dmadac.h index 5bcffecc35f..eb73d338eb9 100644 --- a/src/devices/sound/dmadac.h +++ b/src/devices/sound/dmadac.h @@ -20,6 +20,7 @@ public: void flush(); void transfer(int channel, offs_t channel_spacing, offs_t frame_spacing, offs_t total_frames, int16_t *data); + void transfer(int channel, offs_t channel_spacing, offs_t frame_spacing, offs_t total_frames, stream_buffer::sample_t *data); void enable(uint8_t enable); void set_frequency(double frequency); void set_volume(uint16_t volume); @@ -29,18 +30,18 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // internal state /* sound stream and buffers */ sound_stream * m_channel; - std::unique_ptr<int16_t[]> m_buffer; + std::vector<stream_buffer::sample_t> m_buffer; uint32_t m_bufin; uint32_t m_bufout; /* per-channel parameters */ - int16_t m_volume; + stream_buffer::sample_t m_volume; uint8_t m_enabled; double m_frequency; }; diff --git a/src/devices/sound/dspv.cpp b/src/devices/sound/dspv.cpp index 4df5846d721..7305c1c5298 100644 --- a/src/devices/sound/dspv.cpp +++ b/src/devices/sound/dspv.cpp @@ -93,7 +93,7 @@ void dspv_device::snd_w(offs_t offset, u16 data) logerror("w %02x, %04x %s\n", offset, data, machine().describe_context()); } -void dspv_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void dspv_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { } diff --git a/src/devices/sound/dspv.h b/src/devices/sound/dspv.h index ba39428005f..fb68acda569 100644 --- a/src/devices/sound/dspv.h +++ b/src/devices/sound/dspv.h @@ -29,7 +29,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: address_space_config m_program_config, m_data_config; diff --git a/src/devices/sound/es1373.cpp b/src/devices/sound/es1373.cpp index 6ff92fcc90b..9475b410f0b 100644 --- a/src/devices/sound/es1373.cpp +++ b/src/devices/sound/es1373.cpp @@ -120,7 +120,7 @@ void es1373_device::device_start() add_map(0x40, M_IO, FUNC(es1373_device::map)); // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100/2); + m_stream = stream_alloc_legacy(0, 2, 44100/2); m_timer = timer_alloc(0, nullptr); m_timer->adjust(attotime::zero, 0, attotime::from_hz(44100/2/16)); @@ -230,13 +230,13 @@ void es1373_device::device_timer(emu_timer &timer, device_timer_id tid, int para } //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void es1373_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void es1373_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { if (m_dac1.enable) { - logerror("%s: sound_stream_update DAC1 not implemented yet\n", tag()); + logerror("%s: sound_stream_update_legacy DAC1 not implemented yet\n", tag()); } if (m_dac2.enable) { @@ -245,7 +245,7 @@ void es1373_device::sound_stream_update(sound_stream &stream, stream_sample_t ** if (m_adc.enable) { if (m_adc.format!=SCTRL_16BIT_MONO) { - logerror("%s: sound_stream_update Only SCTRL_16BIT_MONO recorded supported\n", tag()); + logerror("%s: sound_stream_update_legacy Only SCTRL_16BIT_MONO recorded supported\n", tag()); } else { for (int i=0; i<samples; i++) { if (m_adc.buf_count<=m_adc.buf_size) { @@ -345,7 +345,7 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s } if (LOG_ES_FILE && m_tempCount<1000000) { m_tempCount++; - //logerror("es1373_device::sound_stream_update count: %i samp16: %X\n", i, samp16); + //logerror("es1373_device::sound_stream_update_legacy count: %i samp16: %X\n", i, samp16); //if (LOG_ES_FILE && m_eslog) //fprintf(m_eslog, "%i\n", samp16); } diff --git a/src/devices/sound/es1373.h b/src/devices/sound/es1373.h index e5f107eed11..856d90d7af8 100644 --- a/src/devices/sound/es1373.h +++ b/src/devices/sound/es1373.h @@ -29,7 +29,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_add_mconfig(machine_config &config) override; virtual void device_post_load() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // Sound stream sound_stream *m_stream; diff --git a/src/devices/sound/es5503.cpp b/src/devices/sound/es5503.cpp index fccc2f3a6e4..36fcaaf8af1 100644 --- a/src/devices/sound/es5503.cpp +++ b/src/devices/sound/es5503.cpp @@ -128,7 +128,7 @@ void es5503_device::halt_osc(int onum, int type, uint32_t *accumulator, int ress } } -void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { static int32_t mix[(44100/60)*2*8]; int32_t *mixp; @@ -201,7 +201,7 @@ void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t ** mixp = &mix[0]; for (i = 0; i < samples; i++) for (int chan = 0; chan < output_channels; chan++) - outputs[chan][i] = (*mixp++)>>1; + outputs[chan][i] = (*mixp++)>>3; } @@ -224,7 +224,7 @@ void es5503_device::device_start() save_pointer(STRUCT_MEMBER(oscillators, irqpend), 32); output_rate = (clock() / 8) / (2 + oscsenabled); - m_stream = machine().sound().stream_alloc(*this, 0, output_channels, output_rate); + m_stream = stream_alloc_legacy(0, output_channels, output_rate); m_timer = timer_alloc(0, nullptr); attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never; diff --git a/src/devices/sound/es5503.h b/src/devices/sound/es5503.h index 18305d500bb..1483e91c8ac 100644 --- a/src/devices/sound/es5503.h +++ b/src/devices/sound/es5503.h @@ -36,7 +36,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/es5506.cpp b/src/devices/sound/es5506.cpp index 481830271b5..b238409a1fa 100644 --- a/src/devices/sound/es5506.cpp +++ b/src/devices/sound/es5506.cpp @@ -159,7 +159,7 @@ es550x_device::es550x_device(const machine_config &mconfig, device_type type, co , m_volume_shift(0) , m_volume_acc_shift(0) , m_current_page(0) - , m_active_voices(0) + , m_active_voices(0x1f) , m_mode(0) , m_irqv(0x80) , m_voice_index(0) @@ -249,7 +249,7 @@ void es5506_device::device_start() channels = m_channels; // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2 * channels, clock() / (16*32)); + m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); // initialize the regions if (m_region0 && !has_configured_map(0)) @@ -378,7 +378,7 @@ void es5505_device::device_start() channels = m_channels; // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2 * channels, clock() / (16*32)); + m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); // initialize the regions if (m_region0 && !has_configured_map(0)) @@ -1022,7 +1022,7 @@ inline void es550x_device::generate_irq(es550x_voice *voice, int v) ***********************************************************************************************/ -void es5506_device::generate_samples(s32 **outputs, int offset, int samples) +void es5506_device::generate_samples(s32 * const *outputs, int offset, int samples) { // skip if nothing to do if (!samples) @@ -1067,7 +1067,7 @@ void es5506_device::generate_samples(s32 **outputs, int offset, int samples) } } -void es5505_device::generate_samples(s32 **outputs, int offset, int samples) +void es5505_device::generate_samples(s32 * const *outputs, int offset, int samples) { // skip if nothing to do if (!samples) @@ -2123,10 +2123,10 @@ u16 es5505_device::read(offs_t offset) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void es550x_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void es550x_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { #if ES5506_MAKE_WAVS // start the logging once we have a sample rate diff --git a/src/devices/sound/es5506.h b/src/devices/sound/es5506.h index 30e79d5f0ae..da438066ceb 100644 --- a/src/devices/sound/es5506.h +++ b/src/devices/sound/es5506.h @@ -84,7 +84,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; void update_irq_state(); void update_internal_irq_state(); @@ -114,7 +114,7 @@ protected: void generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); void generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); inline void generate_irq(es550x_voice *voice, int v); - virtual void generate_samples(s32 **outputs, int offset, int samples) {}; + virtual void generate_samples(s32 * const *outputs, int offset, int samples) {}; inline void update_index(es550x_voice *voice) { m_voice_index = voice->index; } virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) { return 0; } @@ -190,7 +190,7 @@ protected: virtual void update_envelopes(es550x_voice *voice) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; - virtual void generate_samples(s32 **outputs, int offset, int samples) override; + virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } @@ -244,7 +244,7 @@ protected: virtual void update_envelopes(es550x_voice *voice) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; - virtual void generate_samples(s32 **outputs, int offset, int samples) override; + virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } diff --git a/src/devices/sound/esqpump.cpp b/src/devices/sound/esqpump.cpp index 5ed977b9f81..7b37a2c9abd 100644 --- a/src/devices/sound/esqpump.cpp +++ b/src/devices/sound/esqpump.cpp @@ -32,7 +32,7 @@ void esq_5505_5510_pump_device::device_start() { logerror("Clock = %d\n", clock()); - m_stream = machine().sound().stream_alloc(*this, 8, 2, clock()); + m_stream = stream_alloc_legacy(8, 2, clock()); m_timer = timer_alloc(0); m_timer->enable(false); @@ -73,7 +73,7 @@ void esq_5505_5510_pump_device::device_clock_changed() m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); } -void esq_5505_5510_pump_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { if (samples != 1) { logerror("Pump: request for %d samples\n", samples); diff --git a/src/devices/sound/esqpump.h b/src/devices/sound/esqpump.h index 8ebd12bccb0..a4fb62b60ff 100644 --- a/src/devices/sound/esqpump.h +++ b/src/devices/sound/esqpump.h @@ -75,7 +75,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // timer callback overrides virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; diff --git a/src/devices/sound/flt_rc.cpp b/src/devices/sound/flt_rc.cpp index 88fb3c7624f..8de64b37a40 100644 --- a/src/devices/sound/flt_rc.cpp +++ b/src/devices/sound/flt_rc.cpp @@ -37,7 +37,7 @@ filter_rc_device::filter_rc_device(const machine_config &mconfig, const char *ta void filter_rc_device::device_start() { - m_stream = stream_alloc(1, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); recalc(); save_item(NAME(m_k)); @@ -51,12 +51,12 @@ void filter_rc_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void filter_rc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void filter_rc_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { - stream_sample_t *src = inputs[0]; + stream_sample_t const *src = inputs[0]; stream_sample_t *dst = outputs[0]; int memory = m_memory; diff --git a/src/devices/sound/flt_rc.h b/src/devices/sound/flt_rc.h index cbf5772607e..9c1bc7f3381 100644 --- a/src/devices/sound/flt_rc.h +++ b/src/devices/sound/flt_rc.h @@ -109,7 +109,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void recalc(); diff --git a/src/devices/sound/flt_vol.cpp b/src/devices/sound/flt_vol.cpp index eec55c413f8..8b8438f9b94 100644 --- a/src/devices/sound/flt_vol.cpp +++ b/src/devices/sound/flt_vol.cpp @@ -27,17 +27,17 @@ filter_volume_device::filter_volume_device(const machine_config &mconfig, const void filter_volume_device::device_start() { m_gain = 0x100; - m_stream = stream_alloc(1, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(1, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void filter_volume_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void filter_volume_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { - stream_sample_t *src = inputs[0]; + stream_sample_t const *src = inputs[0]; stream_sample_t *dst = outputs[0]; while (samples--) diff --git a/src/devices/sound/flt_vol.h b/src/devices/sound/flt_vol.h index bcd4a05d399..034c3a3cf79 100644 --- a/src/devices/sound/flt_vol.h +++ b/src/devices/sound/flt_vol.h @@ -24,7 +24,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream* m_stream; diff --git a/src/devices/sound/fm.cpp b/src/devices/sound/fm.cpp index 23ea6633674..5679860a2f2 100644 --- a/src/devices/sound/fm.cpp +++ b/src/devices/sound/fm.cpp @@ -2727,7 +2727,7 @@ static inline void YM2608IRQMaskWrite(FM_OPN *OPN, ym2608_state *F2608, int v) } /* Generate samples for one of the YM2608s */ -void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length) +void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length) { ym2608_state *F2608 = (ym2608_state *)chip; FM_OPN *OPN = &F2608->OPN; @@ -3275,7 +3275,7 @@ int ym2608_timer_over(void *chip,int c) /* YM2610(OPNB) */ /* Generate samples for one of the YM2610s */ -void ym2610_update_one(void *chip, FMSAMPLE **buffer, int length) +void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length) { ym2610_state *F2610 = (ym2610_state *)chip; FM_OPN *OPN = &F2610->OPN; @@ -3411,7 +3411,7 @@ void ym2610_update_one(void *chip, FMSAMPLE **buffer, int length) #if BUILD_YM2610B /* Generate samples for one of the YM2610Bs */ -void ym2610b_update_one(void *chip, FMSAMPLE **buffer, int length) +void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length) { ym2610_state *F2610 = (ym2610_state *)chip; FM_OPN *OPN = &F2610->OPN; diff --git a/src/devices/sound/fm.h b/src/devices/sound/fm.h index d49c5a40e99..d5d8760a449 100644 --- a/src/devices/sound/fm.h +++ b/src/devices/sound/fm.h @@ -142,7 +142,7 @@ void * ym2608_init(device_t *device, int baseclock, int rate, void ym2608_clock_changed(void *chip, int clock, int rate); void ym2608_shutdown(void *chip); void ym2608_reset_chip(void *chip); -void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length); +void ym2608_update_one(void *chip, FMSAMPLE * const *buffer, int length); int ym2608_write(void *chip, int a,unsigned char v); unsigned char ym2608_read(void *chip,int a); @@ -158,10 +158,10 @@ void * ym2610_init(device_t *device, int baseclock, int rate, void ym2610_clock_changed(void *chip, int clock, int rate); void ym2610_shutdown(void *chip); void ym2610_reset_chip(void *chip); -void ym2610_update_one(void *chip, FMSAMPLE **buffer, int length); +void ym2610_update_one(void *chip, FMSAMPLE * const *buffer, int length); #if BUILD_YM2610B -void ym2610b_update_one(void *chip, FMSAMPLE **buffer, int length); +void ym2610b_update_one(void *chip, FMSAMPLE * const *buffer, int length); #endif /* BUILD_YM2610B */ int ym2610_write(void *chip, int a,unsigned char v); @@ -176,7 +176,7 @@ void * ym2612_init(device_t *device, int baseclock, int rate, void ym2612_clock_changed(void *chip, int clock, int rate); void ym2612_shutdown(void *chip); void ym2612_reset_chip(void *chip); -void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length, u8 output_bits); +void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 output_bits); int ym2612_write(void *chip, int a,unsigned char v); unsigned char ym2612_read(void *chip,int a); diff --git a/src/devices/sound/fm2612.cpp b/src/devices/sound/fm2612.cpp index 6d5f71dac55..b3482d0ac72 100644 --- a/src/devices/sound/fm2612.cpp +++ b/src/devices/sound/fm2612.cpp @@ -2174,7 +2174,7 @@ static void init_tables(void) /*******************************************************************************/ /* Generate samples for one of the YM2612s */ -void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length, u8 output_bits) +void ym2612_update_one(void *chip, FMSAMPLE * const *buffer, int length, u8 output_bits) { // TODO : 'ladder' effects for Mega Drive/Genesis const u8 output_shift = (output_bits > 14) ? 0 : (14 - output_bits); diff --git a/src/devices/sound/gaelco.cpp b/src/devices/sound/gaelco.cpp index 0c2495a4d64..41fbfc0a4c4 100644 --- a/src/devices/sound/gaelco.cpp +++ b/src/devices/sound/gaelco.cpp @@ -76,7 +76,7 @@ gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, device_typ Writes length bytes to the sound buffer ============================================================================*/ -void gaelco_gae1_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void gaelco_gae1_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { /* fill all data needed */ for (int j = 0; j < samples; j++) @@ -253,7 +253,7 @@ void gaelco_gae1_device::gaelcosnd_w(offs_t offset, uint16_t data, uint16_t mem_ void gaelco_gae1_device::device_start() { u32 rate = clock() / 128; - m_stream = stream_alloc(0, 2, rate); + m_stream = stream_alloc_legacy(0, 2, rate); /* init volume table */ for (int vol = 0; vol < VOLUME_LEVELS; vol++) diff --git a/src/devices/sound/gaelco.h b/src/devices/sound/gaelco.h index 07af14a73ec..4f7eeaeb7a7 100644 --- a/src/devices/sound/gaelco.h +++ b/src/devices/sound/gaelco.h @@ -43,7 +43,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/gb.cpp b/src/devices/sound/gb.cpp index e5fe37688cc..42944daf152 100644 --- a/src/devices/sound/gb.cpp +++ b/src/devices/sound/gb.cpp @@ -142,7 +142,7 @@ cgb04_apu_device::cgb04_apu_device(const machine_config &mconfig, const char *ta void gameboy_sound_device::device_start() { - m_channel = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate()); + m_channel = stream_alloc_legacy(0, 2, machine().sample_rate()); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameboy_sound_device::timer_callback),this)); m_timer->adjust(clocks_to_attotime(FRAME_CYCLES/128), 0, clocks_to_attotime(FRAME_CYCLES/128)); @@ -1211,11 +1211,13 @@ void cgb04_apu_device::apu_power_off() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void gameboy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void gameboy_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { + stream_sample_t *outputl = outputs[0]; + stream_sample_t *outputr = outputs[1]; while (samples-- > 0) { stream_sample_t sample; @@ -1272,7 +1274,7 @@ void gameboy_sound_device::sound_stream_update(sound_stream &stream, stream_samp right <<= 6; /* Update the buffers */ - *(outputs[0]++) = left; - *(outputs[1]++) = right; + *outputl++ = left; + *outputr++ = right; } } diff --git a/src/devices/sound/gb.h b/src/devices/sound/gb.h index 989871fe08c..a0ea67ed0a8 100644 --- a/src/devices/sound/gb.h +++ b/src/devices/sound/gb.h @@ -25,7 +25,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; protected: enum diff --git a/src/devices/sound/hc55516.cpp b/src/devices/sound/hc55516.cpp index 99cc782dc20..6397d2c927c 100644 --- a/src/devices/sound/hc55516.cpp +++ b/src/devices/sound/hc55516.cpp @@ -115,7 +115,7 @@ void hc55516_device::start_common(uint8_t _shiftreg_mask, int _active_clock_hi) m_last_clock_state = 0; /* create the stream */ - m_channel = machine().sound().stream_alloc(*this, 0, 1, SAMPLE_RATE); + m_channel = stream_alloc_legacy(0, 1, SAMPLE_RATE); save_item(NAME(m_last_clock_state)); save_item(NAME(m_digit)); @@ -241,10 +241,10 @@ int hc55516_device::clock_state_r() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void hc55516_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void hc55516_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; int i; @@ -301,12 +301,12 @@ void hc55516_device::sound_stream_update(sound_stream &stream, stream_sample_t * *buffer++ = sample; } -void mc3417_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mc3417_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { - hc55516_device::sound_stream_update(stream, inputs, outputs, samples); + hc55516_device::sound_stream_update_legacy(stream, inputs, outputs, samples); } -void mc3418_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mc3418_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { - hc55516_device::sound_stream_update(stream, inputs, outputs, samples); + hc55516_device::sound_stream_update_legacy(stream, inputs, outputs, samples); } diff --git a/src/devices/sound/hc55516.h b/src/devices/sound/hc55516.h index d375de7c413..96284167c52 100644 --- a/src/devices/sound/hc55516.h +++ b/src/devices/sound/hc55516.h @@ -27,7 +27,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; void start_common(uint8_t _shiftreg_mask, int _active_clock_hi); @@ -70,7 +70,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; }; @@ -84,7 +84,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; }; diff --git a/src/devices/sound/huc6230.cpp b/src/devices/sound/huc6230.cpp index 88206877a36..fd2ef5b9689 100644 --- a/src/devices/sound/huc6230.cpp +++ b/src/devices/sound/huc6230.cpp @@ -21,7 +21,7 @@ constexpr int clamp(int val, int min, int max) { return std::min(max, std::max(min, val)); } -void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void huc6230_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int i = 0; i < samples; i++) { @@ -172,7 +172,7 @@ void huc6230_device::device_start() m_vca_cb.resolve_safe(); - m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 6); + m_stream = stream_alloc_legacy(2, 2, clock() / 6); m_adpcm_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(huc6230_device::adpcm_timer),this)); for (int i = 0; i < 2; i++) diff --git a/src/devices/sound/huc6230.h b/src/devices/sound/huc6230.h index 0337d3165e5..27e67ce41a3 100644 --- a/src/devices/sound/huc6230.h +++ b/src/devices/sound/huc6230.h @@ -28,7 +28,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct adpcm_channel { diff --git a/src/devices/sound/i5000.cpp b/src/devices/sound/i5000.cpp index c317d976d9f..747d5e96e19 100644 --- a/src/devices/sound/i5000.cpp +++ b/src/devices/sound/i5000.cpp @@ -44,7 +44,7 @@ void i5000snd_device::device_start() m_lut_volume[0xff] = 0; // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock() / 0x400); + m_stream = stream_alloc_legacy(0, 2, clock() / 0x400); m_rom_base = (uint16_t *)device().machine().root_device().memregion(":i5000snd")->base(); m_rom_mask = device().machine().root_device().memregion(":i5000snd")->bytes() / 2 - 1; @@ -114,7 +114,7 @@ bool i5000snd_device::read_sample(int ch) } -void i5000snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void i5000snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int i = 0; i < samples; i++) { diff --git a/src/devices/sound/i5000.h b/src/devices/sound/i5000.h index 9a9a8efb3af..0bb994ebdb6 100644 --- a/src/devices/sound/i5000.h +++ b/src/devices/sound/i5000.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; sound_stream *m_stream; diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp index c61ddd819b2..fa570814019 100644 --- a/src/devices/sound/ics2115.cpp +++ b/src/devices/sound/ics2115.cpp @@ -63,7 +63,7 @@ void ics2115_device::device_start() m_timer[0].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_0),this), this); m_timer[1].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ics2115_device::timer_cb_1),this), this); - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock() / (32 * 32)); + m_stream = stream_alloc_legacy(0, 2, clock() / (32 * 32)); m_irq_cb.resolve_safe(); @@ -385,7 +385,7 @@ void ics2115_device::ics2115_voice::update_ramp() } } -int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2], int samples) +int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t * const outputs[2], int samples) { bool irq_invalid = false; const u16 fine = 1 << (3*(voice.vol.incr >> 6)); @@ -426,7 +426,7 @@ int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2 return irq_invalid; } -void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ics2115_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { memset(outputs[0], 0, samples * sizeof(stream_sample_t)); memset(outputs[1], 0, samples * sizeof(stream_sample_t)); diff --git a/src/devices/sound/ics2115.h b/src/devices/sound/ics2115.h index ea26826da4a..777ee8eabf4 100644 --- a/src/devices/sound/ics2115.h +++ b/src/devices/sound/ics2115.h @@ -39,7 +39,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; @@ -119,7 +119,7 @@ private: void recalc_irq(); // stream helper functions - int fill_output(ics2115_voice& voice, stream_sample_t *outputs[2], int samples); + int fill_output(ics2115_voice& voice, stream_sample_t * const outputs[2], int samples); stream_sample_t get_sample(ics2115_voice& voice); u8 read_sample(ics2115_voice& voice, u32 addr) { return m_cache.read_byte((voice.osc.saddr << 20) | (addr & 0xfffff)); } diff --git a/src/devices/sound/iopspu.cpp b/src/devices/sound/iopspu.cpp index 1d4e78f879c..73399b1ef2c 100644 --- a/src/devices/sound/iopspu.cpp +++ b/src/devices/sound/iopspu.cpp @@ -89,7 +89,7 @@ void iop_spu_device::dma_done(int bank) core.m_status &= ~STATUS_DMA_ACTIVE; } -void iop_spu_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void iop_spu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // TODO } diff --git a/src/devices/sound/iopspu.h b/src/devices/sound/iopspu.h index 6a9e6235409..4348e471051 100644 --- a/src/devices/sound/iopspu.h +++ b/src/devices/sound/iopspu.h @@ -48,7 +48,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // HACK: This timer is currently used to trigger an interrupt after the auto-DMA-transferred buffer would have been // mixed and played back, as the PS2 BIOS pulls a null return address and crashes if we trigger the auto-DMA-complete diff --git a/src/devices/sound/iremga20.cpp b/src/devices/sound/iremga20.cpp index 041ec44241e..ba49eaa75c4 100644 --- a/src/devices/sound/iremga20.cpp +++ b/src/devices/sound/iremga20.cpp @@ -73,7 +73,7 @@ iremga20_device::iremga20_device(const machine_config &mconfig, const char *tag, void iremga20_device::device_start() { - m_stream = stream_alloc(0, 2, clock()/4); + m_stream = stream_alloc_legacy(0, 2, clock()/4); save_item(NAME(m_regs)); for (int i = 0; i < 4; i++) @@ -126,10 +126,10 @@ void iremga20_device::rom_bank_updated() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void iremga20_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void iremga20_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *outL, *outR; diff --git a/src/devices/sound/iremga20.h b/src/devices/sound/iremga20.h index dfe5040f65e..df9942c9ccb 100644 --- a/src/devices/sound/iremga20.h +++ b/src/devices/sound/iremga20.h @@ -36,7 +36,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/k005289.cpp b/src/devices/sound/k005289.cpp index 26d14258406..bf07743f7d3 100644 --- a/src/devices/sound/k005289.cpp +++ b/src/devices/sound/k005289.cpp @@ -74,7 +74,7 @@ void k005289_device::device_start() { /* get stream channels */ m_rate = clock() / CLOCK_DIVIDER; - m_stream = stream_alloc(0, 1, m_rate); + m_stream = stream_alloc_legacy(0, 1, m_rate); /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ m_mixer_buffer = std::make_unique<short[]>(2 * m_rate); @@ -101,10 +101,10 @@ void k005289_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void k005289_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void k005289_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; short *mix; diff --git a/src/devices/sound/k005289.h b/src/devices/sound/k005289.h index 39cac2cc300..a8dc7b1d0b0 100644 --- a/src/devices/sound/k005289.h +++ b/src/devices/sound/k005289.h @@ -26,7 +26,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void make_mixer_table(int voices); diff --git a/src/devices/sound/k007232.cpp b/src/devices/sound/k007232.cpp index 2795053520d..3b35eeb9d5c 100644 --- a/src/devices/sound/k007232.cpp +++ b/src/devices/sound/k007232.cpp @@ -86,7 +86,7 @@ void k007232_device::device_start() for (auto & elem : m_wreg) elem = 0; - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()/128); + m_stream = stream_alloc_legacy(0, 2, clock()/128); save_item(STRUCT_MEMBER(m_channel, vol)); save_item(STRUCT_MEMBER(m_channel, addr)); @@ -206,10 +206,10 @@ void k007232_device::set_bank(int chan_a_bank, int chan_b_bank) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void k007232_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void k007232_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { memset(outputs[0], 0, samples * sizeof(stream_sample_t)); memset(outputs[1], 0, samples * sizeof(stream_sample_t)); diff --git a/src/devices/sound/k007232.h b/src/devices/sound/k007232.h index 72d5e701dc9..e9a4ba255da 100644 --- a/src/devices/sound/k007232.h +++ b/src/devices/sound/k007232.h @@ -37,7 +37,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/k051649.cpp b/src/devices/sound/k051649.cpp index 07df808d42f..0e39a94230a 100644 --- a/src/devices/sound/k051649.cpp +++ b/src/devices/sound/k051649.cpp @@ -71,7 +71,7 @@ void k051649_device::device_start() { // get stream channels m_rate = clock()/16; - m_stream = stream_alloc(0, 1, m_rate); + m_stream = stream_alloc_legacy(0, 1, m_rate); // allocate a buffer to mix into - 1 second's worth should be more than enough m_mixer_buffer.resize(2 * m_rate); @@ -140,10 +140,10 @@ void k051649_device::device_clock_changed() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void k051649_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void k051649_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // zap the contents of the mixer buffer std::fill(m_mixer_buffer.begin(), m_mixer_buffer.end(), 0); diff --git a/src/devices/sound/k051649.h b/src/devices/sound/k051649.h index f69ae00b707..2fda5936685 100644 --- a/src/devices/sound/k051649.h +++ b/src/devices/sound/k051649.h @@ -38,7 +38,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: // Parameters for a channel diff --git a/src/devices/sound/k053260.cpp b/src/devices/sound/k053260.cpp index 181c992f360..ff2356ac600 100644 --- a/src/devices/sound/k053260.cpp +++ b/src/devices/sound/k053260.cpp @@ -115,7 +115,7 @@ void k053260_device::device_start() m_sh1_cb.resolve_safe(); m_sh2_cb.resolve_safe(); - m_stream = stream_alloc( 0, 2, clock() / CLOCKS_PER_SAMPLE ); + m_stream = stream_alloc_legacy( 0, 2, clock() / CLOCKS_PER_SAMPLE ); /* register with the save state system */ save_item(NAME(m_portdata)); @@ -310,10 +310,10 @@ static constexpr s32 MAXOUT = 0x7fff; static constexpr s32 MINOUT = -0x8000; //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void k053260_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void k053260_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { if (m_mode & 2) { @@ -429,7 +429,7 @@ void k053260_device::KDSC_Voice::update_pan_volume() void k053260_device::KDSC_Voice::key_on() { m_position = m_kadpcm ? 1 : 0; // for kadpcm low bit is nybble offset, so must start at 1 due to preincrement - m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update + m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update_legacy m_output = 0; m_playing = true; if (LOG) m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x:%x, loop = %s, %s\n", diff --git a/src/devices/sound/k053260.h b/src/devices/sound/k053260.h index 648fa00cb58..4288b603d5a 100644 --- a/src/devices/sound/k053260.h +++ b/src/devices/sound/k053260.h @@ -42,7 +42,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/k054539.cpp b/src/devices/sound/k054539.cpp index 5fbeaa14b3d..2ed7dc134a2 100644 --- a/src/devices/sound/k054539.cpp +++ b/src/devices/sound/k054539.cpp @@ -105,7 +105,7 @@ void k054539_device::keyoff(int channel) regs[0x22c] &= ~(1 << channel); } -void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void k054539_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { #define VOL_CAP 1.80 @@ -118,9 +118,14 @@ void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t * int16_t *rbase = (int16_t *)ram.get(); if(!(regs[0x22f] & 1)) + { + outputs[0].fill(0); + outputs[1].fill(0); return; + } - for(int sample = 0; sample != samples; sample++) { + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for(int sample = 0; sample != outputs[0].samples(); sample++) { double lval, rval; if(!(flags & DISABLE_REVERB)) lval = rval = rbase[reverb_pos]; @@ -298,8 +303,8 @@ void k054539_device::sound_stream_update(sound_stream &stream, stream_sample_t * } } reverb_pos = (reverb_pos + 1) & 0x1fff; - outputs[0][sample] = int16_t(lval); - outputs[1][sample] = int16_t(rval); + outputs[0].put(sample, stream_buffer::sample_t(lval) * sample_scale); + outputs[1].put(sample, stream_buffer::sample_t(rval) * sample_scale); } } diff --git a/src/devices/sound/k054539.h b/src/devices/sound/k054539.h index ba1c96ffc64..6e4b6c10c8c 100644 --- a/src/devices/sound/k054539.h +++ b/src/devices/sound/k054539.h @@ -67,7 +67,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ks0164.cpp b/src/devices/sound/ks0164.cpp index 8974ddeaa74..5280af611f6 100644 --- a/src/devices/sound/ks0164.cpp +++ b/src/devices/sound/ks0164.cpp @@ -50,7 +50,7 @@ void ks0164_device::device_start() space().install_rom(0, rend, ((1 << 23) - 1) ^ rmask, m_mem_region->base()); } - m_stream = stream_alloc(0, 2, clock()/3/2/2/32); + m_stream = stream_alloc_legacy(0, 2, clock()/3/2/2/32); space().cache(m_mem_cache); m_timer = timer_alloc(0); @@ -368,7 +368,7 @@ u16 ks0164_device::uncomp_8_16(u8 value) return o; } -void ks0164_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ks0164_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for(int sample = 0; sample != samples; sample++) { s32 suml = 0, sumr = 0; diff --git a/src/devices/sound/ks0164.h b/src/devices/sound/ks0164.h index bb654c83cc4..a668753f250 100644 --- a/src/devices/sound/ks0164.h +++ b/src/devices/sound/ks0164.h @@ -23,7 +23,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void device_add_mconfig(machine_config &config) override; virtual space_config_vector memory_space_config() const override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.cpp b/src/devices/sound/l7a1045_l6028_dsp_a.cpp index 1c7cf2631c1..280d12a20d9 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.cpp +++ b/src/devices/sound/l7a1045_l6028_dsp_a.cpp @@ -117,7 +117,7 @@ l7a1045_sound_device::l7a1045_sound_device(const machine_config &mconfig, const void l7a1045_sound_device::device_start() { /* Allocate the stream */ - m_stream = stream_alloc(0, 2, 66150); //clock() / 384); + m_stream = stream_alloc_legacy(0, 2, 66150); //clock() / 384); for (int voice = 0; voice < 32; voice++) { @@ -143,10 +143,10 @@ void l7a1045_sound_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void l7a1045_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void l7a1045_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { /* Clear the buffers */ memset(outputs[0], 0, samples*sizeof(*outputs[0])); diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.h b/src/devices/sound/l7a1045_l6028_dsp_a.h index 06cdd5b7509..bc9c3b5d500 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.h +++ b/src/devices/sound/l7a1045_l6028_dsp_a.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct l7a1045_voice diff --git a/src/devices/sound/lmc1992.cpp b/src/devices/sound/lmc1992.cpp index 84eb7f7c9d7..ad412395d9d 100644 --- a/src/devices/sound/lmc1992.cpp +++ b/src/devices/sound/lmc1992.cpp @@ -171,11 +171,11 @@ void lmc1992_device::device_start() //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void lmc1992_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void lmc1992_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/lmc1992.h b/src/devices/sound/lmc1992.h index 88763628999..cfaffc1f13f 100644 --- a/src/devices/sound/lmc1992.h +++ b/src/devices/sound/lmc1992.h @@ -71,7 +71,7 @@ protected: virtual void device_start() override; // internal callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: inline void execute_command(int addr, int data); diff --git a/src/devices/sound/mas3507d.cpp b/src/devices/sound/mas3507d.cpp index 9fa4eeadbc9..641ec52a06e 100644 --- a/src/devices/sound/mas3507d.cpp +++ b/src/devices/sound/mas3507d.cpp @@ -29,7 +29,7 @@ mas3507d_device::mas3507d_device(const machine_config &mconfig, const char *tag, void mas3507d_device::device_start() { current_rate = 44100; - stream = stream_alloc(0, 2, current_rate); + stream = stream_alloc_legacy(0, 2, current_rate); cb_sample.resolve(); } @@ -290,7 +290,7 @@ void mas3507d_device::mem_write(int bank, uint32_t adr, uint32_t val) case 0x0032f: logerror("MAS3507D: OutputConfig = %05x\n", val); break; case 0x107f8: logerror("MAS3507D: left->left gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); - stream->set_output_gain(0, gain_to_percentage(val)); + set_output_gain(0, gain_to_percentage(val)); break; case 0x107f9: logerror("MAS3507D: left->right gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); @@ -300,7 +300,7 @@ void mas3507d_device::mem_write(int bank, uint32_t adr, uint32_t val) break; case 0x107fb: logerror("MAS3507D: right->right gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); - stream->set_output_gain(1, gain_to_percentage(val)); + set_output_gain(1, gain_to_percentage(val)); break; default: logerror("MAS3507D: %d:%04x = %05x\n", bank, adr, val); break; } @@ -359,7 +359,7 @@ void mas3507d_device::fill_buffer() } } -void mas3507d_device::append_buffer(stream_sample_t **outputs, int &pos, int scount) +void mas3507d_device::append_buffer(stream_sample_t * const *outputs, int &pos, int scount) { if(!sample_count) return; @@ -400,7 +400,7 @@ void mas3507d_device::append_buffer(stream_sample_t **outputs, int &pos, int sco total_frame_count += s1; } -void mas3507d_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int csamples) +void mas3507d_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int csamples) { int pos = 0; diff --git a/src/devices/sound/mas3507d.h b/src/devices/sound/mas3507d.h index 64876cb321b..31410fa576e 100644 --- a/src/devices/sound/mas3507d.h +++ b/src/devices/sound/mas3507d.h @@ -27,7 +27,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: devcb_read16 cb_sample; @@ -63,7 +63,7 @@ private: void reg_write(uint32_t adr, uint32_t val); void fill_buffer(); - void append_buffer(stream_sample_t **outputs, int &pos, int samples); + void append_buffer(stream_sample_t * const *outputs, int &pos, int samples); }; diff --git a/src/devices/sound/mea8000.cpp b/src/devices/sound/mea8000.cpp index ef528309897..4f7fbc453ac 100644 --- a/src/devices/sound/mea8000.cpp +++ b/src/devices/sound/mea8000.cpp @@ -134,7 +134,7 @@ void mea8000_device::device_start() init_tables(); - m_stream = stream_alloc(0, 1, clock() / 60); + m_stream = stream_alloc_legacy(0, 1, clock() / 60); save_item(NAME(m_output)); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mea8000_device::timer_expire),this)); @@ -422,7 +422,7 @@ void mea8000_device::stop_frame() -void mea8000_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mea8000_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int samp = 0; samp < samples; samp++) { diff --git a/src/devices/sound/mea8000.h b/src/devices/sound/mea8000.h index 77c61669721..14cb0384d09 100644 --- a/src/devices/sound/mea8000.h +++ b/src/devices/sound/mea8000.h @@ -29,7 +29,7 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: /* filter coefficients from frequencies */ diff --git a/src/devices/sound/mos6560.cpp b/src/devices/sound/mos6560.cpp index a0121a79e08..05ab0bcd08e 100644 --- a/src/devices/sound/mos6560.cpp +++ b/src/devices/sound/mos6560.cpp @@ -622,7 +622,7 @@ void mos6560_device::sound_start() { int i; - m_channel = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); /* buffer for fastest played sample for 5 second so we have enough data for min 5 second */ m_noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC; @@ -888,10 +888,10 @@ void mos6560_device::device_timer(emu_timer &timer, device_timer_id id, int para } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void mos6560_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mos6560_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i, v; stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/mos6560.h b/src/devices/sound/mos6560.h index ecee2ec3f82..cf657255198 100644 --- a/src/devices/sound/mos6560.h +++ b/src/devices/sound/mos6560.h @@ -124,7 +124,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; inline uint8_t read_videoram(offs_t offset); inline uint8_t read_colorram(offs_t offset); diff --git a/src/devices/sound/mos6581.cpp b/src/devices/sound/mos6581.cpp index 99b3620c228..2fe073a1347 100644 --- a/src/devices/sound/mos6581.cpp +++ b/src/devices/sound/mos6581.cpp @@ -199,7 +199,7 @@ void mos6581_device::device_start() m_read_poty.resolve_safe(0xff); // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); // initialize SID engine m_token->device = this; @@ -235,11 +235,11 @@ void mos6581_device::device_post_load() //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void mos6581_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mos6581_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { m_token->fill_buffer(outputs[0], samples); } diff --git a/src/devices/sound/mos6581.h b/src/devices/sound/mos6581.h index e6d694ae90d..47e5959ef41 100644 --- a/src/devices/sound/mos6581.h +++ b/src/devices/sound/mos6581.h @@ -65,7 +65,7 @@ protected: virtual void device_post_load() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; void save_state(SID6581_t *token); private: diff --git a/src/devices/sound/mos7360.cpp b/src/devices/sound/mos7360.cpp index 09f0a310b45..9105fd656e3 100644 --- a/src/devices/sound/mos7360.cpp +++ b/src/devices/sound/mos7360.cpp @@ -297,7 +297,7 @@ void mos7360_device::device_start() screen().register_screen_bitmap(m_bitmap); // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); // buffer for fastest played sample for 5 second so we have enough data for min 5 second m_noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC; @@ -454,11 +454,11 @@ void mos7360_device::device_timer(emu_timer &timer, device_timer_id id, int para //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void mos7360_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mos7360_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i, v, a; stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/mos7360.h b/src/devices/sound/mos7360.h index 93ec30b2277..7e41bddb7c6 100644 --- a/src/devices/sound/mos7360.h +++ b/src/devices/sound/mos7360.h @@ -110,7 +110,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; inline void set_interrupt(int mask); inline void clear_interrupt(int mask); diff --git a/src/devices/sound/msm5205.cpp b/src/devices/sound/msm5205.cpp index 718f82530e7..9e889503ed9 100644 --- a/src/devices/sound/msm5205.cpp +++ b/src/devices/sound/msm5205.cpp @@ -98,7 +98,7 @@ void msm5205_device::device_start() compute_tables(); /* stream system initialize */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()); + m_stream = stream_alloc(0, 1, clock()); m_vck_timer = timer_alloc(TIMER_VCK); m_capture_timer = timer_alloc(TIMER_ADPCM_CAPTURE); @@ -360,23 +360,20 @@ void msm5205_device::device_clock_changed() // sound_stream_update - handle a stream update //------------------------------------------------- -void msm5205_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void msm5205_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; + auto &output = outputs[0]; /* if this voice is active */ - if(m_signal) + if (m_signal) { + constexpr stream_buffer::sample_t sample_scale = 1.0 / double(1 << 12); const int dac_mask = (m_dac_bits >= 12) ? 0 : (1 << (12 - m_dac_bits)) - 1; - short val = (m_signal & ~dac_mask) * 16; // 10 bit DAC - while (samples) - { - *buffer++ = val; - samples--; - } + stream_buffer::sample_t val = stream_buffer::sample_t(m_signal & ~dac_mask) * sample_scale; + output.fill(val); } else - memset(buffer, 0, samples * sizeof(*buffer)); + output.fill(0); } @@ -407,8 +404,8 @@ void msm6585_device::device_timer(emu_timer &timer, device_timer_id id, int para // sound_stream_update - handle a stream update //------------------------------------------------- -void msm6585_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void msm6585_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // should this be different? - msm5205_device::sound_stream_update(stream, inputs, outputs,samples); + msm5205_device::sound_stream_update(stream, inputs, outputs); } diff --git a/src/devices/sound/msm5205.h b/src/devices/sound/msm5205.h index 87df5e870f8..02b8bc3746c 100644 --- a/src/devices/sound/msm5205.h +++ b/src/devices/sound/msm5205.h @@ -65,7 +65,7 @@ protected: void update_adpcm(); // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void compute_tables(); virtual int get_prescaler() const; @@ -108,7 +108,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; diff --git a/src/devices/sound/msm5232.cpp b/src/devices/sound/msm5232.cpp index 9a4317491e3..da8fc499dc7 100644 --- a/src/devices/sound/msm5232.cpp +++ b/src/devices/sound/msm5232.cpp @@ -34,7 +34,7 @@ void msm5232_device::device_start() init(clock(), rate); - m_stream = machine().sound().stream_alloc(*this, 0, 11, rate); + m_stream = stream_alloc_legacy(0, 11, rate); /* register with the save state system */ save_item(NAME(m_EN_out16)); @@ -725,10 +725,10 @@ void msm5232_device::set_clock(int clock) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void msm5232_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void msm5232_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buf1 = outputs[0]; stream_sample_t *buf2 = outputs[1]; diff --git a/src/devices/sound/msm5232.h b/src/devices/sound/msm5232.h index 2dd3997a346..364f944353b 100644 --- a/src/devices/sound/msm5232.h +++ b/src/devices/sound/msm5232.h @@ -26,7 +26,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct VOICE { diff --git a/src/devices/sound/multipcm.cpp b/src/devices/sound/multipcm.cpp index 6698792fbe1..c4a5892990f 100644 --- a/src/devices/sound/multipcm.cpp +++ b/src/devices/sound/multipcm.cpp @@ -450,22 +450,22 @@ void multipcm_device::write(offs_t offset, uint8_t data) DEFINE_DEVICE_TYPE(MULTIPCM, multipcm_device, "ymw258f", "Yamaha YMW-258-F") -multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, MULTIPCM, tag, owner, clock), - device_sound_interface(mconfig, *this), - device_rom_interface(mconfig, *this), - m_stream(nullptr), - m_slots(nullptr), - m_cur_slot(0), - m_address(0), - m_rate(0), - m_attack_step(nullptr), - m_decay_release_step(nullptr), - m_freq_step_table(nullptr), - m_left_pan_table(nullptr), - m_right_pan_table(nullptr), - m_linear_to_exp_volume(nullptr), - m_total_level_steps(nullptr) +multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, MULTIPCM, tag, owner, clock), + device_sound_interface(mconfig, *this), + device_rom_interface(mconfig, *this), + m_stream(nullptr), + m_slots(nullptr), + m_cur_slot(0), + m_address(0), + m_rate(0), + m_attack_step(nullptr), + m_decay_release_step(nullptr), + m_freq_step_table(nullptr), + m_left_pan_table(nullptr), + m_right_pan_table(nullptr), + m_linear_to_exp_volume(nullptr), + m_total_level_steps(nullptr) { } @@ -479,7 +479,7 @@ void multipcm_device::device_start() const float clock_divider = 180.0f; m_rate = (float)clock() / clock_divider; - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_rate); + m_stream = stream_alloc_legacy(0, 2, m_rate); // Volume + pan table m_left_pan_table = make_unique_clear<int32_t[]>(0x800); @@ -677,10 +677,10 @@ void multipcm_device::dump_sample(slot_t &slot) #endif //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void multipcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int32_t samples) +void multipcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int32_t samples) { stream_sample_t *datap[2]; diff --git a/src/devices/sound/multipcm.h b/src/devices/sound/multipcm.h index 7a4bc55fc2c..4308703b9dc 100644 --- a/src/devices/sound/multipcm.h +++ b/src/devices/sound/multipcm.h @@ -29,7 +29,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/n63701x.cpp b/src/devices/sound/n63701x.cpp index 7ba7eb2af7f..f9dea8e4509 100644 --- a/src/devices/sound/n63701x.cpp +++ b/src/devices/sound/n63701x.cpp @@ -46,7 +46,7 @@ namco_63701x_device::namco_63701x_device(const machine_config &mconfig, const ch void namco_63701x_device::device_start() { - m_stream = stream_alloc(0, 2, clock()/1000); + m_stream = stream_alloc_legacy(0, 2, clock()/1000); for (int i = 0; i < 2; i++) { @@ -61,10 +61,10 @@ void namco_63701x_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void namco_63701x_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_63701x_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int ch; diff --git a/src/devices/sound/n63701x.h b/src/devices/sound/n63701x.h index 0bb48b5afc8..4992065d7bf 100644 --- a/src/devices/sound/n63701x.h +++ b/src/devices/sound/n63701x.h @@ -25,7 +25,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct voice_63701x diff --git a/src/devices/sound/namco.cpp b/src/devices/sound/namco.cpp index 3eeb77617bc..830f3713b45 100644 --- a/src/devices/sound/namco.cpp +++ b/src/devices/sound/namco.cpp @@ -43,6 +43,8 @@ /* a position of waveform sample */ #define WAVEFORM_POSITION(n) (((n) >> m_f_fracbits) & 0x1f) +static constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + DEFINE_DEVICE_TYPE(NAMCO, namco_device, "namco", "Namco") DEFINE_DEVICE_TYPE(NAMCO_15XX, namco_15xx_device, "namco_15xx", "Namco 15xx") DEFINE_DEVICE_TYPE(NAMCO_CUS30, namco_cus30_device, "namco_cus30", "Namco CUS30") @@ -99,9 +101,9 @@ void namco_audio_device::device_start() /* get stream channels */ if (m_stereo) - m_stream = machine().sound().stream_alloc(*this, 0, 2, 192000); + m_stream = stream_alloc(0, 2, 192000); else - m_stream = machine().sound().stream_alloc(*this, 0, 1, 192000); + m_stream = stream_alloc(0, 1, 192000); /* start with sound enabled, many games don't have a sound enable register */ m_sound_enable = true; @@ -233,11 +235,11 @@ void namco_audio_device::build_decoded_waveform(uint8_t *rgnbase) /* generate sound by oversampling */ -uint32_t namco_audio_device::namco_update_one(stream_sample_t *buffer, int length, const int16_t *wave, uint32_t counter, uint32_t freq) +uint32_t namco_audio_device::namco_update_one(write_stream_view &buffer, const int16_t *wave, uint32_t counter, uint32_t freq) { - while (length-- > 0) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { - *buffer++ += wave[WAVEFORM_POSITION(counter)]; + buffer.add(sampindex, stream_buffer::sample_t(wave[WAVEFORM_POSITION(counter)]) * sample_scale); counter += freq; } @@ -655,25 +657,23 @@ void namco_15xx_device::sharedram_w(offs_t offset, uint8_t data) // sound_stream_update - handle a stream update //------------------------------------------------- -void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_audio_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { if (m_stereo) { - sound_channel *voice; - /* zap the contents of the buffers */ - memset(outputs[0], 0, samples * sizeof(*outputs[0])); - memset(outputs[1], 0, samples * sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); /* if no sound, we're done */ if (!m_sound_enable) return; /* loop over each voice and add its contribution */ - for (voice = m_channel_list; voice < m_last_channel; voice++) + for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) { - stream_sample_t *lmix = outputs[0]; - stream_sample_t *rmix = outputs[1]; + auto &lmix = outputs[0]; + auto &rmix = outputs[1]; int lv = voice->volume[0]; int rv = voice->volume[1]; @@ -693,19 +693,19 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample int i; /* add our contribution */ - for (i = 0; i < samples; i++) + for (i = 0; i < lmix.samples(); i++) { int cnt; if (voice->noise_state) { - *lmix++ += l_noise_data; - *rmix++ += r_noise_data; + lmix.add(i, stream_buffer::sample_t(l_noise_data) * sample_scale); + rmix.add(i, stream_buffer::sample_t(r_noise_data) * sample_scale); } else { - *lmix++ -= l_noise_data; - *rmix++ -= r_noise_data; + lmix.add(i, stream_buffer::sample_t(-l_noise_data) * sample_scale); + rmix.add(i, stream_buffer::sample_t(-r_noise_data) * sample_scale); } if (hold) @@ -746,7 +746,7 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32]; /* generate sound into the buffer */ - c = namco_update_one(lmix, samples, lw, voice->counter, voice->frequency); + c = namco_update_one(lmix, lw, voice->counter, voice->frequency); } /* only update if we have non-zero right volume */ @@ -755,7 +755,7 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32]; /* generate sound into the buffer */ - c = namco_update_one(rmix, samples, rw, voice->counter, voice->frequency); + c = namco_update_one(rmix, rw, voice->counter, voice->frequency); } /* update the counter for this voice */ @@ -768,9 +768,9 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample { sound_channel *voice; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; /* zap the contents of the buffer */ - memset(buffer, 0, samples * sizeof(*buffer)); + buffer.fill(0); /* if no sound, we're done */ if (!m_sound_enable) @@ -779,81 +779,80 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample /* loop over each voice and add its contribution */ for (voice = m_channel_list; voice < m_last_channel; voice++) { - stream_sample_t *mix = buffer; int v = voice->volume[0]; - if (voice->noise_sw) - { + if (voice->noise_sw) + { int f = voice->frequency & 0xff; /* only update if we have non-zero volume and frequency */ if (v && f) { - int hold_time = 1 << (m_f_fracbits - 16); - int hold = voice->noise_hold; - uint32_t delta = f << 4; - uint32_t c = voice->noise_counter; - int16_t noise_data = OUTPUT_LEVEL(0x07 * (v >> 1)); - int i; - - /* add our contribution */ - for (i = 0; i < samples; i++) + int hold_time = 1 << (m_f_fracbits - 16); + int hold = voice->noise_hold; + uint32_t delta = f << 4; + uint32_t c = voice->noise_counter; + int16_t noise_data = OUTPUT_LEVEL(0x07 * (v >> 1)); + int i; + + /* add our contribution */ + for (i = 0; i < buffer.samples(); i++) + { + int cnt; + + if (voice->noise_state) + buffer.add(i, stream_buffer::sample_t(noise_data) * sample_scale); + else + buffer.add(i, stream_buffer::sample_t(-noise_data) * sample_scale); + + if (hold) { - int cnt; - - if (voice->noise_state) - *mix++ += noise_data; - else - *mix++ -= noise_data; - - if (hold) - { - hold--; - continue; - } - - hold = hold_time; - - c += delta; - cnt = (c >> 12); - c &= (1 << 12) - 1; - for( ;cnt > 0; cnt--) - { - if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1; - if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000; - voice->noise_seed >>= 1; - } + hold--; + continue; } - /* update the counter and hold time for this voice */ - voice->noise_counter = c; - voice->noise_hold = hold; + hold = hold_time; + + c += delta; + cnt = (c >> 12); + c &= (1 << 12) - 1; + for( ;cnt > 0; cnt--) + { + if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1; + if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000; + voice->noise_seed >>= 1; + } } + + /* update the counter and hold time for this voice */ + voice->noise_counter = c; + voice->noise_hold = hold; } - else - { + } + else + { /* only update if we have non-zero volume and frequency */ if (v && voice->frequency) { const int16_t *w = &m_waveform[v][voice->waveform_select * 32]; /* generate sound into buffer and update the counter for this voice */ - voice->counter = namco_update_one(mix, samples, w, voice->counter, voice->frequency); + voice->counter = namco_update_one(buffer, w, voice->counter, voice->frequency); } } } } } -void namco_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - namco_audio_device::sound_stream_update(stream, inputs, outputs, samples); + namco_audio_device::sound_stream_update(stream, inputs, outputs); } -void namco_15xx_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_15xx_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - namco_audio_device::sound_stream_update(stream, inputs, outputs, samples); + namco_audio_device::sound_stream_update(stream, inputs, outputs); } -void namco_cus30_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_cus30_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - namco_audio_device::sound_stream_update(stream, inputs, outputs, samples); + namco_audio_device::sound_stream_update(stream, inputs, outputs); } diff --git a/src/devices/sound/namco.h b/src/devices/sound/namco.h index 770e0e287c8..6b3cee6a1f5 100644 --- a/src/devices/sound/namco.h +++ b/src/devices/sound/namco.h @@ -44,7 +44,7 @@ protected: void build_decoded_waveform( uint8_t *rgnbase ); void update_namco_waveform(int offset, uint8_t data); - uint32_t namco_update_one(stream_sample_t *buffer, int length, const int16_t *wave, uint32_t counter, uint32_t freq); + uint32_t namco_update_one(write_stream_view &buffer, const int16_t *wave, uint32_t counter, uint32_t freq); /* waveform region */ optional_region_ptr<uint8_t> m_wave_ptr; @@ -69,7 +69,7 @@ protected: /* decoded waveform table */ int16_t *m_waveform[MAX_VOLUME]; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; class namco_device : public namco_audio_device @@ -85,7 +85,7 @@ public: void polepos_sound_w(offs_t offset, uint8_t data); protected: - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; @@ -99,7 +99,7 @@ public: void sharedram_w(offs_t offset, uint8_t data); protected: - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; @@ -115,7 +115,7 @@ public: void pacman_sound_w(offs_t offset, uint8_t data); protected: - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; }; diff --git a/src/devices/sound/namco_163.cpp b/src/devices/sound/namco_163.cpp index 11ff6ed1eb5..153b0bfe042 100644 --- a/src/devices/sound/namco_163.cpp +++ b/src/devices/sound/namco_163.cpp @@ -34,7 +34,7 @@ namco_163_sound_device::namco_163_sound_device(const machine_config &mconfig, co void namco_163_sound_device::device_start() { m_ram = make_unique_clear<u8[]>(0x80); - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 15); + m_stream = stream_alloc_legacy(0, 1, clock() / 15); save_pointer(NAME(m_ram), 0x80); save_item(NAME(m_reg_addr)); @@ -143,7 +143,7 @@ u8 namco_163_sound_device::data_r() } -void namco_163_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void namco_163_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { std::fill_n(&outputs[0][0], samples, 0); diff --git a/src/devices/sound/namco_163.h b/src/devices/sound/namco_163.h index 1256884242b..74d2ceacb68 100644 --- a/src/devices/sound/namco_163.h +++ b/src/devices/sound/namco_163.h @@ -34,7 +34,7 @@ protected: // internals inline s8 get_sample(u16 addr); - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; }; DECLARE_DEVICE_TYPE(NAMCO_163, namco_163_sound_device) diff --git a/src/devices/sound/nes_apu.cpp b/src/devices/sound/nes_apu.cpp index 3f5c7787a93..1e79304fb3a 100644 --- a/src/devices/sound/nes_apu.cpp +++ b/src/devices/sound/nes_apu.cpp @@ -134,7 +134,7 @@ void nesapu_device::calculate_rates() if (m_stream != nullptr) m_stream->set_sample_rate(rate); else - m_stream = machine().sound().stream_alloc(*this, 0, 1, rate); + m_stream = stream_alloc_legacy(0, 1, rate); } //------------------------------------------------- @@ -725,13 +725,14 @@ void nesapu_device::write(offs_t address, u8 value) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void nesapu_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void nesapu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int accum; - memset( outputs[0], 0, samples*sizeof(*outputs[0]) ); + stream_sample_t *output = outputs[0]; + memset( output, 0, samples*sizeof(*output) ); while (samples--) { @@ -747,6 +748,6 @@ void nesapu_device::sound_stream_update(sound_stream &stream, stream_sample_t ** else if (accum < -128) accum = -128; - *(outputs[0]++)=accum<<8; + *output++=accum<<8; } } diff --git a/src/devices/sound/nes_apu.h b/src/devices/sound/nes_apu.h index 731bf565940..c0e2e02244b 100644 --- a/src/devices/sound/nes_apu.h +++ b/src/devices/sound/nes_apu.h @@ -60,7 +60,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: /* GLOBAL CONSTANTS */ diff --git a/src/devices/sound/nile.cpp b/src/devices/sound/nile.cpp index 80023870593..aeaeeaca59c 100644 --- a/src/devices/sound/nile.cpp +++ b/src/devices/sound/nile.cpp @@ -68,7 +68,7 @@ nile_device::nile_device(const machine_config &mconfig, const char *tag, device_ void nile_device::device_start() { - m_stream = stream_alloc(0, 2, 44100); + m_stream = stream_alloc_legacy(0, 2, 44100); save_item(NAME(m_sound_regs)); save_item(NAME(m_vpos)); save_item(NAME(m_frac)); @@ -78,11 +78,11 @@ void nile_device::device_start() //------------------------------------------------- -// sound_stream_update - handle update requests +// sound_stream_update_legacy - handle update requests // for our sound stream //------------------------------------------------- -void nile_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void nile_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { uint8_t *sound_ram = &m_sound_ram[0]; int v, i, snum; diff --git a/src/devices/sound/nile.h b/src/devices/sound/nile.h index 169c90c9e4d..a87fb875c11 100644 --- a/src/devices/sound/nile.h +++ b/src/devices/sound/nile.h @@ -23,7 +23,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; public: void nile_snd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); diff --git a/src/devices/sound/okim6258.cpp b/src/devices/sound/okim6258.cpp index 639c6fde50d..5f063f4cd87 100644 --- a/src/devices/sound/okim6258.cpp +++ b/src/devices/sound/okim6258.cpp @@ -114,7 +114,7 @@ void okim6258_device::device_start() m_divider = dividers[m_start_divider]; - m_stream = stream_alloc(0, 1, clock()/m_divider); + m_stream = stream_alloc_legacy(0, 1, clock()/m_divider); m_signal = -2; m_step = 0; @@ -138,10 +138,10 @@ void okim6258_device::device_reset() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void okim6258_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void okim6258_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/okim6258.h b/src/devices/sound/okim6258.h index 57f764d4eb7..c8397b998bf 100644 --- a/src/devices/sound/okim6258.h +++ b/src/devices/sound/okim6258.h @@ -47,7 +47,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: void state_save_register(); diff --git a/src/devices/sound/okim6295.cpp b/src/devices/sound/okim6295.cpp index 63a039a0b32..c3aee26e52e 100644 --- a/src/devices/sound/okim6295.cpp +++ b/src/devices/sound/okim6295.cpp @@ -56,24 +56,24 @@ DEFINE_DEVICE_TYPE(OKIM6295, okim6295_device, "okim6295", "OKI MSM6295 ADPCM") // volume lookup table. The manual lists only 9 steps, ~3dB per step. Given the dB values, // that seems to map to a 5-bit volume control. Any volume parameter beyond the 9th index // results in silent playback. -const uint8_t okim6295_device::s_volume_table[16] = +const stream_buffer::sample_t okim6295_device::s_volume_table[16] = { - 0x20, // 0 dB - 0x16, // -3.2 dB - 0x10, // -6.0 dB - 0x0b, // -9.2 dB - 0x08, // -12.0 dB - 0x06, // -14.5 dB - 0x04, // -18.0 dB - 0x03, // -20.5 dB - 0x02, // -24.0 dB - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, + stream_buffer::sample_t(0x20) / stream_buffer::sample_t(0x20), // 0 dB + stream_buffer::sample_t(0x16) / stream_buffer::sample_t(0x20), // -3.2 dB + stream_buffer::sample_t(0x10) / stream_buffer::sample_t(0x20), // -6.0 dB + stream_buffer::sample_t(0x0b) / stream_buffer::sample_t(0x20), // -9.2 dB + stream_buffer::sample_t(0x08) / stream_buffer::sample_t(0x20), // -12.0 dB + stream_buffer::sample_t(0x06) / stream_buffer::sample_t(0x20), // -14.5 dB + stream_buffer::sample_t(0x04) / stream_buffer::sample_t(0x20), // -18.0 dB + stream_buffer::sample_t(0x03) / stream_buffer::sample_t(0x20), // -20.5 dB + stream_buffer::sample_t(0x02) / stream_buffer::sample_t(0x20), // -24.0 dB + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), + stream_buffer::sample_t(0x00) / stream_buffer::sample_t(0x20), }; @@ -118,7 +118,7 @@ void okim6295_device::device_start() // create the stream int divisor = m_pin7_state ? 132 : 165; - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / divisor); + m_stream = stream_alloc(0, 1, clock() / divisor); save_item(NAME(m_command)); save_item(NAME(m_pin7_state)); @@ -171,18 +171,18 @@ void okim6295_device::device_clock_changed() //------------------------------------------------- -// stream_generate - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- -void okim6295_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void okim6295_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // reset the output stream - memset(outputs[0], 0, samples * sizeof(*outputs[0])); + outputs[0].fill(0); // iterate over voices and accumulate sample data for (auto & elem : m_voice) - elem.generate_adpcm(*this, outputs[0], samples); + elem.generate_adpcm(*this, outputs[0]); } @@ -337,21 +337,22 @@ okim6295_device::okim_voice::okim_voice() // add them to an output stream //------------------------------------------------- -void okim6295_device::okim_voice::generate_adpcm(device_rom_interface &rom, stream_sample_t *buffer, int samples) +void okim6295_device::okim_voice::generate_adpcm(device_rom_interface &rom, write_stream_view &buffer) { // skip if not active if (!m_playing) return; // loop while we still have samples to generate - while (samples-- != 0) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 2048.0; + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { // fetch the next sample byte int nibble = rom.read_byte(m_base_offset + m_sample / 2) >> (((m_sample & 1) << 2) ^ 4); // output to the buffer, scaling by the volume - // signal in range -2048..2047, volume in range 2..32 => signal * volume / 2 in range -32768..32767 - *buffer++ += m_adpcm.clock(nibble) * m_volume / 2; + // signal in range -2048..2047 + buffer.add(sampindex, m_adpcm.clock(nibble) * sample_scale * m_volume); // next! if (++m_sample >= m_count) diff --git a/src/devices/sound/okim6295.h b/src/devices/sound/okim6295.h index ee7c38f03c1..29f0a17f1a1 100644 --- a/src/devices/sound/okim6295.h +++ b/src/devices/sound/okim6295.h @@ -60,7 +60,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -70,14 +70,14 @@ protected: { public: okim_voice(); - void generate_adpcm(device_rom_interface &rom, stream_sample_t *buffer, int samples); + void generate_adpcm(device_rom_interface &rom, write_stream_view &buffer); - oki_adpcm_state m_adpcm; // current ADPCM state + oki_adpcm_state m_adpcm; // current ADPCM state bool m_playing; - offs_t m_base_offset; // pointer to the base memory location - uint32_t m_sample; // current sample number - uint32_t m_count; // total samples to play - int8_t m_volume; // output volume + offs_t m_base_offset; // pointer to the base memory location + uint32_t m_sample; // current sample number + uint32_t m_count; // total samples to play + stream_buffer::sample_t m_volume; // output volume }; // configuration state @@ -86,12 +86,12 @@ protected: // internal state static constexpr int OKIM6295_VOICES = 4; - okim_voice m_voice[OKIM6295_VOICES]; + okim_voice m_voice[OKIM6295_VOICES]; int32_t m_command; - sound_stream * m_stream; + sound_stream * m_stream; uint8_t m_pin7_state; - static const uint8_t s_volume_table[16]; + static const stream_buffer::sample_t s_volume_table[16]; }; diff --git a/src/devices/sound/okim6376.cpp b/src/devices/sound/okim6376.cpp index 76ee6a5f0a7..3cb3e6fc17b 100644 --- a/src/devices/sound/okim6376.cpp +++ b/src/devices/sound/okim6376.cpp @@ -169,7 +169,7 @@ void okim6376_device::device_start() m_ch2_update = 0; m_st_pulses = 0; /* generate the name and create the stream */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / m_divisor); + m_stream = stream_alloc_legacy(0, 1, get_sample_rate()); /* initialize the voices */ for (voice = 0; voice < OKIM6376_VOICES; voice++) @@ -252,6 +252,18 @@ offs_t okim6650_device::get_start_position(int channel) } +u32 okim6376_device::get_sample_rate() +{ + return clock() / m_divisor; +} + +u32 okim6650_device::get_sample_rate() +{ + return clock() / 64 / m_divisor; +} + + + void okim6376_device::oki_process(int channel, int command) { /* if a command is pending, process the second half */ @@ -433,12 +445,7 @@ void okim6376_device::okim6376_state_save_register() void okim6376_device::device_clock_changed() { - m_stream->set_sample_rate(clock() / m_divisor); -} - -void okim6650_device::device_clock_changed() -{ - m_stream->set_sample_rate(clock() / 64 / m_divisor); + m_stream->set_sample_rate(get_sample_rate()); } @@ -571,10 +578,10 @@ void okim6376_device::write(uint8_t data) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void okim6376_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void okim6376_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i; diff --git a/src/devices/sound/okim6376.h b/src/devices/sound/okim6376.h index 5a73bae88e3..83be973fadf 100644 --- a/src/devices/sound/okim6376.h +++ b/src/devices/sound/okim6376.h @@ -32,12 +32,13 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; virtual offs_t get_start_position(int channel); + virtual u32 get_sample_rate(); /* struct describing a single playing ADPCM voice */ struct ADPCMVoice @@ -88,10 +89,8 @@ public: DECLARE_WRITE_LINE_MEMBER( cmd_w ); protected: - // device-level overrides - virtual void device_clock_changed() override; - virtual offs_t get_start_position(int channel) override; + virtual u32 get_sample_rate() override; }; DECLARE_DEVICE_TYPE(OKIM6376, okim6376_device) diff --git a/src/devices/sound/okim9810.cpp b/src/devices/sound/okim9810.cpp index 78717fd9ae9..a28cfb1af79 100644 --- a/src/devices/sound/okim9810.cpp +++ b/src/devices/sound/okim9810.cpp @@ -112,7 +112,7 @@ okim9810_device::okim9810_device(const machine_config &mconfig, const char *tag, void okim9810_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()); + m_stream = stream_alloc_legacy(0, 2, clock()); // save state stuff save_item(NAME(m_TMP_register)); @@ -214,7 +214,7 @@ void okim9810_device::rom_bank_updated() // our sound stream //------------------------------------------------- -void okim9810_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void okim9810_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // reset the output streams memset(outputs[0], 0, samples * sizeof(*outputs[0])); @@ -613,7 +613,7 @@ okim9810_device::okim_voice::okim_voice() //------------------------------------------------- void okim9810_device::okim_voice::generate_audio(device_rom_interface &rom, - stream_sample_t **buffers, + stream_sample_t * const *buffers, int samples, const uint8_t global_volume, const uint8_t filter_type) diff --git a/src/devices/sound/okim9810.h b/src/devices/sound/okim9810.h index b5c8d566de0..dfb4cd047aa 100644 --- a/src/devices/sound/okim9810.h +++ b/src/devices/sound/okim9810.h @@ -87,7 +87,7 @@ protected: virtual void device_clock_changed() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; @@ -98,7 +98,7 @@ protected: public: okim_voice(); void generate_audio(device_rom_interface &rom, - stream_sample_t **buffers, + stream_sample_t * const *buffers, int samples, const uint8_t global_volume, const uint8_t filter_type); diff --git a/src/devices/sound/pcd3311.cpp b/src/devices/sound/pcd3311.cpp index d332caa3400..deae4f61062 100644 --- a/src/devices/sound/pcd3311.cpp +++ b/src/devices/sound/pcd3311.cpp @@ -48,10 +48,10 @@ void pcd3311_device::device_start() //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void pcd3311_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void pcd3311_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/pcd3311.h b/src/devices/sound/pcd3311.h index 25c5c630fc6..f56d63633ba 100644 --- a/src/devices/sound/pcd3311.h +++ b/src/devices/sound/pcd3311.h @@ -48,7 +48,7 @@ protected: virtual void device_start() override; // internal callbacks - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: int m_a0; diff --git a/src/devices/sound/pokey.cpp b/src/devices/sound/pokey.cpp index 3b174c22766..f749afad2ae 100644 --- a/src/devices/sound/pokey.cpp +++ b/src/devices/sound/pokey.cpp @@ -677,14 +677,13 @@ void pokey_device::step_one_clock(void) } //------------------------------------------------- -// stream_generate - handle update requests for +// sound_stream_update - handle update requests for // our sound stream //------------------------------------------------- - -void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void pokey_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; if (m_output_type == LEGACY_LINEAR) { @@ -693,26 +692,21 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i out += ((m_out_raw >> (4*i)) & 0x0f); out *= POKEY_DEFAULT_GAIN; out = (out > 0x7fff) ? 0x7fff : out; - while( samples > 0 ) - { - *buffer++ = out; - samples--; - } + stream_buffer::sample_t outsamp = out * stream_buffer::sample_t(1.0 / 32768.0); + buffer.fill(outsamp); } else if (m_output_type == RC_LOWPASS) { double rTot = m_voltab[m_out_raw]; - double V0 = rTot / (rTot+m_r_pullup) * m_v_ref / 5.0 * 32767.0; + double V0 = rTot / (rTot+m_r_pullup) * m_v_ref / 5.0; double mult = (m_cap == 0.0) ? 1.0 : 1.0 - exp(-(rTot + m_r_pullup) / (m_cap * m_r_pullup * rTot) * m_clock_period.as_double()); - while( samples > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { /* store sum of output signals into the buffer */ m_out_filter += (V0 - m_out_filter) * mult; - *buffer++ = m_out_filter; - samples--; - + buffer.put(sampindex, m_out_filter); } } else if (m_output_type == OPAMP_C_TO_GROUND) @@ -727,15 +721,8 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i * It is approximated by eliminating m_v_ref ( -1.0 term) */ - double V0 = ((rTot+m_r_pullup) / rTot - 1.0) * m_v_ref / 5.0 * 32767.0; - - while( samples > 0 ) - { - /* store sum of output signals into the buffer */ - *buffer++ = V0; - samples--; - - } + double V0 = ((rTot+m_r_pullup) / rTot - 1.0) * m_v_ref / 5.0; + buffer.fill(V0); } else if (m_output_type == OPAMP_LOW_PASS) { @@ -744,25 +731,19 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i * It is approximated by not adding in VRef below. */ - double V0 = (m_r_pullup / rTot) * m_v_ref / 5.0 * 32767.0; + double V0 = (m_r_pullup / rTot) * m_v_ref / 5.0; double mult = (m_cap == 0.0) ? 1.0 : 1.0 - exp(-1.0 / (m_cap * m_r_pullup) * m_clock_period.as_double()); - while( samples > 0 ) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { /* store sum of output signals into the buffer */ m_out_filter += (V0 - m_out_filter) * mult; - *buffer++ = m_out_filter /* + m_v_ref */; // see above - samples--; + buffer.put(sampindex, m_out_filter); } } else if (m_output_type == DISCRETE_VAR_R) { - int32_t out = m_voltab[m_out_raw]; - while( samples > 0 ) - { - *buffer++ = out; - samples--; - } + buffer.fill(m_voltab[m_out_raw]); } } diff --git a/src/devices/sound/pokey.h b/src/devices/sound/pokey.h index 47ad6519ab8..0717429aff3 100644 --- a/src/devices/sound/pokey.h +++ b/src/devices/sound/pokey.h @@ -193,7 +193,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void execute_run() override; @@ -306,7 +306,7 @@ private: uint32_t m_poly5[0x1f]; uint32_t m_poly9[0x1ff]; uint32_t m_poly17[0x1ffff]; - uint32_t m_voltab[0x10000]; + stream_buffer::sample_t m_voltab[0x10000]; output_type m_output_type; double m_r_pullup; diff --git a/src/devices/sound/qs1000.cpp b/src/devices/sound/qs1000.cpp index 0fd23945a2e..5674ab6db18 100644 --- a/src/devices/sound/qs1000.cpp +++ b/src/devices/sound/qs1000.cpp @@ -229,7 +229,7 @@ void qs1000_device::device_start() // The QS1000 operates at 24MHz. Creating a stream at that rate // would be overkill so we opt for a fraction of that rate which // gives reasonable results - m_stream = stream_alloc(0, 2, clock() / 32); + m_stream = stream_alloc_legacy(0, 2, clock() / 32); // Resolve CPU port callbacks m_in_p1_cb.resolve_safe(0); @@ -466,9 +466,9 @@ void qs1000_device::wave_w(offs_t offset, uint8_t data) //------------------------------------------------- -// sound_stream_update - +// sound_stream_update_legacy - //------------------------------------------------- -void qs1000_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void qs1000_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // Rset the output stream memset(outputs[0], 0x0, samples * sizeof(*outputs[0])); diff --git a/src/devices/sound/qs1000.h b/src/devices/sound/qs1000.h index d8e5fa8c545..0c16e69b193 100644 --- a/src/devices/sound/qs1000.h +++ b/src/devices/sound/qs1000.h @@ -73,7 +73,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/qsound.cpp b/src/devices/sound/qsound.cpp index 05410b73c6c..232e367f1d2 100644 --- a/src/devices/sound/qsound.cpp +++ b/src/devices/sound/qsound.cpp @@ -207,7 +207,7 @@ void qsound_device::device_add_mconfig(machine_config &config) void qsound_device::device_start() { // hope we get good synchronisation between the DSP and the sound system - m_stream = stream_alloc(0, 2, clock() / 2 / 1248); + m_stream = stream_alloc_legacy(0, 2, clock() / 2 / 1248); // save DSP communication state save_item(NAME(m_rom_bank)); @@ -251,10 +251,10 @@ void qsound_device::device_reset() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void qsound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void qsound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { std::fill_n(outputs[0], samples, m_samples[0]); std::fill_n(outputs[1], samples, m_samples[1]); diff --git a/src/devices/sound/qsound.h b/src/devices/sound/qsound.h index 401991c6a59..ac0a1053ffe 100644 --- a/src/devices/sound/qsound.h +++ b/src/devices/sound/qsound.h @@ -32,7 +32,7 @@ protected: virtual void device_reset() override; // device_sound_interface implementation - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface implementation virtual void rom_bank_updated() override; diff --git a/src/devices/sound/qsoundhle.cpp b/src/devices/sound/qsoundhle.cpp index ef99f0ee837..9ff99ee8cab 100644 --- a/src/devices/sound/qsoundhle.cpp +++ b/src/devices/sound/qsoundhle.cpp @@ -64,7 +64,7 @@ void qsound_hle_device::rom_bank_updated() void qsound_hle_device::device_start() { - m_stream = stream_alloc(0, 2, clock() / 2 / 1248); // DSP program uses 1248 machine cycles per iteration + m_stream = stream_alloc_legacy(0, 2, clock() / 2 / 1248); // DSP program uses 1248 machine cycles per iteration init_register_map(); @@ -158,10 +158,10 @@ void qsound_hle_device::device_reset() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void qsound_hle_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void qsound_hle_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // Clear the buffers std::fill_n(outputs[0], samples, 0); diff --git a/src/devices/sound/qsoundhle.h b/src/devices/sound/qsoundhle.h index 6c9872fcc9d..23b92738b9b 100644 --- a/src/devices/sound/qsoundhle.h +++ b/src/devices/sound/qsoundhle.h @@ -30,7 +30,7 @@ protected: virtual void device_reset() override; // device_sound_interface implementation - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface implementation virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rf5c400.cpp b/src/devices/sound/rf5c400.cpp index d61ccb65337..b8de150f7f6 100644 --- a/src/devices/sound/rf5c400.cpp +++ b/src/devices/sound/rf5c400.cpp @@ -180,7 +180,7 @@ void rf5c400_device::device_start() save_item(STRUCT_MEMBER(m_channels, env_step)); save_item(STRUCT_MEMBER(m_channels, env_scale)); - m_stream = stream_alloc(0, 2, clock() / 384); + m_stream = stream_alloc_legacy(0, 2, clock() / 384); } //------------------------------------------------- @@ -195,10 +195,10 @@ void rf5c400_device::device_clock_changed() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void rf5c400_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i, ch; uint64_t end, loop; diff --git a/src/devices/sound/rf5c400.h b/src/devices/sound/rf5c400.h index faccf327bf2..fdd82910b76 100644 --- a/src/devices/sound/rf5c400.h +++ b/src/devices/sound/rf5c400.h @@ -34,7 +34,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rf5c68.cpp b/src/devices/sound/rf5c68.cpp index adb544afc64..1c00941000b 100644 --- a/src/devices/sound/rf5c68.cpp +++ b/src/devices/sound/rf5c68.cpp @@ -81,7 +81,7 @@ void rf5c68_device::device_start() m_sample_end_cb.resolve(); /* allocate the stream */ - m_stream = stream_alloc(0, 2, clock() / 384); + m_stream = stream_alloc_legacy(0, 2, clock() / 384); save_item(STRUCT_MEMBER(m_chan, enable)); save_item(STRUCT_MEMBER(m_chan, env)); @@ -116,10 +116,10 @@ device_memory_interface::space_config_vector rf5c68_device::memory_space_config( } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void rf5c68_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *left = outputs[0]; stream_sample_t *right = outputs[1]; diff --git a/src/devices/sound/rf5c68.h b/src/devices/sound/rf5c68.h index f5585506828..4a1d465e291 100644 --- a/src/devices/sound/rf5c68.h +++ b/src/devices/sound/rf5c68.h @@ -45,7 +45,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/rolandpcm.cpp b/src/devices/sound/rolandpcm.cpp index 08e8158afbe..4916605dd7e 100644 --- a/src/devices/sound/rolandpcm.cpp +++ b/src/devices/sound/rolandpcm.cpp @@ -61,7 +61,7 @@ void mb87419_mb87420_device::device_start() m_clock = clock() / 2; m_rate = m_clock / 512; // usually 32 KHz - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_rate); + m_stream = stream_alloc_legacy(0, 2, m_rate); logerror("Roland PCM: Clock %u, Rate %u\n", m_clock, m_rate); } @@ -266,10 +266,10 @@ void mb87419_mb87420_device::write(offs_t offset, u8 data) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void mb87419_mb87420_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mb87419_mb87420_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { memset(outputs[0], 0, samples * sizeof(stream_sample_t)); memset(outputs[1], 0, samples * sizeof(stream_sample_t)); diff --git a/src/devices/sound/rolandpcm.h b/src/devices/sound/rolandpcm.h index 42dfa91efba..5d1e814d517 100644 --- a/src/devices/sound/rolandpcm.h +++ b/src/devices/sound/rolandpcm.h @@ -24,7 +24,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/rp2c33_snd.cpp b/src/devices/sound/rp2c33_snd.cpp index 15446374ac1..57e60cf9fb5 100644 --- a/src/devices/sound/rp2c33_snd.cpp +++ b/src/devices/sound/rp2c33_snd.cpp @@ -56,7 +56,7 @@ void rp2c33_sound_device::device_start() for (int i = 0; i < 4; i++) m_mvol_table[i] = int((65536.0 / (32.0 * 64.0)) * 2.0 / double(i + 2)); - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()); + m_stream = stream_alloc_legacy(0, 1, clock()); // save states save_item(NAME(m_regs)); @@ -218,10 +218,10 @@ void rp2c33_sound_device::write(offs_t offset, u8 data) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void rp2c33_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void rp2c33_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int i = 0; i < samples; i++) { diff --git a/src/devices/sound/rp2c33_snd.h b/src/devices/sound/rp2c33_snd.h index cf3c5c23b55..73b737409c2 100644 --- a/src/devices/sound/rp2c33_snd.h +++ b/src/devices/sound/rp2c33_snd.h @@ -43,7 +43,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream *m_stream = nullptr; diff --git a/src/devices/sound/s14001a.cpp b/src/devices/sound/s14001a.cpp index c7ceacb59a5..5230a66b534 100644 --- a/src/devices/sound/s14001a.cpp +++ b/src/devices/sound/s14001a.cpp @@ -226,7 +226,7 @@ ALLOW_SAVE_TYPE(s14001a_device::states); // allow save_item on a non-fundamental void s14001a_device::device_start() { - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate()); + m_stream = stream_alloc_legacy(0, 1, clock() ? clock() : machine().sample_rate()); // resolve callbacks m_ext_read_handler.resolve(); @@ -311,10 +311,10 @@ void s14001a_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void s14001a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void s14001a_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int i = 0; i < samples; i++) { diff --git a/src/devices/sound/s14001a.h b/src/devices/sound/s14001a.h index 819cfba1920..09f985a51dc 100644 --- a/src/devices/sound/s14001a.h +++ b/src/devices/sound/s14001a.h @@ -31,7 +31,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: uint8_t readmem(uint16_t offset, bool phase); diff --git a/src/devices/sound/s_dsp.cpp b/src/devices/sound/s_dsp.cpp index 487b77bff2f..9385273ba66 100644 --- a/src/devices/sound/s_dsp.cpp +++ b/src/devices/sound/s_dsp.cpp @@ -160,7 +160,7 @@ void s_dsp_device::device_start() space().cache(m_cache); space().specific(m_data); - m_channel = machine().sound().stream_alloc(*this, 0, 2, clock() / 64); + m_channel = stream_alloc_legacy(0, 2, clock() / 64); state_register(); } @@ -965,8 +965,8 @@ int s_dsp_device::advance_envelope( int v ) void s_dsp_device::set_volume(int volume) { - m_channel->set_output_gain(0, volume / 100.0); - m_channel->set_output_gain(1, volume / 100.0); + set_output_gain(0, volume / 100.0); + set_output_gain(1, volume / 100.0); } @@ -1061,10 +1061,10 @@ void s_dsp_device::state_register() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void s_dsp_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void s_dsp_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { s16 mix[2]; diff --git a/src/devices/sound/s_dsp.h b/src/devices/sound/s_dsp.h index 953991dcd2c..4ab841d0ebd 100644 --- a/src/devices/sound/s_dsp.h +++ b/src/devices/sound/s_dsp.h @@ -30,7 +30,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/saa1099.cpp b/src/devices/sound/saa1099.cpp index 9edec91113a..cad84d184bb 100644 --- a/src/devices/sound/saa1099.cpp +++ b/src/devices/sound/saa1099.cpp @@ -161,7 +161,7 @@ saa1099_device::saa1099_device(const machine_config &mconfig, const char *tag, d void saa1099_device::device_start() { /* for each chip allocate one stream */ - m_stream = stream_alloc(0, 2, clock()/clock_divider); + m_stream = stream_alloc_legacy(0, 2, clock()/clock_divider); save_item(NAME(m_noise_params)); save_item(NAME(m_env_enable)); @@ -200,10 +200,10 @@ void saa1099_device::device_clock_changed() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void saa1099_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void saa1099_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int j, ch; /* if the channels are disabled we're done */ diff --git a/src/devices/sound/saa1099.h b/src/devices/sound/saa1099.h index 2831b4b1f73..2f9361d5ce8 100644 --- a/src/devices/sound/saa1099.h +++ b/src/devices/sound/saa1099.h @@ -32,7 +32,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct saa1099_channel diff --git a/src/devices/sound/samples.cpp b/src/devices/sound/samples.cpp index 82ce481e72e..5c8d129b799 100644 --- a/src/devices/sound/samples.cpp +++ b/src/devices/sound/samples.cpp @@ -86,12 +86,11 @@ void samples_device::start(uint8_t channel, uint32_t samplenum, bool loop) // update the parameters sample_t &sample = m_sample[samplenum]; chan.source = (sample.data.size() > 0) ? &sample.data[0] : nullptr; - chan.source_length = sample.data.size(); - chan.source_num = (chan.source_length > 0) ? samplenum : -1; + chan.source_num = (chan.source_len > 0) ? samplenum : -1; + chan.source_len = sample.data.size(); chan.pos = 0; - chan.frac = 0; chan.basefreq = sample.frequency; - chan.step = (int64_t(chan.basefreq) << FRAC_BITS) / machine().sample_rate(); + chan.curfreq = sample.frequency; chan.loop = loop; } @@ -111,12 +110,11 @@ void samples_device::start_raw(uint8_t channel, const int16_t *sampledata, uint3 // update the parameters chan.source = sampledata; - chan.source_length = samples; chan.source_num = -1; + chan.source_len = samples; chan.pos = 0; - chan.frac = 0; chan.basefreq = frequency; - chan.step = (int64_t(chan.basefreq) << FRAC_BITS) / machine().sample_rate(); + chan.curfreq = frequency; chan.loop = loop; } @@ -133,7 +131,7 @@ void samples_device::set_frequency(uint8_t channel, uint32_t freq) // force an update before we start channel_t &chan = m_channel[channel]; chan.stream->update(); - chan.step = (int64_t(freq) << FRAC_BITS) / machine().sample_rate(); + chan.curfreq = freq; } @@ -147,8 +145,7 @@ void samples_device::set_volume(uint8_t channel, float volume) assert(channel < m_channels); // force an update before we start - channel_t &chan = m_channel[channel]; - chan.stream->set_output_gain(0, volume); + set_output_gain(channel, volume); } @@ -201,11 +198,7 @@ void samples_device::stop_all() uint32_t samples_device::base_frequency(uint8_t channel) const { assert(channel < m_channels); - - // force an update before we start - const channel_t &chan = m_channel[channel]; - chan.stream->update(); - return chan.basefreq; + return m_channel[channel].basefreq; } @@ -245,19 +238,17 @@ void samples_device::device_start() { // initialize channel channel_t &chan = m_channel[channel]; - chan.stream = stream_alloc(0, 1, machine().sample_rate()); + chan.stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); chan.source = nullptr; chan.source_num = -1; - chan.step = 0; + chan.pos = 0; chan.loop = 0; chan.paused = 0; // register with the save state system - save_item(NAME(chan.source_length), channel); save_item(NAME(chan.source_num), channel); + save_item(NAME(chan.source_len), channel); save_item(NAME(chan.pos), channel); - save_item(NAME(chan.frac), channel); - save_item(NAME(chan.step), channel); save_item(NAME(chan.loop), channel); save_item(NAME(chan.paused), channel); } @@ -296,16 +287,21 @@ void samples_device::device_post_load() { sample_t &sample = m_sample[chan.source_num]; chan.source = &sample.data[0]; - chan.source_length = sample.data.size(); + chan.source_len = sample.data.size(); if (sample.data.empty()) chan.source_num = -1; } // validate the position against the length in case the sample is smaller - if (chan.source != nullptr && chan.pos >= chan.source_length) + double endpos = chan.source_len; + if (chan.source != nullptr && chan.pos >= endpos) { if (chan.loop) - chan.pos %= chan.source_length; + { + double posfloor = floor(chan.pos); + chan.pos -= posfloor; + chan.pos += double(int32_t(posfloor) % chan.source_len); + } else { chan.source = nullptr; @@ -320,60 +316,55 @@ void samples_device::device_post_load() // sound_stream_update - update a sound stream //------------------------------------------------- -void samples_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void samples_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { // find the channel with this stream + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; for (int channel = 0; channel < m_channels; channel++) if (&stream == m_channel[channel].stream) { channel_t &chan = m_channel[channel]; - stream_sample_t *buffer = outputs[0]; + auto &buffer = outputs[0]; // process if we still have a source and we're not paused if (chan.source != nullptr && !chan.paused) { // load some info locally - uint32_t pos = chan.pos; - uint32_t frac = chan.frac; - uint32_t step = chan.step; + double step = double(chan.curfreq) / double(buffer.sample_rate()); + double endpos = chan.source_len; const int16_t *sample = chan.source; - uint32_t sample_length = chan.source_length; - while (samples--) + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) { // do a linear interp on the sample - int32_t sample1 = sample[pos]; - int32_t sample2 = sample[(pos + 1) % sample_length]; - int32_t fracmult = frac >> (FRAC_BITS - 14); - *buffer++ = ((0x4000 - fracmult) * sample1 + fracmult * sample2) >> 14; + double pos_floor = floor(chan.pos); + double frac = chan.pos - pos_floor; + int32_t ipos = int32_t(pos_floor); + + stream_buffer::sample_t sample1 = stream_buffer::sample_t(sample[ipos++]); + stream_buffer::sample_t sample2 = stream_buffer::sample_t(sample[(ipos + 1) % chan.source_len]); + buffer.put(sampindex, sample_scale * ((1.0 - frac) * sample1 + frac * sample2)); // advance - frac += step; - pos += frac >> FRAC_BITS; - frac = frac & ((1 << FRAC_BITS) - 1); + chan.pos += step; // handle looping/ending - if (pos >= sample_length) + if (chan.pos >= endpos) { if (chan.loop) - pos %= sample_length; + chan.pos -= endpos; else { chan.source = nullptr; chan.source_num = -1; - if (samples > 0) - memset(buffer, 0, samples * sizeof(*buffer)); + buffer.fill(0, sampindex); break; } } } - - // push position back out - chan.pos = pos; - chan.frac = frac; } else - memset(buffer, 0, samples * sizeof(*buffer)); + buffer.fill(0); break; } } diff --git a/src/devices/sound/samples.h b/src/devices/sound/samples.h index aae6aa2cef1..394af9d0fdf 100644 --- a/src/devices/sound/samples.h +++ b/src/devices/sound/samples.h @@ -85,19 +85,18 @@ protected: virtual void device_post_load() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; // internal classes struct channel_t { sound_stream * stream; - const int16_t * source; - int32_t source_length; - int32_t source_num; - uint32_t pos; - uint32_t frac; - uint32_t step; - uint32_t basefreq; + const int16_t * source; + int32_t source_num; + uint32_t source_len; + double pos; + uint32_t basefreq; + uint32_t curfreq; bool loop; bool paused; }; diff --git a/src/devices/sound/scsp.cpp b/src/devices/sound/scsp.cpp index 97256bfe01a..143be37ca40 100644 --- a/src/devices/sound/scsp.cpp +++ b/src/devices/sound/scsp.cpp @@ -212,7 +212,7 @@ void scsp_device::device_start() m_main_irq_cb.resolve_safe(); // Stereo output with EXTS0,1 Input (External digital audio output) - m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 512); + m_stream = stream_alloc_legacy(2, 2, clock() / 512); for (int slot = 0; slot < 32; slot++) { @@ -297,8 +297,8 @@ void scsp_device::device_post_load() for (int slot = 0; slot < 32; slot++) Compute_LFO(&m_Slots[slot]); - m_stream->set_output_gain(0, MVOL() / 15.0); - m_stream->set_output_gain(1, MVOL() / 15.0); + set_output_gain(0, MVOL() / 15.0); + set_output_gain(1, MVOL() / 15.0); } //------------------------------------------------- @@ -317,10 +317,10 @@ void scsp_device::rom_bank_updated() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void scsp_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void scsp_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { m_exts0 = inputs[0]; m_exts1 = inputs[1]; @@ -738,8 +738,8 @@ void scsp_device::UpdateReg(int reg) switch (reg & 0x3f) { case 0x0: - m_stream->set_output_gain(0, MVOL() / 15.0); - m_stream->set_output_gain(1, MVOL() / 15.0); + set_output_gain(0, MVOL() / 15.0); + set_output_gain(1, MVOL() / 15.0); break; case 0x2: case 0x3: @@ -1279,7 +1279,7 @@ inline s32 scsp_device::UpdateSlot(SCSP_SLOT *slot) void scsp_device::DoMasterSamples(int nsamples) { stream_sample_t *bufr,*bufl; - stream_sample_t *exts[2]; + stream_sample_t const *exts[2]; bufr = m_bufferr; bufl = m_bufferl; diff --git a/src/devices/sound/scsp.h b/src/devices/sound/scsp.h index 3a4e94074a6..4fe8c5e2a91 100644 --- a/src/devices/sound/scsp.h +++ b/src/devices/sound/scsp.h @@ -45,7 +45,7 @@ protected: virtual void rom_bank_updated() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: enum SCSP_STATE { SCSP_ATTACK, SCSP_DECAY1, SCSP_DECAY2, SCSP_RELEASE }; @@ -150,8 +150,8 @@ private: stream_sample_t *m_bufferl; stream_sample_t *m_bufferr; - stream_sample_t *m_exts0; - stream_sample_t *m_exts1; + stream_sample_t const *m_exts0; + stream_sample_t const *m_exts1; int m_length; diff --git a/src/devices/sound/segapcm.cpp b/src/devices/sound/segapcm.cpp index 576bc3d2cd0..e93bbaec7ee 100644 --- a/src/devices/sound/segapcm.cpp +++ b/src/devices/sound/segapcm.cpp @@ -39,7 +39,7 @@ void segapcm_device::device_start() std::fill(&m_ram[0], &m_ram[0x800], 0xff); - m_stream = stream_alloc(0, 2, clock() / 128); + m_stream = stream_alloc_legacy(0, 2, clock() / 128); save_item(NAME(m_low)); save_pointer(NAME(m_ram), 0x800); @@ -68,10 +68,10 @@ void segapcm_device::rom_bank_updated() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void segapcm_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { /* clear the buffers */ memset(outputs[0], 0, samples*sizeof(*outputs[0])); diff --git a/src/devices/sound/segapcm.h b/src/devices/sound/segapcm.h index 666a0efed2c..8b9942a5727 100644 --- a/src/devices/sound/segapcm.h +++ b/src/devices/sound/segapcm.h @@ -41,7 +41,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/sn76477.cpp b/src/devices/sound/sn76477.cpp index 3a487d29edf..2903af1904b 100644 --- a/src/devices/sound/sn76477.cpp +++ b/src/devices/sound/sn76477.cpp @@ -203,7 +203,7 @@ sn76477_device::sn76477_device(const machine_config &mconfig, const char *tag, d void sn76477_device::device_start() { - m_channel = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); if (clock() > 0) { @@ -1698,10 +1698,10 @@ void sn76477_device::state_save_register() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void sn76477_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { double one_shot_cap_charging_step; double one_shot_cap_discharging_step; diff --git a/src/devices/sound/sn76477.h b/src/devices/sound/sn76477.h index 5e58407cb50..42fa82e5efc 100644 --- a/src/devices/sound/sn76477.h +++ b/src/devices/sound/sn76477.h @@ -147,7 +147,7 @@ protected: virtual void device_stop() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: /* chip's external interface */ diff --git a/src/devices/sound/sn76496.cpp b/src/devices/sound/sn76496.cpp index 83f2d0c5e50..9bc686dedb2 100644 --- a/src/devices/sound/sn76496.cpp +++ b/src/devices/sound/sn76496.cpp @@ -233,7 +233,7 @@ void sn76496_base_device::device_start() m_ready_handler.resolve_safe(); - m_sound = machine().sound().stream_alloc(*this, 0, (m_stereo? 2:1), sample_rate); + m_sound = stream_alloc(0, (m_stereo? 2:1), sample_rate); for (i = 0; i < 4; i++) m_volume[i] = 0; @@ -369,16 +369,17 @@ inline bool sn76496_base_device::in_noise_mode() return ((m_register[6] & 4)!=0); } -void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void sn76496_base_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int i; - stream_sample_t *lbuffer = outputs[0]; - stream_sample_t *rbuffer = (m_stereo)? outputs[1] : nullptr; + auto *lbuffer = &outputs[0]; + auto *rbuffer = m_stereo ? &outputs[1] : nullptr; int16_t out; int16_t out2 = 0; - while (samples > 0) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for (int sampindex = 0; sampindex < lbuffer->samples(); sampindex++) { // clock chip once if (m_current_clock > 0) // not ready for new divided clock @@ -444,9 +445,9 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl if (m_negate) { out = -out; out2 = -out2; } - *(lbuffer++) = out; - if (m_stereo) *(rbuffer++) = out2; - samples--; + lbuffer->put(sampindex, stream_buffer::sample_t(out) * sample_scale); + if (m_stereo) + rbuffer->put(sampindex, stream_buffer::sample_t(out2) * sample_scale); } } diff --git a/src/devices/sound/sn76496.h b/src/devices/sound/sn76496.h index f58e259b439..da6ec178f3e 100644 --- a/src/devices/sound/sn76496.h +++ b/src/devices/sound/sn76496.h @@ -44,7 +44,7 @@ protected: virtual void device_start() override; virtual void device_clock_changed() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: inline bool in_noise_mode(); diff --git a/src/devices/sound/snkwave.cpp b/src/devices/sound/snkwave.cpp index 2c9e9b75f9f..718dde017fb 100644 --- a/src/devices/sound/snkwave.cpp +++ b/src/devices/sound/snkwave.cpp @@ -44,7 +44,7 @@ void snkwave_device::device_start() m_sample_rate = m_external_clock >> CLOCK_SHIFT; /* get stream channels */ - m_stream = stream_alloc(0, 1, m_sample_rate); + m_stream = stream_alloc_legacy(0, 1, m_sample_rate); /* reset all the voices */ m_frequency = 0; @@ -60,11 +60,11 @@ void snkwave_device::device_start() //------------------------------------------------- -// sound_stream_update - handle update requests +// sound_stream_update_legacy - handle update requests // for our sound stream //------------------------------------------------- -void snkwave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void snkwave_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/snkwave.h b/src/devices/sound/snkwave.h index 6777118c7ca..2ecb5f7715d 100644 --- a/src/devices/sound/snkwave.h +++ b/src/devices/sound/snkwave.h @@ -26,7 +26,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: static constexpr unsigned WAVEFORM_LENGTH = 16; diff --git a/src/devices/sound/sp0250.cpp b/src/devices/sound/sp0250.cpp index 1ced1f3ff87..e18143a29b0 100644 --- a/src/devices/sound/sp0250.cpp +++ b/src/devices/sound/sp0250.cpp @@ -63,10 +63,7 @@ void sp0250_device::device_start() // output PWM data at the ROMCLOCK frequency int sample_rate = clock() / 2; int frame_rate = sample_rate / (4 * PWM_CLOCKS); - if (!m_pwm_mode) - m_stream = machine().sound().stream_alloc(*this, 0, 1, frame_rate); - else - m_stream = machine().sound().stream_alloc(*this, 0, 1, sample_rate); + m_stream = stream_alloc(0, 1, m_pwm_mode ? sample_rate : frame_rate); // if a DRQ callback is offered, run a timer at the frame rate // to ensure the DRQ gets picked up in a timely manner @@ -255,17 +252,19 @@ int8_t sp0250_device::next() // sound_stream_update - handle a stream update //------------------------------------------------- -void sp0250_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void sp0250_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - stream_sample_t *output = outputs[0]; + auto &output = outputs[0]; + if (!m_pwm_mode) { - while (samples-- != 0) - *output++ = next() << 8; + constexpr stream_buffer::sample_t sample_scale = 1.0 / 128.0; + for (int sampindex = 0; sampindex < output.samples(); sampindex++) + output.put(sampindex, stream_buffer::sample_t(next()) * sample_scale); } else { - while (samples != 0) + for (int sampindex = 0; sampindex < output.samples(); ) { // see where we're at in the current PWM cycle if (m_pwm_index >= PWM_CLOCKS) @@ -279,28 +278,27 @@ void sp0250_device::sound_stream_update(sound_stream &stream, stream_sample_t ** // determine the value to fill and the number of samples remaining // until it changes - stream_sample_t value; + stream_buffer::sample_t value; int remaining; if (m_pwm_index < m_pwm_count) { - value = 32767; + value = 1.0; remaining = m_pwm_count - m_pwm_index; } else { - value = 0; + value = 0.0; remaining = PWM_CLOCKS - m_pwm_index; } // clamp to the number of samples requested and advance the counters - if (remaining > samples) - remaining = samples; + if (remaining > output.samples() - sampindex) + remaining = output.samples() - sampindex; m_pwm_index += remaining; - samples -= remaining; // fill the output while (remaining-- != 0) - *output++ = value; + outputs[0].put(sampindex++, value); } } } diff --git a/src/devices/sound/sp0250.h b/src/devices/sound/sp0250.h index 48f77a69d01..d51ab2286bd 100644 --- a/src/devices/sound/sp0250.h +++ b/src/devices/sound/sp0250.h @@ -22,7 +22,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // internal helpers diff --git a/src/devices/sound/sp0256.cpp b/src/devices/sound/sp0256.cpp index 54c17fcaf21..b4d18e6d6d3 100644 --- a/src/devices/sound/sp0256.cpp +++ b/src/devices/sound/sp0256.cpp @@ -74,7 +74,7 @@ void sp0256_device::device_start() m_drq_cb(1); m_sby_cb(1); - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / CLOCK_DIVIDER); + m_stream = stream_alloc_legacy(0, 1, clock() / CLOCK_DIVIDER); /* -------------------------------------------------------------------- */ /* Configure our internal variables. */ @@ -1260,10 +1260,10 @@ TIMER_CALLBACK_MEMBER(sp0256_device::set_lrq_timer_proc) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void sp0256_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void sp0256_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *output = outputs[0]; int output_index = 0; diff --git a/src/devices/sound/sp0256.h b/src/devices/sound/sp0256.h index 83a3aa75c5d..3720b3429ed 100644 --- a/src/devices/sound/sp0256.h +++ b/src/devices/sound/sp0256.h @@ -61,7 +61,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: struct lpc12_t diff --git a/src/devices/sound/spkrdev.cpp b/src/devices/sound/spkrdev.cpp index c44e00f5708..3fc3467771e 100644 --- a/src/devices/sound/spkrdev.cpp +++ b/src/devices/sound/spkrdev.cpp @@ -102,7 +102,7 @@ void speaker_sound_device::device_start() int i; double x; - m_channel = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_channel = stream_alloc_legacy(0, 1, machine().sample_rate()); m_level = 0; for (i = 0; i < FILTER_LENGTH; i++) @@ -198,11 +198,11 @@ void speaker_sound_device::device_post_load() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- // This can be triggered by the core (based on emulated time) or via level_w(). -void speaker_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void speaker_sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; int volume = m_levels[m_level]; diff --git a/src/devices/sound/spkrdev.h b/src/devices/sound/spkrdev.h index 49e953b5d40..7411e47170d 100644 --- a/src/devices/sound/spkrdev.h +++ b/src/devices/sound/spkrdev.h @@ -32,7 +32,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: // Length of anti-aliasing filter kernel, measured in number of intermediate samples diff --git a/src/devices/sound/spu.cpp b/src/devices/sound/spu.cpp index c4550e928c7..82f5d3973ac 100644 --- a/src/devices/sound/spu.cpp +++ b/src/devices/sound/spu.cpp @@ -444,7 +444,7 @@ struct spu_device::voiceinfo // // -class stream_buffer +class spu_stream_buffer { public: struct stream_marker @@ -466,7 +466,7 @@ public: stream_marker *marker_head, *marker_tail; - stream_buffer(const unsigned int _sector_size, + spu_stream_buffer(const unsigned int _sector_size, const unsigned int _num_sectors) : head(0), tail(0), @@ -481,7 +481,7 @@ public: memset(&buffer[0], 0, buffer_size); } - ~stream_buffer() + ~spu_stream_buffer() { flush_all(); } @@ -969,8 +969,8 @@ void spu_device::device_start() voice=new voiceinfo [24]; spu_ram=new unsigned char [spu_ram_size]; - xa_buffer=new stream_buffer(xa_sector_size,xa_buffer_sectors); - cdda_buffer=new stream_buffer(cdda_sector_size,cdda_buffer_sectors); + xa_buffer=new spu_stream_buffer(xa_sector_size,xa_buffer_sectors); + cdda_buffer=new spu_stream_buffer(cdda_sector_size,cdda_buffer_sectors); init_stream(); @@ -1093,7 +1093,7 @@ void spu_device::init_stream() { const unsigned int hz=44100; - m_stream = machine().sound().stream_alloc(*this, 0, 2, hz); + m_stream = stream_alloc_legacy(0, 2, hz); rev=new reverb(hz); @@ -2761,7 +2761,7 @@ void spu_device::update_timing() // // -void spu_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void spu_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *outL, *outR; int16_t temp[44100], *src; @@ -3034,7 +3034,7 @@ bool spu_device::play_cdda(const unsigned int sector, const unsigned char *cdda) flip[i] = flip[i+1]; flip[i+1] = temp; } - // this should be done in generate but sound_stream_update may not be called frequently enough + // this should be done in generate but sound_stream_update_legacy may not be called frequently enough if(((spureg.irq_addr << 3) < 0x800) && (spureg.ctrl & spuctrl_irq_enable)) m_irq_handler(1); diff --git a/src/devices/sound/spu.h b/src/devices/sound/spu.h index b4e73c04726..7913670c667 100644 --- a/src/devices/sound/spu.h +++ b/src/devices/sound/spu.h @@ -7,7 +7,7 @@ // ======================> spu_device -class stream_buffer; +class spu_stream_buffer; class psxcpu_device; class spu_device : public device_t, public device_sound_interface @@ -35,7 +35,7 @@ protected: virtual void device_post_load() override; virtual void device_stop() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; static constexpr float ms_to_rate(float ms) { return 1.0f / (ms * (float(spu_base_frequency_hz) / 1000.0f)); } static constexpr float s_to_rate(float s) { return ms_to_rate(s * 1000.0f); } @@ -54,8 +54,8 @@ protected: unsigned int taddr; unsigned int sample_t; - stream_buffer *xa_buffer; - stream_buffer *cdda_buffer; + spu_stream_buffer *xa_buffer; + spu_stream_buffer *cdda_buffer; unsigned int xa_cnt; unsigned int cdda_cnt; unsigned int xa_freq; diff --git a/src/devices/sound/st0016.cpp b/src/devices/sound/st0016.cpp index 6ba2a8ec015..e0318eca466 100644 --- a/src/devices/sound/st0016.cpp +++ b/src/devices/sound/st0016.cpp @@ -43,7 +43,7 @@ st0016_device::st0016_device(const machine_config &mconfig, const char *tag, dev void st0016_device::device_start() { - m_stream = stream_alloc(0, 2, 44100); + m_stream = stream_alloc_legacy(0, 2, 44100); m_ram_read_cb.resolve_safe(0); save_item(NAME(m_vpos)); @@ -54,10 +54,10 @@ void st0016_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void st0016_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void st0016_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int v, i, snum; unsigned char *slot; diff --git a/src/devices/sound/st0016.h b/src/devices/sound/st0016.h index 4dde038cfe8..21dd14e07c7 100644 --- a/src/devices/sound/st0016.h +++ b/src/devices/sound/st0016.h @@ -27,7 +27,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream *m_stream; diff --git a/src/devices/sound/swp00.cpp b/src/devices/sound/swp00.cpp index 0fa494658b1..d4d323af0a5 100644 --- a/src/devices/sound/swp00.cpp +++ b/src/devices/sound/swp00.cpp @@ -21,7 +21,7 @@ void swp00_device::device_add_mconfig(machine_config &config) void swp00_device::device_start() { - m_stream = stream_alloc(0, 2, 44100); + m_stream = stream_alloc_legacy(0, 2, 44100); } void swp00_device::device_reset() @@ -97,6 +97,6 @@ void swp00_device::snd_w(offs_t offset, u8 data) // Synthesis -void swp00_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void swp00_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/swp00.h b/src/devices/sound/swp00.h index 9ada0cdaadb..0bf2d8b43d3 100644 --- a/src/devices/sound/swp00.h +++ b/src/devices/sound/swp00.h @@ -21,7 +21,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void rom_bank_updated() override; virtual void device_add_mconfig(machine_config &config) override; diff --git a/src/devices/sound/swp20.cpp b/src/devices/sound/swp20.cpp index c5127168f11..c1c92c8cb27 100644 --- a/src/devices/sound/swp20.cpp +++ b/src/devices/sound/swp20.cpp @@ -69,7 +69,7 @@ void swp20_device::snd_w(offs_t offset, u8 data) logerror("w %02x, %02x %s\n", offset, data, machine().describe_context()); } -void swp20_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void swp20_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/swp20.h b/src/devices/sound/swp20.h index b2aca4c8a71..a65bae793a3 100644 --- a/src/devices/sound/swp20.h +++ b/src/devices/sound/swp20.h @@ -20,7 +20,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void rom_bank_updated() override; private: diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp index 18b4f498c1b..849af9f9946 100644 --- a/src/devices/sound/swp30.cpp +++ b/src/devices/sound/swp30.cpp @@ -163,7 +163,7 @@ void swp30_device::device_add_mconfig(machine_config &config) void swp30_device::device_start() { - m_stream = stream_alloc(0, 2, 44100); + m_stream = stream_alloc_legacy(0, 2, 44100); // Attenuantion for panning is 4.4 floating point. That means 0 // to -96.3dB. Since it's a nice range, we assume it's the same @@ -761,7 +761,7 @@ void swp30_device::snd_w(offs_t offset, u16 data) // Synthesis -void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void swp30_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // Loop first on the samples and not on the channels otherwise // effects will be annoying to implement. diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h index 35a90341bf3..fc8424b66d2 100644 --- a/src/devices/sound/swp30.h +++ b/src/devices/sound/swp30.h @@ -21,7 +21,7 @@ public: protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void rom_bank_updated() override; virtual void device_add_mconfig(machine_config &config) override; diff --git a/src/devices/sound/t6721a.cpp b/src/devices/sound/t6721a.cpp index 423cd3edc19..7c0c07544e0 100644 --- a/src/devices/sound/t6721a.cpp +++ b/src/devices/sound/t6721a.cpp @@ -56,16 +56,16 @@ void t6721a_device::device_start() m_write_apd.resolve_safe(); // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_stream = stream_alloc_legacy(0, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void t6721a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void t6721a_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/t6721a.h b/src/devices/sound/t6721a.h index ebc7ea6924e..208cd7e8896 100644 --- a/src/devices/sound/t6721a.h +++ b/src/devices/sound/t6721a.h @@ -65,7 +65,7 @@ protected: virtual void device_start() override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: enum diff --git a/src/devices/sound/t6w28.cpp b/src/devices/sound/t6w28.cpp index cc7324d41f1..6c024c37757 100644 --- a/src/devices/sound/t6w28.cpp +++ b/src/devices/sound/t6w28.cpp @@ -101,10 +101,10 @@ void t6w28_device::write(offs_t offset, uint8_t data) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void t6w28_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void t6w28_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i; stream_sample_t *buffer0 = outputs[0]; @@ -296,7 +296,7 @@ void t6w28_device::device_start() int i; m_sample_rate = clock() / 16; - m_channel = machine().sound().stream_alloc(*this, 0, 2, m_sample_rate); + m_channel = stream_alloc_legacy(0, 2, m_sample_rate); for (i = 0;i < 8;i++) m_volume[i] = 0; diff --git a/src/devices/sound/t6w28.h b/src/devices/sound/t6w28.h index e6cc2d9319d..f1112f58839 100644 --- a/src/devices/sound/t6w28.h +++ b/src/devices/sound/t6w28.h @@ -18,7 +18,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; void set_gain(int gain); diff --git a/src/devices/sound/tc8830f.cpp b/src/devices/sound/tc8830f.cpp index 37a6fecdbe3..e387cc746f7 100644 --- a/src/devices/sound/tc8830f.cpp +++ b/src/devices/sound/tc8830f.cpp @@ -46,7 +46,7 @@ tc8830f_device::tc8830f_device(const machine_config &mconfig, const char *tag, d void tc8830f_device::device_start() { // create the stream - m_stream = stream_alloc(0, 1, clock() / 0x10); + m_stream = stream_alloc_legacy(0, 1, clock() / 0x10); // register for savestates save_item(NAME(m_playing)); @@ -79,7 +79,7 @@ void tc8830f_device::device_clock_changed() -void tc8830f_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tc8830f_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int32_t mix = 0; diff --git a/src/devices/sound/tc8830f.h b/src/devices/sound/tc8830f.h index f108eb72f69..e0e715ccbef 100644 --- a/src/devices/sound/tc8830f.h +++ b/src/devices/sound/tc8830f.h @@ -32,7 +32,7 @@ protected: virtual void device_post_load() override; virtual void device_clock_changed() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream *m_stream; diff --git a/src/devices/sound/tiaintf.cpp b/src/devices/sound/tiaintf.cpp index d382707612a..5c85db19b91 100644 --- a/src/devices/sound/tiaintf.cpp +++ b/src/devices/sound/tiaintf.cpp @@ -31,7 +31,7 @@ tia_device::tia_device(const machine_config &mconfig, const char *tag, device_t void tia_device::device_start() { - m_channel = stream_alloc(0, 1, clock()); + m_channel = stream_alloc_legacy(0, 1, clock()); m_chip = tia_sound_init(this, clock(), clock(), 16); if (!m_chip) throw emu_fatalerror("tia_device(%s): Error creating TIA chip", tag()); @@ -49,10 +49,10 @@ void tia_device::device_stop() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void tia_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tia_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { tia_process(m_chip, outputs[0], samples); } diff --git a/src/devices/sound/tiaintf.h b/src/devices/sound/tiaintf.h index 140c4f3de65..c86be7173a9 100644 --- a/src/devices/sound/tiaintf.h +++ b/src/devices/sound/tiaintf.h @@ -24,7 +24,7 @@ protected: virtual void device_stop() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: sound_stream *m_channel; diff --git a/src/devices/sound/tms3615.cpp b/src/devices/sound/tms3615.cpp index 85f1ec5ece0..e59c64eab04 100644 --- a/src/devices/sound/tms3615.cpp +++ b/src/devices/sound/tms3615.cpp @@ -3,9 +3,6 @@ #include "emu.h" #include "tms3615.h" -#define VMIN 0x0000 -#define VMAX 0x7fff - const int tms3615_device::divisor[TMS3615_TONES] = { 478, 451, 426, 402, 379, 358, 338, 319, 301, 284, 268, 253, 239 }; @@ -49,20 +46,22 @@ void tms3615_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void tms3615_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tms3615_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - int samplerate = m_samplerate; - stream_sample_t *buffer8 = outputs[FOOTAGE_8]; - stream_sample_t *buffer16 = outputs[FOOTAGE_16]; + auto &buffer8 = outputs[FOOTAGE_8]; + auto &buffer16 = outputs[FOOTAGE_16]; + + int samplerate = buffer8.sample_rate(); - while( samples-- > 0 ) + constexpr stream_buffer::sample_t VMAX = 1.0f / stream_buffer::sample_t(TMS3615_TONES); + for (int sampindex = 0; sampindex < buffer8.samples(); sampindex++) { - int sum8 = 0, sum16 = 0, tone = 0; + stream_buffer::sample_t sum8 = 0, sum16 = 0; - for (tone = 0; tone < TMS3615_TONES; tone++) + for (int tone = 0; tone < TMS3615_TONES; tone++) { // 8' @@ -95,11 +94,9 @@ void tms3615_device::sound_stream_update(sound_stream &stream, stream_sample_t * } } - *buffer8++ = sum8 / TMS3615_TONES; - *buffer16++ = sum16 / TMS3615_TONES; + buffer8.put(sampindex, sum8); + buffer16.put(sampindex, sum16); } - - m_enable = 0; } diff --git a/src/devices/sound/tms3615.h b/src/devices/sound/tms3615.h index b3325ebc354..a1eeaab5318 100644 --- a/src/devices/sound/tms3615.h +++ b/src/devices/sound/tms3615.h @@ -28,7 +28,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: static constexpr unsigned TMS3615_TONES = 13; diff --git a/src/devices/sound/tms36xx.cpp b/src/devices/sound/tms36xx.cpp index 89211700a7d..73ec59b4121 100644 --- a/src/devices/sound/tms36xx.cpp +++ b/src/devices/sound/tms36xx.cpp @@ -355,7 +355,7 @@ void tms36xx_device::device_start() { int enable = 0; - m_channel = stream_alloc(0, 1, clock() * 64); + m_channel = stream_alloc_legacy(0, 1, clock() * 64); m_samplerate = clock() * 64; m_basefreq = clock(); @@ -394,10 +394,10 @@ void tms36xx_device::device_start() //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void tms36xx_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tms36xx_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int samplerate = m_samplerate; stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/tms36xx.h b/src/devices/sound/tms36xx.h index 3e517a09f77..03dd5dc2412 100644 --- a/src/devices/sound/tms36xx.h +++ b/src/devices/sound/tms36xx.h @@ -63,7 +63,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; public: // MM6221AA interface functions diff --git a/src/devices/sound/tms5110.cpp b/src/devices/sound/tms5110.cpp index d9d8427688a..73f5244738e 100644 --- a/src/devices/sound/tms5110.cpp +++ b/src/devices/sound/tms5110.cpp @@ -1048,7 +1048,7 @@ void tms5110_device::device_start() m_data_cb.resolve(); /* initialize a stream */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80); + m_stream = stream_alloc_legacy(0, 1, clock() / 80); m_state = CTL_STATE_INPUT; /* most probably not defined */ m_romclk_hack_timer = timer_alloc(0); @@ -1220,10 +1220,10 @@ int tms5110_device::romclk_hack_r() ******************************************************************************/ //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void tms5110_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tms5110_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int16_t sample_data[MAX_SAMPLE_CHUNK]; stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/tms5110.h b/src/devices/sound/tms5110.h index d873da55db4..84c7f68fc73 100644 --- a/src/devices/sound/tms5110.h +++ b/src/devices/sound/tms5110.h @@ -60,7 +60,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; uint8_t TALK_STATUS() const { return m_SPEN | m_TALKD; } diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index 4889cd85c60..9c4974c34e2 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -1649,7 +1649,7 @@ void tms5220_device::device_start() m_data_cb.resolve(); /* initialize a stream */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80); + m_stream = stream_alloc(0, 1, clock() / 80); m_timer_io_ready = timer_alloc(0); @@ -2055,24 +2055,21 @@ READ_LINE_MEMBER( tms5220_device::intq_r ) // sound_stream_update - handle a stream update //------------------------------------------------- -void tms5220_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void tms5220_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { int16_t sample_data[MAX_SAMPLE_CHUNK]; - stream_sample_t *buffer = outputs[0]; + auto &output = outputs[0]; /* loop while we still have samples to generate */ - while (samples) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for (int sampindex = 0; sampindex < output.samples(); ) { - int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples; - int index; + int length = (output.samples() > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : output.samples(); /* generate the samples and copy to the target buffer */ process(sample_data, length); - for (index = 0; index < length; index++) - *buffer++ = sample_data[index]; - - /* account for the samples */ - samples -= length; + for (int index = 0; index < length; index++) + output.put(sampindex++, sample_data[index] * sample_scale); } } diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index bc844b04e7b..5c45a685e21 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -75,7 +75,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: static constexpr unsigned FIFO_SIZE = 16; diff --git a/src/devices/sound/upd1771.cpp b/src/devices/sound/upd1771.cpp index c646f9954a6..bb8e61f2d00 100644 --- a/src/devices/sound/upd1771.cpp +++ b/src/devices/sound/upd1771.cpp @@ -255,7 +255,7 @@ void upd1771c_device::device_start() m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(upd1771c_device::ack_callback),this)); - m_channel = machine().sound().stream_alloc(*this, 0, 1, clock() / 4); + m_channel = stream_alloc_legacy(0, 1, clock() / 4); save_item(NAME(m_packet)); save_item(NAME(m_index)); @@ -476,10 +476,10 @@ TIMER_CALLBACK_MEMBER( upd1771c_device::ack_callback ) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void upd1771c_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void upd1771c_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *buffer = outputs[0]; diff --git a/src/devices/sound/upd1771.h b/src/devices/sound/upd1771.h index 7dfc7ae32e5..9fe86b58c1d 100644 --- a/src/devices/sound/upd1771.h +++ b/src/devices/sound/upd1771.h @@ -32,7 +32,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: static constexpr unsigned MAX_PACKET_SIZE = 0x8000; diff --git a/src/devices/sound/upd7752.cpp b/src/devices/sound/upd7752.cpp index c1253da1a2b..19977dcafdc 100644 --- a/src/devices/sound/upd7752.cpp +++ b/src/devices/sound/upd7752.cpp @@ -72,7 +72,7 @@ device_memory_interface::space_config_vector upd7752_device::memory_space_config void upd7752_device::device_start() { /* TODO: clock */ - m_stream = stream_alloc(0, 1, clock() / 64); + m_stream = stream_alloc_legacy(0, 1, clock() / 64); m_status = 0; } @@ -96,10 +96,10 @@ void upd7752_device::device_stop() } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void upd7752_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void upd7752_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { } diff --git a/src/devices/sound/upd7752.h b/src/devices/sound/upd7752.h index 85c3cd82d3c..b65048624f1 100644 --- a/src/devices/sound/upd7752.h +++ b/src/devices/sound/upd7752.h @@ -30,7 +30,7 @@ protected: virtual void device_stop() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual space_config_vector memory_space_config() const override; private: diff --git a/src/devices/sound/upd7759.cpp b/src/devices/sound/upd7759.cpp index 35a66d0b736..fc07c0f95ab 100644 --- a/src/devices/sound/upd7759.cpp +++ b/src/devices/sound/upd7759.cpp @@ -210,7 +210,7 @@ upd7756_device::upd7756_device(const machine_config &mconfig, device_type type, void upd775x_device::device_start() { // allocate a stream channel - m_channel = machine().sound().stream_alloc(*this, 0, 1, clock()/4); + m_channel = stream_alloc(0, 1, clock()/4); // compute the stepping rate based on the chip's clock speed m_step = 4 * FRAC_ONE; @@ -264,7 +264,7 @@ void upd7759_device::device_start() // chip configuration m_sample_offset_shift = 1; - m_timer = timer_alloc(TIMER_SLAVE_UPDATE); + m_timer = timer_alloc(TID_SLAVE_UPDATE); m_drqcallback.resolve_safe(); @@ -599,24 +599,35 @@ void upd7759_device::device_timer(emu_timer &timer, device_timer_id id, int para switch (id) { - case TIMER_SLAVE_UPDATE: + case TID_PORT_WRITE: + m_fifo_in = param; + break; + + case TID_RESET_WRITE: + internal_reset_w(param); + break; + + case TID_START_WRITE: + internal_start_w(param); + break; - /* update the stream */ - m_channel->update(); + case TID_SLAVE_UPDATE: + /* update the stream */ + m_channel->update(); - /* advance the state */ - advance_state(); + /* advance the state */ + advance_state(); - /* if the DRQ changed, update it */ - if (DEBUG_STATES) - logerror("upd7759_slave_update: DRQ %d->%d\n", olddrq, m_drq); - if (olddrq != m_drq) - m_drqcallback(m_drq); + /* if the DRQ changed, update it */ + if (DEBUG_STATES) + logerror("upd7759_slave_update: DRQ %d->%d\n", olddrq, m_drq); + if (olddrq != m_drq) + m_drqcallback(m_drq); - /* set a timer to go off when that is done */ - if (m_state != STATE_IDLE) - m_timer->adjust(m_clock_period * m_clocks_left); - break; + /* set a timer to go off when that is done */ + if (m_state != STATE_IDLE) + m_timer->adjust(m_clock_period * m_clocks_left); + break; default: throw emu_fatalerror("Unknown id in upd7759_device::device_timer"); @@ -631,6 +642,11 @@ void upd7759_device::device_timer(emu_timer &timer, device_timer_id id, int para WRITE_LINE_MEMBER( upd775x_device::reset_w ) { + synchronize(TID_RESET_WRITE, state); +} + +void upd775x_device::internal_reset_w(int state) +{ /* update the reset value */ uint8_t oldreset = m_reset; m_reset = (state != 0); @@ -643,12 +659,12 @@ WRITE_LINE_MEMBER( upd775x_device::reset_w ) device_reset(); } -WRITE_LINE_MEMBER(upd7759_device::md_w) +WRITE_LINE_MEMBER( upd775x_device::start_w ) { - m_md = state; + synchronize(TID_START_WRITE, state); } -WRITE_LINE_MEMBER( upd7759_device::start_w ) +void upd7759_device::internal_start_w(int state) { /* update the start value */ uint8_t oldstart = m_start; @@ -671,8 +687,9 @@ WRITE_LINE_MEMBER( upd7759_device::start_w ) } } -WRITE_LINE_MEMBER( upd7756_device::start_w ) +void upd7756_device::internal_start_w(int state) { + /* update the start value */ uint8_t oldstart = m_start; m_start = (state != 0); @@ -694,7 +711,7 @@ WRITE_LINE_MEMBER( upd7756_device::start_w ) void upd775x_device::port_w(u8 data) { /* update the FIFO value */ - m_fifo_in = data; + synchronize(TID_PORT_WRITE, data); } @@ -712,21 +729,21 @@ READ_LINE_MEMBER( upd775x_device::busy_r ) // sound_stream_update - handle a stream update //------------------------------------------------- -void upd775x_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void upd775x_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { + constexpr stream_buffer::sample_t sample_scale = 128.0 / 32768.0; + stream_buffer::sample_t sample = stream_buffer::sample_t(m_sample) * sample_scale; int32_t clocks_left = m_clocks_left; - int16_t sample = m_sample; uint32_t step = m_step; uint32_t pos = m_pos; - stream_sample_t *buffer = outputs[0]; /* loop until done */ + u32 index = 0; if (m_state != STATE_IDLE) - while (samples != 0) + for ( ; index < outputs[0].samples(); index++) { /* store the current sample */ - *buffer++ = sample << 7; - samples--; + outputs[0].put(index, sample); /* advance by the number of clocks/output sample */ pos += step; @@ -752,14 +769,14 @@ void upd775x_device::sound_stream_update(sound_stream &stream, stream_sample_t * /* reimport the variables that we cached */ clocks_left = m_clocks_left; - sample = m_sample; + sample = stream_buffer::sample_t(m_sample) * sample_scale; } } } /* if we got out early, just zap the rest of the buffer */ - if (samples != 0) - memset(buffer, 0, samples * sizeof(*buffer)); + for (; index < outputs[0].samples(); index++) + outputs[0].put(index, 0); /* flush the state back */ m_clocks_left = clocks_left; diff --git a/src/devices/sound/upd7759.h b/src/devices/sound/upd7759.h index 813f5270d89..ab1ff98e3a2 100644 --- a/src/devices/sound/upd7759.h +++ b/src/devices/sound/upd7759.h @@ -23,11 +23,23 @@ public: enum : u32 { STANDARD_CLOCK = 640'000 }; DECLARE_WRITE_LINE_MEMBER( reset_w ); + DECLARE_WRITE_LINE_MEMBER( start_w ); DECLARE_READ_LINE_MEMBER( busy_r ); virtual void port_w(u8 data); void set_start_delay(uint32_t data) { m_start_delay = data; }; protected: + virtual void internal_start_w(int state) = 0; + virtual void internal_reset_w(int state); + + enum + { + TID_PORT_WRITE, + TID_START_WRITE, + TID_RESET_WRITE, + TID_SLAVE_UPDATE + }; + // chip states enum { @@ -56,7 +68,7 @@ protected: virtual void rom_bank_updated() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; void update_adpcm(int data); virtual void advance_state(); @@ -110,14 +122,10 @@ public: upd7759_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = STANDARD_CLOCK); - DECLARE_WRITE_LINE_MEMBER( md_w ); - DECLARE_WRITE_LINE_MEMBER( start_w ); + DECLARE_WRITE_LINE_MEMBER( md_w ) { m_md = state; } protected: - enum - { - TIMER_SLAVE_UPDATE - }; + virtual void internal_start_w(int state) override; upd7759_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -136,9 +144,9 @@ public: virtual void device_reset() override; - DECLARE_WRITE_LINE_MEMBER( start_w ); - protected: + virtual void internal_start_w(int state) override; + upd7756_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); virtual void device_start() override; diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp index 75ba3fb4186..fecb6fc8a18 100644 --- a/src/devices/sound/upd934g.cpp +++ b/src/devices/sound/upd934g.cpp @@ -49,7 +49,7 @@ upd934g_device::upd934g_device(const machine_config &mconfig, const char *tag, d void upd934g_device::device_start() { // create sound stream - m_stream = machine().sound().stream_alloc(*this, 0, 4, 20000); + m_stream = stream_alloc_legacy(0, 4, 20000); // resolve callbacks m_data_cb.resolve_safe(0); @@ -81,11 +81,11 @@ void upd934g_device::device_reset() } //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void upd934g_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void upd934g_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (unsigned ch = 0; ch < 4; ch++) { diff --git a/src/devices/sound/upd934g.h b/src/devices/sound/upd934g.h index 9d872104617..ed145671c38 100644 --- a/src/devices/sound/upd934g.h +++ b/src/devices/sound/upd934g.h @@ -36,7 +36,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: devcb_read8 m_data_cb; diff --git a/src/devices/sound/vgm_visualizer.cpp b/src/devices/sound/vgm_visualizer.cpp index 129f84c0a5a..c1f438f2b2c 100644 --- a/src/devices/sound/vgm_visualizer.cpp +++ b/src/devices/sound/vgm_visualizer.cpp @@ -283,35 +283,25 @@ void vgmviz_device::cycle_viz_mode() // audio stream and process as necessary //------------------------------------------------- -void vgmviz_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void vgmviz_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - // clear output buffers - for (int output = 0; output < m_outputs; output++) - std::fill_n(outputs[output], samples, 0); + // call the normal interface to actually mix + device_mixer_interface::sound_stream_update(stream, inputs, outputs); - m_current_rate = stream.sample_rate(); - - // loop over samples - const u8 *outmap = &m_outputmap[0]; - - // for each input, add it to the appropriate output - for (int pos = 0; pos < samples; pos++) + // now consume the outputs + for (int pos = 0; pos < outputs[0].samples(); pos++) { - for (int inp = 0; inp < m_auto_allocated_inputs; inp++) - { - outputs[outmap[inp]][pos] += inputs[inp][pos]; - } - - for (int i = 0; i < m_outputs; i++) + for (int i = 0; i < outputs.size(); i++) { - const float sample = (float)(int16_t)outputs[i][pos] / 65336.0f; + // Original code took 16-bit sample / 65536.0 instead of 32768.0, so multiply by 0.5 here but is it necessary? + const float sample = outputs[i].get(pos) * 0.5f; m_audio_buf[m_audio_fill_index][i][m_audio_count[m_audio_fill_index]] = sample + 0.5f; } switch (m_viz_mode) { default: - update_waveform(outputs); + update_waveform(); break; case VIZ_WATERFALL: case VIZ_RAW_SPEC: @@ -325,7 +315,7 @@ void vgmviz_device::sound_stream_update(sound_stream &stream, stream_sample_t ** case VIZ_TOP_SPEC4: case VIZ_TOP_SPEC8: case VIZ_TOP_SPEC16: - update_fft(outputs); + update_fft(); break; } } @@ -336,7 +326,7 @@ void vgmviz_device::sound_stream_update(sound_stream &stream, stream_sample_t ** // update_waveform - perform a wave-style update //------------------------------------------------- -void vgmviz_device::update_waveform(stream_sample_t **outputs) +void vgmviz_device::update_waveform() { m_history_length++; m_audio_count[m_audio_fill_index]++; @@ -355,7 +345,7 @@ void vgmviz_device::update_waveform(stream_sample_t **outputs) // update_fft - keep the FFT up-to-date //------------------------------------------------- -void vgmviz_device::update_fft(stream_sample_t **outputs) +void vgmviz_device::update_fft() { m_audio_count[m_audio_fill_index]++; if (m_audio_count[m_audio_fill_index] >= FFT_LENGTH) diff --git a/src/devices/sound/vgm_visualizer.h b/src/devices/sound/vgm_visualizer.h index 8455b3d2bc0..516e4e4bfad 100644 --- a/src/devices/sound/vgm_visualizer.h +++ b/src/devices/sound/vgm_visualizer.h @@ -91,10 +91,10 @@ protected: virtual void device_reset() override; // device_sound_interface-level overrides - void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; - void update_waveform(stream_sample_t **outputs); - void update_fft(stream_sample_t **outputs); + void update_waveform(); + void update_fft(); void init_palette(palette_device &palette) const; diff --git a/src/devices/sound/vlm5030.cpp b/src/devices/sound/vlm5030.cpp index 0d71f7e60b9..3d3cc7863fd 100644 --- a/src/devices/sound/vlm5030.cpp +++ b/src/devices/sound/vlm5030.cpp @@ -214,7 +214,7 @@ void vlm5030_device::device_start() device_reset(); m_phase = PH_IDLE; - m_channel = machine().sound().stream_alloc(*this, 0, 1, clock() / 440); + m_channel = stream_alloc_legacy(0, 1, clock() / 440); save_item(NAME(m_address)); save_item(NAME(m_pin_BSY)); @@ -491,10 +491,10 @@ if( m_interp_step != 1) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void vlm5030_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void vlm5030_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int buf_count=0; int interp_effect; diff --git a/src/devices/sound/vlm5030.h b/src/devices/sound/vlm5030.h index 891fb7ca595..7520bf76007 100644 --- a/src/devices/sound/vlm5030.h +++ b/src/devices/sound/vlm5030.h @@ -34,7 +34,7 @@ protected: virtual void device_post_load() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/volt_reg.cpp b/src/devices/sound/volt_reg.cpp index dbd922a808f..48693204e46 100644 --- a/src/devices/sound/volt_reg.cpp +++ b/src/devices/sound/volt_reg.cpp @@ -21,19 +21,16 @@ voltage_regulator_device::voltage_regulator_device(const machine_config &mconfig device_t(mconfig, VOLTAGE_REGULATOR, tag, owner, clock), device_sound_interface(mconfig, *this), m_stream(nullptr), - m_output(0x7fff) + m_output(1.0) { } void voltage_regulator_device::device_start() { - m_stream = stream_alloc(0, 1, 48000 * 4); + m_stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE); } -void voltage_regulator_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void voltage_regulator_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for (int samp = 0; samp < samples; samp++) - { - outputs[0][samp] = m_output; - } + outputs[0].fill(m_output); } diff --git a/src/devices/sound/volt_reg.h b/src/devices/sound/volt_reg.h index 516039aac17..c672878fd4b 100644 --- a/src/devices/sound/volt_reg.h +++ b/src/devices/sound/volt_reg.h @@ -17,7 +17,7 @@ class voltage_regulator_device : public device_t, public device_sound_interface { public: - voltage_regulator_device &set_output(double analogue_dc) { m_output = (analogue_dc * 0x7fff) / 5.0f; return *this; } + voltage_regulator_device &set_output(double analogue_dc) { m_output = analogue_dc / 5.0f; return *this; } voltage_regulator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); @@ -28,11 +28,11 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: sound_stream* m_stream; - stream_sample_t m_output; + stream_buffer::sample_t m_output; }; DECLARE_DEVICE_TYPE(VOLTAGE_REGULATOR, voltage_regulator_device) diff --git a/src/devices/sound/votrax.cpp b/src/devices/sound/votrax.cpp index 8b416da6188..000a568d2a3 100644 --- a/src/devices/sound/votrax.cpp +++ b/src/devices/sound/votrax.cpp @@ -131,13 +131,13 @@ void votrax_sc01_device::inflection_w(uint8_t data) // for our sound stream //------------------------------------------------- -void votrax_sc01_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void votrax_sc01_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { - for(int i=0; i<samples; i++) { + for(int i=0; i<outputs[0].samples(); i++) { m_sample_count++; if(m_sample_count & 1) chip_update(); - outputs[0][i] = analog_calc(); + outputs[0].put(i, analog_calc()); } } @@ -568,7 +568,7 @@ void votrax_sc01_device::filters_commit(bool force) m_filt_fa, m_filt_va, m_filt_fc, m_filt_f1, m_filt_f2, m_filt_f2q, m_filt_f3); } -stream_sample_t votrax_sc01_device::analog_calc() +stream_buffer::sample_t votrax_sc01_device::analog_calc() { // Voice-only path. // 1. Pick up the pitch wave @@ -632,7 +632,7 @@ stream_sample_t votrax_sc01_device::analog_calc() vn = apply_filter(m_vn_5, m_vn_6, m_fx_a, m_fx_b); shift_hist(vn, m_vn_6); - return int(vn*50000); + return vn*1.5; } /* diff --git a/src/devices/sound/votrax.h b/src/devices/sound/votrax.h index aa3b88cc7e3..19d98ca1da7 100644 --- a/src/devices/sound/votrax.h +++ b/src/devices/sound/votrax.h @@ -37,7 +37,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; private: // Possible timer parameters @@ -177,7 +177,7 @@ private: void chip_update(); // Global update called at 20KHz (main/36) void filters_commit(bool force); // Commit the currently computed interpolation values to the filters void phone_commit(); // Commit the current phone id - stream_sample_t analog_calc(); // Compute one more sample + stream_buffer::sample_t analog_calc(); // Compute one more sample }; diff --git a/src/devices/sound/vrc6.cpp b/src/devices/sound/vrc6.cpp index 237a8487bc9..58022411766 100644 --- a/src/devices/sound/vrc6.cpp +++ b/src/devices/sound/vrc6.cpp @@ -45,7 +45,7 @@ vrc6snd_device::vrc6snd_device(const machine_config &mconfig, const char *tag, d void vrc6snd_device::device_start() { - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()); + m_stream = stream_alloc_legacy(0, 1, clock()); m_freqctrl = m_pulsectrl[0] = m_pulsectrl[1] = 0; m_pulsefrql[0] = m_pulsefrql[1] = m_pulsefrqh[0] = m_pulsefrqh[1] = 0; @@ -89,11 +89,11 @@ void vrc6snd_device::device_reset() } //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void vrc6snd_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { std::fill_n(&outputs[0][0], samples, 0); diff --git a/src/devices/sound/vrc6.h b/src/devices/sound/vrc6.h index f1ea8f5c9e3..0c1dd422d14 100644 --- a/src/devices/sound/vrc6.h +++ b/src/devices/sound/vrc6.h @@ -31,7 +31,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: u8 m_freqctrl, m_pulsectrl[2], m_sawrate, m_master_freq; diff --git a/src/devices/sound/vrender0.cpp b/src/devices/sound/vrender0.cpp index 370bc2f44e0..09fb0f14940 100644 --- a/src/devices/sound/vrender0.cpp +++ b/src/devices/sound/vrender0.cpp @@ -148,7 +148,7 @@ void vr0sound_device::device_start() for (auto &elem : m_channel) elem.Cache = &m_fbcache; - m_stream = stream_alloc(0, 2, clock() / 972); // TODO : Correct source / divider? + m_stream = stream_alloc_legacy(0, 2, clock() / 972); // TODO : Correct source / divider? save_item(STRUCT_MEMBER(m_channel, CurSAddr)); save_item(STRUCT_MEMBER(m_channel, EnvVol)); @@ -208,11 +208,11 @@ device_memory_interface::space_config_vector vr0sound_device::memory_space_confi } //------------------------------------------------- -// sound_stream_update - handle update requests +// sound_stream_update_legacy - handle update requests // for our sound stream //------------------------------------------------- -void vr0sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void vr0sound_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { VR0_RenderAudio(samples, outputs[0], outputs[1]); } diff --git a/src/devices/sound/vrender0.h b/src/devices/sound/vrender0.h index 324276b8ff0..99e2235a1be 100644 --- a/src/devices/sound/vrender0.h +++ b/src/devices/sound/vrender0.h @@ -78,7 +78,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_memory_interface configuration virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/sound/wave.cpp b/src/devices/sound/wave.cpp index 6506ef41d13..27407a2dbd2 100644 --- a/src/devices/sound/wave.cpp +++ b/src/devices/sound/wave.cpp @@ -43,16 +43,16 @@ void wave_device::device_start() speaker_device_iterator spkiter(*owner()); int speakers = spkiter.count(); if (speakers > 1) - machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate()); + stream_alloc_legacy(0, 2, machine().sample_rate()); else - machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + stream_alloc_legacy(0, 1, machine().sample_rate()); } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void wave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void wave_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *left_buffer = outputs[0]; stream_sample_t *right_buffer = nullptr; diff --git a/src/devices/sound/wave.h b/src/devices/sound/wave.h index fe5cf6b51a2..9f2a834d6c1 100644 --- a/src/devices/sound/wave.h +++ b/src/devices/sound/wave.h @@ -30,7 +30,7 @@ protected: virtual void device_start() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: required_device<cassette_image_device> m_cass; diff --git a/src/devices/sound/x1_010.cpp b/src/devices/sound/x1_010.cpp index fdb824c0df7..8334db4a299 100644 --- a/src/devices/sound/x1_010.cpp +++ b/src/devices/sound/x1_010.cpp @@ -119,7 +119,7 @@ void x1_010_device::device_start() LOG_SOUND("masterclock = %d rate = %d\n", clock(), m_rate); /* get stream channels */ - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_rate); + m_stream = stream_alloc_legacy(0, 2, m_rate); m_reg = make_unique_clear<u8[]>(0x2000); m_HI_WORD_BUF = make_unique_clear<u8[]>(0x2000); @@ -204,10 +204,10 @@ void x1_010_device::word_w(offs_t offset, u16 data) //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void x1_010_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void x1_010_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { // mixer buffer zero clear memset(outputs[0], 0, samples*sizeof(*outputs[0])); diff --git a/src/devices/sound/x1_010.h b/src/devices/sound/x1_010.h index 1664e2abd4c..3c8f1e60dc6 100644 --- a/src/devices/sound/x1_010.h +++ b/src/devices/sound/x1_010.h @@ -26,7 +26,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp index 744fec923ad..b519d9a1224 100644 --- a/src/devices/sound/ym2151.cpp +++ b/src/devices/sound/ym2151.cpp @@ -1836,16 +1836,17 @@ WRITE_LINE_MEMBER(ym2151_device::reset_w) // sound_stream_update - handle a stream update //------------------------------------------------- -void ym2151_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2151_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { if (m_reset_active) { - std::fill(&outputs[0][0], &outputs[0][samples], 0); - std::fill(&outputs[1][0], &outputs[1][samples], 0); + outputs[0].fill(0); + outputs[1].fill(0); return; } - for (int i=0; i<samples; i++) + constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0; + for (int sampindex=0; sampindex<outputs[0].samples(); sampindex++) { advance_eg(); @@ -1871,8 +1872,8 @@ void ym2151_device::sound_stream_update(sound_stream &stream, stream_sample_t ** outr = 32767; else if (outr < -32768) outr = -32768; - outputs[0][i] = outl; - outputs[1][i] = outr; + outputs[0].put(sampindex, stream_buffer::sample_t(outl) * sample_scale); + outputs[1].put(sampindex, stream_buffer::sample_t(outr) * sample_scale); advance(); } diff --git a/src/devices/sound/ym2151.h b/src/devices/sound/ym2151.h index 51020ec12d2..3f3f07bae91 100644 --- a/src/devices/sound/ym2151.h +++ b/src/devices/sound/ym2151.h @@ -75,7 +75,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void calculate_timers(); virtual void write_reg(int r, int v); diff --git a/src/devices/sound/ym2413.cpp b/src/devices/sound/ym2413.cpp index 0f78fad1daa..ca4a9acb874 100644 --- a/src/devices/sound/ym2413.cpp +++ b/src/devices/sound/ym2413.cpp @@ -1470,10 +1470,10 @@ void ym2413_device::write_reg(int r, int v) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ym2413_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ym2413_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for(int i=0; i < samples ; i++ ) { @@ -1511,7 +1511,7 @@ void ym2413_device::device_start() { int rate = clock()/72; - m_stream = machine().sound().stream_alloc(*this,0,2,rate); + m_stream = stream_alloc_legacy(0,2,rate); for (int x=0; x<TL_RES_LEN; x++) { diff --git a/src/devices/sound/ym2413.h b/src/devices/sound/ym2413.h index 52bd1907ecc..2e1db357150 100644 --- a/src/devices/sound/ym2413.h +++ b/src/devices/sound/ym2413.h @@ -25,7 +25,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; uint8_t m_inst_table[19][8]; diff --git a/src/devices/sound/ymf262.cpp b/src/devices/sound/ymf262.cpp index 2117b972dce..6ec8e081021 100644 --- a/src/devices/sound/ymf262.cpp +++ b/src/devices/sound/ymf262.cpp @@ -2618,7 +2618,7 @@ void ymf262_set_update_handler(void *chip, OPL3_UPDATEHANDLER UpdateHandler, dev ** '**buffers' is table of 4 pointers to the buffers: CH.A, CH.B, CH.C and CH.D ** 'length' is the number of samples that should be generated */ -void ymf262_update_one(void *_chip, OPL3SAMPLE **buffers, int length) +void ymf262_update_one(void *_chip, OPL3SAMPLE * const *buffers, int length) { int i; OPL3 *chip = (OPL3 *)_chip; diff --git a/src/devices/sound/ymf262.h b/src/devices/sound/ymf262.h index e7451216b95..d459a9a68ee 100644 --- a/src/devices/sound/ymf262.h +++ b/src/devices/sound/ymf262.h @@ -33,7 +33,7 @@ void ymf262_reset_chip(void *chip); int ymf262_write(void *chip, int a, int v); unsigned char ymf262_read(void *chip, int a); int ymf262_timer_over(void *chip, int c); -void ymf262_update_one(void *chip, OPL3SAMPLE **buffers, int length); +void ymf262_update_one(void *chip, OPL3SAMPLE * const *buffers, int length); void ymf262_set_timer_handler(void *chip, OPL3_TIMERHANDLER TimerHandler, device_t *device); void ymf262_set_irq_handler(void *chip, OPL3_IRQHANDLER IRQHandler, device_t *device); diff --git a/src/devices/sound/ymf271.cpp b/src/devices/sound/ymf271.cpp index 4032a2b6bd8..03ca33a2382 100644 --- a/src/devices/sound/ymf271.cpp +++ b/src/devices/sound/ymf271.cpp @@ -563,10 +563,10 @@ void ymf271_device::set_feedback(int slotnum, int64_t inp) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ymf271_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymf271_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i, j; int op; @@ -1748,7 +1748,7 @@ void ymf271_device::device_start() init_state(); m_mix_buffer.resize(m_master_clock/(384/4)); - m_stream = machine().sound().stream_alloc(*this, 0, 4, m_master_clock/384); + m_stream = stream_alloc_legacy(0, 4, m_master_clock/384); } //------------------------------------------------- diff --git a/src/devices/sound/ymf271.h b/src/devices/sound/ymf271.h index 18ddd4e7b67..87f06eb8e73 100644 --- a/src/devices/sound/ymf271.h +++ b/src/devices/sound/ymf271.h @@ -28,7 +28,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymf278b.cpp b/src/devices/sound/ymf278b.cpp index 4e8ed1005ee..7bda7b6b8ef 100644 --- a/src/devices/sound/ymf278b.cpp +++ b/src/devices/sound/ymf278b.cpp @@ -212,10 +212,10 @@ void ymf278b_device::compute_envelope(YMF278BSlot *slot) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ymf278b_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymf278b_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { int i, j; YMF278BSlot *slot; @@ -1009,7 +1009,7 @@ void ymf278b_device::device_start() m_slots[i].num = i; } - m_stream = machine().sound().stream_alloc(*this, 0, 6, m_rate); + m_stream = stream_alloc_legacy(0, 6, m_rate); m_mix_buffer.resize(m_rate*4,0); // rate tables diff --git a/src/devices/sound/ymf278b.h b/src/devices/sound/ymf278b.h index 039662fed1a..03fa9880442 100644 --- a/src/devices/sound/ymf278b.h +++ b/src/devices/sound/ymf278b.h @@ -29,7 +29,7 @@ protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymz280b.cpp b/src/devices/sound/ymz280b.cpp index f5a69bc6d37..94ef134bd4c 100644 --- a/src/devices/sound/ymz280b.cpp +++ b/src/devices/sound/ymz280b.cpp @@ -412,10 +412,10 @@ int ymz280b_device::generate_pcm16(struct YMZ280BVoice *voice, s16 *buffer, int //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void ymz280b_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymz280b_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *lacc = outputs[0]; stream_sample_t *racc = outputs[1]; @@ -565,7 +565,7 @@ void ymz280b_device::device_start() } /* create the stream */ - m_stream = machine().sound().stream_alloc(*this, 0, 2, INTERNAL_SAMPLE_RATE); + m_stream = stream_alloc_legacy(0, 2, INTERNAL_SAMPLE_RATE); /* allocate memory */ assert(MAX_SAMPLE_CHUNK < 0x10000); diff --git a/src/devices/sound/ymz280b.h b/src/devices/sound/ymz280b.h index a375f4a7ed0..ccbcb393bd8 100644 --- a/src/devices/sound/ymz280b.h +++ b/src/devices/sound/ymz280b.h @@ -36,7 +36,7 @@ protected: virtual void device_clock_changed() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; // device_rom_interface overrides virtual void rom_bank_updated() override; diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp index bba6ca59622..3934c6ac6dd 100644 --- a/src/devices/sound/ymz770.cpp +++ b/src/devices/sound/ymz770.cpp @@ -77,7 +77,7 @@ ymz770_device::ymz770_device(const machine_config &mconfig, device_type type, co void ymz770_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, m_sclock); + m_stream = stream_alloc_legacy(0, 2, m_sclock); for (auto & channel : m_channels) { @@ -178,11 +178,11 @@ void ymz770_device::device_reset() //------------------------------------------------- -// sound_stream_update - handle update requests for +// sound_stream_update_legacy - handle update requests for // our sound stream //------------------------------------------------- -void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void ymz770_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { stream_sample_t *outL, *outR; diff --git a/src/devices/sound/ymz770.h b/src/devices/sound/ymz770.h index 6d322490e46..ade24f61501 100644 --- a/src/devices/sound/ymz770.h +++ b/src/devices/sound/ymz770.h @@ -33,7 +33,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void internal_reg_write(uint8_t reg, uint8_t data); virtual uint32_t get_phrase_offs(int phrase) { return m_rom[(4 * phrase) + 1] << 16 | m_rom[(4 * phrase) + 2] << 8 | m_rom[(4 * phrase) + 3]; }; diff --git a/src/devices/sound/zsg2.cpp b/src/devices/sound/zsg2.cpp index 3376f466b19..b964bce5f14 100644 --- a/src/devices/sound/zsg2.cpp +++ b/src/devices/sound/zsg2.cpp @@ -134,7 +134,7 @@ void zsg2_device::device_start() memset(&m_chan, 0, sizeof(m_chan)); - m_stream = stream_alloc(0, 4, clock() / 768); + m_stream = stream_alloc_legacy(0, 4, clock() / 768); m_mem_blocks = m_mem_base.length(); m_mem_copy = make_unique_clear<uint32_t[]>(m_mem_blocks); @@ -280,10 +280,10 @@ void zsg2_device::filter_samples(zchan *ch) } //------------------------------------------------- -// sound_stream_update - handle a stream update +// sound_stream_update_legacy - handle a stream update //------------------------------------------------- -void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void zsg2_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) { for (int i = 0; i < samples; i++) { diff --git a/src/devices/sound/zsg2.h b/src/devices/sound/zsg2.h index b0506927440..592cbf83787 100644 --- a/src/devices/sound/zsg2.h +++ b/src/devices/sound/zsg2.h @@ -29,7 +29,7 @@ protected: virtual void device_reset() override; // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; private: const uint16_t STATUS_ACTIVE = 0x8000; diff --git a/src/devices/video/i8244.cpp b/src/devices/video/i8244.cpp index 5e7893aa6ae..8288dd9e552 100644 --- a/src/devices/video/i8244.cpp +++ b/src/devices/video/i8244.cpp @@ -740,16 +740,16 @@ uint32_t i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap } -void i8244_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void i8244_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { u8 volume = m_vdc.s.sound & 0xf; - int sample_on = (m_sh_output & m_vdc.s.sound >> 7) * 0x4000; + stream_buffer::sample_t sample_on = (m_sh_output & m_vdc.s.sound >> 7) * 0.5; - for (int i = 0; i < samples; i++) + for (int i = 0; i < outputs[0].samples(); i++) { // clock duty cycle m_sh_duty = (m_sh_duty + 1) & 0xf; - outputs[0][i] = (m_sh_duty < volume) ? sample_on : 0; + outputs[0].put(i, (m_sh_duty < volume) ? sample_on : 0.0); } } diff --git a/src/devices/video/i8244.h b/src/devices/video/i8244.h index c46034dd2b4..3568f5a613d 100644 --- a/src/devices/video/i8244.h +++ b/src/devices/video/i8244.h @@ -97,11 +97,10 @@ protected: virtual const tiny_rom_entry *device_rom_region() const override; // device_sound_interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; virtual void set_default_params(); - //void render_scanline(int vpos); int get_y_beam(); int get_x_beam(); offs_t fix_register_mirrors( offs_t offset ); diff --git a/src/devices/video/pwm.cpp b/src/devices/video/pwm.cpp index 50b608759ef..453216ded7d 100644 --- a/src/devices/video/pwm.cpp +++ b/src/devices/video/pwm.cpp @@ -6,7 +6,7 @@ This thing is a generic helper for PWM(strobed) display elements, to prevent fli and optionally handle perceived brightness levels. Common usecase is to call matrix(selmask, datamask), a collision between the 2 masks -implies a powered-on display element (eg, a LED, or VFD sprite). The maximum matrix +implies a powered-on display element (eg. a LED, or VFD sprite). The maximum matrix size is 64 by 64, simply due to uint64_t constraints. If a larger size is needed, create an array of pwm_display_device. @@ -112,8 +112,7 @@ void pwm_display_device::device_start() save_item(NAME(m_bri)); save_item(NAME(m_update_time)); - save_item(NAME(m_acc_attos)); - save_item(NAME(m_acc_secs)); + save_item(NAME(m_acc)); } void pwm_display_device::device_reset() @@ -128,29 +127,6 @@ void pwm_display_device::device_reset() //------------------------------------------------- -// custom savestate handling (MAME doesn't save array of attotime) -//------------------------------------------------- - -void pwm_display_device::device_pre_save() -{ - for (int y = 0; y < ARRAY_LENGTH(m_acc); y++) - for (int x = 0; x < ARRAY_LENGTH(m_acc[0]); x++) - { - m_acc_attos[y][x] = m_acc[y][x].attoseconds(); - m_acc_secs[y][x] = m_acc[y][x].seconds(); - } -} - -void pwm_display_device::device_post_load() -{ - for (int y = 0; y < ARRAY_LENGTH(m_acc); y++) - for (int x = 0; x < ARRAY_LENGTH(m_acc[0]); x++) - m_acc[y][x] = attotime(m_acc_secs[y][x], m_acc_attos[y][x]); -} - - - -//------------------------------------------------- // public handlers (most of the interface is in the .h file) //------------------------------------------------- diff --git a/src/devices/video/pwm.h b/src/devices/video/pwm.h index 4fba10e00d4..91a04b06620 100644 --- a/src/devices/video/pwm.h +++ b/src/devices/video/pwm.h @@ -59,8 +59,6 @@ protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; - virtual void device_pre_save() override; - virtual void device_post_load() override; private: output_finder<0x40, 0x40> m_out_x; @@ -90,8 +88,6 @@ private: double m_bri[0x40][0x41]; attotime m_update_time; attotime m_acc[0x40][0x41]; - attoseconds_t m_acc_attos[0x40][0x41]; - seconds_t m_acc_secs[0x40][0x41]; emu_timer *m_frame_timer; TIMER_CALLBACK_MEMBER(frame_tick); |