more DEBUG::Destruction messages
[ardour.git] / libs / ardour / ardour / disk_writer.h
index 984a84a938ef48b7e2b010fda1045489077af6ec..f85eb26f11db8cc385ab1a6b6462fc887f8c33e9 100644 (file)
 #define __ardour_disk_writer_h__
 
 #include <list>
+#include <vector>
+
+#include "pbd/i18n.h"
 
 #include "ardour/disk_io.h"
+#include "ardour/midi_buffer.h"
 
 namespace ARDOUR
 {
 
+class AudioFileSource;
+class SMFSource;
+class MidiSource;
+
 class LIBARDOUR_API DiskWriter : public DiskIOProcessor
 {
   public:
        DiskWriter (Session&, std::string const & name, DiskIOProcessor::Flag f = DiskIOProcessor::Flag (0));
+       ~DiskWriter ();
+
+       bool set_name (std::string const & str);
+       std::string display_name() const { return std::string (_("writer")); }
 
        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 non_realtime_locate (framepos_t);
        void realtime_handle_transport_stopped ();
-       void realtime_locate ();
 
        virtual XMLNode& state (bool full);
        int set_state (const XMLNode&, int version);
 
-       virtual int use_new_write_source (uint32_t n=0) = 0;
-
        std::string write_source_name () const {
                if (_write_source_name.empty()) {
                        return name();
@@ -60,7 +67,20 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
                }
        }
 
-       virtual std::string steal_write_source_name () { return std::string(); }
+       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 ();
+       int use_new_write_source (DataType, uint32_t n = 0);
+       void reset_write_sources (bool, bool force = false);
 
        AlignStyle  alignment_style() const { return _alignment_style; }
        AlignChoice alignment_choice() const { return _alignment_choice; }
@@ -72,17 +92,19 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
        void set_input_latency (framecnt_t);
        framecnt_t input_latency () const { return _input_latency; }
 
+       bool configure_io (ChanCount in, ChanCount out);
+
        std::list<boost::shared_ptr<Source> >& last_capture_sources () { return _last_capture_sources; }
 
        bool         record_enabled() const { return g_atomic_int_get (const_cast<gint*>(&_record_enabled)); }
        bool         record_safe () const { return g_atomic_int_get (const_cast<gint*>(&_record_safe)); }
-       virtual void set_record_enabled (bool yn) = 0;
-       virtual void set_record_safe (bool yn) = 0;
+       virtual void set_record_enabled (bool yn);
+       virtual void set_record_safe (bool yn);
 
        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,32 +120,52 @@ class LIBARDOUR_API DiskWriter : public DiskIOProcessor
        framecnt_t   capture_offset() const { return _capture_offset; }
        virtual void set_capture_offset ();
 
+       int seek (framepos_t frame, bool complete_refill);
+
+       static PBD::Signal0<void> Overrun;
+
+       void set_note_mode (NoteMode m);
+
+       /** Emitted when some MIDI data has been received for recording.
+        *  Parameter is the source that it is destined for.
+        *  A caller can get a copy of the data with get_gui_feed_buffer ()
+        */
+       PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;
+
+       PBD::Signal0<void> RecordEnableChanged;
+       PBD::Signal0<void> RecordSafeChanged;
+
+       void check_record_status (framepos_t transport_frame, bool can_record);
+
+       void transport_looped (framepos_t transport_frame);
+       void transport_stopped_wallclock (struct tm&, time_t, bool abort);
+
+       void adjust_buffering ();
+
   protected:
-       virtual int do_flush (RunContext context, bool force = false) = 0;
+       friend class Track;
+       int do_flush (RunContext context, bool force = false);
 
-       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 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,
                framecnt_t& rec_nframes, framecnt_t& rec_offset
                );
 
-       static framecnt_t disk_read_chunk_frames;
-       static framecnt_t disk_write_chunk_frames;
-
        struct CaptureInfo {
                framepos_t start;
                framecnt_t frames;
@@ -133,16 +175,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 +189,25 @@ 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;
+
+       /** 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;
+
+       void finish_capture (boost::shared_ptr<ChannelList> c);
 };
 
 } // namespace