summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/audio_track.h4
-rw-r--r--libs/ardour/ardour/buffer.h27
-rw-r--r--libs/ardour/ardour/buffer_set.h6
-rw-r--r--libs/ardour/ardour/midi_diskstream.h23
-rw-r--r--libs/ardour/ardour/midi_playlist.h4
-rw-r--r--libs/ardour/ardour/midi_port.h16
-rw-r--r--libs/ardour/ardour/midi_region.h14
-rw-r--r--libs/ardour/ardour/midi_ring_buffer.h242
-rw-r--r--libs/ardour/ardour/midi_track.h4
-rw-r--r--libs/ardour/ardour/route.h5
-rw-r--r--libs/ardour/ardour/track.h3
-rw-r--r--libs/ardour/ardour/types.h3
12 files changed, 305 insertions, 46 deletions
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 54a8c19a22..bca79b0d7d 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -64,10 +64,6 @@ class AudioTrack : public Track
protected:
XMLNode& state (bool full);
- void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t nframes, jack_nframes_t offset, int declick,
- bool meter);
-
ChanCount n_process_buffers ();
private:
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
index df7f57455b..896d6e7616 100644
--- a/libs/ardour/ardour/buffer.h
+++ b/libs/ardour/ardour/buffer.h
@@ -181,23 +181,36 @@ public:
~MidiBuffer();
- // FIXME: clear events starting at offset in time
- void silence(jack_nframes_t len, jack_nframes_t offset=0) { assert(offset == 0); _size = 0; }
+ void silence(jack_nframes_t dur, jack_nframes_t offset=0);
void read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t offset);
- void set_size(size_t size) { _size = size; }
+ bool push_back(const MidiEvent& event);
+
+ const MidiEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; }
+ MidiEvent& operator[](size_t i) { assert(i < _size); return _events[i]; }
+
+ static size_t max_event_size() { return MAX_EVENT_SIZE; }
+
+ //void set_size(size_t size) { _size = size; }
- const RawMidi* data() const { return _data; }
- RawMidi* data() { return _data; }
+ //const RawMidi* data() const { return _data; }
+ //RawMidi* data() { return _data; }
private:
// These are undefined (prevent copies)
MidiBuffer(const MidiBuffer& copy);
MidiBuffer& operator=(const MidiBuffer& copy);
- bool _owns_data;
- RawMidi* _data; ///< Actual buffer contents
+ // FIXME: Jack needs to tell us this
+ static const size_t MAX_EVENT_SIZE = 4; // bytes
+
+ /* We use _size as "number of events", so the size of _data is
+ * (_size * MAX_EVENT_SIZE)
+ */
+
+ MidiEvent* _events; ///< Event structs that point to offsets in _data
+ RawMidi* _data; ///< MIDI, straight up. No time stamps.
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index dfb5dd3611..43df729e05 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -28,6 +28,7 @@ namespace ARDOUR {
class Buffer;
class AudioBuffer;
+class MidiBuffer;
class PortSet;
@@ -77,6 +78,11 @@ public:
{
return (AudioBuffer&)get(DataType::AUDIO, i);
}
+
+ MidiBuffer& get_midi(size_t i)
+ {
+ return (MidiBuffer&)get(DataType::MIDI, i);
+ }
void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0)
{
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index 901baf3c64..ccff993638 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -45,6 +45,8 @@
#include <ardour/utils.h>
#include <ardour/diskstream.h>
#include <ardour/midi_playlist.h>
+#include <ardour/midi_ring_buffer.h>
+
struct tm;
namespace ARDOUR {
@@ -65,8 +67,7 @@ class MidiDiskstream : public Diskstream
float playback_buffer_load() const;
float capture_buffer_load() const;
- RawMidi* playback_buffer () { return _current_playback_buffer; }
- RawMidi* capture_buffer () { return _current_capture_buffer; }
+ void get_playback(MidiBuffer& dst, jack_nframes_t start, jack_nframes_t end);
void set_record_enabled (bool yn);
@@ -124,7 +125,7 @@ class MidiDiskstream : public Diskstream
int do_refill_with_alloc();
- int read (MidiBuffer& dst, jack_nframes_t& start, jack_nframes_t cnt, bool reversed);
+ int read (jack_nframes_t& start, jack_nframes_t cnt, bool reversed);
void finish_capture (bool rec_monitors_input);
void transport_stopped (struct tm&, time_t, bool abort);
@@ -147,17 +148,17 @@ class MidiDiskstream : public Diskstream
void disengage_record_enable ();
// FIXME: This is basically a single ChannelInfo.. abstractify that concept?
- RingBufferNPT<RawMidi>* _playback_buf;
- RingBufferNPT<RawMidi>* _capture_buf;
- RawMidi* _current_playback_buffer;
- RawMidi* _current_capture_buffer;
- RawMidi* _playback_wrap_buffer;
- RawMidi* _capture_wrap_buffer;
+ MidiRingBuffer* _playback_buf;
+ MidiRingBuffer* _capture_buf;
+ //RawMidi* _current_playback_buffer;
+ //RawMidi* _current_capture_buffer;
+ //RawMidi* _playback_wrap_buffer;
+ //RawMidi* _capture_wrap_buffer;
MidiPort* _source_port;
SMFSource* _write_source; ///< aka capturing source
RingBufferNPT<CaptureTransition>* _capture_transition_buf;
- RingBufferNPT<RawMidi>::rw_vector _playback_vector;
- RingBufferNPT<RawMidi>::rw_vector _capture_vector;
+ //RingBufferNPT<RawMidi>::rw_vector _playback_vector;
+ //RingBufferNPT<RawMidi>::rw_vector _capture_vector;
};
}; /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h
index 9e9cf250e2..11627b5a07 100644
--- a/libs/ardour/ardour/midi_playlist.h
+++ b/libs/ardour/ardour/midi_playlist.h
@@ -33,7 +33,7 @@ class Session;
class Region;
class MidiRegion;
class Source;
-class MidiBuffer;
+class MidiRingBuffer;
class MidiPlaylist : public ARDOUR::Playlist
{
@@ -56,7 +56,7 @@ public:
MidiPlaylist (const MidiPlaylist&, jack_nframes_t start, jack_nframes_t cnt,
string name, bool hidden = false);
- jack_nframes_t read (MidiBuffer& buf,
+ jack_nframes_t read (MidiRingBuffer& buf,
jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
int set_state (const XMLNode&);
diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h
index 3c48f0ce9e..f6eafe11bd 100644
--- a/libs/ardour/ardour/midi_port.h
+++ b/libs/ardour/ardour/midi_port.h
@@ -39,19 +39,23 @@ class MidiPort : public Port {
DataType type() const { return DataType(DataType::MIDI); }
- MidiBuffer& get_buffer() {
- return *_buffer;
+ Buffer& get_buffer() {
+ return _buffer;
+ }
+
+ MidiBuffer& get_midi_buffer() {
+ return _buffer;
}
void cycle_start(jack_nframes_t nframes);
void cycle_end();
- size_t capacity() { return _buffer->capacity(); }
- size_t size() { return _buffer->size(); }
+ size_t capacity() { return _buffer.capacity(); }
+ size_t size() { return _buffer.size(); }
/** Assumes that the port is an output port */
void silence (jack_nframes_t nframes, jack_nframes_t offset) {
- _buffer->silence(nframes, offset);
+ _buffer.silence(nframes, offset);
}
protected:
@@ -61,7 +65,7 @@ class MidiPort : public Port {
/* engine isn't supposed to access below here */
- MidiBuffer* _buffer;
+ MidiBuffer _buffer;
jack_nframes_t _nframes_this_cycle;
};
diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h
index 0144f52473..745d3fa4a8 100644
--- a/libs/ardour/ardour/midi_region.h
+++ b/libs/ardour/ardour/midi_region.h
@@ -41,7 +41,7 @@ class Playlist;
class Session;
class MidiFilter;
class MidiSource;
-class MidiBuffer;
+class MidiRingBuffer;
class MidiRegion : public Region
{
@@ -57,16 +57,16 @@ class MidiRegion : public Region
MidiSource& midi_source (uint32_t n=0) const;
- jack_nframes_t read_at (MidiBuffer& out,
+ jack_nframes_t read_at (MidiRingBuffer& dst,
jack_nframes_t position,
- jack_nframes_t cnt,
+ jack_nframes_t dur,
uint32_t chan_n = 0,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const;
- jack_nframes_t master_read_at (MidiBuffer& buf,
+ jack_nframes_t master_read_at (MidiRingBuffer& dst,
jack_nframes_t position,
- jack_nframes_t cnt,
+ jack_nframes_t dur,
uint32_t chan_n=0) const;
XMLNode& state (bool);
@@ -83,9 +83,9 @@ class MidiRegion : public Region
StateManager::State* state_factory (std::string why) const;
Change restore_state (StateManager::State&);
- jack_nframes_t _read_at (const SourceList&, MidiBuffer& buf,
+ jack_nframes_t _read_at (const SourceList&, MidiRingBuffer& dst,
jack_nframes_t position,
- jack_nframes_t cnt,
+ jack_nframes_t dur,
uint32_t chan_n = 0,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const;
diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h
new file mode 100644
index 0000000000..53057dbcba
--- /dev/null
+++ b/libs/ardour/ardour/midi_ring_buffer.h
@@ -0,0 +1,242 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ 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_ring_buffer_h__
+#define __ardour_midi_ring_buffer_h__
+
+#include <algorithm>
+#include <ardour/types.h>
+#include <pbd/ringbufferNPT.h>
+#include <ardour/buffer.h>
+
+namespace ARDOUR {
+
+/** A MIDI RingBuffer
+ * (necessary because MIDI events are variable sized so a generic RB won't do).
+ *
+ * ALL publically accessible sizes refer to event COUNTS. What actually goes
+ * on in here is none of the callers business :)
+ */
+class MidiRingBuffer {
+public:
+ MidiRingBuffer (size_t size)
+ : _size(size)
+ , _max_event_size(MidiBuffer::max_event_size())
+ , _ev_buf(new MidiEvent[size])
+ , _raw_buf(new RawMidi[size * _max_event_size])
+ {
+ reset ();
+ assert(read_space() == 0);
+ assert(write_space() == size - 1);
+ }
+
+ virtual ~MidiRingBuffer() {
+ delete[] _ev_buf;
+ delete[] _raw_buf;
+ }
+
+ void reset () {
+ /* !!! NOT THREAD SAFE !!! */
+ g_atomic_int_set (&_write_ptr, 0);
+ g_atomic_int_set (&_read_ptr, 0);
+ }
+
+ size_t write_space () {
+ size_t w, r;
+
+ w = g_atomic_int_get (&_write_ptr);
+ r = g_atomic_int_get (&_read_ptr);
+
+ if (w > r) {
+ return ((r - w + _size) % _size) - 1;
+ } else if (w < r) {
+ return (r - w) - 1;
+ } else {
+ return _size - 1;
+ }
+ }
+
+ size_t read_space () {
+ size_t w, r;
+
+ w = g_atomic_int_get (&_write_ptr);
+ r = g_atomic_int_get (&_read_ptr);
+
+ if (w > r) {
+ return w - r;
+ } else {
+ return (w - r + _size) % _size;
+ }
+ }
+
+ size_t capacity() const { return _size; }
+
+ /** Read one event and appends it to @a out. */
+ //size_t read(MidiBuffer& out);
+
+ /** Write one event (@a in) */
+ size_t write(const MidiEvent& in); // deep copies in
+
+ /** Read events all events up to time @a end into @a out, leaving stamps intact.
+ * Any events before @a start will be dropped. */
+ size_t read(MidiBuffer& out, jack_nframes_t start, jack_nframes_t end);
+
+ /** Write all events from @a in, applying @a offset to all time stamps */
+ size_t write(const MidiBuffer& in, jack_nframes_t offset = 0);
+
+ inline void clear_event(size_t index);
+
+private:
+
+ // _event_ indices
+ mutable gint _write_ptr;
+ mutable gint _read_ptr;
+
+ size_t _size; // size (capacity) in events
+ size_t _max_event_size; // ratio of raw_buf size to ev_buf size
+ MidiEvent* _ev_buf; // these point into...
+ RawMidi* _raw_buf; // this
+
+};
+
+/** Just for sanity checking */
+inline void
+MidiRingBuffer::clear_event(size_t index)
+{
+ memset(&_ev_buf[index].buffer, 0, _max_event_size);
+ _ev_buf[index].time = 0;
+ _ev_buf[index].size = 0;
+ _ev_buf[index].buffer = 0;
+
+}
+#if 0
+inline size_t
+MidiRingBuffer::read (MidiBuffer& buf)
+{
+ const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
+
+ if (read_space() == 0) {
+ return 0;
+ } else {
+ MidiEvent* const read_ev = &_ev_buf[priv_read_ptr];
+ assert(read_ev->size > 0);
+ buf.push_back(*read_ev);
+ printf("MRB - read %xd %d %d with time %u at index %zu\n",
+ read_ev->buffer[0], read_ev->buffer[1], read_ev->buffer[2], read_ev->time,
+ priv_read_ptr);
+ clear_event(priv_read_ptr);
+ g_atomic_int_set(&_read_ptr, (priv_read_ptr + 1) % _size);
+ return 1;
+ }
+}
+#endif
+inline size_t
+MidiRingBuffer::write (const MidiEvent& ev)
+{
+ //static jack_nframes_t last_write_time = 0;
+
+ assert(ev.size > 0);
+
+ size_t priv_write_ptr = g_atomic_int_get(&_write_ptr);
+
+ if (write_space () == 0) {
+ return 0;
+ } else {
+ //assert(ev.time >= last_write_time);
+
+ const size_t raw_index = priv_write_ptr * _max_event_size;
+
+ MidiEvent* const write_ev = &_ev_buf[priv_write_ptr];
+ *write_ev = ev;
+
+ memcpy(&_raw_buf[raw_index], ev.buffer, ev.size);
+ write_ev->buffer = &_raw_buf[raw_index];
+ g_atomic_int_set(&_write_ptr, (priv_write_ptr + 1) % _size);
+
+ printf("MRB - wrote %xd %d %d with time %u at index %zu (raw index %zu)\n",
+ write_ev->buffer[0], write_ev->buffer[1], write_ev->buffer[2], write_ev->time,
+ priv_write_ptr, raw_index);
+
+ assert(write_ev->size = ev.size);
+
+ //last_write_time = ev.time;
+ printf("(W) read space: %zu\n", read_space());
+
+ return 1;
+ }
+}
+
+inline size_t
+MidiRingBuffer::read(MidiBuffer& dst, jack_nframes_t start, jack_nframes_t end)
+{
+ if (read_space() == 0)
+ return 0;
+
+ size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
+ jack_nframes_t time = _ev_buf[priv_read_ptr].time;
+ size_t count = 0;
+ size_t limit = read_space();
+
+ while (time <= end && limit > 0) {
+ MidiEvent* const read_ev = &_ev_buf[priv_read_ptr];
+ if (time >= start) {
+ dst.push_back(*read_ev);
+ printf("MRB - read %xd %d %d with time %u at index %zu\n",
+ read_ev->buffer[0], read_ev->buffer[1], read_ev->buffer[2], read_ev->time,
+ priv_read_ptr);
+ } else {
+ cerr << "MRB: LOST EVENT!" << endl;
+ }
+
+ clear_event(priv_read_ptr);
+
+ ++count;
+ --limit;
+
+ priv_read_ptr = (priv_read_ptr + 1) % _size;
+
+ assert(read_ev->time <= end);
+ time = _ev_buf[priv_read_ptr].time;
+ }
+
+ g_atomic_int_set(&_read_ptr, priv_read_ptr);
+ printf("(R) read space: %zu\n", read_space());
+
+ return count;
+}
+
+inline size_t
+MidiRingBuffer::write(const MidiBuffer& in, jack_nframes_t offset)
+{
+ size_t num_events = in.size();
+ size_t to_write = std::min(write_space(), num_events);
+
+ // FIXME: double copy :/
+ for (size_t i=0; i < to_write; ++i) {
+ MidiEvent ev = in[i];
+ ev.time += offset;
+ write(ev);
+ }
+
+ return to_write;
+}
+
+} // namespace ARDOUR
+
+#endif // __ardour_midi_ring_buffer_h__
+
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index 654eb98e30..409aa171e9 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -76,10 +76,6 @@ public:
protected:
XMLNode& state (bool full);
- void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t nframes, jack_nframes_t offset, int declick,
- bool meter);
-
ChanCount n_process_buffers ();
private:
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index db5cddca39..107abb7b48 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -309,10 +309,13 @@ class Route : public IO
bool meter);
protected:
- /* for derived classes */
virtual XMLNode& state(bool);
+ void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset, int declick,
+ bool meter);
+
void silence (jack_nframes_t nframes, jack_nframes_t offset);
sigc::connection input_signal_connection;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 15a0a28aab..2b317a0299 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -95,9 +95,6 @@ class Track : public Route
virtual XMLNode& state (bool full) = 0;
- virtual void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter) = 0;
-
virtual ChanCount n_process_buffers () = 0;
Diskstream *_diskstream;
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 00833f6547..d5bfded460 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -50,7 +50,8 @@ namespace ARDOUR {
typedef uint32_t layer_t;
typedef uint64_t microseconds_t;
- typedef jack_midi_event_t RawMidi;
+ typedef jack_midi_event_t MidiEvent;
+ typedef unsigned char RawMidi;
enum IOChange {
NoChange = 0,