13
0

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
This commit is contained in:
Paul Davis 2008-10-08 20:14:22 +00:00
parent 1d210a54f9
commit 89e4d35244
26 changed files with 252 additions and 78 deletions

View File

@ -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

View File

@ -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 ();

View File

@ -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(); }

View File

@ -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() {}

View File

@ -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

View File

@ -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

View File

@ -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) {}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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)));
}
}

View File

@ -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];

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}
@ -81,6 +108,27 @@ JackMidiPort::cycle_end (nframes_t nframes, nframes_t offset)
jack_midi_clear_buffer (jack_buffer);
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());
}
#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

View File

@ -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];

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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")))) {

View File

@ -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;