a much better fix for track-add crashes, albeit slightly more complex
git-svn-id: svn://localhost/ardour2/trunk@1604 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
bca0450c18
commit
3e36907353
@ -32,6 +32,7 @@
|
||||
#include <pbd/fastlog.h>
|
||||
#include <pbd/ringbufferNPT.h>
|
||||
#include <pbd/stateful.h>
|
||||
#include <pbd/rcu.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/configuration.h>
|
||||
@ -65,24 +66,28 @@ class AudioDiskstream : public Diskstream
|
||||
float capture_buffer_load() const;
|
||||
|
||||
string input_source (uint32_t n=0) const {
|
||||
if (n < channels.size()) {
|
||||
return channels[n].source ? channels[n].source->name() : "";
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
if (n < c->size()) {
|
||||
return (*c)[n]->source ? (*c)[n]->source->name() : "";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Port *input_source_port (uint32_t n=0) const {
|
||||
if (n < channels.size()) return channels[n].source; return 0;
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
if (n < c->size()) return (*c)[n]->source; return 0;
|
||||
}
|
||||
|
||||
void set_record_enabled (bool yn);
|
||||
int set_destructive (bool yn);
|
||||
bool can_become_destructive (bool& requires_bounce) const;
|
||||
|
||||
float peak_power(uint32_t n=0) {
|
||||
float x = channels[n].peak_power;
|
||||
channels[n].peak_power = 0.0f;
|
||||
float peak_power(uint32_t n = 0) {
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
ChannelInfo* chaninfo = (*c)[n];
|
||||
float x = chaninfo->peak_power;
|
||||
chaninfo->peak_power = 0.0f;
|
||||
if (x > 0.0f) {
|
||||
return 20.0f * fast_log10(x);
|
||||
} else {
|
||||
@ -96,27 +101,29 @@ class AudioDiskstream : public Diskstream
|
||||
int use_new_playlist ();
|
||||
int use_copy_playlist ();
|
||||
|
||||
Sample *playback_buffer (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].current_playback_buffer;
|
||||
Sample *playback_buffer (uint32_t n = 0) {
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
if (n < c->size())
|
||||
return (*c)[n]->current_playback_buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Sample *capture_buffer (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].current_capture_buffer;
|
||||
Sample *capture_buffer (uint32_t n = 0) {
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
if (n < c->size())
|
||||
return (*c)[n]->current_capture_buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].write_source;
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
if (n < c->size())
|
||||
return (*c)[n]->write_source;
|
||||
return boost::shared_ptr<AudioFileSource>();
|
||||
}
|
||||
|
||||
int add_channel ();
|
||||
int remove_channel ();
|
||||
|
||||
int add_channel (uint32_t how_many);
|
||||
int remove_channel (uint32_t how_many);
|
||||
|
||||
/* stateful */
|
||||
|
||||
@ -174,12 +181,9 @@ class AudioDiskstream : public Diskstream
|
||||
|
||||
struct ChannelInfo {
|
||||
|
||||
ChannelInfo ();
|
||||
ChannelInfo (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
|
||||
~ChannelInfo ();
|
||||
|
||||
void init (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
|
||||
void release ();
|
||||
|
||||
Sample *playback_wrap_buffer;
|
||||
Sample *capture_wrap_buffer;
|
||||
Sample *speed_buffer;
|
||||
@ -208,6 +212,8 @@ class AudioDiskstream : public Diskstream
|
||||
nframes_t curr_capture_cnt;
|
||||
};
|
||||
|
||||
typedef std::vector<ChannelInfo*> ChannelList;
|
||||
|
||||
/* The two central butler operations */
|
||||
int do_flush (Session::RunContext context, bool force = false);
|
||||
int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); }
|
||||
@ -215,10 +221,10 @@ class AudioDiskstream : public Diskstream
|
||||
int do_refill_with_alloc ();
|
||||
|
||||
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
|
||||
nframes_t& start, nframes_t cnt,
|
||||
ChannelInfo& channel_info, int channel, bool reversed);
|
||||
nframes_t& start, nframes_t cnt,
|
||||
ChannelInfo* channel_info, int channel, bool reversed);
|
||||
|
||||
void finish_capture (bool rec_monitors_input);
|
||||
void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
|
||||
void transport_stopped (struct tm&, time_t, bool abort);
|
||||
|
||||
void init (Diskstream::Flag);
|
||||
@ -253,12 +259,15 @@ class AudioDiskstream : public Diskstream
|
||||
|
||||
std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
|
||||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
ChannelList channels;
|
||||
SerializedRCUManager<ChannelList> channels;
|
||||
|
||||
/* really */
|
||||
private:
|
||||
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
|
||||
|
||||
int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
|
||||
int remove_channel_from (boost::shared_ptr<ChannelList>, uint32_t how_many);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define __ardour_diskstream_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
@ -54,7 +53,7 @@ class Session;
|
||||
class Playlist;
|
||||
class IO;
|
||||
|
||||
class Diskstream : public PBD::StatefulDestructible, public boost::enable_shared_from_this<ARDOUR::Diskstream>
|
||||
class Diskstream : public PBD::StatefulDestructible
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
@ -207,7 +206,6 @@ class Diskstream : public PBD::StatefulDestructible, public boost::enable_shared
|
||||
virtual void playlist_modified ();
|
||||
virtual void playlist_deleted (boost::weak_ptr<Playlist>);
|
||||
|
||||
virtual void finish_capture (bool rec_monitors_input) = 0;
|
||||
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
|
||||
|
||||
struct CaptureInfo {
|
||||
|
@ -165,7 +165,6 @@ class Session : public PBD::StatefulDestructible
|
||||
};
|
||||
|
||||
boost::shared_ptr<Region> region;
|
||||
boost::shared_ptr<Diskstream> diskstream;
|
||||
|
||||
list<AudioRange> audio_range;
|
||||
list<MusicRange> music_range;
|
||||
@ -362,7 +361,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 (boost::shared_ptr<ARDOUR::Diskstream>);
|
||||
void request_input_change_handling ();
|
||||
|
||||
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
|
||||
bool transport_locked () const;
|
||||
@ -1425,7 +1424,6 @@ 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&);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,7 +64,7 @@ Auditioner::Auditioner (Session& s)
|
||||
}
|
||||
|
||||
if (right.length()) {
|
||||
audio_diskstream()->add_channel();
|
||||
audio_diskstream()->add_channel (1);
|
||||
add_output_port (right, this, DataType::AUDIO);
|
||||
}
|
||||
|
||||
@ -138,12 +138,10 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
|
||||
_diskstream->playlist()->clear ();
|
||||
_diskstream->playlist()->add_region (the_region, 0, 1);
|
||||
|
||||
while (_diskstream->n_channels() < the_region->n_channels()) {
|
||||
audio_diskstream()->add_channel ();
|
||||
}
|
||||
|
||||
while (_diskstream->n_channels() > the_region->n_channels()) {
|
||||
audio_diskstream()->remove_channel ();
|
||||
if (_diskstream->n_channels() < the_region->n_channels()) {
|
||||
audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels());
|
||||
} else if (_diskstream->n_channels() > the_region->n_channels()) {
|
||||
audio_diskstream()->remove_channel (_diskstream->n_channels() - the_region->n_channels());
|
||||
}
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
@ -143,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 (shared_from_this());
|
||||
_session.request_input_change_handling ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,6 @@ 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),
|
||||
@ -333,7 +332,6 @@ Session::Session (AudioEngine &eng,
|
||||
pending_events (2048),
|
||||
midi_requests (16),
|
||||
diskstreams (new DiskstreamList),
|
||||
diskstreams_input_pending (new DiskstreamList),
|
||||
routes (new RouteList),
|
||||
main_outs (0)
|
||||
|
||||
@ -2008,7 +2006,7 @@ Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
|
||||
|
||||
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);
|
||||
@ -3387,11 +3385,7 @@ Session::graph_reordered ()
|
||||
we were connecting. do it now.
|
||||
*/
|
||||
|
||||
boost::shared_ptr<DiskstreamList> ds = diskstreams.reader();
|
||||
|
||||
for (DiskstreamList::iterator i = ds->begin(); i != ds->end(); ++i) {
|
||||
request_input_change_handling (*i);
|
||||
}
|
||||
request_input_change_handling ();
|
||||
|
||||
resort_routes ();
|
||||
|
||||
|
@ -410,18 +410,6 @@ 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,11 +49,10 @@ using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
Session::request_input_change_handling (boost::shared_ptr<Diskstream> ds)
|
||||
Session::request_input_change_handling ()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -197,27 +196,9 @@ Session::butler_transport_work ()
|
||||
}
|
||||
|
||||
if (post_transport_work & PostTransportInputChange) {
|
||||
{
|
||||
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();
|
||||
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
|
||||
(*i)->non_realtime_input_change ();
|
||||
}
|
||||
|
||||
diskstreams_input_pending.flush ();
|
||||
}
|
||||
|
||||
if (post_transport_work & PostTransportSpeed) {
|
||||
|
Loading…
Reference in New Issue
Block a user