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
This commit is contained in:
David Robillard 2007-06-29 06:58:07 +00:00
parent 44867662a3
commit eb296b2c95
18 changed files with 76 additions and 66 deletions

View file

@ -270,8 +270,8 @@ PluginSelector::input_refiller ()
// Insert into GTK list // Insert into GTK list
for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
snprintf (ibuf, sizeof(ibuf)-1, "%zu", (*i)->n_inputs.n_total()); snprintf (ibuf, sizeof(ibuf)-1, "%u", (*i)->n_inputs.n_total());
snprintf (obuf, sizeof(obuf)-1, "%zu", (*i)->n_outputs.n_total()); snprintf (obuf, sizeof(obuf)-1, "%u", (*i)->n_outputs.n_total());
Gtk::TreeModel::Row newrow = *(lmodel->append()); Gtk::TreeModel::Row newrow = *(lmodel->append());
newrow[lcols.name] = (*i)->name.c_str(); newrow[lcols.name] = (*i)->name.c_str();

View file

@ -48,7 +48,7 @@ public:
void read_from(const Buffer& src, nframes_t len, nframes_t offset) void read_from(const Buffer& src, nframes_t len, nframes_t offset)
{ {
assert(_capacity > 0); assert(_capacity > 0);
assert(src.type() == _type == DataType::AUDIO); assert(src.type() == DataType::AUDIO);
assert(offset + len <= _capacity); assert(offset + len <= _capacity);
memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len); memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
_silent = src.silent(); _silent = src.silent();

View file

@ -71,7 +71,7 @@ public:
Buffer& get(DataType type, size_t i) Buffer& get(DataType type, size_t i)
{ {
assert(i <= _count.get(type)); assert(i <= _count.get(type));
return *_buffers[type.to_index()][i]; return *_buffers[type][i];
} }
AudioBuffer& get_audio(size_t i) AudioBuffer& get_audio(size_t i)
@ -140,7 +140,7 @@ public:
private: private:
typedef std::vector<Buffer*> BufferVec; typedef std::vector<Buffer*> BufferVec;
/// Vector of vectors, indexed by DataType::to_index() /// Vector of vectors, indexed by DataType
std::vector<BufferVec> _buffers; std::vector<BufferVec> _buffers;
/// Use counts (there may be more actual buffers than this) /// Use counts (there may be more actual buffers than this)

View file

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2006 Paul Davis Copyright (C) 2006 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify 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 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 You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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__ #ifndef __ardour_chan_count_h__
#define __ardour_chan_count_h__ #define __ardour_chan_count_h__
#include <ardour/data_type.h> #include <ardour/data_type.h>
#include <cassert>
namespace ARDOUR { 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 { class ChanCount {
public: public:
ChanCount() { reset(); } ChanCount() { reset(); }
// Convenience constructor for making single-typed streams (stereo, mono, etc) // Convenience constructor for making single-typed streams (stereo, mono, etc)
ChanCount(DataType type, size_t channels) ChanCount(DataType type, uint32_t channels)
{ {
reset(); reset();
set(type, channels); set(type, channels);
@ -40,31 +45,31 @@ public:
void reset() void reset()
{ {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { 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.. void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; }
inline size_t n_audio() const { return _counts[DataType::AUDIO-1]; } uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; }
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; }
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; uint32_t ret = 0;
for (size_t i=0; i < DataType::num_types; ++i) for (uint32_t i=0; i < DataType::num_types; ++i)
ret += _counts[i]; ret += _counts[i];
return ret; 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 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]) if (_counts[i] != other._counts[i])
return false; return false;
@ -79,7 +84,7 @@ public:
bool operator<(const ChanCount& other) const bool operator<(const ChanCount& other) const
{ {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { 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; return false;
} }
} }
@ -94,7 +99,7 @@ public:
bool operator>(const ChanCount& other) const bool operator>(const ChanCount& other) const
{ {
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { 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; return false;
} }
} }
@ -111,7 +116,7 @@ public:
private: private:
size_t _counts[DataType::num_types]; uint32_t _counts[DataType::num_types];
}; };

