summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-08-28 17:48:37 +0000
committerDavid Robillard <d@drobilla.net>2007-08-28 17:48:37 +0000
commit056b2a59d5cb28042926dab61f56e49917c8eec4 (patch)
tree7c5ae738749667bc5800da51db63205fb0793659 /libs/ardour/ardour
parent23949886e6f207e423d11b330b8d7e9ad5a949bf (diff)
Split MidiModel::Note out to ARDOUR::Note in it's own file (midi_model.h was getting fat).
Initial work on MidiModel iterator. git-svn-id: svn://localhost/ardour2/trunk@2355 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/automation_event.h4
-rw-r--r--libs/ardour/ardour/midi_event.h14
-rw-r--r--libs/ardour/ardour/midi_model.h78
-rw-r--r--libs/ardour/ardour/note.h71
-rw-r--r--libs/ardour/ardour/parameter.h3
5 files changed, 126 insertions, 44 deletions
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index 1675dbc822..e2a98e50b0 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -84,8 +84,8 @@ class AutomationList : public PBD::StatefulDestructible
AutomationList& operator= (const AutomationList&);
bool operator== (const AutomationList&);
- Parameter parameter() const { return _parameter; }
- void set_parameter(Parameter p) { _parameter = p; }
+ const Parameter& parameter() const { return _parameter; }
+ void set_parameter(Parameter p) { _parameter = p; }
void freeze();
void thaw ();
diff --git a/libs/ardour/ardour/midi_event.h b/libs/ardour/ardour/midi_event.h
index 61e6b8af6e..a04a19cec8 100644
--- a/libs/ardour/ardour/midi_event.h
+++ b/libs/ardour/ardour/midi_event.h
@@ -21,7 +21,9 @@
#ifndef __ardour_midi_event_h__
#define __ardour_midi_event_h__
+#include <ardour/types.h>
#include <ardour/midi_events.h>
+#include <stdint.h>
/** If this is not defined, all methods of MidiEvent are RT safe
* but MidiEvent will never deep copy and (depending on the scenario)
@@ -38,7 +40,7 @@ namespace ARDOUR {
*/
struct MidiEvent {
#ifdef MIDI_EVENT_ALLOW_ALLOC
- MidiEvent(double t=0, size_t s=0, Byte* b=NULL, bool owns_buffer=false)
+ MidiEvent(double t=0, uint32_t s=0, Byte* b=NULL, bool owns_buffer=false)
: _time(t)
, _size(s)
, _buffer(b)
@@ -96,7 +98,15 @@ struct MidiEvent {
}
inline bool owns_buffer() const { return _owns_buffer; }
- inline void set_buffer(Byte* buf) { assert(!_owns_buffer); _buffer = buf; }
+
+ inline void set_buffer(Byte* buf) {
+ if (_owns_buffer) {
+ free(_buffer);
+ _buffer = NULL;
+ }
+ _buffer = buf;
+ _owns_buffer = false;
+ }
#else
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
index 27a11fa9fc..41382b1be3 100644
--- a/libs/ardour/ardour/midi_model.h
+++ b/libs/ardour/ardour/midi_model.h
@@ -22,6 +22,7 @@
#define __ardour_midi_model_h__
#include <queue>
+#include <utility>
#include <boost/utility.hpp>
#include <glibmm/thread.h>
#include <pbd/command.h>
@@ -29,11 +30,16 @@
#include <ardour/midi_buffer.h>
#include <ardour/midi_ring_buffer.h>
#include <ardour/automatable.h>
+#include <ardour/note.h>
namespace ARDOUR {
class Session;
class MidiSource;
+
+// x , y
+typedef std::pair<boost::shared_ptr<const AutomationList>, std::pair<double,double> >
+ MidiControlIterator;
/** This is a slightly higher level (than MidiBuffer) model of MIDI note data.
@@ -44,45 +50,13 @@ class MidiSource;
*/
class MidiModel : public boost::noncopyable, public Automatable {
public:
- struct Note {
- Note(double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40);
- Note(const Note& copy);
-
- const MidiModel::Note& operator=(const MidiModel::Note& copy);
-
- inline bool operator==(const Note& other)
- { return time() == other.time() && note() == other.note(); }
-
- inline double time() const { return _on_event.time(); }
- inline double end_time() const { return _off_event.time(); }
- inline uint8_t note() const { return _on_event.note(); }
- inline uint8_t velocity() const { return _on_event.velocity(); }
- inline double duration() const { return _off_event.time() - _on_event.time(); }
-
- inline void set_time(double t) { _off_event.time() = t + duration(); _on_event.time() = t; }
- inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; }
- inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; }
- inline void set_duration(double d) { _off_event.time() = _on_event.time() + d; }
-
- inline MidiEvent& on_event() { return _on_event; }
- inline MidiEvent& off_event() { return _off_event; }
-
- inline const MidiEvent& on_event() const { return _on_event; }
- inline const MidiEvent& off_event() const { return _off_event; }
-
- private:
- // Event buffers are self-contained
- MidiEvent _on_event;
- MidiEvent _off_event;
- };
-
MidiModel(Session& s, size_t size=0);
// This is crap.
- void write_lock() { _lock.writer_lock(); _automation_lock.lock(); }
- void write_unlock() { _lock.writer_unlock(); _automation_lock.unlock(); }
- void read_lock() { _lock.reader_lock(); _automation_lock.lock(); }
- void read_unlock() { _lock.reader_unlock(); _automation_lock.unlock(); }
+ void write_lock() { _lock.writer_lock(); _automation_lock.lock(); }
+ void write_unlock() { _lock.writer_unlock(); _automation_lock.unlock(); }
+ void read_lock() const { _lock.reader_lock(); _automation_lock.lock(); }
+ void read_unlock() const { _lock.reader_unlock(); _automation_lock.unlock(); }
void clear() { _notes.clear(); }
@@ -90,7 +64,7 @@ public:
void set_note_mode(NoteMode mode) { _note_mode = mode; }
void start_write();
- bool currently_writing() const { return _writing; }
+ bool writing() const { return _writing; }
void end_write(bool delete_stuck=false);
size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset) const;
@@ -99,7 +73,6 @@ public:
void append(const MidiBuffer& data);
/** Resizes vector if necessary (NOT realtime safe) */
- //void append(double time, size_t size, const Byte* in_buffer);
void append(const MidiEvent& ev);
inline const Note& note_at(unsigned i) const { return _notes[i]; }
@@ -164,11 +137,37 @@ public:
sigc::signal<void> ContentsChanged;
+ /** Read iterator */
+ class const_iterator {
+ public:
+ const_iterator(MidiModel& model, double t);
+ ~const_iterator();
+
+ const MidiEvent& operator*() const { return _event; }
+
+ const const_iterator& operator++(); // prefix only
+
+ private:
+ const MidiModel& _model;
+ MidiEvent _event;
+
+ typedef std::priority_queue<const Note*,std::vector<const Note*>, LaterNoteEndComparator>
+ ActiveNotes;
+ mutable ActiveNotes _active_notes;
+
+ Notes::iterator _note_iter;
+
+ std::vector<MidiControlIterator> _control_iters;
+ };
+
private:
friend class DeltaCommand;
void add_note_unlocked(const Note& note);
void remove_note_unlocked(const Note& note);
+ friend class const_iterator;
+ bool control_to_midi_event(MidiEvent& ev, const MidiControlIterator& iter);
+
#ifndef NDEBUG
bool is_sorted() const;
#endif
@@ -177,7 +176,7 @@ private:
void append_note_off_unlocked(double time, uint8_t note);
void append_cc_unlocked(double time, uint8_t number, uint8_t value);
- Glib::RWLock _lock;
+ mutable Glib::RWLock _lock;
Notes _notes;
NoteMode _note_mode;
@@ -188,6 +187,7 @@ private:
bool _edited;
// note state for read():
+ // (TODO: Remove and replace with iterator)
typedef std::priority_queue<const Note*,std::vector<const Note*>,
LaterNoteEndComparator> ActiveNotes;
diff --git a/libs/ardour/ardour/note.h b/libs/ardour/ardour/note.h
new file mode 100644
index 0000000000..d88ecd05b0
--- /dev/null
+++ b/libs/ardour/ardour/note.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_note_h__
+#define __ardour_note_h__
+
+#include <stdint.h>
+#include <ardour/midi_event.h>
+
+namespace ARDOUR {
+
+
+/** A MIDI Note.
+ *
+ * A note is (unfortunately) special and not just another MidiEvent as it
+ * has a duration and two separate MIDI events (on and off).
+ */
+class Note {
+public:
+ Note(double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40);
+ Note(const Note& copy);
+
+ const Note& operator=(const Note& copy);
+
+ inline bool operator==(const Note& other)
+ { return time() == other.time() && note() == other.note(); }
+
+ inline double time() const { return _on_event.time(); }
+ inline double end_time() const { return _off_event.time(); }
+ inline uint8_t note() const { return _on_event.note(); }
+ inline uint8_t velocity() const { return _on_event.velocity(); }
+ inline double duration() const { return _off_event.time() - _on_event.time(); }
+
+ inline void set_time(double t) { _off_event.time() = t + duration(); _on_event.time() = t; }
+ inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; }
+ inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; }
+ inline void set_duration(double d) { _off_event.time() = _on_event.time() + d; }
+
+ inline MidiEvent& on_event() { return _on_event; }
+ inline MidiEvent& off_event() { return _off_event; }
+
+ inline const MidiEvent& on_event() const { return _on_event; }
+ inline const MidiEvent& off_event() const { return _off_event; }
+
+private:
+ // Event buffers are self-contained
+ MidiEvent _on_event;
+ MidiEvent _off_event;
+};
+
+
+} // namespace ARDOUR
+
+#endif /* __ardour_note_h__ */
diff --git a/libs/ardour/ardour/parameter.h b/libs/ardour/ardour/parameter.h
index 803bd889cb..d56124ee53 100644
--- a/libs/ardour/ardour/parameter.h
+++ b/libs/ardour/ardour/parameter.h
@@ -90,9 +90,10 @@ public:
/** Arbitrary but fixed ordering, so we're comparable (usable in std::map) */
inline bool operator<(const Parameter& id) const {
- // FIXME: branch a performance problem? #ifdef DEBUG?
+#ifndef NDEBUG
if (_type == NullAutomation)
PBD::warning << "Uninitialized Parameter compared." << endmsg;
+#endif
return (_type < id._type || _id < id._id);
}