summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/delivery.h
blob: 887da3b1da9343969d0550b57cad252cba77fa1b (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
/*
 * Copyright (C) 2009-2011 David Robillard <d@drobilla.net>
 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
 * Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
 * Copyright (C) 2018 Len Ovens <len@ovenwerks.net>
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef __ardour_delivery_h__
#define __ardour_delivery_h__

#include <string>

#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
#include "ardour/chan_count.h"
#include "ardour/io_processor.h"

namespace ARDOUR {

class BufferSet;
class IO;
class MuteMaster;
class PannerShell;
class Panner;
class Pannable;

class LIBARDOUR_API Delivery : public IOProcessor
{
public:
	enum Role {
		/* main outputs - delivers out-of-place to port buffers, and cannot be removed */
		Main   = 0x1,
		/* send - delivers to port buffers, leaves input buffers untouched */
		Send   = 0x2,
		/* insert - delivers to port buffers and receives in-place from port buffers */
		Insert = 0x4,
		/* listen - internal send used only to deliver to control/monitor bus */
		Listen = 0x8,
		/* aux - internal send used to deliver to any bus, by user request */
		Aux    = 0x10,
		/* foldback - internal send used only to deliver to a personal monitor bus */
		Foldback = 0x20
	};

	static bool role_requires_output_ports (Role r) { return r == Main || r == Send || r == Insert; }

	bool does_routing() const { return true; }

	/* Delivery to an existing output */

	Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable>, boost::shared_ptr<MuteMaster> mm, const std::string& name, Role);

	/* Delivery to a new output owned by this object */

	Delivery (Session& s, boost::shared_ptr<Pannable>, boost::shared_ptr<MuteMaster> mm, const std::string& name, Role);
	~Delivery ();

	bool set_name (const std::string& name);
	std::string display_name() const;

	Role role() const { return _role; }
	bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
	bool configure_io (ChanCount in, ChanCount out);

	void run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool);

	/* supplemental method used with MIDI */

	void flush_buffers (samplecnt_t nframes);
	void no_outs_cuz_we_no_monitor(bool);
	void non_realtime_transport_stop (samplepos_t now, bool flush);
	void realtime_locate (bool);

	BufferSet& output_buffers() { return *_output_buffers; }

	PBD::Signal0<void> MuteChange;

	int set_state (const XMLNode&, int version);

	/* Panning */

	static int  disable_panners (void);
	static void reset_panners ();

	boost::shared_ptr<PannerShell> panner_shell() const { return _panshell; }
	boost::shared_ptr<Panner> panner() const;

	void unpan ();
	void reset_panner ();
	void defer_pan_reset ();
	void allow_pan_reset ();

	uint32_t pans_required() const { return _configured_input.n_audio(); }
	virtual uint32_t pan_outs() const;

protected:
	XMLNode& state ();

	Role        _role;
	BufferSet*  _output_buffers;
	gain_t      _current_gain;
	boost::shared_ptr<PannerShell> _panshell;

#ifdef MIXBUS
public: /* expose target_gain to mixbus processor Route::process_output_buffers */
#endif
	gain_t target_gain ();

private:
	bool        _no_outs_cuz_we_no_monitor;
	boost::shared_ptr<MuteMaster> _mute_master;

	static bool panners_legal;
	static PBD::Signal0<void> PannersLegal;

	void panners_became_legal ();
	PBD::ScopedConnection panner_legal_c;
	void output_changed (IOChange, void*);

	bool _no_panner_reset;
};


} // namespace ARDOUR

#endif // __ardour__h__