View file

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2006 Paul Davis Copyright (C) 2006 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the Free
@ -35,17 +36,25 @@ namespace ARDOUR {
class DataType class DataType
{ {
public: 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 { enum Symbol {
NIL = 0, AUDIO = 0,
AUDIO, MIDI = 1,
MIDI NIL = 2,
}; };
/** Number of types (not including NIL). /** Number of types (not including NIL).
* WARNING: make sure this matches Symbol! * WARNING: make sure this matches Symbol!
*/ */
static const size_t num_types = 2; static const uint32_t num_types = 2;
DataType(const Symbol& symbol) DataType(const Symbol& symbol)
: _symbol(symbol) : _symbol(symbol)
@ -54,17 +63,12 @@ public:
/** Construct from a string (Used for loading from XML and Ports) /** 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 * The string can be as in an XML file (eg "audio" or "midi"), or a
* Jack type string (from jack_port_type) */ * Jack type string (from jack_port_type) */
DataType(const std::string& str) { DataType(const std::string& str)
if (str == "audio") : _symbol(NIL) {
if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE)
_symbol = AUDIO; _symbol = AUDIO;
else if (str == JACK_DEFAULT_AUDIO_TYPE) else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE)
_symbol = AUDIO;
else if (str == "midi")
_symbol = MIDI; _symbol = MIDI;
else if (str == JACK_DEFAULT_MIDI_TYPE)
_symbol = MIDI;
else
_symbol = NIL;
} }
/** Get the Jack type this DataType corresponds to */ /** Get the Jack type this DataType corresponds to */
@ -85,8 +89,7 @@ public:
} }
} }
//Symbol to_symbol() const { return _symbol; } inline operator uint32_t() const { return (uint32_t)_symbol; }
inline size_t to_index() const { return (size_t)_symbol - 1; }
/** DataType iterator, for writing generic loops that iterate over all /** DataType iterator, for writing generic loops that iterate over all
* available types. * available types.
@ -94,7 +97,7 @@ public:
class iterator { class iterator {
public: public:
iterator(size_t index) : _index(index) {} iterator(uint32_t index) : _index(index) {}
DataType operator*() { return DataType((Symbol)_index); } DataType operator*() { return DataType((Symbol)_index); }
iterator& operator++() { ++_index; return *this; } // yes, prefix only iterator& operator++() { ++_index; return *this; } // yes, prefix only
@ -104,11 +107,11 @@ public:
private: private:
friend class DataType; friend class DataType;
size_t _index; uint32_t _index;
}; };
static iterator begin() { return iterator(1); } static iterator begin() { return iterator(0); }
static iterator end() { return iterator(num_types+1); } static iterator end() { return iterator(num_types); }
bool operator==(const Symbol symbol) { return (_symbol == symbol); } bool operator==(const Symbol symbol) { return (_symbol == symbol); }
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); } bool operator!=(const DataType other) { return (_symbol != other._symbol); }
private: private:
Symbol _symbol; Symbol _symbol; // could be const if not for the string constructor
}; };

View file

@ -39,7 +39,7 @@ public:
PortSet(); PortSet();
size_t num_ports() const; 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); void add(Port* port);
bool remove(Port* port); bool remove(Port* port);

View file

@ -67,7 +67,7 @@ BufferSet::attach_buffers(PortSet& ports)
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
_buffers.push_back(BufferVec()); _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) { for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
assert(p->type() == *t); assert(p->type() == *t);
@ -97,13 +97,13 @@ void
BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity) BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
{ {
assert(type != DataType::NIL); assert(type != DataType::NIL);
assert(type.to_index() < _buffers.size()); assert(type < _buffers.size());
if (num_buffers == 0) if (num_buffers == 0)
return; return;
// The vector of buffers of the type we care about // 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 we're a mirror just make sure we're ok
if (_is_mirror) { if (_is_mirror) {
@ -146,7 +146,7 @@ size_t
BufferSet::buffer_capacity(DataType type) const BufferSet::buffer_capacity(DataType type) const
{ {
assert(_available.get(type) > 0); assert(_available.get(type) > 0);
return _buffers[type.to_index()][0]->capacity(); return _buffers[type][0]->capacity();
} }
// FIXME: make 'in' const // FIXME: make 'in' const

View file

@ -33,7 +33,7 @@ infinity_factory()
ChanCount ret; ChanCount ret;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
ret.set(*t, SIZE_MAX); ret.set(*t, UINT32_MAX);
} }
return ret; return ret;

View file

@ -36,7 +36,7 @@ namespace ARDOUR {
void void
PeakMeter::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) 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; size_t n = 0;

View file

@ -34,17 +34,14 @@ static bool sort_ports_by_name (Port* a, Port* b)
void void
PortSet::add(Port* port) PortSet::add(Port* port)
{ {
const size_t list_index = port->type().to_index(); PortVec& v = _ports[port->type()];
assert(list_index < _ports.size());
PortVec& v = _ports[list_index];
v.push_back(port); v.push_back(port);
sort(v.begin(), v.end(), sort_ports_by_name); sort(v.begin(), v.end(), sort_ports_by_name);
_count.set(port->type(), _count.get(port->type()) + 1); _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 bool
@ -108,7 +105,7 @@ PortSet::port(DataType type, size_t n) const
if (type == DataType::NIL) { if (type == DataType::NIL) {
return port(n); return port(n);
} else { } else {
const PortVec& v = _ports[type.to_index()]; const PortVec& v = _ports[type];
assert(n < v.size()); assert(n < v.size());
return v[n]; return v[n];
} }

View file

@ -2308,7 +2308,7 @@ Route::pans_required () const
return 0; return 0;
} }
return max (n_inputs ().n_audio(), static_cast<size_t>(processor_max_outs.n_audio())); return max (n_inputs ().n_audio(), processor_max_outs.n_audio());
} }
int int

View file

@ -3678,7 +3678,12 @@ Session::tempo_map_changed (Change ignored)
void void
Session::ensure_buffers (ChanCount howmany) 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); _scratch_buffers->ensure_buffers(howmany, current_block_size);
_send_buffers->ensure_buffers(howmany, current_block_size); _send_buffers->ensure_buffers(howmany, current_block_size);
_silent_buffers->ensure_buffers(howmany, current_block_size); _silent_buffers->ensure_buffers(howmany, current_block_size);