summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/buffer.h18
-rw-r--r--libs/ardour/ardour/midi_model.h52
-rw-r--r--libs/ardour/ardour/midi_source.h7
-rw-r--r--libs/ardour/midi_model.cc65
-rw-r--r--libs/ardour/smf_source.cc7
6 files changed, 132 insertions, 18 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index d33aaa852f..7ae7024f46 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -57,6 +57,7 @@ midi_diskstream.cc
midi_playlist.cc
midi_track.cc
midi_region.cc
+midi_model.cc
smf_source.cc
auditioner.cc
automation.cc
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
index 86a7aa9f95..61e7a843f1 100644
--- a/libs/ardour/ardour/buffer.h
+++ b/libs/ardour/ardour/buffer.h
@@ -22,6 +22,7 @@
#include <cstdlib>
#include <cassert>
#include <iostream>
+#include <boost/utility.hpp>
#include <ardour/types.h>
#include <ardour/data_type.h>
#include <ardour/runtime_functions.h>
@@ -38,7 +39,7 @@ namespace ARDOUR {
*
* To actually read/write buffer contents, use the appropriate derived class.
*/
-class Buffer
+class Buffer : public boost::noncopyable
{
public:
virtual ~Buffer() {}
@@ -76,11 +77,6 @@ protected:
size_t _capacity;
size_t _size;
bool _silent;
-
-private:
- // Prevent copies (undefined)
- Buffer(const Buffer& copy);
- void operator=(const Buffer& other);
};
@@ -175,10 +171,6 @@ public:
{ assert(offset + nframes <= _capacity); return _data + offset; }
private:
- // These are undefined (prevent copies)
- AudioBuffer(const AudioBuffer& copy);
- AudioBuffer& operator=(const AudioBuffer& copy);
-
bool _owns_data;
Sample* _data; ///< Actual buffer contents
};
@@ -197,7 +189,7 @@ public:
void read_from(const Buffer& src, nframes_t nframes, nframes_t offset);
- bool push_back(const MidiEvent& event);
+ bool push_back(const ARDOUR::MidiEvent& event);
Byte* reserve(nframes_t time, size_t size);
const MidiEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; }
@@ -206,10 +198,6 @@ public:
static size_t max_event_size() { return MAX_EVENT_SIZE; }
private:
- // These are undefined (prevent copies)
- MidiBuffer(const MidiBuffer& copy);
- MidiBuffer& operator=(const MidiBuffer& copy);
-
// FIXME: Jack needs to tell us this
static const size_t MAX_EVENT_SIZE = 4; // bytes
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
new file mode 100644
index 0000000000..5d343d7fa9
--- /dev/null
+++ b/libs/ardour/ardour/midi_model.h
@@ -0,0 +1,52 @@
+
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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_midi_model_h__
+#define __ardour_midi_model_h__
+
+#include <boost/utility.hpp>
+#include <ardour/types.h>
+#include <ardour/buffer.h>
+
+namespace ARDOUR {
+
+/** A dynamically resizable collection of MIDI events, sorted by time
+ */
+class MidiModel : public boost::noncopyable {
+public:
+ MidiModel(size_t size=0);
+ ~MidiModel();
+
+ /** Resizes vector if necessary (NOT realtime safe) */
+ void append(const MidiBuffer& data);
+
+ inline const MidiEvent& event_at(unsigned i) const { return _events[i]; }
+
+ inline size_t n_events() const { return _events.size(); }
+
+private:
+ std::vector<MidiEvent> _events;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_midi_model_h__ */
+
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index dec9536c74..40ef87f8c9 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -31,6 +31,7 @@
#include <ardour/source.h>
#include <ardour/ardour.h>
#include <ardour/buffer.h>
+#include <ardour/midi_model.h>
#include <pbd/stateful.h>
#include <pbd/xml++.h>
@@ -62,12 +63,14 @@ class MidiSource : public Source
static sigc::signal<void,MidiSource*> MidiSourceCreated;
- // The MIDI equivalent to "peaks"
+ // The MIDI equivalent to "peaks" (but complete data)
mutable sigc::signal<void,boost::shared_ptr<MidiBuffer>,nframes_t,nframes_t> ViewDataRangeReady;
XMLNode& get_state ();
int set_state (const XMLNode&);
+ MidiModel& model() { return _model; }
+
protected:
virtual nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const = 0;
virtual nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt) = 0;
@@ -77,6 +80,8 @@ class MidiSource : public Source
mutable uint32_t _read_data_count; ///< modified in read()
mutable uint32_t _write_data_count; ///< modified in write()
+ MidiModel _model;
+
private:
bool file_changed (string path);
};
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
new file mode 100644
index 0000000000..56bfd14b88
--- /dev/null
+++ b/libs/ardour/midi_model.cc
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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.
+
+*/
+
+#include <iostream>
+#include <ardour/midi_model.h>
+#include <ardour/types.h>
+
+using namespace std;
+using namespace ARDOUR;
+
+
+MidiModel::MidiModel(size_t size)
+: _events(size)
+{
+}
+
+MidiModel::~MidiModel()
+{
+ for (size_t i=0; i < _events.size(); ++i)
+ delete _events[i].buffer;
+}
+
+
+/** Append contents of \a buf to model. NOT (even remotely) realtime safe.
+ *
+ * Timestamps of events in \a buf are expected to be relative to
+ * the start of this model (t=0) and MUST be monotonically increasing
+ * and MUST be >= the latest event currently in the model.
+ *
+ * Events in buf are deep copied.
+ */
+void
+MidiModel::append(const MidiBuffer& buf)
+{
+ for (size_t i=0; i < buf.size(); ++i) {
+ const MidiEvent& buf_event = buf[i];
+ assert(buf_event.time >= _events.back().time);
+
+ _events.push_back(buf_event);
+ MidiEvent& my_event = _events.back();
+ assert(my_event.time == buf_event.time);
+ assert(my_event.size == buf_event.size);
+
+ my_event.buffer = new Byte[my_event.size];
+ memcpy(my_event.buffer, buf_event.buffer, my_event.size);
+ }
+}
+
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 52a17997a0..061a2f1234 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -352,9 +352,10 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
// FIXME: start of source time?
for (size_t i=0; i < buf.size(); ++i) {
- const MidiEvent& ev = buf[i];
+ MidiEvent& ev = buf[i];
assert(ev.time >= _timeline_position);
- uint32_t delta_time = (ev.time - _timeline_position) - _last_ev_time;
+ ev.time -= _timeline_position;
+ uint32_t delta_time = ev.time - _last_ev_time;
/*printf("SMF - writing event, delta = %u, size = %zu, data = ",
delta_time, ev.size);
@@ -376,6 +377,8 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
const nframes_t oldlen = _length;
update_length(oldlen, cnt);
+ _model.append(buf);
+
ViewDataRangeReady (buf_ptr, oldlen, cnt); /* EMIT SIGNAL */
return cnt;