Add reverse playback support

This commit is contained in:
cam900 2023-04-03 00:34:09 +09:00
parent 9b877764c4
commit 048728b496
6 changed files with 37 additions and 8 deletions

View File

@ -49,7 +49,7 @@ void k053260_core::voice_t::tick(u32 cycle)
if (m_bitpos < 8)
{
m_bitpos += 8;
m_addr = bitfield(m_addr + 1, 0, 21);
m_addr = m_reverse ? bitfield(m_addr - 1, 0, 21) : bitfield(m_addr + 1, 0, 21);
m_remain--;
if (m_remain < 0) // check end flag
{
@ -69,7 +69,7 @@ void k053260_core::voice_t::tick(u32 cycle)
if (m_adpcm)
{
m_bitpos -= 4;
const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM
const u8 nibble = bitfield(m_data, m_reverse ? (~m_bitpos & 4) : (m_bitpos & 4), 4); // get nibble from ROM
if (nibble)
{
m_output += m_host.adpcm_lut(nibble);
@ -169,6 +169,7 @@ void k053260_core::write(u8 address, u8 data)
case 0x28: // keyon/off toggle
for (int i = 0; i < 4; i++)
{
m_voice[i].set_reverse(bitfield(data, 4 + i));
if (bitfield(data, i) && (!m_voice[i].enable()))
{ // rising edge (keyon)
m_voice[i].keyon();
@ -276,6 +277,7 @@ void k053260_core::voice_t::reset()
m_loop = 0;
m_adpcm = 0;
m_pitch = 0;
m_reverse = 0;
m_start = 0;
m_length = 0;
m_volume = 0;

View File

@ -59,6 +59,7 @@ class k053260_core : public vgsound_emu_core
, m_loop(0)
, m_adpcm(0)
, m_pitch(0)
, m_reverse(0)
, m_start(0)
, m_length(0)
, m_volume(0)
@ -91,6 +92,11 @@ class k053260_core : public vgsound_emu_core
inline void set_adpcm(bool adpcm) { m_adpcm = adpcm ? 1 : 0; }
inline void set_reverse(const bool reverse)
{
m_reverse = reverse ? 1 : 0;
}
inline void length_inc() { m_length = (m_length + 1) & 0xffff; }
inline void set_pan(u8 pan) { m_pan = pan & 7; }
@ -114,10 +120,11 @@ class k053260_core : public vgsound_emu_core
u16 m_loop : 1; // loop flag
u16 m_adpcm : 1; // ADPCM flag
u16 m_pitch : 12; // pitch
u8 m_reverse : 1; // reverse playback
u32 m_start = 0; // start position
u16 m_length = 0; // source length
u8 m_volume = 0; // master volume
int m_pan = -1; // master pan
s32 m_pan = 4; // master pan
u16 m_counter = 0; // frequency counter
u32 m_addr = 0; // current address
s32 m_remain = 0; // remain for end sample

View File

@ -133,7 +133,7 @@ void DivPlatformK053260::tick(bool sysTick) {
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
unsigned char keyon=regPool[0x28]|(1<<i);
unsigned char keyoff=keyon&~(1<<i);
unsigned char keyoff=keyon&~(17<<i);
unsigned char loopon=regPool[0x2a]|(1<<i);
unsigned char loopoff=loopon&~(1<<i);
double off=1.0;
@ -155,10 +155,19 @@ void DivPlatformK053260::tick(bool sysTick) {
unsigned int length=0;
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
start=sampleOffK053260[chan[i].sample];
length=start+s->length8;
length=s->length8;
if (chan[i].reverse) {
start+=length;
keyon|=(16<<i);
}
}
if (chan[i].audPos>0) {
start=start+MIN(chan[i].audPos,s->length8);
if (chan[i].reverse) {
start=start-MIN(chan[i].audPos,s->length8);
}
else {
start=start+MIN(chan[i].audPos,s->length8);
}
length=MAX(1,length-chan[i].audPos);
}
start=MIN(start,getSampleMemCapacity());
@ -314,6 +323,12 @@ int DivPlatformK053260::dispatch(DivCommand c) {
chan[c.chan].audPos=c.value;
chan[c.chan].setPos=true;
break;
case DIV_CMD_SAMPLE_DIR: {
if (chan[c.chan].reverse!=(bool)(c.value&1)) {
chan[c.chan].reverse=c.value&1;
}
break;
}
case DIV_CMD_GET_VOLMAX:
return 127;
break;

View File

@ -29,7 +29,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
unsigned int audPos;
int sample, wave;
int panning;
bool setPos;
bool setPos, reverse;
int macroVolMul;
Channel():
SharedChannel<int>(127),
@ -38,6 +38,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
wave(-1),
panning(4),
setPos(false),
reverse(false),
macroVolMul(64) {}
};
Channel chan[4];

View File

@ -1862,7 +1862,10 @@ void DivEngine::registerSystems() {
{"CH1", "CH2", "CH3", "CH4"},
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
{DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260},
{DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}
{DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
{
{0xdf, {DIV_CMD_SAMPLE_DIR, "DFxx: Set sample playback direction (0: normal; 1: reverse)"}}
}
);
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(

View File

@ -1101,6 +1101,7 @@ void putDispatchChan(void* data, int chanNum, int type) {
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
COMMON_CHAN_DEBUG_BOOL;
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse");
break;
}
default: