Use PBD::copy_file in Session::create() to copy the template file.
[ardour.git] / libs / ardour / ardour / session.h
index 6324dd52785a76a8a24950dc214d6d10a3156238..35f4d32372b6bc80073cb02eda796b5a0e3280a0 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef __ardour_session_h__
 #define __ardour_session_h__
 
-
 #include <string>
 #include <list>
 #include <map>
@@ -55,6 +54,8 @@
 #include <ardour/gain.h>
 #include <ardour/io.h>
 
+#include <ardour/smpte.h>
+
 class XMLTree;
 class XMLNode;
 class AEffect;
@@ -72,13 +73,18 @@ namespace ARDOUR {
 class Port;
 class AudioEngine;
 class Slave;
-class Diskstream;      
-class AudioDiskstream; 
+class Diskstream;
 class Route;
 class AuxInput;
 class Source;
 class AudioSource;
+class BufferSet;
+
+class Diskstream;
+class AudioDiskstream;
+class MidiDiskstream;
 class AudioFileSource;
+class MidiSource;
 class Auditioner;
 class Insert;
 class Send;
@@ -90,11 +96,16 @@ class TempoMap;
 class AudioTrack;
 class NamedSelection;
 class AudioRegion;
+
 class Region;
 class Playlist;
 class VSTPlugin;
 class ControlProtocolInfo;
 
+class MidiTrack;
+class MidiRegion;
+class SMFSource;
+
 struct AudioExportSpecification;
 struct RouteGroup;
 
@@ -104,7 +115,6 @@ using std::map;
 using std::set;
 
 class Session : public PBD::StatefulDestructible
-
 {
   private:
        typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
@@ -151,8 +161,8 @@ class Session : public PBD::StatefulDestructible
                    Replace,
                    Clear
            };
-
-           Type           type;
+               
+               Type           type;
            Action         action;
            nframes_t action_frame;
            nframes_t target_frame;
@@ -162,6 +172,7 @@ class Session : public PBD::StatefulDestructible
                        void*                ptr;
                        bool                 yes_or_no;
                        SlaveSource slave;
+                       Route*               route;
            };
 
            boost::shared_ptr<Region>     region;
@@ -229,9 +240,6 @@ class Session : public PBD::StatefulDestructible
        
        virtual ~Session ();
 
-
-       static int find_session (string str, string& path, string& snapshot, bool& isnew);
-       
        string path() const { return _path; }
        string name() const { return _name; }
        string snap_name() const { return _current_snapshot_name; }
@@ -252,8 +260,6 @@ class Session : public PBD::StatefulDestructible
        std::string dead_sound_dir () const;
        std::string automation_dir () const;
 
-       string peak_path_from_audio_path (string) const;
-
        static string suffixed_search_path (std::string suffix, bool data);
        static string control_protocol_path ();
        static string template_path ();
@@ -261,14 +267,18 @@ class Session : public PBD::StatefulDestructible
        static void get_template_list (list<string>&);
        
        static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
+       static string change_midi_path_by_name (string oldpath, string oldname, string newname, bool destructive);
+       
+       string peak_path_from_audio_path (string) const;
        string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
+       string midi_path_from_name (string);
 
        void process (nframes_t nframes);
 
-       vector<Sample*>& get_passthru_buffers() { return _passthru_buffers; }
-       vector<Sample*>& get_silent_buffers (uint32_t howmany);
-       vector<Sample*>& get_send_buffers () { return _send_buffers; }
-
+       BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+       BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+       BufferSet& get_send_buffers (ChanCount count = ChanCount::ZERO);
+       
        void add_diskstream (boost::shared_ptr<Diskstream>);
        boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
        boost::shared_ptr<Diskstream> diskstream_by_name (string name);
@@ -283,11 +293,11 @@ class Session : public PBD::StatefulDestructible
        
        typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
        typedef std::list<boost::shared_ptr<Route> >      RouteList; 
-
+       
        boost::shared_ptr<RouteList> get_routes() const {
                return routes.reader ();
        }
-
+       
        uint32_t nroutes() const { return routes.reader()->size(); }
        uint32_t ntracks () const;
        uint32_t nbusses () const;
@@ -323,6 +333,8 @@ class Session : public PBD::StatefulDestructible
        void disable_record (bool rt_context, bool force = false);
        void step_back_from_record ();
        
+       void maybe_write_autosave ();
+
        /* Proxy signal for region hidden changes */
 
        sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
@@ -368,6 +380,7 @@ class Session : public PBD::StatefulDestructible
        bool transport_locked () const;
 
        int wipe ();
+       //int wipe_diskstream (AudioDiskstream *);
 
        int remove_region_from_region_list (boost::shared_ptr<Region>);
 
@@ -411,6 +424,8 @@ class Session : public PBD::StatefulDestructible
        int save_template (string template_name);
         int save_history (string snapshot_name = "");
         int restore_history (string snapshot_name);
+       void remove_state (string snapshot_name);
+       void rename_state (string old_name, string new_name);
 
        static int rename_template (string old_name, string new_name);
 
@@ -470,12 +485,14 @@ class Session : public PBD::StatefulDestructible
 
        std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
        RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many);
+       
+       std::list<boost::shared_ptr<MidiTrack> > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1);
+       //boost::shared_ptr<Route>     new_midi_route (uint32_t how_many = 1);
 
        void   remove_route (boost::shared_ptr<Route>);
-
        void   resort_routes ();
        void   resort_routes_using (boost::shared_ptr<RouteList>);
-
+       
        void    set_remote_control_ids();
 
        AudioEngine &engine() { return _engine; };
@@ -537,19 +554,22 @@ class Session : public PBD::StatefulDestructible
        
        /* region info  */
 
-       sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionAdded;
-       sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionRemoved;
+       sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
+       sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
 
        int region_name (string& result, string base = string(""), bool newlevel = false) const;
        string new_region_name (string);
        string path_from_region_name (string name, string identifier);
 
-       boost::shared_ptr<AudioRegion> find_whole_file_parent (boost::shared_ptr<AudioRegion const>);
+       boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);
+       
        void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
 
-       boost::shared_ptr<AudioRegion> XMLRegionFactory (const XMLNode&, bool full);
+       boost::shared_ptr<Region>      XMLRegionFactory (const XMLNode&, bool full);
+       boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
+       boost::shared_ptr<MidiRegion>  XMLMidiRegionFactory (const XMLNode&, bool full);
 
-       template<class T> void foreach_audio_region (T *obj, void (T::*func)(boost::shared_ptr<AudioRegion>));
+       template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>));
 
        /* source management */
 
@@ -563,8 +583,7 @@ class Session : public PBD::StatefulDestructible
            std::vector<Glib::ustring> paths;
            
            /* result */
-           std::vector<boost::shared_ptr<AudioRegion> > new_regions;
-           
+           std::vector<boost::shared_ptr<Region> > new_regions;
        };
 
        int import_audiofile (import_status&);
@@ -609,6 +628,8 @@ class Session : public PBD::StatefulDestructible
        
        boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
 
+       boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+
        boost::shared_ptr<Source> source_by_id (const PBD::ID&);
        boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
 
@@ -656,7 +677,7 @@ class Session : public PBD::StatefulDestructible
 
        /* flattening stuff */
 
-       int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite, vector<boost::shared_ptr<AudioSource> >&,
+       int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite, vector<boost::shared_ptr<Source> >&,
                                   InterThreadInfo& wot);
        int freeze (InterThreadInfo&);
 
@@ -738,6 +759,9 @@ class Session : public PBD::StatefulDestructible
 
        /* History (for editors, mixers, UIs etc.) */
 
+       /** Undo some transactions.
+        * @param n Number of transactions to undo.
+        */
        void undo (uint32_t n) {
                _history.undo (n);
        }
@@ -880,17 +904,11 @@ class Session : public PBD::StatefulDestructible
        static int read_favorite_dirs (FavoriteDirs&);
 
        static int write_favorite_dirs (FavoriteDirs&);
-       
-       /* file suffixes */
-
-       static const char* template_suffix() { return _template_suffix; }
-       static const char* statefile_suffix() { return _statefile_suffix; }
-       static const char* pending_suffix() { return _pending_suffix; }
 
        /* buffers for gain and pan */
 
        gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
-       pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
+       pan_t** pan_automation_buffer () const  { return _pan_automation_buffer; }
 
        /* buffers for conversion */
        enum RunContext {
@@ -908,18 +926,6 @@ class Session : public PBD::StatefulDestructible
                                  void* ptr,
                                  float opt);
 
-       typedef float (*compute_peak_t)                 (Sample *, nframes_t, float);
-       typedef void  (*find_peaks_t)                   (Sample *, nframes_t, float *, float*);
-       typedef void  (*apply_gain_to_buffer_t)         (Sample *, nframes_t, float);
-       typedef void  (*mix_buffers_with_gain_t)        (Sample *, Sample *, nframes_t, float);
-       typedef void  (*mix_buffers_no_gain_t)          (Sample *, Sample *, nframes_t);
-
-       static compute_peak_t           compute_peak;
-       static find_peaks_t             find_peaks;
-       static apply_gain_to_buffer_t   apply_gain_to_buffer;
-       static mix_buffers_with_gain_t  mix_buffers_with_gain;
-       static mix_buffers_no_gain_t    mix_buffers_no_gain;
-
        static sigc::signal<void> SendFeedback;
 
        /* Controllables */
@@ -950,10 +956,6 @@ class Session : public PBD::StatefulDestructible
 
        nframes_t compute_initial_length ();
 
-       static const char* _template_suffix;
-       static const char* _statefile_suffix;
-       static const char* _pending_suffix;
-
        enum SubState {
                PendingDeclickIn   = 0x1,
                PendingDeclickOut  = 0x2,
@@ -971,6 +973,7 @@ class Session : public PBD::StatefulDestructible
 
        AudioEngine            &_engine;
        mutable gint            processing_prohibited;
+       /// the function called when the main JACK process callback happens
        process_function_type    process_function;
        process_function_type    last_process_function;
        bool                     waiting_for_sync_offset;
@@ -989,9 +992,9 @@ class Session : public PBD::StatefulDestructible
        nframes_t          _last_slave_transport_frame;
        nframes_t           maximum_output_latency;
        nframes_t           last_stop_frame;
-       vector<Sample *>        _passthru_buffers;
-       vector<Sample *>        _silent_buffers;
-       vector<Sample *>        _send_buffers;
+       BufferSet*              _scratch_buffers;
+       BufferSet*              _silent_buffers;
+       BufferSet*              _send_buffers;
        nframes_t           current_block_size;
        nframes_t          _worst_output_latency;
        nframes_t          _worst_input_latency;
@@ -1008,7 +1011,7 @@ class Session : public PBD::StatefulDestructible
 
        void update_latency_compensation_proxy (void* ignored);
 
-       void ensure_passthru_buffers (uint32_t howmany);
+       void ensure_buffers (ChanCount howmany);
        
        void process_scrub          (nframes_t);
        void process_without_events (nframes_t);
@@ -1229,7 +1232,7 @@ class Session : public PBD::StatefulDestructible
        void remove_empty_sounds ();
 
        void setup_midi_control ();
-       int  midi_read (MIDI::Port *);
+       //int  midi_read (MIDI::Port *);
 
        void enable_record ();
        
@@ -1255,13 +1258,13 @@ class Session : public PBD::StatefulDestructible
        void *do_work();
 
        void set_next_event ();
-       void process_event (Event *);
+       void process_event (Event *ev);
 
        /* MIDI Machine Control */
 
        void deliver_mmc (MIDI::MachineControl::Command, nframes_t);
-       void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
-       void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
+       //void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
+       //void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
 
        void spp_start (MIDI::Parser&);
        void spp_continue (MIDI::Parser&);
@@ -1304,22 +1307,16 @@ class Session : public PBD::StatefulDestructible
        nframes_t _smpte_offset;
        bool _smpte_offset_negative;
 
-       /* cache the most-recently requested time conversions.
-          this helps when we have multiple clocks showing the
-          same time (e.g. the transport frame)
-       */
-
-       bool       last_smpte_valid;
-       nframes_t  last_smpte_when;
-       SMPTE::Time last_smpte;
-
-       int send_full_time_code ();
-       int send_midi_time_code ();
+       /* cache the most-recently requested time conversions. This helps when we
+        * have multiple clocks showing the same time (e.g. the transport frame) */
+       bool           last_smpte_valid;
+       nframes_t last_smpte_when;
+       SMPTE::Time    last_smpte;
+       
+       bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle
 
-       void send_full_time_code_in_another_thread ();
-       void send_midi_time_code_in_another_thread ();
-       void send_time_code_in_another_thread (bool full);
-       void send_mmc_in_another_thread (MIDI::MachineControl::Command, nframes_t frame = 0);
+       int send_full_time_code(nframes_t nframes);
+       int send_midi_time_code_for_cycle(nframes_t nframes);
 
        nframes_t adjust_apparent_position (nframes_t frames);
        
@@ -1374,17 +1371,8 @@ class Session : public PBD::StatefulDestructible
            static MultiAllocSingleReleasePool pool;
        };
 
