-Add: Delay recording until first event option.

-Add: Sync option (unimplemented)


git-svn-id: http://svn.fuzzle.org/mloop/trunk@17 ba049829-c6ef-42ef-81ac-908dd8d2e907
master
petern 2009-07-22 13:45:36 +00:00
parent 97ac198448
commit 981e3454e7
6 changed files with 64 additions and 20 deletions

View File

@ -107,6 +107,8 @@ int Jack::ProcessCallback(jack_nframes_t nframes)
m_buffer->Write((uint8_t *)&ev.time, sizeof ev.time);
m_buffer->Write((uint8_t *)&ev.size, sizeof ev.size);
m_buffer->Write((uint8_t *)ev.buffer, ev.size);
m_delay_record = false;
} else {
fprintf(stderr, "Buffer full, dropping input!\n");
}
@ -124,7 +126,7 @@ int Jack::ProcessCallback(jack_nframes_t nframes)
}
}
if (m_recording) {
if (m_recording && !m_delay_record) {
m_recording_time += nframes;
m_loops[m_recording_loop].SetLength(m_recording_time);
}
@ -132,7 +134,7 @@ int Jack::ProcessCallback(jack_nframes_t nframes)
return 0;
}
void Jack::ToggleRecording(int loop, int bpm)
void Jack::ToggleRecording(int loop, int bpm, bool delay)
{
if (m_recording) {
m_recording = false;
@ -151,12 +153,13 @@ void Jack::ToggleRecording(int loop, int bpm)
m_loops[m_recording_loop].StartFromNoteCache(m_notecache);
m_recording_time = 0;
m_recording = true;
m_delay_record = delay;
}
}
void Jack::StartLoop(int loop, bool repeat)
void Jack::StartLoop(int loop, bool repeat, bool sync)
{
m_loops[loop].Start(repeat);
m_loops[loop].Start(repeat, sync);
}
void Jack::StopLoop(int loop)

View File

@ -24,6 +24,7 @@ private:
RingBuffer *m_buffer;
bool m_recording;
bool m_delay_record;
int m_recording_loop;
jack_nframes_t m_recording_time;
@ -49,8 +50,8 @@ public:
void Disconnect();
bool Run();
void ToggleRecording(int loop, int bpm);
void StartLoop(int loop, bool repeat);
void ToggleRecording(int loop, int bpm, bool delay);
void StartLoop(int loop, bool repeat, bool sync);
void StopLoop(int loop);
void EraseLoop(int loop);
@ -73,6 +74,11 @@ public:
{
return m_loops[loop].State();
}
bool LoopLooping(int loop)
{
return m_loops[loop].Looping();
}
};
#endif /* JACK_H */

View File

