possible fix for crash while adding new tracks
git-svn-id: svn://localhost/ardour2/trunk@1603 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
0b7a7cba78
commit
bca0450c18
@ -212,7 +212,7 @@ class AudioDiskstream : public Diskstream
|
||||
int do_flush (Session::RunContext context, bool force = false);
|
||||
int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); }
|
||||
|
||||
int do_refill_with_alloc();
|
||||
int do_refill_with_alloc ();
|
||||
|
||||
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
|
||||
nframes_t& start, nframes_t cnt,
|
||||
@ -251,14 +251,14 @@ class AudioDiskstream : public Diskstream
|
||||
static Sample* _mixdown_buffer;
|
||||
static gain_t* _gain_buffer;
|
||||
|
||||
// Uh, /really/ private? (there should probably be less friends of Diskstream)
|
||||
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
|
||||
|
||||
|
||||
std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
|
||||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
ChannelList channels;
|
||||
|
||||
/* really */
|
||||
private:
|
||||
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define __ardour_diskstream_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
@ -53,7 +54,7 @@ class Session;
|
||||
class Playlist;
|
||||
class IO;
|
||||
|
||||
class Diskstream : public PBD::StatefulDestructible
|
||||
class Diskstream : public PBD::StatefulDestructible, public boost::enable_shared_from_this<ARDOUR::Diskstream>
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
@ -199,7 +200,6 @@ class IO;
|
||||
|
||||
/** For non-butler contexts (allocates temporary working buffers) */
|
||||
virtual int do_refill_with_alloc() = 0;
|
||||
|
||||
|
||||
/* XXX fix this redundancy ... */
|
||||
|
||||
|
@ -164,7 +164,8 @@ class Session : public PBD::StatefulDestructible
|
||||
SlaveSource slave;
|
||||
};
|
||||
|
||||
boost::shared_ptr<Region> region;
|
||||
boost::shared_ptr<Region> region;
|
||||
boost::shared_ptr<Diskstream> diskstream;
|
||||
|
||||
list<AudioRange> audio_range;
|
||||
list<MusicRange> music_range;
|
||||
@ -361,7 +362,7 @@ class Session : public PBD::StatefulDestructible
|
||||
void request_transport_speed (float speed);
|
||||
void request_overwrite_buffer (Diskstream*);
|
||||
void request_diskstream_speed (Diskstream&, float speed);
|
||||
void request_input_change_handling ();
|
||||
void request_input_change_handling (boost::shared_ptr<ARDOUR::Diskstream>);
|
||||
|
||||
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
|
||||
bool transport_locked () const;
|
||||
@ -1424,6 +1425,7 @@ class Session : public PBD::StatefulDestructible
|
||||
/* disk-streams */
|
||||
|
||||
SerializedRCUManager<DiskstreamList> diskstreams;
|
||||
SerializedRCUManager<DiskstreamList> diskstreams_input_pending;
|
||||
|
||||
uint32_t dstream_buffer_size;
|
||||
int load_diskstreams (const XMLNode&);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/memento_command.h>
|
||||
#include <pbd/enumwriter.h>
|
||||
#include <pbd/stacktrace.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/audioengine.h>
|
||||
@ -912,25 +913,25 @@ AudioDiskstream::overwrite_existing_buffers ()
|
||||
int
|
||||
AudioDiskstream::seek (nframes_t frame, bool complete_refill)
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
uint32_t n;
|
||||
int ret;
|
||||
ChannelList::iterator chan;
|
||||
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
|
||||
(*chan).playback_buf->reset ();
|
||||
(*chan).capture_buf->reset ();
|
||||
}
|
||||
|
||||
/* can't rec-enable in destructive mode if transport is before start */
|
||||
|
||||
|
||||
if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
|
||||
disengage_record_enable ();
|
||||
}
|
||||
|
||||
|
||||
playback_sample = frame;
|
||||
file_frame = frame;
|
||||
|
||||
|
||||
if (complete_refill) {
|
||||
while ((ret = do_refill_with_alloc ()) > 0) ;
|
||||
} else {
|
||||
@ -1065,7 +1066,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::do_refill_with_alloc()
|
||||
AudioDiskstream::do_refill_with_alloc ()
|
||||
{
|
||||
Sample* mix_buf = new Sample[disk_io_chunk_frames];
|
||||
float* gain_buf = new float[disk_io_chunk_frames];
|
||||
@ -1100,7 +1101,6 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer)
|
||||
vector.len[1] = 0;
|
||||
|
||||
channels.front().playback_buf->get_write_vector (&vector);
|
||||
|
||||
|
||||
if ((total_space = vector.len[0] + vector.len[1]) == 0) {
|
||||
return 0;
|
||||
@ -1833,9 +1833,6 @@ AudioDiskstream::set_state (const XMLNode& node)
|
||||
|
||||
if (nchans > _n_channels) {
|
||||
|
||||
// we need to add new channel infos
|
||||
//LockMonitor lm (state_lock, __LINE__, __FILE__);
|
||||
|
||||
int diff = nchans - channels.size();
|
||||
|
||||
for (int i=0; i < diff; ++i) {
|
||||
@ -1844,9 +1841,6 @@ AudioDiskstream::set_state (const XMLNode& node)
|
||||
|
||||
} else if (nchans < _n_channels) {
|
||||
|
||||
// we need to get rid of channels
|
||||
//LockMonitor lm (state_lock, __LINE__, __FILE__);
|
||||
|
||||
int diff = channels.size() - nchans;
|
||||
|
||||
for (int i = 0; i < diff; ++i) {
|
||||
|
@ -60,6 +60,7 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
|
||||
}
|
||||
|
||||
boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
|
||||
|
||||
_session.add_diskstream (ds);
|
||||
|
||||
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
|
||||
|
@ -125,9 +125,6 @@ Diskstream::init (Flag f)
|
||||
|
||||
Diskstream::~Diskstream ()
|
||||
{
|
||||
// Taken by derived class destrctors.. should assure locked here somehow?
|
||||
//Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (_playlist)
|
||||
_playlist->release ();
|
||||
}
|
||||
@ -146,7 +143,7 @@ Diskstream::handle_input_change (IOChange change, void *src)
|
||||
|
||||
if (!(input_change_pending & change)) {
|
||||
input_change_pending = IOChange (input_change_pending|change);
|
||||
_session.request_input_change_handling ();
|
||||
_session.request_input_change_handling (shared_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,7 @@ Session::Session (AudioEngine &eng,
|
||||
pending_events (2048),
|
||||
midi_requests (128), // the size of this should match the midi request pool size
|
||||
diskstreams (new DiskstreamList),
|
||||
diskstreams_input_pending (new DiskstreamList),
|
||||
routes (new RouteList),
|
||||
auditioner ((Auditioner*) 0),
|
||||
_click_io ((IO*) 0),
|
||||
@ -332,6 +333,7 @@ Session::Session (AudioEngine &eng,
|
||||
pending_events (2048),
|
||||
midi_requests (16),
|
||||
diskstreams (new DiskstreamList),
|
||||
diskstreams_input_pending (new DiskstreamList),
|
||||
routes (new RouteList),
|
||||
main_outs (0)
|
||||
|
||||
@ -2002,21 +2004,23 @@ void
|
||||
Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
|
||||
{
|
||||
/* need to do this in case we're rolling at the time, to prevent false underruns */
|
||||
dstream->do_refill_with_alloc();
|
||||
dstream->do_refill_with_alloc ();
|
||||
|
||||
{
|
||||
dstream->set_block_size (current_block_size);
|
||||
|
||||
if (_state_of_the_state & InitialConnecting) {
|
||||
RCUWriter<DiskstreamList> writer (diskstreams);
|
||||
boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
|
||||
ds->push_back (dstream);
|
||||
}
|
||||
|
||||
dstream->set_block_size (current_block_size);
|
||||
/* writer goes out of scope, copies ds back to main */
|
||||
}
|
||||
|
||||
dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
|
||||
/* this will connect to future changes, and check the current length */
|
||||
diskstream_playlist_changed (dstream);
|
||||
|
||||
dstream->prepare ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -3383,7 +3387,11 @@ Session::graph_reordered ()
|
||||
we were connecting. do it now.
|
||||
*/
|
||||
|
||||
request_input_change_handling ();
|
||||
boost::shared_ptr<DiskstreamList> ds = diskstreams.reader();
|
||||
|
||||
for (DiskstreamList::iterator i = ds->begin(); i != ds->end(); ++i) {
|
||||
request_input_change_handling (*i);
|
||||
}
|
||||
|
||||
resort_routes ();
|
||||
|
||||
|
@ -410,6 +410,18 @@ Session::process_event (Event* ev)
|
||||
|
||||
case Event::InputConfigurationChange:
|
||||
post_transport_work = PostTransportWork (post_transport_work | PostTransportInputChange);
|
||||
{
|
||||
RCUWriter<DiskstreamList> writer (diskstreams);
|
||||
boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
|
||||
ds->remove (ev->diskstream);
|
||||
/* writer goes out of scope, copies ds back to main */
|
||||
}
|
||||
{
|
||||
RCUWriter<DiskstreamList> writer (diskstreams_input_pending);
|
||||
boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
|
||||
ds->push_back (ev->diskstream);
|
||||
/* writer goes out of scope, copies ds back to main */
|
||||
}
|
||||
schedule_butler_transport_work ();
|
||||
break;
|
||||
|
||||
|
@ -49,10 +49,11 @@ using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
Session::request_input_change_handling ()
|
||||
Session::request_input_change_handling (boost::shared_ptr<Diskstream> ds)
|
||||
{
|
||||
if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
|
||||
Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
|
||||
ev->diskstream = ds;
|
||||
queue_event (ev);
|
||||
}
|
||||
}
|
||||
@ -196,9 +197,27 @@ Session::butler_transport_work ()
|
||||
}
|
||||
|
||||
if (post_transport_work & PostTransportInputChange) {
|
||||
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
|
||||
(*i)->non_realtime_input_change ();
|
||||
{
|
||||
RCUWriter<DiskstreamList> input_writer (diskstreams_input_pending);
|
||||
boost::shared_ptr<DiskstreamList> input_list = input_writer.get_copy ();
|
||||
RCUWriter<DiskstreamList> dswriter (diskstreams);
|
||||
boost::shared_ptr<DiskstreamList> ds = dswriter.get_copy();
|
||||
|
||||
for (DiskstreamList::iterator i = input_list->begin(); i != input_list->end(); ++i) {
|
||||
|
||||
/* make the change */
|
||||
|
||||
(*i)->non_realtime_input_change ();
|
||||
|
||||
/* now transfer it back onto the regular diskstreams list */
|
||||
|
||||
ds->push_back (*i);
|
||||
}
|
||||
|
||||
input_list->clear();
|
||||
}
|
||||
|
||||
diskstreams_input_pending.flush ();
|
||||
}
|
||||
|
||||
if (post_transport_work & PostTransportSpeed) {
|
||||
|
Loading…
Reference in New Issue
Block a user