From 7eef4f4c775466fda94bcb81e5c56a15e32cff87 Mon Sep 17 00:00:00 2001 From: petern Date: Tue, 30 Mar 2010 16:54:24 +0000 Subject: [PATCH] -Add: Preliminary save/load support -Add: Stop all function git-svn-id: http://svn.fuzzle.org/mloop/trunk@37 ba049829-c6ef-42ef-81ac-908dd8d2e907 --- src/jack.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- src/jack.h | 4 ++++ src/loop.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/loop.h | 1 + src/ui.cpp | 9 +++++++++ src/ui.h | 2 ++ 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/jack.cpp b/src/jack.cpp index 0b80057..f28dded 100644 --- a/src/jack.cpp +++ b/src/jack.cpp @@ -37,8 +37,6 @@ bool Jack::Connect() return false; } - m_connected = true; - m_client_name = jack_get_client_name(m_client); m_sample_rate = jack_get_sample_rate(m_client); @@ -50,6 +48,8 @@ bool Jack::Connect() m_control = jack_port_register(m_client, "control", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput|JackPortIsTerminal, 0); + m_connected = true; + jack_activate(m_client); return true; @@ -181,12 +181,49 @@ bool Jack::Run() return false; } +void Jack::StopAll() +{ + for (int i = 0; i < NUM_LOOPS; i++) { + StopLoop(i); + } +} + +void Jack::EraseAll() +{ + for (int i = 0; i < NUM_LOOPS; i++) { + EraseLoop(i); + } +} + void Jack::Save() const { FILE *f = fopen("test.txt", "w"); + fprintf(f, "sample_rate:%d bpm:%u\n", m_sample_rate); for (int i = 0; i < NUM_LOOPS; i++) { - fprintf(f, "LOOP %d\n", i); + fprintf(f, "loop:%d\n", i); m_loops[i].Save(f); } fclose(f); } + +void Jack::Load() +{ + StopAll(); + EraseAll(); + + int ret; + FILE *f = fopen("test.txt", "r"); + + int sample_rate; + ret = fscanf(f, "sample_rate:%d\n", &sample_rate); + if (ret != 1) return; + + while (!feof(f)) { + int i; + + ret = fscanf(f, "loop:%d\n", &i); + if (ret != 1) return; + + m_loops[i].Load(f, sample_rate, m_sample_rate); + } +} diff --git a/src/jack.h b/src/jack.h index 6086049..aab9b00 100644 --- a/src/jack.h +++ b/src/jack.h @@ -97,7 +97,11 @@ public: return m_loops[loop].Tempo(); } + void StopAll(); + void EraseAll(); + void Save() const; + void Load(); }; #endif /* JACK_H */ diff --git a/src/loop.cpp b/src/loop.cpp index 443925c..26df0bb 100644 --- a/src/loop.cpp +++ b/src/loop.cpp @@ -1,6 +1,7 @@ /* $Id$ */ #include +#include #include "loop.h" Loop::Loop() @@ -170,16 +171,47 @@ void Loop::Empty() void Loop::Save(FILE *f) const { - fprintf(f, "%u %f %f\n", m_length, m_position, m_tempo); - fprintf(f, "%lu\n", (unsigned long)m_events.size()); + fprintf(f, "length:%u position:%f tempo:%f events:%lu\n", m_length, m_position, m_tempo, (unsigned long)m_events.size()); EventList::const_iterator it; for (it = m_events.begin(); it != m_events.end(); ++it) { const jack_midi_event_t &ev = *it; - fprintf(f, "%u %lu", ev.time, (unsigned long)ev.size); + fprintf(f, "time:%u size:%lu", ev.time, (unsigned long)ev.size); for (uint i = 0; i < ev.size; i++) { fprintf(f, " %02X", ev.buffer[i]); } fprintf(f, "\n"); } } + +void Loop::Load(FILE *f, int file_sample_rate, int jack_sample_rate) +{ + int ret; + unsigned long events; + + ret = fscanf(f, "length:%u position:%f tempo:%f events:%lu\n", &m_length, &m_position, &m_tempo, &events); + if (ret != 4) return; + + while (events--) { + char *data; + unsigned long size; + jack_midi_event_t ev; + + ret = fscanf(f, "time:%u size:%lu %a[0-9A-F ]\n", &ev.time, &size, &data); + if (ret != 3) return; + //ev.time = ev.time * jack_sample_rate / file_sample_rate; + ev.size = (size_t)size; + ev.buffer = (unsigned char *)malloc(ev.size); + + /* Yup, no bounds checking... */ + unsigned char *p = ev.buffer; + char *q = data; + while (size--) { + *p++ = strtol(q, NULL, 16); + q += 3; + } + free(data); + + AddEvent(&ev); + } +} diff --git a/src/loop.h b/src/loop.h index fe1392d..d0fc8d3 100644 --- a/src/loop.h +++ b/src/loop.h @@ -84,6 +84,7 @@ public: void Finalise(); void Save(FILE *f) const; + void Load(FILE *f, int file_sample_rate, int jack_sample_rate); }; #endif /* LOOP_H */ diff --git a/src/ui.cpp b/src/ui.cpp index 2254fb2..497c6c3 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -201,6 +201,11 @@ bool UI::Run(Jack &j) j.StopLoop(m_loop); break; + case UIKEY_STOP_ALL: + snprintf(status, sizeof status, "Stopping all loops"); + j.StopAll(); + break; + case UIKEY_ERASE: snprintf(status, sizeof status, "Erasing loop %d", m_loop); j.EraseLoop(m_loop); @@ -270,6 +275,10 @@ bool UI::Run(Jack &j) j.Save(); break; + case UIKEY_LOAD: + j.Load(); + break; + case UIKEY_RECONNECT: if (!j.Connected()) { if (j.Connect()) { diff --git a/src/ui.h b/src/ui.h index b18fa4c..de711b9 100644 --- a/src/ui.h +++ b/src/ui.h @@ -34,6 +34,7 @@ public: #define UIKEY_PLAY_ONCE 'z' #define UIKEY_PLAY_LOOP 'x' #define UIKEY_STOP 'c' +#define UIKEY_STOP_ALL 'C' #define UIKEY_ERASE 'e' #define UIKEY_QUANTISE 'q' #define UIKEY_DELAY 'd' @@ -41,6 +42,7 @@ public: #define UIKEY_BPM 'b' #define UIKEY_TEMPO 't' #define UIKEY_SAVE 'S' +#define UIKEY_LOAD 'L' #define UIKEY_RECONNECT 18 #define UIKEY_DISCONNECT 4