diff --git a/src/mame/philips/cdi.h b/src/mame/philips/cdi.h index 92b696f29f8d8..6a65476740f2b 100644 --- a/src/mame/philips/cdi.h +++ b/src/mame/philips/cdi.h @@ -21,6 +21,7 @@ class cdi_state : public driver_device public: cdi_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) + , m_cdic(*this, "cdic") , m_maincpu(*this, "maincpu") , m_main_rom(*this, "maincpu") , m_lcd(*this, "lcd") @@ -28,7 +29,6 @@ class cdi_state : public driver_device , m_plane_ram(*this, "plane%u", 0U) , m_servo(*this, "servo") , m_slave(*this, "slave") - , m_cdic(*this, "cdic") , m_cdrom(*this, "cdrom") , m_mcd212(*this, "mcd212") , m_dmadac(*this, "dac%u", 1U) @@ -39,6 +39,7 @@ class cdi_state : public driver_device void cdimono2(machine_config &config); void cdi910(machine_config &config); + optional_device m_cdic; protected: enum servo_portc_bit_t { @@ -54,7 +55,6 @@ class cdi_state : public driver_device required_shared_ptr_array m_plane_ram; optional_device m_servo; optional_device m_slave; - optional_device m_cdic; required_device m_cdrom; required_device m_mcd212; diff --git a/src/mame/philips/cdicdic.cpp b/src/mame/philips/cdicdic.cpp index a71078c9b1912..1c7ddf94223b2 100644 --- a/src/mame/philips/cdicdic.cpp +++ b/src/mame/philips/cdicdic.cpp @@ -318,50 +318,33 @@ void cdicdic_device::play_raw_group(const uint8_t *data) m_dmadac[1]->transfer(0, 1, 1, 28, samples); } -void cdicdic_device::play_xa_group(const uint8_t coding, const uint8_t *data) +void cdicdic_device::play_xa_group(const uint8_t coding, const uint8_t *data, const uint16_t idx) { - static const uint16_t s_4bit_header_offsets[8] = { 4, 5, 6, 7, 12, 13, 14, 15 }; - static const uint16_t s_8bit_header_offsets[4] = { 4, 5, 6, 7 }; - static const uint16_t s_4bit_data_offsets[8] = { 16, 16, 17, 17, 18, 18, 19, 19 }; - static const uint16_t s_8bit_data_offsets[4] = { 16, 17, 18, 19 }; - - int16_t samples[28]; - - switch (coding & (CODING_BPS_MASK | CODING_CHAN_MASK)) + static const uint16_t HEADER_OFFSET_4BIT[8] = { 4, 5, 6, 7, 12, 13, 14, 15 }; + static const uint16_t HEADER_OFFSET_8BIT[4] = { 4, 5, 6, 7 }; + static const uint16_t DATA_OFFSET_4BIT[8] = { 16, 16, 17, 17, 18, 18, 19, 19 }; + static const uint16_t DATA_OFFSET_8BIT[4] = { 16, 17, 18, 19 }; + uint8_t num_samples = coding & CODING_8BPS ? 4 : 8; + for (uint8_t i = 0; i < num_samples; i++) { + switch (coding & (CODING_BPS_MASK | CODING_CHAN_MASK)) + { case CODING_4BPS | CODING_MONO: - for (uint8_t i = 0; i < 8; i++) - { - decode_4bit_xa_unit(0, data[s_4bit_header_offsets[i]], data + s_4bit_data_offsets[i], (i & 1) ? 4 : 0, samples); - m_dmadac[0]->transfer(0, 1, 1, 28, samples); - m_dmadac[1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_4bit_xa_unit(0, data[HEADER_OFFSET_4BIT[i]], data + DATA_OFFSET_4BIT[i], (i & 1) ? 4 : 0, &m_samples[0][idx + i * 28]); + break; case CODING_4BPS | CODING_STEREO: - for (uint8_t i = 0; i < 8; i++) - { - decode_4bit_xa_unit(i & 1, data[s_4bit_header_offsets[i]], data + s_4bit_data_offsets[i], (i & 1) ? 4 : 0, samples); - m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_4bit_xa_unit(i & 1, data[HEADER_OFFSET_4BIT[i]], data + DATA_OFFSET_4BIT[i], (i & 1) ? 4 : 0, &m_samples[i & 1][idx + (i >> 1) * 28]); + break; case CODING_8BPS | CODING_MONO: - for (uint8_t i = 0; i < 4; i++) - { - decode_8bit_xa_unit(0, data[s_8bit_header_offsets[i]], data + s_8bit_data_offsets[i], samples); - m_dmadac[0]->transfer(0, 1, 1, 28, samples); - m_dmadac[1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_8bit_xa_unit(0, data[HEADER_OFFSET_8BIT[i]], data + DATA_OFFSET_8BIT[i], &m_samples[0][idx + i * 28]); + break; case CODING_8BPS | CODING_STEREO: - for (uint8_t i = 0; i < 4; i++) - { - decode_8bit_xa_unit(i & 1, data[s_8bit_header_offsets[i]], data + s_8bit_data_offsets[i], samples); - m_dmadac[i & 1]->transfer(0, 1, 1, 28, samples); - } - return; + decode_8bit_xa_unit(i & 1, data[HEADER_OFFSET_8BIT[i]], data + DATA_OFFSET_8BIT[i], &m_samples[i & 1][idx + (i >> 1) * 28]); + break; + } } } @@ -377,10 +360,12 @@ void cdicdic_device::play_cdda_sector(const uint8_t *data) { samples[0][i] = (int16_t)((data[(i * 4) + 1] << 8) | data[(i * 4) + 0]); samples[1][i] = (int16_t)((data[(i * 4) + 3] << 8) | data[(i * 4) + 2]); + m_samples[0][i] = samples[0][i]; + m_samples[1][i] = samples[1][i]; } - m_dmadac[0]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[0]); - m_dmadac[1]->transfer(0, 1, 1, SECTOR_SIZE/4, samples[1]); + m_dmadac[0]->transfer(0, 1, 1, SECTOR_SIZE / 4, &m_samples[0][0]); + m_dmadac[1]->transfer(0, 1, 1, SECTOR_SIZE / 4, &m_samples[1][0]); } void cdicdic_device::play_audio_sector(const uint8_t coding, const uint8_t *data) @@ -439,6 +424,19 @@ void cdicdic_device::play_audio_sector(const uint8_t coding, const uint8_t *data m_dmadac[0]->set_volume(0x100); m_dmadac[1]->set_volume(0x100); + uint8_t num_samples = 4; + + switch (coding & (CODING_BPS_MASK | CODING_CHAN_MASK)) + { + case CODING_4BPS | CODING_MONO: + num_samples = 8; + break; + case CODING_8BPS | CODING_STEREO: + num_samples = 2; + break; + } + + if (bits == 16 && channels == 2) { for (uint16_t i = 0; i < SECTOR_AUDIO_SIZE; i += 112, data += 112) @@ -448,13 +446,38 @@ void cdicdic_device::play_audio_sector(const uint8_t coding, const uint8_t *data } else { + uint16_t offset = 0; for (uint16_t i = 0; i < SECTOR_AUDIO_SIZE; i += 128, data += 128) { - play_xa_group(coding, data); + play_xa_group(coding, data, offset); + offset += 28 * num_samples; + } + int16_t sampleL = 0, sampleR = 0, outL = 0, outR = 0; + for (uint16_t i = 0; i < 18 * 28 * num_samples; i++) + { + sampleL = m_samples[0][i]; + sampleR = m_samples[coding & CODING_STEREO][i]; + + float scaleLL = powf(10.0f, -m_atten[0] / 20.0f); + float scaleLR = powf(10.0f, -m_atten[1] / 20.0f); + float scaleRR = powf(10.0f, -m_atten[2] / 20.0f); + float scaleRL = powf(10.0f, -m_atten[3] / 20.0f); + outL = (sampleL * scaleLL + sampleR * scaleRL) * 0.5; + outR = (sampleL * scaleLR + sampleR * scaleRR) * 0.5; + m_dmadac[0]->transfer(0, 1, 1, 1, &outL); + m_dmadac[1]->transfer(0, 1, 1, 1, &outR); } } } +void cdicdic_device::atten_w(uint8_t* args) { + // TODO: The mutes here should be stored separately and used in the mixer directly. + m_atten[0] = ((args[0] & 0x8) << 7) | args[1]; + m_atten[1] = ((args[0] & 0x4) << 7) | args[2]; + m_atten[2] = ((args[0] & 0x2) << 7) | args[3]; + m_atten[3] = ((args[0] & 0x1) << 7) | args[4]; +} + TIMER_CALLBACK_MEMBER( cdicdic_device::audio_tick ) { if (m_audio_sector_counter > 0) @@ -1318,6 +1341,7 @@ void cdicdic_device::device_start() save_item(NAME(m_decode_addr)); save_item(NAME(m_xa_last)); + save_item(NAME(m_atten)); m_audio_timer = timer_alloc(FUNC(cdicdic_device::audio_tick), this); m_audio_timer->adjust(attotime::never); @@ -1364,7 +1388,8 @@ void cdicdic_device::device_reset() m_dmadac[0]->enable(1); m_dmadac[1]->enable(1); - std::fill_n(&m_xa_last[0], 4, 0); + std::fill_n(m_xa_last, 4, 0); + std::fill_n(m_atten, 4, 0); } void cdicdic_device::ram_w(offs_t offset, uint16_t data, uint16_t mem_mask) diff --git a/src/mame/philips/cdicdic.h b/src/mame/philips/cdicdic.h index d41018dc8310e..c362e2ec4c44d 100644 --- a/src/mame/philips/cdicdic.h +++ b/src/mame/philips/cdicdic.h @@ -58,6 +58,7 @@ class cdicdic_device : public device_t void ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint8_t intack_r(); + void atten_w(uint8_t* args); protected: // device_t implementation @@ -189,12 +190,13 @@ class cdicdic_device : public device_t int16_t m_xa_last[4]; std::unique_ptr m_ram; std::unique_ptr m_samples[2]; + uint8_t m_atten[4]; - void decode_xa_unit(const uint8_t param, int16_t sample, int16_t &sample0, int16_t &sample1, int16_t &out_buffer); + void decode_xa_unit(const uint8_t param, int16_t sample, int16_t& sample0, int16_t& sample1, int16_t& out_buffer); void decode_8bit_xa_unit(int channel, uint8_t param, const uint8_t *data, int16_t *out_buffer); void decode_4bit_xa_unit(int channel, uint8_t param, const uint8_t *data, uint8_t shift, int16_t *out_buffer); void play_raw_group(const uint8_t *data); - void play_xa_group(const uint8_t coding, const uint8_t *data); + void play_xa_group(const uint8_t coding, const uint8_t *data, const uint16_t idx); void play_audio_sector(const uint8_t coding, const uint8_t *data); void play_cdda_sector(const uint8_t *data); void process_audio_map(); diff --git a/src/mame/philips/cdislavehle.cpp b/src/mame/philips/cdislavehle.cpp index bb0b5e483b656..2c98288a60feb 100644 --- a/src/mame/philips/cdislavehle.cpp +++ b/src/mame/philips/cdislavehle.cpp @@ -29,6 +29,7 @@ #define VERBOSE (0) #include "logmacro.h" +#include "cdi.h" // device type definition DEFINE_DEVICE_TYPE(CDI_SLAVE_HLE, cdislave_hle_device, "cdislavehle", "CD-i Mono-I Slave HLE") @@ -227,6 +228,12 @@ void cdislave_hle_device::slave_w(offs_t offset, uint16_t data) { switch (m_in_buf[0]) { + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + dynamic_cast(m_owner)->m_cdic->atten_w(m_in_buf); + m_in_index = 0; + m_in_count = 0; + break; case 0xf0: // Set Front Panel LCD memset(m_in_buf + 1, 0, 16); m_in_count = 17; @@ -264,6 +271,13 @@ void cdislave_hle_device::slave_w(offs_t offset, uint16_t data) m_in_count = 0; break; } + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + { + LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Set Attenuation Audio\n", offset); + m_in_count = 5; + break; + } case 0xf0: // Set Front Panel LCD LOGMASKED(LOG_COMMANDS, "slave_w: Channel %d: Set Front Panel LCD (0xf0)\n", offset); m_in_count = 17;