-Add: Preliminary save/load support
-Add: Stop all function git-svn-id: http://svn.fuzzle.org/mloop/trunk@37 ba049829-c6ef-42ef-81ac-908dd8d2e907master
parent
f2e073a383
commit
7eef4f4c77
43
src/jack.cpp
43
src/jack.cpp
|
@ -37,8 +37,6 @@ bool Jack::Connect()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connected = true;
|
|
||||||
|
|
||||||
m_client_name = jack_get_client_name(m_client);
|
m_client_name = jack_get_client_name(m_client);
|
||||||
m_sample_rate = jack_get_sample_rate(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_control = jack_port_register(m_client, "control", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput|JackPortIsTerminal, 0);
|
||||||
|
|
||||||
|
m_connected = true;
|
||||||
|
|
||||||
jack_activate(m_client);
|
jack_activate(m_client);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -181,12 +181,49 @@ bool Jack::Run()
|
||||||
return false;
|
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
|
void Jack::Save() const
|
||||||
{
|
{
|
||||||
FILE *f = fopen("test.txt", "w");
|
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++) {
|
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);
|
m_loops[i].Save(f);
|
||||||
}
|
}
|
||||||
fclose(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -97,7 +97,11 @@ public:
|
||||||
return m_loops[loop].Tempo();
|
return m_loops[loop].Tempo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StopAll();
|
||||||
|
void EraseAll();
|
||||||
|
|
||||||
void Save() const;
|
void Save() const;
|
||||||
|
void Load();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* JACK_H */
|
#endif /* JACK_H */
|
||||||
|
|
38
src/loop.cpp
38
src/loop.cpp
|
@ -1,6 +1,7 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
|
||||||
Loop::Loop()
|
Loop::Loop()
|
||||||
|
@ -170,16 +171,47 @@ void Loop::Empty()
|
||||||
|
|
||||||
void Loop::Save(FILE *f) const
|
void Loop::Save(FILE *f) const
|
||||||
{
|
{
|
||||||
fprintf(f, "%u %f %f\n", m_length, m_position, m_tempo);
|
fprintf(f, "length:%u position:%f tempo:%f events:%lu\n", m_length, m_position, m_tempo, (unsigned long)m_events.size());
|
||||||
fprintf(f, "%lu\n", (unsigned long)m_events.size());
|
|
||||||
|
|
||||||
EventList::const_iterator it;
|
EventList::const_iterator it;
|
||||||
for (it = m_events.begin(); it != m_events.end(); ++it) {
|
for (it = m_events.begin(); it != m_events.end(); ++it) {
|
||||||
const jack_midi_event_t &ev = *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++) {
|
for (uint i = 0; i < ev.size; i++) {
|
||||||
fprintf(f, " %02X", ev.buffer[i]);
|
fprintf(f, " %02X", ev.buffer[i]);
|
||||||
}
|
}
|
||||||
fprintf(f, "\n");
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
void Finalise();
|
void Finalise();
|
||||||
|
|
||||||
void Save(FILE *f) const;
|
void Save(FILE *f) const;
|
||||||
|
void Load(FILE *f, int file_sample_rate, int jack_sample_rate);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LOOP_H */
|
#endif /* LOOP_H */
|
||||||
|
|
|
@ -201,6 +201,11 @@ bool UI::Run(Jack &j)
|
||||||
j.StopLoop(m_loop);
|
j.StopLoop(m_loop);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UIKEY_STOP_ALL:
|
||||||
|
snprintf(status, sizeof status, "Stopping all loops");
|
||||||
|
j.StopAll();
|
||||||
|
break;
|
||||||
|
|
||||||
case UIKEY_ERASE:
|
case UIKEY_ERASE:
|
||||||
snprintf(status, sizeof status, "Erasing loop %d", m_loop);
|
snprintf(status, sizeof status, "Erasing loop %d", m_loop);
|
||||||
j.EraseLoop(m_loop);
|
j.EraseLoop(m_loop);
|
||||||
|
@ -270,6 +275,10 @@ bool UI::Run(Jack &j)
|
||||||
j.Save();
|
j.Save();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UIKEY_LOAD:
|
||||||
|
j.Load();
|
||||||
|
break;
|
||||||
|
|
||||||
case UIKEY_RECONNECT:
|
case UIKEY_RECONNECT:
|
||||||
if (!j.Connected()) {
|
if (!j.Connected()) {
|
||||||
if (j.Connect()) {
|
if (j.Connect()) {
|
||||||
|
|
2
src/ui.h
2
src/ui.h
|
@ -34,6 +34,7 @@ public:
|
||||||
#define UIKEY_PLAY_ONCE 'z'
|
#define UIKEY_PLAY_ONCE 'z'
|
||||||
#define UIKEY_PLAY_LOOP 'x'
|
#define UIKEY_PLAY_LOOP 'x'
|
||||||
#define UIKEY_STOP 'c'
|
#define UIKEY_STOP 'c'
|
||||||
|
#define UIKEY_STOP_ALL 'C'
|
||||||
#define UIKEY_ERASE 'e'
|
#define UIKEY_ERASE 'e'
|
||||||
#define UIKEY_QUANTISE 'q'
|
#define UIKEY_QUANTISE 'q'
|
||||||
#define UIKEY_DELAY 'd'
|
#define UIKEY_DELAY 'd'
|
||||||
|
@ -41,6 +42,7 @@ public:
|
||||||
#define UIKEY_BPM 'b'
|
#define UIKEY_BPM 'b'
|
||||||
#define UIKEY_TEMPO 't'
|
#define UIKEY_TEMPO 't'
|
||||||
#define UIKEY_SAVE 'S'
|
#define UIKEY_SAVE 'S'
|
||||||
|
#define UIKEY_LOAD 'L'
|
||||||
#define UIKEY_RECONNECT 18
|
#define UIKEY_RECONNECT 18
|
||||||
#define UIKEY_DISCONNECT 4
|
#define UIKEY_DISCONNECT 4
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue