a7b54585d969bf45abd3fc3134620ba03886639d
[ardour.git] / libs / ardour / ardour / midi_model.h
1 /*
2     Copyright (C) 2007 Paul Davis
3     Author: Dave Robillard
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #ifndef __ardour_midi_model_h__ 
22 #define __ardour_midi_model_h__
23
24 #include <boost/utility.hpp>
25 #include <pbd/command.h>
26 #include <ardour/types.h>
27 #include <ardour/midi_buffer.h>
28
29 namespace ARDOUR {
30
31 class Session;
32
33
34 /** This is a slightly higher level (than MidiBuffer) model of MIDI note data.
35  * Currently it only represents note data, which is represented as complete
36  * note events (ie with a start time and a duration) rather than separate
37  * note on and off events (controller data is not here since it's represented
38  * as an AutomationList)
39  */
40 class MidiModel : public boost::noncopyable {
41 public:
42         struct Note {
43                 Note(double s=0, double d=0, uint8_t n=0, uint8_t v=0)
44                 : start(s), duration(d), note(n), velocity(v) {}
45
46                 inline bool operator==(const Note& other)
47                         { return start == other.start && note == other.note; }
48
49                 double start;
50                 double duration;
51                 uint8_t note;
52                 uint8_t velocity;
53         };
54
55         MidiModel(Session& s, size_t size=0);
56
57         void clear() { _notes.clear(); }
58
59         void start_write();
60         void end_write(bool delete_stuck=false);
61
62         /** Resizes vector if necessary (NOT realtime safe) */
63         void append(const MidiBuffer& data);
64         
65         /** Resizes vector if necessary (NOT realtime safe) */
66         void append(double time, size_t size, const Byte* in_buffer);
67         
68         inline const Note& note_at(unsigned i) const { return _notes[i]; }
69
70         inline size_t n_notes() const { return _notes.size(); }
71
72         typedef std::vector<Note> Notes;
73         
74         struct NoteTimeComparator {
75                 inline bool operator() (const Note& a, const Note& b) const { 
76                         return a.start < b.start;
77                 }
78         };
79
80         inline       Notes& notes()       { return _notes; }
81         inline const Notes& notes() const { return _notes; }
82
83         void     begin_command();
84         Command* current_command() { return _command; }
85         void     finish_command();
86
87         // Commands
88         void add_note(const Note& note);
89         void remove_note(const Note& note);
90
91         sigc::signal<void> ContentsChanged;
92         
93 private:
94         class MidiEditCommand : public Command
95         {
96         public:
97                 MidiEditCommand (MidiModel& m) : _model(m) {}
98                 //MidiEditCommand (MidiModel&, const XMLNode& node);
99                 
100                 void operator()();
101                 void undo();
102                 
103                 /*int set_state (const XMLNode&);
104                 XMLNode& get_state ();*/
105
106                 void add_note(const Note& note);
107                 void remove_note(const Note& note);
108
109         private:
110                 MidiModel&      _model;
111                 std::list<Note> _added_notes;
112                 std::list<Note> _removed_notes;
113         };
114
115         void append_note_on(double time, uint8_t note, uint8_t velocity);
116         void append_note_off(double time, uint8_t note);
117
118         Session& _session;
119
120         Notes _notes;
121         
122         typedef std::vector<size_t> WriteNotes;
123         WriteNotes _write_notes;
124
125         MidiEditCommand* _command; ///< In-progress command
126 };
127
128 } /* namespace ARDOUR */
129
130 #endif /* __ardour_midi_model_h__ */
131