Ardour  9.0-pre0-582-g084a23a80d
disk_reader.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017-2019 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_reader_h_
21 #define _ardour_disk_reader_h_
22 
23 #include <atomic>
24 
25 #include <optional>
26 
27 #include "evoral/Curve.h"
28 
29 #include "ardour/disk_io.h"
30 #include "ardour/midi_buffer.h"
32 
33 namespace ARDOUR
34 {
35 class Playlist;
36 class AudioPlaylist;
37 class MidiPlaylist;
38 
39 template <typename T> class MidiRingBuffer;
40 
41 class /*LIBARDOUR_API*/ DiskReader : public DiskIOProcessor
42 {
43 public:
46 
47  LIBARDOUR_API bool set_name (std::string const& str);
48 
49  LIBARDOUR_API std::string display_name () const;
50 
52  {
53  return _chunk_samples;
54  }
55 
57  {
58  _chunk_samples = n;
59  }
60 
62 
63  LIBARDOUR_API void run (BufferSet& /*bufs*/, samplepos_t /*start_sample*/, samplepos_t /*end_sample*/, double speed, pframes_t /*nframes*/, bool /*result_required*/);
69 
70  LIBARDOUR_API int set_state (const XMLNode&, int version);
71 
73 
74  LIBARDOUR_API float buffer_load () const;
75 
76  LIBARDOUR_API void move_processor_automation (std::weak_ptr<Processor>, std::list<Temporal::RangeMove> const&);
77 
78  /* called by the Butler in a non-realtime context as part of its normal
79  * buffer refill loop (not due to transport-mechanism requests like
80  * locate)
81  */
83 
85  int do_refill_with_alloc (bool partial_fill, bool reverse);
86 
88 
89  /* Working buffers for do_refill (butler thread) */
92 
94 
97  LIBARDOUR_API int seek (samplepos_t sample, bool complete_refill = false);
98 
100 
103 
105 
107 
108  /* inc/dec variants MUST be called as part of the process call tree, before any
109  * disk readers are invoked. We use it when the session needs the
110  * transport (and thus effective read position for DiskReaders) to keep
111  * advancing as part of syncing up with a transport master, but we
112  * don't want any actual disk output yet because we are still not
113  * synced.
114  */
118  {
119  return _no_disk_output.load ();
120  }
122  LIBARDOUR_API static void alloc_loop_declick (samplecnt_t sample_rate);
123 
124 protected:
125  friend class Track;
126  friend class MidiTrack;
127 
130  : DiskIOProcessor::ChannelInfo (buffer_size)
131  , pre_loop_buffer (0)
133  , initialized (false)
134  {
135  resize (buffer_size);
136  }
137 
139  {
140  delete[] pre_loop_buffer;
141  }
142 
145 
149  };
150 
152 
154 
155  LIBARDOUR_API int use_playlist (DataType, std::shared_ptr<Playlist>);
156  LIBARDOUR_API void playlist_ranges_moved (std::list<Temporal::RangeMove> const&, bool);
157 
158  LIBARDOUR_API int add_channel_to (std::shared_ptr<ChannelList>, uint32_t how_many);
159 
161  {
162  public:
163  DeclickAmp (samplecnt_t sample_rate);
164 
165  void apply_gain (AudioBuffer& buf, samplecnt_t n_samples, const float target, sampleoffset_t buffer_offset = 0);
166 
167  float gain () const
168  {
169  return _g;
170  }
171  void set_gain (float g)
172  {
173  _g = g;
174  }
175 
176  private:
177  float _a;
178  float _l;
179  float _g;
180  };
181 
182  class Declicker
183  {
184  public:
187 
188  void alloc (samplecnt_t sr, bool fadein, bool linear);
189 
191  void reset (samplepos_t start, samplepos_t end, bool fadein, samplecnt_t sr);
192 
197  };
198 
199 private:
206 
207  mutable std::atomic<OverwriteReason> _pending_overwrite;
208 
213  std::optional<bool> _last_read_reversed;
214  std::optional<bool> _last_read_loop;
215 
217 
218  static std::atomic<int> _no_disk_output;
219 
223 
225  Sample* mixdown_buffer,
226  float* gain_buffer,
228  ReaderChannelInfo* rci,
229  int channel,
230  bool reversed);
231 
232  static thread_local Sample* _sum_buffer;
233  static thread_local Sample* _mixdown_buffer;
234  static thread_local gain_t* _gain_buffer;
235 
236  int refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed);
237  int refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed);
238 
240 
242 
243  void get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet&, double speed, samplecnt_t distance);
245 
247 
250 
253 
256 };
257 
258 } // namespace ARDOUR
259 
260 #endif /* _ardour_disk_reader_h_ */
static const uint32_t num_types
Definition: data_type.h:61
DeclickAmp(samplecnt_t sample_rate)
void apply_gain(AudioBuffer &buf, samplecnt_t n_samples, const float target, sampleoffset_t buffer_offset=0)
void reset(samplepos_t start, samplepos_t end, bool fadein, samplecnt_t sr)
void alloc(samplecnt_t sr, bool fadein, bool linear)
void run(Sample *buf, samplepos_t start, samplepos_t end)
std::optional< bool > _last_read_reversed
Definition: disk_reader.h:213
bool declick_in_progress() const
static Declicker loop_declick_in
Definition: disk_reader.h:220
void maybe_xfade_loop(Sample *, samplepos_t read_start, samplepos_t read_end, ReaderChannelInfo *)
void internal_playback_seek(sampleoffset_t distance)
static samplecnt_t _chunk_samples
Definition: disk_reader.h:216
bool pending_overwrite() const
int set_state(const XMLNode &, int version)
DiskReader(Session &, Track &, std::string const &name, Temporal::TimeDomainProvider const &, DiskIOProcessor::Flag f=DiskIOProcessor::Flag(0))
static samplecnt_t loop_fade_length
Definition: disk_reader.h:222
static Declicker loop_declick_out
Definition: disk_reader.h:221
static bool no_disk_output()
Definition: disk_reader.h:117
static samplecnt_t chunk_samples()
Definition: disk_reader.h:51
DeclickAmp _declick_amp
Definition: disk_reader.h:209
void resolve_tracker(Evoral::EventSink< samplepos_t > &buffer, samplepos_t time)
void setup_preloop_buffer()
XMLNode & state() const
static void allocate_working_buffers()
bool overwrite_existing_audio()
void get_midi_playback(MidiBuffer &dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet &, double speed, samplecnt_t distance)
static thread_local Sample * _sum_buffer
Definition: disk_reader.h:232
PBD::Signal< void()> AlignmentStyleChanged
Definition: disk_reader.h:72
std::atomic< OverwriteReason > _pending_overwrite
Definition: disk_reader.h:207
static thread_local gain_t * _gain_buffer
Definition: disk_reader.h:234
int seek(samplepos_t sample, bool complete_refill=false)
static void set_chunk_samples(samplecnt_t n)
Definition: disk_reader.h:56
void configuration_changed()
void move_processor_automation(std::weak_ptr< Processor >, std::list< Temporal::RangeMove > const &)
void set_need_midi_catchup(bool)
bool set_name(std::string const &str)
std::string display_name() const
static PBD::Signal< void()> Underrun
Definition: disk_reader.h:99
int refill_audio(Sample *sum_buffer, Sample *mixdown_buffer, float *gain_buffer, samplecnt_t fill_level, bool reversed)
static void free_working_buffers()
static void alloc_loop_declick(samplecnt_t sample_rate)
static void inc_no_disk_output()
sampleoffset_t _declick_offs
Definition: disk_reader.h:210
sampleoffset_t calculate_playback_distance(pframes_t)
samplecnt_t audio_read(Sample *sum_buffer, Sample *mixdown_buffer, float *gain_buffer, samplepos_t &start, samplecnt_t cnt, ReaderChannelInfo *rci, int channel, bool reversed)
void set_pending_overwrite(OverwriteReason)
sampleoffset_t overwrite_offset
Definition: disk_reader.h:201
int do_refill_with_alloc(bool partial_fill, bool reverse)
int add_channel_to(std::shared_ptr< ChannelList >, uint32_t how_many)
static samplecnt_t default_chunk_samples()
MidiNoteTracker _tracker
Definition: disk_reader.h:212
void realtime_handle_transport_stopped()
float buffer_load() const
RTMidiBuffer * rt_midibuffer()
std::optional< bool > _last_read_loop
Definition: disk_reader.h:214
static thread_local Sample * _mixdown_buffer
Definition: disk_reader.h:233
static void reset_loop_declick(Location *, samplecnt_t sample_rate)
bool overwrite_existing_buffers()
bool overwrite_existing_midi()
void playlist_ranges_moved(std::list< Temporal::RangeMove > const &, bool)
IOChange input_change_pending
Definition: disk_reader.h:204
samplepos_t last_refill_loop_start
Definition: disk_reader.h:251
samplepos_t file_sample[DataType::num_types]
Definition: disk_reader.h:205
samplepos_t overwrite_sample
Definition: disk_reader.h:200
static void dec_no_disk_output()
void realtime_locate(bool)
int use_playlist(DataType, std::shared_ptr< Playlist >)
int refill(Sample *sum_buffer, Sample *mixdown_buffer, float *gain_buffer, samplecnt_t fill_level, bool reversed)
samplepos_t new_file_sample
Definition: disk_reader.h:202
void run(BufferSet &, samplepos_t, samplepos_t, double speed, pframes_t, bool)
bool can_internal_playback_seek(sampleoffset_t distance)
static std::atomic< int > _no_disk_output
Definition: disk_reader.h:218
void set_loop(Location *)
std::string name() const
Definition: xml++.h:114
#define LIBARDOUR_API
PBD::PropertyDescriptor< timepos_t > start
uint32_t pframes_t
Temporal::samplecnt_t samplecnt_t
Temporal::sampleoffset_t sampleoffset_t
Temporal::samplepos_t samplepos_t
DebugBits MidiRingBuffer
ReaderChannelInfo(samplecnt_t buffer_size, samplecnt_t preloop_size)
Definition: disk_reader.h:129