@ -43,7 +43,7 @@ void Loop::PlayFrame(void *port_buffer, jack_nframes_t frame)
m_position++;
if (m_position == m_length) {
if (m_state == LS_PLAY_ONCE) {
if (!m_loop) {
m_state = LS_IDLE;
}
m_position = 0;
@ -66,10 +66,10 @@ void Loop::SetLength(jack_nframes_t length)
m_length = length;
}
void Loop::Start(bool loop)
void Loop::Start(bool loop, bool sync)
{
if (m_state == LS_PLAY_LOOP || m_state == LS_PLAY_ONCE) {
m_state = loop ? LS_PLAY_LOOP : LS_PLAY_ONCE;
if (m_state == LS_PLAY || m_state == LS_SYNC) {
m_loop = loop;
}
if (m_state != LS_IDLE) return;
@ -78,13 +78,16 @@ void Loop::Start(bool loop)
m_position = 0;
m_iterator = m_events.begin();
m_state = loop ? LS_PLAY_LOOP : LS_PLAY_ONCE;
m_loop = loop;
m_state = sync ? LS_PLAY : LS_PLAY;
}
void Loop::Stop()
{
if (m_state == LS_PLAY_ONCE || m_state == LS_PLAY_LOOP) {
if (m_state == LS_PLAY) {
m_state = LS_STOPPING;
} else if (m_state == LS_SYNC) {
m_state = LS_IDLE;
}
}

View File

@ -11,8 +11,8 @@
enum LoopState {
LS_IDLE,
LS_PLAY_LOOP,
LS_PLAY_ONCE,
LS_SYNC,
LS_PLAY,
LS_STOPPING,
LS_RECORDING,
};
@ -25,6 +25,7 @@ private:
jack_nframes_t m_length; ///< Length of loop, in samples.
jack_nframes_t m_position; ///< Current position of loop, in samples.
LoopState m_state;
bool m_loop;
EventList m_events;
EventList::iterator m_iterator;
@ -42,7 +43,7 @@ public:
}
void SetLength(jack_nframes_t length);
void Start(bool loop);
void Start(bool loop, bool sync);
void Stop();
void Empty();
@ -63,6 +64,11 @@ public:
{
return m_position;
}
bool Looping() const
{
return m_loop;
}
};
#endif /* LOOP_H */

View File

@ -84,6 +84,8 @@ UI::UI()
m_loop = 0;
m_bpm = 120;
m_quantise = false;
m_delay_record = false;
m_sync_playback = false;
m_edit_mode = EM_LOOPS;
m_edit_timer = 0;
}
@ -118,7 +120,21 @@ bool UI::Run(Jack &j)
bkgdset(color_map[0]);
attrset(color_map[0]);
snprintf(buf, sizeof buf, " Quantisation %s", m_quantise ? "on" : "off");
snprintf(buf, sizeof buf, " Quantisation: %s", m_quantise ? "on" : "off");
mvaddstr(y_offs, 0, buf);
clrtoeol();
y_offs++;
bkgdset(color_map[0]);
attrset(color_map[0]);
snprintf(buf, sizeof buf, " Delay before record: %s", m_delay_record ? "on" : "off");
mvaddstr(y_offs, 0, buf);
clrtoeol();
y_offs++;
bkgdset(color_map[0]);
attrset(color_map[0]);
snprintf(buf, sizeof buf, " Synchronise playback: %s", m_sync_playback ? "on" : "off");
mvaddstr(y_offs, 0, buf);
clrtoeol();
y_offs++;
@ -145,10 +161,10 @@ bool UI::Run(Jack &j)
const char *c; int k = 3;
switch (j.GetLoopState(i)) {
case LS_IDLE: c = " "; k = 0; break;
case LS_PLAY_ONCE: c = ">"; break;
case LS_PLAY_LOOP: c = "»"; break;
case LS_PLAY: c = j.LoopLooping(i) ? "»" : ">"; break;
case LS_STOPPING: c = "·"; break;
case LS_RECORDING: c = "R"; break;
case LS_SYNC: c = "~"; break;
}
bkgdset(color_map[(m_loop == i && m_edit_mode == EM_LOOPS) ? 2 : k]);
@ -171,7 +187,7 @@ bool UI::Run(Jack &j)
return true;
case 'r':
j.ToggleRecording(m_loop, m_quantise ? m_bpm : 0);
j.ToggleRecording(m_loop, m_quantise ? m_bpm : 0, m_delay_record);
if (j.Recording()) {
snprintf(status, sizeof status, "Start recording loop %d", m_loop);
} else {
@ -207,7 +223,7 @@ bool UI::Run(Jack &j)
case 'z':
case 'x':
snprintf(status, sizeof status, "Starting loop %d (%s)", m_loop, c == 'x' ? "loop" : "once");
j.StartLoop(m_loop, c == 'x');
j.StartLoop(m_loop, c == 'x', m_sync_playback);
break;
case 'c':
@ -225,6 +241,14 @@ bool UI::Run(Jack &j)
snprintf(status, sizeof status, "Set quantise %s", m_quantise ? "on" : "off");
break;
case 'd':
m_delay_record = !m_delay_record;
break;
case 's':
m_sync_playback = !m_sync_playback;
break;
case 'b':
if (m_edit_mode == EM_BPM) {
m_edit_mode = EM_LOOPS;

View File

@ -15,6 +15,8 @@ private:
int m_loop;
int m_bpm;
bool m_quantise;
bool m_delay_record;
bool m_sync_playback;
EditMode m_edit_mode;
int m_edit_timer;