Merged with trunk R1304

git-svn-id: svn://localhost/ardour2/branches/midi@1311 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-01-11 19:50:49 +00:00
parent 532f6aad4a
commit f7563c2b15
29 changed files with 512 additions and 396 deletions

View file

@ -844,6 +844,8 @@ if env['SYSLIBS']:
# libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas') # libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
libraries['soundtouch'] = LibraryInfo() libraries['soundtouch'] = LibraryInfo()
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch') libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
# Comment the previous line and uncomment this for Debian:
#libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
libraries['appleutility'] = LibraryInfo(LIBS='libappleutility', libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
LIBPATH='#libs/appleutility', LIBPATH='#libs/appleutility',

View file

@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
. `dirname "$0"`/ardev_common.sh . `dirname "$0"`/ardev_common.sh
exec $EXECUTABLE "$*" exec $EXECUTABLE $*

View file

@ -6,6 +6,13 @@ export LD_LIBRARY_PATH=%INSTALL_PREFIX%/%LIBDIR%/ardour2:$LD_LIBRARY_PATH
# DYLD_LIBRARY_PATH is for Darwin # DYLD_LIBRARY_PATH is for Darwin
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
MLOCK_LIMIT=$(ulimit -l)
if [ "$MLOCK_LIMIT" != "unlimited" ]; then
echo "WARNING: Your system has a limit for maximum amount of locked memory!"
echo "This might cause Ardour to run out of memory before your system runs out of memory. You can view the memory limit with 'ulimit -l', and it is normally controlled by /etc/security/limits.conf"
fi
exec %INSTALL_PREFIX%/%LIBDIR%/ardour2/ardour-%VERSION% $* exec %INSTALL_PREFIX%/%LIBDIR%/ardour2/ardour-%VERSION% $*

View file

@ -39,6 +39,7 @@
#include <pbd/pathscanner.h> #include <pbd/pathscanner.h>
#include <pbd/failed_constructor.h> #include <pbd/failed_constructor.h>
#include <pbd/enumwriter.h> #include <pbd/enumwriter.h>
#include <pbd/stacktrace.h>
#include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/utils.h> #include <gtkmm2ext/utils.h>
#include <gtkmm2ext/click_box.h> #include <gtkmm2ext/click_box.h>
@ -113,7 +114,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
/* big clock */ /* big clock */
big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true), big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
/* transport */ /* transport */
@ -252,9 +253,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
throw failed_constructor(); throw failed_constructor();
} }
/* listen to clock mode changes */ /* set default clock modes */
AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes)); primary_clock.set_mode (AudioClock::SMPTE);
secondary_clock.set_mode (AudioClock::BBT);
/* start the time-of-day-clock */ /* start the time-of-day-clock */
@ -1834,6 +1836,7 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string*
Session *new_session; Session *new_session;
int x; int x;
session_loaded = false; session_loaded = false;
x = unload_session (); x = unload_session ();
if (x < 0) { if (x < 0) {
@ -2447,6 +2450,8 @@ ARDOUR_UI::update_transport_clocks (nframes_t pos)
void void
ARDOUR_UI::record_state_changed () ARDOUR_UI::record_state_changed ()
{ {
ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
if (!session || !big_clock_window) { if (!session || !big_clock_window) {
/* why bother - the clock isn't visible */ /* why bother - the clock isn't visible */
return; return;
@ -2454,10 +2459,10 @@ ARDOUR_UI::record_state_changed ()
switch (session->record_status()) { switch (session->record_status()) {
case Session::Recording: case Session::Recording:
big_clock.set_name ("BigClockRecording"); big_clock.set_widget_name ("BigClockRecording");
break; break;
default: default:
big_clock.set_name ("BigClockNonRecording"); big_clock.set_widget_name ("BigClockNonRecording");
break; break;
} }
} }

View file

@ -325,9 +325,6 @@ ARDOUR_UI::setup_transport ()
ARDOUR_UI::Clock.connect (bind (mem_fun (primary_clock, &AudioClock::set), false)); ARDOUR_UI::Clock.connect (bind (mem_fun (primary_clock, &AudioClock::set), false));
ARDOUR_UI::Clock.connect (bind (mem_fun (secondary_clock, &AudioClock::set), false)); ARDOUR_UI::Clock.connect (bind (mem_fun (secondary_clock, &AudioClock::set), false));
primary_clock.set_mode (AudioClock::SMPTE);
secondary_clock.set_mode (AudioClock::BBT);
primary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::primary_clock_value_changed)); primary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::primary_clock_value_changed));
secondary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed)); secondary_clock.ValueChanged.connect (mem_fun(*this, &ARDOUR_UI::secondary_clock_value_changed));

View file

@ -125,6 +125,13 @@ ARDOUR_UI::connect_to_session (Session *s)
connect_dependents_to_session (s); connect_dependents_to_session (s);
/* listen to clock mode changes. don't do this earlier because otherwise as the clocks
restore their modes or are explicitly set, we will cause the "new" mode to be saved
back to the session XML ("extra") state.
*/
AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
start_clocking (); start_clocking ();
start_blinking (); start_blinking ();

View file

@ -599,7 +599,7 @@ AudioClock::set_session (Session *s)
AudioClock::Mode amode; AudioClock::Mode amode;
if (node) { if (node) {
if ((prop = node->property (_name.c_str())) != 0) { if ((prop = node->property (_name)) != 0) {
amode = AudioClock::Mode (string_2_enum (prop->value(), amode)); amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
set_mode (amode); set_mode (amode);
} }

View file

@ -223,7 +223,7 @@ AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
++tmp; ++tmp;
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r); boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
if (ar && (*i)->crossfade.involves (ar)) { if (ar && (*i)->crossfade->involves (ar)) {
delete *i; delete *i;
crossfade_views.erase (i); crossfade_views.erase (i);
} }
@ -274,17 +274,17 @@ AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
} }
void void
AudioStreamView::add_crossfade (Crossfade *crossfade) AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
{ {
AudioRegionView* lview = 0; AudioRegionView* lview = 0;
AudioRegionView* rview = 0; AudioRegionView* rview = 0;
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade)); ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade));
/* first see if we already have a CrossfadeView for this Crossfade */ /* first see if we already have a CrossfadeView for this Crossfade */
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade == *crossfade) { if ((*i)->crossfade == crossfade) {
if (!crossfades_visible) { if (!crossfades_visible) {
(*i)->hide(); (*i)->hide();
} else { } else {
@ -310,7 +310,7 @@ AudioStreamView::add_crossfade (Crossfade *crossfade)
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display, CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
_trackview, _trackview,
*crossfade, crossfade,
_samples_per_unit, _samples_per_unit,
region_color, region_color,
*lview, *rview); *lview, *rview);
@ -324,12 +324,12 @@ AudioStreamView::add_crossfade (Crossfade *crossfade)
} }
void void
AudioStreamView::remove_crossfade (Crossfade *xfade) AudioStreamView::remove_crossfade (boost::shared_ptr<Crossfade> xfade)
{ {
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade)); ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade));
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if (&(*i)->crossfade == xfade) { if ((*i)->crossfade == xfade) {
delete *i; delete *i;
crossfade_views.erase (i); crossfade_views.erase (i);
break; break;
@ -716,7 +716,7 @@ void
AudioStreamView::hide_xfades_involving (AudioRegionView& rv) AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
{ {
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade.involves (rv.audio_region())) { if ((*i)->crossfade->involves (rv.audio_region())) {
(*i)->fake_hide (); (*i)->fake_hide ();
} }
} }
@ -726,7 +726,7 @@ void
AudioStreamView::reveal_xfades_involving (AudioRegionView& rv) AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
{ {
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) { if ((*i)->crossfade->involves (rv.audio_region()) && (*i)->visible()) {
(*i)->show (); (*i)->show ();
} }
} }

View file

@ -93,8 +93,8 @@ class AudioStreamView : public StreamView
void playlist_modified (); void playlist_modified ();
void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>); void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
void add_crossfade (ARDOUR::Crossfade*); void add_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
void remove_crossfade (ARDOUR::Crossfade*); void remove_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
void color_handler (ColorID id, uint32_t val); void color_handler (ColorID id, uint32_t val);

View file

@ -72,7 +72,7 @@ CrossfadeEditor::Half::Half ()
{ {
} }
CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double mxy) CrossfadeEditor::CrossfadeEditor (Session& s, boost::shared_ptr<Crossfade> xf, double my, double mxy)
: ArdourDialog (_("ardour: x-fade edit")), : ArdourDialog (_("ardour: x-fade edit")),
xfade (xf), xfade (xf),
session (s), session (s),
@ -279,14 +279,14 @@ CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double m
// vpacker.pack_start (*foobut, false, false); // vpacker.pack_start (*foobut, false, false);
current = In; current = In;
set (xfade.fade_in(), In); set (xfade->fade_in(), In);
current = Out; current = Out;
set (xfade.fade_out(), Out); set (xfade->fade_out(), Out);
curve_select_clicked (In); curve_select_clicked (In);
xfade.StateChanged.connect (mem_fun(*this, &CrossfadeEditor::xfade_changed)); xfade->StateChanged.connect (mem_fun(*this, &CrossfadeEditor::xfade_changed));
session.AuditionActive.connect (mem_fun(*this, &CrossfadeEditor::audition_state_changed)); session.AuditionActive.connect (mem_fun(*this, &CrossfadeEditor::audition_state_changed));
show_all_children(); show_all_children();
@ -577,21 +577,21 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
redraw (); redraw ();
current = old_current; current = old_current;
double spu = xfade.length() / (double) effective_width(); double spu = xfade->length() / (double) effective_width();
if (fade[In].waves.empty()) { if (fade[In].waves.empty()) {
make_waves (xfade.in(), In); make_waves (xfade->in(), In);
} }
if (fade[Out].waves.empty()) { if (fade[Out].waves.empty()) {
make_waves (xfade.out(), Out); make_waves (xfade->out(), Out);
} }
double ht; double ht;
vector<ArdourCanvas::WaveView*>::iterator i; vector<ArdourCanvas::WaveView*>::iterator i;
uint32_t n; uint32_t n;
ht = canvas->get_allocation().get_height() / xfade.in()->n_channels(); ht = canvas->get_allocation().get_height() / xfade->in()->n_channels();
for (n = 0, i = fade[In].waves.begin(); i != fade[In].waves.end(); ++i, ++n) { for (n = 0, i = fade[In].waves.begin(); i != fade[In].waves.end(); ++i, ++n) {
double yoff; double yoff;
@ -603,7 +603,7 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
(*i)->property_samples_per_unit() = spu; (*i)->property_samples_per_unit() = spu;
} }
ht = canvas->get_allocation().get_height() / xfade.out()->n_channels(); ht = canvas->get_allocation().get_height() / xfade->out()->n_channels();
for (n = 0, i = fade[Out].waves.begin(); i != fade[Out].waves.end(); ++i, ++n) { for (n = 0, i = fade[Out].waves.begin(); i != fade[Out].waves.end(); ++i, ++n) {
double yoff; double yoff;
@ -621,8 +621,8 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
void void
CrossfadeEditor::xfade_changed (Change ignored) CrossfadeEditor::xfade_changed (Change ignored)
{ {
set (xfade.fade_in(), In); set (xfade->fade_in(), In);
set (xfade.fade_out(), Out); set (xfade->fade_out(), Out);
} }
void void
@ -632,7 +632,7 @@ CrossfadeEditor::redraw ()
return; return;
} }
nframes_t len = xfade.length (); nframes_t len = xfade->length ();
fade[current].normative_curve.clear (); fade[current].normative_curve.clear ();
fade[current].gain_curve.clear (); fade[current].gain_curve.clear ();
@ -741,11 +741,11 @@ CrossfadeEditor::apply_preset (Preset *preset)
void void
CrossfadeEditor::apply () CrossfadeEditor::apply ()
{ {
_apply_to (&xfade); _apply_to (xfade);
} }
void void
CrossfadeEditor::_apply_to (Crossfade* xf) CrossfadeEditor::_apply_to (boost::shared_ptr<Crossfade> xf)
{ {
ARDOUR::Curve& in (xf->fade_in()); ARDOUR::Curve& in (xf->fade_in());
ARDOUR::Curve& out (xf->fade_out()); ARDOUR::Curve& out (xf->fade_out());
@ -796,7 +796,7 @@ CrossfadeEditor::_apply_to (Crossfade* xf)
} }
void void
CrossfadeEditor::setup (Crossfade* xfade) CrossfadeEditor::setup (boost::shared_ptr<Crossfade> xfade)
{ {
_apply_to (xfade); _apply_to (xfade);
xfade->set_active (true); xfade->set_active (true);
@ -819,8 +819,8 @@ CrossfadeEditor::clear ()
void void
CrossfadeEditor::reset () CrossfadeEditor::reset ()
{ {
set (xfade.fade_in(), In); set (xfade->fade_in(), In);
set (xfade.fade_out(), Out); set (xfade->fade_out(), Out);
} }
void void
@ -1028,7 +1028,7 @@ CrossfadeEditor::make_waves (boost::shared_ptr<AudioRegion> region, WhichFade wh
} }
ht = canvas->get_allocation().get_height() / (double) nchans; ht = canvas->get_allocation().get_height() / (double) nchans;
spu = xfade.length() / (double) effective_width(); spu = xfade->length() / (double) effective_width();
for (uint32_t n = 0; n < nchans; ++n) { for (uint32_t n = 0; n < nchans; ++n) {
@ -1095,25 +1095,25 @@ CrossfadeEditor::audition_both ()
postroll = 0; postroll = 0;
} }
if ((left_start_offset = xfade.out()->length() - xfade.length()) >= preroll) { if ((left_start_offset = xfade->out()->length() - xfade->length()) >= preroll) {
left_start_offset -= preroll; left_start_offset -= preroll;
} }
length = 0; length = 0;
if ((left_length = xfade.length()) < xfade.out()->length() - left_start_offset) { if ((left_length = xfade->length()) < xfade->out()->length() - left_start_offset) {
length += postroll; length += postroll;
} }
right_length = xfade.length(); right_length = xfade->length();
if (xfade.in()->length() - right_length < postroll) { if (xfade->in()->length() - right_length < postroll) {
right_length += postroll; right_length += postroll;
} }
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), left_start_offset, left_length, "xfade out", boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), left_start_offset, left_length, "xfade out",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, right_length, "xfade in", boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, right_length, "xfade in",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
pl.add_region (left, 0); pl.add_region (left, 0);
@ -1129,7 +1129,7 @@ CrossfadeEditor::audition_both ()
void void
CrossfadeEditor::audition_left_dry () CrossfadeEditor::audition_left_dry ()
{ {
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade left", boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade left",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
session.audition_region (left); session.audition_region (left);
@ -1140,9 +1140,9 @@ CrossfadeEditor::audition_left ()
{ {
AudioPlaylist& pl (session.the_auditioner()->prepare_playlist()); AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade left", boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade left",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, xfade.length(), "xfade in", boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, xfade->length(), "xfade in",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
pl.add_region (left, 0); pl.add_region (left, 0);
@ -1162,7 +1162,7 @@ CrossfadeEditor::audition_left ()
void void
CrossfadeEditor::audition_right_dry () CrossfadeEditor::audition_right_dry ()
{ {
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, xfade.length(), "xfade in", boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, xfade->length(), "xfade in",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
session.audition_region (right); session.audition_region (right);
} }
@ -1172,9 +1172,9 @@ CrossfadeEditor::audition_right ()
{ {
AudioPlaylist& pl (session.the_auditioner()->prepare_playlist()); AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade out", boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade out",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), 0, xfade.length(), "xfade out", boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), 0, xfade->length(), "xfade out",
0, Region::DefaultFlags, false))); 0, Region::DefaultFlags, false)));
pl.add_region (left, 0); pl.add_region (left, 0);

View file

@ -21,170 +21,170 @@ namespace ARDOUR
class CrossfadeEditor : public ArdourDialog class CrossfadeEditor : public ArdourDialog
{ {
public: public:
CrossfadeEditor (ARDOUR::Session&, ARDOUR::Crossfade&, double miny, double maxy); CrossfadeEditor (ARDOUR::Session&, boost::shared_ptr<ARDOUR::Crossfade>, double miny, double maxy);
~CrossfadeEditor (); ~CrossfadeEditor ();
void apply (); void apply ();
static const double canvas_border; static const double canvas_border;
/* these are public so that a caller/subclass can make them do the right thing. /* these are public so that a caller/subclass can make them do the right thing.
*/ */
Gtk::Button* cancel_button; Gtk::Button* cancel_button;
Gtk::Button* ok_button; Gtk::Button* ok_button;
struct PresetPoint { struct PresetPoint {
double x; double x;
double y; double y;
PresetPoint (double a, double b) PresetPoint (double a, double b)
: x (a), y (b) {} : x (a), y (b) {}
}; };
struct Preset : public list<PresetPoint> { struct Preset : public list<PresetPoint> {
string xpm; string xpm;
Preset (string x)
: xpm (x) {}
};
typedef list<Preset*> Presets;
static Presets* fade_in_presets;
static Presets* fade_out_presets;
Preset (string x)
: xpm (x) {}
};
typedef list<Preset*> Presets;
static Presets* fade_in_presets;
static Presets* fade_out_presets;
private: private:
ARDOUR::Crossfade& xfade; boost::shared_ptr<ARDOUR::Crossfade> xfade;
ARDOUR::Session& session; ARDOUR::Session& session;
Gtk::VBox vpacker;
struct Point {
~Point();
ArdourCanvas::SimpleRect* box;
ArdourCanvas::Line* curve;
double x;
double y;
static const int32_t size;
void move_to (double x, double y, double xfract, double yfract);
};
struct PointSorter
{
bool operator() (const CrossfadeEditor::Point* a, const CrossfadeEditor::Point *b) {
return a->x < b->x;
}
};
ArdourCanvas::SimpleRect* toplevel;
ArdourCanvas::Canvas* canvas;
struct Half {
ArdourCanvas::Line* line;
ArdourCanvas::Polygon* shading;
list<Point*> points;
ARDOUR::Curve normative_curve; /* 0 - 1.0, linear */
ARDOUR::Curve gain_curve; /* 0 - 2.0, gain mapping */
vector<ArdourCanvas::WaveView*> waves;
Half();
};
enum WhichFade {
In = 0,
Out = 1
};
Half fade[2];
WhichFade current;
bool point_grabbed;
vector<Gtk::Button*> fade_out_buttons;
vector<Gtk::Button*> fade_in_buttons;
Gtk::VBox vpacker; Gtk::VBox vpacker2;
struct Point { Gtk::Button clear_button;
~Point(); Gtk::Button revert_button;
ArdourCanvas::SimpleRect* box; Gtk::ToggleButton audition_both_button;
ArdourCanvas::Line* curve; Gtk::ToggleButton audition_left_dry_button;
double x; Gtk::ToggleButton audition_left_button;
double y; Gtk::ToggleButton audition_right_dry_button;
Gtk::ToggleButton audition_right_button;
static const int32_t size; Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
void move_to (double x, double y, double xfract, double yfract); Gtk::HBox roll_box;
};
struct PointSorter gint event_handler (GdkEvent*);
{
bool operator() (const CrossfadeEditor::Point* a, const CrossfadeEditor::Point *b) {
return a->x < b->x;
}
};
ArdourCanvas::SimpleRect* toplevel; bool canvas_event (GdkEvent* event);
ArdourCanvas::Canvas* canvas; bool point_event (GdkEvent* event, Point*);
bool curve_event (GdkEvent* event);
struct Half { void canvas_allocation (Gtk::Allocation&);
ArdourCanvas::Line* line; void add_control_point (double x, double y);
ArdourCanvas::Polygon* shading; Point* make_point ();
list<Point*> points; void redraw ();
ARDOUR::Curve normative_curve; /* 0 - 1.0, linear */
ARDOUR::Curve gain_curve; /* 0 - 2.0, gain mapping */
vector<ArdourCanvas::WaveView*> waves;
Half();
};
enum WhichFade {
In = 0,
Out = 1
};
Half fade[2];
WhichFade current;
bool point_grabbed;
vector<Gtk::Button*> fade_out_buttons;
vector<Gtk::Button*> fade_in_buttons;
Gtk::VBox vpacker2;
Gtk::Button clear_button;
Gtk::Button revert_button;
Gtk::ToggleButton audition_both_button;
Gtk::ToggleButton audition_left_dry_button;
Gtk::ToggleButton audition_left_button;
Gtk::ToggleButton audition_right_dry_button;
Gtk::ToggleButton audition_right_button;
Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
Gtk::HBox roll_box;
gint event_handler (GdkEvent*);
bool canvas_event (GdkEvent* event);
bool point_event (GdkEvent* event, Point*);
bool curve_event (GdkEvent* event);
void canvas_allocation (Gtk::Allocation&);
void add_control_point (double x, double y);
Point* make_point ();
void redraw ();
double effective_width () const { return canvas->get_allocation().get_width() - (2.0 * canvas_border); } double effective_width () const { return canvas->get_allocation().get_width() - (2.0 * canvas_border); }
double effective_height () const { return canvas->get_allocation().get_height() - (2.0 * canvas_border); } double effective_height () const { return canvas->get_allocation().get_height() - (2.0 * canvas_border); }
void clear (); void clear ();
void reset (); void reset ();
double miny; double miny;
double maxy; double maxy;
Gtk::Table fade_in_table; Gtk::Table fade_in_table;
Gtk::Table fade_out_table; Gtk::Table fade_out_table;
void build_presets (); void build_presets ();
void apply_preset (Preset*); void apply_preset (Preset*);
Gtk::RadioButton select_in_button; Gtk::RadioButton select_in_button;
Gtk::RadioButton select_out_button; Gtk::RadioButton select_out_button;
Gtk::HBox curve_button_box; Gtk::HBox curve_button_box;
Gtk::HBox audition_box; Gtk::HBox audition_box;
void curve_select_clicked (WhichFade); void curve_select_clicked (WhichFade);
double x_coordinate (double& xfract) const; double x_coordinate (double& xfract) const;
double y_coordinate (double& yfract) const; double y_coordinate (double& yfract) const;
void set (const ARDOUR::Curve& alist, WhichFade); void set (const ARDOUR::Curve& alist, WhichFade);
sigc::connection peaks_ready_connection; sigc::connection peaks_ready_connection;
void make_waves (boost::shared_ptr<ARDOUR::AudioRegion>, WhichFade); void make_waves (boost::shared_ptr<ARDOUR::AudioRegion>, WhichFade);
void peaks_ready (boost::shared_ptr<ARDOUR::AudioRegion> r, WhichFade); void peaks_ready (boost::shared_ptr<ARDOUR::AudioRegion> r, WhichFade);
void _apply_to (ARDOUR::Crossfade* xf); void _apply_to (boost::shared_ptr<ARDOUR::Crossfade> xf);
void setup (ARDOUR::Crossfade*); void setup (boost::shared_ptr<ARDOUR::Crossfade>);
void cancel_audition (); void cancel_audition ();
void audition_state_changed (bool); void audition_state_changed (bool);
void audition_toggled (); void audition_toggled ();
void audition_right_toggled (); void audition_right_toggled ();
void audition_right_dry_toggled (); void audition_right_dry_toggled ();
void audition_left_toggled (); void audition_left_toggled ();
void audition_left_dry_toggled (); void audition_left_dry_toggled ();
void audition_both (); void audition_both ();
void audition_left_dry (); void audition_left_dry ();
void audition_left (); void audition_left ();
void audition_right_dry (); void audition_right_dry ();
void audition_right (); void audition_right ();
void xfade_changed (ARDOUR::Change); void xfade_changed (ARDOUR::Change);
void dump (); void dump ();
}; };
#endif /* __gtk_ardour_xfade_edit_h__ */ #endif /* __gtk_ardour_xfade_edit_h__ */

View file

@ -44,15 +44,15 @@ sigc::signal<void,CrossfadeView*> CrossfadeView::GoingAway;
CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent, CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
RouteTimeAxisView &tv, RouteTimeAxisView &tv,
Crossfade& xf, boost::shared_ptr<Crossfade> xf,
double spu, double spu,
Gdk::Color& basic_color, Gdk::Color& basic_color,
AudioRegionView& lview, AudioRegionView& lview,
AudioRegionView& rview) AudioRegionView& rview)
: TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf.position(), : TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf->position(),
xf.length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)), xf->length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
crossfade (xf), crossfade (xf),
left_view (lview), left_view (lview),
right_view (rview) right_view (rview)
@ -84,7 +84,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
crossfade_changed (Change (~0)); crossfade_changed (Change (~0));
crossfade.StateChanged.connect (mem_fun(*this, &CrossfadeView::crossfade_changed)); crossfade->StateChanged.connect (mem_fun(*this, &CrossfadeView::crossfade_changed));
} }
CrossfadeView::~CrossfadeView () CrossfadeView::~CrossfadeView ()
@ -123,8 +123,8 @@ CrossfadeView::crossfade_changed (Change what_changed)
bool need_redraw_curves = false; bool need_redraw_curves = false;
if (what_changed & BoundsChanged) { if (what_changed & BoundsChanged) {
set_position (crossfade.position(), this); set_position (crossfade->position(), this);
set_duration (crossfade.length(), this); set_duration (crossfade->length(), this);
need_redraw_curves = true; need_redraw_curves = true;
} }
@ -148,7 +148,7 @@ CrossfadeView::redraw_curves ()
float* vec; float* vec;
double h; double h;
if (!crossfade.following_overlap()) { if (!crossfade->following_overlap()) {
/* curves should not be visible */ /* curves should not be visible */
fade_in->hide (); fade_in->hide ();
fade_out->hide (); fade_out->hide ();
@ -172,10 +172,10 @@ CrossfadeView::redraw_curves ()
return; return;
} }
npoints = get_time_axis_view().editor.frame_to_pixel (crossfade.length()); npoints = get_time_axis_view().editor.frame_to_pixel (crossfade->length());
npoints = std::min (gdk_screen_width(), npoints); npoints = std::min (gdk_screen_width(), npoints);
if (!_visible || !crossfade.active() || npoints < 3) { if (!_visible || !crossfade->active() || npoints < 3) {
fade_in->hide(); fade_in->hide();
fade_out->hide(); fade_out->hide();
return; return;
@ -187,7 +187,7 @@ CrossfadeView::redraw_curves ()
points = get_canvas_points ("xfade edit redraw", npoints); points = get_canvas_points ("xfade edit redraw", npoints);
vec = new float[npoints]; vec = new float[npoints];
crossfade.fade_in().get_vector (0, crossfade.length(), vec, npoints); crossfade->fade_in().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) { for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++]; Art::Point &p = (*points)[pci++];
p.set_x(i); p.set_x(i);
@ -195,7 +195,7 @@ CrossfadeView::redraw_curves ()
} }
fade_in->property_points() = *points; fade_in->property_points() = *points;
crossfade.fade_out().get_vector (0, crossfade.length(), vec, npoints); crossfade->fade_out().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) { for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++]; Art::Point &p = (*points)[pci++];
p.set_x(i); p.set_x(i);
@ -217,7 +217,7 @@ CrossfadeView::redraw_curves ()
void void
CrossfadeView::active_changed () CrossfadeView::active_changed ()
{ {
if (crossfade.active()) { if (crossfade->active()) {
frame->property_fill_color_rgba() = color_map[cActiveCrossfade]; frame->property_fill_color_rgba() = color_map[cActiveCrossfade];
} else { } else {
frame->property_fill_color_rgba() = color_map[cInactiveCrossfade]; frame->property_fill_color_rgba() = color_map[cInactiveCrossfade];

View file

@ -35,14 +35,15 @@ struct CrossfadeView : public TimeAxisViewItem
{ {
CrossfadeView (ArdourCanvas::Group*, CrossfadeView (ArdourCanvas::Group*,
RouteTimeAxisView&, RouteTimeAxisView&,
ARDOUR::Crossfade&, boost::shared_ptr<ARDOUR::Crossfade>,
double initial_samples_per_unit, double initial_samples_per_unit,
Gdk::Color& basic_color, Gdk::Color& basic_color,
AudioRegionView& leftview, AudioRegionView& leftview,
AudioRegionView& rightview); AudioRegionView& rightview);
~CrossfadeView (); ~CrossfadeView ();
ARDOUR::Crossfade& crossfade; // ok, let 'em have it boost::shared_ptr<ARDOUR::Crossfade> crossfade; // ok, let 'em have it
AudioRegionView& left_view; // and these too AudioRegionView& left_view; // and these too
AudioRegionView& right_view; AudioRegionView& right_view;

View file

@ -901,6 +901,8 @@ Editor::instant_save ()
void void
Editor::reposition_x_origin (nframes_t frame) Editor::reposition_x_origin (nframes_t frame)
{ {
cerr << "repsosition to " << frame << endl;
if (frame != leftmost_frame) { if (frame != leftmost_frame) {
leftmost_frame = frame; leftmost_frame = frame;
@ -1141,6 +1143,13 @@ Editor::connect_to_session (Session *t)
{ {
session = t; session = t;
XMLNode* node = ARDOUR_UI::instance()->editor_settings();
set_state (*node);
/* catch up with the playhead */
session->request_locate (playhead_cursor->current_frame);
if (first_action_message) { if (first_action_message) {
first_action_message->hide(); first_action_message->hide();
} }
@ -1237,27 +1246,12 @@ Editor::connect_to_session (Session *t)
(static_cast<TimeAxisView*>(*i))->set_samples_per_unit (frames_per_unit); (static_cast<TimeAxisView*>(*i))->set_samples_per_unit (frames_per_unit);
} }
/* ::reposition_x_origin() doesn't work right here, since the old
position may be zero already, and it does nothing in such
circumstances.
*/
leftmost_frame = 0;
horizontal_adjustment.set_value (0);
restore_ruler_visibility (); restore_ruler_visibility ();
//tempo_map_changed (Change (0)); //tempo_map_changed (Change (0));
session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks);
edit_cursor->set_position (0);
playhead_cursor->set_position (0);
start_scrolling (); start_scrolling ();
XMLNode* node = ARDOUR_UI::instance()->editor_settings();
set_state (*node);
/* don't show master bus in a new session */ /* don't show master bus in a new session */
if (ARDOUR_UI::instance()->session_is_new ()) { if (ARDOUR_UI::instance()->session_is_new ()) {
@ -1650,7 +1644,7 @@ Editor::build_track_selection_context_menu (nframes_t ignored)
} }
void void
Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many) Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr<Crossfade> xfade, Menu_Helpers::MenuList& edit_items, bool many)
{ {
using namespace Menu_Helpers; using namespace Menu_Helpers;
Menu *xfade_menu = manage (new Menu); Menu *xfade_menu = manage (new Menu);
@ -1664,8 +1658,8 @@ Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Me
str = _("Unmute"); str = _("Unmute");
} }
items.push_back (MenuElem (str, bind (mem_fun(*this, &Editor::toggle_xfade_active), xfade))); items.push_back (MenuElem (str, bind (mem_fun(*this, &Editor::toggle_xfade_active), boost::weak_ptr<Crossfade> (xfade))));
items.push_back (MenuElem (_("Edit"), bind (mem_fun(*this, &Editor::edit_xfade), xfade))); items.push_back (MenuElem (_("Edit"), bind (mem_fun(*this, &Editor::edit_xfade), boost::weak_ptr<Crossfade> (xfade))));
if (xfade->can_follow_overlap()) { if (xfade->can_follow_overlap()) {
@ -2115,6 +2109,28 @@ Editor::set_state (const XMLNode& node)
set_default_size (g.base_width, g.base_height); set_default_size (g.base_width, g.base_height);
move (x, y); move (x, y);
if (session && (prop = node.property ("playhead"))) {
nframes_t pos = atol (prop->value().c_str());
playhead_cursor->set_position (pos);
} else {
playhead_cursor->set_position (0);
/* ::reposition_x_origin() doesn't work right here, since the old
position may be zero already, and it does nothing in such
circumstances.
*/
leftmost_frame = 0;
horizontal_adjustment.set_value (0);
}
if (session && (prop = node.property ("edit-cursor"))) {
nframes_t pos = atol (prop->value().c_str());
edit_cursor->set_position (pos);
} else {
edit_cursor->set_position (0);
}
if ((prop = node.property ("zoom-focus"))) { if ((prop = node.property ("zoom-focus"))) {
set_zoom_focus ((ZoomFocus) atoi (prop->value())); set_zoom_focus ((ZoomFocus) atoi (prop->value()));
} }
@ -2264,6 +2280,11 @@ Editor::get_state ()
snprintf (buf, sizeof(buf), "%d", (int) snap_mode); snprintf (buf, sizeof(buf), "%d", (int) snap_mode);
node->add_property ("snap-mode", buf); node->add_property ("snap-mode", buf);
snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
node->add_property ("playhead", buf);
snprintf (buf, sizeof (buf), "%" PRIu32, edit_cursor->current_frame);
node->add_property ("edit-cursor", buf);
node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no"); node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no");
node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no"); node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no");
node->add_property ("show-measures", _show_measures ? "yes" : "no"); node->add_property ("show-measures", _show_measures ? "yes" : "no");
@ -3901,21 +3922,33 @@ Editor::set_follow_playhead (bool yn)
} }
void void
Editor::toggle_xfade_active (Crossfade* xfade) Editor::toggle_xfade_active (boost::weak_ptr<Crossfade> wxfade)
{ {
xfade->set_active (!xfade->active()); boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (xfade) {
xfade->set_active (!xfade->active());
}
} }
void void
Editor::toggle_xfade_length (Crossfade* xfade) Editor::toggle_xfade_length (boost::weak_ptr<Crossfade> wxfade)
{ {
xfade->set_follow_overlap (!xfade->following_overlap()); boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (xfade) {
xfade->set_follow_overlap (!xfade->following_overlap());
}
} }
void void
Editor::edit_xfade (Crossfade* xfade) Editor::edit_xfade (boost::weak_ptr<Crossfade> wxfade)
{ {
CrossfadeEditor cew (*session, *xfade, xfade->fade_in().get_min_y(), 1.0); boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (!xfade) {
return;
}
CrossfadeEditor cew (*session, xfade, xfade->fade_in().get_min_y(), 1.0);
ensure_float (cew); ensure_float (cew);

View file

@ -464,7 +464,7 @@ class Editor : public PublicEditor
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&); void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&); void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
void add_region_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Region>, Gtk::Menu_Helpers::MenuList&); void add_region_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Region>, Gtk::Menu_Helpers::MenuList&);
void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many); void add_crossfade_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Crossfade>, Gtk::Menu_Helpers::MenuList&, bool many);
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&); void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
void handle_new_route (ARDOUR::Session::RouteList&); void handle_new_route (ARDOUR::Session::RouteList&);
@ -1735,9 +1735,9 @@ class Editor : public PublicEditor
ImageFrameSocketHandler* image_socket_listener ; ImageFrameSocketHandler* image_socket_listener ;
/* </CMT Additions> */ /* </CMT Additions> */
void toggle_xfade_active (ARDOUR::Crossfade*); void toggle_xfade_active (boost::weak_ptr<ARDOUR::Crossfade>);
void toggle_xfade_length (ARDOUR::Crossfade*); void toggle_xfade_length (boost::weak_ptr<ARDOUR::Crossfade>);
void edit_xfade (ARDOUR::Crossfade*); void edit_xfade (boost::weak_ptr<ARDOUR::Crossfade>);
void xfade_edit_left_region (); void xfade_edit_left_region ();
void xfade_edit_right_region (); void xfade_edit_right_region ();

View file

@ -2779,8 +2779,14 @@ Editor::freeze_route ()
itt.done = false; itt.done = false;
itt.cancel = false; itt.cancel = false;
itt.progress = 0.0f; itt.progress = 0.0f;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 500000);
pthread_create (&itt.thread, 0, _freeze_thread, this); pthread_create (&itt.thread, &attr, _freeze_thread, this);
pthread_attr_destroy(&attr);
track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));

View file

@ -21,6 +21,8 @@
#include <cerrno> #include <cerrno>
#include <sstream> #include <sstream>
#include <sys/stat.h>
#include <gtkmm/box.h> #include <gtkmm/box.h>
#include <gtkmm/stock.h> #include <gtkmm/stock.h>
@ -65,6 +67,8 @@ SoundFileBox::SoundFileBox ()
border_frame.set_label (_("Soundfile Info")); border_frame.set_label (_("Soundfile Info"));
border_frame.add (main_box); border_frame.add (main_box);
Gtk::Label* tag_label = manage(new Gtk::Label(_("comma seperated tags")));
pack_start (border_frame); pack_start (border_frame);
set_border_width (4); set_border_width (4);
@ -75,7 +79,8 @@ SoundFileBox::SoundFileBox ()
main_box.pack_start(channels, false, false); main_box.pack_start(channels, false, false);
main_box.pack_start(samplerate, false, false); main_box.pack_start(samplerate, false, false);
main_box.pack_start(timecode, false, false); main_box.pack_start(timecode, false, false);
main_box.pack_start(tags_entry, true, true); main_box.pack_start(*tag_label, false, false);
main_box.pack_start(tags_entry, false, false);
main_box.pack_start(apply_btn, false, false); main_box.pack_start(apply_btn, false, false);
main_box.pack_start(bottom_box, false, false); main_box.pack_start(bottom_box, false, false);
@ -83,10 +88,10 @@ SoundFileBox::SoundFileBox ()
bottom_box.pack_start(play_btn); bottom_box.pack_start(play_btn);
bottom_box.pack_start(stop_btn); bottom_box.pack_start(stop_btn);
// tags_entry.signal_focus_out_event().connect (mem_fun (*this, &SoundFileBox::tags_entry_left));
play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::play_btn_clicked)); play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::play_btn_clicked));
stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_btn_clicked)); stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_btn_clicked));
apply_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked)); apply_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked));
tags_entry.signal_activate().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked));
length.set_alignment (0.0f, 0.0f); length.set_alignment (0.0f, 0.0f);
format.set_alignment (0.0f, 0.0f); format.set_alignment (0.0f, 0.0f);
@ -306,7 +311,8 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s)
found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected)); found_list_view.get_selection()->signal_changed().connect(mem_fun(*this, &SoundFileBrowser::found_list_view_selected));
found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked));
show_all (); show_all ();
set_session (s); set_session (s);
@ -386,17 +392,25 @@ SoundFileChooser::get_filename ()
Gtk::TreeModel::iterator iter; Gtk::TreeModel::iterator iter;
Gtk::TreeModel::Row row; Gtk::TreeModel::Row row;
string filename;
switch (notebook.get_current_page()) { switch (notebook.get_current_page()) {
case 0: case 0:
return chooser.get_filename(); filename = chooser.get_filename();
case 1: case 1:
iter = found_list_view.get_selection()->get_selected(); iter = found_list_view.get_selection()->get_selected();
row = *iter; row = *iter;
return row[found_list_columns.pathname]; filename = row[found_list_columns.pathname];
default: default:
/* NOT REACHED */ /* NOT REACHED */
return ""; return "";
} }
struct stat buf;
if (stat (filename.c_str(), &buf) || !S_ISREG(buf.st_mode)) {
return "";
}
return filename;
} }
vector<string> SoundFileOmega::mode_strings; vector<string> SoundFileOmega::mode_strings;
@ -442,22 +456,34 @@ SoundFileOmega::get_split ()
vector<Glib::ustring> vector<Glib::ustring>
SoundFileOmega::get_paths () SoundFileOmega::get_paths ()
{ {
vector<Glib::ustring> results;
int n = notebook.get_current_page (); int n = notebook.get_current_page ();
if (n == 0) { if (n == 0) {
return chooser.get_filenames (); vector<Glib::ustring> filenames = chooser.get_filenames();
vector<Glib::ustring>::iterator i;
for (i = filenames.begin(); i != filenames.end(); ++i) {
struct stat buf;
if ((!stat((*i).c_str(), &buf)) && S_ISREG(buf.st_mode)) {
results.push_back (*i);
}
}
return results;
} else {
typedef Gtk::TreeView::Selection::ListHandle_Path ListPath;
ListPath rows = found_list_view.get_selection()->get_selected_rows ();
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
Gtk::TreeIter iter = found_list->get_iter(*i);
string str = (*iter)[found_list_columns.pathname];
results.push_back (str);
}
return results;
} }
typedef Gtk::TreeView::Selection::ListHandle_Path ListPath;
vector<Glib::ustring> results;
ListPath rows = found_list_view.get_selection()->get_selected_rows ();
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
Gtk::TreeIter iter = found_list->get_iter(*i);
string str = (*iter)[found_list_columns.pathname];
results.push_back (str);
}
return results;
} }
void void

View file

