changes from 2.X starting in march 2009 through oct 20 2009 (5826 inclusive)
git-svn-id: svn://localhost/ardour2/branches/3.0@6761 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -1,15 +1,12 @@
|
||||
(1) VST SUPPORT
|
||||
|
||||
You may not distribute binaries of Ardour with VST support. Doing so
|
||||
is a violation of the license agreement for the Steinberg VST SDK. If
|
||||
you are found to be distributing such binaries, you risk both
|
||||
prosecution by Steinberg and public humiliation by me.
|
||||
|
||||
This is not my choice, and as soon as Steinberg change their
|
||||
licensing, which they have indicated they will do, this policy (and
|
||||
file) will be removed.
|
||||
Please do not distribution Ardour with VST support under the package
|
||||
name "ardour" (or any case-variant on that). Use some other name such
|
||||
as "ardourvst", "ArdourVST", "ardour-vst" etc. In the near future,
|
||||
work will be done to make it possible to share as much as possible of
|
||||
the packaging.
|
||||
|
||||
(2) STANDARD TEMPLATES
|
||||
|
||||
The templates in ./templates are intended for installation in
|
||||
$prefix/share/ardour3/templates.
|
||||
$prefix/share/ardour2/templates.
|
||||
|
||||
2
README
2
README
@@ -1,3 +1,3 @@
|
||||
Please see the Ardour web site at http://ardour.org/ for all documentation..
|
||||
|
||||
|
||||
For information on building ardour: http://ardour.org/building.
|
||||
|
||||
@@ -156,6 +156,7 @@ static const char* authors[] = {
|
||||
N_("Nimal Ratnayake"),
|
||||
N_("Dave Robillard"),
|
||||
N_("Taybin Rutkin"),
|
||||
N_("Andreas Ruge"),
|
||||
N_("Sampo Savolainen"),
|
||||
N_("Per Sigmond"),
|
||||
N_("Lincoln Spiteri"),
|
||||
@@ -168,7 +169,7 @@ static const char* authors[] = {
|
||||
};
|
||||
|
||||
static const char* translators[] = {
|
||||
N_("French:\n\tAlain Fréhel <alain.frehel@free.fr>\n\tChristophe Combelles <ccomb@free.fr>\n"),
|
||||
N_("French:\n\tAlain Fréhel <alain.frehel@free.fr>\n\tChristophe Combelles <ccomb@free.fr>\n\tMartin Blanchard\n"),
|
||||
N_("German:\n\tKarsten Petersen <kapet@kapet.de>\
|
||||
\n\tSebastian Arnold <mail@sebastian-arnold.net>\
|
||||
\n\tRobert Schwede<schwede@ironshark.com>\n"),
|
||||
@@ -181,6 +182,8 @@ static const char* translators[] = {
|
||||
N_("Greek:\n\t Klearchos Gourgourinis <muadib@in.gr>\n"),
|
||||
N_("Swedish:\n\t Petter Sundlöf <petter.sundlof@gmail.com>\n"),
|
||||
N_("Polish:\n\t Piotr Zaryk <pzaryk@gmail.com>\n"),
|
||||
N_("Czech:\n\t Pavel Frich\n"),
|
||||
N_("Norwegian:\n\t Eivind Ødegård\n"),
|
||||
0
|
||||
};
|
||||
|
||||
@@ -559,7 +562,7 @@ About::About ()
|
||||
}
|
||||
|
||||
set_translator_credits (t);
|
||||
set_copyright (_("Copyright (C) 1999-2009 Paul Davis\n"));
|
||||
set_copyright (_("Copyright (C) 1999-2010 Paul Davis\n"));
|
||||
set_license (gpl);
|
||||
set_name (X_("ardour"));
|
||||
set_website (X_("http://ardour.org/"));
|
||||
|
||||
@@ -286,6 +286,7 @@
|
||||
<menuitem action='track-height-smaller'/>
|
||||
<menuitem action='track-height-small'/>
|
||||
</menu>
|
||||
<menuitem action='track-record-enable-toggle'/>
|
||||
<menuitem action='toggle-track-active'/>
|
||||
<menuitem action='remove-track'/>
|
||||
</menu>
|
||||
@@ -433,7 +434,10 @@
|
||||
<separator/>
|
||||
</menu>
|
||||
<menu name='Help' action='Help'>
|
||||
#ifndef GTKOSX
|
||||
<menuitem action='About'/>
|
||||
#endif
|
||||
<menuitem action='Chat'/>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/enumwriter.h"
|
||||
#include "pbd/memento_command.h"
|
||||
#include "pbd/openuri.h"
|
||||
#include "pbd/file_utils.h"
|
||||
|
||||
#include "gtkmm2ext/gtk_ui.h"
|
||||
@@ -2036,6 +2037,7 @@ ARDOUR_UI::snapshot_session ()
|
||||
prompter.set_prompt (_("Name of New Snapshot"));
|
||||
prompter.set_initial_text (timebuf);
|
||||
|
||||
again:
|
||||
switch (prompter.run()) {
|
||||
case RESPONSE_ACCEPT:
|
||||
{
|
||||
@@ -2043,6 +2045,21 @@ ARDOUR_UI::snapshot_session ()
|
||||
|
||||
bool do_save = (snapname.length() != 0);
|
||||
|
||||
if (do_save) {
|
||||
if (snapname.find ('/') != string::npos) {
|
||||
MessageDialog msg (_("To ensure compatibility with various systems\n"
|
||||
"snapshot names may not contain a '/' character"));
|
||||
msg.run ();
|
||||
goto again;
|
||||
}
|
||||
if (snapname.find ('\\') != string::npos) {
|
||||
MessageDialog msg (_("To ensure compatibility with various systems\n"
|
||||
"snapshot names may not contain a '\\' character"));
|
||||
msg.run ();
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
vector<sys::path> p;
|
||||
get_state_files_in_directory (_session->session_directory().root_path(), p);
|
||||
vector<string> n = get_file_names_no_extension (p);
|
||||
@@ -2493,6 +2510,10 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
|
||||
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
|
||||
(session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
|
||||
|
||||
/* absolute path or cwd-relative path specified for session name: infer session folder
|
||||
from what was given.
|
||||
*/
|
||||
|
||||
session_path = Glib::path_get_dirname (session_name);
|
||||
session_name = Glib::path_get_basename (session_name);
|
||||
|
||||
@@ -2529,6 +2550,22 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session_name.find ('/') != Glib::ustring::npos) {
|
||||
MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n"
|
||||
"session names may not contain a '/' character"));
|
||||
msg.run ();
|
||||
ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
|
||||
continue;
|
||||
}
|
||||
|
||||
if (session_name.find ('\\') != Glib::ustring::npos) {
|
||||
MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n"
|
||||
"session names may not contain a '\\' character"));
|
||||
msg.run ();
|
||||
ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
|
||||
continue;
|
||||
}
|
||||
|
||||
_session_is_new = true;
|
||||
}
|
||||
|
||||
@@ -2556,7 +2593,9 @@ ARDOUR_UI::close_session()
|
||||
return;
|
||||
}
|
||||
|
||||
unload_session (true);
|
||||
if (unload_session (true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ARDOUR_COMMAND_LINE::session_name = "";
|
||||
get_session_parameters (true, false);
|
||||
@@ -2726,6 +2765,16 @@ ARDOUR_UI::show ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::launch_chat ()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
open_uri("http://webchat.freenode.net/?channels=ardour-osx");
|
||||
#else
|
||||
open_uri("http://webchat.freenode.net/?channels=ardour");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::show_about ()
|
||||
{
|
||||
@@ -2734,6 +2783,7 @@ ARDOUR_UI::show_about ()
|
||||
about->signal_response().connect(sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response) );
|
||||
}
|
||||
|
||||
about->set_transient_for(*editor);
|
||||
about->show_all ();
|
||||
}
|
||||
|
||||
@@ -2837,9 +2887,6 @@ require some unused files to continue to exist."));
|
||||
|
||||
const string dead_sound_directory = _session->session_directory().dead_sound_path().to_string();
|
||||
|
||||
|
||||
|
||||
|
||||
/* subst:
|
||||
%1 - number of files removed
|
||||
%2 - location of "dead_sounds"
|
||||
@@ -2848,19 +2895,22 @@ require some unused files to continue to exist."));
|
||||
*/
|
||||
|
||||
const char* bprefix;
|
||||
double space_adjusted = 0;
|
||||
|
||||
if (rep.space < 1048576.0f) {
|
||||
if (rep.space < 100000.0f) {
|
||||
bprefix = X_("kilo");
|
||||
} else if (rep.space < 1048576.0f * 1000) {
|
||||
} else if (rep.space < 1000000.0f * 1000) {
|
||||
bprefix = X_("mega");
|
||||
space_adjusted = truncf((float)rep.space / 1000.0);
|
||||
} else {
|
||||
bprefix = X_("giga");
|
||||
space_adjusted = truncf((float)rep.space / (1000000.0 * 1000));
|
||||
}
|
||||
|
||||
if (removed > 1) {
|
||||
txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
|
||||
txt.set_text (string_compose (plural_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix));
|
||||
} else {
|
||||
txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
|
||||
txt.set_text (string_compose (singular_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix));
|
||||
}
|
||||
|
||||
dhbox.pack_start (*dimage, true, false, 5);
|
||||
|
||||
@@ -115,6 +115,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
||||
void show_splash ();
|
||||
void hide_splash ();
|
||||
|
||||
void launch_chat ();
|
||||
void show_about ();
|
||||
void hide_about ();
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ ARDOUR_UI::install_actions ()
|
||||
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::register_action (common_actions, X_("About"), _("About"), sigc::mem_fun(*this, &ARDOUR_UI::show_about));
|
||||
ActionManager::register_action (common_actions, X_("Chat"), _("Chat"), sigc::mem_fun(*this, &ARDOUR_UI::launch_chat));
|
||||
ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
|
||||
ActionManager::register_toggle_action (common_actions, X_("ToggleKeyEditor"), _("Key Bindings"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_key_editor));
|
||||
ActionManager::register_toggle_action (common_actions, X_("ToggleBundleManager"), _("Bundle Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_bundle_manager));
|
||||
|
||||
@@ -473,8 +473,6 @@ AudioRegionView::set_height (gdouble height)
|
||||
// FIXME: ick
|
||||
height -= 2;
|
||||
|
||||
_height = height;
|
||||
|
||||
for (uint32_t n=0; n < wcnt; ++n) {
|
||||
gdouble ht;
|
||||
|
||||
@@ -503,11 +501,6 @@ AudioRegionView::set_height (gdouble height)
|
||||
|
||||
manage_zero_line ();
|
||||
reset_fade_shapes ();
|
||||
|
||||
if (name_pixbuf) {
|
||||
name_pixbuf->raise_to_top();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -497,6 +497,18 @@ CrossfadeEditor::add_control_point (double x, double y)
|
||||
void
|
||||
CrossfadeEditor::Point::move_to (double nx, double ny, double xfract, double yfract)
|
||||
{
|
||||
if ( xfract < 0.0 ) {
|
||||
xfract = 0.0;
|
||||
} else if ( xfract > 1.0 ) {
|
||||
xfract = 1.0;
|
||||
}
|
||||
|
||||
if ( yfract < 0.0 ) {
|
||||
yfract = 0.0;
|
||||
} else if ( yfract > 1.0 ) {
|
||||
yfract = 1.0;
|
||||
}
|
||||
|
||||
const double half_size = rint(size/2.0);
|
||||
double x1 = nx - half_size;
|
||||
double x2 = nx + half_size;
|
||||
|
||||
@@ -319,6 +319,7 @@ Editor::Editor ()
|
||||
|
||||
have_pending_keyboard_selection = false;
|
||||
_follow_playhead = true;
|
||||
_stationary_playhead = false;
|
||||
_xfade_visibility = true;
|
||||
editor_ruler_menu = 0;
|
||||
no_ruler_shown_update = false;
|
||||
@@ -1730,6 +1731,8 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
|
||||
region_mute_item->set_active();
|
||||
fooc.block (false);
|
||||
}
|
||||
|
||||
items.push_back (MenuElem (_("Transpose"), mem_fun(*this, &Editor::pitch_shift_regions)));
|
||||
|
||||
if (!Profile->get_sae()) {
|
||||
items.push_back (CheckMenuElem (_("Opaque")));
|
||||
@@ -2243,7 +2246,8 @@ Editor::set_state (const XMLNode& node, int /*version*/)
|
||||
move (x, y);
|
||||
|
||||
if (_session && (prop = node.property ("playhead"))) {
|
||||
nframes64_t pos = atol (prop->value().c_str());
|
||||
nframes64_t pos;
|
||||
sscanf (prop->value().c_str(), "%" PRIi64, &pos);
|
||||
playhead_cursor->set_position (pos);
|
||||
} else {
|
||||
playhead_cursor->set_position (0);
|
||||
@@ -2341,6 +2345,18 @@ Editor::set_state (const XMLNode& node, int /*version*/)
|
||||
}
|
||||
}
|
||||
|
||||
if ((prop = node.property ("stationary-playhead"))) {
|
||||
bool yn = (prop->value() == "yes");
|
||||
set_stationary_playhead (yn);
|
||||
RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
|
||||
if (act) {
|
||||
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
|
||||
if (tact->get_active() != yn) {
|
||||
tact->set_active (yn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((prop = node.property ("region-list-sort-type"))) {
|
||||
RegionListSortType st;
|
||||
_regions->reset_sort_type ((RegionListSortType) string_2_enum (prop->value(), st), true);
|
||||
@@ -2447,6 +2463,7 @@ Editor::get_state ()
|
||||
node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no");
|
||||
node->add_property ("show-measures", _show_measures ? "yes" : "no");
|
||||
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
|
||||
node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
|
||||
node->add_property ("xfades-visible", _xfade_visibility ? "yes" : "no");
|
||||
node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
|
||||
node->add_property ("mouse-mode", enum2str(mouse_mode));
|
||||
@@ -3697,6 +3714,29 @@ Editor::set_follow_playhead (bool yn)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::toggle_stationary_playhead ()
|
||||
{
|
||||
RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
|
||||
if (act) {
|
||||
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
|
||||
set_stationary_playhead (tact->get_active());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_stationary_playhead (bool yn)
|
||||
{
|
||||
if (_stationary_playhead != yn) {
|
||||
if ((_stationary_playhead = yn) == true) {
|
||||
/* catch up */
|
||||
// FIXME need a 3.0 equivalent of this 2.X call
|
||||
// update_current_screen ();
|
||||
}
|
||||
instant_save ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::toggle_xfade_active (boost::weak_ptr<Crossfade> wxfade)
|
||||
{
|
||||
@@ -4119,10 +4159,11 @@ Editor::undo_visual_state ()
|
||||
return;
|
||||
}
|
||||
|
||||
redo_visual_stack.push_back (current_visual_state());
|
||||
|
||||
VisualState* vs = undo_visual_stack.back();
|
||||
undo_visual_stack.pop_back();
|
||||
use_visual_state (*vs);
|
||||
redo_visual_stack.push_back (vs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4132,10 +4173,11 @@ Editor::redo_visual_state ()
|
||||
return;
|
||||
}
|
||||
|
||||
undo_visual_stack.push_back (current_visual_state());
|
||||
|
||||
VisualState* vs = redo_visual_stack.back();
|
||||
redo_visual_stack.pop_back();
|
||||
use_visual_state (*vs);
|
||||
undo_visual_stack.push_back (vs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4669,6 +4711,8 @@ _idle_resizer (gpointer arg)
|
||||
void
|
||||
Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
|
||||
{
|
||||
cerr << "add tav " << view << " with hdelta = " << h << endl;
|
||||
|
||||
if (resize_idle_id < 0) {
|
||||
resize_idle_id = g_idle_add (_idle_resizer, this);
|
||||
_pending_resize_amount = 0;
|
||||
@@ -4682,6 +4726,8 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
|
||||
_pending_resize_amount += h;
|
||||
_pending_resize_view = view;
|
||||
|
||||
cerr << "Pending resize amount initially set at " << _pending_resize_amount << endl;
|
||||
|
||||
min_resulting = min (min_resulting, int32_t (_pending_resize_view->current_height()) + _pending_resize_amount);
|
||||
|
||||
if (selection->tracks.contains (_pending_resize_view)) {
|
||||
@@ -4697,6 +4743,7 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
|
||||
/* clamp */
|
||||
if (uint32_t (min_resulting) < TimeAxisView::hSmall) {
|
||||
_pending_resize_amount += TimeAxisView::hSmall - min_resulting;
|
||||
cerr << "pending resize amount = " << _pending_resize_amount << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4704,6 +4751,9 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
|
||||
bool
|
||||
Editor::idle_resize ()
|
||||
{
|
||||
cerr << "Idle resize, pra = " << _pending_resize_amount
|
||||
<< " set height to " << _pending_resize_view->current_height() << " + " << _pending_resize_amount << endl;
|
||||
|
||||
_pending_resize_view->idle_resize (_pending_resize_view->current_height() + _pending_resize_amount);
|
||||
|
||||
if (dynamic_cast<AutomationTimeAxisView*> (_pending_resize_view) == 0 &&
|
||||
@@ -4716,6 +4766,7 @@ Editor::idle_resize ()
|
||||
}
|
||||
}
|
||||
|
||||
_pending_resize_amount = 0;
|
||||
flush_canvas ();
|
||||
_group_tabs->set_dirty ();
|
||||
resize_idle_id = -1;
|
||||
@@ -5121,33 +5172,33 @@ Editor::super_rapid_screen_update ()
|
||||
playhead_cursor->set_position (frame);
|
||||
}
|
||||
|
||||
#undef CONTINUOUS_SCROLL
|
||||
#ifndef CONTINUOUS_SCROLL
|
||||
if (!_stationary_playhead) {
|
||||
|
||||
if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
|
||||
reset_x_origin_to_follow_playhead ();
|
||||
}
|
||||
if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
|
||||
reset_x_origin_to_follow_playhead ();
|
||||
}
|
||||
|
||||
#else // CONTINUOUS_SCROLL
|
||||
|
||||
/* don't do continuous scroll till the new position is in the rightmost quarter of the
|
||||
editor canvas
|
||||
*/
|
||||
|
||||
double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_unit;
|
||||
if (target <= 0.0) {
|
||||
target = 0.0;
|
||||
}
|
||||
if (fabs(target - current) < current_page_frames() / frames_per_unit) {
|
||||
target = (target * 0.15) + (current * 0.85);
|
||||
} else {
|
||||
/* relax */
|
||||
}
|
||||
|
||||
current = target;
|
||||
horizontal_adjustment.set_value (current);
|
||||
|
||||
#endif // CONTINUOUS_SCROLL
|
||||
} else {
|
||||
|
||||
/* don't do continuous scroll till the new position is in the rightmost quarter of the
|
||||
editor canvas
|
||||
*/
|
||||
#if 0
|
||||
// FIXME DO SOMETHING THAT WORKS HERE - this is 2.X code
|
||||
double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_unit;
|
||||
if (target <= 0.0) {
|
||||
target = 0.0;
|
||||
}
|
||||
if (fabs(target - current) < current_page_frames() / frames_per_unit) {
|
||||
target = (target * 0.15) + (current * 0.85);
|
||||
} else {
|
||||
/* relax */
|
||||
}
|
||||
|
||||
current = target;
|
||||
horizontal_adjustment.set_value (current);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +357,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
|
||||
/* playhead/screen stuff */
|
||||
|
||||
void set_stationary_playhead (bool yn);
|
||||
void toggle_stationary_playhead ();
|
||||
bool stationary_playhead() const { return _stationary_playhead; }
|
||||
|
||||
void set_follow_playhead (bool yn);
|
||||
void toggle_follow_playhead ();
|
||||
bool follow_playhead() const { return _follow_playhead; }
|
||||
@@ -419,6 +423,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
void goto_visual_state (uint32_t);
|
||||
void save_visual_state (uint32_t);
|
||||
|
||||
void queue_draw_resize_line (int at);
|
||||
void start_resize_line_ops ();
|
||||
void end_resize_line_ops ();
|
||||
|
||||
TrackViewList const & get_track_views () {
|
||||
return track_views;
|
||||
}
|
||||
@@ -1401,6 +1409,8 @@ public:
|
||||
bool _show_measures;
|
||||
/// true if the editor should follow the playhead, otherwise false
|
||||
bool _follow_playhead;
|
||||
/// true if we scroll the tracks rather than the playhead
|
||||
bool _stationary_playhead;
|
||||
/// true if waveforms should be shown while recording audio tracks, otherwise false
|
||||
bool _show_waveforms_recording;
|
||||
|
||||
|
||||
@@ -207,6 +207,7 @@ Editor::register_actions ()
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "track-record-enable-toggle", _("Toggle Record Enable"), sigc::mem_fun(*this, &Editor::toggle_record_enable));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
|
||||
for (int i = 1; i <= 12; ++i) {
|
||||
string const a = string_compose (X_("save-visual-state-%1"), i);
|
||||
@@ -270,17 +271,23 @@ Editor::register_actions ()
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), true));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), false));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), sigc::mem_fun(*this, &Editor::scroll_tracks_up));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (editor_actions, "scroll-tracks-down", _("Scroll Tracks Down"), sigc::mem_fun(*this, &Editor::scroll_tracks_down));
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (editor_actions, "step-tracks-up", _("Step Tracks Up"), sigc::mem_fun(*this, &Editor::scroll_tracks_up_line));
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (editor_actions, "step-tracks-down", _("Step Tracks Down"), sigc::mem_fun(*this, &Editor::scroll_tracks_down_line));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "scroll-backward", _("Scroll Backward"), sigc::bind (sigc::mem_fun(*this, &Editor::scroll_backward), 0.8f));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
@@ -550,6 +557,8 @@ Editor::register_actions ()
|
||||
act = ActionManager::register_action (editor_actions, "remove-last-capture", _("Remove Last Capture"), (sigc::mem_fun(*this, &Editor::remove_last_capture)));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
ActionManager::register_toggle_action (editor_actions, "toggle-stationary-playhead", _("Stationary Playhead"), (mem_fun(*this, &Editor::toggle_stationary_playhead)));
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time)));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
@@ -567,6 +576,7 @@ Editor::register_actions ()
|
||||
|
||||
act = ActionManager::register_action (editor_actions, "fit-tracks", _("Fit Selected Tracks"), sigc::mem_fun(*this, &Editor::fit_selected_tracks));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), sigc::bind (
|
||||
sigc::mem_fun(*this, &Editor::set_track_height), TimeAxisView::hLargest));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
@@ -801,7 +801,7 @@ Editor::scroll_canvas_horizontally ()
|
||||
}
|
||||
|
||||
#ifndef GTKOSX
|
||||
if (!autoscroll_active) {
|
||||
if (!autoscroll_active && !_stationary_playhead) {
|
||||
/* force rulers and canvas to move in lock step */
|
||||
while (gtk_events_pending ()) {
|
||||
gtk_main_iteration ();
|
||||
|
||||
@@ -1555,7 +1555,7 @@ Editor::temporal_zoom (gdouble fpu)
|
||||
|
||||
/* XXX this limit is also in ::set_frames_per_unit() */
|
||||
|
||||
if (frames_per_unit <= 2.0 && fpu <= frames_per_unit) {
|
||||
if (frames_per_unit <= 1.0 && fpu <= frames_per_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2512,8 +2512,8 @@ Editor::rename_region()
|
||||
d.get_vbox()->set_border_width (12);
|
||||
d.get_vbox()->pack_start (hbox, false, false);
|
||||
|
||||
d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
|
||||
d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
||||
d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
|
||||
|
||||
d.set_size_request (300, -1);
|
||||
d.set_position (Gtk::WIN_POS_MOUSE);
|
||||
|
||||
@@ -1255,24 +1255,34 @@ EngineControl::set_state (const XMLNode& root)
|
||||
} else if (child->name() == "periodsize") {
|
||||
period_size_combo.set_active_text(strval);
|
||||
} else if (child->name() == "serverpath") {
|
||||
/* do not allow us to use a server path that doesn't
|
||||
exist on this system. this handles cases where
|
||||
the user has an RC file listing a serverpath
|
||||
from some other machine.
|
||||
*/
|
||||
vector<string>::iterator x;
|
||||
for (x = server_strings.begin(); x != server_strings.end(); ++x) {
|
||||
if (*x == strval) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x != server_strings.end()) {
|
||||
serverpath_combo.set_active_text (strval);
|
||||
} else {
|
||||
warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
|
||||
strval)
|
||||
<< endmsg;
|
||||
}
|
||||
|
||||
/* only attempt to set this if we have bothered to look
|
||||
up server names already. otherwise this is all
|
||||
redundant (actually, all of this dialog/widget
|
||||
is redundant in that case ...)
|
||||
*/
|
||||
|
||||
if (!server_strings.empty()) {
|
||||
/* do not allow us to use a server path that doesn't
|
||||
exist on this system. this handles cases where
|
||||
the user has an RC file listing a serverpath
|
||||
from some other machine.
|
||||
*/
|
||||
vector<string>::iterator x;
|
||||
for (x = server_strings.begin(); x != server_strings.end(); ++x) {
|
||||
if (*x == strval) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x != server_strings.end()) {
|
||||
serverpath_combo.set_active_text (strval);
|
||||
} else {
|
||||
warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
|
||||
strval)
|
||||
<< endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (child->name() == "driver") {
|
||||
driver_combo.set_active_text(strval);
|
||||
} else if (child->name() == "interface") {
|
||||
|
||||
@@ -322,7 +322,7 @@ GenericPluginUI::ControlUI::ControlUI ()
|
||||
below). be sure to include a descender.
|
||||
*/
|
||||
|
||||
set_size_request_to_display_given_text (*automate_button.get_child(), _("Mgnual"), 5, 5);
|
||||
set_size_request_to_display_given_text (automate_button, _("Mgnual"), 15, 10);
|
||||
|
||||
ignore_change = 0;
|
||||
display = 0;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ardour/track.h"
|
||||
#include "ardour/audio_track.h"
|
||||
#include "ardour/midi_track.h"
|
||||
#include "ardour/mtdm.h"
|
||||
#include "ardour/data_type.h"
|
||||
#include "ardour/port.h"
|
||||
#include "ardour/bundle.h"
|
||||
@@ -216,16 +217,88 @@ IOSelectorWindow::io_name_changed (void* src)
|
||||
}
|
||||
|
||||
PortInsertUI::PortInsertUI (Gtk::Window* parent, ARDOUR::Session* sess, boost::shared_ptr<ARDOUR::PortInsert> pi)
|
||||
: input_selector (parent, sess, pi->input())
|
||||
, output_selector (parent, sess, pi->output())
|
||||
: _pi (pi)
|
||||
, latency_button (_("Measure Latency"))
|
||||
, input_selector (parent, sess, pi->input())
|
||||
, output_selector (parent, sess, pi->output())
|
||||
{
|
||||
latency_hbox.pack_start (latency_button, false, false);
|
||||
latency_hbox.pack_start (latency_display, false, false);
|
||||
latency_frame.add (latency_hbox);
|
||||
|
||||
output_selector.set_min_height_divisor (2);
|
||||
input_selector.set_min_height_divisor (2);
|
||||
|
||||
|
||||
pack_start (latency_frame);
|
||||
pack_start (output_selector, true, true);
|
||||
pack_start (input_selector, true, true);
|
||||
|
||||
latency_button.signal_toggled().connect (mem_fun (*this, &PortInsertUI::latency_button_toggled));
|
||||
}
|
||||
|
||||
bool
|
||||
PortInsertUI::check_latency_measurement ()
|
||||
{
|
||||
MTDM* mtdm = _pi->mtdm ();
|
||||
|
||||
if (mtdm->resolve () < 0) {
|
||||
latency_display.set_text (_("No signal detected"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mtdm->err () > 0.3) {
|
||||
mtdm->invert ();
|
||||
mtdm->resolve ();
|
||||
}
|
||||
|
||||
char buf[64];
|
||||
nframes_t sample_rate = AudioEngine::instance()->frame_rate();
|
||||
|
||||
if (sample_rate == 0) {
|
||||
latency_display.set_text (_("Disconnected from audio engine"));
|
||||
_pi->stop_latency_detection ();
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof (buf), "%10.3lf frames %10.3lf ms", mtdm->del (), mtdm->del () * 1000.0f/sample_rate);
|
||||
|
||||
bool solid = true;
|
||||
|
||||
if (mtdm->err () > 0.2) {
|
||||
strcat (buf, " ??");
|
||||
solid = false;
|
||||
}
|
||||
|
||||
if (mtdm->inv ()) {
|
||||
strcat (buf, " (Inv)");
|
||||
solid = false;
|
||||
}
|
||||
|
||||
if (solid) {
|
||||
_pi->set_measured_latency ((nframes_t) rint (mtdm->del()));
|
||||
strcat (buf, " (set)");
|
||||
}
|
||||
|
||||
latency_display.set_text (buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PortInsertUI::latency_button_toggled ()
|
||||
{
|
||||
if (latency_button.get_active ()) {
|
||||
|
||||
_pi->start_latency_detection ();
|
||||
latency_display.set_text (_("Detecting ..."));
|
||||
latency_timeout = Glib::signal_timeout().connect (mem_fun (*this, &PortInsertUI::check_latency_measurement), 250);
|
||||
|
||||
} else {
|
||||
_pi->stop_latency_detection ();
|
||||
latency_timeout.disconnect ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortInsertUI::redisplay ()
|
||||
{
|
||||
|
||||
@@ -98,8 +98,18 @@ class PortInsertUI : public Gtk::HBox
|
||||
void finished (IOSelector::Result);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::PortInsert> _pi;
|
||||
|
||||
Gtk::ToggleButton latency_button;
|
||||
IOSelector input_selector;
|
||||
IOSelector output_selector;
|
||||
Gtk::Label latency_display;
|
||||
Gtk::Frame latency_frame;
|
||||
Gtk::HBox latency_hbox;
|
||||
sigc::connection latency_timeout;
|
||||
|
||||
bool check_latency_measurement ();
|
||||
void latency_button_toggled ();
|
||||
};
|
||||
|
||||
class PortInsertWindow : public ArdourDialog
|
||||
|
||||
@@ -281,10 +281,52 @@ fixup_bundle_environment ()
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
sigpipe_handler (int /*sig*/)
|
||||
static gboolean
|
||||
tell_about_jack_death (void* /* ignored */)
|
||||
{
|
||||
cerr << _("SIGPIPE received - JACK has probably died") << endl;
|
||||
if (AudioEngine::instance()->processed_frames() == 0) {
|
||||
/* died during startup */
|
||||
MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
|
||||
msg.set_position (Gtk::WIN_POS_CENTER);
|
||||
msg.set_secondary_text (_(
|
||||
"JACK exited unexpectedly, and without notifying Ardour.\n\
|
||||
\n\
|
||||
This could be due to misconfiguration or to an error inside JACK.\n\
|
||||
\n\
|
||||
Click OK to exit Ardour."));
|
||||
|
||||
msg.run ();
|
||||
_exit (0);
|
||||
|
||||
} else {
|
||||
|
||||
/* engine has already run, so this is a mid-session JACK death */
|
||||
|
||||
MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
|
||||
msg->set_secondary_text (_(
|
||||
"JACK exited unexpectedly, and without notifying Ardour.\n\
|
||||
\n\
|
||||
This is probably due to an error inside JACK. You should restart JACK\n\
|
||||
and reconnect Ardour to it, or exit Ardour now. You cannot save your\n\
|
||||
session at this time, because we would lose your connection information.\n"));
|
||||
msg->present ();
|
||||
}
|
||||
return false; /* do not call again */
|
||||
}
|
||||
|
||||
static void
|
||||
sigpipe_handler (int sig)
|
||||
{
|
||||
/* XXX fix this so that we do this again after a reconnect to JACK
|
||||
*/
|
||||
|
||||
static bool done_the_jack_thing = false;
|
||||
|
||||
if (!done_the_jack_thing) {
|
||||
AudioEngine::instance()->died ();
|
||||
g_idle_add (tell_about_jack_death, 0);
|
||||
done_the_jack_thing = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LV2
|
||||
|
||||
@@ -255,20 +255,17 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
|
||||
/* setup name pixbuf sizes */
|
||||
name_font = get_font_for_style (N_("MarkerText"));
|
||||
|
||||
Gtk::Window win;
|
||||
Gtk::Label foo;
|
||||
win.add (foo);
|
||||
|
||||
Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
|
||||
int width;
|
||||
int height;
|
||||
|
||||
layout->set_font_description (*name_font);
|
||||
Gtkmm2ext::get_ink_pixel_size (layout, width, height);
|
||||
name_height = height + 6;
|
||||
Gtkmm2ext::get_ink_pixel_size (layout, width, name_height);
|
||||
|
||||
name_pixbuf = new ArdourCanvas::Pixbuf(*group);
|
||||
name_pixbuf->property_x() = label_offset;
|
||||
name_pixbuf->property_y() = (13/2) - (name_height/2);
|
||||
|
||||
set_name (annotation.c_str());
|
||||
|
||||
|
||||
@@ -207,6 +207,7 @@ MixerStrip::init ()
|
||||
ARDOUR_UI::instance()->set_tip (&group_button, _("Mix group"), "");
|
||||
group_button.add (group_label);
|
||||
group_button.set_name ("MixerGroupButton");
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (group_button, "Group", 2, 2);
|
||||
group_label.set_name ("MixerGroupButtonLabel");
|
||||
|
||||
comment_button.set_name ("MixerCommentButton");
|
||||
@@ -1319,12 +1320,7 @@ MixerStrip::route_group_changed ()
|
||||
RouteGroup *rg = _route->route_group();
|
||||
|
||||
if (rg) {
|
||||
/* XXX: this needs a better algorithm */
|
||||
string truncated = rg->name ();
|
||||
if (truncated.length () > 5) {
|
||||
truncated = truncated.substr (0, 5);
|
||||
}
|
||||
group_label.set_text (truncated);
|
||||
group_label.set_text (PBD::short_version (rg->name(), 5));
|
||||
} else {
|
||||
switch (_width) {
|
||||
case Wide:
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <fstream>
|
||||
#include <gtkmm/stock.h>
|
||||
|
||||
#include "pbd/openuri.h"
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/filesystem_paths.h"
|
||||
|
||||
@@ -176,35 +178,16 @@ NagScreen::offer_to_donate ()
|
||||
|
||||
/* we don't care if it fails */
|
||||
|
||||
open_uri (uri);
|
||||
PBD::open_uri (uri);
|
||||
}
|
||||
|
||||
void
|
||||
NagScreen::offer_to_subscribe ()
|
||||
{
|
||||
const char* uri = "http://ardour.org/subscribe";
|
||||
|
||||
if (open_uri (uri)) {
|
||||
|
||||
if (PBD::open_uri (uri)) {
|
||||
mark_subscriber ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NagScreen::open_uri (const char* uri)
|
||||
{
|
||||
#ifdef HAVE_GTK_OPEN_URI
|
||||
GError* err;
|
||||
return gtk_open_uri (0, uri, GDK_CURRENT_TIME, &err);
|
||||
#else
|
||||
#ifdef GTKOSX
|
||||
extern bool cocoa_open_url (const char*);
|
||||
return cocoa_open_url (uri);
|
||||
#else
|
||||
std::string command = "xdg-open ";
|
||||
command += uri;
|
||||
spawn_command_line_async (command);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ class NagScreen : public ArdourDialog
|
||||
void mark_affirmed_subscriber ();
|
||||
void offer_to_donate ();
|
||||
void offer_to_subscribe ();
|
||||
bool open_uri (const char*);
|
||||
static bool is_subscribed (bool& really);
|
||||
};
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ using namespace Gtkmm2ext;
|
||||
|
||||
ProcessorBox* ProcessorBox::_current_processor_box = 0;
|
||||
RefPtr<Action> ProcessorBox::paste_action;
|
||||
RefPtr<Action> ProcessorBox::cut_action;
|
||||
Glib::RefPtr<Gdk::Pixbuf> SendProcessorEntry::_slider;
|
||||
|
||||
ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
|
||||
@@ -494,6 +495,7 @@ ProcessorBox::show_processor_menu (gint arg)
|
||||
}
|
||||
}
|
||||
|
||||
cut_action->set_sensitive (can_cut());
|
||||
paste_action->set_sensitive (!_rr_selection.processors.empty());
|
||||
|
||||
processor_menu->popup (1, arg);
|
||||
@@ -1054,6 +1056,27 @@ ProcessorBox::rename_processors ()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessorBox::can_cut () const
|
||||
{
|
||||
vector<boost::shared_ptr<Processor> > sel;
|
||||
|
||||
get_selected_processors (sel);
|
||||
|
||||
/* cut_processors () does not cut inserts */
|
||||
|
||||
for (vector<boost::shared_ptr<Processor> >::const_iterator i = sel.begin (); i != sel.end (); ++i) {
|
||||
|
||||
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
|
||||
(boost::dynamic_pointer_cast<Send>((*i)) != 0) ||
|
||||
(boost::dynamic_pointer_cast<Return>((*i)) != 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::cut_processors ()
|
||||
{
|
||||
@@ -1333,10 +1356,10 @@ ProcessorBox::deactivate_processor (boost::shared_ptr<Processor> r)
|
||||
}
|
||||
|
||||
void
|
||||
ProcessorBox::get_selected_processors (ProcSelection& processors)
|
||||
ProcessorBox::get_selected_processors (ProcSelection& processors) const
|
||||
{
|
||||
list<ProcessorEntry*> selection = processor_display.selection ();
|
||||
for (list<ProcessorEntry*>::iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||
const list<ProcessorEntry*> selection = processor_display.selection ();
|
||||
for (list<ProcessorEntry*>::const_iterator i = selection.begin(); i != selection.end(); ++i) {
|
||||
processors.push_back ((*i)->processor ());
|
||||
}
|
||||
}
|
||||
@@ -1551,9 +1574,9 @@ ProcessorBox::register_actions ()
|
||||
sigc::ptr_fun (ProcessorBox::rb_clear_post));
|
||||
|
||||
/* standard editing stuff */
|
||||
act = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_cut));
|
||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||
cut_action = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_cut));
|
||||
ActionManager::plugin_selection_sensitive_actions.push_back(cut_action);
|
||||
act = ActionManager::register_action (popup_act_grp, X_("copy"), _("Copy"),
|
||||
sigc::ptr_fun (ProcessorBox::rb_copy));
|
||||
ActionManager::plugin_selection_sensitive_actions.push_back(act);
|
||||
|
||||
@@ -238,8 +238,11 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
|
||||
void rename_processors ();
|
||||
|
||||
void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<ARDOUR::Processor>));
|
||||
void get_selected_processors (ProcSelection&);
|
||||
void get_selected_processors (ProcSelection&) const;
|
||||
|
||||
bool can_cut() const;
|
||||
|
||||
static Glib::RefPtr<Gtk::Action> cut_action;
|
||||
static Glib::RefPtr<Gtk::Action> paste_action;
|
||||
void paste_processor_state (const XMLNodeList&, boost::shared_ptr<ARDOUR::Processor>);
|
||||
|
||||
|
||||
@@ -228,6 +228,10 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
|
||||
virtual void set_selected_mixer_strip (TimeAxisView&) = 0;
|
||||
virtual void hide_track_in_display (TimeAxisView& tv, bool temporary = false) = 0;
|
||||
|
||||
virtual void set_stationary_playhead (bool yn) = 0;
|
||||
virtual void toggle_stationary_playhead () = 0;
|
||||
virtual bool stationary_playhead() const = 0;
|
||||
|
||||
/** Set whether the editor should follow the playhead.
|
||||
* @param yn true to follow playhead, otherwise false.
|
||||
*/
|
||||
|
||||
@@ -94,7 +94,6 @@ RegionView::RegionView (const RegionView& other)
|
||||
current_visible_sync_position = other.current_visible_sync_position;
|
||||
valid = false;
|
||||
_pixel_width = other._pixel_width;
|
||||
_height = other._height;
|
||||
|
||||
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
|
||||
}
|
||||
@@ -114,7 +113,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
|
||||
current_visible_sync_position = other.current_visible_sync_position;
|
||||
valid = false;
|
||||
_pixel_width = other._pixel_width;
|
||||
_height = other._height;
|
||||
|
||||
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
|
||||
}
|
||||
@@ -147,7 +145,6 @@ RegionView::init (Gdk::Color const & basic_color, bool wfd)
|
||||
editor = 0;
|
||||
valid = true;
|
||||
in_destructor = false;
|
||||
_height = 0;
|
||||
wait_for_data = wfd;
|
||||
sync_mark = 0;
|
||||
sync_line = 0;
|
||||
|
||||
@@ -135,7 +135,6 @@ class RegionView : public TimeAxisViewItem
|
||||
bool valid; ///< see StreamView::redisplay_diskstream()
|
||||
bool _enable_display; ///< see StreamView::redisplay_diskstream()
|
||||
double _pixel_width;
|
||||
double _height;
|
||||
bool in_destructor;
|
||||
|
||||
bool wait_for_data;
|
||||
|
||||
@@ -1471,6 +1471,12 @@ RouteTimeAxisView::get_child_list()
|
||||
}
|
||||
|
||||
|
||||
struct PlaylistSorter {
|
||||
bool operator() (boost::shared_ptr<Playlist> a, boost::shared_ptr<Playlist> b) const {
|
||||
return a->sort_id() < b->sort_id();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
|
||||
{
|
||||
@@ -1486,32 +1492,36 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
|
||||
|
||||
delete playlist_menu;
|
||||
|
||||
playlist_menu = new Menu;
|
||||
playlist_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
vector<boost::shared_ptr<Playlist> > playlists;
|
||||
vector<boost::shared_ptr<Playlist> > playlists, playlists_ds;
|
||||
boost::shared_ptr<Diskstream> ds = get_diskstream();
|
||||
RadioMenuItem::Group playlist_group;
|
||||
|
||||
_session->playlists->get (playlists);
|
||||
|
||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
|
||||
if ((*i)->get_orig_diskstream_id() == ds->id()) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist),
|
||||
boost::weak_ptr<Playlist> (*i))));
|
||||
|
||||
if (ds->playlist()->id() == (*i)->id()) {
|
||||
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
|
||||
}
|
||||
} else if (ds->playlist()->id() == (*i)->id()) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist),
|
||||
boost::weak_ptr<Playlist>(*i))));
|
||||
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
|
||||
/* find the playlists for this diskstream */
|
||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
if (((*i)->get_orig_diskstream_id() == ds->id()) || (ds->playlist()->id() == (*i)->id())) {
|
||||
playlists_ds.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
/* sort the playlists */
|
||||
PlaylistSorter cmp;
|
||||
sort(playlists_ds.begin(), playlists_ds.end(), cmp);
|
||||
|
||||
/* add the playlists to the menu */
|
||||
for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists_ds.begin(); i != playlists_ds.end(); ++i) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name()));
|
||||
RadioMenuItem *item = static_cast<RadioMenuItem*>(&playlist_items.back());
|
||||
item->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
|
||||
|
||||
if (ds->playlist()->id() == (*i)->id()) {
|
||||
item->set_active();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Rename"), sigc::mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
@@ -1535,10 +1545,15 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
|
||||
RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist> wpl)
|
||||
{
|
||||
assert (is_track());
|
||||
|
||||
// exit if we were triggered by deactivating the old playlist
|
||||
if (!item->get_active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> pl (wpl.lock());
|
||||
|
||||
if (!pl) {
|
||||
@@ -1549,8 +1564,8 @@ RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
|
||||
|
||||
if (apl) {
|
||||
if (get_diskstream()->playlist() == apl) {
|
||||
// radio button cotnrols mean this function is called for both the
|
||||
// old and new playlist
|
||||
// exit when use_playlist is called by the creation of the playlist menu
|
||||
// or the playlist choice is unchanged
|
||||
return;
|
||||
}
|
||||
get_diskstream()->use_playlist (apl);
|
||||
|
||||
@@ -294,7 +294,7 @@ protected:
|
||||
virtual Gtk::Menu* build_mode_menu() { return 0; }
|
||||
virtual Gtk::Menu* build_color_mode_menu() { return 0; }
|
||||
|
||||
void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
|
||||
void use_playlist (Gtk::RadioMenuItem *item, boost::weak_ptr<ARDOUR::Playlist> wpl);
|
||||
|
||||
ArdourCanvas::SimpleRect* timestretch_rect;
|
||||
|
||||
|
||||
@@ -262,9 +262,10 @@ RouteUI::mute_press (GdkEventButton* ev)
|
||||
// Primary-button2 click is the midi binding click
|
||||
// button2-click is "momentary"
|
||||
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mute_button->on_button_press_event (ev)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_mute_release = new SoloMuteRelease (_route->muted ());
|
||||
}
|
||||
@@ -357,9 +358,9 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
// Primary-button2 click is the midi binding click
|
||||
// button2-click is "momentary"
|
||||
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
|
||||
return false;
|
||||
}
|
||||
if (solo_button->on_button_press_event (ev)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_solo_release = new SoloMuteRelease (_route->soloed());
|
||||
}
|
||||
@@ -491,10 +492,10 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
|
||||
|
||||
if (!ignore_toggle && is_track() && rec_enable_button) {
|
||||
|
||||
if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
if (Keyboard::is_button2_event (ev)) {
|
||||
|
||||
// do nothing on midi sigc::bind event
|
||||
return false;
|
||||
return rec_enable_button->on_button_press_event (ev);
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
||||
|
||||
|
||||
@@ -443,6 +443,10 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
|
||||
chooser.set_select_multiple (true);
|
||||
chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
|
||||
chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
|
||||
#ifdef GTKOSX
|
||||
/* some broken redraw behaviour - this is a bandaid */
|
||||
chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
|
||||
#endif
|
||||
|
||||
if (!persistent_folder.empty()) {
|
||||
chooser.set_current_folder (persistent_folder);
|
||||
@@ -1000,7 +1004,7 @@ SoundFileOmega::reset_options ()
|
||||
channel_strings.push_back (_("sequence files"));
|
||||
}
|
||||
if (same_size) {
|
||||
channel_strings.push_back (_("all files in one region"));
|
||||
channel_strings.push_back (_("all files in one track"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
|
||||
resizer.signal_button_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_press));
|
||||
resizer.signal_button_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_release));
|
||||
resizer.signal_motion_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_motion));
|
||||
|
||||
resizer.set_events (Gdk::BUTTON_PRESS_MASK|
|
||||
Gdk::BUTTON_RELEASE_MASK|
|
||||
Gdk::POINTER_MOTION_MASK|
|
||||
@@ -1307,13 +1308,11 @@ TimeAxisView::idle_resize (uint32_t h)
|
||||
bool
|
||||
TimeAxisView::resizer_motion (GdkEventMotion* ev)
|
||||
{
|
||||
if (_resize_drag_start < 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
|
||||
_editor.add_to_idle_resize (this, delta);
|
||||
_resize_drag_start = ev->y_root;
|
||||
if (_resize_drag_start >= 0) {
|
||||
int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
|
||||
_editor.add_to_idle_resize (this, delta);
|
||||
_resize_drag_start = ev->y_root;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
|
||||
TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color,
|
||||
nframes64_t start, nframes64_t duration, bool recording,
|
||||
Visibility vis)
|
||||
: trackview (tv), _recregion(recording)
|
||||
: trackview (tv), _height (1.0), _recregion(recording)
|
||||
{
|
||||
if (!have_name_font) {
|
||||
|
||||
@@ -558,6 +558,8 @@ TimeAxisViewItem::set_name_text(const ustring& new_name)
|
||||
void
|
||||
TimeAxisViewItem::set_height (double height)
|
||||
{
|
||||
_height = height;
|
||||
|
||||
if (name_highlight) {
|
||||
if (height < NAME_HIGHLIGHT_THRESH) {
|
||||
name_highlight->hide ();
|
||||
@@ -841,9 +843,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
|
||||
|
||||
if (name_highlight) {
|
||||
|
||||
double height = name_highlight->property_y2 ();
|
||||
|
||||
if (height < NAME_HIGHLIGHT_THRESH) {
|
||||
if (_height < NAME_HIGHLIGHT_THRESH) {
|
||||
name_highlight->hide();
|
||||
high_enough_for_name = false;
|
||||
} else {
|
||||
@@ -853,7 +853,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
|
||||
}
|
||||
high_enough_for_name = true;
|
||||
}
|
||||
|
||||
|
||||
if (visibility & FullWidthNameHighlight) {
|
||||
name_highlight->property_x2() = pixel_width;
|
||||
} else {
|
||||
@@ -878,6 +878,8 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
|
||||
frame_handle_end->property_x2() = pixel_width;
|
||||
}
|
||||
}
|
||||
|
||||
update_name_pixbuf_visibility ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -467,6 +467,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
|
||||
ArdourCanvas::SimpleRect* frame_handle_start;
|
||||
ArdourCanvas::SimpleRect* frame_handle_end;
|
||||
|
||||
double _height;
|
||||
Visibility visibility;
|
||||
bool _recregion;
|
||||
|
||||
|
||||
@@ -247,7 +247,6 @@ _ the regular process() call to session->process() is not made.
|
||||
nframes_t _processed_frames;
|
||||
bool _freewheeling;
|
||||
bool _freewheel_pending;
|
||||
bool _freewheel_thread_registered;
|
||||
boost::function<int(nframes_t)> freewheel_action;
|
||||
bool reconnect_on_halt;
|
||||
int _usecs_per_cycle;
|
||||
|
||||
@@ -116,6 +116,7 @@ class Playlist : public SessionObject
|
||||
bool used () const { return _refcnt != 0; }
|
||||
|
||||
bool set_name (const std::string& str);
|
||||
int sort_id() { return _sort_id; }
|
||||
|
||||
const DataType& data_type() const { return _type; }
|
||||
|
||||
@@ -240,6 +241,7 @@ class Playlist : public SessionObject
|
||||
std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
|
||||
PBD::ScopedConnectionList region_state_changed_connections;
|
||||
DataType _type;
|
||||
int _sort_id;
|
||||
mutable gint block_notifications;
|
||||
mutable gint ignore_state_changes;
|
||||
mutable Glib::RecMutex region_lock;
|
||||
@@ -289,6 +291,8 @@ class Playlist : public SessionObject
|
||||
virtual void flush_notifications ();
|
||||
void clear_pending ();
|
||||
|
||||
void _set_sort_id ();
|
||||
|
||||
void notify_region_removed (boost::shared_ptr<Region>);
|
||||
void notify_region_added (boost::shared_ptr<Region>);
|
||||
void notify_length_changed ();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ardour/types.h"
|
||||
|
||||
class XMLNode;
|
||||
class MTDM;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
@@ -64,6 +65,12 @@ class PortInsert : public IOProcessor
|
||||
|
||||
uint32_t bit_slot() const { return bitslot; }
|
||||
|
||||
void start_latency_detection ();
|
||||
void stop_latency_detection ();
|
||||
|
||||
MTDM* mtdm () const { return _mtdm; }
|
||||
void set_measured_latency (nframes_t);
|
||||
|
||||
private:
|
||||
/* disallow copy construction */
|
||||
PortInsert (const PortInsert&);
|
||||
@@ -71,7 +78,10 @@ class PortInsert : public IOProcessor
|
||||
boost::shared_ptr<Delivery> _out;
|
||||
|
||||
uint32_t bitslot;
|
||||
};
|
||||
MTDM* _mtdm;
|
||||
bool _latency_detect;
|
||||
nframes_t _latency_flush_frames;
|
||||
nframes_t _measured_latency;};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
|
||||
CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
|
||||
CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50)
|
||||
CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true)
|
||||
CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", true)
|
||||
CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", false)
|
||||
CONFIG_VARIABLE (bool, new_plugins_active, "new-plugins-active", true)
|
||||
CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
|
||||
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
|
||||
|
||||
@@ -76,7 +76,6 @@ AudioEngine::AudioEngine (string client_name)
|
||||
_jack = 0;
|
||||
_frame_rate = 0;
|
||||
_buffer_size = 0;
|
||||
_freewheel_thread_registered = false;
|
||||
_freewheeling = false;
|
||||
|
||||
m_meter_thread = 0;
|
||||
@@ -1104,16 +1103,11 @@ AudioEngine::freewheel (bool onoff)
|
||||
GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
|
||||
|
||||
if (onoff != _freewheeling) {
|
||||
|
||||
if (onoff) {
|
||||
_freewheel_thread_registered = false;
|
||||
}
|
||||
|
||||
return jack_set_freewheel (_priv_jack, onoff);
|
||||
|
||||
return jack_set_freewheel (_priv_jack, onoff);
|
||||
|
||||
} else {
|
||||
/* already doing what has been asked for */
|
||||
return 0;
|
||||
/* already doing what has been asked for */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1387,14 +1387,22 @@ AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
|
||||
|
||||
/* no existing/complete transient info */
|
||||
|
||||
static bool analyse_dialog_shown = false; /* global per instance of Ardour */
|
||||
|
||||
if (!Config->get_auto_analyse_audio()) {
|
||||
pl->session().Dialog (_("\
|
||||
You have requested an operation that requires audio analysis.\n\n\
|
||||
if (!analyse_dialog_shown) {
|
||||
pl->session().Dialog (_("\
|
||||
You have requested an operation that requires audio analysis.\n\n \
|
||||
You currently have \"auto-analyse-audio\" disabled, which means\n\
|
||||
that transient data must be generated every time it is required.\n\n\
|
||||
If you are doing work that will require transient data on a\n\
|
||||
regular basis, you should probably enable \"auto-analyse-audio\"\n\
|
||||
then quit ardour and restart."));
|
||||
+then quit ardour and restart.\n\n\
|
||||
+This dialog will not display again. But you may notice a slight delay\n\
|
||||
+in this and future transient-detection operations.\n\
|
||||
+"));
|
||||
analyse_dialog_shown = true;
|
||||
}
|
||||
}
|
||||
|
||||
TransientDetector t (pl->session().frame_rate());
|
||||
|
||||
@@ -100,6 +100,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
|
||||
_out = out;
|
||||
_anchor_point = ap;
|
||||
_fixed = true;
|
||||
_follow_overlap = false;
|
||||
|
||||
initialize ();
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
|
||||
static bool
|
||||
create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
|
||||
uint samplerate, vector<boost::shared_ptr<Source> >& newfiles,
|
||||
nframes64_t /*timeline_position*/)
|
||||
framepos_t timeline_position)
|
||||
{
|
||||
for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i)
|
||||
{
|
||||
@@ -229,6 +229,14 @@ create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
|
||||
}
|
||||
|
||||
newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
|
||||
|
||||
/* for audio files, reset the timeline position so that any BWF-ish
|
||||
information in the original files we are importing from is maintained.
|
||||
*/
|
||||
|
||||
boost::shared_ptr<AudioFileSource> afs;
|
||||
afs = boost::dynamic_pointer_cast<AudioFileSource>(source);
|
||||
afs->set_timeline_position(timeline_position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -425,13 +433,13 @@ Session::import_audiofiles (ImportStatus& status)
|
||||
get_best_session_directory_for_new_source (),
|
||||
channels);
|
||||
Sources newfiles;
|
||||
nframes64_t natural_position = source ? source->natural_position() : 0;
|
||||
framepos_t natural_position = source ? source->natural_position() : 0;
|
||||
|
||||
if (status.replace_existing_source) {
|
||||
fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
|
||||
status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
|
||||
} else {
|
||||
status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
|
||||
status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
|
||||
}
|
||||
|
||||
// copy on cancel/failure so that any files that were created will be removed below
|
||||
@@ -468,7 +476,7 @@ Session::import_audiofiles (ImportStatus& status)
|
||||
|
||||
for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
|
||||
if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
|
||||
afs->update_header(0, *now, xnow);
|
||||
afs->update_header((*x)->natural_position(), *now, xnow);
|
||||
afs->done_with_peakfile_writes ();
|
||||
|
||||
/* now that there is data there, requeue the file for analysis */
|
||||
|
||||
@@ -178,8 +178,6 @@ LadspaPlugin::default_value (uint32_t port)
|
||||
sr_scaling = true;
|
||||
}
|
||||
|
||||
/* FIXME: add support for logarithmic defaults */
|
||||
|
||||
else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) {
|
||||
if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) {
|
||||
ret = exp(log(prh[port].LowerBound) * 0.75f + log(prh[port].UpperBound) * 0.25f);
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <string>
|
||||
#include <climits>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/stateful_diff_command.h"
|
||||
#include "pbd/xml++.h"
|
||||
@@ -150,6 +152,7 @@ Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
|
||||
init (hide);
|
||||
first_set_state = false;
|
||||
_name = nom;
|
||||
_set_sort_id ();
|
||||
|
||||
}
|
||||
|
||||
@@ -164,6 +167,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide
|
||||
|
||||
init (hide);
|
||||
_name = "unnamed"; /* reset by set_state */
|
||||
_set_sort_id ();
|
||||
|
||||
/* set state called by derived class */
|
||||
}
|
||||
@@ -359,6 +363,32 @@ Playlist::~Playlist ()
|
||||
/* GoingAway must be emitted by derived classes */
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::_set_sort_id ()
|
||||
{
|
||||
/*
|
||||
Playlists are given names like <track name>.<id>
|
||||
or <track name>.<edit group name>.<id> where id
|
||||
is an integer. We extract the id and sort by that.
|
||||
*/
|
||||
|
||||
size_t dot_position = _name.val().find_last_of(".");
|
||||
|
||||
if (dot_position == string::npos) {
|
||||
_sort_id = 0;
|
||||
} else {
|
||||
string t = _name.val().substr(dot_position + 1);
|
||||
|
||||
try {
|
||||
_sort_id = boost::lexical_cast<int>(t);
|
||||
}
|
||||
|
||||
catch (boost::bad_lexical_cast e) {
|
||||
_sort_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Playlist::set_name (const string& str)
|
||||
{
|
||||
@@ -370,9 +400,13 @@ Playlist::set_name (const string& str)
|
||||
|
||||
if (_refcnt > 2) {
|
||||
return false;
|
||||
} else {
|
||||
return SessionObject::set_name(str);
|
||||
}
|
||||
}
|
||||
|
||||
bool ret = SessionObject::set_name(str);
|
||||
if (ret) {
|
||||
_set_sort_id ();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -2121,6 +2155,7 @@ Playlist::set_state (const XMLNode& node, int version)
|
||||
|
||||
if (prop->name() == X_("name")) {
|
||||
_name = prop->value();
|
||||
_set_sort_id ();
|
||||
} else if (prop->name() == X_("id")) {
|
||||
_id = prop->value();
|
||||
} else if (prop->name() == X_("orig_diskstream_id")) {
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/audio_port.h"
|
||||
#include "ardour/buffer_set.h"
|
||||
#include "ardour/delivery.h"
|
||||
#include "ardour/port_insert.h"
|
||||
#include "ardour/mtdm.h"
|
||||
#include "ardour/plugin.h"
|
||||
#include "ardour/port.h"
|
||||
#include "ardour/port_insert.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/buffer_set.h"
|
||||
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/types.h"
|
||||
|
||||
@@ -44,6 +45,11 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm)
|
||||
: IOProcessor (s, true, true, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), "")
|
||||
, _out (new Delivery (s, _output, mm, _name, Delivery::Insert))
|
||||
{
|
||||
_mtdm = 0;
|
||||
_latency_detect = false;
|
||||
_latency_flush_frames = false;
|
||||
_measured_latency = 0;
|
||||
|
||||
ProcessorCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
@@ -52,6 +58,11 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLN
|
||||
, _out (new Delivery (s, _output, mm, _name, Delivery::Insert))
|
||||
|
||||
{
|
||||
_mtdm = 0;
|
||||
_latency_detect = false;
|
||||
_latency_flush_frames = false;
|
||||
_measured_latency = 0;
|
||||
|
||||
if (set_state (node, Stateful::loading_state_version)) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
@@ -61,6 +72,33 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLN
|
||||
|
||||
PortInsert::~PortInsert ()
|
||||
{
|
||||
delete _mtdm;
|
||||
}
|
||||
|
||||
void
|
||||
PortInsert::start_latency_detection ()
|
||||
{
|
||||
if (_mtdm != 0) {
|
||||
delete _mtdm;
|
||||
}
|
||||
|
||||
_mtdm = new MTDM;
|
||||
_latency_flush_frames = false;
|
||||
_latency_detect = true;
|
||||
_measured_latency = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PortInsert::stop_latency_detection ()
|
||||
{
|
||||
_latency_flush_frames = signal_latency() + _session.engine().frames_per_cycle();
|
||||
_latency_detect = false;
|
||||
}
|
||||
|
||||
void
|
||||
PortInsert::set_measured_latency (nframes_t n)
|
||||
{
|
||||
_measured_latency = n;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -70,6 +108,38 @@ PortInsert::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nf
|
||||
return;
|
||||
}
|
||||
|
||||
if (_latency_detect) {
|
||||
|
||||
if (_input->n_ports().n_audio() != 0) {
|
||||
|
||||
AudioBuffer& outbuf (_output->ports().nth_audio_port(0)->get_audio_buffer (nframes));
|
||||
Sample* in = _input->ports().nth_audio_port(0)->get_audio_buffer (nframes).data();
|
||||
Sample* out = outbuf.data();
|
||||
|
||||
_mtdm->process (nframes, in, out);
|
||||
|
||||
outbuf.is_silent (false);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else if (_latency_flush_frames) {
|
||||
|
||||
/* wait for the entire input buffer to drain before picking up input again so that we can't
|
||||
hear the remnants of whatever MTDM pumped into the pipeline.
|
||||
*/
|
||||
|
||||
silence (nframes);
|
||||
|
||||
if (_latency_flush_frames > nframes) {
|
||||
_latency_flush_frames -= nframes;
|
||||
} else {
|
||||
_latency_flush_frames = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_active && !_pending_active) {
|
||||
/* deliver silence */
|
||||
silence (nframes);
|
||||
@@ -151,7 +221,11 @@ PortInsert::signal_latency() const
|
||||
need to take that into account too.
|
||||
*/
|
||||
|
||||
return _session.engine().frames_per_cycle() + _input->signal_latency();
|
||||
if (_measured_latency == 0) {
|
||||
return _session.engine().frames_per_cycle() + _input->signal_latency();
|
||||
} else {
|
||||
return _measured_latency;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include "ardour/port_set.h"
|
||||
#include "ardour/midi_port.h"
|
||||
#include "ardour/audio_port.h"
|
||||
@@ -30,7 +32,41 @@ PortSet::PortSet()
|
||||
|
||||
static bool sort_ports_by_name (Port* a, Port* b)
|
||||
{
|
||||
return (a->name() < b->name());
|
||||
Glib::ustring aname (a->name());
|
||||
Glib::ustring bname (b->name());
|
||||
|
||||
Glib::ustring::size_type last_digit_position_a = aname.size();
|
||||
Glib::ustring::const_reverse_iterator r_iterator = aname.rbegin();
|
||||
|
||||
while (r_iterator!= aname.rend() && Glib::Unicode::isdigit(*r_iterator)) {
|
||||
r_iterator++;
|
||||
last_digit_position_a--;
|
||||
}
|
||||
|
||||
Glib::ustring::size_type last_digit_position_b = bname.size();
|
||||
r_iterator = bname.rbegin();
|
||||
|
||||
while (r_iterator != bname.rend() && Glib::Unicode::isdigit(*r_iterator)) {
|
||||
r_iterator++;
|
||||
last_digit_position_b--;
|
||||
}
|
||||
|
||||
// if some of the names don't have a number as posfix, compare as strings
|
||||
|
||||
if (last_digit_position_a == aname.size() or last_digit_position_b == bname.size()) {
|
||||
return aname < bname;
|
||||
}
|
||||
|
||||
const std::string prefix_a = aname.substr(0, last_digit_position_a - 1);
|
||||
const unsigned int posfix_a = std::atoi(aname.substr(last_digit_position_a, aname.size() - last_digit_position_a).c_str());
|
||||
const std::string prefix_b = bname.substr(0, last_digit_position_b - 1);
|
||||
const unsigned int posfix_b = std::atoi(bname.substr(last_digit_position_b, bname.size() - last_digit_position_b).c_str());
|
||||
|
||||
if (prefix_a != prefix_b) {
|
||||
return aname < bname;
|
||||
} else {
|
||||
return posfix_a < posfix_b;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -32,6 +32,7 @@ gtkmm2ext_sources = [
|
||||
'focus_entry.cc',
|
||||
'grouped_buttons.cc',
|
||||
'gtk_ui.cc',
|
||||
'gtkapplication.c',
|
||||
'idle_adjustment.cc',
|
||||
'keyboard.cc',
|
||||
'motionfeedback.cc',
|
||||
@@ -84,7 +85,9 @@ def build(bld):
|
||||
'-DLOCALEDIR="' + os.path.join(
|
||||
os.path.normpath(bld.env['DATADIRNAME']), 'locale') + '"']
|
||||
if bld.env['GTKOSX']:
|
||||
obj.source += ['sync-menu.c']
|
||||
obj.source += ['gtkapplication_quartz.mm']
|
||||
else:
|
||||
obj.source += ['gtkapplication_x11.c']
|
||||
|
||||
def shutdown():
|
||||
autowaf.shutdown()
|
||||
|
||||
28
libs/pbd/openuri.cc
Normal file
28
libs/pbd/openuri.cc
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifdef WAF_BUILD
|
||||
#include "libpbd-config.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <glibmm/spawn.h>
|
||||
|
||||
#include "pbd/openuri.h"
|
||||
|
||||
bool
|
||||
PBD::open_uri (const char* uri)
|
||||
{
|
||||
#ifdef HAVE_GTK_OPEN_URI
|
||||
GError* err;
|
||||
return gtk_open_uri (0, uri, GDK_CURRENT_TIME, &err);
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
extern bool cocoa_open_url (const char*);
|
||||
return cocoa_open_url (uri);
|
||||
#else
|
||||
std::string command = "xdg-open ";
|
||||
command += uri;
|
||||
Glib::spawn_command_line_async (command);
|
||||
|
||||
return true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
8
libs/pbd/pbd/openuri.h
Normal file
8
libs/pbd/pbd/openuri.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __libpbd_openuri_h__
|
||||
#define __libpbd_openuri_h__
|
||||
|
||||
namespace PBD {
|
||||
bool open_uri (const char*);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -73,6 +73,7 @@ def build(bld):
|
||||
locale_guard.cc
|
||||
malign.cc
|
||||
mountpoint.cc
|
||||
openuri.cc
|
||||
pathscanner.cc
|
||||
pool.cc
|
||||
property_list.cc
|
||||
|
||||
@@ -321,6 +321,7 @@ OSC::register_callbacks()
|
||||
REGISTER_CALLBACK (serv, "/ardour/transport_stop", "", transport_stop);
|
||||
REGISTER_CALLBACK (serv, "/ardour/transport_play", "", transport_play);
|
||||
REGISTER_CALLBACK (serv, "/ardour/set_transport_speed", "f", set_transport_speed);
|
||||
REGISTER_CALLBACK (serv, "/ardour/locate", "ii", locate);
|
||||
REGISTER_CALLBACK (serv, "/ardour/save_state", "", save_state);
|
||||
REGISTER_CALLBACK (serv, "/ardour/prev_marker", "", prev_marker);
|
||||
REGISTER_CALLBACK (serv, "/ardour/next_marker", "", next_marker);
|
||||
|
||||
@@ -167,6 +167,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
|
||||
return 0; \
|
||||
}
|
||||
|
||||
PATH_CALLBACK2(locate,i,i);
|
||||
PATH_CALLBACK2(route_mute,i,i);
|
||||
PATH_CALLBACK2(route_solo,i,i);
|
||||
PATH_CALLBACK2(route_recenable,i,i);
|
||||
|
||||
@@ -78,11 +78,11 @@ foreach my $tmp (keys %sources) {
|
||||
"-t", "raw", # /dev/zero is raw :)
|
||||
"-r", $samplerate, # set sample rate
|
||||
"-c", "1", # 1 channel
|
||||
"-b", # input in bytes
|
||||
"-b", "8" # input in 8 bit chunks
|
||||
"-s", # signed
|
||||
"/dev/zero", # input signal
|
||||
|
||||
"-w", # output 16 bit
|
||||
"-b", "16" # input in 16 bit chunks
|
||||
"-t", "wav", # format wav
|
||||
$audioFileDirectory."/".$sources{$tmp}->{name}, # filename
|
||||
"trim", "0", $sources{$tmp}->{calculated_length}."s" # trim silence to wanted sample amount
|
||||
|
||||
Reference in New Issue
Block a user