mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-05 09:01:39 -05:00
-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:
parent
07a6aa7d6d
commit
05984fbc9b
13 changed files with 107 additions and 46 deletions
|
@ -15,6 +15,8 @@
|
|||
// Logic : Warning NON RT!
|
||||
#define DEBUG_LOGIC 1
|
||||
|
||||
// Saving state
|
||||
#define DEBUG_SAVE 1
|
||||
|
||||
/// General Options
|
||||
#define NTRACKS 8
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
|
||||
#include "diskwriter.hxx"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
DiskWriter::DiskWriter()
|
||||
{
|
||||
session = cJSON_CreateObject();
|
||||
audioConfig = cJSON_CreateObject();
|
||||
};
|
||||
|
||||
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
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "cjson/cJSON.h"
|
||||
|
||||
class AudioBuffer;
|
||||
|
||||
/** DiskWriter
|
||||
|
@ -22,7 +24,8 @@ class DiskWriter
|
|||
void writeSession( std::string path, std::string sessionName );
|
||||
|
||||
private:
|
||||
|
||||
cJSON* session;
|
||||
cJSON* audioConfig;
|
||||
};
|
||||
|
||||
#endif // LUPPP_DISK_WRITER_H
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Event
|
|||
RECORD,
|
||||
|
||||
SAVE, // save action
|
||||
SAVE_FINISH,// save action finished, flush metadata to disk
|
||||
SAVE_BUFFER,// save an individual AudioBuffer* to disk
|
||||
|
||||
REQUEST_SAVE_BUFFER, // gets an audioBuffer of a certain size
|
||||
|
@ -116,6 +117,15 @@ class EventSave : public EventBase
|
|||
EventSave(){};
|
||||
};
|
||||
|
||||
class EventSaveFinish : public EventBase
|
||||
{
|
||||
public:
|
||||
int type() { return int(SAVE_FINISH); }
|
||||
uint32_t size() { return sizeof(EventSaveFinish); }
|
||||
|
||||
EventSaveFinish(){};
|
||||
};
|
||||
|
||||
class EventGridEvent : public EventBase
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -99,11 +99,20 @@ void handleGuiEvents()
|
|||
if ( availableRead >= sizeof(EventSaveBuffer) ) {
|
||||
EventSaveBuffer ev;
|
||||
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;
|
||||
|
||||
|
||||
#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; }
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ static void gui_static_read_rb(void* inst)
|
|||
}
|
||||
|
||||
Gui::Gui() :
|
||||
window(1110,650)
|
||||
window(1110,650),
|
||||
diskWriter( new DiskWriter )
|
||||
{
|
||||
window.color(FL_BLACK);
|
||||
window.label("Luppp");
|
||||
|
@ -91,8 +92,6 @@ int Gui::show()
|
|||
|
||||
gui_static_read_rb( this );
|
||||
|
||||
Worker::save("dummyPath", "dummyName");
|
||||
|
||||
return Fl::run();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "config.hxx"
|
||||
#include "gtrack.hxx"
|
||||
#include "gunittrack.hxx"
|
||||
#include "diskwriter.hxx"
|
||||
#include "gmastertrack.hxx"
|
||||
|
||||
#include <vector>
|
||||
|
@ -24,6 +25,8 @@ class Gui
|
|||
GTrack* getTrack(int id);
|
||||
GMasterTrack* getMasterTrack(){return master;}
|
||||
|
||||
DiskWriter* getDiskWriter(){return diskWriter;}
|
||||
|
||||
// for pushing strings to tooltip area
|
||||
void setTooltip( std::string s );
|
||||
|
||||
|
@ -31,6 +34,8 @@ class Gui
|
|||
Fl_Double_Window window;
|
||||
Fl_Box* box;
|
||||
|
||||
DiskWriter* diskWriter;
|
||||
|
||||
GMasterTrack* master;
|
||||
|
||||
vector<GTrack*> tracks;
|
||||
|
|
|
@ -44,7 +44,10 @@ void LooperClip::save()
|
|||
EventRequestSaveBuffer e2( track, scene, _buffer->getData().size() );
|
||||
writeToGuiRingbuffer( &e2 );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
SaveAble::done();
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 );
|
||||
writeToGuiRingbuffer( &e );
|
||||
|
||||
SaveAble::done();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "save.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include "../event.hxx"
|
||||
#include "../eventhandler.hxx"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -23,4 +25,17 @@ void Save::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 );
|
||||
|
||||
}
|
||||
|
|
|
@ -17,8 +17,16 @@ class Save
|
|||
|
||||
void save();
|
||||
|
||||
/// called when each part is finished, and we can flush the metadata to disk
|
||||
void finish();
|
||||
|
||||
void registerSaveable(SaveAble* s);
|
||||
|
||||
int getNumSaveables()
|
||||
{
|
||||
return saveables.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<SaveAble*> saveables;
|
||||
};
|
||||
|
|
|
@ -6,9 +6,21 @@
|
|||
|
||||
extern Jack* jack;
|
||||
|
||||
int SaveAble::savesDone = 0;
|
||||
|
||||
SaveAble::SaveAble()
|
||||
{
|
||||
jack->getSave()->registerSaveable( this );
|
||||
}
|
||||
|
||||
void SaveAble::save(){};
|
||||
|
||||
void SaveAble::done()
|
||||
{
|
||||
savesDone++;
|
||||
|
||||
if ( savesDone == jack->getSave()->getNumSaveables() )
|
||||
{
|
||||
jack->getSave()->finish();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,13 @@ class SaveAble
|
|||
|
||||
/// this function is called when the user initiates a save action
|
||||
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
|
||||
|
|
|
@ -9,47 +9,11 @@
|
|||
|
||||
#include "audiobuffer.hxx"
|
||||
|
||||
#include "cjson/cJSON.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
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
|
||||
static AudioBuffer* loadSample( string path )
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue