mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-22 06:36:29 +01:00
fix abort-capture path, including many subtle issues with shared_ptr<>; remove old automation feedback code; make new automation feedback code slightly configurable ; fix zoom focus options for playhead + edit cursor ; prevent zoom < 2 samples per pixel to avoid crashes ; peak building now uses shared_ptr<Source> not Source*
git-svn-id: svn://localhost/ardour2/trunk@959 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
8011cbf5f8
commit
0d0f71ee92
37 changed files with 287 additions and 292 deletions
|
|
@ -178,7 +178,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
|
|||
gettimeofday (&last_peak_grab, 0);
|
||||
gettimeofday (&last_shuttle_request, 0);
|
||||
|
||||
ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
|
||||
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
|
||||
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
|
||||
|
||||
|
|
@ -1041,8 +1040,7 @@ ARDOUR_UI::transport_record ()
|
|||
switch (session->record_status()) {
|
||||
case Session::Disabled:
|
||||
if (session->ntracks() == 0) {
|
||||
string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
|
||||
MessageDialog msg (*editor, txt);
|
||||
MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
|
||||
msg.run ();
|
||||
return;
|
||||
}
|
||||
|
|
@ -2197,18 +2195,6 @@ ARDOUR_UI::halt_on_xrun_message ()
|
|||
msg.run ();
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >* deletion_list)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
|
||||
|
||||
for (list<boost::shared_ptr<Source> >::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
|
||||
(*i)->drop_references ();
|
||||
}
|
||||
|
||||
delete deletion_list;
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::disk_overrun_handler ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -624,8 +624,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
|||
struct timeval last_peak_grab;
|
||||
struct timeval last_shuttle_request;
|
||||
|
||||
void delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >*);
|
||||
|
||||
void editor_display_control_changed (Editing::DisplayControl c);
|
||||
|
||||
bool have_disk_overrun_displayed;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
|
|||
void
|
||||
AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
|
||||
{
|
||||
AudioRegionView *region_view;
|
||||
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
|
||||
|
||||
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
|
||||
|
|
@ -136,10 +138,7 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
|
|||
return;
|
||||
}
|
||||
|
||||
AudioRegionView *region_view;
|
||||
list<RegionView *>::iterator i;
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if ((*i)->region() == r) {
|
||||
|
||||
/* great. we already have a AudioRegionView for this Region. use it again. */
|
||||
|
|
@ -170,15 +169,21 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
|
|||
|
||||
/* catch regionview going away */
|
||||
|
||||
region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), region));
|
||||
region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
|
||||
|
||||
RegionViewAdded (region_view);
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::remove_region_view (boost::shared_ptr<Region> r)
|
||||
AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), r));
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), weak_r));
|
||||
|
||||
boost::shared_ptr<Region> r (weak_r.lock());
|
||||
|
||||
if (!r) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
|
||||
list<CrossfadeView*>::iterator tmp;
|
||||
|
|
@ -406,7 +411,7 @@ AudioStreamView::setup_rec_box ()
|
|||
boost::shared_ptr<AudioFileSource> src = boost::static_pointer_cast<AudioFileSource> (ads->write_source (n));
|
||||
if (src) {
|
||||
sources.push_back (src);
|
||||
peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src)));
|
||||
peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), boost::weak_ptr<Source>(src))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -420,11 +425,8 @@ AudioStreamView::setup_rec_box ()
|
|||
boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion>
|
||||
(RegionFactory::create (sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false)));
|
||||
region->set_position (_trackview.session().transport_frame(), this);
|
||||
|
||||
rec_regions.push_back (region);
|
||||
|
||||
// rec regions are destroyed in setup_rec_box
|
||||
|
||||
/* we add the region later */
|
||||
}
|
||||
|
||||
/* start a new rec box */
|
||||
|
|
@ -504,12 +506,8 @@ AudioStreamView::setup_rec_box ()
|
|||
|
||||
/* remove temp regions */
|
||||
|
||||
for (list<boost::shared_ptr<Region> >::iterator iter = rec_regions.begin(); iter != rec_regions.end();) {
|
||||
list<boost::shared_ptr<Region> >::iterator tmp;
|
||||
tmp = iter;
|
||||
++tmp;
|
||||
for (list<boost::shared_ptr<Region> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); ++iter) {
|
||||
(*iter)->drop_references ();
|
||||
iter = tmp;
|
||||
}
|
||||
|
||||
rec_regions.clear();
|
||||
|
|
@ -537,11 +535,17 @@ AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
|
|||
}
|
||||
|
||||
void
|
||||
AudioStreamView::rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::shared_ptr<Source> src)
|
||||
AudioStreamView::rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<Source> weak_src)
|
||||
{
|
||||
// this is called from the peak building thread
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, weak_src));
|
||||
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src));
|
||||
boost::shared_ptr<Source> src (weak_src.lock());
|
||||
|
||||
if (!src) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this is called from the peak building thread
|
||||
|
||||
if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
|
||||
last_rec_peak_frame = start + cnt;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <map>
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
#include <ardour/location.h>
|
||||
#include "enums.h"
|
||||
#include "simplerect.h"
|
||||
|
|
@ -76,13 +78,12 @@ class AudioStreamView : public StreamView
|
|||
|
||||
private:
|
||||
void setup_rec_box ();
|
||||
void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::shared_ptr<ARDOUR::Source> src);
|
||||
void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src);
|
||||
void update_rec_regions ();
|
||||
|
||||
void add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
|
||||
void remove_region_view (boost::shared_ptr<ARDOUR::Region> );
|
||||
void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
|
||||
void remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
|
||||
void remove_audio_rec_region (boost::shared_ptr<ARDOUR::AudioRegion>);
|
||||
|
||||
void undisplay_diskstream ();
|
||||
void redisplay_diskstream ();
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ static const gchar *zoom_focus_strings[] = {
|
|||
N_("Focus Left"),
|
||||
N_("Focus Right"),
|
||||
N_("Focus Center"),
|
||||
N_("Focus Play"),
|
||||
N_("Focus Edit"),
|
||||
N_("Focus Playhead"),
|
||||
N_("Focus Edit Cursor"),
|
||||
0
|
||||
};
|
||||
|
||||
|
|
@ -801,8 +801,8 @@ Editor::set_frames_per_unit (double fpu)
|
|||
return;
|
||||
}
|
||||
|
||||
if (fpu < 1.0) {
|
||||
fpu = 1.0;
|
||||
if (fpu < 2.0) {
|
||||
fpu = 2.0;
|
||||
}
|
||||
|
||||
// convert fpu to frame count
|
||||
|
|
@ -817,6 +817,10 @@ Editor::set_frames_per_unit (double fpu)
|
|||
return;
|
||||
}
|
||||
|
||||
if (fpu == frames_per_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
frames_per_unit = fpu;
|
||||
|
||||
if (frames != zoom_range_clock.current_duration()) {
|
||||
|
|
|
|||
|
|
@ -164,9 +164,11 @@ StreamView::add_region_view (boost::shared_ptr<Region> r)
|
|||
}
|
||||
|
||||
void
|
||||
StreamView::remove_region_view (boost::shared_ptr<Region> r)
|
||||
StreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), r));
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), weak_r));
|
||||
|
||||
boost::shared_ptr<Region> r (weak_r.lock());
|
||||
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (((*i)->region()) == r) {
|
||||
|
|
@ -177,27 +179,6 @@ StreamView::remove_region_view (boost::shared_ptr<Region> r)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
(unused)
|
||||
void
|
||||
StreamView::remove_rec_region (boost::shared_ptr<Region> r)
|
||||
{
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &StreamView::remove_rec_region), r));
|
||||
|
||||
if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {
|
||||
fatal << "region deleted from non-GUI thread!" << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
for (list<boost::shared_ptr<Region> >::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
|
||||
if (*i == r) {
|
||||
rec_regions.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
StreamView::undisplay_diskstream ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ protected:
|
|||
virtual void update_rec_regions () = 0;
|
||||
|
||||
virtual void add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves) = 0;
|
||||
virtual void remove_region_view (boost::shared_ptr<ARDOUR::Region> );
|
||||
virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
|
||||
//void remove_rec_region (boost::shared_ptr<ARDOUR::Region>); (unused)
|
||||
|
||||
void display_diskstream (boost::shared_ptr<ARDOUR::Diskstream>);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ class AudioFileSource : public AudioSource {
|
|||
static void set_search_path (string);
|
||||
static void set_header_position_offset (nframes_t offset );
|
||||
|
||||
int setup_peakfile ();
|
||||
|
||||
static sigc::signal<void> HeaderPositionOffsetChanged;
|
||||
|
||||
XMLNode& get_state ();
|
||||
|
|
@ -122,6 +124,7 @@ class AudioFileSource : public AudioSource {
|
|||
Flag _flags;
|
||||
string _take_id;
|
||||
uint64_t timeline_position;
|
||||
bool file_is_new;
|
||||
|
||||
static string peak_dir;
|
||||
static string search_path;
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ class AudioRegion : public Region
|
|||
void envelope_changed (Change);
|
||||
void source_offset_changed ();
|
||||
|
||||
void source_deleted (boost::shared_ptr<Source>);
|
||||
void source_deleted ();
|
||||
|
||||
SourceList sources;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
|
@ -44,7 +47,7 @@ namespace ARDOUR {
|
|||
|
||||
const nframes_t frames_per_peak = 256;
|
||||
|
||||
class AudioSource : public Source
|
||||
class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource>
|
||||
{
|
||||
public:
|
||||
AudioSource (Session&, string name);
|
||||
|
|
@ -104,6 +107,8 @@ class AudioSource : public Source
|
|||
_build_peakfiles = yn;
|
||||
}
|
||||
|
||||
virtual int setup_peakfile () { return 0; }
|
||||
|
||||
protected:
|
||||
static bool _build_missing_peakfiles;
|
||||
static bool _build_peakfiles;
|
||||
|
|
@ -143,10 +148,10 @@ class AudioSource : public Source
|
|||
};
|
||||
};
|
||||
|
||||
static vector<AudioSource*> pending_peak_sources;
|
||||
static vector<boost::shared_ptr<AudioSource> > pending_peak_sources;
|
||||
static Glib::Mutex* pending_peak_sources_lock;
|
||||
|
||||
static void queue_for_peaks (AudioSource*);
|
||||
static void queue_for_peaks (boost::shared_ptr<AudioSource>);
|
||||
static void clear_queue_for_peaks ();
|
||||
|
||||
struct PeakBuildRecord {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,6 @@ class IO;
|
|||
|
||||
static sigc::signal<void> DiskOverrun;
|
||||
static sigc::signal<void> DiskUnderrun;
|
||||
static sigc::signal<void,std::list<boost::shared_ptr<Source> >*> DeleteSources;
|
||||
|
||||
protected:
|
||||
friend class Session;
|
||||
|
|
|
|||
|
|
@ -157,7 +157,6 @@ class PluginInsert : public Insert
|
|||
nframes_t latency();
|
||||
|
||||
void transport_stopped (nframes_t now);
|
||||
void automation_snapshot (nframes_t now);
|
||||
|
||||
protected:
|
||||
void store_state (PluginInsertState&) const;
|
||||
|
|
|
|||
|
|
@ -234,16 +234,7 @@ public:
|
|||
AutoStyle gain_automation_style () const { return _gain_automation_curve.automation_style(); }
|
||||
sigc::signal<void> gain_automation_style_changed;
|
||||
|
||||
static void set_automation_interval (nframes_t frames) {
|
||||
_automation_interval = frames;
|
||||
}
|
||||
|
||||
static nframes_t automation_interval() {
|
||||
return _automation_interval;
|
||||
}
|
||||
|
||||
virtual void transport_stopped (nframes_t now);
|
||||
virtual void automation_snapshot (nframes_t now);
|
||||
|
||||
ARDOUR::Curve& gain_automation_curve () { return _gain_automation_curve; }
|
||||
|
||||
|
|
@ -310,11 +301,6 @@ public:
|
|||
Change restore_state (State&);
|
||||
StateManager::State* state_factory (std::string why) const;
|
||||
|
||||
/* automation */
|
||||
|
||||
nframes_t last_automation_snapshot;
|
||||
static nframes_t _automation_interval;
|
||||
|
||||
AutoState _gain_automation_state;
|
||||
AutoStyle _gain_automation_style;
|
||||
|
||||
|
|
|
|||
|
|
@ -238,8 +238,6 @@ class Route : public IO
|
|||
return _mute_control;
|
||||
}
|
||||
|
||||
void automation_snapshot (nframes_t now);
|
||||
|
||||
void protect_automation ();
|
||||
|
||||
void set_remote_control_id (uint32_t id);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ class SourceFactory {
|
|||
// MIDI sources will have to be hacked in here somehow
|
||||
static boost::shared_ptr<Source> createReadable (Session&, std::string idstr, AudioFileSource::Flag flags, bool announce = true);
|
||||
static boost::shared_ptr<Source> createWritable (Session&, std::string name, bool destructive, nframes_t rate, bool announce = true);
|
||||
|
||||
private:
|
||||
static int setup_peakfile (boost::shared_ptr<Source>);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1484,30 +1484,22 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
|||
|
||||
if (abort_capture) {
|
||||
|
||||
ChannelList::iterator chan;
|
||||
if (destructive()) {
|
||||
goto outout;
|
||||
}
|
||||
|
||||
list<boost::shared_ptr<Source> >* deletion_list = new list<boost::shared_ptr<Source> >;
|
||||
|
||||
for ( chan = channels.begin(); chan != channels.end(); ++chan) {
|
||||
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
|
||||
|
||||
if ((*chan).write_source) {
|
||||
|
||||
(*chan).write_source->mark_for_remove ();
|
||||
|
||||
deletion_list->push_back ((*chan).write_source);
|
||||
|
||||
(*chan).write_source->drop_references ();
|
||||
(*chan).write_source.reset ();
|
||||
}
|
||||
|
||||
/* new source set up in "out" below */
|
||||
}
|
||||
|
||||
if (!deletion_list->empty()) {
|
||||
DeleteSources (deletion_list);
|
||||
} else {
|
||||
delete deletion_list;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1606,9 +1598,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
|||
|
||||
mark_write_completed = true;
|
||||
|
||||
out:
|
||||
reset_write_sources (mark_write_completed);
|
||||
|
||||
out:
|
||||
outout:
|
||||
|
||||
for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||
delete *ci;
|
||||
}
|
||||
|
|
@ -1933,13 +1927,8 @@ AudioDiskstream::use_new_write_source (uint32_t n)
|
|||
ChannelInfo &chan = channels[n];
|
||||
|
||||
if (chan.write_source) {
|
||||
|
||||
if (AudioFileSource::is_empty (_session, chan.write_source->path())) {
|
||||
chan.write_source->mark_for_remove ();
|
||||
chan.write_source->set_allow_remove_if_empty (true);
|
||||
chan.write_source.reset ();
|
||||
} else {
|
||||
chan.write_source.reset ();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -507,15 +507,6 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
|||
nframes_t transport_frame;
|
||||
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
|
||||
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
|
||||
if (lm.locked()) {
|
||||
// automation snapshot can also be called from the non-rt context
|
||||
// and it uses the redirect list, so we take the lock out here
|
||||
automation_snapshot (start_frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (n_outputs() == 0 && _redirects.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,11 @@ string AudioFileSource::search_path;
|
|||
sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged;
|
||||
uint64_t AudioFileSource::header_position_offset = 0;
|
||||
|
||||
/* XXX turn this into a Config option */
|
||||
char AudioFileSource::bwf_country_code[3] = "US";
|
||||
/* XXX turn this into a Config option */
|
||||
char AudioFileSource::bwf_organization_code[4] = "LAS";
|
||||
/* XXX maybe this too */
|
||||
char AudioFileSource::bwf_serial_number[13] = "000000000000";
|
||||
|
||||
AudioFileSource::AudioFileSource (Session& s, string idstr, Flag flags)
|
||||
|
|
@ -120,6 +123,8 @@ AudioFileSource::init (string pathstr, bool must_exist)
|
|||
_length = 0;
|
||||
timeline_position = 0;
|
||||
next_peak_clear_should_notify = false;
|
||||
_peaks_built = false;
|
||||
file_is_new = false;
|
||||
|
||||
if (!find (pathstr, must_exist, is_new)) {
|
||||
return -1;
|
||||
|
|
@ -285,7 +290,8 @@ AudioFileSource::mark_for_remove ()
|
|||
if (!writable()) {
|
||||
return;
|
||||
}
|
||||
_flags = Flag (_flags | RemoveAtDestroy);
|
||||
|
||||
_flags = Flag (_flags | Removable | RemoveAtDestroy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -518,8 +524,14 @@ AudioFileSource::set_timeline_position (nframes_t pos)
|
|||
void
|
||||
AudioFileSource::set_allow_remove_if_empty (bool yn)
|
||||
{
|
||||
if (writable()) {
|
||||
if (!writable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (yn) {
|
||||
_flags = Flag (_flags | RemovableIfEmpty);
|
||||
} else {
|
||||
_flags = Flag (_flags & ~RemovableIfEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -565,3 +577,12 @@ AudioFileSource::is_empty (Session& s, string path)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
AudioFileSource::setup_peakfile ()
|
||||
{
|
||||
if (!(_flags & NoPeakFile)) {
|
||||
return initialize_peakfile (file_is_new, _path);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
|
|||
|
||||
sources.push_back (src);
|
||||
master_sources.push_back (src);
|
||||
src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
|
||||
src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
|
||||
if (afs) {
|
||||
|
|
@ -102,7 +102,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
|
|||
|
||||
sources.push_back (src);
|
||||
master_sources.push_back (src);
|
||||
src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
|
||||
src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
|
||||
if (afs) {
|
||||
|
|
@ -129,7 +129,7 @@ AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, c
|
|||
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
|
||||
sources.push_back (*i);
|
||||
master_sources.push_back (*i);
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), (*i)));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
|
||||
if (afs) {
|
||||
|
|
@ -159,7 +159,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
|
|||
|
||||
for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) {
|
||||
sources.push_back (*i);
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
|
|||
|
||||
for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
|
||||
if (unique_srcs.find (*i) == unique_srcs.end()) {
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
}
|
||||
master_sources.push_back (*i);
|
||||
}
|
||||
|
|
@ -224,7 +224,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
|
|||
|
||||
for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
|
||||
sources.push_back (*i);
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
|
||||
|
||||
result = unique_srcs.insert (*i);
|
||||
|
|
@ -240,7 +240,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
|
|||
for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
|
||||
master_sources.push_back (*i);
|
||||
if (unique_srcs.find (*i) == unique_srcs.end()) {
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod
|
|||
{
|
||||
sources.push_back (src);
|
||||
master_sources.push_back (src);
|
||||
src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
|
||||
src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
|
||||
if (afs) {
|
||||
|
|
@ -291,7 +291,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
|
|||
|
||||
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
|
||||
sources.push_back (*i);
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
|
||||
|
||||
result = unique_srcs.insert (*i);
|
||||
|
|
@ -307,7 +307,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
|
|||
for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
|
||||
master_sources.push_back (*i);
|
||||
if (unique_srcs.find (*i) == unique_srcs.end()) {
|
||||
(*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
|
||||
(*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1117,9 +1117,10 @@ AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) con
|
|||
}
|
||||
|
||||
void
|
||||
AudioRegion::source_deleted (boost::shared_ptr<Source> ignored)
|
||||
AudioRegion::source_deleted ()
|
||||
{
|
||||
delete this;
|
||||
sources.clear ();
|
||||
drop_references ();
|
||||
}
|
||||
|
||||
vector<string>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ using namespace PBD;
|
|||
|
||||
pthread_t AudioSource::peak_thread;
|
||||
bool AudioSource::have_peak_thread = false;
|
||||
vector<AudioSource*> AudioSource::pending_peak_sources;
|
||||
vector<boost::shared_ptr<AudioSource> > AudioSource::pending_peak_sources;
|
||||
Glib::Mutex* AudioSource::pending_peak_sources_lock = 0;
|
||||
int AudioSource::peak_request_pipe[2];
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ AudioSource::peak_thread_work (void* arg)
|
|||
|
||||
while (!pending_peak_sources.empty()) {
|
||||
|
||||
AudioSource* s = pending_peak_sources.front();
|
||||
boost::shared_ptr<AudioSource> s = pending_peak_sources.front();
|
||||
pending_peak_sources.erase (pending_peak_sources.begin());
|
||||
|
||||
pending_peak_sources_lock->unlock ();
|
||||
|
|
@ -251,7 +251,7 @@ AudioSource::stop_peak_thread ()
|
|||
}
|
||||
|
||||
void
|
||||
AudioSource::queue_for_peaks (AudioSource* source)
|
||||
AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source)
|
||||
{
|
||||
if (have_peak_thread) {
|
||||
|
||||
|
|
@ -847,7 +847,7 @@ AudioSource::build_peaks_from_scratch ()
|
|||
|
||||
next_peak_clear_should_notify = true;
|
||||
pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
|
||||
queue_for_peaks (this);
|
||||
queue_for_peaks (shared_from_this());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -86,10 +86,7 @@ CoreAudioSource::init (const string& idstr)
|
|||
}
|
||||
|
||||
if (_build_peakfiles) {
|
||||
if (initialize_peakfile (false, _path)) {
|
||||
error << string_compose("CoreAudioSource: initialize peakfile failed (%1)", name()) << endmsg;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
_need_peakfile = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ DestructiveFileSource::write_unlocked (Sample* data, nframes_t cnt)
|
|||
}
|
||||
|
||||
if (_build_peakfiles) {
|
||||
queue_for_peaks (this);
|
||||
queue_for_peaks (shared_from_this ());
|
||||
}
|
||||
|
||||
return cnt;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ using namespace PBD;
|
|||
*/
|
||||
nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
|
||||
|
||||
sigc::signal<void,list<boost::shared_ptr<Source> >*> Diskstream::DeleteSources;
|
||||
sigc::signal<void> Diskstream::DiskOverrun;
|
||||
sigc::signal<void> Diskstream::DiskUnderrun;
|
||||
|
||||
|
|
|
|||
|
|
@ -316,23 +316,6 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
|
|||
/* leave remaining channel buffers alone */
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::automation_snapshot (nframes_t now)
|
||||
{
|
||||
map<uint32_t,AutomationList*>::iterator li;
|
||||
|
||||
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
|
||||
|
||||
AutomationList *alist = ((*li).second);
|
||||
if (alist != 0 && alist->automation_write ()) {
|
||||
|
||||
float val = _plugins[0]->get_parameter ((*li).first);
|
||||
alist->rt_add (now, val);
|
||||
last_automation_snapshot = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::transport_stopped (nframes_t now)
|
||||
{
|
||||
|
|
@ -468,7 +451,6 @@ PluginInsert::set_port_automation_state (uint32_t port, AutoState s)
|
|||
|
||||
if (s != al.automation_state()) {
|
||||
al.set_automation_state (s);
|
||||
last_automation_snapshot = 0;
|
||||
_session.set_dirty ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ using namespace PBD;
|
|||
|
||||
static float current_automation_version_number = 1.0;
|
||||
|
||||
nframes_t IO::_automation_interval = 0;
|
||||
const string IO::state_node_name = "IO";
|
||||
bool IO::connecting_legal = false;
|
||||
bool IO::ports_legal = false;
|
||||
|
|
@ -127,8 +126,6 @@ IO::IO (Session& s, string name,
|
|||
|
||||
apply_gain_automation = false;
|
||||
|
||||
last_automation_snapshot = 0;
|
||||
|
||||
_gain_automation_state = Off;
|
||||
_gain_automation_style = Absolute;
|
||||
|
||||
|
|
@ -2513,7 +2510,6 @@ IO::set_gain_automation_state (AutoState state)
|
|||
|
||||
if (state != _gain_automation_curve.automation_state()) {
|
||||
changed = true;
|
||||
last_automation_snapshot = 0;
|
||||
_gain_automation_curve.set_automation_state (state);
|
||||
|
||||
if (state != Off) {
|
||||
|
|
@ -2611,21 +2607,6 @@ IO::end_pan_touch (uint32_t which)
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
IO::automation_snapshot (nframes_t now)
|
||||
{
|
||||
if (last_automation_snapshot > now || (now - last_automation_snapshot) > _automation_interval) {
|
||||
|
||||
if (gain_automation_recording()) {
|
||||
_gain_automation_curve.rt_add (now, gain());
|
||||
}
|
||||
|
||||
_panner->snapshot (now);
|
||||
|
||||
last_automation_snapshot = now;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IO::transport_stopped (nframes_t frame)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1373,10 +1373,21 @@ Playlist::set_state (const XMLNode& node)
|
|||
|
||||
if (child->name() == "Region") {
|
||||
|
||||
#if 0
|
||||
if ((prop = child->property ("id")) == 0) {
|
||||
error << _("region state node has no ID, ignored") << endmsg;
|
||||
continue;
|
||||
}
|
||||
|
||||
ID id = prop->value ();
|
||||
|
||||
if ((region = region_by_id (id)) == 0) {
|
||||
#endif
|
||||
if ((region = RegionFactory::create (_session, *child, true)) == 0) {
|
||||
error << _("Playlist: cannot create region from state file") << endmsg;
|
||||
continue;
|
||||
}
|
||||
// }
|
||||
|
||||
add_region (region, region->position(), 1.0, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1959,10 +1959,6 @@ Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_f
|
|||
{
|
||||
Glib::RWLock::ReaderLock lm (redirect_lock);
|
||||
|
||||
if (!did_locate) {
|
||||
automation_snapshot (now);
|
||||
}
|
||||
|
||||
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
|
||||
|
||||
if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
|
||||
|
|
@ -2075,15 +2071,6 @@ int
|
|||
Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
|
||||
bool can_record, bool rec_monitors_input)
|
||||
{
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
|
||||
if (lm.locked()) {
|
||||
// automation snapshot can also be called from the non-rt context
|
||||
// and it uses the redirect list, so we take the lock out here
|
||||
automation_snapshot (_session.transport_frame());
|
||||
}
|
||||
}
|
||||
|
||||
if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
|
||||
silence (nframes, offset);
|
||||
return 0;
|
||||
|
|
@ -2220,16 +2207,6 @@ Route::set_latency_delay (nframes_t longest_session_latency)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Route::automation_snapshot (nframes_t now)
|
||||
{
|
||||
IO::automation_snapshot (now);
|
||||
|
||||
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
|
||||
(*i)->automation_snapshot (now);
|
||||
}
|
||||
}
|
||||
|
||||
Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
|
||||
: Controllable (name), route (s), type(tp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1220,8 +1220,8 @@ Session::maybe_enable_record ()
|
|||
{
|
||||
g_atomic_int_set (&_record_status, Enabled);
|
||||
|
||||
/* XXX this save should really happen in another thread. its needed so that
|
||||
pending capture state can be recovered if we crash.
|
||||
/* this function is currently called from somewhere other than an RT thread.
|
||||
this save_state() call therefore doesn't impact anything.
|
||||
*/
|
||||
|
||||
save_state ("", true);
|
||||
|
|
@ -1310,8 +1310,6 @@ Session::set_frame_rate (nframes_t frames_per_second)
|
|||
|
||||
sync_time_vars();
|
||||
|
||||
Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
|
||||
|
||||
// XXX we need some equivalent to this, somehow
|
||||
// DestructiveFileSource::setup_standard_crossfades (frames_per_second);
|
||||
|
||||
|
|
@ -2480,6 +2478,7 @@ Session::remove_region (boost::shared_ptr<Region> region)
|
|||
if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
|
||||
audio_regions.erase (i);
|
||||
removed = true;
|
||||
cerr << "done\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -2642,9 +2641,8 @@ Session::remove_source (boost::weak_ptr<Source> src)
|
|||
boost::shared_ptr<Source> source = src.lock();
|
||||
|
||||
if (!source) {
|
||||
cerr << "removing a source DEAD\n";
|
||||
} else {
|
||||
cerr << "removing a source " << source->name () << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock lm (audio_source_lock);
|
||||
|
|
@ -2664,7 +2662,6 @@ Session::remove_source (boost::weak_ptr<Source> src)
|
|||
}
|
||||
|
||||
SourceRemoved(source); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Source>
|
||||
|
|
|
|||
|
|
@ -161,7 +161,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
|||
mmc = 0;
|
||||
session_send_mmc = false;
|
||||
session_send_mtc = false;
|
||||
session_midi_feedback = false;
|
||||
post_transport_work = PostTransportWork (0);
|
||||
g_atomic_int_set (&butler_should_do_transport_work, 0);
|
||||
g_atomic_int_set (&butler_active, 0);
|
||||
|
|
|
|||
|
|
@ -261,8 +261,10 @@ Session::non_realtime_stop (bool abort)
|
|||
struct tm* now;
|
||||
time_t xnow;
|
||||
bool did_record;
|
||||
bool saved;
|
||||
|
||||
did_record = false;
|
||||
saved = false;
|
||||
|
||||
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
|
||||
|
||||
|
|
@ -401,6 +403,7 @@ Session::non_realtime_stop (bool abort)
|
|||
if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
|
||||
/* capture start has been changed, so save pending state */
|
||||
save_state ("", true);
|
||||
saved = true;
|
||||
}
|
||||
|
||||
/* always try to get rid of this */
|
||||
|
|
@ -409,7 +412,7 @@ Session::non_realtime_stop (bool abort)
|
|||
|
||||
/* save the current state of things if appropriate */
|
||||
|
||||
if (did_record) {
|
||||
if (did_record && !saved) {
|
||||
save_state (_current_snapshot_name);
|
||||
}
|
||||
|
||||
|
|
@ -812,9 +815,11 @@ Session::stop_transport (bool abort)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((transport_sub_state & PendingDeclickOut) == 0) {
|
||||
transport_sub_state |= PendingDeclickOut;
|
||||
/* we'll be called again after the declick */
|
||||
pending_abort = abort;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,14 +43,6 @@ SndFileSource::SndFileSource (Session& s, const XMLNode& node)
|
|||
if (open()) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if (_build_peakfiles) {
|
||||
if (initialize_peakfile (false, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
|
||||
|
|
@ -62,14 +54,6 @@ SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
|
|||
if (open()) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if (!(_flags & NoPeakFile) && _build_peakfiles) {
|
||||
if (initialize_peakfile (false, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
|
||||
|
|
@ -79,6 +63,12 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade
|
|||
|
||||
init (idstr);
|
||||
|
||||
/* this constructor is used to construct new files, not open
|
||||
existing ones.
|
||||
*/
|
||||
|
||||
file_is_new = true;
|
||||
|
||||
switch (hf) {
|
||||
case CAF:
|
||||
fmt = SF_FORMAT_CAF;
|
||||
|
|
@ -171,14 +161,6 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
if (!(_flags & NoPeakFile) && _build_peakfiles) {
|
||||
if (initialize_peakfile (true, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -413,7 +395,7 @@ SndFileSource::write_unlocked (Sample *data, nframes_t cnt)
|
|||
|
||||
|
||||
if (_build_peakfiles) {
|
||||
queue_for_peaks (this);
|
||||
queue_for_peaks (shared_from_this ());
|
||||
}
|
||||
|
||||
_write_data_count = cnt;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include <ardour/source_factory.h>
|
||||
#include <ardour/sndfilesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
|
|
@ -31,9 +33,24 @@
|
|||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated;
|
||||
|
||||
int
|
||||
SourceFactory::setup_peakfile (boost::shared_ptr<Source> s)
|
||||
{
|
||||
boost::shared_ptr<AudioSource> as (boost::dynamic_pointer_cast<AudioSource> (s));
|
||||
if (as) {
|
||||
if (as->setup_peakfile ()) {
|
||||
error << string_compose("SourceFactory: could not set up peakfile for %1", as->name()) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
boost::shared_ptr<Source>
|
||||
SourceFactory::create (Session& s, const XMLNode& node)
|
||||
|
|
@ -41,6 +58,9 @@ SourceFactory::create (Session& s, const XMLNode& node)
|
|||
if (node.property (X_("destructive")) != 0) {
|
||||
|
||||
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
SourceCreated (ret);
|
||||
return ret;
|
||||
|
||||
|
|
@ -48,6 +68,9 @@ SourceFactory::create (Session& s, const XMLNode& node)
|
|||
|
||||
try {
|
||||
boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
SourceCreated (ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -55,6 +78,9 @@ SourceFactory::create (Session& s, const XMLNode& node)
|
|||
|
||||
catch (failed_constructor& err) {
|
||||
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
SourceCreated (ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -71,12 +97,18 @@ SourceFactory::create (Session& s, const XMLNode& node)
|
|||
if (node.property (X_("destructive")) != 0) {
|
||||
|
||||
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
SourceCreated (ret);
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
|
||||
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
SourceCreated (ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -90,6 +122,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
|
|||
{
|
||||
if (flags & Destructive) {
|
||||
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, idstr, flags));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
@ -98,6 +133,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
|
|||
|
||||
try {
|
||||
boost::shared_ptr<Source> ret (new CoreAudioSource (s, idstr, flags));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
@ -106,6 +144,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
|
|||
|
||||
catch (failed_constructor& err) {
|
||||
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
@ -121,6 +162,9 @@ boost::shared_ptr<Source>
|
|||
SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
|
||||
{
|
||||
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
@ -139,6 +183,9 @@ SourceFactory::createWritable (Session& s, std::string path, bool destructive, n
|
|||
Config->get_native_file_data_format(),
|
||||
Config->get_native_file_header_format(),
|
||||
rate));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
@ -149,6 +196,9 @@ SourceFactory::createWritable (Session& s, std::string path, bool destructive, n
|
|||
Config->get_native_file_data_format(),
|
||||
Config->get_native_file_header_format(),
|
||||
rate));
|
||||
if (setup_peakfile (ret)) {
|
||||
return boost::shared_ptr<Source>();
|
||||
}
|
||||
if (announce) {
|
||||
SourceCreated (ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include <ostream>
|
||||
|
||||
namespace PBD {
|
||||
void stacktrace (std::ostream& out);
|
||||
void stacktrace (std::ostream& out, int levels = 0);
|
||||
}
|
||||
|
||||
#endif /* __libpbd_stacktrace_h__ */
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
PBD::stacktrace (std::ostream& out)
|
||||
PBD::stacktrace (std::ostream& out, int levels)
|
||||
{
|
||||
void *array[200];
|
||||
size_t size;
|
||||
|
|
@ -23,7 +23,7 @@ PBD::stacktrace (std::ostream& out)
|
|||
|
||||
printf ("Obtained %zd stack frames.\n", size);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < size && (levels == 0 || i < levels); i++) {
|
||||
out << strings[i] << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ PBD::stacktrace (std::ostream& out)
|
|||
#else
|
||||
|
||||
void
|
||||
PBD::stacktrace (std::ostream& out)
|
||||
PBD::stacktrace (std::ostream& out, int levels)
|
||||
{
|
||||
out << "stack tracing is not enabled on this platform" << std::endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ class ControlProtocol : public sigc::trackable, public Stateful, public BasicUI
|
|||
virtual int set_active (bool yn) = 0;
|
||||
bool get_active() const { return _active; }
|
||||
|
||||
virtual int set_feedback (bool yn) { return 0; }
|
||||
virtual bool get_feedback () const { return false; }
|
||||
virtual bool supports_feedback () const { return false; }
|
||||
|
||||
sigc::signal<void> ActiveChanged;
|
||||
|
||||
/* signals that a control protocol can emit and other (presumably graphical)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
|||
throw failed_constructor();
|
||||
}
|
||||
|
||||
do_feedback = false;
|
||||
_feedback_interval = 10000; // microseconds
|
||||
last_feedback_time = 0;
|
||||
|
||||
|
|
@ -82,6 +83,10 @@ GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
|
|||
void
|
||||
GenericMidiControlProtocol::send_feedback ()
|
||||
{
|
||||
if (!do_feedback) {
|
||||
return;
|
||||
}
|
||||
|
||||
microseconds_t now = get_microseconds ();
|
||||
|
||||
if (last_feedback_time != 0) {
|
||||
|
|
@ -98,7 +103,7 @@ GenericMidiControlProtocol::send_feedback ()
|
|||
void
|
||||
GenericMidiControlProtocol::_send_feedback ()
|
||||
{
|
||||
const int32_t bufsize = 16 * 1024;
|
||||
const int32_t bufsize = 16 * 1024; /* XXX too big */
|
||||
MIDI::byte buf[bufsize];
|
||||
int32_t bsize = bufsize;
|
||||
MIDI::byte* end = buf;
|
||||
|
|
@ -174,8 +179,12 @@ XMLNode&
|
|||
GenericMidiControlProtocol::get_state ()
|
||||
{
|
||||
XMLNode* node = new XMLNode ("Protocol");
|
||||
char buf[32];
|
||||
|
||||
node->add_property (X_("name"), _name);
|
||||
node->add_property (X_("feedback"), do_feedback ? "1" : "0");
|
||||
snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
|
||||
node->add_property (X_("feedback_interval"), buf);
|
||||
|
||||
XMLNode* children = new XMLNode (X_("controls"));
|
||||
|
||||
|
|
@ -194,6 +203,22 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
|
|||
{
|
||||
XMLNodeList nlist;
|
||||
XMLNodeConstIterator niter;
|
||||
const XMLProperty* prop;
|
||||
|
||||
if ((prop = node.property ("feedback")) != 0) {
|
||||
do_feedback = (bool) atoi (prop->value().c_str());
|
||||
} else {
|
||||
do_feedback = false;
|
||||
}
|
||||
|
||||
if ((prop = node.property ("feedback_interval")) != 0) {
|
||||
if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
|
||||
_feedback_interval = 10000;
|
||||
}
|
||||
} else {
|
||||
_feedback_interval = 10000;
|
||||
}
|
||||
|
||||
Controllable* c;
|
||||
|
||||
{
|
||||
|
|
@ -215,8 +240,6 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
|
|||
|
||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||
|
||||
XMLProperty* prop;
|
||||
|
||||
if ((prop = (*niter)->property ("id")) != 0) {
|
||||
|
||||
ID id = prop->value ();
|
||||
|
|
@ -239,3 +262,17 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GenericMidiControlProtocol::set_feedback (bool yn)
|
||||
{
|
||||
do_feedback = yn;
|
||||
last_feedback_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
GenericMidiControlProtocol::get_feedback () const
|
||||
{
|
||||
return do_feedback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
|||
MIDI::Port* port () const { return _port; }
|
||||
void set_feedback_interval (ARDOUR::microseconds_t);
|
||||
|
||||
int set_feedback (bool yn);
|
||||
bool get_feedback () const;
|
||||
bool supports_feedback () const { return true; }
|
||||
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
|
|
@ -40,6 +44,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
|||
ARDOUR::microseconds_t _feedback_interval;
|
||||
ARDOUR::microseconds_t last_feedback_time;
|
||||
|
||||
bool do_feedback;
|
||||
void _send_feedback ();
|
||||
void send_feedback ();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue