-Updated Save to work with LooperClip, added Save::done() static function for counting finished saves, and knowing when to flush metadata to disk.

This commit is contained in:
Harry van Haaren 2013-09-03 20:06:11 +01:00
parent 07a6aa7d6d
commit 05984fbc9b
13 changed files with 107 additions and 46 deletions

View file

@ -15,6 +15,8 @@
// Logic : Warning NON RT! // Logic : Warning NON RT!
#define DEBUG_LOGIC 1 #define DEBUG_LOGIC 1
// Saving state
#define DEBUG_SAVE 1
/// General Options /// General Options
#define NTRACKS 8 #define NTRACKS 8

View file

@ -1,13 +1,28 @@
#include "diskwriter.hxx" #include "diskwriter.hxx"
#include <iostream>
using namespace std;
DiskWriter::DiskWriter() DiskWriter::DiskWriter()
{ {
session = cJSON_CreateObject();
audioConfig = cJSON_CreateObject();
}; };
void DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab ) void DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab )
{ {
// add the track / scene / name combo to audioConfig JSON node // add the track / scene / name combo to session JSON node
cJSON* clip = cJSON_CreateObject();
cJSON_AddItemToObject(session, "clip", clip );
cJSON_AddNumberToObject(clip,"track", track);
cJSON_AddNumberToObject(clip,"scene", scene);
cJSON_AddStringToObject(clip,"file", "filenameHere.wav");
// write the AudioBuffer contents to <path>/samples/ as <name>.wav // write the AudioBuffer contents to <path>/samples/ as <name>.wav
// or alternatively t_<track>_s_<scene>.wav // or alternatively t_<track>_s_<scene>.wav
@ -20,6 +35,13 @@ void DiskWriter::writeSession( std::string path, std::string sessionName )
// write session.luppp JSON node to <path>/<sessionName>.luppp // write session.luppp JSON node to <path>/<sessionName>.luppp
cJSON_AddItemToObject ( session, "session", cJSON_CreateString( sessionName.c_str() ));
cJSON_AddNumberToObject( session, "version_major", 1 );
cJSON_AddNumberToObject( session, "version_minor", 0 );
cJSON_AddNumberToObject( session, "version_patch", 0 );
cJSON_AddNumberToObject( session, "bpm", 120 );
char* out = cJSON_Print( session );
cout << out << endl;
} }

View file

@ -4,6 +4,8 @@
#include <string> #include <string>
#include "cjson/cJSON.h"
class AudioBuffer; class AudioBuffer;
/** DiskWriter /** DiskWriter
@ -22,7 +24,8 @@ class DiskWriter
void writeSession( std::string path, std::string sessionName ); void writeSession( std::string path, std::string sessionName );
private: private:
cJSON* session;
cJSON* audioConfig;
}; };
#endif // LUPPP_DISK_WRITER_H #endif // LUPPP_DISK_WRITER_H

View file

@ -31,6 +31,7 @@ namespace Event
RECORD, RECORD,
SAVE, // save action SAVE, // save action
SAVE_FINISH,// save action finished, flush metadata to disk
SAVE_BUFFER,// save an individual AudioBuffer* to disk SAVE_BUFFER,// save an individual AudioBuffer* to disk
REQUEST_SAVE_BUFFER, // gets an audioBuffer of a certain size REQUEST_SAVE_BUFFER, // gets an audioBuffer of a certain size
@ -116,6 +117,15 @@ class EventSave : public EventBase
EventSave(){}; EventSave(){};
}; };
class EventSaveFinish : public EventBase
{
public:
int type() { return int(SAVE_FINISH); }
uint32_t size() { return sizeof(EventSaveFinish); }
EventSaveFinish(){};
};
class EventGridEvent : public EventBase class EventGridEvent : public EventBase
{ {
public: public:

View file

@ -99,11 +99,20 @@ void handleGuiEvents()
if ( availableRead >= sizeof(EventSaveBuffer) ) { if ( availableRead >= sizeof(EventSaveBuffer) ) {
EventSaveBuffer ev; EventSaveBuffer ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSaveBuffer) ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSaveBuffer) );
// stream buffer to disk, add to JSON #ifdef DEBUG_SAVE
cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl; cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl;
#endif
gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
} break; }
case Event::SAVE_FINISH: {
if ( availableRead >= sizeof(EventSaveFinish) ) {
EventSaveFinish ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSaveFinish) );
#ifdef DEBUG_SAVE
cout << "EventSaveFinish!" << endl;
#endif
gui->getDiskWriter()->writeSession("path", "sessionName");
} break; } } break; }

View file

@ -49,7 +49,8 @@ static void gui_static_read_rb(void* inst)
} }
Gui::Gui() : Gui::Gui() :
window(1110,650) window(1110,650),
diskWriter( new DiskWriter )
{ {
window.color(FL_BLACK); window.color(FL_BLACK);
window.label("Luppp"); window.label("Luppp");
@ -91,8 +92,6 @@ int Gui::show()
gui_static_read_rb( this ); gui_static_read_rb( this );
Worker::save("dummyPath", "dummyName");
return Fl::run(); return Fl::run();
} }

View file

@ -9,6 +9,7 @@
#include "config.hxx" #include "config.hxx"
#include "gtrack.hxx" #include "gtrack.hxx"
#include "gunittrack.hxx" #include "gunittrack.hxx"
#include "diskwriter.hxx"
#include "gmastertrack.hxx" #include "gmastertrack.hxx"
#include <vector> #include <vector>
@ -24,6 +25,8 @@ class Gui
GTrack* getTrack(int id); GTrack* getTrack(int id);
GMasterTrack* getMasterTrack(){return master;} GMasterTrack* getMasterTrack(){return master;}
DiskWriter* getDiskWriter(){return diskWriter;}
// for pushing strings to tooltip area // for pushing strings to tooltip area
void setTooltip( std::string s ); void setTooltip( std::string s );
@ -31,6 +34,8 @@ class Gui
Fl_Double_Window window; Fl_Double_Window window;
Fl_Box* box; Fl_Box* box;
DiskWriter* diskWriter;
GMasterTrack* master; GMasterTrack* master;
vector<GTrack*> tracks; vector<GTrack*> tracks;

View file

@ -44,7 +44,10 @@ void LooperClip::save()
EventRequestSaveBuffer e2( track, scene, _buffer->getData().size() ); EventRequestSaveBuffer e2( track, scene, _buffer->getData().size() );
writeToGuiRingbuffer( &e2 ); writeToGuiRingbuffer( &e2 );
} }
else
{
SaveAble::done();
}
} }
/// loads a sample: eg from disk, unloading current sample if necessary /// loads a sample: eg from disk, unloading current sample if necessary
@ -104,6 +107,8 @@ void LooperClip::recieveSaveBuffer( AudioBuffer* saveBuffer )
EventSaveBuffer e ( track, scene, saveBuffer ); EventSaveBuffer e ( track, scene, saveBuffer );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
SaveAble::done();
} }

View file

@ -2,6 +2,8 @@
#include "save.hxx" #include "save.hxx"
#include <iostream> #include <iostream>
#include "../event.hxx"
#include "../eventhandler.hxx"
using namespace std; using namespace std;
@ -23,4 +25,17 @@ void Save::save()
{ {
saveables.at(i)->save(); saveables.at(i)->save();
} }
// now each SaveAble has reqested save state, but not yet *saved* its state.
// we need a way to determine if the saves are flushed.
}
void Save::finish()
{
// trigger the GUI to write the metadata to disk, as each component of the
// engine is done saving
EventSaveFinish e;
writeToGuiRingbuffer( &e );
} }

View file

@ -17,8 +17,16 @@ class Save
void save(); void save();
/// called when each part is finished, and we can flush the metadata to disk
void finish();
void registerSaveable(SaveAble* s); void registerSaveable(SaveAble* s);
int getNumSaveables()
{
return saveables.size();
}
private: private:
std::vector<SaveAble*> saveables; std::vector<SaveAble*> saveables;
}; };

View file

@ -6,9 +6,21 @@
extern Jack* jack; extern Jack* jack;
int SaveAble::savesDone = 0;
SaveAble::SaveAble() SaveAble::SaveAble()
{ {
jack->getSave()->registerSaveable( this ); jack->getSave()->registerSaveable( this );
} }
void SaveAble::save(){}; void SaveAble::save(){};
void SaveAble::done()
{
savesDone++;
if ( savesDone == jack->getSave()->getNumSaveables() )
{
jack->getSave()->finish();
}
}

View file

@ -18,6 +18,13 @@ class SaveAble
/// this function is called when the user initiates a save action /// this function is called when the user initiates a save action
virtual void save(); virtual void save();
/// this function *must* be called by each sub-class when it is *finished*
/// its save action. Once each Saveable is done, the final save is OK-ed.
static void done();
private:
static int savesDone;
}; };
#endif // LUPPP_SAVEABLE_H #endif // LUPPP_SAVEABLE_H

View file

@ -9,47 +9,11 @@
#include "audiobuffer.hxx" #include "audiobuffer.hxx"
#include "cjson/cJSON.h"
using namespace std; using namespace std;
namespace Worker namespace Worker
{ {
static void save(std::string path, std::string sessionName)
{
cJSON *root = cJSON_CreateObject();
cJSON_AddItemToObject(root, "session", cJSON_CreateString( sessionName.c_str() ));
cJSON_AddNumberToObject( root, "version_major", 1 );
cJSON_AddNumberToObject( root, "version_minor", 0 );
cJSON_AddNumberToObject( root, "version_patch", 0 );
cJSON_AddNumberToObject( root, "bpm", 120 );
for(int t = 0; t < NTRACKS; t++ )
{
cJSON* track = cJSON_CreateObject();
cJSON_AddItemToObject(root, "track", track );
cJSON_AddNumberToObject(track,"ID", t);
for(int s = 0; s < NSCENES; s++ )
{
cJSON* clip = cJSON_CreateObject();
cJSON_AddItemToObject(track, "clip", clip );
cJSON_AddNumberToObject(clip,"ID", s);
cJSON_AddStringToObject(clip,"file", "filenameHere.wav");
}
}
char* out = cJSON_Print(root);
//cout << out << endl;
}
/// loads a sample into a new AudioBuffer, returning the buffer /// loads a sample into a new AudioBuffer, returning the buffer
static AudioBuffer* loadSample( string path ) static AudioBuffer* loadSample( string path )
{ {