diff options
Diffstat (limited to 'libs/ardour/ardour')
26 files changed, 383 insertions, 192 deletions
diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h index 1eab294028..45949dc59e 100644 --- a/libs/ardour/ardour/audio_port.h +++ b/libs/ardour/ardour/audio_port.h @@ -78,7 +78,7 @@ class AudioPort : public Port { /** Assumes that the port is an audio output port */ void silence (jack_nframes_t nframes, jack_nframes_t offset) { if (!_silent) { - _buffer.clear(offset); + _buffer.silence(nframes, offset); if (offset == 0 && nframes == _buffer.capacity()) { _silent = true; } diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 9892179085..54a8c19a22 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -51,7 +51,7 @@ class AudioTrack : public Track int use_diskstream (string name); int use_diskstream (const PBD::ID& id); - int export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame); + int export_stuff (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t end_frame); void freeze (InterThreadInfo&); void unfreeze (); @@ -68,7 +68,7 @@ class AudioTrack : public Track jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter); - uint32_t n_process_buffers (); + ChanCount n_process_buffers (); private: int set_diskstream (AudioDiskstream&, void *); diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index 348a8ff863..5b5cd537ab 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -64,7 +64,7 @@ class AUPlugin : public ARDOUR::Plugin void deactivate (); void set_block_size (jack_nframes_t nframes); - int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset); + int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, jack_nframes_t nframes, jack_nframes_t offset); std::set<uint32_t> automatable() const; void store_state (ARDOUR::PluginState&); void restore_state (ARDOUR::PluginState&); diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 72989abb59..570ad2830d 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -108,11 +108,11 @@ class AudioEngine : public sigc::trackable Port *register_input_port (DataType type, const std::string& portname); Port *register_output_port (DataType type, const std::string& portname); - int unregister_port (Port *); + int unregister_port (Port &); int connect (const std::string& source, const std::string& destination); int disconnect (const std::string& source, const std::string& destination); - int disconnect (Port *); + int disconnect (Port &); const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags); @@ -215,7 +215,7 @@ class AudioEngine : public sigc::trackable typedef std::list<PortConnection> PortConnections; PortConnections port_connections; - void remove_connections_for (Port*); + void remove_connections_for (Port&); std::string get_nth_physical (DataType type, uint32_t n, int flags); diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h index 981d941de7..accdd9c181 100644 --- a/libs/ardour/ardour/buffer.h +++ b/libs/ardour/ardour/buffer.h @@ -57,9 +57,12 @@ public: DataType type() const { return _type; } /** Clear (eg zero, or empty) buffer starting at TIME @a offset */ - virtual void clear(jack_nframes_t offset = 0) = 0; + virtual void silence(jack_nframes_t len, jack_nframes_t offset=0) = 0; - virtual void write(const Buffer& src, jack_nframes_t offset, jack_nframes_t len) = 0; + /** Clear the entire buffer */ + virtual void clear() { silence(_capacity, 0); } + + virtual void read_from(const Buffer& src, jack_nframes_t offset, jack_nframes_t len) = 0; protected: Buffer(DataType type, size_t capacity) @@ -88,23 +91,51 @@ public: ~AudioBuffer(); - void clear(jack_nframes_t offset=0) { memset(_data + offset, 0, sizeof (Sample) * _capacity); } - - /** Copy @a len frames starting at @a offset, from the start of @a src */ - void write(const Buffer& src, jack_nframes_t offset, jack_nframes_t len) + void silence(jack_nframes_t len, jack_nframes_t offset=0) { + assert(_capacity > 0); + assert(offset + len <= _capacity); + memset(_data + offset, 0, sizeof (Sample) * len); + } + + /** Read @a len frames FROM THE START OF @a src into self at @a offset */ + void read_from(const Buffer& src, jack_nframes_t len, jack_nframes_t offset) + { + assert(_capacity > 0); assert(src.type() == _type == DataType::AUDIO); assert(offset + len <= _capacity); - memcpy(_data + offset, ((AudioBuffer&)src).data(len, offset), sizeof(Sample) * len); + memcpy(_data + offset, ((AudioBuffer&)src).data(len), sizeof(Sample) * len); } - /** Copy @a len frames starting at @a offset, from the start of @a src */ - void write(const Sample* src, jack_nframes_t offset, jack_nframes_t len) + /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */ + void accumulate_from(const AudioBuffer& src, jack_nframes_t len, jack_nframes_t offset) { + assert(_capacity > 0); assert(offset + len <= _capacity); - memcpy(_data + offset, src, sizeof(Sample) * len); + + Sample* const dst_raw = _data + offset; + const Sample* const src_raw = src.data(len); + + for (jack_nframes_t n = 0; n < len; ++n) { + dst_raw[n] += src_raw[n]; + } } + + /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset + * scaling by @a gain_coeff */ + void accumulate_with_gain_from(const AudioBuffer& src, jack_nframes_t len, jack_nframes_t offset, gain_t gain_coeff) + { + assert(_capacity > 0); + assert(offset + len <= _capacity); + Sample* const dst_raw = _data + offset; + const Sample* const src_raw = src.data(len); + + for (jack_nframes_t n = 0; n < len; ++n) { + dst_raw[n] += src_raw[n] * gain_coeff; + } + } + /** Set the data contained by this buffer manually (for setting directly to jack buffer). * * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks). @@ -142,10 +173,10 @@ public: ~MidiBuffer(); - // FIXME: clear events starting at offset - void clear(jack_nframes_t offset=0) { assert(offset == 0); _size = 0; } + // FIXME: clear events starting at offset in time + void silence(jack_nframes_t len, jack_nframes_t offset=0) { assert(offset == 0); _size = 0; } - void write(const Buffer& src, jack_nframes_t offset, jack_nframes_t nframes); + void read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t offset); void set_size(size_t size) { _size = size; } diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h index 1799858794..dfb5dd3611 100644 --- a/libs/ardour/ardour/buffer_set.h +++ b/libs/ardour/ardour/buffer_set.h @@ -19,14 +19,17 @@ #ifndef __ardour_buffer_set_h__ #define __ardour_buffer_set_h__ +#include <cassert> #include <vector> -#include <ardour/buffer.h> #include <ardour/chan_count.h> #include <ardour/data_type.h> -#include <ardour/port_set.h> namespace ARDOUR { +class Buffer; +class AudioBuffer; +class PortSet; + /** A set of buffers of various types. * @@ -44,52 +47,91 @@ namespace ARDOUR { class BufferSet { public: - BufferSet(const PortSet& ports); BufferSet(); ~BufferSet(); void clear(); - void ensure_buffers(const ChanCount& chan_count, size_t buffer_capacity); - void ensure_buffers(size_t num_buffers, DataType type, size_t buffer_capacity); + void attach_buffers(PortSet& ports); + + void ensure_buffers(const ChanCount& count, size_t buffer_capacity); + void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity); - // FIXME: add these - //const ChanCount& available() const { return _count; } - //ChanCount& available() { return _count; } + const ChanCount& available() const { return _available; } + ChanCount& available() { return _available; } const ChanCount& count() const { return _count; } ChanCount& count() { return _count; } - size_t available_buffers(DataType type) const; + void set_count(const ChanCount& count) { _count = count; } + size_t buffer_capacity(DataType type) const; - Buffer& buffer(DataType type, size_t i) + Buffer& get(DataType type, size_t i) { assert(i <= _count.get(type)); return *_buffers[type.to_index()][i]; } - AudioBuffer& audio_buffer(size_t i) + AudioBuffer& get_audio(size_t i) + { + return (AudioBuffer&)get(DataType::AUDIO, i); + } + + void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0) { - return (AudioBuffer&)buffer(DataType::AUDIO, i); + throw; // FIXME: implement this with spiffy DataType iterator etc. } - #if 0 - /** See PortInsert::run for an example of usage */ - class IndexSet { + + // ITERATORS + + // FIXME: this is a filthy copy-and-paste mess + // FIXME: litter these with assertions + + class audio_iterator { public: - IndexSet() { reset(); } - - void reset() { _is[0] = 0; _is[1] = 0; } - size_t index(DataType type) { return _is[type.to_index()]; } - void increment(DataType type) { _is[type.to_index()] += 1; } + AudioBuffer& operator*() { return _set.get_audio(_index); } + AudioBuffer* operator->() { return &_set.get_audio(_index); } + audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only + bool operator==(const audio_iterator& other) { return (_index == other._index); } + bool operator!=(const audio_iterator& other) { return (_index != other._index); } private: - int _is[2]; + friend class BufferSet; + + audio_iterator(BufferSet& list, size_t index) : _set(list), _index(index) {} + + BufferSet& _set; + size_t _index; }; - #endif - - const ChanCount& chan_count() const { return _count; } + + audio_iterator audio_begin() { return audio_iterator(*this, 0); } + audio_iterator audio_end() { return audio_iterator(*this, _count.get(DataType::AUDIO)); } + + class iterator { + public: + + Buffer& operator*() { return _set.get(_type, _index); } + Buffer* operator->() { return &_set.get(_type, _index); } + iterator& operator++() { ++_index; return *this; } // yes, prefix only + bool operator==(const iterator& other) { return (_index == other._index); } + bool operator!=(const iterator& other) { return (_index != other._index); } + + private: + friend class BufferSet; + + iterator(BufferSet& list, DataType type, size_t index) + : _set(list), _type(type), _index(index) {} + + BufferSet& _set; + DataType _type; + size_t _index; + }; + + iterator begin(DataType type) { return iterator(*this, type, 0); } + iterator end(DataType type) { return iterator(*this, type, _count.get(type)); } + private: typedef std::vector<Buffer*> BufferVec; @@ -100,6 +142,9 @@ private: /// Use counts (there may be more actual buffers than this) ChanCount _count; + /// Available counts (number of buffers actually allocated) + ChanCount _available; + /// Whether we (don't) 'own' the contained buffers (are a mirror of a PortSet) bool _is_mirror; }; diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h index 67ad5406e3..26e41a9bcd 100644 --- a/libs/ardour/ardour/chan_count.h +++ b/libs/ardour/ardour/chan_count.h @@ -73,41 +73,31 @@ public: bool operator<(const ChanCount& other) const { for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[(*t).to_index()] >= other._counts[(*t).to_index()]) { + if (_counts[(*t).to_index()] > other._counts[(*t).to_index()]) { return false; } } - return true; + return (*this != other); } - + bool operator<=(const ChanCount& other) const { - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[(*t).to_index()] > other._counts[(*t).to_index()]) { - return false; - } - } - return true; + return ( (*this < other) || (*this == other) ); } bool operator>(const ChanCount& other) const { for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[(*t).to_index()] <= other._counts[(*t).to_index()]) { + if (_counts[(*t).to_index()] < other._counts[(*t).to_index()]) { return false; } } - return true; + return (*this != other); } - + bool operator>=(const ChanCount& other) const { - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[(*t).to_index()] < other._counts[(*t).to_index()]) { - return false; - } - } - return true; + return ( (*this > other) || (*this == other) ); } static const ChanCount INFINITE; diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h index 7f8a43cfe1..df632c5171 100644 --- a/libs/ardour/ardour/curve.h +++ b/libs/ardour/ardour/curve.h @@ -52,8 +52,8 @@ class Curve : public AutomationList Curve (const Curve& other); Curve (const Curve& other, double start, double end); - bool rt_safe_get_vector (double x0, double x1, float *arg, int32_t veclen); - void get_vector (double x0, double x1, float *arg, int32_t veclen); + bool rt_safe_get_vector (double x0, double x1, float *arg, size_t veclen); + void get_vector (double x0, double x1, float *arg, size_t veclen); AutomationEventList::iterator closest_control_point_before (double xval); AutomationEventList::iterator closest_control_point_after (double xval); @@ -72,14 +72,14 @@ class Curve : public AutomationList double unlocked_eval (double where); double multipoint_eval (double x); - void _get_vector (double x0, double x1, float *arg, int32_t veclen); + void _get_vector (double x0, double x1, float *arg, size_t veclen); }; } // namespace ARDOUR extern "C" { - void curve_get_vector_from_c (void *arg, double, double, float*, int32_t); + void curve_get_vector_from_c (void *arg, double, double, float*, size_t); } #endif /* __ardour_curve_h__ */ diff --git a/libs/ardour/ardour/data_type.h b/libs/ardour/ardour/data_type.h index cbb88afccf..2703372311 100644 --- a/libs/ardour/ardour/data_type.h +++ b/libs/ardour/ardour/data_type.h @@ -19,6 +19,7 @@ #ifndef __ardour_data_type_h__ #define __ardour_data_type_h__ +#include <cassert> #include <string> #include <ardour/data_type.h> #include <jack/jack.h> @@ -95,7 +96,7 @@ public: } Symbol to_symbol() const { return _symbol; } - inline size_t to_index() const { return symbol_index(_symbol); } + inline size_t to_index() const { assert(_symbol != NIL); return symbol_index(_symbol); } /** DataType iterator, for writing generic loops that iterate over all * available types. diff --git a/libs/ardour/ardour/declicker.h b/libs/ardour/ardour/declicker.h new file mode 100644 index 0000000000..7e4c034f5d --- /dev/null +++ b/libs/ardour/ardour/declicker.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2006 Paul Davis + + This program 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. + + This program 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 more 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., + 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_declicker_h__ +#define __ardour_declicker_h__ + +#include <ardour/types.h> + +namespace ARDOUR { + +class BufferSet; + + +/** Applies a declick operation to all audio inputs, passing the same number of + * audio outputs, and passing through any other types unchanged. + */ +class Declicker { +public: + static void run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity); +}; + + +} // namespace ARDOUR + +#endif // __ardour_declicker_h__ diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index 08dea4fb27..c4e85c00ce 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -115,7 +115,7 @@ class Diskstream : public Stateful, public sigc::trackable jack_nframes_t get_capture_start_frame (uint32_t n=0); jack_nframes_t get_captured_frames (uint32_t n=0); - uint32_t n_channels() { return _n_channels; } + ChanCount n_channels() { return _n_channels; } static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; } static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; } @@ -250,7 +250,7 @@ class Diskstream : public Stateful, public sigc::trackable string _name; ARDOUR::Session& _session; ARDOUR::IO* _io; - uint32_t _n_channels; + ChanCount _n_channels; PBD::ID _id; Playlist* _playlist; diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index c81d4e5761..b958f20b95 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -53,7 +53,7 @@ class Insert : public Redirect virtual ~Insert() { } - virtual void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; + virtual void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; virtual void activate () {} virtual void deactivate () {} @@ -75,12 +75,12 @@ class PortInsert : public Insert int set_state(const XMLNode&); void init (); - void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); jack_nframes_t latency(); - uint32_t output_streams() const; - uint32_t input_streams() const; + ChanCount output_streams() const; + ChanCount input_streams() const; int32_t can_support_input_configuration (int32_t) const; int32_t configure_io (int32_t magic, int32_t in, int32_t out); @@ -113,17 +113,17 @@ class PluginInsert : public Insert StateManager::State* state_factory (std::string why) const; Change restore_state (StateManager::State&); - void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); void silence (jack_nframes_t nframes, jack_nframes_t offset); void activate (); void deactivate (); void set_block_size (jack_nframes_t nframes); - uint32_t output_streams() const; - uint32_t input_streams() const; - uint32_t natural_output_streams() const; - uint32_t natural_input_streams() const; + ChanCount output_streams() const; + ChanCount input_streams() const; + ChanCount natural_output_streams() const; + ChanCount natural_input_streams() const; int set_count (uint32_t num); uint32_t get_count () const { return _plugins.size(); } @@ -167,8 +167,8 @@ class PluginInsert : public Insert void parameter_changed (uint32_t, float); vector<boost::shared_ptr<Plugin> > _plugins; - void automation_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); - void connect_and_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now = 0); + void automation_run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void connect_and_run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now = 0); void init (); void set_automatable (); diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index a4b50618bb..0b8c84a459 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -54,9 +54,11 @@ class Session; class AudioEngine; class Connection; class Panner; +class PeakMeter; class Port; class AudioPort; class MidiPort; +class BufferSet; /** A collection of input and output ports with connections. * @@ -99,27 +101,26 @@ class IO : public Stateful, public ARDOUR::StateManager virtual void silence (jack_nframes_t, jack_nframes_t offset); - // These should be moved in to a separate object that manipulates an IO - - void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); - void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame, - jack_nframes_t nframes, jack_nframes_t offset); - void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); - void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); + void pan_automated (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); + void collect_input (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void deliver_output (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); + void deliver_output_no_pan (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset); - virtual uint32_t n_process_buffers () { return 0; } + virtual ChanCount n_process_buffers () { return ChanCount::ZERO; } virtual void set_gain (gain_t g, void *src); void inc_gain (gain_t delta, void *src); gain_t gain () const { return _desired_gain; } virtual gain_t effective_gain () const; - Panner& panner() { return *_panner; } + Panner& panner() { return *_panner; } + PeakMeter& peak_meter() { return *_meter; } int ensure_io (uint32_t, uint32_t, bool clear, void *src); + int ensure_io (const ChanCount& in, const ChanCount& out, bool clear, void *src); int use_input_connection (Connection&, void *src); int use_output_connection (Connection&, void *src); @@ -148,6 +149,9 @@ class IO : public Stateful, public ARDOUR::StateManager jack_nframes_t input_latency() const; void set_port_latency (jack_nframes_t); + const PortSet& inputs() const { return _inputs; } + const PortSet& outputs() const { return _outputs; } + Port *output (uint32_t n) const { if (n < _outputs.num_ports()) { return _outputs.port(n); @@ -169,8 +173,10 @@ class IO : public Stateful, public ARDOUR::StateManager MidiPort* midi_input(uint32_t n) const; MidiPort* midi_output(uint32_t n) const; - const ChanCount& n_inputs () const { return _inputs.chan_count(); } - const ChanCount& n_outputs () const { return _outputs.chan_count(); } + const ChanCount& n_inputs () const { return _inputs.count(); } + const ChanCount& n_outputs () const { return _outputs.count(); } + + void attach_buffers(ChanCount ignored); sigc::signal<void,IOChange,void*> input_changed; sigc::signal<void,IOChange,void*> output_changed; @@ -197,27 +203,16 @@ class IO : public Stateful, public ARDOUR::StateManager static int reset_panners (void); - static sigc::signal<int> PortsLegal; - static sigc::signal<int> PannersLegal; - static sigc::signal<int> ConnectingLegal; - static sigc::signal<void,ChanCount> MoreOutputs; - static sigc::signal<int> PortsCreated; + static sigc::signal<int> PortsLegal; + static sigc::signal<int> PannersLegal; + static sigc::signal<int> ConnectingLegal; + static sigc::signal<void,ChanCount> MoreChannels; + static sigc::signal<int> PortsCreated; PBD::Controllable& gain_control() { return _gain_control; } - /* Peak metering */ - - float peak_input_power (uint32_t n) { - if (n < std::max (_inputs.chan_count().get(DataType::AUDIO), - _outputs.chan_count().get(DataType::AUDIO))) { - return _visible_peak_power[n]; - } else { - return minus_infinity(); - } - } - static void update_meters(); private: @@ -285,34 +280,30 @@ public: mutable Glib::Mutex io_lock; protected: - Session& _session; - Panner* _panner; - gain_t _gain; - gain_t _effective_gain; - gain_t _desired_gain; - Glib::Mutex declick_lock; - PortSet _outputs; - PortSet _inputs; - vector<float> _peak_power; - vector<float> _visible_peak_power; - string _name; - Connection* _input_connection; - Connection* _output_connection; - PBD::ID _id; - bool no_panner_reset; - XMLNode* deferred_state; - DataType _default_type; + Session& _session; + Panner* _panner; + BufferSet* _output_buffers; //< Set directly to our output port buffers + gain_t _gain; + gain_t _effective_gain; + gain_t _desired_gain; + Glib::Mutex declick_lock; + PortSet _outputs; + PortSet _inputs; + PeakMeter* _meter; + string _name; + Connection* _input_connection; + Connection* _output_connection; + PBD::ID _id; + bool no_panner_reset; + XMLNode* deferred_state; + DataType _default_type; virtual void set_deferred_state() {} - void reset_peak_meters(); void reset_panner (); virtual uint32_t pans_required() const - { return _inputs.chan_count().get(DataType::AUDIO); } - - static void apply_declick (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, - gain_t initial, gain_t target, bool invert_polarity); + { return _inputs.count().get(DataType::AUDIO); } struct GainControllable : public PBD::Controllable { GainControllable (IO& i) : io (i) {} @@ -354,8 +345,9 @@ public: static bool connecting_legal; static bool ports_legal; - private: + BufferSet& output_buffers() { return *_output_buffers; } + private: /* are these the best variable names ever, or what? */ diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index 99fc884898..c2bb10a843 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -83,7 +83,7 @@ class LadspaPlugin : public ARDOUR::Plugin } void set_block_size (jack_nframes_t nframes) {} - int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset); + int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, jack_nframes_t nframes, jack_nframes_t offset); void store_state (ARDOUR::PluginState&); void restore_state (ARDOUR::PluginState&); string describe_parameter (uint32_t); diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h new file mode 100644 index 0000000000..f18a2e6de9 --- /dev/null +++ b/libs/ardour/ardour/meter.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2006 Paul Davis + + This program 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. + + This program 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 more 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., + 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_meter_h__ +#define __ardour_meter_h__ + +#include <vector> +#include <ardour/types.h> +#include <pbd/fastlog.h> + +namespace ARDOUR { + +class BufferSet; +class ChanCount; +class Session; + + +/** Meters peaks on the input and stores them for access. + */ +class PeakMeter { +public: + PeakMeter(Session& s) : _session(s) {} + + void setup (const ChanCount& in); + void reset (); + + /** Compute peaks */ + void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset=0); + + float peak_power (uint32_t n) { + if (n < _visible_peak_power.size()) { + return _visible_peak_power[n]; + } else { + return minus_infinity(); + } + } + +private: + + friend class IO; + void meter(); + + Session& _session; + std::vector<float> _peak_power; + std::vector<float> _visible_peak_power; +}; + + +} // namespace ARDOUR + +#endif // __ardour_meter_h__ diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h index 9b1092f300..a2bc259a6e 100644 --- a/libs/ardour/ardour/midi_port.h +++ b/libs/ardour/ardour/midi_port.h @@ -52,8 +52,7 @@ class MidiPort : public Port { /** Assumes that the port is an output port */ void silence (jack_nframes_t nframes, jack_nframes_t offset) { - // FIXME: silence starting at offset.. - _buffer->clear(); + _buffer->silence(nframes, offset); } protected: diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 4b942c7a21..9274cfbcf6 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -48,7 +48,7 @@ public: int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, bool can_record, bool rec_monitors_input); - void process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs, + void process_output_buffers (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, bool meter); @@ -64,7 +64,7 @@ public: void set_latency_delay (jack_nframes_t); - int export_stuff (vector<unsigned char*>& buffers, uint32_t nbufs, + int export_stuff (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t end_frame); void freeze (InterThreadInfo&); @@ -84,7 +84,7 @@ protected: jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter); - uint32_t n_process_buffers (); + ChanCount n_process_buffers (); private: int set_diskstream (MidiDiskstream&); diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 75c59eb924..5ea9f95f7a 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -40,6 +40,8 @@ namespace ARDOUR { class Session; class Panner; +class BufferSet; +class AudioBuffer; class StreamPanner : public sigc::trackable, public Stateful { @@ -62,10 +64,10 @@ class StreamPanner : public sigc::trackable, public Stateful void get_effective_position (float& xpos, float& ypos) const { xpos = effective_x; ypos = effective_y; } void get_effective_position (float& xpos, float& ypos, float& zpos) const { xpos = effective_x; ypos = effective_y; zpos = effective_z; } - /* the basic panner API */ + /* the basic StreamPanner API */ - virtual void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes) = 0; - virtual void distribute_automated (Sample* src, Sample** obufs, + virtual void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, jack_nframes_t nframes) = 0; + virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs, jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers) = 0; /* automation */ @@ -141,7 +143,7 @@ class BaseStereoPanner : public StreamPanner and a type name. See EqualPowerStereoPanner as an example. */ - void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes); + void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, jack_nframes_t nframes); int load (istream&, string path, uint32_t&); int save (ostream&) const; @@ -169,7 +171,7 @@ class EqualPowerStereoPanner : public BaseStereoPanner EqualPowerStereoPanner (Panner&); ~EqualPowerStereoPanner (); - void distribute_automated (Sample* src, Sample** obufs, + void distribute_automated (AudioBuffer& src, BufferSet& obufs, jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers); void get_current_coefficients (pan_t*) const; @@ -203,8 +205,8 @@ class Multi2dPanner : public StreamPanner Curve& automation() { return _automation; } - void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes); - void distribute_automated (Sample* src, Sample** obufs, + void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, jack_nframes_t nframes); + void distribute_automated (AudioBuffer& src, BufferSet& obufs, jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers); int load (istream&, string path, uint32_t&); @@ -239,6 +241,14 @@ class Panner : public std::vector<StreamPanner*>, public Stateful, public sigc:: Panner (string name, Session&); virtual ~Panner (); + // FIXME: unify these two + + /// The fundamental Panner function + void distribute (BufferSet& src, BufferSet& dest, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff); + + /// The other fundamental Panner function + void distribute_automated (BufferSet& src, BufferSet& dest, jack_nframes_t start_frame, jack_nframes_t end_frames, jack_nframes_t nframes, jack_nframes_t offset); + void set_name (string); bool bypassed() const { return _bypassed; } diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index e5a81f1ef9..a199e99933 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -45,6 +45,7 @@ namespace ARDOUR { class AudioEngine; class Session; +class BufferSet; class Plugin; @@ -120,7 +121,7 @@ class Plugin : public Stateful, public sigc::trackable virtual void deactivate () = 0; virtual void set_block_size (jack_nframes_t nframes) = 0; - virtual int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset) = 0; + virtual int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, jack_nframes_t nframes, jack_nframes_t offset) = 0; virtual std::set<uint32_t> automatable() const = 0; virtual void store_state (ARDOUR::PluginState&) = 0; virtual void restore_state (ARDOUR::PluginState&) = 0; diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index cf36f95b87..769e1fe98d 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -51,7 +51,7 @@ class Port : public sigc::trackable { virtual void silence (jack_nframes_t nframes, jack_nframes_t offset) = 0; - std::string name() { + std::string name() const { return _name; } diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h index d38aab2c4b..df6b20b37a 100644 --- a/libs/ardour/ardour/port_set.h +++ b/libs/ardour/ardour/port_set.h @@ -43,9 +43,11 @@ public: void add_port(Port* port); + /** nth port */ Port* port(size_t index) const; - - Port* nth_port_of_type(DataType type, size_t n) const; + + /** nth port of type @a t, or nth port if t = NIL */ + Port* port(DataType t, size_t index) const; AudioPort* nth_audio_port(size_t n) const; @@ -58,19 +60,19 @@ public: */ void clear() { _ports.clear(); } - const ChanCount& chan_count() const { return _chan_count; } + const ChanCount& count() const { return _count; } - bool empty() const { return (_chan_count.get_total() == 0); } + bool empty() const { return (_count.get_total() == 0); } // ITERATORS - // obviously these iterators will need to get more clever - // experimental phase, it's the interface that counts right now + // FIXME: this is a filthy copy-and-paste mess class iterator { public: - Port* operator*() { return _list.port(_index); } + Port& operator*() { return *_set.port(_type, _index); } + Port* operator->() { return _set.port(_type, _index); } iterator& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const iterator& other) { return (_index == other._index); } bool operator!=(const iterator& other) { return (_index != other._index); } @@ -78,19 +80,29 @@ public: private: friend class PortSet; - iterator(PortSet& list, size_t index) : _list(list), _index(index) {} + iterator(PortSet& list, DataType type, size_t index) + : _set(list), _type(type), _index(index) {} - PortSet& _list; - size_t _index; + PortSet& _set; + DataType _type; ///< Ignored if NIL (to iterator over entire set) + size_t _index; }; - iterator begin() { return iterator(*this, 0); } - iterator end() { return iterator(*this, _chan_count.get_total()); } + iterator begin(DataType type = DataType::NIL) + { return iterator(*this, type, 0); } + iterator end(DataType type = DataType::NIL) + { + return iterator(*this, type, + (type == DataType::NIL) ? _count.get_total() : _count.get(type)); + } + + // FIXME: typeify class const_iterator { public: - const Port* operator*() { return _list.port(_index); } + const Port& operator*() { return *_set.port(_index); } + const Port* operator->() { return _set.port(_index); } const_iterator& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const const_iterator& other) { return (_index == other._index); } bool operator!=(const const_iterator& other) { return (_index != other._index); } @@ -98,21 +110,21 @@ public: private: friend class PortSet; - const_iterator(const PortSet& list, size_t index) : _list(list), _index(index) {} + const_iterator(const PortSet& list, size_t index) : _set(list), _index(index) {} - const PortSet& _list; + const PortSet& _set; size_t _index; }; const_iterator begin() const { return const_iterator(*this, 0); } - const_iterator end() const { return const_iterator(*this, _chan_count.get_total()); } + const_iterator end() const { return const_iterator(*this, _count.get_total()); } - class audio_iterator { public: - AudioPort* operator*() { return _list.nth_audio_port(_index); } + AudioPort& operator*() { return *_set.nth_audio_port(_index); } + AudioPort* operator->() { return _set.nth_audio_port(_index); } audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only bool operator==(const audio_iterator& other) { return (_index == other._index); } bool operator!=(const audio_iterator& other) { return (_index != other._index); } @@ -120,14 +132,14 @@ public: private: friend class PortSet; - audio_iterator(PortSet& list, size_t index) : _list(list), _index(index) {} + audio_iterator(PortSet& list, size_t index) : _set(list), _index(index) {} - PortSet& _list; + PortSet& _set; size_t _index; }; audio_iterator audio_begin() { return audio_iterator(*this, 0); } - audio_iterator audio_end() { return audio_iterator(*this, _chan_count.get(DataType::AUDIO)); } + audio_iterator audio_end() { return audio_iterator(*this, _count.get(DataType::AUDIO)); } @@ -142,7 +154,7 @@ private: // Vector of vectors, indexed by DataType::to_index() std::vector<PortVec> _ports; - ChanCount _chan_count; + ChanCount _count; }; diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h index 4e6ef5124c..62da98aed1 100644 --- a/libs/ardour/ardour/redirect.h +++ b/libs/ardour/ardour/redirect.h @@ -70,10 +70,10 @@ class Redirect : public IO bool active () const { return _active; } void set_active (bool yn, void *src); - virtual uint32_t output_streams() const { return n_outputs().get(_default_type); } - virtual uint32_t input_streams () const { return n_inputs().get(_default_type); } - virtual uint32_t natural_output_streams() const { return n_outputs().get(_default_type); } - virtual uint32_t natural_input_streams () const { return n_inputs().get(_default_type); } + virtual ChanCount output_streams() const { return n_outputs(); } + virtual ChanCount input_streams () const { return n_inputs(); } + virtual ChanCount natural_output_streams() const { return n_outputs(); } + virtual ChanCount natural_input_streams () const { return n_inputs(); } uint32_t sort_key() const { return _sort_key; } void set_sort_key (uint32_t key); @@ -81,7 +81,7 @@ class Redirect : public IO Placement placement() const { return _placement; } void set_placement (Placement, void *src); - virtual void run (vector<Sample *>& ibufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; + virtual void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset) = 0; virtual void activate () = 0; virtual void deactivate () = 0; virtual jack_nframes_t latency() { return 0; } diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 493a5e7bc0..cf6b2b7c60 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -161,8 +161,11 @@ class Route : public IO } } - uint32_t max_redirect_outs () const { return redirect_max_outs; } - + ChanCount max_redirect_outs () const { return redirect_max_outs; } + + // FIXME: remove/replace err_streams parameters with something appropriate + // they are used by 'wierd_plugin_dialog'(sic) to display the number of input streams + // at the insertion point if the insert fails int add_redirect (boost::shared_ptr<Redirect>, void *src, uint32_t* err_streams = 0); int add_redirects (const RedirectList&, void *src, uint32_t* err_streams = 0); int remove_redirect (boost::shared_ptr<Redirect>, void *src, uint32_t* err_streams = 0); @@ -304,7 +307,7 @@ class Route : public IO void passthru (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_inputs); - virtual void process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs, + virtual void process_output_buffers (BufferSet& bufs, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, bool meter); @@ -318,11 +321,11 @@ class Route : public IO sigc::connection input_signal_connection; state_id_t _current_state_id; - uint32_t redirect_max_outs; + ChanCount redirect_max_outs; uint32_t _remote_control_id; uint32_t pans_required() const; - uint32_t n_process_buffers (); + ChanCount n_process_buffers (); private: void init (); diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 0a068e8af0..426ff5deed 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -40,7 +40,7 @@ class Send : public Redirect { Send (const Send&); ~Send (); - void run (vector<Sample *> &bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); + void run (BufferSet& bufs, jack_nframes_t nframes, jack_nframes_t offset); void activate() {} void deactivate () {} @@ -50,12 +50,12 @@ class Send : public Redirect { XMLNode& get_state(void); int set_state(const XMLNode& node); - uint32_t pans_required() const { return expected_inputs; } - void expect_inputs (uint32_t); + uint32_t pans_required() const { return _expected_inputs.get(DataType::AUDIO); } + void expect_inputs (const ChanCount&); private: - bool _metering; - uint32_t expected_inputs; + bool _metering; + ChanCount _expected_inputs; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 5cffe8a7c6..cac27168a1 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -73,6 +73,7 @@ class Route; class AuxInput; class Source; class AudioSource; +class BufferSet; class Diskstream; class AudioDiskstream; @@ -280,10 +281,10 @@ class Session : public sigc::trackable, public Stateful void process (jack_nframes_t nframes); - vector<Sample*>& get_passthru_buffers() { return _passthru_buffers; } - vector<Sample*>& get_silent_buffers (uint32_t howmany); - vector<Sample*>& get_send_buffers () { return _send_buffers; } - + BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO); + BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO); + BufferSet& get_send_buffers (ChanCount count = ChanCount::ZERO); + Diskstream *diskstream_by_id (const PBD::ID& id); Diskstream *diskstream_by_name (string name); @@ -1072,9 +1073,9 @@ class Session : public sigc::trackable, public Stateful jack_nframes_t _last_slave_transport_frame; jack_nframes_t maximum_output_latency; jack_nframes_t last_stop_frame; - vector<Sample *> _passthru_buffers; - vector<Sample *> _silent_buffers; - vector<Sample *> _send_buffers; + BufferSet* _scratch_buffers; + BufferSet* _silent_buffers; + BufferSet* _send_buffers; jack_nframes_t current_block_size; jack_nframes_t _worst_output_latency; jack_nframes_t _worst_input_latency; @@ -1091,7 +1092,7 @@ class Session : public sigc::trackable, public Stateful void update_latency_compensation_proxy (void* ignored); - void ensure_passthru_buffers (ChanCount howmany); + void ensure_buffers (ChanCount howmany); void process_scrub (jack_nframes_t); void process_without_events (jack_nframes_t); diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 4e2af5c80e..4fc7cf4326 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -98,7 +98,7 @@ class Track : public Route virtual void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter) = 0; - virtual uint32_t n_process_buffers () = 0; + virtual ChanCount n_process_buffers () = 0; Diskstream *_diskstream; MeterPoint _saved_meter_point; |