diff options
author | David Robillard <d@drobilla.net> | 2012-08-11 02:13:56 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-08-11 02:13:56 +0000 |
commit | 571cbb33901b2a6b6fbc6f311723bc9bc561e731 (patch) | |
tree | 90c1731c8aea550277cf5b83b3429502a7fb3040 /src/server | |
parent | 46eff0830c8894997fb624733fadcea9c6d74812 (diff) | |
download | ingen-571cbb33901b2a6b6fbc6f311723bc9bc561e731.tar.gz ingen-571cbb33901b2a6b6fbc6f311723bc9bc561e731.tar.bz2 ingen-571cbb33901b2a6b6fbc6f311723bc9bc561e731.zip |
Vectorizable (by GCC with -ftree-vectorize) mixing and Buffer::set_block().
Custom SSE accelerated peak detection when SSE is available at compile time.
Less mixing overhead in general.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4651 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server')
30 files changed, 161 insertions, 134 deletions
diff --git a/src/server/Buffer.cpp b/src/server/Buffer.cpp index b10ccfc6..6d605490 100644 --- a/src/server/Buffer.cpp +++ b/src/server/Buffer.cpp @@ -18,10 +18,13 @@ #include <assert.h> #include <math.h> +#include <new> #include <stdint.h> #include <string.h> -#include <new> +#ifdef __SSE__ +# include <xmmintrin.h> +#endif #include "ingen/URIMap.hpp" #include "ingen/URIs.hpp" @@ -75,24 +78,6 @@ Buffer::~Buffer() free(_atom); } -bool -Buffer::is_audio() const -{ - return _type == _factory.uris().atom_Sound; -} - -bool -Buffer::is_control() const -{ - return _type == _factory.uris().atom_Float; -} - -bool -Buffer::is_sequence() const -{ - return _type == _factory.uris().atom_Sequence; -} - void Buffer::recycle() { @@ -111,14 +96,14 @@ Buffer::clear() } void -Buffer::copy(Context& context, const Buffer* src) +Buffer::copy(const Context& context, const Buffer* src) { if (_type == src->type() && src->_atom->size + sizeof(LV2_Atom) <= _capacity) { memcpy(_atom, src->_atom, sizeof(LV2_Atom) + src->_atom->size); } else if (src->is_audio() && is_control()) { - samples()[0] = src->samples()[context.offset()]; + samples()[0] = src->samples()[0]; } else if (src->is_control() && is_audio()) { - samples()[context.offset()] = src->samples()[0]; + set_block(src->samples()[0], 0, context.nframes()); } else { clear(); } @@ -129,8 +114,9 @@ Buffer::set_block(Sample val, const SampleCount start, const SampleCount end) { assert(end <= nframes()); - Sample* const buf = samples(); - for (SampleCount i = start; i < end; ++i) { + // Note: This is done in this particular way so GCC can vectorize it + Sample* const buf = samples() + start; + for (SampleCount i = 0; i < (end - start); ++i) { buf[i] = val; } } @@ -144,7 +130,7 @@ Buffer::resize(uint32_t capacity) } void* -Buffer::port_data(PortType port_type, SampleCount offset) +Buffer::port_data(PortType port_type) { switch (port_type.symbol()) { case PortType::CONTROL: @@ -154,7 +140,7 @@ Buffer::port_data(PortType port_type, SampleCount offset) if (_atom->type == _factory.uris().atom_Float) { return (float*)LV2_ATOM_BODY(_atom); } else if (_atom->type == _factory.uris().atom_Sound) { - return (float*)LV2_ATOM_CONTENTS(LV2_Atom_Vector, _atom) + offset; + return (float*)LV2_ATOM_CONTENTS(LV2_Atom_Vector, _atom); } else { Raul::warn << "Audio data requested from non-audio buffer " << this << " :: " << _atom->type << " - " @@ -170,21 +156,53 @@ Buffer::port_data(PortType port_type, SampleCount offset) } const void* -Buffer::port_data(PortType port_type, SampleCount offset) const +Buffer::port_data(PortType port_type) const { return const_cast<void*>( - const_cast<Buffer*>(this)->port_data(port_type, offset)); + const_cast<Buffer*>(this)->port_data(port_type)); } float Buffer::peak(const Context& context) const { - float peak = 0.0f; - const Sample* const buf = samples(); - for (FrameTime i = 0; i < context.nframes(); ++i) { +#ifdef __SSE__ + const __m128* const vbuf = (const __m128* const)samples(); + __m128 vpeak = vbuf[0]; + const SampleCount nblocks = context.nframes() / 4; + + // First, find the vector max of the buffer + for (SampleCount i = 1; i < nblocks; ++i) { + vpeak = _mm_max_ps(vpeak, vbuf[i]); + } + + // Now we need the single max of vpeak + // vpeak = ABCD + // tmp = CDAB + __m128 tmp = _mm_shuffle_ps(vpeak, vpeak, _MM_SHUFFLE(2, 3, 0, 1)); + + // vpeak = MAX(A,C) MAX(B,D) MAX(C,A) MAX(D,B) + vpeak = _mm_max_ps(vpeak, tmp); + + // tmp = BADC of the new vpeak + // tmp = MAX(B,D) MAX(A,C) MAX(D,B) MAX(C,A) + tmp = _mm_shuffle_ps(vpeak, vpeak, _MM_SHUFFLE(1, 0, 3, 2)); + + // vpeak = MAX(MAX(A,C), MAX(B,D)), ... + vpeak = _mm_max_ps(vpeak, tmp); + + // peak = vpeak[0] + float peak; + _mm_store_ss(&peak, vpeak); + + return peak; +#else + const Sample* const buf = samples(); + float peak = 0.0f; + for (SampleCount i = 0; i < context.nframes(); ++i) { peak = fmaxf(peak, buf[i]); } return peak; +#endif } void @@ -228,5 +246,17 @@ Buffer::append_event(int64_t frames, return true; } +void +intrusive_ptr_add_ref(Buffer* b) +{ + b->ref(); +} + +void +intrusive_ptr_release(Buffer* b) +{ + b->deref(); +} + } // namespace Server } // namespace Ingen diff --git a/src/server/Buffer.hpp b/src/server/Buffer.hpp index 329abb12..720b1073 100644 --- a/src/server/Buffer.hpp +++ b/src/server/Buffer.hpp @@ -27,6 +27,7 @@ #include "raul/Deletable.hpp" #include "raul/SharedPtr.hpp" +#include "BufferFactory.hpp" #include "PortType.hpp" #include "types.hpp" @@ -37,26 +38,34 @@ class Context; class Engine; class BufferFactory; -class Buffer : public boost::noncopyable, public Raul::Deletable +class Buffer : public boost::noncopyable { public: Buffer(BufferFactory& bufs, LV2_URID type, uint32_t capacity); - bool is_audio() const; - bool is_control() const; - bool is_sequence() const; + void clear(); + void resize(uint32_t size); + void copy(const Context& context, const Buffer* src); + void set_block(Sample val, SampleCount start, SampleCount end); + void prepare_write(Context& context); - virtual void clear(); - virtual void resize(uint32_t size); - virtual void copy(Context& context, const Buffer* src); - virtual void set_block(Sample val, SampleCount start, SampleCount end); - virtual void prepare_write(Context& context); + void* port_data(PortType port_type); + const void* port_data(PortType port_type) const; - void* port_data(PortType port_type, SampleCount offset); - const void* port_data(PortType port_type, SampleCount offset) const; + inline LV2_URID type() const { return _type; } + inline uint32_t capacity() const { return _capacity; } - LV2_URID type() const { return _type; } - uint32_t capacity() const { return _capacity; } + inline bool is_audio() const { + return _type == _factory.uris().atom_Sound; + } + + inline bool is_control() const { + return _type == _factory.uris().atom_Float; + } + + inline bool is_sequence() const { + return _type == _factory.uris().atom_Sequence; + } /// Audio buffers only inline const Sample* samples() const { @@ -89,7 +98,8 @@ public: } /// Audio buffers only - inline const Sample& value_at(size_t offset) const { + inline const Sample& value_at(SampleCount offset) const { + assert(is_audio() || is_control()); assert(offset < nframes()); return samples()[offset]; } @@ -124,7 +134,7 @@ protected: uint32_t _capacity; friend class BufferFactory; - virtual ~Buffer(); + ~Buffer(); private: void recycle(); diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp index ccb3170d..98bb0def 100644 --- a/src/server/BufferFactory.cpp +++ b/src/server/BufferFactory.cpp @@ -17,6 +17,7 @@ #include "ingen/URIs.hpp" #include "raul/log.hpp" +#include "Buffer.hpp" #include "BufferFactory.hpp" #include "Driver.hpp" #include "Engine.hpp" diff --git a/src/server/BufferFactory.hpp b/src/server/BufferFactory.hpp index 643c5d97..242cf31a 100644 --- a/src/server/BufferFactory.hpp +++ b/src/server/BufferFactory.hpp @@ -29,7 +29,6 @@ #include "ingen/Forge.hpp" #include "ingen/URIs.hpp" -#include "Buffer.hpp" #include "BufferRef.hpp" #include "PortType.hpp" #include "types.hpp" diff --git a/src/server/BufferRef.hpp b/src/server/BufferRef.hpp index ac5d79ad..77e3c130 100644 --- a/src/server/BufferRef.hpp +++ b/src/server/BufferRef.hpp @@ -19,8 +19,6 @@ #include <boost/intrusive_ptr.hpp> -#include "Buffer.hpp" - namespace Ingen { namespace Server { @@ -28,8 +26,9 @@ class Buffer; typedef boost::intrusive_ptr<Buffer> BufferRef; -inline void intrusive_ptr_add_ref(Buffer* b) { b->ref(); } -inline void intrusive_ptr_release(Buffer* b) { b->deref(); } +// Defined in Buffer.cpp +void intrusive_ptr_add_ref(Buffer* b); +void intrusive_ptr_release(Buffer* b); } // namespace Server } // namespace Ingen diff --git a/src/server/Context.cpp b/src/server/Context.cpp index 9aeb08db..13c2c43f 100644 --- a/src/server/Context.cpp +++ b/src/server/Context.cpp @@ -50,7 +50,6 @@ Context::Context(Engine& engine, ID id) , _start(0) , _end(0) , _nframes(0) - , _offset(0) , _realtime(true) {} diff --git a/src/server/Context.hpp b/src/server/Context.hpp index c5502687..62bcfba9 100644 --- a/src/server/Context.hpp +++ b/src/server/Context.hpp @@ -66,25 +66,22 @@ public: inline ID id() const { return _id; } - inline void locate(FrameTime s, SampleCount nframes, SampleCount offset) { + inline void locate(FrameTime s, SampleCount nframes) { _start = s; _end = s + nframes; _nframes = nframes; - _offset = offset; } inline void locate(const Context& other) { _start = other._start; _end = other._end; _nframes = other._nframes; - _offset = other._offset; } inline Engine& engine() const { return _engine; } inline FrameTime start() const { return _start; } inline FrameTime end() const { return _end; } inline SampleCount nframes() const { return _nframes; } - inline SampleCount offset() const { return _offset; } inline bool realtime() const { return _realtime; } protected: @@ -96,7 +93,6 @@ protected: FrameTime _start; ///< Start frame of this cycle, timeline relative FrameTime _end; ///< End frame of this cycle, timeline relative SampleCount _nframes; ///< Length of this cycle in frames - SampleCount _offset; ///< Start offset relative to start of driver buffers bool _realtime; ///< True iff context is hard realtime }; diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp index c42002ab..1cc1518c 100644 --- a/src/server/ControlBindings.cpp +++ b/src/server/ControlBindings.cpp @@ -23,12 +23,13 @@ #include "raul/log.hpp" #include "raul/midi_events.h" +#include "Buffer.hpp" #include "ControlBindings.hpp" +#include "Driver.hpp" #include "Engine.hpp" #include "PortImpl.hpp" #include "ProcessContext.hpp" #include "ThreadManager.hpp" -#include "Driver.hpp" #define LOG(s) s << "[ControlBindings] " diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp index d0349f91..c12a0b56 100644 --- a/src/server/DuplexPort.hpp +++ b/src/server/DuplexPort.hpp @@ -18,7 +18,8 @@ #define INGEN_ENGINE_DUPLEXPORT_HPP #include <string> -#include "Buffer.hpp" + +#include "BufferRef.hpp" #include "InputPort.hpp" #include "OutputPort.hpp" diff --git a/src/server/EdgeImpl.cpp b/src/server/EdgeImpl.cpp index 7fad4e94..a88290e8 100644 --- a/src/server/EdgeImpl.cpp +++ b/src/server/EdgeImpl.cpp @@ -18,6 +18,7 @@ #include "lv2/lv2plug.in/ns/ext/atom/util.h" #include "raul/log.hpp" +#include "Buffer.hpp" #include "BufferFactory.hpp" #include "EdgeImpl.hpp" #include "Engine.hpp" @@ -83,7 +84,7 @@ EdgeImpl::get_sources(Context& context, _queue->peek(sizeof(LV2_Atom), &obj); BufferRef buf = context.engine().buffer_factory()->get( context, head()->buffer_type(), sizeof(LV2_Atom) + obj.size); - void* data = buf->port_data(PortType::ATOM, context.offset()); + void* data = buf->port_data(PortType::ATOM); _queue->read(sizeof(LV2_Atom) + obj.size, (LV2_Atom*)data); srcs[num_srcs++] = buf.get(); } else if (must_mix()) { diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index f2957616..af7bb86f 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -276,7 +276,7 @@ Engine::deactivate() unsigned Engine::run(uint32_t sample_count) { - _process_context.locate(_process_context.end(), sample_count, 0); + _process_context.locate(_process_context.end(), sample_count); // Apply control bindings to input control_bindings()->pre_process( diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 901a409a..0ded3e5b 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -17,6 +17,7 @@ #include <cstdlib> #include <cassert> +#include "Buffer.hpp" #include "BufferFactory.hpp" #include "EdgeImpl.hpp" #include "Engine.hpp" @@ -194,7 +195,7 @@ InputPort::pre_process(Context& context) e->get_sources(context, v, srcs, max_num_srcs, num_srcs); } - mix(context, bufs().uris(), buffer(v).get(), srcs, num_srcs); + mix(context, buffer(v).get(), srcs, num_srcs); } } diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp index b3c2fc6c..3f6ed5c0 100644 --- a/src/server/JackDriver.cpp +++ b/src/server/JackDriver.cpp @@ -33,6 +33,7 @@ #include "raul/List.hpp" #include "raul/log.hpp" +#include "Buffer.hpp" #include "DuplexPort.hpp" #include "Engine.hpp" #include "JackDriver.hpp" @@ -403,7 +404,7 @@ JackDriver::_process_cb(jack_nframes_t nframes) _transport_state = jack_transport_query(_client, &_position); - _engine.process_context().locate(start_of_current_cycle, nframes, 0); + _engine.process_context().locate(start_of_current_cycle, nframes); // Read input for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) diff --git a/src/server/LV2Node.cpp b/src/server/LV2Node.cpp index 4ed6c05a..8857edbb 100644 --- a/src/server/LV2Node.cpp +++ b/src/server/LV2Node.cpp @@ -30,6 +30,7 @@ #include "ingen/URIMap.hpp" #include "ingen/URIs.hpp" +#include "Buffer.hpp" #include "Driver.hpp" #include "Engine.hpp" #include "InputPort.hpp" @@ -461,13 +462,12 @@ LV2Node::process(ProcessContext& context) void LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, - BufferRef buf, - SampleCount offset) + BufferRef buf) { - NodeImpl::set_port_buffer(voice, port_num, buf, offset); + NodeImpl::set_port_buffer(voice, port_num, buf); lilv_instance_connect_port( instance(voice), port_num, - buf ? buf->port_data(_ports->at(port_num)->type(), offset) : NULL); + buf ? buf->port_data(_ports->at(port_num)->type()) : NULL); } } // namespace Server diff --git a/src/server/LV2Node.hpp b/src/server/LV2Node.hpp index 104c64d9..b83cf943 100644 --- a/src/server/LV2Node.hpp +++ b/src/server/LV2Node.hpp @@ -59,10 +59,9 @@ public: void process(ProcessContext& context); - void set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf, - SampleCount offset); + void set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf); protected: SharedPtr<LilvInstance> make_instance(URIs& uris, diff --git a/src/server/LV2ResizeFeature.hpp b/src/server/LV2ResizeFeature.hpp index d9a9330f..a32d3d8f 100644 --- a/src/server/LV2ResizeFeature.hpp +++ b/src/server/LV2ResizeFeature.hpp @@ -17,11 +17,13 @@ #ifndef INGEN_ENGINE_LV2RESIZEFEATURE_HPP #define INGEN_ENGINE_LV2RESIZEFEATURE_HPP -#include "raul/log.hpp" -#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" #include "ingen/LV2Features.hpp" +#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" +#include "raul/log.hpp" + #include "NodeImpl.hpp" #include "PortImpl.hpp" +#include "Buffer.hpp" namespace Ingen { namespace Server { diff --git a/src/server/NodeImpl.cpp b/src/server/NodeImpl.cpp index 791396c1..bf17d325 100644 --- a/src/server/NodeImpl.cpp +++ b/src/server/NodeImpl.cpp @@ -19,7 +19,7 @@ #include "raul/Array.hpp" -#include "BufferFactory.hpp" +#include "Buffer.hpp" #include "Engine.hpp" #include "NodeImpl.hpp" #include "PatchImpl.hpp" @@ -155,7 +155,7 @@ NodeImpl::pre_process(ProcessContext& context) for (uint32_t i = 0; i < num_ports(); ++i) { PortImpl* const port = _ports->at(i); port->pre_process(context); - port->connect_buffers(context.offset()); + port->connect_buffers(); } } @@ -171,10 +171,9 @@ NodeImpl::post_process(ProcessContext& context) } void -NodeImpl::set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf, - SampleCount offset) +NodeImpl::set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf) { /*std::cout << path() << " set port " << port_num << " voice " << voice << " buffer " << buf << " offset " << offset << std::endl;*/ diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp index 2b0faf03..0b44e58e 100644 --- a/src/server/NodeImpl.hpp +++ b/src/server/NodeImpl.hpp @@ -107,10 +107,9 @@ public: virtual void post_process(ProcessContext& context); /** Set the buffer of a port to a given buffer (e.g. connect plugin to buffer) */ - virtual void set_port_buffer(uint32_t voice, - uint32_t port_num, - BufferRef buf, - SampleCount offset); + virtual void set_port_buffer(uint32_t voice, + uint32_t port_num, + BufferRef buf); virtual GraphObject* port(uint32_t index) const; virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } diff --git a/src/server/PatchImpl.cpp b/src/server/PatchImpl.cpp index 16cff0c9..9abadadb 100644 --- a/src/server/PatchImpl.cpp +++ b/src/server/PatchImpl.cpp @@ -127,7 +127,7 @@ PatchImpl::apply_internal_poly(ProcessContext& context, PortImpl* const port = (*i)->port_impl(j); if (port->is_input() && dynamic_cast<InputPort*>(port)->direct_connect()) port->setup_buffers(context, bufs, port->poly()); - port->connect_buffers(context.offset()); + port->connect_buffers(); } } diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 21c77b42..aee380ff 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -19,6 +19,7 @@ #include "raul/Array.hpp" #include "raul/Maid.hpp" +#include "Buffer.hpp" #include "BufferFactory.hpp" #include "Engine.hpp" #include "NodeImpl.hpp" @@ -274,10 +275,10 @@ PortImpl::set_buffer_size(Context& context, BufferFactory& bufs, size_t size) } void -PortImpl::connect_buffers(SampleCount offset) +PortImpl::connect_buffers() { for (uint32_t v = 0; v < _poly; ++v) - PortImpl::parent_node()->set_port_buffer(v, _index, buffer(v), offset); + PortImpl::parent_node()->set_port_buffer(v, _index, buffer(v)); } void diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp index f4a8975b..0a8415f7 100644 --- a/src/server/PortImpl.hpp +++ b/src/server/PortImpl.hpp @@ -23,7 +23,6 @@ #include "raul/Array.hpp" #include "raul/Atom.hpp" -#include "Buffer.hpp" #include "BufferRef.hpp" #include "GraphObjectImpl.hpp" #include "PortType.hpp" @@ -123,7 +122,7 @@ public: get_buffers(context, bufs, _buffers, poly); } - virtual void connect_buffers(SampleCount offset=0); + virtual void connect_buffers(); virtual void recycle_buffers(); virtual bool is_input() const = 0; diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp index 6ee86eed..a3d472eb 100644 --- a/src/server/events/Disconnect.cpp +++ b/src/server/events/Disconnect.cpp @@ -23,8 +23,9 @@ #include "raul/log.hpp" #include "Broadcaster.hpp" -#include "EdgeImpl.hpp" +#include "Buffer.hpp" #include "DuplexPort.hpp" +#include "EdgeImpl.hpp" #include "Engine.hpp" #include "EngineStore.hpp" #include "InputPort.hpp" diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp index 1ecdf285..139bbd78 100644 --- a/src/server/events/SetPortValue.cpp +++ b/src/server/events/SetPortValue.cpp @@ -20,6 +20,7 @@ #include "raul/log.hpp" #include "Broadcaster.hpp" +#include "Buffer.hpp" #include "ControlBindings.hpp" #include "Driver.hpp" #include "Engine.hpp" diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp index 33de440f..e5b0c658 100644 --- a/src/server/ingen_lv2.cpp +++ b/src/server/ingen_lv2.cpp @@ -42,9 +42,10 @@ #include "raul/Thread.hpp" #include "raul/log.hpp" -#include "EnginePort.hpp" +#include "Buffer.hpp" #include "Driver.hpp" #include "Engine.hpp" +#include "EnginePort.hpp" #include "EventWriter.hpp" #include "PatchImpl.hpp" #include "PostProcessor.hpp" @@ -172,7 +173,7 @@ public: {} void run(uint32_t nframes) { - _engine.process_context().locate(_frame_time, nframes, 0); + _engine.process_context().locate(_frame_time, nframes); for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) (*i)->pre_process(_engine.process_context()); @@ -535,7 +536,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor, engine->activate(); Server::ThreadManager::single_threaded = true; - engine->process_context().locate(0, block_length, 0); + engine->process_context().locate(0, block_length); engine->post_processor()->set_end_time(block_length); engine->process_events(); diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp index 6c0e6858..a088488c 100644 --- a/src/server/internals/Controller.cpp +++ b/src/server/internals/Controller.cpp @@ -23,6 +23,7 @@ #include "lv2/lv2plug.in/ns/ext/atom/util.h" #include "raul/midi_events.h" +#include "Buffer.hpp" #include "Engine.hpp" #include "InputPort.hpp" #include "InternalPlugin.hpp" diff --git a/src/server/internals/Delay.cpp b/src/server/internals/Delay.cpp index f478bd67..01a48683 100644 --- a/src/server/internals/Delay.cpp +++ b/src/server/internals/Delay.cpp @@ -25,6 +25,7 @@ #include "raul/log.hpp" #include "raul/midi_events.h" +#include "Buffer.hpp" #include "Driver.hpp" #include "Engine.hpp" #include "InputPort.hpp" diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp index 3bb7273a..3970169b 100644 --- a/src/server/internals/Note.cpp +++ b/src/server/internals/Note.cpp @@ -24,6 +24,7 @@ #include "raul/log.hpp" #include "raul/midi_events.h" +#include "Buffer.hpp" #include "Driver.hpp" #include "InputPort.hpp" #include "InternalPlugin.hpp" diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp index 55184b1f..0eb0c9f1 100644 --- a/src/server/internals/Trigger.cpp +++ b/src/server/internals/Trigger.cpp @@ -22,6 +22,7 @@ #include "raul/log.hpp" #include "raul/midi_events.h" +#include "Buffer.hpp" #include "Engine.hpp" #include "InputPort.hpp" #include "InternalPlugin.hpp" diff --git a/src/server/mix.cpp b/src/server/mix.cpp index b4ba4b8a..773b2aa7 100644 --- a/src/server/mix.cpp +++ b/src/server/mix.cpp @@ -16,7 +16,6 @@ #include "lv2/lv2plug.in/ns/ext/atom/util.h" -#include "ingen/URIs.hpp" #include "raul/log.hpp" #include "Buffer.hpp" @@ -26,38 +25,6 @@ namespace Ingen { namespace Server { -static inline void -audio_accumulate(Context& context, Buffer* dst, const Buffer* src) -{ - Sample* const dst_buf = dst->samples(); - const Sample* const src_buf = src->samples(); - - if (dst->is_control()) { - if (src->is_control()) { // control => control - dst_buf[0] += src_buf[0]; - } else { // audio => control - dst_buf[0] += src_buf[context.offset()]; - } - } else { - const SampleCount end = context.offset() + context.nframes(); - if (src->is_control()) { // control => audio - for (SampleCount i = context.offset(); i < end; ++i) { - dst_buf[i] += src_buf[0]; - } - } else { // audio => audio - for (SampleCount i = context.offset(); i < end; ++i) { - dst_buf[i] += src_buf[i]; - } - } - } -} - -static inline bool -is_audio(URIs& uris, LV2_URID type) -{ - return type == uris.atom_Float || type == uris.atom_Sound; -} - static inline bool is_end(const Buffer* buf, LV2_Atom_Event* ev) { @@ -68,28 +35,44 @@ is_end(const Buffer* buf, LV2_Atom_Event* ev) } void -mix(Context& context, - URIs& uris, +mix(const Context& context, Buffer* dst, const Buffer*const* srcs, uint32_t num_srcs) { if (num_srcs == 1) { dst->copy(context, srcs[0]); - } else if (is_audio(uris, dst->type())) { + } else if (dst->is_control()) { + Sample* const out = dst->samples(); + out[0] = srcs[0]->value_at(0); + for (uint32_t i = 1; i < num_srcs; ++i) { + out[0] += srcs[i]->value_at(0); + } + } else if (dst->is_audio()) { // Copy the first source dst->copy(context, srcs[0]); // Mix in the rest + Sample* __restrict const out = dst->samples(); + const SampleCount end = context.nframes(); for (uint32_t i = 1; i < num_srcs; ++i) { - assert(is_audio(uris, srcs[i]->type())); - audio_accumulate(context, dst, srcs[i]); + const Sample* __restrict const in = srcs[i]->samples(); + if (srcs[i]->is_control()) { // control => audio + for (SampleCount i = 0; i < end; ++i) { + out[i] += in[0]; + } + } else { // audio => audio + assert(srcs[i]->is_audio()); + for (SampleCount i = 0; i < end; ++i) { + out[i] += in[i]; + } + } } } else { - assert(dst->type() == uris.atom_Sequence); + assert(dst->is_sequence()); LV2_Atom_Event* iters[num_srcs]; for (uint32_t i = 0; i < num_srcs; ++i) { - assert(srcs[i]->type() == uris.atom_Sequence); + assert(srcs[i]->is_sequence()); iters[i] = lv2_atom_sequence_begin( (const LV2_Atom_Sequence_Body*)LV2_ATOM_BODY_CONST(srcs[i]->atom())); if (is_end(srcs[i], iters[i])) { diff --git a/src/server/mix.hpp b/src/server/mix.hpp index 320019a0..b06d2ac4 100644 --- a/src/server/mix.hpp +++ b/src/server/mix.hpp @@ -29,8 +29,7 @@ class Context; class Buffer; void -mix(Context& context, - URIs& uris, +mix(const Context& context, Buffer* dst, const Buffer*const* srcs, uint32_t num_srcs); |