Merge remote-tracking branch 'openav-master/master'

Conflicts:
	src/gtrack.cxx
	src/gui.cxx
	src/jacksendreturn.cxx
main
Gerald 2016-11-25 12:17:56 +01:00
commit 51407a4bc1
13 changed files with 1082 additions and 54 deletions

View File

@ -0,0 +1,947 @@
{
"name": "AKAI_APCkey25",
"author": "Romain Caneill",
"link": "",
"inputBindings": [{
" __COMMMENT__ ###############################" : "track 0",
"action": "grid:event",
"status": 144,
"data": 32,
"track": 0,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 24,
"track": 0,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 16,
"track": 0,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 8,
"track": 0,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 0,
"track": 0,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 48,
"track": 0,
"send": 1,
"active": 0
},
{
"action": "track:send_active",
"status": 144,
"data": 64,
"track": 0,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 64,
"track": 0,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 1",
"action": "grid:event",
"status": 144,
"data": 33,
"track": 1,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 25,
"track": 1,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 17,
"track": 1,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 9,
"track": 1,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 1,
"track": 1,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 49,
"track": 1
},
{
"action": "track:send_active",
"status": 144,
"data": 65,
"track": 1,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 65,
"track": 1,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 2",
"action": "grid:event",
"status": 144,
"data": 34,
"track": 2,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 26,
"track": 2,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 18,
"track": 2,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 10,
"track": 2,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 2,
"track": 2,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 50,
"track": 2
},
{
"action": "track:send_active",
"status": 144,
"data": 66,
"track": 2,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 66,
"track": 2,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 3",
"action": "grid:event",
"status": 144,
"data": 35,
"track": 3,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 27,
"track": 3,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 19,
"track": 3,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 11,
"track": 3,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 3,
"track": 3,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 51,
"track": 3
},
{
"action": "track:send_active",
"status": 144,
"data": 67,
"track": 3,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 67,
"track": 3,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 4",
"action": "grid:event",
"status": 144,
"data": 36,
"track": 4,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 28,
"track": 4,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 20,
"track": 4,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 12,
"track": 4,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 4,
"track": 4,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 52,
"track": 4
},
{
"action": "track:send_active",
"status": 144,
"data": 68,
"track": 4,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 68,
"track": 4,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 5",
"action": "grid:event",
"status": 144,
"data": 37,
"track": 5,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 29,
"track": 5,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 21,
"track": 5,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 13,
"track": 5,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 5,
"track": 5,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 53,
"track": 5
},
{
"action": "track:send_active",
"status": 144,
"data": 69,
"track": 5,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 69,
"track": 5,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 6",
"action": "grid:event",
"status": 144,
"data": 38,
"track": 6,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 30,
"track": 6,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 22,
"track": 6,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 14,
"track": 6,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 6,
"track": 6,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 54,
"track": 6
},
{
"action": "track:send_active",
"status": 144,
"data": 70,
"track": 6,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 70,
"track": 6,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "track 7",
"action": "grid:event",
"status": 144,
"data": 39,
"track": 7,
"scene": 0
},
{
"action": "grid:event",
"status": 144,
"data": 31,
"track": 7,
"scene": 1
},
{
"action": "grid:event",
"status": 144,
"data": 23,
"track": 7,
"scene": 2
},
{
"action": "grid:event",
"status": 144,
"data": 15,
"track": 7,
"scene": 3
},
{
"action": "grid:event",
"status": 144,
"data": 7,
"track": 7,
"scene": 4
},
{
"action": "track:volume",
"status": 176,
"data": 55,
"track": 7
},
{
"action": "track:send_active",
"status": 144,
"data": 71,
"track": 7,
"send": 0,
"active": 1
},
{
"action": "track:send_active",
"status": 128,
"data": 71,
"track": 7,
"send": 0,
"active": 0
},
{
" __COMMMENT__ ###############################" : "lauch scenes",
"action": "grid:launch_scene",
"status": 144,
"data": 82,
"scene": 0
}, {
"action": "grid:launch_scene",
"status": 144,
"data": 83,
"scene": 1
}, {
"action": "grid:launch_scene",
"status": 144,
"data": 84,
"scene": 2
}, {
"action": "grid:launch_scene",
"status": 144,
"data": 85,
"scene": 3
}, {
"action": "grid:launch_scene",
"status": 144,
"data": 86,
"scene": 4
}],
"outputBindings": [{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 32,
"track" : 0,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 24,
"track" : 0,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 16,
"track" : 0,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 8,
"track" : 0,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 0,
"track" : 0,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 33,
"track" : 1,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 25,
"track" : 1,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 17,
"track" : 1,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 9,
"track" : 1,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 1,
"track" : 1,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 34,
"track" : 2,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 26,
"track" : 2,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 18,
"track" : 2,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 10,
"track" : 2,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 2,
"track" : 2,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 35,
"track" : 3,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 27,
"track" : 3,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 19,
"track" : 3,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 11,
"track" : 3,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 3,
"track" : 3,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 36,
"track" : 4,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 28,
"track" : 4,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 20,
"track" : 4,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 12,
"track" : 4,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 4,
"track" : 4,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 37,
"track" : 5,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 29,
"track" : 5,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 21,
"track" : 5,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 13,
"track" : 5,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 5,
"track" : 5,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 38,
"track" : 6,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 30,
"track" : 6,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 22,
"track" : 6,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 14,
"track" : 6,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 6,
"track" : 6,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
" __COMMMENT__ ###############################" : "track 0",
"action" : "grid:clip_state",
"status" : 144,
"data" : 39,
"track" : 7,
"scene" : 0,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 31,
"track" : 7,
"scene" : 1,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 23,
"track" : 7,
"scene" : 2,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 15,
"track" : 7,
"scene" : 3,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
},
{
"action" : "grid:clip_state",
"status" : 144,
"data" : 7,
"track" : 7,
"scene" : 4,
"state" : {
"empty" : 0, "stopped" : 5, "playing" : 1, "recording" : 3,
"queueStopped" : 6, "queuePlaying" : 2, "queueRecording" : 4}
}]
}

View File

@ -19,6 +19,8 @@
#include "clipselector.hxx"
#include <unistd.h>
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "../gui.hxx"
@ -292,6 +294,7 @@ int ClipSelector::handle(int event)
Fl_Menu_Item rclick_menu[] =
{
{ "Load" },
{ "Save" },
{ "Special"},
{ "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER },
{"1 "},
@ -317,6 +320,22 @@ int ClipSelector::handle(int event)
{
gui->selectLoadSample( ID, clipNum );
}
else if ( strcmp(m->label(), "Save") == 0 )
{
//gui->saveBufferPath = "/tmp/test.wav";
char* tmp = gui->selectSavePath();
if(tmp && strlen(tmp)) {
if( access( tmp, F_OK ) != -1 ) {
int overwrite = fl_choice("Overwrite file?","Cancel","Overwrite",0);
if (!overwrite) {
return 0;
}
}
gui->saveBufferPath = tmp;
free(tmp);
gui->selectSaveSample( ID, clipNum );
}
}
else if ( strcmp(m->label(), "1 ") == 0 ) {
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,1);
writeToDspRingbuffer( &e );

View File

@ -308,34 +308,42 @@ int DiskWriter::writeControllerFile( Controller* c )
return LUPPP_RETURN_OK;
}
int DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab )
int DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab,
const char *gui_path)
{
if ( !foldersCreated )
stringstream path;
if ( gui_path && strlen(gui_path) ) {
printf("saving single buffer to %s\n", gui_path);
path << gui_path;
}
else if ( foldersCreated )
{
stringstream filename;
filename << "t_" << track << "_s_" << scene << ".wav";
// store the clip in clipData, we will write the session JSON for it in writeSession
clipData.push_back( ClipData( track, scene, filename.str() ) );
// add the AudioBuffer metadata to the sample JSON node
cJSON* sampleClip = cJSON_CreateObject();
cJSON_AddItemToObject(audioJson, filename.str().c_str(), sampleClip );
cJSON_AddNumberToObject(sampleClip,"beats", ab->getBeats() );
// get pretty name from GUI
std::string clipName = gui->getTrack(track)->getClipSelector()->clipName( scene );
cJSON_AddItemToObject ( sampleClip, "name", cJSON_CreateString( clipName.c_str() ));
// write the AudioBuffer contents to <path>/audio/ as <name>.wav
// or alternatively t_<track>_s_<scene>.wav
path << audioDir << "/" << filename.str();
}
else
{
LUPPP_WARN("%s", "Session folders not created yet, while trying to write audioBuffers.");
return LUPPP_RETURN_ERROR;
}
stringstream filename;
filename << "t_" << track << "_s_" << scene << ".wav";
// store the clip in clipData, we will write the session JSON for it in writeSession
clipData.push_back( ClipData( track, scene, filename.str() ) );
// add the AudioBuffer metadata to the sample JSON node
cJSON* sampleClip = cJSON_CreateObject();
cJSON_AddItemToObject(audioJson, filename.str().c_str(), sampleClip );
cJSON_AddNumberToObject(sampleClip,"beats", ab->getBeats() );
// get pretty name from GUI
std::string clipName = gui->getTrack(track)->getClipSelector()->clipName( scene );
cJSON_AddItemToObject ( sampleClip, "name", cJSON_CreateString( clipName.c_str() ));
// write the AudioBuffer contents to <path>/audio/ as <name>.wav
// or alternatively t_<track>_s_<scene>.wav
stringstream path;
path << audioDir << "/" << filename.str();
SndfileHandle outfile( path.str(), SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_FLOAT, 1, gui->samplerate );

View File

@ -59,8 +59,10 @@ class DiskWriter
/// sets up session write path etc
void initialize( std::string path, std::string sessionName );
/// writes a single audio buffer to disk
int writeAudioBuffer(int track, int scene, AudioBuffer* ab );
/// writes a single audio buffer to disk for saving whole state.
// When gui_path is set, it only saves a single AB* to that path
int writeAudioBuffer(int track, int scene, AudioBuffer* ab,
const char* gui_path = 0);
/// flush the JSON to disk, finalizing the save
int writeSession();

View File

@ -695,8 +695,9 @@ class EventStateSaveBuffer : public EventBase
int scene;
// pointer to the AudioBuffer to be saved
AudioBuffer* ab;
bool no_dealloc;
EventStateSaveBuffer(): track(0), scene(0), ab(0) {}
EventStateSaveBuffer(): track(0), scene(0), ab(0), no_dealloc(0) {}
EventStateSaveBuffer(int t, int s, AudioBuffer* a): track(t), scene(s), ab(a) {}
};

