MAJOR change: send/returns are always there. New feature: per track output (optional, use enablePerTrackOutput in luppp.prfs)

This commit is contained in:
Gerald 2016-11-19 00:35:43 +01:00 committed by Harry van Haaren
parent efa6d9054c
commit bb91ac0e58
10 changed files with 92 additions and 28 deletions

View file

@ -80,6 +80,15 @@ class Buffers
RETURN_TRACK_6, RETURN_TRACK_6,
RETURN_TRACK_7, RETURN_TRACK_7,
JACK_TRACK_0,
JACK_TRACK_1,
JACK_TRACK_2,
JACK_TRACK_3,
JACK_TRACK_4,
JACK_TRACK_5,
JACK_TRACK_6,
JACK_TRACK_7,
BUFFER_COUNT, BUFFER_COUNT,
}; };

View file

@ -103,12 +103,12 @@ int DiskReader::loadPreferences()
} }
//Enable per track send and resturn jack ports? //Enable per track send and resturn jack ports?
cJSON* jackSendReturns=cJSON_GetObjectItem(preferencesJson,"enablePerTrackSendReturns"); cJSON* jackPerTrackOutput=cJSON_GetObjectItem(preferencesJson,"enablePerTrackOutput");
if(jackSendReturns) if(jackPerTrackOutput)
{ {
gui->enableJackSendReturns=jackSendReturns->valueint; gui->enablePerTrackOutput=jackPerTrackOutput->valueint;
if(gui->enableJackSendReturns) if(gui->enablePerTrackOutput)
LUPPP_NOTE("Enabling per track send and return ports"); LUPPP_NOTE("Enabling per track output ports");
} }
@ -638,6 +638,19 @@ int DiskReader::readTracks()
writeToDspRingbuffer( &e2 ); writeToDspRingbuffer( &e2 );
writeToDspRingbuffer( &e3 ); writeToDspRingbuffer( &e3 );
} }
cJSON* jacksend = cJSON_GetObjectItem( track, "jacksendAmount");
cJSON* jacksendActive = cJSON_GetObjectItem( track, "jacksendActive");
if(jacksend)
{
EventTrackJackSend ev(t,jacksend->valuedouble);
writeToDspRingbuffer(&ev);
}
if(jacksendActive)
{
EventTrackJackSendActivate ev(t,jacksendActive->valueint);
writeToDspRingbuffer(&ev);
}
} }
}// if track }// if track
} // nTracks loop } // nTracks loop

View file

@ -431,6 +431,9 @@ int DiskWriter::writeSession()
cJSON_AddNumberToObject( track, "sendAmount" , gui->getTrack(t)->getSend() ); cJSON_AddNumberToObject( track, "sendAmount" , gui->getTrack(t)->getSend() );
cJSON_AddNumberToObject( track, "sendActive" , gui->getTrack(t)->getSendActive() ); cJSON_AddNumberToObject( track, "sendActive" , gui->getTrack(t)->getSendActive() );
cJSON_AddNumberToObject( track, "jacksendAmount" , gui->getTrack(t)->getJackSend() );
cJSON_AddNumberToObject( track, "jacksendActive" , gui->getTrack(t)->getJackSendActivate() );
cJSON_AddNumberToObject( track, "xsideAmount", gui->getTrack(t)->getXSide() ); cJSON_AddNumberToObject( track, "xsideAmount", gui->getTrack(t)->getXSide() );
cJSON_AddNumberToObject( track, "keyActive" , gui->getTrack(t)->getKeyActive() ); cJSON_AddNumberToObject( track, "keyActive" , gui->getTrack(t)->getKeyActive() );

View file

@ -109,6 +109,16 @@ void GTrack::setJackSendActivate(bool a)
jackSendActivate.value(a); jackSendActivate.value(a);
} }
float GTrack::getJackSend()
{
return jackSendDial.value();
}
bool GTrack::getJackSendActivate()
{
return jackSendActivate.value();
}
void gtrack_sendDial_cb(Fl_Widget *w, void *data) void gtrack_sendDial_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;

View file

@ -85,7 +85,9 @@ class GTrack : public Fl_Group
Avtk::Volume volume; Avtk::Volume volume;
private: float getJackSend();
bool getJackSendActivate();
private:
Avtk::Box jackSendBox; Avtk::Box jackSendBox;
Avtk::Dial jackSendDial; Avtk::Dial jackSendDial;
Avtk::LightButton jackSendActivate; Avtk::LightButton jackSendActivate;

View file

@ -363,7 +363,7 @@ static int cb_nsm_save ( char **out_msg, void *userdata )
Gui::Gui(const char* argZero) : Gui::Gui(const char* argZero) :
samplerate( 0 ), samplerate( 0 ),
window(1110,700), window(1110,700),
enableJackSendReturns(false), enablePerTrackOutput(false),
diskReader( new DiskReader() ), diskReader( new DiskReader() ),
diskWriter( new DiskWriter() ) diskWriter( new DiskWriter() )
{ {

View file

@ -86,7 +86,7 @@ class Gui
int samplerate; int samplerate;
////Enable per track send and resturn jack ports ////Enable per track send and resturn jack ports
bool enableJackSendReturns; bool enablePerTrackOutput;
int getWindowWidth(){return window.w();} int getWindowWidth(){return window.w();}

View file

@ -204,22 +204,28 @@ Jack::Jack( std::string name ) :
**/ **/
loopers.push_back( new Looper(i) ); loopers.push_back( new Looper(i) );
if(gui->enableJackSendReturns) tracksendreturns.push_back(new JackSendReturn(i,loopers.back(),client));
{ trackOutputs.push_back( new TrackOutput(i, tracksendreturns.back() ) );
tracksendreturns.push_back(new JackSendReturn(i,loopers.back(),client));
trackOutputs.push_back( new TrackOutput(i, tracksendreturns.back() ) );
}
else
trackOutputs.push_back( new TrackOutput(i, loopers.back() ) );
buffers.audio[Buffers::TRACK_0 + i] = new float[ buffers.nframes ]; buffers.audio[Buffers::TRACK_0 + i] = new float[ buffers.nframes ];
buffers.audio[Buffers::SEND_TRACK_0+i]=new float[buffers.nframes]; buffers.audio[Buffers::SEND_TRACK_0+i]=new float[buffers.nframes];
if(gui->enableJackSendReturns) buffers.audio[Buffers::RETURN_TRACK_0+i]=new float[buffers.nframes];
buffers.audio[Buffers::RETURN_TRACK_0+i]=new float[buffers.nframes];
else
buffers.audio[Buffers::RETURN_TRACK_0+i]=buffers.audio[Buffers::SEND_TRACK_0+i];
timeManager->registerObserver( loopers.back() ); timeManager->registerObserver( loopers.back() );
if(gui->enablePerTrackOutput)
{
char name[50];
sprintf(name,"track_%d\0",i);
trackJackOutputPorts[i]=jack_port_register( client,
name,
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput,
0 );
}
} }
/// setup DSP instances /// setup DSP instances
@ -282,11 +288,8 @@ Jack::~Jack()
{ {
delete [] buffers.audio[Buffers::TRACK_0+i]; delete [] buffers.audio[Buffers::TRACK_0+i];
delete [] buffers.audio[Buffers::SEND_TRACK_0+i]; delete [] buffers.audio[Buffers::SEND_TRACK_0+i];
if(gui->enableJackSendReturns) delete [] buffers.audio[Buffers::RETURN_TRACK_0+i];
{ delete tracksendreturns[i];
delete [] buffers.audio[Buffers::RETURN_TRACK_0+i];
delete tracksendreturns[i];
}
delete loopers[i]; delete loopers[i];
delete trackOutputs[i]; delete trackOutputs[i];
} }
@ -393,6 +396,12 @@ int Jack::process (jack_nframes_t nframes)
buffers.audio[Buffers::JACK_MASTER_OUT_R] = (float*)jack_port_get_buffer( masterOutputR , nframes ); buffers.audio[Buffers::JACK_MASTER_OUT_R] = (float*)jack_port_get_buffer( masterOutputR , nframes );
buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = (float*)jack_port_get_buffer(sidechainKeyOutput,nframes); buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = (float*)jack_port_get_buffer(sidechainKeyOutput,nframes);
buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=(float*)jack_port_get_buffer(sidechainSignalOutput,nframes); buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=(float*)jack_port_get_buffer(sidechainSignalOutput,nframes);
if(gui->enablePerTrackOutput)
{
for(int t=0;t<NTRACKS;t++)
buffers.audio[Buffers::JACK_TRACK_0+t] = (float*)jack_port_get_buffer( trackJackOutputPorts[t] , nframes );
}
// clear the buffers // clear the buffers
@ -404,6 +413,12 @@ int Jack::process (jack_nframes_t nframes)
memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes );
if(gui->enablePerTrackOutput)
{
for(int t=0;t<NTRACKS;t++)
memset( buffers.audio[Buffers::JACK_TRACK_0+t] , 0, sizeof(float) * nframes );
}
//buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes ); //buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes );
@ -571,6 +586,13 @@ void Jack::processFrames(int nframes)
buffers.audio[Buffers::JACK_MASTER_OUT_R] = &buffers.audio[Buffers::JACK_MASTER_OUT_R][nframes]; buffers.audio[Buffers::JACK_MASTER_OUT_R] = &buffers.audio[Buffers::JACK_MASTER_OUT_R][nframes];
buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = &buffers.audio[Buffers::JACK_SIDECHAIN_KEY][nframes]; buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = &buffers.audio[Buffers::JACK_SIDECHAIN_KEY][nframes];
buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=&buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL][nframes]; buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=&buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL][nframes];
if(gui->enablePerTrackOutput)
{
for(int t=0;t<NTRACKS;t++)
{
buffers.audio[Buffers::JACK_TRACK_0+t] = &buffers.audio[Buffers::JACK_TRACK_0+t][nframes];
}
}
} }
return; return;
@ -587,8 +609,8 @@ void Jack::clearInternalBuffers(int nframes)
{ {
memset(buffers.audio[Buffers::TRACK_0 + i],0,sizeof(float)*nframes); memset(buffers.audio[Buffers::TRACK_0 + i],0,sizeof(float)*nframes);
memset(buffers.audio[Buffers::SEND_TRACK_0 + i],0,sizeof(float)*nframes); memset(buffers.audio[Buffers::SEND_TRACK_0 + i],0,sizeof(float)*nframes);
if(gui->enableJackSendReturns)
memset(buffers.audio[Buffers::RETURN_TRACK_0 + i],0,sizeof(float)*nframes); memset(buffers.audio[Buffers::RETURN_TRACK_0 + i],0,sizeof(float)*nframes);
} }
} }