@ -37,7 +37,7 @@ class Source;
class AudioPlaylist : public ARDOUR::Playlist class AudioPlaylist : public ARDOUR::Playlist
{ {
public: public:
typedef std::list<Crossfade*> Crossfades; typedef std::list<boost::shared_ptr<Crossfade> > Crossfades;
public: public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false); AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
@ -53,9 +53,9 @@ class AudioPlaylist : public ARDOUR::Playlist
int set_state (const XMLNode&); int set_state (const XMLNode&);
sigc::signal<void,Crossfade *> NewCrossfade; sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade;
template<class T> void foreach_crossfade (T *t, void (T::*func)(Crossfade *)); template<class T> void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>));
void crossfades_at (nframes_t frame, Crossfades&); void crossfades_at (nframes_t frame, Crossfades&);
bool destroy_region (boost::shared_ptr<Region>); bool destroy_region (boost::shared_ptr<Region>);
@ -63,7 +63,7 @@ class AudioPlaylist : public ARDOUR::Playlist
protected: protected:
/* playlist "callbacks" */ /* playlist "callbacks" */
void notify_crossfade_added (Crossfade *); void notify_crossfade_added (boost::shared_ptr<Crossfade>);
void flush_notifications (); void flush_notifications ();
void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right); void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
@ -73,16 +73,16 @@ class AudioPlaylist : public ARDOUR::Playlist
void remove_dependents (boost::shared_ptr<Region> region); void remove_dependents (boost::shared_ptr<Region> region);
private: private:
Crossfades _crossfades; /* xfades currently in use */ Crossfades _crossfades;
Crossfades _pending_xfade_adds; Crossfades _pending_xfade_adds;
void crossfade_invalidated (Crossfade*); void crossfade_invalidated (boost::shared_ptr<Crossfade>);
XMLNode& state (bool full_state); XMLNode& state (bool full_state);
void dump () const; void dump () const;
bool region_changed (Change, boost::shared_ptr<Region>); bool region_changed (Change, boost::shared_ptr<Region>);
void crossfade_changed (Change); void crossfade_changed (Change);
void add_crossfade (Crossfade&); void add_crossfade (boost::shared_ptr<Crossfade>);
void source_offset_changed (boost::shared_ptr<AudioRegion> region); void source_offset_changed (boost::shared_ptr<AudioRegion> region);
}; };

View file

