Optimize automation-event process splitting
[ardour.git] / libs / ardour / ardour / disk_writer.h
1 /*
2     Copyright (C) 2009-2016 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
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/i18n.h"
27
28 #include "ardour/disk_io.h"
29 #include "ardour/midi_buffer.h"
30
31 namespace ARDOUR
32 {
33
34 class AudioFileSource;
35 class SMFSource;
36 class MidiSource;
37
38 class LIBARDOUR_API DiskWriter : public DiskIOProcessor
39 {
40 public:
41         DiskWriter (Session&, std::string const & name, DiskIOProcessor::Flag f = DiskIOProcessor::Flag (0));
42         ~DiskWriter ();
43
44         bool set_name (std::string const & str);
45         std::string display_name() const { return std::string (_("recorder")); }
46
47         bool               recordable()  const { return _flags & Recordable; }
48
49         static samplecnt_t chunk_samples() { return _chunk_samples; }
50         static samplecnt_t default_chunk_samples ();
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*/, double speed, pframes_t /*nframes*/, bool /*result_required*/);
54
55         void non_realtime_locate (samplepos_t);
56         void realtime_handle_transport_stopped ();
57
58         int set_state (const XMLNode&, int version);
59
60         virtual bool set_write_source_name (const std::string& str);
61         std::string  write_source_name () const {
62                 if (_write_source_name.empty()) {
63                         return name();
64                 } else {
65                         return _write_source_name;
66                 }
67         }
68
69         boost::shared_ptr<AudioFileSource> audio_write_source (uint32_t n=0) {
70                 boost::shared_ptr<ChannelList> c = channels.reader();
71                 if (n < c->size()) {
72                         return (*c)[n]->write_source;
73                 }
74
75                 return boost::shared_ptr<AudioFileSource>();
76         }
77
78         boost::shared_ptr<SMFSource> midi_write_source () { return _midi_write_source; }
79
80         virtual std::string steal_write_source_name ();
81         int  use_new_write_source (DataType, uint32_t n = 0);
82         void reset_write_sources (bool, bool force = false);
83
84         AlignStyle alignment_style() const { return _alignment_style; }
85         void       set_align_style (AlignStyle, bool force=false);
86
87         PBD::Signal0<void> AlignmentStyleChanged;
88
89         bool configure_io (ChanCount in, ChanCount out);
90
91         std::list<boost::shared_ptr<Source> >& last_capture_sources () { return _last_capture_sources; }
92
93         bool         record_enabled() const { return g_atomic_int_get (const_cast<gint*>(&_record_enabled)); }
94         bool         record_safe () const { return g_atomic_int_get (const_cast<gint*>(&_record_safe)); }
95         virtual void set_record_enabled (bool yn);
96         virtual void set_record_safe (bool yn);
97
98         bool destructive() const { return _flags & Destructive; }
99
100         /** @return Start position of currently-running capture (in session samples) */
101         samplepos_t current_capture_start() const { return capture_start_sample; }
102         samplepos_t current_capture_end()   const { return capture_start_sample + capture_captured; }
103         samplepos_t get_capture_start_sample (uint32_t n = 0) const;
104         samplecnt_t get_captured_samples (uint32_t n = 0) const;
105
106         float buffer_load() const;
107
108         virtual void request_input_monitoring (bool) {}
109         virtual void ensure_input_monitoring (bool) {}
110
111         int seek (samplepos_t sample, bool complete_refill);
112
113         static PBD::Signal0<void> Overrun;
114
115         void set_note_mode (NoteMode m);
116
117         /** Emitted when some MIDI data has been received for recording.
118          *  Parameter is the source that it is destined for.
119          *  A caller can get a copy of the data with get_gui_feed_buffer ()
120          */
121         PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;
122
123         PBD::Signal0<void> RecordEnableChanged;
124         PBD::Signal0<void> RecordSafeChanged;
125
126         void transport_looped (samplepos_t transport_sample);
127         void transport_stopped_wallclock (struct tm&, time_t, bool abort);
128
129         void adjust_buffering ();
130
131         boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
132
133 protected:
134         friend class Track;
135
136         struct WriterChannelInfo : public DiskIOProcessor::ChannelInfo {
137                 WriterChannelInfo (samplecnt_t buffer_size)
138                         : DiskIOProcessor::ChannelInfo (buffer_size)
139                 {
140                         resize (buffer_size);
141                 }
142                 void resize (samplecnt_t);
143         };
144
145         virtual XMLNode& state ();
146
147         int do_flush (RunContext context, bool force = false);
148
149         void get_input_sources ();
150         void prepare_record_status (samplepos_t /*capture_start_sample*/);
151         void set_align_style_from_io();
152         void setup_destructive_playlist ();
153         void use_destructive_playlist ();
154
155         int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
156
157         void engage_record_enable ();
158         void disengage_record_enable ();
159         void engage_record_safe ();
160         void disengage_record_safe ();
161
162         bool prep_record_enable ();
163         bool prep_record_disable ();
164
165         void calculate_record_range (
166                 Evoral::OverlapType ot, samplepos_t transport_sample, samplecnt_t nframes,
167                 samplecnt_t& rec_nframes, samplecnt_t& rec_offset
168                 );
169
170         mutable Glib::Threads::Mutex capture_info_lock;
171         CaptureInfos capture_info;
172
173 private:
174         gint         _record_enabled;
175         gint         _record_safe;
176         samplepos_t  capture_start_sample;
177         samplecnt_t  capture_captured;
178         bool         was_recording;
179         samplepos_t  first_recordable_sample;
180         samplepos_t  last_recordable_sample;
181         int          last_possibly_recording;
182         AlignStyle   _alignment_style;
183         std::string  _write_source_name;
184
185         boost::shared_ptr<SMFSource> _midi_write_source;
186
187         std::list<boost::shared_ptr<Source> > _last_capture_sources;
188         std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
189
190         static samplecnt_t _chunk_samples;
191
192         NoteMode           _note_mode;
193         volatile gint      _samples_pending_write;
194         volatile gint      _num_captured_loops;
195         samplepos_t        _accumulated_capture_offset;
196
197         /** A buffer that we use to put newly-arrived MIDI data in for
198             the GUI to read (so that it can update itself).
199         */
200         MidiBuffer                   _gui_feed_buffer;
201         mutable Glib::Threads::Mutex _gui_feed_buffer_mutex;
202
203         void check_record_status (samplepos_t transport_sample, double speed, bool can_record);
204         void finish_capture (boost::shared_ptr<ChannelList> c);
205 };
206
207 } // namespace
208
209 #endif /* __ardour_disk_writer_h__ */