View file

@ -157,6 +157,7 @@ private:
jack_port_t* masterInput; jack_port_t* masterInput;
jack_port_t* masterOutputL; jack_port_t* masterOutputL;
jack_port_t* masterOutputR; jack_port_t* masterOutputR;
jack_port_t* masterReturnL; jack_port_t* masterReturnL;
jack_port_t* masterReturnR; jack_port_t* masterReturnR;
jack_port_t* headphonesPort; jack_port_t* headphonesPort;
@ -167,7 +168,7 @@ private:
jack_port_t* masterMidiInput; jack_port_t* masterMidiInput;
vector<jack_port_t*> trackJackOutputPorts; jack_port_t* trackJackOutputPorts[NTRACKS];
// JACK callback // JACK callback
int process (jack_nframes_t); int process (jack_nframes_t);

View file

@ -135,6 +135,9 @@ void TrackOutput::process(unsigned int nframes, Buffers* buffers)
float* masterL = buffers->audio[Buffers::MASTER_OUT_L]; float* masterL = buffers->audio[Buffers::MASTER_OUT_L];
float* masterR = buffers->audio[Buffers::MASTER_OUT_R]; float* masterR = buffers->audio[Buffers::MASTER_OUT_R];
float* jackoutput = buffers->audio[Buffers::JACK_TRACK_0+track];
for(unsigned int i = 0; i < nframes; i++) for(unsigned int i = 0; i < nframes; i++)
{ {
@ -144,7 +147,8 @@ void TrackOutput::process(unsigned int nframes, Buffers* buffers)
// post-sidechain *moves* signal between "before/after" ducking, not add! // post-sidechain *moves* signal between "before/after" ducking, not add!
masterL[i] += tmp * _toMasterLag * (1-_toPostSidechain); masterL[i] += tmp * _toMasterLag * (1-_toPostSidechain);
masterR[i] += tmp * _toMasterLag * (1-_toPostSidechain); masterR[i] += tmp * _toMasterLag * (1-_toPostSidechain);
if(jackoutput)
jackoutput[i] = tmp * _toMasterLag * (1-_toPostSidechain);
if ( _toPostfaderActive ) if ( _toPostfaderActive )
reverb[i] += tmp * _toReverb * _toMasterLag; reverb[i] += tmp * _toReverb * _toMasterLag;