tentative fix for losing (empty) MIDI files. Incomplete because testing shows issues...
[ardour.git] / libs / ardour / ardour / midi_model.h
index 38bd3ab982f26d1df57c90728e8a625472f11d6f..dc1c7af0e9796daf97c14a29e06f567543bbbea7 100644 (file)
 #include <boost/utility.hpp>
 #include <glibmm/threads.h>
 #include "pbd/command.h"
+#include "ardour/libardour_visibility.h"
 #include "ardour/types.h"
 #include "ardour/midi_buffer.h"
 #include "ardour/midi_ring_buffer.h"
 #include "ardour/automatable_sequence.h"
+#include "ardour/libardour_visibility.h"
 #include "ardour/types.h"
 #include "evoral/Note.hpp"
 #include "evoral/Sequence.hpp"
@@ -47,7 +49,7 @@ class MidiSource;
  * Because of this MIDI controllers and automatable controllers/widgets/etc
  * are easily interchangeable.
  */
-class MidiModel : public AutomatableSequence<Evoral::MusicalTime> {
+class LIBARDOUR_API MidiModel : public AutomatableSequence<Evoral::MusicalTime> {
 public:
        typedef Evoral::MusicalTime TimeType;
 
@@ -56,7 +58,7 @@ public:
        NoteMode note_mode() const { return (percussive() ? Percussive : Sustained); }
        void set_note_mode(NoteMode mode) { set_percussive(mode == Percussive); };
 
-       class DiffCommand : public Command {
+       class LIBARDOUR_API DiffCommand : public Command {
        public:
 
                DiffCommand (boost::shared_ptr<MidiModel> m, const std::string& name);
@@ -77,7 +79,7 @@ public:
 
        };
 
-       class NoteDiffCommand : public DiffCommand {
+       class LIBARDOUR_API NoteDiffCommand : public DiffCommand {
        public:
 
                NoteDiffCommand (boost::shared_ptr<MidiModel> m, const std::string& name) : DiffCommand (m, name) {}
@@ -114,6 +116,8 @@ public:
                struct NoteChange {
                        NoteDiffCommand::Property property;
                        NotePtr note;
+                       uint32_t note_id; 
+                   
                        union {
                                uint8_t  old_value;
                                TimeType old_time;
@@ -141,7 +145,7 @@ public:
        };
 
        /* Currently this class only supports changes of sys-ex time, but could be expanded */
-       class SysExDiffCommand : public DiffCommand {
+       class LIBARDOUR_API SysExDiffCommand : public DiffCommand {
        public:
                SysExDiffCommand (boost::shared_ptr<MidiModel> m, const XMLNode& node);
 
@@ -152,6 +156,7 @@ public:
                int set_state (const XMLNode&, int version);
                XMLNode & get_state ();
 
+               void remove (SysExPtr sysex);
                void operator() ();
                void undo ();
 
@@ -160,6 +165,7 @@ public:
        private:
                struct Change {
                        boost::shared_ptr<Evoral::Event<TimeType> > sysex;
+                       gint sysex_id;
                        SysExDiffCommand::Property property;
                        TimeType old_time;
                        TimeType new_time;
@@ -168,11 +174,13 @@ public:
                typedef std::list<Change> ChangeList;
                ChangeList _changes;
 
+               std::list<SysExPtr> _removed;
+
                XMLNode & marshal_change (const Change &);
                Change unmarshal_change (XMLNode *);
        };
 
-       class PatchChangeDiffCommand : public DiffCommand {
+       class LIBARDOUR_API PatchChangeDiffCommand : public DiffCommand {
        public:
                PatchChangeDiffCommand (boost::shared_ptr<MidiModel>, const std::string &);
                PatchChangeDiffCommand (boost::shared_ptr<MidiModel>, const XMLNode &);
@@ -201,6 +209,7 @@ public:
                struct Change {
                        PatchChangePtr patch;
                        Property       property;
+                       gint           patch_id;
                        union {
                                TimeType   old_time;
                                uint8_t    old_channel;
@@ -213,6 +222,8 @@ public:
                                uint8_t    new_program;
                                int        new_bank;
                        };
+
+                   Change() : patch_id (-1) {}
                };
 
                typedef std::list<Change> ChangeList;