2 Copyright (C) 2009 Paul Davis
3 Author: David Robillard
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 $Id: insert.cc 712 2006-07-28 01:08:57Z drobilla $
24 #include "ardour/chan_mapping.h"
30 ChanMapping::ChanMapping(ChanCount identity)
32 if (identity == ChanCount::INFINITE) {
36 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
37 for (size_t i = 0; i < identity.get(*t); ++i) {
43 ChanMapping::ChanMapping (const ChanMapping& other )
45 const ChanMapping::Mappings& mp (other.mappings());
46 for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
47 for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
48 set (tm->first, i->first, i->second);
54 ChanMapping::get(DataType t, uint32_t from, bool* valid) const
56 Mappings::const_iterator tm = _mappings.find(t);
57 if (tm == _mappings.end()) {
58 if (valid) { *valid = false; }
61 TypeMapping::const_iterator m = tm->second.find(from);
62 if (m == tm->second.end()) {
63 if (valid) { *valid = false; }
66 if (valid) { *valid = true; }
71 ChanMapping::set(DataType t, uint32_t from, uint32_t to)
73 assert(t != DataType::NIL);
74 Mappings::iterator tm = _mappings.find (t);
75 if (tm == _mappings.end()) {
76 tm = _mappings.insert(std::make_pair(t, TypeMapping())).first;
78 tm->second.insert(std::make_pair(from, to));
82 ChanMapping::unset(DataType t, uint32_t from)
84 assert(t != DataType::NIL);
85 Mappings::iterator tm = _mappings.find (t);
86 if (tm == _mappings.end()) {
89 tm->second.erase(from);
92 /** Offset the 'from' field of every mapping for type @a t by @a delta */
94 ChanMapping::offset_from(DataType t, int32_t delta)
96 Mappings::iterator tm = _mappings.find(t);
97 if (tm != _mappings.end ()) {
99 for (TypeMapping::iterator m = tm->second.begin(); m != tm->second.end(); ++m) {
100 new_map.insert (make_pair (m->first + delta, m->second));
102 tm->second = new_map;
106 /** Offset the 'to' field of every mapping for type @a t by @a delta */
108 ChanMapping::offset_to(DataType t, int32_t delta)
110 Mappings::iterator tm = _mappings.find(t);
111 if (tm != _mappings.end()) {
112 for (TypeMapping::iterator m = tm->second.begin(); m != tm->second.end(); ++m) {
119 ChanMapping::is_subset (const ChanMapping& superset) const
121 const Mappings& mp (mappings());
122 for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
123 for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
125 if (i->second != superset.get (tm->first, i->first, &valid)) {
137 ChanMapping::is_monotonic () const
139 const Mappings& mp (mappings());
140 for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
141 uint32_t prev = UINT32_MAX;
142 for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
143 // set keys are strictly weak ordered
144 if (i->first < i->second || i->second == prev) {
154 ChanMapping::is_identity (ChanCount offset) const
156 const Mappings& mp (mappings());
157 for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
158 for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
159 if (i->first + offset.get (tm->first) != i->second) {
167 } // namespace ARDOUR
169 std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
171 const ARDOUR::ChanMapping::Mappings& mp (cm.mappings());
172 for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
173 o << tm->first.to_string() << endl;
174 for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin();
175 i != tm->second.end(); ++i) {
176 o << "\t" << i->first << " => " << i->second << endl;