@ -24,6 +24,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <sigc++/signal.h> #include <sigc++/signal.h>
@ -40,7 +41,7 @@ namespace ARDOUR {
class AudioRegion; class AudioRegion;
class Playlist; class Playlist;
class Crossfade : public PBD::StatefulDestructible class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_from_this<ARDOUR::Crossfade>
{ {
public: public:
@ -111,7 +112,7 @@ class Crossfade : public PBD::StatefulDestructible
void invalidate(); void invalidate();
sigc::signal<void,Crossfade*> Invalidated; sigc::signal<void,boost::shared_ptr<Crossfade> > Invalidated;
sigc::signal<void,Change> StateChanged; sigc::signal<void,Change> StateChanged;
bool covers (nframes_t frame) const { bool covers (nframes_t frame) const {

View file

@ -23,7 +23,7 @@
namespace ARDOUR { namespace ARDOUR {
template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(Crossfade *)) { template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>)) {
RegionLock rlock (this, false); RegionLock rlock (this, false);
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) { for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) {
(t->*func) (*i); (t->*func) (*i);

View file

@ -65,7 +65,7 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, stri
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o); boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
// We look only for crossfades which begin with the current region, so we don't get doubles // We look only for crossfades which begin with the current region, so we don't get doubles
for (list<Crossfade *>::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) { for (Crossfades::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
if ((*xfades)->in() == ar) { if ((*xfades)->in() == ar) {
// We found one! Now copy it! // We found one! Now copy it!
@ -79,8 +79,8 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, stri
if ((*xfades)->out() == ar2) { if ((*xfades)->out() == ar2) {
boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n); boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n); boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
Crossfade *new_fade = new Crossfade (*(*xfades), in, out); boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*(*xfades), in, out));
add_crossfade(*new_fade); add_crossfade(new_fade);
break; break;
} }
@ -104,31 +104,13 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nfra
AudioPlaylist::~AudioPlaylist () AudioPlaylist::~AudioPlaylist ()
{ {
set<Crossfade*> all_xfades;
GoingAway (); /* EMIT SIGNAL */ GoingAway (); /* EMIT SIGNAL */
/* drop connections to signals */ /* drop connections to signals */
notify_callbacks (); notify_callbacks ();
_crossfades.clear ();
cerr << "deleting crossfades " << _crossfades.size() << endl;
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ) {
Crossfades::iterator tmp;
tmp = x;
++tmp;
delete *x;
cerr << _crossfades.size() << " to go\n";
x = tmp;
}
cerr << "done\n";
} }
struct RegionSortByLayer { struct RegionSortByLayer {
@ -174,7 +156,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
_read_data_count = 0; _read_data_count = 0;
map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions; map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
map<uint32_t,vector<Crossfade*> > relevant_xfades; map<uint32_t,vector<boost::shared_ptr<Crossfade> > > relevant_xfades;
vector<uint32_t> relevant_layers; vector<uint32_t> relevant_layers;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
@ -204,7 +186,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) { for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
vector<boost::shared_ptr<Region> > r (relevant_regions[*l]); vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
vector<Crossfade*>& x (relevant_xfades[*l]); vector<boost::shared_ptr<Crossfade> >& x (relevant_xfades[*l]);
for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) { for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i); boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
@ -213,7 +195,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
_read_data_count += ar->read_data_count(); _read_data_count += ar->read_data_count();
} }
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) { for (vector<boost::shared_ptr<Crossfade> >::iterator i = x.begin(); i != x.end(); ++i) {
(*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n); (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
/* don't JACK up _read_data_count, since its the same data as we just /* don't JACK up _read_data_count, since its the same data as we just
@ -229,7 +211,6 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
void void
AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region) AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{ {
Crossfades::iterator i, tmp;
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region); boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
if (in_set_state) { if (in_set_state) {
@ -242,16 +223,13 @@ AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
return; return;
} }
for (i = _crossfades.begin(); i != _crossfades.end(); ) { for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
tmp = i;
tmp++;
if ((*i)->involves (r)) { if ((*i)->involves (r)) {
delete *i; i = _crossfades.erase (i);
} else {
++i;
} }
i = tmp;
} }
} }
@ -281,7 +259,7 @@ void
AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r) AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{ {
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r); boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
set<Crossfade*> updated; set<boost::shared_ptr<Crossfade> > updated;
if (ar == 0) { if (ar == 0) {
return; return;
@ -322,29 +300,29 @@ AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared
tmp = x; tmp = x;
++tmp; ++tmp;
Crossfade *fade = 0; boost::shared_ptr<Crossfade> fade;
if ((*x)->_in == orig) { if ((*x)->_in == orig) {
if (! (*x)->covers(right->position())) { if (! (*x)->covers(right->position())) {
fade = new Crossfade (**x, left, (*x)->_out); fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, left, (*x)->_out));
} else { } else {
// Overlap, the crossfade is copied on the left side of the right region instead // Overlap, the crossfade is copied on the left side of the right region instead
fade = new Crossfade (**x, right, (*x)->_out); fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, right, (*x)->_out));
} }
} }
if ((*x)->_out == orig) { if ((*x)->_out == orig) {
if (! (*x)->covers(right->position())) { if (! (*x)->covers(right->position())) {
fade = new Crossfade (**x, (*x)->_in, right); fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, (*x)->_in, right));
} else { } else {
// Overlap, the crossfade is copied on the right side of the left region instead // Overlap, the crossfade is copied on the right side of the left region instead
fade = new Crossfade (**x, (*x)->_in, left); fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, (*x)->_in, left));
} }
} }
if (fade) { if (fade) {
_crossfades.remove (*x); _crossfades.remove (*x);
add_crossfade (*fade); add_crossfade (fade);
} }
x = tmp; x = tmp;
} }
@ -357,7 +335,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
boost::shared_ptr<AudioRegion> region; boost::shared_ptr<AudioRegion> region;
boost::shared_ptr<AudioRegion> top; boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom; boost::shared_ptr<AudioRegion> bottom;
Crossfade* xfade; boost::shared_ptr<Crossfade> xfade;
if (in_set_state || in_partition) { if (in_set_state || in_partition) {
return; return;
@ -381,6 +359,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
nframes_t xfade_length;
other = boost::dynamic_pointer_cast<AudioRegion> (*i); other = boost::dynamic_pointer_cast<AudioRegion> (*i);
if (other == region) { if (other == region) {
@ -390,6 +370,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
if (other->muted() || region->muted()) { if (other->muted() || region->muted()) {
continue; continue;
} }
if (other->layer() < region->layer()) { if (other->layer() < region->layer()) {
top = region; top = region;
@ -399,50 +380,55 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
bottom = region; bottom = region;
} }
OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
try { try {
switch (c) {
case OverlapNone:
break;
case OverlapInternal:
/* {=============== top =============}
* [ ----- bottom ------- ]
*/
break;
case OverlapExternal:
/* [ -------- top ------- ]
* {=========== bottom =============}
*/
if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) { /* to avoid discontinuities at the region boundaries of an internal
overlap (this region is completely within another), we create
two hidden crossfades at each boundary. this is not dependent
on the auto-xfade option, because we require it as basic
audio engineering.
*/
/* check if the upper region is within the lower region */ xfade_length = min ((nframes_t) 720, top->length());
if (top->first_frame() > bottom->first_frame() && xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn));
top->last_frame() < bottom->last_frame()) { add_crossfade (xfade);
if (top_region_at (top->last_frame() - 1) == top) {
/* [ -------- top ------- ] /*
* {=========== bottom =============} only add a fade out if there is no region on top of the end of 'top' (which
*/ would cover it).
/* to avoid discontinuities at the region boundaries of an internal
overlap (this region is completely within another), we create
two hidden crossfades at each boundary. this is not dependent
on the auto-xfade option, because we require it as basic
audio engineering.
*/ */
nframes_t xfade_length = min ((nframes_t) 720, top->length()); xfade = boost::shared_ptr<Crossfade> (new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut));
add_crossfade (xfade);
/* in, out */
xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
add_crossfade (*xfade);
if (top_region_at (top->last_frame() - 1) == top) {
/*
only add a fade out if there is no region on top of the end of 'top' (which
would cover it).
*/
xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
add_crossfade (*xfade);
}
} else {
xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_xfades_active());
add_crossfade (*xfade);
} }
} break;
default:
xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
add_crossfade (xfade);
}
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
continue; continue;
} }
@ -455,32 +441,29 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
} }
void void
AudioPlaylist::add_crossfade (Crossfade& xfade) AudioPlaylist::add_crossfade (boost::shared_ptr<Crossfade> xfade)
{ {
Crossfades::iterator ci; Crossfades::iterator ci;
cerr << "adding xfade involving " << xfade.in()->name() << " and " << xfade.out()->name() << endl;
for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) { for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
cerr << "\tcompare to " << (*ci)->in()->name() << " and " << (*ci)->out()->name() << endl; if (*(*ci) == *xfade) { // Crossfade::operator==()
if (*(*ci) == xfade) { // Crossfade::operator==()
break; break;
} }
} }
if (ci != _crossfades.end()) { if (ci != _crossfades.end()) {
delete &xfade; // it will just go away
} else { } else {
_crossfades.push_back (&xfade); _crossfades.push_back (xfade);
xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
notify_crossfade_added (&xfade); notify_crossfade_added (xfade);
} }
} }
void AudioPlaylist::notify_crossfade_added (Crossfade *x) void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x)
{ {
if (g_atomic_int_get(&block_notifications)) { if (g_atomic_int_get(&block_notifications)) {
_pending_xfade_adds.insert (_pending_xfade_adds.end(), x); _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
@ -490,7 +473,7 @@ void AudioPlaylist::notify_crossfade_added (Crossfade *x)
} }
void void
AudioPlaylist::crossfade_invalidated (Crossfade* xfade) AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Crossfade> xfade)
{ {
Crossfades::iterator i; Crossfades::iterator i;
@ -525,7 +508,7 @@ AudioPlaylist::set_state (const XMLNode& node)
} }
try { try {
Crossfade* xfade = new Crossfade (*((const Playlist *)this), *child); boost::shared_ptr<Crossfade> xfade = boost::shared_ptr<Crossfade> (new Crossfade (*((const Playlist *)this), *child));
_crossfades.push_back (xfade); _crossfades.push_back (xfade);
xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
@ -549,19 +532,7 @@ AudioPlaylist::set_state (const XMLNode& node)
void void
AudioPlaylist::clear (bool with_signals) AudioPlaylist::clear (bool with_signals)
{ {
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
Crossfades::iterator tmp;
tmp = i;
++tmp;
delete *i;
i = tmp;
}
_crossfades.clear (); _crossfades.clear ();
Playlist::clear (with_signals); Playlist::clear (with_signals);
} }
@ -583,7 +554,7 @@ void
AudioPlaylist::dump () const AudioPlaylist::dump () const
{ {
boost::shared_ptr<Region>r; boost::shared_ptr<Region>r;
Crossfade *x; boost::shared_ptr<Crossfade> x;
cerr << "Playlist \"" << _name << "\" " << endl cerr << "Playlist \"" << _name << "\" " << endl
<< regions.size() << " regions " << regions.size() << " regions "
@ -623,7 +594,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region); boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
bool changed = false; bool changed = false;
Crossfades::iterator c, ctmp; Crossfades::iterator c, ctmp;
set<Crossfade*> unique_xfades; set<boost::shared_ptr<Crossfade> > unique_xfades;
if (r == 0) { if (r == 0) {
fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist") fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
@ -676,10 +647,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
c = ctmp; c = ctmp;
} }
for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
delete *c;
}
if (changed) { if (changed) {
/* overload this, it normally means "removed", not destroyed */ /* overload this, it normally means "removed", not destroyed */
notify_region_removed (region); notify_region_removed (region);

View file

@ -413,7 +413,8 @@ void
AudioEngine::start_metering_thread () AudioEngine::start_metering_thread ()
{ {
if (m_meter_thread == 0) { if (m_meter_thread == 0) {
m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), true); m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread),
500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
} }
} }

View file

@ -20,6 +20,8 @@
#include <sigc++/bind.h> #include <sigc++/bind.h>
#include <pbd/stacktrace.h>
#include <ardour/types.h> #include <ardour/types.h>
#include <ardour/crossfade.h> #include <ardour/crossfade.h>
#include <ardour/crossfade_compare.h> #include <ardour/crossfade_compare.h>
@ -80,6 +82,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
{ {
_in = in; _in = in;
_out = out; _out = out;
_length = length; _length = length;
_position = position; _position = position;
_anchor_point = ap; _anchor_point = ap;
@ -197,9 +200,8 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi
Crossfade::~Crossfade () Crossfade::~Crossfade ()
{ {
cerr << "Deleting xfade @ " << this << endl; cerr << "Crossfade deleted\n";
Invalidated (this); notify_callbacks ();
cerr << "invalidation signal sent\n";
} }
void void
@ -256,6 +258,8 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
/* first check for matching ends */ /* first check for matching ends */
if (top->first_frame() == bottom->first_frame()) { if (top->first_frame() == bottom->first_frame()) {
cerr << "same start\n";
/* Both regions start at the same point */ /* Both regions start at the same point */
@ -297,6 +301,8 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
} else if (top->last_frame() == bottom->last_frame()) { } else if (top->last_frame() == bottom->last_frame()) {
cerr << "same end\n";
/* Both regions end at the same point */ /* Both regions end at the same point */
if (top->first_frame() > bottom->first_frame()) { if (top->first_frame() > bottom->first_frame()) {
@ -335,17 +341,21 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame()); OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
cerr << "ot = " << ot << endl;
switch (ot) { switch (ot) {
case OverlapNone: case OverlapNone:
/* should be NOTREACHED as a precondition of creating /* should be NOTREACHED as a precondition of creating
a new crossfade, but we need to handle it here. a new crossfade, but we need to handle it here.
*/ */
cerr << "no sir\n";
throw NoCrossfadeHere(); throw NoCrossfadeHere();
break; break;
case OverlapInternal: case OverlapInternal:
case OverlapExternal: case OverlapExternal:
/* should be NOTREACHED because of tests above */ /* should be NOTREACHED because of tests above */
cerr << "nu-uh\n";
throw NoCrossfadeHere(); throw NoCrossfadeHere();
break; break;
@ -357,15 +367,16 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
_in = bottom; _in = bottom;
_out = top; _out = top;
_position = bottom->first_frame();
_anchor_point = StartOfIn; _anchor_point = StartOfIn;
if (model == FullCrossfade) { if (model == FullCrossfade) {
_position = bottom->first_frame(); // "{"
_length = _out->first_frame() + _out->length() - _in->first_frame(); _length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */ /* leave active alone */
_follow_overlap = true; _follow_overlap = true;
} else { } else {
_length = min (short_xfade_length, top->length()); _length = min (short_xfade_length, top->length());
_position = top->last_frame() - _length; // "]" - length
_active = true; _active = true;
_follow_overlap = false; _follow_overlap = false;
@ -499,7 +510,13 @@ Crossfade::refresh ()
/* crossfades must be between non-muted regions */ /* crossfades must be between non-muted regions */
if (_out->muted() || _in->muted()) { if (_out->muted() || _in->muted()) {
Invalidated (this); Invalidated (shared_from_this());
return false;
}
if (_in->layer() < _out->layer()) {
cerr << "layer change, invalidated\n";
Invalidated (shared_from_this());
return false; return false;
} }
@ -508,11 +525,11 @@ Crossfade::refresh ()
OverlapType ot; OverlapType ot;
ot = _in->coverage (_out->first_frame(), _out->last_frame()); ot = _in->coverage (_out->first_frame(), _out->last_frame());
switch (ot) { switch (ot) {
case OverlapNone: case OverlapNone:
case OverlapInternal: case OverlapInternal:
Invalidated (this); Invalidated (shared_from_this());
return false; return false;
default: default:
@ -522,7 +539,7 @@ Crossfade::refresh ()
/* overlap type must not have altered */ /* overlap type must not have altered */
if (ot != overlap_type) { if (ot != overlap_type) {
Invalidated (this); Invalidated (shared_from_this());
return false; return false;
} }
@ -543,7 +560,7 @@ Crossfade::update (bool force)
} }
if (newlen == 0) { if (newlen == 0) {
Invalidated (this); Invalidated (shared_from_this());
return false; return false;
} }
@ -563,7 +580,13 @@ Crossfade::update (bool force)
switch (_anchor_point) { switch (_anchor_point) {
case StartOfIn: case StartOfIn:
if (_position != _in->first_frame()) { if (_position != _in->first_frame()) {
_position = _in->first_frame(); if (_length > _short_xfade_length) {
/* assume FullCrossfade */
_position = _in->first_frame();
} else {
/* assume short xfade */
_position = _out->last_frame() - _length;
}
} }
break; break;
@ -865,5 +888,5 @@ Crossfade::set_short_xfade_length (nframes_t n)
void void
Crossfade::invalidate () Crossfade::invalidate ()
{ {
Invalidated (this); /* EMIT SIGNAL */ Invalidated (shared_from_this()); /* EMIT SIGNAL */
} }

View file

@ -197,43 +197,44 @@ setup_hardware_optimization (bool try_optimization)
{ {
bool generic_mix_functions = true; bool generic_mix_functions = true;
if (try_optimization) { if (try_optimization) {
#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
unsigned int use_sse = 0; unsigned long use_sse = 0;
#ifndef USE_X86_64_ASM #ifndef USE_X86_64_ASM
asm volatile ( asm (
"mov $1, %%eax\n" "mov $1, %%eax\n"
"pushl %%ebx\n" "pushl %%ebx\n"
"cpuid\n" "cpuid\n"
"popl %%ebx\n"
"andl $33554432, %%edx\n"
"movl %%edx, %0\n" "movl %%edx, %0\n"
: "=m" (use_sse) "popl %%ebx\n"
: "=l" (use_sse)
: :
: "%eax", "%ecx", "%edx", "memory"); : "%eax", "%ecx", "%edx", "memory");
#else #else
asm volatile ( asm (
"movq $1, %%rax\n"
"pushq %%rbx\n" "pushq %%rbx\n"
"movq $1, %%rax\n"
"cpuid\n" "cpuid\n"
"popq %%rbx\n"
"andq $33554432, %%rdx\n"
"movq %%rdx, %0\n" "movq %%rdx, %0\n"
: "=m" (use_sse) "popq %%rbx\n"
: "=l" (use_sse)
: :
: "%rax", "%rcx", "%rdx", "memory"); : "%rax", "%rcx", "%rdx", "memory");
#endif /* USE_X86_64_ASM */ #endif /* USE_X86_64_ASM */
use_sse &= (1 << 25); // bit 25 = SSE support
if (use_sse) { if (use_sse) {
info << "Using SSE optimized routines" << endmsg; info << "Using SSE optimized routines" << endmsg;
// SSE SET // SSE SET
Session::compute_peak = x86_sse_compute_peak; Session::compute_peak = x86_sse_compute_peak;
Session::apply_gain_to_buffer = x86_sse_apply_gain_to_buffer; Session::apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
Session::mix_buffers_with_gain = x86_sse_mix_buffers_with_gain; Session::mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
Session::mix_buffers_no_gain = x86_sse_mix_buffers_no_gain; Session::mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;

View file

@ -199,10 +199,15 @@ OSC::init_osc_thread ()
return false; return false;
} }
pthread_create (&_osc_thread, NULL, &OSC::_osc_receiver, this); pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 500000);
pthread_create (&_osc_thread, &attr, &OSC::_osc_receiver, this);
if (!_osc_thread) { if (!_osc_thread) {
return false; return false;
} }
pthread_attr_destroy(&attr);
//pthread_detach (_osc_thread); //pthread_detach (_osc_thread);
return true; return true;

View file

@ -1671,6 +1671,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
string port; string port;
RouteList new_routes; RouteList new_routes;
list<boost::shared_ptr<AudioTrack> > ret; list<boost::shared_ptr<AudioTrack> > ret;
uint32_t control_id;
/* count existing audio tracks */ /* count existing audio tracks */
@ -1694,6 +1695,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
_engine.get_physical_outputs (physoutputs); _engine.get_physical_outputs (physoutputs);
_engine.get_physical_inputs (physinputs); _engine.get_physical_inputs (physinputs);
control_id = 0;
while (how_many) { while (how_many) {
@ -1782,7 +1784,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
} }
track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
track->set_remote_control_id (ntracks()); track->set_remote_control_id (ntracks() + control_id + 1);
++control_id;
new_routes.push_back (track); new_routes.push_back (track);
ret.push_back (track); ret.push_back (track);

View file

@ -95,8 +95,11 @@ public:
const XMLPropertyList & properties() const { return _proplist; }; const XMLPropertyList & properties() const { return _proplist; };
XMLProperty *property(const char * ); XMLProperty *property(const char * );
XMLProperty *property(const std::string&);
const XMLProperty *property(const char * n) const const XMLProperty *property(const char * n) const
{ return ((XMLNode *) this)->property(n); }; { return ((XMLNode *) this)->property(n); };
const XMLProperty *property(const std::string& ns) const
{ return ((XMLNode *) this)->property(ns); };
XMLProperty *add_property(const char *, const string &); XMLProperty *add_property(const char *, const string &);
XMLProperty *add_property(const char *, const char * = ""); XMLProperty *add_property(const char *, const char * = "");

View file

@ -43,6 +43,16 @@ pthread_create_and_store (string name, pthread_t *thread, pthread_attr_t *attr,
{ {
int ret; int ret;
pthread_attr_t default_attr;
bool use_default_attr = (attr == NULL);
if (use_default_attr) {
// set default stack size to sensible default for memlocking
pthread_attr_init(&default_attr);
pthread_attr_setstacksize(&default_attr, 500000);
attr = &default_attr;
}
if ((ret = pthread_create (thread, attr, start_routine, arg)) == 0) { if ((ret = pthread_create (thread, attr, start_routine, arg)) == 0) {
std::pair<string,pthread_t> newpair; std::pair<string,pthread_t> newpair;
newpair.first = name; newpair.first = name;
@ -53,6 +63,10 @@ pthread_create_and_store (string name, pthread_t *thread, pthread_attr_t *attr,
pthread_mutex_unlock (&thread_map_lock); pthread_mutex_unlock (&thread_map_lock);
} }
if (use_default_attr) {
pthread_attr_destroy(&default_attr);
}
return ret; return ret;
} }

View file

@ -289,11 +289,25 @@ XMLProperty *
XMLNode::property(const char * n) XMLNode::property(const char * n)
{ {
string ns(n); string ns(n);
if (_propmap.find(ns) == _propmap.end()) { map<string,XMLProperty*>::iterator iter;
return 0;
if ((iter = _propmap.find(ns)) != _propmap.end()) {
return iter->second;
}
return 0;
}
XMLProperty *
XMLNode::property(const string & ns)
{
map<string,XMLProperty*>::iterator iter;
if ((iter = _propmap.find(ns)) != _propmap.end()) {
return iter->second;
} }
return _propmap[ns]; return 0;
} }
XMLProperty * XMLProperty *