Ardour  9.2-79-gba93f2fe52
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*/);
71 
72  LIBARDOUR_API int set_state (const XMLNode&, int version);
73 
75 
76  LIBARDOUR_API float buffer_load () const;
77 
78  LIBARDOUR_API void move_processor_automation (std::weak_ptr<Processor>, std::list<Temporal::RangeMove> const&);
79 
80  /* called by the Butler in a non-realtime context as part of its normal
81  * buffer refill loop (not due to transport-mechanism requests like
82  * locate)
83  */
85 
87  int do_refill_with_alloc (bool partial_fill, bool reverse);
88 
90 
91  /* Working buffers for do_refill (butler thread) */
94 
96 
99  LIBARDOUR_API int seek (samplepos_t sample, bool complete_refill = false);
100 
102 
105 
107 
109 
110  /* inc/dec variants MUST be called as part of the process call tree, before any
111  * disk readers are invoked. We use it when the session needs the
112  * transport (and thus effective read position for DiskReaders) to keep
113  * advancing as part of syncing up with a transport master, but we
114  * don't want any actual disk output yet because we are still not
115  * synced.
116  */
120  {
121  return _no_disk_output.load ();
122  }
124  LIBARDOUR_API static void alloc_loop_declick (samplecnt_t sample_rate);
125 
126 protected:
127  friend class Track;
128  friend class MidiTrack;
129 
132  : DiskIOProcessor::ChannelInfo (buffer_size)
133  , pre_loop_buffer (0)
135  , initialized (false)
136  {
137  resize (buffer_size);
138  }
139 
141  {
142  delete[] pre_loop_buffer;
143  }
144 
147 
151  };
152 
154 
156 
157  LIBARDOUR_API int use_playlist (DataType, std::shared_ptr<Playlist>);
158  LIBARDOUR_API void playlist_ranges_moved (std::list<Temporal::RangeMove> const&, bool);
159 
160  LIBARDOUR_API int add_channel_to (std::shared_ptr<ChannelList>, uint32_t how_many);
161 
163  {
164  public:
165  DeclickAmp (samplecnt_t sample_rate);
166 
167  void apply_gain (AudioBuffer& buf, samplecnt_t n_samples, const float target, sampleoffset_t buffer_offset = 0);
168 
169  float gain () const
170  {
171  return _g;
172  }
173  void set_gain (float g)
174  {
175  _g = g;
176  }
177 
178  private:
179  float _a;
180  float _l;
181  float _g;
182  };
183 
184  class Declicker
185  {
186  public:
189 
190  void alloc (samplecnt_t sr, bool fadein, bool linear);
191 
193  void reset (samplepos_t start, samplepos_t end, bool fadein, samplecnt_t sr);
194 
199  };
200 
201 private:
208 
209  mutable std::atomic<OverwriteReason> _pending_overwrite;
210 
216  std::optional<bool> _last_read_reversed;
217  std::optional<bool> _last_read_loop;
218 
220 
221  static std::atomic<int> _no_disk_output;
222 
226 
228  Sample* mixdown_buffer,
229  float* gain_buffer,
231  ReaderChannelInfo* rci,
232  int channel,
233  bool reversed);
234 
235  static thread_local Sample* _sum_buffer;
236  static thread_local Sample* _mixdown_buffer;
237  static thread_local gain_t* _gain_buffer;
238 
239  int refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed);
240  int refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed);
241 
243 
245 
246  void get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet&, double speed, samplecnt_t distance);
248 
250 
253 
256 
259 };
260 
261 } // namespace ARDOUR
262 
263 #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:216
bool declick_in_progress() const
static Declicker loop_declick_in
Definition: disk_reader.h:223
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:219
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:225
static Declicker loop_declick_out
Definition: disk_reader.h:224
void midi_chase(samplepos_t spos)
static bool no_disk_output()
Definition: disk_reader.h:119
static samplecnt_t chunk_samples()
Definition: disk_reader.h:51
DeclickAmp _declick_amp
Definition: disk_reader.h:211
void resolve_tracker(Evoral::EventSink< samplepos_t > &buffer, samplepos_t time)
void setup_preloop_buffer()
XMLNode & state() const
MidiNoteTracker _locate_tracker
Definition: disk_reader.h:215
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:235
PBD::Signal< void()> AlignmentStyleChanged
Definition: disk_reader.h:74
std::atomic< OverwriteReason > _pending_overwrite
Definition: disk_reader.h:209
static thread_local gain_t * _gain_buffer
Definition: disk_reader.h:237
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:101
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:212
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:203
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:214
void realtime_handle_transport_stopped()
float buffer_load() const
RTMidiBuffer * rt_midibuffer()
std::optional< bool > _last_read_loop
Definition: disk_reader.h:217
static thread_local Sample * _mixdown_buffer
Definition: disk_reader.h:236
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:206
samplepos_t last_refill_loop_start
Definition: disk_reader.h:254
samplepos_t file_sample[DataType::num_types]
Definition: disk_reader.h:207
samplepos_t overwrite_sample
Definition: disk_reader.h:202
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:204
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:221
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:131