Added per track sends and returns via JackSendReturn (subclass of AudioProcessor)

main
Gerald 2016-10-03 19:43:13 +02:00
parent 71e9c8526c
commit 6f88b009f6
7 changed files with 124 additions and 5 deletions

View File

@ -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,

View File

@ -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<NTRACKS;i++)
{
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::RETURN_TRACK_0 + i],0,sizeof(float)*nframes);
}
}
void Jack::masterVolume(float vol)

View File

@ -40,7 +40,7 @@ class Metronome;
class GridLogic;
class TimeManager;
class ControllerUpdater;
class JackSendReturn;
class TrackOutput;
// INPUT_TO
@ -124,6 +124,7 @@ class Jack
ControllerUpdater* controllerUpdater;
vector<Looper*> loopers;
vector<JackSendReturn*> tracksendreturns;
vector<TrackOutput*> trackOutputs;
vector<MidiIO*> midiIO;

38
src/jacksendreturn.cxx Normal file
View File

@ -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));
}

49
src/jacksendreturn.hxx Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef JACKSENDREUTRN_H
#define JACKSENDRETURN_H
#include "buffers.hxx"
#include "audioprocessor.hxx"
#include <jack/jack.h>
/// 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

View File

@ -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++ )
{

View File

@ -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