#ifndef __ardour_smf_filesource_h__
#define __ardour_smf_filesource_h__
+#include <cstdio>
#include <time.h>
#include <ardour/midi_source.h>
+#include <evoral/SMF.hpp>
+
+namespace Evoral { template<typename T> class Event; }
namespace ARDOUR {
+template<typename T> class MidiRingBuffer;
+
/** Standard Midi File (Type 0) Source */
-class SMFSource : public MidiSource {
+class SMFSource : public MidiSource, public Evoral::SMF {
public:
enum Flag {
Writable = 0x1,
};
/** Constructor for existing external-to-session files */
- SMFSource (std::string path, Flag flags);
+ SMFSource (Session& session, std::string path, Flag flags = Flag(0));
/* Constructor for existing in-session files */
- SMFSource (const XMLNode&);
+ SMFSource (Session& session, const XMLNode&);
virtual ~SMFSource ();
- int set_name (string newname, bool destructive);
+ /* this block of methods do nothing for regular file sources, but are significant
+ for files used in destructive recording.
+ */
+ // FIXME and thus are useless for MIDI.. but make MidiDiskstream compile easier! :)
+
+ virtual nframes_t last_capture_start_frame() const { return 0; }
+ virtual void mark_capture_start (nframes_t) {}
+ virtual void mark_capture_end () {}
+ virtual void clear_capture_marks() {}
- string path() const { return _path; }
+ bool set_name (const std::string& newname) { return (set_source_name(newname, false) == 0); }
+ int set_source_name (string newname, bool destructive);
+
+ static bool safe_file_extension (const Glib::ustring& path);
+
+ Glib::ustring path() const { return _path; }
void set_allow_remove_if_empty (bool yn);
void mark_for_remove();
- virtual int update_header (jack_nframes_t when, struct tm&, time_t) = 0;
- virtual int flush_header () = 0;
+ void append_event_unlocked(EventTimeUnit unit, const Evoral::Event<double>& ev);
int move_to_trash (const string trash_dir_name);
- static bool is_empty (string path);
+ void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
void mark_streaming_write_completed ();
void mark_take (string);
string take_id() const { return _take_id; }
static void set_search_path (string);
- static void set_header_position_offset (jack_nframes_t offset, bool negative);
+ static void set_header_position_offset (nframes_t offset, bool negative);
XMLNode& get_state ();
int set_state (const XMLNode&);
- protected:
+ void load_model(bool lock=true, bool force_reload=false);
+ void destroy_model();
+
+ double last_event_time() const { return _last_ev_time; }
+
+ void flush_midi();
+
+ private:
int init (string idstr, bool must_exist);
+ nframes_t read_unlocked (
+ MidiRingBuffer<nframes_t>& dst,
+ nframes_t start,
+ nframes_t cn,
+ nframes_t stamp_offset,
+ nframes_t negative_stamp_offset) const;
+
+ nframes_t write_unlocked (
+ MidiRingBuffer<nframes_t>& src,
+ nframes_t cnt);
+
bool find (std::string path, bool must_exist, bool& is_new);
bool removable() const;
bool writable() const { return _flags & Writable; }
- uint16_t _channel;
- string _path;
- Flag _flags;
- string _take_id;
- bool _allow_remove_if_empty;
- uint64_t _timeline_position;
+ void set_default_controls_interpolation();
+
+ Glib::ustring _path;
+ Flag _flags;
+ string _take_id;
+ bool _allow_remove_if_empty;
+ double _last_ev_time;
static string _search_path;
};