From 289efafb392c7d0407b302bf21b202cc642f992f Mon Sep 17 00:00:00 2001 From: hap Date: Thu, 1 Apr 2021 22:23:29 +0200 Subject: multipcm: retrigger after writing to sample register if key is on (YMF278 also does this) [dink, hap] --- src/devices/sound/multipcm.cpp | 58 ++++++++++++++++++++++++------------------ src/devices/sound/multipcm.h | 1 + src/devices/sound/ymf278b.cpp | 6 ++--- src/devices/sound/ymf278b.h | 2 +- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/devices/sound/multipcm.cpp b/src/devices/sound/multipcm.cpp index 1f3b86d83b5..6f12ccf37c0 100644 --- a/src/devices/sound/multipcm.cpp +++ b/src/devices/sound/multipcm.cpp @@ -95,6 +95,21 @@ void multipcm_device::init_sample(sample_t *sample, uint32_t index) sample->m_lfo_amplitude_reg = read_byte(address + 11) & 0xf; } +void multipcm_device::retrigger_sample(slot_t &slot) +{ + slot.m_offset = 0; + slot.m_prev_sample = 0; + slot.m_total_level = slot.m_dest_total_level << TL_SHIFT; + + envelope_generator_calc(slot); + slot.m_envelope_gen.m_state = state_t::ATTACK; + slot.m_envelope_gen.m_volume = 0; + +#if MULTIPCM_LOG_SAMPLES + dump_sample(slot); +#endif +} + int32_t multipcm_device::envelope_generator_update(slot_t &slot) { switch(slot.m_envelope_gen.m_state) @@ -334,15 +349,21 @@ void multipcm_device::write_slot(slot_t &slot, int32_t reg, uint8_t data) case 1: // Sample { - //according to YMF278 sample write causes some base params written to the regs (envelope+lfos) - //the game should never change the sample while playing. - sample_t sample; - init_sample(&sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8)); - write_slot(slot, 6, sample.m_lfo_vibrato_reg); - write_slot(slot, 7, sample.m_lfo_amplitude_reg); + // according to YMF278 sample write causes some base params written to the regs (envelope+lfos) + init_sample(&slot.m_sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8)); + write_slot(slot, 6, slot.m_sample.m_lfo_vibrato_reg); + write_slot(slot, 7, slot.m_sample.m_lfo_amplitude_reg); + + slot.m_base = slot.m_sample.m_start; + slot.m_format = slot.m_sample.m_format; + + // retrigger if key is on + if (slot.m_playing) + retrigger_sample(slot); + break; } - case 2: //Pitch + case 2: // Pitch case 3: { uint32_t oct = ((slot.m_regs[3] >> 4) - 1) & 0xf; @@ -359,24 +380,11 @@ void multipcm_device::write_slot(slot_t &slot, int32_t reg, uint8_t data) slot.m_step = pitch / m_rate; } break; - case 4: //KeyOn/Off (and more?) - if (data & 0x80) //KeyOn + case 4: // KeyOn/Off + if (data & 0x80) // KeyOn { - init_sample(&slot.m_sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8)); slot.m_playing = true; - slot.m_base = slot.m_sample.m_start; - slot.m_offset = 0; - slot.m_prev_sample = 0; - slot.m_total_level = slot.m_dest_total_level << TL_SHIFT; - slot.m_format = slot.m_sample.m_format; - - envelope_generator_calc(slot); - slot.m_envelope_gen.m_state = state_t::ATTACK; - slot.m_envelope_gen.m_volume = 0; - -#if MULTIPCM_LOG_SAMPLES - dump_sample(slot); -#endif + retrigger_sample(slot); } else { @@ -395,7 +403,7 @@ void multipcm_device::write_slot(slot_t &slot, int32_t reg, uint8_t data) break; case 5: // TL + Interpolation slot.m_dest_total_level = (data >> 1) & 0x7f; - if (!(data & 1)) //Interpolate TL + if (!(data & 1)) // Interpolate TL { if ((slot.m_total_level >> TL_SHIFT) > slot.m_dest_total_level) { @@ -437,7 +445,7 @@ void multipcm_device::write(offs_t offset, uint8_t data) { switch(offset) { - case 0: //Data write + case 0: // Data write write_slot(m_slots[m_cur_slot], m_address, data); break; case 1: diff --git a/src/devices/sound/multipcm.h b/src/devices/sound/multipcm.h index 1349c8cf980..27f5f6d5de0 100644 --- a/src/devices/sound/multipcm.h +++ b/src/devices/sound/multipcm.h @@ -123,6 +123,7 @@ private: uint32_t value_to_fixed(const uint32_t bits, const float value); void init_sample(sample_t *sample, uint32_t index); + void retrigger_sample(slot_t &slot); // Internal LFO functions void lfo_init(); diff --git a/src/devices/sound/ymf278b.cpp b/src/devices/sound/ymf278b.cpp index 50f655f1942..042b8951022 100644 --- a/src/devices/sound/ymf278b.cpp +++ b/src/devices/sound/ymf278b.cpp @@ -459,7 +459,7 @@ void ymf278b_device::B_w(uint8_t reg, uint8_t data) } } -void ymf278b_device::retrigger_note(YMF278BSlot *slot) +void ymf278b_device::retrigger_sample(YMF278BSlot *slot) { // activate channel if (slot->octave != 8) @@ -521,7 +521,7 @@ void ymf278b_device::C_w(uint8_t reg, uint8_t data) // retrigger if key is on if (slot->KEY_ON) - retrigger_note(slot); + retrigger_sample(slot); else if (slot->active) { // deactivate channel @@ -589,7 +589,7 @@ void ymf278b_device::C_w(uint8_t reg, uint8_t data) break; } - retrigger_note(slot); + retrigger_sample(slot); } else if (slot->active) { diff --git a/src/devices/sound/ymf278b.h b/src/devices/sound/ymf278b.h index d872ce13e38..2d20ad253bf 100644 --- a/src/devices/sound/ymf278b.h +++ b/src/devices/sound/ymf278b.h @@ -83,7 +83,7 @@ private: void irq_check(); void A_w(uint8_t reg, uint8_t data); void B_w(uint8_t reg, uint8_t data); - void retrigger_note(YMF278BSlot *slot); + void retrigger_sample(YMF278BSlot *slot); void C_w(uint8_t reg, uint8_t data); void timer_busy_start(int is_pcm); void precompute_rate_tables(); -- cgit v1.2.3