merge with master
This commit is contained in:
commit
9aacefc170
@ -214,6 +214,16 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||
void
|
||||
AudioTimeAxisView::ensure_pan_views (bool show)
|
||||
{
|
||||
bool changed = false;
|
||||
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
|
||||
changed = true;
|
||||
(*i)->set_marked_for_display (false);
|
||||
}
|
||||
if (changed) {
|
||||
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
pan_tracks.clear();
|
||||
|
||||
if (!_route->panner()) {
|
||||
return;
|
||||
}
|
||||
@ -250,6 +260,8 @@ AudioTimeAxisView::ensure_pan_views (bool show)
|
||||
|
||||
pan_tracks.push_back (t);
|
||||
add_automation_child (*p, t, show);
|
||||
} else {
|
||||
pan_tracks.push_back (automation_child (pan_control->parameter ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,14 +403,16 @@ AudioTimeAxisView::build_automation_action_menu (bool for_selection)
|
||||
|
||||
_main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item;
|
||||
|
||||
automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility)));
|
||||
pan_automation_item = dynamic_cast<Gtk::CheckMenuItem*> (&automation_items.back ());
|
||||
pan_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
|
||||
(!pan_tracks.empty() && string_is_affirmative (pan_tracks.front()->gui_property ("visible"))));
|
||||
if (!pan_tracks.empty()) {
|
||||
automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility)));
|
||||
pan_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
|
||||
pan_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
|
||||
(!pan_tracks.empty() && string_is_affirmative (pan_tracks.front()->gui_property ("visible"))));
|
||||
|
||||
set<Evoral::Parameter> const & params = _route->pannable()->what_can_be_automated ();
|
||||
for (set<Evoral::Parameter>::const_iterator p = params.begin(); p != params.end(); ++p) {
|
||||
_main_automation_menu_map[*p] = pan_automation_item;
|
||||
set<Evoral::Parameter> const & params = _route->pannable()->what_can_be_automated ();
|
||||
for (set<Evoral::Parameter>::iterator p = params.begin(); p != params.end(); ++p) {
|
||||
_main_automation_menu_map[*p] = pan_automation_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1153,9 +1153,10 @@ AutomationLine::view_to_model_coord_y (double& y) const
|
||||
y = max (0.0, y);
|
||||
y = min (2.0, y);
|
||||
} else if (alist->parameter().type() == PanAzimuthAutomation ||
|
||||
alist->parameter().type() == PanElevationAutomation ||
|
||||
alist->parameter().type() == PanWidthAutomation) {
|
||||
alist->parameter().type() == PanElevationAutomation) {
|
||||
y = 1.0 - y;
|
||||
} else if (alist->parameter().type() == PanWidthAutomation) {
|
||||
y = 2.0 * y - 1.0;
|
||||
} else if (alist->parameter().type() == PluginAutomation) {
|
||||
y = y * (double)(alist->get_max_y()- alist->get_min_y()) + alist->get_min_y();
|
||||
} else {
|
||||
@ -1171,10 +1172,10 @@ AutomationLine::model_to_view_coord (double& x, double& y) const
|
||||
alist->parameter().type() == EnvelopeAutomation) {
|
||||
y = gain_to_slider_position_with_max (y, Config->get_max_gain());
|
||||
} else if (alist->parameter().type() == PanAzimuthAutomation ||
|
||||
alist->parameter().type() == PanElevationAutomation ||
|
||||
alist->parameter().type() == PanWidthAutomation) {
|
||||
// vertical coordinate axis reversal
|
||||
alist->parameter().type() == PanElevationAutomation) {
|
||||
y = 1.0 - y;
|
||||
} else if (alist->parameter().type() == PanWidthAutomation) {
|
||||
y = .5 + y * .5;
|
||||
} else if (alist->parameter().type() == PluginAutomation) {
|
||||
y = (y - alist->get_min_y()) / (double)(alist->get_max_y()- alist->get_min_y());
|
||||
} else {
|
||||
|
@ -46,6 +46,9 @@
|
||||
#include "ardour/midi_source.h"
|
||||
#include "ardour/midi_track.h"
|
||||
#include "ardour/operations.h"
|
||||
#include "ardour/pannable.h"
|
||||
#include "ardour/panner.h"
|
||||
#include "ardour/panner_shell.h"
|
||||
#include "ardour/playlist.h"
|
||||
#include "ardour/region.h"
|
||||
#include "ardour/region_factory.h"
|
||||
@ -162,7 +165,17 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
||||
controls_ebox.set_name ("MidiBusControlsBaseUnselected");
|
||||
}
|
||||
|
||||
/* if set_state above didn't create a gain automation child, we need to make one */
|
||||
if (automation_child (GainAutomation) == 0) {
|
||||
create_automation_child (GainAutomation, false);
|
||||
}
|
||||
|
||||
if (_route->panner_shell()) {
|
||||
_route->panner_shell()->Changed.connect (*this, invalidator (*this), boost::bind (&MidiTimeAxisView::ensure_pan_views, this, false), gui_context());
|
||||
}
|
||||
|
||||
/* map current state of the route */
|
||||
ensure_pan_views (false);
|
||||
|
||||
processors_changed (RouteProcessorChange ());
|
||||
|
||||
@ -580,6 +593,27 @@ MidiTimeAxisView::build_automation_action_menu (bool for_selection)
|
||||
MenuElem (string_compose ("<i>%1</i>", _("No MIDI Channels selected"))));
|
||||
dynamic_cast<Label*> (automation_items.back().get_child())->set_use_markup (true);
|
||||
}
|
||||
|
||||
automation_items.push_back (SeparatorElem());
|
||||
automation_items.push_back (CheckMenuElem (_("Fader"), sigc::mem_fun (*this, &MidiTimeAxisView::update_gain_track_visibility)));
|
||||
gain_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
|
||||
gain_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
|
||||
(gain_track && string_is_affirmative (gain_track->gui_property ("visible"))));
|
||||
|
||||
_main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item;
|
||||
|
||||
if (!pan_tracks.empty()) {
|
||||
automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &MidiTimeAxisView::update_pan_track_visibility)));
|
||||
pan_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
|
||||
pan_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
|
||||
(!pan_tracks.empty() && string_is_affirmative (pan_tracks.front()->gui_property ("visible"))));
|
||||
|
||||
set<Evoral::Parameter> const & params = _route->pannable()->what_can_be_automated ();
|
||||
for (set<Evoral::Parameter>::iterator p = params.begin(); p != params.end(); ++p) {
|
||||
_main_automation_menu_map[*p] = pan_automation_item;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -1071,6 +1105,94 @@ MidiTimeAxisView::update_range()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::ensure_pan_views (bool show)
|
||||
{
|
||||
bool changed = false;
|
||||
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
|
||||
changed = true;
|
||||
(*i)->set_marked_for_display (false);
|
||||
}
|
||||
if (changed) {
|
||||
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
pan_tracks.clear();
|
||||
|
||||
if (!_route->panner()) {
|
||||
return;
|
||||
}
|
||||
|
||||
set<Evoral::Parameter> params = _route->panner()->what_can_be_automated();
|
||||
set<Evoral::Parameter>::iterator p;
|
||||
|
||||
for (p = params.begin(); p != params.end(); ++p) {
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> pan_control = _route->pannable()->automation_control(*p);
|
||||
|
||||
if (pan_control->parameter().type() == NullAutomation) {
|
||||
error << "Pan control has NULL automation type!" << endmsg;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (automation_child (pan_control->parameter ()).get () == 0) {
|
||||
|
||||
/* we don't already have an AutomationTimeAxisView for this parameter */
|
||||
|
||||
std::string const name = _route->panner()->describe_parameter (pan_control->parameter ());
|
||||
|
||||
boost::shared_ptr<AutomationTimeAxisView> t (
|
||||
new AutomationTimeAxisView (_session,
|
||||
_route,
|
||||
_route->pannable(),
|
||||
pan_control,
|
||||
pan_control->parameter (),
|
||||
_editor,
|
||||
*this,
|
||||
false,
|
||||
parent_canvas,
|
||||
name)
|
||||
);
|
||||
|
||||
pan_tracks.push_back (t);
|
||||
add_automation_child (*p, t, show);
|
||||
} else {
|
||||
pan_tracks.push_back (automation_child (pan_control->parameter ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::update_gain_track_visibility ()
|
||||
{
|
||||
bool const showit = gain_automation_item->get_active();
|
||||
|
||||
if (showit != string_is_affirmative (gain_track->gui_property ("visible"))) {
|
||||
gain_track->set_marked_for_display (showit);
|
||||
|
||||
/* now trigger a redisplay */
|
||||
|
||||
if (!no_redraw) {
|
||||
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::update_pan_track_visibility ()
|
||||
{
|
||||
bool const showit = pan_automation_item->get_active();
|
||||
bool changed = false;
|
||||
|
||||
for (list<boost::shared_ptr<AutomationTimeAxisView> >::iterator i = pan_tracks.begin(); i != pan_tracks.end(); ++i) {
|
||||
if ((*i)->set_marked_for_display (showit)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
_route->gui_changed (X_("visible_tracks"), (void *) 0); /* EMIT_SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTimeAxisView::show_all_automation (bool apply_to_selection)
|
||||
{
|
||||
@ -1177,6 +1299,12 @@ MidiTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||
add_automation_child (param, track, show);
|
||||
break;
|
||||
|
||||
case PanWidthAutomation:
|
||||
case PanElevationAutomation:
|
||||
case PanAzimuthAutomation:
|
||||
ensure_pan_views (show);
|
||||
break;
|
||||
|
||||
default:
|
||||
error << "MidiTimeAxisView: unknown automation child "
|
||||
<< EventTypeMap::instance().to_symbol(param) << endmsg;
|
||||
|
@ -178,6 +178,15 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
||||
|
||||
void capture_channel_mode_changed();
|
||||
void playback_channel_mode_changed();
|
||||
|
||||
void ensure_pan_views (bool show = true);
|
||||
|
||||
void update_gain_track_visibility ();
|
||||
void update_pan_track_visibility ();
|
||||
|
||||
Gtk::CheckMenuItem* gain_automation_item;
|
||||
std::list<boost::shared_ptr<AutomationTimeAxisView> > pan_tracks;
|
||||
Gtk::CheckMenuItem* pan_automation_item;
|
||||
};
|
||||
|
||||
#endif /* __ardour_midi_time_axis_h__ */
|
||||
|
@ -166,6 +166,7 @@ Panner2d::on_size_allocate (Gtk::Allocation& alloc)
|
||||
radius = min (width, height);
|
||||
radius -= border;
|
||||
radius /= 2;
|
||||
radius = rint(radius) + .5;
|
||||
|
||||
hoffset = max ((double) (width - height), border);
|
||||
voffset = max ((double) (height - width), border);
|
||||
@ -251,12 +252,8 @@ Panner2d::handle_position_change ()
|
||||
uint32_t n;
|
||||
double w = panner_shell->pannable()->pan_width_control->get_value();
|
||||
|
||||
if (have_elevation) {
|
||||
position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0,
|
||||
panner_shell->pannable()->pan_elevation_control->get_value() * 90.0);
|
||||
} else {
|
||||
position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, 0);
|
||||
}
|
||||
position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0,
|
||||
panner_shell->pannable()->pan_elevation_control->get_value() * 90.0);
|
||||
|
||||
for (uint32_t i = 0; i < signals.size(); ++i) {
|
||||
signals[i]->position = panner_shell->panner()->signal_position (i);
|
||||
@ -300,7 +297,11 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal)
|
||||
|
||||
/* start with the position itself */
|
||||
|
||||
position.position.cartesian (c);
|
||||
PBD::AngularVector dp = position.position;
|
||||
if (!have_elevation) dp.ele = 0;
|
||||
dp.azi = 270 - dp.azi;
|
||||
dp.cartesian (c);
|
||||
|
||||
cart_to_gtk (c);
|
||||
best_distance = sqrt ((c.x - x) * (c.x - x) +
|
||||
(c.y - y) * (c.y - y));
|
||||
@ -342,9 +343,11 @@ Panner2d::find_closest_object (gdouble x, gdouble y, bool& is_signal)
|
||||
if (!closest) {
|
||||
for (Targets::const_iterator i = speakers.begin(); i != speakers.end(); ++i) {
|
||||
candidate = *i;
|
||||
|
||||
candidate->position.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
PBD::AngularVector sp = candidate->position;
|
||||
sp.azi = 270 -sp.azi;
|
||||
CartesianVector c;
|
||||
sp.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
|
||||
distance = sqrt ((c.x - x) * (c.x - x) +
|
||||
(c.y - y) * (c.y - y));
|
||||
@ -426,14 +429,14 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
/* horizontal line of "crosshairs" */
|
||||
|
||||
cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 1.0);
|
||||
cairo_move_to (cr, 0.0, rint(radius) + .5);
|
||||
cairo_line_to (cr, diameter, rint(radius) + .5);
|
||||
cairo_move_to (cr, 0.0, radius);
|
||||
cairo_line_to (cr, diameter, radius);
|
||||
cairo_stroke (cr);
|
||||
|
||||
/* vertical line of "crosshairs" */
|
||||
|
||||
cairo_move_to (cr, rint(radius) + .5, 0);
|
||||
cairo_line_to (cr, rint(radius) + .5, diameter);
|
||||
cairo_move_to (cr, radius, 0);
|
||||
cairo_line_to (cr, radius, diameter);
|
||||
cairo_stroke (cr);
|
||||
|
||||
/* the circle on which signals live */
|
||||
@ -456,15 +459,17 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
}
|
||||
|
||||
if (!panner_shell->bypassed()) {
|
||||
/* convention top == front ^= azimuth == .5 (same as stereo/mono panners) */
|
||||
|
||||
if (signals.size() > 1) {
|
||||
/* arc to show "diffusion" */
|
||||
|
||||
double width_angle = fabs (panner_shell->pannable()->pan_width_control->get_value()) * 2 * M_PI;
|
||||
double position_angle = (2 * M_PI) - panner_shell->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
|
||||
double position_angle = panner_shell->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, radius, radius);
|
||||
cairo_rotate (cr, M_PI / 2.0);
|
||||
cairo_rotate (cr, position_angle - (width_angle/2.0));
|
||||
cairo_move_to (cr, 0, 0);
|
||||
cairo_arc_negative (cr, 0, 0, radius, width_angle, 0.0);
|
||||
@ -493,7 +498,10 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
|
||||
/* draw position */
|
||||
|
||||
position.position.cartesian (c);
|
||||
PBD::AngularVector dp = position.position;
|
||||
if (!have_elevation) dp.ele = 0;
|
||||
dp.azi = 270 - dp.azi;
|
||||
dp.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
|
||||
cairo_new_path (cr);
|
||||
@ -505,7 +513,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
|
||||
/* signals */
|
||||
|
||||
if (signals.size() > 1) {
|
||||
if (signals.size() > 0) {
|
||||
for (Targets::iterator i = signals.begin(); i != signals.end(); ++i) {
|
||||
Target* signal = *i;
|
||||
|
||||
@ -516,6 +524,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
*/
|
||||
PBD::AngularVector sp = signal->position;
|
||||
if (!have_elevation) sp.ele = 0;
|
||||
sp.azi += 270.0;
|
||||
sp.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
|
||||
@ -553,9 +562,10 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
|
||||
if (speaker->visible) {
|
||||
|
||||
PBD::AngularVector sp = speaker->position;
|
||||
sp.azi += 270.0;
|
||||
CartesianVector c;
|
||||
|
||||
speaker->position.cartesian (c);
|
||||
sp.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
|
||||
snprintf (buf, sizeof (buf), "%d", n);
|
||||
@ -564,7 +574,7 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
|
||||
cairo_move_to (cr, c.x, c.y);
|
||||
cairo_save (cr);
|
||||
cairo_rotate (cr, -(speaker->position.azi/360.0) * (2.0 * M_PI));
|
||||
cairo_rotate (cr, -(sp.azi/360.0) * (2.0 * M_PI));
|
||||
if (small) {
|
||||
cairo_scale (cr, 0.8, 0.8);
|
||||
} else {
|
||||
@ -588,7 +598,8 @@ Panner2d::on_expose_event (GdkEventExpose *event)
|
||||
|
||||
/* move the text in just a bit */
|
||||
|
||||
AngularVector textpos (speaker->position.azi, speaker->position.ele, 0.85);
|
||||
AngularVector textpos (speaker->position.azi + 270.0, speaker->position.ele, 0.85);
|
||||
|
||||
textpos.cartesian (c);
|
||||
cart_to_gtk (c);
|
||||
cairo_move_to (cr, c.x, c.y);
|
||||
@ -716,6 +727,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
|
||||
if (!have_elevation) {
|
||||
clamp_to_circle (cp.x, cp.y);
|
||||
cp.angular (av);
|
||||
av.azi = fmod(270 - av.azi, 360);
|
||||
if (drag_target == &position) {
|
||||
double degree_fract = av.azi / 360.0;
|
||||
panner_shell->panner()->set_position (degree_fract);
|
||||
@ -727,6 +739,7 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
|
||||
double r2d = 180.0 / M_PI;
|
||||
av.azi = r2d * atan2(cp.y, cp.x);
|
||||
av.ele = r2d * asin(cp.z);
|
||||
av.azi = fmod(270 - av.azi, 360);
|
||||
|
||||
if (drag_target == &position) {
|
||||
double azi_fract = av.azi / 360.0;
|
||||
|
@ -397,8 +397,7 @@ Delivery::reset_panner ()
|
||||
if (panners_legal) {
|
||||
if (!_no_panner_reset) {
|
||||
|
||||
if (_panshell) {
|
||||
assert (_role == Main || _role == Aux || _role == Send);
|
||||
if (_panshell && _role != Insert) {
|
||||
_panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
|
||||
}
|
||||
}
|
||||
@ -412,8 +411,7 @@ Delivery::reset_panner ()
|
||||
void
|
||||
Delivery::panners_became_legal ()
|
||||
{
|
||||
if (_panshell) {
|
||||
assert (_role == Main || _role == Aux || _role == Send);
|
||||
if (_panshell && _role != Insert) {
|
||||
_panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs()));
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ Speakers::move_speaker (int id, const AngularVector& new_position)
|
||||
void
|
||||
Speakers::setup_default_speakers (uint32_t n)
|
||||
{
|
||||
double o = 90.0;
|
||||
double o = 180.0;
|
||||
|
||||
/* default assignment of speaker position for n speakers */
|
||||
|
||||
@ -229,12 +229,12 @@ Speakers::setup_default_speakers (uint32_t n)
|
||||
*/
|
||||
|
||||
if (n % 2) {
|
||||
deg = 90.0 - degree_step;
|
||||
deg = 360 + o + degree_step;
|
||||
} else {
|
||||
deg = 90.0;
|
||||
deg = 360 + o;
|
||||
}
|
||||
for (i = 0; i < n; ++i, deg += degree_step) {
|
||||
add_speaker (AngularVector (deg, 0.0));
|
||||
for (i = 0; i < n; ++i, deg -= degree_step) {
|
||||
add_speaker (AngularVector (fmod(deg, 360), 0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -528,23 +528,36 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
|
||||
{
|
||||
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
|
||||
|
||||
// VC++ doesn't support this C99 extension. Use alloca instead of dynamic array (rather than std::vector which allocs on the heap)
|
||||
ChanCount bufs_count;
|
||||
bufs_count.set(DataType::AUDIO, 1);
|
||||
bufs_count.set(DataType::MIDI, 1);
|
||||
|
||||
BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
|
||||
BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
|
||||
|
||||
float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*));
|
||||
float** outs = (float**)alloca(_plugin->numInputs*sizeof(float*));
|
||||
|
||||
int32_t i;
|
||||
|
||||
const uint32_t nbufs = bufs.count().n_audio();
|
||||
|
||||
int in_index = 0;
|
||||
uint32_t in_index = 0;
|
||||
for (i = 0; i < (int32_t) _plugin->numInputs; ++i) {
|
||||
ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset;
|
||||
in_index++;
|
||||
uint32_t index;
|
||||
bool valid = false;
|
||||
index = in_map.get(DataType::AUDIO, in_index++, &valid);
|
||||
ins[i] = (valid)
|
||||
? bufs.get_audio(index).data(offset)
|
||||
: silent_bufs.get_audio(0).data(offset);
|
||||
}
|
||||
|
||||
int out_index = 0;
|
||||
uint32_t out_index = 0;
|
||||
for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) {
|
||||
outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset;
|
||||
out_index++;
|
||||
uint32_t index;
|
||||
bool valid = false;
|
||||
index = out_map.get(DataType::AUDIO, out_index++, &valid);
|
||||
outs[i] = (valid)
|
||||
? bufs.get_audio(index).data(offset)
|
||||
: scratch_bufs.get_audio(0).data(offset);
|
||||
}
|
||||
|
||||
if (bufs.count().n_midi() > 0) {
|
||||
|
@ -385,7 +385,7 @@ Panner1in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||
(int) rint (100.0 * val));
|
||||
|
||||
default:
|
||||
return _pannable->value_as_string (ac);
|
||||
return _("unused");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,14 @@ Panner2in2out::Panner2in2out (boost::shared_ptr<Pannable> p)
|
||||
if (!_pannable->has_state()) {
|
||||
_pannable->pan_azimuth_control->set_value (0.5);
|
||||
_pannable->pan_width_control->set_value (1.0);
|
||||
}
|
||||
}
|
||||
|
||||
double const w = width();
|
||||
double const wrange = min (position(), (1 - position())) * 2;
|
||||
if (fabs(w) > wrange) {
|
||||
set_width(w > 0 ? wrange : -wrange);
|
||||
}
|
||||
|
||||
|
||||
update ();
|
||||
|
||||
@ -158,6 +165,11 @@ Panner2in2out::update ()
|
||||
double width = this->width ();
|
||||
const double direction_as_lr_fract = position ();
|
||||
|
||||
double const wrange = min (position(), (1 - position())) * 2;
|
||||
if (fabs(width) > wrange) {
|
||||
width = (width > 0 ? wrange : -wrange);
|
||||
}
|
||||
|
||||
if (width < 0.0) {
|
||||
width = -width;
|
||||
pos[0] = direction_as_lr_fract + (width/2.0); // left signal lr_fract
|
||||
@ -421,6 +433,8 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
|
||||
panR = position[n] + (width[n]/2.0f); // center - width/2
|
||||
}
|
||||
|
||||
panR = max(0.f, min(1.f, panR));
|
||||
|
||||
const float panL = 1 - panR;
|
||||
|
||||
/* note that are overwriting buffers, but its OK
|
||||
@ -522,7 +536,7 @@ Panner2in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||
return string_compose (_("Width: %1%%"), (int) floor (100.0 * val));
|
||||
|
||||
default:
|
||||
return _pannable->value_as_string (ac);
|
||||
return _("unused");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ Pannerbalance::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||
(int) rint (100.0 * val));
|
||||
|
||||
default:
|
||||
return _pannable->value_as_string (ac);
|
||||
return _("unused");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ VBAPanner::update ()
|
||||
|
||||
if (_signals.size() > 1) {
|
||||
double w = - (_pannable->pan_width_control->get_value());
|
||||
double signal_direction = _pannable->pan_azimuth_control->get_value() - (w/2);
|
||||
double signal_direction = 1.0 - (_pannable->pan_azimuth_control->get_value() + (w/2));
|
||||
double grd_step_per_signal = w / (_signals.size() - 1);
|
||||
for (vector<Signal*>::iterator s = _signals.begin(); s != _signals.end(); ++s) {
|
||||
|
||||
@ -141,7 +141,7 @@ VBAPanner::update ()
|
||||
signal_direction += grd_step_per_signal;
|
||||
}
|
||||
} else if (_signals.size() == 1) {
|
||||
double center = _pannable->pan_azimuth_control->get_value() * 360.0;
|
||||
double center = (1.0 - _pannable->pan_azimuth_control->get_value()) * 360.0;
|
||||
|
||||
/* width has no role to play if there is only 1 signal: VBAP does not do "diffusion" of a single channel */
|
||||
|
||||
@ -425,7 +425,7 @@ VBAPanner::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||
|
||||
switch (ac->parameter().type()) {
|
||||
case PanAzimuthAutomation: /* direction */
|
||||
return string_compose (_("%1\u00B0"), int (rint (val * 360.0)));
|
||||
return string_compose (_("%1\u00B0"), (int (rint (val * 360.0))+180)%360);
|
||||
|
||||
case PanWidthAutomation: /* diffusion */
|
||||
return string_compose (_("%1%%"), (int) floor (100.0 * fabs(val)));
|
||||
@ -434,7 +434,7 @@ VBAPanner::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||
return string_compose (_("%1\u00B0"), (int) floor (90.0 * fabs(val)));
|
||||
|
||||
default:
|
||||
return _pannable->value_as_string (ac);
|
||||
return _("unused");
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,11 +479,11 @@ VBAPanner::set_elevation (double e)
|
||||
void
|
||||
VBAPanner::reset ()
|
||||
{
|
||||
set_position (0);
|
||||
set_position (.5);
|
||||
if (_signals.size() > 1) {
|
||||
set_width (1.0 - (1.0 / (double)_signals.size()));
|
||||
} else {
|
||||
set_width (0);
|
||||
set_width (1.0);
|
||||
}
|
||||
set_elevation (0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user