diff --git a/src/buffers.hxx b/src/buffers.hxx index 3100b2d..315af58 100644 --- a/src/buffers.hxx +++ b/src/buffers.hxx @@ -63,6 +63,14 @@ class Buffers TRACK_6, TRACK_7, //Per track sends/returns + SEND_TRACK_0, + SEND_TRACK_1, + SEND_TRACK_2, + SEND_TRACK_3, + SEND_TRACK_4, + SEND_TRACK_5, + SEND_TRACK_6, + SEND_TRACK_7, JACK_SEND_TRACK_0, JACK_SEND_TRACK_1, JACK_SEND_TRACK_2, @@ -71,6 +79,14 @@ class Buffers JACK_SEND_TRACK_5, JACK_SEND_TRACK_6, JACK_SEND_TRACK_7, + RETURN_TRACK_0, + RETURN_TRACK_1, + RETURN_TRACK_2, + RETURN_TRACK_3, + RETURN_TRACK_4, + RETURN_TRACK_5, + RETURN_TRACK_6, + RETURN_TRACK_7, JACK_RETURN_TRACK_0, JACK_RETURN_TRACK_1, JACK_RETURN_TRACK_2, diff --git a/src/jack.cxx b/src/jack.cxx index c0d9b79..252e996 100644 --- a/src/jack.cxx +++ b/src/jack.cxx @@ -33,7 +33,7 @@ #include "trackoutput.hxx" #include "timemanager.hxx" #include "controllerupdater.hxx" - +#include "jacksendreturn.hxx" #include "dsp/dsp_reverb.hxx" #include "dsp/dsp_dbmeter.hxx" @@ -201,9 +201,14 @@ Jack::Jack( std::string name ) : * In this case, the track's Looper instance. **/ loopers.push_back( new Looper(i) ); - trackOutputs.push_back( new TrackOutput(i, loopers.back() ) ); + + + tracksendreturns.push_back(new JackSendReturn(i,loopers.back(),client)); + trackOutputs.push_back( new TrackOutput(i, tracksendreturns.back() ) ); buffers.audio[Buffers::TRACK_0 + i] = new float[ buffers.nframes ]; + buffers.audio[Buffers::SEND_TRACK_0+i]=new float[buffers.nframes]; + buffers.audio[Buffers::RETURN_TRACK_0+i]=new float[buffers.nframes]; timeManager->registerObserver( loopers.back() ); } @@ -264,6 +269,12 @@ Jack::~Jack() delete inputMeter; delete masterMeter; + for(int i = 0; i < NTRACKS; i++) + { + delete [] buffers.audio[Buffers::TRACK_0+i]; + delete [] buffers.audio[Buffers::SEND_TRACK_0+i]; + delete [] buffers.audio[Buffers::RETURN_TRACK_0+i]; + } } void Jack::activate() @@ -543,7 +554,11 @@ void Jack::clearInternalBuffers(int nframes) memset(buffers.audio[Buffers::MASTER_OUT_L],0,sizeof(float)*nframes); memset(buffers.audio[Buffers::MASTER_OUT_R],0,sizeof(float)*nframes); for(int i=0;i loopers; + vector tracksendreturns; vector trackOutputs; vector midiIO; diff --git a/src/jacksendreturn.cxx b/src/jacksendreturn.cxx new file mode 100644 index 0000000..b66f42f --- /dev/null +++ b/src/jacksendreturn.cxx @@ -0,0 +1,38 @@ +#include "jacksendreturn.hxx" +#include "jack.hxx" +extern Jack* jack; +JackSendReturn::JackSendReturn(int trackid, AudioProcessor *prev, jack_client_t *client) + :m_trackid(trackid), m_previousProcessor(prev) +{ + char name[50]; + sprintf(name, "Send_track_%d\0",trackid); + m_sendport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0); + sprintf(name, "Return_track_%d\0",trackid); + m_returnport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0); +} + +void JackSendReturn::process(unsigned int nframes, Buffers *buffers) +{ + //Reset send buffer + memset(buffers->audio[Buffers::SEND_TRACK_0+m_trackid],0,nframes*sizeof(float)); + + //Process previous AudioProcessor + m_previousProcessor->process(nframes,buffers); + float* send=(float*)jack_port_get_buffer(m_sendport,(jack_nframes_t)nframes); + float* ret=(float*)jack_port_get_buffer(m_returnport,(jack_nframes_t)nframes); + + //Copy result of previous AudioProcessor to send port + memcpy(send,buffers->audio[Buffers::SEND_TRACK_0+m_trackid],nframes*sizeof(float)); + + //Get connection status + bool connected=jack_port_connected(m_returnport); + //Is return port connected? + //Yes then grab the audio data from the connected port + //No: get the audio from the previous AudioProcessor + if(connected) + memcpy(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid],ret,nframes*sizeof(float)); + else + memcpy(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid], + buffers->audio[Buffers::SEND_TRACK_0+m_trackid],nframes*sizeof(float)); + +} diff --git a/src/jacksendreturn.hxx b/src/jacksendreturn.hxx new file mode 100644 index 0000000..3d31ca2 --- /dev/null +++ b/src/jacksendreturn.hxx @@ -0,0 +1,49 @@ +/* + * Author: Gerald Mwangi 2016 + * gerald.mwangi@gmx.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef JACKSENDREUTRN_H +#define JACKSENDRETURN_H +#include "buffers.hxx" +#include "audioprocessor.hxx" +#include + +/// JackSendReturn: This class provides per track send and return jack ports +/// The send port always sends the output of the previous AudioProcesser +/// The content of the return channel depends on whether the return jack port is connected: +/// If it is connected it receives what ever audio comes into it. +/// If it is not connected, it receives the output of the previous AudioProcessor (it gets what goes into the send port) +class JackSendReturn: public AudioProcessor +{ +public: + //Constructor: the registration of the jack send/return is done here + JackSendReturn(int trackid,AudioProcessor* prev,jack_client_t* client); + + //The process callback + virtual void process(unsigned int nframes, Buffers* buffers); + +private: + jack_port_t* m_sendport; + jack_port_t* m_returnport; + int m_trackid; + AudioProcessor* m_previousProcessor; +}; + + + + +#endif diff --git a/src/looper.cxx b/src/looper.cxx index b6458aa..34d3e9d 100644 --- a/src/looper.cxx +++ b/src/looper.cxx @@ -136,7 +136,7 @@ void Looper::process(unsigned int nframes, Buffers* buffers) playSpeed = float(actualFrames) / targetFrames; } - float* out = buffers->audio[Buffers::TRACK_0 + track]; + float* out = buffers->audio[Buffers::SEND_TRACK_0 + track]; for(unsigned int i = 0; i < nframes; i++ ) { diff --git a/src/trackoutput.cxx b/src/trackoutput.cxx index c1e64ba..549bfbd 100644 --- a/src/trackoutput.cxx +++ b/src/trackoutput.cxx @@ -108,7 +108,7 @@ void TrackOutput::process(unsigned int nframes, Buffers* buffers) if(fabs(_toMaster-_toMasterLag)>=fabs(_toMasterDiff/10.0)) _toMasterLag+=_toMasterDiff/10.0; // get & zero track buffer - float* trackBuffer = buffers->audio[Buffers::TRACK_0 + track]; + float* trackBuffer = buffers->audio[Buffers::RETURN_TRACK_0 + track]; memset( trackBuffer, 0, sizeof(float)*nframes ); // call process() up the chain