1 /*
2  * Copyright (C) 2017-2018 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2017 Paul Davis <paul@linuxaudiosystems.com>
4  *
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.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __ardour_disk_writer_h__
21 #define __ardour_disk_writer_h__
22 
23 #include <list>
24 #include <vector>
25 
26 #include "pbd/g_atomic_compat.h"
27 
28 #include "ardour/disk_io.h"
29 #include "ardour/midi_buffer.h"
30 
31 namespace ARDOUR
32 {
33 class AudioFileSource;
34 class SMFSource;
35 class MidiSource;
36 
37 class LIBARDOUR_API DiskWriter : public DiskIOProcessor
38 {
39 public:
40 	DiskWriter (Session&, Track&, std::string const& name,
41 	            DiskIOProcessor::Flag f = DiskIOProcessor::Flag (0));
42 	~DiskWriter ();
43 
44 	bool set_name (std::string const& str);
45 	std::string display_name () const;
46 
recordable()47 	bool recordable () const { return _flags & Recordable; }
48 
chunk_samples()49 	static samplecnt_t chunk_samples () { return _chunk_samples; }
50 	static samplecnt_t default_chunk_samples ();
set_chunk_samples(samplecnt_t n)51 	static void        set_chunk_samples (samplecnt_t n) { _chunk_samples = n; }
52 
53 	void run (BufferSet& /*bufs*/, samplepos_t /*start_sample*/, samplepos_t /*end_sample*/,
54 	          double speed, pframes_t /*nframes*/, bool /*result_required*/);
55 
56 	void non_realtime_locate (samplepos_t);
57 	void realtime_handle_transport_stopped ();
58 
59 	int set_state (const XMLNode&, int version);
60 
61 	bool set_write_source_name (const std::string& str);
62 
63 	std::string write_source_name () const;
64 
65 	boost::shared_ptr<AudioFileSource> audio_write_source (uint32_t n = 0) {
66 		boost::shared_ptr<ChannelList> c = channels.reader ();
67 		if (n < c->size ()) {
68 			return (*c)[n]->write_source;
69 		}
70 		return boost::shared_ptr<AudioFileSource> ();
71 	}
72 
midi_write_source()73 	boost::shared_ptr<SMFSource> midi_write_source () const { return _midi_write_source; }
74 
75 	std::string steal_write_source_name ();
76 	int use_new_write_source (DataType, uint32_t n = 0);
77 	void reset_write_sources (bool, bool force = false);
78 
alignment_style()79 	AlignStyle alignment_style () const { return _alignment_style; }
80 	void       set_align_style (AlignStyle, bool force = false);
81 
82 	PBD::Signal0<void> AlignmentStyleChanged;
83 
84 	bool configure_io (ChanCount in, ChanCount out);
85 
last_capture_sources()86 	std::list<boost::shared_ptr<Source> >& last_capture_sources () { return _last_capture_sources; }
87 
record_enabled()88 	bool record_enabled () const { return g_atomic_int_get (&_record_enabled); }
record_safe()89 	bool record_safe () const { return g_atomic_int_get (&_record_safe); }
90 
91 	void set_record_enabled (bool yn);
92 	void set_record_safe (bool yn);
93 	void mark_capture_xrun ();
94 
95 	/** @return Start position of currently-running capture (in session samples) */
current_capture_start()96 	samplepos_t current_capture_start () const { return _capture_start_sample; }
current_capture_end()97 	samplepos_t current_capture_end () const { return _capture_start_sample + _capture_captured; }
98 	samplepos_t get_capture_start_sample (uint32_t n = 0) const;
99 	samplecnt_t get_captured_samples (uint32_t n = 0) const;
100 
101 	float buffer_load () const;
102 
103 	int seek (samplepos_t sample, bool complete_refill);
104 
105 	static PBD::Signal0<void> Overrun;
106 
107 	void set_note_mode (NoteMode m);
108 
109 	/** Emitted when some MIDI data has been received for recording.
110 	 *  Parameter is the source that it is destined for.
111 	 *  A caller can get a copy of the data with get_gui_feed_buffer ()
112 	 */
113 	PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;
114 
115 	PBD::Signal0<void> RecordEnableChanged;
116 	PBD::Signal0<void> RecordSafeChanged;
117 
118 	void transport_looped (samplepos_t transport_sample);
119 	void transport_stopped_wallclock (struct tm&, time_t, bool abort);
120 
121 	void adjust_buffering ();
122 
123 	boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
124 
125 protected:
126 	friend class Track;
127 
128 	struct WriterChannelInfo : public DiskIOProcessor::ChannelInfo {
WriterChannelInfoWriterChannelInfo129 		WriterChannelInfo (samplecnt_t buffer_size)
130 		        : DiskIOProcessor::ChannelInfo (buffer_size)
131 		{
132 			resize (buffer_size);
133 		}
134 		void resize (samplecnt_t);
135 	};
136 
137 	virtual XMLNode& state ();
138 
139 	int use_playlist (DataType, boost::shared_ptr<Playlist>);
140 
141 	int do_flush (RunContext context, bool force = false);
142 
143 	void configuration_changed ();
144 
145 private:
146 	static samplecnt_t _chunk_samples;
147 
148 	void prepare_record_status (samplepos_t /*capture_start_sample*/);
149 
150 	int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
151 
152 	void engage_record_enable ();
153 	void disengage_record_enable ();
154 	void engage_record_safe ();
155 	void disengage_record_safe ();
156 
157 	bool prep_record_enable ();
158 	bool prep_record_disable ();
159 
160 	void calculate_record_range (Evoral::OverlapType ot, samplepos_t transport_sample,
161 	                             samplecnt_t nframes, samplecnt_t& rec_nframes,
162 	                             samplecnt_t& rec_offset);
163 
164 	void check_record_status (samplepos_t transport_sample, double speed, bool can_record);
165 	void finish_capture (boost::shared_ptr<ChannelList> c);
166 
167 	void loop (samplepos_t);
168 
169 	CaptureInfos                 capture_info;
170 	mutable Glib::Threads::Mutex capture_info_lock;
171 
172 	samplepos_t   _capture_start_sample;
173 	samplecnt_t   _capture_captured;
174 	bool          _was_recording;
175 	bool          _xrun_flag;
176 	XrunPositions _xruns;
177 	samplepos_t   _first_recordable_sample;
178 	samplepos_t   _last_recordable_sample;
179 	int           _last_possibly_recording;
180 	AlignStyle    _alignment_style;
181 	std::string   _write_source_name;
182 	NoteMode      _note_mode;
183 	samplepos_t   _accumulated_capture_offset;
184 
185 	bool          _transport_looped;
186 	samplepos_t   _transport_loop_sample;
187 
188 	GATOMIC_QUAL gint _record_enabled;
189 	GATOMIC_QUAL gint _record_safe;
190 	GATOMIC_QUAL gint _samples_pending_write;
191 	GATOMIC_QUAL gint _num_captured_loops;
192 
193 	boost::shared_ptr<SMFSource> _midi_write_source;
194 
195 	std::list<boost::shared_ptr<Source> >            _last_capture_sources;
196 	std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
197 
198 	/** A buffer that we use to put newly-arrived MIDI data in for
199 	 * the GUI to read (so that it can update itself).
200 	 */
201 	MidiBuffer                   _gui_feed_buffer;
202 	mutable Glib::Threads::Mutex _gui_feed_buffer_mutex;
203 };
204 
205 } // namespace
206 
207 #endif /* __ardour_disk_writer_h__ */
208