From d90921319b2cefd3edf6b2cd0867786ab2ddb6dc Mon Sep 17 00:00:00 2001 From: Harry van Haaren Date: Tue, 13 Aug 2013 00:02:59 +0100 Subject: [PATCH] -Bug hunting, copying different buffers to master outs, refactored buffers to be allocated statically --- src/buffers.hxx | 11 +++--- src/eventhandlergui.cxx | 1 + src/gridlogic.hxx | 2 +- src/jack.cxx | 77 ++++++++++++++++++++++++----------------- src/jack.hxx | 6 ++-- src/looperclip.hxx | 2 +- src/metronome.hxx | 10 +++--- src/trackoutput.hxx | 27 +++++++-------- 8 files changed, 75 insertions(+), 61 deletions(-) diff --git a/src/buffers.hxx b/src/buffers.hxx index a25b88f..5f673f2 100644 --- a/src/buffers.hxx +++ b/src/buffers.hxx @@ -10,13 +10,8 @@ class Buffers public: Buffers() { - for(int i = 0; i < 32; i++) - { - audio[i] = 0; - midi [i] = 0; - } - //memset( audio, 0, sizeof(float*)*32); - //memset( midi , 0, sizeof(void *)*32); + memset( audio, 0, sizeof(float*)*32); + memset( midi , 0, sizeof(void *)*32); } float* audio[32]; void* midi [32]; @@ -24,8 +19,10 @@ class Buffers enum BUFFER { // AUDIO MASTER_INPUT = 0, + MASTER_OUT_L = 1, MASTER_OUT_R = 2, + JACK_MASTER_OUT_L = 3, JACK_MASTER_OUT_R = 4, diff --git a/src/eventhandlergui.cxx b/src/eventhandlergui.cxx index efa6575..a736355 100644 --- a/src/eventhandlergui.cxx +++ b/src/eventhandlergui.cxx @@ -74,6 +74,7 @@ void handleGuiEvents() EventTrackSignalLevel ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) ); if ( ev.track < 0 ) { + printf("%f\t%f\n", ev.left, ev.right); gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right ); } else { gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right ); } diff --git a/src/gridlogic.hxx b/src/gridlogic.hxx index 04946f9..f6a0479 100644 --- a/src/gridlogic.hxx +++ b/src/gridlogic.hxx @@ -9,7 +9,7 @@ * 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 * 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 details of the Looper control, and exposing its functionality using a diff --git a/src/jack.cxx b/src/jack.cxx index 270aded..fe0f1c6 100644 --- a/src/jack.cxx +++ b/src/jack.cxx @@ -22,7 +22,7 @@ Jack::Jack() : logic( new Logic() ), gridLogic( new GridLogic() ) { - // open the client + /// open the client client = jack_client_open ( "Luppp", JackNullOption , 0 , 0 ); buffers.nframes = jack_get_buffer_size( client ); @@ -31,23 +31,24 @@ Jack::Jack() : uiUpdateCounter = 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, "master_left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); + masterOutputR = jack_port_register( client, "master_right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); - masterInput = jack_port_register( client, - "master_in", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, - 0 ); - masterMidiInput = jack_port_register( client, "midi_in", JACK_DEFAULT_MIDI_TYPE, @@ -67,25 +68,31 @@ Jack::Jack() : 0 ); + masterL.resize( buffers.nframes ); + masterR.resize( buffers.nframes ); + /// prepare internal buffers - buffers.audio[Buffers::REVERB] = new float( nframes ); - buffers.audio[Buffers::SIDECHAIN] = new float( nframes ); - buffers.audio[Buffers::POST_SIDECHAIN] = new float( nframes ); - buffers.audio[Buffers::MASTER_OUT_L] = new float( nframes ); - buffers.audio[Buffers::MASTER_OUT_R] = new float( nframes ); + buffers.audio[Buffers::REVERB] = new float( buffers.nframes ); + buffers.audio[Buffers::SIDECHAIN] = new float( buffers.nframes ); + buffers.audio[Buffers::POST_SIDECHAIN] = new float( buffers.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++) { - //buffers.audio[Buffers::TRACK_0 + i] = new float( nframes ); - loopers.push_back( new Looper(i) ); trackOutputs.push_back( new TrackOutput(i, loopers.back() ) ); timeManager.registerObserver( loopers.back() ); } - //timeManager.registerObserver( &metronome ); - /// setup FX reverb = new Reverb( buffers.samplerate ); reverbMeter = new DBMeter( buffers.samplerate ); @@ -128,7 +135,7 @@ void Jack::activate() 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::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 ); @@ -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_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_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::JACK_MASTER_OUT_L] , 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::REVERB] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::SIDECHAIN] , 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::POST_SIDECHAIN] , 0, sizeof(float) * nframes ); - jack_midi_clear_buffer( buffers.midi[Buffers::APC_OUTPUT] ); - // do events from the ringbuffer + + /// do events from the ringbuffer handleDspEvents(); - // process incoming MIDI + + /// process incoming MIDI jack_midi_event_t in_event; - - int masterMidiInputIndex = 0; 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 ); writeToGuiRingbuffer( &e ); - // check each looper for MIDI match + // run each event trought the midiObservers vector for( int i = 0; i < midiObservers.size(); i++ ) { midiObservers.at(i)->midi( (unsigned char*) &in_event.buffer[0] ); @@ -178,16 +182,16 @@ int Jack::process (jack_nframes_t nframes) 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++) { - //loopers.at(i)->process( nframes, &buffers ); trackOutputs.at(i)->process( nframes, &buffers ); } metronome->process( nframes, &buffers ); + /* // process fx float* buf[] = { 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] ); reverb->process( nframes, &buf[0], &buf[2] ); } + */ // db meter on master output, then memcpy to JACK 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; + 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( buffers.audio[Buffers::JACK_MASTER_OUT_L], buffers.audio[Buffers::MASTER_OUT_L], + //buffers.audio[Buffers::TRACK_7], sizeof(float)*nframes); memcpy( buffers.audio[Buffers::JACK_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 sizeof(float)*nframes); + */ return false; } diff --git a/src/jack.hxx b/src/jack.hxx index d6e01ed..5a1ce66 100644 --- a/src/jack.hxx +++ b/src/jack.hxx @@ -72,8 +72,10 @@ class Jack vector trackOutputs; vector midiObservers; - int nframes; - int samplerate; + // internal audio buffers + vector masterL; + vector masterR; + // FX Reverb* reverb; diff --git a/src/looperclip.hxx b/src/looperclip.hxx index 1de6eab..91cc98e 100644 --- a/src/looperclip.hxx +++ b/src/looperclip.hxx @@ -32,7 +32,7 @@ class LooperClip _playing = false; _recording = false; - _buffer = new AudioBuffer(44100); + _buffer = 0; //new AudioBuffer(44100); _newBufferInTransit = false; _playhead = 0; diff --git a/src/metronome.hxx b/src/metronome.hxx index acdb6a6..0bce221 100644 --- a/src/metronome.hxx +++ b/src/metronome.hxx @@ -26,7 +26,7 @@ class Metronome : public TimeObserver // samples per cycle of float scale = 2 * 3.1415 / endPoint; - /*And fill it up*/ + // And fill it up for(int i=0;i < endPoint*40;i++){ beatSample[i]= sin(i*scale); barSample [i]= sin(i*scale*1.5); @@ -68,7 +68,8 @@ class Metronome : public TimeObserver if ( not active ) 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]; if( playBar ) { sample = &barSample[0]; playBar = false; } @@ -77,9 +78,10 @@ class Metronome : public TimeObserver { if ( playPoint < endPoint ) { - out[i] += sample[playPoint++]; + outL[i] += sample[playPoint]; + outR[i] += sample[playPoint]; + playPoint++; } - } } diff --git a/src/trackoutput.hxx b/src/trackoutput.hxx index 1500d4f..6c99e62 100644 --- a/src/trackoutput.hxx +++ b/src/trackoutput.hxx @@ -2,6 +2,7 @@ #ifndef LUPPP_TRACK_OUTPUT_H #define LUPPP_TRACK_OUTPUT_H +#include #include #include "config.hxx" @@ -20,8 +21,8 @@ class TrackOutput : public AudioProcessor previousInChain(ap), dbMeter(44100) { - printf("trackOutput ID: %i\n", track); - + printf("trackOutput ID: %i, ap = ", track ); + std::cout << ap << std::endl; // UI update @@ -64,11 +65,8 @@ class TrackOutput : public AudioProcessor // zero track buffer 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 @@ -86,7 +84,6 @@ class TrackOutput : public AudioProcessor /// copy audio data into reverb / sidechain / master buffers - float* trackBuf = buffers->audio[Buffers::TRACK_0 + track]; float* reverb = buffers->audio[Buffers::REVERB]; float* sidechain = buffers->audio[Buffers::SIDECHAIN]; float* postSidechain = buffers->audio[Buffers::POST_SIDECHAIN]; @@ -98,15 +95,15 @@ class TrackOutput : public AudioProcessor { float tmp = _trackBuffer[i]; - *masterL++ += tmp * _toMaster; - *masterR++ += tmp * _toMaster; + masterL[i] += tmp * _toMaster; + masterR[i] += tmp * _toMaster; - //*reverb++ += tmp * _toReverb; - //*sidechain++ += tmp * _toSidechain; - //*postSidechain++ += tmp * _toPostSidechain; + masterL++; + masterR++; - - trackBuf++; + *reverb++ += tmp * _toReverb; + *sidechain++ += tmp * _toSidechain; + *postSidechain++ += tmp * _toPostSidechain; } }