2 * Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
3 * Copyright (C) 2008-2013 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
5 * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef __ardour_chan_count_h__
23 #define __ardour_chan_count_h__
28 #include "pbd/xml++.h"
29 #include "ardour/data_type.h"
34 /** A count of channels, possibly with many types.
36 * Operators are defined so this may safely be used as if it were a simple
37 * (single-typed) integer count of channels.
39 class LIBARDOUR_API ChanCount {
41 ChanCount(const XMLNode& node);
42 ChanCount() { reset(); }
44 /** Convenience constructor for making single-typed streams (mono, stereo, midi, etc)
45 * @param type data type
46 * @param count number of channels
48 ChanCount(DataType type, uint32_t count) {
53 /** zero count of all data types */
55 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
60 /** set channel count for given type
62 * @param count number of channels
64 void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; }
66 /** query channel count for given type
68 * @returns channel count for given type
70 uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; }
72 inline uint32_t n (DataType t) const { return _counts[t]; }
74 /** query number of audio channels
75 * @returns number of audio channels
77 inline uint32_t n_audio() const { return _counts[DataType::AUDIO]; }
79 /** set number of audio channels
80 * @param a number of audio channels
82 inline void set_audio(uint32_t a) { _counts[DataType::AUDIO] = a; }
84 /** query number of midi channels
85 * @returns number of midi channels
87 inline uint32_t n_midi() const { return _counts[DataType::MIDI]; }
89 /** set number of audio channels
90 * @param m number of midi channels
92 inline void set_midi(uint32_t m) { _counts[DataType::MIDI] = m; }
94 /** query total channel count of all data types
95 * @returns total channel count (audio + midi)
97 uint32_t n_total() const {
99 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t)
105 bool operator==(const ChanCount& other) const {
106 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t)
107 if (_counts[*t] != other._counts[*t])
113 bool operator!=(const ChanCount& other) const {
114 return ! (*this == other);
117 bool operator<(const ChanCount& other) const {
118 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
119 if (_counts[*t] > other._counts[*t]) {
123 return (*this != other);
126 bool operator<=(const ChanCount& other) const {
127 return ( (*this < other) || (*this == other) );
130 bool operator>(const ChanCount& other) const {
131 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
132 if (_counts[*t] < other._counts[*t]) {
136 return (*this != other);
139 bool operator>=(const ChanCount& other) const {
140 return ( (*this > other) || (*this == other) );
143 ChanCount operator+(const ChanCount& other) const {
145 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
146 ret.set(*t, get(*t) + other.get(*t));
151 /** underflow safe subtraction */
152 ChanCount operator-(const ChanCount& other) const {
154 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
155 if (get(*t) < other.get(*t)) {
158 ret.set(*t, get(*t) - other.get(*t));
164 ChanCount operator*(const unsigned int factor) const {
166 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
167 ret.set(*t, get(*t) * factor );
172 /** underflow safe subtraction */
173 ChanCount& operator-=(const ChanCount& other) {
174 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
175 if (_counts[*t] < other._counts[*t]) {
178 _counts[*t] -= other._counts[*t];
184 ChanCount& operator+=(const ChanCount& other) {
185 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
186 _counts[*t] += other._counts[*t];
191 static ChanCount min(const ChanCount& a, const ChanCount& b) {
193 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
194 ret.set(*t, std::min(a.get(*t), b.get(*t)));
199 static ChanCount max(const ChanCount& a, const ChanCount& b) {
201 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
202 ret.set(*t, std::max(a.get(*t), b.get(*t)));
207 XMLNode* state(const std::string& name) const;
209 static const ChanCount ZERO;
212 uint32_t _counts[DataType::num_types];
215 } // namespace ARDOUR
217 LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanCount& c);
219 #endif // __ardour_chan_count_h__