# HG changeset patch
# User Chris Cannam
# Date 1235563373 0
# Node ID efe0f232685f177697c57026cc054c15cfffcd8e
# Parent  33572f3ad62be7d9949d0c778c48e582236a4be9
* Make it possible to record live MIDI to a note layer.
  Now we're a proper MIDI sequencer. Ha, ha.

diff -r 33572f3ad62b -r efe0f232685f layer/NoteLayer.cpp
--- a/layer/NoteLayer.cpp	Wed Feb 25 11:33:03 2009 +0000
+++ b/layer/NoteLayer.cpp	Wed Feb 25 12:02:53 2009 +0000
@@ -1155,6 +1155,38 @@
     return true;
 }
 
+void
+NoteLayer::addNoteOn(long frame, int pitch, int velocity)
+{
+    m_pendingNoteOns.insert(Note(frame, pitch, 0, float(velocity) / 127.0, ""));
+}
+
+void
+NoteLayer::addNoteOff(long frame, int pitch)
+{
+    for (NoteSet::iterator i = m_pendingNoteOns.begin();
+         i != m_pendingNoteOns.end(); ++i) {
+        if (lrintf((*i).value) == pitch) {
+            Note note(*i);
+            m_pendingNoteOns.erase(i);
+            note.duration = frame - note.frame;
+            if (m_model) {
+                NoteModel::AddPointCommand *c = new NoteModel::AddPointCommand
+                    (m_model, note, tr("Record Note"));
+                // execute and bundle:
+                CommandHistory::getInstance()->addCommand(c, true, true);
+            }
+            break;
+        }
+    }
+}
+
+void
+NoteLayer::abandonNoteOns()
+{
+    m_pendingNoteOns.clear();
+}
+
 int
 NoteLayer::getDefaultColourHint(bool darkbg, bool &impose)
 {
diff -r 33572f3ad62b -r efe0f232685f layer/NoteLayer.h
--- a/layer/NoteLayer.h	Wed Feb 25 11:33:03 2009 +0000
+++ b/layer/NoteLayer.h	Wed Feb 25 12:02:53 2009 +0000
@@ -102,6 +102,24 @@
     virtual void setVerticalZoomStep(int);
     virtual RangeMapper *getNewVerticalZoomRangeMapper() const;
 
+    /**
+     * Add a note-on.  Used when recording MIDI "live".  The note will
+     * not be finally added to the layer until the corresponding
+     * note-off.
+     */
+    void addNoteOn(long frame, int pitch, int velocity);
+    
+    /**
+     * Add a note-off.  This will cause a note to appear, if and only
+     * if there is a matching pending note-on.
+     */
+    void addNoteOff(long frame, int pitch);
+
+    /**
+     * Abandon all pending note-on events.
+     */
+    void abandonNoteOns();
+
     virtual void toXml(QTextStream &stream, QString indent = "",
                        QString extraAttributes = "") const;
 
@@ -124,6 +142,9 @@
     NoteModel::EditCommand *m_editingCommand;
     VerticalScale m_verticalScale;
 
+    typedef std::set<NoteModel::Point, NoteModel::Point::Comparator> NoteSet;
+    NoteSet m_pendingNoteOns;
+
     mutable float m_scaleMinimum;
     mutable float m_scaleMaximum;