-Bug hunting, copying different buffers to master outs, refactored buffers to be allocated statically

main
Harry van Haaren 2013-08-13 00:02:59 +01:00
parent 5823cad680
commit d90921319b
8 changed files with 75 additions and 61 deletions

View File

@ -10,13 +10,8 @@ class Buffers
public: public:
Buffers() Buffers()
{ {
for(int i = 0; i < 32; i++) memset( audio, 0, sizeof(float*)*32);
{ memset( midi , 0, sizeof(void *)*32);
audio[i] = 0;
midi [i] = 0;
}
//memset( audio, 0, sizeof(float*)*32);
//memset( midi , 0, sizeof(void *)*32);
} }
float* audio[32]; float* audio[32];
void* midi [32]; void* midi [32];
@ -24,8 +19,10 @@ class Buffers
enum BUFFER { enum BUFFER {
// AUDIO // AUDIO
MASTER_INPUT = 0, MASTER_INPUT = 0,
MASTER_OUT_L = 1, MASTER_OUT_L = 1,
MASTER_OUT_R = 2, MASTER_OUT_R = 2,
JACK_MASTER_OUT_L = 3, JACK_MASTER_OUT_L = 3,
JACK_MASTER_OUT_R = 4, JACK_MASTER_OUT_R = 4,

View File

@ -74,6 +74,7 @@ void handleGuiEvents()
EventTrackSignalLevel ev; EventTrackSignalLevel ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) );
if ( ev.track < 0 ) { if ( ev.track < 0 ) {
printf("%f\t%f\n", ev.left, ev.right);
gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right ); gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right );
} else { } else {
gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right ); } gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right ); }

View File

@ -9,7 +9,7 @@
* The logic code for the luppp tracks / grid resides here. This logic is * The logic code for the luppp tracks / grid resides here. This logic is
* separtated from the Looper class so it can be repurposed by different * separtated from the Looper class so it can be repurposed by different
* controllers and input devices. The UI and eg. APC / Launchpad all have a * controllers and input devices. The UI and eg. APC / Launchpad all have a
* similar grid style interface: implementing the logic in each is not good. * similar grid style interface: the logic is implemented here once.
* *
* The class sends Looper messages to change its state, thus abstracting away * The class sends Looper messages to change its state, thus abstracting away
* the details of the Looper control, and exposing its functionality using a * the details of the Looper control, and exposing its functionality using a

View File