View File

@ -104,6 +104,20 @@ void handleDspEvents()
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateReset) );
jack->getState()->reset();
} break; }
case Event::STATE_SAVE_BUFFER: {
if ( availableRead >= sizeof(EventStateReset) ) {
EventStateSaveBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateSaveBuffer) );
printf("jack got save buffer in %d, %d\n", ev.track, ev.scene);
LooperClip* lc = jack->getLooper(ev.track)->getClip(ev.scene);
if(!lc) break;
EventStateSaveBuffer e;
e.track = ev.track;
e.scene = ev.scene;
e.ab = lc->getAudioBuffer();
e.no_dealloc = 1;
writeToGuiRingbuffer( &e );
} break; }
// ========= MASTER ===
case Event::MASTER_VOL: {

View File

@ -181,8 +181,17 @@ void handleGuiEvents()
cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl;
#endif
gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
// de allocate the AudioBuffer
delete ev.ab;
// de allocate the AudioBuffer only if reqested
if(!ev.no_dealloc) {
gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
delete ev.ab;
} else
{
gui->getDiskWriter()->writeAudioBuffer(ev.track, ev.scene, ev.ab,
gui->saveBufferPath.c_str());
gui->saveBufferPath = "";
}
} break; }
case Event::STATE_SAVE_FINISH: {

View File

@ -194,6 +194,7 @@ static void gmastertrack_button_callback(Fl_Widget *w, void *data)
}
}
#define OFST 33
GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
Fl_Group(x, y, w, h),
title( strdup(l) ),
@ -203,14 +204,14 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
clipSel(x + 5, y + 26 + 102, 140, 294,"", true),
source(x+5, y+26, 140, 100, ""),
volBox(x+5, y+422, 140, 172, ""),
volBox(x+5, y+422, 140, 232, ""),
transport ( x + w * 2/4.f - 18, y + 426 + 26 * 0, 44,24, "Stop" ),
tapTempo ( x + w * 2/4.f - 18, y + 426 + 26 * 1, 44,24, "Tap" ),
metronomeButton( x + w * 2/4.f - 18, y + 426 + 26 * 2, 44,24,"Metro"),
transport ( x + w * 2/4.f - 18, y + 436 + OFST * 0, 44,28, "Stop" ),
tapTempo ( x + w * 2/4.f - 18, y + 436 + OFST * 1, 44,28, "Tap" ),
metronomeButton( x + w * 2/4.f - 18, y + 436 + OFST * 2, 44,28,"Metro"),
tempoDial ( x + w * 2/4.f - 18, y + 426 + 41 * 2, 45, 36,"BPM"),
returnVol ( x + w * 2/4.f - 18, y + 426 + 41 * 3, 45, 36,"Return"),
tempoDial ( x + w * 2/4.f - 18, y + 436 + OFST * 3.5, 45, 38,"BPM"),
returnVol ( x + w * 2/4.f - 18, y + 436 + OFST * 5, 45, 38,"Return"),
inputVolume(x + 9,y + 26 + 4, w - 18, 30,""),
@ -223,7 +224,7 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
inputToMix (x + w*0.8-20,y + 28 + 68, 40, 26,"Mix"),
inputToMixVol(x + w*0.8-15,y + 28 + 36, 30, 30,""),
volume(x+106, y +425, 36, 166, "")
volume(x+106, y +425, 36, 216, "")
{
ID = privateID++;
@ -254,8 +255,6 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
inputToMix.callback ( gmastertrack_mixButton_callback, 0 );
inputToMixVol.callback ( gmastertrack_mixVol_callback, 0 );
tempoDial.align( FL_ALIGN_CENTER );
returnVol.value( 1.f );
@ -264,7 +263,7 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
for(int i = 0; i < 4; i++)
{
beatLights[i] = new Avtk::LightButton( x + 11, y + 427 + 41 * i, 38, 38, "" );
beatLights[i] = new Avtk::LightButton( x + 10, y + 437 + 54 * i, 40, 42, "" );
}
beatLights[0]->setColor( 1.0, 0.0 , 0.0 );
beatLights[1]->setColor( 1.0, 0.48, 0.0 );

View File

@ -79,6 +79,7 @@ GTrack::GTrack(int x, int y, int w, int h, const char* l ) :
jackSendActivate.callback(gtrack_jacksendactivate_cb,this);
jackSendDial.align(FL_ALIGN_INSIDE);
jackSendDial.callback(gtrack_jacksend_cb,this);
jackSendDial.value(1.0);
//volBox.color( fl_rgb_color( 0,0,0 ) );
end(); // close the group

View File

@ -252,6 +252,40 @@ void Gui::selectLoadController(Fl_Widget* w, void*)
}
void Gui::selectSaveSample( int track, int scene )
{
EventStateSaveBuffer e;
e.track = track,
e.scene = scene,
writeToDspRingbuffer( &e );
}
char *
Gui::selectSavePath()
{
string path;
Fl_Native_File_Chooser fnfc;
fnfc.title("Save filename?");
fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
std::string defLoadPath = gui->getDiskReader()->getLastLoadedSamplePath();
fnfc.directory( defLoadPath.c_str() ); // default directory to use
// Show native chooser
switch ( fnfc.show() ) {
case -1: /*printf("ERROR: %s\n", fnfc.errmsg()); */ break; // ERROR
case 1: /*(printf("CANCEL\n"); */ break; // CANCEL
default: /*printf("Loading directory: %s\n", fnfc.filename()); */
path = fnfc.filename();
break;
}
if ( strcmp( path.c_str(), "" ) == 0 )
return 0;
return strdup(path.c_str());
}
void Gui::selectLoadSample( int track, int scene )
{
// FIXME: refactor
@ -409,26 +443,14 @@ Gui::Gui(const char* argZero) :
// create a new "Group" with all Luppp GUI contents, for resizing
lupppGroup = new Fl_Group( 0, 0, 1110, 650, "Luppp");
{
// everything in here will have resize() called when main window is resized
/*
Fl_Bitmap* headImg = new Fl_Bitmap( (unsigned char*)header.pixel_data, 1110, 36 );
Fl_Box* pic_box = new Fl_Box(0,0,1110,36);
pic_box->image( headImg );
pic_box->redraw();
*/
int i = 0;
for (; i < NTRACKS; i++ )
{
stringstream s;
s << "Track " << i+1;
//printf("track name %s\n", s.str().c_str() );
tracks.push_back( new GTrack(8 + i * 118, 40, 110, 650, s.str().c_str() ) );
}
master = new GMasterTrack(8 + i * 118, 40, 150, 600, "Master");
master = new GMasterTrack(8 + i * 118, 40, 150, 650, "Master");
}
lupppGroup->end();

View File

@ -76,6 +76,8 @@ class Gui
/// used to load samples into the grid
void selectLoadSample( int track, int clip );
void selectSaveSample( int track, int clip );
char* selectSavePath();
/// allows the user to select a Controller definition
static void selectLoadController(Fl_Widget* w, void*);
@ -94,7 +96,9 @@ class Gui
/// current special clip:
int specialTrack;
int specialScene;
// save a particular sample to path
std::string saveBufferPath;
private:
vector<std::string> controllerVector;

View File

@ -4,12 +4,12 @@
#include <assert.h>
extern Jack* jack;
JackSendReturn::JackSendReturn(int trackid, AudioProcessor *prev, jack_client_t *client)
:m_trackid(trackid), m_previousProcessor(prev)
:m_trackid(trackid), m_previousProcessor(prev), m_sendvol(1.0f)
{
char name[50];
sprintf(name, "Send_track_%d\0",trackid);
sprintf(name, "Send_track_%d\n",trackid);
m_sendport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0);
sprintf(name, "Return_track_%d\0",trackid);
sprintf(name, "Return_track_%d\n",trackid);
m_returnport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0);
m_active=false;
m_counter=0;

View File

@ -82,6 +82,8 @@ class LooperClip : public Stately
//Return the nr of samples holding actual audio. This is less then getBufferLength();
long getActualAudioLength();
size_t audioBufferSize();
AudioBuffer* getAudioBuffer() {return _buffer;}
/// set clip state
void queuePlay(bool=true);