/*
- Copyright (C) 2000-2007 Paul Davis
+ Copyright (C) 2000-2007 Paul Davis
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <iostream>
using namespace ARDOUR;
StereoPanner::StereoPanner (boost::shared_ptr<Panner> panner)
- : _panner (panner)
- , position_control (_panner->pannable()->pan_azimuth_control)
- , width_control (_panner->pannable()->pan_width_control)
- , dragging (false)
- , dragging_position (false)
- , dragging_left (false)
- , dragging_right (false)
- , drag_start_x (0)
- , last_drag_x (0)
- , accumulated_delta (0)
- , detented (false)
- , drag_data_window (0)
- , drag_data_label (0)
- , position_binder (position_control)
- , width_binder (width_control)
+ : _panner (panner)
+ , position_control (_panner->pannable()->pan_azimuth_control)
+ , width_control (_panner->pannable()->pan_width_control)
+ , dragging (false)
+ , dragging_position (false)
+ , dragging_left (false)
+ , dragging_right (false)
+ , drag_start_x (0)
+ , last_drag_x (0)
+ , accumulated_delta (0)
+ , detented (false)
+ , drag_data_window (0)
+ , drag_data_label (0)
+ , position_binder (position_control)
+ , width_binder (width_control)
{
- if (!have_colors) {
- set_colors ();
- have_colors = true;
- }
+ if (!have_colors) {
+ set_colors ();
+ have_colors = true;
+ }
- position_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
- width_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
+ position_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
+ width_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context());
- set_flags (Gtk::CAN_FOCUS);
+ set_flags (Gtk::CAN_FOCUS);
- add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|
- Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|
- Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|
- Gdk::SCROLL_MASK|
- Gdk::POINTER_MOTION_MASK);
+ add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|
+ Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|
+ Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|
+ Gdk::SCROLL_MASK|
+ Gdk::POINTER_MOTION_MASK);
- ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler));
+ ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler));
}
StereoPanner::~StereoPanner ()
{
- delete drag_data_window;
+ delete drag_data_window;
}
void
StereoPanner::set_drag_data ()
{
- if (!drag_data_label) {
- return;
- }
-
- double pos = position_control->get_value(); // 0..1
-
- /* We show the position of the center of the image relative to the left & right.
- This is expressed as a pair of percentage values that ranges from (100,0)
- (hard left) through (50,50) (hard center) to (0,100) (hard right).
-
- This is pretty wierd, but its the way audio engineers expect it. Just remember that
- the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
- */
-
- char buf[64];
- snprintf (buf, sizeof (buf), "L:%3d R:%3d Width:%d%%", (int) rint (100.0 * (1.0 - pos)),
- (int) rint (100.0 * pos),
- (int) floor (100.0 * width_control->get_value()));
- drag_data_label->set_markup (buf);
+ if (!drag_data_label) {
+ return;
+ }
+
+ double pos = position_control->get_value(); // 0..1
+
+ /* We show the position of the center of the image relative to the left & right.
+ This is expressed as a pair of percentage values that ranges from (100,0)
+ (hard left) through (50,50) (hard center) to (0,100) (hard right).
+
+ This is pretty wierd, but its the way audio engineers expect it. Just remember that
+ the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
+ */
+
+ char buf[64];
+ snprintf (buf, sizeof (buf), "L:%3d R:%3d Width:%d%%", (int) rint (100.0 * (1.0 - pos)),
+ (int) rint (100.0 * pos),
+ (int) floor (100.0 * width_control->get_value()));
+ drag_data_label->set_markup (buf);
}
void
StereoPanner::value_change ()
{
- set_drag_data ();
- queue_draw ();
+ set_drag_data ();
+ queue_draw ();
}
bool
{
Glib::RefPtr<Gdk::Window> win (get_window());
Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state()));
- Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
-
- int width, height;
- double pos = position_control->get_value (); /* 0..1 */
- double swidth = width_control->get_value (); /* -1..+1 */
- double fswidth = fabs (swidth);
- uint32_t o, f, t, b, r;
- State state;
- const double corner_radius = 5.0;
-
- width = get_width();
- height = get_height ();
-
- if (swidth == 0.0) {
- state = Mono;
- } else if (swidth < 0.0) {
- state = Inverted;
- } else {
- state = Normal;
- }
-
- o = colors[state].outline;
- f = colors[state].fill;
- t = colors[state].text;
- b = colors[state].background;
- r = colors[state].rule;
-
- /* background */
-
- context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b));
- rounded_rectangle (context, 0, 0, width, height, corner_radius);
- context->fill ();
-
- /* the usable width is reduced from the real width, because we need space for
- the two halves of LR boxes that will extend past the actual left/right
- positions (indicated by the vertical line segment above them).
- */
-
- double usable_width = width - lr_box_size;
-
- /* compute the centers of the L/R boxes based on the current stereo width */
-
- if (fmod (usable_width,2.0) == 0) {
- /* even width, but we need odd, so that there is an exact center.
- So, offset cairo by 1, and reduce effective width by 1
- */
- usable_width -= 1.0;
- context->translate (1.0, 0.0);
- }
-
- double center = (lr_box_size/2.0) + (usable_width * pos);
- const double pan_spread = (fswidth * usable_width)/2.0;
- const double half_lr_box = lr_box_size/2.0;
- int left;
- int right;
-
- left = center - pan_spread; // center of left box
- right = center + pan_spread; // center of right box
-
- /* center line */
-
- context->set_line_width (1.0);
- context->move_to ((usable_width + lr_box_size)/2.0, 0);
- context->rel_line_to (0, height);
- context->set_source_rgba (UINT_RGBA_R_FLT(r), UINT_RGBA_G_FLT(r), UINT_RGBA_B_FLT(r), UINT_RGBA_A_FLT(r));
- context->stroke ();
-
- /* compute & draw the line through the box */
-
- context->set_line_width (2);
- context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
- context->move_to (left, top_step+(pos_box_size/2.0)+step_down);
- context->line_to (left, top_step+(pos_box_size/2.0));
- context->line_to (right, top_step+(pos_box_size/2.0));
- context->line_to (right, top_step+(pos_box_size/2.0) + step_down);
- context->stroke ();
-
- /* left box */
-
- rounded_rectangle (context, left - half_lr_box,
- half_lr_box+step_down,
- lr_box_size, lr_box_size, corner_radius);
- context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
- context->stroke_preserve ();
- context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
+ Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
+
+ int width, height;
+ double pos = position_control->get_value (); /* 0..1 */
+ double swidth = width_control->get_value (); /* -1..+1 */
+ double fswidth = fabs (swidth);
+ uint32_t o, f, t, b, r;
+ State state;
+ const double corner_radius = 5.0;
+
+ width = get_width();
+ height = get_height ();
+
+ if (swidth == 0.0) {
+ state = Mono;
+ } else if (swidth < 0.0) {
+ state = Inverted;
+ } else {
+ state = Normal;
+ }
+
+ o = colors[state].outline;
+ f = colors[state].fill;
+ t = colors[state].text;
+ b = colors[state].background;
+ r = colors[state].rule;
+
+ /* background */
+
+ context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b));
+ rounded_rectangle (context, 0, 0, width, height, corner_radius);
context->fill ();
-
- /* add text */
-
- context->move_to (left - half_lr_box + 3,
- (lr_box_size/2) + step_down + 13);
- context->select_font_face ("sans-serif", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD);
-
- if (state != Mono) {
- context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
- if (swidth < 0.0) {
- context->show_text (_("R"));
- } else {
- context->show_text (_("L"));
- }
- }
-
- /* right box */
-
- rounded_rectangle (context, right - half_lr_box,
- half_lr_box+step_down,
- lr_box_size, lr_box_size, corner_radius);
- context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
- context->stroke_preserve ();
- context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
+
+ /* the usable width is reduced from the real width, because we need space for
+ the two halves of LR boxes that will extend past the actual left/right
+ positions (indicated by the vertical line segment above them).
+ */
+
+ double usable_width = width - lr_box_size;
+
+ /* compute the centers of the L/R boxes based on the current stereo width */
+
+ if (fmod (usable_width,2.0) == 0) {
+ /* even width, but we need odd, so that there is an exact center.
+ So, offset cairo by 1, and reduce effective width by 1
+ */
+ usable_width -= 1.0;
+ context->translate (1.0, 0.0);
+ }
+
+ double center = (lr_box_size/2.0) + (usable_width * pos);
+ const double pan_spread = (fswidth * usable_width)/2.0;
+ const double half_lr_box = lr_box_size/2.0;
+ int left;
+ int right;
+
+ left = center - pan_spread; // center of left box
+ right = center + pan_spread; // center of right box
+
+ /* center line */
+
+ context->set_line_width (1.0);
+ context->move_to ((usable_width + lr_box_size)/2.0, 0);
+ context->rel_line_to (0, height);
+ context->set_source_rgba (UINT_RGBA_R_FLT(r), UINT_RGBA_G_FLT(r), UINT_RGBA_B_FLT(r), UINT_RGBA_A_FLT(r));
+ context->stroke ();
+
+ /* compute & draw the line through the box */
+
+ context->set_line_width (2);
+ context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
+ context->move_to (left, top_step+(pos_box_size/2.0)+step_down);
+ context->line_to (left, top_step+(pos_box_size/2.0));
+ context->line_to (right, top_step+(pos_box_size/2.0));
+ context->line_to (right, top_step+(pos_box_size/2.0) + step_down);
+ context->stroke ();
+
+ /* left box */
+
+ rounded_rectangle (context, left - half_lr_box,
+ half_lr_box+step_down,
+ lr_box_size, lr_box_size, corner_radius);
+ context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
+ context->stroke_preserve ();
+ context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
context->fill ();
- /* add text */
-
- context->move_to (right - half_lr_box + 3, (lr_box_size/2)+step_down + 13);
- context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
-
- if (state == Mono) {
- context->show_text (_("M"));
- } else {
- if (swidth < 0.0) {
- context->show_text (_("L"));
- } else {
- context->show_text (_("R"));
- }
- }
-
- /* draw the central box */
-
- context->set_line_width (2.0);
+ /* add text */
+
+ context->move_to (left - half_lr_box + 3,
+ (lr_box_size/2) + step_down + 13);
+ context->select_font_face ("sans-serif", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD);
+
+ if (state != Mono) {
+ context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
+ if (swidth < 0.0) {
+ context->show_text (_("R"));
+ } else {
+ context->show_text (_("L"));
+ }
+ }
+
+ /* right box */
+
+ rounded_rectangle (context, right - half_lr_box,
+ half_lr_box+step_down,
+ lr_box_size, lr_box_size, corner_radius);
+ context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
+ context->stroke_preserve ();
+ context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
+ context->fill ();
+
+ /* add text */
+
+ context->move_to (right - half_lr_box + 3, (lr_box_size/2)+step_down + 13);
+ context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t));
+
+ if (state == Mono) {
+ context->show_text (_("M"));
+ } else {
+ if (swidth < 0.0) {
+ context->show_text (_("L"));
+ } else {
+ context->show_text (_("R"));
+ }
+ }
+
+ /* draw the central box */
+
+ context->set_line_width (2.0);
context->move_to (center + (pos_box_size/2.0), top_step); /* top right */
- context->rel_line_to (0.0, pos_box_size); /* lower right */
- context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */
- context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */
- context->rel_line_to (0.0, -pos_box_size); /* upper left */
- context->close_path ();
-
- context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
- context->stroke_preserve ();
- context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
+ context->rel_line_to (0.0, pos_box_size); /* lower right */
+ context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */
+ context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */
+ context->rel_line_to (0.0, -pos_box_size); /* upper left */
+ context->close_path ();
+
+ context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o));
+ context->stroke_preserve ();
+ context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f));
context->fill ();
return true;
bool
StereoPanner::on_button_press_event (GdkEventButton* ev)
{
- drag_start_x = ev->x;
- last_drag_x = ev->x;
-
- dragging_position = false;
- dragging_left = false;
- dragging_right = false;
- dragging = false;
- accumulated_delta = 0;
- detented = false;
-
- /* Let the binding proxies get first crack at the press event
- */
-
- if (ev->y < 20) {
- if (position_binder.button_press_handler (ev)) {
- return true;
- }
- } else {
- if (width_binder.button_press_handler (ev)) {
- return true;
- }
- }
-
- if (ev->button != 1) {
- return false;
- }
-
- if (ev->type == GDK_2BUTTON_PRESS) {
- int width = get_width();
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
- /* handled by button release */
- return true;
- }
-
- if (ev->y < 20) {
-
- /* upper section: adjusts position, constrained by width */
-
- const double w = fabs (width_control->get_value ());
- const double max_pos = 1.0 - (w/2.0);
- const double min_pos = w/2.0;
-
- if (ev->x <= width/3) {
- /* left side dbl click */
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
- /* 2ndary-double click on left, collapse to hard left */
- width_control->set_value (0);
- position_control->set_value (0);
- } else {
- position_control->set_value (min_pos);
- }
- } else if (ev->x > 2*width/3) {
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
- /* 2ndary-double click on right, collapse to hard right */
- width_control->set_value (0);
- position_control->set_value (1.0);
- } else {
- position_control->set_value (max_pos);
- }
- } else {
- position_control->set_value (0.5);
- }
-
- } else {
-
- /* lower section: adjusts width, constrained by position */
-
- const double p = position_control->get_value ();
- const double max_width = 2.0 * min ((1.0 - p), p);
-
- if (ev->x <= width/3) {
- /* left side dbl click */
- width_control->set_value (max_width); // reset width to 100%
- } else if (ev->x > 2*width/3) {
- /* right side dbl click */
- width_control->set_value (-max_width); // reset width to inverted 100%
- } else {
- /* center dbl click */
- width_control->set_value (0); // collapse width to 0%
- }
- }
-
- dragging = false;
-
- } else if (ev->type == GDK_BUTTON_PRESS) {
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
- /* handled by button release */
- return true;
- }
-
- if (ev->y < 20) {
- /* top section of widget is for position drags */
- dragging_position = true;
- StartPositionGesture ();
- } else {
- /* lower section is for dragging width */
-
- double pos = position_control->get_value (); /* 0..1 */
- double swidth = width_control->get_value (); /* -1..+1 */
- double fswidth = fabs (swidth);
- int usable_width = get_width() - lr_box_size;
- double center = (lr_box_size/2.0) + (usable_width * pos);
- int left = lrint (center - (fswidth * usable_width / 2.0)); // center of leftmost box
- int right = lrint (center + (fswidth * usable_width / 2.0)); // center of rightmost box
- const int half_box = lr_box_size/2;
-
- if (ev->x >= (left - half_box) && ev->x < (left + half_box)) {
- if (swidth < 0.0) {
- dragging_right = true;
- } else {
- dragging_left = true;
- }
- } else if (ev->x >= (right - half_box) && ev->x < (right + half_box)) {
- if (swidth < 0.0) {
- dragging_left = true;
- } else {
- dragging_right = true;
- }
- }
- StartWidthGesture ();
- }
-
- dragging = true;
- }
-
- return true;
+ drag_start_x = ev->x;
+ last_drag_x = ev->x;
+
+ dragging_position = false;
+ dragging_left = false;
+ dragging_right = false;
+ dragging = false;
+ accumulated_delta = 0;
+ detented = false;
+
+ /* Let the binding proxies get first crack at the press event
+ */
+
+ if (ev->y < 20) {
+ if (position_binder.button_press_handler (ev)) {
+ return true;
+ }
+ } else {
+ if (width_binder.button_press_handler (ev)) {
+ return true;
+ }
+ }
+
+ if (ev->button != 1) {
+ return false;
+ }
+
+ if (ev->type == GDK_2BUTTON_PRESS) {
+ int width = get_width();
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
+ /* handled by button release */
+ return true;
+ }
+
+ if (ev->y < 20) {
+
+ /* upper section: adjusts position, constrained by width */
+
+ const double w = fabs (width_control->get_value ());
+ const double max_pos = 1.0 - (w/2.0);
+ const double min_pos = w/2.0;
+
+ if (ev->x <= width/3) {
+ /* left side dbl click */
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
+ /* 2ndary-double click on left, collapse to hard left */
+ width_control->set_value (0);
+ position_control->set_value (0);
+ } else {
+ position_control->set_value (min_pos);
+ }
+ } else if (ev->x > 2*width/3) {
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier)) {
+ /* 2ndary-double click on right, collapse to hard right */
+ width_control->set_value (0);
+ position_control->set_value (1.0);
+ } else {
+ position_control->set_value (max_pos);
+ }
+ } else {
+ position_control->set_value (0.5);
+ }
+
+ } else {
+
+ /* lower section: adjusts width, constrained by position */
+
+ const double p = position_control->get_value ();
+ const double max_width = 2.0 * min ((1.0 - p), p);
+
+ if (ev->x <= width/3) {
+ /* left side dbl click */
+ width_control->set_value (max_width); // reset width to 100%
+ } else if (ev->x > 2*width/3) {
+ /* right side dbl click */
+ width_control->set_value (-max_width); // reset width to inverted 100%
+ } else {
+ /* center dbl click */
+ width_control->set_value (0); // collapse width to 0%
+ }
+ }
+
+ dragging = false;
+
+ } else if (ev->type == GDK_BUTTON_PRESS) {
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
+ /* handled by button release */
+ return true;
+ }
+
+ if (ev->y < 20) {
+ /* top section of widget is for position drags */
+ dragging_position = true;
+ StartPositionGesture ();
+ } else {
+ /* lower section is for dragging width */
+
+ double pos = position_control->get_value (); /* 0..1 */
+ double swidth = width_control->get_value (); /* -1..+1 */
+ double fswidth = fabs (swidth);
+ int usable_width = get_width() - lr_box_size;
+ double center = (lr_box_size/2.0) + (usable_width * pos);
+ int left = lrint (center - (fswidth * usable_width / 2.0)); // center of leftmost box
+ int right = lrint (center + (fswidth * usable_width / 2.0)); // center of rightmost box
+ const int half_box = lr_box_size/2;
+
+ if (ev->x >= (left - half_box) && ev->x < (left + half_box)) {
+ if (swidth < 0.0) {
+ dragging_right = true;
+ } else {
+ dragging_left = true;
+ }
+ } else if (ev->x >= (right - half_box) && ev->x < (right + half_box)) {
+ if (swidth < 0.0) {
+ dragging_left = true;
+ } else {
+ dragging_right = true;
+ }
+ }
+ StartWidthGesture ();
+ }
+
+ dragging = true;
+ }
+
+ return true;
}
bool
StereoPanner::on_button_release_event (GdkEventButton* ev)
{
- if (ev->button != 1) {
- return false;
- }
-
- bool dp = dragging_position;
-
- dragging = false;
- dragging_position = false;
- dragging_left = false;
- dragging_right = false;
- accumulated_delta = 0;
- detented = false;
-
- if (drag_data_window) {
- drag_data_window->hide ();
- }
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
- /* reset to default */
- position_control->set_value (0.5);
- width_control->set_value (1.0);
- } else {
- if (dp) {
- StopPositionGesture ();
- } else {
- StopWidthGesture ();
- }
- }
-
- return true;
+ if (ev->button != 1) {
+ return false;
+ }
+
+ bool dp = dragging_position;
+
+ dragging = false;
+ dragging_position = false;
+ dragging_left = false;
+ dragging_right = false;
+ accumulated_delta = 0;
+ detented = false;
+
+ if (drag_data_window) {
+ drag_data_window->hide ();
+ }
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
+ /* reset to default */
+ position_control->set_value (0.5);
+ width_control->set_value (1.0);
+ } else {
+ if (dp) {
+ StopPositionGesture ();
+ } else {
+ StopWidthGesture ();
+ }
+ }
+
+ return true;
}
bool
StereoPanner::on_scroll_event (GdkEventScroll* ev)
{
- double one_degree = 1.0/180.0; // one degree as a number from 0..1, since 180 degrees is the full L/R axis
- double pv = position_control->get_value(); // 0..1.0 ; 0 = left
- double wv = width_control->get_value(); // 0..1.0 ; 0 = left
- double step;
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
- step = one_degree;
- } else {
- step = one_degree * 5.0;
- }
-
- switch (ev->direction) {
- case GDK_SCROLL_LEFT:
- wv += step;
- width_control->set_value (wv);
- break;
- case GDK_SCROLL_UP:
- pv -= step;
- position_control->set_value (pv);
- break;
- case GDK_SCROLL_RIGHT:
- wv -= step;
- width_control->set_value (wv);
- break;
- case GDK_SCROLL_DOWN:
- pv += step;
- position_control->set_value (pv);
- break;
- }
-
- return true;
+ double one_degree = 1.0/180.0; // one degree as a number from 0..1, since 180 degrees is the full L/R axis
+ double pv = position_control->get_value(); // 0..1.0 ; 0 = left
+ double wv = width_control->get_value(); // 0..1.0 ; 0 = left
+ double step;
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
+ step = one_degree;
+ } else {
+ step = one_degree * 5.0;
+ }
+
+ switch (ev->direction) {
+ case GDK_SCROLL_LEFT:
+ wv += step;
+ width_control->set_value (wv);
+ break;
+ case GDK_SCROLL_UP:
+ pv -= step;
+ position_control->set_value (pv);
+ break;
+ case GDK_SCROLL_RIGHT:
+ wv -= step;
+ width_control->set_value (wv);
+ break;
+ case GDK_SCROLL_DOWN:
+ pv += step;
+ position_control->set_value (pv);
+ break;
+ }
+
+ return true;
}
bool
StereoPanner::on_motion_notify_event (GdkEventMotion* ev)
{
- if (!dragging) {
- return false;
- }
-
- if (!drag_data_window) {
- drag_data_window = new Window (WINDOW_POPUP);
- drag_data_window->set_name (X_("ContrastingPopup"));
- drag_data_window->set_position (WIN_POS_MOUSE);
- drag_data_window->set_decorated (false);
-
- drag_data_label = manage (new Label);
- drag_data_label->set_use_markup (true);
-
- drag_data_window->set_border_width (6);
- drag_data_window->add (*drag_data_label);
- drag_data_label->show ();
-
- Window* toplevel = dynamic_cast<Window*> (get_toplevel());
- if (toplevel) {
- drag_data_window->set_transient_for (*toplevel);
- }
- }
-
- if (!drag_data_window->is_visible ()) {
- /* move the popup window vertically down from the panner display */
- int rx, ry;
- get_window()->get_origin (rx, ry);
- drag_data_window->move (rx, ry+get_height());
- drag_data_window->present ();
- }
-
- int w = get_width();
- double delta = (ev->x - last_drag_x) / (double) w;
- double current_width = width_control->get_value ();
-
- if (dragging_left) {
- delta = -delta;
- }
-
- if (dragging_left || dragging_right) {
-
- /* maintain position as invariant as we change the width */
-
-
- /* create a detent close to the center */
-
- if (!detented && fabs (current_width) < 0.02) {
- detented = true;
- /* snap to zero */
- width_control->set_value (0);
- }
-
- if (detented) {
-
- accumulated_delta += delta;
-
- /* have we pulled far enough to escape ? */
-
- if (fabs (accumulated_delta) >= 0.025) {
- width_control->set_value (current_width + accumulated_delta);
- detented = false;
- accumulated_delta = false;
- }
-
- } else {
- width_control->set_value (current_width + delta);
- }
-
- } else if (dragging_position) {
-
- double pv = position_control->get_value(); // 0..1.0 ; 0 = left
- position_control->set_value (pv + delta);
- }
-
- last_drag_x = ev->x;
- return true;
+ if (!dragging) {
+ return false;
+ }
+
+ if (!drag_data_window) {
+ drag_data_window = new Window (WINDOW_POPUP);
+ drag_data_window->set_name (X_("ContrastingPopup"));
+ drag_data_window->set_position (WIN_POS_MOUSE);
+ drag_data_window->set_decorated (false);
+
+ drag_data_label = manage (new Label);
+ drag_data_label->set_use_markup (true);
+
+ drag_data_window->set_border_width (6);
+ drag_data_window->add (*drag_data_label);
+ drag_data_label->show ();
+
+ Window* toplevel = dynamic_cast<Window*> (get_toplevel());
+ if (toplevel) {
+ drag_data_window->set_transient_for (*toplevel);
+ }
+ }
+
+ if (!drag_data_window->is_visible ()) {
+ /* move the popup window vertically down from the panner display */
+ int rx, ry;
+ get_window()->get_origin (rx, ry);
+ drag_data_window->move (rx, ry+get_height());
+ drag_data_window->present ();
+ }
+
+ int w = get_width();
+ double delta = (ev->x - last_drag_x) / (double) w;
+ double current_width = width_control->get_value ();
+
+ if (dragging_left) {
+ delta = -delta;
+ }
+
+ if (dragging_left || dragging_right) {
+
+ /* maintain position as invariant as we change the width */
+
+
+ /* create a detent close to the center */
+
+ if (!detented && fabs (current_width) < 0.02) {
+ detented = true;
+ /* snap to zero */
+ width_control->set_value (0);
+ }
+
+ if (detented) {
+
+ accumulated_delta += delta;
+
+ /* have we pulled far enough to escape ? */
+
+ if (fabs (accumulated_delta) >= 0.025) {
+ width_control->set_value (current_width + accumulated_delta);
+ detented = false;
+ accumulated_delta = false;
+ }
+
+ } else {
+ width_control->set_value (current_width + delta);
+ }
+
+ } else if (dragging_position) {
+
+ double pv = position_control->get_value(); // 0..1.0 ; 0 = left
+ position_control->set_value (pv + delta);
+ }
+
+ last_drag_x = ev->x;
+ return true;
}
bool
StereoPanner::on_key_press_event (GdkEventKey* ev)
{
- double one_degree = 1.0/180.0;
- double pv = position_control->get_value(); // 0..1.0 ; 0 = left
- double wv = width_control->get_value(); // 0..1.0 ; 0 = left
- double step;
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
- step = one_degree;
- } else {
- step = one_degree * 5.0;
- }
-
- /* up/down control width because we consider pan position more "important"
- (and thus having higher "sense" priority) than width.
- */
-
- switch (ev->keyval) {
- case GDK_Up:
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
- width_control->set_value (1.0);
- } else {
- width_control->set_value (wv + step);
- }
- break;
- case GDK_Down:
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
- width_control->set_value (-1.0);
- } else {
- width_control->set_value (wv - step);
- }
-
- case GDK_Left:
- pv -= step;
- position_control->set_value (pv);
- break;
- case GDK_Right:
- pv += step;
- position_control->set_value (pv);
- break;
-
- break;
- case GDK_0:
- case GDK_KP_0:
- width_control->set_value (0.0);
- break;
-
- default:
- return false;
- }
-
- return true;
+ double one_degree = 1.0/180.0;
+ double pv = position_control->get_value(); // 0..1.0 ; 0 = left
+ double wv = width_control->get_value(); // 0..1.0 ; 0 = left
+ double step;
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
+ step = one_degree;
+ } else {
+ step = one_degree * 5.0;
+ }
+
+ /* up/down control width because we consider pan position more "important"
+ (and thus having higher "sense" priority) than width.
+ */
+
+ switch (ev->keyval) {
+ case GDK_Up:
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
+ width_control->set_value (1.0);
+ } else {
+ width_control->set_value (wv + step);
+ }
+ break;
+ case GDK_Down:
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
+ width_control->set_value (-1.0);
+ } else {
+ width_control->set_value (wv - step);
+ }
+
+ case GDK_Left:
+ pv -= step;
+ position_control->set_value (pv);
+ break;
+ case GDK_Right:
+ pv += step;
+ position_control->set_value (pv);
+ break;
+
+ break;
+ case GDK_0:
+ case GDK_KP_0:
+ width_control->set_value (0.0);
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
}
bool
StereoPanner::on_key_release_event (GdkEventKey* ev)
{
- return false;
+ return false;
}
bool
void
StereoPanner::set_colors ()
{
- colors[Normal].fill = ARDOUR_UI::config()->canvasvar_StereoPannerFill.get();
- colors[Normal].outline = ARDOUR_UI::config()->canvasvar_StereoPannerOutline.get();
- colors[Normal].text = ARDOUR_UI::config()->canvasvar_StereoPannerText.get();
- colors[Normal].background = ARDOUR_UI::config()->canvasvar_StereoPannerBackground.get();
- colors[Normal].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
-
- colors[Mono].fill = ARDOUR_UI::config()->canvasvar_StereoPannerMonoFill.get();
- colors[Mono].outline = ARDOUR_UI::config()->canvasvar_StereoPannerMonoOutline.get();
- colors[Mono].text = ARDOUR_UI::config()->canvasvar_StereoPannerMonoText.get();
- colors[Mono].background = ARDOUR_UI::config()->canvasvar_StereoPannerMonoBackground.get();
- colors[Mono].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
-
- colors[Inverted].fill = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedFill.get();
- colors[Inverted].outline = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedOutline.get();
- colors[Inverted].text = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedText.get();
- colors[Inverted].background = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedBackground.get();
- colors[Inverted].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
+ colors[Normal].fill = ARDOUR_UI::config()->canvasvar_StereoPannerFill.get();
+ colors[Normal].outline = ARDOUR_UI::config()->canvasvar_StereoPannerOutline.get();
+ colors[Normal].text = ARDOUR_UI::config()->canvasvar_StereoPannerText.get();
+ colors[Normal].background = ARDOUR_UI::config()->canvasvar_StereoPannerBackground.get();
+ colors[Normal].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
+
+ colors[Mono].fill = ARDOUR_UI::config()->canvasvar_StereoPannerMonoFill.get();
+ colors[Mono].outline = ARDOUR_UI::config()->canvasvar_StereoPannerMonoOutline.get();
+ colors[Mono].text = ARDOUR_UI::config()->canvasvar_StereoPannerMonoText.get();
+ colors[Mono].background = ARDOUR_UI::config()->canvasvar_StereoPannerMonoBackground.get();
+ colors[Mono].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
+
+ colors[Inverted].fill = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedFill.get();
+ colors[Inverted].outline = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedOutline.get();
+ colors[Inverted].text = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedText.get();
+ colors[Inverted].background = ARDOUR_UI::config()->canvasvar_StereoPannerInvertedBackground.get();
+ colors[Inverted].rule = ARDOUR_UI::config()->canvasvar_StereoPannerRule.get();
}
void
StereoPanner::color_handler ()
{
- set_colors ();
- queue_draw ();
+ set_colors ();
+ queue_draw ();
}
sp[nx] *= gab[nx];
}
}
-
+
_current_gain = gab[nframes-1];
} else { /* manual (scalar) gain */
Sample* const buffer = buf.data();
-
+
fractional_pos = 1.0;
-
+
for (pframes_t nx = 0; nx < declick; ++nx) {
buffer[nx] *= (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos))));
fractional_pos += fractional_shift;
}
-
+
/* now ensure the rest of the buffer has the target value applied, if necessary. */
-
+
if (declick != nframes) {
-
+
if (target == 0.0) {
memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
} else if (target != 1.0) {
if ((gain_node = node.child (Controllable::xml_node_name.c_str())) != 0) {
_gain_control->set_state (*gain_node, version);
}
-
+
return 0;
}
static void apply_gain (BufferSet& bufs, framecnt_t nframes, gain_t initial, gain_t target);
static void apply_simple_gain(BufferSet& bufs, framecnt_t nframes, gain_t target);
-
- static void apply_gain (AudioBuffer& buf, framecnt_t nframes, gain_t initial, gain_t target);
+
+ static void apply_gain (AudioBuffer& buf, framecnt_t nframes, gain_t initial, gain_t target);
static void apply_simple_gain(AudioBuffer& buf, framecnt_t nframes, gain_t target);
static void declick (BufferSet& bufs, framecnt_t nframes, int dir);
#include "ardour/types.h"
-#include <jack/jack.h>
+#include <jack/jack.h>
namespace MIDI {
class MachineControl;
int cleanup ();
bool no_auto_connect ();
void make_property_quarks ();
-
+
extern PBD::PropertyChange bounds_change;
extern const char* const ardour_config_info;
void find_bindings_files (std::map<std::string,std::string>&);
- std::string translation_kill_path ();
- bool translations_are_disabled ();
+ std::string translation_kill_path ();
+ bool translations_are_disabled ();
const layer_t max_layer = UCHAR_MAX;
assert(len <= _capacity);
Sample* dst = _data + dst_offset;
- gain_t gain_delta = (target - initial)/len;
+ gain_t gain_delta = (target - initial)/len;
- for (framecnt_t n = 0; n < len; ++n) {
- *dst++ += (*src++ * initial);
- initial += gain_delta;
- }
+ for (framecnt_t n = 0; n < len; ++n) {
+ *dst++ += (*src++ * initial);
+ initial += gain_delta;
+ }
_silent = (_silent && initial == 0 && target == 0);
_written = true;
void set_block_size (pframes_t);
int internal_playback_seek (framecnt_t distance);
int can_internal_playback_seek (framecnt_t distance);
- std::list<boost::shared_ptr<Source> > steal_write_sources();
+ std::list<boost::shared_ptr<Source> > steal_write_sources();
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
void non_realtime_locate (framepos_t location);
bool commit (framecnt_t nframes);
private:
- struct ChannelSource {
- std::string name;
+ struct ChannelSource {
+ std::string name;
- bool is_physical () const;
- void ensure_monitor_input (bool) const;
- };
+ bool is_physical () const;
+ void ensure_monitor_input (bool) const;
+ };
struct ChannelInfo : public boost::noncopyable {
- ChannelInfo (framecnt_t playback_buffer_size,
- framecnt_t capture_buffer_size,
- framecnt_t speed_buffer_size,
- framecnt_t wrap_buffer_size);
+ ChannelInfo (framecnt_t playback_buffer_size,
+ framecnt_t capture_buffer_size,
+ framecnt_t speed_buffer_size,
+ framecnt_t wrap_buffer_size);
~ChannelInfo ();
Sample *playback_wrap_buffer;
boost::shared_ptr<AudioFileSource> write_source;
/// information the Port that our audio data comes from
-
- ChannelSource source;
+
+ ChannelSource source;
Sample *current_capture_buffer;
Sample *current_playback_buffer;
// the following are used in the butler thread only
framecnt_t curr_capture_cnt;
- void resize_playback (framecnt_t);
- void resize_capture (framecnt_t);
+ void resize_playback (framecnt_t);
+ void resize_capture (framecnt_t);
};
typedef std::vector<ChannelInfo*> ChannelList;
int do_refill_with_alloc ();
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
- framepos_t& start, framecnt_t cnt,
- ChannelInfo* channel_info, int channel, bool reversed);
+ framepos_t& start, framecnt_t cnt,
+ ChannelInfo* channel_info, int channel, bool reversed);
void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
void transport_stopped_wallclock (struct tm&, time_t, bool abort);
void setup_destructive_playlist ();
void use_destructive_playlist ();
- void adjust_playback_buffering ();
- void adjust_capture_buffering ();
+ void adjust_playback_buffering ();
+ void adjust_capture_buffering ();
void engage_record_enable ();
void disengage_record_enable ();
class AudioPlaylist;
class AudioPlaylistSource : public PlaylistSource, public AudioSource {
- public:
- virtual ~AudioPlaylistSource ();
-
- bool empty() const;
- std::string peak_path (std::string audio_path);
- uint32_t n_channels() const;
- bool clamped_at_unity () const { return false; }
-
- framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
- framecnt_t write_unlocked (Sample *src, framecnt_t cnt);
-
- float sample_rate () const;
- int setup_peakfile ();
-
- XMLNode& get_state ();
- int set_state (const XMLNode&, int version);
-
- bool can_truncate_peaks() const { return false; }
- bool can_be_analysed() const { return _length > 0; }
-
- protected:
- friend class SourceFactory;
-
- AudioPlaylistSource (Session&, const PBD::ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist>, uint32_t chn,
- frameoffset_t begin, framecnt_t len, Source::Flag flags);
- AudioPlaylistSource (Session&, const XMLNode&);
-
-
- private:
- uint32_t _playlist_channel;
- std::string _peak_path;
-
- int set_state (const XMLNode&, int version, bool with_descendants);
+public:
+ virtual ~AudioPlaylistSource ();
+ bool empty() const;
+ std::string peak_path (std::string audio_path);
+ uint32_t n_channels() const;
+ bool clamped_at_unity () const { return false; }
+
+ framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
+ framecnt_t write_unlocked (Sample *src, framecnt_t cnt);
+
+ float sample_rate () const;
+ int setup_peakfile ();
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&, int version);
+
+ bool can_truncate_peaks() const { return false; }
+ bool can_be_analysed() const { return _length > 0; }
+
+protected:
+ friend class SourceFactory;
+
+ AudioPlaylistSource (Session&, const PBD::ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist>, uint32_t chn,
+ frameoffset_t begin, framecnt_t len, Source::Flag flags);
+ AudioPlaylistSource (Session&, const XMLNode&);
+
+
+private:
+ uint32_t _playlist_channel;
+ std::string _peak_path;
+
+ int set_state (const XMLNode&, int version, bool with_descendants);
};
-
+
} /* namespace */
#endif /* __ardour_audio_playlist_source_h__ */
class AudioDiskstream;
class AudioPlaylist;
class RouteGroup;
-class AudioFileSource;
+class AudioFileSource;
class AudioTrack : public Track
{
bool can_use_mode (TrackMode m, bool& bounce_required);
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
+ int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
void use_new_diskstream ();
- void set_diskstream (boost::shared_ptr<Diskstream>);
+ void set_diskstream (boost::shared_ptr<Diskstream>);
DataType data_type () const {
return DataType::AUDIO;
boost::shared_ptr<AudioFileSource> write_source (uint32_t n = 0);
bool bounceable () const;
-
+
protected:
boost::shared_ptr<AudioDiskstream> audio_diskstream () const;
XMLNode& state (bool full);
-
+
int _set_state (const XMLNode&, int, bool call_base);
private:
/*
- Copyright (C) 2006 Paul Davis
+ Copyright (C) 2006 Paul Davis
Written by Taybin Rutkin
This program is free software; you can redistribute it and/or modify
AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
AUPlugin (const AUPlugin& other);
virtual ~AUPlugin ();
-
- std::string unique_id () const;
+
+ std::string unique_id () const;
const char * label () const;
const char * name () const { return _info->name.c_str(); }
const char * maker () const { return _info->creator.c_str(); }
framecnt_t signal_latency() const;
void set_parameter (uint32_t which, float val);
float get_parameter (uint32_t which) const;
-
+
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
uint32_t nth_parameter (uint32_t which, bool& ok) const;
void activate ();
void deactivate ();
void flush ();
int set_block_size (pframes_t nframes);
-
+
int connect_and_run (BufferSet& bufs,
ChanMapping in, ChanMapping out,
pframes_t nframes, framecnt_t offset);
std::string describe_parameter (Evoral::Parameter);
std::string state_node_name () const { return "audiounit"; }
void print_parameter (uint32_t, char*, uint32_t len) const;
-
+
bool parameter_is_audio (uint32_t) const;
bool parameter_is_control (uint32_t) const;
bool parameter_is_input (uint32_t) const;
bool parameter_is_output (uint32_t) const;
-
+
int set_state(const XMLNode& node, int);
-
+
PresetRecord save_preset (std::string name);
bool load_preset (PresetRecord);
std::string current_preset() const;
bool has_editor () const;
-
+
bool reconfigurable_io() const { return true; }
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool configure_io (ChanCount in, ChanCount out);
bool requires_fixed_size_buffers() const;
- void set_fixed_size_buffers (bool yn) {
+ void set_fixed_size_buffers (bool yn) {
_requires_fixed_size_buffers = yn;
}
boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
boost::shared_ptr<CAComponent> get_comp () const { return comp; }
-
- OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList* ioData);
+
+ OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData);
/* "host" callbacks */
- OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
+ OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
Float64* outCurrentTempo);
OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
private:
void find_presets ();
-
- boost::shared_ptr<CAComponent> comp;
- boost::shared_ptr<CAAudioUnit> unit;
-
- bool initialized;
+
+ boost::shared_ptr<CAComponent> comp;
+ boost::shared_ptr<CAAudioUnit> unit;
+
+ bool initialized;
int32_t input_channels;
int32_t output_channels;
std::vector<std::pair<int,int> > io_configs;
UInt32 global_elements;
UInt32 output_elements;
UInt32 input_elements;
-
+
int set_output_format (AudioStreamBasicDescription&);
int set_input_format (AudioStreamBasicDescription&);
int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
uint32_t current_maxbuf;
- framecnt_t current_offset;
- framecnt_t cb_offset;
- BufferSet* current_buffers;
- framecnt_t frames_processed;
-
+ framecnt_t current_offset;
+ framecnt_t cb_offset;
+ BufferSet* current_buffers;
+ framecnt_t frames_processed;
+
std::vector<AUParameterDescriptor> descriptors;
void init ();
bool last_transport_rolling;
float last_transport_speed;
};
-
+
typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
-struct AUPluginCachedInfo {
+struct AUPluginCachedInfo {
std::vector<std::pair<int,int> > io_configs;
};
class AUPluginInfo : public PluginInfo {
- public:
+ public:
AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
~AUPluginInfo ();
static PluginInfoList* discover ();
static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
- static std::string stringify_descriptor (const CAComponentDescription&);
+ static std::string stringify_descriptor (const CAComponentDescription&);
static int load_cached_info ();
private:
boost::shared_ptr<CAComponentDescription> descriptor;
UInt32 version;
-
+
static void discover_music (PluginInfoList&);
static void discover_fx (PluginInfoList&);
static void discover_generators (PluginInfoList&);
typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
static CachedInfoMap cached_info;
-
+
static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
static void add_cached_info (const std::string&, AUPluginCachedInfo&);
- static void save_cached_info ();
+ static void save_cached_info ();
};
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
class AudioEngine : public SessionHandlePtr
{
- public:
+public:
typedef std::set<Port*> Ports;
- class disconnected_exception : public std::exception {
- public:
- virtual const char *what() const throw() { return "AudioEngine is disconnected"; }
- };
+ class disconnected_exception : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "AudioEngine is disconnected"; }
+ };
AudioEngine (std::string client_name, std::string session_uuid);
virtual ~AudioEngine ();
bool is_realtime () const;
- ProcessThread* main_thread() const { return _main_thread; }
+ ProcessThread* main_thread() const { return _main_thread; }
std::string client_name() const { return jack_client_name; }
}
return jack_frames_since_cycle_start (_priv_jack);
}
-
+
pframes_t frame_time () {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
Port *register_output_port (DataType, const std::string& portname);
int unregister_port (Port &);
- bool port_is_physical (const std::string&) const;
- void ensure_monitor_input (const std::string&, bool) const;
+ bool port_is_physical (const std::string&) const;
+ void ensure_monitor_input (const std::string&, bool) const;
void split_cycle (pframes_t offset);
std::string make_port_name_relative (std::string) const;
std::string make_port_name_non_relative (std::string) const;
- bool port_is_mine (const std::string&) const;
+ bool port_is_mine (const std::string&) const;
static AudioEngine* instance() { return _instance; }
void died ();
- int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
+ int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
- private:
+private:
static AudioEngine* _instance;
jack_client_t* volatile _jack; /* could be reset to null by SIGPIPE or another thread */
int jack_bufsize_callback (pframes_t);
int jack_sample_rate_callback (pframes_t);
- void set_jack_callbacks ();
+ void set_jack_callbacks ();
- static void _latency_callback (jack_latency_callback_mode_t, void*);
- void jack_latency_callback (jack_latency_callback_mode_t);
+ static void _latency_callback (jack_latency_callback_mode_t, void*);
+ void jack_latency_callback (jack_latency_callback_mode_t);
int connect_to_jack (std::string client_name, std::string session_uuid);
Glib::Thread* m_meter_thread;
static gint m_meter_exit;
-
- ProcessThread* _main_thread;
-
- struct ThreadData {
- AudioEngine* engine;
- boost::function<void()> f;
- size_t stacksize;
-
- ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz)
- : engine (ae) , f (fp) , stacksize (stacksz) {}
- };
-
- static void* _start_process_thread (void*);
+
+ ProcessThread* _main_thread;
+
+ struct ThreadData {
+ AudioEngine* engine;
+ boost::function<void()> f;
+ size_t stacksize;
+
+ ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz)
+ : engine (ae) , f (fp) , stacksize (stacksz) {}
+ };
+
+ static void* _start_process_thread (void*);
};
} // namespace ARDOUR
return (set_source_name(newname, destructive()) == 0);
}
- std::string peak_path (std::string audio_path);
- std::string find_broken_peakfile (std::string missing_peak_path,
- std::string audio_path);
+ std::string peak_path (std::string audio_path);
+ std::string find_broken_peakfile (std::string missing_peak_path,
+ std::string audio_path);
static void set_peak_dir (std::string dir) { peak_dir = dir; }
class Source;
namespace Properties {
- /* fake the type, since crossfades are handled by SequenceProperty which doesn't
- care about such things.
- */
- extern PBD::PropertyDescriptor<bool> crossfades;
+ /* fake the type, since crossfades are handled by SequenceProperty which doesn't
+ care about such things.
+ */
+ extern PBD::PropertyDescriptor<bool> crossfades;
}
-class AudioPlaylist;
+class AudioPlaylist;
class CrossfadeListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Crossfade> > >
{
/* copy construction only by ourselves */
CrossfadeListProperty (CrossfadeListProperty const & p);
- friend class AudioPlaylist;
- /* we live and die with our playlist, no lifetime management needed */
- AudioPlaylist& _playlist;
+ friend class AudioPlaylist;
+ /* we live and die with our playlist, no lifetime management needed */
+ AudioPlaylist& _playlist;
};
-
+
class AudioPlaylist : public ARDOUR::Playlist
{
public:
void clear (bool with_signals=true);
- framecnt_t read (Sample *dst, Sample *mixdown, float *gain_buffer, framepos_t start, framecnt_t cnt, uint32_t chan_n=0);
+ framecnt_t read (Sample *dst, Sample *mixdown, float *gain_buffer, framepos_t start, framecnt_t cnt, uint32_t chan_n=0);
int set_state (const XMLNode&, int version);
PBD::Signal1<void,boost::shared_ptr<Crossfade> > NewCrossfade;
-
+
void foreach_crossfade (boost::function<void (boost::shared_ptr<Crossfade>)>);
void crossfades_at (framepos_t frame, Crossfades&);
void update (const CrossfadeListProperty::ChangeRecord &);
boost::shared_ptr<Crossfade> find_crossfade (const PBD::ID &) const;
-
- protected:
+
+protected:
/* playlist "callbacks" */
void notify_crossfade_added (boost::shared_ptr<Crossfade>);
void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
- void refresh_dependents (boost::shared_ptr<Region> region);
- void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
- void remove_dependents (boost::shared_ptr<Region> region);
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void remove_dependents (boost::shared_ptr<Region> region);
void copy_dependents (const std::vector<TwoRegions>&, Playlist*) const;
void pre_combine (std::vector<boost::shared_ptr<Region> >&);
void post_combine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>);
void pre_uncombine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>);
- private:
- CrossfadeListProperty _crossfades;
- Crossfades _pending_xfade_adds;
+private:
+ CrossfadeListProperty _crossfades;
+ Crossfades _pending_xfade_adds;
- void crossfade_invalidated (boost::shared_ptr<Region>);
- XMLNode& state (bool full_state);
- void dump () const;
+ void crossfade_invalidated (boost::shared_ptr<Region>);
+ XMLNode& state (bool full_state);
+ void dump () const;
- bool region_changed (const PBD::PropertyChange&, boost::shared_ptr<Region>);
- void crossfade_changed (const PBD::PropertyChange&);
- void add_crossfade (boost::shared_ptr<Crossfade>);
+ bool region_changed (const PBD::PropertyChange&, boost::shared_ptr<Region>);
+ void crossfade_changed (const PBD::PropertyChange&);
+ 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);
};
} /* namespace ARDOUR */
uint32_t chan_n = 0,
framecnt_t read_frames = 0,
framecnt_t skip_frames = 0) const;
-
+
virtual framecnt_t master_read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf,
framepos_t position, framecnt_t cnt, uint32_t chan_n=0) const;
-
+
virtual framecnt_t read_raw_internal (Sample*, framepos_t, framecnt_t, int channel) const;
XMLNode& state ();
PBD::Property<bool> _fade_out_active;
/** linear gain to apply to the whole region */
PBD::Property<gain_t> _scale_amplitude;
-
+
void register_properties ();
void post_set (const PBD::PropertyChange&);
framecnt_t readable_length() const { return _length; }
virtual uint32_t n_channels() const { return 1; }
- virtual bool empty() const;
+ virtual bool empty() const;
framecnt_t length (framepos_t pos) const;
void update_length (framepos_t pos, framecnt_t cnt);
virtual bool clamped_at_unity () const = 0;
static void allocate_working_buffers (framecnt_t framerate);
-
+
protected:
static bool _build_missing_peakfiles;
static bool _build_peakfiles;
static size_t _working_buffers_size;
-
+
/* these collections of working buffers for supporting
playlist's reading from potentially nested/recursive
sources assume SINGLE THREADED reads by the butler
- thread, or a lock around calls that use them.
+ thread, or a lock around calls that use them.
*/
static std::vector<boost::shared_ptr<Sample> > _mixdown_buffers;
virtual framecnt_t write_unlocked (Sample *dst, framecnt_t cnt) = 0;
virtual std::string peak_path(std::string audio_path) = 0;
virtual std::string find_broken_peakfile (std::string missing_peak_path,
- std::string audio_path) { return peak_path (audio_path); }
+ std::string audio_path) { return peak_path (audio_path); }
virtual int read_peaks_with_fpp (PeakData *peaks,
framecnt_t npeaks, framepos_t start, framecnt_t cnt,
double samples_per_visual_peak, framecnt_t fpp) const;
-
+
int compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
- bool force, bool intermediate_peaks_ready_signal,
+ bool force, bool intermediate_peaks_ready_signal,
framecnt_t frames_per_peak);
private:
* during the handling of the signal.
*/
mutable Glib::Mutex _peaks_ready_lock;
-
+
PBD::FdFileDescriptor* _peakfile_descriptor;
int _peakfile_fd;
framecnt_t peak_leftover_cnt;
Auditioner (Session&);
~Auditioner ();
- int init ();
+ int init ();
void audition_region (boost::shared_ptr<Region>);
}
bool auditioning() const { return g_atomic_int_get (&_auditioning); }
- bool needs_monitor() const { return via_monitor; }
+ bool needs_monitor() const { return via_monitor; }
- virtual ChanCount input_streams () const;
+ virtual ChanCount input_streams () const;
private:
boost::shared_ptr<AudioRegion> the_region;
mutable gint _auditioning;
Glib::Mutex lock;
framecnt_t length;
- bool via_monitor;
+ bool via_monitor;
void drop_ports ();
static void *_drop_ports (void *);
{
public:
Automatable(Session&);
- Automatable (const Automatable& other);
+ Automatable (const Automatable& other);
virtual ~Automatable() {}
virtual void transport_stopped (framepos_t now);
virtual std::string describe_parameter(Evoral::Parameter param);
- virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
+ virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
AutoState get_parameter_automation_state (Evoral::Parameter param);
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
typedef Evoral::ControlSet::Controls Controls;
- static const std::string xml_node_name;
+ static const std::string xml_node_name;
int set_automation_xml_state (const XMLNode&, Evoral::Parameter default_param);
XMLNode& get_automation_xml_state();
-
+
protected:
Session& _a_session;
void set_value (double);
double get_value () const;
- double lower() const { return parameter().min(); }
- double upper() const { return parameter().max(); }
+ double lower() const { return parameter().min(); }
+ double upper() const { return parameter().max(); }
- const ARDOUR::Session& session() const { return _session; }
+ const ARDOUR::Session& session() const { return _session; }
/** Convert user values to UI values. See pbd/controllable.h */
virtual double user_to_ui (double val) const {
virtual double ui_to_user (double val) const {
return val;
}
-
+
protected:
-
+
ARDOUR::Session& _session;
};
return (_state & Play) || ((_state & Touch) && !touching());
}
bool automation_write () const {
- return ((_state & Write) || ((_state & Touch) && touching()));
- }
+ return ((_state & Write) || ((_state & Touch) && touching()));
+ }
PBD::Signal0<void> StateChanged;
void stop_touch (bool mark, double when);
bool touching() const { return g_atomic_int_get (&_touching); }
bool writing() const { return _state == Write; }
- bool touch_enabled() const { return _state == Touch; }
+ bool touch_enabled() const { return _state == Touch; }
- XMLNode& get_state ();
+ XMLNode& get_state ();
int set_state (const XMLNode &, int version);
XMLNode& state (bool full);
XMLNode& serialize_events ();
-#ifndef __libardour_buffer_manager__
+#ifndef __libardour_buffer_manager__
#define __libardour_buffer_manager__
#include <stdint.h>
class BufferManager
{
- public:
- static void init (uint32_t);
-
- static ThreadBuffers* get_thread_buffers ();
- static void put_thread_buffers (ThreadBuffers*);
+public:
+ static void init (uint32_t);
- static void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
+ static ThreadBuffers* get_thread_buffers ();
+ static void put_thread_buffers (ThreadBuffers*);
- private:
+ static void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
+
+private:
static Glib::StaticMutex rb_mutex;
-
- typedef PBD::RingBufferNPT<ThreadBuffers*> ThreadBufferFIFO;
+
+ typedef PBD::RingBufferNPT<ThreadBuffers*> ThreadBufferFIFO;
typedef std::list<ThreadBuffers*> ThreadBufferList;
- static ThreadBufferFIFO* thread_buffers;
+ static ThreadBufferFIFO* thread_buffers;
static ThreadBufferList* thread_buffers_list;
};
#include "evoral/MIDIEvent.hpp"
struct VstEvents;
struct VstMidiEvent;
-#endif
+#endif
namespace ARDOUR {
#ifdef VST_SUPPORT
VstEvents* get_vst_midi (size_t);
-#endif
+#endif
void read_from(const BufferSet& in, framecnt_t nframes);
void merge_from(const BufferSet& in, framecnt_t nframes);
private:
/* prevent copy construction */
VSTBuffer (VSTBuffer const &);
-
+
VstEvents* _events; /// the parent VSTEvents struct
VstMidiEvent* _midi_events; ///< storage area for VSTMidiEvents
size_t _capacity;
};
-
+
typedef std::vector<VSTBuffer*> VSTBuffers;
VSTBuffers _vst_buffers;
-#endif
+#endif
/// Use counts (there may be more actual buffers than this)
ChanCount _count;
public:
Butler (Session& session);
~Butler();
-
+
int start_thread();
void terminate_thread();
void schedule_transport_work();
private:
void empty_pool_trash ();
- void config_changed (std::string);
+ void config_changed (std::string);
};
} // namespace ARDOUR
framecnt_t duration;
framecnt_t offset;
const Sample *data;
-
+
Click (framepos_t s, framecnt_t d, const Sample *b) : start (s), duration (d), offset (0), data (b) {}
-
+
void *operator new (size_t) {
return pool.alloc ();
};
-
+
void operator delete(void *ptr, size_t /*size*/) {
pool.release (ptr);
}
-
+
private:
static Pool pool;
};
public:
ClickIO (Session& s, const std::string& name) : IO (s, name, IO::Output) {}
~ClickIO() {}
-
+
protected:
uint32_t pans_required () const { return 1; }
};
}
void set_from_string (std::string const & s) {
- value = string_is_affirmative (s);
+ value = string_is_affirmative (s);
}
protected:
}
void set_from_string (std::string const & s) {
- T v;
- std::stringstream ss;
- ss << s;
+ T v;
+ std::stringstream ss;
+ ss << s;
ss >> v;
- set (v);
+ set (v);
}
protected:
CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag);
~CoreAudioSource ();
- void set_path (const std::string& p);
+ void set_path (const std::string& p);
float sample_rate() const;
int update_header (framepos_t when, struct tm&, time_t);
protected:
framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
framecnt_t write_unlocked (Sample *, framecnt_t) { return 0; }
-
+
private:
mutable CAAudioFile af;
uint16_t n_channels;
EndOfIn,
EndOfOut
};
-
+
class Playlist;
class Crossfade : public ARDOUR::AudioRegion
bool update ();
bool operator== (const ARDOUR::Crossfade&);
-
+
protected:
framecnt_t read_raw_internal (Sample*, framepos_t, framecnt_t, int) const;
};
typedef uint32_t long cycles_t;
static inline cycles_t get_cycles(void)
{
- cycles_t cycles;
- __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
- return cycles >> 2;
+ cycles_t cycles;
+ __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
+ return cycles >> 2;
}
#elif defined(__hppa__)
/* hppa/parisc */
#define mfctl(reg) ({ \
- uint32_t cr; \
- __asm__ __volatile__( \
- "mfctl " #reg ",%0" : \
- "=r" (cr) \
- ); \
- cr; \
+ uint32_t cr; \
+ __asm__ __volatile__( \
+ "mfctl " #reg ",%0" : \
+ "=r" (cr) \
+ ); \
+ cr; \
})
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
- return mfctl(16);
+ return mfctl(16);
}
#elif defined(__mips__)
* We know that all SMP capable CPUs have cycle counters.
*/
-#define __read_32bit_c0_register(source, sel) \
-({ int __res; \
- if (sel == 0) \
- __asm__ __volatile__( \
- "mfc0\t%0, " #source "\n\t" \
- : "=r" (__res)); \
- else \
- __asm__ __volatile__( \
- ".set\tmips32\n\t" \
- "mfc0\t%0, " #source ", " #sel "\n\t" \
- ".set\tmips0\n\t" \
- : "=r" (__res)); \
- __res; \
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
})
/* #define CP0_COUNT $9 */
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
- return read_c0_count();
+ return read_c0_count();
}
/* begin mach */
typedef UInt64 cycles_t;
static inline cycles_t get_cycles (void)
{
- UInt64 time = AudioGetCurrentHostTime();
- return AudioConvertHostTimeToNanos(time);
+ UInt64 time = AudioGetCurrentHostTime();
+ return AudioConvertHostTimeToNanos(time);
}
/* end mach */
static inline cycles_t get_cycles(void)
{
- struct timeval tv;
- gettimeofday (&tv, NULL);
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
- return tv.tv_usec;
+ return tv.tv_usec;
}
#endif
namespace PBD {
namespace DEBUG {
- extern uint64_t MidiSourceIO;
- extern uint64_t MidiPlaylistIO;
- extern uint64_t MidiDiskstreamIO;
- extern uint64_t SnapBBT;
- extern uint64_t Configuration;
- extern uint64_t Latency;
- extern uint64_t Processors;
- extern uint64_t ProcessThreads;
- extern uint64_t Graph;
- extern uint64_t Destruction;
- extern uint64_t MTC;
- extern uint64_t Transport;
- extern uint64_t Slave;
- extern uint64_t SessionEvents;
- extern uint64_t MidiIO;
- extern uint64_t MackieControl;
- extern uint64_t MidiClock;
- extern uint64_t Monitor;
- extern uint64_t Solo;
- extern uint64_t AudioPlayback;
- extern uint64_t Panning;
- extern uint64_t LV2;
- extern uint64_t CaptureAlignment;
+ extern uint64_t MidiSourceIO;
+ extern uint64_t MidiPlaylistIO;
+ extern uint64_t MidiDiskstreamIO;
+ extern uint64_t SnapBBT;
+ extern uint64_t Configuration;
+ extern uint64_t Latency;
+ extern uint64_t Processors;
+ extern uint64_t ProcessThreads;
+ extern uint64_t Graph;
+ extern uint64_t Destruction;
+ extern uint64_t MTC;
+ extern uint64_t Transport;
+ extern uint64_t Slave;
+ extern uint64_t SessionEvents;
+ extern uint64_t MidiIO;
+ extern uint64_t MackieControl;
+ extern uint64_t MidiClock;
+ extern uint64_t Monitor;
+ extern uint64_t Solo;
+ extern uint64_t AudioPlayback;
+ extern uint64_t Panning;
+ extern uint64_t LV2;
+ extern uint64_t CaptureAlignment;
}
}
boost::shared_ptr<MuteMaster> _mute_master;
bool no_panner_reset;
boost::shared_ptr<PannerShell> _panshell;
- framecnt_t scnt;
+ framecnt_t scnt;
static bool panners_legal;
static PBD::Signal0<int> PannersLegal;
class Source;
class Session;
class Track;
-class Location;
+class Location;
class Diskstream : public SessionObject, public PublicDiskstream
{
virtual void transport_looped (framepos_t transport_frame) = 0;
struct CaptureInfo {
- framepos_t start;
- framecnt_t frames;
+ framepos_t start;
+ framecnt_t frames;
};
virtual int use_new_write_source (uint32_t n=0) = 0;
virtual void set_align_style_from_io() {}
virtual void setup_destructive_playlist () {}
virtual void use_destructive_playlist () {}
- virtual void prepare_to_stop (framepos_t pos);
+ virtual void prepare_to_stop (framepos_t pos);
void calculate_record_range(OverlapType ot, framepos_t transport_frame, framecnt_t nframes,
framecnt_t& rec_nframes, framecnt_t& rec_offset);
};
/// Handles RegionExportChannels and does actual reading from region
-class RegionExportChannelFactory
+class RegionExportChannelFactory
{
public:
enum Type {
public:
bool operator== (ExportChannelConfiguration const & other) const { return channels == other.channels; }
bool operator!= (ExportChannelConfiguration const & other) const { return channels != other.channels; }
-
+
XMLNode & get_state ();
int set_state (const XMLNode &);
std::copy (new_channels.begin(), new_channels.end(), std::back_inserter(channels));
}
void clear_channels () { channels.clear (); }
-
+
/** Returns a list of channel configurations that match the files created.
* I.e. many configurations if splitting is enabled, one if not. */
void configurations_for_files (std::list<boost::shared_ptr<ExportChannelConfiguration> > & configs);
void set_extension (std::string const & extension) { _extension = extension; }
std::string const & extension () const { return _extension; }
-
+
static SampleRate nearest_sample_rate (framecnt_t sample_rate);
protected:
private:
public:
- ExportFormatCompatibility (std::string name)
+ ExportFormatCompatibility (std::string name)
{
set_name (name);
sample_formats.insert (SF_None);
class SampleFormatState : public ExportFormatBase::SelectableCompatible {
public:
- SampleFormatState (ExportFormatBase::SampleFormat format, std::string name) :
- format (format) { set_name (name); }
+ SampleFormatState (ExportFormatBase::SampleFormat format, std::string name)
+ : format (format)
+ {
+ set_name (name);
+ }
ExportFormatBase::SampleFormat format;
};
typedef std::map<ExportChannelPtr, IdentityVertexPtr> ChannelMap;
public:
-
+
ExportGraphBuilder (Session const & session);
~ExportGraphBuilder ();
-
+
int process (framecnt_t frames, bool last_cycle);
bool process_normalize (); // returns true when finished
-
+
void reset ();
void set_current_timespan (boost::shared_ptr<ExportTimespan> span);
void add_config (FileSpec const & config);
-
+
private:
-
+
void add_split_config (FileSpec const & config);
-
+
class Encoder {
public:
template <typename T> boost::shared_ptr<AudioGrapher::Sink<T> > init (FileSpec const & new_config);
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
static int get_real_format (FileSpec const & config);
-
+
private:
typedef boost::shared_ptr<AudioGrapher::SndfileWriter<Sample> > FloatWriterPtr;
typedef boost::shared_ptr<AudioGrapher::SndfileWriter<int> > IntWriterPtr;
typedef boost::shared_ptr<AudioGrapher::SndfileWriter<short> > ShortWriterPtr;
-
+
template<typename T> void init_writer (boost::shared_ptr<AudioGrapher::SndfileWriter<T> > & writer);
void copy_files (std::string orig_path);
-
+
FileSpec config;
std::list<FilenamePtr> filenames;
PBD::ScopedConnection copy_files_connection;
-
+
// Only one of these should be available at a time
FloatWriterPtr float_writer;
IntWriterPtr int_writer;
ShortWriterPtr short_writer;
};
-
+
// sample format converter
class SFC {
public:
FloatSinkPtr sink ();
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
private:
typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<Sample> > FloatConverterPtr;
typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<int> > IntConverterPtr;
typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<short> > ShortConverterPtr;
-
+
FileSpec config;
boost::ptr_list<Encoder> children;
int data_width;
-
+
// Only one of these should be available at a time
FloatConverterPtr float_converter;
IntConverterPtr int_converter;
ShortConverterPtr short_converter;
};
-
+
class Normalizer {
public:
Normalizer (ExportGraphBuilder & parent, FileSpec const & new_config, framecnt_t max_frames);
FloatSinkPtr sink ();
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
/// Returns true when finished
bool process ();
-
+
private:
typedef boost::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr;
typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr;
typedef boost::shared_ptr<AudioGrapher::TmpFile<Sample> > TmpFilePtr;
typedef boost::shared_ptr<AudioGrapher::Threader<Sample> > ThreaderPtr;
typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr;
-
+
void start_post_processing();
-
+
ExportGraphBuilder & parent;
-
+
FileSpec config;
framecnt_t max_frames_out;
-
+
BufferPtr buffer;
PeakReaderPtr peak_reader;
TmpFilePtr tmp_file;
NormalizerPtr normalizer;
ThreaderPtr threader;
boost::ptr_list<SFC> children;
-
+
PBD::ScopedConnection post_processing_connection;
};
-
+
// sample rate converter
class SRC {
public:
FloatSinkPtr sink ();
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
private:
typedef boost::shared_ptr<AudioGrapher::SampleRateConverter> SRConverterPtr;
-
+
template<typename T>
void add_child_to_list (FileSpec const & new_config, boost::ptr_list<T> & list);
-
+
ExportGraphBuilder & parent;
FileSpec config;
boost::ptr_list<SFC> children;
SRConverterPtr converter;
framecnt_t max_frames_out;
};
-
+
// Silence trimmer + adder
class SilenceHandler {
public:
FloatSinkPtr sink ();
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
private:
typedef boost::shared_ptr<AudioGrapher::SilenceTrimmer<Sample> > SilenceTrimmerPtr;
-
+
ExportGraphBuilder & parent;
FileSpec config;
boost::ptr_list<SRC> children;
SilenceTrimmerPtr silence_trimmer;
framecnt_t max_frames_in;
};
-
+
// channel configuration
class ChannelConfig {
public:
ChannelConfig (ExportGraphBuilder & parent, FileSpec const & new_config, ChannelMap & channel_map);
void add_child (FileSpec const & new_config);
bool operator== (FileSpec const & other_config) const;
-
+
private:
typedef boost::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
-
+
ExportGraphBuilder & parent;
FileSpec config;
boost::ptr_list<SilenceHandler> children;
Session const & session;
boost::shared_ptr<ExportTimespan> timespan;
-
+
// Roots for export processor trees
typedef boost::ptr_list<ChannelConfig> ChannelConfigList;
ChannelConfigList channel_configs;
-
+
// The sources of all data, each channel is read only once
ChannelMap channels;
-
+
framecnt_t process_buffer_frames;
-
+
std::list<Normalizer *> normalizers;
-
+
Glib::ThreadPool thread_pool;
};
FilenamePtr filename;
boost::shared_ptr<AudioGrapher::BroadcastInfo> broadcast_info;
};
-
+
private:
/* Stuff for export configs
private:
int process (framecnt_t frames);
-
+
Session & session;
GraphBuilderPtr graph_builder;
StatusPtr export_status;
typedef std::pair<ConfigMap::iterator, ConfigMap::iterator> TimespanBounds;
TimespanPtr current_timespan;
TimespanBounds timespan_bounds;
-
+
PBD::ScopedConnection process_connection;
framepos_t process_position;
ChannelConfigStatePtr channel_config_state,
FormatStatePtr format_state,
FilenameStatePtr filename_state);
-
+
bool check_format (FormatPtr format, uint32_t channels);
bool check_sndfile_format (FormatPtr format, unsigned int channels);
namespace ARDOUR {
-class MissingSource : public std::exception
+class MissingSource : public std::exception
{
public:
- MissingSource (const std::string& p, DataType t) throw ()
- : path (p), type (t) {}
- ~MissingSource() throw() {}
+ MissingSource (const std::string& p, DataType t) throw ()
+ : path (p), type (t) {}
+ ~MissingSource() throw() {}
virtual const char *what() const throw() { return "source file does not exist"; }
- std::string path;
- DataType type;
+ std::string path;
+ DataType type;
};
/** A source associated with a file on disk somewhere */
class FileSource : virtual public Source {
public:
virtual ~FileSource () {}
-
+
virtual const std::string& path() const { return _path; }
virtual bool safe_file_extension (const std::string& path) const = 0;
int set_source_name (const std::string& newname, bool destructive);
static bool find (Session&, DataType type, const std::string& path,
- bool must_exist, bool& is_new, uint16_t& chan,
- std::string& found_path);
+ bool must_exist, bool& is_new, uint16_t& chan,
+ std::string& found_path);
static bool find_2X (Session&, DataType type, const std::string& path,
- bool must_exist, bool& is_new, uint16_t& chan,
- std::string& found_path);
+ bool must_exist, bool& is_new, uint16_t& chan,
+ std::string& found_path);
- void inc_use_count ();
+ void inc_use_count ();
bool removable () const;
- const std::string& origin() const { return _origin; }
+ const std::string& origin() const { return _origin; }
static PBD::Signal3<int,std::string,std::string,std::vector<std::string> > AmbiguousFileName;
protected:
FileSource (Session& session, DataType type,
- const std::string& path,
- const std::string& origin,
- Source::Flag flags = Source::Flag(0));
+ const std::string& path,
+ const std::string& origin,
+ Source::Flag flags = Source::Flag(0));
FileSource (Session& session, const XMLNode& node, bool must_exist);
virtual int init (const std::string& idstr, bool must_exist);
- virtual void set_path (const std::string&);
+ virtual void set_path (const std::string&);
virtual int move_dependents_to_trash() { return 0; }
void set_within_session_from_path (const std::string&);
bool _file_is_new;
uint16_t _channel;
bool _within_session;
- std::string _origin;
- bool _open;
-
- void prevent_deletion ();
+ std::string _origin;
+ bool _open;
+
+ void prevent_deletion ();
};
} // namespace ARDOUR
/*
Copyright (C) 2010 Paul Davis
- Author: Torben Hohn
+ Author: Torben Hohn
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
class Graph : public SessionHandleRef
{
- public:
+public:
Graph (Session & session);
- uint32_t threads_in_use () const { return _thread_list.size(); }
+ uint32_t threads_in_use () const { return _thread_list.size(); }
void prep();
void trigger (GraphNode * n);
void main_thread();
int silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool rec_monitors_input, bool& need_butler);
+ bool can_record, bool rec_monitors_input, bool& need_butler);
int process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool can_record, bool rec_monitors_input, bool& need_butler);
+ bool can_record, bool rec_monitors_input, bool& need_butler);
- int routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool non_rt_pending, bool can_record, int declick);
+ int routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+ bool non_rt_pending, bool can_record, int declick);
void process_one_route (Route * route);
- void clear_other_chain ();
+ void clear_other_chain ();
bool in_process_thread () const;
- protected:
- virtual void session_going_away ();
+protected:
+ virtual void session_going_away ();
- private:
- std::list<pthread_t> _thread_list;
- volatile bool _quit_threads;
- PBD::ScopedConnection processor_usage_connection;
+private:
+ std::list<pthread_t> _thread_list;
+ volatile bool _quit_threads;
+ PBD::ScopedConnection processor_usage_connection;
- void parameter_changed (std::string);
- void reset_thread_list ();
- void drop_threads ();
+ void parameter_changed (std::string);
+ void reset_thread_list ();
+ void drop_threads ();
node_list_t _nodes_rt[2];
node_list_t _init_trigger_list[2];
std::vector<GraphNode *> _trigger_queue;
- pthread_mutex_t _trigger_mutex;
+ pthread_mutex_t _trigger_mutex;
PBD::ProcessSemaphore _execution_sem;
volatile gint _finished_refcount;
volatile gint _init_finished_refcount[2];
- bool _graph_empty;
+ bool _graph_empty;
// chain swapping
- Glib::Mutex _swap_mutex;
- Glib::Cond _cleanup_cond;
+ Glib::Mutex _swap_mutex;
+ Glib::Cond _cleanup_cond;
volatile int _current_chain;
volatile int _pending_chain;
volatile int _setup_chain;
// parameter caches.
- pframes_t _process_nframes;
- framepos_t _process_start_frame;
- framepos_t _process_end_frame;
- bool _process_can_record;
- bool _process_rec_monitors_input;
- bool _process_non_rt_pending;
- int _process_declick;
-
- bool _process_silent;
- bool _process_noroll;
- int _process_retval;
- bool _process_need_butler;
+ pframes_t _process_nframes;
+ framepos_t _process_start_frame;
+ framepos_t _process_end_frame;
+ bool _process_can_record;
+ bool _process_rec_monitors_input;
+ bool _process_non_rt_pending;
+ int _process_declick;
+
+ bool _process_silent;
+ bool _process_noroll;
+ int _process_retval;
+ bool _process_need_butler;
};
-} // namespace
+} // namespace
#endif /* __ardour_graph_h__ */
node_set_t _activation_set[2];
- boost::shared_ptr<Graph> _graph;
+ boost::shared_ptr<Graph> _graph;
gint _refcount;
gint _init_refcount[2];
namespace ARDOUR {
-class InternalSend;
+class InternalSend;
class InternalReturn : public Return
{
void add_send (InternalSend *);
void remove_send (InternalSend *);
-
+
static PBD::Signal1<void, pframes_t> CycleStart;
private:
BufferSet buffers;
/** sends that we are receiving data from */
std::list<InternalSend*> _sends;
-
+
void allocate_buffers (pframes_t);
void cycle_start (pframes_t);
};
XMLNode& state(bool full);
XMLNode& get_state(void);
int set_state(const XMLNode& node, int version);
-
+
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
bool feeds (boost::shared_ptr<Route> other) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
boost::shared_ptr<Route> _send_to;
PBD::ID _send_to_id;
PBD::ScopedConnection connect_c;
- PBD::ScopedConnectionList target_connections;
+ PBD::ScopedConnectionList target_connections;
void send_to_going_away ();
void send_to_property_changed (const PBD::PropertyChange&);
int connect_when_legal ();
int set_our_state (XMLNode const &, int);
- int use_target (boost::shared_ptr<Route>);
+ int use_target (boost::shared_ptr<Route>);
};
} // namespace ARDOUR
void set_speed (double new_speed) { _speed = new_speed; _target_speed = new_speed; }
void set_target_speed (double new_speed) { _target_speed = new_speed; }
-
+
double target_speed() const { return _target_speed; }
double speed() const { return _speed; }
-
+
void add_channel_to (int /*input_buffer_size*/, int /*output_buffer_size*/) { phase.push_back (0.0); }
void remove_channel_from () { phase.pop_back (); }
-
+
void reset () {
for (size_t i = 0; i < phase.size(); i++) {
phase[i] = 0.0;
bool set_name (const std::string& str);
virtual void silence (framecnt_t);
- void increment_port_buffer_offset (pframes_t offset);
+ void increment_port_buffer_offset (pframes_t offset);
int ensure_io (ChanCount cnt, bool clear, void *src);
int disconnect (Port *our_port, std::string other_port, void *src);
int disconnect (void *src);
bool connected_to (boost::shared_ptr<const IO>) const;
- bool connected () const;
- bool physically_connected () const;
-
+ bool connected () const;
+ bool physically_connected () const;
+
framecnt_t signal_latency () const { return _own_latency; }
framecnt_t latency () const;
* the change from happening.
*/
PBD::Signal1<bool, ChanCount, BoolCombiner> PortCountChanging;
-
+
static int disable_connecting (void);
static int enable_connecting (void);
static int disable_ports (void);
boost::shared_ptr<UserBundle> bundle;
PBD::ScopedConnection changed;
};
-
+
std::vector<UserBundleInfo*> _bundles_connected; ///< user bundles connected to our ports
static int parse_io_string (const std::string&, std::vector<std::string>& chns);
void silence (framecnt_t nframes);
void disconnect ();
- void increment_port_buffer_offset (pframes_t);
+ void increment_port_buffer_offset (pframes_t);
virtual bool feeds (boost::shared_ptr<Route> other) const;
XMLNode& state (bool full_state);
int set_state (const XMLNode&, int version);
-
+
protected:
boost::shared_ptr<IO> _input;
boost::shared_ptr<IO> _output;
IOProcessor (const IOProcessor&);
virtual int set_state_2X (const XMLNode &, int);
-
+
bool _own_input;
bool _own_output;
bool _was_activated;
void find_presets ();
-
+
void init (void *mod, uint32_t index, framecnt_t rate);
void run_in_place (pframes_t nsamples);
void latency_compute_run ();
XMLNode& get_state (void);
int set_state (const XMLNode&, int version);
- Location *get_location_by_id(PBD::ID);
+ Location *get_location_by_id(PBD::ID);
Location* auto_loop_location () const;
Location* auto_punch_location () const;
boost::shared_ptr<Plugin::ScalePoints>
get_scale_points(uint32_t port_index) const;
-
+
static uint32_t midi_event_type () { return _midi_event_type; }
void set_insert_info(const PluginInsert* insert);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool configure_io (ChanCount in, ChanCount out);
-
+
/* special method for meter, to ensure that it can always handle the maximum
number of streams in the route, no matter where we put it.
*/
}
XMLNode& state (bool full);
-
+
private:
friend class IO;
* as it can be altered outside a ::configure_io by ::reflect_inputs.
*/
ChanCount current_meters;
-
+
std::vector<float> _peak_power;
std::vector<float> _visible_peak_power;
std::vector<float> _max_peak_power;
const_iterator begin() const { return const_iterator(*this, 0); }
const_iterator end() const { return const_iterator(*this, _size); }
-
- uint8_t* data() const { return _data; }
-
+
+ uint8_t* data() const { return _data; }
+
private:
friend class iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >;
friend class iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> >;
void set_block_size (pframes_t);
int internal_playback_seek (framecnt_t distance);
int can_internal_playback_seek (framecnt_t distance);
- std::list<boost::shared_ptr<Source> > steal_write_sources();
+ std::list<boost::shared_ptr<Source> > steal_write_sources();
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
void non_realtime_locate (framepos_t location);
void get_input_sources ();
void set_align_style_from_io();
- /* fixed size buffers per instance of ardour for now (non-dynamic)
- */
+ /* fixed size buffers per instance of ardour for now (non-dynamic)
+ */
- void adjust_playback_buffering () {}
- void adjust_capture_buffering () {}
+ void adjust_playback_buffering () {}
+ void adjust_capture_buffering () {}
void engage_record_enable ();
void disengage_record_enable ();
class MidiPlaylist;
class MidiPlaylistSource : public MidiSource, public PlaylistSource {
- public:
- virtual ~MidiPlaylistSource ();
-
- bool empty() const;
- framecnt_t length (framepos_t) const;
-
- framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
- framecnt_t write_unlocked (Sample *src, framecnt_t cnt);
-
- XMLNode& get_state ();
- int set_state (const XMLNode&, int version);
-
- void append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& ev);
- void append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start);
- void load_model(bool lock=true, bool force_reload=false);
- void destroy_model();
-
- protected:
- friend class SourceFactory;
-
- MidiPlaylistSource (Session&, const PBD::ID& orig, const std::string& name, boost::shared_ptr<MidiPlaylist>, uint32_t chn,
- frameoffset_t begin, framecnt_t len, Source::Flag flags);
- MidiPlaylistSource (Session&, const XMLNode&);
-
-
- void flush_midi();
-
- framepos_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
- framepos_t position,
- framepos_t start, framecnt_t cnt,
- MidiStateTracker* tracker) const;
-
- framepos_t write_unlocked (MidiRingBuffer<framepos_t>& dst,
- framepos_t position,
- framecnt_t cnt);
-
- private:
- int set_state (const XMLNode&, int version, bool with_descendants);
- framecnt_t _length;
+public:
+ virtual ~MidiPlaylistSource ();
+
+ bool empty() const;
+ framecnt_t length (framepos_t) const;
+
+ framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
+ framecnt_t write_unlocked (Sample *src, framecnt_t cnt);
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&, int version);
+
+ void append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& ev);
+ void append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start);
+ void load_model(bool lock=true, bool force_reload=false);
+ void destroy_model();
+
+protected:
+ friend class SourceFactory;
+
+ MidiPlaylistSource (Session&, const PBD::ID& orig, const std::string& name, boost::shared_ptr<MidiPlaylist>, uint32_t chn,
+ frameoffset_t begin, framecnt_t len, Source::Flag flags);
+ MidiPlaylistSource (Session&, const XMLNode&);
+
+
+ void flush_midi();
+
+ framepos_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
+ framepos_t position,
+ framepos_t start, framecnt_t cnt,
+ MidiStateTracker* tracker) const;
+
+ framepos_t write_unlocked (MidiRingBuffer<framepos_t>& dst,
+ framepos_t position,
+ framecnt_t cnt);
+
+private:
+ int set_state (const XMLNode&, int version, bool with_descendants);
+ framecnt_t _length;
};
-
+
} /* namespace */
#endif /* __ardour_midi_playlist_source_h__ */
namespace Properties {
/* this is pseudo-property: nothing has this as an actual
property, but it allows us to signal changes to the
- MidiModel used by the MidiRegion
+ MidiModel used by the MidiRegion
*/
extern PBD::PropertyDescriptor<void*> midi_data;
extern PBD::PropertyDescriptor<Evoral::MusicalTime> length_beats;
~MidiRegion();
boost::shared_ptr<MidiRegion> clone ();
-
+
boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
/* Stub Readable interface */
uint32_t chan_n = 0,
NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
-
+
framepos_t master_read_at (MidiRingBuffer<framepos_t>& dst,
framepos_t position,
framecnt_t dur,
XMLNode& state ();
int set_state (const XMLNode&, int version);
-
+
int separate_by_channel (ARDOUR::Session&, std::vector< boost::shared_ptr<Region> >&) const;
/* automation */
-
+
boost::shared_ptr<Evoral::Control>
control(const Evoral::Parameter& id, bool create=false) {
return model()->control(id, create);
void transpose (int);
protected:
-
+
virtual bool can_trim_start_before_source_start () const {
return true;
}
framepos_t position,
framecnt_t dur,
uint32_t chan_n = 0,
- NoteMode mode = Sustained,
+ NoteMode mode = Sustained,
MidiStateTracker* tracker = 0) const;
void register_properties ();
MidiSource (Session& session, const XMLNode&);
virtual ~MidiSource ();
- boost::shared_ptr<MidiSource> clone (Evoral::MusicalTime begin = Evoral::MinMusicalTime,
- Evoral::MusicalTime end = Evoral::MaxMusicalTime);
+ boost::shared_ptr<MidiSource> clone (Evoral::MusicalTime begin = Evoral::MinMusicalTime,
+ Evoral::MusicalTime end = Evoral::MaxMusicalTime);
/** Read the data in a given time range from the MIDI source.
* All time stamps in parameters are in audio frames (even if the source has tempo time).
void reset ();
bool empty() const { return _on == 0; }
uint16_t on() const { return _on; }
- bool active (uint8_t note, uint8_t channel) {
- return _active_notes[(channel*128)+note] > 0;
- }
+ bool active (uint8_t note, uint8_t channel) {
+ return _active_notes[(channel*128)+note] > 0;
+ }
private:
void track_note_onoffs(const Evoral::MIDIEvent<MidiBuffer::TimeType>& event);
class MidiDiskstream;
class MidiPlaylist;
class RouteGroup;
-class SMFSource;
+class SMFSource;
class MidiTrack : public Track
{
~MidiTrack ();
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
+ int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
void realtime_handle_transport_stopped ();
void realtime_locate ();
void use_new_diskstream ();
- void set_diskstream (boost::shared_ptr<Diskstream>);
+ void set_diskstream (boost::shared_ptr<Diskstream>);
void set_record_enabled (bool yn, void *src);
DataType data_type () const {
void freeze_me (InterThreadInfo&);
void unfreeze ();
-
+
boost::shared_ptr<Region> bounce (InterThreadInfo&);
boost::shared_ptr<Region> bounce_range (
framepos_t start, framepos_t end, InterThreadInfo&, bool enable_processing
void set_step_editing (bool yn);
MidiRingBuffer<framepos_t>& step_edit_ring_buffer() { return _step_edit_ring_buffer; }
- PBD::Signal1<void,bool> StepEditStatusChange;
+ PBD::Signal1<void,bool> StepEditStatusChange;
bool midi_thru() const { return _midi_thru; }
void set_midi_thru (bool yn);
bool bounceable () const {
return false;
}
-
+
PBD::Signal2<void, boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource> > DataRecorded;
protected:
XMLNode& state (bool full);
-
+
int _set_state (const XMLNode&, int, bool call_base);
- bool should_monitor () const;
- bool send_silence () const;
+ bool should_monitor () const;
+ bool send_silence () const;
private:
boost::shared_ptr<MidiDiskstream> midi_diskstream () const;
#include "pbd/abstract_ui.h"
#include "pbd/signals.h"
-namespace MIDI {
+namespace MIDI {
class Port;
}
~MidiControlUI ();
static MidiControlUI* instance() { return _instance; }
-
+
static BaseUI::RequestType PortChange;
-
+
void change_midi_ports ();
-
+
protected:
void thread_init ();
void do_request (MidiUIRequest*);
-
+
private:
typedef std::list<GSource*> PortSources;
PortSources port_sources;
extern "C" {
/* SSE functions */
- float x86_sse_compute_peak (const ARDOUR::Sample * buf, ARDOUR::pframes_t nsamples, float current);
- void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::pframes_t nframes, float gain);
- void x86_sse_mix_buffers_with_gain(ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::pframes_t nframes, float gain);
- void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::pframes_t nframes);
+float x86_sse_compute_peak (const ARDOUR::Sample * buf, ARDOUR::pframes_t nsamples, float current);
+void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::pframes_t nframes, float gain);
+void x86_sse_mix_buffers_with_gain(ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::pframes_t nframes, float gain);
+void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::pframes_t nframes);
}
void x86_sse_find_peaks (const ARDOUR::Sample * buf, ARDOUR::pframes_t nsamples, float *min, float *max);
class Session;
-template<typename T> class MPControl : public PBD::Controllable {
- public:
- MPControl (T initial, const std::string& name, PBD::Controllable::Flag flag,
- float lower = 0.0f, float upper = 1.0f)
- : PBD::Controllable (name, flag)
- , _value (initial)
- , _lower (lower)
- , _upper (upper)
- {}
-
- /* Controllable API */
-
- void set_value (double v) {
- T newval = (T) v;
- if (newval != _value) {
- _value = newval;
- Changed(); /* EMIT SIGNAL */
- }
- }
-
- double get_value () const {
- return (float) _value;
- }
-
- double lower () const { return _lower; }
- double upper () const { return _upper; }
-
- /* "access as T" API */
-
- MPControl& operator=(const T& v) {
- if (v != _value) {
- _value = v;
- Changed (); /* EMIT SIGNAL */
- }
- return *this;
- }
-
- bool operator==(const T& v) const {
- return _value == v;
- }
-
- bool operator<(const T& v) const {
- return _value < v;
- }
-
- bool operator<=(const T& v) const {
- return _value <= v;
- }
-
- bool operator>(const T& v) const {
- return _value > v;
- }
-
- bool operator>=(const T& v) const {
- return _value >= v;
- }
-
- operator T() const { return _value; }
- T val() const { return _value; }
-
- protected:
- T _value;
- T _lower;
- T _upper;
+template<typename T>
+class MPControl : public PBD::Controllable {
+public:
+ MPControl (T initial, const std::string& name, PBD::Controllable::Flag flag,
+ float lower = 0.0f, float upper = 1.0f)
+ : PBD::Controllable (name, flag)
+ , _value (initial)
+ , _lower (lower)
+ , _upper (upper)
+ {}
+
+ /* Controllable API */
+
+ void set_value (double v) {
+ T newval = (T) v;
+ if (newval != _value) {
+ _value = newval;
+ Changed(); /* EMIT SIGNAL */
+ }
+ }
+
+ double get_value () const {
+ return (float) _value;
+ }
+
+ double lower () const { return _lower; }
+ double upper () const { return _upper; }
+
+ /* "access as T" API */
+
+ MPControl& operator=(const T& v) {
+ if (v != _value) {
+ _value = v;
+ Changed (); /* EMIT SIGNAL */
+ }
+ return *this;
+ }
+
+ bool operator==(const T& v) const {
+ return _value == v;
+ }
+
+ bool operator<(const T& v) const {
+ return _value < v;
+ }
+
+ bool operator<=(const T& v) const {
+ return _value <= v;
+ }
+
+ bool operator>(const T& v) const {
+ return _value > v;
+ }
+
+ bool operator>=(const T& v) const {
+ return _value >= v;
+ }
+
+ operator T() const { return _value; }
+ T val() const { return _value; }
+
+protected:
+ T _value;
+ T _lower;
+ T _upper;
};
class MonitorProcessor : public Processor
{
- public:
- MonitorProcessor (Session&);
- ~MonitorProcessor ();
+public:
+ MonitorProcessor (Session&);
+ ~MonitorProcessor ();
- bool display_to_user() const;
+ bool display_to_user() const;
void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t /*nframes*/, bool /*result_required*/);
- XMLNode& state (bool full);
- int set_state (const XMLNode&, int /* version */);
+ XMLNode& state (bool full);
+ int set_state (const XMLNode&, int /* version */);
- bool configure_io (ChanCount in, ChanCount out);
+ bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
- void set_cut_all (bool);
- void set_dim_all (bool);
- void set_polarity (uint32_t, bool invert);
- void set_cut (uint32_t, bool cut);
- void set_dim (uint32_t, bool dim);
- void set_solo (uint32_t, bool);
- void set_mono (bool);
-
- gain_t dim_level() const { return _dim_level; }
- gain_t solo_boost_level() const { return _solo_boost_level; }
-
- bool dimmed (uint32_t chn) const;
- bool soloed (uint32_t chn) const;
- bool inverted (uint32_t chn) const;
- bool cut (uint32_t chn) const;
- bool cut_all () const;
- bool dim_all () const;
- bool mono () const;
-
- PBD::Signal0<void> Changed;
-
- boost::shared_ptr<PBD::Controllable> channel_cut_control (uint32_t) const;
- boost::shared_ptr<PBD::Controllable> channel_dim_control (uint32_t) const;
- boost::shared_ptr<PBD::Controllable> channel_polarity_control (uint32_t) const;
- boost::shared_ptr<PBD::Controllable> channel_solo_control (uint32_t) const;
-
- boost::shared_ptr<PBD::Controllable> dim_control () const { return _dim_all_control; }
- boost::shared_ptr<PBD::Controllable> cut_control () const { return _cut_all_control; }
- boost::shared_ptr<PBD::Controllable> mono_control () const { return _mono_control; }
- boost::shared_ptr<PBD::Controllable> dim_level_control () const { return _dim_level_control; }
- boost::shared_ptr<PBD::Controllable> solo_boost_control () const { return _solo_boost_level_control; }
-
- private:
- struct ChannelRecord {
- gain_t current_gain;
-
- /* pointers - created first, but managed by boost::shared_ptr<> */
-
- MPControl<gain_t>* cut_ptr;
- MPControl<bool>* dim_ptr;
- MPControl<gain_t>* polarity_ptr;
- MPControl<bool>* soloed_ptr;
-
- /* shared ptr access and lifetime management, for external users */
-
- boost::shared_ptr<PBD::Controllable> cut_control;
- boost::shared_ptr<PBD::Controllable> dim_control;
- boost::shared_ptr<PBD::Controllable> polarity_control;
- boost::shared_ptr<PBD::Controllable> soloed_control;
-
- /* typed controllables for internal use */
-
- MPControl<gain_t>& cut;
- MPControl<bool>& dim;
- MPControl<gain_t>& polarity;
- MPControl<bool>& soloed;
-
- ChannelRecord (uint32_t);
- };
-
- std::vector<ChannelRecord*> _channels;
-
- uint32_t solo_cnt;
-
- /* pointers - created first, but managed by boost::shared_ptr<> */
-
- MPControl<bool>* _dim_all_ptr;
- MPControl<bool>* _cut_all_ptr;
- MPControl<bool>* _mono_ptr;
- MPControl<volatile gain_t>* _dim_level_ptr;
- MPControl<volatile gain_t>* _solo_boost_level_ptr;
-
- /* shared ptr access and lifetime management, for external users */
-
- boost::shared_ptr<PBD::Controllable> _dim_all_control;
- boost::shared_ptr<PBD::Controllable> _cut_all_control;
- boost::shared_ptr<PBD::Controllable> _mono_control;
- boost::shared_ptr<PBD::Controllable> _dim_level_control;
- boost::shared_ptr<PBD::Controllable> _solo_boost_level_control;
-
- /* typed controllables for internal use */
-
- MPControl<bool>& _dim_all;
- MPControl<bool>& _cut_all;
- MPControl<bool>& _mono;
- MPControl<volatile gain_t>& _dim_level;
- MPControl<volatile gain_t>& _solo_boost_level;
-
- void allocate_channels (uint32_t);
+ void set_cut_all (bool);
+ void set_dim_all (bool);
+ void set_polarity (uint32_t, bool invert);
+ void set_cut (uint32_t, bool cut);
+ void set_dim (uint32_t, bool dim);
+ void set_solo (uint32_t, bool);
+ void set_mono (bool);
+
+ gain_t dim_level() const { return _dim_level; }
+ gain_t solo_boost_level() const { return _solo_boost_level; }
+
+ bool dimmed (uint32_t chn) const;
+ bool soloed (uint32_t chn) const;
+ bool inverted (uint32_t chn) const;
+ bool cut (uint32_t chn) const;
+ bool cut_all () const;
+ bool dim_all () const;
+ bool mono () const;
+
+ PBD::Signal0<void> Changed;
+
+ boost::shared_ptr<PBD::Controllable> channel_cut_control (uint32_t) const;
+ boost::shared_ptr<PBD::Controllable> channel_dim_control (uint32_t) const;
+ boost::shared_ptr<PBD::Controllable> channel_polarity_control (uint32_t) const;
+ boost::shared_ptr<PBD::Controllable> channel_solo_control (uint32_t) const;
+
+ boost::shared_ptr<PBD::Controllable> dim_control () const { return _dim_all_control; }
+ boost::shared_ptr<PBD::Controllable> cut_control () const { return _cut_all_control; }
+ boost::shared_ptr<PBD::Controllable> mono_control () const { return _mono_control; }
+ boost::shared_ptr<PBD::Controllable> dim_level_control () const { return _dim_level_control; }
+ boost::shared_ptr<PBD::Controllable> solo_boost_control () const { return _solo_boost_level_control; }
+
+private:
+ struct ChannelRecord {
+ gain_t current_gain;
+
+ /* pointers - created first, but managed by boost::shared_ptr<> */
+
+ MPControl<gain_t>* cut_ptr;
+ MPControl<bool>* dim_ptr;
+ MPControl<gain_t>* polarity_ptr;
+ MPControl<bool>* soloed_ptr;
+
+ /* shared ptr access and lifetime management, for external users */
+
+ boost::shared_ptr<PBD::Controllable> cut_control;
+ boost::shared_ptr<PBD::Controllable> dim_control;
+ boost::shared_ptr<PBD::Controllable> polarity_control;
+ boost::shared_ptr<PBD::Controllable> soloed_control;
+
+ /* typed controllables for internal use */
+
+ MPControl<gain_t>& cut;
+ MPControl<bool>& dim;
+ MPControl<gain_t>& polarity;
+ MPControl<bool>& soloed;
+
+ ChannelRecord (uint32_t);
+ };
+
+ std::vector<ChannelRecord*> _channels;
+
+ uint32_t solo_cnt;
+
+ /* pointers - created first, but managed by boost::shared_ptr<> */
+
+ MPControl<bool>* _dim_all_ptr;
+ MPControl<bool>* _cut_all_ptr;
+ MPControl<bool>* _mono_ptr;
+ MPControl<volatile gain_t>* _dim_level_ptr;
+ MPControl<volatile gain_t>* _solo_boost_level_ptr;
+
+ /* shared ptr access and lifetime management, for external users */
+
+ boost::shared_ptr<PBD::Controllable> _dim_all_control;
+ boost::shared_ptr<PBD::Controllable> _cut_all_control;
+ boost::shared_ptr<PBD::Controllable> _mono_control;
+ boost::shared_ptr<PBD::Controllable> _dim_level_control;
+ boost::shared_ptr<PBD::Controllable> _solo_boost_level_control;
+
+ /* typed controllables for internal use */
+
+ MPControl<bool>& _dim_all;
+ MPControl<bool>& _cut_all;
+ MPControl<bool>& _mono;
+ MPControl<volatile gain_t>& _dim_level;
+ MPControl<volatile gain_t>& _solo_boost_level;
+
+ void allocate_channels (uint32_t);
};
} /* namespace */
class Movable {
public:
- Movable() {}
+ Movable() {}
- bool locked () const { return false; }
+ bool locked () const { return false; }
};
}
~MuteMaster() {}
bool muted_by_self () const { return _muted_by_self && (_mute_point != MutePoint (0)); }
- bool muted_by_self_at (MutePoint mp) const { return _muted_by_self && (_mute_point & mp); }
+ bool muted_by_self_at (MutePoint mp) const { return _muted_by_self && (_mute_point & mp); }
bool muted_by_others_at (MutePoint mp) const;
gain_t mute_gain_at (MutePoint) const;
- void set_muted_by_self (bool yn) { _muted_by_self = yn; }
+ void set_muted_by_self (bool yn) { _muted_by_self = yn; }
void mute_at (MutePoint);
void unmute_at (MutePoint);
void set_mute_points (const std::string& mute_point);
- void set_mute_points (MutePoint);
- MutePoint mute_points() const { return _mute_point; }
+ void set_mute_points (MutePoint);
+ MutePoint mute_points() const { return _mute_point; }
- void set_soloed (bool);
- void set_solo_ignore (bool yn) { _solo_ignore = yn; }
+ void set_soloed (bool);
+ void set_solo_ignore (bool yn) { _solo_ignore = yn; }
PBD::Signal0<void> MutePointChanged;
private:
volatile MutePoint _mute_point;
- volatile bool _muted_by_self;
- volatile bool _soloed;
- volatile bool _solo_ignore;
+ volatile bool _muted_by_self;
+ volatile bool _soloed;
+ volatile bool _solo_ignore;
};
} // namespace ARDOUR
namespace ARDOUR
{
+
class Session;
class Playlist;
struct NamedSelection : public PBD::Stateful
{
- NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
- NamedSelection (Session&, const XMLNode&);
- virtual ~NamedSelection ();
+ NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
+ NamedSelection (Session&, const XMLNode&);
+ virtual ~NamedSelection ();
- std::string name;
- std::list<boost::shared_ptr<Playlist> > playlists;
+ std::string name;
+ std::list<boost::shared_ptr<Playlist> > playlists;
- XMLNode& get_state (void);
+ XMLNode& get_state (void);
- int set_state (const XMLNode&, int version);
+ int set_state (const XMLNode&, int version);
- static PBD::Signal1<void,NamedSelection*> NamedSelectionCreated;
+ static PBD::Signal1<void,NamedSelection*> NamedSelectionCreated;
};
}/* namespace ARDOUR */
class OnsetDetector : public AudioAnalyser
{
+public:
+ OnsetDetector (float sample_rate);
+ ~OnsetDetector();
- public:
- OnsetDetector (float sample_rate);
- ~OnsetDetector();
+ static std::string operational_identifier();
- static std::string operational_identifier();
+ void set_silence_threshold (float);
+ void set_peak_threshold (float);
+ void set_function (int);
- void set_silence_threshold (float);
- void set_peak_threshold (float);
- void set_function (int);
+ int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
- int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
+ static void cleanup_onsets (AnalysisFeatureList&, float sr, float gap_msecs);
- static void cleanup_onsets (AnalysisFeatureList&, float sr, float gap_msecs);
+protected:
+ AnalysisFeatureList* current_results;
+ int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
- protected:
- AnalysisFeatureList* current_results;
- int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
-
- static std::string _op_id;
+ static std::string _op_id;
};
} /* namespace */
extern GQuark fixed_time_region_copy;
};
-
+
class Session;
class Pannable;
-class PanControllable : public AutomationControl
+class PanControllable : public AutomationControl
{
- public:
- PanControllable (Session& s, std::string name, Pannable* o, Evoral::Parameter param)
- : AutomationControl (s, param, boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
- , owner (o)
- {}
-
- double lower () const;
- void set_value (double);
-
- private:
-
- Pannable* owner;
+public:
+ PanControllable (Session& s, std::string name, Pannable* o, Evoral::Parameter param)
+ : AutomationControl (s, param, boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
+ , owner (o)
+ {}
+
+ double lower () const;
+ void set_value (double);
+
+private:
+ Pannable* owner;
};
-} // namespace
+} // namespace
#endif /* __libardour_pan_controllable_h__ */
class AutomationControl;
class Panner;
-class Pannable : public PBD::Stateful, public Automatable, public SessionHandleRef
+class Pannable : public PBD::Stateful, public Automatable, public SessionHandleRef
{
public:
- Pannable (Session& s);
- ~Pannable ();
+ Pannable (Session& s);
+ ~Pannable ();
- boost::shared_ptr<AutomationControl> pan_azimuth_control;
- boost::shared_ptr<AutomationControl> pan_elevation_control;
- boost::shared_ptr<AutomationControl> pan_width_control;
- boost::shared_ptr<AutomationControl> pan_frontback_control;
- boost::shared_ptr<AutomationControl> pan_lfe_control;
-
- boost::shared_ptr<Panner> panner() const { return _panner.lock(); }
- void set_panner(boost::shared_ptr<Panner>);
+ boost::shared_ptr<AutomationControl> pan_azimuth_control;
+ boost::shared_ptr<AutomationControl> pan_elevation_control;
+ boost::shared_ptr<AutomationControl> pan_width_control;
+ boost::shared_ptr<AutomationControl> pan_frontback_control;
+ boost::shared_ptr<AutomationControl> pan_lfe_control;
- Session& session() { return _session; }
+ boost::shared_ptr<Panner> panner() const { return _panner.lock(); }
+ void set_panner(boost::shared_ptr<Panner>);
+
+ Session& session() { return _session; }
void set_automation_state (AutoState);
AutoState automation_state() const { return _auto_state; }
return (_auto_state & Play) || ((_auto_state & Touch) && !touching());
}
bool automation_write () const {
- return ((_auto_state & Write) || ((_auto_state & Touch) && touching()));
- }
+ return ((_auto_state & Write) || ((_auto_state & Touch) && touching()));
+ }
- std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
+ std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
void start_touch (double when);
void stop_touch (bool mark, double when);
bool touching() const { return g_atomic_int_get (&_touching); }
bool writing() const { return _auto_state == Write; }
- bool touch_enabled() const { return _auto_state == Touch; }
+ bool touch_enabled() const { return _auto_state == Touch; }
- XMLNode& get_state ();
- XMLNode& state (bool full_state);
- int set_state (const XMLNode&, int version);
+ XMLNode& get_state ();
+ XMLNode& state (bool full_state);
+ int set_state (const XMLNode&, int version);
- bool has_state() const { return _has_state; }
+ bool has_state() const { return _has_state; }
protected:
- boost::weak_ptr<Panner> _panner;
- AutoState _auto_state;
- AutoStyle _auto_style;
- gint _touching;
- bool _has_state;
- uint32_t _responding_to_control_auto_state_change;
+ boost::weak_ptr<Panner> _panner;
+ AutoState _auto_state;
+ AutoStyle _auto_style;
+ gint _touching;
+ bool _has_state;
+ uint32_t _responding_to_control_auto_state_change;
- void control_auto_state_changed (AutoState);
+ void control_auto_state_changed (AutoState);
private:
void value_changed ();
};
-} // namespace
+} // namespace
#endif /* __libardour_pannable_h__ */
class Panner : public PBD::Stateful, public PBD::ScopedConnectionList
{
- public:
+public:
Panner (boost::shared_ptr<Pannable>);
~Panner ();
- virtual boost::shared_ptr<Speakers> get_speakers() const { return boost::shared_ptr<Speakers>(); }
+ virtual boost::shared_ptr<Speakers> get_speakers() const { return boost::shared_ptr<Speakers>(); }
- virtual ChanCount in() const = 0;
- virtual ChanCount out() const = 0;
+ virtual ChanCount in() const = 0;
+ virtual ChanCount out() const = 0;
- virtual void configure_io (ARDOUR::ChanCount /*in*/, ARDOUR::ChanCount /*out*/) {}
-
- /* derived implementations of these methods must indicate
- whether it is legal for a Controllable to use the
- value of the argument (post-call) in a call to
- Controllable::set_value().
-
- they have a choice of:
+ virtual void configure_io (ARDOUR::ChanCount /*in*/, ARDOUR::ChanCount /*out*/) {}
- * return true, leave argument unchanged
- * return true, modify argument
- * return false
+ /* derived implementations of these methods must indicate
+ whether it is legal for a Controllable to use the
+ value of the argument (post-call) in a call to
+ Controllable::set_value().
- */
+ they have a choice of:
- virtual bool clamp_position (double&) { return true; }
- virtual bool clamp_width (double&) { return true; }
- virtual bool clamp_elevation (double&) { return true; }
+ * return true, leave argument unchanged
+ * return true, modify argument
+ * return false
+ */
- virtual void set_position (double) { }
- virtual void set_width (double) { }
- virtual void set_elevation (double) { }
-
- virtual double position () const { return 0.0; }
- virtual double width () const { return 0.0; }
- virtual double elevation () const { return 0.0; }
+ virtual bool clamp_position (double&) { return true; }
+ virtual bool clamp_width (double&) { return true; }
+ virtual bool clamp_elevation (double&) { return true; }
- virtual PBD::AngularVector signal_position (uint32_t) const { return PBD::AngularVector(); }
+ virtual void set_position (double) { }
+ virtual void set_width (double) { }
+ virtual void set_elevation (double) { }
+
+ virtual double position () const { return 0.0; }
+ virtual double width () const { return 0.0; }
+ virtual double elevation () const { return 0.0; }
+
+ virtual PBD::AngularVector signal_position (uint32_t) const { return PBD::AngularVector(); }
+
+ virtual void reset() {}
- virtual void reset() {}
-
virtual bool bypassed() const { return _bypassed; }
virtual void set_bypassed (bool yn);
AutoStyle automation_style() const;
virtual std::set<Evoral::Parameter> what_can_be_automated() const;
- virtual std::string describe_parameter (Evoral::Parameter);
- virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
+ virtual std::string describe_parameter (Evoral::Parameter);
+ virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
bool touching() const;
- static double azimuth_to_lr_fract (double azi) {
+ static double azimuth_to_lr_fract (double azi) {
/* 180.0 degrees=> left => 0.0 */
/* 0.0 degrees => right => 1.0 */
- /* humans can only distinguish 1 degree of arc between two positions,
- so force azi back to an integral value before computing
- */
+ /* humans can only distinguish 1 degree of arc between two positions,
+ so force azi back to an integral value before computing
+ */
return 1.0 - (rint(azi)/180.0);
}
- static double lr_fract_to_azimuth (double fract) {
+ static double lr_fract_to_azimuth (double fract) {
/* fract = 0.0 => degrees = 180.0 => left */
/* fract = 1.0 => degrees = 0.0 => right */
- /* humans can only distinguish 1 degree of arc between two positions,
- so force azi back to an integral value after computing
- */
+ /* humans can only distinguish 1 degree of arc between two positions,
+ so force azi back to an integral value after computing
+ */
return rint (180.0 - (fract * 180.0));
}
-
+
/**
* Pan some input buffers to a number of output buffers.
*
* @param obufs Output buffers (one per panner output).
* @param gain_coeff fixed, additional gain coefficient to apply to output samples.
* @param nframes Number of frames in the input.
- *
- * Derived panners can choose to implement these if they need to gain more control over the panning algorithm.
- * the default is to call distribute_one() or distribute_one_automated() on each input buffer to deliver it to each output
- * buffer.
- *
- * If a panner does not need to override this default behaviour, it can just implement
- * distribute_one() and distribute_one_automated() (below).
+ *
+ * Derived panners can choose to implement these if they need to gain more
+ * control over the panning algorithm. The default is to call
+ * distribute_one() or distribute_one_automated() on each input buffer to
+ * deliver it to each output buffer.
+ *
+ * If a panner does not need to override this default behaviour, it can
+ * just implement distribute_one() and distribute_one_automated() (below).
*/
virtual void distribute (BufferSet& ibufs, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes);
virtual void distribute_automated (BufferSet& ibufs, BufferSet& obufs,
- framepos_t start, framepos_t end, pframes_t nframes,
- pan_t** buffers);
+ framepos_t start, framepos_t end, pframes_t nframes,
+ pan_t** buffers);
PBD::Signal0<void> StateChanged;
int set_state (const XMLNode&, int version);
virtual XMLNode& state (bool full_state) = 0;
- boost::shared_ptr<Pannable> pannable() const { return _pannable; }
+ boost::shared_ptr<Pannable> pannable() const { return _pannable; }
- //virtual std::string describe_parameter (Evoral::Parameter);
- //virtual std::string value_as_string (Evoral::Parameter, double val);
+ //virtual std::string describe_parameter (Evoral::Parameter);
+ //virtual std::string value_as_string (Evoral::Parameter, double val);
static bool equivalent (pan_t a, pan_t b) {
return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner
}
static bool equivalent (const PBD::AngularVector& a, const PBD::AngularVector& b) {
- /* XXX azimuth only, at present */
+ /* XXX azimuth only, at present */
return fabs (a.azi - b.azi) < 1.0;
}
- protected:
- boost::shared_ptr<Pannable> _pannable;
- bool _bypassed;
+protected:
+ boost::shared_ptr<Pannable> _pannable;
+ bool _bypassed;
XMLNode& get_state ();
virtual void distribute_one (AudioBuffer&, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which) = 0;
virtual void distribute_one_automated (AudioBuffer&, BufferSet& obufs,
- framepos_t start, framepos_t end, pframes_t nframes,
- pan_t** buffers, uint32_t which) = 0;
+ framepos_t start, framepos_t end, pframes_t nframes,
+ pan_t** buffers, uint32_t which) = 0;
};
} // namespace
extern "C" {
- struct PanPluginDescriptor {
- std::string name;
- int32_t in;
- int32_t out;
- ARDOUR::Panner* (*factory)(boost::shared_ptr<ARDOUR::Pannable>, boost::shared_ptr<ARDOUR::Speakers>);
- };
+struct PanPluginDescriptor {
+ std::string name;
+ int32_t in;
+ int32_t out;
+ ARDOUR::Panner* (*factory)(boost::shared_ptr<ARDOUR::Pannable>, boost::shared_ptr<ARDOUR::Speakers>);
+};
}
#endif /* __ardour_panner_h__ */
namespace ARDOUR {
struct PannerInfo {
- PanPluginDescriptor descriptor;
- void* module;
-
- PannerInfo (PanPluginDescriptor& d, void* handle)
- : descriptor (d)
- , module (handle)
- {}
-
- ~PannerInfo () {
- dlclose (module);
- }
+ PanPluginDescriptor descriptor;
+ void* module;
+
+ PannerInfo (PanPluginDescriptor& d, void* handle)
+ : descriptor (d)
+ , module (handle)
+ {}
+
+ ~PannerInfo () {
+ dlclose (module);
+ }
};
-
+
class PannerManager : public ARDOUR::SessionHandlePtr
{
- public:
- ~PannerManager ();
- static PannerManager& instance ();
-
- void discover_panners ();
- std::list<PannerInfo*> panner_info;
-
- PannerInfo* select_panner (ChanCount in, ChanCount out);
-
- private:
- PannerManager();
- static PannerManager* _instance;
-
- PannerInfo* get_descriptor (std::string path);
- int panner_discover (std::string path);
+public:
+ ~PannerManager ();
+ static PannerManager& instance ();
+
+ void discover_panners ();
+ std::list<PannerInfo*> panner_info;
+
+ PannerInfo* select_panner (ChanCount in, ChanCount out);
+
+private:
+ PannerManager();
+ static PannerManager* _instance;
+
+ PannerInfo* get_descriptor (std::string path);
+ int panner_discover (std::string path);
};
} // namespace
PBD::Signal0<void> Changed; /* panner and/or outputs count changed */
- boost::shared_ptr<Panner> panner() const { return _panner; }
- boost::shared_ptr<Pannable> pannable() const { return _pannable; }
+ boost::shared_ptr<Panner> panner() const { return _panner; }
+ boost::shared_ptr<Pannable> pannable() const { return _pannable; }
private:
void distribute_no_automation (BufferSet& src, BufferSet& dest, pframes_t nframes, gain_t gain_coeff);
- boost::shared_ptr<Panner> _panner;
- boost::shared_ptr<Pannable> _pannable;
-
+ boost::shared_ptr<Panner> _panner;
+ boost::shared_ptr<Pannable> _pannable;
+
static float current_automation_version_number;
};
/*
Copyright (C) 2008 Torben Hohn
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#include "ardour/types.h"
class PIController {
+public:
+ PIController (double resample_factor, int fir_size);
+ ~PIController();
+
+ void reset (double resample_factor) {
+ resample_mean = resample_factor;
+ static_resample_factor = resample_factor;
+ out_of_bounds ();
+ }
- public:
- PIController (double resample_factor, int fir_size);
- ~PIController();
-
- void reset (double resample_factor) {
- resample_mean = resample_factor;
- static_resample_factor = resample_factor;
- out_of_bounds ();
- }
-
- double get_ratio (int fill_level, int period_size);
- void out_of_bounds();
-
- public:
- double resample_mean;
- double static_resample_factor;
- double* offset_array;
- double* window_array;
- int offset_differential_index;
- double offset_integral;
- double catch_factor;
- double catch_factor2;
- double pclamp;
- double controlquant;
- int smooth_size;
- double smooth_offset;
- double current_resample_factor;
- bool fir_empty;
+ double get_ratio (int fill_level, int period_size);
+ void out_of_bounds();
+
+public:
+ double resample_mean;
+ double static_resample_factor;
+ double* offset_array;
+ double* window_array;
+ int offset_differential_index;
+ double offset_integral;
+ double catch_factor;
+ double catch_factor2;
+ double pclamp;
+ double controlquant;
+ int smooth_size;
+ double smooth_offset;
+ double current_resample_factor;
+ bool fir_empty;
};
#define ESTIMATOR_SIZE 16
class PIChaser {
- public:
- PIChaser();
- ~PIChaser();
+public:
+ PIChaser();
+ ~PIChaser();
- double get_ratio( framepos_t chasetime_measured, framepos_t chasetime, framepos_t slavetime_measured, framepos_t slavetime, bool in_control, int period_size );
- void reset();
- framepos_t want_locate() { return want_locate_val; }
+ double get_ratio( framepos_t chasetime_measured, framepos_t chasetime, framepos_t slavetime_measured, framepos_t slavetime, bool in_control, int period_size );
+ void reset();
+ framepos_t want_locate() { return want_locate_val; }
- private:
- PIController *pic;
- framepos_t realtime_stamps[ESTIMATOR_SIZE];
- framepos_t chasetime_stamps[ESTIMATOR_SIZE];
- int array_index;
- framepos_t want_locate_val;
+private:
+ PIController *pic;
+ framepos_t realtime_stamps[ESTIMATOR_SIZE];
+ framepos_t chasetime_stamps[ESTIMATOR_SIZE];
+ int array_index;
+ framepos_t want_locate_val;
- void feed_estimator( framepos_t realtime, framepos_t chasetime );
- double get_estimate();
+ void feed_estimator( framepos_t realtime, framepos_t chasetime );
+ double get_estimate();
- double speed;
+ double speed;
- double speed_threshold;
- framepos_t pos_threshold;
+ double speed_threshold;
+ framepos_t pos_threshold;
};
-
#endif /* __libardour_pi_controller__ */
class Session;
class Region;
class Playlist;
-class Crossfade;
+class Crossfade;
namespace Properties {
- /* fake the type, since regions are handled by SequenceProperty which doesn't
- care about such things.
- */
- extern PBD::PropertyDescriptor<bool> regions;
+ /* fake the type, since regions are handled by SequenceProperty which doesn't
+ care about such things.
+ */
+ extern PBD::PropertyDescriptor<bool> regions;
}
class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > >
{
public:
- RegionListProperty (Playlist&);
+ RegionListProperty (Playlist&);
RegionListProperty* clone () const;
void get_content_as_xml (boost::shared_ptr<Region>, XMLNode &) const;
/* copy construction only by ourselves */
RegionListProperty (RegionListProperty const & p);
- friend class Playlist;
- /* we live and die with our playlist, no lifetime management needed */
- Playlist& _playlist;
+ friend class Playlist;
+ /* we live and die with our playlist, no lifetime management needed */
+ Playlist& _playlist;
};
class Playlist : public SessionObject , public boost::enable_shared_from_this<Playlist>
{
public:
typedef std::list<boost::shared_ptr<Region> > RegionList;
- static void make_property_quarks ();
+ static void make_property_quarks ();
Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
Playlist (Session&, std::string name, DataType type, bool hidden = false);
virtual ~Playlist ();
- void update (const RegionListProperty::ChangeRecord&);
- void clear_owned_changes ();
- void rdiff (std::vector<Command*>&) const;
+ void update (const RegionListProperty::ChangeRecord&);
+ void clear_owned_changes ();
+ void rdiff (std::vector<Command*>&) const;
boost::shared_ptr<Region> region_by_id (const PBD::ID&) const;
bool used () const { return _refcnt != 0; }
bool set_name (const std::string& str);
- int sort_id() { return _sort_id; }
+ int sort_id() { return _sort_id; }
const DataType& data_type() const { return _type; }
const RegionListProperty& region_list () const { return regions; }
RegionList* regions_at (framepos_t frame);
- uint32_t count_regions_at (framepos_t) const;
+ uint32_t count_regions_at (framepos_t) const;
uint32_t count_joined_regions () const;
RegionList* regions_touched (framepos_t start, framepos_t end);
RegionList* regions_to_read (framepos_t start, framepos_t end);
bool region_is_shuffle_constrained (boost::shared_ptr<Region>);
bool has_region_at (framepos_t const) const;
- bool uses_source (boost::shared_ptr<const Source> src) const;
+ bool uses_source (boost::shared_ptr<const Source> src) const;
framepos_t find_next_transient (framepos_t position, int dir);
virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
- void sync_all_regions_with_regions ();
+ void sync_all_regions_with_regions ();
/* special case function used by UI selection objects, which have playlists that actually own the regions
within them.
return boost::shared_ptr<Crossfade> ();
}
- framepos_t find_next_top_layer_position (framepos_t) const;
+ framepos_t find_next_top_layer_position (framepos_t) const;
uint32_t combine_ops() const { return _combine_ops; }
protected:
friend class RegionLock;
- RegionListProperty regions; /* the current list of regions in the playlist */
+ RegionListProperty regions; /* the current list of regions in the playlist */
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;
+ int _sort_id;
mutable gint block_notifications;
mutable gint ignore_state_changes;
mutable Glib::RecMutex region_lock;
virtual void flush_notifications (bool from_undo = false);
void clear_pending ();
- void _set_sort_id ();
+ void _set_sort_id ();
void notify_region_removed (boost::shared_ptr<Region>);
void notify_region_added (boost::shared_ptr<Region>);
class Playlist;
class PlaylistSource : virtual public Source {
- public:
- virtual ~PlaylistSource ();
-
- int set_state (const XMLNode&, int version);
- boost::shared_ptr<const Playlist> playlist() const { return _playlist; }
- const PBD::ID& original() const { return _original; }
-
- protected:
- boost::shared_ptr<Playlist> _playlist;
- PBD::ID _original;
- frameoffset_t _playlist_offset;
- framecnt_t _playlist_length;
-
- PlaylistSource (Session&, const PBD::ID&, const std::string& name, boost::shared_ptr<Playlist>, DataType,
- frameoffset_t begin, framecnt_t len, Source::Flag flags);
- PlaylistSource (Session&, const XMLNode&);
-
- void add_state (XMLNode&);
+public:
+ virtual ~PlaylistSource ();
+
+ int set_state (const XMLNode&, int version);
+ boost::shared_ptr<const Playlist> playlist() const { return _playlist; }
+ const PBD::ID& original() const { return _original; }
+
+protected:
+ boost::shared_ptr<Playlist> _playlist;
+ PBD::ID _original;
+ frameoffset_t _playlist_offset;
+ framecnt_t _playlist_length;
+
+ PlaylistSource (Session&, const PBD::ID&, const std::string& name, boost::shared_ptr<Playlist>, DataType,
+ frameoffset_t begin, framecnt_t len, Source::Flag flags);
+ PlaylistSource (Session&, const XMLNode&);
+
+ void add_state (XMLNode&);
};
-
+
} /* namespace */
#endif /* __ardour_playlist_source_h__ */
virtual uint32_t nth_parameter (uint32_t which, bool& ok) const = 0;
virtual void activate () = 0;
virtual void deactivate () = 0;
- virtual void flush () { deactivate(); activate(); }
+ virtual void flush () { deactivate(); activate(); }
virtual int set_block_size (pframes_t nframes) = 0;
bool operator!= (PresetRecord const & a) const {
return uri != a.uri || label != a.label;
}
-
+
std::string uri;
std::string label;
bool user;
void remove_preset (std::string);
virtual bool load_preset (PresetRecord);
-
+
const PresetRecord * preset_by_label (const std::string &);
const PresetRecord * preset_by_uri (const std::string &);
PresetRecord last_preset () const {
return _last_preset;
}
-
+
bool parameter_changed_since_last_preset () const {
return _parameter_changed_since_last_preset;
}
-
+
virtual int first_user_preset_index () const {
return 0;
}
-
+
/** Emitted when a preset is added or removed, respectively */
PBD::Signal0<void> PresetAdded;
PBD::Signal0<void> PresetRemoved;
cycles_t cycles() const { return _cycles; }
protected:
-
+
friend class PluginInsert;
friend struct PluginInsert::PluginControl;
private:
double user_to_plugin (double) const;
-
+
PluginInsert* _plugin;
bool _logarithmic;
bool _sr_dependent;
virtual ~Port ();
- static void set_connecting_blocked( bool yn ) {
+ static void set_connecting_blocked( bool yn ) {
_connecting_blocked = yn;
}
- static bool connecting_blocked() {
+ static bool connecting_blocked() {
return _connecting_blocked;
}
int reestablish ();
int reconnect ();
void request_monitor_input (bool);
-
- bool last_monitor() const { return _last_monitor; }
- void set_last_monitor (bool yn) { _last_monitor = yn; }
- jack_port_t* jack_port() const { return _jack_port; }
-
- void get_connected_latency_range (jack_latency_range_t& range, bool playback) const;
+ bool last_monitor() const { return _last_monitor; }
+ void set_last_monitor (bool yn) { _last_monitor = yn; }
- void set_private_latency_range (jack_latency_range_t& range, bool playback);
- const jack_latency_range_t& private_latency_range (bool playback) const;
+ jack_port_t* jack_port() const { return _jack_port; }
- void set_public_latency_range (jack_latency_range_t& range, bool playback) const;
- jack_latency_range_t public_latency_range (bool playback) const;
+ void get_connected_latency_range (jack_latency_range_t& range, bool playback) const;
+
+ void set_private_latency_range (jack_latency_range_t& range, bool playback);
+ const jack_latency_range_t& private_latency_range (bool playback) const;
+
+ void set_public_latency_range (jack_latency_range_t& range, bool playback) const;
+ jack_latency_range_t public_latency_range (bool playback) const;
virtual void reset ();
virtual void transport_stopped () {}
virtual void realtime_locate () {}
- bool physically_connected () const;
+ bool physically_connected () const;
static void set_engine (AudioEngine *);
PBD::Signal1<void,bool> MonitorInputChanged;
- static void set_cycle_framecnt (pframes_t n) {
- _cycle_nframes = n;
- }
+ static void set_cycle_framecnt (pframes_t n) {
+ _cycle_nframes = n;
+ }
static framecnt_t port_offset() { return _global_port_buffer_offset; }
static void set_global_port_buffer_offset (pframes_t off) {
_global_port_buffer_offset = off;
_global_port_buffer_offset += n;
}
- virtual void increment_port_buffer_offset (pframes_t n);
+ virtual void increment_port_buffer_offset (pframes_t n);
protected:
static bool _connecting_blocked;
static pframes_t _global_port_buffer_offset; /* access only from process() tree */
- static pframes_t _cycle_nframes; /* access only from process() tree */
+ static pframes_t _cycle_nframes; /* access only from process() tree */
+
+ framecnt_t _port_buffer_offset; /* access only from process() tree */
- framecnt_t _port_buffer_offset; /* access only from process() tree */
+ jack_latency_range_t _private_playback_latency;
+ jack_latency_range_t _private_capture_latency;
- jack_latency_range_t _private_playback_latency;
- jack_latency_range_t _private_capture_latency;
-
static AudioEngine* _engine; ///< the AudioEngine
private:
bool _last_monitor;
/** ports that we are connected to, kept so that we can
- reconnect to JACK when required
- */
+ reconnect to JACK when required
+ */
std::set<std::string> _connections;
};
uint32_t bit_slot() const { return bitslot; }
- void start_latency_detection ();
- void stop_latency_detection ();
+ void start_latency_detection ();
+ void stop_latency_detection ();
- MTDM* mtdm () const { return _mtdm; }
- void set_measured_latency (framecnt_t);
- framecnt_t latency () const;
+ MTDM* mtdm () const { return _mtdm; }
+ void set_measured_latency (framecnt_t);
+ framecnt_t latency () const;
private:
/* disallow copy construction */
boost::shared_ptr<Delivery> _out;
uint32_t bitslot;
- MTDM* _mtdm;
- bool _latency_detect;
- framecnt_t _latency_flush_frames;
- framecnt_t _measured_latency;
+ MTDM* _mtdm;
+ bool _latency_detect;
+ framecnt_t _latency_flush_frames;
+ framecnt_t _measured_latency;
};
} // namespace ARDOUR
class ProcessThread
{
- public:
- ProcessThread ();
- ~ProcessThread ();
+public:
+ ProcessThread ();
+ ~ProcessThread ();
- static void init();
+ static void init();
- void get_buffers ();
- void drop_buffers ();
+ void get_buffers ();
+ void drop_buffers ();
- /* these MUST be called by a process thread's thread, nothing else
- */
+ /* these MUST be called by a process thread's thread, nothing else
+ */
- static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
- static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
- static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
- static gain_t* gain_automation_buffer ();
- static pan_t** pan_automation_buffer ();
+ static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+ static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
+ static gain_t* gain_automation_buffer ();
+ static pan_t** pan_automation_buffer ();
- protected:
- void session_going_away ();
+protected:
+ void session_going_away ();
- private:
- Glib::Thread* _thread;
+private:
+ Glib::Thread* _thread;
- static Glib::Private<ThreadBuffers>* _private_thread_buffers;
+ static Glib::Private<ThreadBuffers>* _private_thread_buffers;
};
} // namespace
static const std::string state_node_name;
Processor(Session&, const std::string& name);
- Processor (const Processor& other);
+ Processor (const Processor& other);
virtual ~Processor() { }
virtual framecnt_t signal_latency() const { return 0; }
virtual int set_block_size (pframes_t /*nframes*/) { return 0; }
- virtual bool requires_fixed_sized_buffers() const { return false; }
+ virtual bool requires_fixed_sized_buffers() const { return false; }
/** @param result_required true if, on return from this method, @a bufs is required to contain valid data;
* if false, the method need not bother writing to @a bufs if it doesn't want to.
- */
+ */
virtual void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t /*nframes*/, bool /*result_required*/) {}
virtual void silence (framecnt_t /*nframes*/) {}
virtual void activate () { _pending_active = true; ActiveChanged(); }
virtual void deactivate () { _pending_active = false; ActiveChanged(); }
- virtual void flush() {}
+ virtual void flush() {}
virtual bool configure_io (ChanCount in, ChanCount out);
virtual XMLNode& state (bool full);
XMLNode& get_state (void);
int set_state (const XMLNode&, int version);
-
+
void set_pre_fader (bool);
PBD::Signal0<void> ActiveChanged;
PBD::Signal2<void,ChanCount,ChanCount> ConfigurationChanged;
-
- void set_ui (void*);
- void* get_ui () const { return _ui_pointer; }
+
+ void set_ui (void*);
+ void* get_ui () const { return _ui_pointer; }
protected:
virtual int set_state_2X (const XMLNode&, int version);
-
+
int _pending_active;
bool _active;
bool _next_ab_is_active;
ChanCount _configured_output;
bool _display_to_user;
bool _pre_fader; ///< true if this processor is currently placed before the Amp, otherwise false
- void* _ui_pointer;
+ void* _ui_pointer;
};
} // namespace ARDOUR
namespace ARDOUR {
-/** A class to handle reporting of progress of something */
+/** A class to handle reporting of progress of something */
class Progress
{
public:
void descend (float);
bool cancelled () const;
-
+
protected:
void cancel ();
struct Level {
Level (float a) : allocation (a), normalised (0) {}
-
+
float allocation;
float normalised;
};
, _setter (setter)
, _getter (getter)
{}
-
+
void set_value (double v) { _setter (v); }
double get_value () const { return _getter (); }
-
+
private:
boost::function1<void,double> _setter;
boost::function0<double> _getter;
};
-
+
} // namespace
#endif /* __libardour_proxy_controllable_h__ */
class Source;
class Location;
-/** Public interface to a Diskstream */
+/** Public interface to a Diskstream */
class PublicDiskstream
{
public:
virtual void transport_stopped_wallclock (struct tm &, time_t, bool) = 0;
virtual bool pending_overwrite () const = 0;
virtual double speed () const = 0;
- virtual void prepare_to_stop (framepos_t) = 0;
+ virtual void prepare_to_stop (framepos_t) = 0;
virtual void set_slaved (bool) = 0;
virtual ChanCount n_channels () = 0;
virtual framepos_t get_capture_start_frame (uint32_t n = 0) const = 0;
virtual void set_align_choice (AlignChoice, bool force=false) = 0;
virtual int use_copy_playlist () = 0;
virtual int use_new_playlist () = 0;
- virtual void adjust_playback_buffering () = 0;
- virtual void adjust_capture_buffering () = 0;
-
+ virtual void adjust_playback_buffering () = 0;
+ virtual void adjust_capture_buffering () = 0;
};
}
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
#define CONFIG_VARIABLE(Type,var,name,value) \
- Type get_##var () const { return var.get(); } \
- bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \
- Type get_##var () const { return var.get(); } \
- bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
#include "ardour/rc_configuration_vars.h"
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
class Playlist;
class Filter;
class ExportSpecification;
-class Progress;
+class Progress;
enum RegionEditState {
EditChangesNothing = 0,
typedef std::vector<boost::shared_ptr<Source> > SourceList;
static void make_property_quarks ();
-
+
static PBD::Signal2<void,boost::shared_ptr<ARDOUR::Region>, const PBD::PropertyChange&> RegionPropertyChanged;
virtual ~Region();
-
+
/** Note: changing the name of a Region does not constitute an edit */
bool set_name (const std::string& str);
const DataType& data_type () const { return _type; }
-
+
AnalysisFeatureList transients () { return _transients; };
/** How the region parameters play together:
- *
+ *
* POSITION: first frame of the region along the timeline
* START: first frame of the region within its source(s)
* LENGTH: number of frames the region represents
framepos_t ancestral_start () const { return _ancestral_start; }
framecnt_t ancestral_length () const { return _ancestral_length; }
-
+
float stretch () const { return _stretch; }
float shift () const { return _shift; }
frameoffset_t sync_offset (int& dir) const;
framepos_t sync_position () const;
framepos_t sync_point () const;
-
+
framepos_t adjust_to_sync (framepos_t) const;
/* first_frame() is an alias; last_frame() just hides some math */
bool sync_marked () const { return _sync_marked; }
bool external () const { return _external; }
bool import () const { return _import; }
-
- Trimmable::CanTrim can_trim () const;
+
+ Trimmable::CanTrim can_trim () const;
PositionLockStyle position_lock_style () const { return _position_lock_style; }
-
+
void set_position_lock_style (PositionLockStyle ps);
void recompute_position_from_lock_style ();
bool source_equivalent (boost::shared_ptr<const Region>) const;
bool uses_source (boost::shared_ptr<const Source>) const;
bool uses_source_path (const std::string&) const;
-
+
std::string source_string () const;
/** Construct a region from another region, at an offset within that region */
Region (boost::shared_ptr<const Region>, frameoffset_t start_offset);
-
+
/** Construct a region as a copy of another region, but with different sources */
Region (boost::shared_ptr<const Region>, const SourceList&);
virtual void recompute_at_start () = 0;
virtual void recompute_at_end () = 0;
-
+
DataType _type;
PBD::Property<bool> _muted;
mutable RegionEditState _first_edit;
Timecode::BBT_Time _bbt_time;
AnalysisFeatureList _transients;
-
+
mutable uint64_t _read_data_count; ///< modified in read()
uint64_t _last_layer_op; ///< timestamp
SourceList _sources;
static boost::shared_ptr<Region> create (boost::shared_ptr<const Region> other, bool announce = false);
/** create a region from a single Source */
- static boost::shared_ptr<Region> create (boost::shared_ptr<Source>,
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Source>,
const PBD::PropertyList&, bool announce = true);
-
+
/** create a region from a multiple sources */
- static boost::shared_ptr<Region> create (const SourceList &,
+ static boost::shared_ptr<Region> create (const SourceList &,
const PBD::PropertyList&, bool announce = true);
/** create a copy of @other starting at zero within @param other's sources */
- static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other,
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other,
const PBD::PropertyList&, bool announce = true);
/** create a copy of @param other starting at @param offset within @param other */
- static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, frameoffset_t offset,
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, frameoffset_t offset,
const PBD::PropertyList&, bool announce = true);
/** create a "copy" of @param other but using a different set of sources @param srcs */
- static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs,
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs,
const PBD::PropertyList&, bool announce = true);
-
+
/** create a region with no sources, using XML state */
static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
/** create a region with specified sources @param srcs and XML state */
static int region_name (std::string &, std::string, bool new_level = false);
static std::string new_region_name (std::string);
static std::string compound_region_name (const std::string& playlist, uint32_t compound_ops, uint32_t depth, bool whole_source);
-
+
/* when we make a compound region, for every region involved there
* are two "instances" - the original, which is removed from this
- * playlist, and a copy, which is added to the playlist used as
+ * playlist, and a copy, which is added to the playlist used as
* the source for the compound.
*
* when we uncombine, we want to put the originals back into this
static CompoundAssociations& compound_associations() { return _compound_associations; }
static void add_compound_association (boost::shared_ptr<Region>, boost::shared_ptr<Region>);
-
+
private:
static void region_changed (PBD::PropertyChange const &, boost::weak_ptr<Region>);
-
+
static Glib::StaticMutex region_map_lock;
-
+
static RegionMap region_map;
static void map_add (boost::shared_ptr<Region>);
namespace ARDOUR {
struct RegionSortByPosition {
- bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
- return a->position() < b->position();
- }
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
+ return a->position() < b->position();
+ }
};
struct RegionSortByLastLayerOp {
- bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
- return a->last_layer_op() < b->last_layer_op();
- }
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
+ return a->last_layer_op() < b->last_layer_op();
+ }
};
struct RegionSortByLayer {
- bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
- return a->layer() < b->layer();
- }
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
+ return a->layer() < b->layer();
+ }
};
struct RegionSortByLayerWithPending {
}
};
-} // namespace
+} // namespace
#endif /* __libardour_region_sorters_h__ */
private:
boost::shared_ptr<ImportableSource> source;
- float* input;
+ float* input;
int _src_type;
SRC_STATE* src_state;
SRC_DATA src_data;
/* these are the core of the API of a Route. see the protected sections as well */
virtual int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
+ int declick, bool can_record, bool rec_monitors_input, bool& need_butler);
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool state_changing, bool can_record, bool rec_monitors_input);
+ bool state_changing, bool can_record, bool rec_monitors_input);
virtual int silent_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool rec_monitors_input, bool& need_butler);
+ bool can_record, bool rec_monitors_input, bool& need_butler);
virtual void toggle_monitor_input ();
virtual bool can_record() { return false; }
void set_solo (bool yn, void *src);
bool soloed () const { return self_soloed () || soloed_by_others (); }
- bool soloed_by_others () const { return _soloed_by_others_upstream||_soloed_by_others_downstream; }
+ bool soloed_by_others () const { return _soloed_by_others_upstream||_soloed_by_others_downstream; }
bool soloed_by_others_upstream () const { return _soloed_by_others_upstream; }
bool soloed_by_others_downstream () const { return _soloed_by_others_downstream; }
bool self_soloed () const { return _self_solo; }
-
+
void set_solo_isolated (bool yn, void *src);
bool solo_isolated() const;
bool processor_is_prefader (boost::shared_ptr<Processor> p);
- bool has_io_processor_named (const std::string&);
+ bool has_io_processor_named (const std::string&);
ChanCount max_processor_streams () const { return processor_max_streams; }
std::list<std::string> unknown_processors () const;
-
+
/* special processors */
boost::shared_ptr<Delivery> monitor_send() const { return _monitor_send; }
void all_processors_flip();
void all_processors_active (Placement, bool state);
- framecnt_t set_private_port_latencies (bool playback) const;
- void set_public_port_latencies (framecnt_t, bool playback) const;
+ framecnt_t set_private_port_latencies (bool playback) const;
+ void set_public_port_latencies (framecnt_t, bool playback) const;
framecnt_t update_signal_latency();
virtual void set_latency_compensation (framecnt_t);
void set_user_latency (framecnt_t);
framecnt_t initial_delay() const { return _initial_delay; }
- framecnt_t signal_latency() const { return _signal_latency; }
+ framecnt_t signal_latency() const { return _signal_latency; }
PBD::Signal0<void> active_changed;
PBD::Signal0<void> phase_invert_changed;
PBD::Signal1<void,RouteProcessorChange> processors_changed;
PBD::Signal1<void,void*> record_enable_changed;
/** the metering point has changed */
- PBD::Signal0<void> meter_change;
+ PBD::Signal0<void> meter_change;
PBD::Signal0<void> signal_latency_changed;
PBD::Signal0<void> initial_delay_changed;
PBD::Signal0<void> order_key_changed;
int listen_via (boost::shared_ptr<Route>, Placement p);
void drop_listen (boost::shared_ptr<Route>);
- /**
- * return true if this route feeds the first argument via at least one
- * (arbitrarily long) signal pathway.
- */
- bool feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
+ /**
+ * return true if this route feeds the first argument via at least one
+ * (arbitrarily long) signal pathway.
+ */
+ bool feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
- /**
- * return true if this route feeds the first argument directly, via
- * either its main outs or a send.
- */
+ /**
+ * return true if this route feeds the first argument directly, via
+ * either its main outs or a send.
+ */
bool direct_feeds (boost::shared_ptr<Route>, bool* via_send_only = 0);
- struct FeedRecord {
- boost::weak_ptr<Route> r;
- bool sends_only;
+ struct FeedRecord {
+ boost::weak_ptr<Route> r;
+ bool sends_only;
- FeedRecord (boost::shared_ptr<Route> rp, bool sendsonly)
- : r (rp)
- , sends_only (sendsonly) {}
- };
+ FeedRecord (boost::shared_ptr<Route> rp, bool sendsonly)
+ : r (rp)
+ , sends_only (sendsonly) {}
+ };
- struct FeedRecordCompare {
- bool operator() (const FeedRecord& a, const FeedRecord& b) const {
- return a.r < b.r;
- }
- };
+ struct FeedRecordCompare {
+ bool operator() (const FeedRecord& a, const FeedRecord& b) const {
+ return a.r < b.r;
+ }
+ };
- typedef std::set<FeedRecord,FeedRecordCompare> FedBy;
+ typedef std::set<FeedRecord,FeedRecordCompare> FedBy;
- const FedBy& fed_by() const { return _fed_by; }
- void clear_fed_by ();
- bool add_fed_by (boost::shared_ptr<Route>, bool sends_only);
- bool not_fed() const { return _fed_by.empty(); }
+ const FedBy& fed_by() const { return _fed_by; }
+ void clear_fed_by ();
+ bool add_fed_by (boost::shared_ptr<Route>, bool sends_only);
+ bool not_fed() const { return _fed_by.empty(); }
/* Controls (not all directly owned by the Route */
void set_value (double);
double get_value () const;
- private:
+ private:
boost::weak_ptr<Route> _route;
};
boost::shared_ptr<Panner> panner() const; /* may return null */
boost::shared_ptr<PannerShell> panner_shell() const;
boost::shared_ptr<AutomationControl> gain_control() const;
- boost::shared_ptr<Pannable> pannable() const;
+ boost::shared_ptr<Pannable> pannable() const;
void automation_snapshot (framepos_t now, bool force=false);
void protect_automation ();
framecnt_t /* nframes */) {}
virtual void process_output_buffers (BufferSet& bufs,
- framepos_t start_frame, framepos_t end_frame,
- pframes_t nframes, bool with_processors, int declick,
- bool gain_automation_ok);
+ framepos_t start_frame, framepos_t end_frame,
+ pframes_t nframes, bool with_processors, int declick,
+ bool gain_automation_ok);
boost::shared_ptr<IO> _input;
boost::shared_ptr<IO> _output;
bool _active;
- framecnt_t _signal_latency;
+ framecnt_t _signal_latency;
framecnt_t _initial_delay;
framecnt_t _roll_delay;
boost::shared_ptr<Delivery> _monitor_send;
boost::shared_ptr<InternalReturn> _intreturn;
boost::shared_ptr<MonitorProcessor> _monitor_control;
- boost::shared_ptr<Pannable> _pannable;
+ boost::shared_ptr<Pannable> _pannable;
Flag _flags;
int _pending_declick;
boost::shared_ptr<SoloControllable> _solo_control;
boost::shared_ptr<MuteControllable> _mute_control;
boost::shared_ptr<MuteMaster> _mute_master;
-
+
std::string _comment;
bool _have_internal_generator;
bool _solo_safe;
DataType _default_type;
- FedBy _fed_by;
+ FedBy _fed_by;
- virtual ChanCount input_streams () const;
+ virtual ChanCount input_streams () const;
protected:
virtual XMLNode& state(bool);
uint32_t pans_required() const;
ChanCount n_process_buffers ();
- virtual bool should_monitor () const;
- virtual void maybe_declick (BufferSet&, framecnt_t, int);
+ virtual bool should_monitor () const;
+ virtual void maybe_declick (BufferSet&, framecnt_t, int);
virtual int _set_state (const XMLNode&, int, bool call_base);
void set_mute_master_solo ();
void set_processor_positions ();
- framecnt_t update_port_latencies (PortSet& ports, PortSet& feeders, bool playback, framecnt_t) const;
+ framecnt_t update_port_latencies (PortSet& ports, PortSet& feeders, bool playback, framecnt_t) const;
void setup_invisible_processors ();
class AudioTrack;
class Session;
-class RouteGroup : public SessionObject
+class RouteGroup : public SessionObject
{
public:
static void make_property_quarks();
-
+
RouteGroup (Session& s, const std::string &n);
~RouteGroup ();
PBD::Signal0<void> MembershipChanged;
XMLNode& get_state ();
-
+
int set_state (const XMLNode&, int version);
-
+
private:
boost::shared_ptr<RouteList> routes;
boost::shared_ptr<Route> subgroup_bus;
class RouteGroup;
-class RouteGroupMember
+class RouteGroupMember
{
public:
RouteGroupMember () : _route_group (0) {}
void refresh_disk_space ();
int load_diskstreams_2X (XMLNode const &, int);
-
+
int load_routes (const XMLNode&, int);
boost::shared_ptr<RouteList> get_routes() const {
return routes.reader ();
* - engine halted
*/
PBD::Signal0<void> TransportStateChange;
-
+
PBD::Signal1<void,framepos_t> PositionChanged; /* sent after any non-sequential motion */
PBD::Signal1<void,framepos_t> Xrun;
PBD::Signal0<void> TransportLooped;
framecnt_t worst_track_latency () const { return _worst_track_latency; }
framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; }
-#ifdef HAVE_JACK_SESSION
+#ifdef HAVE_JACK_SESSION
void jack_session_event (jack_session_event_t* event);
#endif
int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
void timecode_duration_string (char *, framecnt_t) const;
framecnt_t convert_to_frames (AnyTime const & position);
- framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration);
+ framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration);
static PBD::Signal1<void, framepos_t> StartTimeChanged;
static PBD::Signal1<void, framepos_t> EndTimeChanged;
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
size_t, std::string const &, uint32_t, bool destructive);
-
+
boost::shared_ptr<MidiSource> create_midi_source_for_session (
Track*, std::string const &);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
PBD::Signal0<void> IsolatedChanged;
-
+
/* control/master out */
boost::shared_ptr<Route> monitor_out() const { return _monitor_out; }
/* Speakers */
- boost::shared_ptr<Speakers> get_speakers ();
+ boost::shared_ptr<Speakers> get_speakers ();
/* Controllables */
void add_controllable (boost::shared_ptr<PBD::Controllable>);
void remove_controllable (PBD::Controllable*);
- boost::shared_ptr<PBD::Controllable> solo_cut_control() const;
+ boost::shared_ptr<PBD::Controllable> solo_cut_control() const;
SessionMetadata & metadata () { return *_metadata; }
Waiting,
Running
};
-
+
SlaveState slave_state() const { return _slave_state; }
boost::shared_ptr<SessionPlaylists> playlists;
bool _silent;
void maybe_update_session_range (framepos_t, framepos_t);
-
+
// varispeed playback
double _transport_speed;
double _last_transport_speed;
void set_worst_io_latencies_x (IOChange, void *) {
set_worst_io_latencies ();
}
- void post_capture_latency ();
- void post_playback_latency ();
+ void post_capture_latency ();
+ void post_playback_latency ();
void update_latency_compensation_proxy (void* ignored);
bool find_route_name (std::string const &, uint32_t& id, char* name, size_t name_len, bool);
void count_existing_track_channels (ChanCount& in, ChanCount& out);
void auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
- bool with_lock, bool connect_inputs = true,
- ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ());
- void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
+ bool with_lock, bool connect_inputs = true,
+ ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ());
+ void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
/* mixer stuff */
mutable Glib::Mutex source_lock;
- public:
+ public:
typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
- private:
+ private:
SourceMap sources;
public:
void reset_jack_connection (jack_client_t* jack);
void process_rtop (SessionEvent*);
- void update_latency (bool playback);
+ void update_latency (bool playback);
XMLNode& state(bool);
Glib::Mutex controllables_lock;
Controllables controllables;
- boost::shared_ptr<PBD::Controllable> _solo_cut_control;
+ boost::shared_ptr<PBD::Controllable> _solo_cut_control;
void reset_native_file_format();
bool first_file_data_format_reset;
/* realtime "apply to set of routes" operations */
SessionEvent* get_rt_event (
boost::shared_ptr<RouteList> rl, bool yn,
- SessionEvent::RTeventCallback after, bool group_override,
+ SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void start_time_changed (framepos_t);
void end_time_changed (framepos_t);
- void set_track_monitor_input_status (bool);
+ void set_track_monitor_input_status (bool);
framepos_t compute_stop_limit () const;
- boost::shared_ptr<Speakers> _speakers;
+ boost::shared_ptr<Speakers> _speakers;
void load_nested_sources (const XMLNode& node);
};
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
#define CONFIG_VARIABLE(Type,var,name,value) \
- Type get_##var () const { return var.get(); } \
- bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \
- Type get_##var () const { return var.get(); } \
- bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val); if (ret) { ParameterChanged (name); } return ret; }
#include "ardour/session_configuration_vars.h"
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
class Region;
struct SessionEvent {
- enum Type {
- SetTransportSpeed,
- SetTrackSpeed,
- Locate,
- LocateRoll,
- LocateRollLocate,
- SetLoop,
- PunchIn,
- PunchOut,
- RangeStop,
- RangeLocate,
- Overwrite,
- SetSyncSource,
- Audition,
- InputConfigurationChange,
- SetPlayAudioRange,
- RealTimeOperation,
- AdjustPlaybackBuffering,
- AdjustCaptureBuffering,
- SetTimecodeTransmission,
-
- /* only one of each of these events can be queued at any one time */
-
- StopOnce,
- AutoLoop
- };
-
- enum Action {
- Add,
- Remove,
- Replace,
- Clear
- };
-
- Type type;
- Action action;
- framepos_t action_frame;
- framepos_t target_frame;
- double speed;
-
- union {
- void* ptr;
- bool yes_or_no;
- framepos_t target2_frame;
- Slave* slave;
- Route* route;
- };
-
- union {
- bool second_yes_or_no;
- };
-
- /* 4 members to handle a multi-group event handled in RT context */
-
- typedef boost::function<void (SessionEvent*)> RTeventCallback;
-
- boost::shared_ptr<RouteList> routes; /* apply to */
- boost::function<void (void)> rt_slot; /* what to call in RT context */
- RTeventCallback rt_return; /* called after rt_slot, with this event as an argument */
- PBD::EventLoop* event_loop;
-
- std::list<AudioRange> audio_range;
- std::list<MusicRange> music_range;
-
- boost::shared_ptr<Region> region;
-
- SessionEvent (Type t, Action a, framepos_t when, framepos_t where, double spd, bool yn = false, bool yn2 = false)
- : type (t)
- , action (a)
- , action_frame (when)
- , target_frame (where)
- , speed (spd)
- , yes_or_no (yn)
- , second_yes_or_no (yn2)
- , event_loop (0) {}
-
- void set_ptr (void* p) {
- ptr = p;
- }
-
- bool before (const SessionEvent& other) const {
- return action_frame < other.action_frame;
- }
-
- bool after (const SessionEvent& other) const {
- return action_frame > other.action_frame;
- }
-
- static bool compare (const SessionEvent *e1, const SessionEvent *e2) {
- return e1->before (*e2);
- }
-
- void* operator new (size_t);
- void operator delete (void *ptr, size_t /*size*/);
-
- static const framepos_t Immediate = 0;
-
- static void create_per_thread_pool (const std::string& n, uint32_t nitems);
- static void init_event_pool ();
+ enum Type {
+ SetTransportSpeed,
+ SetTrackSpeed,
+ Locate,
+ LocateRoll,
+ LocateRollLocate,
+ SetLoop,
+ PunchIn,
+ PunchOut,
+ RangeStop,
+ RangeLocate,
+ Overwrite,
+ SetSyncSource,
+ Audition,
+ InputConfigurationChange,
+ SetPlayAudioRange,
+ RealTimeOperation,
+ AdjustPlaybackBuffering,
+ AdjustCaptureBuffering,
+ SetTimecodeTransmission,
+
+ /* only one of each of these events can be queued at any one time */
+
+ StopOnce,
+ AutoLoop
+ };
+
+ enum Action {
+ Add,
+ Remove,
+ Replace,
+ Clear
+ };
+
+ Type type;
+ Action action;
+ framepos_t action_frame;
+ framepos_t target_frame;
+ double speed;
+
+ union {
+ void* ptr;
+ bool yes_or_no;
+ framepos_t target2_frame;
+ Slave* slave;
+ Route* route;
+ };
+
+ union {
+ bool second_yes_or_no;
+ };
+
+ /* 4 members to handle a multi-group event handled in RT context */
+
+ typedef boost::function<void (SessionEvent*)> RTeventCallback;
+
+ boost::shared_ptr<RouteList> routes; /* apply to */
+ boost::function<void (void)> rt_slot; /* what to call in RT context */
+ RTeventCallback rt_return; /* called after rt_slot, with this event as an argument */
+ PBD::EventLoop* event_loop;
+
+ std::list<AudioRange> audio_range;
+ std::list<MusicRange> music_range;
+
+ boost::shared_ptr<Region> region;
+
+ SessionEvent (Type t, Action a, framepos_t when, framepos_t where, double spd, bool yn = false, bool yn2 = false)
+ : type (t)
+ , action (a)
+ , action_frame (when)
+ , target_frame (where)
+ , speed (spd)
+ , yes_or_no (yn)
+ , second_yes_or_no (yn2)
+ , event_loop (0) {}
+
+ void set_ptr (void* p) {
+ ptr = p;
+ }
+
+ bool before (const SessionEvent& other) const {
+ return action_frame < other.action_frame;
+ }
+
+ bool after (const SessionEvent& other) const {
+ return action_frame > other.action_frame;
+ }
+
+ static bool compare (const SessionEvent *e1, const SessionEvent *e2) {
+ return e1->before (*e2);
+ }
+
+ void* operator new (size_t);
+ void operator delete (void *ptr, size_t /*size*/);
+
+ static const framepos_t Immediate = 0;
+
+ static void create_per_thread_pool (const std::string& n, uint32_t nitems);
+ static void init_event_pool ();
private:
- static PerThreadPool* pool;
- CrossThreadPool* own_pool;
+ static PerThreadPool* pool;
+ CrossThreadPool* own_pool;
- friend class Butler;
+ friend class Butler;
};
class SessionEventManager {
public:
SessionEventManager () : pending_events (2048),
- auto_loop_event(0), punch_out_event(0), punch_in_event(0) {}
+ auto_loop_event(0), punch_out_event(0), punch_in_event(0) {}
virtual ~SessionEventManager() {}
virtual void queue_event (SessionEvent *ev) = 0;
{
add_property (_name);
}
-
+
Session& session() const { return _session; }
std::string name() const { return _name; }
class XMLNode;
namespace PBD {
- class ID;
+ class ID;
}
namespace ARDOUR {
class Region;
class Source;
class Session;
-class Crossfade;
-
+class Crossfade;
+
class SessionPlaylists : public PBD::ScopedConnectionList
{
public:
~SessionPlaylists ();
-
+
boost::shared_ptr<Playlist> by_name (std::string name);
boost::shared_ptr<Playlist> by_id (const PBD::ID&);
uint32_t source_use_count (boost::shared_ptr<const Source> src) const;
- uint32_t region_use_count (boost::shared_ptr<Region> region) const;
+ uint32_t region_use_count (boost::shared_ptr<Region> region) const;
template<class T> void foreach (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
void get (std::vector<boost::shared_ptr<Playlist> >&);
void unassigned (std::list<boost::shared_ptr<Playlist> > & list);
- void destroy_region (boost::shared_ptr<Region>);
+ void destroy_region (boost::shared_ptr<Region>);
boost::shared_ptr<Crossfade> find_crossfade (const PBD::ID &);
- void sync_all_regions_with_regions ();
+ void sync_all_regions_with_regions ();
private:
friend class Session;
-
+
bool add (boost::shared_ptr<Playlist>);
void remove (boost::shared_ptr<Playlist>);
void remove_weak (boost::weak_ptr<Playlist>);
void track (bool, boost::weak_ptr<Playlist>);
-
+
uint32_t n_playlists() const;
void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
void update_after_tempo_map_change ();
int load (Session &, const XMLNode&);
int load_unused (Session &, const XMLNode&);
boost::shared_ptr<Playlist> XMLPlaylistFactory (Session &, const XMLNode&);
-
+
mutable Glib::Mutex lock;
typedef std::set<boost::shared_ptr<Playlist> > List;
List playlists;
}
framecnt_t write_unlocked (Sample */*dst*/, framecnt_t /*cnt*/) { return 0; }
-
+
void set_header_timeline_position () {}
int read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t /*start*/, framecnt_t /*cnt*/,
};
struct SafeTime {
- volatile int guard1;
- framepos_t position;
- framepos_t timestamp;
- double speed;
- volatile int guard2;
-
- SafeTime() {
- guard1 = 0;
- position = 0;
- timestamp = 0;
- speed = 0;
- guard2 = 0;
- }
+ volatile int guard1;
+ framepos_t position;
+ framepos_t timestamp;
+ double speed;
+ volatile int guard2;
+
+ SafeTime() {
+ guard1 = 0;
+ position = 0;
+ timestamp = 0;
+ speed = 0;
+ guard2 = 0;
+ }
};
class MTC_Slave : public Slave {
class SMFSource : public MidiSource, public FileSource, public Evoral::SMF {
public:
/** Constructor for existing external-to-session files */
- SMFSource (Session& session, const std::string& path,
+ SMFSource (Session& session, const std::string& path,
Source::Flag flags = Source::Flag(0));
/** Constructor for existing in-session files */
static bool safe_midi_file_extension (const std::string& path);
protected:
- void set_path (const std::string& newpath);
-
+ void set_path (const std::string& newpath);
+
private:
- int open_for_write ();
+ int open_for_write ();
framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
framepos_t position,
protected:
SF_INFO sf_info;
boost::shared_ptr<SNDFILE> in;
-
- /* these are int64_t so as to be independent of whatever
- types Ardour may use for framepos_t, framecnt_t etc.
- */
+
+ /* these are int64_t so as to be independent of whatever
+ types Ardour may use for framepos_t, framecnt_t etc.
+ */
int64_t timecode;
int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&);
class SndFileSource : public AudioFileSource {
public:
/** Constructor to be called for existing external-to-session files */
- SndFileSource (Session&, const std::string& path, int chn, Flag flags);
+ SndFileSource (Session&, const std::string& path, int chn, Flag flags);
/* Constructor to be called for new in-session files */
SndFileSource (Session&, const std::string& path, const std::string& origin,
- SampleFormat samp_format, HeaderFormat hdr_format, framecnt_t rate,
- Flag flags = SndFileSource::default_writable_flags);
+ SampleFormat samp_format, HeaderFormat hdr_format, framecnt_t rate,
+ Flag flags = SndFileSource::default_writable_flags);
/** Constructor to be called for existing in-session files */
SndFileSource (Session&, const XMLNode&);
static int get_soundfile_info (const std::string& path, SoundFileInfo& _info, std::string& error_msg);
protected:
- void set_path (const std::string& p);
+ void set_path (const std::string& p);
void set_header_timeline_position ();
framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
framecnt_t xfade_out_count;
framecnt_t xfade_in_count;
Sample* xfade_buf;
-
+
framecnt_t crossfade (Sample* data, framecnt_t cnt, int dir);
void set_timeline_position (framepos_t);
framecnt_t destructive_write_unlocked (Sample *dst, framecnt_t cnt);
Glib::Mutex& mutex() { return _lock; }
Flag flags() const { return _flags; }
- virtual void inc_use_count ();
- virtual void dec_use_count ();
- int use_count() const { return g_atomic_int_get (&_use_count); }
- bool used() const { return use_count() > 0; }
+ virtual void inc_use_count ();
+ virtual void dec_use_count ();
+ int use_count() const { return g_atomic_int_get (&_use_count); }
+ bool used() const { return use_count() > 0; }
uint32_t level() const { return _level; }
protected:
bool _analysed;
mutable Glib::Mutex _lock;
mutable Glib::Mutex _analysis_lock;
- gint _use_count; /* atomic */
+ gint _use_count; /* atomic */
uint32_t _level; /* how deeply nested is this source w.r.t a disk file */
private:
static boost::shared_ptr<Source> create (Session&, const XMLNode& node, bool async = false);
static boost::shared_ptr<Source> createSilent (Session&, const XMLNode& node,
- framecnt_t nframes, float sample_rate);
+ framecnt_t nframes, float sample_rate);
- static boost::shared_ptr<Source> createReadable
+ static boost::shared_ptr<Source> createReadable
(DataType type, Session&,
- const std::string& path,
+ const std::string& path,
int chn, Source::Flag flags, bool announce = true, bool async = false);
- static boost::shared_ptr<Source> createWritable
+ static boost::shared_ptr<Source> createWritable
(DataType type, Session&,
const std::string& path, const std::string& origin,
bool destructive, framecnt_t rate, bool announce = true, bool async = false);
- static boost::shared_ptr<Source> createFromPlaylist
+ static boost::shared_ptr<Source> createFromPlaylist
(DataType type, Session& s, boost::shared_ptr<Playlist> p, const PBD::ID& orig, const std::string& name,
uint32_t chn, frameoffset_t start, framecnt_t len, bool copy, bool defer_peaks);
#include "pbd/cartesian.h"
#include "pbd/signals.h"
-namespace ARDOUR {
+namespace ARDOUR {
class Speaker {
public:
Speaker (int, const PBD::AngularVector& position);
Speaker (const Speaker &);
Speaker& operator= (const Speaker &);
-
+
void move (const PBD::AngularVector& new_position);
const PBD::CartesianVector& coords() const { return _coords; }
class Speakers : public PBD::Stateful {
public:
Speakers ();
- Speakers (const Speakers&);
+ Speakers (const Speakers&);
virtual ~Speakers ();
- Speakers& operator= (const Speakers&);
+ Speakers& operator= (const Speakers&);
virtual int add_speaker (const PBD::AngularVector&);
virtual void remove_speaker (int id);
virtual void move_speaker (int id, const PBD::AngularVector& new_position);
virtual void clear_speakers ();
- uint32_t size() const { return _speakers.size(); }
+ uint32_t size() const { return _speakers.size(); }
- void setup_default_speakers (uint32_t nspeakers);
+ void setup_default_speakers (uint32_t nspeakers);
std::vector<Speaker>& speakers() { return _speakers; }
void dump_speakers (std::ostream&);
- XMLNode& get_state ();
- int set_state (const XMLNode&, int version);
+ XMLNode& get_state ();
+ int set_state (const XMLNode&, int version);
PBD::Signal0<void> Changed;
-
+
protected:
std::vector<Speaker> _speakers;
- virtual void update () {}
+ virtual void update () {}
};
} /* namespace */
struct _spline_point
{
- float x;
- float y;
+ float x;
+ float y;
};
Spline *spline_new (void);
namespace ARDOUR {
/// A filter to strip silence from regions
-class StripSilence : public Filter
+class StripSilence : public Filter
{
public:
StripSilence (Session &, const AudioIntervalMap&, framecnt_t fade_length);
int run (boost::shared_ptr<ARDOUR::Region>, Progress* progress = 0);
private:
- const AudioIntervalMap& _smap;
+ const AudioIntervalMap& _smap;
framecnt_t _fade_length; ///< fade in/out to use on trimmed regions, in samples
};
class TempoMetric {
public:
TempoMetric (const Meter& m, const Tempo& t) : _meter (&m), _tempo (&t), _frame (0) {}
-
+
void set_tempo (const Tempo& t) { _tempo = &t; }
void set_meter (const Meter& m) { _meter = &m; }
void set_frame (framepos_t f) { _frame = f; }
void set_start (const Timecode::BBT_Time& t) { _start = t; }
-
+
const Meter& meter() const { return *_meter; }
const Tempo& tempo() const { return *_tempo; }
framepos_t frame() const { return _frame; }
const Timecode::BBT_Time& start() const { return _start; }
-
+
private:
const Meter* _meter;
const Tempo* _tempo;
Timecode::BBT_Time bbt_add (const Timecode::BBT_Time& a, const Timecode::BBT_Time& b) const;
Timecode::BBT_Time bbt_subtract (const Timecode::BBT_Time&, const Timecode::BBT_Time&) const;
- framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b) const;
- double framewalk_to_beats (framepos_t pos, framecnt_t distance) const;
+ framepos_t framepos_plus_bbt (framepos_t pos, Timecode::BBT_Time b) const;
+ double framewalk_to_beats (framepos_t pos, framecnt_t distance) const;
void change_existing_tempo_at (framepos_t, double bpm, double note_type);
void change_initial_tempo (double bpm, double note_type);
class BufferSet;
class ThreadBuffers {
- public:
- ThreadBuffers ();
- ~ThreadBuffers ();
+public:
+ ThreadBuffers ();
+ ~ThreadBuffers ();
- void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
+ void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
- BufferSet* silent_buffers;
- BufferSet* scratch_buffers;
- BufferSet* mix_buffers;
- gain_t* gain_automation_buffer;
- pan_t** pan_automation_buffer;
- uint32_t npan_buffers;
+ BufferSet* silent_buffers;
+ BufferSet* scratch_buffers;
+ BufferSet* mix_buffers;
+ gain_t* gain_automation_buffer;
+ pan_t** pan_automation_buffer;
+ uint32_t npan_buffers;
- private:
- void allocate_pan_automation_buffers (framecnt_t nframes, uint32_t howmany, bool force);
+private:
+ void allocate_pan_automation_buffers (framecnt_t nframes, uint32_t howmany, bool force);
};
} // namespace
/*
Copyright (C) 2006 Paul Davis
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-
+
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
Track (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
virtual ~Track ();
- int init ();
+ int init ();
bool set_name (const std::string& str);
PBD::Signal0<void> TrackModeChanged;
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool state_changing, bool can_record, bool rec_monitors_input);
+ bool state_changing, bool can_record, bool rec_monitors_input);
int silent_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool rec_monitors_input, bool& need_butler);
+ bool can_record, bool rec_monitors_input, bool& need_butler);
virtual int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool rec_monitors_input, bool& need_butler) = 0;
+ int declick, bool can_record, bool rec_monitors_input, bool& need_butler) = 0;
- bool needs_butler() const { return _needs_butler; }
+ bool needs_butler() const { return _needs_butler; }
void toggle_monitor_input ();
virtual DataType data_type () const = 0;
bool can_record();
- virtual void use_new_diskstream () = 0;
- virtual void set_diskstream (boost::shared_ptr<Diskstream>);
+ virtual void use_new_diskstream () = 0;
+ virtual void set_diskstream (boost::shared_ptr<Diskstream>);
void set_latency_compensation (framecnt_t);
bool destructive () const;
std::list<boost::shared_ptr<Source> > & last_capture_sources ();
void set_capture_offset ();
- std::list<boost::shared_ptr<Source> > steal_write_sources();
+ std::list<boost::shared_ptr<Source> > steal_write_sources();
void reset_write_sources (bool, bool force = false);
float playback_buffer_load () const;
float capture_buffer_load () const;
void transport_stopped_wallclock (struct tm &, time_t, bool);
bool pending_overwrite () const;
double speed () const;
- void prepare_to_stop (framepos_t);
+ void prepare_to_stop (framepos_t);
void set_slaved (bool);
ChanCount n_channels ();
framepos_t get_capture_start_frame (uint32_t n = 0) const;
void set_align_choice (AlignChoice, bool force=false);
int use_copy_playlist ();
int use_new_playlist ();
- void adjust_playback_buffering ();
- void adjust_capture_buffering ();
+ void adjust_playback_buffering ();
+ void adjust_capture_buffering ();
PBD::Signal0<void> DiskstreamChanged;
PBD::Signal0<void> FreezeChange;
boost::shared_ptr<Diskstream> _diskstream;
MeterPoint _saved_meter_point;
TrackMode _mode;
- bool _needs_butler;
+ bool _needs_butler;
//private: (FIXME)
struct FreezeRecordProcessorInfo {
XMLNode* pending_state;
bool _destructive;
- void maybe_declick (BufferSet&, framecnt_t, int);
+ void maybe_declick (BufferSet&, framecnt_t, int);
virtual bool send_silence () const;
class TransientDetector : public AudioAnalyser
{
+public:
+ TransientDetector (float sample_rate);
+ ~TransientDetector();
- public:
- TransientDetector (float sample_rate);
- ~TransientDetector();
+ static std::string operational_identifier();
- static std::string operational_identifier();
+ void set_threshold (float);
+ void set_sensitivity (float);
- void set_threshold (float);
- void set_sensitivity (float);
+ float get_threshold () const;
+ float get_sensitivity () const;
- float get_threshold () const;
- float get_sensitivity () const;
+ int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
+ void update_positions (Readable* src, uint32_t channel, AnalysisFeatureList& results);
- int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
- void update_positions (Readable* src, uint32_t channel, AnalysisFeatureList& results);
-
- static void cleanup_transients (AnalysisFeatureList&, float sr, float gap_msecs);
-
+ static void cleanup_transients (AnalysisFeatureList&, float sr, float gap_msecs);
- protected:
- AnalysisFeatureList* current_results;
- int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
+protected:
+ AnalysisFeatureList* current_results;
+ int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
- static std::string _op_id;
- float threshold;
+ static std::string _op_id;
+ float threshold;
};
} /* namespace */
#ifndef __libardour_trimmable_h__
#define __libardour_trimmable_h__
-namespace ARDOUR {
+namespace ARDOUR {
class Trimmable {
public:
- Trimmable() {}
- virtual ~Trimmable() {}
+ Trimmable() {}
+ virtual ~Trimmable() {}
- enum CanTrim {
- FrontTrimEarlier = 0x1,
- FrontTrimLater = 0x2,
- EndTrimEarlier = 0x4,
- EndTrimLater = 0x8,
- TopTrimUp = 0x10,
- TopTrimDown = 0x20,
- BottomTrimUp = 0x40,
- BottomTrimDown = 0x80
- } ;
+ enum CanTrim {
+ FrontTrimEarlier = 0x1,
+ FrontTrimLater = 0x2,
+ EndTrimEarlier = 0x4,
+ EndTrimLater = 0x8,
+ TopTrimUp = 0x10,
+ TopTrimDown = 0x20,
+ BottomTrimUp = 0x40,
+ BottomTrimDown = 0x80
+ } ;
- virtual CanTrim can_trim() const {
- return CanTrim (FrontTrimEarlier |
- FrontTrimLater |
- EndTrimEarlier |
- EndTrimLater |
- TopTrimUp |
- TopTrimDown |
- BottomTrimUp |
- BottomTrimDown);
- }
+ virtual CanTrim can_trim() const {
+ return CanTrim (FrontTrimEarlier |
+ FrontTrimLater |
+ EndTrimEarlier |
+ EndTrimLater |
+ TopTrimUp |
+ TopTrimDown |
+ BottomTrimUp |
+ BottomTrimDown);
+ }
};
}
*/
typedef int64_t frameoffset_t;
- /* Any count of audio frames.
+ /* Any count of audio frames.
Assumed to be positive but not enforced.
*/
typedef int64_t framecnt_t;
OverlapEnd, // overlap begins within and covers end
OverlapExternal // overlap extends to (at least) begin+end
};
-
- ARDOUR::OverlapType coverage (framepos_t sa, framepos_t ea,
- framepos_t sb, framepos_t eb);
- /* policies for inserting/pasting material where overlaps
- might be an issue.
- */
+ ARDOUR::OverlapType coverage (framepos_t sa, framepos_t ea,
+ framepos_t sb, framepos_t eb);
- enum InsertMergePolicy {
- InsertMergeReject, // no overlaps allowed
- InsertMergeRelax, // we just don't care about overlaps
- InsertMergeReplace, // replace old with new
- InsertMergeTruncateExisting, // shorten existing to avoid overlap
- InsertMergeTruncateAddition, // shorten new to avoid overlap
- InsertMergeExtend // extend new (or old) to the range of old+new
- };
+ /* policies for inserting/pasting material where overlaps
+ might be an issue.
+ */
+
+ enum InsertMergePolicy {
+ InsertMergeReject, // no overlaps allowed
+ InsertMergeRelax, // we just don't care about overlaps
+ InsertMergeReplace, // replace old with new
+ InsertMergeTruncateExisting, // shorten existing to avoid overlap
+ InsertMergeTruncateAddition, // shorten new to avoid overlap
+ InsertMergeExtend // extend new (or old) to the range of old+new
+ };
/** See evoral/Parameter.hpp
*/
enum AlignChoice {
UseCaptureTime,
UseExistingMaterial,
- Automatic
+ Automatic
};
enum MeterPoint {
MeterInput,
MeterPreFader,
MeterPostFader,
- MeterOutput,
+ MeterOutput,
MeterCustom
};
};
AnyTime() { type = Frames; frames = 0; }
-
+
bool operator== (AnyTime const & other) const {
if (type != other.type) { return false; }
-
+
switch (type) {
case Timecode:
return timecode == other.timecode;
return seconds == other.seconds;
}
}
-
+
bool not_zero() const
{
switch (type) {
struct InterThreadInfo {
InterThreadInfo () : done (false), cancel (false), progress (0), thread (0) {}
-
+
volatile bool done;
volatile bool cancel;
volatile float progress;
bool meter_visibly_changed;
};
- struct BusProfile {
- AutoConnectOption input_ac; /* override the RC config for input auto-connection */
- AutoConnectOption output_ac; /* override the RC config for output auto-connection */
- uint32_t master_out_channels; /* how many channels for the master bus */
- uint32_t requested_physical_in; /* now many of the available physical inputs to consider usable */
- uint32_t requested_physical_out; /* now many of the available physical inputs to consider usable */
- };
+ struct BusProfile {
+ AutoConnectOption input_ac; /* override the RC config for input auto-connection */
+ AutoConnectOption output_ac; /* override the RC config for output auto-connection */
+ uint32_t master_out_channels; /* how many channels for the master bus */
+ uint32_t requested_physical_in; /* now many of the available physical inputs to consider usable */
+ uint32_t requested_physical_out; /* now many of the available physical inputs to consider usable */
+ };
enum FadeShape {
FadeLinear,
bool can_support_io_configuration (const ChanCount &, ChanCount &) const {
return false;
}
-
+
XMLNode & state (bool);
private:
bool load_user_preset (PresetRecord);
bool load_plugin_preset (PresetRecord);
void add_state (XMLNode *) const;
-
+
FSTHandle* handle;
FST* _fst;
AEffect* _plugin;
(*chan)->current_playback_buffer = 0;
}
- // Safeguard against situations where process() goes haywire when autopunching
+ // Safeguard against situations where process() goes haywire when autopunching
// and last_recordable_frame < first_recordable_frame
if (last_recordable_frame < first_recordable_frame) {
OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset);
-
+
if (rec_nframes && !was_recording) {
capture_captured = 0;
was_recording = true;
_speed = _target_speed;
- }
+ }
ret = 0;
capture_captured += adjust_capture_position;
adjust_capture_position = 0;
}
-
+
if (c->empty()) {
return false;
}
-
+
if (_slaved) {
if (_io && _io->active()) {
need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2;
_pending_overwrite = false;
return 0;
}
-
+
Sample* mixdown_buffer;
float* gain_buffer;
int ret = -1;
}
int
-AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
+AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
framepos_t& start, framecnt_t cnt,
ChannelInfo* /*channel_info*/, int channel, bool reversed)
{
if (reversed) {
start -= cnt;
}
-
+
while (cnt) {
/* take any loop into account. we can't read past the end of the loop. */
file_frame = file_frame_tmp;
assert (file_frame >= 0);
-
+
out:
return ret;
string region_name;
RegionFactory::region_name (region_name, whole_file_region_name, false);
-
+
DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
_name, (*ci)->start, (*ci)->frames, region_name));
try {
PropertyList plist;
-
+
plist.add (Properties::start, buffer_position);
plist.add (Properties::length, (*ci)->frames);
plist.add (Properties::name, region_name);
-
+
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
region = boost::dynamic_pointer_cast<AudioRegion> (rx);
}
region->set_layer (_playlist->top_layer() + 1);
region->set_pending_explicit_relayer (true);
}
-
+
_playlist->add_region (region, (*ci)->start, 1, non_layered());
i_am_the_modifier--;
/* do not remove destructive files even if they are empty */
chan->write_source->set_allow_remove_if_empty (!destructive());
-
+
return 0;
}
-list<boost::shared_ptr<Source> >
+list<boost::shared_ptr<Source> >
AudioDiskstream::steal_write_sources()
{
/* not possible to steal audio write sources */
(*chan)->write_source->mark_for_remove ();
(*chan)->write_source->drop_references ();
}
-
+
(*chan)->write_source.reset ();
}
{
while (how_many--) {
c->push_back (new ChannelInfo(
- _session.butler()->audio_diskstream_playback_buffer_size(),
+ _session.butler()->audio_diskstream_playback_buffer_size(),
_session.butler()->audio_diskstream_capture_buffer_size(),
speed_buffer_size, wrap_buffer_size));
interpolation.add_channel_to (
if (c->empty ()) {
return 0;
}
-
+
return (float) ((double) c->front()->capture_buf->write_space()/
(double) c->front()->capture_buf->bufsize());
}
boost::shared_ptr<AudioRegion> region;
try {
-
+
PropertyList plist;
-
+
plist.add (Properties::start, 0);
plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
return true;
}
-void
+void
AudioDiskstream::adjust_playback_buffering ()
{
boost::shared_ptr<ChannelList> c = channels.reader();
}
}
-void
+void
AudioDiskstream::adjust_capture_buffering ()
{
boost::shared_ptr<ChannelList> c = channels.reader();
boost::shared_ptr<ChannelList> c = channels.reader();
ChannelList::iterator i;
int n = 0;
-
+
for (n = 0, i = c->begin(); i != c->end(); ++i, ++n) {
use_new_write_source (n);
}
: SequenceProperty<std::list<boost::shared_ptr<Crossfade> > > (Properties::crossfades.property_id, boost::bind (&AudioPlaylist::update, &pl, _1))
, _playlist (pl)
{
-
+
}
CrossfadeListProperty::CrossfadeListProperty (CrossfadeListProperty const & p)
, _crossfades (*this)
{
add_property (_crossfades);
-
+
RegionList::const_iterator in_o = other->regions.begin();
RegionList::iterator in_n = regions.begin();
{
RegionLock rlock2 (const_cast<AudioPlaylist*> (other.get()));
in_set_state++;
-
+
add_property (_crossfades);
framepos_t const end = start + cnt - 1;
fade_out = region->fade_out()->back()->when - ( region->last_frame() - end ); //end is inside the fadeout, preserve the fades endpoint
break;
}
-
+
case OverlapEnd: {
position = 0;
offset = start - region->position();
if (start < region->last_frame() - region->fade_out()->back()->when) //start is before fade-out, preserve the fadeout
fade_out = region->fade_out()->back()->when;
-
+
if (start < region->position() + region->fade_in()->back()->when)
fade_in = region->fade_in()->back()->when - (start - region->position()); //end is inside the fade-in, preserve the fade-in endpoint
break;
}
-
+
case OverlapExternal:
fade_in = region->fade_in()->back()->when;
fade_out = region->fade_out()->back()->when;
for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
if ((*i)->in() == on->first) {
-
+
CrossfadeInfo::iterator cf;
if ((cf = crossfade_info.find (*i)) != crossfade_info.end()) {
- /* already have a record for the old fade-in region,
+ /* already have a record for the old fade-in region,
so note the new fade-in region
*/
-
+
cf->second.new_in = on->second;
-
+
} else {
-
+
/* add a record of this crossfade, keeping an association
with the new fade-in region
*/
-
+
crossfade_triple ct;
-
+
ct.old_in = on->first;
ct.new_in = on->second;
}
} else if ((*i)->out() == on->first) {
-
+
/* this old region is the fade-out region of this crossfade */
-
+
CrossfadeInfo::iterator cf;
-
+
if ((cf = crossfade_info.find (*i)) != crossfade_info.end()) {
-
+
/* already have a record for this crossfade, so just keep
an association for the new fade out region
*/
-
+
cf->second.new_out = on->second;
} else {
-
+
/* add a record of this crossfade, keeping an association
with the new fade-in region
*/
}
for (CrossfadeInfo::iterator ci = crossfade_info.begin(); ci != crossfade_info.end(); ++ci) {
-
+
/* for each crossfade that involves at least two of the old regions,
create a new identical crossfade with the new regions
*/
-
+
if (!ci->second.new_in || !ci->second.new_out) {
continue;
}
- boost::shared_ptr<Crossfade> new_xfade (new Crossfade (ci->first,
+ boost::shared_ptr<Crossfade> new_xfade (new Crossfade (ci->first,
boost::dynamic_pointer_cast<AudioRegion>(ci->second.new_in),
boost::dynamic_pointer_cast<AudioRegion>(ci->second.new_out)));
-
+
/* add it at the right position - which must be at the start
* of the fade-in region
*/
ar->set_scale_amplitude (ar->scale_amplitude() * cr->scale_amplitude());
if (i == originals.begin()) {
-
+
/* copy the compound region's fade in back into the first
original region.
*/
-
+
if (cr->fade_in()->back()->when <= ar->length()) {
/* don't do this if the fade is longer than the
* region
ar->set_fade_in (cr->fade_in());
}
-
+
} else if (*i == originals.back()) {
/* copy the compound region's fade out back into the last
original region.
*/
-
+
if (cr->fade_out()->back()->when <= ar->length()) {
/* don't do this if the fade is longer than the
* region
using namespace ARDOUR;
using namespace PBD;
-AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
+AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
: Source (s, DataType::AUDIO, name)
, PlaylistSource (s, orig, name, p, DataType::AUDIO, begin, len, flags)
/* ancestors have already called ::set_state() in their XML-based
constructors.
*/
-
+
if (set_state (node, Stateful::loading_state_version, false)) {
throw failed_constructor ();
}
return node;
}
-
+
int
-AudioPlaylistSource::set_state (const XMLNode& node, int version)
+AudioPlaylistSource::set_state (const XMLNode& node, int version)
{
return set_state (node, version, true);
}
int
-AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
+AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
{
if (with_descendants) {
- if (Source::set_state (node, version) ||
+ if (Source::set_state (node, version) ||
PlaylistSource::set_state (node, version) ||
AudioSource::set_state (node, version)) {
return -1;
return 0;
}
-framecnt_t
+framecnt_t
AudioPlaylistSource::read_unlocked (Sample* dst, framepos_t start, framecnt_t cnt) const
{
boost::shared_ptr<Sample> sbuf;
to_zero = 0;
}
- {
+ {
/* Don't need to hold the lock for the actual read, and
actually, we cannot, but we do want to interlock
with any changes to the list of buffers caused
return cnt;
}
-framecnt_t
-AudioPlaylistSource::write_unlocked (Sample *src, framecnt_t cnt)
+framecnt_t
+AudioPlaylistSource::write_unlocked (Sample *src, framecnt_t cnt)
{
fatal << string_compose (_("programming error: %1"), "AudioPlaylistSource::write() called - should be impossible") << endmsg;
/*NOTREACHED*/
AudioPort::cycle_end (pframes_t nframes)
{
if (sends_output() && !_buffer->written()) {
- /* we can't use nframes here because the current buffer capacity may
+ /* we can't use nframes here because the current buffer capacity may
be shorter than the full buffer size if we split the cycle.
*/
if (_buffer->capacity () > 0) {
AudioPort::get_audio_buffer (pframes_t nframes)
{
/* caller must hold process lock */
- _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
+ _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
_global_port_buffer_offset + _port_buffer_offset, nframes);
return *_buffer;
}
Sample* tmpb;
framepos_t transport_frame;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
-
+
automation_snapshot (start_frame, false);
if (n_outputs().n_total() == 0 && _processors.empty()) {
boost::shared_ptr<Processor> processor = boost::dynamic_pointer_cast<Processor> (*i);
boost::shared_ptr<Delivery> delivery = boost::dynamic_pointer_cast<Delivery> (*i);
boost::shared_ptr<PeakMeter> meter = boost::dynamic_pointer_cast<PeakMeter> (*i);
-
+
if (processor && (!delivery || !Delivery::role_requires_output_ports (delivery->role())) && !meter) {
processor->run (buffers, start, start+nframes, nframes, true);
}
/* create a new region from all filesources, keep it private */
PropertyList plist;
-
+
plist.add (Properties::start, 0);
plist.add (Properties::length, srcs[0]->length(srcs[0]->timeline_position()));
plist.add (Properties::name, region_name);
/*
- Copyright (C) 2006-2009 Paul Davis
+ Copyright (C) 2006-2009 Paul Davis
Some portions Copyright (C) Sophia Poirier.
This program is free software; you can redistribute it and/or modify
static bool preset_search_path_initialized = false;
static bool debug_io_config = true;
-static OSStatus
+static OSStatus
_render_callback(void *userData,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
return paramErr;
}
-static OSStatus
+static OSStatus
_get_beat_and_tempo_callback (void* userData,
- Float64* outCurrentBeat,
+ Float64* outCurrentBeat,
Float64* outCurrentTempo)
{
if (userData) {
return ((AUPlugin*)userData)->get_beat_and_tempo_callback (outCurrentBeat, outCurrentTempo);
}
-
+
return paramErr;
}
-static OSStatus
+static OSStatus
_get_musical_time_location_callback (void * userData,
UInt32 * outDeltaSampleOffsetToNextBeat,
Float32 * outTimeSig_Numerator,
return paramErr;
}
-static OSStatus
+static OSStatus
_get_transport_state_callback (void* userData,
Boolean* outIsPlaying,
Boolean* outTransportStateChanged,
}
-static int
+static int
save_property_list (CFPropertyListRef propertyList, Glib::ustring path)
{
int fd;
// Convert the property list into XML data.
-
+
xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, propertyList);
if (!xmlData) {
close (fd);
return 0;
}
-
-static CFPropertyListRef
-load_property_list (Glib::ustring path)
+
+static CFPropertyListRef
+load_property_list (Glib::ustring path)
{
int fd;
CFPropertyListRef propertyList = 0;
CFStringRef errorString;
// Read the XML file.
-
+
if ((fd = open (path.c_str(), O_RDONLY)) < 0) {
return propertyList;
}
-
+
off_t len = lseek (fd, 0, SEEK_END);
char* buf = new char[len];
lseek (fd, 0, SEEK_SET);
close (fd);
return propertyList;
}
-
+
close (fd);
xmlData = CFDataCreateWithBytesNoCopy (kCFAllocatorDefault, (UInt8*) buf, len, kCFAllocatorNull);
-
+
// Reconstitute the dictionary using the XML data.
-
+
propertyList = CFPropertyListCreateFromXMLData( kCFAllocatorDefault,
xmlData,
kCFPropertyListImmutable,
}
//-----------------------------------------------------------------------------
-static void
+static void
set_preset_name_in_plist (CFPropertyListRef plist, string preset_name)
{
if (!plist) {
if (CFGetTypeID (plist) == CFDictionaryGetTypeID()) {
CFDictionarySetValue ((CFMutableDictionaryRef)plist, CFSTR(kAUPresetNameKey), pn);
}
-
+
CFRelease (pn);
}
if (CFStringGetCString (str, local_buffer, len, kCFStringEncodingUTF8)) {
ret = local_buffer;
}
- }
+ }
}
return ret;
}
if ( (inComponentDescription1 == NULL) || (inComponentDescription2 == NULL) )
return FALSE;
- if ( (inComponentDescription1->componentSubType == inComponentDescription2->componentSubType)
+ if ( (inComponentDescription1->componentSubType == inComponentDescription2->componentSubType)
&& (inComponentDescription1->componentManufacturer == inComponentDescription2->componentManufacturer) )
{
// only sub-type and manufacturer IDs need to be equal
//--------------------------------------------------------------------------
// determine if 2 ComponentDescriptions are basically equal
-// (by that, I mean that the important identifying values are compared,
+// (by that, I mean that the important identifying values are compared,
// but not the ComponentDescription flags)
Boolean ComponentDescriptionsMatch(const ComponentDescription * inComponentDescription1, const ComponentDescription * inComponentDescription2)
{
, frames_processed (0)
, last_transport_rolling (false)
, last_transport_speed (0.0)
-{
+{
if (!preset_search_path_initialized) {
Glib::ustring p = Glib::get_home_dir();
p += "/Library/Audio/Presets:";
, current_offset (0)
, current_buffers (0)
, frames_processed (0)
-
+
{
init ();
}
CFArrayRef presets;
UInt32 dataSize = sizeof (presets);
OSStatus err;
-
+
TRACE_API ("get property FactoryPresets in global scope\n");
if ((err = unit->GetProperty (kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, (void*) &presets, &dataSize)) != 0) {
cerr << "cannot get factory preset info: " << err << endl;
string name = CFStringRefToStdString (preset->presetName);
factory_preset_map[name] = preset->presetNumber;
}
-
+
CFRelease (presets);
}
error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg;
throw failed_constructor ();
}
-
+
TRACE_API ("count global elements\n");
unit->GetElementCount (kAudioUnitScope_Global, global_elements);
TRACE_API ("count input elements\n");
if (input_elements > 0) {
AURenderCallbackStruct renderCallbackInfo;
-
+
renderCallbackInfo.inputProc = _render_callback;
renderCallbackInfo.inputProcRefCon = this;
-
+
TRACE_API ("set render callback in input scope\n");
- if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+ if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
0, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo))) != 0) {
cerr << "cannot install render callback (err = " << err << ')' << endl;
throw failed_constructor();
info.beatAndTempoProc = _get_beat_and_tempo_callback;
info.musicalTimeLocationProc = _get_musical_time_location_callback;
info.transportStateProc = _get_transport_state_callback;
-
+
//ignore result of this - don't care if the property isn't supported
TRACE_API ("set host callbacks in global scope\n");
- unit->SetProperty (kAudioUnitProperty_HostCallbacks,
- kAudioUnitScope_Global,
- 0, //elementID
+ unit->SetProperty (kAudioUnitProperty_HostCallbacks,
+ kAudioUnitScope_Global,
+ 0, //elementID
&info,
sizeof (HostCallbackInfo));
AUPlugin::discover_parameters ()
{
/* discover writable parameters */
-
- AudioUnitScope scopes[] = {
+
+ AudioUnitScope scopes[] = {
kAudioUnitScope_Global,
kAudioUnitScope_Output,
kAudioUnitScope_Input
for (uint32_t i = 0; i < sizeof (scopes) / sizeof (scopes[0]); ++i) {
AUParamInfo param_info (unit->AU(), false, false, scopes[i]);
-
+
for (uint32_t i = 0; i < param_info.NumParams(); ++i) {
AUParameterDescriptor d;
d.toggled = (info.unit == kAudioUnitParameterUnit_Boolean) ||
(d.integer_step && ((d.upper - d.lower) == 1.0));
d.sr_dependent = (info.unit == kAudioUnitParameterUnit_SampleFrames);
- d.automatable = !d.toggled &&
+ d.automatable = !d.toggled &&
!(info.flags & kAudioUnitParameterFlag_NonRealTime) &&
(info.flags & kAudioUnitParameterFlag_IsWritable);
-
+
d.logarithmic = (info.flags & kAudioUnitParameterFlag_DisplayLogarithmic);
d.unit = info.unit;
/* ID format is xxxx-xxxx-xxxx
where x maybe \xNN or a printable character.
-
- Split at the '-' and and process each part into an integer.
+
+ Split at the '-' and and process each part into an integer.
Then put it back together.
*/
++in;
} else {
-
+
if (cstr[1] == 'x' && isxdigit (cstr[2]) && isxdigit (cstr[3])) {
-
+
/* parse \xNN */
-
+
memcpy (short_buf, &cstr[2], 2);
nascent[in] = strtol (short_buf, NULL, 16);
cstr += 4;
++in;
-
+
} else {
/* treat as literal characters */
}
s << n[0] << '-' << n[1] << '-' << n[2];
-
+
return s.str();
err:
if (which >= descriptors.size()) {
return;
}
-
+
const AUParameterDescriptor& d (descriptors[which]);
TRACE_API ("set parameter %d in scope %d element %d to %f\n", d.id, d.scope, d.element, val);
unit->SetParameter (d.id, d.scope, d.element, val);
-
+
/* tell the world what we did */
-
+
AudioUnitEvent theEvent;
-
+
theEvent.mEventType = kAudioUnitEvent_ParameterValueChange;
theEvent.mArgument.mParameter.mAudioUnit = unit->AU();
theEvent.mArgument.mParameter.mParameterID = d.id;
theEvent.mArgument.mParameter.mScope = d.scope;
theEvent.mArgument.mParameter.mElement = d.element;
-
+
TRACE_API ("notify about parameter change\n");
AUEventListenerNotify (NULL, NULL, &theEvent);
-
+
Plugin::set_parameter (which, val);
}
if (which < descriptors.size()) {
pd = descriptors[which];
return 0;
- }
+ }
return -1;
}
}
TRACE_API ("set MaximumFramesPerSlice in global scope to %u\n", numFrames);
- if ((err = unit->SetProperty (kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global,
+ if ((err = unit->SetProperty (kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global,
0, &numFrames, sizeof (numFrames))) != noErr) {
cerr << "cannot set max frames (err = " << err << ')' << endl;
return -1;
plugcnt = 1;
}
}
-
+
if (possible_in == -1) {
/* wildcard for input */
audio_out = possible_out;
plugcnt = 1;
}
- }
-
+ }
+
if (possible_in == -2) {
if (possible_out == -1) {
if (possible_in == audio_in) {
/* exact number of inputs ... must match obviously */
-
+
if (possible_out == -1) {
/* out must match in */
audio_out = audio_in;
free (buffers);
buffers = 0;
}
-
- buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
+
+ buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
fmt.mChannelsPerFrame * sizeof(::AudioBuffer));
Glib::Mutex::Lock em (_session.engine().process_lock());
return 0;
}
-OSStatus
+OSStatus
AUPlugin::render_callback(AudioUnitRenderActionFlags*,
const AudioTimeStamp*,
UInt32,
case MIDI_CMD_BENDER:
case MIDI_CMD_PGM_CHANGE:
case MIDI_CMD_CHANNEL_PRESSURE:
- {
+ {
const uint8_t* b = ev.buffer();
unit->MIDIEvent (b[0], b[1], b[2], ev.time());
break;
}
-
+
default:
/* plugins do not get other stuff by default */
break;
AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_map, pframes_t nframes, framecnt_t offset)
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
-
+
AudioUnitRenderActionFlags flags = 0;
AudioTimeStamp ts;
OSErr err;
current_maxbuf = 0;
frames_processed += nframes;
-
+
uint32_t limit = min ((uint32_t) buffers->mNumberBuffers, maxbuf);
uint32_t i;
}
return 0;
- }
+ }
cerr << name() << " render status " << err << endl;
return -1;
}
-OSStatus
-AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat,
+OSStatus
+AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat,
Float64* outCurrentTempo)
{
TempoMap& tmap (_session.tempo_map());
TRACE_API ("AU calls ardour beat&tempo callback\n");
- /* more than 1 meter or more than 1 tempo means that a simplistic computation
- (and interpretation) of a beat position will be incorrect. So refuse to
+ /* more than 1 meter or more than 1 tempo means that a simplistic computation
+ (and interpretation) of a beat position will be incorrect. So refuse to
offer the value.
*/
}
-OSStatus
+OSStatus
AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
Float32* outTimeSig_Numerator,
UInt32* outTimeSig_Denominator,
TRACE_API ("AU calls ardour music time location callback\n");
- /* more than 1 meter or more than 1 tempo means that a simplistic computation
- (and interpretation) of a beat position will be incorrect. So refuse to
+ /* more than 1 meter or more than 1 tempo means that a simplistic computation
+ (and interpretation) of a beat position will be incorrect. So refuse to
offer the value.
*/
metric.tempo().frames_per_beat(_session.frame_rate(), metric.meter())); // frames per beat
}
}
-
+
if (outTimeSig_Numerator) {
*outTimeSig_Numerator = (UInt32) lrintf (metric.meter().beats_per_bar());
}
if (outCurrentMeasureDownBeat) {
- /* beat for the start of the bar.
+ /* beat for the start of the bar.
1|1|0 -> 1
2|1|0 -> 1 + beats_per_bar
3|1|0 -> 1 + (2 * beats_per_bar)
- etc.
+ etc.
*/
*outCurrentMeasureDownBeat = 1 + metric.meter().beats_per_bar() * (bbt.bars - 1);
return noErr;
}
-OSStatus
+OSStatus
AUPlugin::get_transport_state_callback (Boolean* outIsPlaying,
Boolean* outTransportStateChanged,
Float64* outCurrentSampleInTimeLine,
TempoMap& tmap (_session.tempo_map());
- /* more than 1 meter means that a simplistic computation (and interpretation) of
+ /* more than 1 meter means that a simplistic computation (and interpretation) of
a beat position will be incorrect. so refuse to offer the value.
*/
if (tmap.n_meters() > 1) {
return kAudioUnitErr_CannotDoInCurrentContext;
}
-
+
Timecode::BBT_Time bbt;
if (outCycleStartBeat) {
beat = metric.meter().beats_per_bar() * bbt.bars;
beat += bbt.beats;
beat += bbt.ticks / BBT_Time::ticks_per_beat;
-
+
*outCycleStartBeat = beat;
}
if (outCycleEndBeat) {
TempoMetric metric = tmap.metric_at (loc->end() + current_offset);
_session.tempo_map().bbt_time_with_metric (loc->end(), bbt, metric);
-
+
float beat;
beat = metric.meter().beats_per_bar() * bbt.bars;
beat += bbt.beats;
beat += bbt.ticks / BBT_Time::ticks_per_beat;
-
+
*outCycleEndBeat = beat;
}
}
}
// Convert the property list into XML data.
-
+
xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, propertyList);
if (!xmlData) {
error << _("Bad node sent to AUPlugin::set_state") << endmsg;
return -1;
}
-
+
if (node.children().empty()) {
return -1;
}
&errorString);
CFRelease (xmlData);
-
+
if (propertyList) {
TRACE_API ("set preset\n");
if (unit->SetAUPreset (propertyList) == noErr) {
ret = 0;
-
+
/* tell the world */
AudioUnitParameter changedUnit;
changedUnit.mAudioUnit = unit->AU();
changedUnit.mParameterID = kAUParameterListener_AnyParameter;
AUParameterListenerNotify (NULL, NULL, &changedUnit);
- }
+ }
CFRelease (propertyList);
}
-
+
Plugin::set_state (node, version);
return ret;
#else
AUPlugin::load_preset (PluginRecord r)
{
Plugin::load_preset (r);
-
+
#ifdef AU_STATE_SUPPORT
bool ret = false;
CFPropertyListRef propertyList;
/* look first in "user" presets */
if ((ux = user_preset_map.find (preset_label)) != user_preset_map.end()) {
-
+
if ((propertyList = load_property_list (ux->second)) != 0) {
TRACE_API ("set preset from user presets\n");
if (unit->SetAUPreset (propertyList) == noErr) {
ret = true;
/* tell the world */
-
+
AudioUnitParameter changedUnit;
changedUnit.mAudioUnit = unit->AU();
changedUnit.mParameterID = kAUParameterListener_AnyParameter;
}
} else if ((fx = factory_preset_map.find (preset_label)) != factory_preset_map.end()) {
-
+
AUPreset preset;
-
+
preset.presetNumber = fx->second;
preset.presetName = CFStringCreateWithCString (kCFAllocatorDefault, fx->first.c_str(), kCFStringEncodingUTF8);
-
+
TRACE_API ("set preset from factory presets\n");
if (unit->SetPresentPreset (preset) == 0) {
AUParameterListenerNotify (NULL, NULL, &changedUnit);
}
}
-
+
return ret;
#else
if (!seen_loading_message) {
std::string m = maker();
std::string n = name();
-
+
strip_whitespace_edges (m);
strip_whitespace_edges (n);
v.push_back ("Presets");
v.push_back (m);
v.push_back (n);
-
+
user_preset_path = Glib::build_filename (v);
if (g_mkdir_with_parents (user_preset_path.c_str(), 0775) < 0) {
// add the actual preset name */
v.push_back (preset_name + preset_suffix);
-
+
// rebuild
user_preset_path = Glib::build_filename (v);
-
+
set_preset_name_in_plist (propertyList, preset_name);
if (save_property_list (propertyList, user_preset_path)) {
//-----------------------------------------------------------------------------
// this is just a little helper function used by GetAUComponentDescriptionFromPresetFile()
-static SInt32
+static SInt32
GetDictionarySInt32Value(CFDictionaryRef inAUStateDictionary, CFStringRef inDictionaryKey, Boolean * outSuccess)
{
CFNumberRef cfNumber;
return 0;
}
-static OSStatus
+static OSStatus
GetAUComponentDescriptionFromStateData(CFPropertyListRef inAUStateData, ComponentDescription * outComponentDescription)
{
CFDictionaryRef auStateDictionary;
if ( (inAUStateData == NULL) || (outComponentDescription == NULL) )
return paramErr;
-
+
// the property list for AU state data must be of the dictionary type
if (CFGetTypeID(inAUStateData) != CFDictionaryGetTypeID()) {
return kAudioUnitErr_InvalidPropertyValue;
/* Not a dotfile, has a prefix before a period, suffix is aupreset */
bool ret;
-
+
ret = (str[0] != '.' && str.length() > 9 && str.find (preset_suffix) == (str.length() - preset_suffix.length()));
if (ret && arg) {
match = m;
match += '/';
match += n;
-
+
ret = str.find (match) != string::npos;
}
}
-
+
return ret;
}
-bool
+bool
check_and_get_preset_name (Component component, const string& pathstr, string& preset_name)
{
OSStatus status;
CFPropertyListRef plist;
ComponentDescription presetDesc;
bool ret = false;
-
+
plist = load_property_list (pathstr);
if (!plist) {
return ret;
}
-
+
// get the ComponentDescription from the AU preset file
-
+
status = GetAUComponentDescriptionFromStateData(plist, &presetDesc);
-
+
if (status == noErr) {
if (ComponentAndDescriptionMatch_Loosely(component, &presetDesc)) {
}
}
}
- }
+ }
}
CFRelease (plist);
AUPlugin::current_preset() const
{
string preset_name;
-
+
#ifdef AU_STATE_SUPPORT
CFPropertyListRef propertyList;
user_preset_map.clear ();
preset_files = scanner (preset_search_path, au_preset_filter, this, true, true, -1, true);
-
+
if (!preset_files) {
return;
}
if (check_and_get_preset_name (get_comp()->Comp(), path, preset_name)) {
user_preset_map[preset_name] = path;
- }
+ }
delete *x;
}
TRACE_API ("load AU as a component\n");
boost::shared_ptr<CAComponent> comp (new CAComponent(*descriptor));
-
+
if (!comp->IsValid()) {
error << ("AudioUnit: not a valid Component") << endmsg;
} else {
plugin.reset (new AUPlugin (session.engine(), session, comp));
}
-
+
AUPluginInfo *aup = new AUPluginInfo (*this);
plugin->set_info (PluginInfoPtr (aup));
boost::dynamic_pointer_cast<AUPlugin> (plugin)->set_fixed_size_buffers (aup->creator == "Universal Audio");
}
PluginInfoList* plugs = new PluginInfoList;
-
+
discover_fx (*plugs);
discover_music (*plugs);
discover_generators (*plugs);
CAComponentDescription temp;
GetComponentInfo (comp, &temp, NULL, NULL, NULL);
- AUPluginInfoPtr info (new AUPluginInfo
+ AUPluginInfoPtr info (new AUPluginInfo
(boost::shared_ptr<CAComponentDescription> (new CAComponentDescription(temp))));
/* although apple designed the subtype field to be a "category" indicator,
there are no categories for AudioUnits. However, to keep the plugins
showing up under "categories", we'll use the "type" as a high level
selector.
-
+
NOTE: no panners, format converters or i/o AU's for our purposes
*/
}
AUPluginInfo::get_names (temp, info->name, info->creator);
-
+
info->type = ARDOUR::AudioUnit;
info->unique_id = stringify_descriptor (*info->descriptor);
if (cacomp.GetResourceVersion (info->version) != noErr) {
info->version = 0;
}
-
+
if (cached_io_configuration (info->unique_id, info->version, cacomp, info->cache, info->name)) {
/* here we have to map apple's wildcard system to a simple pair
} else {
error << string_compose (_("Cannot get I/O configuration info for AU %1"), info->name) << endmsg;
}
-
+
comp = FindNextComponent (comp, &desc);
}
}
bool
-AUPluginInfo::cached_io_configuration (const std::string& unique_id,
+AUPluginInfo::cached_io_configuration (const std::string& unique_id,
UInt32 version,
- CAComponent& comp,
- AUPluginCachedInfo& cinfo,
+ CAComponent& comp,
+ AUPluginCachedInfo& cinfo,
const std::string& name)
{
std::string id;
AUChannelInfo* channel_info;
UInt32 cnt;
int ret;
-
+
ARDOUR::BootMessage (string_compose (_("Checking AudioUnit: %1"), name));
-
+
try {
if (CAAudioUnit::Open (comp, unit) != noErr) {
return false;
}
-
+
TRACE_API ("get AU channel info\n");
if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
return false;
cinfo.io_configs.push_back (pair<int,int> (-1, -1));
} else {
-
+
/* store each configuration */
-
+
for (uint32_t n = 0; n < cnt; ++n) {
cinfo.io_configs.push_back (pair<int,int> (channel_info[n].inChannels,
channel_info[n].outChannels));
node = new XMLNode (X_("AudioUnitPluginCache"));
node->add_property( "version", AU_CACHE_VERSION );
-
+
for (map<string,AUPluginCachedInfo>::iterator i = cached_info.begin(); i != cached_info.end(); ++i) {
XMLNode* parent = new XMLNode (X_("plugin"));
parent->add_property ("id", i->first);
{
Glib::ustring path = au_cache_path ();
XMLTree tree;
-
+
if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
return 0;
}
error << "au_cache is not a valid XML file. AU plugins will be re-scanned" << endmsg;
return -1;
}
-
+
const XMLNode* root (tree.root());
if (root->name() != X_("AudioUnitPluginCache")) {
return -1;
}
-
+
//initial version has incorrectly stored i/o info, and/or garbage chars.
const XMLProperty* version = root->property(X_("version"));
if (! ((version != NULL) && (version->value() == X_(AU_CACHE_VERSION)))) {
error << "au_cache is not correct version. AU plugins will be re-scanned" << endmsg;
return -1;
}
-
+
cached_info.clear ();
const XMLNodeList children = root->children();
for (XMLNodeConstIterator iter = children.begin(); iter != children.end(); ++iter) {
-
+
const XMLNode* child = *iter;
-
+
if (child->name() == X_("plugin")) {
const XMLNode* gchild;
if (!prop) {
continue;
}
-
+
string id = prop->value();
string fixed;
string version;
if (fixed.empty()) {
error << string_compose (_("Your AudioUnit configuration cache contains an AU plugin whose ID cannot be understood - ignored (%1)"), id) << endmsg;
continue;
- }
+ }
id = fixed;
id += version;
((oprop = gchild->property (X_("out"))) != 0)) {
in = atoi (iprop->value());
out = atoi (oprop->value());
-
+
cinfo.io_configs.push_back (pair<int,int> (in, out));
}
}
DisposeHandle(nameHandle);
}
}
-
+
// if Marc-style fails, do the original way
if (itemName == NULL) {
CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType);
CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType);
CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer);
-
- itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
+
+ itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
compTypeString, compManufacturerString, compSubTypeString);
-
+
if (compTypeString != NULL)
CFRelease(compTypeString);
if (compSubTypeString != NULL)
if (compManufacturerString != NULL)
CFRelease(compManufacturerString);
}
-
+
string str = CFStringRefToStdString(itemName);
string::size_type colon = str.find (':');
} else {
jack_on_shutdown (_priv_jack, halted, this);
}
-
+
jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
jack_set_process_thread (_priv_jack, _process_thread, this);
jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
}
-#ifdef HAVE_JACK_SESSION
+#ifdef HAVE_JACK_SESSION
if( jack_set_session_callback)
jack_set_session_callback (_priv_jack, _session_callback, this);
#endif
* this is reliable, but not clean.
*/
- if (!jack_port_type_get_buffer_size) {
+ if (!jack_port_type_get_buffer_size) {
jack_bufsize_callback (blocksize);
}
}
++i;
}
-
+
ae->PortConnectedOrDisconnected (port_a, port_b, conn == 0 ? false : true); /* EMIT SIGNAL */
}
void*
AudioEngine::process_thread ()
{
- /* JACK doesn't do this for us when we use the wait API
+ /* JACK doesn't do this for us when we use the wait API
*/
_thread_init_callback (0);
if (_freewheeling && !Freewheel.empty()) {
- /* emit the Freewheel signal and stop freewheeling in the event of trouble
+ /* emit the Freewheel signal and stop freewheeling in the event of trouble
*/
boost::optional<int> r = Freewheel (nframes);
if (r.get_value_or (0)) {
} else {
/* Old version of JACK.
-
+
These crude guesses, see below where we try to get the right answers.
-
+
Note that our guess for MIDI deliberatey tries to overestimate
by a little. It would be nicer if we could get the actual
- size from a port, but we have to use this estimate in the
+ size from a port, but we have to use this estimate in the
event that there are no MIDI ports currently. If there are
the value will be adjusted below.
*/
-
+
_raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
_raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
}
- {
+ {
Glib::Mutex::Lock lm (_process_lock);
-
+
boost::shared_ptr<Ports> p = ports.reader();
-
+
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
(*i)->reset();
}
AudioEngine::set_session (Session *s)
{
Glib::Mutex::Lock pl (_process_lock);
-
+
SessionHandlePtr::set_session (s);
if (_session) {
start_metering_thread ();
-
+
pframes_t blocksize = jack_get_buffer_size (_jack);
-
+
/* page in as much of the session process code as we
can before we really start running.
*/
-
+
boost::shared_ptr<Ports> p = ports.reader();
-
+
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
(*i)->cycle_start (blocksize);
}
-
+
_session->process (blocksize);
_session->process (blocksize);
_session->process (blocksize);
_session->process (blocksize);
_session->process (blocksize);
_session->process (blocksize);
-
+
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
(*i)->cycle_end (blocksize);
}
}
-}
+}
void
AudioEngine::remove_session ()
AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
{
/* called from jack shutdown handler */
-
+
AudioEngine* ae = static_cast<AudioEngine *> (arg);
bool was_running = ae->_running;
-
+
ae->stop_metering_thread ();
-
+
ae->_running = false;
ae->_buffer_size = 0;
ae->_frame_rate = 0;
ae->_jack = 0;
-
+
if (was_running) {
#ifdef HAVE_JACK_ON_INFO_SHUTDOWN
switch (code) {
AudioEngine::n_physical (unsigned long flags) const
{
ChanCount c;
-
+
GET_PRIVATE_JACK_POINTER_RET (_jack, c);
const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
if (onoff != _freewheeling) {
return jack_set_freewheel (_priv_jack, onoff);
-
+
} else {
/* already doing what has been asked for */
return 0;
/* make sure that JACK callbacks that will be invoked as we cleanup
* ports know that they have nothing to do.
*/
-
+
port_remove_in_progress = true;
/* process lock MUST be held by caller
GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
MIDI::Manager::instance()->reestablish (_priv_jack);
-
+
if (_session) {
_session->reset_jack_connection (_priv_jack);
jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
}
last_monitor_check = 0;
-
+
set_jack_callbacks ();
if (jack_activate (_priv_jack) == 0) {
if (nframes == jack_get_buffer_size (_priv_jack)) {
return 0;
}
-
+
return jack_set_buffer_size (_priv_jack, nframes);
}
GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
ThreadData* td = new ThreadData (this, f, stacksize);
- if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
+ if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
jack_is_realtime (_priv_jack), _start_process_thread, td)) {
return -1;
- }
+ }
return 0;
}
return 0;
}
-bool
+bool
AudioEngine::port_is_physical (const std::string& portname) const
{
GET_PRIVATE_JACK_POINTER_RET(_jack, false);
if (!port) {
return false;
}
-
+
return jack_port_flags (port) & JackPortIsPhysical;
}
-void
+void
AudioEngine::ensure_monitor_input (const std::string& portname, bool yn) const
{
GET_PRIVATE_JACK_POINTER(_jack);
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor ();
}
-
+
if (init (_path, must_exist)) {
throw failed_constructor ();
}
if (SndFileSource::get_soundfile_info (path, _info, error_msg) != 0) {
return true;
}
-
+
#ifdef HAVE_COREAUDIO
if (CoreAudioSource::get_soundfile_info (path, _info, error_msg) == 0) {
return true;
, _fade_in_active (Properties::fade_in_active, true) \
, _fade_out_active (Properties::fade_out_active, true) \
, _scale_amplitude (Properties::scale_amplitude, 1.0)
-
+
#define AUDIOREGION_COPY_STATE(other) \
_envelope_active (Properties::envelope_active, other->_envelope_active) \
, _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
if (_left_of_split) {
if (_fade_in->back()->when >= _length) {
set_default_fade_in ();
- }
+ }
set_default_fade_out ();
_left_of_split = false;
}
if (_right_of_split) {
if (_fade_out->back()->when >= _length) {
set_default_fade_out ();
- }
+ }
set_default_fade_in ();
_right_of_split = false;
framecnt_t
AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
- framepos_t position,
+ framepos_t position,
framecnt_t cnt,
uint32_t chan_n,
framecnt_t /*read_frames*/,
if (Config->get_replicate_missing_region_channels()) {
/* track is N-channel, this region has less channels, so use a relevant channel
*/
-
+
uint32_t channel = n_channels() % chan_n;
boost::shared_ptr<AudioSource> src = audio_source (channel);
child = node.add_child ("Envelope");
bool default_env = false;
-
+
// If there are only two points, the points are in the start of the region and the end of the region
// so, if they are both at 1.0f, that means the default region.
-
+
if (_envelope->size() == 2 &&
_envelope->front()->value == 1.0f &&
_envelope->back()->value==1.0f) {
default_env = true;
}
}
-
+
if (default_env) {
child->add_property ("default", "yes");
} else {
const XMLNodeList& nlist = node.children();
const XMLProperty *prop;
LocaleGuard lg (X_("POSIX"));
- boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
+ boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
suspend_property_changes ();
_fade_in->freeze ();
*_fade_in = *f;
_fade_in->thaw ();
-
+
send_change (PropertyChange (Properties::fade_in));
}
_envelope->truncate_end (_length);
_envelope->set_max_xval (_length);
_envelope->thaw ();
-
+
suspend_property_changes();
if (_left_of_split) {
_fade_in->extend_to (_length);
send_change (PropertyChange (Properties::fade_in));
}
-
+
resume_property_changes();
}
/* as above, but the shift was from the front */
_envelope->truncate_start (_length);
-
+
suspend_property_changes();
if (_right_of_split) {
_fade_out->extend_to (_length);
send_change (PropertyChange (Properties::fade_out));
}
-
+
resume_property_changes();
}
*/
PropertyList plist;
-
+
plist.add (Properties::start, _start.val());
plist.add (Properties::length, _length.val());
plist.add (Properties::name, new_name);
framecnt_t const blocksize = 64 * 1024;
Sample buf[blocksize];
-
+
while (fpos < fend) {
uint32_t n;
return boost::dynamic_pointer_cast<AudioSource>(source(n));
}
-int
+int
AudioRegion::adjust_transients (frameoffset_t delta)
{
for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
(*x) = (*x) + delta;
}
-
+
send_change (PropertyChange (Properties::valid_transients));
-
- return 0;
-}
+
+ return 0;
+}
int
AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
if ((*x) == old_position) {
(*x) = new_position;
send_change (PropertyChange (Properties::valid_transients));
-
+
break;
}
}
-
+
return 0;
}
{
_transients.push_back(where);
_valid_transients = true;
-
+
send_change (PropertyChange (Properties::valid_transients));
}
{
_transients.remove(where);
_valid_transients = true;
-
+
send_change (PropertyChange (Properties::valid_transients));
}
_transients.clear();
_transients = results;
_valid_transients = true;
-
+
send_change (PropertyChange (Properties::valid_transients));
-
+
return 0;
}
*/
const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0);
-
+
staging = new PeakData[chunksize];
/* compute the rounded up frame position */
adjusting zero_fill and npeaks and then breaking out of
this loop early
*/
-
+
memset (raw_staging, 0, sizeof (Sample) * chunksize);
-
+
} else {
-
+
to_read = min (chunksize, (_length - current_frame));
-
-
+
+
if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
_name, to_read, current_frame, _length, strerror (errno))
goto out;
}
}
-
+
i = 0;
}
if (val < _read_data_count) {
_read_data_count -= val;
- } else {
+ } else {
_read_data_count = 0;
}
}
AudioSource::allocate_working_buffers (framecnt_t framerate)
{
Glib::Mutex::Lock lm (_level_buffer_lock);
-
-
+
+
/* Note: we don't need any buffers allocated until
a level 1 audiosource is created, at which
time we'll call ::ensure_buffers_for_level()
with the right value and do the right thing.
*/
-
+
if (!_mixdown_buffers.empty()) {
ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
}
}
void
-AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
+AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
{
Glib::Mutex::Lock lm (_level_buffer_lock);
ensure_buffers_for_level_locked (level, frame_rate);
}
void
-AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
+AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
{
framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
/* force a panner reset now that we have all channels */
- _main_outs->panner_shell()->configure_io (ChanCount (DataType::AUDIO, _diskstream->n_channels().n_audio()),
+ _main_outs->panner_shell()->configure_io (ChanCount (DataType::AUDIO, _diskstream->n_channels().n_audio()),
ChanCount (DataType::AUDIO, n_outputs().n_audio()));
g_atomic_int_set (&_auditioning, 1);
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (configure_processors (&ps)) {
- error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
+ error << string_compose (_("Cannot setup auditioner processing flow for %1 channels"),
_diskstream->n_channels()) << endmsg;
return;
}
}
}
-ChanCount
+ChanCount
Auditioner::input_streams () const
{
/* auditioner never has any inputs - its channel configuration
if (audio_diskstream()) {
return audio_diskstream()->n_channels();
- }
+ }
return ChanCount ();
}
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (ac->list ());
assert (al);
-
+
al->automation_state_changed.connect_same_thread (
_list_connections, boost::bind (&Automatable::automation_list_automation_state_changed, this, ac->parameter(), _1)
);
}
-
+
if (!id_prop) {
warning << "AutomationList node without automation-id property, "
<< "using default: " << EventTypeMap::instance().to_symbol(legacy_param) << endmsg;
if (c) {
boost::shared_ptr<AutomationList> l
= boost::dynamic_pointer_cast<AutomationList>(c->list());
-
+
if (l) {
/* Stop any active touch gesture just before we mark the write pass
as finished. If we don't do this, the transport can end up stopped with
*/
l->stop_touch (true, now);
l->write_pass_finished (now);
-
+
if (l->automation_playback()) {
c->set_value(c->list()->eval(now));
}
-
+
if (l->automation_state() == Write) {
l->set_automation_state (Touch);
}
{
bool to_list = _list && _session.transport_stopped()
&& ((AutomationList*)_list.get())->automation_write();
-
+
if (to_list && parameter().toggled()) {
- // store the previous value just before this so any
+ // store the previous value just before this so any
// interpolation works right
-
+
_list->add (get_double(), _session.transport_frame()-1);
}
*/
return;
}
-
+
g_atomic_int_set (&_touching, 0);
if (_state == Touch) {
assert (!nascent.empty ());
Glib::Mutex::Lock lm (ControlList::_lock);
-
+
if (mark) {
nascent.back()->end_time = when;
-
+
} else {
-
+
/* nascent info created in start touch but never used. just get rid of it.
*/
}
bool have_events = false;
-
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == X_("events")) {
deserialize_events (*(*niter));
BeatsFramesConverter::to (double beats) const
{
assert (beats >= 0);
-
+
return _tempo_map.framepos_plus_bbt (_origin_b, Timecode::BBT_Time(beats)) - _origin_b;
}
BroadcastInfo::BroadcastInfo ()
{
-
+
}
void
thread_buffers = new ThreadBufferFIFO (size+1); // must be one larger than requested
thread_buffers_list = new ThreadBufferList;
- /* and populate with actual ThreadBuffers
+ /* and populate with actual ThreadBuffers
*/
- for (uint32_t n = 0; n < size; ++n) {
+ for (uint32_t n = 0; n < size; ++n) {
ThreadBuffers* ts = new ThreadBuffers;
thread_buffers->write (&ts, 1);
thread_buffers_list->push_back (ts);
_count.reset();
_available.reset();
-#ifdef VST_SUPPORT
+#ifdef VST_SUPPORT
for (VSTBuffers::iterator i = _vst_buffers.begin(); i != _vst_buffers.end(); ++i) {
delete *i;
}
_vst_buffers.clear ();
-#endif
+#endif
}
/** Set up this BufferSet so that its data structures mirror a PortSet's buffers.
_vst_buffers.push_back (new VSTBuffer (buffer_capacity));
}
}
-#endif
+#endif
// Post-conditions
assert(bufs[0]->type() == type);
BufferSet::get_lv2_midi(bool input, size_t i)
{
assert (count().get(DataType::MIDI) > i);
-
+
MidiBuffer& mbuf = get_midi(i);
LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
LV2EventBuffer* ebuf = b.second;
for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) {
const Evoral::MIDIEvent<framepos_t> ev(*e, false);
uint32_t type = LV2Plugin::midi_event_type();
-#ifndef NDEBUG
+#ifndef NDEBUG
DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("(FLUSH) MIDI event of size %1\n", ev.size()));
for (uint16_t x = 0; x < ev.size(); ++x) {
DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("\tByte[%1] = %2\n", x, (int) ev.buffer()[x]));
uint16_t size;
uint8_t* data;
ebuf->get_event(&frames, &subframes, &type, &size, &data);
-#ifndef NDEBUG
+#ifndef NDEBUG
DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("(FLUSH) MIDI event of size %1\n", size));
for (uint16_t x = 0; x < size; ++x) {
DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("\tByte[%1] = %2\n", x, (int) data[x]));
for (MidiBuffer::iterator i = m.begin(); i != m.end(); ++i) {
vst->push_back (*i);
}
-
+
return vst->events();
}
_events->events[n] = reinterpret_cast<VstEvent*> (_midi_events + n);
VstMidiEvent* v = reinterpret_cast<VstMidiEvent*> (_events->events[n]);
-
+
v->type = kVstMidiType;
v->byteSize = sizeof (VstMidiEvent);
v->deltaFrames = ev.time ();
(*b)->is_silent (yn);
}
}
-
+
}
} // namespace ARDOUR
Glib::Mutex::Lock lm (_channel_mutex);
return _channel[c].type;
-}
+}
ostream &
operator<< (ostream& os, Bundle const & b)
bytes = 0;
compute_io = true;
-restart:
+restart:
disk_work_outstanding = false;
-
+
if (transport_work_requested()) {
_session.butler_transport_work ();
}
if (!tr) {
continue;
}
-
+
/* note that we still try to flush diskstreams attached to inactive routes
*/
Butler::empty_pool_trash ()
{
/* look in the trash, deleting empty pools until we come to one that is not empty */
-
+
RingBuffer<CrossThreadPool*>::rw_vector vec;
pool_trash.get_read_vector (&vec);
guint deleted = 0;
-
+
for (int i = 0; i < 2; ++i) {
for (guint j = 0; j < vec.len[i]; ++j) {
if (vec.buf[i][j]->empty()) {
void
call_the_mothership (const string& version)
{
- /* check if the user says never to do this
+ /* check if the user says never to do this
*/
if (mothership_blocked()) {
if (uname (&utb)) {
return;
}
-
+
curl_global_init (CURL_GLOBAL_NOTHING);
c = curl_easy_init ();
if (!wm.empty()) {
data += string_compose ("&watermark=%1", wm);
}
-
+
curl_easy_setopt(c, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(c, CURLOPT_URL, PING_URL);
- curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, curl_write_data);
- curl_easy_setopt(c, CURLOPT_WRITEDATA, &versionstr);
-
+ curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, curl_write_data);
+ curl_easy_setopt(c, CURLOPT_WRITEDATA, &versionstr);
+
std::cerr << "Callback to ardour.org ...\n";
char errbuf[CURL_ERROR_SIZE];
- curl_easy_setopt(c, CURLOPT_ERRORBUFFER, errbuf);
+ curl_easy_setopt(c, CURLOPT_ERRORBUFFER, errbuf);
if (curl_easy_perform (c) == 0) {
cerr << "Current release is " << versionstr << endl;
vector<string> ours;
vector<string> current;
-
+
split (version, ours, '.');
split (versionstr, current, '.');
-
+
if (ours.size() == 3 && current.size() == 3) {
int ours_n[3];
current_n[2] = atoi (current[2]);
if (ours_n[0] < current_n[0] ||
- ((ours_n[0] == current_n[0]) && (ours_n[1] < current_n[1])) ||
+ ((ours_n[0] == current_n[0]) && (ours_n[1] < current_n[1])) ||
((ours_n[0] == current_n[0]) && (ours_n[1] == current_n[1]) && (ours_n[2] < current_n[2]))) {
cerr << "TOO OLD\n";
} else {
cerr << "Unusual local version: " << version << endl;
}
}
-
+
curl_easy_cleanup (c);
}
node.add_property (X_("type"), X_("capture"));
return node;
}
-
+
} // namespace ARDOUR
if ((*i)->requested || (*i)->mandatory) {
instantiate (**i);
(*i)->requested = false;
-
+
if ((*i)->protocol && (*i)->state) {
(*i)->protocol->set_state (*(*i)->state, Stateful::loading_state_version);
}
*/
r = RegionFactory::region_by_id (id);
}
-
+
if (!r) {
error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2 nor in region map"), id, playlist.name())
<< endmsg;
if (!r) {
r = RegionFactory::region_by_id (id2);
}
-
+
if (!r) {
error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2 nor in region map"), id2, playlist.name())
<< endmsg;
for (SourceList::iterator i = _sources.begin(); i != _sources.end(); ++i) {
(*i)->inc_use_count ();
}
-
+
_master_sources = _in->master_sources();
_master_sources.insert(_master_sources.end(), _out->master_sources().begin(), _out->master_sources().end());
Sample* mixdown = new Sample[cnt];
float* gain = new float[cnt];
framecnt_t ret;
-
+
ret = read_at (buf, mixdown, gain, start, cnt, channel, cnt);
delete [] mixdown;
Invalidated (shared_from_this());
return false;
}
-
+
/* regions must cannot be identically sized and placed */
if (_in->position() == _out->position() && _in->length() == _out->length()) {
_length = len;
PropertyChanged (PropertyChange (Properties::length));
-
+
return len;
}
/* deliver to an existing IO object */
-Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
+Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
: IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name)
, _role (r)
Delivery::~Delivery()
{
- DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
+ DEBUG_TRACE (DEBUG::Destruction, string_compose ("delivery %1 destructor\n", _name));
delete _output_buffers;
}
}
}
-
+
if (!Processor::configure_io (in, out)) {
return false;
}
#endif
if (panner && !panner->bypassed()) {
-
+
// Use the panner to distribute audio to output port buffers
_panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
/* io_lock, not taken: function must be called from Session::process() calltree */
PortSet& ports (_output->ports());
-
+
for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
(*i).flush_buffers (nframes, time);
}
if (_output) {
PortSet& ports (_output->ports());
-
+
for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
(*i).transport_stopped ();
}
{
if (_output) {
PortSet& ports (_output->ports());
-
+
for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
(*i).realtime_locate ();
}
}
MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
-
+
switch (_role) {
case Main:
mp = MuteMaster::Main;
}
gain_t desired_gain = _mute_master->mute_gain_at (mp);
-
+
if (_role == Listen && _session.monitor_out() && !_session.listening()) {
-
+
/* nobody is soloed, and this delivery is a listen-send to the
control/monitor/listen bus, we should be silent since
it gets its signal from the master out.
*/
-
+
desired_gain = 0.0;
-
- }
+
+ }
return desired_gain;
}
if (capture_info.size() > n) {
/* this is a completed capture */
return capture_info[n]->frames;
- } else {
+ } else {
/* this is the currently in-progress capture */
return capture_captured;
}
if (_extra_xml) {
node->add_child_copy (*_extra_xml);
}
-
+
return *node;
}
automation undo (it must, since automation-follows-regions
can lose automation data). Hence we can do nothing here.
*/
-
+
if (from_undo) {
return;
}
-
+
if (!_track || Config->get_automation_follows_regions () == false) {
return;
}
/* move panner automation */
boost::shared_ptr<Pannable> pannable = _track->pannable();
Evoral::ControlSet::Controls& c (pannable->controls());
-
+
for (Evoral::ControlSet::Controls::iterator ci = c.begin(); ci != c.end(); ++ci) {
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
if (!ac) {
continue;
}
boost::shared_ptr<AutomationList> alist = ac->alist();
-
+
XMLNode & before = alist->get_state ();
bool const things_moved = alist->move_ranges (movements);
if (things_moved) {
name(), first_recordable_frame, last_recordable_frame, capture_start_frame,
_capture_offset,
existing_material_offset,
- transport_frame,
+ transport_frame,
_roll_delay,
_session.transport_frame(),
_session.worst_output_latency(),
_session.worst_track_latency()));
-
+
if (_alignment_style == ExistingMaterial) {
first_recordable_frame += existing_material_offset;
DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tshift FRF by EMO %1\n",
first_recordable_frame));
- }
-
+ }
+
prepare_record_status (capture_start_frame);
} else {
if (last_possibly_recording == fully_rec_enabled) {
/* we were recording last time */
-
+
if (change & transport_rolling) {
/* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop(). We
had to set it there because we likely rolled past the stopping point to declick out,
and then backed up.
*/
-
+
} else {
/* punch out */
-
+
last_recordable_frame = _session.transport_frame() + _capture_offset;
-
+
if (_alignment_style == ExistingMaterial) {
last_recordable_frame += existing_material_offset;
- }
+ }
}
}
}
}
DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
- _name, enum_2_string (ot), transport_frame, nframes,
+ _name, enum_2_string (ot), transport_frame, nframes,
first_recordable_frame, last_recordable_frame, rec_nframes, rec_offset));
}
REGISTER_ENUM (MoveAddHigher);
REGISTER_ENUM (AddHigher);
REGISTER (_LayerModel);
-
+
REGISTER_ENUM (InsertMergeReject);
REGISTER_ENUM (InsertMergeRelax);
REGISTER_ENUM (InsertMergeReplace);
REGISTER_CLASS_ENUM (MidiModel::PatchChangeDiffCommand, Program);
REGISTER_CLASS_ENUM (MidiModel::PatchChangeDiffCommand, Bank);
REGISTER (_MidiModel_PatchChangeDiffCommand_Property);
-
+
REGISTER_ENUM(Linear);
REGISTER_ENUM(Logarithmic);
REGISTER(_WaveformScale);
/* deserializing types from ardour/types.h */
-std::istream& operator>>(std::istream& o, HeaderFormat& var)
-{
+std::istream& operator>>(std::istream& o, HeaderFormat& var)
+{
std::string s;
o >> s;
var = (HeaderFormat) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const HeaderFormat& var)
-{
+std::ostream& operator<<(std::ostream& o, const HeaderFormat& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, SampleFormat& var)
-{
+std::istream& operator>>(std::istream& o, SampleFormat& var)
+{
std::string s;
o >> s;
var = (SampleFormat) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const SampleFormat& var)
-{
+std::ostream& operator<<(std::ostream& o, const SampleFormat& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, AutoConnectOption& var)
-{
+std::istream& operator>>(std::istream& o, AutoConnectOption& var)
+{
std::string s;
o >> s;
var = (AutoConnectOption) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const AutoConnectOption& var)
-{
+std::ostream& operator<<(std::ostream& o, const AutoConnectOption& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, MonitorModel& var)
-{
+std::istream& operator>>(std::istream& o, MonitorModel& var)
+{
std::string s;
o >> s;
var = (MonitorModel) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const MonitorModel& var)
-{
+std::ostream& operator<<(std::ostream& o, const MonitorModel& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, PFLPosition& var)
-{
+std::istream& operator>>(std::istream& o, PFLPosition& var)
+{
std::string s;
o >> s;
var = (PFLPosition) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const PFLPosition& var)
-{
+std::ostream& operator<<(std::ostream& o, const PFLPosition& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, AFLPosition& var)
-{
+std::istream& operator>>(std::istream& o, AFLPosition& var)
+{
std::string s;
o >> s;
var = (AFLPosition) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const AFLPosition& var)
-{
+std::ostream& operator<<(std::ostream& o, const AFLPosition& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, RemoteModel& var)
+std::istream& operator>>(std::istream& o, RemoteModel& var)
{
std::string s;
o >> s;
return o;
}
-std::ostream& operator<<(std::ostream& o, const RemoteModel& var)
+std::ostream& operator<<(std::ostream& o, const RemoteModel& var)
{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, EditMode& var)
-{
+std::istream& operator>>(std::istream& o, EditMode& var)
+{
std::string s;
o >> s;
var = (EditMode) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const EditMode& var)
-{
+std::ostream& operator<<(std::ostream& o, const EditMode& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, ListenPosition& var)
-{
+std::istream& operator>>(std::istream& o, ListenPosition& var)
+{
std::string s;
o >> s;
var = (ListenPosition) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const ListenPosition& var)
-{
+std::ostream& operator<<(std::ostream& o, const ListenPosition& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, LayerModel& var)
-{
+std::istream& operator>>(std::istream& o, LayerModel& var)
+{
std::string s;
o >> s;
var = (LayerModel) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const LayerModel& var)
-{
+std::ostream& operator<<(std::ostream& o, const LayerModel& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, InsertMergePolicy& var)
-{
+std::istream& operator>>(std::istream& o, InsertMergePolicy& var)
+{
std::string s;
o >> s;
var = (InsertMergePolicy) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const InsertMergePolicy& var)
-{
+std::ostream& operator<<(std::ostream& o, const InsertMergePolicy& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, CrossfadeModel& var)
-{
+std::istream& operator>>(std::istream& o, CrossfadeModel& var)
+{
std::string s;
o >> s;
var = (CrossfadeModel) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const CrossfadeModel& var)
-{
+std::ostream& operator<<(std::ostream& o, const CrossfadeModel& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, SyncSource& var)
-{
+std::istream& operator>>(std::istream& o, SyncSource& var)
+{
std::string s;
o >> s;
var = (SyncSource) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const SyncSource& var)
-{
+std::ostream& operator<<(std::ostream& o, const SyncSource& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, ShuttleBehaviour& var)
-{
+std::istream& operator>>(std::istream& o, ShuttleBehaviour& var)
+{
std::string s;
o >> s;
var = (ShuttleBehaviour) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const ShuttleBehaviour& var)
-{
+std::ostream& operator<<(std::ostream& o, const ShuttleBehaviour& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, ShuttleUnits& var)
-{
+std::istream& operator>>(std::istream& o, ShuttleUnits& var)
+{
std::string s;
o >> s;
var = (ShuttleUnits) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const ShuttleUnits& var)
-{
+std::ostream& operator<<(std::ostream& o, const ShuttleUnits& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, TimecodeFormat& var)
-{
+std::istream& operator>>(std::istream& o, TimecodeFormat& var)
+{
std::string s;
o >> s;
var = (TimecodeFormat) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const TimecodeFormat& var)
-{
+std::ostream& operator<<(std::ostream& o, const TimecodeFormat& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, DenormalModel& var)
-{
+std::istream& operator>>(std::istream& o, DenormalModel& var)
+{
std::string s;
o >> s;
var = (DenormalModel) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const DenormalModel& var)
-{
+std::ostream& operator<<(std::ostream& o, const DenormalModel& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, WaveformScale& var)
-{
+std::istream& operator>>(std::istream& o, WaveformScale& var)
+{
std::string s;
o >> s;
var = (WaveformScale) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const WaveformScale& var)
-{
+std::ostream& operator<<(std::ostream& o, const WaveformScale& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, WaveformShape& var)
-{
+std::istream& operator>>(std::istream& o, WaveformShape& var)
+{
std::string s;
o >> s;
var = (WaveformShape) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const WaveformShape& var)
-{
+std::ostream& operator<<(std::ostream& o, const WaveformShape& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
-std::istream& operator>>(std::istream& o, PositionLockStyle& var)
-{
+std::istream& operator>>(std::istream& o, PositionLockStyle& var)
+{
std::string s;
o >> s;
var = (PositionLockStyle) string_2_enum (s, var);
return o;
}
-std::ostream& operator<<(std::ostream& o, const PositionLockStyle& var)
-{
+std::ostream& operator<<(std::ostream& o, const PositionLockStyle& var)
+{
std::string s = enum_2_string (var);
return o << s;
}
data = (*ports.begin())->get_audio_buffer(frames).data();
return;
}
-
+
memset (buffer.get(), 0, frames * sizeof (Sample));
for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
ExportChannelConfiguration::configurations_for_files (std::list<boost::shared_ptr<ExportChannelConfiguration> > & configs)
{
configs.clear ();
-
+
if (!split) {
configs.push_back (shared_from_this ());
return;
}
-
+
for (ChannelList::const_iterator it = channels.begin (); it != channels.end (); ++it) {
boost::shared_ptr<ExportChannelConfiguration> config (new ExportChannelConfiguration (session));
config->set_name (_name);
int diff = 0;
int smallest_diff = INT_MAX;
SampleRate best_match = SR_None;
-
+
#define DO_SR_COMPARISON(rate) \
diff = std::abs((rate) - sample_rate); \
if(diff < smallest_diff) { \
DO_SR_COMPARISON(SR_88_2);
DO_SR_COMPARISON(SR_96);
DO_SR_COMPARISON(SR_192);
-
+
return best_match;
#undef DO_SR_COMPARISON
}
fl_ptr->add_sample_format (ExportFormatBase::SF_32);
fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
- fl_ptr->add_endianness (ExportFormatBase::E_Big);
+ fl_ptr->add_endianness (ExportFormatBase::E_Big);
fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
fl_ptr->set_extension ("aiff");
add_format (f_ptr);
fl_ptr->add_sample_format (ExportFormatBase::SF_32);
fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
- fl_ptr->add_endianness (ExportFormatBase::E_Little);
+ fl_ptr->add_endianness (ExportFormatBase::E_Little);
fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
fl_ptr->set_extension ("wav");
add_format (f_ptr);
set_silence_beginning (other.silence_beginning_time());
set_silence_end (other.silence_end_time());
-
+
set_extension(other.extension());
}
ExportGraphBuilder::process (framecnt_t frames, bool last_cycle)
{
assert(frames <= process_buffer_frames);
-
+
for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) {
Sample const * process_buffer = 0;
it->first->read (process_buffer, frames);
if (last_cycle) { context().set_flag (ProcessContext<Sample>::EndOfInput); }
it->second->process (context);
}
-
+
return 0;
}
++it;
}
}
-
+
return normalizers.empty();
}
framecnt_t session_rate = session.nominal_frame_rate();
new_config.format->set_sample_rate(ExportFormatBase::nearest_sample_rate(session_rate));
}
-
-
+
+
if (!new_config.channel_config->get_split ()) {
add_split_config (new_config);
return;
}
-
+
// Split channel configurations are split into several channel configurations,
// each corresponding to a file, at this stage
typedef std::list<boost::shared_ptr<ExportChannelConfiguration> > ConfigList;
ConfigList file_configs;
new_config.channel_config->configurations_for_files (file_configs);
-
+
unsigned chan = 1;
for (ConfigList::iterator it = file_configs.begin(); it != file_configs.end(); ++it, ++chan) {
FileSpec copy = new_config;
copy.channel_config = *it;
-
+
copy.filename.reset (new ExportFilename (*copy.filename));
copy.filename->include_channel = true;
copy.filename->set_channel (chan);
-
+
add_split_config (copy);
}
}
return;
}
}
-
+
// No duplicate channel config found, create new one
channel_configs.push_back (new ChannelConfig (*this, config, channels));
}
int format = get_real_format (config);
config.filename->set_channel_config(config.channel_config);
string filename = config.filename->get_path (config.format);
-
+
writer.reset (new AudioGrapher::SndfileWriter<T> (filename, format, channels, config.format->sample_rate(), config.broadcast_info));
writer->FileWritten.connect_same_thread (copy_files_connection, boost::bind (&ExportGraphBuilder::Encoder::copy_files, this, _1));
}
config = new_config;
data_width = sndfile_data_width (Encoder::get_real_format (config));
unsigned channels = new_config.channel_config->get_n_chans();
-
+
if (data_width == 8 || data_width == 16) {
short_converter = ShortConverterPtr (new SampleFormatConverter<short> (channels));
short_converter->init (max_frames, config.format->dither_type(), data_width);
return;
}
}
-
+
children.push_back (new Encoder());
Encoder & encoder = children.back();
-
+
if (data_width == 8 || data_width == 16) {
short_converter->add_output (encoder.init<short> (new_config));
} else if (data_width == 24 || data_width == 32) {
{
config = new_config;
max_frames_out = 4086; // TODO good chunk size
-
+
buffer.reset (new AllocatingProcessContext<Sample> (max_frames_out, config.channel_config->get_n_chans()));
peak_reader.reset (new PeakReader ());
normalizer.reset (new AudioGrapher::Normalizer (config.format->normalize_target()));
threader.reset (new Threader<Sample> (parent.thread_pool));
-
+
normalizer->alloc_buffer (max_frames_out);
normalizer->add_output (threader);
-
+
int format = ExportFormatBase::F_RAW | ExportFormatBase::SF_Float;
- tmp_file.reset (new TmpFile<float> (format, config.channel_config->get_n_chans(),
+ tmp_file.reset (new TmpFile<float> (format, config.channel_config->get_n_chans(),
config.format->sample_rate()));
tmp_file->FileWritten.connect_same_thread (post_processing_connection, boost::bind (&Normalizer::start_post_processing, this));
-
+
add_child (new_config);
-
+
peak_reader->add_output (tmp_file);
}
return;
}
}
-
+
children.push_back (new SFC (parent, new_config, max_frames_out));
threader->add_output (children.back().sink());
}
ExportFormatSpecification & format = *new_config.format;
converter->init (parent.session.nominal_frame_rate(), format.sample_rate(), format.src_quality());
max_frames_out = converter->allocate_buffers (max_frames);
-
+
add_child (new_config);
}
return;
}
}
-
+
list.push_back (new T (parent, new_config, max_frames_out));
converter->add_output (list.back().sink ());
}
config = new_config;
max_frames_in = max_frames;
framecnt_t sample_rate = parent.session.nominal_frame_rate();
-
+
silence_trimmer.reset (new SilenceTrimmer<Sample>(max_frames_in));
silence_trimmer->set_trim_beginning (config.format->trim_beginning());
silence_trimmer->set_trim_end (config.format->trim_end());
-
+
framecnt_t sb = config.format->silence_beginning_at (parent.timespan->get_start(), sample_rate);
framecnt_t se = config.format->silence_end_at (parent.timespan->get_end(), sample_rate);
-
+
silence_trimmer->add_silence_to_beginning (sb);
silence_trimmer->add_silence_to_end (se);
-
+
add_child (new_config);
}
return;
}
}
-
+
children.push_back (new SRC (parent, new_config, max_frames_in));
silence_trimmer->add_output (children.back().sink());
}
: parent (parent)
{
typedef ExportChannelConfiguration::ChannelList ChannelList;
-
+
config = new_config;
max_frames = parent.session.engine().frames_per_cycle();
-
+
interleaver.reset (new Interleaver<Sample> ());
interleaver->init (new_config.channel_config->get_n_chans(), max_frames);
-
+
ChannelList const & channel_list = config.channel_config->get_channels();
unsigned chan = 0;
for (ChannelList::const_iterator it = channel_list.begin(); it != channel_list.end(); ++it, ++chan) {
}
map_it->second->add_output (interleaver->input (chan));
}
-
+
add_child (new_config);
}
return;
}
}
-
+
framecnt_t const max_frames_out = new_config.channel_config->get_n_chans() * max_frames;
children.push_back (new SilenceHandler (parent, new_config, max_frames_out));
interleaver->add_output (children.back().sink ());
FileSpec spec (channel_config, format, filename, broadcast_info);
ConfigPair pair (timespan, spec);
config_map.insert (pair);
-
+
return true;
}
framecnt_t frames_to_read = 0;
framepos_t const start = current_timespan->get_start();
framepos_t const end = current_timespan->get_end();
-
+
bool const last_cycle = (process_position + frames >= end);
if (last_cycle) {
if (graph_builder->process_normalize ()) {
finish_timespan ();
}
-
+
return 0;
}
if (timespans.empty()) {
TimespanStatePtr state (new TimespanState (session_range, selection_range, ranges));
timespans.push_back (state);
-
+
// Add session as default selection
TimespanPtr timespan = handler->add_timespan();
timespan->set_name (session_range->name());
if (nodes.empty()) {
ChannelConfigStatePtr config (new ChannelConfigState (handler->add_channel_config()));
channel_configs.push_back (config);
-
+
// Add master outs as default
IO* master_out = session.master_out()->output().get();
if (!master_out) { return false; }
-
+
for (uint32_t n = 0; n < master_out->n_ports().n_audio(); ++n) {
PortExportChannel * channel = new PortExportChannel ();
channel->add_port (master_out->audio (n));
-
+
ExportChannelPtr chan_ptr (channel);
config->config->register_channel (chan_ptr);
}
position (0),
frame_rate (frame_rate)
{
-
+
}
ExportTimespan::~ExportTimespan ()
{
/* if this file already exists, it cannot be removed, ever
*/
-
+
if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) {
if (!(_flags & Destructive)) {
mark_immutable ();
FileSource::removable () const
{
bool r = ((_flags & Removable)
- && ((_flags & RemoveAtDestroy) ||
+ && ((_flags & RemoveAtDestroy) ||
((_flags & RemovableIfEmpty) && empty() == 0)));
-
+
return r;
}
string keeppath;
isnew = false;
-
+
if (!Glib::path_is_absolute (path)) {
vector<string> dirs;
vector<string> hits;
}
split (search_path, dirs, ':');
-
+
cnt = 0;
hits.clear ();
-
+
for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
-
+
fullpath = Glib::build_filename (*i, path);
-
+
if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
keeppath = fullpath;
hits.push_back (fullpath);
++cnt;
}
}
-
+
if (cnt > 1) {
-
+
int which = FileSource::AmbiguousFileName (path, search_path, hits).get_value_or (-1);
-
+
if (which < 0) {
goto out;
} else {
keeppath = hits[which];
}
-
+
} else if (cnt == 0) {
-
+
if (must_exist) {
error << string_compose(
_("Filesource: cannot find required file (%1): while searching %2"),
} else {
keeppath = path;
}
-
+
/* Current find() is unable to parse relative path names to yet non-existant
- sources. QuickFix(tm)
+ sources. QuickFix(tm)
*/
if (keeppath == "") {
if (must_exist) {
keeppath = path;
}
}
-
+
found_path = keeppath;
-
+
ret = true;
-
+
out:
return ret;
}
cnt = 0;
for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
-
+
fullpath = Glib::build_filename (*i, pathstr);
/* i (paul) made a nasty design error by using ':' as a special character in
error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
return -1;
}
-
+
if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
return -1;
_path = newpath;
}
-void
+void
FileSource::inc_use_count ()
{
Source::inc_use_count ();
}
-
+
p = c;
} else {
const string home_dir = Glib::get_home_dir();
-
+
if (home_dir.empty ()) {
const string error_msg = "Unable to determine home directory";
-
+
// log the error
error << error_msg << endmsg;
-
+
throw sys::filesystem_error(error_msg);
}
p = home_dir;
p /= ".config";
}
-
+
p /= user_config_dir_name;
return p;
results.clear ();
PropertyList plist;
-
+
plist.add (Properties::start, 0);
plist.add (Properties::length, region->length());
plist.add (Properties::name, region_name);
*/
PBD::PropertyChange ARDOUR::bounds_change;
-namespace ARDOUR {
+namespace ARDOUR {
namespace Properties {
/* the envelope and fades are not scalar items and so
currently (2010/02) are not stored using Property.
However, these descriptors enable us to notify
- about changes to them via PropertyChange.
+ about changes to them via PropertyChange.
Declared in ardour/audioregion.h ...
*/
info << "No H/W specific optimizations in use" << endmsg;
}
-
+
AudioGrapher::Routines::override_compute_peak (compute_peak);
AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
}
PBD::ID::init ();
SessionEvent::init_event_pool ();
-
+
make_property_quarks ();
SessionObject::make_property_quarks ();
Region::make_property_quarks ();
if (Config->load_state ()) {
return -1;
}
-
+
Config->set_use_vst (use_vst);
Profile = new RuntimeProfile;
}
#endif
-Graph::Graph (Session & session)
- : SessionHandleRef (session)
+Graph::Graph (Session & session)
+ : SessionHandleRef (session)
, _quit_threads (false)
, _execution_sem ("graph_execution", 0)
, _callback_start_sem ("graph_start", 0)
_setup_chain = 1;
_quit_threads = false;
_graph_empty = true;
-
+
reset_thread_list ();
Config->ParameterChanged.connect_same_thread (processor_usage_connection, boost::bind (&Graph::parameter_changed, this, _1));
-#ifdef DEBUG_RT_ALLOC
+#ifdef DEBUG_RT_ALLOC
graph = this;
pbd_alloc_allowed = &::alloc_allowed;
-#endif
+#endif
}
void
/* setup chain == pending chain - we have
to wait till this is no longer true.
*/
- _cleanup_cond.wait (_swap_mutex);
+ _cleanup_cond.wait (_swap_mutex);
}
}
// ok... this cycle is finished now.
// we are the only thread alive.
-
+
this->restart_cycle();
}
}
for (RouteList::iterator ri=routelist->begin(); ri!=routelist->end(); ri++) {
if (rp->direct_feeds (*ri)) {
if (is_feedback (routelist, rp.get(), *ri)) {
- continue;
+ continue;
}
has_output = true;
if (!has_output)
_init_finished_refcount[chain] += 1;
- }
+ }
_pending_chain = chain;
dump(chain);
if (priority) {
struct sched_param rtparam;
-
+
memset (&rtparam, 0, sizeof (rtparam));
rtparam.sched_priority = priority;
-
+
pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam);
}
}
}
int
-Graph::routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+Graph::routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
bool non_rt_pending, bool can_record, int declick)
{
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("no-roll graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes));
if (retval) {
_process_retval = retval;
}
-
+
if (need_butler) {
_process_need_butler = true;
}
GraphNode::GraphNode (graph_ptr_t graph)
: _graph(graph)
-{
+{
}
GraphNode::~GraphNode()
if (_send_to) {
_send_to->remove_send_from_internal_return (this);
}
-
+
_send_to = sendto;
_send_to->add_send_to_internal_return (this);
-
+
set_name (sendto->name());
_send_to_id = _send_to->id();
Amp::apply_gain (mixbufs, nframes, _current_gain, tgain);
_current_gain = tgain;
-
+
} else if (tgain == 0.0) {
/* we were quiet last time, and we're still supposed to be quiet.
}
/* keep this condition out of the inner loop */
-
+
if (input && output) {
Sample inm1;
-
+
if (floor (distance) == 0.0) {
- /* best guess for the fake point we have to add to be able to interpolate at i == 0:
+ /* best guess for the fake point we have to add to be able to interpolate at i == 0:
.... maintain slope of first actual segment ...
*/
inm1 = input[i] - (input[i+1] - input[i]);
if (fractional_phase_part >= 1.0) {
fractional_phase_part -= 1.0;
++i;
- }
+ }
// Cubically interpolate into the output buffer: keep this inlined for speed and rely on compiler
// optimization to take care of the rest
}
}
-void
+void
IO::increment_port_buffer_offset (pframes_t offset)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
{
Glib::Mutex::Lock lm (io_lock);
-
+
/* check that our_port is really one of ours */
-
+
if ( ! _ports.contains(our_port)) {
return -1;
}
-
+
/* disconnect it from the source */
-
+
if (our_port->disconnect (other_port)) {
error << string_compose(_("IO: cannot disconnect port %1 from %2"), our_port->name(), other_port) << endmsg;
return -1;
}
-
+
check_bundles_connected ();
}
-
+
changed (IOChange (IOChange::ConnectionsChanged), src); /* EMIT SIGNAL */
_session.set_dirty ();
{
Glib::Mutex::Lock lm (io_lock);
-
+
/* check that our_port is really one of ours */
-
+
if ( ! _ports.contains(our_port) ) {
return -1;
}
-
+
/* connect it to the source */
-
+
if (our_port->connect (other_port)) {
return -1;
}
}
PortCountChanged (n_ports()); /* EMIT SIGNAL */
-
+
// pan_changed (src); /* EMIT SIGNAL */
change.type = IOChange::ConfigurationChanged;
change.after = _ports.count ();
{
{
Glib::Mutex::Lock lm (io_lock);
-
+
for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
i->disconnect_all ();
}
-
+
check_bundles_connected ();
}
-
+
changed (IOChange (IOChange::ConnectionsChanged), src); /* EMIT SIGNAL */
return 0;
IO::ensure_ports_locked (ChanCount count, bool clear, void* /*src*/)
{
assert (!AudioEngine::instance()->process_lock().trylock());
-
+
Port* port = 0;
bool changed = false;
IO::ensure_ports (ChanCount count, bool clear, void* src)
{
assert (!AudioEngine::instance()->process_lock().trylock());
-
+
bool changed = false;
if (count == n_ports() && !clear) {
IOChange change;
change.before = _ports.count ();
-
+
{
Glib::Mutex::Lock im (io_lock);
changed = ensure_ports_locked (count, clear, src);
IO::ensure_io (ChanCount count, bool clear, void* src)
{
assert (!AudioEngine::instance()->process_lock().trylock());
-
+
return ensure_ports (count, clear, src);
}
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
if (ensure_ports (n, true, this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
return -1;
if ((prop = cnode->property (X_("other"))) == 0) {
continue;
}
-
+
if (prop) {
connect (p, prop->value(), this);
}
}
- }
+ }
}
}
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
// FIXME: audio-only
if (ensure_ports (ChanCount(DataType::AUDIO, nports), true, this)) {
return -1;
/* replace all colons in the name. i wish we didn't have to do this */
- replace_all (name, ":", "-");
+ replace_all (name, ":", "-");
for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
string current_name = i->name();
for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
if ((latency = i->private_latency_range (_direction == Output).max) > max_latency) {
DEBUG_TRACE (DEBUG::Latency, string_compose ("port %1 has %2 latency of %3 - use\n",
- name(),
+ name(),
((_direction == Output) ? "PLAYBACK" : "CAPTURE"),
latency));
max_latency = latency;
}
}
- DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: max %4 latency from %2 ports = %3\n",
+ DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: max %4 latency from %2 ports = %3\n",
name(), _ports.num_ports(), max_latency,
((_direction == Output) ? "PLAYBACK" : "CAPTURE")));
return max_latency;
IO::connected () const
{
/* do we have any connections at all? */
-
+
for (PortSet::const_iterator p = _ports.begin(); p != _ports.end(); ++p) {
if (p->connected()) {
return true;
}
}
-
+
return false;
}
}
}
-void
+void
IOProcessor::increment_port_buffer_offset (pframes_t offset)
{
if (_own_output && _output) {
if (which < _descriptor->PortCount) {
_shadow_data[which] = (LADSPA_Data) val;
-#if 0
+#if 0
if (which < parameter_count() && controls[which]) {
controls[which]->Changed ();
}
pframes_t nframes, framecnt_t offset)
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
-
+
cycles_t now;
cycles_t then = get_cycles ();
}
assert (_was_activated);
-
+
_descriptor->run (_handle, nframes);
}
lrdf_statement *i;
char setting_uri_copy[64];
char buf[64];
-
+
strncpy(setting_uri_copy, setting_uri, sizeof(setting_uri_copy));
p.subject = setting_uri_copy;
if (!p) {
return;
}
-
+
string const source = preset_source (envvar);
lrdf_remove_preset (source.c_str(), p->uri.c_str ());
if ((envvar = getenv ("HOME")) == 0) {
return "";
}
-
+
return envvar;
}
input_parameter_pids.push_back (i);
}
}
-
+
std::string unique (unique_id());
if (!isdigit (unique[0])) {
/* Note: _position_lock_style is initialised above in case set_state doesn't set it
(for 2.X session file compatibility).
*/
-
+
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor ();
}
assert (_start >= 0);
assert (_end >= 0);
-
+
return 0;
}
-
+
if (s != _start) {
framepos_t const old = _start;
-
+
_start = s;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
assert (_start >= 0);
-
+
return 0;
}
return -1;
}
}
-
+
if (is_mark()) {
if (_start != e) {
_start = e;
assert (_start >= 0);
assert (_end >= 0);
-
+
return 0;
}
if (e != _end) {
framepos_t const old = _end;
-
+
_end = e;
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
if (_position_lock_style != MusicTime) {
return;
}
-
+
_session.tempo_map().bbt_time (_start, _bbt_start);
_session.tempo_map().bbt_time (_end, _bbt_end);
}
Locations::add (Location *loc, bool make_current)
{
assert (loc);
-
+
{
Glib::Mutex::Lock lm (lock);
locations.push_back (loc);
XMLProperty const * prop_id = (*niter)->property ("id");
assert (prop_id);
PBD::ID id (prop_id->value ());
-
+
LocationList::const_iterator i = locations.begin();
while (i != locations.end () && (*i)->id() != id) {
++i;
Locations::marks_either_side (framepos_t const frame, framepos_t& before, framepos_t& after) const
{
before = after = max_framepos;
-
+
LocationList locs;
{
}
/* Get a list of positions; don't store any that are exactly on our requested position */
-
+
std::list<framepos_t> positions;
for (LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
/* none before */
return;
}
-
+
--i;
before = *i;
}
_ui = this_ui;
_ui_type = this_ui_type;
break;
- }
+ }
}
#else
// Look for Gtk native UI
_uri_map.id_to_uri(NULL, type)));
LV2PersistState* state = (LV2PersistState*)host_data;
- state->add_uri(key, _uri_map.id_to_uri(NULL, key));
- state->add_uri(type, _uri_map.id_to_uri(NULL, type));
+ state->add_uri(key, _uri_map.id_to_uri(NULL, key));
+ state->add_uri(type, _uri_map.id_to_uri(NULL, type));
return state->add_value(key, value, size, type, flags);
}
DEBUG_TRACE(DEBUG::LV2, string_compose("new file path %1 => %2\n",
relative_path, path));
-
+
return g_strndup(path.c_str(), path.length());
}
_impl->ui = this_ui;
_impl->ui_type = this_ui_type;
break;
- }
+ }
}
#else
// Look for Gtk native UI
_uri_map.id_to_uri(NULL, type)));
LV2PersistState* state = (LV2PersistState*)host_data;
- state->add_uri(key, _uri_map.id_to_uri(NULL, key));
- state->add_uri(type, _uri_map.id_to_uri(NULL, type));
+ state->add_uri(key, _uri_map.id_to_uri(NULL, key));
+ state->add_uri(type, _uri_map.id_to_uri(NULL, type));
return state->add_value(key, value, size, type, flags);
}
DEBUG_TRACE(DEBUG::LV2, string_compose("new file path %1 => %2\n",
relative_path, path));
-
+
return g_strndup(path.c_str(), path.length());
}
: _source (s)
, _parameter (p)
{
-
+
}
MidiAutomationListBinder::MidiAutomationListBinder (XMLNode* node, Session::SourceMap const & sources)
{
XMLProperty* source = node->property ("source-id");
assert (source);
-
+
XMLProperty* parameter = node->property ("parameter");
assert (parameter);
{
boost::shared_ptr<MidiModel> model = _source->model ();
assert (model);
-
+
boost::shared_ptr<AutomationControl> control = model->automation_control (_parameter);
assert (control);
-
+
return control->alist().get();
}
t1 * session->frame_rate(),
session->frame_rate(),
((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames));
-
+
last_timestamp = timestamp;
}
_starting = true;
_started = true;
-
+
// session->request_locate(0, false);
}
// calculate speed
speed = ((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames;
-
+
// provide a 3% deadzone to lock the speed
if (fabs(speed - 1.0) <= 0.03)
speed = 1.0;
_n_channels, input_change_pending.type)
<< endmsg;
}
-
+
if (ni == 0) {
_source_port = 0;
} else {
}
if (nominally_recording || rec_nframes) {
-
+
// Pump entire port buffer into the ring buffer (FIXME: split cycles?)
MidiBuffer& buf = _source_port->get_midi_buffer(nframes);
for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
// << frames_written - frames_read << endl;
to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
-
+
if (read (file_frame, to_read, reversed)) {
ret = -1;
}
_write_source.reset();
}
}
-
+
mark_write_completed = true;
}
if (!_session.writable() || !recordable()) {
return 1;
}
-
+
assert(n == 0);
_write_source.reset();
return;
}
- /* XXX Not sure what, if anything we can do with MIDI
+ /* XXX Not sure what, if anything we can do with MIDI
as far as capture alignment etc.
*/
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
- "%1 MDS pre-read read from %2 write to %3\n", _name,
+ "%1 MDS pre-read read from %2 write to %3\n", _name,
_playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
// cerr << "================\n";
// _playback_buf->dump (cerr);
{
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
return new NoteDiffCommand (ms->model(), name);
}
{
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
return new SysExDiffCommand (ms->model(), name);
}
{
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
return new PatchChangeDiffCommand (ms->model(), name);
}
uint8_t new_value)
{
assert (note);
-
+
NoteChange change;
switch (prop) {
TimeType new_time)
{
assert (note);
-
+
NoteChange change;
switch (prop) {
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
Property prop = i->property;
switch (prop) {
-
+
case NoteNumber:
if (
temporary_removals.find (i->note) == temporary_removals.end() &&
list (which means that it has already been removed and it
will be re-added anyway)
*/
-
+
_model->remove_note_unlocked (i->note);
temporary_removals.insert (i->note);
}
i->note->set_note (i->old_value);
break;
-
+
case StartTime:
if (
temporary_removals.find (i->note) == temporary_removals.end() &&
}
i->note->set_time (i->old_time);
break;
-
+
case Channel:
if (
temporary_removals.find (i->note) == temporary_removals.end() &&
) {
/* See above ... */
-
+
_model->remove_note_unlocked (i->note);
temporary_removals.insert (i->note);
}
case Velocity:
i->note->set_velocity (i->old_value);
break;
-
+
case Length:
i->note->set_length (i->old_time);
break;
diff_command->add_property("midi-source", _model->midi_source()->id().to_s());
XMLNode* changes = diff_command->add_child(DIFF_NOTES_ELEMENT);
- for_each(_changes.begin(), _changes.end(),
+ for_each(_changes.begin(), _changes.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, changes, _1),
boost::bind (&NoteDiffCommand::marshal_change, this, _1)));
XMLNode* added_notes = diff_command->add_child(ADDED_NOTES_ELEMENT);
- for_each(_added_notes.begin(), _added_notes.end(),
+ for_each(_added_notes.begin(), _added_notes.end(),
boost::bind(
boost::bind (&XMLNode::add_child_nocopy, added_notes, _1),
boost::bind (&NoteDiffCommand::marshal_note, this, _1)));
XMLNode* removed_notes = diff_command->add_child(REMOVED_NOTES_ELEMENT);
- for_each(_removed_notes.begin(), _removed_notes.end(),
+ for_each(_removed_notes.begin(), _removed_notes.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, removed_notes, _1),
boost::bind (&NoteDiffCommand::marshal_note, this, _1)));
- /* if this command had side-effects, store that state too
+ /* if this command had side-effects, store that state too
*/
if (!side_effect_removals.empty()) {
XMLNode* side_effect_notes = diff_command->add_child(SIDE_EFFECT_REMOVALS_ELEMENT);
- for_each(side_effect_removals.begin(), side_effect_removals.end(),
+ for_each(side_effect_removals.begin(), side_effect_removals.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, side_effect_notes, _1),
boost::bind (&NoteDiffCommand::marshal_note, this, _1)));
diff_command->add_property ("midi-source", _model->midi_source()->id().to_s());
XMLNode* changes = diff_command->add_child(DIFF_SYSEXES_ELEMENT);
- for_each (_changes.begin(), _changes.end(),
+ for_each (_changes.begin(), _changes.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, changes, _1),
boost::bind (&SysExDiffCommand::marshal_change, this, _1)));
c.patch = patch;
c.old_bank = patch->bank ();
c.new_bank = bank;
-
+
_changes.push_back (c);
}
{
{
MidiModel::WriteLock lock (_model->edit_lock ());
-
+
for (list<PatchChangePtr>::iterator i = _added.begin(); i != _added.end(); ++i) {
_model->add_patch_change_unlocked (*i);
}
for (list<PatchChangePtr>::iterator i = _removed.begin(); i != _removed.end(); ++i) {
_model->remove_patch_change_unlocked (*i);
}
-
+
set<PatchChangePtr> temporary_removals;
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
for (list<PatchChangePtr>::iterator i = _removed.begin(); i != _removed.end(); ++i) {
_model->add_patch_change_unlocked (*i);
}
-
+
set<PatchChangePtr> temporary_removals;
for (ChangeList::iterator i = _changes.begin(); i != _changes.end(); ++i) {
for (set<PatchChangePtr>::iterator i = temporary_removals.begin(); i != temporary_removals.end(); ++i) {
_model->add_patch_change_unlocked (*i);
}
-
+
}
_model->ContentsChanged (); /* EMIT SIGNAL */
s << c.patch->id ();
n->add_property ("id", s.str ());
}
-
+
return *n;
}
istringstream s (prop->value());
s >> id;
}
-
+
if ((prop = n->property ("time")) != 0) {
istringstream s (prop->value ());
s >> time;
prop = n->property ("id");
assert (prop);
Evoral::event_id_t const id = atoi (prop->value().c_str());
-
+
prop = n->property ("old");
assert (prop);
{
diff_command->add_property("midi-source", _model->midi_source()->id().to_s());
XMLNode* added = diff_command->add_child (ADDED_PATCH_CHANGES_ELEMENT);
- for_each (_added.begin(), _added.end(),
+ for_each (_added.begin(), _added.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, added, _1),
boost::bind (&PatchChangeDiffCommand::marshal_patch_change, this, _1)
);
XMLNode* removed = diff_command->add_child (REMOVED_PATCH_CHANGES_ELEMENT);
- for_each (_removed.begin(), _removed.end(),
+ for_each (_removed.begin(), _removed.end(),
boost::bind (
boost::bind (&XMLNode::add_child_nocopy, removed, _1),
boost::bind (&PatchChangeDiffCommand::marshal_patch_change, this, _1)
)
);
-
+
XMLNode* changes = diff_command->add_child (DIFF_PATCH_CHANGES_ELEMENT);
for_each (_changes.begin(), _changes.end(),
boost::bind (
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
source->drop_model();
source->mark_streaming_midi_write_started (note_mode());
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
ms->mark_streaming_midi_write_started (note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms);
-
+
source->drop_model();
source->mark_streaming_midi_write_started (note_mode());
if (ev.time() >= begin_time && ev.time() < end_time) {
- const Evoral::MIDIEvent<Evoral::MusicalTime>* mev =
+ const Evoral::MIDIEvent<Evoral::MusicalTime>* mev =
static_cast<const Evoral::MIDIEvent<Evoral::MusicalTime>* > (&ev);
if (!mev) {
TimeType note_length = note->length();
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 checking overlaps for note %2 @ %3\n", this, (int)note->note(), note->time()));
-
- for (Pitches::const_iterator i = p.lower_bound (search_note);
+
+ for (Pitches::const_iterator i = p.lower_bound (search_note);
i != p.end() && (*i)->note() == note->note(); ++i) {
TimeType sb = (*i)->time();
case InsertMergeExtend:
if (cmd) {
cmd->change ((*i), NoteDiffCommand::Length, note->end_time() - (*i)->time());
- }
+ }
(*i)->set_length (note->end_time() - (*i)->time());
return -1; /* do not add the new note */
break;
if (set_note_time) {
if (cmd) {
cmd->change (note, NoteDiffCommand::StartTime, note_time);
- }
+ }
note->set_time (note_time);
}
if (set_note_length) {
if (cmd) {
cmd->change (note, NoteDiffCommand::Length, note_length);
- }
+ }
note->set_length (note_length);
}
}
InsertMergePolicy
-MidiModel::insert_merge_policy () const
+MidiModel::insert_merge_policy () const
{
/* XXX ultimately this should be a per-track or even per-model policy */
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
MidiModel::set_midi_source (boost::shared_ptr<MidiSource> s)
{
boost::shared_ptr<MidiSource> old = _midi_source.lock ();
-
+
if (old) {
old->invalidate ();
}
{
boost::shared_ptr<MidiSource> s = _midi_source.lock ();
assert (s);
-
+
/* Notes */
if (!notes().empty ()) {
NoteDiffCommand* c = new_note_diff_command ("insert silence");
-
+
for (Notes::const_iterator i = notes().begin(); i != notes().end(); ++i) {
c->change (*i, NoteDiffCommand::StartTime, (*i)->time() + t);
}
-
+
apply_command_as_subcommand (s->session(), c);
}
MidiModel::transpose (TimeType from, TimeType to, int semitones)
{
boost::shared_ptr<const MidiSource> s = midi_source ();
-
+
NoteDiffCommand* c = new_note_diff_command (_("transpose"));
-
+
for (Notes::iterator i = notes().begin(); i != notes().end(); ++i) {
if ((*i)->time() >= to) {
-
+
/* finished */
break;
-
+
} else if ((*i)->time() >= from) {
int new_note = (*i)->note() + semitones;
-
+
if (new_note < 0) {
new_note = 0;
} else if (new_note > 127) {
}
c->change (*i, NoteDiffCommand::NoteNumber, (uint8_t) new_note);
-
+
}
}
on other ways to approach this issue.
********************************************************************************/
-MidiPlaylistSource::MidiPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<MidiPlaylist> p,
+MidiPlaylistSource::MidiPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<MidiPlaylist> p,
uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
: Source (s, DataType::MIDI, name)
, MidiSource (s, name, flags)
/* ancestors have already called ::set_state() in their XML-based
constructors.
*/
-
+
if (set_state (node, Stateful::loading_state_version, false)) {
throw failed_constructor ();
}
return node;
}
-
+
int
-MidiPlaylistSource::set_state (const XMLNode& node, int version)
+MidiPlaylistSource::set_state (const XMLNode& node, int version)
{
return set_state (node, version, true);
}
int
-MidiPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
+MidiPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
{
if (with_descendants) {
- if (Source::set_state (node, version) ||
+ if (Source::set_state (node, version) ||
MidiSource::set_state (node, version) ||
PlaylistSource::set_state (node, version)) {
return -1;
return extent.second - extent.first;
}
-framepos_t
+framepos_t
MidiPlaylistSource::read_unlocked (Evoral::EventSink<framepos_t>& dst,
framepos_t position,
framepos_t start, framecnt_t cnt,
- MidiStateTracker* tracker) const
+ MidiStateTracker* tracker) const
{
boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlist);
return mp->read (dst, start, cnt);
}
-framepos_t
+framepos_t
MidiPlaylistSource::write_unlocked (MidiRingBuffer<framepos_t>& dst,
framepos_t position,
- framecnt_t cnt)
+ framecnt_t cnt)
{
fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::write_unlocked() called - should be impossible") << endmsg;
/*NOTREACHED*/
return 0;
}
-void
+void
MidiPlaylistSource::append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& /*ev*/)
{
fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_beats() called - should be impossible") << endmsg;
/*NOTREACHED*/
}
-void
+void
MidiPlaylistSource::append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start)
{
fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_frames() called - should be impossible") << endmsg;
}
void
-MidiPlaylistSource::load_model (bool, bool)
+MidiPlaylistSource::load_model (bool, bool)
{
/* nothing to do */
}
void
-MidiPlaylistSource::destroy_model ()
+MidiPlaylistSource::destroy_model ()
{
/* nothing to do */
}
/* check that the event is in the acceptable time range */
- if ((ev.time >= (_global_port_buffer_offset + _port_buffer_offset)) &&
+ if ((ev.time >= (_global_port_buffer_offset + _port_buffer_offset)) &&
(ev.time < (_global_port_buffer_offset + _port_buffer_offset + nframes))) {
_buffer->push_back (ev);
} else {
- cerr << "Dropping incoming MIDI at time " << ev.time << "; offset="
- << _global_port_buffer_offset << " limit="
+ cerr << "Dropping incoming MIDI at time " << ev.time << "; offset="
+ << _global_port_buffer_offset << " limit="
<< (_global_port_buffer_offset + _port_buffer_offset + nframes) << "\n";
}
}
MidiPort::resolve_notes (void* jack_buffer, MidiBuffer::TimeType when)
{
uint8_t ev[3];
-
+
ev[2] = 0;
-
+
for (uint8_t channel = 0; channel <= 0xF; channel++) {
ev[0] = (MIDI_CMD_CONTROL | channel);
-
+
/* we need to send all notes off AND turn the
* sustain/damper pedal off to handle synths
* that prioritize sustain over AllNotesOff
*/
-
+
ev[1] = MIDI_CTL_SUSTAIN;
-
+
if (jack_midi_event_write (jack_buffer, when, ev, 3) != 0) {
cerr << "failed to deliver sustain-zero on channel " << channel << " on port " << name() << endl;
- }
-
+ }
+
ev[1] = MIDI_CTL_ALL_NOTES_OFF;
-
+
if (jack_midi_event_write (jack_buffer, 0, ev, 3) != 0) {
cerr << "failed to deliver ALL NOTES OFF on channel " << channel << " on port " << name() << endl;
- }
+ }
}
}
if (ev.time() >= _global_port_buffer_offset + _port_buffer_offset) {
if (jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size()) != 0) {
- cerr << "write failed, drop flushed note off on the floor, time "
+ cerr << "write failed, drop flushed note off on the floor, time "
<< ev.time() << " > " << _global_port_buffer_offset + _port_buffer_offset << endl;
}
} else {
- cerr << "drop flushed event on the floor, time " << ev.time()
+ cerr << "drop flushed event on the floor, time " << ev.time()
<< " < " << _global_port_buffer_offset + _port_buffer_offset << endl;
}
}
{
}
-/** Create a new MidiRegion that has its own version of some/all of the Source used by another.
+/** Create a new MidiRegion that has its own version of some/all of the Source used by another.
*/
boost::shared_ptr<MidiRegion>
MidiRegion::clone ()
}
framecnt_t
-MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>& dst, framepos_t position, framecnt_t dur, uint32_t chan_n,
+MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>& dst, framepos_t position, framecnt_t dur, uint32_t chan_n,
NoteMode mode, MidiStateTracker* tracker) const
{
frameoffset_t internal_offset = 0;
boost::shared_ptr<MidiSource> src = midi_source(chan_n);
src->set_note_mode(mode);
-
+
/*
cerr << "MR read @ " << position << " * " << to_read
<< " _position = " << _position
if (!model()) {
return;
}
-
+
/* build list of filtered Parameters, being those whose automation state is not `Play' */
_filtered_parameters.clear ();
void
MidiRegion::model_contents_changed ()
{
- send_change (PropertyChange (Properties::midi_data));
+ send_change (PropertyChange (Properties::midi_data));
}
void
MidiRegion::model_automation_state_changed (Evoral::Parameter const & p)
{
/* Update our filtered parameters list after a change to a parameter's AutoState */
-
+
boost::shared_ptr<AutomationControl> ac = model()->automation_control (p);
assert (ac);
to the MidiBuffer with adjusted times. The situation is as follows:
session frames----------------------------->
-
+
| | |
start_of_loop start end_of_loop
} else {
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 in range %2 .. %3\n", ev_time, start, end));
}
-
+
/* lets see if we are going to be able to write this event into dst.
*/
assert(ev_time >= start);
-
+
ev_time -= start;
ev_time += offset;
return;
}
- str << this << ": Dump size = " << vec.len[0] + vec.len[1]
- << " r@ " << RingBufferNPT<uint8_t>::get_read_ptr()
+ str << this << ": Dump size = " << vec.len[0] + vec.len[1]
+ << " r@ " << RingBufferNPT<uint8_t>::get_read_ptr()
<< " w@" << RingBufferNPT<uint8_t>::get_write_ptr() << endl;
const uint8_t* end = buf + vec.len[0] + vec.len[1];
while (data < end) {
-
+
memcpy (&ev_time, data, sizeof (T));
data += sizeof (T);
str << "\ttime " << ev_time;
error << _("Missing parameter property on InterpolationStyle") << endmsg;
return -1;
}
-
+
Evoral::Parameter p = EventTypeMap::instance().new_parameter (prop->value());
if ((prop = (*i)->property (X_("style"))) == 0) {
Evoral::ControlList::InterpolationStyle s = static_cast<Evoral::ControlList::InterpolationStyle> (string_2_enum (prop->value(), s));
set_interpolation_of (p, s);
-
+
} else if ((*i)->name() == X_("AutomationState")) {
-
+
XMLProperty* prop;
if ((prop = (*i)->property (X_("parameter"))) == 0) {
error << _("Missing parameter property on AutomationState") << endmsg;
return -1;
}
-
+
Evoral::Parameter p = EventTypeMap::instance().new_parameter (prop->value());
if ((prop = (*i)->property (X_("state"))) == 0) {
/* get a new name for the MIDI file we're going to write to
*/
- do {
+ do {
newname = bump_name_once (newname, '-');
/* XXX build path safely */
newpath = _session.session_directory().midi_path().to_string() +"/"+ newname + ".mid";
} while (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS));
-
+
boost::shared_ptr<MidiSource> newsrc = boost::dynamic_pointer_cast<MidiSource>(
SourceFactory::createWritable(DataType::MIDI, _session,
newpath, string(), false, _session.frame_rate()));
newsrc->flush_midi();
/* force a reload of the model if the range is partial */
-
+
if (begin != Evoral::MinMusicalTime || end != Evoral::MaxMusicalTime) {
newsrc->load_model (true, true);
} else {
newsrc->set_model (_model);
}
-
+
return newsrc;
}
void
MidiSource::session_saved()
{
- /* this writes a copy of the data to disk.
+ /* this writes a copy of the data to disk.
XXX do we need to do this every time?
*/
*/
boost::shared_ptr<MidiModel> mm = _model ;
- _model.reset ();
+ _model.reset ();
/* flush model contents to disk
*/
void
MidiSource::drop_model ()
{
- _model.reset();
+ _model.reset();
ModelChanged (); /* EMIT SIGNAL */
}
if (interpolation_of (p) == s) {
return;
}
-
+
if (EventTypeMap::instance().interpolation_of (p) == s) {
/* interpolation type is being set to the default, so we don't need a note in our map */
_interpolation_style.erase (p);
if (automation_state_of (p) == s) {
return;
}
-
+
if (s == Play) {
/* automation state is being set to the default, so we don't need a note in our map */
_automation_state.erase (p);
MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
Track::set_diskstream (ds);
-
+
_diskstream->set_track (this);
_diskstream->set_destructive (_mode == Destructive);
const Evoral::MIDIEvent<framepos_t> ev(*e, false);
/* note on, since for step edit, note length is determined
- elsewhere
+ elsewhere
*/
if (ev.is_note_on()) {
if (_immediate_events.read_space()) {
- DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
+ DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
name(), _immediate_events.read_space()));
/* write as many of the immediate events as we can, but give "true" as
* ship the rest out next time.
*
* the (nframes-1) argument puts all these events at the last
- * possible position of the output buffer, so that we do not
+ * possible position of the output buffer, so that we do not
* violate monotonicity when writing.
*/
-
+
_immediate_events.read (buf, 0, 1, nframes-1, true);
}
{
DataRecorded (buf, src); /* EMIT SIGNAL */
}
-
+
bool
MidiTrack::should_monitor () const
{
MidiControlUI::MidiControlUI (Session& s)
: AbstractUI<MidiUIRequest> (_("midiui"))
- , _session (s)
+ , _session (s)
{
MIDI::Manager::instance()->PortsChanged.connect_same_thread (rebind_connection, boost::bind (&MidiControlUI::change_midi_ports, this));
_instance = this;
port_sources.push_back (psrc->gobj());
g_source_ref (psrc->gobj());
- }
+ }
}
}
void
MidiControlUI::thread_init ()
-{
+{
struct sched_param rtparam;
pthread_set_name (X_("midiUI"));
, _dim_all_ptr (new MPControl<bool> (false, _("monitor dim"), Controllable::Toggle))
, _cut_all_ptr (new MPControl<bool> (false, _("monitor cut"), Controllable::Toggle))
, _mono_ptr (new MPControl<bool> (false, _("monitor mono"), Controllable::Toggle))
- , _dim_level_ptr (new MPControl<volatile gain_t>
+ , _dim_level_ptr (new MPControl<volatile gain_t>
(0.2, _("monitor mono"), Controllable::Flag (0), 0.0f, 1.0f))
- , _solo_boost_level_ptr (new MPControl<volatile gain_t>
+ , _solo_boost_level_ptr (new MPControl<volatile gain_t>
(1.0, _("monitor mono"), Controllable::Flag (0), 1.0f, 3.0f))
-
+
, _dim_all_control (_dim_all_ptr)
, _cut_all_control (_cut_all_ptr)
, _mono_control (_mono_ptr)
<< endmsg;
return -1;
}
-
+
allocate_channels (atoi (prop->value()));
if ((prop = node.property (X_("dim-level"))) != 0) {
<< endmsg;
return -1;
}
-
+
if (chn >= _channels.size()) {
error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings has an illegal channel count"))
<< endmsg;
}
}
}
-
+
/* reset solo cnt */
solo_cnt = 0;
solo_cnt++;
}
}
-
+
return 0;
}
/* this replaces any existing "type" property */
node.add_property (X_("type"), X_("monitor"));
-
+
snprintf (buf, sizeof(buf), "%.12g", _dim_level.val());
node.add_property (X_("dim-level"), buf);
node.add_property (X_("cut-all"), (_cut_all ? "yes" : "no"));
node.add_property (X_("dim-all"), (_dim_all ? "yes" : "no"));
node.add_property (X_("mono"), (_mono ? "yes" : "no"));
-
+
uint32_t limit = _channels.size();
snprintf (buf, sizeof (buf), "%u", limit);
snprintf (buf, sizeof (buf), "%u", chn);
chn_node->add_property ("id", buf);
-
+
chn_node->add_property (X_("cut"), (*x)->cut == 1.0f ? "no" : "yes");
chn_node->add_property (X_("invert"), (*x)->polarity == 1.0f ? "no" : "yes");
chn_node->add_property (X_("dim"), (*x)->dim ? "yes" : "no");
chn_node->add_property (X_("solo"), (*x)->soloed ? "yes" : "no");
-
+
node.add_child_nocopy (*chn_node);
}
return Processor::configure_io (in, out);
}
-bool
+bool
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
out = in;
} else {
_channels[chn]->polarity = 1.0f;
}
-}
+}
void
MonitorProcessor::set_dim (uint32_t chn, bool yn)
{
if (solo != _channels[chn]->soloed) {
_channels[chn]->soloed = solo;
-
+
if (solo) {
solo_cnt++;
} else {
return false;
}
-bool
+bool
MonitorProcessor::soloed (uint32_t chn) const
{
return _channels[chn]->soloed;
}
-bool
+bool
MonitorProcessor::inverted (uint32_t chn) const
{
return _channels[chn]->polarity < 0.0f;
}
-bool
+bool
MonitorProcessor::cut (uint32_t chn) const
{
return _channels[chn]->cut == 0.0f;
}
-bool
+bool
MonitorProcessor::dimmed (uint32_t chn) const
{
return _channels[chn]->dim;
, dim_ptr (new MPControl<bool> (false, string_compose (_("dim control"), chn), PBD::Controllable::Toggle))
, polarity_ptr (new MPControl<gain_t> (1.0, string_compose (_("polarity control"), chn), PBD::Controllable::Toggle))
, soloed_ptr (new MPControl<bool> (false, string_compose (_("solo control"), chn), PBD::Controllable::Toggle))
-
+
, cut_control (cut_ptr)
, dim_control (dim_ptr)
, polarity_control (polarity_ptr)
, soloed_control (soloed_ptr)
-
+
, cut (*cut_ptr)
, dim (*dim_ptr)
, polarity (*polarity_ptr)
reset_position = false;
pic = new PIChaser();
-
+
last_mtc_fps_byte = session.get_mtc_timecode_bits ();
mtc_frame = 0;
delete [] speed_accumulator;
}
-bool
+bool
MTC_Slave::give_slave_full_control_over_transport_speed() const
{
return true; // for PiC control */
MTC_Slave::rebind (MIDI::Port& p)
{
port_connections.drop_connections ();
-
+
port = &p;
-
+
port->parser()->mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
port->parser()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
port->parser()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
framepos_t window_root = -1;
DEBUG_TRACE (DEBUG::MTC, string_compose ("full mtc time known at %1, full ? %2\n", now, was_full));
-
+
timecode.hours = msg[3];
timecode.minutes = msg[2];
timecode.seconds = msg[1];
session.config.set_timecode_format (tc_format);
}
- DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC time timestamp = %1 TC %2 = frame %3 (from full message ? %4)\n",
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC time timestamp = %1 TC %2 = frame %3 (from full message ? %4)\n",
now, timecode, mtc_frame, was_full));
-
+
if (was_full || outside_window (mtc_frame)) {
session.timecode_to_sample (timecode, mtc_frame, true, false);
reset_window (mtc_frame);
} else {
-
+
/* we've had the first set of 8 qtr frame messages, determine position
and allow continuing qtr frame messages to provide position
and speed information.
*/
-
+
/* do a careful conversion of the timecode value to a position
- so that we take drop/nondrop and all that nonsense into
+ so that we take drop/nondrop and all that nonsense into
consideration.
*/
session.timecode_to_sample (timecode, mtc_frame, true, false);
-
+
/* We received the last quarter frame 7 quarter frames (1.75 mtc
frames) after the instance when the contents of the mtc quarter
frames were decided. Add time to compensate for the elapsed 1.75
frames. Also compensate for audio latency.
*/
-
+
mtc_frame += (long) (1.75 * session.frames_per_timecode_frame()) + session.worst_playback_latency();
} else {
if (give_slave_full_control_over_transport_speed()) {
- /* PIC
- *
+ /* PIC
+ *
* its not the average, but we will assign it to current.speed below
*/
- static framepos_t last_seen_timestamp = 0;
- static framepos_t last_seen_position = 0;
+ static framepos_t last_seen_timestamp = 0;
+ static framepos_t last_seen_position = 0;
if ((now - last_seen_timestamp) < 300) {
mtc_frame = (mtc_frame + last_seen_position)/2;
last_seen_timestamp = now;
last_seen_position = mtc_frame;
-
-
+
+
} else {
- /* Non-PiC
+ /* Non-PiC
*/
framepos_t time_delta = (now - last_mtc_timestamp);
-
+
if (time_delta != 0) {
double apparent_speed = (mtc_frame - last_mtc_frame) / (double) (time_delta);
-
+
process_apparent_speed (apparent_speed);
DEBUG_TRACE (DEBUG::Slave, string_compose ("apparent speed was %1 average is now %2\n", apparent_speed, average_speed));
} else {
DEBUG_TRACE (DEBUG::Slave, string_compose ("no apparent calc, average is %1\n", average_speed));
}
-
+
/* every second, recalibrate the starting point for the speed measurement */
if (mtc_frame - last_mtc_frame > session.frame_rate()) {
last_mtc_timestamp = now;
current.guard2++;
break;
}
-
+
}
void
if (give_slave_full_control_over_transport_speed()) {
in_control = (session.slave_state() == Session::Running);
- framepos_t pic_want_locate = 0;
+ framepos_t pic_want_locate = 0;
//framepos_t slave_pos = session.audible_frame();
framepos_t slave_pos = session.transport_frame();
static double average_speed = 0;
-
+
framepos_t ref_now = session.engine().frame_time_at_cycle_start();
average_speed = pic->get_ratio (last.timestamp, last.position, ref_now, slave_pos, in_control, session.engine().frames_per_cycle());
-
+
pic_want_locate = pic->want_locate();
-
+
if (in_control && pic_want_locate) {
last.speed = average_speed + (double) (pic_want_locate - session.transport_frame()) / (double)session.get_block_size();
- std::cout << "locate req " << pic_want_locate << " speed: " << average_speed << "\n";
+ std::cout << "locate req " << pic_want_locate << " speed: " << average_speed << "\n";
} else {
last.speed = average_speed;
}
if (in_control) {
pos = session.transport_frame();
} else {
- pos = last.position + elapsed;
+ pos = last.position + elapsed;
}
speed = last.speed;
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position FINAL %1 %2\n", last.speed, pos));
-
+
DEBUG_TRACE (DEBUG::MTC, string_compose ("last = %1 elapsed = %2 pos = %3 speed = %4\n", last.position, elapsed, pos, speed));
-
+
return true;
}
reset (reset_position);
reset_pending = 0;
reset_position = false;
- }
+ }
}
void
void
MTC_Slave::reset_window (framepos_t root)
{
-
+
/* if we're waiting for the master to catch us after seeking ahead, keep the window
of acceptable MTC frames wide open. otherwise, shrink it down to just 2 video frames
ahead of the window root (taking direction into account).
}
window_end = root;
break;
-
+
default:
/* do nothing */
break;
, _soloed (false)
, _solo_ignore (false)
{
-
+
if (Config->get_mute_affects_pre_fader ()) {
_mute_point = MutePoint (_mute_point | PreFader);
}
}
}
}
-
+
return gain;
}
MutePoint old = _mute_point;
_mute_point = (MutePoint) string_2_enum (mute_point, _mute_point);
-
+
if (old != _mute_point) {
MutePointChanged(); /* EMIT SIGNAL */
}
}
void
-MuteMaster::set_mute_points (MutePoint mp)
+MuteMaster::set_mute_points (MutePoint mp)
{
if (_mute_point != mp) {
_mute_point = mp;
{
return (!_solo_ignore && _session.soloing() && (_mute_point & mp));
}
-
+
_auto_state = state;
const Controls& c (controls());
-
+
for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
if (ac) {
ac->alist()->set_automation_state (state);
}
}
-
+
session().set_dirty ();
automation_state_changed (_auto_state);
}
_auto_style = style;
const Controls& c (controls());
-
+
for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
if (ac) {
ac->alist()->set_automation_style (style);
}
}
-
+
session().set_dirty ();
automation_style_changed ();
}
Pannable::start_touch (double when)
{
const Controls& c (controls());
-
+
for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
if (ac) {
Pannable::stop_touch (bool mark, double when)
{
const Controls& c (controls());
-
+
for (Controls::const_iterator ci = c.begin(); ci != c.end(); ++ci) {
boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
if (ac) {
snprintf (buf, sizeof(buf), "%.12g", pan_azimuth_control->get_value());
control_node->add_property (X_("value"), buf);
node->add_child_nocopy (*control_node);
-
+
control_node = new XMLNode (X_("width"));
snprintf (buf, sizeof(buf), "%.12g", pan_width_control->get_value());
control_node->add_property (X_("value"), buf);
snprintf (buf, sizeof(buf), "%.12g", pan_lfe_control->get_value());
control_node->add_property (X_("value"), buf);
node->add_child_nocopy (*control_node);
-
+
node->add_child_nocopy (get_automation_xml_state ());
return *node;
warning << string_compose (_("Pannable given XML data for %1 - ignored"), root.name()) << endmsg;
return -1;
}
-
+
XMLNodeList nlist;
XMLNodeConstIterator niter;
const XMLProperty *prop;
set_automation_xml_state (**niter, PanAzimuthAutomation);
}
}
-
+
_has_state = true;
return 0;
}
-string
+string
Pannable::value_as_string (boost::shared_ptr<AutomationControl> ac) const
{
boost::shared_ptr<Panner> p = panner ();
if (p) {
return p->value_as_string (ac);
- }
+ }
return Automatable::value_as_string (ac);
}
return _pannable->touching ();
}
-set<Evoral::Parameter>
+set<Evoral::Parameter>
Panner::what_can_be_automated() const
{
return _pannable->what_can_be_automated ();
return _pannable->describe_parameter (p);
}
-string
+string
Panner::value_as_string (boost::shared_ptr<AutomationControl> ac) const
{
return _pannable->value_as_string (ac);
PanPluginDescriptor* d;
int32_t nin = in.n_audio();
int32_t nout = out.n_audio();
-
+
/* look for exact match first */
for (list<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) {
for (list<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) {
d = &(*p)->descriptor;
-
+
if (d->in == nin && d->out == -1) {
return *p;
}
for (list<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) {
d = &(*p)->descriptor;
-
+
if (d->in == -1 && d->out == nout) {
return *p;
}
for (list<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) {
d = &(*p)->descriptor;
-
+
if (d->in == -1 && d->out == -1) {
return *p;
}
are of the same type. pretty good
assumption, but it's still an assumption.
*/
-
+
_panner.reset ((*p)->descriptor.factory (_pannable, _session.get_speakers ()));
-
+
if (_panner->set_state (**niter, version) == 0) {
return -1;
}
// Speed quietning
gain_t gain_coeff = 1.0;
-
+
if (fabsf(_session.transport_speed()) > 1.5f && Config->get_quieten_at_speed ()) {
gain_coeff = speed_quietning;
}
for (BufferSet::audio_iterator i = outbufs.audio_begin(); i != outbufs.audio_end(); ++i) {
i->silence(nframes);
}
-
+
_panner->distribute_automated (inbufs, outbufs, start_frame, end_frame, nframes, _session.pan_automation_buffer());
}
}
/*
Copyright (C) 2008 Torben Hohn
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
static inline double hann(double x) {
return 0.5 * (1.0 - cos(2 * M_PI * x));
}
-
-PIController::PIController (double resample_factor, int fir_size)
+
+PIController::PIController (double resample_factor, int fir_size)
{
resample_mean = resample_factor;
static_resample_factor = resample_factor;
offset_differential_index = 0;
offset_integral = 0.0;
smooth_size = fir_size;
-
+
for (int i = 0; i < fir_size; i++) {
offset_array[i] = 0.0;
window_array[i] = hann(double(i) / (double(fir_size) - 1.0));
}
-
+
// These values could be configurable
catch_factor = 20000;
catch_factor2 = 4000;
double this_catch_factor = catch_factor;
double this_catch_factor2 = catch_factor2 * 4096.0/(double)period_size;
-
+
// Save offset.
if( fir_empty ) {
for (int i = 0; i < smooth_size; i++) {
} else {
offset_array[(offset_differential_index++) % smooth_size] = offset;
}
-
+
// Build the mean of the windowed offset array basically fir lowpassing.
smooth_offset = 0.0;
for (int i = 0; i < smooth_size; i++) {
smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i];
}
smooth_offset /= double(smooth_size);
-
+
// This is the integral of the smoothed_offset
offset_integral += smooth_offset;
std::cerr << smooth_offset << " ";
-
+
// Clamp offset : the smooth offset still contains unwanted noise which would go straigth onto the resample coeff.
// It only used in the P component and the I component is used for the fine tuning anyways.
-
+
if (fabs(smooth_offset) < pclamp)
smooth_offset = 0.0;
-
+
smooth_offset += (static_resample_factor - resample_mean) * this_catch_factor;
-
- // Ok, now this is the PI controller.
+
+ // Ok, now this is the PI controller.
// u(t) = K * (e(t) + 1/T \int e(t') dt')
- // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T
- current_resample_factor
+ // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T
+ current_resample_factor
= static_resample_factor - smooth_offset / this_catch_factor - offset_integral / this_catch_factor / this_catch_factor2;
-
+
// Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt.
current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean;
-
+
// Calculate resample_mean so we can init ourselves to saner values.
// resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor;
resample_mean = (1.0-0.01) * resample_mean + 0.01 * current_resample_factor;
std::cerr << fill_level << " " << smooth_offset << " " << offset_integral << " " << current_resample_factor << " " << resample_mean << "\n";
return current_resample_factor;
}
-
-void
+
+void
PIController::out_of_bounds()
{
int i;
// Set the resample_rate... we need to adjust the offset integral, to do this.
// first look at the PI controller, this code is just a special case, which should never execute once
- // everything is swung in.
+ // everything is swung in.
offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
// Also clear the array. we are beginning a new control cycle.
for (i = 0; i < smooth_size; i++) {
feed_estimator( chasetime_measured, chasetime );
std::cerr << (double)chasetime_measured/48000.0 << " " << chasetime << " " << slavetime << " ";
double crude = get_estimate();
- double fine;
+ double fine;
framepos_t massaged_chasetime = chasetime + (framepos_t)( (double)(slavetime_measured - chasetime_measured) * crude );
fine = pic->get_ratio (slavetime - massaged_chasetime, period_size);
speed = crude;
pic->reset( crude );
}
-
+
return speed;
}
: SequenceProperty<std::list<boost::shared_ptr<Region> > > (Properties::regions.property_id, boost::bind (&Playlist::update, &pl, _1))
, _playlist (pl)
{
-
+
}
RegionListProperty::RegionListProperty (RegionListProperty const & p)
/* All regions (even those which are deleted) have their state saved by other
code, so we can just store ID here.
*/
-
+
node.add_property ("id", region->id().to_s ());
}
PBD::ID id (prop->value ());
boost::shared_ptr<Region> ret = _playlist.region_by_id (id);
-
+
if (!ret) {
ret = RegionFactory::region_by_id (id);
}
Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
: SessionObject(sess, "unnamed playlist")
- , regions (*this)
+ , regions (*this)
, _type(type)
{
#ifndef NDEBUG
RegionFactory::region_name (new_name, region->name(), false);
- PropertyList plist;
+ PropertyList plist;
plist.add (Properties::start, region->start() + offset);
plist.add (Properties::length, len);
_session.history().BeginUndoRedo.connect_same_thread (*this, boost::bind (&Playlist::begin_undo, this));
_session.history().EndUndoRedo.connect_same_thread (*this, boost::bind (&Playlist::end_undo, this));
-
+
ContentsChanged.connect_same_thread (*this, boost::bind (&Playlist::mark_session_dirty, this));
}
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) {
if (_refcnt > 2) {
return false;
- }
+ }
bool ret = SessionObject::set_name(str);
if (ret) {
}
Evoral::Range<framepos_t> const extra (r->position(), r->last_position());
-
+
if (holding_state ()) {
-
+
pending_region_extensions.push_back (extra);
-
+
} else {
-
+
list<Evoral::Range<framepos_t> > r;
r.push_back (extra);
RegionsExtended (r);
-
+
}
}
if (!pending_region_extensions.empty ()) {
RegionsExtended (pending_region_extensions);
}
-
+
clear_pending ();
in_flush = false;
{
PropertyList plist;
-
+
plist.add (Properties::start, region->start());
plist.add (Properties::length, length);
plist.add (Properties::name, name);
RegionFactory::region_name (new_name, current->name(), false);
PropertyList plist;
-
+
plist.add (Properties::start, current->start() + (pos2 - pos1));
plist.add (Properties::length, pos3 - pos2);
plist.add (Properties::name, new_name);
RegionFactory::region_name (new_name, current->name(), false);
PropertyList plist;
-
+
plist.add (Properties::start, current->start() + (pos3 - pos1));
plist.add (Properties::length, pos4 - pos3);
plist.add (Properties::name, new_name);
plist.add (Properties::layer, regions.size());
plist.add (Properties::automatic, true);
plist.add (Properties::right_of_split, true);
-
+
region = RegionFactory::create (current, plist);
add_region_internal (region, end);
/* end +++++ */
RegionFactory::region_name (new_name, current->name(), false);
-
+
PropertyList plist;
-
+
plist.add (Properties::start, current->start() + (pos2 - pos1));
plist.add (Properties::length, pos4 - pos2);
plist.add (Properties::name, new_name);
RegionFactory::region_name (new_name, current->name(), false);
PropertyList plist;
-
+
plist.add (Properties::start, current->start());
plist.add (Properties::length, pos3 - pos1);
plist.add (Properties::name, new_name);
framecnt_t length = (framecnt_t) floor (region->length() * (times - floor (times)));
string name;
RegionFactory::region_name (name, region->name(), false);
-
+
{
PropertyList plist;
-
+
plist.add (Properties::start, region->start());
plist.add (Properties::length, length);
plist.add (Properties::name, name);
-
+
boost::shared_ptr<Region> sub = RegionFactory::create (region, plist);
add_region_internal (sub, pos);
}
(*x)->name(),
(*t)));
}
-
+
}
RegionSortByLayer cmp;
void
Playlist::update (const RegionListProperty::ChangeRecord& change)
{
- DEBUG_TRACE (DEBUG::Properties, string_compose ("Playlist %1 updates from a change record with %2 adds %3 removes\n",
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("Playlist %1 updates from a change record with %2 adds %3 removes\n",
name(), change.added.size(), change.removed.size()));
-
+
freeze ();
/* add the added regions */
for (RegionListProperty::ChangeContainer::iterator i = change.added.begin(); i != change.added.end(); ++i) {
error << _("region state node has no ID, ignored") << endmsg;
continue;
}
-
+
ID id = prop->value ();
if ((region = region_by_id (id))) {
region->resume_property_changes ();
continue;
}
-
+
} else if ((region = RegionFactory::create (_session, *child, true)) != 0) {
region->suspend_property_changes ();
} else {
error << _("Playlist: cannot create region from XML") << endmsg;
continue;
}
-
+
add_region (region, region->position(), 1.0);
region->set_last_layer_op( region->layer());
region->resume_property_changes ();
- }
+ }
}
/* update dependents, which was not done during add_region_internal
for (int k = start_division; k <= end_division; ++k) {
layers[j][k].push_back (*i);
}
-
+
if ((*i)->layer() != j) {
changed = true;
}
Playlist::has_region_at (framepos_t const p) const
{
RegionLock (const_cast<Playlist *> (this));
-
+
RegionList::const_iterator i = regions.begin ();
while (i != regions.end() && !(*i)->covers (p)) {
++i;
Playlist::remove_region_by_source (boost::shared_ptr<Source> s)
{
RegionLock rl (this);
-
+
RegionList::iterator i = regions.begin();
while (i != regions.end()) {
RegionList::iterator j = i;
++j;
-
+
if ((*i)->uses_source (s)) {
remove_region_internal (*i);
}
Playlist::find_next_top_layer_position (framepos_t t) const
{
RegionLock rlock (const_cast<Playlist *> (this));
-
+
layer_t const top = top_layer ();
RegionList copy = regions.rlist ();
boost::shared_ptr<Region>
Playlist::combine (const RegionList& r)
{
- PropertyList plist;
+ PropertyList plist;
uint32_t channels = 0;
uint32_t layer = 0;
framepos_t earliest_position = max_framepos;
/* make position relative to zero */
pl->add_region (copied_region, original_region->position() - earliest_position);
-
+
/* use the maximum number of channels for any region */
channels = max (channels, original_region->n_channels());
SourceList sources;
pair<framepos_t,framepos_t> extent = pl->get_extent();
-
+
for (uint32_t chn = 0; chn < channels; ++chn) {
sources.push_back (SourceFactory::createFromPlaylist (_type, _session, pl, id(), parent_name, chn, 0, extent.second, false, false));
-
+
}
-
+
/* now a new whole-file region using the list of sources */
plist.add (Properties::start, 0);
boost::shared_ptr<Region> parent_region = RegionFactory::create (sources, plist, true);
/* now the non-whole-file region that we will actually use in the
- * playlist
+ * playlist
*/
plist.clear ();
*/
freeze ();
-
+
for (RegionList::const_iterator i = r.begin(); i != r.end(); ++i) {
remove_region (*i);
}
/* do type-specific stuff with the originals and the new compound
- region
+ region
*/
-
+
post_combine (originals, compound_region);
/* add the new region at the right location */
-
+
add_region (compound_region, earliest_position);
_combine_ops++;
vector<TwoRegions> old_and_new_regions;
// (1) check that its really a compound region
-
+
if ((pls = boost::dynamic_pointer_cast<PlaylistSource>(target->source (0))) == 0) {
return;
}
/* the leftmost (earliest) edge of the compound region
starts at zero in its source, or larger if it
has been trimmed or content-scrolled.
-
+
the rightmost (latest) edge of the compound region
relative to its source is the starting point plus
the length of the region.
*/
-
+
// (2) get all the original regions
const RegionList& rl (pl->region_list().rlist());
RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
frameoffset_t move_offset = 0;
-
+
/* there are two possibilities here:
1) the playlist that the playlist source was based on
is us, so just add the originals (which belonged to
us anyway) back in the right place.
-
+
2) the playlist that the playlist source was based on
is NOT us, so we need to make copies of each of
the original regions that we find, and add them
switch (original->coverage (adjusted_start, adjusted_end)) {
case OverlapNone:
- /* original region does not cover any part
+ /* original region does not cover any part
of the current state of the compound region
*/
continue;
original->trim_to (adjusted_start, adjusted_end - adjusted_start);
modified_region = true;
break;
-
+
case OverlapExternal:
/* overlap fully covers original, so leave it
as is
original->trim_front (adjusted_start);
modified_region = true;
break;
-
+
case OverlapStart:
/* overlap covers start but ends within, so
* trim the end of the region.
}
/* and add to the list of regions waiting to be
- * re-inserted
+ * re-inserted
*/
originals.push_back (original);
}
/* now move dependent regions back from the compound to this playlist */
-
+
pl->copy_dependents (old_and_new_regions, this);
in_partition = false;
{
/* PlaylistSources are never writable, renameable, removable or destructive */
_flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
-
+
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor ();
snprintf (buf, sizeof (buf), "%" PRIu64, _playlist_length);
node.add_property ("length", buf);
node.add_property ("original", _id.to_s());
-
+
node.add_child_nocopy (_playlist->get_state());
}
int
-PlaylistSource::set_state (const XMLNode& node, int version)
+PlaylistSource::set_state (const XMLNode& node, int version)
{
/* check that we have a playlist ID */
if ((prop = node.property (X_("name"))) == 0) {
throw failed_constructor ();
}
-
+
set_name (prop->value());
if ((prop = node.property (X_("offset"))) == 0) {
, _have_pending_stop_events (false)
, _parameter_changed_since_last_preset (false)
{
-
+
}
Plugin::~Plugin ()
{
-
+
}
void
return &i->second;
}
}
-
+
return 0;
}
MidiBuffer& b = bufs.get_midi (0);
bool looped;
_tracker.track (b.begin(), b.end(), looped);
-
+
if (_have_pending_stop_events) {
/* Transmit note-offs that are pending from the last transport stop */
bufs.merge_from (_pending_stop_events, 0);
/* Create note-offs for any active notes and put them in _pending_stop_events, to be picked
up on the next call to connect_and_run ().
*/
-
+
_pending_stop_events.ensure_buffers (DataType::MIDI, 1, 4096);
_pending_stop_events.get_midi(0).clear ();
_tracker.resolve_notes (_pending_stop_events.get_midi (0), 0);
for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
p.push_back (i->second);
}
-
+
return p;
}
}
bufs.count().set_audio (out);
-
+
} else {
/* does this need to be done with MIDI? it appears not */
-
+
uint32_t in = _plugins[0]->get_info()->n_inputs.n_audio();
uint32_t out = _plugins[0]->get_info()->n_outputs.n_audio();
-
+
if (out > in) {
-
+
/* not active, but something has make up for any channel count increase */
-
+
for (uint32_t n = out - in; n < out; ++n) {
memcpy (bufs.get_audio(n).data(), bufs.get_audio(in - 1).data(), sizeof (Sample) * nframes);
}
}
-
+
bufs.count().set_audio (out);
}
}
ofs << "Hidden";
break;
}
-
+
ofs << ' ';
ofs << (*i).unique_id;;
ofs << endl;
if (!ifs) {
return;
}
-
+
std::string stype;
std::string sstatus;
std::string id;
<< endmsg;
continue;
}
-
+
id = buf;
strip_whitespace_edges (id);
set_status (type, id, status);
}
-
+
ifs.close ();
}
Port::connected_to (std::string const & o) const
{
if (!_engine->connected()) {
- /* in some senses, this answer isn't the right one all the time,
+ /* in some senses, this answer isn't the right one all the time,
because we know about our connections and will re-establish
them when we reconnect to JACK.
*/
c.push_back (jc[i]);
++n;
}
-
+
if (jack_free) {
jack_free (jc);
} else {
{
_port_buffer_offset += nframes;
}
-
+
void
Port::set_public_latency_range (jack_latency_range_t& range, bool playback) const
{
if (!jack_port_set_latency_range) {
return;
}
-
+
DEBUG_TRACE (DEBUG::Latency,
string_compose ("SET PORT %1 %4 PUBLIC latency now [%2 - %3]\n",
name(), range.min, range.max,
DEBUG_TRACE (DEBUG::Latency, string_compose (
"SET PORT %1 playback PRIVATE latency now [%2 - %3]\n",
name(),
- _private_playback_latency.min,
+ _private_playback_latency.min,
_private_playback_latency.max));
} else {
_private_capture_latency = range;
DEBUG_TRACE (DEBUG::Latency, string_compose (
"SET PORT %1 capture PRIVATE latency now [%2 - %3]\n",
- name(),
- _private_capture_latency.min,
+ name(),
+ _private_capture_latency.min,
_private_capture_latency.max));
}
if (playback) {
DEBUG_TRACE (DEBUG::Latency, string_compose (
"GET PORT %1 playback PRIVATE latency now [%2 - %3]\n",
- name(),
- _private_playback_latency.min,
- _private_playback_latency.max));
+ name(),
+ _private_playback_latency.min,
+ _private_playback_latency.max));
return _private_playback_latency;
} else {
DEBUG_TRACE (DEBUG::Latency, string_compose (
"GET PORT %1 capture PRIVATE latency now [%2 - %3]\n",
- name(),
- _private_playback_latency.min,
+ name(),
+ _private_playback_latency.min,
_private_playback_latency.max));
return _private_capture_latency;
}
{
jack_latency_range_t r;
- jack_port_get_latency_range (_jack_port,
+ jack_port_get_latency_range (_jack_port,
sends_output() ? JackPlaybackLatency : JackCaptureLatency,
&r);
DEBUG_TRACE (DEBUG::Latency, string_compose (
- "GET PORT %1: %4 PUBLIC latency range %2 .. %3\n",
+ "GET PORT %1: %4 PUBLIC latency range %2 .. %3\n",
name(), r.min, r.max,
sends_output() ? "PLAYBACK" : "CAPTURE"));
return r;
vector<string> connections;
jack_client_t* jack = _engine->jack();
-
+
if (!jack) {
range.min = 0;
range.max = 0;
get_connections (connections);
if (!connections.empty()) {
-
+
range.min = ~((jack_nframes_t) 0);
range.max = 0;
c != connections.end(); ++c) {
jack_latency_range_t lr;
-
+
if (!AudioEngine::instance()->port_is_mine (*c)) {
/* port belongs to some other JACK client, use
remote_port,
(playback ? JackPlaybackLatency : JackCaptureLatency),
&lr);
-
+
DEBUG_TRACE (DEBUG::Latency, string_compose (
"\t%1 <-> %2 : latter has latency range %3 .. %4\n",
name(), *c, lr.min, lr.max));
for (int i = 0; jc[i]; ++i) {
jack_port_t* port = jack_port_by_name (_engine->jack(), jc[i]);
-
+
if (port && (jack_port_flags (port) & JackPortIsPhysical)) {
if (jack_free) {
jack_free (jc);
_measured_latency = n;
}
-framecnt_t
-PortInsert::latency() const
+framecnt_t
+PortInsert::latency() const
{
/* because we deliver and collect within the same cycle,
all I/O is necessarily delayed by at least frames_per_cycle().
}
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);
if ((prop = node.property ("block_size")) != 0) {
sscanf (prop->value().c_str(), "%u", &blocksize);
}
-
+
//if the jack period is the same as when the value was saved, we can recall our latency..
if ( (_session.get_block_size() == blocksize) && (prop = node.property ("latency")) != 0) {
uint32_t latency = 0;
PortInsert::configure_io (ChanCount in, ChanCount out)
{
assert (!AudioEngine::instance()->process_lock().trylock());
-
+
/* for an insert, processor input corresponds to IO output, and vice versa */
if (_input->ensure_io (in, false, this) != 0) {
return false;
}
-
+
if (_output->ensure_io (out, false, this) != 0) {
return false;
}
{
string aname (a->name());
string bname (b->name());
-
+
string::size_type last_digit_position_a = aname.size();
string::reverse_iterator r_iterator = aname.rbegin();
-
+
while (r_iterator!= aname.rend() && Glib::Unicode::isdigit(*r_iterator)) {
- r_iterator++;
+ r_iterator++;
last_digit_position_a--;
}
-
+
string::size_type last_digit_position_b = bname.size();
r_iterator = bname.rbegin();
-
+
while (r_iterator != bname.rend() && Glib::Unicode::isdigit(*r_iterator)) {
- 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 {
Private<ThreadBuffers>* ProcessThread::_private_thread_buffers = 0;
-static void
+static void
release_thread_buffer (void* arg)
{
BufferManager::put_thread_buffers ((ThreadBuffers*) arg);
if (version < 3000) {
return set_state_2X (node, version);
}
-
+
const XMLProperty *prop;
const XMLProperty *legacy_active = 0;
}
void
-Processor::set_display_to_user (bool yn)
+Processor::set_display_to_user (bool yn)
{
_display_to_user = yn;
}
framepos_t pos = 0;
framecnt_t avail = 0;
boost::shared_ptr<AudioRegion> result;
-
+
cerr << "RBEffect: source region: position = " << region->position()
<< ", start = " << region->start()
<< ", length = " << region->length()
root = new XMLNode("Ardour");
MIDI::Manager* mm = MIDI::Manager::instance();
-
+
if (mm) {
const MIDI::Manager::PortList& ports = mm->get_midi_ports();
-
+
for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
root->add_child_nocopy((*i)->get_state());
}
using namespace ARDOUR;
using namespace PBD;
-namespace ARDOUR {
+namespace ARDOUR {
namespace Properties {
PBD::PropertyDescriptor<bool> muted;
PBD::PropertyDescriptor<bool> opaque;
PBD::PropertyDescriptor<PositionLockStyle> position_lock_style;
}
}
-
+
PBD::Signal2<void,boost::shared_ptr<ARDOUR::Region>,const PropertyChange&> Region::RegionPropertyChanged;
void
/* sync pos is relative to start of file. our start-in-file is now zero,
so set our sync position to whatever the the difference between
_start and _sync_pos was in the other region.
-
+
result is that our new sync pos points to the same point in our source(s)
as the sync in the other region did in its source(s).
-
+
since we start at zero in our source(s), it is not possible to use a sync point that
is before the start. reset it to _start if that was true in the other region.
*/
-
+
if (other->sync_marked()) {
if (other->_start < other->_sync_position) {
/* sync pos was after the start point of the other region */
use_sources (other->_sources);
_start = other->_start + offset;
-
+
/* if the other region had a distinct sync point
set, then continue to use it as best we can.
otherwise, reset sync point back to start.
*/
-
+
if (other->sync_marked()) {
if (other->_sync_position < _start) {
_sync_marked = false;
if (_position_lock_style != ps) {
boost::shared_ptr<Playlist> pl (playlist());
-
+
if (!pl) {
return;
}
-
+
_position_lock_style = ps;
-
+
if (_position_lock_style == MusicTime) {
_session.tempo_map().bbt_time (_position, _bbt_time);
}
send_change (Properties::position_lock_style);
-
+
}
}
a GUI that has moved its representation already.
*/
send_change (Properties::position);
-
+
}
void
} else {
new_start = _start + start_shift;
}
-
+
} else {
return;
}
}
if (new_position < end) { /* can't trim it zero or negative length */
-
+
framecnt_t newlen = 0;
framepos_t delta = 0;
/* can't trim it back past where source position zero is located */
new_position = max (new_position, source_zero);
}
-
+
if (new_position > _position) {
newlen = _length - (new_position - _position);
delta = -1 * (new_position - _position);
newlen = _length + (_position - new_position);
delta = _position - new_position;
}
-
+
trim_to_internal (new_position, newlen);
-
+
if (reset_fade) {
_right_of_split = true;
}
-
+
if (!property_changes_suspended()) {
recompute_at_start ();
}
-
+
if (_transients.size() > 0){
adjust_transients(delta);
}
* length in beats from (1) but at the new position, which is wrong if the region
* straddles a tempo/meter change.
*/
-
+
if (_position != position) {
if (!property_changes_suspended()) {
_last_position = _position;
set_position_internal (position, true);
what_changed.add (Properties::position);
}
-
+
if (_length != length) {
if (!property_changes_suspended()) {
_last_length = _length;
}
if (max_source_level() > 0) {
-
+
XMLNode* nested_node = new XMLNode (X_("NestedSource"));
-
+
/* region is compound - get its playlist and
store that before we list the region that
needs it ...
*/
-
+
for (SourceList::const_iterator s = _sources.begin(); s != _sources.end(); ++s) {
nested_node->add_child_nocopy ((*s)->get_state ());
}
if (_stretch == 0.0f) {
_stretch = 1.0f;
}
-
+
if (_shift == 0.0f) {
_shift = 1.0f;
}
if (send) {
send_change (what_changed);
}
-
+
/* Quick fix for 2.x sessions when region is muted */
if ((prop = node.property (X_("flags")))) {
if (string::npos != prop->value().find("Muted")){
set_muted (true);
}
}
-
+
return 0;
}
Stateful::send_change (what_changed);
if (!Stateful::frozen()) {
-
+
/* Try and send a shared_pointer unless this is part of the constructor.
If so, do nothing.
*/
{
if (!other)
return false;
-
+
if ((_sources.size() != other->_sources.size()) ||
(_master_sources.size() != other->_master_sources.size())) {
return false;
stringstream res;
res << _sources.size() << ":";
-
+
SourceList::const_iterator i;
for (i = _sources.begin(); i != _sources.end(); ++i) {
{
_valid_transients = false;
_transients.clear ();
-
+
send_change (PropertyChange (Properties::valid_transients));
}
return ct;
}
- /* if not locked, we can always move the front later, and the end earlier
+ /* if not locked, we can always move the front later, and the end earlier
*/
ct = CanTrim (ct | FrontTrimLater | EndTrimEarlier);
return ct;
}
-
+
uint32_t
Region::max_source_level () const
{
}
}
-#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
boost_debug_shared_ptr_mark_interesting (ret.get(), "Region");
#endif
return ret;
if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
ret = boost::shared_ptr<Region> (new AudioRegion (other_a, offset));
-
+
} else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
ret = boost::shared_ptr<Region> (new MidiRegion (other_m, offset));
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
// XXX use me in caller where plist is setup, this is start i think srcs.front()->length (srcs.front()->timeline_position())
-
+
ret = boost::shared_ptr<Region> (new AudioRegion (other, srcs));
} else {
}
}
-#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
boost_debug_shared_ptr_mark_interesting (ret.get(), "Region");
#endif
return ret;
boost::shared_ptr<Region>
RegionFactory::create (const SourceList& srcs, const PropertyList& plist, bool announce)
{
- boost::shared_ptr<Region> ret;
+ boost::shared_ptr<Region> ret;
boost::shared_ptr<AudioSource> as;
boost::shared_ptr<MidiSource> ms;
ret = boost::shared_ptr<Region> (new AudioRegion (srcs));
} else if (srcs[0]->type() == DataType::MIDI) {
-
+
ret = boost::shared_ptr<Region> (new MidiRegion (srcs));
}
p.first = r->id();
p.second = r;
- {
+ {
Glib::Mutex::Lock lm (region_map_lock);
region_map.insert (p);
}
region_map.erase (i);
} else if (r == i->second) {
region_map.erase (i);
- }
+ }
i = tmp;
}
}
}
return boost::shared_ptr<Region>();
-}
+}
boost::shared_ptr<Region>
RegionFactory::region_by_name (const std::string& name)
}
}
return boost::shared_ptr<Region>();
-}
+}
void
RegionFactory::clear_map ()
vanish as we leave this scope, thus calling all destructors.
*/
}
-
+
uint32_t
RegionFactory::nregions ()
{
char buf[len];
if ((last_period = old.find_last_of ('.')) == string::npos) {
-
+
/* no period present - add one explicitly */
-
+
old += '.';
last_period = old.length() - 1;
number = 0;
-
+
} else {
-
+
if (last_period < old.length() - 1) {
string period_to_end = old.substr (last_period+1);
-
+
/* extra material after the period */
string::size_type numerals_end = period_to_end.find_first_not_of ("0123456789");
-
+
number = atoi (period_to_end);
-
+
if (numerals_end < period_to_end.length() - 1) {
/* extra material after the end of the digits */
remainder = period_to_end.substr (numerals_end);
}
while (number < (UINT_MAX-1)) {
-
+
const RegionMap& regions (RegionFactory::regions());
RegionMap::const_iterator i;
string sbuf;
return old;
}
-void
+void
RegionFactory::get_regions_using_source (boost::shared_ptr<Source> s, std::set<boost::shared_ptr<Region> >& r)
{
Glib::Mutex::Lock lm (region_map_lock);
}
}
-void
+void
RegionFactory::remove_regions_using_source (boost::shared_ptr<Source> src)
{
Glib::Mutex::Lock lm (region_map_lock);
input = new float[blocksize];
seek (0);
-
+
src_data.src_ratio = ((float) rate) / source->samplerate();
}
error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
throw failed_constructor ();
}
-
+
src_data.input_frames = 0;
src_data.data_in = input;
src_data.end_of_input = 0;
}
-
+
framepos_t
ResampledImportableSource::natural_position () const
{
sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
_session.mark_return_id (_bitslot);
}
-
+
return 0;
}
_intreturn.reset (new InternalReturn (_session));
_intreturn->activate ();
- /* the thing that provides proper control over a control/monitor/listen bus
+ /* the thing that provides proper control over a control/monitor/listen bus
(such as per-channel cut, dim, solo, invert, etc).
*/
_monitor_control.reset (new MonitorProcessor (_session));
{
DEBUG_TRACE (DEBUG::Destruction, string_compose ("route %1 destructor\n", _name));
- /* do this early so that we don't get incoming signals as we are going through destruction
+ /* do this early so that we don't get incoming signals as we are going through destruction
*/
drop_connections ();
/* don't use clear_processors here, as it depends on the session which may
- be half-destroyed by now
+ be half-destroyed by now
*/
Glib::RWLock::WriterLock lm (_processor_lock);
}
bool changed = false;
-
+
for (; i != order_keys.end(); ++i) {
if (i->second != key) {
i->second = key;
abort ();
}
}
-#endif
+#endif
/* should we NOT run plugins here if the route is inactive?
do we catch route != active somewhere higher?
*/
if (_solo_safe != yn) {
_solo_safe = yn;
solo_safe_changed (src);
- }
+ }
}
bool
DEBUG_TRACE (DEBUG::Solo, string_compose (
"%1 SbU delta %2 = %3 old = %4 sbd %5 ss %6 exclusive %7\n",
- name(), delta, _soloed_by_others_upstream, old_sbu,
+ name(), delta, _soloed_by_others_upstream, old_sbu,
_soloed_by_others_downstream, _self_solo, Config->get_exclusive_solo()));
- /* push the inverse solo change to everything that feeds us.
+ /* push the inverse solo change to everything that feeds us.
This is important for solo-within-group. When we solo 1 track out of N that
feed a bus, that track will cause mod_solo_by_upstream (+1) to be called
on the bus. The bus then needs to call mod_solo_by_downstream (-1) on all
tracks that feed it. This will silence them if they were audible because
- of a bus solo, but the newly soloed track will still be audible (because
+ of a bus solo, but the newly soloed track will still be audible (because
it is self-soloed).
but .. do this only when we are being told to solo-by-upstream (i.e delta = +1),
*/
if ((_self_solo || _soloed_by_others_downstream) &&
- ((old_sbu == 0 && _soloed_by_others_upstream > 0) ||
+ ((old_sbu == 0 && _soloed_by_others_upstream > 0) ||
(old_sbu > 0 && _soloed_by_others_upstream == 0))) {
if (delta > 0 || !Config->get_exclusive_solo()) {
sr->mod_solo_by_others_downstream (-delta);
}
}
- }
+ }
}
set_mute_master_solo ();
_route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, _route_group));
return;
}
-
+
/* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
boost::shared_ptr<RouteList> routes = _session.get_routes ();
bool sends_only;
bool does_feed = direct_feeds (*i, &sends_only); // we will recurse anyway, so don't use ::feeds()
-
+
if (does_feed && !sends_only) {
(*i)->set_solo_isolated (yn, (*i)->route_group());
}
DEBUG_TRACE (DEBUG::Processors, string_compose (
"%1 adding processor %2\n", name(), processor->name()));
-
+
ChanCount old_pms = processor_max_streams;
if (!_session.engine().connected() || !processor) {
XMLNodeList const & children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
-
+
while (i != children.end() && (*i)->name() != X_("Redirect")) {
++i;
}
if ((prop = node.property ("type")) != 0) {
- if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
+ if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
prop->value() == "audiounit") {
{
Glib::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
-
+
ProcessorList::iterator i;
bool removed = false;
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
if (configure_processors_unlocked (err)) {
pstate.restore ();
/* we know this will work, because it worked before :) */
{
Glib::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
-
+
ProcessorList::iterator i;
boost::shared_ptr<Processor> processor;
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
if (configure_processors_unlocked (err)) {
pstate.restore ();
/* we know this will work, because it worked before :) */
Route::configure_processors (ProcessorStreams* err)
{
assert (!AudioEngine::instance()->process_lock().trylock());
-
+
if (!_in_configure_processors) {
Glib::RWLock::WriterLock lm (_processor_lock);
return configure_processors_unlocked (err);
}
-
+
return 0;
}
DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
break;
}
-
+
if ((*p)->can_support_io_configuration(in, out)) {
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID=%2 in=%3 out=%4\n",(*p)->name(), (*p)->id(), in, out));
configuration.push_back(make_pair(in, out));
}
DEBUG_TRACE (DEBUG::Processors, "}\n");
-
+
return configuration;
}
if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
break;
}
-
+
(*p)->configure_io(c->first, c->second);
processor_max_streams = ChanCount::max(processor_max_streams, c->first);
processor_max_streams = ChanCount::max(processor_max_streams, c->second);
{
Glib::RWLock::WriterLock lm (_processor_lock);
ProcessorState pstate (this);
-
+
ProcessorList::iterator oiter;
ProcessorList::const_iterator niter;
ProcessorList as_it_will_be;
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
if (configure_processors_unlocked (err)) {
pstate.restore ();
return -1;
} else {
_flags = Flag (0);
}
-
+
if ((prop = node.property (X_("phase-invert"))) != 0) {
boost::dynamic_bitset<> p (_input->n_ports().n_audio ());
if (string_is_affirmative (prop->value ())) {
p.set ();
- }
+ }
set_phase_invert (p);
}
}
if ((prop = node.property (X_("muted"))) != 0) {
-
+
bool first = true;
bool muted = string_is_affirmative (prop->value());
-
+
if (muted) {
string mute_point;
-
+
if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) {
-
+
if (string_is_affirmative (prop->value())){
mute_point = mute_point + "PreFader";
first = false;
}
}
-
+
if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) {
-
+
if (string_is_affirmative (prop->value())){
-
+
if (!first) {
mute_point = mute_point + ",";
}
-
+
mute_point = mute_point + "PostFader";
first = false;
}
}
if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) {
-
+
if (string_is_affirmative (prop->value())){
-
+
if (!first) {
mute_point = mute_point + ",";
}
-
+
mute_point = mute_point + "Listen";
first = false;
}
}
if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) {
-
+
if (string_is_affirmative (prop->value())){
-
+
if (!first) {
mute_point = mute_point + ",";
}
-
+
mute_point = mute_point + "Main";
}
}
-
+
_mute_master->set_mute_points (mute_point);
_mute_master->set_muted_by_self (true);
}
_active = !yn; // force switch
set_active (yn, this);
}
-
+
if ((prop = child->property (X_("gain"))) != 0) {
gain_t val;
_amp->gain_control()->set_value (val);
}
}
-
+
/* Set up Panners in the IO */
XMLNodeList io_nlist = child->children ();
-
+
XMLNodeConstIterator io_niter;
XMLNode *io_child;
-
+
for (io_niter = io_nlist.begin(); io_niter != io_nlist.end(); ++io_niter) {
io_child = *io_niter;
-
+
if (io_child->name() == X_("Panner")) {
_main_outs->panner_shell()->set_state(*io_child, version);
} else if (io_child->name() == X_("Automation")) {
set_remote_control_id (x);
}
- }
+ }
}
return 0;
}
}
- // If the processor (*niter) is not on the route then create it
+ // If the processor (*niter) is not on the route then create it
if (o == _processors.end()) {
Route::silence_unlocked (framecnt_t nframes)
{
/* Must be called with the processor lock held */
-
+
if (!_silent) {
_output->silence (nframes);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<PluginInsert> pi;
-
+
if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
// skip plugins, they don't need anything when we're not active
continue;
}
-
+
(*i)->silence (nframes);
}
-
+
if (nframes == _session.get_block_size()) {
// _silent = true;
}
{
/* master never sends to control outs */
assert (!is_master ());
-
+
/* make sure we have one */
if (!_monitor_send) {
_monitor_send.reset (new InternalSend (_session, _pannable, _mute_master, _session.monitor_out(), Delivery::Listen));
_monitor_send->set_display_to_user (false);
}
-
+
/* set it up */
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
configure_processors (0);
return 0;
}
-/** Add an internal send to a route.
+/** Add an internal send to a route.
* @param route route to send to.
* @param placement placement for the send.
*/
Route::listen_via (boost::shared_ptr<Route> route, Placement placement)
{
assert (route != _session.monitor_out ());
-
+
{
Glib::RWLock::ReaderLock rm (_processor_lock);
return true;
}
-
+
for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
boost::shared_ptr<IOProcessor> iop;
} else {
DEBUG_TRACE (DEBUG::Graph, string_compose ("\tPROC %1 is not an IOP\n", (*r)->name()));
}
-
+
}
DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdoes NOT feed %1\n", other->name()));
if (_session.transport_speed() != 0.0f) {
/* we're rolling but some state is changing (e.g. our diskstream contents)
so we cannot use them. Be silent till this is over.
-
+
XXX note the absurdity of ::no_roll() being called when we ARE rolling!
*/
silence_unlocked (nframes);
_roll_delay = 0;
- }
+ }
return nframes;
}
if (!lm.locked()) {
return 0;
}
-
+
automation_snapshot (_session.transport_frame(), false);
if (n_outputs().n_total() == 0) {
}
_meter_point = p;
-
+
bool meter_was_visible_to_user = _meter->display_to_user ();
{
Glib::RWLock::WriterLock lm (_processor_lock);
-
+
if (_meter_point != MeterCustom) {
_meter->set_display_to_user (false);
-
+
setup_invisible_processors ();
-
+
ProcessorList::iterator loc = find (_processors.begin(), _processors.end(), _meter);
ChanCount m_in;
-
+
if (loc == _processors.begin()) {
m_in = _input->n_ports();
} else {
--before;
m_in = (*before)->output_streams ();
}
-
+
_meter->reflect_inputs (m_in);
-
+
/* we do not need to reconfigure the processors, because the meter
(a) is always ready to handle processor_max_streams
(b) is always an N-in/N-out processor, and thus moving
it doesn't require any changes to the other processors.
*/
-
+
} else {
-
+
// just make it visible and let the user move it
-
+
_meter->set_display_to_user (true);
}
}
meter_change (); /* EMIT SIGNAL */
bool const meter_visibly_changed = (_meter->display_to_user() != meter_was_visible_to_user);
-
+
processors_changed (RouteProcessorChange (RouteProcessorChange::MeterPointChange, meter_visibly_changed)); /* EMIT SIGNAL */
}
{
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
if (configure_processors_unlocked (0)) {
pstate.restore ();
configure_processors_unlocked (0); // it worked before we tried to add it ...
Route::add_export_point()
{
if (!_capturing_processor) {
-
+
_capturing_processor.reset (new CapturingProcessor (_session));
_capturing_processor->activate ();
}
}
-
+
return _capturing_processor;
}
if (!r) {
return;
}
-
+
rl->push_back (r);
if (Config->get_solo_control_is_listen_control()) {
if (!r) {
return 0;
}
-
+
if (Config->get_solo_control_is_listen_control()) {
return r->listening_via_monitor() ? 1.0f : 0.0f;
} else {
if (!r) {
return;
}
-
+
rl->push_back (r);
_session.set_mute (rl, bval);
}
if (!r) {
return 0;
}
-
+
return r->muted() ? 1.0f : 0.0f;
}
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->set_block_size (nframes);
}
-
+
_session.ensure_buffers (n_process_buffers ());
}
* just fine as it is (it will not contain the route
* name if its a port insert, port send or port return).
*/
-
+
if (_main_outs) {
if (_main_outs->set_name (name)) {
/* XXX returning false here is stupid because
_route_group->foreach_route (boost::bind (&Route::set_active, _1, yn, _route_group));
return;
}
-
+
if (_active != yn) {
_active = yn;
_input->set_active (yn);
if (n-- == 0) {
return *i;
}
- }
+ }
}
return boost::shared_ptr<Processor> ();
Route::unknown_processors () const
{
list<string> p;
-
+
Glib::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (boost::dynamic_pointer_cast<UnknownProcessor const> (*i)) {
}
/* we'll build this new list here and then use it */
-
+
ProcessorList new_processors;
/* find visible processors */
-
+
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((*i)->display_to_user ()) {
new_processors.push_back (*i);
assert (!_monitor_control->display_to_user ());
new_processors.push_front (_monitor_control);
}
-
+
/* INTERNAL RETURN */
/* doing this here means that any monitor control will come just after
}
/* EXPORT PROCESSOR */
-
+
if (_capturing_processor) {
assert (!_capturing_processor->display_to_user ());
new_processors.push_front (_capturing_processor);
PropertyDescriptor<bool> select;
PropertyDescriptor<bool> edit;
PropertyDescriptor<bool> route_active;
- }
+ }
}
void
++tmp;
(*i)->leave_route_group ();
-
+
i = tmp;
}
}
if (find (routes->begin(), routes->end(), r) != routes->end()) {
return 0;
}
-
+
r->leave_route_group ();
routes->push_back (r);
r->join_route_group (this);
r->DropReferences.connect_same_thread (*this, boost::bind (&RouteGroup::remove_when_going_away, this, boost::weak_ptr<Route> (r)));
-
+
_session.set_dirty ();
MembershipChanged (); /* EMIT SIGNAL */
return 0;
RouteGroup::get_state (void)
{
XMLNode *node = new XMLNode ("RouteGroup");
-
+
add_properties (*node);
if (!routes->empty()) {
stringstream str;
-
+
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
str << (*i)->id () << ' ';
}
stringstream str (prop->value());
vector<string> ids;
split (str.str(), ids, ' ');
-
+
for (vector<string>::iterator i = ids.begin(); i != ids.end(); ++i) {
PBD::ID id (*i);
boost::shared_ptr<Route> r = _session.route_by_id (id);
-
+
if (r) {
add (r);
- }
+ }
}
}
_active = yn;
send_change (PropertyChange (Properties::active));
-
+
_session.set_dirty ();
}
if (is_hidden() == yn) {
return;
}
-
+
if (yn) {
_hidden = true;
if (Config->get_hiding_groups_deactivates_groups()) {
}
PropertyChanged (Properties::hidden); /* EMIT SIGNAL */
-
+
_session.set_dirty ();
}
} else {
boost::shared_ptr<Bundle> bundle = subgroup_bus->input()->bundle ();
-
+
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
(*i)->output()->disconnect (this);
(*i)->output()->connect_ports_to_bundle (bundle, this);
if (!subgroup_bus) {
return;
}
-
+
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
(*i)->output()->disconnect (this);
/* XXX find a new bundle to connect to */
_amp->deactivate ();
_meter->deactivate ();
_meter->reset ();
-
+
Processor::deactivate ();
}
if (version < 3000) {
return set_state_2X (node, version);
}
-
+
const XMLProperty* prop;
Delivery::set_state (node, version);
, _suspend_timecode_transmission (0)
{
_locations = new Locations (*this);
-
+
playlists.reset (new SessionPlaylists);
_all_route_group->set_active (true, this);
routes.flush ();
_bundles.flush ();
-
+
AudioDiskstream::free_working_buffers();
/* tell everyone who is still standing that we're about to die */
DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
-
+
delete *i;
}
} else {
c = _click_io->set_state (*child->children().front(), Stateful::loading_state_version);
}
-
+
if (c == 0) {
_clicking = Config->get_clicking ();
-
+
} else {
-
+
error << _("could not setup Click I/O") << endmsg;
_clicking = false;
}
}
}
}
-
+
if (_click_io->n_ports () > ChanCount::ZERO) {
_clicking = Config->get_clicking ();
}
}
}
-
+
catch (failed_constructor& err) {
error << _("cannot setup Click I/O") << endmsg;
}
for (uint32_t np = 0; np < inputs[DataType::MIDI].size(); ++np) {
string n = inputs[DataType::MIDI][np];
boost::erase_first (n, X_("alsa_pcm:"));
-
+
boost::shared_ptr<Bundle> c (new Bundle (n, false));
c->add_channel ("", DataType::MIDI);
c->set_port (0, inputs[DataType::MIDI][np]);
add_bundle (c);
}
-
+
/* MIDI output bundles */
for (uint32_t np = 0; np < outputs[DataType::MIDI].size(); ++np) {
if (_is_new && !no_auto_connect()) {
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
-
+
/* don't connect the master bus outputs if there is a monitor bus */
if (_master_out && Config->get_auto_connect_standard_busses() && !_monitor_out) {
uint32_t limit = _monitor_out->n_outputs().get (DataType::AUDIO);
if (mod != 0) {
-
+
for (uint32_t n = 0; n < limit; ++n) {
Port* p = _monitor_out->output()->ports().port(DataType::AUDIO, n);
if (outputs[DataType::AUDIO].size() > (n % mod)) {
connect_to = outputs[DataType::AUDIO][n % mod];
}
-
+
if (!connect_to.empty()) {
if (_monitor_out->output()->connect (p, connect_to, this)) {
error << string_compose (
if (_monitor_out) {
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
-
+
if ((*x)->is_monitor()) {
-
+
/* relax */
-
+
} else if ((*x)->is_master()) {
-
+
/* relax */
-
+
} else {
(*x)->listen_via_monitor ();
if (!track) {
return;
}
-
+
boost::shared_ptr<Playlist> playlist;
if ((playlist = track->playlist()) != 0) {
{
while (1) {
RecordState rs = (RecordState) g_atomic_int_get (&_record_status);
-
+
if (rs == Recording) {
break;
}
if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
-
+
_last_record_location = _transport_frame;
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
-
+
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
set_track_monitor_input_status (true);
}
-
+
RecordStateChanged ();
break;
}
means that we save pending state of which sources the next record will use,
which gives us some chance of recovering from a crash during the record.
*/
-
+
save_state ("", true);
-
+
if (_transport_speed) {
if (!config.get_punch_in()) {
enable_record ();
}
}
}
-
+
bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
if (r2->feeds (r1)) {
/* r1 fed by r2; run r2 early */
} else {
if (r1->not_fed ()) {
if (r2->not_fed ()) {
- /* no ardour-based connections inbound to either route. */
+ /* no ardour-based connections inbound to either route. */
return sort_by_rec_enabled (r1, r2);
} else {
/* r2 has connections, r1 does not; run r1 early */
/* make a copy of the existing list of routes that feed r1 */
Route::FedBy existing (r1->fed_by());
-
+
/* for each route that feeds r1, recurse, marking it as feeding
rbase as well.
*/
/* (*i) went away, ignore it */
continue;
}
-
+
/* r2 is a route that feeds r1 which somehow feeds base. mark
base as being fed by r2
*/
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
DEBUG_TRACE (DEBUG::Graph, string_compose ("%1 fed by ...\n", (*i)->name()));
-
+
const Route::FedBy& fb ((*i)->fed_by());
for (Route::FedBy::const_iterator f = fb.begin(); f != fb.end(); ++f) {
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
+ DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
(*i)->name(), (*i)->order_key ("signal")));
}
#endif
snprintf (name, name_len, "%s", base.c_str());
return true;
}
-
+
do {
snprintf (name, name_len, "%s %" PRIu32, base.c_str(), id);
control_id = ntracks() + nbusses();
bool const use_number = (how_many != 1);
-
+
while (how_many) {
if (!find_route_name (name_template.empty() ? _("Midi") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
error << "cannot find name for new midi track" << endmsg;
}
boost::shared_ptr<MidiTrack> track;
-
+
try {
track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
return;
}
- /* new audio ports: make sure the audio goes somewhere useful,
+ /* new audio ports: make sure the audio goes somewhere useful,
unless the user has no-auto-connect selected.
-
+
The existing ChanCounts don't matter for this call as they are only
to do with matching input and output indices, and we are only changing
outputs here.
*/
ChanCount dummy;
-
+
auto_connect_route (midi_track, dummy, dummy, false, false, ChanCount(), change.before);
}
}
* @param output_start As \a input_start, but for outputs.
*/
void
-Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
+Session::auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start)
{
if (!IO::connecting_legal) {
for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) {
string port;
-
+
if (Config->get_input_auto_connect() & AutoConnectPhysical) {
DEBUG_TRACE (DEBUG::Graph,
string_compose("Get index %1 + %2 % %3 = %4\n",
control_id = ntracks() + nbusses() + 1;
bool const use_number = (how_many != 1);
-
+
while (how_many) {
if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) {
error << "cannot find name for new audio track" << endmsg;
}
boost::shared_ptr<AudioTrack> track;
-
+
try {
track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
<< endmsg;
goto failed;
}
-
+
if (track->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
error << string_compose (
_("cannot configure %1 in/%2 out configuration for new audio track"),
<< endmsg;
goto failure;
}
-
-
+
+
if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) {
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
input_channels, output_channels)
picks up the configuration of the route. During session
loading this normally happens in a different way.
*/
-
+
Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
-
+
IOChange change (IOChange::Type (IOChange::ConfigurationChanged | IOChange::ConnectionsChanged));
change.after = route->input()->n_ports();
route->input()->changed (change, this);
{
ChanCount existing_inputs;
ChanCount existing_outputs;
-
+
count_existing_track_channels (existing_inputs, existing_outputs);
{
mt->output()->changed.connect_same_thread (*this, boost::bind (&Session::midi_output_change_handler, this, _1, _2, boost::weak_ptr<Route>(mt)));
}
}
-
+
if (auto_connect) {
auto_connect_route (r, existing_inputs, existing_outputs, true);
}
(*i)->remove_processor (s);
}
}
- }
+ }
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (route);
if (mt && mt->step_editing()) {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
continue;
- }
+ }
(*i)->set_listen (false, this);
}
}
error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
return;
}
-
+
bool send_changed = false;
if (route->solo_isolated()) {
IsolatedChanged (); /* EMIT SIGNAL */
}
}
-
+
void
Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
{
error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
return;
}
-
+
boost::shared_ptr<RouteList> r = routes.reader ();
int32_t delta;
} else {
delta = -1;
}
-
+
if (delta == 1 && Config->get_exclusive_solo()) {
/* new solo: disable all other solos */
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
continue;
- }
+ }
(*i)->set_solo (false, this);
}
}
solo_update_disabled = true;
-
+
RouteList uninvolved;
-
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
bool via_sends_only;
bool in_signal_flow;
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
continue;
- }
+ }
in_signal_flow = false;
}
in_signal_flow = true;
}
- }
-
+ }
+
if (route->feeds (*i, &via_sends_only)) {
(*i)->mod_solo_by_others_upstream (delta);
in_signal_flow = true;
}
}
-boost::shared_ptr<RouteList>
+boost::shared_ptr<RouteList>
Session::get_routes_with_internal_returns() const
{
boost::shared_ptr<RouteList> r = routes.reader ();
Session::io_name_is_legal (const std::string& name)
{
boost::shared_ptr<RouteList> r = routes.reader ();
-
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->name() == name) {
return false;
}
-
+
if ((*i)->has_io_processor_named (name)) {
return false;
}
}
-
+
return true;
}
}
if (_session_range_location == 0) {
-
+
add_session_range_location (a, b);
-
+
} else {
-
+
if (a < _session_range_location->start()) {
_session_range_location->set_start (a);
}
-
+
if (b > _session_range_location->end()) {
_session_range_location->set_end (b);
}
}
for (list<boost::shared_ptr<Source> >::iterator s = srcs.begin(); s != srcs.end(); ) {
-
+
{
Glib::Mutex::Lock ls (source_lock);
/* remove from the main source list */
if (!tr) {
continue;
}
-
+
list<boost::shared_ptr<Source> >& l = tr->last_capture_sources();
if (!l.empty()) {
set_dirty();
boost::shared_ptr<AudioFileSource> afs;
-
+
if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
if (Config->get_auto_analyse_audio()) {
Analyser::queue_source_for_analysis (source, false);
if (_state_of_the_state & Deletion) {
return;
}
-
+
SourceMap::iterator i;
boost::shared_ptr<Source> source = src.lock();
string spath = sdir.sound_path().to_string();
/* note that we search *without* the extension so that
- we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
+ we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
in the event that this new name is required for
a file format change.
*/
throw failed_constructor();
}
}
-
+
return Glib::path_get_basename (buf);
}
boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (Track* track, string const & n)
{
- /* try to use the existing write source for the track, to keep numbering sane
+ /* try to use the existing write source for the track, to keep numbering sane
*/
if (track) {
*/
list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
-
+
if (!l.empty()) {
assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
return boost::dynamic_pointer_cast<MidiSource> (l.front());
bool
Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
{
- if (a->is_monitor()) {
+ if (a->is_monitor()) {
return true;
}
if (b->is_monitor()) {
if (_total_free_4k_blocks * scale > (double) max_framecnt) {
return max_framecnt;
}
-
+
return (framecnt_t) floor (_total_free_4k_blocks * scale);
}
playlists->update_after_tempo_map_change ();
_locations->apply (*this, &Session::update_locations_after_tempo_map_change);
-
+
set_dirty ();
}
}
/* tell redirects that care that we are about to use a much larger blocksize */
-
+
need_block_size_reset = true;
track.set_block_size (chunk_size);
/* construct a region to represent the bounced material */
PropertyList plist;
-
+
plist.add (Properties::start, 0);
plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position()));
plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true));
-
+
result = RegionFactory::create (srcs, plist);
-
+
}
out:
if (need_block_size_reset) {
track.set_block_size (get_block_size());
}
-
+
unblock_processing ();
return result;
if (tr && tr->record_enabled ()) {
break;
}
-
+
++i;
}
Session::get_available_sync_options () const
{
vector<SyncSource> ret;
-
+
ret.push_back (JACK);
ret.push_back (MTC);
ret.push_back (MIDIClock);
if (!tr) {
continue;
}
-
+
boost::shared_ptr<Playlist> pl = tr->playlist ();
if (!pl) {
continue;
}
-
+
if (pl->has_region_at (p)) {
rl->push_back (*i);
}
}
}
-
+
void
Session::start_time_changed (framepos_t old)
{
if (s == 0) {
return;
}
-
+
Location* l = _locations->auto_loop_location ();
if (l->start() == old) {
if (s == 0) {
return;
}
-
+
Location* l = _locations->auto_loop_location ();
if (l->end() == old) {
SessionDirectory sdir (i->path);
if (!search_path.empty()) {
search_path += ':';
- }
+ }
switch (type) {
case DataType::AUDIO:
search_path += sdir.sound_path().to_string();
}
}
}
-
+
/* now add user-specified locations
*/
for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
search_path += ':';
search_path += *i;
-
+
}
-
+
return search_path;
}
}
search_path += path;
-
+
switch (type) {
case DataType::AUDIO:
config.set_audio_search_path (search_path);
}
boost::shared_ptr<Speakers>
-Session::get_speakers()
+Session::get_speakers()
{
return _speakers;
}
*/
DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency));
-
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_public_port_latencies (max_latency, playback);
}
-
+
if (playback) {
post_playback_latency ();
-
+
} else {
post_capture_latency ();
{
set_worst_playback_latency ();
- boost::shared_ptr<RouteList> r = routes.reader ();
+ boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->is_hidden() && ((*i)->active())) {
_worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ());
}
-
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_latency_compensation (_worst_track_latency);
}
Session::post_capture_latency ()
{
set_worst_capture_latency ();
-
+
/* reflect any changes in capture latencies into capture offsets
*/
-
+
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
_worst_track_latency = 0;
boost::shared_ptr<RouteList> r = routes.reader ();
-
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->is_hidden() && ((*i)->active())) {
framecnt_t tl;
if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) {
some_track_latency_changed = true;
}
- _worst_track_latency = max (tl, _worst_track_latency);
+ _worst_track_latency = max (tl, _worst_track_latency);
}
}
*/
_engine.update_total_latencies ();
return; // everything else will be done in the latency callback
- }
+ }
DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n")
}
SF_INFO info;
SNDFILE* sndfile;
-
+
info.format = 0;
if ((sndfile = sf_open (path.c_str(), SFM_READ, &info)) == 0) {
char errbuf[256];
}
/* read the (possibly multi-channel) click data into a temporary buffer */
-
+
sf_count_t const samples = info.frames * info.channels;
Sample* tmp = new Sample[samples];
warning << _("cannot read data from click soundfile") << endmsg;
*data = 0;
_clicking = false;
-
+
} else {
*data = new Sample[info.frames];
*length = info.frames;
-
+
/* mix down to mono */
-
+
for (int i = 0; i < info.frames; ++i) {
(*data)[i] = 0;
for (int j = 0; j < info.channels; ++j) {
before, after
);
}
-
+
cerr << "Alist not found\n";
} else if (obj_T == "ARDOUR::Crossfade") {
}
/* we failed */
-
+
error << string_compose (
_("could not reconstitute StatefulDiffCommand from XMLNode. object type = %1 id = %2"), obj_T, id.to_s())
<< endmsg;
-
+
return 0;
}
}
void *
-SessionEvent::operator new (size_t)
+SessionEvent::operator new (size_t)
{
CrossThreadPool* p = pool->per_thread_pool ();
SessionEvent* ev = static_cast<SessionEvent*> (p->alloc ());
ev->own_pool = p;
return ev;
}
-
-void
-SessionEvent::operator delete (void *ptr, size_t /*size*/)
+
+void
+SessionEvent::operator delete (void *ptr, size_t /*size*/)
{
Pool* p = pool->per_thread_pool ();
SessionEvent* ev = static_cast<SessionEvent*> (ptr);
stacktrace (cerr, 40);
}
#endif
-
+
if (p == ev->own_pool) {
p->release (ptr);
} else {
process_without_events (nframes);
}
-
+
try {
/* handle export - XXX what about error handling? */
using namespace PBD;
SessionHandlePtr::SessionHandlePtr (Session* s)
- : _session (s)
+ : _session (s)
{
if (_session) {
_session->DropReferences.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this));
}
-}
+}
void
SessionHandlePtr::set_session (Session* s)
SessionHandleRef::SessionHandleRef (Session& s)
- : _session (s)
+ : _session (s)
{
_session.DropReferences.connect_same_thread (*this, boost::bind (&SessionHandleRef::session_going_away, this));
_session.Destroyed.connect_same_thread (*this, boost::bind (&SessionHandleRef::insanity_check, this));
-}
+}
SessionHandleRef::~SessionHandleRef ()
{
RouteList::iterator i;
boost::shared_ptr<RouteList> r = routes.reader();
-
+
for (i = r->begin(); i != r->end(); ++i) {
AudioTrack *at;
-
+
if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
if (trk == at->remote_control_id()) {
at->set_record_enabled (enabled, &mmc);
}
}
-void
-SessionObject::make_property_quarks ()
+void
+SessionObject::make_property_quarks ()
{
Properties::name.property_id = g_quark_from_static_string (X_("name"));
DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for name = %1\n", Properties::name.property_id));
SessionPlaylists::~SessionPlaylists ()
{
DEBUG_TRACE (DEBUG::Destruction, "delete playlists\n");
-
+
for (List::iterator i = playlists.begin(); i != playlists.end(); ) {
SessionPlaylists::List::iterator tmp;
unused_playlists.erase (i);
}
}
-
+
void
SessionPlaylists::track (bool inuse, boost::weak_ptr<Playlist> wpl)
return* i;
}
}
-
+
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
if ((*i)->name() == name) {
return* i;
return* i;
}
}
-
+
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
if ((*i)->id() == id) {
return* i;
list.push_back (*i);
}
}
-
+
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
list.push_back (*i);
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
s.push_back (*i);
}
-
+
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
s.push_back (*i);
}
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
(*i)->destroy_region (r);
}
-
+
for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
(*i)->destroy_region (r);
}
Glib::Mutex::Lock lm (lock);
boost::shared_ptr<Crossfade> c;
-
+
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
c = (*i)->find_crossfade (id);
if (c) {
{
Glib::Mutex::Lock lm (lock);
uint32_t cnt = 0;
-
+
for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
cnt += (*i)->region_use_count (region);
}
Session::compute_stop_limit () const
{
bool const punching = (config.get_punch_in () && _locations->auto_punch_location());
-
+
if (!actively_recording() && !punching && Config->get_stop_at_session_end()) {
return current_end_frame ();
}
using namespace Glib;
SessionEvent*
-Session::get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
+Session::get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool))
{
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
void
Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::RTeventCallback after)
{
- /* its a bit silly to have to do this, but it keeps the API for this public method sane (we're
+ /* its a bit silly to have to do this, but it keeps the API for this public method sane (we're
only going to solo one route) and keeps our ability to use get_rt_event() for the internal
private method.
*/
(*i)->set_solo (!yn, (*i)->route_group());
}
}
-
+
r->set_solo (yn, r->route_group());
-
+
set_dirty();
}
(*i)->set_mute (yn, this);
}
}
-
+
set_dirty();
}
(*i)->set_solo_isolated (yn, this);
}
}
-
+
set_dirty();
}
if (!writable()) {
return;
}
-
+
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_enabled));
}
/* set initial start + end point */
_state_of_the_state = Clean;
-
+
/* set up Master Out and Control Out if necessary */
if (bus_profile) {
r->output()->ensure_io (count, false, this);
}
r->set_remote_control_id (control_id);
-
+
rl.push_back (r);
}
bus_profile->input_ac = AutoConnectOption (0);
bus_profile->output_ac = AutoConnectOption (0);
}
-
+
Config->set_input_auto_connect (bus_profile->input_ac);
Config->set_output_auto_connect (bus_profile->output_ac);
}
if (event->type == JackSessionSaveTemplate)
{
if (save_template( timebuf )) {
- event->flags = JackSessionSaveError;
+ event->flags = JackSessionSaveError;
} else {
string cmd ("ardour3 -P -U ");
cmd += event->client_uuid;
else
{
if (save_state (timebuf)) {
- event->flags = JackSessionSaveError;
+ event->flags = JackSessionSaveError;
} else {
sys::path xml_path (_session_dir->root_path());
xml_path /= legalize_for_path (timebuf) + statefile_suffix;
sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
Stateful::loading_state_version = (major * 1000) + minor;
}
-
+
if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
sys::path backup_path(_session_dir->root_path());
continue;
}
}
-
+
child->add_child_nocopy (siter->second->get_state());
}
}
child->add_child_nocopy (r->state ());
}
}
-
+
RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
if (!cassocs.empty()) {
can->add_property (X_("original"), buf);
ca->add_child_nocopy (*can);
}
- }
+ }
}
if (full_state) {
} else if (playlists->load_unused (*this, *child)) {
goto out;
}
-
+
if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
if (load_compounds (*child)) {
goto out;
}
}
-
+
if ((child = find_named_node (node, "NamedSelections")) != 0) {
if (load_named_selections (*child)) {
goto out;
_bundle_xml_node = new XMLNode (*child);
}
}
-
+
if (version < 3000) {
if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
error << _("Session: XML state has no diskstreams section") << endmsg;
_diskstreams_2X.clear ();
if (version >= 3000) {
-
+
if ((child = find_named_node (node, "RouteGroups")) == 0) {
error << _("Session: XML state has no route groups section") << endmsg;
goto out;
} else if (load_route_groups (*child, version)) {
goto out;
}
-
+
} else if (version < 3000) {
-
+
if ((child = find_named_node (node, "EditGroups")) == 0) {
error << _("Session: XML state has no edit groups section") << endmsg;
goto out;
} else {
route = XMLRouteFactory (**niter, version);
}
-
+
if (route == 0) {
error << _("Session: cannot create Route from XML description.") << endmsg;
return -1;
if (ds_child) {
boost::shared_ptr<Track> track;
-
+
if (type == DataType::AUDIO) {
track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
} else {
track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
}
-
+
if (track->init()) {
return ret;
}
-
+
if (track->set_state (node, version)) {
return ret;
}
-
+
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
#endif
ret = track;
-
+
} else {
boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
} else {
track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
}
-
+
if (track->init()) {
return ret;
}
-
+
if (track->set_state (node, version)) {
return ret;
}
track->set_diskstream (*i);
-
-#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
#endif
ret = track;
-
+
} else {
boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
XMLNodeList calist = node.children();
XMLNodeConstIterator caiter;
XMLProperty *caprop;
-
+
for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
XMLNode* ca = *caiter;
ID orig_id;
ID copy_id;
-
+
if ((caprop = ca->property (X_("original"))) == 0) {
continue;
}
orig_id = caprop->value();
-
+
if ((caprop = ca->property (X_("copy"))) == 0) {
continue;
}
copy_id = caprop->value();
-
+
boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
-
+
if (!orig || !copy) {
warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
- orig_id, copy_id)
+ orig_id, copy_id)
<< endmsg;
continue;
}
-
+
RegionFactory::add_compound_association (orig, copy);
}
if ((*niter)->name() == "Source") {
try {
SourceFactory::create (*this, **niter, true);
- }
+ }
catch (failed_constructor& err) {
error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
}
try {
const XMLNodeList& nlist = node.children();
-
+
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLNode *child = (*niter);
if (child->name() == "NestedSource") {
case 0:
/* user added a new search location, so try again */
goto retry;
-
-
+
+
case 1:
/* user asked to quit the entire session load
*/
set_dirty ();
if (version >= 3000) {
-
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == "RouteGroup") {
RouteGroup* rg = new RouteGroup (*this, "");
g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
-
+
set_dirty ();
}
to hold all the commands that are committed. This keeps the order of
commands correct in the history.
*/
-
+
if (_current_trans == 0) {
/* start a new transaction */
assert (_current_trans_quarks.empty ());
_current_trans = new UndoTransaction();
_current_trans->set_name (g_quark_to_string (q));
}
-
+
_current_trans_quarks.push_front (q);
}
{
assert (_current_trans);
assert (!_current_trans_quarks.empty ());
-
+
struct timeval now;
if (cmd) {
static bool
accept_all_audio_files (const string& path, void */*arg*/)
-{
+{
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false;
}
for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
-
+
if (!audio_region) {
continue;
}
-
+
uint32_t used = playlists->region_use_count (audio_region);
if (used == 0 && !audio_region->automatic()) {
_state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
/* consider deleting all unused playlists */
-
+
if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
ret = 0;
goto out;
if (playlists->source_use_count (fs) != 0) {
all_sources.insert (fs->path());
} else {
-
+
/* we might not remove this source from disk, because it may be used
by other snapshots, but its not being used in this version
so lets get rid of it now, along with any representative regions
in the region list.
*/
-
+
RegionFactory::remove_regions_using_source (i->second);
sources.erase (i);
}
if (candidates) {
for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
-
+
used = false;
spath = **x;
-
+
for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
-
+
if (realpath(spath.c_str(), tmppath1) == 0) {
error << string_compose (_("Cannot expand path %1 (%2)"),
spath, strerror (errno)) << endmsg;
continue;
}
-
+
if (realpath((*i).c_str(), tmppath2) == 0) {
error << string_compose (_("Cannot expand path %1 (%2)"),
(*i), strerror (errno)) << endmsg;
break;
}
}
-
+
if (!used) {
unused.push_back (spath);
}
}
newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
-
+
if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
/* the new path already exists, try versioning */
*/
string base = basename_nosuffix (*x);
- base += "%A"; /* this is what we add for the channel suffix of all native files,
+ base += "%A"; /* this is what we add for the channel suffix of all native files,
or for the first channel of embedded files. it will miss
some peakfiles for other channels
*/
string peakpath = peak_path (base);
-
+
if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
if (::unlink (peakpath.c_str()) != 0) {
error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
r = route_by_remote_id (desc.rid());
break;
}
-
+
if (!r) {
return c;
}
case ControllableDescriptor::Recenable:
{
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
-
+
if (t) {
c = t->rec_enable_control ();
}
uint32_t parameter_index = desc.target (1);
/* revert to zero based counting */
-
+
if (plugin > 0) {
--plugin;
}
-
+
if (parameter_index > 0) {
--parameter_index;
}
boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
-
+
if (p) {
c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
break;
}
- case ControllableDescriptor::SendGain:
+ case ControllableDescriptor::SendGain:
{
uint32_t send = desc.target (0);
/* revert to zero-based counting */
-
+
if (send > 0) {
--send;
}
-
+
boost::shared_ptr<Processor> p = r->nth_send (send);
-
+
if (p) {
boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
boost::shared_ptr<Amp> a = s->amp();
} else {
error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
}
-
+
} else if (n->name() == "PatchChangeDiffCommand") {
PBD::ID id (n->property("midi-source")->value());
Session::setup_midi_machine_control ()
{
MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
-
+
mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
parameter.
*/
-
+
return _solo_cut_control;
}
}
if (abort && did_record) {
- _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
+ _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
}
boost::shared_ptr<RouteList> r = routes.reader ();
if (_requested_return_frame >= 0) {
/* explicit return request pre-queued in event list. overrides everything else */
-
+
cerr << "explicit auto-return to " << _requested_return_frame << endl;
_transport_frame = _requested_return_frame;
if (!synced_to_jack()) {
Location *location = _locations->auto_loop_location();
-
+
if (location != 0) {
_transport_frame = location->start();
} else {
}
} else {
-
+
/* regular auto-return */
-
+
_transport_frame = _last_roll_location;
do_locate = true;
}
- }
+ }
}
- _requested_return_frame = -1;
+ _requested_return_frame = -1;
if (do_locate) {
_engine.transport_locate (_transport_frame);
}
- }
+ }
}
{
play_loop = false;
clear_events (SessionEvent::AutoLoop);
-
+
// set all tracks to NOT use internal looping
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
/* nothing to do, or can't change loop status while recording */
return;
}
-
+
if (yn && Config->get_seamless_loop() && synced_to_jack()) {
warning << string_compose (
_("Seamless looping cannot be supported while %1 is using JACK transport.\n"
<< endmsg;
return;
}
-
+
if (yn) {
play_loop = true;
}
}
}
-
+
/* put the loop event into the event list */
-
+
SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
merge_event (event);
- /* locate to start of loop and roll. If doing seamless loop, force a
+ /* locate to start of loop and roll. If doing seamless loop, force a
locate+buffer refill even if we are positioned there already.
*/
* !(playing a loop with JACK sync)
*
*/
-
+
if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
} else {
if (with_roll) {
todo = PostTransportWork (todo | PostTransportRoll);
- }
+ }
add_post_transport_work (todo);
_butler->schedule_transport_work ();
if (synced_to_jack ()) {
if (clear_state) {
- /* do this here because our response to the slave won't
+ /* do this here because our response to the slave won't
take care of it.
*/
_play_range = false;
} else {
stop_transport (abort);
}
-
+
unset_play_loop ();
} else if (transport_stopped() && speed == 1.0) {
}
} else {
-
+
/* not zero, not 1.0 ... varispeed */
if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
/* if we are reversing relative to the current speed, or relative to the speed
before the last stop, then we have to do extra work.
*/
-
+
PostTransportWork todo = PostTransportWork (0);
if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
add_post_transport_work (todo);
_butler->schedule_transport_work ();
}
-
+
TransportStateChange (); /* EMIT SIGNAL */
}
}
_last_roll_location = _transport_frame;
_last_roll_or_reversal_location = _transport_frame;
-
+
have_looped = false;
/* if record status is Enabled, move it to Recording. if its
try {
new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
}
-
+
catch (failed_constructor& err) {
return;
}
new_slave = new JACK_Slave (_engine.jack());
break;
-
+
default:
new_slave = 0;
break;
/* Called from event-processing context */
unset_play_range ();
-
+
if (range.empty()) {
/* _play_range set to false in unset_play_range()
*/
unset_play_loop ();
list<AudioRange>::size_type sz = range.size();
-
+
if (sz > 1) {
-
- list<AudioRange>::iterator i = range.begin();
+
+ list<AudioRange>::iterator i = range.begin();
list<AudioRange>::iterator next;
-
+
while (i != range.end()) {
-
+
next = i;
++next;
-
+
/* locating/stopping is subject to delays for declicking.
*/
-
+
framepos_t requested_frame = i->end;
-
+
if (requested_frame > current_block_size) {
requested_frame -= current_block_size;
} else {
requested_frame = 0;
}
-
+
if (next == range.end()) {
ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
} else {
ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
}
-
+
merge_event (ev);
-
+
i = next;
}
-
+
} else if (sz == 1) {
ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
merge_event (ev);
-
- }
+
+ }
/* save range so we can do auto-return etc. */
ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
merge_event (ev);
-
+
TransportStateChange ();
}
if (init(_path, false)) {
throw failed_constructor ();
}
-
+
/* file is not opened until write */
}
{
if (create (_path)) {
return -1;
- }
+ }
_open = true;
return 0;
}
if (ev.size() == 0) {
return;
}
-
+
/* printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
name().c_str(), ev.id(), ev.time(), ev.size());
for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
}
if (_model) {
- const Evoral::Event<double> beat_ev (ev.event_type(),
- ev_time_beats,
- ev.size(),
+ const Evoral::Event<double> beat_ev (ev.event_type(),
+ ev_time_beats,
+ ev.size(),
(uint8_t*)ev.buffer());
_model->append (beat_ev, event_id);
- }
+ }
_length_beats = max(_length_beats, ev_time_beats);
if (!_open && open_for_write()) {
error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
/* XXX should probably throw or return something */
- return;
+ return;
}
MidiSource::mark_streaming_midi_write_started (mode);
if (_model) {
_model->set_edited(false);
}
-
+
Evoral::SMF::end_write ();
/* data in the file now, not removable */
- mark_nonremovable ();
+ mark_nonremovable ();
}
bool
while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
time += delta_t;
-
+
if (ret == 0) {
/* meta-event : did we get an event ID ?
}
continue;
- }
-
- if (ret > 0) {
+ }
+
+ if (ret > 0) {
/* not a meta-event */
ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
if (!have_event_id) {
- event_id = Evoral::next_event_id();
+ event_id = Evoral::next_event_id();
}
#ifndef NDEBUG
std::string ss;
-
+
for (uint32_t xx = 0; xx < size; ++xx) {
char b[8];
snprintf (b, sizeof (b), "0x%x ", buf[xx]);
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
delta_t, time, size, ss , ev.event_type(), name()));
#endif
-
+
_model->append (ev, event_id);
if (ev.size() > scratch_size) {
scratch_size = ev.size();
}
-
+
ev.size() = scratch_size; // ensure read_event only allocates if necessary
-
+
_length_beats = max(_length_beats, ev.time());
}
/* event ID's must immediately precede the event they are for
*/
-
+
have_event_id = false;
}
Evoral::SMF::end_write();
/* data in the file means its no longer removable */
- mark_nonremovable ();
+ mark_nonremovable ();
}
void
m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name;
/* normalize a couple of names rather than use what libsndfile gives us */
-
+
if (strncasecmp (format_info.name, "OGG", 3) == 0) {
m[format_info.format & SF_FORMAT_TYPEMASK] = "Ogg";
} else if (strncasecmp (format_info.name, "WAV", 3) == 0) {
_info.channels = 1;
_info.samplerate = rate;
_info.format = fmt;
-
+
/* do not open the file here - do that in write_unlocked() as needed
*/
}
_descriptor = new SndFileDescriptor (_path, writable(), &_info);
_descriptor->Closed.connect_same_thread (file_manager_connection, boost::bind (&SndFileSource::file_closed, this));
SNDFILE* sf = _descriptor->allocate ();
-
+
if (sf == 0) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
if (writable()) {
sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
-
+
if (_flags & Broadcast) {
-
+
if (!_broadcast_info) {
_broadcast_info = new BroadcastInfo;
}
-
+
_broadcast_info->set_from_session (_session, header_position_offset);
_broadcast_info->set_description (string_compose ("BWF %1", _name));
-
+
if (!_broadcast_info->write_to_file (sf)) {
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
_path, _broadcast_info->get_error())
error << string_compose (_("could not allocate file %1 to write header"), _path) << endmsg;
return -1;
}
-
+
int const r = sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE;
_descriptor->release ();
_broadcast_info->set_time_reference (_timeline_position);
SNDFILE* sf = _descriptor->allocate ();
-
+
if (sf == 0 || !_broadcast_info->write_to_file (sf)) {
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
_path, _broadcast_info->get_error())
SndFileSource::write_float (Sample* data, framepos_t frame_pos, framecnt_t cnt)
{
SNDFILE* sf = _descriptor->allocate ();
-
+
if (sf == 0 || sf_seek (sf, frame_pos, SEEK_SET|SFM_WRITE) < 0) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
for (framecnt_t n = 0; n < xfade; ++n) {
xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]);
}
-
+
} else if (xfade) {
/* long xfade length, has to be computed across several calls */
info.samplerate = sf_info.samplerate;
info.channels = sf_info.channels;
info.length = sf_info.frames;
-
+
string major = sndfile_major_format(sf_info.format);
string minor = sndfile_minor_format(sf_info.format);
-
+
if (major.length() + minor.length() < 16) { /* arbitrary */
info.format_name = string_compose("%1/%2", major, minor);
} else {
to make sure its time is as new as the audio
file.
*/
-
+
touch_peakfile ();
}
}
if (version < 3000) {
- /* a source with an XML node must necessarily already exist,
+ /* a source with an XML node must necessarily already exist,
and therefore cannot be removable/writable etc. etc.; 2.X
sometimes marks sources as removable which shouldn't be.
*/
{
// This operation is not allowed for sources for destructive tracks or out-of-session files.
- /* XXX need a way to detect _within_session() condition here - move it from FileSource?
+ /* XXX need a way to detect _within_session() condition here - move it from FileSource?
*/
- if ((_flags & Destructive)) {
+ if ((_flags & Destructive)) {
return;
}
abort ();
}
assert (oldval > 0);
-#else
+#else
g_atomic_int_exchange_and_add (&_use_count, -1);
#endif
}
} catch (failed_constructor&) {
/* oh well, so much for that then ... */
}
-
+
} else {
}
catch (failed_constructor& err) {
-
+
#ifdef USE_COREAUDIO_FOR_FILES
-
+
/* this is allowed to throw */
-
+
Source *src = new CoreAudioSource (s, node);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif
boost::shared_ptr<Source> ret (src);
-
+
if (setup_peakfile (ret, defer_peaks)) {
return boost::shared_ptr<Source>();
}
-
+
ret->check_for_analysis_data_on_disk ();
SourceCreated (ret);
return ret;
// boost_debug_shared_ptr_mark_interesting (src, "Source");
#endif
boost::shared_ptr<Source> ret (src);
-
+
if (setup_peakfile (ret, defer_peaks)) {
return boost::shared_ptr<Source>();
}
}
} else if (type == DataType::MIDI) {
-
+
SMFSource* src = new SMFSource (s, path, SMFSource::Flag(0));
src->load_model (true, true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// XXX writable flags should belong to MidiSource too
boost::shared_ptr<SMFSource> src (new SMFSource (s, path, SndFileSource::default_writable_flags));
assert (src->writable ());
-
+
src->load_model (true, true);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
// boost_debug_shared_ptr_mark_interesting (src, "Source");
try {
boost::shared_ptr<AudioPlaylist> ap = boost::dynamic_pointer_cast<AudioPlaylist>(p);
-
+
if (ap) {
-
+
if (copy) {
ap.reset (new AudioPlaylist (ap, start, len, name, true));
start = 0;
}
-
+
Source* src = new AudioPlaylistSource (s, orig, name, ap, chn, start, len, Source::Flag (0));
boost::shared_ptr<Source> ret (src);
-
+
if (setup_peakfile (ret, defer_peaks)) {
return boost::shared_ptr<Source>();
}
-
+
ret->check_for_analysis_data_on_disk ();
SourceCreated (ret);
return ret;
}
} else if (type == DataType::MIDI) {
-
+
try {
boost::shared_ptr<MidiPlaylist> ap = boost::dynamic_pointer_cast<MidiPlaylist>(p);
-
+
if (ap) {
-
+
if (copy) {
ap.reset (new MidiPlaylist (ap, start, len, name, true));
start = 0;
}
-
+
Source* src = new MidiPlaylistSource (s, orig, name, ap, chn, start, len, Source::Flag (0));
boost::shared_ptr<Source> ret (src);
-
+
SourceCreated (ret);
return ret;
}
, _coords (o._coords)
, _angles (o._angles)
{
-
+
}
Speaker &
Speakers::dump_speakers (ostream& o)
{
for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
- o << "Speaker " << (*i).id << " @ "
+ o << "Speaker " << (*i).id << " @ "
<< (*i).coords().x << ", " << (*i).coords().y << ", " << (*i).coords().z
<< " azimuth " << (*i).angles().azi
<< " elevation " << (*i).angles().ele
update ();
}
-int
+int
Speakers::add_speaker (const AngularVector& position)
{
int id = _speakers.size();
Changed ();
return id;
-}
+}
void
Speakers::remove_speaker (int id)
add_speaker (AngularVector (215.0, 0.0));
break;
- default:
+ default:
{
double degree_step = 360.0 / n;
double deg;
}
}
}
-
+
XMLNode&
Speakers::get_state ()
{
node->add_child_nocopy (*speaker);
}
-
+
return *node;
}
continue;
}
e = atof (prop->value());
-
+
if ((prop = (*i)->property (X_("distance"))) == 0) {
warning << _("Speaker information is missing distance - speaker ignored") << endmsg;
continue;
}
update ();
-
+
return 0;
}
results.clear ();
/* we only operate on AudioRegions, for now, though this could be adapted to MIDI
- as well I guess
+ as well I guess
*/
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
InterThreadInfo itt;
--last_silence;
frameoffset_t const end_of_region = r->start() + r->length();
-
+
if (last_silence->second != end_of_region - 1) {
audible.push_back (std::make_pair (last_silence->second, end_of_region - 1));
}
int n = 0;
int const N = audible.size ();
-
+
for (AudioIntervalResult::const_iterator i = audible.begin(); i != audible.end(); ++i) {
PBD::PropertyList plist;
plist.add (Properties::length, i->second - i->first);
plist.add (Properties::position, r->position() + (i->first - r->start()));
-
+
copy = boost::dynamic_pointer_cast<AudioRegion> (
RegionFactory::create (region, (i->first - r->start()), plist)
);
-
+
copy->set_name (RegionFactory::new_region_name (region->name ()));
framecnt_t const f = std::min (_fade_length, (i->second - i->first));
-
+
copy->set_fade_in_active (true);
copy->set_fade_in (FadeLinear, f);
copy->set_fade_out (FadeLinear, f);
results.push_back (copy);
-
+
if (progress && (n <= N)) {
progress->set_progress (float (n) / N);
}
beats_per_bar = metric.meter().beats_per_bar();
}
-
+
/* We now counted the beats and landed in the target measure, now deal
with ticks this seems complicated, but we want to deal with the
corner case of a sequence of time signatures like 0.2/4-0.7/4 and
difference = mod;
}
- try {
+ try {
the_beat = bbt_subtract (the_beat, BBT_Time (0, 0, difference));
} catch (...) {
/* can't go backwards from wherever pos is, so just return it */
midbar_beats = metric.meter().beats_per_bar() / 2 + 1;
midbar_ticks = BBT_Time::ticks_per_beat * fmod (midbar_beats, 1.0f);
midbar_beats = floor (midbar_beats);
-
+
BBT_Time midbar (bbt.bars, lrintf (midbar_beats), lrintf (midbar_ticks));
if (bbt < midbar) {
/* find beat position preceding frame */
try {
- bbt = bbt_subtract (bbt, one_beat);
+ bbt = bbt_subtract (bbt, one_beat);
}
catch (...) {
/* now comes the complicated part. we have to add one beat a time,
checking for a new metric on every beat.
*/
-
+
/* grab all meter sections */
-
+
list<const MeterSection*> meter_sections;
-
+
for (Metrics::const_iterator x = metrics->begin(); x != metrics->end(); ++x) {
const MeterSection* ms;
if ((ms = dynamic_cast<const MeterSection*>(*x)) != 0) {
meter_sections.push_back (ms);
}
}
-
+
assert (!meter_sections.empty());
-
+
list<const MeterSection*>::const_iterator next_meter;
const Meter* meter = 0;
-
+
/* go forwards through the meter sections till we get to the one
- covering the current value of result. this positions i to point to
+ covering the current value of result. this positions i to point to
the next meter section too, or the end.
*/
-
+
for (next_meter = meter_sections.begin(); next_meter != meter_sections.end(); ++next_meter) {
-
+
if (result < (*next_meter)->start()) {
/* this metric is past the result time. stop looking, we have what we need */
break;
++next_meter;
break;
}
-
+
meter = *next_meter;
}
-
+
assert (meter != 0);
-
- /* OK, now have the meter for the bar start we are on, and i is an iterator
- that points to the metric after the one we are currently dealing with
- (or to metrics->end(), of course)
+
+ /* OK, now have the meter for the bar start we are on, and i is an iterator
+ that points to the metric after the one we are currently dealing with
+ (or to metrics->end(), of course)
*/
-
+
while (op.beats) {
-
+
/* given the current meter, have we gone past the end of the bar ? */
-
+
if (result.beats >= meter->beats_per_bar()) {
/* move to next bar, first beat */
result.bars++;
} else {
result.beats++;
}
-
+
/* one down ... */
-
+
op.beats--;
-
- /* check if we need to use a new meter section: has adding beats to result taken us
+
+ /* check if we need to use a new meter section: has adding beats to result taken us
to or after the start of the next meter section? in which case, use it.
*/
/* now comes the complicated part. we have to subtract one beat a time,
checking for a new metric on every beat.
*/
-
+
/* grab all meter sections */
-
+
list<const MeterSection*> meter_sections;
-
+
for (Metrics::const_iterator x = metrics->begin(); x != metrics->end(); ++x) {
const MeterSection* ms;
if ((ms = dynamic_cast<const MeterSection*>(*x)) != 0) {
meter_sections.push_back (ms);
}
}
-
+
assert (!meter_sections.empty());
-
+
/* go backwards through the meter sections till we get to the one
- covering the current value of result. this positions i to point to
+ covering the current value of result. this positions i to point to
the next (previous) meter section too, or the end.
*/
-
+
const MeterSection* meter = 0;
- list<const MeterSection*>::reverse_iterator next_meter; // older versions of GCC don't
+ list<const MeterSection*>::reverse_iterator next_meter; // older versions of GCC don't
// support const_reverse_iterator::operator!=()
-
+
for (next_meter = meter_sections.rbegin(); next_meter != meter_sections.rend(); ++next_meter) {
-
+
/* when we find the first meter section that is before or at result, use it,
- and set next_meter to the previous one
+ and set next_meter to the previous one
*/
-
+
if ((*next_meter)->start() < result || (*next_meter)->start() == result) {
meter = *next_meter;
++next_meter;
}
assert (meter != 0);
-
- /* OK, now have the meter for the bar start we are on, and i is an iterator
- that points to the metric after the one we are currently dealing with
- (or to metrics->end(), of course)
+
+ /* OK, now have the meter for the bar start we are on, and i is an iterator
+ that points to the metric after the one we are currently dealing with
+ (or to metrics->end(), of course)
*/
-
+
while (op.beats) {
/* have we reached the start of the bar? if so, move to the last beat of the previous
bar. opwise, just step back 1 beat.
*/
-
+
if (result.beats == 1) {
-
+
/* move to previous bar, last beat */
-
+
if (result.bars <= 1) {
/* i'm sorry dave, i can't do that */
throw std::out_of_range ("illegal BBT subtraction");
}
-
+
result.bars--;
result.beats = meter->beats_per_bar();
} else {
result.beats--;
}
-
+
/* one down ... */
op.beats--;
-
- /* check if we need to use a new meter section: has subtracting beats to result taken us
+
+ /* check if we need to use a new meter section: has subtracting beats to result taken us
to before the start of the current meter section? in which case, use the prior one.
*/
frames_per_beat is rounded. Other errors can be introduced
by op.ticks' integer nature.
*/
-
+
Metrics::const_iterator i;
const MeterSection* meter;
const MeterSection* m;
/* now comes the complicated part. we have to add one beat a time,
checking for a new metric on every beat.
*/
-
+
frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
while (op.bars) {
pos += llrint (frames_per_beat * meter->beats_per_bar());
op.bars--;
-
+
/* check if we need to use a new metric section: has adding frames moved us
to or after the start of the next metric section? in which case, use it.
*/
}
while (op.beats) {
-
+
/* given the current meter, have we gone past the end of the bar ? */
pos += frames_per_beat;
op.beats--;
-
+
/* check if we need to use a new metric section: has adding frames moved us
to or after the start of the next metric section? in which case, use it.
*/
meter = m;
}
++i;
- frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
+ frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
}
}
}
/* now comes the complicated part. we have to add one beat a time,
checking for a new metric on every beat.
*/
-
+
frames_per_beat = tempo->frames_per_beat (_frame_rate, *meter);
while (ddist > 0) {
AudioEngine engine ("test", "");
MIDI::Manager::create (engine.jack ());
CPPUNIT_ASSERT (engine.start () == 0);
-
+
Session session (engine, "../../libs/ardour/test/data/mantis_3356", "mantis_3356");
engine.set_session (&session);
CPPUNIT_ASSERT (!result.eof ());
CPPUNIT_ASSERT (!ref.eof ());
}
-
+
}
r.read (A, 64);
r.seek (0);
-
+
Sample B[64];
r.read (B, 64);
void
MidiClockTicker::session_going_away ()
{
- SessionHandlePtr::session_going_away();
- _midi_port = 0;
+ SessionHandlePtr::session_going_away();
+ _midi_port = 0;
}
void MidiClockTicker::update_midi_clock_port()
DEBUG_TRACE (PBD::DEBUG::MidiClock,
string_compose ("Transport state change, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop())
);
-
+
if (speed == 1.0f) {
_last_tick = position;
if (!_midi_port) {
return;
}
-
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
_midi_port->write (_midi_clock_tick, 1, offset);
}
if (!_midi_port) {
return;
}
-
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
_midi_port->write (_midi_clock_tick, 1, offset);
}
if (!_midi_port) {
return;
}
-
+
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
_midi_port->write (_midi_clock_tick, 1, offset);
}
Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
{
_diskstream = ds;
-
+
ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
diskstream_playlist_changed ();
ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
_diskstream->set_capture_offset ();
}
-list<boost::shared_ptr<Source> >
+list<boost::shared_ptr<Source> >
Track::steal_write_sources()
{
return _diskstream->steal_write_sources ();
_diskstream->set_block_size (n);
}
-void
+void
Track::adjust_playback_buffering ()
{
if (_diskstream) {
}
}
-void
+void
Track::adjust_capture_buffering ()
{
if (_diskstream) {
void
Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
-{
- /* never declick if there is an internal generator - we just want it to
+{
+ /* never declick if there is an internal generator - we just want it to
keep generating sound without interruption.
*/
// XXX this should load the above-named plugin and get the current version
_op_id += ":2";
-
+
threshold = 0.00;
}
TransientDetector::update_positions (Readable* src, uint32_t channel, AnalysisFeatureList& positions)
{
Plugin::FeatureSet features;
-
+
Sample* data = 0;
float* bufs[1] = { 0 };
-
+
int buff_size = 1024;
int step_size = 64;
-
+
data = new Sample[buff_size];
bufs[0] = data;
-
+
AnalysisFeatureList::iterator i = positions.begin();
-
+
while (i != positions.end()) {
framecnt_t to_read;
if (src->read (data, (*i) - buff_size, to_read, channel) != to_read) {
break;
}
-
+
// Simple heuristic for locating approx correct cut position.
for (int j = 0; j < buff_size;){
(*i) = (*i) - buff_size + (j + 24);
break;
}
-
+
j = j + step_size;
}
/*
Copyright (C) 2008-2010 Paul Davis
Author: David Robillard
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
return legal;
}
-string
+string
bump_name_once (const std::string& name, char delimiter)
{
string::size_type delim;
posix_dirs.erase (--posix_dirs.end());
dos_dirs.erase (--dos_dirs.end());
-
+
if (G_DIR_SEPARATOR == '/') {
for (vector<string>::iterator x = posix_dirs.begin(); x != posix_dirs.end(); ++x) {
testpath = Glib::build_filename (testpath, *x);
if (type == DataType::MIDI) {
return ".mid";
}
-
+
switch (hf) {
case BWF:
return ".wav";
error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl;
return false;
}
-
+
while ((dentry = ::readdir (dead)) != 0) {
-
+
/* avoid '.' and '..' */
-
+
if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
(dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
continue;
}
-
+
string fullpath = Glib::build_filename (dir, dentry->d_name);
if (::stat (fullpath.c_str(), &statbuf)) {
continue;
}
-
+
if (!S_ISREG (statbuf.st_mode)) {
continue;
}
string bws2 = basename_nosuffix (dentry->d_name);
-
+
if (bws2 == bws) {
ret = true;
break;
} else if (pu == 0) {
- /* use all available CPUs
+ /* use all available CPUs
*/
-
+
num_threads = num_cpu;
} else {
/* use "pu" cores, if available
*/
-
+
num_threads = min (num_cpu, pu);
}
fst_close (_fst);
}
-int
+int
VSTPlugin::set_block_size (pframes_t nframes)
{
deactivate ();
if (data_size == 0) {
return 0;
}
-
+
return g_base64_encode (data, data_size);
}
/* This is a user preset; we load it, and this code also knows about the
non-direct-dispatch thing.
*/
-
+
boost::shared_ptr<XMLTree> t (presets_tree ());
if (t == 0) {
return false;
}
-
+
XMLNode* root = t->root ();
-
+
for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
-
+
XMLProperty* uri = (*i)->property (X_("uri"));
XMLProperty* label = (*i)->property (X_("label"));
-
+
assert (uri);
assert (label);
-
+
if (label->value() != r.label) {
continue;
}
-
+
if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
-
+
/* Load a user preset chunk from our XML file and send it via a circuitous route to the plugin */
-
+
if (_fst->wanted_chunk) {
g_free (_fst->wanted_chunk);
}
-
+
for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
if ((*j)->is_content ()) {
/* we can't dispatch directly here; too many plugins expect only one GUI thread */
return true;
}
}
-
+
return false;
-
+
} else {
-
+
for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
if ((*j)->name() == X_("Parameter")) {
-
+
XMLProperty* index = (*j)->property (X_("index"));
XMLProperty* value = (*j)->property (X_("value"));
-
+
assert (index);
assert (value);
-
+
set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
}
}
-
+
return true;
}
}
-
+
return false;
}
gchar* data = get_chunk (true);
p->add_content (string (data));
g_free (data);
-
+
} else {
p = new XMLNode (X_("Preset"));
p->add_child_nocopy (*c);
}
}
-
+
}
t->root()->add_child_nocopy (*p);
-
+
sys::path f = ARDOUR::user_config_directory ();
f /= "presets";
f /= presets_file ();
-
+
t->write (f.to_string ());
return uri;
}
if (t == 0) {
return;
}
-
+
t->root()->remove_nodes_and_delete (X_("label"), name);
-
+
sys::path f = ARDOUR::user_config_directory ();
f /= "presets";
f /= presets_file ();
-
+
t->write (f.to_string ());
}
pframes_t nframes, framecnt_t offset)
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
-
+
float *ins[_plugin->numInputs];
float *outs[_plugin->numOutputs];
int32_t i;
VSTPlugin::find_presets ()
{
/* Built-in presets */
-
+
int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0);
for (int i = 0; i < _plugin->numPrograms; ++i) {
PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", false);
-
+
if (vst_version >= 2) {
char buf[256];
if (_plugin->dispatcher (_plugin, 29, i, 0, buf, 0) == 1) {
t->set_root (new XMLNode (X_("VSTPresets")));
return t;
}
-
+
t->set_filename (p.to_string ());
if (!t->read ()) {
delete t;
/*
- Copyright (C) 2011 Paul Davis
+ Copyright (C) 2011 Paul Davis
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
using namespace Gtkmm2ext;
CairoCell::CairoCell ()
- : _visible (true)
- , _xpad (5)
+ : _visible (true)
+ , _xpad (5)
{
- bbox.x = 0;
- bbox.y = 0;
- bbox.width = 0;
- bbox.height = 0;
+ bbox.x = 0;
+ bbox.y = 0;
+ bbox.width = 0;
+ bbox.height = 0;
}
CairoTextCell::CairoTextCell (uint32_t wc)
- : _width_chars (wc)
+ : _width_chars (wc)
{
}
void
CairoTextCell::render (Cairo::RefPtr<Cairo::Context>& context)
{
- if (!_visible || _width_chars == 0) {
- return;
- }
+ if (!_visible || _width_chars == 0) {
+ return;
+ }
- context->move_to (bbox.x, bbox.y);
- pango_cairo_update_layout (context->cobj(), layout->gobj());
- pango_cairo_show_layout (context->cobj(), layout->gobj());
+ context->move_to (bbox.x, bbox.y);
+ pango_cairo_update_layout (context->cobj(), layout->gobj());
+ pango_cairo_show_layout (context->cobj(), layout->gobj());
}
void
-CairoTextCell::set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font)
+CairoTextCell::set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font)
{
- layout = Pango::Layout::create (context);
- layout->set_font_description (font);
+ layout = Pango::Layout::create (context);
+ layout->set_font_description (font);
- Pango::FontMetrics metrics = context->get_metrics (font);
+ Pango::FontMetrics metrics = context->get_metrics (font);
- bbox.width = (_width_chars * metrics.get_approximate_digit_width ()) / PANGO_SCALE;
- bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
+ bbox.width = (_width_chars * metrics.get_approximate_digit_width ()) / PANGO_SCALE;
+ bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
}
CairoCell*
-CairoEditableText::get_cell (uint32_t id)
+CairoEditableText::get_cell (uint32_t id)
{
- CellMap::iterator i = cells.find (id);
- if (i == cells.end()) {
- return 0;
- }
- return i->second;
+ CellMap::iterator i = cells.find (id);
+ if (i == cells.end()) {
+ return 0;
+ }
+ return i->second;
}
CairoEditableText::CairoEditableText ()
- : editing_id (0)
- , editing_pos (0)
- , width (0)
- , max_cell_height (0)
- , height (0)
- , corner_radius (24)
- , xpad (10)
- , ypad (5)
+ : editing_id (0)
+ , editing_pos (0)
+ , width (0)
+ , max_cell_height (0)
+ , height (0)
+ , corner_radius (24)
+ , xpad (10)
+ , ypad (5)
{
- add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK |
- Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
- set_flags (Gtk::CAN_FOCUS);
- set_can_default (true);
- set_receives_default (true);
+ add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK |
+ Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+ set_flags (Gtk::CAN_FOCUS);
+ set_can_default (true);
+ set_receives_default (true);
}
bool
CairoEditableText::on_focus_in_event (GdkEventFocus* ev)
{
- return false;
+ return false;
}
bool
CairoEditableText::on_focus_out_event (GdkEventFocus* ev)
{
- if (editing_id) {
- CairoCell* cell = get_cell (editing_id);
- queue_draw_cell (cell);
- editing_id = 0;
- editing_pos = 0;
- }
-
- return false;
+ if (editing_id) {
+ CairoCell* cell = get_cell (editing_id);
+ queue_draw_cell (cell);
+ editing_id = 0;
+ editing_pos = 0;
+ }
+
+ return false;
}
void
CairoEditableText::add_cell (uint32_t id, CairoCell* cell)
{
- if (id > 0) {
- Glib::RefPtr<Pango::Context> context = get_pango_context ();
- cell->set_size (context, font);
+ if (id > 0) {
+ Glib::RefPtr<Pango::Context> context = get_pango_context ();
+ cell->set_size (context, font);
- cells[id] = cell; /* we own it */
- }
+ cells[id] = cell; /* we own it */
+ }
}
void
CairoEditableText::set_text (uint32_t id, const string& text)
{
- CellMap::iterator i = cells.find (id);
+ CellMap::iterator i = cells.find (id);
- if (i == cells.end()) {
- return;
- }
+ if (i == cells.end()) {
+ return;
+ }
- CairoTextCell* textcell = dynamic_cast<CairoTextCell*> (i->second);
+ CairoTextCell* textcell = dynamic_cast<CairoTextCell*> (i->second);
- if (textcell) {
- set_text (textcell, text);
- }
-}
+ if (textcell) {
+ set_text (textcell, text);
+ }
+}
void
CairoEditableText::set_text (CairoTextCell* cell, const string& text)
{
- cell->set_text (text);
- queue_draw_cell (cell);
+ cell->set_text (text);
+ queue_draw_cell (cell);
}
bool
CairoEditableText::on_expose_event (GdkEventExpose* ev)
{
- Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
+ Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
- if (cells.empty()) {
- return true;
- }
+ if (cells.empty()) {
+ return true;
+ }
context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
context->clip ();
- context->set_source_rgba (bg_r, bg_g, bg_b, bg_a);
- rounded_rectangle (context, 0, 0, width, height, corner_radius);
- context->fill ();
-
- for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
-
- uint32_t id = i->first;
- CairoCell* cell = i->second;
-
- /* is cell inside the expose area?
- */
-
- if (cell->intersects (ev->area)) {
-
- if (id == editing_id) {
- context->set_source_rgba (edit_r, edit_b, edit_g, edit_a);
- } else {
- context->set_source_rgba (r, g, b, a);
- }
-
- cell->render (context);
- }
- }
- return true;
+ context->set_source_rgba (bg_r, bg_g, bg_b, bg_a);
+ rounded_rectangle (context, 0, 0, width, height, corner_radius);
+ context->fill ();
+
+ for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
+
+ uint32_t id = i->first;
+ CairoCell* cell = i->second;
+
+ /* is cell inside the expose area?
+ */
+
+ if (cell->intersects (ev->area)) {
+
+ if (id == editing_id) {
+ context->set_source_rgba (edit_r, edit_b, edit_g, edit_a);
+ } else {
+ context->set_source_rgba (r, g, b, a);
+ }
+
+ cell->render (context);
+ }
+ }
+ return true;
}
void
CairoEditableText::queue_draw_cell (CairoCell* cell)
{
- Glib::RefPtr<Gdk::Window> win = get_window();
+ Glib::RefPtr<Gdk::Window> win = get_window();
- if (!win) {
- return;
- }
+ if (!win) {
+ return;
+ }
- Gdk::Rectangle r;
+ Gdk::Rectangle r;
- r.set_x (cell->x());
- r.set_y (cell->y());
- r.set_width (cell->width());
- r.set_height (cell->height());
+ r.set_x (cell->x());
+ r.set_y (cell->y());
+ r.set_width (cell->width());
+ r.set_height (cell->height());
- Gdk::Region rg (r);
- win->invalidate_region (rg, true);
+ Gdk::Region rg (r);
+ win->invalidate_region (rg, true);
}
-CairoCell*
+CairoCell*
CairoEditableText::find_cell (uint32_t x, uint32_t y, uint32_t& id)
{
- for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
- if (i->second->covers (x, y)) {
- id = i->first;
- return i->second;
- }
- }
-
- return 0;
+ for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
+ if (i->second->covers (x, y)) {
+ id = i->first;
+ return i->second;
+ }
+ }
+
+ return 0;
}
bool
CairoEditableText::on_button_press_event (GdkEventButton* ev)
{
- uint32_t id;
- CairoCell* cell;
-
- if (editing_id) {
- cell = get_cell (editing_id);
- /* redraw the old cell */
- queue_draw_cell (cell);
- }
-
- cell = find_cell (ev->x, ev->y, id);
-
- if (!cell) {
- editing_id = 0;
- return false;
- }
-
- grab_focus ();
- editing_id = id;
- editing_pos = 0;
-
- /* redraw the new cell (maybe the same as the old - no real cost) */
- queue_draw_cell (cell);
-
- return true;
+ uint32_t id;
+ CairoCell* cell;
+
+ if (editing_id) {
+ cell = get_cell (editing_id);
+ /* redraw the old cell */
+ queue_draw_cell (cell);
+ }
+
+ cell = find_cell (ev->x, ev->y, id);
+
+ if (!cell) {
+ editing_id = 0;
+ return false;
+ }
+
+ grab_focus ();
+ editing_id = id;
+ editing_pos = 0;
+
+ /* redraw the new cell (maybe the same as the old - no real cost) */
+ queue_draw_cell (cell);
+
+ return true;
}
bool
CairoEditableText::on_button_release_event (GdkEventButton* ev)
{
- return true;
+ return true;
}
bool
CairoEditableText::on_key_press_event (GdkEventKey* ev)
{
- if (!editing_id) {
- return true;
- }
-
- bool commit_change = false;
-
- CairoCell* cell = get_cell (editing_id);
-
- if (!cell) {
- return true;
- }
-
- CairoTextCell* text_cell = dynamic_cast<CairoTextCell*> (cell);
-
- if (!text_cell) {
- return true;
- }
-
- string txt = text_cell->get_text ();
-
- switch (ev->keyval) {
- case GDK_Tab:
- queue_draw_cell (cell);
- edit_next_cell ();
- break;
-
- case GDK_0:
- case GDK_KP_0:
- txt[editing_pos] = '0';
- commit_change = true;
- break;
- case GDK_1:
- case GDK_KP_1:
- txt[editing_pos] = '1';
- commit_change = true;
- break;
- case GDK_2:
- case GDK_KP_2:
- txt[editing_pos] = '2';
- commit_change = true;
- break;
- case GDK_3:
- case GDK_KP_3:
- txt[editing_pos] = '3';
- commit_change = true;
- break;
- case GDK_4:
- case GDK_KP_4:
- txt[editing_pos] = '4';
- commit_change = true;
- break;
- case GDK_5:
- case GDK_KP_5:
- txt[editing_pos] = '5';
- commit_change = true;
- break;
- case GDK_6:
- case GDK_KP_6:
- txt[editing_pos] = '6';
- commit_change = true;
- break;
- case GDK_7:
- case GDK_KP_7:
- txt[editing_pos] = '7';
- commit_change = true;
- break;
- case GDK_8:
- case GDK_KP_8:
- txt[editing_pos] = '8';
- commit_change = true;
- break;
- case GDK_9:
- case GDK_KP_9:
- txt[editing_pos] = '9';
- commit_change = true;
- break;
-
- case GDK_Right:
- if (editing_pos < text_cell->width_chars() - 1) {
- editing_pos++;
- }
- break;
-
- case GDK_Left:
- if (editing_pos > 0) {
- editing_pos--;
- }
- break;
-
- default:
- break;
- }
-
- if (commit_change) {
- set_text (text_cell, txt);
-
- if (++editing_pos >= text_cell->width_chars()) {
- edit_next_cell ();
- }
- }
-
-
- return true;
+ if (!editing_id) {
+ return true;
+ }
+
+ bool commit_change = false;
+
+ CairoCell* cell = get_cell (editing_id);
+
+ if (!cell) {
+ return true;
+ }
+
+ CairoTextCell* text_cell = dynamic_cast<CairoTextCell*> (cell);
+
+ if (!text_cell) {
+ return true;
+ }
+
+ string txt = text_cell->get_text ();
+
+ switch (ev->keyval) {
+ case GDK_Tab:
+ queue_draw_cell (cell);
+ edit_next_cell ();
+ break;
+
+ case GDK_0:
+ case GDK_KP_0:
+ txt[editing_pos] = '0';
+ commit_change = true;
+ break;
+ case GDK_1:
+ case GDK_KP_1:
+ txt[editing_pos] = '1';
+ commit_change = true;
+ break;
+ case GDK_2:
+ case GDK_KP_2:
+ txt[editing_pos] = '2';
+ commit_change = true;
+ break;
+ case GDK_3:
+ case GDK_KP_3:
+ txt[editing_pos] = '3';
+ commit_change = true;
+ break;
+ case GDK_4:
+ case GDK_KP_4:
+ txt[editing_pos] = '4';
+ commit_change = true;
+ break;
+ case GDK_5:
+ case GDK_KP_5:
+ txt[editing_pos] = '5';
+ commit_change = true;
+ break;
+ case GDK_6:
+ case GDK_KP_6:
+ txt[editing_pos] = '6';
+ commit_change = true;
+ break;
+ case GDK_7:
+ case GDK_KP_7:
+ txt[editing_pos] = '7';
+ commit_change = true;
+ break;
+ case GDK_8:
+ case GDK_KP_8:
+ txt[editing_pos] = '8';
+ commit_change = true;
+ break;
+ case GDK_9:
+ case GDK_KP_9:
+ txt[editing_pos] = '9';
+ commit_change = true;
+ break;
+
+ case GDK_Right:
+ if (editing_pos < text_cell->width_chars() - 1) {
+ editing_pos++;
+ }
+ break;
+
+ case GDK_Left:
+ if (editing_pos > 0) {
+ editing_pos--;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (commit_change) {
+ set_text (text_cell, txt);
+
+ if (++editing_pos >= text_cell->width_chars()) {
+ edit_next_cell ();
+ }
+ }
+
+
+ return true;
}
void
CairoEditableText::edit_next_cell ()
{
- CairoCell* next;
- CairoTextCell* next_text;
- uint32_t next_id = editing_id + 1;
-
- while (true) {
- next = get_cell (next_id);
-
- if (!next || !next->visible() || (next_text = dynamic_cast<CairoTextCell*> (next)) != 0) {
- break;
- }
-
- next_id += 1;
- }
-
- if (next) {
- editing_id = next_id;
- editing_pos = 0;
- queue_draw_cell (next_text);
- } else {
- editing_id = 0;
- editing_pos = 0;
- }
+ CairoCell* next;
+ CairoTextCell* next_text;
+ uint32_t next_id = editing_id + 1;
+
+ while (true) {
+ next = get_cell (next_id);
+
+ if (!next || !next->visible() || (next_text = dynamic_cast<CairoTextCell*> (next)) != 0) {
+ break;
+ }
+
+ next_id += 1;
+ }
+
+ if (next) {
+ editing_id = next_id;
+ editing_pos = 0;
+ queue_draw_cell (next_text);
+ } else {
+ editing_id = 0;
+ editing_pos = 0;
+ }
}
bool
CairoEditableText::on_key_release_event (GdkEventKey* ev)
{
- return true;
+ return true;
}
void
CairoEditableText::on_size_request (GtkRequisition* req)
{
- double x = 0;
+ double x = 0;
+
+ max_cell_height = 0;
- max_cell_height = 0;
+ x = xpad;
- x = xpad;
+ for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
+ CairoCell* cell = i->second;
- for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
- CairoCell* cell = i->second;
+ if (cell->visible()) {
+ cell->set_position (x, ypad);
+ }
- if (cell->visible()) {
- cell->set_position (x, ypad);
- }
+ x += cell->width() + cell->xpad();
+ max_cell_height = std::max ((double) cell->height(), max_cell_height);
+ }
- x += cell->width() + cell->xpad();
- max_cell_height = std::max ((double) cell->height(), max_cell_height);
- }
+ x += xpad;
- x += xpad;
-
- req->width = x;
- req->height = max_cell_height + (ypad * 2);
+ req->width = x;
+ req->height = max_cell_height + (ypad * 2);
}
void
CairoEditableText::on_size_allocate (Gtk::Allocation& alloc)
{
- Misc::on_size_allocate (alloc);
+ Misc::on_size_allocate (alloc);
- width = alloc.get_width();
- height = alloc.get_height();
+ width = alloc.get_width();
+ height = alloc.get_height();
}
/*
- Copyright (C) 2011 Paul Davis
+ Copyright (C) 2011 Paul Davis
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cairomm/cairomm.h>
#include <gtkmm.h>
-class CairoCell
+class CairoCell
{
- public:
- CairoCell();
- virtual ~CairoCell() {}
-
- virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
-
- double x() const { return bbox.x; }
- double y() const { return bbox.y; }
- double width() const { return bbox.width; }
- double height() const { return bbox.height; }
-
- void set_position (double x, double y) {
- bbox.x = x;
- bbox.y = y;
- }
-
- bool intersects (GdkRectangle& r) const {
- return gdk_rectangle_intersect (&r, &bbox, 0);
- }
-
- bool covers (double x, double y) const {
- return bbox.x <= x && bbox.x + bbox.width > x &&
- bbox.y <= y && bbox.y + bbox.height > y;
- }
-
- double xpad() const { return _xpad; }
- void set_xpad (double x) { _xpad = x; }
-
- void set_visible (bool yn) { _visible = yn; }
- bool visible() const { return _visible; }
- virtual void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&) {}
-
- protected:
- GdkRectangle bbox;
- bool _visible;
- uint32_t _xpad;
+public:
+ CairoCell();
+ virtual ~CairoCell() {}
+
+ virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
+
+ double x() const { return bbox.x; }
+ double y() const { return bbox.y; }
+ double width() const { return bbox.width; }
+ double height() const { return bbox.height; }
+
+ void set_position (double x, double y) {
+ bbox.x = x;
+ bbox.y = y;
+ }
+
+ bool intersects (GdkRectangle& r) const {
+ return gdk_rectangle_intersect (&r, &bbox, 0);
+ }
+
+ bool covers (double x, double y) const {
+ return bbox.x <= x && bbox.x + bbox.width > x &&
+ bbox.y <= y && bbox.y + bbox.height > y;
+ }
+
+ double xpad() const { return _xpad; }
+ void set_xpad (double x) { _xpad = x; }
+
+ void set_visible (bool yn) { _visible = yn; }
+ bool visible() const { return _visible; }
+ virtual void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&) {}
+
+protected:
+ GdkRectangle bbox;
+ bool _visible;
+ uint32_t _xpad;
};
-class CairoBarCell : public CairoCell
+class CairoBarCell : public CairoCell
{
- public:
- CairoBarCell() {};
-
- void render (Cairo::RefPtr<Cairo::Context>& context) {
- context->move_to (bbox.x, bbox.y);
- context->set_line_width (bbox.width);
- context->rel_line_to (0, bbox.height);
- context->stroke ();
- }
-
- void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
- Pango::FontMetrics metrics = context->get_metrics (font);
- bbox.width = 2;
- bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
- }
-
- private:
+public:
+ CairoBarCell() {};
+
+ void render (Cairo::RefPtr<Cairo::Context>& context) {
+ context->move_to (bbox.x, bbox.y);
+ context->set_line_width (bbox.width);
+ context->rel_line_to (0, bbox.height);
+ context->stroke ();
+ }
+
+ void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
+ Pango::FontMetrics metrics = context->get_metrics (font);
+ bbox.width = 2;
+ bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
+ }
+
+private:
};
-class CairoColonCell : public CairoCell
+class CairoColonCell : public CairoCell
{
- public:
- CairoColonCell() {};
-
- void render (Cairo::RefPtr<Cairo::Context>& context) {
- /* two very small circles, at 1/3 and 2/3 of the height */
- context->arc (bbox.x, bbox.y + (bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
- context->fill ();
- context->arc (bbox.x, bbox.y + (2.0 * bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
- context->fill ();
- }
-
- void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
- Pango::FontMetrics metrics = context->get_metrics (font);
- bbox.width = 3.0;
- bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
- }
-
- private:
+public:
+ CairoColonCell() {};
+
+ void render (Cairo::RefPtr<Cairo::Context>& context) {
+ /* two very small circles, at 1/3 and 2/3 of the height */
+ context->arc (bbox.x, bbox.y + (bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
+ context->fill ();
+ context->arc (bbox.x, bbox.y + (2.0 * bbox.height/3.0), 1.5, 0.0, M_PI*2.0);
+ context->fill ();
+ }
+
+ void set_size (Glib::RefPtr<Pango::Context>& context, const Pango::FontDescription& font) {
+ Pango::FontMetrics metrics = context->get_metrics (font);
+ bbox.width = 3.0;
+ bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
+ }
+
+private:
};
class CairoTextCell : public CairoCell
{
- public:
- CairoTextCell (uint32_t width_chars);
+public:
+ CairoTextCell (uint32_t width_chars);
- void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&);
+ void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&);
- void set_text (const std::string& txt) {
- layout->set_text (txt);
- }
- std::string get_text() const {
- return layout->get_text ();
- }
- uint32_t width_chars() const { return _width_chars; }
+ void set_text (const std::string& txt) {
+ layout->set_text (txt);
+ }
+ std::string get_text() const {
+ return layout->get_text ();
+ }
+ uint32_t width_chars() const { return _width_chars; }
- void render (Cairo::RefPtr<Cairo::Context>&);
+ void render (Cairo::RefPtr<Cairo::Context>&);
- protected:
- uint32_t _width_chars;
- Glib::RefPtr<Pango::Layout> layout;
+protected:
+ uint32_t _width_chars;
+ Glib::RefPtr<Pango::Layout> layout;
};
class CairoEditableText : public Gtk::Misc
{
- public:
- CairoEditableText ();
-
- void add_cell (uint32_t id, CairoCell*);
- CairoCell* get_cell (uint32_t id);
-
- void set_text (uint32_t id, const std::string& text);
-
- void set_colors (double cr, double cg, double cb, double ca) {
- r = cr;
- g = cg;
- b = cb;
- a = ca;
- queue_draw ();
- }
-
- void set_edit_colors (double cr, double cg, double cb, double ca) {
- edit_r = cr;
- edit_g = cg;
- edit_b = cb;
- edit_a = ca;
- queue_draw ();
- }
-
- void set_bg (double r, double g, double b, double a) {
- bg_r = r;
- bg_g = g;
- bg_b = b;
- bg_a = a;
- }
-
- bool on_expose_event (GdkEventExpose*);
- bool on_key_press_event (GdkEventKey*);
- bool on_key_release_event (GdkEventKey*);
- bool on_button_press_event (GdkEventButton*);
- bool on_button_release_event (GdkEventButton*);
- void on_size_request (GtkRequisition*);
- void on_size_allocate (Gtk::Allocation&);
- bool on_focus_in_event (GdkEventFocus*);
- bool on_focus_out_event (GdkEventFocus*);
-
- void set_font (const std::string& str) {
- font = Pango::FontDescription (str);
- }
-
- private:
- typedef std::map<uint32_t,CairoCell*> CellMap;
-
- CellMap cells;
- Pango::FontDescription font;
- uint32_t editing_id;
- uint32_t editing_pos;
- double width;
- double max_cell_height;
- double height;
- double corner_radius;
- double xpad;
- double ypad;
- double r;
- double g;
- double b;
- double a;
- double edit_r;
- double edit_g;
- double edit_b;
- double edit_a;
- double bg_r;
- double bg_g;
- double bg_b;
- double bg_a;
-
-
- CairoCell* find_cell (uint32_t x, uint32_t y, uint32_t& cell_id);
- void edit_next_cell ();
- void queue_draw_cell (CairoCell* target);
- void set_text (CairoTextCell* cell, const std::string&);
+public:
+ CairoEditableText ();
+
+ void add_cell (uint32_t id, CairoCell*);
+ CairoCell* get_cell (uint32_t id);
+
+ void set_text (uint32_t id, const std::string& text);
+
+ void set_colors (double cr, double cg, double cb, double ca) {
+ r = cr;
+ g = cg;
+ b = cb;
+ a = ca;
+ queue_draw ();
+ }
+
+ void set_edit_colors (double cr, double cg, double cb, double ca) {
+ edit_r = cr;
+ edit_g = cg;
+ edit_b = cb;
+ edit_a = ca;
+ queue_draw ();
+ }
+
+ void set_bg (double r, double g, double b, double a) {
+ bg_r = r;
+ bg_g = g;
+ bg_b = b;
+ bg_a = a;
+ }
+
+ bool on_expose_event (GdkEventExpose*);
+ bool on_key_press_event (GdkEventKey*);
+ bool on_key_release_event (GdkEventKey*);
+ bool on_button_press_event (GdkEventButton*);
+ bool on_button_release_event (GdkEventButton*);
+ void on_size_request (GtkRequisition*);
+ void on_size_allocate (Gtk::Allocation&);
+ bool on_focus_in_event (GdkEventFocus*);
+ bool on_focus_out_event (GdkEventFocus*);
+
+ void set_font (const std::string& str) {
+ font = Pango::FontDescription (str);
+ }
+
+private:
+ typedef std::map<uint32_t,CairoCell*> CellMap;
+
+ CellMap cells;
+ Pango::FontDescription font;
+ uint32_t editing_id;
+ uint32_t editing_pos;
+ double width;
+ double max_cell_height;
+ double height;
+ double corner_radius;
+ double xpad;
+ double ypad;
+ double r;
+ double g;
+ double b;
+ double a;
+ double edit_r;
+ double edit_g;
+ double edit_b;
+ double edit_a;
+ double bg_r;
+ double bg_g;
+ double bg_b;
+ double bg_a;
+
+
+ CairoCell* find_cell (uint32_t x, uint32_t y, uint32_t& cell_id);
+ void edit_next_cell ();
+ void queue_draw_cell (CairoCell* target);
+ void set_text (CairoTextCell* cell, const std::string&);
};
#endif /* __libgtmm2ext_cairocell_h__ */