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) if (m_bitpos < 8)
{ {
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--; m_remain--;
if (m_remain < 0) // check end flag if (m_remain < 0) // check end flag
{ {
@ -69,7 +69,7 @@ void k053260_core::voice_t::tick(u32 cycle)
if (m_adpcm) if (m_adpcm)
{ {
m_bitpos -= 4; 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) if (nibble)
{ {
m_output += m_host.adpcm_lut(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 case 0x28: // keyon/off toggle
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
m_voice[i].set_reverse(bitfield(data, 4 + i));
if (bitfield(data, i) && (!m_voice[i].enable())) if (bitfield(data, i) && (!m_voice[i].enable()))
{ // rising edge (keyon) { // rising edge (keyon)
m_voice[i].keyon(); m_voice[i].keyon();
@ -276,6 +277,7 @@ void k053260_core::voice_t::reset()
m_loop = 0; m_loop = 0;
m_adpcm = 0; m_adpcm = 0;
m_pitch = 0; m_pitch = 0;
m_reverse = 0;
m_start = 0; m_start = 0;
m_length = 0; m_length = 0;
m_volume = 0; m_volume = 0;

View File

@ -59,6 +59,7 @@ class k053260_core : public vgsound_emu_core
, m_loop(0) , m_loop(0)
, m_adpcm(0) , m_adpcm(0)
, m_pitch(0) , m_pitch(0)
, m_reverse(0)
, m_start(0) , m_start(0)
, m_length(0) , m_length(0)
, m_volume(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_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 length_inc() { m_length = (m_length + 1) & 0xffff; }
inline void set_pan(u8 pan) { m_pan = pan & 7; } 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_loop : 1; // loop flag
u16 m_adpcm : 1; // ADPCM flag u16 m_adpcm : 1; // ADPCM flag
u16 m_pitch : 12; // pitch u16 m_pitch : 12; // pitch
u8 m_reverse : 1; // reverse playback
u32 m_start = 0; // start position u32 m_start = 0; // start position
u16 m_length = 0; // source length u16 m_length = 0; // source length
u8 m_volume = 0; // master volume u8 m_volume = 0; // master volume
int m_pan = -1; // master pan s32 m_pan = 4; // master pan
u16 m_counter = 0; // frequency counter u16 m_counter = 0; // frequency counter
u32 m_addr = 0; // current address u32 m_addr = 0; // current address
s32 m_remain = 0; // remain for end sample 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) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
unsigned char keyon=regPool[0x28]|(1<<i); 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 loopon=regPool[0x2a]|(1<<i);
unsigned char loopoff=loopon&~(1<<i); unsigned char loopoff=loopon&~(1<<i);
double off=1.0; double off=1.0;
@ -155,10 +155,19 @@ void DivPlatformK053260::tick(bool sysTick) {
unsigned int length=0; unsigned int length=0;
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) { if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
start=sampleOffK053260[chan[i].sample]; 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) { 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); length=MAX(1,length-chan[i].audPos);
} }
start=MIN(start,getSampleMemCapacity()); start=MIN(start,getSampleMemCapacity());
@ -314,6 +323,12 @@ int DivPlatformK053260::dispatch(DivCommand c) {
chan[c.chan].audPos=c.value; chan[c.chan].audPos=c.value;
chan[c.chan].setPos=true; chan[c.chan].setPos=true;
break; 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: case DIV_CMD_GET_VOLMAX:
return 127; return 127;
break; break;

View File

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

View File

@ -1862,7 +1862,10 @@ void DivEngine::registerSystems() {
{"CH1", "CH2", "CH3", "CH4"}, {"CH1", "CH2", "CH3", "CH4"},
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {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_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( 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); ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
COMMON_CHAN_DEBUG_BOOL; COMMON_CHAN_DEBUG_BOOL;
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse");
break; break;
} }
default: default: