diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2017-03-16 17:26:53 +0100 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2017-09-18 11:40:52 -0400 |
commit | 94604c6979be790a072c9d76566250a3aadf6e79 (patch) | |
tree | cd0b071ff702d7b9ebafd194f1521fec5825a5ad /libs/ardour/ardour | |
parent | f8ef82fceb6dfa8900f29871f706cced7eda55f5 (diff) |
merge almost all audio & midi diskstream code, redistribute between DiskIOProcessor, DiskReader,DiskWriter; compile and link
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/disk_io.h | 76 | ||||
-rw-r--r-- | libs/ardour/ardour/disk_reader.h | 39 | ||||
-rw-r--r-- | libs/ardour/ardour/disk_writer.h | 74 |
3 files changed, 114 insertions, 75 deletions
diff --git a/libs/ardour/ardour/disk_io.h b/libs/ardour/ardour/disk_io.h index d1fa1e7d66..dd775cbe84 100644 --- a/libs/ardour/ardour/disk_io.h +++ b/libs/ardour/ardour/disk_io.h @@ -32,9 +32,16 @@ namespace ARDOUR { -class Session; -class Route; +class AudioFileSource; +class AudioPlaylist; class Location; +class MidiPlaylist; +class Playlist; +class Route; +class Route; +class Session; + +template<typename T> class MidiRingBuffer; class LIBARDOUR_API DiskIOProcessor : public Processor { @@ -50,8 +57,14 @@ class LIBARDOUR_API DiskIOProcessor : public Processor DiskIOProcessor (Session&, const std::string& name, Flag f); + void set_route (boost::shared_ptr<Route>); + static void set_buffering_parameters (BufferingPreset bp); + int set_block_size (pframes_t); + bool configure_io (ChanCount in, ChanCount out); + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); + /** @return A number between 0 and 1, where 0 indicates that the playback buffer * is dry (ie the disk subsystem could not keep up) and 1 indicates that the * buffer is full. @@ -68,7 +81,7 @@ class LIBARDOUR_API DiskIOProcessor : public Processor bool reversed() const { return _actual_speed < 0.0f; } double speed() const { return _visible_speed; } - ChanCount n_channels() { return _n_channels; } + virtual void non_realtime_locate (framepos_t); void non_realtime_set_speed (); bool realtime_set_speed (double sp, bool global); @@ -94,14 +107,24 @@ class LIBARDOUR_API DiskIOProcessor : public Processor bool need_butler() const { return _need_butler; } + boost::shared_ptr<Playlist> get_playlist (DataType dt) const { return _playlists[dt]; } + boost::shared_ptr<MidiPlaylist> midi_playlist() const; + boost::shared_ptr<AudioPlaylist> audio_playlist() const; + + virtual void playlist_modified () {} + virtual int use_playlist (DataType, boost::shared_ptr<Playlist>); + virtual int use_new_playlist (DataType); + virtual int use_copy_playlist (DataType); + + PBD::Signal1<void,DataType> PlaylistChanged; + protected: friend class Auditioner; virtual int seek (framepos_t which_sample, bool complete_refill = false) = 0; protected: Flag _flags; - uint32_t i_am_the_modifier; - ChanCount _n_channels; + uint32_t i_am_the_modifier; double _visible_speed; double _actual_speed; double _speed; @@ -115,6 +138,9 @@ class LIBARDOUR_API DiskIOProcessor : public Processor framecnt_t wrap_buffer_size; framecnt_t speed_buffer_size; bool _need_butler; + boost::shared_ptr<Route> _route; + + void init (); Glib::Threads::Mutex state_lock; @@ -124,22 +150,24 @@ class LIBARDOUR_API DiskIOProcessor : public Processor framecnt_t& write_chunk_size, framecnt_t& write_buffer_size); - virtual void allocate_temporary_buffers () = 0; + enum TransitionType { + CaptureStart = 0, + CaptureEnd + }; + + struct CaptureTransition { + TransitionType type; + framepos_t capture_val; ///< The start or end file frame position + }; /** Information about one audio channel, playback or capture * (depending on the derived class) */ struct ChannelInfo : public boost::noncopyable { - ChannelInfo (framecnt_t buffer_size, - framecnt_t speed_buffer_size, - framecnt_t wrap_buffer_size); + ChannelInfo (framecnt_t buffer_size); ~ChannelInfo (); - Sample *wrap_buffer; - Sample *speed_buffer; - Sample *current_buffer; - /** A ringbuffer for data to be played back, written to in the butler thread, read from in the process thread. */ @@ -149,7 +177,13 @@ class LIBARDOUR_API DiskIOProcessor : public Processor Sample* scrub_forward_buffer; Sample* scrub_reverse_buffer; - PBD::RingBufferNPT<Sample>::rw_vector read_vector; + PBD::RingBufferNPT<Sample>::rw_vector rw_vector; + + /* used only by capture */ + boost::shared_ptr<AudioFileSource> write_source; + PBD::RingBufferNPT<CaptureTransition> * capture_transition_buf; + // the following are used in the butler thread only + framecnt_t curr_capture_cnt; void resize (framecnt_t); }; @@ -162,6 +196,20 @@ class LIBARDOUR_API DiskIOProcessor : public Processor CubicInterpolation interpolation; + boost::shared_ptr<Playlist> _playlists[DataType::num_types]; + PBD::ScopedConnectionList playlist_connections; + + virtual void playlist_changed (const PBD::PropertyChange&) {} + virtual void playlist_deleted (boost::weak_ptr<Playlist>); + virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool) {} + int find_and_use_playlist (DataType, std::string const &); + + /* The MIDI stuff */ + + MidiRingBuffer<framepos_t>* _midi_buf; + gint _frames_written_to_ringbuffer; + gint _frames_read_from_ringbuffer; + CubicMidiInterpolation midi_interpolation; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/disk_reader.h b/libs/ardour/ardour/disk_reader.h index 6a50594dc4..7b076ab23f 100644 --- a/libs/ardour/ardour/disk_reader.h +++ b/libs/ardour/ardour/disk_reader.h @@ -44,12 +44,8 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor static void set_chunk_frames (framecnt_t n) { _chunk_frames = n; } void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double speed, pframes_t /*nframes*/, bool /*result_required*/); - int set_block_size (pframes_t); - bool configure_io (ChanCount in, ChanCount out); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) = 0; void realtime_handle_transport_stopped (); void realtime_locate (); - void non_realtime_locate (framepos_t); int overwrite_existing_buffers (); void set_pending_overwrite (bool yn); @@ -59,16 +55,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor virtual XMLNode& state (bool full); int set_state (const XMLNode&, int version); - boost::shared_ptr<Playlist> get_playlist (DataType dt) const { return _playlists[dt]; } - boost::shared_ptr<MidiPlaylist> midi_playlist() const; - boost::shared_ptr<AudioPlaylist> audio_playlist() const; - - virtual void playlist_modified (); - virtual int use_playlist (DataType, boost::shared_ptr<Playlist>); - virtual int use_new_playlist (DataType); - virtual int use_copy_playlist (DataType); - - PBD::Signal1<void,DataType> PlaylistChanged; PBD::Signal0<void> AlignmentStyleChanged; float buffer_load() const; @@ -93,8 +79,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor bool pending_overwrite () const { return _pending_overwrite; } - virtual int find_and_use_playlist (DataType, std::string const &); - // Working buffers for do_refill (butler thread) static void allocate_working_buffers(); static void free_working_buffers(); @@ -104,19 +88,19 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor int can_internal_playback_seek (framecnt_t distance); int seek (framepos_t frame, bool complete_refill = false); - PBD::Signal0<void> Underrun; - - protected: - boost::shared_ptr<Playlist> _playlists[DataType::num_types]; + static PBD::Signal0<void> Underrun; - virtual void playlist_changed (const PBD::PropertyChange&); - virtual void playlist_deleted (boost::weak_ptr<Playlist>); - virtual void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool); + void playlist_modified (); + protected: void reset_tracker (); void resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time); boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const; + void playlist_changed (const PBD::PropertyChange&); + int use_playlist (DataType, boost::shared_ptr<Playlist>); + void playlist_ranges_moved (std::list< Evoral::RangeMove<framepos_t> > const &, bool); + private: /** The number of frames by which this diskstream's output should be delayed with respect to the transport frame. This is used for latency compensation. @@ -133,8 +117,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor framepos_t playback_sample; MonitorChoice _monitoring_choice; - PBD::ScopedConnectionList playlist_connections; - int _do_refill_with_alloc (bool partial_fill); static framecnt_t _chunk_frames; @@ -142,17 +124,11 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor /* The MIDI stuff */ - MidiRingBuffer<framepos_t>* _midi_buf; - /** A buffer that we use to put newly-arrived MIDI data in for the GUI to read (so that it can update itself). */ MidiBuffer _gui_feed_buffer; mutable Glib::Threads::Mutex _gui_feed_buffer_mutex; - CubicMidiInterpolation midi_interpolation; - gint _frames_written_to_ringbuffer; - gint _frames_read_from_ringbuffer; - int audio_read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, framepos_t& start, framecnt_t cnt, @@ -169,7 +145,6 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor int internal_playback_seek (framecnt_t distance); frameoffset_t calculate_playback_distance (pframes_t); - void allocate_temporary_buffers(); void get_playback (MidiBuffer& dst, framecnt_t nframes); void flush_playback (framepos_t start, framepos_t end); }; diff --git a/libs/ardour/ardour/disk_writer.h b/libs/ardour/ardour/disk_writer.h index 984a84a938..3eed3c6d99 100644 --- a/libs/ardour/ardour/disk_writer.h +++ b/libs/ardour/ardour/disk_writer.h @@ -21,12 +21,16 @@ #define __ardour_disk_writer_h__ #include <list> +#include <vector> #include "ardour/disk_io.h" namespace ARDOUR { +class AudioFileSource; +class SMFSource; + class LIBARDOUR_API DiskWriter : public DiskIOProcessor { public: @@ -34,18 +38,14 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor virtual bool set_write_source_name (const std::string& str); + bool recordable() const { return _flags & Recordable; } + static framecnt_t chunk_frames() { return _chunk_frames; } static framecnt_t default_chunk_frames (); static void set_chunk_frames (framecnt_t n) { _chunk_frames = n; } void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double speed, pframes_t /*nframes*/, bool /*result_required*/); - void silence (framecnt_t /*nframes*/, framepos_t /*start_frame*/); - bool configure_io (ChanCount in, ChanCount out); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) = 0; - ChanCount input_streams () const; - ChanCount output_streams() const; - void realtime_handle_transport_stopped (); - void realtime_locate (); + void non_realtime_locate (framepos_t); virtual XMLNode& state (bool full); int set_state (const XMLNode&, int version); @@ -60,6 +60,17 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor } } + boost::shared_ptr<AudioFileSource> audio_write_source (uint32_t n=0) { + boost::shared_ptr<ChannelList> c = channels.reader(); + if (n < c->size()) { + return (*c)[n]->write_source; + } + + return boost::shared_ptr<AudioFileSource>(); + } + + boost::shared_ptr<SMFSource> midi_write_source () { return _midi_write_source; } + virtual std::string steal_write_source_name () { return std::string(); } AlignStyle alignment_style() const { return _alignment_style; } @@ -80,9 +91,9 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor virtual void set_record_safe (bool yn) = 0; bool destructive() const { return _flags & Destructive; } - virtual int set_destructive (bool /*yn*/) { return -1; } - virtual int set_non_layered (bool /*yn*/) { return -1; } - virtual bool can_become_destructive (bool& /*requires_bounce*/) const { return false; } + int set_destructive (bool yn); + int set_non_layered (bool yn); + bool can_become_destructive (bool& requires_bounce) const; /** @return Start position of currently-running capture (in session frames) */ framepos_t current_capture_start() const { return capture_start_frame; } @@ -98,23 +109,29 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor framecnt_t capture_offset() const { return _capture_offset; } virtual void set_capture_offset (); + static PBD::Signal0<void> Overrun; + + PBD::Signal0<void> RecordEnableChanged; + PBD::Signal0<void> RecordSafeChanged; + protected: virtual int do_flush (RunContext context, bool force = false) = 0; - virtual void check_record_status (framepos_t transport_frame, bool can_record); - virtual void prepare_record_status (framepos_t /*capture_start_frame*/) {} - virtual void set_align_style_from_io() {} - virtual void setup_destructive_playlist () {} - virtual void use_destructive_playlist () {} - virtual void prepare_to_stop (framepos_t transport_pos, framepos_t audible_frame); + void get_input_sources (); + void check_record_status (framepos_t transport_frame, bool can_record); + void prepare_record_status (framepos_t /*capture_start_frame*/); + void set_align_style_from_io(); + void setup_destructive_playlist (); + void use_destructive_playlist (); + void prepare_to_stop (framepos_t transport_pos, framepos_t audible_frame); void engage_record_enable (); void disengage_record_enable (); void engage_record_safe (); void disengage_record_safe (); - virtual bool prep_record_enable () = 0; - virtual bool prep_record_disable () = 0; + bool prep_record_enable (); + bool prep_record_disable (); void calculate_record_range ( Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes, @@ -133,16 +150,6 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor mutable Glib::Threads::Mutex capture_info_lock; private: - enum TransitionType { - CaptureStart = 0, - CaptureEnd - }; - - struct CaptureTransition { - TransitionType type; - framepos_t capture_val; ///< The start or end file frame position - }; - framecnt_t _input_latency; gint _record_enabled; gint _record_safe; @@ -157,10 +164,19 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor AlignStyle _alignment_style; AlignChoice _alignment_choice; std::string _write_source_name; + boost::shared_ptr<SMFSource> _midi_write_source; std::list<boost::shared_ptr<Source> > _last_capture_sources; - + std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources; + static framecnt_t _chunk_frames; + + NoteMode _note_mode; + volatile gint _frames_pending_write; + volatile gint _num_captured_loops; + framepos_t _accumulated_capture_offset; + + void finish_capture (boost::shared_ptr<ChannelList> c); }; } // namespace |