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

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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<Buffer*> BufferVec;
/// Vector of vectors, indexed by DataType::to_index()
/// Vector of vectors, indexed by DataType
std::vector<BufferVec> _buffers;
/// Use counts (there may be more actual buffers than this)

View File

@ -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 <ardour/data_type.h>
#include <cassert>
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];
};

View File

@ -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
};

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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];
}

View File

@ -2308,7 +2308,7 @@ Route::pans_required () const
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

View File

@ -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);