From 298b18af04d9be4cc7ebaf04458a5189d2c29a56 Mon Sep 17 00:00:00 2001 From: Harry van Haaren Date: Tue, 3 Sep 2013 19:35:02 +0100 Subject: [PATCH] -Updated LooperClip, it now handles save() gracefully, copying data to GUI thread to be serialized to disk. --- src/event.hxx | 40 +++++++++++++++++++++++++++++++++++++++- src/eventhandlerdsp.cxx | 8 ++++++++ src/eventhandlergui.cxx | 35 +++++++++++++++++++++++++++++++++++ src/gmastertrack.hxx | 4 +++- src/looperclip.cxx | 32 ++++++++++++++++++++++++++++---- src/looperclip.hxx | 3 +++ 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/src/event.hxx b/src/event.hxx index 54a0e0c..0299729 100644 --- a/src/event.hxx +++ b/src/event.hxx @@ -30,7 +30,10 @@ namespace Event MASTER_VOL, RECORD, - SAVE, + SAVE, // save action + SAVE_BUFFER,// save an individual AudioBuffer* to disk + + REQUEST_SAVE_BUFFER, // gets an audioBuffer of a certain size GRID_EVENT, // press / release events GRID_STATE, // state of one block @@ -332,6 +335,41 @@ class EventLooperClipRequestBuffer : public EventBase EventLooperClipRequestBuffer(int t, int s, AudioBuffer* a): track(t), scene(s), numElements(0), ab(a) {} }; + +class EventSaveBuffer : public EventBase +{ + public: + int type() { return int(SAVE_BUFFER); } + uint32_t size() { return sizeof(EventSaveBuffer); } + + int track; + int scene; + // pointer to the AudioBuffer to be saved + AudioBuffer* ab; + + EventSaveBuffer(): track(0), scene(0), ab(0) {} + EventSaveBuffer(int t, int s, AudioBuffer* a): track(t), scene(s), ab(a) {} +}; + +class EventRequestSaveBuffer : public EventBase +{ + public: + int type() { return int(REQUEST_SAVE_BUFFER); } + uint32_t size() { return sizeof(EventRequestSaveBuffer); } + + int track; + int scene; + + size_t bufferSize; + + // pointer to the AudioBuffer to be saved + AudioBuffer* ab; + + EventRequestSaveBuffer(): track(0), scene(0), ab(0) {} + EventRequestSaveBuffer(int t, int s, size_t si): track(t), scene(s), bufferSize(si), ab(0) {} + EventRequestSaveBuffer(int t, int s, AudioBuffer* a): track(t), scene(s), ab(a) {} +}; + class EventDeallocateBuffer : public EventBase { public: diff --git a/src/eventhandlerdsp.cxx b/src/eventhandlerdsp.cxx index 3944090..9e1fa4e 100644 --- a/src/eventhandlerdsp.cxx +++ b/src/eventhandlerdsp.cxx @@ -144,6 +144,14 @@ void handleDspEvents() jack->getLooper( ev.track )->setRequestedBuffer( ev.scene, ev.ab ); } break; } + case Event::REQUEST_SAVE_BUFFER: { + if ( availableRead >= sizeof(EventRequestSaveBuffer) ) { + EventRequestSaveBuffer ev; + jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRequestSaveBuffer) ); + cout << "Save buffer sent with t s ab* " << ev.track << " " << ev.scene << " " << ev.ab << endl; + jack->getLooper( ev.track )->getClip(ev.scene)->recieveSaveBuffer( ev.ab ); + } break; } + default: { cout << "DSP: Unkown message!! Will clog ringbuffer" << endl; diff --git a/src/eventhandlergui.cxx b/src/eventhandlergui.cxx index 534e337..543c346 100644 --- a/src/eventhandlergui.cxx +++ b/src/eventhandlergui.cxx @@ -95,6 +95,18 @@ void handleGuiEvents() } break; } + case Event::SAVE_BUFFER: { + if ( availableRead >= sizeof(EventSaveBuffer) ) { + EventSaveBuffer ev; + jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSaveBuffer) ); + // stream buffer to disk, add to JSON + + cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl; + + + } break; } + + case Event::GRID_STATE: { if ( availableRead >= sizeof(EventGridState) ) { EventGridState ev; @@ -170,6 +182,29 @@ void handleGuiEvents() printf("new buffer going to track %i, scene %i\n",ev.track, ev.scene); #endif } break; } + + case Event::REQUEST_SAVE_BUFFER: { + if ( availableRead >= sizeof(EventRequestSaveBuffer) ) { + EventRequestSaveBuffer ev; + jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventRequestSaveBuffer) ); +#ifdef DEBUG_BUFFER + printf("Save buffer to track %i, scene %i\n",ev.track, ev.scene); +#endif + /// allocate a new AudioBuffer with ev.numElements, pass back to DSP + AudioBuffer* ab = new AudioBuffer(ev.bufferSize); + + if ( ab ) + { + cout << "Save buffer sent with t s ab* " << ev.track << " " << ev.scene << " " << ab << endl; + EventRequestSaveBuffer returnEvent( ev.track, ev.scene, ab); + writeToDspRingbuffer( &returnEvent ); + } + else + { + cout << "error allocating save buffer!" << endl; + } + } break; } + case Event::DEALLOCATE_BUFFER: { if ( availableRead >= sizeof(EventDeallocateBuffer) ) { EventDeallocateBuffer ev; diff --git a/src/gmastertrack.hxx b/src/gmastertrack.hxx index fbddf85..afd3af0 100644 --- a/src/gmastertrack.hxx +++ b/src/gmastertrack.hxx @@ -49,7 +49,9 @@ static void gmastertrack_button_callback(Fl_Widget *w, void *data) { else if ( strcmp( w->label(), "Tap" ) == 0 ) { //Avtk::Button* b = (Avtk::Button*)w; - EventTimeTempoTap e; + //EventTimeTempoTap e; + //writeToDspRingbuffer( &e ); + EventSave e; writeToDspRingbuffer( &e ); } else diff --git a/src/looperclip.cxx b/src/looperclip.cxx index ee207ae..a5e9de4 100644 --- a/src/looperclip.cxx +++ b/src/looperclip.cxx @@ -33,10 +33,18 @@ LooperClip::LooperClip(int t, int s) : void LooperClip::save() { - char buffer [50]; - sprintf (buffer, "LooperClip::save() track %i, scene %i", track,scene); - EventGuiPrint e( buffer ); - writeToGuiRingbuffer( &e ); + // ensure there is something in the buffer to be saved + if ( _loaded ) + { + char buffer [50]; + sprintf (buffer, "LooperClip::save() track %i, scene %i", track,scene); + EventGuiPrint e( buffer ); + writeToGuiRingbuffer( &e ); + + EventRequestSaveBuffer e2( track, scene, _buffer->getData().size() ); + writeToGuiRingbuffer( &e2 ); + } + } /// loads a sample: eg from disk, unloading current sample if necessary @@ -84,6 +92,22 @@ void LooperClip::setRequestedBuffer( AudioBuffer* ab ) } + +void LooperClip::recieveSaveBuffer( AudioBuffer* saveBuffer ) +{ + // copy current contents into save buffer, + size_t size = _buffer->getData().size(); + memcpy( &saveBuffer->getData().at(0), &_buffer->getData().at(0), sizeof(float)*size); + + saveBuffer->setID ( _buffer->getID() ); + saveBuffer->setBeats( _buffer->getBeats() ); + + EventSaveBuffer e ( track, scene, saveBuffer ); + writeToGuiRingbuffer( &e ); +} + + + void LooperClip::record(int count, float* L, float* R) { // write "count" samples into current buffer. diff --git a/src/looperclip.hxx b/src/looperclip.hxx index ccc15c5..d5181d0 100644 --- a/src/looperclip.hxx +++ b/src/looperclip.hxx @@ -74,6 +74,9 @@ class LooperClip : public SaveAble * for de-allocation. **/ void setRequestedBuffer( AudioBuffer* ab ); + + /// used for saving the contents of this buffer to disk + void recieveSaveBuffer( AudioBuffer* ab ); private: int track, scene;