C140 fixes and optimizations
Minor optimization Move output shift function to dispatch Fix loop Fix pan scaling if using INS_AMIGA correct about
This commit is contained in:
parent
21d1dfefa1
commit
4d7d610f8c
|
@ -59,6 +59,9 @@ void DivPlatformC140::acquire(short** buf, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c140_tick(&c140, 1);
|
c140_tick(&c140, 1);
|
||||||
|
// scale as 16bit
|
||||||
|
c140.lout >>= 10;
|
||||||
|
c140.rout >>= 10;
|
||||||
|
|
||||||
if (c140.lout<-32768) c140.lout=-32768;
|
if (c140.lout<-32768) c140.lout=-32768;
|
||||||
if (c140.lout>32767) c140.lout=32767;
|
if (c140.lout>32767) c140.lout=32767;
|
||||||
|
@ -101,12 +104,12 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.panL.had) {
|
if (chan[i].std.panL.had) {
|
||||||
chan[i].chPanL=chan[i].std.panL.val&255;
|
chan[i].chPanL=(255*(chan[i].std.panL.val&255))/chan[i].macroPanMul;
|
||||||
chan[i].volChangedL=true;
|
chan[i].volChangedL=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.panR.had) {
|
if (chan[i].std.panR.had) {
|
||||||
chan[i].chPanR=chan[i].std.panR.val&255;
|
chan[i].chPanR=(255*(chan[i].std.panR.val&255))/chan[i].macroPanMul;
|
||||||
chan[i].volChangedR=true;
|
chan[i].volChangedR=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,13 +150,14 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
unsigned int end=0;
|
unsigned int end=0;
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
start=sampleOff[chan[i].sample];
|
start=sampleOff[chan[i].sample];
|
||||||
end=MIN(start+s->length8,getSampleMemCapacity()-1);
|
end=MIN(start+s->length8-1,65535);
|
||||||
}
|
}
|
||||||
if (chan[i].audPos>0) {
|
if (chan[i].audPos>0) {
|
||||||
start=start+MIN(chan[i].audPos,s->length8);
|
start=start+MIN(chan[i].audPos,s->length8);
|
||||||
}
|
}
|
||||||
if (s->isLoopable()) {
|
if (s->isLoopable()) {
|
||||||
loop=start+s->loopStart;
|
loop=MIN(start+s->loopStart,65535);
|
||||||
|
end=MIN(start+s->loopEnd-1,65535);
|
||||||
}
|
}
|
||||||
rWrite(0x05+(i<<4),0); // force keyoff first
|
rWrite(0x05+(i<<4),0); // force keyoff first
|
||||||
rWrite(0x06+(i<<4),(start>>8)&0xff);
|
rWrite(0x06+(i<<4),(start>>8)&0xff);
|
||||||
|
@ -187,6 +191,7 @@ int DivPlatformC140::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
|
||||||
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
|
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
|
||||||
|
chan[c.chan].macroPanMul=ins->type==DIV_INS_AMIGA?127:255;
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
chan[c.chan].sample=ins->amiga.getSample(c.value);
|
||||||
c.value=ins->amiga.getFreq(c.value);
|
c.value=ins->amiga.getFreq(c.value);
|
||||||
|
|
|
@ -32,6 +32,7 @@ class DivPlatformC140: public DivDispatch {
|
||||||
int chPanL, chPanR;
|
int chPanL, chPanR;
|
||||||
int chVolL, chVolR;
|
int chVolL, chVolR;
|
||||||
int macroVolMul;
|
int macroVolMul;
|
||||||
|
int macroPanMul;
|
||||||
Channel():
|
Channel():
|
||||||
SharedChannel<int>(255),
|
SharedChannel<int>(255),
|
||||||
audPos(0),
|
audPos(0),
|
||||||
|
@ -44,7 +45,8 @@ class DivPlatformC140: public DivDispatch {
|
||||||
chPanR(255),
|
chPanR(255),
|
||||||
chVolL(255),
|
chVolL(255),
|
||||||
chVolR(255),
|
chVolR(255),
|
||||||
macroVolMul(64) {}
|
macroVolMul(64),
|
||||||
|
macroPanMul(127) {}
|
||||||
};
|
};
|
||||||
Channel chan[24];
|
Channel chan[24];
|
||||||
DivDispatchOscBuffer* oscBuf[24];
|
DivDispatchOscBuffer* oscBuf[24];
|
||||||
|
|
|
@ -2,9 +2,13 @@
|
||||||
|
|
||||||
============================================================================
|
============================================================================
|
||||||
|
|
||||||
Namco C140 sound emulator
|
MODIFIED Namco C140 sound emulator - MODIFIED VERSION
|
||||||
by cam900
|
by cam900
|
||||||
|
|
||||||
|
MODIFICATION by tildearrow - adds muting function
|
||||||
|
THIS IS NOT THE ORIGINAL VERSION - you can find the original one in
|
||||||
|
commit 72d04777c013988ed8cf6da27c62a9d784a59dff
|
||||||
|
|
||||||
This file is licensed under zlib license.
|
This file is licensed under zlib license.
|
||||||
|
|
||||||
============================================================================
|
============================================================================
|
||||||
|
@ -52,58 +56,64 @@ void c140_tick(struct c140_t *c140, const int cycle)
|
||||||
for (int i = 0; i < 24; i++)
|
for (int i = 0; i < 24; i++)
|
||||||
{
|
{
|
||||||
c140_voice_tick(c140, i, cycle);
|
c140_voice_tick(c140, i, cycle);
|
||||||
if (!c140->voice[i].muted) {
|
c140->lout += c140->voice[i].lout;
|
||||||
c140->lout += c140->voice[i].lout;
|
c140->rout += c140->voice[i].rout;
|
||||||
c140->rout += c140->voice[i].rout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// scale as 16bit
|
|
||||||
c140->lout >>= 10;
|
|
||||||
c140->rout >>= 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void c140_voice_tick(struct c140_t *c140, const unsigned char voice, const int cycle)
|
void c140_voice_tick(struct c140_t *c140, const unsigned char v, const int cycle)
|
||||||
{
|
{
|
||||||
struct c140_voice_t *c140_voice = &c140->voice[voice];
|
struct c140_voice_t *voice = &c140->voice[v];
|
||||||
if (c140_voice->busy && c140_voice->keyon)
|
if (voice->busy && voice->keyon)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < cycle; c++)
|
for (int c = 0; c < cycle; c++)
|
||||||
{
|
{
|
||||||
c140_voice->frac += c140_voice->freq;
|
voice->frac += voice->freq;
|
||||||
if (c140_voice->frac > 0xffff)
|
if (voice->frac > 0xffff)
|
||||||
{
|
{
|
||||||
c140_voice->addr += c140_voice->frac >> 16;
|
voice->addr += voice->frac >> 16;
|
||||||
if (c140_voice->addr > c140_voice->end_addr)
|
if (voice->addr > voice->end_addr)
|
||||||
{
|
{
|
||||||
if (c140_voice->loop)
|
if (voice->loop)
|
||||||
{
|
{
|
||||||
c140_voice->addr = (c140_voice->addr + c140_voice->end_addr) - c140_voice->loop_addr;
|
voice->addr = (voice->addr + voice->loop_addr) - voice->end_addr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c140_voice->keyon = false;
|
voice->keyon = false;
|
||||||
|
voice->lout = 0;
|
||||||
|
voice->rout = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c140_voice->frac &= 0xffff;
|
voice->frac &= 0xffff;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!voice->muted)
|
||||||
|
{
|
||||||
// fetch 12 bit sample
|
// fetch 12 bit sample
|
||||||
signed short s1 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | c140_voice->addr] & ~0xf;
|
signed short s1 = c140->sample_mem[((unsigned int)(voice->bank) << 16) | voice->addr] & ~0xf;
|
||||||
signed short s2 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | ((c140_voice->addr + 1) & 0xffff)] & ~0xf;
|
signed short s2 = c140->sample_mem[((unsigned int)(voice->bank) << 16) | ((voice->addr + 1) & 0xffff)] & ~0xf;
|
||||||
if (c140_voice->compressed)
|
if (voice->compressed)
|
||||||
{
|
{
|
||||||
s1 = c140->mulaw[(s1 >> 8) & 0xff];
|
s1 = c140->mulaw[(s1 >> 8) & 0xff];
|
||||||
s2 = c140->mulaw[(s2 >> 8) & 0xff];
|
s2 = c140->mulaw[(s2 >> 8) & 0xff];
|
||||||
}
|
}
|
||||||
// interpolate
|
// interpolate
|
||||||
signed int sample = s1 + (((c140_voice->frac) * (s2 - s1)) >> 16);
|
signed int sample = s1 + (((voice->frac) * (s2 - s1)) >> 16);
|
||||||
c140_voice->lout = sample * c140_voice->lvol;
|
voice->lout = sample * voice->lvol;
|
||||||
c140_voice->rout = sample * c140_voice->rvol;
|
voice->rout = sample * voice->rvol;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voice->lout = 0;
|
||||||
|
voice->rout = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c140_voice->lout = 0;
|
voice->lout = 0;
|
||||||
c140_voice->rout = 0;
|
voice->rout = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct c140_t
|
||||||
|
|
||||||
void c140_tick(struct c140_t *c140, const int cycle);
|
void c140_tick(struct c140_t *c140, const int cycle);
|
||||||
|
|
||||||
void c140_voice_tick(struct c140_t *c140, const unsigned char voice, const int cycle);
|
void c140_voice_tick(struct c140_t *c140, const unsigned char v, const int cycle);
|
||||||
|
|
||||||
void c140_keyon(struct c140_voice_t *c140_voice);
|
void c140_keyon(struct c140_voice_t *c140_voice);
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ const char* aboutLine[]={
|
||||||
"vgsound_emu (second version, modified version) by cam900",
|
"vgsound_emu (second version, modified version) by cam900",
|
||||||
"SM8521 emulator (modified version) by cam900",
|
"SM8521 emulator (modified version) by cam900",
|
||||||
"D65010G031 emulator (modified version) by cam900",
|
"D65010G031 emulator (modified version) by cam900",
|
||||||
"Namco C140 emulator by cam900",
|
"Namco C140 (modified version) emulator by cam900",
|
||||||
"",
|
"",
|
||||||
"greetings to:",
|
"greetings to:",
|
||||||
"NEOART Costa Rica",
|
"NEOART Costa Rica",
|
||||||
|
|
|
@ -1105,7 +1105,10 @@ void putDispatchChan(void* data, int chanNum, int type) {
|
||||||
ImGui::Text("- chVolL: %.2x",ch->chVolL);
|
ImGui::Text("- chVolL: %.2x",ch->chVolL);
|
||||||
ImGui::Text("- chVolR: %.2x",ch->chVolR);
|
ImGui::Text("- chVolR: %.2x",ch->chVolR);
|
||||||
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
|
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
|
||||||
|
ImGui::Text("- macroPanMul: %.2x",ch->macroPanMul);
|
||||||
COMMON_CHAN_DEBUG_BOOL;
|
COMMON_CHAN_DEBUG_BOOL;
|
||||||
|
ImGui::TextColored(ch->volChangedL?colorOn:colorOff,">> VolChangedL");
|
||||||
|
ImGui::TextColored(ch->volChangedR?colorOn:colorOff,">> VolChangedR");
|
||||||
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
|
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,7 +210,7 @@ TAParamResult pVersion(String) {
|
||||||
printf("- ASAP POKEY emulator by Piotr Fusik ported to C++ by laoo (GPLv2)\n");
|
printf("- ASAP POKEY emulator by Piotr Fusik ported to C++ by laoo (GPLv2)\n");
|
||||||
printf("- SM8521 emulator (modified version) by cam900 (zlib license)\n");
|
printf("- SM8521 emulator (modified version) by cam900 (zlib license)\n");
|
||||||
printf("- D65010G031 emulator (modified version) by cam900 (zlib license)\n");
|
printf("- D65010G031 emulator (modified version) by cam900 (zlib license)\n");
|
||||||
printf("- C140 emulator by cam900 (zlib license)\n");
|
printf("- C140 emulator (modified version) by cam900 (zlib license)\n");
|
||||||
return TA_PARAM_QUIT;
|
return TA_PARAM_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue