mirror of
https://github.com/holub/mame
synced 2025-07-01 08:18:59 +03:00
multipcm: retrigger after writing to sample register if key is on (YMF278 also does this) [dink, hap]
This commit is contained in:
parent
0d897d07e6
commit
289efafb39
@ -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;
|
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)
|
int32_t multipcm_device::envelope_generator_update(slot_t &slot)
|
||||||
{
|
{
|
||||||
switch(slot.m_envelope_gen.m_state)
|
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
|
case 1: // Sample
|
||||||
{
|
{
|
||||||
//according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
|
// according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
|
||||||
//the game should never change the sample while playing.
|
init_sample(&slot.m_sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8));
|
||||||
sample_t sample;
|
write_slot(slot, 6, slot.m_sample.m_lfo_vibrato_reg);
|
||||||
init_sample(&sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8));
|
write_slot(slot, 7, slot.m_sample.m_lfo_amplitude_reg);
|
||||||
write_slot(slot, 6, sample.m_lfo_vibrato_reg);
|
|
||||||
write_slot(slot, 7, 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;
|
break;
|
||||||
}
|
}
|
||||||
case 2: //Pitch
|
case 2: // Pitch
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
uint32_t oct = ((slot.m_regs[3] >> 4) - 1) & 0xf;
|
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;
|
slot.m_step = pitch / m_rate;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: //KeyOn/Off (and more?)
|
case 4: // KeyOn/Off
|
||||||
if (data & 0x80) //KeyOn
|
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_playing = true;
|
||||||
slot.m_base = slot.m_sample.m_start;
|
retrigger_sample(slot);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -395,7 +403,7 @@ void multipcm_device::write_slot(slot_t &slot, int32_t reg, uint8_t data)
|
|||||||
break;
|
break;
|
||||||
case 5: // TL + Interpolation
|
case 5: // TL + Interpolation
|
||||||
slot.m_dest_total_level = (data >> 1) & 0x7f;
|
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)
|
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)
|
switch(offset)
|
||||||
{
|
{
|
||||||
case 0: //Data write
|
case 0: // Data write
|
||||||
write_slot(m_slots[m_cur_slot], m_address, data);
|
write_slot(m_slots[m_cur_slot], m_address, data);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -123,6 +123,7 @@ private:
|
|||||||
uint32_t value_to_fixed(const uint32_t bits, const float value);
|
uint32_t value_to_fixed(const uint32_t bits, const float value);
|
||||||
|
|
||||||
void init_sample(sample_t *sample, uint32_t index);
|
void init_sample(sample_t *sample, uint32_t index);
|
||||||
|
void retrigger_sample(slot_t &slot);
|
||||||
|
|
||||||
// Internal LFO functions
|
// Internal LFO functions
|
||||||
void lfo_init();
|
void lfo_init();
|
||||||
|
@ -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
|
// activate channel
|
||||||
if (slot->octave != 8)
|
if (slot->octave != 8)
|
||||||
@ -521,7 +521,7 @@ void ymf278b_device::C_w(uint8_t reg, uint8_t data)
|
|||||||
|
|
||||||
// retrigger if key is on
|
// retrigger if key is on
|
||||||
if (slot->KEY_ON)
|
if (slot->KEY_ON)
|
||||||
retrigger_note(slot);
|
retrigger_sample(slot);
|
||||||
else if (slot->active)
|
else if (slot->active)
|
||||||
{
|
{
|
||||||
// deactivate channel
|
// deactivate channel
|
||||||
@ -589,7 +589,7 @@ void ymf278b_device::C_w(uint8_t reg, uint8_t data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
retrigger_note(slot);
|
retrigger_sample(slot);
|
||||||
}
|
}
|
||||||
else if (slot->active)
|
else if (slot->active)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ private:
|
|||||||
void irq_check();
|
void irq_check();
|
||||||
void A_w(uint8_t reg, uint8_t data);
|
void A_w(uint8_t reg, uint8_t data);
|
||||||
void B_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 C_w(uint8_t reg, uint8_t data);
|
||||||
void timer_busy_start(int is_pcm);
|
void timer_busy_start(int is_pcm);
|
||||||
void precompute_rate_tables();
|
void precompute_rate_tables();
|
||||||
|
Loading…
Reference in New Issue
Block a user