Amiga: acquireDirect, part 2

the filter is back!
This commit is contained in:
tildearrow 2025-03-05 04:49:22 -05:00
parent e116f2e523
commit e941dfb174
5 changed files with 85 additions and 44 deletions

View file

@ -173,12 +173,12 @@ void DivDispatchContainer::acquire(size_t offset, size_t count) {
}
}
void DivDispatchContainer::flush(size_t count) {
void DivDispatchContainer::flush(size_t offset, size_t count) {
int outs=dispatch->getOutputCount();
for (int i=0; i<outs; i++) {
if (bb[i]==NULL) continue;
blip_read_samples(bb[i],bbOut[i],count,0);
blip_read_samples(bb[i],bbOut[i]+offset,count,0);
}
}

View file

@ -262,7 +262,7 @@ struct DivDispatchContainer {
void setQuality(bool lowQual, bool dcHiPass);
void grow(size_t size);
void acquire(size_t offset, size_t count);
void flush(size_t count);
void flush(size_t offset, size_t count);
void fillBuf(size_t runtotal, size_t offset, size_t size);
void clear();
void init(DivSystem sys, DivEngine* eng, int chanCount, double gotRate, const DivConfig& flags, bool isRender=false);

View file

@ -381,7 +381,21 @@ void DivPlatformAmiga::acquireDirect(blip_buffer_t** bb, size_t off, size_t len)
}
void DivPlatformAmiga::postProcess(short* buf, int outIndex, size_t len, int sampleRate) {
//buf[0]=32767;
// filtering
if (amigaModel) {
filtConstOff=4000;
filtConstOn=sin(M_PI*8000.0/((double)sampleRate*2.0))*4096.0;
} else {
filtConstOff=sin(M_PI*16000.0/((double)sampleRate*2.0))*4096.0;
filtConstOn=sin(M_PI*5500.0/((double)sampleRate*2.0))*4096.0;
}
filtConst=filterOn?filtConstOn:filtConstOff;
for (size_t i=0; i<len; i++) {
filter[outIndex][0]+=(filtConst*(buf[i]-filter[outIndex][0]))>>12;
filter[outIndex][1]+=(filtConst*(filter[outIndex][0]-filter[outIndex][1]))>>12;
buf[i]=filter[outIndex][1];
}
}
void DivPlatformAmiga::irq(int ch) {

View file

@ -26,8 +26,6 @@
#include "../ta-log.h"
#include <math.h>
constexpr int MASTER_CLOCK_PREC=(sizeof(void*)==8)?8:0;
void DivEngine::nextOrder() {
curRow=0;
if (repeatPattern) return;
@ -992,7 +990,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz
divider=(double)(((effect&0x3)<<8)|effectVal);
if (divider<1) divider=1;
cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/divider;
cycles=got.rate/divider;
clockDrift=0;
subticks=0;
break;
@ -1146,7 +1144,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
case 0xf0: // set Hz by tempo
divider=(double)effectVal*2.0/5.0;
if (divider<1) divider=1;
cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/divider;
cycles=got.rate/divider;
clockDrift=0;
subticks=0;
break;
@ -1551,8 +1549,8 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
tickMult=1;
}
cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/(divider*tickMult);
clockDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(divider*tickMult));
cycles=got.rate/(divider*tickMult);
clockDrift+=fmod(got.rate,(double)(divider*tickMult));
if (clockDrift>=(divider*tickMult)) {
clockDrift-=(divider*tickMult);
cycles++;
@ -2027,7 +2025,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
}
int DivEngine::getBufferPos() {
return bufferPos>>MASTER_CLOCK_PREC;
return bufferPos;
}
void DivEngine::runMidiClock(int totalCycles) {
@ -2053,10 +2051,10 @@ void DivEngine::runMidiClock(int totalCycles) {
if (vD<1) vD=1;
double bpm=((24.0*divider)/(timeBase*hl*speedSum))*(double)virtualTempoN/vD;
if (bpm<1.0) bpm=1.0;
int increment=got.rate*pow(2,MASTER_CLOCK_PREC)/(bpm);
int increment=got.rate/(bpm);
midiClockCycles+=increment;
midiClockDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(bpm));
midiClockDrift+=fmod(got.rate,(double)(bpm));
if (midiClockDrift>=(bpm)) {
midiClockDrift-=(bpm);
midiClockCycles++;
@ -2164,8 +2162,8 @@ void DivEngine::runMidiTime(int totalCycles) {
}
curMidiTimePiece=(curMidiTimePiece+1)&7;
midiTimeCycles+=got.rate*pow(2,MASTER_CLOCK_PREC)/(frameRate);
midiTimeDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(frameRate));
midiTimeCycles+=got.rate/(frameRate);
midiTimeDrift+=fmod(got.rate,(double)(frameRate));
if (midiTimeDrift>=(frameRate)) {
midiTimeDrift-=(frameRate);
midiTimeCycles++;
@ -2428,21 +2426,6 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (mustPlay) {
// logic starts here
for (int i=0; i<song.systemLen; i++) {
// TODO: we may have a problem here
disCont[i].lastAvail=blip_samples_avail(disCont[i].bb[0]);
if (disCont[i].lastAvail>0) {
disCont[i].flush(disCont[i].lastAvail);
}
if (size<disCont[i].lastAvail) {
disCont[i].runtotal=0;
} else {
disCont[i].runtotal=blip_clocks_needed(disCont[i].bb[0],size-disCont[i].lastAvail);
}
if (disCont[i].runtotal>disCont[i].bbInLen) {
logD("growing dispatch %d bbIn to %d",i,disCont[i].runtotal+256);
disCont[i].grow(disCont[i].runtotal+256);
}
disCont[i].runLeft=disCont[i].runtotal;
disCont[i].runPos=0;
}
@ -2455,10 +2438,10 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
memset(metroTick,0,size);
int attempts=0;
int runLeftG=size<<MASTER_CLOCK_PREC;
int runLeftG=size;
while (++attempts<(int)size) {
// -1. set bufferPos
bufferPos=(size<<MASTER_CLOCK_PREC)-runLeftG;
bufferPos=size-runLeftG;
// 0. check if we've halted
if (halted) break;
@ -2471,7 +2454,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (nextTick()) {
/*totalTicks=0;
totalSeconds=0;*/
lastLoopPos=size-(runLeftG>>MASTER_CLOCK_PREC);
lastLoopPos=size-runLeftG;
logD("last loop pos: %d for a size of %d and runLeftG of %d",lastLoopPos,size,runLeftG);
totalLoops++;
if (remainingLoops>0) {
@ -2487,7 +2470,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
}
}
if (pendingMetroTick) {
unsigned int realPos=size-(runLeftG>>MASTER_CLOCK_PREC);
unsigned int realPos=size-runLeftG;
if (realPos>=size) realPos=size-1;
metroTick[realPos]=pendingMetroTick;
pendingMetroTick=0;
@ -2502,30 +2485,70 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
// 5. tick the clock and fill buffers as needed
if (cycles<runLeftG) {
// run until the end of this tick
for (int i=0; i<song.systemLen; i++) {
disCont[i].cycles=cycles;
disCont[i].size=size;
renderPool->push([](void* d) {
DivDispatchContainer* dc=(DivDispatchContainer*)d;
int total=(dc->cycles*dc->runtotal)/(dc->size<<MASTER_CLOCK_PREC);
dc->acquire(dc->runPos,total);
dc->runLeft-=total;
dc->runPos+=total;
int lastAvail=blip_samples_avail(dc->bb[0]);
if (lastAvail>0) {
if (lastAvail>=dc->cycles) {
dc->flush(dc->runPos,dc->cycles);
dc->runPos+=dc->cycles;
return;
} else {
dc->flush(dc->runPos,lastAvail);
dc->runPos+=lastAvail;
dc->cycles-=lastAvail;
}
}
int total=blip_clocks_needed(dc->bb[0],dc->cycles);
if (total>(int)dc->bbInLen) {
logD("growing dispatch %p bbIn to %d",(void*)dc,total+256);
dc->grow(total+256);
}
dc->acquire(0,total);
dc->fillBuf(total,dc->runPos,dc->cycles);
dc->runPos+=dc->cycles;
},&disCont[i]);
}
renderPool->wait();
runLeftG-=cycles;
cycles=0;
} else {
// run until the end of this audio buffer
cycles-=runLeftG;
runLeftG=0;
for (int i=0; i<song.systemLen; i++) {
disCont[i].cycles=runLeftG;
renderPool->push([](void* d) {
DivDispatchContainer* dc=(DivDispatchContainer*)d;
dc->acquire(dc->runPos,dc->runLeft);
dc->runLeft=0;
int lastAvail=blip_samples_avail(dc->bb[0]);
if (lastAvail>0) {
if (lastAvail>=dc->cycles) {
dc->flush(dc->runPos,dc->cycles);
dc->runPos+=dc->cycles;
return;
} else {
dc->flush(dc->runPos,lastAvail);
dc->runPos+=lastAvail;
dc->cycles-=lastAvail;
}
}
int total=blip_clocks_needed(dc->bb[0],dc->cycles);
if (total>(int)dc->bbInLen) {
logD("growing dispatch %p bbIn to %d",(void*)dc,total+256);
dc->grow(total+256);
}
dc->acquire(0,total);
dc->fillBuf(total,dc->runPos,dc->cycles);
},&disCont[i]);
}
runLeftG=0;
renderPool->wait();
}
}
@ -2538,7 +2561,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
playing=false;
extValuePresent=false;
}
totalProcessed=size-(runLeftG>>MASTER_CLOCK_PREC);
totalProcessed=size-runLeftG;
for (int i=0; i<song.systemLen; i++) {
if (size<disCont[i].lastAvail) {
@ -2546,10 +2569,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
continue;
}
disCont[i].size=size;
/*
renderPool->push([](void* d) {
DivDispatchContainer* dc=(DivDispatchContainer*)d;
dc->fillBuf(dc->runtotal,dc->lastAvail,dc->size-dc->lastAvail);
},&disCont[i]);
},&disCont[i]);*/
}
renderPool->wait();
}

View file

@ -553,9 +553,12 @@ void putDispatchChip(void* data, int type) {
COMMON_CHIP_DEBUG_BOOL;
break;
}
default:
default: {
DivDispatch* ch=(DivDispatch*)data;
COMMON_CHIP_DEBUG;
ImGui::Text("Unimplemented chip! Help!");
break;
}
}
}
void putDispatchChan(void* data, int chanNum, int type) {