support more than 2 output channels

up to 16 on JACK
to-do: add more mixer settings
This commit is contained in:
tildearrow 2023-01-05 02:40:17 -05:00
parent 77f7fcd555
commit 71e40dc015
11 changed files with 127 additions and 42 deletions

View file

@ -131,6 +131,7 @@ void DivDispatchContainer::fillBuf(size_t runtotal, size_t offset, size_t size)
bool mustClear=false;
for (int i=0; i<outs; i++) {
if (bb[i]==NULL) {
logV("creating buf %d because it doesn't exist",i);
bb[i]=blip_new(bbInLen);
if (bb[i]==NULL) {
logE("not enough memory!");
@ -142,6 +143,7 @@ void DivDispatchContainer::fillBuf(size_t runtotal, size_t offset, size_t size)
if (bbOut[i]==NULL) bbOut[i]=new short[bbInLen];
memset(bbIn[i],0,bbInLen*sizeof(short));
memset(bbOut[i],0,bbInLen*sizeof(short));
mustClear=true;
}
}
if (mustClear) clear();

View file

@ -4150,10 +4150,13 @@ bool DivEngine::initAudioBackend() {
want.rate=getConfInt("audioRate",44100);
want.fragments=2;
want.inChans=0;
want.outChans=2;
want.outChans=getConfInt("audioChans",2);
want.outFormat=TA_AUDIO_FORMAT_F32;
want.name="Furnace";
if (want.outChans<1) want.outChans=1;
if (want.outChans>16) want.outChans=16;
output->setCallback(process,this);
if (!output->init(want,got)) {
@ -4164,6 +4167,13 @@ bool DivEngine::initAudioBackend() {
return false;
}
for (int i=0; i<got.outChans; i++) {
if (oscBuf[i]==NULL) {
oscBuf[i]=new float[32768];
}
memset(oscBuf[i],0,32768*sizeof(float));
}
if (output->initMidi(false)) {
midiIns=output->midiIn->listDevices();
midiOuts=output->midiOut->listDevices();
@ -4296,12 +4306,6 @@ bool DivEngine::init() {
keyHit[i]=false;
}
oscBuf[0]=new float[32768];
oscBuf[1]=new float[32768];
memset(oscBuf[0],0,32768*sizeof(float));
memset(oscBuf[1],0,32768*sizeof(float));
initDispatch();
renderSamples();
reset();
@ -4328,8 +4332,9 @@ bool DivEngine::quit() {
logI("saving config.");
saveConf();
active=false;
delete[] oscBuf[0];
delete[] oscBuf[1];
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
if (oscBuf[i]!=NULL) delete[] oscBuf[i];
}
if (yrw801ROM!=NULL) delete[] yrw801ROM;
if (tg100ROM!=NULL) delete[] tg100ROM;
if (mu5ROM!=NULL) delete[] mu5ROM;

View file

@ -493,7 +493,7 @@ class DivEngine {
int dispatchOfChan[DIV_MAX_CHANS];
int dispatchChanOfChan[DIV_MAX_CHANS];
bool keyHit[DIV_MAX_CHANS];
float* oscBuf[2];
float* oscBuf[DIV_MAX_OUTPUTS];
float oscSize;
int oscReadPos, oscWritePos;
int tickMult;
@ -1123,7 +1123,6 @@ class DivEngine {
curOrders(NULL),
curPat(NULL),
tempIns(NULL),
oscBuf{NULL,NULL},
oscSize(1),
oscReadPos(0),
oscWritePos(0),
@ -1142,6 +1141,7 @@ class DivEngine {
memset(pitchTable,0,4096*sizeof(int));
memset(sysDefs,0,256*sizeof(void*));
memset(walked,0,8192);
memset(oscBuf,0,DIV_MAX_OUTPUTS*(sizeof(float*)));
for (int i=0; i<256; i++) {
sysFileMapFur[i]=DIV_SYSTEM_NULL;

View file

@ -67,7 +67,6 @@ void DivPlatformVIC20::acquire(short** buf, size_t len) {
short samp;
vic_sound_machine_calculate_samples(vic,&samp,1,1,0,SAMP_DIVIDER);
buf[0][h]=samp;
buf[1][h]=samp;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=vic->ch[i].out?(vic->volume<<11):0;
}

View file

@ -1579,10 +1579,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (!playing) {
if (out!=NULL) {
// TODO: handle more than 2 outputs
for (unsigned int i=0; i<size; i++) {
oscBuf[0][oscWritePos]=out[0][i];
oscBuf[1][oscWritePos]=out[1][i];
for (int j=0; j<outChans; j++) {
if (oscBuf[j]==NULL) continue;
oscBuf[j][oscWritePos]=out[j][i];
}
if (++oscWritePos>=32768) oscWritePos=0;
}
oscSize=size;
@ -1707,13 +1708,20 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
volR*=disCont[i].dispatch->getPostAmp();
if (disCont[i].dispatch->getOutputCount()>1) {
for (size_t j=0; j<size; j++) {
out[0][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*volL;
out[1][j]+=((float)disCont[i].bbOut[1][j]/32768.0)*volR;
int howManyToFill=MIN(outChans,disCont[i].dispatch->getOutputCount());
for (int k=0; k<howManyToFill; k++) {
// volL if even, volR if odd. if howManyToFill is odd and it is the last channel then ignore
const float whichVol=((howManyToFill&1) && (k==howManyToFill-1))?1.0:((k&1)?volR:volL);
out[k][j]+=((float)disCont[i].bbOut[k][j]/32768.0)*whichVol;
}
}
} else {
for (size_t j=0; j<size; j++) {
out[0][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*volL;
out[1][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*volR;
for (int k=0; k<outChans; k++) {
// volL if even, volR if odd. if outChans is odd and it is the last channel then ignore
const float whichVol=((outChans&1) && (k==outChans-1))?1.0:((k&1)?volR:volL);
out[k][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*whichVol;
}
}
}
}
@ -1739,19 +1747,25 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
while (metroPos>=1) metroPos--;
}
// TODO: handle more than 2 outputs
for (unsigned int i=0; i<size; i++) {
oscBuf[0][oscWritePos]=out[0][i];
oscBuf[1][oscWritePos]=out[1][i];
for (int j=0; j<outChans; j++) {
if (oscBuf[j]==NULL) continue;
oscBuf[j][oscWritePos]=out[j][i];
}
if (++oscWritePos>=32768) oscWritePos=0;
}
oscSize=size;
// TODO: handle more than 2 outputs
if (forceMono) {
if (forceMono && outChans>1) {
for (size_t i=0; i<size; i++) {
out[0][i]=(out[0][i]+out[1][i])*0.5;
out[1][i]=out[0][i];
float chanSum=out[0][i];
for (int j=1; j<outChans; j++) {
chanSum=out[j][i];
}
out[0][i]=chanSum/outChans;
for (int j=1; j<outChans; j++) {
out[j][i]=out[0][i];
}
}
}
if (clampSamples) {