-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
master
petern 2009-07-22 19:43:12 +00:00
parent 7e598788b0
commit 6cf445e1f5
4 changed files with 52 additions and 27 deletions

View File

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

32
src/ringbuffer.cpp 100644
View File

@ -0,0 +1,32 @@
/* $Id$ */
#include <stdint.h>
#include <jack/midiport.h>
#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;
}

View File

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

View File

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