@ -22,7 +22,7 @@ Jack::Jack() :
logic( new Logic() ), logic( new Logic() ),
gridLogic( new GridLogic() ) gridLogic( new GridLogic() )
{ {
// open the client /// open the client
client = jack_client_open ( "Luppp", JackNullOption , 0 , 0 ); client = jack_client_open ( "Luppp", JackNullOption , 0 , 0 );
buffers.nframes = jack_get_buffer_size( client ); buffers.nframes = jack_get_buffer_size( client );
@ -31,23 +31,24 @@ Jack::Jack() :
uiUpdateCounter = buffers.samplerate / 30; uiUpdateCounter = buffers.samplerate / 30;
uiUpdateConstant = buffers.samplerate / 30; uiUpdateConstant = buffers.samplerate / 30;
masterInput = jack_port_register( client,
"master_in",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsInput,
0 );
masterOutputL = jack_port_register( client, masterOutputL = jack_port_register( client,
"master_left", "master_left",
JACK_DEFAULT_AUDIO_TYPE, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, JackPortIsOutput,
0 ); 0 );
masterOutputR = jack_port_register( client, masterOutputR = jack_port_register( client,
"master_right", "master_right",
JACK_DEFAULT_AUDIO_TYPE, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, JackPortIsOutput,
0 ); 0 );
masterInput = jack_port_register( client,
"master_in",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsInput,
0 );
masterMidiInput = jack_port_register( client, masterMidiInput = jack_port_register( client,
"midi_in", "midi_in",
JACK_DEFAULT_MIDI_TYPE, JACK_DEFAULT_MIDI_TYPE,
@ -67,25 +68,31 @@ Jack::Jack() :
0 ); 0 );
masterL.resize( buffers.nframes );
masterR.resize( buffers.nframes );
/// prepare internal buffers /// prepare internal buffers
buffers.audio[Buffers::REVERB] = new float( nframes ); buffers.audio[Buffers::REVERB] = new float( buffers.nframes );
buffers.audio[Buffers::SIDECHAIN] = new float( nframes ); buffers.audio[Buffers::SIDECHAIN] = new float( buffers.nframes );
buffers.audio[Buffers::POST_SIDECHAIN] = new float( nframes ); buffers.audio[Buffers::POST_SIDECHAIN] = new float( buffers.nframes );
buffers.audio[Buffers::MASTER_OUT_L] = new float( nframes );
buffers.audio[Buffers::MASTER_OUT_R] = new float( nframes ); buffers.audio[Buffers::MASTER_OUT_L] = &masterL[0]; //new float( buffers.nframes );
buffers.audio[Buffers::MASTER_OUT_R] = &masterR[0]; //new float( buffers.nframes );
cout << "master L buffer = " << *buffers.audio[Buffers::MASTER_OUT_L] << endl
<< "master R buffer = " << *buffers.audio[Buffers::MASTER_OUT_R] << endl
<< "difference = " << *buffers.audio[Buffers::MASTER_OUT_R] - *buffers.audio[Buffers::MASTER_OUT_L] << endl;
for(int i = 0; i < NTRACKS; i++) for(int i = 0; i < NTRACKS; i++)
{ {
//buffers.audio[Buffers::TRACK_0 + i] = new float( nframes );
loopers.push_back( new Looper(i) ); loopers.push_back( new Looper(i) );
trackOutputs.push_back( new TrackOutput(i, loopers.back() ) ); trackOutputs.push_back( new TrackOutput(i, loopers.back() ) );
timeManager.registerObserver( loopers.back() ); timeManager.registerObserver( loopers.back() );
} }
//timeManager.registerObserver( &metronome );
/// setup FX /// setup FX
reverb = new Reverb( buffers.samplerate ); reverb = new Reverb( buffers.samplerate );
reverbMeter = new DBMeter( buffers.samplerate ); reverbMeter = new DBMeter( buffers.samplerate );
@ -128,7 +135,7 @@ void Jack::activate()
int Jack::process (jack_nframes_t nframes) int Jack::process (jack_nframes_t nframes)
{ {
// get buffers /// get buffers
buffers.audio[Buffers::MASTER_INPUT] = (float*)jack_port_get_buffer( masterInput , nframes ); buffers.audio[Buffers::MASTER_INPUT] = (float*)jack_port_get_buffer( masterInput , nframes );
buffers.audio[Buffers::JACK_MASTER_OUT_L] = (float*)jack_port_get_buffer( masterOutputL , nframes ); buffers.audio[Buffers::JACK_MASTER_OUT_L] = (float*)jack_port_get_buffer( masterOutputL , 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 );
@ -136,26 +143,23 @@ int Jack::process (jack_nframes_t nframes)
buffers.midi [Buffers::APC_INPUT] = (void*) jack_port_get_buffer( apcMidiInput , nframes ); buffers.midi [Buffers::APC_INPUT] = (void*) jack_port_get_buffer( apcMidiInput , nframes );
buffers.midi [Buffers::APC_OUTPUT] = (void*) jack_port_get_buffer( apcMidiOutput , nframes ); buffers.midi [Buffers::APC_OUTPUT] = (void*) jack_port_get_buffer( apcMidiOutput , nframes );
memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::REVERB] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::REVERB] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::SIDECHAIN] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::POST_SIDECHAIN] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::POST_SIDECHAIN] , 0, sizeof(float) * nframes );
jack_midi_clear_buffer( buffers.midi[Buffers::APC_OUTPUT] ); jack_midi_clear_buffer( buffers.midi[Buffers::APC_OUTPUT] );
// do events from the ringbuffer
/// do events from the ringbuffer
handleDspEvents(); handleDspEvents();
// process incoming MIDI
/// process incoming MIDI
jack_midi_event_t in_event; jack_midi_event_t in_event;
int masterMidiInputIndex = 0; int masterMidiInputIndex = 0;
int event_count = (int) jack_midi_get_event_count( buffers.midi[Buffers::MASTER_MIDI_INPUT] ); int event_count = (int) jack_midi_get_event_count( buffers.midi[Buffers::MASTER_MIDI_INPUT] );
@ -168,7 +172,7 @@ int Jack::process (jack_nframes_t nframes)
EventGuiPrint e( buffer ); EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
// check each looper for MIDI match // run each event trought the midiObservers vector
for( int i = 0; i < midiObservers.size(); i++ ) for( int i = 0; i < midiObservers.size(); i++ )
{ {
midiObservers.at(i)->midi( (unsigned char*) &in_event.buffer[0] ); midiObservers.at(i)->midi( (unsigned char*) &in_event.buffer[0] );
@ -178,16 +182,16 @@ int Jack::process (jack_nframes_t nframes)
masterMidiInputIndex++; masterMidiInputIndex++;
} }
// process each track, starting at output and working up signal path /// process each track, starting at output and working up signal path
for(uint i = 0; i < NTRACKS; i++) for(uint i = 0; i < NTRACKS; i++)
{ {
//loopers.at(i)->process( nframes, &buffers );
trackOutputs.at(i)->process( nframes, &buffers ); trackOutputs.at(i)->process( nframes, &buffers );
} }
metronome->process( nframes, &buffers ); metronome->process( nframes, &buffers );
/*
// process fx // process fx
float* buf[] = { float* buf[] = {
buffers.audio[Buffers::REVERB], buffers.audio[Buffers::REVERB],
@ -201,6 +205,7 @@ int Jack::process (jack_nframes_t nframes)
reverbMeter->process(nframes, buffers.audio[Buffers::REVERB], buffers.audio[Buffers::REVERB] ); reverbMeter->process(nframes, buffers.audio[Buffers::REVERB], buffers.audio[Buffers::REVERB] );
reverb->process( nframes, &buf[0], &buf[2] ); reverb->process( nframes, &buf[0], &buf[2] );
} }
*/
// db meter on master output, then memcpy to JACK // db meter on master output, then memcpy to JACK
masterMeter->process(nframes, buffers.audio[Buffers::MASTER_OUT_L], buffers.audio[Buffers::MASTER_OUT_R] ); masterMeter->process(nframes, buffers.audio[Buffers::MASTER_OUT_L], buffers.audio[Buffers::MASTER_OUT_R] );
@ -216,15 +221,25 @@ int Jack::process (jack_nframes_t nframes)
uiUpdateCounter += nframes; uiUpdateCounter += nframes;
for(int i = 0; i < buffers.nframes; i++)
{
buffers.audio[Buffers::JACK_MASTER_OUT_L][i] = buffers.audio[Buffers::MASTER_OUT_L][i];
buffers.audio[Buffers::JACK_MASTER_OUT_R][i] = buffers.audio[Buffers::MASTER_OUT_R][i];
}
/*
// memcpy the internal MASTER_OUTPUT buffer to the JACK_MASTER_OUTPUT // memcpy the internal MASTER_OUTPUT buffer to the JACK_MASTER_OUTPUT
memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_L], memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_L],
buffers.audio[Buffers::MASTER_OUT_L], buffers.audio[Buffers::MASTER_OUT_L],
//buffers.audio[Buffers::TRACK_7],
sizeof(float)*nframes); sizeof(float)*nframes);
memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_R], memcpy( buffers.audio[Buffers::JACK_MASTER_OUT_R],
buffers.audio[Buffers::MASTER_OUT_R], buffers.audio[Buffers::MASTER_OUT_R],
//buffers.audio[Buffers::TRACK_7],
//buffers.audio[Buffers::REVERB], // uncomment to listen to reverb send only //buffers.audio[Buffers::REVERB], // uncomment to listen to reverb send only
sizeof(float)*nframes); sizeof(float)*nframes);
*/
return false; return false;
} }

