-Add: Preliminary save/load support

-Add: Stop all function


git-svn-id: http://svn.fuzzle.org/mloop/trunk@37 ba049829-c6ef-42ef-81ac-908dd8d2e907
master
petern 2010-03-30 16:54:24 +00:00
parent f2e073a383
commit 7eef4f4c77
6 changed files with 91 additions and 6 deletions

View File

@ -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);
}
}

View File

@ -97,7 +97,11 @@ public:
return m_loops[loop].Tempo();
}
void StopAll();
void EraseAll();
void Save() const;
void Load();
};
#endif /* JACK_H */

View File

@ -1,6 +1,7 @@
/* $Id$ */
#include <stdio.h>
#include <string.h>
#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);
}
}

View File

@ -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 */

View File

@ -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()) {

View File

@ -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