summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-10-08 20:14:22 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-10-08 20:14:22 +0000
commit89e4d352445e9394073804f78fbd6845e6820f20 (patch)
tree14cf1f812444a3fa5271cc7c324e1d9a67c744e9 /libs
parent1d210a54f9b1c0da7a196413bd760ff53f198270 (diff)
torben's port buffer reworking; torben's panner automation loading patch (allows loading of 2.X sessions)
git-svn-id: svn://localhost/ardour2/branches/3.0@3890 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audio_port.h4
-rw-r--r--libs/ardour/ardour/base_audio_port.h10
-rw-r--r--libs/ardour/ardour/base_midi_port.h10
-rw-r--r--libs/ardour/ardour/io.h1
-rw-r--r--libs/ardour/ardour/jack_audio_port.h9
-rw-r--r--libs/ardour/ardour/jack_midi_port.h5
-rw-r--r--libs/ardour/ardour/midi_buffer.h1
-rw-r--r--libs/ardour/ardour/midi_port.h5
-rw-r--r--libs/ardour/ardour/port.h3
-rw-r--r--libs/ardour/audio_diskstream.cc6
-rw-r--r--libs/ardour/audio_port.cc29
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/audioengine.cc23
-rw-r--r--libs/ardour/base_audio_port.cc4
-rw-r--r--libs/ardour/base_midi_port.cc6
-rw-r--r--libs/ardour/buffer_set.cc2
-rw-r--r--libs/ardour/export_channel_configuration.cc2
-rw-r--r--libs/ardour/io.cc21
-rw-r--r--libs/ardour/jack_audio_port.cc27
-rw-r--r--libs/ardour/jack_midi_port.cc52
-rw-r--r--libs/ardour/midi_buffer.cc48
-rw-r--r--libs/ardour/midi_diskstream.cc4
-rw-r--r--libs/ardour/midi_port.cc23
-rw-r--r--libs/ardour/midi_track.cc10
-rw-r--r--libs/ardour/panner.cc15
-rw-r--r--libs/ardour/session_process.cc4
26 files changed, 250 insertions, 76 deletions
diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h
index 874f842d83..fa416864e9 100644
--- a/libs/ardour/ardour/audio_port.h
+++ b/libs/ardour/ardour/audio_port.h
@@ -35,10 +35,14 @@ class AudioPort : public BaseAudioPort, public PortFacade {
void cycle_start (nframes_t nframes, nframes_t offset);
void cycle_end (nframes_t nframes, nframes_t offset);
+ AudioBuffer& get_audio_buffer( nframes_t nframes, nframes_t offset );
+
protected:
friend class AudioEngine;
AudioPort (const std::string&, Flags, bool external, nframes_t);
+ private:
+ bool _has_been_mixed_down;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/base_audio_port.h b/libs/ardour/ardour/base_audio_port.h
index 791928fa03..5bad90150b 100644
--- a/libs/ardour/ardour/base_audio_port.h
+++ b/libs/ardour/ardour/base_audio_port.h
@@ -41,15 +41,11 @@ class BaseAudioPort : public virtual Port {
DataType type() const { return DataType::AUDIO; }
- virtual Buffer& get_buffer () {
- assert (_buffer);
- return *_buffer;
+ virtual Buffer& get_buffer ( nframes_t nframes, nframes_t offset ) {
+ return get_audio_buffer( nframes, offset);
}
- virtual AudioBuffer& get_audio_buffer() {
- assert (_buffer);
- return *_buffer;
- }
+ virtual AudioBuffer& get_audio_buffer (nframes_t nframes, nframes_t offset) = 0;
void reset ();
diff --git a/libs/ardour/ardour/base_midi_port.h b/libs/ardour/ardour/base_midi_port.h
index 1c9a69d48d..5ea18fce43 100644
--- a/libs/ardour/ardour/base_midi_port.h
+++ b/libs/ardour/ardour/base_midi_port.h
@@ -37,15 +37,11 @@ class BaseMidiPort : public virtual Port {
DataType type() const { return DataType::MIDI; }
- Buffer& get_buffer() {
- assert (_buffer);
- return *_buffer;
+ Buffer& get_buffer( nframes_t nframes, nframes_t offset ) {
+ return get_midi_buffer( nframes, offset );
}
- MidiBuffer& get_midi_buffer() {
- assert (_buffer);
- return *_buffer;
- }
+ virtual MidiBuffer& get_midi_buffer (nframes_t nframes, nframes_t offset ) = 0;
size_t capacity() { return _buffer->capacity(); }
size_t size() { return _buffer->size(); }
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index af26319e82..69473b5747 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -289,6 +289,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
bool _public_ports;
virtual void prepare_inputs (nframes_t nframes, nframes_t offset);
+ virtual void flush_outputs (nframes_t nframes, nframes_t offset);
virtual void set_deferred_state() {}
diff --git a/libs/ardour/ardour/jack_audio_port.h b/libs/ardour/ardour/jack_audio_port.h
index 703fb81fa3..5ca27132e0 100644
--- a/libs/ardour/ardour/jack_audio_port.h
+++ b/libs/ardour/ardour/jack_audio_port.h
@@ -32,18 +32,21 @@ namespace ARDOUR {
class AudioEngine;
class JackAudioPort : public JackPort, public BaseAudioPort {
public:
- void cycle_start (nframes_t nframes, nframes_t offset) {
- _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes) + offset, nframes);
- }
+ void cycle_end (nframes_t nframes, nframes_t offset);
+ void cycle_start (nframes_t nframes, nframes_t offset);
int reestablish ();
+ AudioBuffer& get_audio_buffer( nframes_t nframes, nframes_t offset );
+
protected:
friend class AudioPort;
JackAudioPort (const std::string& name, Flags flags, AudioBuffer* buf);
AudioBuffer* _source_buffer;
+ private:
+ bool _has_been_mixed_down;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/jack_midi_port.h b/libs/ardour/ardour/jack_midi_port.h
index d1fb5cc4fb..91cbd400aa 100644
--- a/libs/ardour/ardour/jack_midi_port.h
+++ b/libs/ardour/ardour/jack_midi_port.h
@@ -39,12 +39,17 @@ class JackMidiPort : public JackPort, public BaseMidiPort {
public:
void cycle_start (nframes_t nframes, nframes_t offset);
void cycle_end (nframes_t nframes, nframes_t offset);
+ void flush_buffers (nframes_t nframes, nframes_t offset);
void set_buffer (MidiBuffer& buf);
+ MidiBuffer& get_midi_buffer( nframes_t nframes, nframes_t offset );
+
protected:
friend class MidiPort;
JackMidiPort (const std::string&, Flags, MidiBuffer*);
+ private:
+ bool _has_been_mixed_down;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h
index 606cbd0ec8..812f697aa3 100644
--- a/libs/ardour/ardour/midi_buffer.h
+++ b/libs/ardour/ardour/midi_buffer.h
@@ -46,6 +46,7 @@ public:
void resize(size_t);
bool merge(const MidiBuffer& a, const MidiBuffer& b);
+ bool merge_in_place( const MidiBuffer &other );
struct iterator {
iterator(MidiBuffer& b, size_t i) : buffer(b), index(i) {}
diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h
index 485834aaff..a5a269b1ef 100644
--- a/libs/ardour/ardour/midi_port.h
+++ b/libs/ardour/ardour/midi_port.h
@@ -35,11 +35,16 @@ class MidiPort : public BaseMidiPort, public PortFacade {
void cycle_start (nframes_t nframes, nframes_t offset);
void cycle_end (nframes_t nframes, nframes_t offset);
+ void flush_buffers (nframes_t nframes, nframes_t offset);
+
+ MidiBuffer& get_midi_buffer( nframes_t nframes, nframes_t offset );
protected:
friend class AudioEngine;
MidiPort (const std::string& name, Flags, bool external, nframes_t bufsize);
+ private:
+ bool _has_been_mixed_down;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index 084022541d..ad81d6763f 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -79,8 +79,9 @@ class Port : public virtual sigc::trackable {
virtual void cycle_start (nframes_t nframes, nframes_t offset) {}
virtual void cycle_end (nframes_t nframes, nframes_t offset) {}
+ virtual void flush_buffers (nframes_t nframes, nframes_t offset ) {}
virtual DataType type() const = 0;
- virtual Buffer& get_buffer() = 0;
+ virtual Buffer& get_buffer( nframes_t nframes, nframes_t offset ) = 0;
virtual bool connected () const;
virtual bool connected_to (const std::string& portname) const;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index e9f4b9ea15..4cf834b5c1 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -655,8 +655,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
AudioPort* const ap = _io->audio_input(n);
assert(ap);
- assert(rec_nframes <= ap->get_audio_buffer().capacity());
- memcpy (chaninfo->current_capture_buffer, ap->get_audio_buffer().data(rec_nframes, offset + rec_offset), sizeof (Sample) * rec_nframes);
+ assert(rec_nframes <= ap->get_audio_buffer( nframes, offset ).capacity());
+ memcpy (chaninfo->current_capture_buffer, ap->get_audio_buffer( nframes, offset ).data(rec_nframes, offset + rec_offset), sizeof (Sample) * rec_nframes);
} else {
@@ -670,7 +670,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
AudioPort* const ap = _io->audio_input(n);
assert(ap);
- Sample* buf = ap->get_audio_buffer().data(nframes, offset);
+ Sample* buf = ap->get_audio_buffer( nframes, offset ).data(nframes, offset);
nframes_t first = chaninfo->capture_vector.len[0];
memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first);
diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc
index 714be28f34..0e37313d01 100644
--- a/libs/ardour/audio_port.cc
+++ b/libs/ardour/audio_port.cc
@@ -29,6 +29,7 @@ AudioPort::AudioPort (const std::string& name, Flags flags, bool external, nfram
: Port (name, flags)
, BaseAudioPort (name, flags)
, PortFacade (name, flags)
+ , _has_been_mixed_down( false )
{
if (!external || receives_input()) {
@@ -55,9 +56,9 @@ AudioPort::AudioPort (const std::string& name, Flags flags, bool external, nfram
_ext_port = new JackAudioPort (name, flags, 0);
- if (sends_output()) {
- _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer();
- }
+ //if (sends_output()) {
+ // _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset );
+ //}
Port::set_name (_ext_port->name());
}
@@ -92,11 +93,19 @@ AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
if (_ext_port) {
_ext_port->cycle_start (nframes, offset);
}
+ _has_been_mixed_down = false;
+}
+
+AudioBuffer &
+AudioPort::get_audio_buffer( nframes_t nframes, nframes_t offset ) {
+
+ if (_has_been_mixed_down)
+ return *_buffer;
if (_flags & IsInput) {
if (_ext_port) {
- _buffer->read_from (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer(), nframes, offset);
+ _buffer->read_from (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer (nframes, offset), nframes, offset);
if (!_connections.empty()) {
(*_mixdown) (_connections, _buffer, nframes, offset, false);
@@ -115,12 +124,20 @@ AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
// XXX if we could get the output stage to not purely mix into, but also
// to initially overwrite the buffer, we could avoid this silence step.
-
- _buffer->silence (nframes, offset);
+ if (_ext_port) {
+ _buffer = & (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset ));
+ }
+ if (nframes)
+ _buffer->silence (nframes, offset);
}
+ if (nframes)
+ _has_been_mixed_down = true;
+
+ return *_buffer;
}
void
AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
{
+ _has_been_mixed_down=false;
}
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 0418074ef2..d30899caf8 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -540,6 +540,8 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
transport_frame = _session.transport_frame();
+ prepare_inputs( nframes, offset );
+
if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
/* need to do this so that the diskstream sets its
playback distance to zero, thus causing diskstream::commit
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 3122ff760c..0ae71f739c 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -351,9 +351,7 @@ AudioEngine::process_callback (nframes_t nframes)
which requires interleaving with route processing.
*/
- if ((*i)->sends_output()) {
- (*i)->cycle_start (nframes, 0);
- }
+ (*i)->cycle_start (nframes, 0);
}
if (_freewheeling) {
@@ -368,12 +366,6 @@ AudioEngine::process_callback (nframes_t nframes)
}
}
- // Finalize ports (ie write data if necessary)
-
- for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
- (*i)->cycle_end (nframes, 0);
- }
-
if (_freewheeling) {
return 0;
}
@@ -412,11 +404,18 @@ AudioEngine::process_callback (nframes_t nframes)
Port *port = (*i);
if (port->sends_output()) {
- port->get_buffer().silence(nframes);
+ port->get_buffer(nframes, 0 ).silence(nframes);
}
}
}
+ // Finalize ports (ie write data if necessary)
+
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
+
+ (*i)->cycle_end (nframes, 0);
+ }
+
_processed_frames = next_processed_frames;
return 0;
}
@@ -523,9 +522,7 @@ AudioEngine::set_session (Session *s)
boost::shared_ptr<Ports> p = ports.reader();
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
- if ((*i)->sends_output()) {
- (*i)->cycle_start (blocksize, 0);
- }
+ (*i)->cycle_start (blocksize, 0);
}
s->process (blocksize);
diff --git a/libs/ardour/base_audio_port.cc b/libs/ardour/base_audio_port.cc
index ceec4c1d3a..0675a4c992 100644
--- a/libs/ardour/base_audio_port.cc
+++ b/libs/ardour/base_audio_port.cc
@@ -64,12 +64,12 @@ BaseAudioPort::default_mixdown (const set<Port*>& ports, AudioBuffer* dest, nfra
set<Port*>::const_iterator p = ports.begin();
if (first_overwrite) {
- dest->read_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer(), cnt, offset);
+ dest->read_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer( cnt, offset ), cnt, offset);
p++;
}
for (; p != ports.end(); ++p) {
- dest->accumulate_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer(), cnt, offset);
+ dest->accumulate_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer( cnt, offset ), cnt, offset);
}
}
diff --git a/libs/ardour/base_midi_port.cc b/libs/ardour/base_midi_port.cc
index 49d748dd20..d679c7c04f 100644
--- a/libs/ardour/base_midi_port.cc
+++ b/libs/ardour/base_midi_port.cc
@@ -48,15 +48,15 @@ BaseMidiPort::default_mixdown (const set<Port*>& ports, MidiBuffer* dest, nframe
if (first_overwrite) {
cout << "first overwrite" << endl;
- dest->read_from ((dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(), cnt, offset);
+ dest->read_from ((dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(cnt, offset), cnt, offset);
p++;
}
// XXX DAVE: this is just a guess
for (; p != ports.end(); ++p) {
- cout << "merge" << endl;
- dest->merge (*dest, (dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer());
+ //cout << "merge" << endl;
+ dest->merge (*dest, (dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(cnt, offset));
}
}
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index 65e9f8ac8f..5b6f071150 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -71,7 +71,7 @@ BufferSet::attach_buffers(PortSet& ports)
for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
assert(p->type() == *t);
- v.push_back(&(p->get_buffer()));
+ v.push_back(&(p->get_buffer(0,0)));
}
}
diff --git a/libs/ardour/export_channel_configuration.cc b/libs/ardour/export_channel_configuration.cc
index e6eb84be06..a092af88c1 100644
--- a/libs/ardour/export_channel_configuration.cc
+++ b/libs/ardour/export_channel_configuration.cc
@@ -46,7 +46,7 @@ ExportChannel::read_ports (float * data, nframes_t frames) const
for (iterator it = begin(); it != end(); ++it) {
if (*it != 0) {
- Sample* port_buffer = (*it)->get_audio_buffer().data();
+ Sample* port_buffer = (*it)->get_audio_buffer( frames, 0).data();
for (uint32_t i = 0; i < frames; ++i) {
data[i] += (float) port_buffer[i];
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index b994b17358..e245712fee 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -231,7 +231,7 @@ IO::silence (nframes_t nframes, nframes_t offset)
/* io_lock, not taken: function must be called from Session::process() calltree */
for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
- i->get_buffer().silence (nframes, offset);
+ i->get_buffer(nframes,offset).silence (nframes, offset);
}
}
@@ -323,8 +323,7 @@ IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
BufferSet::iterator o = outs.begin(*t);
for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
- (*i).cycle_start (nframes, offset);
- o->read_from(i->get_buffer(), nframes, offset);
+ o->read_from(i->get_buffer(nframes,offset), nframes, offset);
}
}
@@ -2766,8 +2765,20 @@ void
IO::prepare_inputs (nframes_t nframes, nframes_t offset)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
+}
- for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
- (*i).cycle_start (nframes, offset);
+void
+IO::flush_outputs (nframes_t nframes, nframes_t offset)
+{
+ /* io_lock, not taken: function must be called from Session::process() calltree */
+ for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
+
+ /* Only run cycle_start() on output ports, because
+ inputs must be done in the correct processing order,
+ which requires interleaving with route processing.
+ */
+
+ (*i).flush_buffers (nframes, offset);
}
+
}
diff --git a/libs/ardour/jack_audio_port.cc b/libs/ardour/jack_audio_port.cc
index 7ce00b8f11..ed52eada9c 100644
--- a/libs/ardour/jack_audio_port.cc
+++ b/libs/ardour/jack_audio_port.cc
@@ -26,6 +26,7 @@ JackAudioPort::JackAudioPort (const std::string& name, Flags flgs, AudioBuffer*
: Port (name, flgs)
, JackPort (name, DataType::AUDIO, flgs)
, BaseAudioPort (name, flgs)
+ , _has_been_mixed_down( false )
{
if (buf) {
@@ -53,3 +54,29 @@ JackAudioPort::reestablish ()
return ret;
}
+AudioBuffer&
+JackAudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset) {
+ assert (_buffer);
+
+ if (_has_been_mixed_down)
+ return *_buffer;
+
+ if( _flags & IsInput )
+ _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes+offset);
+
+
+ if (nframes)
+ _has_been_mixed_down = true;
+
+ return *_buffer;
+}
+
+void
+JackAudioPort::cycle_start (nframes_t nframes, nframes_t offset) {
+ if( _flags & IsOutput )
+ _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes), nframes+offset);
+}
+void
+JackAudioPort::cycle_end (nframes_t nframes, nframes_t offset) {
+ _has_been_mixed_down=false;
+}
diff --git a/libs/ardour/jack_midi_port.cc b/libs/ardour/jack_midi_port.cc
index d831864ec9..3c3f50c9bb 100644
--- a/libs/ardour/jack_midi_port.cc
+++ b/libs/ardour/jack_midi_port.cc
@@ -24,6 +24,7 @@ JackMidiPort::JackMidiPort (const std::string& name, Flags flgs, MidiBuffer* buf
: Port (name, flgs)
, JackPort (name, DataType::MIDI, flgs)
, BaseMidiPort (name, flgs)
+ , _has_been_mixed_down (false)
{
// MIDI ports always need a buffer since jack buffer format is different
assert(buf);
@@ -40,10 +41,27 @@ JackMidiPort::cycle_start (nframes_t nframes, nframes_t offset)
_buffer->clear();
assert(_buffer->size() == 0);
- if (_flags & IsOutput) {
+ if (_flags & IsInput) {
return;
}
+ // We're an output - delete the midi_events.
+
+ void* jack_buffer = jack_port_get_buffer (_port, nframes);
+
+ jack_midi_clear_buffer (jack_buffer);
+}
+
+MidiBuffer &
+JackMidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
+
+ if (_has_been_mixed_down)
+ return *_buffer;
+
+ if (_flags & IsOutput) {
+ return *_buffer;
+ }
+
// We're an input - copy Jack events to internal buffer
void* jack_buffer = jack_port_get_buffer(_port, nframes);
@@ -57,13 +75,19 @@ JackMidiPort::cycle_start (nframes_t nframes, nframes_t offset)
jack_midi_event_get (&ev, jack_buffer, i);
- _buffer->push_back (ev);
+ // i guess this should do but i leave it off to test the rest first.
+ //if (ev.time > offset && ev.time < offset+nframes)
+ _buffer->push_back (ev);
}
assert(_buffer->size() == event_count);
/*if (_buffer->size() > 0)
cerr << "JackMIDIPort got " << event_count << " events (buf " << _buffer << ")" << endl;*/
+ if (nframes)
+ _has_been_mixed_down = true;
+
+ return *_buffer;
}
void
@@ -71,6 +95,9 @@ JackMidiPort::cycle_end (nframes_t nframes, nframes_t offset)
{
/* FIXME: offset */
+ _has_been_mixed_down = false;
+
+#if 0
if (_flags & IsInput) {
return;
}
@@ -88,4 +115,25 @@ JackMidiPort::cycle_end (nframes_t nframes, nframes_t offset)
assert(ev.time() < nframes);
jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
}
+#endif
+}
+
+void
+JackMidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
+{
+ /* FIXME: offset */
+
+ if (_flags & IsInput) {
+ return;
+ }
+
+ void* jack_buffer = jack_port_get_buffer (_port, nframes);
+
+ for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
+ const Evoral::Event& ev = *i;
+ // event times should be frames, relative to cycle start
+ assert(ev.time() >= 0);
+ assert(ev.time() < nframes);
+ jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
+ }
}
diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc
index f1f6b9b633..6f0620cae1 100644
--- a/libs/ardour/midi_buffer.cc
+++ b/libs/ardour/midi_buffer.cc
@@ -229,6 +229,38 @@ MidiBuffer::silence(nframes_t dur, nframes_t offset)
_silent = true;
}
+bool
+MidiBuffer::merge_in_place( const MidiBuffer &other )
+{
+ if( other.size() == 0 )
+ return true;
+
+ if( this->size() == 0 ) {
+ copy( other );
+ return true;
+ }
+
+ {
+ MidiBuffer merge_buffer( 0 );
+ Evoral::MIDIEvent onstack_events[_capacity];
+ uint8_t onstack_data[_capacity * MAX_EVENT_SIZE];
+ merge_buffer._events = onstack_events;
+ merge_buffer._data = onstack_data;
+ merge_buffer._size = 0;
+
+ bool retval = merge_buffer.merge( *this, other );
+
+ copy( merge_buffer );
+
+ // set pointers to zero again, so destructor
+ // does not end in calling free() for memory
+ // on the stack;
+ merge_buffer._events = 0;
+ merge_buffer._data = 0;
+
+ return retval;
+ }
+}
/** Clear, and merge \a a and \a b into this buffer.
*
@@ -241,14 +273,18 @@ MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b)
{
_size = 0;
- // Die if a merge isn't necessary as it's expensive
- assert(a.size() > 0 && b.size() > 0);
+ // This is mostly the case :(
+ if( this == &a )
+ merge_in_place( b );
+
+ if( this == &b )
+ merge_in_place( a );
size_t a_index = 0;
size_t b_index = 0;
size_t count = a.size() + b.size();
- while (count > 0 && a_index < a.size() && b_index < b.size()) {
+ while (count > 0) {
if (size() == capacity()) {
cerr << "WARNING: MIDI buffer overrun, events lost!" << endl;
@@ -256,11 +292,11 @@ MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b)
}
if (a_index == a.size()) {
- push_back(a[a_index]);
- ++a_index;
- } else if (b_index == b.size()) {
push_back(b[b_index]);
++b_index;
+ } else if (b_index == b.size()) {
+ push_back(a[a_index]);
+ ++a_index;
} else {
const Evoral::MIDIEvent& a_ev = a[a_index];
const Evoral::MIDIEvent& b_ev = b[b_index];
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index bb7f2931f4..0b79213a23 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -514,10 +514,10 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t
// Pump entire port buffer into the ring buffer (FIXME: split cycles?)
//_capture_buf->write(_source_port->get_midi_buffer(), transport_frame);
- size_t num_events = _source_port->get_midi_buffer().size();
+ size_t num_events = _source_port->get_midi_buffer( nframes, offset ).size();
size_t to_write = std::min(_capture_buf->write_space(), num_events);
- MidiBuffer::iterator port_iter = _source_port->get_midi_buffer().begin();
+ MidiBuffer::iterator port_iter = _source_port->get_midi_buffer( nframes, offset ).begin();
for (size_t i=0; i < to_write; ++i) {
const Evoral::MIDIEvent& ev = *port_iter;
diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc
index 14f88f2ad5..779d317247 100644
--- a/libs/ardour/midi_port.cc
+++ b/libs/ardour/midi_port.cc
@@ -30,6 +30,7 @@ MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes
: Port (name, flags)
, BaseMidiPort (name, flags)
, PortFacade (name, flags)
+ , _has_been_mixed_down (false)
{
// FIXME: size kludge (see BufferSet::ensure_buffers)
// Jack needs to tell us this
@@ -73,14 +74,21 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
if (_ext_port) {
_ext_port->cycle_start (nframes, offset);
}
+}
+
+MidiBuffer &
+MidiPort::get_midi_buffer( nframes_t nframes, nframes_t offset ) {
+ if (_has_been_mixed_down)
+ return *_buffer;
+
if (_flags & IsInput) {
if (_ext_port) {
BaseMidiPort* mprt = dynamic_cast<BaseMidiPort*>(_ext_port);
assert(mprt);
- assert(&mprt->get_midi_buffer() == _buffer);
+ assert(&mprt->get_midi_buffer(nframes,offset) == _buffer);
if (!_connections.empty()) {
(*_mixdown) (_connections, _buffer, nframes, offset, false);
@@ -96,9 +104,12 @@ MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
}
} else {
-
_buffer->silence (nframes, offset);
}
+ if (nframes)
+ _has_been_mixed_down = true;
+
+ return *_buffer;
}
@@ -108,5 +119,13 @@ MidiPort::cycle_end (nframes_t nframes, nframes_t offset)
if (_ext_port) {
_ext_port->cycle_end (nframes, offset);
}
+ _has_been_mixed_down = false;
}
+void
+MidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
+{
+ if (_ext_port) {
+ _ext_port->flush_buffers (nframes, offset);
+ }
+}
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index d60aba8bbc..662d19df3c 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -79,7 +79,7 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo
}
MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
- : Track (sess, node)
+ : Track (sess, node, DataType::MIDI )
, _immediate_events(1024) // FIXME: size?
, _note_mode(Sustained)
{
@@ -438,6 +438,11 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
int dret;
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
+ // I guess this is the right place to call cycle_start for our ports.
+ // but it actually sucks, to directly mess with the IO.... oh well.
+
+ prepare_inputs( nframes, offset );
+
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (lm.locked()) {
@@ -458,6 +463,7 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t transport_frame = _session.transport_frame();
+
if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
/* need to do this so that the diskstream sets its
playback distance to zero, thus causing diskstream::commit
@@ -511,6 +517,8 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
}
+ flush_outputs( nframes, offset );
+
return 0;
}
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index c616a6fe00..6a6a840407 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -1000,6 +1000,7 @@ Panner::set_state (const XMLNode& node)
XMLNodeConstIterator niter;
const XMLProperty *prop;
uint32_t i;
+ uint32_t num_panners = 0;
StreamPanner* sp;
LocaleGuard lg (X_("POSIX"));
@@ -1022,15 +1023,6 @@ Panner::set_state (const XMLNode& node)
set_bypassed (prop->value() == "yes");
}
- if ((prop = node.property (X_("ins"))) != 0) {
- ins.set_audio(atoi(prop->value().c_str()));
- }
-
- if ((prop = node.property (X_("outs"))) != 0) {
- outs.set_audio(atoi(prop->value().c_str()));
- }
-
-
if ((prop = node.property (X_("link_direction"))) != 0) {
LinkDirection ld; /* here to provide type information */
set_link_direction (LinkDirection (string_2_enum (prop->value(), ld)));
@@ -1068,7 +1060,8 @@ Panner::set_state (const XMLNode& node)
assumption, but its still an assumption.
*/
- sp = pan_plugins[i].factory (*this, Evoral::Parameter(PanAutomation, 0, i));
+ sp = pan_plugins[i].factory (*this, Evoral::Parameter(PanAutomation, 0, num_panners));
+ num_panners++;
if (sp->set_state (**niter) == 0) {
_streampanners.push_back (sp);
@@ -1094,7 +1087,7 @@ Panner::set_state (const XMLNode& node)
}
}
- reset(ins.n_audio(), outs.n_audio());
+ reset(num_panners, outputs.size());
/* don't try to do old-school automation loading if it wasn't marked as existing */
if ((prop = node.property (X_("automation")))) {
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 5433120f53..5a28fd5890 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -50,6 +50,10 @@ using namespace std;
void
Session::process (nframes_t nframes)
{
+ // This is no more the appriopriate place to call cycle
+ // start. cycle_start needs to be called at the Route::roll()
+ // where the signals which we want to mixdown have been calculated.
+ //
MIDI::Manager::instance()->cycle_start(nframes);
_silent = false;