diff options
author | David Robillard <d@drobilla.net> | 2008-01-21 15:14:53 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-01-21 15:14:53 +0000 |
commit | d6b87aa26ef482a8952437f7472b81a2240f01fd (patch) | |
tree | 620d233b902c78413dc17ee5f921633251239695 /src/libs/engine/MidiBuffer.cpp | |
parent | 2356f96fbd6c9d70dedcd0d64bf0d72786ea36bb (diff) | |
download | ingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.tar.gz ingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.tar.bz2 ingen-d6b87aa26ef482a8952437f7472b81a2240f01fd.zip |
Work on generic LV2 events.
git-svn-id: http://svn.drobilla.net/lad/ingen@1090 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine/MidiBuffer.cpp')
-rw-r--r-- | src/libs/engine/MidiBuffer.cpp | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/src/libs/engine/MidiBuffer.cpp b/src/libs/engine/MidiBuffer.cpp deleted file mode 100644 index 929ac840..00000000 --- a/src/libs/engine/MidiBuffer.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define __STDC_LIMIT_MACROS 1 -#include <stdint.h> -#include <iostream> -#include "MidiBuffer.hpp" - -using namespace std; - -namespace Ingen { - - -/** Allocate a new MIDI buffer. - * \a capacity is in bytes (not number of events). - */ -MidiBuffer::MidiBuffer(size_t capacity) - : Buffer(DataType(DataType::MIDI), capacity) - , _latest_stamp(0) -{ - if (capacity > UINT32_MAX) { - cerr << "MIDI buffer size " << capacity << " too large, aborting." << endl; - throw std::bad_alloc(); - } - - int ret = posix_memalign((void**)&_local_buf, 16, sizeof(LV2_MIDI)); - if (ret) { - cerr << "Failed to allocate MIDI buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - ret = posix_memalign((void**)&_local_buf->data, 16, capacity); - if (ret) { - cerr << "Failed to allocate MIDI buffer contents. Aborting." << endl; - exit(EXIT_FAILURE); - } - - _local_buf->capacity = (uint32_t)capacity; - _buf = _local_buf; - reset(0); - - //cerr << "Creating MIDI Buffer " << _buf << ", capacity = " << _buf->capacity << endl; -} - -MidiBuffer::~MidiBuffer() -{ - free(_local_buf->data); - free(_local_buf); -} - - -/** Use another buffer's data instead of the local one. - * - * This buffer will essentially be identical to @a buf after this call. - */ -bool -MidiBuffer::join(Buffer* buf) -{ - MidiBuffer* mbuf = dynamic_cast<MidiBuffer*>(buf); - if (mbuf) { - _position = mbuf->_position; - _buf = mbuf->local_data(); - _joined_buf = mbuf; - return false; - } else { - return false; - } - - //assert(mbuf->size() == _size); - - _joined_buf = mbuf; - - return true; -} - - -void -MidiBuffer::unjoin() -{ - _joined_buf = NULL; - _buf = _local_buf; - reset(_this_nframes); -} - - -void -MidiBuffer::prepare_read(SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_read: " << event_count() << endl; - - rewind(); - _this_nframes = nframes; -} - - -void -MidiBuffer::prepare_write(SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_write: " << event_count() << endl; - reset(nframes); -} - -/** FIXME: parameters ignored */ -void -MidiBuffer::copy(const Buffer* src_buf, size_t start_sample, size_t end_sample) -{ - MidiBuffer* src = (MidiBuffer*)src_buf; - clear(); - src->rewind(); - const uint32_t frame_count = min(_this_nframes, src->this_nframes()); - double time; - uint32_t size; - unsigned char* data; - while (src->increment() < frame_count) { - src->get_event(&time, &size, &data); - assert(data[0] >= 0x80); - append(time, size, data); - } -} - -/** Increment the read position by one event. - * - * Returns the timestamp of the now current event, or this_nframes if - * there are no events left. - */ -double -MidiBuffer::increment() const -{ - if (_position + sizeof(double) + sizeof(uint32_t) >= _buf->size) { - _position = _buf->size; - return _this_nframes; // hit end - } - - _position += sizeof(double) + sizeof(uint32_t) + - *(uint32_t*)(_buf->data + _position + sizeof(double)); - - if (_position >= _buf->size) { - _position = _buf->size; - return _this_nframes; - } else { - return *(double*)(_buf->data + _position); - } -} - - -/** Append a MIDI event to the buffer. - * - * \a timestamp must be >= the latest event in the buffer, - * and < this_nframes() - * - * \return true on success - */ -bool -MidiBuffer::append(double timestamp, - uint32_t size, - const unsigned char* data) -{ - /*cerr << "Append midi " << size << " bytes @ " << timestamp << ":" << endl; - for (uint32_t i=0; i < size; ++i) { - fprintf(stderr, "( %X )", *((uint8_t*)data + i)); - }*/ - - if (_buf->capacity - _buf->size < sizeof(double) + sizeof(uint32_t) + size) - return false; - - assert(size > 0); - assert(data[0] >= 0x80); - assert(timestamp >= _latest_stamp); - - *(double*)(_buf->data + _buf->size) = timestamp; - _buf->size += sizeof(double); - *(uint32_t*)(_buf->data + _buf->size) = size; - _buf->size += sizeof(uint32_t); - memcpy(_buf->data + _buf->size, data, size); - _buf->size += size; - - ++_buf->event_count; - _latest_stamp = timestamp; - - return true; -} - - -/** Read an event from the current position in the buffer - * - * \return the timestamp for the read event, or this_nframes() - * if there are no more events in the buffer. - */ -double -MidiBuffer::get_event(double* timestamp, - uint32_t* size, - unsigned char** data) const -{ - const LV2_MIDI* buf = this->data(); - - if (_position >= buf->size) { - _position = buf->size; - *timestamp = _this_nframes; - *size = 0; - *data = NULL; - return _this_nframes; - } - - *timestamp = *(double*)(buf->data + _position); - *size = *(uint32_t*)(buf->data + _position + sizeof(double)); - *data = buf->data + _position + sizeof(double) + sizeof(uint32_t); - - return *timestamp; -} - - -/** Clear, and merge \a a and \a b into this buffer. - * - * FIXME: This is slow. - * - * \return true if complete merge was successful - */ -bool -MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b) -{ - // Die if a merge isn't necessary as it's expensive - assert(a.size() > 0 && b.size() > 0); - - reset(_this_nframes); - - a.rewind(); - b.rewind(); - - double a_time; - uint32_t a_size; - unsigned char* a_data; - - double b_time; - uint32_t b_size; - unsigned char* b_data; - - a.get_event(&a_time, &a_size, &a_data); - b.get_event(&b_time, &b_size, &b_data); - - while (true) { - if (a_data && (!b_data || (a_time < b_time))) { - append(a_time, a_size, a_data); - if (a.increment()) - a.get_event(&a_time, &a_size, &a_data); - else - a_data = NULL; - } else if (b_data) { - append(b_time, b_size, b_data); - if (b.increment()) - b.get_event(&b_time, &b_size, &b_data); - else - b_data = NULL; - } else { - break; - } - } - - _latest_stamp = max(a_time, b_time); - - return true; -} - - -} // namespace Ingen - |