summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/delivery.h
blob: 9224d2755c6bb11e5bd2f4785aa2e7f0eee58e58 (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
/*
    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.
*/

#ifndef __ardour_delivery_h__
#define __ardour_delivery_h__

#include <string>
#include "ardour/types.h"
#include "ardour/chan_count.h"
#include "ardour/io_processor.h"

namespace ARDOUR {

class BufferSet;
class IO;
class MuteMaster;
class Panner;

class 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
	};

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

	/* Delivery to an existing output */

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

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

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

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

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

	void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes);

	/* supplemental method used with MIDI */

	void flush (nframes_t nframes, nframes64_t time);
	void transport_stopped ();

	void no_outs_cuz_we_no_monitor(bool);

	void set_solo_level (int32_t sl) { _solo_level = sl; }
	void set_solo_isolated (bool yn) { _solo_isolated = yn; }

	void cycle_start (nframes_t);
	void increment_output_offset (nframes_t);
	void transport_stopped (sframes_t frame);

	BufferSet& output_buffers() { return *_output_buffers; }

	sigc::signal<void> MuteChange;

	static sigc::signal<void,nframes_t> CycleStart;

	XMLNode& state (bool full);
	int set_state (const XMLNode&);

	/* Panning */

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

	boost::shared_ptr<Panner> panner() const { return _panner; }

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

	uint32_t pans_required() const { return _configured_input.n_audio(); }
	void start_pan_touch (uint32_t which);
	void end_pan_touch (uint32_t which);

  protected:
	Role        _role;
	BufferSet*  _output_buffers;
	gain_t      _current_gain;
	nframes_t   _output_offset;
	bool        _no_outs_cuz_we_no_monitor;
	uint32_t    _solo_level;
	bool        _solo_isolated;
	boost::shared_ptr<MuteMaster> _mute_master;
	bool         no_panner_reset;
	boost::shared_ptr<Panner> _panner;

	static bool panners_legal;
	static sigc::signal<int>            PannersLegal;

	int panners_became_legal ();
	sigc::connection panner_legal_c;
	void output_changed (IOChange, void*);

	gain_t target_gain ();
};


} // namespace ARDOUR

#endif // __ardour__h__