From eb296b2c957f574334fae2aefd8b863cf7631769 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 29 Jun 2007 06:58:07 +0000 Subject: [PATCH] Reduce overhead of multi-type-ness (last Summer's SoC): Use uint32_t instead of size_t counts (halves size of ChanCount on 64-bit). Shift DataType values down to eliminate subtraction every index of a ChanCount or *Set. Allow using DataType directly as an array index (prettier/terser). Fix some mixed spaces/tabs in file comment headers. git-svn-id: svn://localhost/ardour2/trunk@2082 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/automation_controller.cc | 2 +- gtk2_ardour/automation_controller.h | 2 +- gtk2_ardour/plugin_selector.cc | 4 +-- libs/ardour/ardour/audio_buffer.h | 2 +- libs/ardour/ardour/automation_control.h | 2 +- libs/ardour/ardour/buffer_set.h | 4 +-- libs/ardour/ardour/chan_count.h | 43 ++++++++++++----------- libs/ardour/ardour/data_type.h | 45 +++++++++++++------------ libs/ardour/ardour/midi_buffer.h | 2 +- libs/ardour/ardour/midi_model.h | 2 +- libs/ardour/ardour/port_set.h | 2 +- libs/ardour/automation_control.cc | 2 +- libs/ardour/buffer_set.cc | 8 ++--- libs/ardour/chan_count.cc | 2 +- libs/ardour/meter.cc | 2 +- libs/ardour/port_set.cc | 9 ++--- libs/ardour/route.cc | 2 +- libs/ardour/session.cc | 7 +++- 18 files changed, 76 insertions(+), 66 deletions(-) diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index a72aa0ba7d..3149b9784f 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2007 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/gtk2_ardour/automation_controller.h b/gtk2_ardour/automation_controller.h index 042f4a3b96..f9e8ab4ce3 100644 --- a/gtk2_ardour/automation_controller.h +++ b/gtk2_ardour/automation_controller.h @@ -1,6 +1,6 @@ /* Copyright (C) 2007 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 7333e45242..6eb12027d5 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -270,8 +270,8 @@ PluginSelector::input_refiller () // Insert into GTK list for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { - snprintf (ibuf, sizeof(ibuf)-1, "%zu", (*i)->n_inputs.n_total()); - snprintf (obuf, sizeof(obuf)-1, "%zu", (*i)->n_outputs.n_total()); + snprintf (ibuf, sizeof(ibuf)-1, "%u", (*i)->n_inputs.n_total()); + snprintf (obuf, sizeof(obuf)-1, "%u", (*i)->n_outputs.n_total()); Gtk::TreeModel::Row newrow = *(lmodel->append()); newrow[lcols.name] = (*i)->name.c_str(); diff --git a/libs/ardour/ardour/audio_buffer.h b/libs/ardour/ardour/audio_buffer.h index 7caea82287..b2c62466bf 100644 --- a/libs/ardour/ardour/audio_buffer.h +++ b/libs/ardour/ardour/audio_buffer.h @@ -48,7 +48,7 @@ public: void read_from(const Buffer& src, nframes_t len, nframes_t offset) { assert(_capacity > 0); - assert(src.type() == _type == DataType::AUDIO); + assert(src.type() == DataType::AUDIO); assert(offset + len <= _capacity); memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len); _silent = src.silent(); diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index d9e7a232af..5810ced9f9 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -1,6 +1,6 @@ /* Copyright (C) 2007 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h index 2e0f604ace..c750615798 100644 --- a/libs/ardour/ardour/buffer_set.h +++ b/libs/ardour/ardour/buffer_set.h @@ -71,7 +71,7 @@ public: Buffer& get(DataType type, size_t i) { assert(i <= _count.get(type)); - return *_buffers[type.to_index()][i]; + return *_buffers[type][i]; } AudioBuffer& get_audio(size_t i) @@ -140,7 +140,7 @@ public: private: typedef std::vector BufferVec; - /// Vector of vectors, indexed by DataType::to_index() + /// Vector of vectors, indexed by DataType std::vector _buffers; /// Use counts (there may be more actual buffers than this) diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h index 1ed50f7abb..986ef76e25 100644 --- a/libs/ardour/ardour/chan_count.h +++ b/libs/ardour/ardour/chan_count.h @@ -1,5 +1,6 @@ /* Copyright (C) 2006 Paul Davis + Author: Dave Robillard 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 @@ -14,24 +15,28 @@ 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. - - $Id: insert.cc 712 2006-07-28 01:08:57Z drobilla $ */ #ifndef __ardour_chan_count_h__ #define __ardour_chan_count_h__ #include +#include namespace ARDOUR { +/** A count of channels, possibly with many types. + * + * Operators are defined so this may safely be used as if it were a simple + * (single-typed) integer count of channels. + */ class ChanCount { public: ChanCount() { reset(); } // Convenience constructor for making single-typed streams (stereo, mono, etc) - ChanCount(DataType type, size_t channels) + ChanCount(DataType type, uint32_t channels) { reset(); set(type, channels); @@ -40,31 +45,31 @@ public: void reset() { for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - _counts[(*t).to_index()] = 0; + _counts[*t] = 0; } } - // -1 is what to_index does. inlined for speed. this should maybe be changed.. - inline size_t n_audio() const { return _counts[DataType::AUDIO-1]; } - inline size_t n_midi() const { return _counts[DataType::MIDI-1]; } - inline void set_audio(size_t a) { _counts[DataType::AUDIO-1] = a; } - inline void set_midi(size_t m) { _counts[DataType::MIDI-1] = m; } + void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; } + uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; } - size_t n_total() const + inline uint32_t n_audio() const { return _counts[DataType::AUDIO]; } + inline void set_audio(uint32_t a) { _counts[DataType::AUDIO] = a; } + + inline uint32_t n_midi() const { return _counts[DataType::MIDI]; } + inline void set_midi(uint32_t m) { _counts[DataType::MIDI] = m; } + + uint32_t n_total() const { - size_t ret = 0; - for (size_t i=0; i < DataType::num_types; ++i) + uint32_t ret = 0; + for (uint32_t i=0; i < DataType::num_types; ++i) ret += _counts[i]; return ret; } - void set(DataType type, size_t count) { _counts[type.to_index()] = count; } - size_t get(DataType type) const { return _counts[type.to_index()]; } - bool operator==(const ChanCount& other) const { - for (size_t i=0; i < DataType::num_types; ++i) + for (uint32_t i=0; i < DataType::num_types; ++i) if (_counts[i] != other._counts[i]) return false; @@ -79,7 +84,7 @@ 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] > other._counts[*t]) { return false; } } @@ -94,7 +99,7 @@ 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] < other._counts[*t]) { return false; } } @@ -111,7 +116,7 @@ public: private: - size_t _counts[DataType::num_types]; + uint32_t _counts[DataType::num_types]; }; diff --git a/libs/ardour/ardour/data_type.h b/libs/ardour/ardour/data_type.h index 3818a8d74f..68d9554904 100644 --- a/libs/ardour/ardour/data_type.h +++ b/libs/ardour/ardour/data_type.h @@ -1,5 +1,6 @@ /* Copyright (C) 2006 Paul Davis + Author: Dave Robillard 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 @@ -35,17 +36,25 @@ namespace ARDOUR { class DataType { public: - /// WARNING: make REALLY sure you don't mess up indexes if you change this + /** Numeric symbol for this DataType. + * + * Castable to int for use as an array index (e.g. by ChanCount). + * Note this means NIL is (ntypes-1) and guaranteed to change when + * types are added, so this number is NOT suitable for serialization, + * network, or binary anything. + * + * WARNING: The number of non-NIL entries here must match num_types. + */ enum Symbol { - NIL = 0, - AUDIO, - MIDI + AUDIO = 0, + MIDI = 1, + NIL = 2, }; /** Number of types (not including NIL). * WARNING: make sure this matches Symbol! */ - static const size_t num_types = 2; + static const uint32_t num_types = 2; DataType(const Symbol& symbol) : _symbol(symbol) @@ -54,17 +63,12 @@ public: /** Construct from a string (Used for loading from XML and Ports) * The string can be as in an XML file (eg "audio" or "midi"), or a * Jack type string (from jack_port_type) */ - DataType(const std::string& str) { - if (str == "audio") + DataType(const std::string& str) + : _symbol(NIL) { + if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE) _symbol = AUDIO; - else if (str == JACK_DEFAULT_AUDIO_TYPE) - _symbol = AUDIO; - else if (str == "midi") + else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE) _symbol = MIDI; - else if (str == JACK_DEFAULT_MIDI_TYPE) - _symbol = MIDI; - else - _symbol = NIL; } /** Get the Jack type this DataType corresponds to */ @@ -85,8 +89,7 @@ public: } } - //Symbol to_symbol() const { return _symbol; } - inline size_t to_index() const { return (size_t)_symbol - 1; } + inline operator uint32_t() const { return (uint32_t)_symbol; } /** DataType iterator, for writing generic loops that iterate over all * available types. @@ -94,7 +97,7 @@ public: class iterator { public: - iterator(size_t index) : _index(index) {} + iterator(uint32_t index) : _index(index) {} DataType operator*() { return DataType((Symbol)_index); } iterator& operator++() { ++_index; return *this; } // yes, prefix only @@ -104,11 +107,11 @@ public: private: friend class DataType; - size_t _index; + uint32_t _index; }; - static iterator begin() { return iterator(1); } - static iterator end() { return iterator(num_types+1); } + static iterator begin() { return iterator(0); } + static iterator end() { return iterator(num_types); } bool operator==(const Symbol symbol) { return (_symbol == symbol); } bool operator!=(const Symbol symbol) { return (_symbol != symbol); } @@ -117,7 +120,7 @@ public: bool operator!=(const DataType other) { return (_symbol != other._symbol); } private: - Symbol _symbol; + Symbol _symbol; // could be const if not for the string constructor }; diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h index 7e69cc9014..ecb48d9da9 100644 --- a/libs/ardour/ardour/midi_buffer.h +++ b/libs/ardour/ardour/midi_buffer.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index d9eb8447d2..909603a017 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h index 947730a5b9..51673472c3 100644 --- a/libs/ardour/ardour/port_set.h +++ b/libs/ardour/ardour/port_set.h @@ -39,7 +39,7 @@ public: PortSet(); size_t num_ports() const; - size_t num_ports(DataType type) const { return _ports[type.to_index()].size(); } + size_t num_ports(DataType type) const { return _ports[type].size(); } void add(Port* port); bool remove(Port* port); diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 8f8e40a641..10020990c6 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2007 Paul Davis - Author: Dave Robillard + Author: Dave Robillard 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 diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc index 24af224845..2206b8885b 100644 --- a/libs/ardour/buffer_set.cc +++ b/libs/ardour/buffer_set.cc @@ -67,7 +67,7 @@ BufferSet::attach_buffers(PortSet& ports) for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { _buffers.push_back(BufferVec()); - BufferVec& v = _buffers[(*t).to_index()]; + BufferVec& v = _buffers[*t]; for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) { assert(p->type() == *t); @@ -97,13 +97,13 @@ void BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity) { assert(type != DataType::NIL); - assert(type.to_index() < _buffers.size()); + assert(type < _buffers.size()); if (num_buffers == 0) return; // The vector of buffers of the type we care about - BufferVec& bufs = _buffers[type.to_index()]; + BufferVec& bufs = _buffers[type]; // If we're a mirror just make sure we're ok if (_is_mirror) { @@ -146,7 +146,7 @@ size_t BufferSet::buffer_capacity(DataType type) const { assert(_available.get(type) > 0); - return _buffers[type.to_index()][0]->capacity(); + return _buffers[type][0]->capacity(); } // FIXME: make 'in' const diff --git a/libs/ardour/chan_count.cc b/libs/ardour/chan_count.cc index 269f985796..b6f51a4d95 100644 --- a/libs/ardour/chan_count.cc +++ b/libs/ardour/chan_count.cc @@ -33,7 +33,7 @@ infinity_factory() ChanCount ret; for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - ret.set(*t, SIZE_MAX); + ret.set(*t, UINT32_MAX); } return ret; diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc index fb8dafbc7b..4a898eecaf 100644 --- a/libs/ardour/meter.cc +++ b/libs/ardour/meter.cc @@ -36,7 +36,7 @@ namespace ARDOUR { void PeakMeter::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) { - size_t meterable = std::min(bufs.count().n_total(), _peak_power.size()); + size_t meterable = std::min((size_t)bufs.count().n_total(), _peak_power.size()); size_t n = 0; diff --git a/libs/ardour/port_set.cc b/libs/ardour/port_set.cc index 388162359b..3182c2b959 100644 --- a/libs/ardour/port_set.cc +++ b/libs/ardour/port_set.cc @@ -34,17 +34,14 @@ static bool sort_ports_by_name (Port* a, Port* b) void PortSet::add(Port* port) { - const size_t list_index = port->type().to_index(); - assert(list_index < _ports.size()); - - PortVec& v = _ports[list_index]; + PortVec& v = _ports[port->type()]; v.push_back(port); sort(v.begin(), v.end(), sort_ports_by_name); _count.set(port->type(), _count.get(port->type()) + 1); - assert(_count.get(port->type()) == _ports[port->type().to_index()].size()); + assert(_count.get(port->type()) == _ports[port->type()].size()); } bool @@ -108,7 +105,7 @@ PortSet::port(DataType type, size_t n) const if (type == DataType::NIL) { return port(n); } else { - const PortVec& v = _ports[type.to_index()]; + const PortVec& v = _ports[type]; assert(n < v.size()); return v[n]; } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index e8e469b446..d14f1de087 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2308,7 +2308,7 @@ Route::pans_required () const return 0; } - return max (n_inputs ().n_audio(), static_cast(processor_max_outs.n_audio())); + return max (n_inputs ().n_audio(), processor_max_outs.n_audio()); } int diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index d5c2817f54..ccf88ff2ac 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3678,7 +3678,12 @@ Session::tempo_map_changed (Change ignored) void Session::ensure_buffers (ChanCount howmany) { - // FIXME: NASTY assumption (midi block size == audio block size) + // We need at least 1 MIDI scratch buffer to mix/merge + if (howmany.n_midi() < 1) + howmany.set_midi(1); + + // FIXME: JACK needs to tell us maximum MIDI buffer size + // Using nasty assumption (max # events == nframes) for now _scratch_buffers->ensure_buffers(howmany, current_block_size); _send_buffers->ensure_buffers(howmany, current_block_size); _silent_buffers->ensure_buffers(howmany, current_block_size);