From 6cf445e1f5663c81637fb7ea9d9acabadc99c67f Mon Sep 17 00:00:00 2001 From: petern Date: Wed, 22 Jul 2009 19:43:12 +0000 Subject: [PATCH] -Change: Specialize the ringbuffer to handle jack_midi_event_t objects simply. -Fix: Memory leak found during above. git-svn-id: http://svn.fuzzle.org/mloop/trunk@22 ba049829-c6ef-42ef-81ac-908dd8d2e907 --- src/jack.cpp | 31 ++++++------------------------- src/ringbuffer.cpp | 32 ++++++++++++++++++++++++++++++++ src/ringbuffer.h | 14 +++++++++++++- src/wscript | 2 +- 4 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 src/ringbuffer.cpp diff --git a/src/jack.cpp b/src/jack.cpp index 301150e..00c51fb 100644 --- a/src/jack.cpp +++ b/src/jack.cpp @@ -102,12 +102,8 @@ int Jack::ProcessCallback(jack_nframes_t nframes) * need for extra logic to determine if the buffer is full * or empty. */ - if (m_loop_buffer->Free() > sizeof ev.time + sizeof ev.size + ev.size) { - ev.time += m_recording_time; - m_loop_buffer->Write((uint8_t *)&ev.time, sizeof ev.time); - m_loop_buffer->Write((uint8_t *)&ev.size, sizeof ev.size); - m_loop_buffer->Write((uint8_t *)ev.buffer, ev.size); - + ev.time += m_recording_time; + if (m_loop_buffer->PushEvent(ev)) { m_delay_record = false; } else { fprintf(stderr, "Buffer full, dropping input!\n"); @@ -174,28 +170,13 @@ void Jack::EraseLoop(int loop) bool Jack::Run() { - static jack_midi_event_t ev; - static bool first = true; - if (first) { - ev.time = UINT_MAX; - first = false; - } - - if (ev.time == UINT_MAX) { - if (m_loop_buffer->Size() >= sizeof ev.time + sizeof ev.size) { - m_loop_buffer->Read((uint8_t *)&ev.time, sizeof ev.time); - m_loop_buffer->Read((uint8_t *)&ev.size, sizeof ev.size); - } - } else { - if (m_loop_buffer->Size() >= ev.size) { - ev.buffer = (jack_midi_data_t *)malloc(ev.size); - m_loop_buffer->Read((uint8_t *)ev.buffer, ev.size); - } - + jack_midi_event_t ev; + if (m_loop_buffer->PopEvent(ev)) { if (m_recording) { m_loops[m_recording_loop].AddEvent(&ev); + } else { + free(ev.buffer); } - ev.time = UINT_MAX; } return false; diff --git a/src/ringbuffer.cpp b/src/ringbuffer.cpp new file mode 100644 index 0000000..9b87c78 --- /dev/null +++ b/src/ringbuffer.cpp @@ -0,0 +1,32 @@ +/* $Id$ */ + +#include +#include +#include "ringbuffer.h" + +bool RingBuffer::PushEvent(jack_midi_event_t &ev) +{ + if (Free() <= sizeof ev.time + sizeof ev.size + ev.size) return false; + + Write((uint8_t *)&ev.time, sizeof ev.time); + Write((uint8_t *)&ev.size, sizeof ev.size); + Write((uint8_t* )ev.buffer, ev.size); + + return true; +} + +bool RingBuffer::PopEvent(jack_midi_event_t &ev) +{ + if (Size() >= sizeof ev.time + sizeof ev.size) { + uint8_t *peek; + peek = Peek((uint8_t *)&ev.time, sizeof ev.time, m_read); + peek = Peek((uint8_t *)&ev.size, sizeof ev.size, peek); + if (Size() >= sizeof ev.time + sizeof ev.size + ev.size) { + ev.buffer = (jack_midi_data_t *)malloc(ev.size); + m_read = peek; + Read((uint8_t *)ev.buffer, ev.size); + return true; + } + } + return false; +} diff --git a/src/ringbuffer.h b/src/ringbuffer.h index e8775b4..dd89e44 100644 --- a/src/ringbuffer.h +++ b/src/ringbuffer.h @@ -24,7 +24,7 @@ public: free(m_buffer); } - void Write(uint8_t *buffer, size_t length) + void Write(const uint8_t *buffer, size_t length) { while (length--) { if (m_write == m_end) m_write = m_buffer; @@ -40,6 +40,15 @@ public: } } + uint8_t *Peek(uint8_t *buffer, size_t length, uint8_t *peek) + { + while (length--) { + if (peek == m_end) peek = m_buffer; + *buffer++ = *peek++; + } + return peek; + } + size_t Size() const { if (m_write >= m_read) return m_write - m_read; @@ -56,6 +65,9 @@ public: m_write = m_buffer; m_read = m_buffer; } + + bool PushEvent(jack_midi_event_t &event); + bool PopEvent(jack_midi_event_t &event); }; #endif /* RINGBUFFER_H */ diff --git a/src/wscript b/src/wscript index 0d0eced..f361c3f 100644 --- a/src/wscript +++ b/src/wscript @@ -8,6 +8,6 @@ def configure(conf): def build(bld): bld.new_task_gen( features = 'cxx cprogram', - source = 'jack.cpp loop.cpp mloop.cpp notecache.cpp ui.cpp', + source = 'jack.cpp loop.cpp mloop.cpp notecache.cpp ringbuffer.cpp ui.cpp', target = 'mloop', uselib = 'JACK NCURSES')