From 191b78d09365112a868ddaf3f813ef2b5bc2c252 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 2 Aug 2007 07:23:56 +0000 Subject: Implement MIDI copying, fixes MIDI patching from patch input -> patch output (fix ticket 70). git-svn-id: http://svn.drobilla.net/lad/ingen@670 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/AudioBuffer.cpp | 5 +++-- src/libs/engine/AudioBuffer.hpp | 4 ++-- src/libs/engine/Buffer.hpp | 4 +++- src/libs/engine/InputPort.cpp | 33 ++++++++++++++++++++++----------- src/libs/engine/MidiBuffer.cpp | 17 +++++++++++++++++ src/libs/engine/MidiBuffer.hpp | 10 ++++++---- src/libs/engine/OSCBuffer.cpp | 9 +++++++++ src/libs/engine/OSCBuffer.hpp | 4 +++- 8 files changed, 65 insertions(+), 21 deletions(-) (limited to 'src/libs') diff --git a/src/libs/engine/AudioBuffer.cpp b/src/libs/engine/AudioBuffer.cpp index f05048ad..53fe6bb8 100644 --- a/src/libs/engine/AudioBuffer.cpp +++ b/src/libs/engine/AudioBuffer.cpp @@ -182,16 +182,17 @@ AudioBuffer::scale(Sample val, size_t start_sample, size_t end_sample) * This function only copies the same range in one buffer to another. */ void -AudioBuffer::copy(const AudioBuffer* src, size_t start_sample, size_t end_sample) +AudioBuffer::copy(const Buffer* src, size_t start_sample, size_t end_sample) { assert(end_sample >= start_sample); assert(end_sample < _size); assert(src); + assert(src->type() == DataType::FLOAT); Sample* const buf = data(); assert(buf); - const Sample* const src_buf = src->data(); + const Sample* const src_buf = ((AudioBuffer*)src)->data(); assert(src_buf); for (size_t i=start_sample; i <= end_sample; ++i) diff --git a/src/libs/engine/AudioBuffer.hpp b/src/libs/engine/AudioBuffer.hpp index ee277313..d0644d27 100644 --- a/src/libs/engine/AudioBuffer.hpp +++ b/src/libs/engine/AudioBuffer.hpp @@ -36,7 +36,7 @@ public: void set(Sample val, size_t start_sample); void set(Sample val, size_t start_sample, size_t end_sample); void scale(Sample val, size_t start_sample, size_t end_sample); - void copy(const AudioBuffer* src, size_t start_sample, size_t end_sample); + void copy(const Buffer* src, size_t start_sample, size_t end_sample); void accumulate(const AudioBuffer* src, size_t start_sample, size_t end_sample); bool join(Buffer* buf); @@ -55,7 +55,7 @@ public: void prepare_read(SampleCount nframes); void prepare_write(SampleCount nframes) {} - void reset(SampleCount nframes) {} + void reset(SampleCount nframes) const {} void resize(size_t size); void filled_size(size_t size) { _filled_size = size; } diff --git a/src/libs/engine/Buffer.hpp b/src/libs/engine/Buffer.hpp index d4b52465..b3f7fe3c 100644 --- a/src/libs/engine/Buffer.hpp +++ b/src/libs/engine/Buffer.hpp @@ -41,7 +41,7 @@ public: virtual void clear() = 0; /** Reset state (ie reset read ptr), but leave contents */ - virtual void reset(SampleCount nframes) = 0; + virtual void reset(SampleCount nframes) const = 0; virtual void prepare_read(SampleCount nframes) = 0; virtual void prepare_write(SampleCount nframes) = 0; @@ -49,6 +49,8 @@ public: virtual bool is_joined_to(Buffer* buf) const = 0; virtual bool join(Buffer* buf) = 0; virtual void unjoin() = 0; + + virtual void copy(const Buffer* src, size_t start_sample, size_t end_sample) = 0; virtual void resize(size_t size) { _size = size; } diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp index 3b853edd..1580dc81 100644 --- a/src/libs/engine/InputPort.cpp +++ b/src/libs/engine/InputPort.cpp @@ -191,21 +191,32 @@ InputPort::pre_process(SampleCount nframes, FrameTime start, FrameTime end) /*assert(!_is_tied || _tied_port != NULL); assert(!_is_tied || _buffers.at(0)->data() == _tied_port->buffer(0)->data());*/ - for (uint32_t voice=0; voice < _poly; ++voice) { - assert(_type == DataType::FLOAT); - // Copy first connection - ((AudioBuffer*)_buffers.at(voice))->copy( - ((AudioBuffer*)(*_connections.begin())->buffer(voice)), 0, _buffer_size-1); - - // Accumulate the rest - if (_connections.size() > 1) { + if (_type == DataType::FLOAT) { + for (uint32_t voice=0; voice < _poly; ++voice) { + // Copy first connection + _buffers.at(voice)->copy( + (*_connections.begin())->buffer(voice), 0, _buffer_size-1); - Connections::iterator c = _connections.begin(); + // Accumulate the rest + if (_connections.size() > 1) { - for (++c; c != _connections.end(); ++c) - ((AudioBuffer*)_buffers.at(voice))->accumulate( + Connections::iterator c = _connections.begin(); + + for (++c; c != _connections.end(); ++c) + ((AudioBuffer*)_buffers.at(voice))->accumulate( ((AudioBuffer*)(*c)->buffer(voice)), 0, _buffer_size-1); + } } + } else { + assert(_poly == 1); + + // FIXME + //if (_connections.size() > 1) + // cerr << "WARNING: MIDI mixing not implemented, only first connection used." << endl; + + // Copy first connection + _buffers.at(0)->copy( + (*_connections.begin())->buffer(0), 0, _buffer_size-1); } } diff --git a/src/libs/engine/MidiBuffer.cpp b/src/libs/engine/MidiBuffer.cpp index f2741dfb..4d515f2e 100644 --- a/src/libs/engine/MidiBuffer.cpp +++ b/src/libs/engine/MidiBuffer.cpp @@ -100,6 +100,23 @@ MidiBuffer::prepare_write(SampleCount nframes) assert(!_joined_buf || data() == _joined_buf->data()); } + +/** 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->reset(_this_nframes); + 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); + put_event(time, size, data); + } +} } // namespace Ingen diff --git a/src/libs/engine/MidiBuffer.hpp b/src/libs/engine/MidiBuffer.hpp index bf1eacac..dbccd4e8 100644 --- a/src/libs/engine/MidiBuffer.hpp +++ b/src/libs/engine/MidiBuffer.hpp @@ -40,6 +40,8 @@ public: uint32_t this_nframes() const { return _this_nframes; } + void copy(const Buffer* src, size_t start_sample, size_t end_sample); + inline LV2_MIDI* data() { return ((_joined_buf != NULL) ? _joined_buf->data() : _state->midi); } @@ -49,13 +51,13 @@ public: inline void clear() { assert(_state); assert(_state->midi); lv2midi_reset_buffer(_state->midi); _state->position = 0; } - inline void reset(SampleCount nframes) + inline void reset(SampleCount nframes) const { assert(_state); assert(_state->midi); lv2midi_reset_state(_state, _state->midi, nframes); _this_nframes = nframes; } - inline double increment() + inline double increment() const { assert(_state); assert(_state->midi); return lv2midi_step(_state); } - inline double get_event(double* timestamp, uint32_t* size, unsigned char** data) + inline double get_event(double* timestamp, uint32_t* size, unsigned char** data) const { assert(_state); assert(_state->midi); return lv2midi_get_event(_state, timestamp, size, data); } inline int put_event(double timestamp, uint32_t size, const unsigned char* data) @@ -68,7 +70,7 @@ private: MidiBuffer* _joined_buf; ///< Buffer to mirror, if joined - uint32_t _this_nframes; + mutable uint32_t _this_nframes; }; diff --git a/src/libs/engine/OSCBuffer.cpp b/src/libs/engine/OSCBuffer.cpp index b4452c13..a5f8f3ff 100644 --- a/src/libs/engine/OSCBuffer.cpp +++ b/src/libs/engine/OSCBuffer.cpp @@ -104,4 +104,13 @@ OSCBuffer::prepare_write(SampleCount nframes) } +void +OSCBuffer::copy(const Buffer* src, size_t start_sample, size_t end_sample) +{ + // FIXME + //cerr << "WARNING: OSC buffer copying not implemented, data dropped." << endl; +} + + + } // namespace Ingen diff --git a/src/libs/engine/OSCBuffer.hpp b/src/libs/engine/OSCBuffer.hpp index 1e7e048a..dc529d30 100644 --- a/src/libs/engine/OSCBuffer.hpp +++ b/src/libs/engine/OSCBuffer.hpp @@ -32,7 +32,7 @@ public: ~OSCBuffer() { } void clear() { lv2_osc_buffer_clear(_buf); } - void reset(SampleCount nframs) {} + void reset(SampleCount nframs) const {} void prepare_read(SampleCount nframes); void prepare_write(SampleCount nframes); @@ -40,6 +40,8 @@ public: bool is_joined_to(Buffer* buf) const; bool join(Buffer* buf); void unjoin(); + + void copy(const Buffer* src, size_t start_sample, size_t end_sample); uint32_t this_nframes() const { return _this_nframes; } -- cgit v1.2.1