mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +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;
|
||||
}
|
||||
|
||||
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:
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user