summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/port.h
blob: 084022541d3993d3c9639237215e87f0dbc501a8 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
    Copyright (C) 2002 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.

*/

#ifndef __ardour_port_h__
#define __ardour_port_h__

#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <ardour/data_type.h>
#include <jack/jack.h>

namespace ARDOUR {

class AudioEngine;
class Buffer;

/** Abstract base for ports
 */
class Port : public virtual sigc::trackable {
   public:
	enum Flags {
		IsInput = JackPortIsInput,
		IsOutput = JackPortIsOutput,
		IsPhysical = JackPortIsPhysical,
		IsTerminal = JackPortIsTerminal,
		CanMonitor = JackPortCanMonitor
	};

	virtual ~Port();

	std::string name() const { 
		return _name;
	}

	Flags flags() const {
		return _flags;
	}

	bool receives_input() const {
		return _flags & IsInput;
	}

	bool sends_output () const {
		return _flags & IsOutput;
	}

	bool can_monitor () const {
		return _flags & CanMonitor;
	}

	void enable_metering() {
		_metering++;
	}
	
	void disable_metering () {
		if (_metering) { _metering--; }
	}

	virtual void cycle_start (nframes_t nframes, nframes_t offset) {}
	virtual void cycle_end (nframes_t nframes, nframes_t offset) {}
	virtual DataType type() const = 0;
	virtual Buffer& get_buffer() = 0;

	virtual bool connected () const;
	virtual bool connected_to (const std::string& portname) const;
	virtual int get_connections (std::vector<std::string>&) const;

	virtual int connect (Port& other);
	virtual int disconnect (Port& other);
	virtual int disconnect_all ();
	
	virtual void reset ();
	virtual int reestablish () {return 0; }
	virtual int reconnect () { return 0; }

	virtual int set_name (const std::string& str) {
		_name = str;
		return 0;
	}

	virtual std::string short_name() const = 0;
	virtual bool monitoring_input () const = 0;
	virtual void ensure_monitor_input (bool yn) = 0;
	virtual void request_monitor_input (bool yn) = 0;
	virtual nframes_t latency () const = 0;
	virtual nframes_t total_latency () const = 0;
	virtual void set_latency (nframes_t nframes) = 0;

	sigc::signal<void,bool> MonitorInputChanged;
	sigc::signal<void,bool> ClockSyncChanged;

	static void set_engine (AudioEngine*);

  protected:
	friend class AudioEngine;

	Port (const std::string& name, Flags flgs);

	virtual void recompute_total_latency() const {}
	
	/* engine isn't supposed to access below here */

	Flags          _flags;
	std::string    _type;
	std::string    _name;
	unsigned short _metering;
	bool           _last_monitor;
	nframes_t      _latency;

	std::set<Port*> _connections;

	static AudioEngine* engine;
};

class PortConnectableByName {
  public:
	PortConnectableByName() {}
	virtual ~PortConnectableByName() {}

	virtual int connect (const std::string& other_name) = 0;
	virtual int disconnect (const std::string& other_name) = 0;
};
 
class PortFacade : public virtual Port, public PortConnectableByName { 
  public:
	PortFacade (const std::string& name, Flags flgs) : Port (name, flgs), _ext_port (0) {}
	~PortFacade() {}

	void reset ();
	int reestablish ();
	int reconnect ();

	int connect (Port& other);
	int disconnect (Port& other);
	int disconnect_all ();

	int connect (const std::string& other_name);
	int disconnect (const std::string& other_name);

	bool connected () const;
	bool connected_to (const std::string& portname) const;
	int get_connections (std::vector<std::string>&) const;

	std::string short_name() const;
	int         set_name (const std::string& str);
	bool        monitoring_input () const;
	void        ensure_monitor_input (bool yn);
	void        request_monitor_input (bool yn);
	nframes_t   latency () const;
	nframes_t   total_latency () const;
	void        set_latency (nframes_t nframes);

  protected:
	Port* _ext_port;
};

} // namespace ARDOUR

#endif /* __ardour_port_h__ */