summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2021-04-01 22:23:29 +0200
committer hap <happppp@users.noreply.github.com>2021-04-01 22:23:29 +0200
commit289efafb392c7d0407b302bf21b202cc642f992f (patch)
tree59f8583a0838f6e6bebc226138e76ecb6b3bcb77
parent0d897d07e65826352fba147ce644a901b2cce7bc (diff)
multipcm: retrigger after writing to sample register if key is on (YMF278 also does this) [dink, hap]
-rw-r--r--src/devices/sound/multipcm.cpp58
-rw-r--r--src/devices/sound/multipcm.h1
-rw-r--r--src/devices/sound/ymf278b.cpp6
-rw-r--r--src/devices/sound/ymf278b.h2
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();