implement patchbay-based output
This commit is contained in:
parent
6273275b47
commit
1154a2bda6
|
@ -410,14 +410,14 @@ a connection is represented as an unsigned int in the following format:
|
||||||
|
|
||||||
a port is in the following format (hexadecimal): `xxxy`
|
a port is in the following format (hexadecimal): `xxxy`
|
||||||
|
|
||||||
- `xxx` (bit 4 to 15) represents an entity.
|
- `xxx` (bit 4 to 15) represents a portset.
|
||||||
- `y` (bit 0 to 3) is the port of that entity.
|
- `y` (bit 0 to 3) is the port in that portset.
|
||||||
|
|
||||||
reserved input entities:
|
reserved input portsets:
|
||||||
- `000`: system outputs
|
- `000`: system outputs
|
||||||
- `FFF`: "null" entity
|
- `FFF`: "null" portset
|
||||||
|
|
||||||
reserved output entities:
|
reserved output portsets:
|
||||||
- `000` through `01F`: chip outputs
|
- `000` through `01F`: chip outputs
|
||||||
|
|
||||||
# subsong
|
# subsong
|
||||||
|
|
|
@ -1466,6 +1466,7 @@ void DivEngine::createNew(const char* description, String sysName, bool inBase64
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
@ -3773,6 +3774,26 @@ bool DivEngine::moveSampleDown(int which) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivEngine::autoPatchbay() {
|
||||||
|
song.patchbay.clear();
|
||||||
|
for (unsigned int i=0; i<song.systemLen; i++) {
|
||||||
|
if (disCont[i].dispatch==NULL) continue;
|
||||||
|
|
||||||
|
unsigned int outs=disCont[i].dispatch->getOutputCount();
|
||||||
|
if (outs>16) outs=16;
|
||||||
|
if (outs<2) {
|
||||||
|
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||||
|
song.patchbay.push_back((i<<20)|j);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned int j=0; j<outs; j++) {
|
||||||
|
|
||||||
|
song.patchbay.push_back((i<<20)|(j<<16)|j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivEngine::noteOn(int chan, int ins, int note, int vol) {
|
void DivEngine::noteOn(int chan, int ins, int note, int vol) {
|
||||||
if (chan<0 || chan>=chans) return;
|
if (chan<0 || chan>=chans) return;
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
@ -4333,6 +4354,7 @@ bool DivEngine::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
initDispatch();
|
initDispatch();
|
||||||
|
if (!hasLoadedSomething || song.version<135) autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
active=true;
|
active=true;
|
||||||
|
|
|
@ -835,6 +835,9 @@ class DivEngine {
|
||||||
bool moveWaveDown(int which);
|
bool moveWaveDown(int which);
|
||||||
bool moveSampleDown(int which);
|
bool moveSampleDown(int which);
|
||||||
|
|
||||||
|
// automatic patchbay
|
||||||
|
void autoPatchbay();
|
||||||
|
|
||||||
// play note
|
// play note
|
||||||
void noteOn(int chan, int ins, int note, int vol=-1);
|
void noteOn(int chan, int ins, int note, int vol=-1);
|
||||||
|
|
||||||
|
|
|
@ -987,6 +987,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
@ -2584,6 +2585,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
if (song.version<135) autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
@ -3006,6 +3008,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
@ -3176,7 +3179,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
ds.systemLen=1;
|
ds.systemLen=1;
|
||||||
ds.system[0]=DIV_SYSTEM_AMIGA;
|
ds.system[0]=DIV_SYSTEM_AMIGA;
|
||||||
ds.systemVol[0]=64;
|
ds.systemVol[0]=1.0f;
|
||||||
ds.systemPan[0]=0;
|
ds.systemPan[0]=0;
|
||||||
ds.systemFlags[0].set("clockSel",1); // PAL
|
ds.systemFlags[0].set("clockSel",1); // PAL
|
||||||
ds.systemFlags[0].set("stereoSep",80);
|
ds.systemFlags[0].set("stereoSep",80);
|
||||||
|
@ -3689,6 +3692,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
||||||
if (active) {
|
if (active) {
|
||||||
initDispatch();
|
initDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
|
autoPatchbay();
|
||||||
renderSamples();
|
renderSamples();
|
||||||
reset();
|
reset();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
|
|
@ -1720,30 +1720,53 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
disCont[i].fillBuf(disCont[i].runtotal,disCont[i].lastAvail,size-disCont[i].lastAvail);
|
disCont[i].fillBuf(disCont[i].runtotal,disCont[i].lastAvail,size-disCont[i].lastAvail);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: patchbay
|
// resolve patchbay
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (unsigned int i: song.patchbay) {
|
||||||
float volL=song.systemVol[i]*MIN(1.0f,1.0f-song.systemPan[i])*song.masterVol;
|
const unsigned short srcPort=i>>16;
|
||||||
float volR=song.systemVol[i]*MIN(1.0f,1.0f+song.systemPan[i])*song.masterVol;
|
const unsigned short destPort=i&0xffff;
|
||||||
volL*=disCont[i].dispatch->getPostAmp();
|
|
||||||
volR*=disCont[i].dispatch->getPostAmp();
|
const unsigned short srcPortSet=srcPort>>4;
|
||||||
if (disCont[i].dispatch->getOutputCount()>1) {
|
const unsigned short destPortSet=destPort>>4;
|
||||||
for (size_t j=0; j<size; j++) {
|
const unsigned char srcSubPort=srcPort&15;
|
||||||
int howManyToFill=MIN(outChans,disCont[i].dispatch->getOutputCount());
|
const unsigned char destSubPort=destPort&15;
|
||||||
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
|
// null portset
|
||||||
const float whichVol=((howManyToFill&1) && (k==howManyToFill-1))?1.0:((k&1)?volR:volL);
|
if (destPortSet==0xfff) continue;
|
||||||
out[k][j]+=((float)disCont[i].bbOut[k][j]/32768.0)*whichVol;
|
|
||||||
}
|
// system outputs
|
||||||
}
|
if (destPortSet==0x000) {
|
||||||
} else {
|
if (destSubPort>=outChans) continue;
|
||||||
for (size_t j=0; j<size; j++) {
|
|
||||||
for (int k=0; k<outChans; k++) {
|
// chip outputs
|
||||||
// volL if even, volR if odd. if outChans is odd and it is the last channel then ignore
|
if (srcPortSet<song.systemLen) {
|
||||||
const float whichVol=((outChans&1) && (k==outChans-1))?1.0:((k&1)?volR:volL);
|
if (srcSubPort<disCont[srcPortSet].dispatch->getOutputCount()) {
|
||||||
out[k][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*whichVol;
|
float vol=song.systemVol[srcPortSet]*disCont[srcPortSet].dispatch->getPostAmp()*song.masterVol;
|
||||||
|
|
||||||
|
switch (destSubPort&3) {
|
||||||
|
case 0:
|
||||||
|
vol*=MIN(1.0f,1.0f-song.systemPan[srcPortSet])*MIN(1.0f,1.0f-song.systemPanFR[srcPortSet]);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
vol*=MIN(1.0f,1.0f+song.systemPan[srcPortSet])*MIN(1.0f,1.0f-song.systemPanFR[srcPortSet]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vol*=MIN(1.0f,1.0f-song.systemPan[srcPortSet])*MIN(1.0f,1.0f+song.systemPanFR[srcPortSet]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vol*=MIN(1.0f,1.0f+song.systemPan[srcPortSet])*MIN(1.0f,1.0f+song.systemPanFR[srcPortSet]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j=0; j<size; j++) {
|
||||||
|
out[destSubPort][j]+=((float)disCont[srcPortSet].bbOut[srcSubPort][j]/32768.0)*vol;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nothing/invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nothing/invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metronome) for (size_t i=0; i<size; i++) {
|
if (metronome) for (size_t i=0; i<size; i++) {
|
||||||
|
|
Loading…
Reference in a new issue