changeset 567:e6d35670e1df

* Somewhat better MIDI-based time instant timing
author Chris Cannam
date Wed, 25 Feb 2009 11:15:22 +0000
parents e2281de2361c
children fa32590f5a61
files base/FrameTimer.h data/midi/MIDIInput.cpp data/midi/MIDIInput.h
diffstat 3 files changed, 42 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base/FrameTimer.h	Wed Feb 25 11:15:22 2009 +0000
@@ -0,0 +1,31 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2009 QMUL.
+    
+    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.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef _FRAME_TIMER_H_
+#define _FRAME_TIMER_H_
+
+/**
+ * A trivial interface for things that permit retrieving "the current
+ * frame".  Implementations of this interface are used, for example,
+ * for timestamping incoming MIDI events when tapping to MIDI.
+ */
+
+class FrameTimer
+{
+public:
+    virtual unsigned long getFrame() const = 0;
+};
+
+#endif
--- a/data/midi/MIDIInput.cpp	Tue Feb 24 17:53:01 2009 +0000
+++ b/data/midi/MIDIInput.cpp	Wed Feb 25 11:15:22 2009 +0000
@@ -17,8 +17,9 @@
 
 #include "rtmidi/RtMidi.h"
 
-MIDIInput::MIDIInput(QString name) :
+MIDIInput::MIDIInput(QString name, FrameTimer *timer) :
     m_rtmidi(),
+    m_frameTimer(timer),
     m_buffer(1023)
 {
     try {
@@ -48,10 +49,13 @@
 MIDIInput::callback(double timestamp, std::vector<unsigned char> *message)
 {
     std::cerr << "MIDIInput::callback(" << timestamp << ")" << std::endl;
-    unsigned long deltaTime = 0;
-    if (timestamp > 0) deltaTime = (unsigned long)(timestamp * 100000); //!!! for now!
+    // In my experience so far, the timings passed to this function
+    // are not reliable enough to use.  We request instead an audio
+    // frame time from whatever FrameTimer we have been given, and use
+    // that as the event time.
     if (!message || message->empty()) return;
-    MIDIEvent ev(deltaTime,
+    unsigned long t = m_frameTimer->getFrame();
+    MIDIEvent ev(t,
                  (*message)[0],
                  message->size() > 1 ? (*message)[1] : 0,
                  message->size() > 2 ? (*message)[2] : 0);
--- a/data/midi/MIDIInput.h	Tue Feb 24 17:53:01 2009 +0000
+++ b/data/midi/MIDIInput.h	Wed Feb 25 11:15:22 2009 +0000
@@ -21,6 +21,7 @@
 
 #include <vector>
 #include "base/RingBuffer.h"
+#include "base/FrameTimer.h"
 
 class RtMidiIn;
 
@@ -29,7 +30,7 @@
     Q_OBJECT
 
 public:
-    MIDIInput(QString name);
+    MIDIInput(QString name, FrameTimer *timer);
     virtual ~MIDIInput();
 
     bool isOK() const { return m_rtmidi != 0; }
@@ -43,6 +44,7 @@
 
 protected:
     RtMidiIn *m_rtmidi;
+    FrameTimer *m_frameTimer;
 
     static void staticCallback(double, std::vector<unsigned char> *, void *);
     void callback(double, std::vector<unsigned char> *);