View File

@ -72,8 +72,10 @@ class Jack
vector<TrackOutput*> trackOutputs; vector<TrackOutput*> trackOutputs;
vector<MidiObserver*> midiObservers; vector<MidiObserver*> midiObservers;
int nframes; // internal audio buffers
int samplerate; vector<float> masterL;
vector<float> masterR;
// FX // FX
Reverb* reverb; Reverb* reverb;

View File

@ -32,7 +32,7 @@ class LooperClip
_playing = false; _playing = false;
_recording = false; _recording = false;
_buffer = new AudioBuffer(44100); _buffer = 0; //new AudioBuffer(44100);
_newBufferInTransit = false; _newBufferInTransit = false;
_playhead = 0; _playhead = 0;

View File

@ -26,7 +26,7 @@ class Metronome : public TimeObserver
// samples per cycle of // samples per cycle of
float scale = 2 * 3.1415 / endPoint; float scale = 2 * 3.1415 / endPoint;
/*And fill it up*/ // And fill it up
for(int i=0;i < endPoint*40;i++){ for(int i=0;i < endPoint*40;i++){
beatSample[i]= sin(i*scale); beatSample[i]= sin(i*scale);
barSample [i]= sin(i*scale*1.5); barSample [i]= sin(i*scale*1.5);
@ -68,7 +68,8 @@ class Metronome : public TimeObserver
if ( not active ) if ( not active )
return; return;
float* out = buffers->audio[Buffers::MASTER_OUT_L]; float* outL = buffers->audio[Buffers::MASTER_OUT_L];
float* outR = buffers->audio[Buffers::MASTER_OUT_R];
float* sample = &beatSample[0]; float* sample = &beatSample[0];
if( playBar ) { sample = &barSample[0]; playBar = false; } if( playBar ) { sample = &barSample[0]; playBar = false; }
@ -77,9 +78,10 @@ class Metronome : public TimeObserver
{ {
if ( playPoint < endPoint ) if ( playPoint < endPoint )
{ {
out[i] += sample[playPoint++]; outL[i] += sample[playPoint];
outR[i] += sample[playPoint];
playPoint++;
} }
} }
} }

View File

@ -2,6 +2,7 @@
#ifndef LUPPP_TRACK_OUTPUT_H #ifndef LUPPP_TRACK_OUTPUT_H
#define LUPPP_TRACK_OUTPUT_H #define LUPPP_TRACK_OUTPUT_H
#include <iostream>
#include <stdio.h> #include <stdio.h>
#include "config.hxx" #include "config.hxx"
@ -20,8 +21,8 @@ class TrackOutput : public AudioProcessor
previousInChain(ap), previousInChain(ap),
dbMeter(44100) dbMeter(44100)
{ {
printf("trackOutput ID: %i\n", track); printf("trackOutput ID: %i, ap = ", track );
std::cout << ap << std::endl;
// UI update // UI update
@ -64,11 +65,8 @@ class TrackOutput : public AudioProcessor
// zero track buffer // zero track buffer
memset( &_trackBuffer[0], 0, nframes ); memset( &_trackBuffer[0], 0, nframes );
if ( previousInChain ) buffers->audio[Buffers::TRACK_0 + track] = &_trackBuffer[0];
{ previousInChain->process( nframes, buffers );
buffers->audio[Buffers::TRACK_0 + track] = &_trackBuffer[0];
previousInChain->process( nframes, buffers );
}
// run the meter // run the meter
@ -86,7 +84,6 @@ class TrackOutput : public AudioProcessor
/// copy audio data into reverb / sidechain / master buffers /// copy audio data into reverb / sidechain / master buffers
float* trackBuf = buffers->audio[Buffers::TRACK_0 + track];
float* reverb = buffers->audio[Buffers::REVERB]; float* reverb = buffers->audio[Buffers::REVERB];
float* sidechain = buffers->audio[Buffers::SIDECHAIN]; float* sidechain = buffers->audio[Buffers::SIDECHAIN];
float* postSidechain = buffers->audio[Buffers::POST_SIDECHAIN]; float* postSidechain = buffers->audio[Buffers::POST_SIDECHAIN];
@ -98,15 +95,15 @@ class TrackOutput : public AudioProcessor
{ {
float tmp = _trackBuffer[i]; float tmp = _trackBuffer[i];
*masterL++ += tmp * _toMaster; masterL[i] += tmp * _toMaster;
*masterR++ += tmp * _toMaster; masterR[i] += tmp * _toMaster;
//*reverb++ += tmp * _toReverb; masterL++;
//*sidechain++ += tmp * _toSidechain; masterR++;
//*postSidechain++ += tmp * _toPostSidechain;
*reverb++ += tmp * _toReverb;
trackBuf++; *sidechain++ += tmp * _toSidechain;
*postSidechain++ += tmp * _toPostSidechain;
} }
} }