-       Glib::Mutex       midi_lock;
-       pthread_t       midi_thread;
-       int             midi_request_pipe[2];
        mutable  gint   butler_active;
-       RingBuffer<MIDIRequest*> midi_requests;
-
-       int           start_midi_thread ();
-       void          terminate_midi_thread ();
-       void          poke_midi_thread ();
-       static void *_midi_thread_work (void *arg);
-       void          midi_thread_work ();
+       
        void          change_midi_ports ();
        int           use_config_midi_ports ();
 
@@ -1456,8 +1444,8 @@ class Session : public PBD::StatefulDestructible
        /* REGION MANAGEMENT */
 
        mutable Glib::Mutex region_lock;
-       typedef map<PBD::ID,boost::shared_ptr<AudioRegion> > AudioRegionList;
-       AudioRegionList audio_regions;
+       typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
+       RegionList regions;
        
        void add_region (boost::shared_ptr<Region>);
        void region_changed (Change, boost::weak_ptr<Region>);
@@ -1467,10 +1455,10 @@ class Session : public PBD::StatefulDestructible
 
        /* SOURCES */
        
-       mutable Glib::Mutex audio_source_lock;
-       typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
+       mutable Glib::Mutex source_lock;
+       typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
 
-       AudioSourceList audio_sources;
+       SourceMap sources;
 
        int load_sources (const XMLNode& node);
        XMLNode& get_sources_as_xml ();
@@ -1506,9 +1494,9 @@ class Session : public PBD::StatefulDestructible
        NamedSelection *named_selection_factory (string name);
        NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
 
-        /* CURVES and AUTOMATION LISTS */
-        std::map<PBD::ID, Curve*> curves;
-        std::map<PBD::ID, AutomationList*> automation_lists;
+       /* CURVES and AUTOMATION LISTS */
+       std::map<PBD::ID, Curve*> curves;
+       std::map<PBD::ID, AutomationList*> automation_lists;
 
        /* DEFAULT FADE CURVES */
 
@@ -1607,6 +1595,7 @@ class Session : public PBD::StatefulDestructible
 
        void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
        int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
+       void reset_jack_connection (jack_client_t* jack);
        void record_enable_change_all (bool yn);
 
        XMLNode& state(bool);
@@ -1684,7 +1673,7 @@ class Session : public PBD::StatefulDestructible
                            void* ptr,
                            float opt);
 
-       /* number of hardware audio ports we're using,
+       /* number of hardware ports we're using,
           based on max (requested,available)
        */