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:
cam900 2023-08-10 20:24:10 +09:00
parent 21d1dfefa1
commit 4d7d610f8c
7 changed files with 55 additions and 35 deletions

View File

@ -59,6 +59,9 @@ void DivPlatformC140::acquire(short** buf, size_t len) {
}
c140_tick(&c140, 1);
// scale as 16bit
c140.lout >>= 10;
c140.rout >>= 10;
if (c140.lout<-32768) c140.lout=-32768;
if (c140.lout>32767) c140.lout=32767;
@ -101,12 +104,12 @@ void DivPlatformC140::tick(bool sysTick) {
chan[i].freqChanged=true;
}
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;
}
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;
}
@ -147,13 +150,14 @@ void DivPlatformC140::tick(bool sysTick) {
unsigned int end=0;
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
start=sampleOff[chan[i].sample];
end=MIN(start+s->length8,getSampleMemCapacity()-1);
end=MIN(start+s->length8-1,65535);
}
if (chan[i].audPos>0) {
start=start+MIN(chan[i].audPos,s->length8);
}
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(0x06+(i<<4),(start>>8)&0xff);
@ -187,6 +191,7 @@ int DivPlatformC140::dispatch(DivCommand c) {
case DIV_CMD_NOTE_ON: {
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].macroPanMul=ins->type==DIV_INS_AMIGA?127:255;
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
c.value=ins->amiga.getFreq(c.value);

View File

@ -32,6 +32,7 @@ class DivPlatformC140: public DivDispatch {
int chPanL, chPanR;
int chVolL, chVolR;
int macroVolMul;
int macroPanMul;
Channel():
SharedChannel<int>(255),
audPos(0),
@ -44,7 +45,8 @@ class DivPlatformC140: public DivDispatch {
chPanR(255),
chVolL(255),
chVolR(255),
macroVolMul(64) {}
macroVolMul(64),
macroPanMul(127) {}
};
Channel chan[24];
DivDispatchOscBuffer* oscBuf[24];

View File

@ -2,9 +2,13 @@
============================================================================
Namco C140 sound emulator
MODIFIED Namco C140 sound emulator - MODIFIED VERSION
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.
============================================================================
@ -52,58 +56,64 @@ void c140_tick(struct c140_t *c140, const int cycle)
for (int i = 0; i < 24; i++)
{
c140_voice_tick(c140, i, cycle);
if (!c140->voice[i].muted) {
c140->lout += c140->voice[i].lout;
c140->rout += c140->voice[i].rout;
}
c140->lout += c140->voice[i].lout;
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];
if (c140_voice->busy && c140_voice->keyon)
struct c140_voice_t *voice = &c140->voice[v];
if (voice->busy && voice->keyon)
{
for (int c = 0; c < cycle; c++)
{
c140_voice->frac += c140_voice->freq;
if (c140_voice->frac > 0xffff)
voice->frac += voice->freq;
if (voice->frac > 0xffff)
{
c140_voice->addr += c140_voice->frac >> 16;
if (c140_voice->addr > c140_voice->end_addr)
voice->addr += voice->frac >> 16;
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
{
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
signed short s1 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | c140_voice->addr] & ~0xf;
signed short s2 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | ((c140_voice->addr + 1) & 0xffff)] & ~0xf;
if (c140_voice->compressed)
signed short s1 = c140->sample_mem[((unsigned int)(voice->bank) << 16) | voice->addr] & ~0xf;
signed short s2 = c140->sample_mem[((unsigned int)(voice->bank) << 16) | ((voice->addr + 1) & 0xffff)] & ~0xf;
if (voice->compressed)
{
s1 = c140->mulaw[(s1 >> 8) & 0xff];
s2 = c140->mulaw[(s2 >> 8) & 0xff];
}
// interpolate
signed int sample = s1 + (((c140_voice->frac) * (s2 - s1)) >> 16);
c140_voice->lout = sample * c140_voice->lvol;
c140_voice->rout = sample * c140_voice->rvol;
signed int sample = s1 + (((voice->frac) * (s2 - s1)) >> 16);
voice->lout = sample * voice->lvol;
voice->rout = sample * voice->rvol;
}
else
{
voice->lout = 0;
voice->rout = 0;
}
}
else
{
c140_voice->lout = 0;
c140_voice->rout = 0;
voice->lout = 0;
voice->rout = 0;
}
}

View File

@ -79,7 +79,7 @@ struct c140_t
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);

View File

@ -195,7 +195,7 @@ const char* aboutLine[]={
"vgsound_emu (second version, modified version) by cam900",
"SM8521 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:",
"NEOART Costa Rica",

View File

@ -1105,7 +1105,10 @@ void putDispatchChan(void* data, int chanNum, int type) {
ImGui::Text("- chVolL: %.2x",ch->chVolL);
ImGui::Text("- chVolR: %.2x",ch->chVolR);
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
ImGui::Text("- macroPanMul: %.2x",ch->macroPanMul);
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");
break;
}

View File

@ -210,7 +210,7 @@ TAParamResult pVersion(String) {
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("- 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;
}