summaryrefslogtreecommitdiff
path: root/libs/ardour/port_set.cc
blob: 22fb032c09b2f36a279cbeffe7e95658cbc827f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
    Copyright (C) 2006 Paul Davis 
    
    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
    Software Foundation; either version 2 of the License, or (at your option)
    any later version.
    
    This program is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.
    
    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.
*/

#include <ardour/port_set.h>

namespace ARDOUR {

PortSet::PortSet()
{
	for (size_t i=0; i < DataType::num_types; ++i)
		_ports.push_back( PortVec() );
}

static bool sort_ports_by_name (Port* a, Port* b)
{
	return (a->name() < b->name());
}

void
PortSet::add_port(Port* port)
{
	const size_t list_index = port->type().to_index();
	assert(list_index < _ports.size());
	
	PortVec& v = _ports[list_index];
	
	v.push_back(port);
	sort(v.begin(), v.end(), sort_ports_by_name);

	_chan_count.set_count(port->type(), _chan_count.get_count(port->type()) + 1);

	assert(_chan_count.get_count(port->type()) == _ports[port->type().to_index()].size());
}


/** Get the total number of ports (of all types) in the PortSet
 */
size_t
PortSet::num_ports() const
{
	size_t ret = 0;

	for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l)
		ret += (*l).size();

	return ret;
}

bool
PortSet::contains(const Port* port) const
{
	for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l)
		if (find((*l).begin(), (*l).end(), port) != (*l).end())
			return true;

	return false;
}

Port*
PortSet::port(size_t n) const
{
	// This is awesome
	
	size_t size_so_far = 0;

	for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) {
		if (n < size_so_far + (*l).size())
			return (*l)[n - size_so_far];
		else
			size_so_far += (*l).size();
	}

	return NULL; // n out of range
}

Port*
PortSet::nth_port_of_type(DataType type, size_t n) const
{
	const PortVec& v = _ports[type.to_index()];
	assert(n < v.size());
	return v[n];
}

AudioPort*
PortSet::nth_audio_port(size_t n) const
{
	return dynamic_cast<AudioPort*>(nth_port_of_type(DataType::AUDIO, n));
}

MidiPort*
PortSet::nth_midi_port(size_t n) const
{
	return dynamic_cast<MidiPort*>(nth_port_of_type(DataType::MIDI, n));
}

} // namepace ARDOUR