diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-10-08 20:14:22 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-10-08 20:14:22 +0000 |
commit | 89e4d352445e9394073804f78fbd6845e6820f20 (patch) | |
tree | 14cf1f812444a3fa5271cc7c324e1d9a67c744e9 | |
parent | 1d210a54f9b1c0da7a196413bd760ff53f198270 (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
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; |