#
import os
+import os.path
import sys
import re
import shutil
BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
- BoolOption('NATIVE_OSX_KEYS', 'Build key bindings file that matches OS X conventions', 0),
BoolOption('OLDFONTS', 'Old school font sizes', 0),
BoolOption('DEBUG', 'Set to build with debugging information and no optimizations', 0),
BoolOption('STL_DEBUG', 'Set to build with Standard Template Library Debugging', 0),
BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 0),
BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
BoolOption('FREEDESKTOP', 'Install MIME type, icons and .desktop file as per the freedesktop.org spec (requires xdg-utils and shared-mime-info). "scons uninstall" removes associations in desktop database', 0),
- BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1)
+ BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1),
+ BoolOption('AUBIO', "Use Paul Brossier's aubio library for feature detection (if available)", 1)
)
#----------------------------------------------------------------------
'raptor' : '1.4.2',
'lrdf' : '0.4.0',
'jack' : '0.109.0',
- 'libgnomecanvas-2.0' : '2.0'
+ 'libgnomecanvas-2.0' : '2.0',
+ 'aubio' : '0.3.2'
}
def DependenciesRequiredMessage():
libraries['fftw3'] = LibraryInfo()
libraries['fftw3'].ParseConfig('pkg-config --cflags --libs fftw3')
+if conf.CheckPKGExists ('aubio'):
+ libraries['aubio'] = LibraryInfo()
+ libraries['aubio'].ParseConfig('pkg-config --cflags --libs aubio')
+ env['AUBIO'] = 1
+else:
+ env['AUBIO'] = 0
+
env = conf.Finish ()
if env['FFT_ANALYSIS']:
# rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
# All libraries needed should be built against this location
if topenv['GTKOSX']:
- libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
- libinfo.Append(CXXFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
+ gtkroot = os.path.expanduser ("~");
+ libinfo.Append(CPPPATH="$GTKROOT/include", LIBPATH="$GTKROOT/lib")
+ libinfo.Append(CXXFLAGS="-I$GTKROOT/include", LINKFLAGS="-L$GTKROOT/lib")
libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
conf = Configure (libraries['boost'])
if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
- print "Boost header files do not appear to be installed."
+ print "Boost header files do not appear to be installed. You also might be running a buggy version of scons. Try scons 0.97 if you can."
sys.exit (1)
libraries['boost'] = conf.Finish ()
CPPPATH='#libs/appleutility')
coredirs = [
- 'templates'
+ 'templates',
+ 'manual'
]
subdirs = [
CPPPATH='#libs/appleutility')
coredirs = [
- 'templates'
+ 'templates',
+ 'manual'
]
subdirs = [
Import('env install_prefix final_prefix config_prefix libraries i18n ardour_version')
-gtkardour = env.Copy()
-gtkmmtests = env.Copy()
+gtkardour = env.Clone()
+gtkmmtests = env.Clone()
#
# this defines the version number of the GTK interface to ardour
keybindings_dict = { }
-if gtkardour['GTKOSX'] and gtkardour['NATIVE_OSX_KEYS']:
+if gtkardour['GTKOSX']:
#
# Command(Meta), Alt(Mod1), Ctrl, Shift
# **** as of february 4th 2008, OUR VERSION OF *****
env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'pixmaps'), pixmap_files))
env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'icons'), icon_files))
env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], []))
+env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], []))
# This will install icons and MIME type as per freedesktop.org specs. #
if env['FREEDESKTOP']:
}
};
+void
+ActionManager::get_all_actions (vector<string>& groups, vector<string>& names, vector<AccelKey>& bindings)
+{
+ /* the C++ API for functions used here appears to be broken in
+ gtkmm2.6, so we fall back to the C level.
+ */
+
+ GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
+ GList* node;
+ GList* acts;
+
+ for (node = list; node; node = g_list_next (node)) {
+
+ GtkActionGroup* group = (GtkActionGroup*) node->data;
+
+ /* first pass: collect them all */
+
+ typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
+ action_list the_acts;
+
+ for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+ GtkAction* action = (GtkAction*) acts->data;
+ the_acts.push_back (Glib::wrap (action, true));
+ }
+
+ /* now sort by label */
+
+ SortActionsByLabel cmp;
+ the_acts.sort (cmp);
+
+ for (action_list::iterator a = the_acts.begin(); a != the_acts.end(); ++a) {
+
+ string accel_path = (*a)->get_accel_path ();
+
+ groups.push_back (gtk_action_group_get_name(group));
+ names.push_back (accel_path.substr (accel_path.find_last_of ('/') + 1));
+
+ AccelKey key;
+ lookup_entry (accel_path, key);
+ bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod())));
+ }
+ }
+}
+
void
ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
{
return ui_manager->get_widget (name);
}
+RefPtr<Action>
+ActionManager::get_action (const char* path)
+{
+ GtkAction* _act;
+ RefPtr<Action> act;
+
+ if ((_act = gtk_ui_manager_get_action (ui_manager->gobj(), path)) != 0) {
+ return Glib::wrap (_act, true);
+ }
+
+ return act;
+}
+
RefPtr<Action>
ActionManager::get_action (const char* group_name, const char* action_name)
{
static Gtk::Widget* get_widget (const char * name);
static Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
+ static Glib::RefPtr<Gtk::Action> get_action (const char* path);
static void add_action_group (Glib::RefPtr<Gtk::ActionGroup>);
std::vector<std::string>& keys,
std::vector<Gtk::AccelKey>& bindings);
+ static void get_all_actions (std::vector<std::string>& groups,
+ std::vector<std::string>& paths,
+ std::vector<Gtk::AccelKey>& bindings);
+
static void uncheck_toggleaction (const char * actionname);
};
continue;
RouteUI *rui = dynamic_cast<RouteUI *>(*i);
-
+ int n_inputs = rui->route()->n_inputs().n_audio(); // FFT is audio only
+
// Busses don't have playlists, so we need to check that we actually are working with a playlist
if (!pl || !rui)
continue;
for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
- nframes_t i = 0;
int n;
-
- while ( i < (*j).length() ) {
- // TODO: What about stereo+ channels? composite all to one, I guess
+ for (int channel = 0; channel < n_inputs; channel++) {
+ nframes_t x = 0;
- n = fft_graph.windowSize();
+ while ( x < (*j).length() ) {
+ // TODO: What about stereo+ channels? composite all to one, I guess
- if (i + n >= (*j).length() ) {
- n = (*j).length() - i;
- }
-
- n = pl->read(buf, mixbuf, gain, (*j).start + i, n);
-
- if ( n < fft_graph.windowSize()) {
- for (int j = n; j < fft_graph.windowSize(); j++) {
- buf[j] = 0.0;
+ n = fft_graph.windowSize();
+
+ if (x + n >= (*j).length() ) {
+ n = (*j).length() - x;
+ }
+
+ n = pl->read(buf, mixbuf, gain, (*j).start + x, n, channel);
+
+ if ( n < fft_graph.windowSize()) {
+ for (int j = n; j < fft_graph.windowSize(); j++) {
+ buf[j] = 0.0;
+ }
}
+
+ res->analyzeWindow(buf);
+
+ x += n;
}
-
- res->analyzeWindow(buf);
-
- i += n;
}
}
} else if (source_selection_regions_rb.get_active()) {
continue;
// cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
- nframes_t i = 0;
int n;
+ for (int channel = 0; channel < n_inputs; channel++) {
- while ( i < arv->region()->length() ) {
- // TODO: What about stereo+ channels? composite all to one, I guess
+ nframes_t x = 0;
- n = fft_graph.windowSize();
- if (i + n >= arv->region()->length() ) {
- n = arv->region()->length() - i;
- }
+ nframes_t length = arv->region()->length();
- n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + i, n);
-
- if ( n < fft_graph.windowSize()) {
- for (int j = n; j < fft_graph.windowSize(); j++) {
- buf[j] = 0.0;
+ while ( x < length ) {
+ // TODO: What about stereo+ channels? composite all to one, I guess
+
+ n = fft_graph.windowSize();
+ if (x + n >= length ) {
+ n = length - x;
}
+
+ n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + x, n, channel);
+
+ if (n == 0)
+ break;
+
+ if ( n < fft_graph.windowSize()) {
+ for (int j = n; j < fft_graph.windowSize(); j++) {
+ buf[j] = 0.0;
+ }
+ }
+
+ res->analyzeWindow(buf);
+
+ x += n;
}
-
- res->analyzeWindow(buf);
-
- i += n;
}
// cerr << "Found: " << (*j)->get_item_name() << endl;
</menubar>
+<<<<<<< .working
<popup action="RulerMenuPopup">
<menuitem action="toggle-minsec-ruler"/>
<menuitem action="toggle-samples-ruler"/>
</popup>
<popup name='processormenu'>
+=======
+ <popup action="RulerMenuPopup">
+ <menuitem action="toggle-minsec-ruler"/>
+ <menuitem action="toggle-samples-ruler"/>
+ <menuitem action="toggle-bbt-ruler"/>
+ <separator/>
+ <menuitem action="toggle-meter-ruler"/>
+ <menuitem action="toggle-tempo-ruler"/>
+ <menuitem action="toggle-loop-punch-ruler"/>
+ <menuitem action="toggle-cd-marker-ruler"/>
+ <menuitem action="toggle-marker-ruler"/>
+ </popup>
+
+ <popup name='redirectmenu'>
+>>>>>>> .merge-right.r3622
<menuitem action='newplugin'/>
<menuitem action='newinsert'/>
<menuitem action='newsend'/>
<menuitem action='TransitionToReverse'/>
<separator/>
-
<menu action="MovePlayHeadMenu">
<menuitem action='set-playhead'/>
<menuitem action='playhead-to-edit'/>
<menuitem action='GotoZero'/>
<menuitem action='GotoStart'/>
<menuitem action='GotoEnd'/>
+ <menuitem action='GotoWallClock'/>
+
</menu>
<menu action="MoveActiveMarkMenu">
</menu>
<menu name='View' action = 'View'>
+ <menu action="ZoomMenu">
+ <menuitem action='temporal-zoom-in'/>
+ <menuitem action='temporal-zoom-out'/>
+ <menuitem action='zoom-to-session'/>
+ <menuitem action='zoom-to-region'/>
+ <menuitem action='zoom-to-region-both-axes'/>
+ <menuitem action='toggle-zoom'/>
+ </menu>
<menu name='ZoomFocus' action='ZoomFocus'>
<menuitem action='zoom-focus-left'/>
<menuitem action='zoom-focus-right'/>
<menuitem action="toggle-cd-marker-ruler"/>
<menuitem action="toggle-marker-ruler"/>
</menu>
- <menu action="ZoomMenu">
- <menuitem action='temporal-zoom-in'/>
- <menuitem action='temporal-zoom-out'/>
- <menuitem action='zoom-to-session'/>
- <menuitem action='zoom-to-region'/>
- <menuitem action='toggle-zoom'/>
- </menu>
<menu action="ScrollMenu">
<menuitem action='scroll-tracks-down'/>
<menuitem action='scroll-tracks-up'/>
<menuitem action='scroll-forward'/>
<menuitem action='scroll-backward'/>
</menu>
+ <menu action="SavedViewMenu">
+ <menuitem action='save-visual-state-1'/>
+ <menuitem action='goto-visual-state-1'/>
+ <menuitem action='save-visual-state-2'/>
+ <menuitem action='goto-visual-state-2'/>
+ <menuitem action='save-visual-state-3'/>
+ <menuitem action='goto-visual-state-3'/>
+ <menuitem action='save-visual-state-4'/>
+ <menuitem action='goto-visual-state-4'/>
+ <menuitem action='save-visual-state-5'/>
+ <menuitem action='goto-visual-state-5'/>
+ <menuitem action='save-visual-state-6'/>
+ <menuitem action='goto-visual-state-6'/>
+ <menuitem action='save-visual-state-7'/>
+ <menuitem action='goto-visual-state-7'/>
+ <menuitem action='save-visual-state-8'/>
+ <menuitem action='goto-visual-state-8'/>
+ <menuitem action='save-visual-state-9'/>
+ <menuitem action='goto-visual-state-9'/>
+ <menuitem action='save-visual-state-10'/>
+ <menuitem action='goto-visual-state-10'/>
+ <menuitem action='save-visual-state-11'/>
+ <menuitem action='goto-visual-state-11'/>
+ <menuitem action='save-visual-state-12'/>
+ <menuitem action='goto-visual-state-12'/>
+ </menu>
<menuitem action='ToggleMaximalEditor'/>
<menuitem action='show-editor-mixer'/>
<menuitem action='ToggleTapeMachineMode'/>
</menu>
<menu action='Metering'>
+ <menuitem action='ShowTrackMeters'/>
<menu action='MeteringFallOffRate'>
<menuitem action='MeterFalloffOff'/>
<menuitem action='MeterFalloffSlowest'/>
<menuitem action="toggle-loop-punch-ruler"/>
</popup>
- <popup name='processormenu'>
+ <popup name='redirectmenu'>
<menuitem action='newplugin'/>
<menuitem action='newinsert'/>
<menuitem action='newsend'/>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
+#include <time.h>
#include <cerrno>
#include <fstream>
#include <ardour/filesystem_paths.h>
#include <ardour/filename_extensions.h>
+typedef uint64_t microseconds_t;
+
#include "actions.h"
#include "ardour_ui.h"
#include "public_editor.h"
#include "gui_thread.h"
#include "theme_manager.h"
#include "bundle_manager.h"
+#include "gain_meter.h"
+#include "route_time_axis.h"
#include "i18n.h"
preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
- /* adjuster table */
-
- adjuster_table (3, 3),
-
/* preroll stuff */
preroll_button (_("pre\nroll")),
/* transport */
- roll_controllable ("transport roll", *this, TransportControllable::Roll),
- stop_controllable ("transport stop", *this, TransportControllable::Stop),
- goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
- goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
- auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
- play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
- rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
- shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
+ roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
+ stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
+ goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
+ goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
+ auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
+ play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
+ rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
+ shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
shuttle_controller_binding_proxy (shuttle_controllable),
roll_button (roll_controllable),
last_speed_displayed = -1.0f;
ignore_dual_punch = false;
- last_configure_time.tv_sec = 0;
- last_configure_time.tv_usec = 0;
+ last_configure_time= 0;
shuttle_grabbed = false;
shuttle_fract = 0.0;
shuttle_style_menu = 0;
shuttle_unit_menu = 0;
- gettimeofday (&last_peak_grab, 0);
- gettimeofday (&last_shuttle_request, 0);
+ // We do not have jack linked in yet so;
+
+ last_shuttle_request = last_peak_grab = 0; // get_microseconds();
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
Config->set_current_owner (ConfigVariableBase::Interface);
setup_profile ();
+ GainMeter::setup_slider_pix ();
+ RouteTimeAxisView::setup_slider_pix ();
+
} catch (failed_constructor& err) {
error << _("could not initialize Ardour.") << endmsg;
// pass it on up
gint
ARDOUR_UI::configure_timeout ()
{
- struct timeval now;
- struct timeval diff;
-
- if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
+ if (last_configure_time == 0) {
/* no configure events yet */
return TRUE;
}
- gettimeofday (&now, 0);
- timersub (&now, &last_configure_time, &diff);
-
/* force a gap of 0.5 seconds since the last configure event
*/
- if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
+ if (get_microseconds() - last_configure_time < 500000) {
return TRUE;
} else {
have_configure_timeout = false;
ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
{
if (have_configure_timeout) {
- gettimeofday (&last_configure_time, 0);
+ last_configure_time = get_microseconds();
} else {
Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
have_configure_timeout = true;
const XMLProperty* prop;
if ((prop = node.property ("roll")) != 0) {
- roll_controllable.set_id (prop->value());
+ roll_controllable->set_id (prop->value());
}
if ((prop = node.property ("stop")) != 0) {
- stop_controllable.set_id (prop->value());
+ stop_controllable->set_id (prop->value());
}
if ((prop = node.property ("goto_start")) != 0) {
- goto_start_controllable.set_id (prop->value());
+ goto_start_controllable->set_id (prop->value());
}
if ((prop = node.property ("goto_end")) != 0) {
- goto_end_controllable.set_id (prop->value());
+ goto_end_controllable->set_id (prop->value());
}
if ((prop = node.property ("auto_loop")) != 0) {
- auto_loop_controllable.set_id (prop->value());
+ auto_loop_controllable->set_id (prop->value());
}
if ((prop = node.property ("play_selection")) != 0) {
- play_selection_controllable.set_id (prop->value());
+ play_selection_controllable->set_id (prop->value());
}
if ((prop = node.property ("rec")) != 0) {
- rec_controllable.set_id (prop->value());
+ rec_controllable->set_id (prop->value());
}
if ((prop = node.property ("shuttle")) != 0) {
- shuttle_controllable.set_id (prop->value());
+ shuttle_controllable->set_id (prop->value());
}
}
XMLNode* node = new XMLNode(X_("TransportControllables"));
char buf[64];
- roll_controllable.id().print (buf, sizeof (buf));
+ roll_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("roll"), buf);
- stop_controllable.id().print (buf, sizeof (buf));
+ stop_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("stop"), buf);
- goto_start_controllable.id().print (buf, sizeof (buf));
+ goto_start_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("goto_start"), buf);
- goto_end_controllable.id().print (buf, sizeof (buf));
+ goto_end_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("goto_end"), buf);
- auto_loop_controllable.id().print (buf, sizeof (buf));
+ auto_loop_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("auto_loop"), buf);
- play_selection_controllable.id().print (buf, sizeof (buf));
+ play_selection_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("play_selection"), buf);
- rec_controllable.id().print (buf, sizeof (buf));
+ rec_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("rec"), buf);
- shuttle_controllable.id().print (buf, sizeof (buf));
+ shuttle_controllable->id().print (buf, sizeof (buf));
node->add_property (X_("shuttle"), buf);
return *node;
gint
ARDOUR_UI::autosave_session ()
{
- if (!Config->get_periodic_safety_backups())
+ if (g_main_depth() > 1) {
+ /* inside a recursive main loop,
+ give up because we may not be able to
+ take a lock.
+ */
return 1;
+ }
- if (session) {
- session->maybe_write_autosave();
+ if (!Config->get_periodic_safety_backups()) {
+ return 1;
}
+ if (session) {
+ session->maybe_write_autosave();
+ }
+
return 1;
}
prompt_label.set_name (X_("PrompterLabel"));
prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
- dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
-;
+ dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
dhbox.set_homogeneous (false);
dhbox.pack_start (*dimage, false, false, 5);
dhbox.pack_start (prompt_label, true, false, 5);
prompt_label.show();
dimage->show();
window.show();
-
- save_the_session = 0;
-
window.set_keep_above (true);
window.present ();
}
}
-bool
-ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
-{
- struct stat statbuf;
-
- if (stat (info.filename.c_str(), &statbuf) != 0) {
- return false;
- }
-
- if (!S_ISDIR(statbuf.st_mode)) {
- return false;
- }
-
- // XXX Portability
-
- string session_file = info.filename;
- session_file += '/';
- session_file += Glib::path_get_basename (info.filename);
- session_file += ".ardour";
-
- if (stat (session_file.c_str(), &statbuf) != 0) {
- return false;
- }
-
- return S_ISREG (statbuf.st_mode);
-}
-
bool
ARDOUR_UI::check_audioengine ()
{
}
}
+void
+ARDOUR_UI::transport_goto_wallclock ()
+{
+ if (session && editor) {
+
+ time_t now;
+ struct tm tmnow;
+ nframes64_t frames;
+
+ time (&now);
+ localtime_r (&now, &tmnow);
+
+ frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
+ frames += tmnow.tm_min * (60 * session->frame_rate());
+ frames += tmnow.tm_sec * session->frame_rate();
+
+ session->request_locate (frames);
+
+ /* force displayed area in editor to start no matter
+ what "follow playhead" setting is.
+ */
+
+ if (editor) {
+ editor->reset_x_origin (frames - (editor->current_page_frames()/2));
+ }
+ }
+}
+
void
ARDOUR_UI::transport_goto_end ()
{
return 0;
}
-void
-ARDOUR_UI::restore_state (string name)
-{
- if (session) {
- if (name.length() == 0) {
- name = session->name();
- }
- session->restore_state (name);
- }
-}
-
void
ARDOUR_UI::primary_clock_value_changed ()
{
}
}
-void
-ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
-{
- if (session && dstream && dstream->record_enabled()) {
-
- Session::RecordState rs;
-
- rs = session->record_status ();
-
- switch (rs) {
- case Session::Disabled:
- case Session::Enabled:
- if (w->get_state() != STATE_SELECTED) {
- w->set_state (STATE_SELECTED);
- }
- break;
-
- case Session::Recording:
- if (w->get_state() != STATE_ACTIVE) {
- w->set_state (STATE_ACTIVE);
- }
- break;
- }
-
- } else {
- if (w->get_state() != STATE_NORMAL) {
- w->set_state (STATE_NORMAL);
- }
- }
-}
-
void
ARDOUR_UI::transport_rec_enable_blink (bool onoff)
{
fontconfig_dialog();
if (!backend_audio_is_running) {
- if (new_session_dialog->engine_control.setup_engine ()) {
- new_session_dialog->hide ();
+ int ret = new_session_dialog->engine_control.setup_engine ();
+ if (ret < 0) {
return false;
- }
+ } else if (ret > 0) {
+ response = Gtk::RESPONSE_REJECT;
+ goto try_again;
+ }
}
if (create_engine ()) {
}
}
- } while (response == Gtk::RESPONSE_NONE);
+ } while (response == Gtk::RESPONSE_NONE || response == Gtk::RESPONSE_REJECT);
done:
show();
}
if (session->cleanup_sources (rep)) {
+ editor->finish_cleanup ();
return;
}
+
+ editor->finish_cleanup ();
checker.hide();
display_cleanup_results (rep,
%4 %5bytes of disk space.\n"
));
-
-
}
void
void
ARDOUR_UI::create_xrun_marker(nframes_t where)
{
- ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::create_xrun_marker), where));
editor->mouse_add_new_marker (where, false, true);
}
void
ARDOUR_UI::xrun_handler(nframes_t where)
{
+ ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
+
if (Config->get_create_xrun_marker() && session->actively_recording()) {
create_xrun_marker(where);
}
#include <ardour/ardour.h>
#include <ardour/session.h>
#include <ardour/configuration.h>
+#include <ardour/types.h>
#include "audio_clock.h"
#include "ardour_dialog.h"
int save_state_canfail (string state_name = "");
void save_state (const string & state_name = "");
- void restore_state (string state_name = "");
static double gain_to_slider_position (ARDOUR::gain_t g);
static ARDOUR::gain_t slider_position_to_gain (double pos);
static sigc::signal<void> SuperRapidScreenUpdate;
static sigc::signal<void,nframes_t, bool, nframes_t> Clock;
- /* this is a helper function to centralize the (complex) logic for
- blinking rec-enable buttons.
- */
-
- void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
-
void name_io_setup (ARDOUR::AudioEngine&, string&, ARDOUR::IO& io, bool in);
static gint hide_and_quit (GdkEventAny *ev, ArdourDialog *);
Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
- Gtk::Table transport_table;
- Gtk::Table option_table;
-
int setup_windows ();
void setup_transport ();
void setup_clock ();
void finish();
int ask_about_saving_session (const string & why);
- int save_the_session;
/* periodic safety backup, to be precise */
gint autosave_session();
void manage_window (Gtk::Window&);
AudioClock big_clock;
- Gtk::Frame big_clock_frame;
Gtk::Window* big_clock_window;
+ void float_big_clock (Gtk::Window* parent);
+ bool main_window_state_event_handler (GdkEventWindowState*, bool window_was_editor);
+
void update_transport_clocks (nframes_t pos);
void record_state_changed ();
ToggleType type;
};
- TransportControllable roll_controllable;
- TransportControllable stop_controllable;
- TransportControllable goto_start_controllable;
- TransportControllable goto_end_controllable;
- TransportControllable auto_loop_controllable;
- TransportControllable play_selection_controllable;
- TransportControllable rec_controllable;
- TransportControllable shuttle_controllable;
+ boost::shared_ptr<TransportControllable> roll_controllable;
+ boost::shared_ptr<TransportControllable> stop_controllable;
+ boost::shared_ptr<TransportControllable> goto_start_controllable;
+ boost::shared_ptr<TransportControllable> goto_end_controllable;
+ boost::shared_ptr<TransportControllable> auto_loop_controllable;
+ boost::shared_ptr<TransportControllable> play_selection_controllable;
+ boost::shared_ptr<TransportControllable> rec_controllable;
+ boost::shared_ptr<TransportControllable> shuttle_controllable;
BindingProxy shuttle_controller_binding_proxy;
void set_transport_controllable_state (const XMLNode&);
void transport_goto_zero ();
void transport_goto_start ();
void transport_goto_end ();
+ void transport_goto_wallclock ();
void transport_stop ();
void transport_stop_and_forget_capture ();
void transport_record (bool roll);
void flush_trash ();
bool have_configure_timeout;
- struct timeval last_configure_time;
+ ARDOUR::microseconds_t last_configure_time;
gint configure_timeout ();
- struct timeval last_peak_grab;
- struct timeval last_shuttle_request;
+ ARDOUR::microseconds_t last_peak_grab;
+ ARDOUR::microseconds_t last_shuttle_request;
bool have_disk_speed_dialog_displayed;
void disk_speed_dialog_gone (int ignored_response, Gtk::MessageDialog*);
Gtk::MenuItem* jack_reconnect_item;
Gtk::Menu* jack_bufsize_menu;
- int make_session_clean ();
- bool filter_ardour_session_dirs (const Gtk::FileFilter::Info&);
-
Glib::RefPtr<Gtk::ActionGroup> common_actions;
void editor_realized ();
void toggle_ShowTrackMeters ();
void toggle_only_copy_imported_files ();
void toggle_use_narrow_ms();
+ void toggle_NameNewMarkers ();
void toggle_rubberbanding_snaps_to_grid ();
void toggle_auto_analyse_audio ();
void toggle_TapeMachineMode();
void
ARDOUR_UI::use_shuttle_fract (bool force)
{
- struct timeval now;
- struct timeval diff;
+ microseconds_t now = get_microseconds();
/* do not attempt to submit a motion-driven transport speed request
more than once per process cycle.
*/
- gettimeofday (&now, 0);
- timersub (&now, &last_shuttle_request, &diff);
-
- if (!force && (diff.tv_usec + (diff.tv_sec * 1000000)) < engine->usecs_per_cycle()) {
+ if (!force && (last_shuttle_request - now) < (microseconds_t) engine->usecs_per_cycle()) {
return;
}
}
}
}
+
+bool
+ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
+{
+ if (window_was_editor) {
+
+ if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
+ (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
+ float_big_clock (editor);
+ }
+
+ } else {
+
+ if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
+ (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
+ float_big_clock (mixer);
+ }
+ }
+
+ return false;
+}
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/window_title.h>
+#include <gtk/gtk.h>
#include "ardour_ui.h"
#include "public_editor.h"
}
editor->Realized.connect (mem_fun (*this, &ARDOUR_UI::editor_realized));
+ editor->signal_window_state_event().connect (sigc::bind (mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true));
return 0;
}
act = ActionManager::register_action (transport_actions, X_("GotoEnd"), _("Goto End"), mem_fun(*this, &ARDOUR_UI::transport_goto_end));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (transport_actions, X_("GotoWallClock"), _("Goto Wall Clock"), mem_fun(*this, &ARDOUR_UI::transport_goto_wallclock));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::transport_sensitive_actions.push_back (act);
act = ActionManager::register_action (transport_actions, X_("focus-on-clock"), _("Focus On Clock"), mem_fun(primary_clock, &AudioClock::focus));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_toggle_action (option_actions, X_("AutoAnalyseAudio"), _("Auto-analyse new audio"), mem_fun (*this, &ARDOUR_UI::toggle_auto_analyse_audio));
ActionManager::register_toggle_action (option_actions, X_("DefaultNarrowMS"), _("Use narrow mixer strips"), mem_fun (*this, &ARDOUR_UI::toggle_use_narrow_ms));
+ ActionManager::register_toggle_action (option_actions, X_("NameNewMarkers"), _("Name New Markers"), mem_fun (*this, &ARDOUR_UI::toggle_NameNewMarkers));
RadioAction::Group denormal_group;
manage_window (*big_clock_window);
}
+
+void
+ARDOUR_UI::float_big_clock (Gtk::Window* parent)
+{
+ if (big_clock_window) {
+ if (parent) {
+ big_clock_window->set_transient_for (*parent);
+ } else {
+ gtk_window_set_transient_for (big_clock_window->gobj(), (GtkWindow*) 0);
+ }
+ }
+}
+
return -1;
}
+ mixer->signal_window_state_event().connect (bind (mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), false));
+
return 0;
}
ActionManager::toggle_config_state ("options", "DefaultNarrowMS", &Configuration::set_default_narrow_ms, &Configuration::get_default_narrow_ms);
}
+void
+ARDOUR_UI::toggle_NameNewMarkers()
+{
+ ActionManager::toggle_config_state ("options", "NameNewMarkers", &Configuration::set_name_new_markers, &Configuration::get_name_new_markers);
+}
+
void
ARDOUR_UI::toggle_rubberbanding_snaps_to_grid ()
{
return -1;
}
+ [win setAutodisplay:YES]; // turn of GTK stuff for this window
+
Gtk::Container* toplevel = get_toplevel();
if (!toplevel || !toplevel->is_toplevel()) {
NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj());
+
[view setFrame:packFrame];
[view addSubview:packView];
break;
case GDK_Tab:
+ case GDK_Return:
+ case GDK_KP_Enter:
move_on = true;
break;
case GDK_Escape:
- case GDK_Return:
- case GDK_KP_Enter:
+ key_entry_state = 0;
clock_base.grab_focus ();
+ ChangeAborted(); /* EMIT SIGNAL */
return true;
default:
}
+ //if user hit Enter, lose focus
+ switch (ev->keyval) {
+ case GDK_Return:
+ case GDK_KP_Enter:
+ clock_base.grab_focus ();
+ }
+
return true;
}
void set_session (ARDOUR::Session *s);
sigc::signal<void> ValueChanged;
+ sigc::signal<void> ChangeAborted;
static sigc::signal<void> ModeChanged;
static std::vector<AudioClock*> clocks;
{
}
+
AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
- Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
- : RegionView (parent, tv, r, spu, basic_color, visibility)
+ Gdk::Color& basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
+ : RegionView (parent, tv, r, spu, basic_color, recording, visibility)
, sync_mark(0)
, zero_line(0)
, fade_in_shape(0)
gain_line->reset ();
- set_y_position_and_height (0, trackview.height);
+ set_y_position_and_height (0, trackview.current_height());
region_muted ();
region_sync_changed ();
AudioRegionView::region_changed (Change what_changed)
{
ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed));
+ //cerr << "AudioRegionView::region_changed() called" << endl;
RegionView::region_changed(what_changed);
}
void
-AudioRegionView::set_y_position_and_height (double y, double h)
+AudioRegionView::setup_fade_handle_positions()
{
- RegionView::set_y_position_and_height(y, h - 1);
+ /* position of fade handle offset from the top of the region view */
+ double const handle_pos = 2;
+ /* height of fade handles */
+ double const handle_height = 5;
+
+ if (fade_in_handle) {
+ fade_in_handle->property_y1() = _y_position + handle_pos;
+ fade_in_handle->property_y2() = _y_position + handle_pos + handle_height;
+ }
- const uint32_t wcnt = waves.size();
+ if (fade_out_handle) {
+ fade_out_handle->property_y1() = _y_position + handle_pos;
+ fade_out_handle->property_y2() = _y_position + handle_pos + handle_height;
+ }
+}
+
+void
+AudioRegionView::set_y_position_and_height (double y, double h)
+{
+ RegionView::set_y_position_and_height (y, h - 1);
+
+ /* XXX why is this code here */
_y_position = y;
_height = h;
- for (uint32_t n = 0; n < wcnt; ++n) {
- double ht;
+ const uint32_t wcnt = waves.size();
+
+ for (uint32_t n=0; n < wcnt; ++n) {
+ gdouble ht;
- if (h <= NAME_HIGHLIGHT_THRESH) {
- ht = ((_height - 2 * wcnt) / (double) wcnt);
+ if ((h) < NAME_HIGHLIGHT_THRESH) {
+ ht = ((_height-2*wcnt) / (double) wcnt);
} else {
- ht = (((_height - 2 * wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
+ ht = (((_height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
}
- double const yoff = n * (ht + 1);
+ gdouble yoff = n * (ht+1);
waves[n]->property_height() = ht;
- waves[n]->property_y() = _y_position + yoff + 2;
+ waves[n]->property_y() = yoff + 2;
}
if (gain_line) {
- if ((_height / wcnt) < NAME_HIGHLIGHT_SIZE) {
+ if ((_height/wcnt) < NAME_HIGHLIGHT_THRESH) {
gain_line->hide ();
} else {
if (_flags & EnvelopeVisible) {
gain_line->set_y_position_and_height ((uint32_t) _y_position, (uint32_t) rint (_height - NAME_HIGHLIGHT_SIZE));
}
- setup_fade_handle_positions ();
manage_zero_line ();
reset_fade_shapes ();
}
}
-void
-AudioRegionView::setup_fade_handle_positions()
-{
- /* position of fade handle offset from the top of the region view */
- double const handle_pos = 2;
- /* height of fade handles */
- double const handle_height = 5;
-
- if (fade_in_handle) {
- fade_in_handle->property_y1() = _y_position + handle_pos;
- fade_in_handle->property_y2() = _y_position + handle_pos + handle_height;
- }
-
- if (fade_out_handle) {
- fade_out_handle->property_y1() = _y_position + handle_pos;
- fade_out_handle->property_y2() = _y_position + handle_pos + handle_height;
- }
-}
-
void
AudioRegionView::manage_zero_line ()
{
points = get_canvas_points ("fade in shape", npoints+3);
- if (_height > NAME_HIGHLIGHT_THRESH) {
+ if (_height >= NAME_HIGHLIGHT_THRESH) {
h = _height - NAME_HIGHLIGHT_SIZE;
} else {
h = _height;
float curve[npoints];
audio_region()->fade_out()->curve().get_vector (0, audio_region()->fade_out()->back()->when, curve, npoints);
- if (_height > NAME_HIGHLIGHT_THRESH) {
+ if (_height >= NAME_HIGHLIGHT_THRESH) {
h = _height - NAME_HIGHLIGHT_SIZE;
} else {
h = _height;
if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
// cerr << "\tData is ready\n";
cerr << "\tData is ready\n";
+ // cerr << "\tData is ready\n";
create_one_wave (n, true);
} else {
// cerr << "\tdata is not ready\n";
uint32_t nwaves = std::min (nchans, audio_region()->n_channels());
gdouble ht;
- if (trackview.height < NAME_HIGHLIGHT_SIZE) {
- ht = ((trackview.height) / (double) nchans);
+ if (trackview.current_height() < NAME_HIGHLIGHT_THRESH) {
+ ht = ((trackview.current_height()) / (double) nchans);
} else {
- ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans);
+ ht = ((trackview.current_height() - NAME_HIGHLIGHT_SIZE) / (double) nchans);
}
gdouble yoff = which * ht;
wave->property_height() = (double) ht;
wave->property_samples_per_unit() = samples_per_unit;
wave->property_amplitude_above_axis() = _amplitude_above_axis;
- wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_WaveForm.get();
- wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+
+ if (_recregion) {
+ wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_RecWaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_RecWaveForm.get();
+ wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_RecWaveFormFill.get();
+ } else {
+ wave->property_wave_color() = _region->muted() ? UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA) : ARDOUR_UI::config()->canvasvar_WaveForm.get();
+ wave->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+ }
+
wave->property_clip_color() = ARDOUR_UI::config()->canvasvar_WaveFormClip.get();
wave->property_zero_color() = ARDOUR_UI::config()->canvasvar_ZeroLine.get();
wave->property_region_start() = _region->start();
/* compute vertical fractional position */
- y = 1.0 - ((y - _y_position) / (_height - NAME_HIGHLIGHT_SIZE));
+ y = 1.0 - (y / (trackview.current_height() - NAME_HIGHLIGHT_SIZE));
/* map using gain line */
}
}
} else {
- UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
- frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
-
- for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
- if (_region->muted()) {
- (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA);
- } else {
- (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm.get();
- (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+ if (_recregion) {
+ UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
+ frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+
+ for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
+ if (_region->muted()) {
+ (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_RecWaveForm.get(), MUTED_ALPHA);
+ } else {
+ (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_RecWaveForm.get();
+ (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_RecWaveFormFill.get();
+ }
+ }
+ } else {
+ UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
+ frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
+
+ for (vector<ArdourCanvas::WaveView*>::iterator w = waves.begin(); w != waves.end(); ++w) {
+ if (_region->muted()) {
+ (*w)->property_wave_color() = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_WaveForm.get(), MUTED_ALPHA);
+ } else {
+ (*w)->property_wave_color() = ARDOUR_UI::config()->canvasvar_WaveForm.get();
+ (*w)->property_fill_color() = ARDOUR_UI::config()->canvasvar_WaveFormFill.get();
+ }
}
}
}
}
+
double initial_samples_per_unit,
Gdk::Color& basic_color);
+ AudioRegionView (ArdourCanvas::Group *,
+ RouteTimeAxisView&,
+ boost::shared_ptr<ARDOUR::AudioRegion>,
+ double samples_per_unit,
+ Gdk::Color& basic_color,
+ bool recording,
+ TimeAxisViewItem::Visibility);
+
AudioRegionView (const AudioRegionView& other);
AudioRegionView (const AudioRegionView& other, boost::shared_ptr<ARDOUR::AudioRegion>);
to the TimeAxisViewItem parent class
*/
- AudioRegionView (ArdourCanvas::Group *,
- RouteTimeAxisView&,
- boost::shared_ptr<ARDOUR::AudioRegion>,
- double samples_per_unit,
- Gdk::Color& basic_color,
- TimeAxisViewItem::Visibility);
-
enum Flags {
EnvelopeVisible = 0x1,
WaveformVisible = 0x4,
}
RegionView*
-AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
+AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
{
AudioRegionView *region_view = 0;
switch (_trackview.audio_track()->mode()) {
case Normal:
- region_view = new AudioRegionView (canvas_group, _trackview, region,
+ if (recording) {
+ region_view = new AudioRegionView (canvas_group, _trackview, region,
+ _samples_per_unit, region_color, recording, TimeAxisViewItem::Visibility(TimeAxisViewItem::ShowFrame | TimeAxisViewItem::HideFrameRight));
+ } else {
+ region_view = new AudioRegionView (canvas_group, _trackview, region,
_samples_per_unit, region_color);
+ }
break;
case Destructive:
region_view = new TapeAudioRegionView (canvas_group, _trackview, region,
region_view->set_amplitude_above_axis(_amplitude_above_axis);
region_views.push_front (region_view);
-
/* if its the special single-sample length that we use for rec-regions, make it
insensitive to events
*/
for (RegionViewList::iterator j = copy.begin(); j != copy.end(); ++j) {
(*j)->enable_display(true);
- (*j)->set_y_position_and_height(0, height);
+ (*j)->set_height (height);
region_layered (*j);
}
}
void
AudioStreamView::setup_rec_box ()
{
- // cerr << _trackview.name() << " streamview SRB\n";
+ //cerr << _trackview.name() << " streamview SRB region_views.size() = " << region_views.size() << endl;
if (_trackview.session().transport_rolling()) {
if (!rec_active &&
_trackview.session().record_status() == Session::Recording &&
_trackview.get_diskstream()->record_enabled()) {
-
if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
/* add a new region, but don't bother if they set use_rec_regions mid-record */
rec_rect->property_x1() = xstart;
rec_rect->property_y1() = 1.0;
rec_rect->property_x2() = xend;
- rec_rect->property_y2() = (double) _trackview.height - 1;
- rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
+ rec_rect->property_y2() = (double) _trackview.current_height() - 1;
+ rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
+ rec_rect->property_outline_what() = 0x1 | 0x2 | 0x4 | 0x8;
rec_rect->property_fill_color_rgba() = fill_color;
rec_rect->lower_to_bottom();
} else if (rec_active &&
(_trackview.session().record_status() != Session::Recording ||
!_trackview.get_diskstream()->record_enabled())) {
-
screen_update_connection.disconnect();
rec_active = false;
rec_updating = false;
-
}
} else {
AudioStreamView::update_rec_regions ()
{
if (use_rec_regions) {
-
uint32_t n = 0;
for (list<pair<boost::shared_ptr<Region>,RegionView*> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
if (origlen == 1) {
/* our special initial length */
- add_region_view_internal (region, false);
+ add_region_view_internal (region, false, true);
}
/* also update rect */
if (origlen == 1) {
/* our special initial length */
- add_region_view_internal (region, false);
+ add_region_view_internal (region, false, true);
}
/* also hide rect */
void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src);
void update_rec_regions ();
- RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
+ RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false);
void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
void remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
CrossfadeViewList crossfade_views;
bool crossfades_visible;
+
+ std::list<sigc::connection> rec_data_ready_connections;
+ nframes_t last_rec_data_frame;
+ map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
+
+ bool outline_region;
+
Editing::WaveformShape _waveform_shape;
Editing::WaveformScale _waveform_scale;
-
- map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map;
};
#endif /* __ardour_audio_streamview_h__ */
void first_idle ();
+ XMLNode* get_child_xml_node (const string & childname);
+
void set_waveform_shape (Editing::WaveformShape);
void set_waveform_scale (Editing::WaveformScale);
AutomationController::AutomationController(boost::shared_ptr<AutomationControl> ac, Adjustment* adj)
- : BarController(*adj, *ac)
+ : BarController(*adj, ac)
, _ignore_change(false)
, _controllable(ac)
, _adjustment(adj)
}
void
-AutomationLine::set_y_position_and_height (guint32 y, guint32 h)
+AutomationLine::set_y_position_and_height (double y, double h)
{
bool changed = false;
if (y != _y_position) {
- _y_position = y;
+ _y_position = (guint32) floor (y);
changed = true;
}
if (h != _height) {
- _height = h;
+ _height = (guint32) floor (h);
double const bsz = control_point_box_size();
void show ();
void hide ();
- void set_y_position_and_height (uint32_t, uint32_t);
+ void set_y_position_and_height (double, double);
void set_verbose_cursor_uses_gain_mapping (bool yn);
TimeAxisView& trackview;
reset_width_dependent_items ((double) _region->length() / samples_per_unit);
- set_y_position_and_height (0, trackview.height);
+ set_height (trackview.current_height());
_region->StateChanged.connect (mem_fun(*this, &AutomationRegionView::region_changed));
/* compute vertical fractional position */
- const double height = trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2;
- y = 1.0 - (y / height);
+ const double h = trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2;
+ y = 1.0 - (y / h);
/* map using line */
RegionView*
-AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd)
+AutomationStreamView::add_region_view_internal (boost::shared_ptr<Region> region, bool wfd, bool recording)
{
if ( ! region) {
cerr << "No region" << endl;
void redisplay_diskstream ();
- inline double contents_height() const
- { return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
+ inline double contents_height() const {
+ return (_trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2);
+ }
private:
void setup_rec_box ();
void rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur);
void update_rec_regions (jack_nframes_t start, jack_nframes_t dur);
- RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data);
+ RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data, bool recording = false);
void display_region(AutomationRegionView* region_view);
void color_handler ();
}
void
-AutomationTimeAxisView::set_height (TrackHeight ht)
+AutomationTimeAxisView::set_height (uint32_t h)
{
- uint32_t h = height_to_pixels (ht);
bool changed = (height != (uint32_t) h) || first_call_to_set_height;
if (first_call_to_set_height)
first_call_to_set_height = false;
+ bool changed_between_small_and_normal = ( (h == hSmall || h == hSmaller) ^ (height == hSmall || height == hSmaller) );
- TimeAxisView::set_height (ht);
+ TimeAxisView* state_parent = get_parent_with_state ();
+ assert(state_parent);
+ XMLNode* xml_node = state_parent->get_automation_child_xml_node (_control->parameter());
+
+ TimeAxisView::set_height (h);
_base_rect->property_y2() = h;
if (_line)
_view->update_contents_y_position_and_height();
}
- TimeAxisView* state_parent = get_parent_with_state ();
- assert(state_parent);
+ char buf[32];
+ snprintf (buf, sizeof (buf), "%u", height);
+ xml_node->add_property ("height", buf);
- XMLNode* xml_node = state_parent->get_automation_child_xml_node(_control->parameter());
- assert(xml_node);
-
- switch (ht) {
- case Largest:
- xml_node->add_property ("track_height", "largest");
- break;
-
- case Large:
- xml_node->add_property ("track_height", "large");
- break;
-
- case Larger:
- xml_node->add_property ("track_height", "larger");
- break;
-
- case Normal:
- xml_node->add_property ("track_height", "normal");
- break;
-
- case Smaller:
- xml_node->add_property ("track_height", "smaller");
- break;
-
- case Small:
- xml_node->add_property ("track_height", "small");
- break;
- }
-
- switch (ht) {
- case Large:
- case Larger:
- case Largest:
- _controller->show ();
-
- case Normal:
- if (ht == Normal)
- _controller->hide();
+ if (changed_between_small_and_normal || first_call_to_set_height) {
+ first_call_to_set_height = false;
+ if (h >= hNormal) {
controls_table.remove (name_hbox);
-
+
if (plugname) {
if (plugname_packed) {
controls_table.remove (*plugname);
hide_name_entry ();
show_name_label ();
name_hbox.show_all ();
-
+
auto_button.show();
height_button.show();
clear_button.show();
hide_button.show_all();
- break;
-
- case Smaller:
- _controller->hide();
-
- case Small:
+ } else if (h >= hSmall) {
controls_table.remove (name_hbox);
if (plugname) {
if (plugname_packed) {
hide_name_entry ();
show_name_label ();
name_hbox.show_all ();
-
+
auto_button.hide();
height_button.hide();
clear_button.hide();
hide_button.hide();
- break;
+ }
}
if (changed) {
/* only emit the signal if the height really changed */
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
}
}
}
-void
+int
AutomationTimeAxisView::set_state (const XMLNode& node)
{
- TimeAxisView::set_state (node);
+ return TimeAxisView::set_state (node);
XMLNodeList kids;
XMLNodeConstIterator iter;
AutomationTimeAxisView::update_extra_xml_shown (bool editor_shown)
{
XMLNode* xml_node = get_state_node();
- xml_node->add_property ("shown", editor_shown ? "yes" : "no");
+// if (xml_node) {
+ xml_node->add_property ("shown", editor_shown ? "yes" : "no");
+// }
}
guint32
~AutomationTimeAxisView();
- void set_height (TimeAxisView::TrackHeight);
+
+ void set_height (uint32_t);
void set_samples_per_unit (double);
std::string name() const { return _name; }
bool paste (nframes_t, float times, Selection&, size_t nth);
void reset_objects (PointSelection&);
- void set_state (const XMLNode&);
+ int set_state (const XMLNode&);
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
void hide ();
virtual string name() const = 0;
virtual bool marked_for_display() const { return _marked_for_display; }
-
virtual void set_marked_for_display (bool yn) {
- if (yn != _marked_for_display) {
- _marked_for_display = yn;
- }
+ _marked_for_display = yn;
}
sigc::signal<void> Hiding;
uint32_t
BundleEditorMatrix::n_rows () const
{
- return _bundle->nchannels ();
+ return _bundle->nchannels ().n_total();
}
uint32_t
CANVAS_VARIABLE(canvasvar_EnteredControlPointSelected, "entered control point selected")
CANVAS_VARIABLE(canvasvar_EnteredGainLine, "entered gain line")
CANVAS_VARIABLE(canvasvar_EnteredMarker, "entered marker")
-CANVAS_VARIABLE(canvasvar_FrameBase, "region base")
CANVAS_VARIABLE(canvasvar_FrameHandle, "frame handle")
CANVAS_VARIABLE(canvasvar_GainLine, "gain line")
CANVAS_VARIABLE(canvasvar_GainLineInactive, "gain line inactive")
CANVAS_VARIABLE(canvasvar_RangeDragRect, "range drag rect")
CANVAS_VARIABLE(canvasvar_RangeMarkerBar, "range marker bar")
CANVAS_VARIABLE(canvasvar_RecordingRect, "recording rect")
+CANVAS_VARIABLE(canvasvar_RecWaveFormFill, "recorded waveform fill")
+CANVAS_VARIABLE(canvasvar_RecWaveForm, "recorded waveform outline")
CANVAS_VARIABLE(canvasvar_RubberBandRect, "rubber band rect")
CANVAS_VARIABLE(canvasvar_SelectedCrossfadeEditorLine, "selected crossfade editor line")
CANVAS_VARIABLE(canvasvar_SelectedCrossfadeEditorWave, "selected crossfade editor wave")
CANVAS_VARIABLE(canvasvar_TrimHandle, "trim handle")
CANVAS_VARIABLE(canvasvar_VerboseCanvasCursor, "verbose canvas cursor")
CANVAS_VARIABLE(canvasvar_VestigialFrame, "vestigial frame")
+CANVAS_VARIABLE(canvasvar_FrameBase, "region base")
+CANVAS_VARIABLE(canvasvar_WaveForm, "waveform outline")
CANVAS_VARIABLE(canvasvar_WaveFormClip, "clipped waveform")
CANVAS_VARIABLE(canvasvar_WaveFormFill, "waveform fill")
-CANVAS_VARIABLE(canvasvar_WaveForm, "waveform outline")
CANVAS_VARIABLE(canvasvar_ZeroLine, "zero line")
CANVAS_VARIABLE(canvasvar_ZoomRect, "zoom rect")
: TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf->position(),
- xf->length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
+ xf->length(), false, TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
crossfade (xf),
left_view (lview),
right_view (rview)
fade_out->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_CrossfadeLine.get();
fade_out->property_width_pixels() = 1;
- set_y_position_and_height (0, get_time_axis_view().height);
+ set_y_position_and_height (0, get_time_axis_view().current_height());
/* no frame around the xfade or overlap rects */
void
CrossfadeView::set_y_position_and_height (double y, double h)
{
- if (h == TimeAxisView::hSmaller || h == TimeAxisView::hSmall) {
- TimeAxisViewItem::set_y_position_and_height (y, h - 3 );
+ if (h <= TimeAxisView::hSmaller) {
+ TimeAxisViewItem::set_y_position_and_height (y, h - 3);
} else {
TimeAxisViewItem::set_y_position_and_height (y, h - NAME_HIGHLIGHT_SIZE - 3 );
}
- _y_position = y;
- _height = h;
-
redraw_curves ();
}
At "height - 3.0" the bottom of the crossfade touches the name highlight or the bottom of the track (if the
track is either Small or Smaller.
*/
- double const tav_height = get_time_axis_view().height;
- if (tav_height == TimeAxisView::hSmaller || tav_height == TimeAxisView::hSmall) {
+
+ double tav_height = get_time_axis_view().current_height();
+ if (tav_height == TimeAxisView::hSmaller ||
+ tav_height == TimeAxisView::hSmall) {
h = tav_height - 3.0;
} else {
h = tav_height - NAME_HIGHLIGHT_SIZE - 3.0;
*/
-#include <string>
+#include <cstring>
#include <cstring>
#include "editing.h"
#include "gui_thread.h"
#include "simpleline.h"
#include "rhythm_ferret.h"
+#include "actions.h"
#ifdef FFT_ANALYSIS
#include "analysis_window.h"
clicked_control_point = 0;
last_update_frame = 0;
drag_info.item = 0;
+ drag_info.copied_location = 0;
current_mixer_strip = 0;
current_bbt_points = 0;
select_new_marker = false;
zoomed_to_region = false;
rhythm_ferret = 0;
+ allow_vertical_scroll = false;
+ no_save_visual = false;
+ need_resize_line = false;
+ resize_line_y = 0;
+ old_resize_line_y = -1;
+ no_region_list_redisplay = false;
+ resize_idle_id = -1;
_scrubbing = false;
scrubbing_direction = 0;
set_midi_edit_mode (MidiEditPencil, true);
set_mouse_mode (MouseObject, true);
- last_visual_state.frames_per_unit = 0;
-
frames_per_unit = 2048; /* too early to use reset_zoom () */
reset_hscrollbar_stepping ();
ControlProtocol::ZoomIn.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), false));
ControlProtocol::ZoomOut.connect (bind (mem_fun (*this, &Editor::temporal_zoom_step), true));
ControlProtocol::ScrollTimeline.connect (mem_fun (*this, &Editor::control_scroll));
+ BasicUI::AccessAction.connect (mem_fun (*this, &Editor::access_action));
Config->ParameterChanged.connect (mem_fun (*this, &Editor::parameter_changed));
Route::SyncOrderKeys.connect (mem_fun (*this, &Editor::sync_order_keys));
delete time_canvas;
time_canvas = 0;
}
+
+ if (track_canvas) {
+ delete track_canvas;
+ track_canvas = 0;
+ }
+
+ if (time_canvas) {
+ delete time_canvas;
+ time_canvas = 0;
+ }
}
void
if (fpu < 1.0) {
fpu = 1.0;
- zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+ zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
} else if (fpu > session->current_end_frame() / canvas_width) {
fpu = session->current_end_frame() / canvas_width;
- zoom_range_clock.set ((nframes_t) floor (fpu * canvas_width));
+ zoom_range_clock.set ((nframes64_t) floor (fpu * canvas_width));
}
temporal_zoom (fpu);
/*
_control_scroll_target is an optional<T>
- it acts like a pointer to an nframes_t, with
+ it acts like a pointer to an nframes64_t, with
a operator conversion to boolean to check
that it has a value could possibly use
playhead_cursor->current_frame to store the
_dragging_playhead = true;
}
- if ((fraction < 0.0f) && (*_control_scroll_target < (nframes_t) fabs(step))) {
+ if ((fraction < 0.0f) && (*_control_scroll_target < (nframes64_t) fabs(step))) {
*_control_scroll_target = 0;
} else if ((fraction > 0.0f) && (max_frames - *_control_scroll_target < step)) {
*_control_scroll_target = max_frames - (current_page_frames()*2); // allow room for slop in where the PH is on the screen
} else {
- *_control_scroll_target += (nframes_t) floor (step);
+ *_control_scroll_target += (nframes64_t) floor (step);
}
/* move visuals, we'll catch up with it later */
}
bool
-Editor::deferred_control_scroll (nframes_t target)
+Editor::deferred_control_scroll (nframes64_t target)
{
session->request_locate (*_control_scroll_target, session->transport_rolling());
// reset for next stream
return false;
}
+void
+Editor::access_action (std::string action_group, std::string action_item)
+{
+ if (!session) {
+ return;
+ }
+
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::access_action), action_group, action_item));
+
+ cout<< "OSC: Recieved: "<< action_item << endl;
+
+ RefPtr<Action> act;
+ act = ActionManager::get_action( action_group.c_str(), action_item.c_str() );
+
+ if (act) {
+ act->activate();
+ }
+
+
+}
+
void
Editor::on_realize ()
{
}
void
-Editor::map_position_change (nframes_t frame)
+Editor::map_position_change (nframes64_t frame)
{
ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::map_position_change), frame));
}
void
-Editor::center_screen (nframes_t frame)
+Editor::center_screen (nframes64_t frame)
{
double page = canvas_width * frames_per_unit;
}
void
-Editor::center_screen_internal (nframes_t frame, float page)
+Editor::center_screen_internal (nframes64_t frame, float page)
{
page /= 2;
if (frame > page) {
- frame -= (nframes_t) page;
+ frame -= (nframes64_t) page;
} else {
frame = 0;
}
{
ENSURE_GUI_THREAD (mem_fun (*this, &Editor::handle_new_duration));
- nframes_t new_end = session->get_maximum_extent() + (nframes_t) floorf (current_page_frames() * 0.10f);
+ nframes64_t new_end = session->get_maximum_extent() + (nframes64_t) floorf (current_page_frames() * 0.10f);
if (new_end > last_canvas_frame) {
last_canvas_frame = new_end;
}
horizontal_adjustment.set_value (leftmost_frame/frames_per_unit);
+ //cerr << "Editor::handle_new_duration () called ha v:l:u:ps:lcf = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << last_canvas_frame << endl;//DEBUG
}
void
zoom_range_clock.set_session (session);
_playlist_selector->set_session (session);
nudge_clock.set_session (session);
+ nudge_clock.set (session->frame_rate() * 5); // default of 5 seconds
if (rhythm_ferret) {
rhythm_ferret->set_session (session);
}
void
-Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes_t frame)
+Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes64_t frame)
{
using namespace Menu_Helpers;
- Menu* (Editor::*build_menu_function)(nframes_t);
+ Menu* (Editor::*build_menu_function)(nframes64_t);
Menu *menu;
switch (item_type) {
}
Menu*
-Editor::build_track_context_menu (nframes_t ignored)
+Editor::build_track_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
}
Menu*
-Editor::build_track_bus_context_menu (nframes_t ignored)
+Editor::build_track_bus_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
}
Menu*
-Editor::build_track_region_context_menu (nframes_t frame)
+Editor::build_track_region_context_menu (nframes64_t frame)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_region_context_menu.items();
boost::shared_ptr<Playlist> pl;
if ((ds = rtv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
- for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (rtv->view(), (*i), edit_items);
+ Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)frame * ds->speed()));
+
+ if (selection->regions.size() > 1) {
+ // there's already a multiple selection: just add a
+ // single region context menu that will act on all
+ // selected regions
+ boost::shared_ptr<Region> dummy_region; // = NULL
+ add_region_context_items (rtv->view(), dummy_region, edit_items);
+ } else {
+ for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+ add_region_context_items (rtv->view(), (*i), edit_items);
+ }
}
+
delete regions;
}
}
}
Menu*
-Editor::build_track_crossfade_context_menu (nframes_t frame)
+Editor::build_track_crossfade_context_menu (nframes64_t frame)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_crossfade_context_menu.items();
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
}
- for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (atv->audio_view(), (*i), edit_items);
+ if (selection->regions.size() > 1) {
+ // there's already a multiple selection: just add a
+ // single region context menu that will act on all
+ // selected regions
+ boost::shared_ptr<Region> dummy_region; // = NULL
+ add_region_context_items (atv->audio_view(), dummy_region, edit_items);
+ } else {
+ for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+ add_region_context_items (atv->audio_view(), (*i), edit_items);
+ }
}
-
delete regions;
}
}
#endif /* FFT_ANALYSIS */
Menu*
-Editor::build_track_selection_context_menu (nframes_t ignored)
+Editor::build_track_selection_context_menu (nframes64_t ignored)
{
using namespace Menu_Helpers;
MenuList& edit_items = track_selection_context_menu.items();
if (region) {
ar = boost::dynamic_pointer_cast<AudioRegion> (region);
mr = boost::dynamic_pointer_cast<MidiRegion> (region);
- }
- /* when this particular menu pops up, make the relevant region
- become selected.
- */
+ /* when this particular menu pops up, make the relevant region
+ become selected.
+ */
- region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+ region_menu->signal_map_event().connect (
+ bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+
+ items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
+ items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+ }
- items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
- items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun (*this, &Editor::lower_region_to_bottom)));
items.push_back (SeparatorElem());
sigc::connection fooc;
- items.push_back (CheckMenuElem (_("Lock")));
- CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
- if (region->locked()) {
- region_lock_item->set_active();
- }
- region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
+ if (region) {
+ items.push_back (CheckMenuElem (_("Lock")));
+ CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
+ if (region->locked()) {
+ region_lock_item->set_active();
+ }
+ region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
- items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
- CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
+ items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
+ CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
- switch (region->positional_lock_style()) {
- case Region::MusicTime:
- bbt_glue_item->set_active (true);
- break;
- default:
- bbt_glue_item->set_active (false);
- break;
- }
+ switch (region->positional_lock_style()) {
+ case Region::MusicTime:
+ bbt_glue_item->set_active (true);
+ break;
+ default:
+ bbt_glue_item->set_active (false);
+ break;
+ }
- bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
+ bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
- items.push_back (CheckMenuElem (_("Mute")));
- CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
- fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
- if (region->muted()) {
- fooc.block (true);
- region_mute_item->set_active();
- fooc.block (false);
- }
-
- if (!Profile->get_sae()) {
- items.push_back (CheckMenuElem (_("Opaque")));
- CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
- fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
- if (region->opaque()) {
+ items.push_back (CheckMenuElem (_("Mute")));
+ CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
+ fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
+ if (region->muted()) {
fooc.block (true);
- region_opaque_item->set_active();
+ region_mute_item->set_active();
fooc.block (false);
}
+
+ if (!Profile->get_sae()) {
+ items.push_back (CheckMenuElem (_("Opaque")));
+ CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
+ fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
+ if (region->opaque()) {
+ fooc.block (true);
+ region_opaque_item->set_active();
+ fooc.block (false);
+ }
+ }
+ } else {
+ // multiple regions selected
+ // how should these act?
+ // here they toggle the property of all selected regions
+
+ items.push_back (MenuElem (_("Lock"), mem_fun(*this, &Editor::toggle_region_lock)));
+ items.push_back (MenuElem (_("Mute"), mem_fun(*this, &Editor::toggle_region_mute)));
+ if (!Profile->get_sae()) {
+ items.push_back (MenuElem (_("Opaque"), mem_fun(*this, &Editor::toggle_region_opaque)));
+ }
}
items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
- if (region->at_natural_position()) {
+ if (region && region->at_natural_position()) {
items.back().set_sensitive (false);
}
items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true))));
items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
+ items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_selected_regions)));
/* OK, stick the region submenu at the top of the list, and then add
the standard items.
*/
string::size_type pos = 0;
- string menu_item_name = region->name();
+ string menu_item_name = (region) ? region->name() : _("Selected regions");
while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
menu_item_name.replace (pos, 1, "__");
items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)));
items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection)));
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Bounce range"), mem_fun(*this, &Editor::bounce_range_selection)));
+ items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true)));
+ items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false)));
items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection)));
}
void
Editor::set_snap_to (SnapType st)
-{
+{
unsigned int snap_ind = (unsigned int)st;
+
snap_type = st;
if (snap_ind > snap_type_strings.size() - 1) {
move (x, y);
if (session && (prop = node.property ("playhead"))) {
- nframes_t pos = atol (prop->value().c_str());
+ nframes64_t pos = atol (prop->value().c_str());
playhead_cursor->set_position (pos);
} else {
playhead_cursor->set_position (0);
node->add_property ("edit-point", enum_2_string (_edit_point));
- snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
+ snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame);
node->add_property ("playhead", buf);
node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no");
switch (snap_type) {
case SnapToCDFrame:
if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
+ start = (nframes64_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
} else {
- start = (nframes_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
+ start = (nframes64_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
}
break;
case SnapToSMPTEFrame:
if (((direction == 0) && (fmod((double)start, (double)session->frames_per_smpte_frame()) > (session->frames_per_smpte_frame() / 2))) || (direction > 0)) {
- start = (nframes_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+ start = (nframes64_t) (ceil ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
} else {
- start = (nframes_t) (floor ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
+ start = (nframes64_t) (floor ((double) start / session->frames_per_smpte_frame()) * session->frames_per_smpte_frame());
}
break;
start -= session->smpte_offset ();
}
if (((direction == 0) && (start % one_smpte_second > one_smpte_second / 2)) || direction > 0) {
- start = (nframes_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
+ start = (nframes64_t) ceil ((double) start / one_smpte_second) * one_smpte_second;
} else {
- start = (nframes_t) floor ((double) start / one_smpte_second) * one_smpte_second;
+ start = (nframes64_t) floor ((double) start / one_smpte_second) * one_smpte_second;
}
if (session->smpte_offset_negative())
start -= session->smpte_offset ();
}
if (((direction == 0) && (start % one_smpte_minute > one_smpte_minute / 2)) || direction > 0) {
- start = (nframes_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
+ start = (nframes64_t) ceil ((double) start / one_smpte_minute) * one_smpte_minute;
} else {
- start = (nframes_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
+ start = (nframes64_t) floor ((double) start / one_smpte_minute) * one_smpte_minute;
}
if (session->smpte_offset_negative())
{
case SnapToSeconds:
if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / one_second) * one_second;
+ start = (nframes64_t) ceil ((double) start / one_second) * one_second;
} else {
- start = (nframes_t) floor ((double) start / one_second) * one_second;
+ start = (nframes64_t) floor ((double) start / one_second) * one_second;
}
break;
case SnapToMinutes:
if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
- start = (nframes_t) ceil ((double) start / one_minute) * one_minute;
+ start = (nframes64_t) ceil ((double) start / one_minute) * one_minute;
} else {
- start = (nframes_t) floor ((double) start / one_minute) * one_minute;
+ start = (nframes64_t) floor ((double) start / one_minute) * one_minute;
}
break;
case SnapToRegionSync:
case SnapToRegionBoundary:
if (!region_boundary_cache.empty()) {
- vector<nframes_t>::iterator i;
+ vector<nframes64_t>::iterator i;
if (direction > 0) {
i = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
}
double
-Editor::snap_length_beats (nframes_t start)
+Editor::snap_length_beats (nframes64_t start)
{
if (!session) {
return 1.0;
focus_type = ZoomFocusEdit;
} else if (choice == _("Active Mark")) {
focus_type = ZoomFocusEdit;
+ } else if (choice == _("Active Mark")) {
+ focus_type = ZoomFocusEdit;
} else {
focus_type = ZoomFocusMouse;
}
return *_playlist_selector;
}
-nframes_t
-Editor::get_nudge_distance (nframes_t pos, nframes_t& next)
+nframes64_t
+Editor::get_nudge_distance (nframes64_t pos, nframes64_t& next)
{
- nframes_t ret;
+ nframes64_t ret;
ret = nudge_clock.current_duration (pos);
next = ret + 1; /* XXXX fix me */
}
bool
-Editor::audio_region_selection_covers (nframes_t where)
+Editor::audio_region_selection_covers (nframes64_t where)
{
for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
if ((*a)->region()->covers (where)) {
selection->clear_regions ();
selection->clear_playlists ();
+
+ no_region_list_redisplay = true;
+}
+
+void
+Editor::finish_cleanup ()
+{
+ no_region_list_redisplay = false;
+ redisplay_regions ();
}
Location*
post_maximal_pane_position = edit_pane.get_width();
}
-
fullscreen();
+
if(post_maximal_editor_width) {
edit_pane.set_position (post_maximal_pane_position -
abs(post_maximal_editor_width - pre_maximal_editor_width));
}
void
-Editor::reset_x_origin (nframes_t frame)
+Editor::reset_x_origin (nframes64_t frame)
{
queue_visual_change (frame);
}
}
void
-Editor::reposition_and_zoom (nframes_t frame, double fpu)
+Editor::reposition_and_zoom (nframes64_t frame, double fpu)
{
+ //cerr << "Editor::reposition_and_zoom () called ha v:l:u:ps:fpu = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << frames_per_unit << endl;//DEBUG
reset_x_origin (frame);
reset_zoom (fpu);
+
+ if (!no_save_visual) {
+ undo_visual_stack.push_back (current_visual_state(false));
+ }
+}
+
+Editor::VisualState*
+Editor::current_visual_state (bool with_tracks)
+{
+ VisualState* vs = new VisualState;
+ vs->y_position = vertical_adjustment.get_value();
+ vs->frames_per_unit = frames_per_unit;
+ vs->leftmost_frame = leftmost_frame;
+ vs->zoom_focus = zoom_focus;
+ vs->zoomed_to_region = zoomed_to_region;
+
+ if (with_tracks) {
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ vs->track_states.push_back (TAVState ((*i), &(*i)->get_state()));
+ }
+ }
+
+ return vs;
}
void
-Editor::swap_visual_state ()
+Editor::undo_visual_state ()
{
- if (last_visual_state.frames_per_unit == 0) {
- // never set
+ if (undo_visual_stack.empty()) {
return;
}
- /* note: the correct functionality here is very dependent on the ordering of
- setting zoom focus, horizontal position and finally zoom. this is because
- it is set_frames_per_unit() that overwrites last_visual_state.
- */
+ VisualState* vs = undo_visual_stack.back();
+ undo_visual_stack.pop_back();
+ use_visual_state (*vs);
+ redo_visual_stack.push_back (vs);
+}
- set_zoom_focus (last_visual_state.zoom_focus);
- reposition_and_zoom (last_visual_state.leftmost_frame, last_visual_state.frames_per_unit);
- zoomed_to_region = false;
+void
+Editor::redo_visual_state ()
+{
+ if (redo_visual_stack.empty()) {
+ return;
+ }
+
+ VisualState* vs = redo_visual_stack.back();
+ redo_visual_stack.pop_back();
+ use_visual_state (*vs);
+ undo_visual_stack.push_back (vs);
+}
+
+void
+Editor::swap_visual_state ()
+{
+ if (undo_visual_stack.empty()) {
+ redo_visual_state ();
+ } else {
+ undo_visual_state ();
+ }
+}
+
+void
+Editor::use_visual_state (VisualState& vs)
+{
+ no_save_visual = true;
+
+ vertical_adjustment.set_value (vs.y_position);
+
+ set_zoom_focus (vs.zoom_focus);
+ reposition_and_zoom (vs.leftmost_frame, vs.frames_per_unit);
+
+ for (list<TAVState>::iterator i = vs.track_states.begin(); i != vs.track_states.end(); ++i) {
+ TrackViewList::iterator t;
+
+ /* check if the track still exists - it could have been deleted */
+
+ if ((t = find (track_views.begin(), track_views.end(), i->first)) != track_views.end()) {
+ (*t)->set_state (*(i->second));
+ }
+ }
+
+ if (!vs.track_states.empty()) {
+ update_route_visibility ();
+ }
+
+ no_save_visual = false;
}
void
if (fpu == frames_per_unit) {
return;
}
-
- last_visual_state.frames_per_unit = frames_per_unit;
- last_visual_state.leftmost_frame = leftmost_frame;
- last_visual_state.zoom_focus = zoom_focus;
frames_per_unit = fpu;
post_zoom ();
{
// convert fpu to frame count
- nframes_t frames = (nframes_t) floor (frames_per_unit * canvas_width);
+ nframes64_t frames = (nframes64_t) floor (frames_per_unit * canvas_width);
if (frames_per_unit != zoom_range_clock.current_duration()) {
zoom_range_clock.set (frames);
}
void
-Editor::queue_visual_change (nframes_t where)
+Editor::queue_visual_change (nframes64_t where)
{
pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
pending_visual_change.time_origin = where;
-
+
if (pending_visual_change.idle_handler_id < 0) {
pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
}
Editor::idle_visual_changer ()
{
VisualChange::Type p = pending_visual_change.pending;
+ nframes64_t csf, cef;
+
+ if (session) {
+ csf = session->current_start_frame();
+ cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker
+ }
pending_visual_change.pending = (VisualChange::Type) 0;
}
if (p & VisualChange::TimeOrigin) {
- nframes_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+ nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+ /* if we seek beyond the current end of the canvas, move the end */
if (time_origin != pending_visual_change.time_origin) {
+
+ if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) {
+ last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames();
+ horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit);
+ reset_scrolling_region ();
+ }
+
horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
} else {
update_fixed_rulers();
redisplay_tempo (true);
}
}
- pending_visual_change.idle_handler_id = -1;
+ pending_visual_change.idle_handler_id = -1;
return 0; /* this is always a one-shot call */
}
}
void
-Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd)
{
if (!session) return;
}
void
-Editor::set_punch_range (nframes_t start, nframes_t end, string cmd)
+Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd)
{
if (!session) return;
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)where * ds->speed()));
+ Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)where * ds->speed()));
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
RegionView* rv = atv->audio_view()->find_view (*i);
if (rv) {
- rs.push_back (rv);
+ rs.add (rv);
}
}
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
- Playlist::RegionList* regions = pl->regions_touched ((nframes_t) floor ( (double)where * ds->speed()), max_frames);
+ Playlist::RegionList* regions = pl->regions_touched ((nframes64_t) floor ( (double)where * ds->speed()), max_frames);
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
_have_idled = true;
}
+
+void
+Editor::start_resize_line_ops ()
+{
+#if 0
+ old_resize_line_y = -1;
+ resize_line_y = -1;
+ need_resize_line = true;
+#endif
+}
+
+void
+Editor::end_resize_line_ops ()
+{
+#if 0
+ need_resize_line = false;
+
+ if (old_resize_line_y >= 0) {
+ Gdk::Rectangle r (0, old_resize_line_y, (int) canvas_width, 3);
+ Glib::RefPtr<Gdk::Window> win = get_window();
+ cerr << "Final invalidation at " << old_resize_line_y << endl;
+ win->invalidate_rect (r, false);
+ }
+#endif
+}
+
+void
+Editor::queue_draw_resize_line (int at)
+{
+#if 0
+ Glib::RefPtr<Gdk::Window> win = get_window();
+
+ resize_line_y = at;
+
+ if (win && canvas_width) {
+
+ int controls_width = controls_layout.get_width();
+ int xroot, discard;
+
+ controls_layout.get_window()->get_origin (xroot, discard);
+
+ if (old_resize_line_y >= 0) {
+
+ /* redraw where it used to be */
+
+
+ Gdk::Rectangle r (xroot, old_resize_line_y - 1, controls_width + (int) canvas_width, 3);
+ win->invalidate_rect (r, true);
+ cerr << "invalidate " << xroot << "," << old_resize_line_y - 1 << ' '
+ << controls_width + canvas_width << " x 3\n";
+ }
+
+ /* draw where it is */
+
+ Gdk::Rectangle r (xroot, at - 1, controls_width + (int) canvas_width, 3);
+ win->invalidate_rect (r, true);
+ }
+#endif
+}
+
+bool
+Editor::on_expose_event (GdkEventExpose* ev)
+{
+ /* cerr << "+++ editor expose "
+ << ev->area.x << ',' << ev->area.y
+ << ' '
+ << ev->area.width << " x " << ev->area.height
+ << " need reize ? " << need_resize_line
+ << endl;
+ */
+ bool ret = Window::on_expose_event (ev);
+
+#if 0
+ if (need_resize_line) {
+
+ int xroot, yroot, discard;
+ int controls_width;
+
+ /* Our root coordinates for drawing the line will be the left edge
+ of the track controls, and the upper left edge of our own window.
+ */
+
+ get_window()->get_origin (discard, yroot);
+ controls_layout.get_window()->get_origin (xroot, discard);
+ controls_width = controls_layout.get_width();
+
+ GdkRectangle lr;
+ GdkRectangle intersection;
+
+ lr.x = xroot;
+ lr.y = resize_line_y;
+ lr.width = controls_width + (int) canvas_width;
+ lr.height = 3;
+
+ if (gdk_rectangle_intersect (&lr, &ev->area, &intersection)) {
+
+ Glib::RefPtr<Gtk::Style> style (get_style());
+ Glib::RefPtr<Gdk::GC> black_gc (style->get_black_gc ());
+ Glib::RefPtr<Gdk::GC> gc = wrap (black_gc->gobj_copy(), false);
+
+ /* draw on root window */
+
+ GdkWindow* win = gdk_get_default_root_window();
+
+ gc->set_subwindow (Gdk::INCLUDE_INFERIORS);
+ gc->set_line_attributes (3, Gdk::LINE_SOLID,
+ Gdk::CAP_NOT_LAST,
+ Gdk::JOIN_MITER);
+
+ gdk_draw_line (win, gc->gobj(),
+ xroot,
+ yroot + resize_line_y,
+ xroot + (int) canvas_width + controls_width,
+ yroot + resize_line_y);
+ cerr << "drew line @ " << xroot << ", " << yroot + resize_line_y
+ << " to " << xroot + (int) canvas_width + controls_width
+ << ", " << yroot + resize_line_y
+ << endl;
+ old_resize_line_y = yroot + resize_line_y;
+ cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl;
+ } else {
+ cerr << "no intersect with "
+ << lr.x << ',' << lr.y
+ << ' '
+ << lr.width << " x " << lr.height
+ << endl;
+ }
+ }
+
+ //cerr << "--- editor expose\n";
+#endif
+
+ return ret;
+}
+
+static gboolean
+_idle_resizer (gpointer arg)
+{
+ return ((Editor*)arg)->idle_resize ();
+}
+
+void
+Editor::add_to_idle_resize (TimeAxisView* view, uint32_t h)
+{
+ if (resize_idle_id < 0) {
+ resize_idle_id = g_idle_add (_idle_resizer, this);
+ }
+
+ resize_idle_target = h;
+
+ pending_resizes.push_back (view);
+
+ if (selection->selected (view) && !selection->tracks.empty()) {
+ pending_resizes.insert (pending_resizes.end(), selection->tracks.begin(), selection->tracks.end());
+ }
+}
+
+bool
+Editor::idle_resize ()
+{
+ for (vector<TimeAxisView*>::iterator i = pending_resizes.begin(); i != pending_resizes.end(); ++i) {
+ (*i)->idle_resize (resize_idle_target);
+ }
+ pending_resizes.clear();
+ resize_idle_id = -1;
+ return false;
+}
void first_idle ();
virtual bool have_idled() const { return _have_idled; }
- nframes_t leftmost_position() const { return leftmost_frame; }
- nframes_t current_page_frames() const {
- return (nframes_t) floor (canvas_width * frames_per_unit);
+ nframes64_t leftmost_position() const { return leftmost_frame; }
+ nframes64_t current_page_frames() const {
+ return (nframes64_t) floor (canvas_width * frames_per_unit);
}
void cycle_snap_mode ();
TimeAxisView* get_named_time_axis(const std::string & name) ;
void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>);
+ void add_to_idle_resize (TimeAxisView*, uint32_t);
RouteTimeAxisView* get_route_view_by_id (PBD::ID& id);
/* undo related */
- nframes_t unit_to_frame (double unit) const {
- return (nframes_t) rint (unit * frames_per_unit);
+ nframes64_t unit_to_frame (double unit) const {
+ return (nframes64_t) rint (unit * frames_per_unit);
}
- double frame_to_unit (nframes_t frame) const {
+ double frame_to_unit (nframes64_t frame) const {
return rint ((double) frame / (double) frames_per_unit);
}
*/
if (pixel >= 0) {
- return (nframes_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit);
+ return (nframes64_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit);
} else {
return 0;
}
void show_editor_mixer (bool yn);
void show_editor_list (bool yn);
void set_selected_mixer_strip (TimeAxisView&);
- void hide_track_in_display (TimeAxisView& tv);
+ void hide_track_in_display (TimeAxisView& tv, bool temporary = false);
void show_track_in_display (TimeAxisView& tv);
/* nudge is initiated by transport controls owned by ARDOUR_UI */
bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; }
void prepare_for_cleanup ();
+ void finish_cleanup ();
void maximise_editing_space();
void restore_editing_space();
- void reset_x_origin (nframes_t);
+ void reset_x_origin (nframes64_t);
void reset_zoom (double);
- void reposition_and_zoom (nframes_t, double);
+ void reposition_and_zoom (nframes64_t, double);
nframes64_t get_preferred_edit_position (bool ignore_playhead = false);
void show_rhythm_ferret();
+ void goto_visual_state (uint32_t);
+ void save_visual_state (uint32_t);
+
+ void queue_draw_resize_line (int at);
+ void start_resize_line_ops ();
+ void end_resize_line_ops ();
+
protected:
void map_transport_state ();
- void map_position_change (nframes_t);
+ void map_position_change (nframes64_t);
void on_realize();
+ bool on_expose_event (GdkEventExpose*);
private:
bool constructed;
// to keep track of the playhead position for control_scroll
- boost::optional<nframes_t> _control_scroll_target;
+ boost::optional<nframes64_t> _control_scroll_target;
PlaylistSelector* _playlist_selector;
+ typedef std::pair<TimeAxisView*,XMLNode*> TAVState;
+
struct VisualState {
- double frames_per_unit;
- nframes_t leftmost_frame;
- Editing::ZoomFocus zoom_focus;
+ double y_position;
+ double frames_per_unit;
+ nframes64_t leftmost_frame;
+ Editing::ZoomFocus zoom_focus;
+ bool zoomed_to_region;
+ std::list<TAVState> track_states;
};
- VisualState last_visual_state;
+ std::list<VisualState*> undo_visual_stack;
+ std::list<VisualState*> redo_visual_stack;
+ VisualState* current_visual_state (bool with_tracks = true);
+ void undo_visual_state ();
+ void redo_visual_state ();
+ void use_visual_state (VisualState&);
+ bool no_save_visual;
+ void swap_visual_state ();
+
+ std::vector<VisualState*> visual_states;
+ sigc::connection visual_state_op_connection;
+ void start_visual_state_op (uint32_t n);
+ void cancel_visual_state_op (uint32_t n);
+ bool end_visual_state_op (uint32_t n);
- nframes_t leftmost_frame;
+ nframes64_t leftmost_frame;
double frames_per_unit;
Editing::ZoomFocus zoom_focus;
- void use_visual_state (const VisualState&);
void set_frames_per_unit (double);
- void swap_visual_state ();
void post_zoom ();
Editing::MouseMode mouse_mode;
void hide();
void show ();
void set_name (const string&);
- void set_position (nframes_t start, nframes_t end = 0);
+ void set_position (nframes64_t start, nframes64_t end = 0);
void set_color_rgba (uint32_t);
};
void hide_marker (ArdourCanvas::Item*, GdkEvent*);
void clear_marker_display ();
- void mouse_add_new_marker (nframes_t where, bool is_cd=false, bool is_xrun=false);
+ void mouse_add_new_marker (nframes64_t where, bool is_cd=false, bool is_xrun=false);
+ bool choose_new_marker_name(string &name);
void update_cd_marker_display ();
void ensure_cd_marker_updated (LocationMarkers * lam, ARDOUR::Location * location);
Gtk::Menu * track_edit_playlist_submenu;
Gtk::Menu * track_selection_edit_playlist_submenu;
- void popup_track_context_menu (int, int, ItemType, bool, nframes_t);
- Gtk::Menu* build_track_context_menu (nframes_t);
- Gtk::Menu* build_track_bus_context_menu (nframes_t);
- Gtk::Menu* build_track_region_context_menu (nframes_t frame);
- Gtk::Menu* build_track_crossfade_context_menu (nframes_t);
- Gtk::Menu* build_track_selection_context_menu (nframes_t);
+ void popup_track_context_menu (int, int, ItemType, bool, nframes64_t);
+ Gtk::Menu* build_track_context_menu (nframes64_t);
+ Gtk::Menu* build_track_bus_context_menu (nframes64_t);
+ Gtk::Menu* build_track_region_context_menu (nframes64_t frame);
+ Gtk::Menu* build_track_crossfade_context_menu (nframes64_t);
+ Gtk::Menu* build_track_selection_context_menu (nframes64_t);
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
void add_region_context_items (StreamView*, boost::shared_ptr<ARDOUR::Region>, Gtk::Menu_Helpers::MenuList&);
Gtk::VBox global_vpacker;
Gtk::VBox vpacker;
+ bool need_resize_line;
+ int resize_line_y;
+ int old_resize_line_y;
+
Gdk::Cursor* current_canvas_cursor;
void set_canvas_cursor ();
Gdk::Cursor* which_grabber_cursor ();
void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
void update_fixed_rulers ();
void update_tempo_based_rulers ();
- void popup_ruler_menu (nframes_t where = 0, ItemType type = RegionItem);
+ void popup_ruler_menu (nframes64_t where = 0, ItemType type = RegionItem);
void update_ruler_visibility ();
void set_ruler_visible (RulerType, bool);
void toggle_ruler_visibility (RulerType rt);
gint bbt_nmarks;
uint32_t bbt_bar_helper_on;
uint32_t bbt_accent_modulo;
- void compute_bbt_ruler_scale (nframes_t lower, nframes_t upper);
+ void compute_bbt_ruler_scale (nframes64_t lower, nframes64_t upper);
gint metric_get_smpte (GtkCustomRulerMark **, gdouble, gdouble, gint);
gint metric_get_bbt (GtkCustomRulerMark **, gdouble, gdouble, gint);
Editor& editor;
ArdourCanvas::Points points;
ArdourCanvas::Line canvas_item;
- nframes_t current_frame;
+ nframes64_t current_frame;
double length;
Cursor (Editor&, bool (Editor::*)(GdkEvent*,ArdourCanvas::Item*));
~Cursor ();
- void set_position (nframes_t);
+ void set_position (nframes64_t);
void set_length (double units);
void set_y_axis (double position);
};
void select_all_selectables_between (bool within);
void select_range_between ();
- boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
+ boost::shared_ptr<ARDOUR::Region> find_next_region (nframes64_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&);
- vector<nframes_t> region_boundary_cache;
+ vector<nframes64_t> region_boundary_cache;
void build_region_boundary_cache ();
- Gtk::VBox trackview_vpacker;
-
Gtk::HBox top_hbox;
Gtk::HBox bottom_hbox;
double canvas_width;
double canvas_height;
double full_canvas_height;
- nframes_t last_canvas_frame;
+ nframes64_t last_canvas_frame;
bool track_canvas_map_handler (GdkEventAny*);
bool time_canvas_map_handler (GdkEventAny*);
Gtk::HBox edit_controls_hbox;
void control_scroll (float);
- bool deferred_control_scroll (nframes_t);
+ void access_action (std::string,std::string);
+ bool deferred_control_scroll (nframes64_t);
sigc::connection control_scroll_connection;
void tie_vertical_scrolling ();
};
Type pending;
- nframes_t time_origin;
+ nframes64_t time_origin;
double frames_per_unit;
int idle_handler_id;
static int _idle_visual_changer (void *arg);
int idle_visual_changer ();
- void queue_visual_change (nframes_t);
+ void queue_visual_change (nframes64_t);
void queue_visual_change (double);
void end_location_changed (ARDOUR::Location*);
static void build_cursors ();
sigc::connection scroll_connection;
- nframes_t last_update_frame;
- void center_screen (nframes_t);
- void center_screen_internal (nframes_t, float);
+ nframes64_t last_update_frame;
+ void center_screen (nframes64_t);
+ void center_screen_internal (nframes64_t, float);
void update_current_screen ();
void session_going_away ();
- nframes_t cut_buffer_start;
- nframes_t cut_buffer_length;
+ nframes64_t cut_buffer_start;
+ nframes64_t cut_buffer_length;
bool typed_event (ArdourCanvas::Item*, GdkEvent*, ItemType);
bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType);
void register_actions ();
- int ensure_cursor (nframes_t* pos);
+ int ensure_cursor (nframes64_t* pos);
void handle_new_region (boost::weak_ptr<ARDOUR::Region>);
void handle_new_regions (vector<boost::weak_ptr<ARDOUR::Region> >& );
void add_regions_to_region_display (std::vector<boost::weak_ptr<ARDOUR::Region> > & );
void region_hidden (boost::shared_ptr<ARDOUR::Region>);
void redisplay_regions ();
+ bool no_region_list_redisplay;
void insert_into_tmp_regionlist(boost::shared_ptr<ARDOUR::Region>);
list<boost::shared_ptr<ARDOUR::Region> > tmp_region_list;
void cut_copy_ranges (Editing::CutCopyOp);
void mouse_paste ();
- void paste_internal (nframes_t position, float times);
+ void paste_internal (nframes64_t position, float times);
/* EDITING OPERATIONS */
void lower_region ();
void lower_region_to_bottom ();
void split_region ();
- void split_region_at (nframes_t);
- void split_regions_at (nframes_t, RegionSelection&);
+ void split_region_at (nframes64_t);
+ void split_regions_at (nframes64_t, RegionSelection&);
void split_region_at_transients ();
void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret);
void crop_region_to_selection ();
- void crop_region_to (nframes_t start, nframes_t end);
+ void crop_region_to (nframes64_t start, nframes64_t end);
void set_sync_point (nframes64_t, const RegionSelection&);
void set_region_sync_from_edit_point ();
void remove_region_sync();
- void align_selection (ARDOUR::RegionPoint, nframes_t position, const RegionSelection&);
- void align_selection_relative (ARDOUR::RegionPoint point, nframes_t position, const RegionSelection&);
- void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
- void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
+ void align_selection (ARDOUR::RegionPoint, nframes64_t position, const RegionSelection&);
+ void align_selection_relative (ARDOUR::RegionPoint point, nframes64_t position, const RegionSelection&);
+ void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
+ void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
void remove_selected_regions ();
void remove_clicked_region ();
void edit_region ();
void quantize_region ();
void do_insert_time ();
- void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue);
+ void insert_time (nframes64_t pos, nframes64_t distance, Editing::InsertTimeOption opt, bool ignore_music_glue, bool markers_too);
void tab_to_transient (bool forward);
void loop_location (ARDOUR::Location&);
void temporal_zoom_selection ();
- void temporal_zoom_region ();
- void toggle_zoom_region ();
+ void temporal_zoom_region (bool both_axes);
+ void toggle_zoom_region (bool both_axes);
bool zoomed_to_region;
void temporal_zoom_session ();
void temporal_zoom (gdouble scale);
- void temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op);
- void temporal_zoom_to_frame (bool coarser, nframes_t frame);
+ void temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & op);
+ void temporal_zoom_to_frame (bool coarser, nframes64_t frame);
void amplitude_zoom (gdouble scale);
void amplitude_zoom_step (bool in);
void set_loop_from_region (bool play);
void set_punch_from_edit_range ();
- void set_loop_range (nframes_t start, nframes_t end, std::string cmd);
- void set_punch_range (nframes_t start, nframes_t end, std::string cmd);
+ void set_loop_range (nframes64_t start, nframes64_t end, std::string cmd);
+ void set_punch_range (nframes64_t start, nframes64_t end, std::string cmd);
void add_location_from_playhead_cursor ();
bool select_new_marker;
void keyboard_selection_begin ();
void keyboard_selection_finish (bool add);
bool have_pending_keyboard_selection;
- nframes_t pending_keyboard_selection_start;
+ nframes64_t pending_keyboard_selection_start;
boost::shared_ptr<ARDOUR::Region> select_region_for_operation (int dir, TimeAxisView **tv);
void extend_selection_to_end_of_region (bool next);
void remove_gain_control_point (ArdourCanvas::Item*, GdkEvent*);
void remove_control_point (ArdourCanvas::Item*, GdkEvent*);
- void mouse_brush_insert_region (RegionView*, nframes_t pos);
- void brush (nframes_t);
+ void mouse_brush_insert_region (RegionView*, nframes64_t pos);
+ void brush (nframes64_t);
- void show_verbose_time_cursor (nframes_t frame, double offset = 0, double xpos=-1, double ypos=-1);
- void show_verbose_duration_cursor (nframes_t start, nframes_t end, double offset = 0, double xpos=-1, double ypos=-1);
+ void show_verbose_time_cursor (nframes64_t frame, double offset = 0, double xpos=-1, double ypos=-1);
+ void show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double offset = 0, double xpos=-1, double ypos=-1);
double clamp_verbose_cursor_x (double);
double clamp_verbose_cursor_y (double);
void new_tempo_section ();
- void mouse_add_new_tempo_event (nframes_t where);
- void mouse_add_new_meter_event (nframes_t where);
+ void mouse_add_new_tempo_event (nframes64_t where);
+ void mouse_add_new_meter_event (nframes64_t where);
void remove_tempo_marker (ArdourCanvas::Item*);
void remove_meter_marker (ArdourCanvas::Item*);
void marker_menu_set_playhead ();
void marker_menu_set_from_playhead ();
void marker_menu_set_from_selection ();
+ void marker_menu_range_to_next ();
+ void marker_menu_export_range ();
void new_transport_marker_menu_set_loop ();
void new_transport_marker_menu_set_punch ();
void update_loop_range_view (bool visibility=false);
void redisplay_tempo (bool immediate_redraw);
void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false);
- void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) {
- /* XXX remove this function when everything moves to 64 bit frame counts */
- nframes64_t first64 = first;
- snap_to (first64, direction, for_mark);
- first = (nframes_t) first64;
- }
- double snap_length_beats (nframes_t start);
+ double snap_length_beats (nframes64_t start);
uint32_t bbt_beat_subdivision;
void region_selection_op (void (ARDOUR::Region::*pmf)(void*), void*);
void region_selection_op (void (ARDOUR::Region::*pmf)(bool), bool);
- bool audio_region_selection_covers (nframes_t where);
+ bool audio_region_selection_covers (nframes64_t where);
/* transport range select process */
enum RangeMarkerOp {
void drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event);
void end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event);
- bool select_all_within (nframes_t start, nframes_t end, gdouble topy, gdouble boty, const TrackViewList&, Selection::Operation op);
+ bool select_all_within (nframes64_t start, nframes64_t end, gdouble topy, gdouble boty, const TrackViewList&, Selection::Operation op);
ArdourCanvas::SimpleRect *rubberband_rect;
void end_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event);
ArdourCanvas::SimpleRect *zoom_rect;
- void reposition_zoom_rect (nframes_t start, nframes_t end);
+ void reposition_zoom_rect (nframes64_t start, nframes64_t end);
/* diskstream/route display management */
RouteDisplayModelColumns() {
add (text);
add (visible);
+ add (temporary_visible);
add (tv);
add (route);
}
Gtk::TreeModelColumn<Glib::ustring> text;
Gtk::TreeModelColumn<bool> visible;
+ Gtk::TreeModelColumn<bool> temporary_visible;
Gtk::TreeModelColumn<TimeAxisView*> tv;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route;
};
Gtk::ScrolledWindow route_list_scroller;
Gtk::Menu* route_list_menu;
+ void update_route_visibility ();
+
void sync_order_keys ();
bool ignore_route_order_sync;
int last_autoscroll_x;
int last_autoscroll_y;
uint32_t autoscroll_cnt;
- nframes_t autoscroll_x_distance;
+ nframes64_t autoscroll_x_distance;
double autoscroll_y_distance;
static gint _autoscroll_canvas (void *);
void start_canvas_autoscroll (int x, int y);
void stop_canvas_autoscroll ();
void maybe_autoscroll (GdkEventMotion*);
+ bool allow_vertical_scroll;
/* trimming */
enum TrimOp {
void start_trim (ArdourCanvas::Item*, GdkEvent*);
void point_trim (GdkEvent*);
void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*);
- void single_contents_trim (RegionView&, nframes_t, bool, bool, bool);
- void single_start_trim (RegionView&, nframes_t, bool, bool);
- void single_end_trim (RegionView&, nframes_t, bool, bool);
+ void single_contents_trim (RegionView&, nframes64_t, bool, bool, bool);
+ void single_start_trim (RegionView&, nframes64_t, bool, bool);
+ void single_end_trim (RegionView&, nframes64_t, bool, bool);
void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
void thaw_region_after_trim (RegionView& rv);
ExportDialog *export_dialog;
ExportDialog *export_range_markers_dialog;
- void export_range (nframes_t start, nframes_t end);
+ void export_range (nframes64_t start, nframes64_t end);
void export_range_markers ();
int write_region_selection(RegionSelection&);
bool write_region (string path, boost::shared_ptr<ARDOUR::AudioRegion>);
void export_region ();
void bounce_region_selection ();
- void bounce_range_selection ();
+ void bounce_range_selection (bool replace);
void external_edit_region ();
int write_audio_selection (TimeSelection&);
void begin_reversible_command (string cmd_name);
void commit_reversible_command ();
- /* visual history */
-
- UndoHistory visual_history;
- UndoTransaction current_visual_command;
-
-
void update_title ();
void update_title_s (const string & snapshot_name);
Gtk::VBox nudge_vbox;
AudioClock nudge_clock;
- nframes_t get_nudge_distance (nframes_t pos, nframes_t& next);
+ nframes64_t get_nudge_distance (nframes64_t pos, nframes64_t& next);
bool nudge_forward_release (GdkEventButton*);
bool nudge_backward_release (GdkEventButton*);
/* tracking step changes of track height */
TimeAxisView* current_stepping_trackview;
- struct timeval last_track_height_step_timestamp;
+ ARDOUR::microseconds_t last_track_height_step_timestamp;
gint track_height_step_timeout();
sigc::connection step_timeout;
RhythmFerret* rhythm_ferret;
- void set_track_height (TimeAxisView::TrackHeight h);
+ void fit_tracks ();
+ void set_track_height (uint32_t h);
void set_track_height_largest ();
void set_track_height_large ();
void set_track_height_larger ();
void waveform_scale_chosen (Editing::WaveformScale);
bool _have_idled;
+ int resize_idle_id;
+ int32_t resize_idle_target;
+ bool idle_resize();
+ friend gboolean _idle_resize (gpointer);
+ std::vector<TimeAxisView*> pending_resizes;
};
#endif /* __ardour_editor_h__ */
ActionManager::register_action (editor_actions, X_("RegionEditOps"), _("Region operations"));
ActionManager::register_action (editor_actions, X_("RegionGainMenu"), _("Gain"));
ActionManager::register_action (editor_actions, X_("RulerMenu"), _("Rulers"));
+ ActionManager::register_action (editor_actions, X_("SavedViewMenu"), _("Views"));
ActionManager::register_action (editor_actions, X_("ScrollMenu"), _("Scroll"));
ActionManager::register_action (editor_actions, X_("SecondaryClockMenu"), _("Secondary Clock"));
ActionManager::register_action (editor_actions, X_("Select"), _("Select"));
ActionManager::register_action (editor_actions, X_("TrimMenu"), _("Trim"));
ActionManager::register_action (editor_actions, X_("View"), _("View"));
ActionManager::register_action (editor_actions, X_("WaveformMenu"), _("Waveforms"));
- ActionManager::register_action (editor_actions, X_("ZoomFocus"), _("Zoom"));
+ ActionManager::register_action (editor_actions, X_("ZoomFocus"), _("Zoom Focus"));
ActionManager::register_action (editor_actions, X_("ZoomMenu"), _("Zoom"));
- ActionManager::register_action (editor_actions, X_("ZoomFocusMenu"), _("Zoom Focus"));
-
/* add named actions for the editor */
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-1", _("Save View 1"), bind (mem_fun (*this, &Editor::start_visual_state_op), 0));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-1", _("Goto View 1"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 0));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-2", _("Save View 2"), bind (mem_fun (*this, &Editor::start_visual_state_op), 1));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-2", _("Goto View 2"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 1));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-3", _("Save View 3"), bind (mem_fun (*this, &Editor::start_visual_state_op), 2));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-3", _("Goto View 3"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 2));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-4", _("Save View 4"), bind (mem_fun (*this, &Editor::start_visual_state_op), 3));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-4", _("Goto View 4"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 3));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-5", _("Save View 5"), bind (mem_fun (*this, &Editor::start_visual_state_op), 4));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-5", _("Goto View 5"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 4));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-6", _("Save View 6"), bind (mem_fun (*this, &Editor::start_visual_state_op), 5));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-6", _("Goto View 6"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 5));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-7", _("Save View 7"), bind (mem_fun (*this, &Editor::start_visual_state_op), 6));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-7", _("Goto View 7"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 6));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-8", _("Save View 8"), bind (mem_fun (*this, &Editor::start_visual_state_op), 7));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-8", _("Goto View 8"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 7));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-9", _("Save View 9"), bind (mem_fun (*this, &Editor::start_visual_state_op), 8));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-9", _("Goto View 9"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 8));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-10", _("Save View 10"), bind (mem_fun (*this, &Editor::start_visual_state_op), 9));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-10", _("Goto View 10"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 9));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-11", _("Save View 11"), bind (mem_fun (*this, &Editor::start_visual_state_op), 10));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-11", _("Goto View 11"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 10));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "save-visual-state-12", _("Save View 12"), bind (mem_fun (*this, &Editor::start_visual_state_op), 11));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "goto-visual-state-12", _("Goto View 12"), bind (mem_fun (*this, &Editor::cancel_visual_state_op), 11));
+ ActionManager::session_sensitive_actions.push_back (act);
+
+
act = ActionManager::register_action (editor_actions, "goto-mark-1", _("Locate to Mark 1"), bind (mem_fun (*this, &Editor::goto_nth_marker), 0));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "goto-mark-2", _("Locate to Mark 2"), bind (mem_fun (*this, &Editor::goto_nth_marker), 1));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "zoom-to-session", _("Zoom to Session"), mem_fun(*this, &Editor::temporal_zoom_session));
ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_action (editor_actions, "zoom-to-region", _("Zoom to Region"), mem_fun(*this, &Editor::toggle_zoom_region));
+ act = ActionManager::register_action (editor_actions, "zoom-to-region", _("Zoom to Region"), bind (mem_fun(*this, &Editor::toggle_zoom_region), false));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "zoom-to-region-both-axes", _("Zoom to Region (W&H)"), bind (mem_fun(*this, &Editor::toggle_zoom_region), true));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "pitch-shift-region", _("Transpose"), mem_fun(*this, &Editor::pitch_shift_regions));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::region_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "toggle-opaque-region", _("Toggle Opaque"), mem_fun(*this, &Editor::toggle_region_opaque));
+ ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "set-fade-in-length", _("Set Fade In Length"), bind (mem_fun(*this, &Editor::set_fade_length), true));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "quantize-region", _("Quantize Region"), mem_fun(*this, &Editor::quantize_region));
ActionManager::session_sensitive_actions.push_back (act);
-
+ ActionManager::region_selection_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "set-tempo-from-region", _("Set Tempo from Region=Bar"), mem_fun(*this, &Editor::use_region_as_bar));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::region_selection_sensitive_actions.push_back (act);
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "fit-tracks", _("Fit Selected Tracks"), (mem_fun(*this, &Editor::fit_tracks)));
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), (mem_fun(*this, &Editor::set_track_height_largest)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);
/* the next two are duplicate items with different names for use in two different contexts */
-
act = ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Import"), mem_fun (*this, &Editor::external_audio_dialog));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Import to Region List"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility));
ActionManager::track_selection_sensitive_actions.push_back (act);
Editor::add_external_audio_action (ImportMode mode_hint)
{
if (session == 0) {
- MessageDialog msg (0, _("You can't import or embed a file until you have a session loaded."));
+ MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
msg.run ();
return;
}
uint32_t track_cnt;
if (session == 0) {
- MessageDialog msg (0, _("You can't import or embed a file until you have a session loaded."));
+ MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
msg.run ();
return;
}
} else {
stop_updating ();
}
+ track_canvas_allocate(track_canvas->get_allocation());
}
void
using namespace Gtkmm2ext;
using namespace Editing;
-/* XXX this is a hack. it ought to be the maximum value of an nframes_t */
+/* XXX this is a hack. it ought to be the maximum value of an nframes64_t */
const double max_canvas_coordinate = (double) JACK_MAX_FRAMES;
marker_time_line_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
marker_tempo_lines = new TempoLines(*time_canvas, marker_time_line_group);
-
meter_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
tempo_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height);
range_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 2.0);
cd_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 5.0);
tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
tempo_bar->property_outline_what() = (0x1 | 0x8);
tempo_bar->property_outline_pixels() = 1;
-
meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
meter_bar->property_outline_what() = (0x1 | 0x8);
meter_bar->property_outline_pixels() = 1;
marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
marker_bar->property_outline_what() = (0x1 | 0x8);
marker_bar->property_outline_pixels() = 1;
cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
cd_marker_bar->property_outline_what() = (0x1 | 0x8);
cd_marker_bar->property_outline_pixels() = 1;
range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+
range_marker_bar->property_outline_what() = (0x1 | 0x8);
range_marker_bar->property_outline_pixels() = 1;
range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
range_bar_drag_rect->property_outline_pixels() = 0;
-
+
transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
transport_bar_drag_rect->property_outline_pixels() = 0;
transport_bar_drag_rect->hide ();
full_canvas_height = height;
}
- zoom_range_clock.set ((nframes_t) floor ((canvas_width * frames_per_unit)));
+ zoom_range_clock.set ((nframes64_t) floor ((canvas_width * frames_per_unit)));
playhead_cursor->set_position (playhead_cursor->current_frame);
reset_hscrollbar_stepping ();
}
double last_canvas_unit = max ((last_canvas_frame / frames_per_unit), canvas_width);
-
+ //cerr << "Editor::reset_scrolling_region () lcf:fpu:cw:lcu " << last_canvas_frame << ":" << frames_per_unit << ":" << canvas_width << ":" << last_canvas_unit << endl;//DEBUG
track_canvas->set_scroll_region (0.0, 0.0, last_canvas_unit, pos);
// XXX what is the correct height value for the time canvas ? this overstates it
/* drop onto canvas background: create new tracks */
+ frame = 0;
+
if (Profile->get_sae() || Config->get_only_copy_imported_files()) {
do_import (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, SrcBest, frame);
} else {
void
Editor::maybe_autoscroll (GdkEventMotion* event)
{
- nframes_t rightmost_frame = leftmost_frame + current_page_frames();
- nframes_t frame = drag_info.current_pointer_frame;
+ nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
+ nframes64_t frame = drag_info.current_pointer_frame;
bool startit = false;
double vertical_pos = vertical_adjustment.get_value();
}
+ if (!allow_vertical_scroll) {
+ autoscroll_y = 0;
+ }
+
if ((autoscroll_x != last_autoscroll_x) || (autoscroll_y != last_autoscroll_y) || (autoscroll_x == 0 && autoscroll_y == 0)) {
stop_canvas_autoscroll ();
}
bool
Editor::autoscroll_canvas ()
{
- nframes_t new_frame;
- nframes_t limit = max_frames - current_page_frames();
+ nframes64_t new_frame;
+ nframes64_t limit = max_frames - current_page_frames();
GdkEventMotion ev;
- nframes_t target_frame;
+ nframes64_t target_frame;
double new_pixel;
double target_pixel;
/* after about a while, speed up a bit by changing the timeout interval */
- autoscroll_x_distance = (nframes_t) floor (current_page_frames()/30.0f);
+ autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f);
} else if (autoscroll_cnt == 150) { /* 1.0 seconds */
- autoscroll_x_distance = (nframes_t) floor (current_page_frames()/20.0f);
+ autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f);
} else if (autoscroll_cnt == 300) { /* 1.5 seconds */
/* after about another while, speed up by increasing the shift per callback */
- autoscroll_x_distance = (nframes_t) floor (current_page_frames()/10.0f);
+ autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/10.0f);
}
}
autoscroll_active = true;
autoscroll_x = dx;
autoscroll_y = dy;
- autoscroll_x_distance = (nframes_t) floor (current_page_frames()/50.0);
+ autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/50.0);
autoscroll_y_distance = fabs (dy * 5); /* pixels */
autoscroll_cnt = 0;
void
Editor::canvas_horizontally_scrolled ()
{
- nframes64_t time_origin = (nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+ nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
if (time_origin != leftmost_frame) {
canvas_scroll_to (time_origin);
void
Editor::canvas_scroll_to (nframes64_t time_origin)
{
- leftmost_frame = time_origin;
- nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
+ leftmost_frame = time_origin;
+
+ nframes64_t rightmost_frame = leftmost_frame + current_page_frames ();
if (rightmost_frame > last_canvas_frame) {
last_canvas_frame = rightmost_frame;
{
int x, y;
double wx, wy;
- nframes_t xdelta;
+ nframes64_t xdelta;
int direction = ev->direction;
CanvasNoteEvent *midi_event = dynamic_cast<CanvasNoteEvent *>(track_canvas->get_item_at(ev->x, ev->y));
event.button.x = wx;
event.button.y = wy;
- nframes_t where = event_frame (&event, 0, 0);
+ nframes64_t where = event_frame (&event, 0, 0);
temporal_zoom_to_frame (false, where);
return true;
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
return false;
}
}
- gettimeofday (&last_track_height_step_timestamp, 0);
+ last_track_height_step_timestamp = get_microseconds();
current_stepping_trackview->step_height (true);
return true;
} else {
event.button.x = wx;
event.button.y = wy;
- nframes_t where = event_frame (&event, 0, 0);
+ nframes64_t where = event_frame (&event, 0, 0);
temporal_zoom_to_frame (true, where);
return true;
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
return false;
}
}
- gettimeofday (&last_track_height_step_timestamp, 0);
+ last_track_height_step_timestamp = get_microseconds();
current_stepping_trackview->step_height (false);
return true;
} else {
bool
Editor::time_canvas_scroll (GdkEventScroll* ev)
{
- nframes_t xdelta;
+ nframes64_t xdelta;
int direction = ev->direction;
switch (direction) {
}
void
-Editor::Cursor::set_position (nframes_t frame)
+Editor::Cursor::set_position (nframes64_t frame)
{
double new_pos = editor.frame_to_unit (frame);
}
void
-Editor::export_range (nframes_t start, nframes_t end)
+Editor::export_range (nframes64_t start, nframes64_t end)
{
if (session) {
if (export_dialog == 0) {
itt.cancel = false;
itt.progress = 0.0f;
- track->bounce_range (region->position(), region->position() + region->length(), itt);
+ boost::shared_ptr<Region> r = track->bounce_range (region->position(), region->position() + region->length(), itt);
+ cerr << "Result of bounce of "
+ << region->name() << " len = " << region->length()
+ << " was "
+ << r->name() << " len = " << r->length()
+ << endl;
}
}
Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
{
boost::shared_ptr<AudioFileSource> fs;
- const nframes_t chunk_size = 4096;
- nframes_t to_read;
+ const nframes64_t chunk_size = 4096;
+ nframes64_t to_read;
Sample buf[chunk_size];
gain_t gain_buffer[chunk_size];
- nframes_t pos;
+ nframes64_t pos;
char s[PATH_MAX+1];
uint32_t cnt;
vector<boost::shared_ptr<AudioFileSource> > sources;
pos = region->position();
while (to_read) {
- nframes_t this_time;
+ nframes64_t this_time;
this_time = min (to_read, chunk_size);
Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list<AudioRange>& range)
{
boost::shared_ptr<AudioFileSource> fs;
- const nframes_t chunk_size = 4096;
- nframes_t nframes;
+ const nframes64_t chunk_size = 4096;
+ nframes64_t nframes;
Sample buf[chunk_size];
gain_t gain_buffer[chunk_size];
- nframes_t pos;
+ nframes64_t pos;
char s[PATH_MAX+1];
uint32_t cnt;
string path;
pos = (*i).start;
while (nframes) {
- nframes_t this_time;
+ nframes64_t this_time;
this_time = min (nframes, chunk_size);
while (nframes) {
- nframes_t this_time = min (nframes, chunk_size);
+ nframes64_t this_time = min (nframes, chunk_size);
memset (buf, 0, sizeof (Sample) * this_time);
for (uint32_t n=0; n < channels; ++n) {
Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
{
// GTK2FIX
- //nframes_t offset = static_cast<nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
- nframes_t offset = 0;
+ //nframes64_t offset = static_cast<nframes64_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
+ nframes64_t offset = 0;
- nframes_t x_pos = 0 ;
+ nframes64_t x_pos = 0 ;
if (item->get_position() < offset) {
x_pos = 0 ;
double cx, cy ;
MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
- nframes_t pending_region_position ;
- nframes_t pointer_frame ;
+ nframes64_t pending_region_position ;
+ nframes64_t pointer_frame ;
pointer_frame = event_frame(event, &cx, &cy) ;
snap_to(pointer_frame) ;
- if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
+ if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
{
pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
snap_to(pending_region_position) ;
ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
- nframes_t pending_region_position;
- nframes_t pointer_frame;
+ nframes64_t pending_region_position;
+ nframes64_t pointer_frame;
pointer_frame = event_frame(event, &cx, &cy) ;
snap_to(pointer_frame) ;
- if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
+ if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
{
pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
snap_to(pending_region_position) ;
void
Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
{
- nframes_t where ;
+ nframes64_t where ;
TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
{
ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
- nframes_t start = 0 ;
- nframes_t end = 0 ;
- nframes_t pointer_frame = event_frame(event) ;
+ nframes64_t start = 0 ;
+ nframes64_t end = 0 ;
+ nframes64_t pointer_frame = event_frame(event) ;
// chekc th eposition of the item is not locked
if(!ifv->get_position_locked()) {
}
// are we getting bigger or smaller?
- nframes_t new_dur_val = end - start ;
+ nframes64_t new_dur_val = end - start ;
// start handle, so a smaller pointer frame increases our component size
if(pointer_frame <= drag_info.grab_frame)
}
else
{
- nframes_t temp = ifv->get_position() + ifv->get_duration() ;
+ nframes64_t temp = ifv->get_position() + ifv->get_duration() ;
- ifv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
- ifv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
+ ifv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
+ ifv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
}
}
{
ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
- nframes_t start = 0 ;
- nframes_t end = 0 ;
- nframes_t pointer_frame = event_frame(event) ;
- nframes_t new_dur_val = 0 ;
+ nframes64_t start = 0 ;
+ nframes64_t end = 0 ;
+ nframes64_t pointer_frame = event_frame(event) ;
+ nframes64_t new_dur_val = 0 ;
snap_to(pointer_frame) ;
}
else
{
- nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
+ nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
{
ifv->set_duration(new_duration, this) ;
{
MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
- nframes_t start = 0 ;
- nframes_t end = 0 ;
- nframes_t pointer_frame = event_frame(event) ;
+ nframes64_t start = 0 ;
+ nframes64_t end = 0 ;
+ nframes64_t pointer_frame = event_frame(event) ;
// chekc th eposition of the item is not locked
if(!mv->get_position_locked())
}
// are we getting bigger or smaller?
- nframes_t new_dur_val = end - start ;
+ nframes64_t new_dur_val = end - start ;
if(pointer_frame <= drag_info.grab_frame)
{
}
else
{
- nframes_t temp = mv->get_position() + mv->get_duration() ;
+ nframes64_t temp = mv->get_position() + mv->get_duration() ;
- mv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
- mv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
+ mv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
+ mv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
}
}
{
MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
- nframes_t start = 0 ;
- nframes_t end = 0 ;
- nframes_t pointer_frame = event_frame(event) ;
- nframes_t new_dur_val = 0 ;
+ nframes64_t start = 0 ;
+ nframes64_t end = 0 ;
+ nframes64_t pointer_frame = event_frame(event) ;
+ nframes64_t new_dur_val = 0 ;
snap_to(pointer_frame) ;
{
// we cant extend beyond the item we are marking
ImageFrameView* marked_item = mv->get_marked_item() ;
- nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
+ nframes64_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
{
}
else
{
- nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
+ nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
mv->set_duration(new_duration, this) ;
}
}
}
void
-Editor::LocationMarkers::set_position (nframes_t startf,
- nframes_t endf)
+Editor::LocationMarkers::set_position (nframes64_t startf,
+ nframes64_t endf)
{
start->set_position (startf);
if (end) { end->set_position (endf); }
}
void
-Editor::mouse_add_new_marker (nframes_t where, bool is_cd, bool is_xrun)
+Editor::mouse_add_new_marker (nframes64_t where, bool is_cd, bool is_xrun)
{
string markername, markerprefix;
int flags = (is_cd ? Location::IsCDMarker|Location::IsMark : Location::IsMark);
if (session) {
session->locations()->next_available_name(markername, markerprefix);
+ if (!is_xrun && !choose_new_marker_name(markername)) {
+ return;
+ }
Location *location = new Location (where, where, markername, (Location::Flags) flags);
session->begin_reversible_command (_("add marker"));
XMLNode &before = session->locations()->get_state();
items.push_back (SeparatorElem());
+ items.push_back (MenuElem (_("Create range to next marker"), mem_fun(*this, &Editor::marker_menu_range_to_next)));
+
items.push_back (MenuElem (_("Hide"), mem_fun(*this, &Editor::marker_menu_hide)));
if (start_or_end) return;
items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::marker_menu_rename)));
items.push_back (MenuElem (_("Set Range from Range Selection"), mem_fun(*this, &Editor::marker_menu_set_from_selection)));
}
+ items.push_back (SeparatorElem());
+ items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::marker_menu_export_range)));
items.push_back (SeparatorElem());
- if (! loop_or_punch) {
+ if (!loop_or_punch) {
items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide)));
items.push_back (MenuElem (_("Rename Range"), mem_fun(*this, &Editor::marker_menu_rename)));
items.push_back (MenuElem (_("Remove Range"), mem_fun(*this, &Editor::marker_menu_remove)));
}
}
+void
+Editor::marker_menu_export_range ()
+{
+ Marker* marker;
+
+ if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
+ fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
+ /*NOTREACHED*/
+ }
+
+ Location* l;
+ bool is_start;
+
+ if ((l = find_location_from_marker (marker, is_start)) != 0) {
+ if (l->is_range_marker()) {
+ export_range (l->start(), l->end());
+ }
+ }
+}
+
+void
+Editor::marker_menu_range_to_next ()
+{
+ Marker* marker;
+ if (!session) {
+ return;
+ }
+
+ if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
+ fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
+ /*NOTREACHED*/
+ }
+
+ Location* l;
+ bool is_start;
+
+ if ((l = find_location_from_marker (marker, is_start)) == 0) {
+ return;
+ }
+
+ nframes_t end = session->locations()->first_mark_after (marker->position());
+
+ if (end != max_frames) {
+ string range_name = l->name();
+ range_name += "-range";
+
+ Location* newrange = new Location (marker->position(), end, range_name, Location::IsRangeMarker);
+ session->locations()->add (newrange);
+ }
+}
+
void
Editor::marker_menu_set_from_playhead ()
{
{
if (session && session->engine().running()) {
- nframes_t frame;
+ nframes64_t frame;
frame = session->audible_frame();
} else {
if (frame != last_update_frame) {
- if (frame < leftmost_frame || frame > leftmost_frame + current_page_frames()) {
- playhead_cursor->canvas_item.hide();
- } else {
- playhead_cursor->set_position (frame);
- }
+ playhead_cursor->set_position (frame);
}
}
bool
Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
+ Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window();
+
+ if (canvas_window) {
+ Glib::RefPtr<const Gdk::Window> pointer_window;
+ int x, y;
+ double wx, wy;
+ Gdk::ModifierType mask;
+
+ pointer_window = canvas_window->get_pointer (x, y, mask);
+
+ if (pointer_window == track_canvas->get_bin_window()) {
+
+ track_canvas->window_to_world (x, y, wx, wy);
+ allow_vertical_scroll = true;
+ } else {
+ allow_vertical_scroll = false;
+ }
+ }
+
track_canvas->grab_focus();
if (session && session->actively_recording()) {
bool
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
- nframes_t where = event_frame (event, 0, 0);
+ nframes64_t where = event_frame (event, 0, 0);
AutomationTimeAxisView* atv = 0;
/* no action if we're recording */
track_canvas->get_pointer (x, y);
}
-
+
if (current_stepping_trackview) {
/* don't keep the persistent stepped trackview if the mouse moves */
current_stepping_trackview = 0;
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- drag_info.pointer_frame_offset = drag_info.grab_frame - ((nframes_t) arv->audio_region()->fade_in()->back()->when + arv->region()->position());
+
+ drag_info.pointer_frame_offset = drag_info.grab_frame - ((nframes64_t) arv->audio_region()->fade_in()->back()->when + arv->region()->position());
}
void
Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- nframes_t pos;
- nframes_t fade_length;
+ nframes64_t pos;
+ nframes64_t fade_length;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- nframes_t pos;
- nframes_t fade_length;
+ nframes64_t pos;
+ nframes64_t fade_length;
if (drag_info.first_move) return;
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region()->length() - (nframes_t) arv->audio_region()->fade_out()->back()->when + arv->region()->position());
+ drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region()->length() - (nframes64_t) arv->audio_region()->fade_out()->back()->when + arv->region()->position());
}
void
Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- nframes_t pos;
- nframes_t fade_length;
+ nframes64_t pos;
+ nframes64_t fade_length;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
if (drag_info.first_move) return;
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- nframes_t pos;
- nframes_t fade_length;
+ nframes64_t pos;
+ nframes64_t fade_length;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
Cursor* cursor = (Cursor *) drag_info.data;
- nframes_t adjusted_frame;
+ nframes64_t adjusted_frame;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
void
Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
- nframes_t f_delta;
+ nframes64_t f_delta;
Marker* marker = (Marker *) drag_info.data;
Location *real_location;
Location *copy_location;
bool is_start;
bool move_both = false;
- nframes_t newframe;
+ nframes64_t newframe;
if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
} else {
newframe = 0;
}
- nframes_t next = newframe;
+ nframes64_t next = newframe;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
snap_to (newframe, 0, true);
Editor::meter_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
MeterMarker* marker = (MeterMarker *) drag_info.data;
- nframes_t adjusted_frame;
+ nframes64_t adjusted_frame;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
Editor::tempo_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
TempoMarker* marker = (TempoMarker *) drag_info.data;
- nframes_t adjusted_frame;
+ nframes64_t adjusted_frame;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
cy = min ((double) (cp->line().y_position() + cp->line().height()), cy);
//translate cx to frames
- nframes_t cx_frames = unit_to_frame (cx);
+ nframes64_t cx_frames = unit_to_frame (cx);
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !drag_info.x_constrained) {
snap_to (cx_frames);
{
double cx;
double cy;
- nframes_t frame_within_region;
+ nframes64_t frame_within_region;
/* need to get x coordinate in terms of parent (TimeAxisItemView)
origin.
cx = event->button.x;
cy = event->button.y;
line->parent_group().w2i (cx, cy);
- frame_within_region = (nframes_t) floor (cx * frames_per_unit);
+ frame_within_region = (nframes64_t) floor (cx * frames_per_unit);
if (!line->control_points_adjacent (frame_within_region, current_line_drag_info.before,
current_line_drag_info.after)) {
speed = tv->get_diskstream()->speed();
}
- drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+ drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
drag_info.dest_trackview = drag_info.source_trackview;
drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
drag_info.dest_trackview = drag_info.source_trackview;
- drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+ drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
// we want a move threshold
drag_info.want_move_threshold = true;
speed = tv->get_diskstream()->speed();
}
- drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed);
+ drag_info.last_frame_position = (nframes64_t) (clicked_regionview->region()->position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
drag_info.source_trackview = &clicked_regionview->get_time_axis_view();
drag_info.dest_trackview = drag_info.source_trackview;
RegionView* rv;
RegionView* nrv;
-
+
rv = (*i);
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
double x_delta;
double y_delta = 0;
RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data);
- nframes_t pending_region_position = 0;
+ nframes64_t pending_region_position = 0;
int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order;
int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen
bool clamp_y_axis = false;
tracks = tracks |= (0x01 << rtv2->order);
}
- height_list[rtv2->order] = (*i)->height;
+ height_list[rtv2->order] = (*i)->current_height();
children = 1;
+
if ((children_list = rtv2->get_child_list()).size() > 0) {
for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) {
tracks = tracks |= (0x01 << (rtv2->order + children));
- height_list[rtv2->order + children] = (*j)->height;
+ height_list[rtv2->order + children] = (*j)->current_height();
numtracks++;
children++;
}
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
- nframes_t sync_frame;
- nframes_t sync_offset;
+ nframes64_t sync_frame;
+ nframes64_t sync_offset;
int32_t sync_dir;
pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
tvp2 = trackview_by_y_position (iy1 + y_delta);
temp_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2);
- rv->set_y_position_and_height (0, temp_rtv->height);
+ rv->set_y_position_and_height (0, temp_rtv->current_height());
/* if you un-comment the following, the region colours will follow the track colours whilst dragging,
personally, i think this can confuse things, but never mind.
double speed;
bool changed_tracks;
bool changed_position;
- nframes_t where;
+ nframes64_t where;
if (rv->region()->locked()) {
++i;
speed = dest_rtv->get_diskstream()->speed();
}
- changed_position = (drag_info.last_frame_position != (nframes_t) (rv->region()->position()/speed));
+ changed_position = (drag_info.last_frame_position != (nframes64_t) (rv->region()->position()/speed));
changed_tracks = (dest_tv != &rv->get_time_axis_view());
if (changed_position && !drag_info.x_constrained) {
- where = (nframes_t) (unit_to_frame (ix1) * speed);
+ where = (nframes64_t) (unit_to_frame (ix1) * speed);
} else {
where = rv->region()->position();
}
boost::shared_ptr<Region> new_region;
+
if (drag_info.copy) {
/* we already made a copy */
new_region = rv->region();
/* get the playlist where this drag started. we can't use rv->region()->playlist()
because we may have copied the region and it has not been attached to a playlist.
*/
-
+
assert ((source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view())));
assert ((ds = source_tv->get_diskstream()));
assert ((from_playlist = ds->playlist()));
begin_reversible_command (_("create region"));
XMLNode &before = mtv->playlist()->get_state();
- nframes_t start = drag_info.grab_frame;
+ nframes64_t start = drag_info.grab_frame;
snap_to (start, -1);
const Meter& m = session->tempo_map().meter_at(start);
const Tempo& t = session->tempo_map().tempo_at(start);
if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
- align_region (rv.region(), SyncPoint, (nframes_t) (where * speed));
+ align_region (rv.region(), SyncPoint, (nframes64_t) (where * speed));
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
- align_region (rv.region(), End, (nframes_t) (where * speed));
+ align_region (rv.region(), End, (nframes64_t) (where * speed));
} else {
- align_region (rv.region(), Start, (nframes_t) (where * speed));
+ align_region (rv.region(), Start, (nframes64_t) (where * speed));
}
}
}
}
void
-Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, double ypos)
+Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos, double ypos)
{
char buf[128];
SMPTE::Time smpte;
BBT_Time bbt;
int hours, mins;
- nframes_t frame_rate;
+ nframes64_t frame_rate;
float secs;
if (session == 0) {
break;
default:
- snprintf (buf, sizeof(buf), "%u", frame);
+ snprintf (buf, sizeof(buf), "%" PRIi64, frame);
break;
}
}
void
-Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double offset, double xpos, double ypos)
+Editor::show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double offset, double xpos, double ypos)
{
char buf[128];
SMPTE::Time smpte;
BBT_Time sbbt;
BBT_Time ebbt;
int hours, mins;
- nframes_t distance, frame_rate;
+ nframes64_t distance, frame_rate;
float secs;
Meter meter_at_start(session->tempo_map().meter_at(start));
break;
default:
- snprintf (buf, sizeof(buf), "%u", end - start);
+ snprintf (buf, sizeof(buf), "%" PRIi64, end - start);
break;
}
void
Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, SelectionOp op)
{
- nframes_t start = 0;
- nframes_t end = 0;
+ nframes64_t start = 0;
+ nframes64_t end = 0;
if (session == 0) {
return;
void
Editor::drag_selection (ArdourCanvas::Item* item, GdkEvent* event)
{
- nframes_t start = 0;
- nframes_t end = 0;
- nframes_t length;
- nframes_t pending_position;
+ nframes64_t start = 0;
+ nframes64_t end = 0;
+ nframes64_t length;
+ nframes64_t pending_position;
if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
pending_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
speed = tv->get_diskstream()->speed();
}
- nframes_t region_start = (nframes_t) (clicked_regionview->region()->position() / speed);
- nframes_t region_end = (nframes_t) (clicked_regionview->region()->last_frame() / speed);
- nframes_t region_length = (nframes_t) (clicked_regionview->region()->length() / speed);
+ nframes64_t region_start = (nframes64_t) (clicked_regionview->region()->position() / speed);
+ nframes64_t region_end = (nframes64_t) (clicked_regionview->region()->last_frame() / speed);
+ nframes64_t region_length = (nframes64_t) (clicked_regionview->region()->length() / speed);
//drag_info.item = clicked_regionview->get_name_highlight();
drag_info.item = item;
Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
RegionView* rv = clicked_regionview;
- nframes_t frame_delta = 0;
+ nframes64_t frame_delta = 0;
bool left_direction;
bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
}
case EndTrim:
- if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes_t) (rv->region()->last_frame()/speed))) {
+ if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes64_t) (rv->region()->last_frame()/speed))) {
break;
} else {
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
switch (trim_op) {
case StartTrim:
- show_verbose_time_cursor((nframes_t) (rv->region()->position()/speed), 10);
+ show_verbose_time_cursor((nframes64_t) (rv->region()->position()/speed), 10);
break;
case EndTrim:
- show_verbose_time_cursor((nframes_t) (rv->region()->last_frame()/speed), 10);
+ show_verbose_time_cursor((nframes64_t) (rv->region()->last_frame()/speed), 10);
break;
case ContentsTrim:
show_verbose_time_cursor(drag_info.current_pointer_frame, 10);
}
void
-Editor::single_contents_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
+Editor::single_contents_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
{
boost::shared_ptr<Region> region (rv.region());
return;
}
- nframes_t new_bound;
+ nframes64_t new_bound;
double speed = 1.0;
TimeAxisView* tvp = clicked_axisview;
if (left_direction) {
if (swap_direction) {
- new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
} else {
- new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
}
} else {
if (swap_direction) {
- new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
} else {
- new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
}
}
if (obey_snap) {
snap_to (new_bound);
}
- region->trim_start ((nframes_t) (new_bound * speed), this);
+ region->trim_start ((nframes64_t) (new_bound * speed), this);
rv.region_changed (StartChanged);
}
void
-Editor::single_start_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_start_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
{
boost::shared_ptr<Region> region (rv.region());
return;
}
- nframes_t new_bound;
+ nframes64_t new_bound;
double speed = 1.0;
TimeAxisView* tvp = clicked_axisview;
}
if (left_direction) {
- new_bound = (nframes_t) (region->position()/speed) - frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) - frame_delta;
} else {
- new_bound = (nframes_t) (region->position()/speed) + frame_delta;
+ new_bound = (nframes64_t) (region->position()/speed) + frame_delta;
}
if (obey_snap) {
snap_to (new_bound, (left_direction ? 0 : 1));
}
- region->trim_front ((nframes_t) (new_bound * speed), this);
+ region->trim_front ((nframes64_t) (new_bound * speed), this);
rv.region_changed (Change (LengthChanged|PositionChanged|StartChanged));
}
void
-Editor::single_end_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_end_trim (RegionView& rv, nframes64_t frame_delta, bool left_direction, bool obey_snap)
{
boost::shared_ptr<Region> region (rv.region());
return;
}
- nframes_t new_bound;
+ nframes64_t new_bound;
double speed = 1.0;
TimeAxisView* tvp = clicked_axisview;
}
if (left_direction) {
- new_bound = (nframes_t) ((region->last_frame() + 1)/speed) - frame_delta;
+ new_bound = (nframes64_t) ((region->last_frame() + 1)/speed) - frame_delta;
} else {
- new_bound = (nframes_t) ((region->last_frame() + 1)/speed) + frame_delta;
+ new_bound = (nframes64_t) ((region->last_frame() + 1)/speed) + frame_delta;
}
if (obey_snap) {
snap_to (new_bound);
}
- region->trim_end ((nframes_t) (new_bound * speed), this);
+ region->trim_end ((nframes64_t) (new_bound * speed), this);
rv.region_changed (LengthChanged);
}
Editor::point_trim (GdkEvent* event)
{
RegionView* rv = clicked_regionview;
- nframes_t new_bound = drag_info.current_pointer_frame;
+ nframes64_t new_bound = drag_info.current_pointer_frame;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
snap_to (new_bound);
void
Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
{
- nframes_t start = 0;
- nframes_t end = 0;
+ nframes64_t start = 0;
+ nframes64_t end = 0;
ArdourCanvas::SimpleRect *crect;
switch (range_marker_op) {
if (Keyboard::no_modifier_keys_pressed (&event->button) && range_marker_op != CreateCDMarker) {
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
start = session->locations()->first_mark_before (drag_info.grab_frame);
end = session->locations()->first_mark_after (drag_info.grab_frame);
void
Editor::drag_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event)
{
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
snap_to (drag_info.current_pointer_frame);
}
void
-Editor::reposition_zoom_rect (nframes_t start, nframes_t end)
+Editor::reposition_zoom_rect (nframes64_t start, nframes64_t end)
{
double x1 = frame_to_pixel (start);
double x2 = frame_to_pixel (end);
void
Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
{
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
double y1;
double y2;
return;
}
- nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position();
+ nframes64_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position();
float percentage = (double) newlen / (double) clicked_regionview->region()->length();
}
void
-Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
+Editor::mouse_brush_insert_region (RegionView* rv, nframes64_t pos)
{
/* no brushing without a useful snap setting */
double speed = rtv->get_diskstream()->speed();
XMLNode &before = playlist->get_state();
- playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed));
+ playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes64_t) (pos * speed));
XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
gint
Editor::track_height_step_timeout ()
{
- struct timeval now;
- struct timeval delta;
-
- gettimeofday (&now, 0);
- timersub (&now, &last_track_height_step_timestamp, &delta);
-
- if (delta.tv_sec * 1000000 + delta.tv_usec > 250000) { /* milliseconds */
+ if (get_microseconds() - last_track_height_step_timestamp < 250000) {
current_stepping_trackview = 0;
return false;
}
#include <cmath>
#include <string>
#include <map>
+#include <set>
#include <pbd/error.h>
#include <pbd/basename.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/choice.h>
#include <gtkmm2ext/window_title.h>
+#include <gtkmm2ext/popup.h>
+
#include <ardour/audioengine.h>
#include <ardour/session.h>
}
void
-Editor::split_region_at (nframes_t where)
+Editor::split_region_at (nframes64_t where)
{
RegionSelection rs;
}
void
-Editor::split_regions_at (nframes_t where, RegionSelection& regions)
+Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
{
list <boost::shared_ptr<Playlist > > used_playlists;
snap_to (where);
}
+ cerr << "Split " << regions.size() << " at " << where << endl;
+
for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
RegionSelection::iterator tmp;
void
Editor::remove_selected_regions ()
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+ get_regions_for_action (rs);
+
+ if (!session) {
+ return;
+ }
+
+ if (rs.empty()) {
return;
}
- /* XXX: should be called remove regions if we're removing more than one */
begin_reversible_command (_("remove region"));
-
- while (!selection->regions.empty()) {
- boost::shared_ptr<Region> region = selection->regions.front()->region ();
- boost::shared_ptr<Playlist> playlist = region->playlist ();
+ list<boost::shared_ptr<Region> > regions_to_remove;
- XMLNode &before = playlist->get_state();
- playlist->remove_region (region);
- XMLNode &after = playlist->get_state();
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ // we can't just remove the region(s) in this loop because
+ // this removes them from the RegionSelection, and they thus
+ // disappear from underneath the iterator, and the ++i above
+ // SEGVs in a puzzling fashion.
+
+ // so, first iterate over the regions to be removed from rs and
+ // add them to the regions_to_remove list, and then
+ // iterate over the list to actually remove them.
+
+ regions_to_remove.push_back ((*i)->region());
+ }
+
+ for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+ boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+ if (!playlist) {
+ // is this check necessary?
+ continue;
+ }
+
+ XMLNode &before = playlist->get_state();
+ playlist->remove_region (*rl);
+ XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
}
{
RegionView* rv;
boost::shared_ptr<Region> region;
- nframes_t start = 0;
+ nframes64_t start = 0;
if (selection->time.start () == selection->time.end_frame ()) {
{
TimeAxisView *tv;
boost::shared_ptr<Region> region;
- nframes_t start;
+ nframes64_t start;
if ((region = select_region_for_operation (next ? 1 : 0, &tv)) == 0) {
return;
{
TimeAxisView *tv;
boost::shared_ptr<Region> region;
- nframes_t end;
+ nframes64_t end;
if ((region = select_region_for_operation (previous ? -1 : 0, &tv)) == 0) {
return;
void
Editor::nudge_forward (bool next, bool force_playhead)
{
- nframes_t distance;
- nframes_t next_distance;
+ nframes64_t distance;
+ nframes64_t next_distance;
RegionSelection rs;
get_regions_for_action (rs);
void
Editor::nudge_backward (bool next, bool force_playhead)
{
- nframes_t distance;
- nframes_t next_distance;
+ nframes64_t distance;
+ nframes64_t next_distance;
RegionSelection rs;
get_regions_for_action (rs);
void
Editor::nudge_forward_capture_offset ()
{
- nframes_t distance;
+ nframes64_t distance;
RegionSelection rs;
get_regions_for_action (rs);
void
Editor::nudge_backward_capture_offset ()
{
- nframes_t distance;
+ nframes64_t distance;
RegionSelection rs;
get_regions_for_action (rs);
void
Editor::build_region_boundary_cache ()
{
- nframes_t pos = 0;
+ nframes64_t pos = 0;
vector<RegionPoint> interesting_points;
boost::shared_ptr<Region> r;
TrackViewList tracks;
while (pos < session->current_end_frame() && !at_end) {
- nframes_t rpos;
- nframes_t lpos = max_frames;
+ nframes64_t rpos;
+ nframes64_t lpos = max_frames;
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
to sort later.
*/
- vector<nframes_t>::iterator ri;
+ vector<nframes64_t>::iterator ri;
for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
if (*ri == rpos) {
}
boost::shared_ptr<Region>
-Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
+Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
{
TrackViewList::iterator i;
- nframes_t closest = max_frames;
+ nframes64_t closest = max_frames;
boost::shared_ptr<Region> ret;
- nframes_t rpos = 0;
+ nframes64_t rpos = 0;
float track_speed;
- nframes_t track_frame;
+ nframes64_t track_frame;
RouteTimeAxisView *rtav;
for (i = tracks.begin(); i != tracks.end(); ++i) {
- nframes_t distance;
+ nframes64_t distance;
boost::shared_ptr<Region> r;
track_speed = 1.0f;
Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
{
boost::shared_ptr<Region> r;
- nframes_t pos = cursor->current_frame;
+ nframes64_t pos = cursor->current_frame;
if (!session) {
return;
void
Editor::cursor_to_selection_start (Cursor *cursor)
{
- nframes_t pos = 0;
+ nframes64_t pos = 0;
RegionSelection rs;
get_regions_for_action (rs);
void
Editor::cursor_to_selection_end (Cursor *cursor)
{
- nframes_t pos = 0;
+ nframes64_t pos = 0;
RegionSelection rs;
get_regions_for_action (rs);
Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
{
boost::shared_ptr<Region> r;
- nframes_t pos;
+ nframes64_t pos;
Location* loc;
bool ignored;
void
Editor::selected_marker_to_selection_start ()
{
- nframes_t pos = 0;
+ nframes64_t pos = 0;
Location* loc;
bool ignored;
void
Editor::selected_marker_to_selection_end ()
{
- nframes_t pos = 0;
+ nframes64_t pos = 0;
Location* loc;
bool ignored;
void
Editor::scroll_playhead (bool forward)
{
- nframes_t pos = playhead_cursor->current_frame;
- nframes_t delta = (nframes_t) floor (current_page_frames() / 0.8);
+ nframes64_t pos = playhead_cursor->current_frame;
+ nframes64_t delta = (nframes64_t) floor (current_page_frames() / 0.8);
if (forward) {
if (pos == max_frames) {
void
Editor::playhead_backward ()
{
- nframes_t pos;
- nframes_t cnt;
+ nframes64_t pos;
+ nframes64_t cnt;
float prefix;
bool was_floating;
cnt = 1;
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate ());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate ());
} else {
- cnt = (nframes_t) prefix;
+ cnt = (nframes64_t) prefix;
}
}
pos = playhead_cursor->current_frame;
- if ((nframes_t) pos < cnt) {
+ if ((nframes64_t) pos < cnt) {
pos = 0;
} else {
pos -= cnt;
void
Editor::playhead_forward ()
{
- nframes_t pos;
- nframes_t cnt;
+ nframes64_t pos;
+ nframes64_t cnt;
bool was_floating;
float prefix;
cnt = 1;
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate ());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate ());
} else {
- cnt = (nframes_t) floor (prefix);
+ cnt = (nframes64_t) floor (prefix);
}
}
cnt = 1;
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate ());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate ());
} else {
- cnt = (nframes_t) prefix;
+ cnt = (nframes64_t) prefix;
}
}
void
Editor::edit_cursor_forward ()
{
- //nframes_t pos;
- nframes_t cnt;
+ //nframes64_t pos;
+ nframes64_t cnt;
bool was_floating;
float prefix;
cnt = 1;
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate ());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate ());
} else {
- cnt = (nframes_t) floor (prefix);
+ cnt = (nframes64_t) floor (prefix);
}
}
{
float prefix;
bool was_floating;
- nframes_t frame;
+ nframes64_t frame;
if (get_prefix (prefix, was_floating)) {
return;
}
if (was_floating) {
- frame = (nframes_t) floor (prefix * session->frame_rate());
+ frame = (nframes64_t) floor (prefix * session->frame_rate());
} else {
- frame = (nframes_t) floor (prefix);
+ frame = (nframes64_t) floor (prefix);
}
session->request_locate (frame);
void
Editor::scroll_backward (float pages)
{
- nframes_t frame;
- nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+ nframes64_t frame;
+ nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
bool was_floating;
float prefix;
- nframes_t cnt;
+ nframes64_t cnt;
if (get_prefix (prefix, was_floating)) {
- cnt = (nframes_t) floor (pages * one_page);
+ cnt = (nframes64_t) floor (pages * one_page);
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate());
} else {
- cnt = (nframes_t) floor (prefix * one_page);
+ cnt = (nframes64_t) floor (prefix * one_page);
}
}
void
Editor::scroll_forward (float pages)
{
- nframes_t frame;
- nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+ nframes64_t frame;
+ nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
bool was_floating;
float prefix;
- nframes_t cnt;
+ nframes64_t cnt;
if (get_prefix (prefix, was_floating)) {
- cnt = (nframes_t) floor (pages * one_page);
+ cnt = (nframes64_t) floor (pages * one_page);
} else {
if (was_floating) {
- cnt = (nframes_t) floor (prefix * session->frame_rate());
+ cnt = (nframes64_t) floor (prefix * session->frame_rate());
} else {
- cnt = (nframes_t) floor (prefix * one_page);
+ cnt = (nframes64_t) floor (prefix * one_page);
}
}
nfpu = fpu;
- new_page_size = (nframes_t) floor (canvas_width * nfpu);
+ new_page_size = (nframes64_t) floor (canvas_width * nfpu);
half_page_size = new_page_size / 2;
switch (zoom_focus) {
}
void
-Editor::temporal_zoom_region ()
+Editor::temporal_zoom_region (bool both_axes)
{
nframes64_t start = max_frames;
nframes64_t end = 0;
RegionSelection rs;
+ set<TimeAxisView*> tracks;
+ double top_y_position = DBL_MAX;
get_regions_for_action (rs);
}
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
if ((*i)->region()->position() < start) {
start = (*i)->region()->position();
}
+
if ((*i)->region()->last_frame() + 1 > end) {
end = (*i)->region()->last_frame() + 1;
}
+
+ tracks.insert (&((*i)->get_time_axis_view()));
+
+ if ((*i)->get_time_axis_view().y_position < top_y_position) {
+ top_y_position = (*i)->get_time_axis_view().y_position;
+ }
}
/* now comes an "interesting" hack ... make sure we leave a little space
gint mmwidth = gdk_screen_get_width_mm (screen);
double pix_per_mm = (double) pixwidth/ (double) mmwidth;
double one_centimeter_in_pixels = pix_per_mm * 10.0;
- nframes_t extra_samples = unit_to_frame (one_centimeter_in_pixels);
-
+
+ if ((start == 0 && end == 0) || end < start) {
+ return;
+ }
+
+ nframes64_t range = end - start;
+ double new_fpu = (double)range / (double)canvas_width;
+ nframes64_t extra_samples = (nframes64_t) floor (one_centimeter_in_pixels * new_fpu);
+
if (start > extra_samples) {
start -= extra_samples;
} else {
end = max_frames;
}
+ if (both_axes) {
+ /* save visual state with track states included, and prevent
+ set_frames_per_unit() from doing it again.
+ */
+ undo_visual_stack.push_back (current_visual_state(true));
+ no_save_visual = true;
+ }
+
temporal_zoom_by_frame (start, end, "zoom to region");
+
+ if (both_axes) {
+ uint32_t per_track_height = (uint32_t) floor ((canvas_height - 10.0) / tracks.size());
+
+ /* set visible track heights appropriately */
+
+ for (set<TimeAxisView*>::iterator t = tracks.begin(); t != tracks.end(); ++t) {
+ (*t)->set_height (per_track_height);
+ }
+
+ /* hide irrelevant tracks */
+
+ no_route_list_redisplay = true;
+
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ if (find (tracks.begin(), tracks.end(), (*i)) == tracks.end()) {
+ hide_track_in_display (**i, true);
+ }
+ }
+
+ no_route_list_redisplay = false;
+ redisplay_route_list ();
+
+ vertical_adjustment.set_value (std::max (top_y_position - 5.0, 0.0));
+ no_save_visual = false;
+ }
+
zoomed_to_region = true;
+ redo_visual_stack.push_back (current_visual_state());
}
void
-Editor::toggle_zoom_region ()
+Editor::toggle_zoom_region (bool both_axes)
{
if (zoomed_to_region) {
swap_visual_state ();
} else {
- temporal_zoom_region ();
+ temporal_zoom_region (both_axes);
}
}
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
temporal_zoom_by_frame (start, end, "zoom to selection");
}
ENSURE_GUI_THREAD (mem_fun (*this, &Editor::temporal_zoom_session));
if (session) {
+ last_canvas_frame = ((session->current_end_frame() - session->current_start_frame()) + (current_page_frames() / 24));
temporal_zoom_by_frame (session->current_start_frame(), session->current_end_frame(), "zoom to session");
}
}
void
-Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op)
+Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & op)
{
if (!session) return;
return;
}
- nframes_t range = end - start;
+ nframes64_t range = end - start;
double new_fpu = (double)range / (double)canvas_width;
-// double p2 = 1.0;
-
-// while (p2 < new_fpu) {
-// p2 *= 2.0;
-// }
-// new_fpu = p2;
- nframes_t new_page = (nframes_t) floor (canvas_width * new_fpu);
- nframes_t middle = (nframes_t) floor( (double)start + ((double)range / 2.0f ));
- nframes_t new_leftmost = (nframes_t) floor( (double)middle - ((double)new_page/2.0f));
+ nframes64_t new_page = (nframes64_t) floor (canvas_width * new_fpu);
+ nframes64_t middle = (nframes64_t) floor( (double)start + ((double)range / 2.0f ));
+ nframes64_t new_leftmost = (nframes64_t) floor( (double)middle - ((double)new_page/2.0f));
- if (new_leftmost > middle) new_leftmost = 0;
-
-// begin_reversible_command (op);
-// session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
-// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
-// commit_reversible_command ();
+ if (new_leftmost > middle) {
+ new_leftmost = 0;
+ }
reposition_and_zoom (new_leftmost, new_fpu);
}
void
-Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
+Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
{
if (!session) return;
if (new_fpu == frames_per_unit) return;
- nframes_t new_leftmost = frame - (nframes_t)range_before;
+ nframes64_t new_leftmost = frame - (nframes64_t)range_before;
if (new_leftmost > frame) new_leftmost = 0;
reposition_and_zoom (new_leftmost, new_fpu);
}
+
+bool
+Editor::choose_new_marker_name(string &name) {
+
+ if (!Config->get_name_new_markers()) {
+ /* don't prompt user for a new name */
+ return true;
+ }
+
+ ArdourPrompter dialog (true);
+
+ dialog.set_prompt (_("New Name:"));
+
+ WindowTitle title(Glib::get_application_name());
+ title += _("Name New Location Marker");
+
+ dialog.set_title(title.get_string());
+
+ dialog.set_name ("MarkNameWindow");
+ dialog.set_size_request (250, -1);
+ dialog.set_position (Gtk::WIN_POS_MOUSE);
+
+ dialog.add_button (Stock::OK, RESPONSE_ACCEPT);
+ dialog.set_initial_text (name);
+
+ dialog.show ();
+
+ switch (dialog.run ()) {
+ case RESPONSE_ACCEPT:
+ break;
+ default:
+ return false;
+ }
+
+ dialog.get_result(name);
+ return true;
+
+}
+
+
void
Editor::add_location_from_selection ()
{
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
session->locations()->next_available_name(rangename,"selection");
Location *location = new Location (start, end, rangename, Location::IsRangeMarker);
select_new_marker = true;
session->locations()->next_available_name(markername,"mark");
+ if (!choose_new_marker_name(markername)) {
+ return;
+ }
Location *location = new Location (where, where, markername, Location::IsMark);
session->begin_reversible_command (_("add marker"));
XMLNode &before = session->locations()->get_state();
void
Editor::set_mark ()
{
- nframes_t pos;
+ nframes64_t pos;
float prefix;
bool was_floating;
string markername;
pos = session->audible_frame ();
} else {
if (was_floating) {
- pos = (nframes_t) floor (prefix * session->frame_rate ());
+ pos = (nframes64_t) floor (prefix * session->frame_rate ());
} else {
- pos = (nframes_t) floor (prefix);
+ pos = (nframes64_t) floor (prefix);
}
}
session->locations()->next_available_name(markername,"mark");
+ if (!choose_new_marker_name(markername)) {
+ return;
+ }
session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true);
}
double wx, wy;
double cx, cy;
TimeAxisView *tv;
- nframes_t where;
+ nframes64_t where;
RouteTimeAxisView *rtv = 0;
boost::shared_ptr<Playlist> playlist;
interthread_progress_bar.set_orientation (Gtk::PROGRESS_LEFT_TO_RIGHT);
+ interthread_progress_window->set_border_width (12);
+ interthread_progress_window->get_vbox()->set_spacing (6);
+
+ interthread_progress_label.set_alignment (0.5, 0.5);
+
interthread_progress_window->get_vbox()->pack_start (interthread_progress_label, false, false);
interthread_progress_window->get_vbox()->pack_start (interthread_progress_bar,false, false);
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
- nframes_t selection_cnt = end - start + 1;
+ nframes64_t selection_cnt = end - start + 1;
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
boost::shared_ptr<AudioRegion> current;
boost::shared_ptr<Region> current_r;
boost::shared_ptr<Playlist> pl;
- nframes_t internal_start;
+ nframes64_t internal_start;
string new_name;
if ((pl = (*i)->playlist()) == 0) {
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
sort_track_selection ();
boost::shared_ptr<AudioRegion> current;
boost::shared_ptr<Region> current_r;
boost::shared_ptr<Playlist> playlist;
- nframes_t internal_start;
+ nframes64_t internal_start;
string new_name;
if ((playlist = (*i)->playlist()) == 0) {
sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
latest_regionviews.clear ();
- playlist->partition ((nframes_t)((*t).start * speed), (nframes_t)((*t).end * speed), true);
+ playlist->partition ((nframes64_t)((*t).start * speed), (nframes64_t)((*t).end * speed), true);
c.disconnect ();
}
void
-Editor::crop_region_to (nframes_t start, nframes_t end)
+Editor::crop_region_to (nframes64_t start, nframes64_t end)
{
vector<boost::shared_ptr<Playlist> > playlists;
boost::shared_ptr<Playlist> playlist;
return;
}
- nframes_t the_start;
- nframes_t the_end;
- nframes_t cnt;
+ nframes64_t the_start;
+ nframes64_t the_end;
+ nframes64_t cnt;
begin_reversible_command (_("trim to selection"));
if the selection extends beyond the region
*/
- the_start = max (the_start, region->position());
+ the_start = max (the_start, (nframes64_t) region->position());
if (max_frames - the_start < region->length()) {
the_end = the_start + region->length() - 1;
} else {
void
Editor::region_fill_track ()
{
- nframes_t end;
+ nframes64_t end;
RegionSelection rs;
get_regions_for_action (rs);
TreeModel::iterator i = region_list_display.get_selection()->get_selected();
boost::shared_ptr<Region> region = (*i)[region_list_columns.region];
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
boost::shared_ptr<Playlist> playlist;
return;
}
- nframes_t selection_length = end - start;
+ nframes64_t selection_length = end - start;
float times = (float)selection_length / region->length();
begin_reversible_command (_("fill selection"));
void
Editor::remove_region_sync ()
{
- begin_reversible_command (_("remove sync"));
+ RegionSelection rs;
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- boost::shared_ptr<Region> r = (*i)->region();
- XMLNode &before = r->playlist()->get_state();
- r->clear_sync_position ();
- XMLNode &after = r->playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
}
+ begin_reversible_command (_("remove sync"));
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
+ XMLNode &before = (*i)->region()->playlist()->get_state();
+ (*i)->region()->clear_sync_position ();
+ XMLNode &after = (*i)->region()->playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
+ }
commit_reversible_command ();
}
};
void
-Editor::align_selection_relative (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection_relative (RegionPoint point, nframes64_t position, const RegionSelection& rs)
{
if (rs.empty()) {
return;
}
- nframes_t distance = 0;
- nframes_t pos = 0;
+ nframes64_t distance;
+ nframes64_t pos = 0;
int dir = 0;
list<RegionView*> sorted;
rs.by_position (sorted);
+
boost::shared_ptr<Region> r ((*sorted.begin())->region());
switch (point) {
}
void
-Editor::align_selection (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection (RegionPoint point, nframes64_t position, const RegionSelection& rs)
{
if (rs.empty()) {
return;
}
void
-Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
{
begin_reversible_command (_("align region"));
align_region_internal (region, point, position);
}
void
-Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
{
XMLNode &before = region->playlist()->get_state();
}
float speed = 1.0;
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
if (atav->get_diskstream() != 0) {
speed = atav->get_diskstream()->speed();
}
void
-Editor::bounce_range_selection ()
+Editor::bounce_range_selection (bool replace)
{
if (selection->time.empty()) {
return;
TrackSelection views = selection->tracks;
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
- nframes_t cnt = end - start + 1;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
+ nframes64_t cnt = end - start + 1;
begin_reversible_command (_("bounce range"));
itt.cancel = false;
itt.progress = false;
- XMLNode &before = playlist->get_state();
- rtv->track()->bounce_range (start, cnt, itt);
- XMLNode &after = playlist->get_state();
+ XMLNode &before = playlist->get_state();
+ boost::shared_ptr<Region> r = rtv->track()->bounce_range (start, start+cnt, itt);
+
+ if (replace) {
+ list<AudioRange> ranges;
+ ranges.push_back (AudioRange (start, start+cnt, 0));
+ playlist->cut (ranges); // discard result
+ playlist->add_region (r, start);
+ }
+
+ XMLNode &after = playlist->get_state();
session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
}
opname = _("clear");
break;
}
+
+ /* if we're deleting something, and the mouse is still pressed,
+ the thing we started a drag for will be gone when we release
+ the mouse button(s). avoid this. see part 2 at the end of
+ this function.
+ */
+
+ if (op == Cut || op == Clear) {
+ if (drag_info.item) {
+ drag_info.item->ungrab (0);
+ drag_info.item = 0;
+ }
+ }
cut_buffer->clear ();
Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
}
+ break_drag ();
+
return;
}
default:
break;
}
+
+
+ if (op == Cut || op == Clear) {
+ break_drag ();
+ }
}
/** Cut, copy or clear selected automation points.
vector<PlaylistMapping> pmap;
- nframes_t first_position = max_frames;
+ nframes64_t first_position = max_frames;
set<PlaylistState, lt_playlist> freezelist;
pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
- first_position = min ((*x)->region()->position(), first_position);
+ first_position = min ((nframes64_t) (*x)->region()->position(), first_position);
if (op == Cut || op == Clear) {
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
}
void
-Editor::paste_internal (nframes_t position, float times)
+Editor::paste_internal (nframes64_t position, float times)
{
bool commit = false;
Editor::nudge_track (bool use_edit, bool forwards)
{
boost::shared_ptr<Playlist> playlist;
- nframes_t distance;
- nframes_t next_distance;
- nframes_t start;
+ nframes64_t distance;
+ nframes64_t next_distance;
+ nframes64_t start;
if (use_edit) {
start = get_preferred_edit_position();
}
void
-Editor::brush (nframes_t pos)
+Editor::brush (nframes64_t pos)
{
RegionSelection sel;
RegionSelection rs;
}
nframes64_t pos = get_preferred_edit_position();
- nframes_t len;
+ nframes64_t len;
char* cmd;
if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) {
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
set_loop_range (start, end, _("set loop range from selection"));
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
set_punch_range (start, end, _("set punch range from selection"));
}
}
}
}
-
void
Editor::playhead_forward_to_grid ()
{
if (!session) return;
nframes64_t pos = playhead_cursor->current_frame;
- if (pos < max_frames) {
- pos++;
+ if (pos < max_frames - 1) {
+ pos += 2;
snap_to_internal (pos, 1, false);
session->request_locate (pos);
}
{
if (!session) return;
nframes64_t pos = playhead_cursor->current_frame;
- if (pos > 1) {
- pos--;
+ if (pos > 2) {
+ pos -= 2;
snap_to_internal (pos, -1, false);
session->request_locate (pos);
}
}
void
-Editor::set_track_height (TimeAxisView::TrackHeight h)
+Editor::set_track_height (uint32_t h)
{
TrackSelection& ts (selection->tracks);
void
Editor::set_track_height_largest ()
{
- set_track_height (TimeAxisView::Largest);
+ set_track_height (TimeAxisView::hLargest);
}
void
Editor::set_track_height_large ()
{
- set_track_height (TimeAxisView::Large);
+ set_track_height (TimeAxisView::hLarge);
}
void
Editor::set_track_height_larger ()
{
- set_track_height (TimeAxisView::Larger);
+ set_track_height (TimeAxisView::hLarger);
}
void
Editor::set_track_height_normal ()
{
- set_track_height (TimeAxisView::Normal);
+ set_track_height (TimeAxisView::hNormal);
}
void
Editor::set_track_height_smaller ()
{
- set_track_height (TimeAxisView::Smaller);
+ set_track_height (TimeAxisView::hSmaller);
}
void
Editor::set_track_height_small ()
{
- set_track_height (TimeAxisView::Small);
+ set_track_height (TimeAxisView::hSmall);
}
void
RadioButton move_button (group, _("Move"));
RadioButton split_button (group, _("Split & Later Section Moves"));
Label intersect_option_label (_("Intersected regions should:"));
- ToggleButton glue_button (_("Move Glued Regions"));
+ CheckButton glue_button (_("Move Glued Regions"));
+ CheckButton marker_button (_("Move Markers"));
AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
HBox clock_box;
option_box.pack_start (intersect_option_label, false, false);
option_box.pack_start (button_box, false, false);
option_box.pack_start (glue_button, false, false);
+ option_box.pack_start (marker_button, false, false);
button_box.pack_start (leave_button, false, false);
button_box.pack_start (move_button, false, false);
glue_button.show ();
clock.show_all();
clock_box.show ();
+ marker_button.show ();
d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
return;
}
- nframes_t distance = clock.current_duration (pos);
+ nframes64_t distance = clock.current_duration (pos);
if (distance == 0) {
return;
opt = SplitIntersected;
}
- insert_time (pos, distance, opt, glue_button.get_active());
+ insert_time (pos, distance, opt, glue_button.get_active(), marker_button.get_active());
}
-
+
void
-Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, bool ignore_music_glue)
+Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
+ bool ignore_music_glue, bool markers_too)
{
bool commit = false;
commit = true;
}
+ if (markers_too) {
+ bool moved = false;
+ XMLNode& before (session->locations()->get_state());
+ Locations::LocationList copy (session->locations()->list());
+
+ for (Locations::LocationList::iterator i = copy.begin(); i != copy.end(); ++i) {
+
+ Locations::LocationList::const_iterator tmp;
+
+ if ((*i)->start() >= pos) {
+ (*i)->set_start ((*i)->start() + frames);
+ if (!(*i)->is_mark()) {
+ (*i)->set_end ((*i)->end() + frames);
+ }
+ moved = true;
+ }
+ }
+
+ if (moved) {
+ XMLNode& after (session->locations()->get_state());
+ session->add_command (new MementoCommand<Locations>(*session->locations(), &before, &after));
+ }
+ }
+
if (commit) {
commit_reversible_command ();
}
}
+
+void
+Editor::fit_tracks ()
+{
+ if (selection->tracks.empty()) {
+ return;
+ }
+
+ uint32_t child_heights = 0;
+
+ for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
+
+ if (!(*t)->marked_for_display()) {
+ continue;
+ }
+
+ child_heights += ((*t)->effective_height - (*t)->current_height());
+ }
+
+ uint32_t h = (uint32_t) floor ((canvas_height - child_heights)/selection->tracks.size());
+ double first_y_pos = DBL_MAX;
+
+ undo_visual_stack.push_back (current_visual_state());
+
+ for (TrackSelection::iterator t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
+ (*t)->set_height (h);
+ first_y_pos = std::min ((*t)->y_position, first_y_pos);
+ }
+
+
+ vertical_adjustment.set_value (first_y_pos);
+
+ redo_visual_stack.push_back (current_visual_state());
+}
+
+void
+Editor::save_visual_state (uint32_t n)
+{
+ while (visual_states.size() <= n) {
+ visual_states.push_back (0);
+ }
+
+ if (visual_states[n] != 0) {
+ delete visual_states[n];
+ }
+
+ visual_states[n] = current_visual_state (true);
+ gdk_beep ();
+}
+
+void
+Editor::goto_visual_state (uint32_t n)
+{
+ if (visual_states.size() <= n) {
+ return;
+ }
+
+ if (visual_states[n] == 0) {
+ return;
+ }
+
+ use_visual_state (*visual_states[n]);
+}
+
+void
+Editor::start_visual_state_op (uint32_t n)
+{
+ cerr << "Start\n";
+ if (visual_state_op_connection.empty()) {
+ cerr << "\tqueue\n";
+ visual_state_op_connection = Glib::signal_timeout().connect (bind (mem_fun (*this, &Editor::end_visual_state_op), n), 1000);
+ }
+}
+
+void
+Editor::cancel_visual_state_op (uint32_t n)
+{
+ cerr << "Cancel\n";
+ if (!visual_state_op_connection.empty()) {
+ cerr << "\tgoto\n";
+ visual_state_op_connection.disconnect();
+ goto_visual_state (n);
+ }
+}
+
+bool
+Editor::end_visual_state_op (uint32_t n)
+{
+ visual_state_op_connection.disconnect();
+ save_visual_state (n);
+
+ PopUp* pup = new PopUp (WIN_POS_MOUSE, 1000, true);
+ char buf[32];
+ snprintf (buf, sizeof (buf), _("Saved view %u"), n+1);
+ pup->set_text (buf);
+ pup->touch();
+
+ return false; // do not call again
+}
} else if (region->whole_file()) {
+ TreeModel::iterator i;
+ TreeModel::Children rows = region_list_model->children();
+
+ for (i = rows.begin(); i != rows.end(); ++i) {
+
+ boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
+
+ if (region->region_list_equivalent (rr)) {
+ return;
+ }
+ }
+
row = *(region_list_model->append());
if (missing_source) {
c.set_rgb(65535,0,0); // FIXME: error color from style
break;
}
}
+
+ TreeModel::iterator ii;
+ TreeModel::Children subrows = (*i).children();
+
+ for (ii = subrows.begin(); ii != subrows.end(); ++ii) {
+
+ boost::shared_ptr<Region> rrr = (*ii)[region_list_columns.region];
+
+ if (region->region_list_equivalent (rrr)) {
+ return;
+ }
+ }
}
if (!found_parent) {
void
Editor::redisplay_regions ()
{
+ if (no_region_list_redisplay) {
+ return;
+ }
+
if (session) {
region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_gui_changes), what, src));
if (what == "track_height") {
+ /* make tracks change height while it happens, instead
+ of on first-idle
+ */
+ track_canvas->update_now ();
redisplay_route_list ();
}
-}
+ if (what == "visible_tracks") {
+ redisplay_route_list ();
+ }
+}
void
Editor::remove_route (TimeAxisView *tv)
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator ri;
+ if (tv == entered_track) {
+ entered_track = 0;
+ }
+
/* Decrement old order keys for tracks `above' the one that is being removed */
for (ri = rows.begin(); ri != rows.end(); ++ri) {
TimeAxisView* v = (*ri)[route_display_columns.tv];
break;
}
}
+}
+
+void
+Editor::update_route_visibility ()
+{
+ TreeModel::Children rows = route_display_model->children();
+ TreeModel::Children::iterator i;
+
+ no_route_list_redisplay = true;
+ for (i = rows.begin(); i != rows.end(); ++i) {
+ TimeAxisView *tv = (*i)[route_display_columns.tv];
+ (*i)[route_display_columns.visible] = tv->marked_for_display ();
+ }
+
+ no_route_list_redisplay = false;
+ redisplay_route_list ();
}
void
-Editor::hide_track_in_display (TimeAxisView& tv)
+Editor::hide_track_in_display (TimeAxisView& tv, bool temponly)
{
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator i;
for (i = rows.begin(); i != rows.end(); ++i) {
if ((*i)[route_display_columns.tv] == &tv) {
(*i)[route_display_columns.visible] = false;
+ // if (temponly) {
+ tv.set_marked_for_display (false);
+ // }
break;
}
}
redisplay_route_list ();
}
-
void
Editor::route_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
int x, int y,
context->drag_finish (true, false, time);
}
-
RouteTimeAxisView*
Editor::get_route_view_by_id (PBD::ID& id)
{
bool
Editor::ruler_scroll (GdkEventScroll* event)
{
- nframes_t xdelta;
+ nframes64_t xdelta;
int direction = event->direction;
bool handled = false;
/* need to use the correct x,y, the event lies */
time_canvas_event_box.get_window()->get_pointer (x, y, state);
- nframes_t where = leftmost_frame + pixel_to_frame (x);
+ nframes64_t where = leftmost_frame + pixel_to_frame (x);
switch (ev->button) {
case 1:
stop_canvas_autoscroll();
- nframes_t where = leftmost_frame + pixel_to_frame (x);
+ nframes64_t where = leftmost_frame + pixel_to_frame (x);
switch (ev->button) {
case 1:
track_canvas->c2w (x, y, wcx, wcy);
track_canvas->w2c (wcx, wcy, cx, cy);
- nframes_t where = leftmost_frame + pixel_to_frame (x);
+ nframes64_t where = leftmost_frame + pixel_to_frame (x);
/// ripped from maybe_autoscroll, and adapted to work here
- nframes_t rightmost_frame = leftmost_frame + current_page_frames ();
+ nframes64_t rightmost_frame = leftmost_frame + current_page_frames ();
jack_nframes_t frame = pixel_to_frame (cx);
void
-Editor::popup_ruler_menu (nframes_t where, ItemType t)
+Editor::popup_ruler_menu (nframes64_t where, ItemType t)
{
using namespace Menu_Helpers;
time_canvas_event_box.show_all();
time_button_frame.show_all();
- compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes_t)(edit_packer.get_width() * frames_per_unit));
- compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes_t)(edit_packer.get_width() * frames_per_unit));
+ compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
+ compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
redisplay_tempo (false);
}
return;
}
- nframes_t rightmost_frame = leftmost_frame + current_page_frames();
+ nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
if (ruler_timecode_action->get_active()) {
gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_smpte_ruler), leftmost_frame, rightmost_frame,
void
Editor::update_fixed_rulers ()
{
- nframes_t rightmost_frame;
+ nframes64_t rightmost_frame;
if (session == 0) {
return;
void
Editor::set_smpte_ruler_scale (gdouble lower, gdouble upper)
{
- nframes_t range;
- nframes_t spacer;
- nframes_t fr;
+ nframes64_t range;
+ nframes64_t spacer;
+ nframes64_t fr;
if (session == 0) {
return;
fr = session->frame_rate();
- if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else {
lower = 0;
}
upper = upper + spacer;
- range = (nframes_t) floor (upper - lower);
+ range = (nframes64_t) floor (upper - lower);
if (range < (2 * session->frames_per_smpte_frame())) { /* 0 - 2 frames */
smpte_ruler_scale = smpte_show_bits;
} else if (range <= (fr / 4)) { /* 2 frames - 0.250 second */
smpte_ruler_scale = smpte_show_frames;
smpte_mark_modulo = 1;
- smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
} else if (range <= (fr / 2)) { /* 0.25-0.5 second */
smpte_ruler_scale = smpte_show_frames;
smpte_mark_modulo = 2;
- smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
} else if (range <= fr) { /* 0.5-1 second */
smpte_ruler_scale = smpte_show_frames;
smpte_mark_modulo = 5;
- smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
} else if (range <= 2 * fr) { /* 1-2 seconds */
smpte_ruler_scale = smpte_show_frames;
smpte_mark_modulo = 10;
- smpte_nmarks = 2 + (range / (nframes_t)session->frames_per_smpte_frame());
+ smpte_nmarks = 2 + (range / (nframes64_t)session->frames_per_smpte_frame());
} else if (range <= 8 * fr) { /* 2-8 seconds */
smpte_ruler_scale = smpte_show_seconds;
smpte_mark_modulo = 1;
smpte_nmarks = 2 + 24;
} else {
- /* not possible if nframes_t is a 32 bit quantity */
+ /* not possible if nframes64_t is a 32 bit quantity */
smpte_ruler_scale = smpte_show_hours;
smpte_mark_modulo = 4;
Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
{
nframes_t pos;
- nframes_t spacer;
+ nframes64_t spacer;
SMPTE::Time smpte;
gchar buf[16];
gint n;
return 0;
}
- if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else {
lower = 0;
void
-Editor::compute_bbt_ruler_scale (nframes_t lower, nframes_t upper)
+Editor::compute_bbt_ruler_scale (nframes64_t lower, nframes64_t upper)
{
if (session == 0) {
return;
char buf[64];
gint n = 0;
- nframes_t pos;
+ nframes64_t pos;
BBT_Time next_beat;
- nframes_t next_beat_pos;
+ nframes64_t next_beat_pos;
uint32_t beats = 0;
uint32_t tick = 0;
uint32_t skip;
uint32_t t;
- nframes_t frame_skip;
+ nframes64_t frame_skip;
double frame_skip_error;
double bbt_position_of_helper;
double accumulated_error;
next_beat_pos = session->tempo_map().frame_time(next_beat);
- frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
snprintf (buf, sizeof(buf), " ");
(*marks)[n].label = g_strdup (buf);
- /* Error compensation for float to nframes_t*/
+ /* Error compensation for float to nframes64_t*/
accumulated_error += frame_skip_error;
if (accumulated_error > 1) {
pos += 1;
next_beat_pos = session->tempo_map().frame_time(next_beat);
- frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
(*marks)[n].label = g_strdup (buf);
- /* Error compensation for float to nframes_t*/
+ /* Error compensation for float to nframes64_t*/
accumulated_error += frame_skip_error;
if (accumulated_error > 1) {
pos += 1;
next_beat_pos = session->tempo_map().frame_time(next_beat);
- frame_skip = (nframes_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
+ frame_skip = (nframes64_t) floor (frame_skip_error = (session->frame_rate() * 60) / (bbt_beat_subdivision * (*i).tempo->beats_per_minute()));
frame_skip_error -= frame_skip;
skip = (uint32_t) (Meter::ticks_per_beat / bbt_beat_subdivision);
(*marks)[n].label = g_strdup (buf);
- /* Error compensation for float to nframes_t*/
+ /* Error compensation for float to nframes64_t*/
accumulated_error += frame_skip_error;
if (accumulated_error > 1) {
pos += 1;
gint
Editor::metric_get_frames (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
{
- nframes_t mark_interval;
- nframes_t pos;
- nframes_t ilower = (nframes_t) floor (lower);
- nframes_t iupper = (nframes_t) floor (upper);
+ nframes64_t mark_interval;
+ nframes64_t pos;
+ nframes64_t ilower = (nframes64_t) floor (lower);
+ nframes64_t iupper = (nframes64_t) floor (upper);
gchar buf[16];
gint nmarks;
gint n;
}
static void
-sample_to_clock_parts ( nframes_t sample,
- nframes_t sample_rate,
+sample_to_clock_parts ( nframes64_t sample,
+ nframes64_t sample_rate,
long *hrs_p,
long *mins_p,
long *secs_p,
long *millisecs_p)
{
- nframes_t left;
+ nframes64_t left;
long hrs;
long mins;
long secs;
void
Editor::set_minsec_ruler_scale (gdouble lower, gdouble upper)
{
- nframes_t range;
- nframes_t fr;
- nframes_t spacer;
+ nframes64_t range;
+ nframes64_t fr;
+ nframes64_t spacer;
if (session == 0) {
return;
fr = session->frame_rate();
/* to prevent 'flashing' */
- if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
lower -= spacer;
} else {
lower = 0;
}
upper += spacer;
- range = (nframes_t) (upper - lower);
+ range = (nframes64_t) (upper - lower);
if (range < (fr / 50)) {
minsec_mark_interval = fr / 1000; /* show 1/1000 seconds */
minsec_mark_modulo = 2;
} else {
- /* not possible if nframes_t is a 32 bit quantity */
+ /* not possible if nframes64_t is a 32 bit quantity */
minsec_mark_interval = 4 * 60 * 60 * fr; /* show 4 hrs */
}
gint
Editor::metric_get_minsec (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
{
- nframes_t pos;
- nframes_t spacer;
+ nframes64_t pos;
+ nframes64_t spacer;
long hrs, mins, secs, millisecs;
gchar buf[16];
gint n;
}
/* to prevent 'flashing' */
- if (lower > (spacer = (nframes_t)(128 * Editor::get_current_zoom ()))) {
+ if (lower > (spacer = (nframes64_t)(128 * Editor::get_current_zoom ()))) {
lower = lower - spacer;
} else {
lower = 0;
}
*marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * minsec_nmarks);
- pos = ((((nframes_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
+ pos = ((((nframes64_t) floor(lower)) + (minsec_mark_interval/2))/minsec_mark_interval) * minsec_mark_interval;
switch (minsec_ruler_scale) {
case minsec_show_seconds:
for (n = 0; n < minsec_nmarks; pos += minsec_mark_interval, ++n) {
*/
#include <algorithm>
-#include <stdlib.h>
+#include <cstdlib>
#include <pbd/stacktrace.h>
/* select this point and any others that it represents */
double y1, y2;
- nframes_t x1, x2;
+ nframes64_t x1, x2;
x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
} else if (op == Selection::Extend) {
list<Selectable*> results;
- nframes_t last_frame;
- nframes_t first_frame;
+ nframes64_t last_frame;
+ nframes64_t first_frame;
bool same_track = false;
/* 1. find the last selected regionview in the track that was clicked in */
}
bool
-Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
+Editor::select_all_within (nframes64_t start, nframes64_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
{
list<Selectable*> touched;
list<Selectable*>::size_type n = 0;
return;
}
- nframes_t start = selection->time[clicked_selection].start;
- nframes_t end = selection->time[clicked_selection].end;
+ nframes64_t start = selection->time[clicked_selection].start;
+ nframes64_t end = selection->time[clicked_selection].end;
if (end - start < 1) {
return;
void
Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
{
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
list<Selectable *> touched;
if (after) {
void
Editor::select_all_selectables_using_edit (bool after)
{
- nframes_t start;
- nframes_t end;
+ nframes64_t start;
+ nframes64_t end;
list<Selectable *> touched;
if (after) {
}
void
-Editor::mouse_add_new_tempo_event (nframes_t frame)
+Editor::mouse_add_new_tempo_event (nframes64_t frame)
{
if (session == 0) {
return;
}
void
-Editor::mouse_add_new_meter_event (nframes_t frame)
+Editor::mouse_add_new_meter_event (nframes64_t frame)
{
if (session == 0) {
return;
bool realtime = false;
bool precise = false;
bool peaklock = true;
- bool softening = true;
bool longwin = false;
bool shortwin = false;
string txt;
if (realtime) options |= RubberBandStretcher::OptionProcessRealTime;
if (precise) options |= RubberBandStretcher::OptionStretchPrecise;
if (!peaklock) options |= RubberBandStretcher::OptionPhaseIndependent;
- if (!softening) options |= RubberBandStretcher::OptionPhasePeakLocked;
if (longwin) options |= RubberBandStretcher::OptionWindowLong;
if (shortwin) options |= RubberBandStretcher::OptionWindowShort;
} else if (str == _("Playback/Recording on 2 Devices")) {
+ string input_device = get_device_name (driver, input_device_combo.get_active_text());
+ string output_device = get_device_name (driver, output_device_combo.get_active_text());
+
+ if (input_device.empty() || output_device.empty()) {
+ cmd.clear ();
+ return;
+ }
+
cmd.push_back ("-C");
- cmd.push_back (get_device_name (driver, input_device_combo.get_active_text()));
+ cmd.push_back (input_device);
cmd.push_back ("-P");
- cmd.push_back (get_device_name (driver, output_device_combo.get_active_text()));
-
+ cmd.push_back (output_device);
+
} else if (str == _("Playback only")) {
cmd.push_back ("-P");
} else if (str == _("Recording only")) {
if (using_alsa) {
if (audio_mode_combo.get_active_text() != _("Playback/Recording on 2 Devices")) {
+
+ string device = get_device_name (driver, interface_combo.get_active_text());
+ if (device.empty()) {
+ cmd.clear ();
+ return;
+ }
+
cmd.push_back ("-d");
- cmd.push_back (get_device_name (driver, interface_combo.get_active_text()));
+ cmd.push_back (device);
}
if (hw_meter_button.get_active()) {
#ifdef __APPLE__
// note: older versions of the CoreAudio JACK backend use -n instead of -d here
+
+ string device = get_device_name (driver, interface_combo.get_active_text());
+ if (device.empty()) {
+ cmd.clear ();
+ return;
+ }
+
cmd.push_back ("-d");
- cmd.push_back (get_device_name (driver, interface_combo.get_active_text()));
+ cmd.push_back (device);
#endif
} else if (using_oss) {
std::string cwd = "/tmp";
build_command_line (args);
+
+ if (args.empty()) {
+ return 1; // try again
+ }
Glib::ustring jackdrc_path = Glib::get_home_dir();
jackdrc_path += "/.jackdrc";
vector<string>::iterator n;
vector<string>::iterator i;
+ if (human_readable.empty()) {
+ /* this can happen if the user's .ardourrc file has a device name from
+ another computer system in it
+ */
+ MessageDialog msg (_("You need to choose an audio device first."));
+ msg.run ();
+ return string();
+ }
+
if (backend_devs.empty()) {
return human_readable;
}
}
if (i == devices[driver].end()) {
- fatal << string_compose (_("programming error: %1"), "true hardware name for ID missing") << endmsg;
- /*NOTREACHED*/
+ warning << string_compose (_("Audio device \"%1\" not known on this computer."), human_readable) << endmsg;
}
- /* keep gcc happy */
-
return string();
}
progress_connection = Glib::signal_timeout().connect (mem_fun(*this, &ExportDialog::progress_timeout), 100);
cancel_label.set_text (_("Stop Export"));
+ session->pre_export ();
export_data();
-
+
progress_connection.disconnect ();
end_dialog ();
}
}
}
- session->finalize_audio_export ();
+ session->finalize_export ();
hide_all ();
*/
if (file_entry.get_text().length() == 0) {
+
sys::path export_file_path = session->session_directory().export_path();
if (!wants_dir()) {
{
spec.path = filepath;
spec.progress = 0;
- spec.running = true;
+ spec.running = false;
spec.stop = false;
spec.port_map.clear();
spec.start_frame = currentLocation->start();
spec.end_frame = currentLocation->end();
- getSession().request_locate(spec.start_frame, false);
-
if (getSession().start_export(spec)){
// if export fails
return;
}
current_range_marker_index++;
+
+ getSession().stop_export (spec);
}
}
using namespace sigc;
using namespace std;
-sigc::signal<void> GainMeter::ResetAllPeakDisplays;
-sigc::signal<void,RouteGroup*> GainMeter::ResetGroupPeakDisplays;
-Glib::RefPtr<Gdk::Pixbuf> GainMeter::slider;
-Glib::RefPtr<Gdk::Pixbuf> GainMeter::rail;
+sigc::signal<void> GainMeterBase::ResetAllPeakDisplays;
+sigc::signal<void,RouteGroup*> GainMeterBase::ResetGroupPeakDisplays;
+
map<string,Glib::RefPtr<Gdk::Pixmap> > GainMeter::metric_pixmaps;
+Glib::RefPtr<Gdk::Pixbuf> GainMeter::slider;
-int
+
+void
GainMeter::setup_slider_pix ()
{
- slider = ::get_icon ("fader_belt");
- return 0;
+ if ((slider = ::get_icon ("fader_belt")) == 0) {
+ throw failed_constructor();
+ }
}
-GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
+GainMeterBase::GainMeterBase (boost::shared_ptr<IO> io, Session& s,
+ const Glib::RefPtr<Gdk::Pixbuf>& pix,
+ bool horizontal)
: _io (io),
_session (s),
- gain_slider (0),
// 0.781787 is the value needed for gain to be set to 0.
gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1),
gain_automation_style_button (""),
gain_automation_state_button ("")
{
- if (slider == 0) {
- setup_slider_pix ();
- }
-
ignore_toggle = false;
meter_menu = 0;
next_release_selects = false;
style_changed = true;
+ _width = Wide;
- gain_slider = manage (new VSliderController (slider,
- &gain_adjustment,
- *_io->gain_control().get(),
- false));
+ if (horizontal) {
+ gain_slider = manage (new HSliderController (pix,
+ &gain_adjustment,
+ _io->gain_control(),
+ false));
+ } else {
+ gain_slider = manage (new VSliderController (pix,
+ &gain_adjustment,
+ _io->gain_control(),
+ false));
+ }
level_meter = new LevelMeter(_io, _session);
gain_display.signal_focus_in_event().connect (mem_fun (*this, &GainMeter::gain_focused), false);
gain_display.signal_focus_out_event().connect (mem_fun (*this, &GainMeter::gain_focused), false);
- gain_display_box.set_name ("MeterMetricsStrip");
- gain_display_box.set_homogeneous (true);
- gain_display_box.set_spacing (2);
- gain_display_box.pack_start (gain_display, true, true);
-
peak_display.set_name ("MixerStripPeakDisplay");
// peak_display.set_has_frame (false);
// peak_display.set_editable (false);
peak_display.set_label (_("-inf"));
peak_display.unset_flags (Gtk::CAN_FOCUS);
- meter_metric_area.set_name ("MeterMetricsStrip");
- set_size_request_to_display_given_text (meter_metric_area, "-50", 0, 0);
-
gain_automation_style_button.set_name ("MixerAutomationModeButton");
gain_automation_state_button.set_name ("MixerAutomationPlaybackButton");
gain_automation_state_button.set_size_request(15, 15);
gain_automation_style_button.set_size_request(15, 15);
- HBox* fader_centering_box = manage (new HBox);
- fader_centering_box->pack_start (*gain_slider, true, false);
-
- fader_vbox = manage (new Gtk::VBox());
- fader_vbox->set_spacing (0);
- fader_vbox->pack_start (*fader_centering_box, false, false, 0);
- hbox.set_spacing (2);
- if (_io->default_type() == ARDOUR::DataType::AUDIO) {
- hbox.pack_start (*fader_vbox, true, true);
- }
-
- set_width (Narrow);
- Route* r;
- if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+ boost::shared_ptr<Route> r;
- /*
- if we have a non-hidden route (ie. we're not the click or the auditioner),
- pack some route-dependent stuff.
- */
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
- gain_display_box.pack_end (peak_display, true, true);
- hbox.pack_end (*level_meter, true, true);
+ if (!r->is_hidden()) {
- using namespace Menu_Helpers;
-
- gain_astate_menu.items().push_back (MenuElem (_("Manual"),
- bind (mem_fun (*_io, &IO::set_parameter_automation_state),
- Parameter(GainAutomation), (AutoState) Off)));
- gain_astate_menu.items().push_back (MenuElem (_("Play"),
- bind (mem_fun (*_io, &IO::set_parameter_automation_state),
- Parameter(GainAutomation), (AutoState) Play)));
- gain_astate_menu.items().push_back (MenuElem (_("Write"),
- bind (mem_fun (*_io, &IO::set_parameter_automation_state),
- Parameter(GainAutomation), (AutoState) Write)));
- gain_astate_menu.items().push_back (MenuElem (_("Touch"),
- bind (mem_fun (*_io, &IO::set_parameter_automation_state),
- Parameter(GainAutomation), (AutoState) Touch)));
-
- gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
- gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
+ using namespace Menu_Helpers;
- gain_astate_menu.set_name ("ArdourContextMenu");
- gain_astyle_menu.set_name ("ArdourContextMenu");
-
- gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_style_button_event), false);
- gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::gain_automation_state_button_event), false);
-
- r->gain_control()->list()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
- r->gain_control()->list()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
- fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
+ gain_astate_menu.items().push_back (MenuElem (_("Manual"),
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ Parameter(GainAutomation), (AutoState) Off)));
+ gain_astate_menu.items().push_back (MenuElem (_("Play"),
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ Parameter(GainAutomation), (AutoState) Play)));
+ gain_astate_menu.items().push_back (MenuElem (_("Write"),
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ Parameter(GainAutomation), (AutoState) Write)));
+ gain_astate_menu.items().push_back (MenuElem (_("Touch"),
+ bind (mem_fun (*_io, &IO::set_parameter_automation_state),
+ Parameter(GainAutomation), (AutoState) Touch)));
+
+ gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
+ gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
+
+ gain_astate_menu.set_name ("ArdourContextMenu");
+ gain_astyle_menu.set_name ("ArdourContextMenu");
+
+ gain_automation_style_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_style_button_event), false);
+ gain_automation_state_button.signal_button_press_event().connect (mem_fun(*this, &GainMeterBase::gain_automation_state_button_event), false);
+
+ r->gain_control()->list()->automation_state_changed.connect (mem_fun(*this, &GainMeter::gain_automation_state_changed));
+ r->gain_control()->list()->automation_style_changed.connect (mem_fun(*this, &GainMeter::gain_automation_style_changed));
- gain_automation_state_changed ();
+ gain_automation_state_changed ();
+ }
}
- set_spacing (2);
-
- pack_start (gain_display_box, Gtk::PACK_SHRINK);
- pack_start (hbox, Gtk::PACK_SHRINK);
-
- _io->gain_control()->Changed.connect (mem_fun(*this, &GainMeter::gain_changed));
+ _io->gain_control()->Changed.connect (mem_fun(*this, &GainMeterBase::gain_changed));
- meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
- gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeter::gain_adjusted));
- peak_display.signal_button_release_event().connect (mem_fun(*this, &GainMeter::peak_button_release), false);
- gain_display.signal_key_press_event().connect (mem_fun(*this, &GainMeter::gain_key_press), false);
+ gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeterBase::gain_adjusted));
+ peak_display.signal_button_release_event().connect (mem_fun(*this, &GainMeterBase::peak_button_release), false);
+ gain_display.signal_key_press_event().connect (mem_fun(*this, &GainMeterBase::gain_key_press), false);
gain_changed ();
show_gain ();
update_gain_sensitive ();
- ResetAllPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_peak_display));
- ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_group_peak_display));
-
- UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeter::on_theme_changed));
-
- ColorsChanged.connect (bind (mem_fun (*this, &GainMeter::color_handler), false));
- DPIReset.connect (bind (mem_fun (*this, &GainMeter::color_handler), true));
+ ResetAllPeakDisplays.connect (mem_fun(*this, &GainMeterBase::reset_peak_display));
+ ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeterBase::reset_group_peak_display));
- //hide_all();
+ UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeterBase::on_theme_changed));
+ ColorsChanged.connect (bind(mem_fun (*this, &GainMeterBase::color_handler), false));
+ DPIReset.connect (bind(mem_fun (*this, &GainMeterBase::color_handler), true));
}
-void
-GainMeter::set_width (Width w, int len)
-{
- _width = w;
- level_meter->setup_meters (len);
-}
-
-Glib::RefPtr<Gdk::Pixmap>
-GainMeter::render_metrics (Gtk::Widget& w)
-{
- //cerr << "GainMeter::render_metrics() called, red = " << w.get_style()->get_bg(Gtk::STATE_NORMAL).get_red() << endl;//DEBUG
- Glib::RefPtr<Gdk::Window> win (w.get_window());
- Glib::RefPtr<Gdk::GC> fg_gc (w.get_style()->get_fg_gc (Gtk::STATE_NORMAL));
- Glib::RefPtr<Gdk::GC> bg_gc (w.get_style()->get_bg_gc (Gtk::STATE_NORMAL));
- gint width, height;
- int db_points[] = { -50, -40, -20, -30, -10, -3, 0, 4 };
- char buf[32];
-
- win->get_size (width, height);
-
- Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (win, width, height);
-
- metric_pixmaps[w.get_name()] = pixmap;
-
- pixmap->draw_rectangle (bg_gc, true, 0, 0, width, height);
-
- Glib::RefPtr<Pango::Layout> layout = w.create_pango_layout("");
-
- for (uint32_t i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) {
-
- float fraction = log_meter (db_points[i]);
- gint pos = height - (gint) floor (height * fraction);
-
- snprintf (buf, sizeof (buf), "%d", abs (db_points[i]));
-
- layout->set_text (buf);
-
- /* we want logical extents, not ink extents here */
-
- int width, height;
- layout->get_pixel_size (width, height);
-
- pixmap->draw_line (fg_gc, 0, pos, 4, pos);
- pixmap->draw_layout (fg_gc, 6, pos - (height/2), layout);
- }
-
- return pixmap;
-}
-
-gint
-GainMeter::meter_metrics_expose (GdkEventExpose *ev)
-{
- /* Only draw dB scale if we're metering audio */
- if (_io->n_inputs().n_audio() + _io->n_outputs().n_audio() == 0)
- return true;
-
- static Glib::RefPtr<Gtk::Style> meter_style;
-
- if (style_changed) {
- meter_style = meter_metric_area.get_style();
- }
-
- Glib::RefPtr<Gdk::Window> win (meter_metric_area.get_window());
- Glib::RefPtr<Gdk::GC> fg_gc (meter_style->get_fg_gc (Gtk::STATE_NORMAL));
- Glib::RefPtr<Gdk::GC> bg_gc (meter_style->get_bg_gc (Gtk::STATE_NORMAL));
-
- GdkRectangle base_rect;
- GdkRectangle draw_rect;
- gint width, height;
-
- win->get_size (width, height);
-
- base_rect.width = width;
- base_rect.height = height;
- base_rect.x = 0;
- base_rect.y = 0;
-
- Glib::RefPtr<Gdk::Pixmap> pixmap;
- std::map<string,Glib::RefPtr<Gdk::Pixmap> >::iterator i = metric_pixmaps.find (meter_metric_area.get_name());
-
- if (i == metric_pixmaps.end() || style_changed || dpi_changed) {
- pixmap = render_metrics (meter_metric_area);
- } else {
- pixmap = i->second;
- }
-
- gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect);
- win->draw_rectangle (bg_gc, false, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
- win->draw_drawable (fg_gc, pixmap, draw_rect.x, draw_rect.y, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
-
- style_changed = false;
- return true;
-}
-
-void
-GainMeter::on_theme_changed()
-{
- style_changed = true;
-}
-
-GainMeter::~GainMeter ()
+GainMeterBase::~GainMeterBase ()
{
if (meter_menu) {
delete meter_menu;
}
}
+void
+GainMeterBase::hide_all_meters ()
+{
+ level_meter->hide_meters();
+}
+
void
GainMeter::hide_all_meters ()
{
bool remove_metric_area = false;
- level_meter->hide_meters();
+ GainMeterBase::hide_all_meters ();
if (remove_metric_area) {
if (meter_metric_area.get_parent()) {
}
void
+GainMeterBase::setup_meters (int len)
+{
+ level_meter->setup_meters(len, 5);
+}
+
+void
GainMeter::setup_meters (int len)
{
if (!meter_metric_area.get_parent()) {
level_meter->pack_end (meter_metric_area, false, false);
meter_metric_area.show_all ();
}
- level_meter->setup_meters(len, 5);
-}
-
-int
-GainMeter::get_gm_width ()
-{
- Gtk::Requisition sz = hbox.size_request ();
- return sz.width;
+ GainMeterBase::setup_meters (len);
}
bool
-GainMeter::gain_key_press (GdkEventKey* ev)
+GainMeterBase::gain_key_press (GdkEventKey* ev)
{
if (key_is_legal_for_numeric_entry (ev->keyval)) {
/* drop through to normal handling */
}
bool
-GainMeter::peak_button_release (GdkEventButton* ev)
+GainMeterBase::peak_button_release (GdkEventButton* ev)
{
/* reset peak label */
if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier|Keyboard::TertiaryModifier)) {
ResetAllPeakDisplays ();
} else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
- Route* r;
- if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+ boost::shared_ptr<Route> r;
+
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
ResetGroupPeakDisplays (r->mix_group());
}
} else {
}
void
-GainMeter::reset_peak_display ()
+GainMeterBase::reset_peak_display ()
{
- Route * r;
- if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+ boost::shared_ptr<Route> r;
+
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
r->peak_meter().reset_max();
}
}
void
-GainMeter::reset_group_peak_display (RouteGroup* group)
+GainMeterBase::reset_group_peak_display (RouteGroup* group)
{
- Route* r;
- if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+ boost::shared_ptr<Route> r;
+
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
if (group == r->mix_group()) {
reset_peak_display ();
}
}
void
-GainMeter::popup_meter_menu (GdkEventButton *ev)
+GainMeterBase::popup_meter_menu (GdkEventButton *ev)
{
using namespace Menu_Helpers;
}
bool
-GainMeter::gain_focused (GdkEventFocus* ev)
+GainMeterBase::gain_focused (GdkEventFocus* ev)
{
if (ev->in) {
gain_display.select_region (0, -1);
}
void
-GainMeter::gain_activated ()
+GainMeterBase::gain_activated ()
{
float f;
}
void
-GainMeter::show_gain ()
+GainMeterBase::show_gain ()
{
char buf[32];
}
void
-GainMeter::gain_adjusted ()
+GainMeterBase::gain_adjusted ()
{
if (!ignore_toggle) {
_io->gain_control()->set_value (slider_position_to_gain (gain_adjustment.get_value()));
}
void
-GainMeter::effective_gain_display ()
+GainMeterBase::effective_gain_display ()
{
gfloat value = gain_to_slider_position (_io->effective_gain());
}
void
-GainMeter::gain_changed ()
+GainMeterBase::gain_changed ()
{
- Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &GainMeter::effective_gain_display));
+ Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &GainMeterBase::effective_gain_display));
}
void
-GainMeter::set_meter_strip_name (const char * name)
+GainMeterBase::set_meter_strip_name (const char * name)
{
meter_metric_area.set_name (name);
}
void
-GainMeter::set_fader_name (const char * name)
+GainMeterBase::set_fader_name (const char * name)
{
gain_slider->set_name (name);
}
void
-GainMeter::update_gain_sensitive ()
+GainMeterBase::update_gain_sensitive ()
{
static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_control()->list()->automation_state() & Play));
}
}
gint
-GainMeter::meter_press(GdkEventButton* ev)
+GainMeterBase::meter_press(GdkEventButton* ev)
{
- Route* _route;
+ boost::shared_ptr<Route> _route;
wait_for_release = false;
-
- if ((_route = dynamic_cast<Route*>(_io.get())) == 0) {
+
+ if ((_route = boost::dynamic_pointer_cast<Route>(_io)) == 0) {
return FALSE;
}
_session.begin_reversible_command (_("meter point change"));
Session::GlobalMeteringStateCommand *cmd = new Session::GlobalMeteringStateCommand (_session, this);
- _session.foreach_route (this, &GainMeter::set_meter_point, next_meter_point (_route->meter_point()));
+ _session.foreach_route (this, &GainMeterBase::set_meter_point, next_meter_point (_route->meter_point()));
cmd->mark();
_session.add_command (cmd);
_session.commit_reversible_command ();
}
gint
-GainMeter::meter_release(GdkEventButton* ev)
+GainMeterBase::meter_release(GdkEventButton* ev)
{
-
if(!ignore_toggle){
if (wait_for_release){
wait_for_release = false;
- set_meter_point (*(dynamic_cast<Route*>(_io.get())), old_meter_point);
+
+ boost::shared_ptr<Route> r;
+
+ if ((r = boost::dynamic_pointer_cast<Route>(_io)) != 0) {
+ set_meter_point (*r, old_meter_point);
+ }
}
}
+
return true;
}
void
-GainMeter::set_meter_point (Route& route, MeterPoint mp)
+GainMeterBase::set_meter_point (Route& route, MeterPoint mp)
{
route.set_meter_point (mp, this);
}
void
-GainMeter::set_mix_group_meter_point (Route& route, MeterPoint mp)
+GainMeterBase::set_mix_group_meter_point (Route& route, MeterPoint mp)
{
RouteGroup* mix_group;
}
void
-GainMeter::meter_point_clicked ()
+GainMeterBase::meter_point_clicked ()
{
- Route* r;
-
- if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
+ boost::shared_ptr<Route> r;
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
+ /* WHAT? */
}
}
gint
-GainMeter::start_gain_touch (GdkEventButton* ev)
+GainMeterBase::start_gain_touch (GdkEventButton* ev)
{
_io->gain_control()->list()->start_touch ();
return FALSE;
}
gint
-GainMeter::end_gain_touch (GdkEventButton* ev)
+GainMeterBase::end_gain_touch (GdkEventButton* ev)
{
_io->gain_control()->list()->stop_touch ();
return FALSE;
}
gint
-GainMeter::gain_automation_state_button_event (GdkEventButton *ev)
+GainMeterBase::gain_automation_state_button_event (GdkEventButton *ev)
{
if (ev->type == GDK_BUTTON_RELEASE) {
return TRUE;
}
gint
-GainMeter::gain_automation_style_button_event (GdkEventButton *ev)
+GainMeterBase::gain_automation_style_button_event (GdkEventButton *ev)
{
if (ev->type == GDK_BUTTON_RELEASE) {
return TRUE;
}
string
-GainMeter::astate_string (AutoState state)
+GainMeterBase::astate_string (AutoState state)
{
return _astate_string (state, false);
}
string
-GainMeter::short_astate_string (AutoState state)
+GainMeterBase::short_astate_string (AutoState state)
{
return _astate_string (state, true);
}
string
-GainMeter::_astate_string (AutoState state, bool shrt)
+GainMeterBase::_astate_string (AutoState state, bool shrt)
{
string sstr;
}
string
-GainMeter::astyle_string (AutoStyle style)
+GainMeterBase::astyle_string (AutoStyle style)
{
return _astyle_string (style, false);
}
string
-GainMeter::short_astyle_string (AutoStyle style)
+GainMeterBase::short_astyle_string (AutoStyle style)
{
return _astyle_string (style, true);
}
string
-GainMeter::_astyle_string (AutoStyle style, bool shrt)
+GainMeterBase::_astyle_string (AutoStyle style, bool shrt)
{
if (style & Trim) {
return _("Trim");
}
void
-GainMeter::gain_automation_style_changed ()
+GainMeterBase::gain_automation_style_changed ()
{
- // Route* _route = dynamic_cast<Route*>(&_io);
switch (_width) {
case Wide:
gain_automation_style_button.set_label (astyle_string(_io->gain_control()->list()->automation_style()));
}
void
-GainMeter::gain_automation_state_changed ()
+GainMeterBase::gain_automation_state_changed ()
{
- ENSURE_GUI_THREAD(mem_fun(*this, &GainMeter::gain_automation_state_changed));
- //Route* _route = dynamic_cast<Route*>(&_io);
+ ENSURE_GUI_THREAD(mem_fun(*this, &GainMeterBase::gain_automation_state_changed));
bool x;
gain_watching.disconnect();
if (x) {
- gain_watching = ARDOUR_UI::RapidScreenUpdate.connect (mem_fun (*this, &GainMeter::effective_gain_display));
+ gain_watching = ARDOUR_UI::RapidScreenUpdate.connect (mem_fun (*this, &GainMeterBase::effective_gain_display));
}
}
void
-GainMeter::update_meters()
+GainMeterBase::update_meters()
{
char buf[32];
float mpeak = level_meter->update_meters();
}
}
-void GainMeter::color_handler (bool dpi)
+void GainMeterBase::color_handler(bool dpi)
{
color_changed = true;
dpi_changed = (dpi) ? true : false;
setup_meters();
}
+
+void
+GainMeterBase::set_width (Width w, int len)
+{
+ _width = w;
+ level_meter->setup_meters (len);
+}
+
+
+void
+GainMeterBase::on_theme_changed()
+{
+ style_changed = true;
+}
+
+GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
+ : GainMeterBase (io, s, slider, false)
+{
+
+ gain_display_box.set_homogeneous (true);
+ gain_display_box.set_spacing (2);
+ gain_display_box.pack_start (gain_display, true, true);
+
+ meter_metric_area.set_name ("AudioTrackMetrics");
+ set_size_request_to_display_given_text (meter_metric_area, "-50", 0, 0);
+
+ gain_automation_style_button.set_name ("MixerAutomationModeButton");
+ gain_automation_state_button.set_name ("MixerAutomationPlaybackButton");
+
+ ARDOUR_UI::instance()->tooltips().set_tip (gain_automation_state_button, _("Fader automation mode"));
+ ARDOUR_UI::instance()->tooltips().set_tip (gain_automation_style_button, _("Fader automation type"));
+
+ gain_automation_style_button.unset_flags (Gtk::CAN_FOCUS);
+ gain_automation_state_button.unset_flags (Gtk::CAN_FOCUS);
+
+ gain_automation_state_button.set_size_request(15, 15);
+ gain_automation_style_button.set_size_request(15, 15);
+
+ HBox* fader_centering_box = manage (new HBox);
+ fader_centering_box->pack_start (*gain_slider, true, false);
+
+ fader_vbox = manage (new Gtk::VBox());
+ fader_vbox->set_spacing (0);
+ fader_vbox->pack_start (*fader_centering_box, false, false, 0);
+
+ hbox.set_spacing (2);
+ hbox.pack_start (*fader_vbox, true, true);
+
+ boost::shared_ptr<Route> r;
+
+ if ((r = boost::dynamic_pointer_cast<Route> (_io)) != 0) {
+
+ /*
+ if we have a non-hidden route (ie. we're not the click or the auditioner),
+ pack some route-dependent stuff.
+ */
+
+ gain_display_box.pack_end (peak_display, true, true);
+ hbox.pack_end (*level_meter, true, true);
+
+ if (!r->is_hidden()) {
+ fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
+ }
+ }
+
+ set_spacing (2);
+
+ pack_start (gain_display_box, Gtk::PACK_SHRINK);
+ pack_start (hbox, Gtk::PACK_SHRINK);
+
+ meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
+}
+
+
+int
+GainMeter::get_gm_width ()
+{
+ Gtk::Requisition sz;
+ hbox.size_request (sz);
+ return sz.width;
+}
+
+Glib::RefPtr<Gdk::Pixmap>
+GainMeter::render_metrics (Gtk::Widget& w)
+{
+ Glib::RefPtr<Gdk::Window> win (w.get_window());
+ Glib::RefPtr<Gdk::GC> fg_gc (w.get_style()->get_fg_gc (Gtk::STATE_NORMAL));
+ Glib::RefPtr<Gdk::GC> bg_gc (w.get_style()->get_bg_gc (Gtk::STATE_NORMAL));
+ gint width, height;
+ int db_points[] = { -50, -40, -20, -30, -10, -3, 0, 4 };
+ char buf[32];
+
+ win->get_size (width, height);
+
+ Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create (win, width, height);
+
+ metric_pixmaps[w.get_name()] = pixmap;
+
+ pixmap->draw_rectangle (bg_gc, true, 0, 0, width, height);
+
+ Glib::RefPtr<Pango::Layout> layout = w.create_pango_layout("");
+
+ for (uint32_t i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) {
+
+ float fraction = log_meter (db_points[i]);
+ gint pos = height - (gint) floor (height * fraction);
+
+ snprintf (buf, sizeof (buf), "%d", abs (db_points[i]));
+
+ layout->set_text (buf);
+
+ /* we want logical extents, not ink extents here */
+
+ int width, height;
+ layout->get_pixel_size (width, height);
+
+ pixmap->draw_line (fg_gc, 0, pos, 4, pos);
+ pixmap->draw_layout (fg_gc, 6, pos - (height/2), layout);
+ }
+
+ return pixmap;
+}
+
+gint
+GainMeter::meter_metrics_expose (GdkEventExpose *ev)
+{
+ static Glib::RefPtr<Gtk::Style> meter_style;
+ if (style_changed) {
+ meter_style = meter_metric_area.get_style();
+ }
+ Glib::RefPtr<Gdk::Window> win (meter_metric_area.get_window());
+ Glib::RefPtr<Gdk::GC> bg_gc (meter_style->get_bg_gc (Gtk::STATE_INSENSITIVE));
+ GdkRectangle base_rect;
+ GdkRectangle draw_rect;
+ gint width, height;
+
+ win->get_size (width, height);
+
+ base_rect.width = width;
+ base_rect.height = height;
+ base_rect.x = 0;
+ base_rect.y = 0;
+
+ Glib::RefPtr<Gdk::Pixmap> pixmap;
+ std::map<string,Glib::RefPtr<Gdk::Pixmap> >::iterator i = metric_pixmaps.find (meter_metric_area.get_name());
+
+ if (i == metric_pixmaps.end() || style_changed || dpi_changed) {
+ pixmap = render_metrics (meter_metric_area);
+ } else {
+ pixmap = i->second;
+ }
+
+ gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect);
+ win->draw_drawable (bg_gc, pixmap, draw_rect.x, draw_rect.y, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height);
+ style_changed = false;
+ return true;
+}
+
class Menu;
}
-class GainMeter : public Gtk::VBox
+class GainMeterBase : virtual public sigc::trackable
{
public:
- GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
- ~GainMeter ();
+ GainMeterBase (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&, const Glib::RefPtr<Gdk::Pixbuf>& pix,
+ bool horizontal);
+ virtual ~GainMeterBase ();
void update_gain_sensitive ();
-
void update_meters ();
void effective_gain_display ();
-
void set_width (Width, int len=0);
- void setup_meters (int len=0);
-
- int get_gm_width ();
-
void set_meter_strip_name (const char * name);
void set_fader_name (const char * name);
- /* should probably switch to using the shared_ptr that underlies
- all this stuff
- */
+ virtual void setup_meters (int len=0);
- PBD::Controllable* get_controllable() { return _io->gain_control().get(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return _io->gain_control(); }
- private:
+ LevelMeter& get_level_meter() const { return *level_meter; }
+ Gtkmm2ext::SliderController& get_gain_slider() const { return *gain_slider; }
+
+ protected:
friend class MixerStrip;
boost::shared_ptr<ARDOUR::IO> _io;
bool ignore_toggle;
bool next_release_selects;
- Gtkmm2ext::VSliderController *gain_slider;
+ Gtkmm2ext::SliderController *gain_slider;
Gtk::Adjustment gain_adjustment;
Gtkmm2ext::FocusEntry gain_display;
Gtk::Button peak_display;
- Gtk::HBox gain_display_box;
- Gtk::HBox fader_box;
Gtk::DrawingArea meter_metric_area;
- LevelMeter *level_meter;
+ LevelMeter *level_meter;
sigc::connection gain_watching;
Width _width;
- static std::map<std::string,Glib::RefPtr<Gdk::Pixmap> > metric_pixmaps;
- static Glib::RefPtr<Gdk::Pixmap> render_metrics (Gtk::Widget&);
-
- gint meter_metrics_expose (GdkEventExpose *);
-
void show_gain ();
void gain_activated ();
bool gain_focused (GdkEventFocus*);
float max_peak;
- Gtk::VBox* fader_vbox;
- Gtk::HBox hbox;
-
void gain_adjusted ();
void gain_changed ();
void meter_point_clicked ();
void gain_unit_changed ();
- void hide_all_meters ();
+ virtual void hide_all_meters ();
gint meter_button_press (GdkEventButton*, uint32_t);
static sigc::signal<void> ResetAllPeakDisplays;
static sigc::signal<void,ARDOUR::RouteGroup*> ResetGroupPeakDisplays;
- static Glib::RefPtr<Gdk::Pixbuf> slider;
- static Glib::RefPtr<Gdk::Pixbuf> rail;
- static int setup_slider_pix ();
-
void on_theme_changed ();
bool style_changed;
bool dpi_changed;
void color_handler(bool);
};
+class GainMeter : public GainMeterBase, public Gtk::VBox
+{
+ public:
+ GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
+ ~GainMeter () {}
+
+ int get_gm_width ();
+ void setup_meters (int len=0);
+
+ static void setup_slider_pix ();
+
+ protected:
+ void hide_all_meters ();
+
+ gint meter_metrics_expose (GdkEventExpose *);
+
+ static std::map<std::string,Glib::RefPtr<Gdk::Pixmap> > metric_pixmaps;
+ static Glib::RefPtr<Gdk::Pixmap> render_metrics (Gtk::Widget&);
+
+ private:
+ Gtk::HBox gain_display_box;
+ Gtk::HBox fader_box;
+ Gtk::VBox* fader_vbox;
+ Gtk::HBox hbox;
+
+ static Glib::RefPtr<Gdk::Pixbuf> slider;
+};
+
#endif /* __ardour_gtk_gain_meter_h__ */
base_rect = new ArdourCanvas::SimpleRect (*group);
base_rect->property_x1() = (double) 0.0;
base_rect->property_y1() = (double) 0.0;
- base_rect->property_y2() = (double) trackview.height;
+ base_rect->property_y2() = (double) trackview.current_height();
base_rect->property_outline_what() = (guint32) 0;
if (!is_automation_ghost()) {
void
GhostRegion::set_height ()
{
- base_rect->property_y2() = (double) trackview.height;
+ base_rect->property_y2() = (double) trackview.current_height();
}
void
GhostRegion::set_height();
- ht = ((trackview.height) / (double) waves.size());
+ ht = ((trackview.current_height()) / (double) waves.size());
for (n = 0, i = waves.begin(); i != waves.end(); ++i, ++n) {
gdouble yoff = n * ht;
label_view() ;
// set the initial height of this time axis
- set_height(Normal) ;
+ set_height(hNormal) ;
}
/**
/**
* Sets the height of this TrackView to one of ths TrackHeghts
*
- * @param h the TrackHeight value to set
+ * @param h
*/
void
-ImageFrameTimeAxis::set_height (TrackHeight h)
+ImageFrameTimeAxis::set_height (uint32_t h)
{
VisualTimeAxis::set_height(h) ;
/**
* Sets the height of this TrackView to one of ths TrackHeghts
*
- * @param h the TrackHeight value to set
+ * @param h the number of pixels to set the height too
*/
- virtual void set_height(TimeAxisView::TrackHeight) ;
+ virtual void set_height(uint32_t h) ;
/**
* Sets the number of samples per unit that are used.
ImageFrameTimeAxisView::ImageFrameTimeAxisView (ImageFrameTimeAxis& tv)
: _trackview (tv),
canvas_group (*_trackview.canvas_display),
- canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.height)
+ canvas_rect (canvas_group, 0.0, 0.0, 1000000.0, tv.current_height())
{
region_color = _trackview.color() ;
stream_base_color = ARDOUR_UI::config()->canvasvar_ImageTrack.get() ;
//calculate our image width based on the track height
double im_ratio = (double)width/(double)height ;
- double im_width = ((double)(trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ;
+ double im_width = ((double)(trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE) * im_ratio) ;
- imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE));
+ imageframe = new ImageFrame (*group, pbuf, 1.0, 1.0, ANCHOR_NW, im_width, (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE));
frame_handle_start->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_start_handle_event), frame_handle_start, this));
frame_handle_end->signal_event().connect (bind (mem_fun (trackview.editor, &PublicEditor::canvas_imageframe_end_handle_event), frame_handle_end, this));
*/
+#include <gtkmm/messagedialog.h>
#include <glibmm/objectbase.h>
+
#include <gtkmm2ext/doi.h>
+
#include <ardour/port_insert.h>
#include "ardour/session.h"
#include "ardour/io.h"
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/data_type.h"
+
#include "io_selector.h"
#include "utils.h"
#include "gui_thread.h"
#include "i18n.h"
+using namespace ARDOUR;
+using namespace Gtk;
+
IOSelector::IOSelector (ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool offer_inputs)
: PortMatrix (
session, io->default_type(), !offer_inputs,
_io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
}
-#ifdef FIXME
- /* these got lost in a merge from 2.0 */
- set_button_sensitivity ();
- io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
-#endif
+ /* this got lost in a merge from 2.0 */
-}
+ // set_button_sensitivity ();
+ // io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
+}
void
IOSelector::ports_changed (ARDOUR::IOChange change, void *src)
_io->add_input_port ("", this);
}
- catch (ARDOUR::AudioEngine::PortRegistrationFailure& err) {
- Gtk::MessageDialog msg (0, _("There are no more JACK ports available."));
+ catch (AudioEngine::PortRegistrationFailure& err) {
+ MessageDialog msg (_("There are no more JACK ports available."));
msg.run ();
}
_io->add_output_port ("", this);
}
- catch (ARDOUR::AudioEngine::PortRegistrationFailure& err) {
- Gtk::MessageDialog msg (0, _("There are no more JACK ports available."));
+ catch (AudioEngine::PortRegistrationFailure& err) {
+ MessageDialog msg (_("There are no more JACK ports available."));
msg.run ();
}
}
}
-
void
IOSelector::remove_row (int r)
{
return _("port");
}
+#if 0
+void
+IOSelector::set_button_sensitivity ()
+{
+ if (for_input) {
+
+ if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) {
+ add_port_button.set_sensitive (true);
+ } else {
+ add_port_button.set_sensitive (false);
+ }
+
+ } else {
+
+ if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) {
+ add_port_button.set_sensitive (true);
+ } else {
+ add_port_button.set_sensitive (false);
+ }
+
+ }
+
+ if (for_input) {
+ if (io->n_inputs() && (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs())) {
+ remove_port_button.set_sensitive (true);
+ } else {
+ remove_port_button.set_sensitive (false);
+ }
+
+ } else {
+ if (io->n_outputs() && (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs())) {
+ remove_port_button.set_sensitive (true);
+ } else {
+ remove_port_button.set_sensitive (false);
+ }
+ }
+}
+#endif
+#if 0
+void
+IOSelector::name_changed (void* src)
+{
+ ENSURE_GUI_THREAD(bind (mem_fun(*this, &IOSelector::name_changed), src));
+
+ display_ports ();
+}
+#endif
IOSelectorWindow::IOSelectorWindow (
ARDOUR::Session& session, boost::shared_ptr<ARDOUR::IO> io, bool for_input, bool can_cancel
*/
+#include <vector>
#include <ardour/ardour.h>
#include "ardour_ui.h"
#include "keyboard.h"
#include "gui_thread.h"
#include "opts.h"
+#include "actions.h"
#include "i18n.h"
using namespace PBD;
using namespace ARDOUR;
+using namespace Gtk;
+using namespace std;
#define KBD_DEBUG 1
bool debug_keyboard = false;
std::string Keyboard::user_keybindings_path;
bool Keyboard::can_save_keybindings = false;
+bool Keyboard::bindings_changed_after_save_became_legal = false;
map<string,string> Keyboard::binding_files;
-std::string Keyboard::_current_binding_name = _("Unknown");
+string Keyboard::_current_binding_name = _("Unknown");
+map<AccelKey,pair<string,string>,Keyboard::AccelKeyLess> Keyboard::release_keys;
/* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
Keyboard::snooper (GtkWidget *widget, GdkEventKey *event)
{
uint32_t keyval;
+ bool ret = false;
#if 0
cerr << "snoop widget " << widget << " key " << event->keyval << " type: " << event->type
if (find (state.begin(), state.end(), keyval) == state.end()) {
state.push_back (keyval);
sort (state.begin(), state.end());
- }
+
+ } else {
+
+ /* key is already down. if its also used for release,
+ prevent auto-repeat events.
+ */
+
+ for (map<AccelKey,two_strings,AccelKeyLess>::iterator k = release_keys.begin(); k != release_keys.end(); ++k) {
+
+ const AccelKey& ak (k->first);
+
+ if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) {
+ ret = true;
+ break;
+ }
+ }
+ }
} else if (event->type == GDK_KEY_RELEASE) {
sort (state.begin(), state.end());
}
+ for (map<AccelKey,two_strings,AccelKeyLess>::iterator k = release_keys.begin(); k != release_keys.end(); ++k) {
+
+ const AccelKey& ak (k->first);
+ two_strings ts (k->second);
+
+ if (keyval == ak.get_key() && (Gdk::ModifierType)(event->state | Gdk::RELEASE_MASK) == ak.get_mod()) {
+ Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (ts.first.c_str(), ts.second.c_str());
+ if (act) {
+ act->activate();
+ ret = true;
+ }
+ break;
+ }
+ }
}
if (event->type == GDK_KEY_RELEASE && event->keyval == GDK_w && modifier_state_equals (event->state, PrimaryModifier)) {
}
}
- return false;
+ return ret;
}
bool
GdkModifierType mod,
gpointer arg)
{
+ Keyboard::keybindings_changed ();
+}
+
+void
+Keyboard::keybindings_changed ()
+{
+ if (Keyboard::can_save_keybindings) {
+ Keyboard::bindings_changed_after_save_became_legal = true;
+ }
+
Keyboard::save_keybindings ();
}
void
Keyboard::save_keybindings ()
{
- if (can_save_keybindings) {
+ if (can_save_keybindings && bindings_changed_after_save_became_legal) {
Gtk::AccelMap::save (user_keybindings_path);
}
}
}
}
- return true;
} catch (...) {
error << string_compose (_("Ardour key bindings file not found at \"%1\" or contains errors."), path)
<< endmsg;
return false;
}
+
+ /* now find all release-driven bindings */
+
+ vector<string> groups;
+ vector<string> names;
+ vector<AccelKey> bindings;
+
+ ActionManager::get_all_actions (groups, names, bindings);
+
+ vector<string>::iterator g;
+ vector<AccelKey>::iterator b;
+ vector<string>::iterator n;
+
+ release_keys.clear ();
+
+ for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) {
+ if ((*b).get_mod() & Gdk::RELEASE_MASK) {
+ release_keys.insert (pair<AccelKey,two_strings> (*b, two_strings (*g, *n)));
+ }
+ }
+
+ return true;
}
#ifndef __ardour_keyboard_h__
#define __ardour_keyboard_h__
+#include <map>
#include <vector>
#include <string>
#include <sigc++/signal.h>
#include <gtk/gtk.h>
+#include <gtkmm/accelkey.h>
#include <ardour/types.h>
#include <pbd/stateful.h>
#include "selection.h"
-using std::vector;
using std::string;
class Keyboard : public sigc::trackable, PBD::Stateful
XMLNode& get_state (void);
int set_state (const XMLNode&);
- typedef vector<uint32_t> State;
+ typedef std::vector<uint32_t> State;
typedef uint32_t ModifierMask;
static uint32_t PrimaryModifier;
static void magic_widget_drop_focus ();
static void setup_keybindings ();
+ static void keybindings_changed ();
static void save_keybindings ();
static bool load_keybindings (std::string path);
static void set_can_save_keybindings (bool yn);
static std::string current_binding_name () { return _current_binding_name; }
static std::map<std::string,std::string> binding_files;
+ struct AccelKeyLess {
+ bool operator() (const Gtk::AccelKey a, const Gtk::AccelKey b) const {
+ if (a.get_key() != b.get_key()) {
+ return a.get_key() < b.get_key();
+ } else {
+ return a.get_mod() < b.get_mod();
+ }
+ }
+ };
+
private:
static Keyboard* _the_keyboard;
static Gtk::Window* current_window;
static std::string user_keybindings_path;
static bool can_save_keybindings;
+ static bool bindings_changed_after_save_became_legal;
static std::string _current_binding_name;
+ typedef std::pair<std::string,std::string> two_strings;
+
+ static std::map<Gtk::AccelKey,two_strings,AccelKeyLess> release_keys;
+
static gint _snooper (GtkWidget*, GdkEventKey*, gpointer);
gint snooper (GtkWidget*, GdkEventKey*);
#include "actions.h"
#include "keyboard.h"
#include "keyeditor.h"
+#include "utils.h"
#include "i18n.h"
goto out;
}
+ possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);
+
bool result = AccelMap::change_entry (path,
ev->keyval,
(ModifierType) ev->state,
initial_value (_latent.signal_latency()),
sample_rate (sr),
period_size (psz),
+ ignored (new PBD::IgnorableControllable()),
/* max 1 second, step by frames, page by msecs */
adjustment (initial_value, 0.0, sample_rate, 1.0, sample_rate / 1000.0f),
bc (adjustment, ignored, sigc::mem_fun (*this, &LatencyGUI::latency_printer)),
nframes64_t initial_value;
nframes64_t sample_rate;
nframes64_t period_size;
- PBD::IgnorableControllable ignored;
+ boost::shared_ptr<PBD::IgnorableControllable> ignored;
Gtk::Adjustment adjustment;
Gtkmm2ext::BarController bc;
if (mpeak > max_peak) {
max_peak = mpeak;
}
+ if (mpeak > max_peak) {
+ max_peak = mpeak;
+ }
}
}
return max_peak;
{
uint32_t nmeters = _io->n_outputs().n_total();
regular_meter_width = initial_width;
+
guint16 width;
hide_all_meters ();
LocationEditRow::LocationEditRow(Session * sess, Location * loc, int32_t num)
: location(0), session(0),
item_table (1, 7, false),
- start_set_button (_("Set")),
+ start_set_button (_("Use PH")),
start_go_button (_("Go")),
start_clock (X_("locationstart"), true, X_("LocationEditRowClock"), true),
- end_set_button (_("Set")),
+ end_set_button (_("Use PH")),
end_go_button (_("Go")),
end_clock (X_("locationend"), true, X_("LocationEditRowClock"), true),
length_clock (X_("locationlength"), true, X_("LocationEditRowClock"), true, true),
composer_label.set_name ("LocationEditNumberLabel");
composer_entry.set_name ("LocationEditNameEntry");
-
+ ARDOUR_UI::instance()->tooltips().set_tip(start_set_button, _("Set value to Playhead"));
+ ARDOUR_UI::instance()->tooltips().set_tip(end_set_button, _("Set value to Playhead"));
+
isrc_label.set_text ("ISRC: ");
isrc_label.set_size_request (30, -1);
performer_label.set_text ("Performer: ");
start_set_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::set_button_pressed), LocStart));
start_go_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::go_button_pressed), LocStart));
start_clock.ValueChanged.connect (bind (mem_fun (*this, &LocationEditRow::clock_changed), LocStart));
+ start_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocStart));
end_hbox.pack_start (end_go_button, false, false);
end_set_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::set_button_pressed), LocEnd));
end_go_button.signal_clicked().connect(bind (mem_fun (*this, &LocationEditRow::go_button_pressed), LocEnd));
end_clock.ValueChanged.connect (bind (mem_fun (*this, &LocationEditRow::clock_changed), LocEnd));
+ end_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocEnd));
// item_table.attach (length_clock, 3, 4, 0, 1, 0, 0, 4, 0);
length_clock.ValueChanged.connect (bind ( mem_fun(*this, &LocationEditRow::clock_changed), LocLength));
+ length_clock.ChangeAborted.connect (bind (mem_fun (*this, &LocationEditRow::change_aborted), LocLength));
// item_table.attach (cd_check_button, 4, 5, 0, 1, 0, Gtk::FILL, 4, 0);
// item_table.attach (hide_check_button, 5, 6, 0, 1, 0, Gtk::FILL, 4, 0);
}
+void
+LocationEditRow::change_aborted (LocationPart part)
+{
+ if (i_am_the_modifier || !location) return;
+
+ set_location(location);
+}
+
void
LocationEditRow::cd_toggled ()
{
i_am_the_modifier--;
}
+void
+LocationEditRow::focus_name() {
+ name_entry.grab_focus();
+}
+
+
LocationUI::LocationUI ()
: ArdourDialog ("locations dialog"),
add_location_button (_("Add New Location")),
location_rows_scroller.set_name ("LocationLocRowsScroller");
location_rows_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
location_rows_scroller.set_size_request (-1, 130);
+
+ newest_location = 0;
loc_frame_box.set_spacing (5);
loc_frame_box.set_border_width (5);
erow->remove_requested.connect (mem_fun(*this, &LocationUI::location_remove_requested));
erow->redraw_ranges.connect (mem_fun(*this, &LocationUI::location_redraw_ranges));
loc_children.push_back(Box_Helpers::Element(*erow, PACK_SHRINK, 1, PACK_START));
+ if (location == newest_location) {
+ newest_location = 0;
+ erow->focus_name();
+ }
}
else if (location->is_auto_punch()) {
punch_edit_row.set_session (session);
nframes_t where = session->audible_frame();
session->locations()->next_available_name(markername,"mark");
Location *location = new Location (where, where, markername, Location::IsMark);
+ if (Config->get_name_new_markers()) {
+ newest_location = location;
+ }
session->begin_reversible_command (_("add marker"));
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
void set_session (ARDOUR::Session *);
void set_number (int);
+ void focus_name();
sigc::signal<void,ARDOUR::Location*> remove_requested;
sigc::signal<void> redraw_ranges;
void go_button_pressed (LocationPart part);
void clock_changed (LocationPart part);
+ void change_aborted (LocationPart part);
void cd_toggled ();
void hide_toggled ();
private:
ARDOUR::LocationStack* locations;
+ ARDOUR::Location *newest_location;
void session_gone();
actually exists ...
*/
+ try {
+ sys::create_directories (user_config_directory ());
+ }
+ catch (const sys::filesystem_error& ex) {
+ error << _("Could not create user configuration directory") << endmsg;
+ }
+
sys::path pangopath = user_config_directory();
pangopath /= "pango.rc";
path = pangopath.to_string();
std::ofstream pangorc (path.c_str());
if (!pangorc) {
error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
+ return;
} else {
pangorc << "[Pango]\nModuleFiles=";
pangopath /= "pango.modules";
pangorc << pangopath.to_string() << endl;
+
pangorc.close ();
setenv ("PANGO_RC_FILE", path.c_str(), 1);
Pango::FontDescription* font = get_font_for_style (N_("MarkerText"));
text = new Text (*group);
- text->property_text() = annotation.c_str();
text->property_font_desc() = *font;
+ text->property_text() = annotation.c_str();
delete font;
label_view() ;
// set the initial height of this time axis
- set_height(Small) ;
+ set_height(hSmall) ;
}
/**
//---------------------------------------------------------------------------------------//
// ui methods & data
-/**
- * Sets the height of this TrackView to one of the defined TrackHeights
- *
- * @param h the TrackHeight value to set
- */
void
-MarkerTimeAxis::set_height (TrackHeight h)
+MarkerTimeAxis::set_height (uint32_t h)
{
VisualTimeAxis::set_height(h) ;
/**
* Sets the height of this TrackView to one of the defined TrackHeights
*
- * @param h the TrackHeight value to set
+ * @param h the number of pixels to set the height to
*/
- virtual void set_height(TimeAxisView::TrackHeight h) ;
+ virtual void set_height(uint32_t h) ;
/**
* Sets the number of samples per unit that are used.
}
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
- : RegionView (parent, tv, r, spu, basic_color, visibility)
+ : RegionView (parent, tv, r, spu, basic_color, false, visibility)
, _force_channel(-1)
, _last_channel_selection(0xFFFF)
, _default_note_length(0.0)
reset_width_dependent_items ((double) _region->length() / samples_per_unit);
- set_y_position_and_height (0, trackview.height);
+ set_y_position_and_height (0, trackview.current_height());
region_muted ();
region_resized (BoundsChanged);
static double drag_start_x, drag_start_y;
static double last_x, last_y;
double event_x, event_y;
- nframes_t event_frame = 0;
+ nframes64_t event_frame = 0;
static ArdourCanvas::SimpleRect* drag_rect = NULL;
assert(note >= 0.0);
assert(note <= 127.0);
- nframes_t new_note_time = trackview.editor.pixel_to_frame (x);
+ nframes64_t new_note_time = trackview.editor.pixel_to_frame (x);
assert(new_note_time >= 0);
new_note_time += _region->start();
double duration = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
*/
- // we need to snap here again in nframes_t in order to be sample accurate
+ // we need to snap here again in nframes64_t in order to be sample accurate
// since note time is region-absolute but snap_to_frame expects position-relative
// time we have to coordinate transform back and forth here.
- nframes_t new_note_time_position_relative = new_note_time - _region->start();
+ nframes64_t new_note_time_position_relative = new_note_time - _region->start();
new_note_time = snap_to_frame(new_note_time_position_relative) + _region->start();
// we need to snap the duration too to be sample accurate
- nframes_t new_note_duration = nframes_t(duration);
+ nframes64_t new_note_duration = nframes_t(duration);
new_note_duration = snap_to_frame(new_note_time_position_relative + new_note_duration) + _region->start()
- new_note_time;
note->property_y2() = y2;
}
if (CanvasHit* hit = dynamic_cast<CanvasHit*>(event)) {
- double x = trackview.editor.frame_to_pixel((nframes_t)
+ double x = trackview.editor.frame_to_pixel((nframes64_t)
event->note()->time() - _region->start());
const double diamond_size = midi_stream_view()->note_height() / 2.0;
double y = midi_stream_view()->note_to_y(event->note()->note())
return;
if (_active_notes && _active_notes[note]) {
- _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes_t)end_time);
+ _active_notes[note]->property_x2() = trackview.editor.frame_to_pixel((nframes64_t)end_time);
_active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
_active_notes[note] = NULL;
}
CanvasNoteEvent* event = 0;
- const double x = trackview.editor.frame_to_pixel((nframes_t)note->time() - _region->start());
+ const double x = trackview.editor.frame_to_pixel((nframes64_t)note->time() - _region->start());
if (midi_view()->note_mode() == Sustained) {
const double y1 = midi_stream_view()->note_to_y(note->note());
const double note_endpixel =
- trackview.editor.frame_to_pixel((nframes_t)note->end_time() - _region->start());
+ trackview.editor.frame_to_pixel((nframes64_t)note->end_time() - _region->start());
CanvasNote* ev_rect = new CanvasNote(*this, *group, note);
ev_rect->property_x1() = x;
return;
ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
- const double x = trackview.editor.frame_to_pixel((nframes_t)event->time() - _region->start());
+ const double x = trackview.editor.frame_to_pixel((nframes64_t)event->time() - _region->start());
double height = midi_stream_view()->contents_height();
_pgm_changes.push_back(
const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get()));
- // we need to snap here again in nframes_t in order to be sample accurate
+ // we need to snap here again in nframes64_t in order to be sample accurate
double new_note_time = (*i)->note()->time();
new_note_time += dt;
// since note time is region-absolute but snap_to_frame expects position-relative
// time we have to coordinate transform back and forth here.
- new_note_time = snap_to_frame(nframes_t(new_note_time) - _region->start()) + _region->start();
+ new_note_time = snap_to_frame(nframes64_t(new_note_time) - _region->start()) + _region->start();
copy->set_time(new_note_time);
}
}
-nframes_t
+nframes64_t
MidiRegionView::snap_to_frame(double x)
{
PublicEditor &editor = trackview.editor;
// x is region relative
// convert x to global frame
- nframes_t frame = editor.pixel_to_frame(x) + _region->position();
+ nframes64_t frame = editor.pixel_to_frame(x) + _region->position();
editor.snap_to(frame);
// convert event_frame back to local coordinates relative to position
frame -= _region->position();
return frame;
}
-nframes_t
-MidiRegionView::snap_to_frame(nframes_t x)
+nframes64_t
+MidiRegionView::snap_to_frame(nframes64_t x)
{
PublicEditor &editor = trackview.editor;
// x is region relative
// convert x to global frame
- nframes_t frame = x + _region->position();
+ nframes64_t frame = x + _region->position();
editor.snap_to(frame);
// convert event_frame back to local coordinates relative to position
frame -= _region->position();
double
MidiRegionView::get_position_pixels(void)
{
- nframes_t region_frame = get_position();
+ nframes64_t region_frame = get_position();
return trackview.editor.frame_to_pixel(region_frame);
}
// because snapping works on world coordinates we have to transform current_x
// to world coordinates before snapping and transform it back afterwards
- nframes_t current_frame = snap_to_frame(current_x);
+ nframes64_t current_frame = snap_to_frame(current_x);
// transform to region start relative
current_frame += _region->start();
/**
* This function provides the snap function for region position relative coordinates
- * for pixel units (double) instead of nframes_t
+ * for pixel units (double) instead of nframes64_t
* @param x a pixel coordinate relative to region start
* @return the snapped pixel coordinate relative to region start
*/
/**
* This function provides the snap function for region position relative coordinates
- * for pixel units (double) instead of nframes_t
+ * for pixel units (double) instead of nframes64_t
* @param x a pixel coordinate relative to region start
- * @return the snapped nframes_t coordinate relative to region start
+ * @return the snapped nframes64_t coordinate relative to region start
*/
- nframes_t snap_to_frame(double x);
+ nframes64_t snap_to_frame(double x);
/**
* This function provides the snap function for region position relative coordinates
* @param x a pixel coordinate relative to region start
- * @return the snapped nframes_t coordinate relative to region start
+ * @return the snapped nframes64_t coordinate relative to region start
*/
- nframes_t snap_to_frame(nframes_t x);
+ nframes64_t snap_to_frame(nframes64_t x);
protected:
RegionView*
-MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd)
+MidiStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wfd, bool recording)
{
boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion> (r);
rec_rect->property_x1() = xstart;
rec_rect->property_y1() = 1.0;
rec_rect->property_x2() = xend;
- rec_rect->property_y2() = (double) _trackview.height - 1;
+ rec_rect->property_y2() = (double) _trackview.current_height() - 1;
rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_RecordingRect.get();
rec_rect->property_fill_color_rgba() = fill_color;
rec_rect->lower_to_bottom();
void redisplay_diskstream ();
inline double contents_height() const
- { return (_trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
+ { return (_trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE - 2); }
inline double note_to_y(uint8_t note) const
{ return contents_height()
void rec_data_range_ready (jack_nframes_t start, jack_nframes_t dur, boost::weak_ptr<ARDOUR::Source> src);
void update_rec_regions (boost::shared_ptr<ARDOUR::MidiModel> data, jack_nframes_t start, jack_nframes_t dur);
- RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
+ RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false);
void display_region(MidiRegionView* region_view, bool load_model);
void display_diskstream (boost::shared_ptr<ARDOUR::Diskstream> ds);
void
MidiTimeAxisView::channel_selector_toggled()
{
- static TimeAxisView::TrackHeight previous_height;
+ static uint32_t previous_height;
if(_midi_expander.property_expanded()) {
- previous_height = height_style;
- if(previous_height != TimeAxisView::Largest) {
- set_height(TimeAxisView::Large);
+
+ previous_height = current_height();
+
+ if (previous_height < TimeAxisView::hLargest) {
+ set_height (TimeAxisView::hLarge);
}
+
} else {
- set_height(previous_height);
+
+ set_height (previous_height);
}
}
MenuList& citems = input_menu.items();
- if (b->nchannels() == _route->n_inputs().n_total()) {
+ if (b->nchannels() == _route->n_inputs()) {
citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_input_chosen), b)));
return;
}
- if (b->nchannels() == _route->n_outputs().n_total()) {
+ if (b->nchannels() == _route->n_outputs()) {
MenuList& citems = output_menu.items();
citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_output_chosen), b)));
break;
}
}
-
hide_redirect_editors ();
}
}
gpm.setup_meters ();
+ // reset peak when meter point changes
+ gpm.reset_peak_display();
set_width(_width, this);
}
signal_configure_event().connect (mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
_selection.RoutesChanged.connect (mem_fun(*this, &Mixer_UI::follow_strip_selection));
-
+
mix_group_display_button_box->show();
mix_group_add_button->show();
mix_group_remove_button->show();
pos++;
}
- PBD::Controllable::CreateBinding ( strip->solo_button->get_controllable(), controlValue, 0);
- PBD::Controllable::CreateBinding ( strip->mute_button->get_controllable(), controlValue, 1);
+ PBD::Controllable::CreateBinding ( strip->solo_button->get_controllable().get(), controlValue, 0);
+ PBD::Controllable::CreateBinding ( strip->mute_button->get_controllable().get(), controlValue, 1);
if( strip->is_audio_track() ) {
- PBD::Controllable::CreateBinding ( strip->rec_enable_button->get_controllable(), controlValue, 2);
+ PBD::Controllable::CreateBinding ( strip->rec_enable_button->get_controllable().get(), controlValue, 2);
}
- PBD::Controllable::CreateBinding ( strip->gpm.get_controllable(), controlValue, 3);
- PBD::Controllable::CreateBinding ( strip->panners.get_controllable(), controlValue, 4);
+ PBD::Controllable::CreateBinding ( strip->gpm.get_controllable().get(), controlValue, 3);
+ PBD::Controllable::CreateBinding ( strip->panners.get_controllable().get(), controlValue, 4);
}
else { // Remove any existing binding
- PBD::Controllable::DeleteBinding ( strip->solo_button->get_controllable() );
- PBD::Controllable::DeleteBinding ( strip->mute_button->get_controllable() );
+ PBD::Controllable::DeleteBinding ( strip->solo_button->get_controllable().get() );
+ PBD::Controllable::DeleteBinding ( strip->mute_button->get_controllable().get() );
if( strip->is_audio_track() ) {
- PBD::Controllable::DeleteBinding ( strip->rec_enable_button->get_controllable() );
+ PBD::Controllable::DeleteBinding ( strip->rec_enable_button->get_controllable().get() );
}
- PBD::Controllable::DeleteBinding ( strip->gpm.get_controllable() );
- PBD::Controllable::DeleteBinding ( strip->panners.get_controllable() ); // This only takes the first panner if there are multiples...
+ PBD::Controllable::DeleteBinding ( strip->gpm.get_controllable().get() );
+ PBD::Controllable::DeleteBinding ( strip->panners.get_controllable().get() ); // This only takes the first panner if there are multiples...
}
} // for
}
-
struct SignalOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
(gtk_accel_path "<Actions>/Common/Save" "<%PRIMARY%>s")
(gtk_accel_path "<Actions>/Editor/duplicate-region" "d")
(gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<%PRIMARY%>d")
-(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f")
+(gtk_accel_path "<Actions>/Editor/fit-tracks" "f")
+(gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "<%PRIMARY%>f")
(gtk_accel_path "<Actions>/Editor/toggle-rhythm-ferret" "<%WINDOW%>f")
(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g")
(gtk_accel_path "<Actions>/Editor/play-selected-regions" "h")
;; HOME ROW
+<<<<<<< .working
(gtk_accel_path "<Actions>/Editor/zoom-to-region" "<%SECONDARY%>z")
+=======
+(gtk_accel_path "<Actions>/Editor/zoom-to-region" "<%PRIMARY%><%SECONDARY%>z")
+(gtk_accel_path "<Actions>/Editor/zoom-to-region-both-axes" "<%SECONDARY%>z")
+>>>>>>> .merge-right.r3622
(gtk_accel_path "<Actions>/Editor/undo" "<%PRIMARY%>z")
(gtk_accel_path "<Actions>/Editor/toggle-zoom" "<%TERTIARY%>z")
+<<<<<<< .working
(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-note" "n")
+=======
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-zoom" "z")
+>>>>>>> .merge-right.r3622
(gtk_accel_path "<Actions>/Editor/editor-cut" "<%PRIMARY%>x")
(gtk_accel_path "<Actions>/Editor/editor-copy" "<%PRIMARY%>c")
(gtk_accel_path "<Actions>/Common/ToggleColorManager" "<%WINDOW%>c")
(gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F6")
(gtk_accel_path "<Actions>/Common/ToggleMaximalEditor" "F11")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-1" "<%PRIMARY%>F1")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-2" "<%PRIMARY%>F2")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-3" "<%PRIMARY%>F3")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-4" "<%PRIMARY%>F4")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-5" "<%PRIMARY%>F5")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-6" "<%PRIMARY%>F6")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-7" "<%PRIMARY%>F7")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-8" "<%PRIMARY%>F8")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-9" "<%PRIMARY%>F9")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-10" "<%PRIMARY%>F10")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-11" "<%PRIMARY%>F11")
+(gtk_accel_path "<Actions>/Editor/save-visual-state-12" "<%PRIMARY%>F12")
+
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-1" "<release><%PRIMARY%>F1")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-2" "<release><%PRIMARY%>F2")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-3" "<release><%PRIMARY%>F3")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-4" "<release><%PRIMARY%>F4")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-5" "<release><%PRIMARY%>F5")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-6" "<release><%PRIMARY%>F6")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-7" "<release><%PRIMARY%>F7")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-8" "<release><%PRIMARY%>F8")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-9" "<release><%PRIMARY%>F9")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-10" "<release><%PRIMARY%>F10")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-11" "<release><%PRIMARY%>F11")
+(gtk_accel_path "<Actions>/Editor/goto-visual-state-12" "<release><%PRIMARY%>F12")
+
+
;; numbers
(gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1")
{
using namespace Notebook_Helpers;
+ first_click_setup = true;
click_io_selector = 0;
auditioner_io_selector = 0;
session = 0;
OptionEditor::clear_click_editor ()
{
if (click_io_selector) {
- click_packer.remove (*click_io_selector);
- click_packer.remove (*click_gpm);
+ click_hpacker.remove (*click_io_selector);
+ click_hpacker.remove (*click_gpm);
delete click_io_selector;
delete click_gpm;
click_io_selector = 0;
OptionEditor::setup_click_editor ()
{
Label* label;
- HBox* hpacker = manage (new HBox);
+
+ if (first_click_setup) {
+
+ click_path_entry.set_name ("OptionsEntry");
+ click_emphasis_path_entry.set_name ("OptionsEntry");
+
+ click_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_sound_changed));
+ click_emphasis_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_emphasis_sound_changed));
+
+ click_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_sound_changed));
+ click_emphasis_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_emphasis_sound_changed));
+
+ click_browse_button.set_name ("EditorGTKButton");
+ click_emphasis_browse_button.set_name ("EditorGTKButton");
+
+ click_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_browse_clicked));
+ click_emphasis_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_emphasis_browse_clicked));
+
+ click_packer.set_border_width (12);
+ click_packer.set_spacing (5);
+
+ click_table.set_col_spacings (10);
+
+ label = manage(new Label(_("Click audio file")));
+ label->set_name ("OptionsLabel");
+ click_table.attach (*label, 0, 1, 0, 1, FILL|EXPAND, FILL);
+ click_table.attach (click_path_entry, 1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, FILL);
+ click_table.attach (click_browse_button, 2, 3, 0, 1, FILL|EXPAND, FILL);
+
+ label = manage(new Label(_("Click emphasis audiofile")));
+ label->set_name ("OptionsLabel");
+ click_table.attach (*label, 0, 1, 1, 2, FILL|EXPAND, FILL);
+ click_table.attach (click_emphasis_path_entry, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, FILL);
+ click_table.attach (click_emphasis_browse_button, 2, 3, 1, 2, FILL|EXPAND, FILL);
+
+ click_packer.pack_start (click_table, false, false);
+ click_packer.pack_start (click_hpacker, false, false);
+
+
+ click_hpacker.set_spacing (10);
+
+ first_click_setup = false;
+ }
click_path_entry.set_sensitive (true);
click_emphasis_path_entry.set_sensitive (true);
- click_path_entry.set_name ("OptionsEntry");
- click_emphasis_path_entry.set_name ("OptionsEntry");
-
- click_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_sound_changed));
- click_emphasis_path_entry.signal_activate().connect (mem_fun(*this, &OptionEditor::click_emphasis_sound_changed));
-
- click_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_sound_changed));
- click_emphasis_path_entry.signal_focus_out_event().connect (bind (mem_fun(*this, &OptionEditor::focus_out_event_handler), &OptionEditor::click_emphasis_sound_changed));
-
- click_browse_button.set_name ("EditorGTKButton");
- click_emphasis_browse_button.set_name ("EditorGTKButton");
- click_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_browse_clicked));
- click_emphasis_browse_button.signal_clicked().connect (mem_fun(*this, &OptionEditor::click_emphasis_browse_clicked));
-
- click_packer.set_border_width (12);
- click_packer.set_spacing (5);
-
click_io_selector = new IOSelector (*session, session->click_io(), false);
click_gpm = new GainMeter (session->click_io(), *session);
+ click_hpacker.pack_start (*click_io_selector, false, false);
+ click_hpacker.pack_start (*click_gpm, false, false);
+
click_table.set_col_spacings (10);
label = manage(new Label(_("Click audio file")));
click_table.attach (click_emphasis_path_entry, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, FILL);
click_table.attach (click_emphasis_browse_button, 2, 3, 1, 2, FILL|EXPAND, FILL);
- hpacker->set_spacing (10);
- hpacker->pack_start (*click_io_selector, false, false);
- hpacker->pack_start (*click_gpm, false, false);
-
- click_packer.pack_start (click_table, false, false);
- click_packer.pack_start (*hpacker, false, false);
-
click_packer.show_all ();
}
IOSelector* click_io_selector;
GainMeter* click_gpm;
PannerUI* click_panner;
+ bool first_click_setup;
+ Gtk::HBox click_hpacker;
Gtk::VBox click_packer;
Gtk::Table click_table;
Gtk::Entry click_path_entry;
PannerBar::PannerBar (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
- : BarController (adj, *c.get(), sigc::ptr_fun (null_label_callback))
+ : BarController (adj, c, sigc::ptr_fun (null_label_callback))
{
set_style (BarController::Line);
}
#include <cmath>
#include <climits>
-#include <string.h>
+#include <cstring>
#include <gtkmm/menu.h>
#include <gtkmm/checkmenuitem.h>
show();
}
-PBD::Controllable*
+boost::shared_ptr<PBD::Controllable>
PannerUI::get_controllable()
{
return pan_bars[0]->get_controllable();
void effective_pan_display ();
void set_meter_strip_name (string name);
- PBD::Controllable* get_controllable();
+ boost::shared_ptr<PBD::Controllable> get_controllable();
private:
friend class MixerStrip;
--- /dev/null
+/*
+ Copyright (C) 2008 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 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.
+
+*/
+
+#ifndef __gtkardour_plugin_interest_h__
+#define __gtkardour_plugin_interest_h__
+
+#include <vector>
+#include <ardour/plugin.h>
+
+typedef std::vector<ARDOUR::PluginPtr> SelectedPlugins;
+
+class PluginInterestedObject {
+ public:
+ PluginInterestedObject() {}
+ virtual ~PluginInterestedObject() {}
+
+ virtual void use_plugins (const SelectedPlugins&) = 0;
+};
+
+#endif /* __gtkardour_plugin_interest_h__ */
#include <cstdio>
#include <lrdf.h>
+#include <map>
#include <algorithm>
N_("Type contains"),
N_("Author contains"),
N_("Library contains"),
+ N_("Favorites only"),
0
};
manager = mgr;
session = 0;
-
+ _menu = 0;
+ in_row_change = false;
+
plugin_model = Gtk::ListStore::create (plugin_columns);
plugin_display.set_model (plugin_model);
+ /* XXX translators: try to convert "Fav" into a short term
+ related to "favorite"
+ */
+ plugin_display.append_column (_("Fav"), plugin_columns.favorite);
plugin_display.append_column (_("Available Plugins"), plugin_columns.name);
plugin_display.append_column (_("Type"), plugin_columns.type_name);
plugin_display.append_column (_("Category"), plugin_columns.category);
plugin_display.set_headers_visible (true);
plugin_display.set_headers_clickable (true);
plugin_display.set_reorderable (false);
+ plugin_display.set_rules_hint (true);
+
+ CellRendererToggle* fav_cell = dynamic_cast<CellRendererToggle*>(plugin_display.get_column_cell_renderer (0));
+ fav_cell->property_activatable() = true;
+ fav_cell->property_radio() = false;
+ fav_cell->signal_toggled().connect (mem_fun (*this, &PluginSelector::favorite_changed));
+
scroller.set_border_width(10);
scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
scroller.add(plugin_display);
std::string compstr;
std::string mode = filter_mode.get_active_text ();
+ if (mode == _("Favorites only")) {
+ return manager->is_a_favorite_plugin (info);
+ }
+
if (!filterstr.empty()) {
if (mode == _("Name contains")) {
compstr = info->creator;
} else if (mode == _("Library contains")) {
compstr = info->path;
- }
-
+ }
+
transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper);
if (compstr.find (filterstr) != string::npos) {
} else {
return false;
}
-
}
return true;
{
std::string filterstr;
+ in_row_change = true;
+
plugin_model->clear ();
setup_filter_string (filterstr);
lv2_refiller (filterstr);
vst_refiller (filterstr);
au_refiller (filterstr);
+
+ in_row_change = false;
}
void
if (show_this_plugin (*i, filterstr)) {
TreeModel::Row newrow = *(plugin_model->append());
+ newrow[plugin_columns.favorite] = manager->is_a_favorite_plugin (*i);
newrow[plugin_columns.name] = (*i)->name;
newrow[plugin_columns.type_name] = type;
newrow[plugin_columns.category] = (*i)->category;
-
string creator = (*i)->creator;
string::size_type pos = 0;
#endif
}
-void
-PluginSelector::use_plugin (PluginInfoPtr pi)
+PluginPtr
+PluginSelector::load_plugin (PluginInfoPtr pi)
{
if (session == 0) {
- return;
+ return PluginPtr();
}
- PluginPtr plugin = pi->load (*session);
-
- if (plugin) {
- PluginCreated (plugin);
- }
+ return pi->load (*session);
}
void
{
ResponseType r;
TreeModel::Children::iterator i;
+ SelectedPlugins plugins;
r = (ResponseType) Dialog::run ();
case RESPONSE_APPLY:
for (i = amodel->children().begin(); i != amodel->children().end(); ++i) {
PluginInfoPtr pp = (*i)[acols.plugin];
- use_plugin (pp);
+ PluginPtr p = load_plugin (pp);
+ if (p) {
+ plugins.push_back (p);
+ }
+ }
+ if (interested_object && !plugins.empty()) {
+ interested_object->use_plugins (plugins);
}
+
break;
default:
break;
}
- cleanup ();
-
- return (int) r;
-}
-
-void
-PluginSelector::cleanup ()
-{
hide();
amodel->clear();
+ interested_object = 0;
+
+ return (int) r;
}
void
void
PluginSelector::filter_mode_changed ()
{
+ std::string mode = filter_mode.get_active_text ();
+
+ if (mode == _("Favorites only")) {
+ filter_entry.set_sensitive (false);
+ } else {
+ filter_entry.set_sensitive (true);
+ }
+
refill ();
}
ArdourDialog::on_show ();
filter_entry.grab_focus ();
}
+
+struct PluginMenuCompare {
+ bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
+ int cmp;
+
+ cmp = strcasecmp (a->creator.c_str(), b->creator.c_str());
+
+ if (cmp < 0) {
+ return true;
+ } else if (cmp == 0) {
+ /* same creator ... compare names */
+ if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+Gtk::Menu&
+PluginSelector::plugin_menu()
+{
+ using namespace Menu_Helpers;
+
+ typedef std::map<Glib::ustring,Gtk::Menu*> SubmenuMap;
+ SubmenuMap submenu_map;
+
+ if (!_menu) {
+ _menu = new Menu();
+ _menu->set_name("ArdourContextMenu");
+ }
+
+ MenuList& items = _menu->items();
+ Menu* favs = new Menu();
+ favs->set_name("ArdourContextMenu");
+
+ items.clear ();
+ items.push_back (MenuElem (_("Favorites"), *favs));
+ items.push_back (MenuElem (_("Plugin Manager"), mem_fun (*this, &PluginSelector::show_manager)));
+ items.push_back (SeparatorElem ());
+
+ PluginInfoList all_plugs;
+
+ all_plugs.insert (all_plugs.end(), manager->ladspa_plugin_info().begin(), manager->ladspa_plugin_info().end());
+#ifdef VST_SUPPORT
+ all_plugs.insert (all_plugs.end(), manager->vst_plugin_info().begin(), manager->vst_plugin_info().end());
+#endif
+#ifdef HAVE_AUDIOUNITS
+ all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end());
+#endif
+#ifdef HAVE_SLV2
+ all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end());
+#endif
+
+ PluginMenuCompare cmp;
+ all_plugs.sort (cmp);
+
+ for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
+ SubmenuMap::iterator x;
+ Gtk::Menu* submenu;
+
+ string creator = (*i)->creator;
+ string::size_type pos = 0;
+
+ if (manager->is_a_favorite_plugin (*i)) {
+ favs->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
+ }
+
+ /* stupid LADSPA creator strings */
+
+ while (pos < creator.length() && (isalnum (creator[pos]) || isspace (creator[pos]))) ++pos;
+ creator = creator.substr (0, pos);
+
+ if ((x = submenu_map.find (creator)) != submenu_map.end()) {
+ submenu = x->second;
+ } else {
+ submenu = new Gtk::Menu;
+ items.push_back (MenuElem (creator, *submenu));
+ submenu_map.insert (pair<Glib::ustring,Menu*> (creator, submenu));
+ submenu->set_name("ArdourContextMenu");
+ }
+
+ submenu->items().push_back (MenuElem ((*i)->name, (bind (mem_fun (*this, &PluginSelector::plugin_chosen_from_menu), *i))));
+ }
+
+ return *_menu;
+}
+
+void
+PluginSelector::plugin_chosen_from_menu (const PluginInfoPtr& pi)
+{
+ PluginPtr p = load_plugin (pi);
+
+ if (p && interested_object) {
+ SelectedPlugins plugins;
+ plugins.push_back (p);
+ interested_object->use_plugins (plugins);
+ }
+
+ interested_object = 0;
+}
+
+void
+PluginSelector::favorite_changed (const Glib::ustring& path)
+{
+ PluginInfoPtr pi;
+
+ if (in_row_change) {
+ return;
+ }
+
+ in_row_change = true;
+
+ TreeModel::iterator iter = plugin_model->get_iter (path);
+
+ if (iter) {
+
+ bool favorite = !(*iter)[plugin_columns.favorite];
+
+ /* change state */
+
+ (*iter)[plugin_columns.favorite] = favorite;
+
+ /* save new favorites list */
+
+ pi = (*iter)[plugin_columns.plugin];
+
+ if (favorite) {
+ manager->add_favorite (pi->type, pi->unique_id);
+ } else {
+ manager->remove_favorite (pi->type, pi->unique_id);
+ }
+
+ manager->save_favorites ();
+ }
+ in_row_change = false;
+}
+
+void
+PluginSelector::show_manager ()
+{
+ show_all();
+ run ();
+}
+
+void
+PluginSelector::set_interested_object (PluginInterestedObject& obj)
+{
+ interested_object = &obj;
+}
#include <gtkmm2ext/selector.h>
#include <ardour/plugin.h>
+#include "plugin_interest.h"
namespace ARDOUR {
class Session;
{
public:
PluginSelector (ARDOUR::PluginManager *);
- sigc::signal<void,boost::shared_ptr<ARDOUR::Plugin> > PluginCreated;
+ void set_interested_object (PluginInterestedObject&);
+
int run (); // XXX should we try not to overload the non-virtual Gtk::Dialog::run() ?
void set_session (ARDOUR::Session*);
void on_show ();
+ Gtk::Menu& plugin_menu ();
+
private:
+ PluginInterestedObject* interested_object;
+
ARDOUR::Session* session;
- Gtk::ScrolledWindow scroller; // Available plugins
+ Gtk::ScrolledWindow scroller; // Available plugins
Gtk::ScrolledWindow ascroller; // Added plugins
Gtk::ComboBoxText filter_mode;
struct PluginColumns : public Gtk::TreeModel::ColumnRecord {
PluginColumns () {
+ add (favorite);
add (name);
add (type_name);
add (category);
add (midi_outs);
add (plugin);
}
+ Gtk::TreeModelColumn<bool> favorite;
Gtk::TreeModelColumn<std::string> name;
Gtk::TreeModelColumn<std::string> type_name;
Gtk::TreeModelColumn<std::string> category;
void added_list_selection_changed();
void display_selection_changed();
void btn_apply_clicked();
- void use_plugin (ARDOUR::PluginInfoPtr);
- void cleanup ();
+ ARDOUR::PluginPtr load_plugin (ARDOUR::PluginInfoPtr);
bool show_this_plugin (const ARDOUR::PluginInfoPtr&, const std::string&);
void setup_filter_string (std::string&);
+
+ void favorite_changed (const Glib::ustring& path);
+ bool in_row_change;
+
+ void plugin_chosen_from_menu (const ARDOUR::PluginInfoPtr&);
+ Gtk::Menu* _menu;
+ void show_manager ();
};
#endif // __ardour_plugin_selector_h__
#include "utils.h"
#include "gui_thread.h"
#include "public_editor.h"
+#include "keyboard.h"
#include "i18n.h"
set_keep_above (true);
}
+bool
+PluginUIWindow::on_enter_notify_event (GdkEventCrossing *ev)
+{
+ Keyboard::the_keyboard().enter_window (ev, this);
+ return false;
+}
+
+bool
+PluginUIWindow::on_leave_notify_event (GdkEventCrossing *ev)
+{
+ Keyboard::the_keyboard().leave_window (ev, this);
+ return false;
+}
+
void
PluginUIWindow::on_show ()
{
void resize_preferred();
void set_parent (Gtk::Window*);
+ bool on_enter_notify_event (GdkEventCrossing*);
+ bool on_leave_notify_event (GdkEventCrossing*);
bool on_key_press_event (GdkEventKey*);
bool on_key_release_event (GdkEventKey*);
void on_show ();
void on_hide ();
void on_map ();
+
private:
PlugUIBase* _pluginui;
Gtk::Window* parent;
msgid "Audition"
msgstr "Avlyssna"
-
-#: gtk2_ardour/editor.cc:105 gtk2_ardour/editor.cc:3517
-msgid "Slide Edit"
-msgstr "Glidred."
-
-#: gtk2_ardour/editor.cc:106 gtk2_ardour/editor.cc:3515
-msgid "Splice Edit"
-msgstr "Fogred."
-
#: gtk2_ardour/editor.cc:111 gtk2_ardour/editor.cc:3572
#: gtk2_ardour/export_dialog.cc:78 gtk2_ardour/export_dialog.cc:92
#: gtk2_ardour/export_dialog.cc:893 gtk2_ardour/export_dialog.cc:1225
#: gtk2_ardour/editor_timefx.cc:73
msgid "Contents:"
msgstr "Innehåll"
+<<<<<<< .working
#: gtk2_ardour/editor_actions.cc:359
#: gtk2_ardour/analysis_window.cc:135
msgid "Re-analyze data"
msgstr "Ã…teranalysera data"
+=======
+
+#: gtk2_ardour/editor_actions.cc:359
+msgid "Playhead to Mouse"
+msgstr "Startmarkören till mus"
+
+#: gtk2_ardour/editor_actions.cc:277
+msgid "Playhead To Active Mark"
+msgstr "Startmarkören till aktiv markör"
+
+#: gtk2_ardour/editor_actions.cc:231
+msgid "Nudge Playhead Forward"
+msgstr "Knuffa startmarkören framåt"
+
+#: gtk2_ardour/editor_actions.cc:233
+msgid "Nudge Playhead Backward"
+msgstr "Knuffa startmarkören bakåt"
+
+#: gtk2_ardour/editor_actions.cc:475
+msgid "Move Forward to Transient"
+msgstr "Gå framåt till transient"
+
+#: gtk2_ardour/editor_actions.cc:477
+msgid "Move Backwards to Transient"
+msgstr "Gå bakåt till transient"
+
+#: gtk2_ardour/editor_actions.cc:235
+msgid "Forward To Grid"
+msgstr "Framåt till rutnät"
+
+#: gtk2_ardour/editor_actions.cc:237
+msgid "Backward To Grid"
+msgstr "Bakåt till rutnät"
+
+#: gtk2_ardour/editor_actions.cc:66 gtk2_ardour/editor.cc:151
+#: gtk2_ardour/editor.cc:3446
+msgid "Active Mark"
+msgstr "Aktiv markör"
+
+#: gtk2_ardour/editor_actions.cc:137
+msgid "to Next Region Boundary"
+msgstr "till nästa regionsgränsen"
+
+#: gtk2_ardour/editor_actions.cc:139
+msgid "to Previous Region Boundary"
+msgstr "till förra regionsgränsen"
+
+#: gtk2_ardour/editor_actions.cc:279
+msgid "Active Mark To Playhead"
+msgstr "Aktiv markör till startmarkören"
+
+#: gtk2_ardour/editor_actions.cc:361
+msgid "Active Marker to Mouse"
+msgstr "Aktiv markör till musen"
+
+#: gtk2_ardour/editor_actions.cc:61 gtk2_ardour/editor_actions.cc:613
+msgid "Markers"
+msgstr "Markörer"
+
+#: gtk2_ardour/ardour_ui_ed.cc:333
+msgid "Punch In/Out"
+msgstr "Inslag/utslag"
+
+#: gtk2_ardour/editor_actions.cc:177
+msgid "Select All Overlapping Edit Range"
+msgstr "Välj allt som överlappar redigeringsomfånget"
+
+#: gtk2_ardour/editor_actions.cc:179
+msgid "Select All Inside Edit Range"
+msgstr "Välj allt inom redigeringsomfånget"
+
+#: gtk2_ardour/editor_actions.cc:182
+msgid "Select Edit Range"
+msgstr "Välj redigeringsomfång"
+
+
+#: gtk2_ardour/editor_actions.cc:444
+msgid "Separate Using Punch Range"
+msgstr "Separera utifrån in-/utslagsomfånget"
+
+#: gtk2_ardour/editor_actions.cc:447
+msgid "Separate Using Loop Range"
+msgstr "Separera utifrån loopomfånget"
+
+#: gtk2_ardour/editor_actions.cc:469
+msgid "Split Regions At Percussion Onsets"
+msgstr "Dela regioner vid perkussiva anslag"
+
+#: gtk2_ardour/editor_actions.cc:282
+msgid "Trim Start At Edit Point"
+msgstr "Beskär början vid redigeringspunkten"
+
+#: gtk2_ardour/editor_actions.cc:285
+msgid "Trim End At Edit Point"
+msgstr "Beskär slutet vid redigeringspunkten"
+
+#: gtk2_ardour/ardour_ui_ed.cc:95
+msgid "Misc. Shortcuts"
+msgstr "Diverse kortkommandon"
+
+#: gtk2_ardour/editor_actions.cc:385
+msgid "Boost Region Gain"
+msgstr "Öka regionens volym"
+
+#: gtk2_ardour/editor_actions.cc:388
+msgid "Cut Region Gain"
+msgstr "Sänk regionens volym"
+
+#: gtk2_ardour/editor_actions.cc:99
+msgid "Break drag"
+msgstr "Avbryt dragning"
+
+
+#: gtk2_ardour/editor_actions.cc:400
+msgid "Raise Region"
+msgstr "Höj regionen"
+
+#: gtk2_ardour/editor_actions.cc:403
+msgid "Lower Region"
+msgstr "Sänk regionen"
+
+#: gtk2_ardour/editor_actions.cc:415
+msgid "Move To Original Position"
+msgstr "Flytta till ursprunglig position"
+
+#: gtk2_ardour/editor_actions.cc:409
+msgid "Lock Region"
+msgstr "LÃ¥s region"
+
+#: gtk2_ardour/editor_actions.cc:397
+msgid "Remove Region Sync"
+msgstr "Ta bort regionsynk.-punkt"
+
+#: gtk2_ardour/editor_actions.cc:505 gtk2_ardour/editor_ops.cc:5651
+msgid "Insert Time"
+msgstr "Infoga tid"
+
+#: gtk2_ardour/editor_actions.cc:93
+msgid "Waveforms"
+msgstr "VÃ¥gformer"
+
+#: gtk2_ardour/editor_actions.cc:509
+msgid "Toggle Active"
+msgstr "Växla aktiv"
+
+#: gtk2_ardour/editor_actions.cc:547
+msgid "Zoom Focus Mouse"
+msgstr "Zoomfokus: mus"
+
+#: gtk2_ardour/editor_actions.cc:582
+msgid "Next Snap Mode"
+msgstr "Nästa fästläge"
+
+#: gtk2_ardour/editor_actions.cc:583
+msgid "Next Snap Choice"
+msgstr "Nästa fästlägealternativ"
+
+#: gtk2_ardour/editor_actions.cc:70
+msgid "Primary Clock"
+msgstr "Primär klocka"
+
+#: gtk2_ardour/editor_actions.cc:77
+msgid "Secondary Clock"
+msgstr "Sekundär klocka"
+
+#: gtk2_ardour/ardour_ui_ed.cc:309 gtk2_ardour/ardour_ui_ed.cc:318
+#: gtk2_ardour/editor_actions.cc:616
+msgid "Bars & Beats"
+msgstr "Takter & slag"
+
+#: gtk2_ardour/ardour_ui_ed.cc:311 gtk2_ardour/ardour_ui_ed.cc:320
+msgid "Minutes & Seconds"
+msgstr "Minuter & sekunder"
+
+#: gtk2_ardour/editor_actions.cc:75
+msgid "Rulers"
+msgstr "Tidslinjevisning"
+
+#: gtk2_ardour/editor_actions.cc:619
+msgid "Min:Sec"
+msgstr "Min:sek"
+
+#: gtk2_ardour/editor_actions.cc:615
+msgid "Loop/Punch"
+msgstr "Loop-/inslagsmarkörer"
+
+#: gtk2_ardour/editor_actions.cc:76
+msgid "Scroll"
+msgstr "Skrollning"
+
+#: gtk2_ardour/rhythm_ferret.cc:40
+msgid "Analysis"
+msgstr "Analys"
+
+#: gtk2_ardour/rhythm_ferret.cc:30
+msgid "Percussive Onset"
+msgstr "Perkussivt anslag"
+
+#: gtk2_ardour/rhythm_ferret.cc:31
+msgid "Note Onset"
+msgstr "Notanslag"
+
+#: gtk2_ardour/rhythm_ferret.cc:48
+msgid "Threshold"
+msgstr "Tröskel"
+
+#: gtk2_ardour/rhythm_ferret.cc:51
+msgid "Sensitivity"
+msgstr "Känslighet"
+
+#: gtk2_ardour/rhythm_ferret.cc:52
+msgid "Analyze"
+msgstr "Analysera"
+
+#: gtk2_ardour/rhythm_ferret.cc:55
+msgid "Trigger gap (msecs)"
+msgstr "Utlösningsmellanrum (msek)"
+
+#: gtk2_ardour/rhythm_ferret.cc:43
+msgid "Set Tempo Map"
+msgstr "Sätt tempokarta"
+
+#: gtk2_ardour/rhythm_ferret.cc:44
+msgid "Conform Region"
+msgstr "Anpassa region"
+
+#: gtk2_ardour/rhythm_ferret.cc:39
+msgid "Selection"
+msgstr "Markering"
+
+
+#: gtk2_ardour/editor_actions.cc:463
+msgid "Set Tempo from Region=Bar"
+msgstr "Sätt tempo från region=takt"
+
+#: gtk2_ardour/editor_actions.cc:466
+msgid "Set Tempo from Edit Range=Bar"
+msgstr "Sätt tempo från redigeringsomfång=takt"
+
+
+#: gtk2_ardour/ardour_ui_ed.cc:548
+msgid "JACK does monitoring"
+msgstr "JACK sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:552
+msgid "Ardour does monitoring"
+msgstr "Ardour sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:553
+msgid "Audio Hardware does monitoring"
+msgstr "Ljudhårdvaran sköter medhörning"
+
+#: gtk2_ardour/ardour_ui_ed.cc:438
+msgid "Tape Machine mode"
+msgstr "Bandmaskinläge"
+
+#: gtk2_ardour/editor_actions.cc:64
+msgid "Misc Options"
+msgstr "Diverse inställningar"
+
+#: gtk2_ardour/ardour_ui_ed.cc:446
+msgid "Create marker at xrun location"
+msgstr "Skapa markör vid xrun-förekomst"
+
+#: gtk2_ardour/ardour_ui_ed.cc:455
+msgid "Rubberbanding Snaps to Grid"
+msgstr "Gummibandning fäster mot rutnätet"
+
+#: gtk2_ardour/ardour_ui_ed.cc:456
+msgid "Auto-analyse new audio"
+msgstr "Autoanalysera nya ljud"
+
+#: gtk2_ardour/editor_actions.cc:689
+msgid "Import to Region List"
+msgstr "Importera till regionslistan"
+
+#: gtk2_ardour/mixer_strip.cc:984
+msgid "Protect against denormals"
+msgstr "Skydda mot denormals"
+
+#: gtk2_ardour/option_editor.cc:1242
+msgid "Keyboard layout"
+msgstr "Tangentbordslayout"
+
+#: gtk2_ardour/option_editor.cc:275
+msgid "Font Scaling"
+msgstr "Typsnittsskalning"
+
+#: gtk2_ardour/option_editor.cc:97
+msgid "Add new MIDI port"
+msgstr "Lägg till ny MIDI-port"
+
+
+#: gtk2_ardour/editor.cc:1779 gtk2_ardour/editor.cc:1948
+msgid "Spectral Analysis"
+msgstr "Spektralanalys"
+
+#: gtk2_ardour/editor.cc:1793
+msgid "Glue to Bars&Beats"
+msgstr "Klistra mot takt&slag"
+
+#: gtk2_ardour/analysis_window.cc:46
+msgid "Signal source"
+msgstr "Signalkälla"
+
+#: gtk2_ardour/analysis_window.cc:47
+msgid "Selected ranges"
+msgstr "Valda omfång"
+
+#: gtk2_ardour/analysis_window.cc:48
+msgid "Selected regions"
+msgstr "Valda regioner"
+
+#: gtk2_ardour/analysis_window.cc:50
+msgid "Display model"
+msgstr "Visningsmodell"
+
+#: gtk2_ardour/analysis_window.cc:51
+msgid "Composite graphs for each track"
+msgstr "Sammansatt graf för varje spår"
+
+#: gtk2_ardour/analysis_window.cc:52
+msgid "Composite graph of all tracks"
+msgstr "Sammansatt graf för alla spår"
+
+#: gtk2_ardour/analysis_window.cc:54
+msgid "Show frequency power range"
+msgstr "Visa frekvenskraftsomfång"
+
+#: gtk2_ardour/analysis_window.cc:55
+msgid "Normalize values"
+msgstr "Normalisera värden"
+
+#: gtk2_ardour/analysis_window.cc:59 gtk2_ardour/analysis_window.cc:60
+msgid "FFT analysis window"
+msgstr "FFT-analysfönster"
+
+#: gtk2_ardour/analysis_window.cc:135
+msgid "Re-analyze data"
+msgstr "Ã…teranalysera data"
+
+#: gtk2_ardour/ardour_ui_ed.cc:195
+msgid "Window"
+msgstr "Fönster"
+
+#: gtk2_ardour/ardour_ui_dependents.cc:74
+msgid "Setup Editor"
+msgstr "Förbereder redigeraren..."
+
+#: gtk2_ardour/ardour_ui_dependents.cc:76
+msgid "Setup Mixer"
+msgstr "Förbereder mixern..."
+
+#: gtk2_ardour/ardour_ui_dependents.cc:81
+msgid "Reload Session History"
+msgstr "Laddar sessionshistoriken..."
+
+#: gtk2_ardour/editor.cc:4571
+msgid "Please wait while Ardour loads visual data"
+msgstr "Vänta medan Ardour laddar visuell data..."
+
+#: gtk2_ardour/editor_actions.cc:368
+msgid "Toggle Opaque"
+msgstr "Växla genomskinligt"
+
+#: gtk2_ardour/editor_actions.cc:570
+msgid "Fit Selected Tracks"
+msgstr "Rym valda spår"
+
+#: gtk2_ardour/editor_actions.cc:299
+msgid "Zoom to Region (W&H)"
+msgstr "Zooma till region (bredd & höjd)"
+
+#: gtk2_ardour/editor_actions.cc:76
+msgid "Views"
+msgstr "Visningslägen"
+
+
+#: gtk2_ardour/editor_actions.cc:196
+msgid "Save View 1"
+msgstr "Spara läge 1"
+
+#: gtk2_ardour/editor_actions.cc:198
+msgid "Goto View 1"
+msgstr "Använd läge 1"
+
+#: gtk2_ardour/editor_actions.cc:200
+msgid "Save View 2"
+msgstr "Spara läge 2"
+
+#: gtk2_ardour/editor_actions.cc:202
+msgid "Goto View 2"
+msgstr "Använd läge 2 "
+
+#: gtk2_ardour/editor_actions.cc:204
+msgid "Save View 3"
+msgstr "Spara läge 3"
+
+#: gtk2_ardour/editor_actions.cc:206
+msgid "Goto View 3"
+msgstr "Använd läge 3"
+
+#: gtk2_ardour/editor_actions.cc:208
+msgid "Save View 4"
+msgstr "Spara läge 4"
+
+#: gtk2_ardour/editor_actions.cc:210
+msgid "Goto View 4"
+msgstr "Använd läge 4"
+
+#: gtk2_ardour/editor_actions.cc:212
+msgid "Save View 5"
+msgstr "Spara läge 5"
+
+#: gtk2_ardour/editor_actions.cc:214
+msgid "Goto View 5"
+msgstr "Använd läge 5"
+
+#: gtk2_ardour/editor_actions.cc:216
+msgid "Save View 6"
+msgstr "Spara läge 6"
+
+#: gtk2_ardour/editor_actions.cc:218
+msgid "Goto View 6"
+msgstr "Använd läge 6"
+
+#: gtk2_ardour/editor_actions.cc:220
+msgid "Save View 7"
+msgstr "Spara läge 7"
+
+#: gtk2_ardour/editor_actions.cc:222
+msgid "Goto View 7"
+msgstr "Använd läge 7"
+
+#: gtk2_ardour/editor_actions.cc:224
+msgid "Save View 8"
+msgstr "Spara läge 8"
+
+#: gtk2_ardour/editor_actions.cc:226
+msgid "Goto View 8"
+msgstr "Använd läge 8"
+
+#: gtk2_ardour/editor_actions.cc:228
+msgid "Save View 9"
+msgstr "Spara läge 9"
+
+#: gtk2_ardour/editor_actions.cc:230
+msgid "Goto View 9"
+msgstr "Använd läge 9"
+
+#: gtk2_ardour/editor_actions.cc:232
+msgid "Save View 10"
+msgstr "Spara läge 10"
+
+#: gtk2_ardour/editor_actions.cc:234
+msgid "Goto View 10"
+msgstr "Använd läge 10"
+
+#: gtk2_ardour/editor_actions.cc:236
+msgid "Save View 11"
+msgstr "Spara läge 11"
+
+#: gtk2_ardour/editor_actions.cc:238
+msgid "Goto View 11"
+msgstr "Använd läge 11"
+
+#: gtk2_ardour/editor_actions.cc:240
+msgid "Save View 12"
+msgstr "Spara läge 12"
+
+#: gtk2_ardour/editor_actions.cc:242
+msgid "Goto View 12"
+msgstr "Använd läge 12"
+
+#: gtk2_ardour/ardour_ui_ed.cc:462
+msgid "Name New Markers"
+msgstr "Namnge nya markörer"
+
+#: gtk2_ardour/editor_ops.cc:1900
+msgid "Name New Location Marker"
+msgstr "Namnge ny platsmarkör"
+
+#: gtk2_ardour/sfdb_ui.cc:513
+msgid "Search Freesound"
+msgstr "Sök i Freesound"
+
+#: gtk2_ardour/sfdb_ui.cc:480
+msgid "User:"
+msgstr "Användarnamn:"
+
+#: gtk2_ardour/sfdb_ui.cc:484
+msgid "Password:"
+msgstr "Lösenord:"
+
+#: gtk2_ardour/sfdb_ui.cc:400 gtk2_ardour/sfdb_ui.cc:789
+msgid "Start Downloading"
+msgstr "Ladda ner"
+
+#: gtk2_ardour/redirect_box.cc:1190
+msgid "New Plugin"
+msgstr "Nytt insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:100
+msgid "Plugins to be connected"
+msgstr "Insticksprogram att ansluta"
+
+#: gtk2_ardour/plugin_selector.cc:156
+msgid "Insert Plugin(s)"
+msgstr "Infoga"
+
+#: gtk2_ardour/plugin_selector.cc:501
+msgid "Favorites"
+msgstr "Favoriter"
+
+#: gtk2_ardour/plugin_selector.cc:502
+msgid "Plugin Manager"
+msgstr "Insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:77
+msgid "Fav"
+msgstr ""
+
+#: gtk2_ardour/plugin_selector.cc:78
+msgid "Available Plugins"
+msgstr "Tillgängliga insticksprogram"
+
+#: gtk2_ardour/plugin_selector.cc:80
+msgid "Category"
+msgstr "Kategori"
+
+#: gtk2_ardour/plugin_selector.cc:81
+msgid "Creator"
+msgstr "Upphovsperson"
+
+#: gtk2_ardour/plugin_selector.cc:51 gtk2_ardour/plugin_selector.cc:209
+msgid "Name contains"
+msgstr "Namn innehåller"
+
+#: gtk2_ardour/plugin_selector.cc:52 gtk2_ardour/plugin_selector.cc:211
+msgid "Type contains"
+msgstr "Typ innehåller"
+
+#: gtk2_ardour/plugin_selector.cc:53 gtk2_ardour/plugin_selector.cc:213
+msgid "Author contains"
+msgstr "Upphovsperson innehåller"
+
+#: gtk2_ardour/plugin_selector.cc:54 gtk2_ardour/plugin_selector.cc:215
+msgid "Library contains"
+msgstr "Bibliotek innehåller"
+
+#: gtk2_ardour/plugin_selector.cc:55 gtk2_ardour/plugin_selector.cc:203
+#: gtk2_ardour/plugin_selector.cc:451
+msgid "Favorites only"
+msgstr "Endast favoriter"
+>>>>>>> .merge-right.r3622
#include <cmath>
#include <iostream>
+#include <set>
#include <sigc++/bind.h>
#include <ardour/plugin_insert.h>
#include <ardour/port_insert.h>
#include <ardour/ladspa_plugin.h>
+#include <ardour/profile.h>
#include "ardour_ui.h"
#include "ardour_dialog.h"
#include "mixer_ui.h"
#include "actions.h"
#include "plugin_ui.h"
-#include "send_ui.h"
#include "io_selector.h"
#include "utils.h"
#include "gui_thread.h"
#include "i18n.h"
-#ifdef HAVE_AUDIOUNIT
-#include "au_pluginui.h"
+#ifdef HAVE_AUDIOUNITS
+class AUPluginUI;
#endif
using namespace sigc;
if (get_colors) {
active_processor_color = new Gdk::Color;
inactive_processor_color = new Gdk::Color;
- set_color (*active_processor_color, rgba_from_style ("RedirectSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
- set_color (*inactive_processor_color, rgba_from_style ("RedirectSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
+ set_color (*active_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_ACTIVE, false ));
+ set_color (*inactive_processor_color, rgba_from_style ("ProcessorSelector", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
get_colors = false;
}
processor_display.set_model (model);
processor_display.append_column (X_("notshown"), columns.text);
- processor_display.set_name ("RedirectSelector");
+ processor_display.set_name ("ProcessorSelector");
processor_display.set_headers_visible (false);
processor_display.set_reorderable (true);
processor_display.set_size_request (-1, 40);
processor_display.get_column(0)->set_sizing(TREE_VIEW_COLUMN_FIXED);
processor_display.get_column(0)->set_fixed_width(48);
- processor_display.set_enable_search (false);
- processor_display.add_object_drag (columns.processor.index(), "redirects");
+ processor_display.add_object_drag (columns.processor.index(), "processors");
processor_display.signal_object_drop.connect (mem_fun (*this, &ProcessorBox::object_drop));
TreeViewColumn* name_col = processor_display.get_column(0);
/* now force an update of all the various elements */
redisplay_processors ();
- processor_eventbox.show();
- processor_scroller.show();
- processor_display.show();
- show();
}
ProcessorBox::~ProcessorBox ()
void
ProcessorBox::object_drop (string type, uint32_t cnt, const boost::shared_ptr<Processor>* ptr)
{
- if (type != "redirects" || cnt == 0 || !ptr) {
+ if (type != "processors" || cnt == 0 || !ptr) {
return;
}
ProcessorBox::remove_processor_gui (boost::shared_ptr<Processor> processor)
{
boost::shared_ptr<Send> send;
- boost::shared_ptr<PortInsert> port_processor;
+ boost::shared_ptr<PortInsert> port_insert;
+
+ if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
+
+ PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui());
+ port_insert->set_gui (0);
+ delete io_selector;
- if ((port_processor = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
- PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_processor->get_gui());
- port_processor->set_gui (0);
- delete io_selector;
} else if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui());
send->set_gui (0);
processor_menu = build_processor_menu ();
}
+ Gtk::MenuItem* plugin_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/processormenu/newplugin"));
+
+ if (plugin_menu_item) {
+ plugin_menu_item->set_submenu (_plugin_selector.plugin_menu());
+ }
+
paste_action->set_sensitive (!_rr_selection.processors.empty());
processor_menu->popup (1, arg);
} else if (processor && ev->button == 1 && selected) {
// this is purely informational but necessary
- InsertSelected (processor); // emit
+ ProcessorSelected (processor); // emit
}
return ret;
} else if (processor && (ev->button == 2) && (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))) {
+ /* button2-click with no modifiers */
+
processor->set_active (!processor->active());
ret = true;
ProcessorBox::build_processor_menu ()
{
processor_menu = dynamic_cast<Gtk::Menu*>(ActionManager::get_widget("/processormenu") );
- assert(processor_menu != 0);
processor_menu->set_name ("ArdourContextMenu");
show_all_children();
void
ProcessorBox::choose_plugin ()
{
- sigc::connection newplug_connection = _plugin_selector.PluginCreated.connect (mem_fun(*this,&ProcessorBox::processor_plugin_chosen));
- _plugin_selector.show_all();
- _plugin_selector.run ();
- newplug_connection.disconnect();
+ _plugin_selector.set_interested_object (*this);
}
void
-ProcessorBox::processor_plugin_chosen (boost::shared_ptr<Plugin> plugin)
+ProcessorBox::use_plugins (const SelectedPlugins& plugins)
{
- if (plugin) {
+ for (SelectedPlugins::const_iterator p = plugins.begin(); p != plugins.end(); ++p) {
- boost::shared_ptr<Processor> processor (new PluginInsert (_session, plugin, _placement));
-
- Route::ProcessorStreams err;
+ boost::shared_ptr<Processor> processor (new PluginInsert (_session, *p, _placement));
- if (_route->add_processor (processor, &err)) {
- weird_plugin_dialog (*plugin, err, _route);
+ Route::ProcessorStreams err_streams;
+
+ if (_route->add_processor (processor, &err_streams)) {
+ weird_plugin_dialog (**p, err_streams, _route);
// XXX SHAREDPTR delete plugin here .. do we even need to care?
} else {
- processor->set_active(true);
+
+ if (Profile->get_sae()) {
+ processor->set_active (true);
+ }
processor->ActiveChanged.connect (bind (mem_fun (*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
}
}
}
void
-ProcessorBox::choose_processor ()
+ProcessorBox::choose_insert ()
{
boost::shared_ptr<Processor> processor (new PortInsert (_session, _placement));
processor->ActiveChanged.connect (bind (mem_fun(*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
outs = _route->n_outputs();
}
- send->io()->ensure_io (ChanCount::ZERO, outs, false, this);
+ /* XXX need processor lock on route */
- SendUIWindow* gui = new SendUIWindow (send, _session);
+ try {
+ send->io()->ensure_io (ChanCount::ZERO, outs, false, this);
+ } catch (AudioEngine::PortRegistrationFailure& err) {
+ error << string_compose (_("Cannot set up new send: %1"), err.what()) << endmsg;
+ return;
+ }
/* let the user adjust the output setup (number and connections) before passing
it along to the Route
*/
- gui->show_all ();
- gui->present ();
+ IOSelectorWindow *ios = new IOSelectorWindow (_session, send->io(), false, true);
- /* pass shared_ptr, it will go out of scope when the GUI is deleted */
- /* also, connect it *before* existing handlers so that its definitely executed */
+ ios->show_all ();
- gui->signal_delete_event().connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), send, gui), false);
+ boost::shared_ptr<Processor> r = boost::static_pointer_cast<Processor>(send);
+
+ ios->selector().Finished.connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), boost::weak_ptr<Processor>(r), ios));
}
-bool
-ProcessorBox::send_io_finished (GdkEventAny* ev, boost::shared_ptr<Send> send, SendUIWindow* sui)
+void
+ProcessorBox::send_io_finished (IOSelector::Result r, boost::weak_ptr<Processor> weak_processor, IOSelectorWindow* ios)
{
- _route->add_processor (send);
- delete sui;
- return false;
+ boost::shared_ptr<Processor> processor (weak_processor.lock());
+
+ if (!processor) {
+ return;
+ }
+
+ switch (r) {
+ case IOSelector::Cancelled:
+ // processor will go away when all shared_ptrs to it vanish
+ break;
+
+ case IOSelector::Accepted:
+ _route->add_processor (processor);
+ break;
+ }
+
+ delete_when_idle (ios);
}
void
ProcessorBox::redisplay_processors ()
{
- ENSURE_GUI_THREAD(mem_fun(*this, &ProcessorBox::redisplay_processors));
+ ENSURE_GUI_THREAD (mem_fun(*this, &ProcessorBox::redisplay_processors));
if (no_processor_redisplay) {
return;
processor_active_connections.clear ();
processor_name_connections.clear ();
- void (ProcessorBox::*pmf)(boost::shared_ptr<Processor>) = &ProcessorBox::add_processor_to_display;
- _route->foreach_processor (this, pmf);
+ void (ProcessorBox::*method)(boost::shared_ptr<Processor>) = &ProcessorBox::add_processor_to_display;
+ _route->foreach_processor (this, method);
switch (_placement) {
case PreFader:
- build_processor_tooltip(processor_eventbox, _("Pre-fader processors, sends & plugins:"));
+ build_processor_tooltip(processor_eventbox, _("Pre-fader inserts, sends & plugins:"));
break;
case PostFader:
- build_processor_tooltip(processor_eventbox, _("Post-fader processors, sends & plugins:"));
+ build_processor_tooltip(processor_eventbox, _("Post-fader inserts, sends & plugins:"));
break;
}
}
for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
Gtk::TreeModel::Row row = *iter;
tip += '\n';
-
- /* don't use the column text, since it may be narrowed */
-
- boost::shared_ptr<Processor> i = row[columns.processor];
- tip += i->name();
+ tip += row[columns.text];
}
ARDOUR_UI::instance()->tooltips().set_tip (box, tip);
}
void
ProcessorBox::show_processor_active (boost::weak_ptr<Processor> weak_processor)
{
- ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
-
boost::shared_ptr<Processor> processor (weak_processor.lock());
if (!processor) {
return;
}
+ ENSURE_GUI_THREAD(bind (mem_fun(*this, &ProcessorBox::show_processor_active), weak_processor));
+
Gtk::TreeModel::Children children = model->children();
Gtk::TreeModel::Children::iterator iter = children.begin();
Gtk::TreeModel::Children children = model->children();
for (Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
- boost::shared_ptr<Processor> i = (*iter)[columns.processor];
- i->set_sort_key (sort_key);
+ boost::shared_ptr<Processor> r = (*iter)[columns.processor];
+ r->set_sort_key (sort_key);
sort_key++;
}
}
void
-ProcessorBox::for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<Processor>))
+ProcessorBox::for_selected_processors (void (ProcessorBox::*method)(boost::shared_ptr<Processor>))
{
vector<Gtk::TreeModel::Path> pathlist = processor_display.get_selection()->get_selected_rows();
for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
boost::shared_ptr<Processor> processor = (*(model->get_iter(*iter)))[columns.processor];
- (this->*pmf)(processor);
+ (this->*method)(processor);
}
}
_route->all_processors_active (_placement, state);
}
-void
-ProcessorBox::all_plugins_active (bool state)
-{
- if (state) {
- // XXX not implemented
- } else {
- _route->disable_plugins (_placement);
- }
-}
-
void
ProcessorBox::ab_plugins ()
{
ab_direction = !ab_direction;
}
+
void
ProcessorBox::clear_processors ()
{
ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
{
boost::shared_ptr<Send> send;
- boost::shared_ptr<PluginInsert> plugin_processor;
- boost::shared_ptr<PortInsert> port_processor;
+ boost::shared_ptr<PluginInsert> plugin_insert;
+ boost::shared_ptr<PortInsert> port_insert;
+ Window* gidget = 0;
if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) {
return;
}
+ boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
+
SendUIWindow *send_ui;
if (send->get_gui() == 0) {
send_ui = reinterpret_cast<SendUIWindow *> (send->get_gui());
}
- if (send_ui->is_visible()) {
- send_ui->get_window()->raise ();
- } else {
- send_ui->show_all ();
- send_ui->present ();
- }
+ gidget = send_ui;
+
+ } else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
+
+ PluginUIWindow *plugin_ui;
- } else if ((plugin_processor = boost::dynamic_pointer_cast<PluginInsert> (processor)) != 0) {
+ /* these are both allowed to be null */
+
+ Container* toplevel = get_toplevel();
+ Window* win = dynamic_cast<Gtk::Window*>(toplevel);
+
+ if (plugin_insert->get_gui() == 0) {
- ARDOUR::PluginType type = plugin_processor->type();
-
- if (type == ARDOUR::LADSPA || type == ARDOUR::VST) {
-
- PluginUIWindow *plugin_ui;
+ plugin_ui = new PluginUIWindow (win, plugin_insert);
- /* these are both allowed to be null */
-
- Container* toplevel = get_toplevel();
- Window* win = dynamic_cast<Gtk::Window*>(toplevel);
-
- if (plugin_processor->get_gui() == 0) {
-
- plugin_ui = new PluginUIWindow (win, plugin_processor);
-
- WindowTitle title(Glib::get_application_name());
- title += generate_processor_title (plugin_processor);
- plugin_ui->set_title (title.get_string());
-
- plugin_processor->set_gui (plugin_ui);
-
- // change window title when route name is changed
- _route->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_processor)));
-
- } else {
- plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_processor->get_gui());
- }
+ WindowTitle title(Glib::get_application_name());
+ title += generate_processor_title (plugin_insert);
+ plugin_ui->set_title (title.get_string());
- if (plugin_ui->is_visible()) {
- plugin_ui->get_window()->raise ();
- } else {
- plugin_ui->show_all ();
- plugin_ui->present ();
- }
-#ifdef HAVE_AUDIOUNIT
- } else if (type == ARDOUR::AudioUnit) {
- AUPluginUI* plugin_ui;
- if (plugin_processor->get_gui() == 0) {
- plugin_ui = new AUPluginUI (plugin_processor);
- } else {
- plugin_ui = reinterpret_cast<AUPluginUI*> (plugin_processor->get_gui());
- }
-
- plugin_ui = new PluginUIWindow (plugin_insert);
-
- // plugin_ui->set_keep_above (true);
-
- WindowTitle title(Glib::get_application_name());
- title += generate_redirect_title (plugin_insert);
- plugin_ui->set_title (title.get_string());
-
- plugin_insert->set_gui (plugin_ui);
-
- // change window title when route name is changed
- _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
-#endif
-
- } else {
- warning << "Unsupported plugin sent to ProcessorBox::edit_processor()" << endmsg;
- return;
- }
-
- } else if ((port_processor = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
-
+ plugin_insert->set_gui (plugin_ui);
+
+ // change window title when route name is changed
+ _route->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_insert)));
+
+ } else {
+ plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
+ plugin_ui->set_parent (win);
+ }
+
+ gidget = plugin_ui;
+
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
+
if (!_session.engine().connected()) {
MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
msg.run ();
return;
}
-
+
PortInsertWindow *io_selector;
-
- if (port_processor->get_gui() == 0) {
- io_selector = new PortInsertWindow (_session, port_processor);
- port_processor->set_gui (io_selector);
-
+
+ if (port_insert->get_gui() == 0) {
+ io_selector = new PortInsertWindow (_session, port_insert);
+ port_insert->set_gui (io_selector);
+
} else {
- io_selector = reinterpret_cast<PortInsertWindow *> (port_processor->get_gui());
+ io_selector = reinterpret_cast<PortInsertWindow *> (port_insert->get_gui());
}
+
+ gidget = io_selector;
+ }
- if (io_selector->is_visible()) {
- io_selector->get_window()->raise ();
+ if (gidget) {
+ if (gidget->is_visible()) {
+ gidget->get_window()->raise ();
} else {
- io_selector->show_all ();
- io_selector->present ();
+ gidget->show_all ();
+ gidget->present ();
}
}
}
Glib::RefPtr<Action> act;
/* new stuff */
- ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin ..."), sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
+ ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin"), sigc::ptr_fun (ProcessorBox::rb_choose_plugin));
- act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"), sigc::ptr_fun (ProcessorBox::rb_choose_processor));
+ act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"), sigc::ptr_fun (ProcessorBox::rb_choose_insert));
ActionManager::jack_sensitive_actions.push_back (act);
act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."), sigc::ptr_fun (ProcessorBox::rb_choose_send));
ActionManager::jack_sensitive_actions.push_back (act);
ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"), sigc::ptr_fun (ProcessorBox::rb_activate_all));
ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"), sigc::ptr_fun (ProcessorBox::rb_deactivate_all));
- ActionManager::register_action (popup_act_grp, X_("a_b_plugins"), _("A/B plugins"), sigc::ptr_fun (ProcessorBox::rb_ab_plugins));
- ActionManager::register_action (popup_act_grp, X_("deactivate_plugins"), _("Deactivate plugins"), sigc::ptr_fun (ProcessorBox::rb_deactivate_plugins));
-
/* show editors */
act = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit"), sigc::ptr_fun (ProcessorBox::rb_edit));
ActionManager::plugin_selection_sensitive_actions.push_back(act);
}
void
-ProcessorBox::rb_choose_processor ()
+ProcessorBox::rb_choose_insert ()
{
if (_current_processor_box == 0) {
return;
}
- _current_processor_box->choose_processor ();
+ _current_processor_box->choose_insert ();
}
void
_current_processor_box->all_processors_active (false);
}
-void
-ProcessorBox::rb_deactivate_plugins ()
-{
- if (_current_processor_box == 0) {
- return;
- }
- _current_processor_box->all_plugins_active (false);
-}
-
-
-void
-ProcessorBox::rb_ab_plugins ()
-{
- if (_current_processor_box == 0) {
- return;
- }
-
- _current_processor_box->ab_plugins ();
-}
-
-
void
ProcessorBox::rb_edit ()
{
ProcessorBox::route_name_changed (PluginUIWindow* plugin_ui, boost::weak_ptr<PluginInsert> wpi)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &ProcessorBox::route_name_changed), plugin_ui, wpi));
+
boost::shared_ptr<PluginInsert> pi (wpi.lock());
-
if (pi) {
WindowTitle title(Glib::get_application_name());
#include <ardour/types.h>
#include <ardour/ardour.h>
#include <ardour/io.h>
+#include <ardour/plugin_insert.h>
+#include <ardour/port_insert.h>
#include <ardour/processor.h>
-#include <ardour/io_processor.h>
#include <pbd/fastlog.h>
+#include "plugin_interest.h"
#include "route_ui.h"
#include "io_selector.h"
+#include "send_ui.h"
#include "enums.h"
class MotionController;
class PluginSelector;
class PluginUIWindow;
class RouteRedirectSelection;
-class SendUIWindow;
namespace ARDOUR {
- class Bundle;
- class Processor;
+ class Connection;
+ class Insert;
class Plugin;
class PluginInsert;
class PortInsert;
class Session;
}
-
-class ProcessorBox : public Gtk::HBox
+class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
{
public:
ProcessorBox (ARDOUR::Placement, ARDOUR::Session&,
void select_all_processors ();
void deselect_all_processors ();
void select_all_plugins ();
+ void select_all_inserts ();
void select_all_sends ();
- sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > InsertSelected;
- sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > InsertUnselected;
+ sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorSelected;
+ sigc::signal<void,boost::shared_ptr<ARDOUR::Processor> > ProcessorUnselected;
static void register_actions();
add (processor);
add (color);
}
- Gtk::TreeModelColumn<std::string> text;
+ Gtk::TreeModelColumn<std::string> text;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Processor> > processor;
- Gtk::TreeModelColumn<Gdk::Color> color;
+ Gtk::TreeModelColumn<Gdk::Color> color;
};
ModelColumns columns;
static Gdk::Color* inactive_processor_color;
Gtk::EventBox processor_eventbox;
- //Gtk::HBox processor_hpacker;
+ Gtk::HBox processor_hpacker;
Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Processor> > processor_display;
Gtk::ScrolledWindow processor_scroller;
void show_processor_menu (gint arg);
void choose_send ();
- bool send_io_finished (GdkEventAny*,boost::shared_ptr<ARDOUR::Send>, SendUIWindow*);
- void choose_processor ();
+ void send_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Processor>, IOSelectorWindow*);
+ void choose_insert ();
void choose_plugin ();
- void processor_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>);
+ void use_plugins (const SelectedPlugins&);
bool no_processor_redisplay;
bool ignore_delete;
void processors_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_processor_sort_keys ();
- vector<sigc::connection> processor_active_connections;
- vector<sigc::connection> processor_name_connections;
+ std::vector<sigc::connection> processor_active_connections;
+ std::vector<sigc::connection> processor_name_connections;
bool processor_drag_in_progress;
void processor_drag_begin (GdkDragContext*);
static bool leave_box (GdkEventCrossing*, ProcessorBox*);
static void rb_choose_plugin ();
- static void rb_choose_processor ();
+ static void rb_choose_insert ();
static void rb_choose_send ();
static void rb_clear ();
static void rb_cut ();
static void rb_deactivate ();
static void rb_activate_all ();
static void rb_deactivate_all ();
- static void rb_edit ();
static void rb_ab_plugins ();
- static void rb_deactivate_plugins ();
+ static void rb_edit ();
void route_name_changed (PluginUIWindow* plugin_ui, boost::weak_ptr<ARDOUR::PluginInsert> pi);
std::string generate_processor_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
PublicEditor* PublicEditor::_instance = 0;
-/** PublicEditor constructor */
+const int PublicEditor::window_border_width = 12;
+const int PublicEditor::container_border_width = 12;
+const int PublicEditor::vertical_spacing = 6;
+const int PublicEditor::horizontal_spacing = 6;
+
PublicEditor::PublicEditor ()
: Window (Gtk::WINDOW_TOPLEVEL)
{
}
-/** PublicEditor destructor */
PublicEditor::~PublicEditor()
{
}
virtual void set_snap_threshold (double t) = 0;
/** Snap a value according to the current snap setting. */
- virtual void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) = 0;
+ virtual void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false) = 0;
/** Get the current snap value in beats */
- virtual double snap_length_beats (nframes_t start) = 0;
+ virtual double snap_length_beats (nframes64_t start) = 0;
/** Undo some transactions.
* @param n Number of transactions to undo.
*/
+
virtual void undo (uint32_t n = 1) = 0;
/** Redo some transactions.
virtual void toggle_playback (bool with_abort) = 0;
virtual void transition_to_rolling (bool fwd) = 0;
- virtual nframes_t unit_to_frame (double unit) const = 0;
- virtual double frame_to_unit (nframes_t frame) const = 0;
+ virtual nframes64_t unit_to_frame (double unit) const = 0;
+ // XXX remove me when libardour goes nframes64_t
+ double frame_to_unit (nframes_t frame) const {
+ return frame_to_unit ((nframes64_t) frame);
+ }
+ virtual double frame_to_unit (nframes64_t frame) const = 0;
virtual double frame_to_unit (double frame) const = 0;
virtual nframes64_t pixel_to_frame (double pixel) const = 0;
virtual gulong frame_to_pixel (nframes64_t frame) const = 0;
virtual void select_all_tracks () = 0;
virtual void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove = false) = 0;
virtual void set_selected_mixer_strip (TimeAxisView&) = 0;
- virtual void hide_track_in_display (TimeAxisView& tv) = 0;
+ virtual void hide_track_in_display (TimeAxisView& tv, bool temporary = false) = 0;
virtual void show_track_in_display (TimeAxisView& tv) = 0;
/** Set whether the editor should follow the playhead.
virtual void ensure_float (Gtk::Window&) = 0;
virtual void show_window () = 0;
virtual TrackViewList* get_valid_views (TimeAxisView*, ARDOUR::RouteGroup* grp = 0) = 0;
- virtual nframes_t leftmost_position () const = 0;
- virtual nframes_t current_page_frames () const = 0;
+ virtual nframes64_t leftmost_position() const = 0;
+ virtual nframes64_t current_page_frames() const = 0;
virtual void temporal_zoom_step (bool coarser) = 0;
virtual void scroll_tracks_down_line () = 0;
virtual void scroll_tracks_up_line () = 0;
virtual bool new_regionviews_display_gain () = 0;
virtual void prepare_for_cleanup () = 0;
- virtual void reset_x_origin (nframes_t frame) = 0;
+ virtual void finish_cleanup () = 0;
+ virtual void reset_x_origin (nframes64_t frame) = 0;
virtual void remove_last_capture () = 0;
virtual void maximise_editing_space () = 0;
virtual void restore_editing_space () = 0;
virtual nframes64_t get_preferred_edit_position (bool ignore_playhead = false) = 0;
virtual void toggle_meter_updating() = 0;
virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret) = 0;
- virtual void mouse_add_new_marker (nframes_t where, bool is_cd=false, bool is_xrun=false) = 0;
+ virtual void mouse_add_new_marker (nframes64_t where, bool is_cd=false, bool is_xrun=false) = 0;
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
+ virtual void add_to_idle_resize (TimeAxisView*,uint32_t) = 0;
#ifdef WITH_CMT
virtual void add_imageframe_time_axis(const std::string & track_name, void*) = 0;
sigc::signal<void> ZoomChanged;
sigc::signal<void> Resized;
sigc::signal<void> Realized;
- sigc::signal<void,nframes_t> UpdateAllTransportClocks;
+ sigc::signal<void,nframes64_t> UpdateAllTransportClocks;
Glib::RefPtr<Gtk::ActionGroup> editor_actions;
virtual bool canvas_markerview_end_handle_event(GdkEvent* event, ArdourCanvas::Item*,MarkerView*) = 0;
#endif
+ virtual void queue_draw_resize_line (int at) = 0;
+ virtual void start_resize_line_ops () = 0;
+ virtual void end_resize_line_ops () = 0;
+
+ static const int window_border_width;
+ static const int container_border_width;
+ static const int vertical_spacing;
+ static const int horizontal_spacing;
+
/// Singleton instance, set up by Editor::Editor()
static PublicEditor* _instance;
boost::shared_ptr<ARDOUR::Region> r,
double spu,
Gdk::Color& basic_color)
- : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(),
+ : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), false,
+
TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText|
TimeAxisViewItem::ShowNameHighlight|
TimeAxisViewItem::ShowFrame))
/* derived concrete type will call init () */
_region = other._region;
- editor = 0;
current_visible_sync_position = other.current_visible_sync_position;
valid = false;
- _enable_display = false;
_pixel_width = other._pixel_width;
+ _height = other._height;
}
RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other_region)
/* derived concrete type will call init () */
_region = other_region;
- editor = other.editor;
current_visible_sync_position = other.current_visible_sync_position;
valid = false;
_pixel_width = other._pixel_width;
boost::shared_ptr<ARDOUR::Region> r,
double spu,
Gdk::Color& basic_color,
+ bool recording,
TimeAxisViewItem::Visibility visibility)
- : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), visibility)
+ : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), recording, visibility)
, _region (r)
, sync_mark(0)
, sync_line(0)
void
RegionView::init (Gdk::Color& basic_color, bool wfd)
{
- valid = true;
- _enable_display = false;
- in_destructor = false;
- wait_for_data = wfd;
+ editor = 0;
+ valid = true;
+ in_destructor = false;
+ _height = 0;
+ wait_for_data = wfd;
sync_mark = 0;
sync_line = 0;
sync_mark = 0;
compute_colors (basic_color);
- name_highlight->set_data ("regionview", this);
+ if (name_highlight) {
+ name_highlight->set_data ("regionview", this);
+ name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
+ }
if (name_text) {
name_text->set_data ("regionview", this);
if (wfd)
_enable_display = true;
- set_y_position_and_height (0, trackview.height - 2);
+ set_height (trackview.current_height());
_region->StateChanged.connect (mem_fun(*this, &RegionView::region_changed));
group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));
- name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
set_colors ();
ColorsChanged.connect (mem_fun (*this, &RegionView::color_handler));
- // set_pango_fontsize();
+
/* XXX sync mark drag? */
}
points.clear ();
points.push_back (Gnome::Art::Point (offset, 0));
- points.push_back (Gnome::Art::Point (offset, trackview.height - NAME_HIGHLIGHT_SIZE));
+ points.push_back (Gnome::Art::Point (offset, trackview.current_height() - NAME_HIGHLIGHT_SIZE));
sync_line->property_points().set_value (points);
sync_line->show ();
boost::shared_ptr<ARDOUR::Region>,
double samples_per_unit,
Gdk::Color& basic_color,
+ bool recording,
TimeAxisViewItem::Visibility);
virtual void region_resized (ARDOUR::Change);
#include <pbd/memento_command.h>
#include <ardour/transient_detector.h>
+#include <ardour/onset_detector.h>
#include <ardour/audiosource.h>
#include <ardour/audioregion.h>
#include <ardour/playlist.h>
0
};
+static const gchar * _onset_function_strings[] = {
+ N_("Energy Based"),
+ N_("Spectral Difference"),
+ N_("High-Frequency Content"),
+ N_("Complex Domain"),
+ N_("Phase Deviation"),
+ N_("Kullback-Liebler"),
+ N_("Modified Kullback-Liebler"),
+ 0
+};
+
RhythmFerret::RhythmFerret (PublicEditor& e)
: ArdourDialog (_("Rhythm Ferret"))
, editor (e)
, sensitivity_scale (sensitivity_adjustment)
, sensitivity_label (_("Sensitivity"))
, analyze_button (_("Analyze"))
+ , onset_function_label (_("Detection function"))
+ , peak_picker_threshold_adjustment (0.3, 0.0, 1.0, 0.01, 0.1)
+ , peak_picker_threshold_scale (peak_picker_threshold_adjustment)
+ , peak_picker_label (_("Peak Threshold"))
+ , silence_threshold_adjustment (-90.0, -120.0, 0.0, 1, 10)
+ , silence_threshold_scale (silence_threshold_adjustment)
+ , silence_label (_("Silent Threshold (dB)"))
, trigger_gap_adjustment (3, 0, 100, 1, 10)
, trigger_gap_spinner (trigger_gap_adjustment)
, trigger_gap_label (_("Trigger gap (msecs)"))
analysis_mode_strings = I18N (_analysis_mode_strings);
Gtkmm2ext::set_popdown_strings (analysis_mode_selector, analysis_mode_strings);
analysis_mode_selector.set_active_text (analysis_mode_strings.front());
+ analysis_mode_selector.signal_changed().connect (mem_fun (*this, &RhythmFerret::analysis_mode_changed));
+
+ onset_function_strings = I18N (_onset_function_strings);
+ Gtkmm2ext::set_popdown_strings (onset_detection_function_selector, onset_function_strings);
+ /* Onset plugin uses complex domain as default function
+ XXX there should be a non-hacky way to set this
+ */
+ onset_detection_function_selector.set_active_text (onset_function_strings[3]);
box = manage (new HBox);
box->set_spacing (6);
box->pack_start (analysis_mode_selector, true, true);
ferret_packer.pack_start (*box, false, false);
+ ferret_packer.pack_start (analysis_packer, false, false);
+
box = manage (new HBox);
box->set_spacing (6);
- box->pack_start (detection_threshold_label, false, false);
- box->pack_start (detection_threshold_scale, true, true);
+ box->pack_start (trigger_gap_label, false, false);
+ box->pack_start (trigger_gap_spinner, false, false);
ferret_packer.pack_start (*box, false, false);
+ ferret_packer.pack_start (analyze_button, false, false);
+
+ analyze_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::run_analysis));
+
+ box = manage (new HBox);
+ box->set_spacing (6);
+ box->pack_start (detection_threshold_label, false, false);
+ box->pack_start (detection_threshold_scale, true, true);
+ perc_onset_packer.pack_start (*box, false, false);
+
box = manage (new HBox);
box->set_spacing (6);
box->pack_start (sensitivity_label, false, false);
box->pack_start (sensitivity_scale, true, true);
- ferret_packer.pack_start (*box, false, false);
+ perc_onset_packer.pack_start (*box, false, false);
box = manage (new HBox);
box->set_spacing (6);
- box->pack_start (trigger_gap_label, false, false);
- box->pack_start (trigger_gap_spinner, false, false);
- ferret_packer.pack_start (*box, false, false);
+ box->pack_start (onset_function_label, false, false);
+ box->pack_start (onset_detection_function_selector, true, true);
+ note_onset_packer.pack_start (*box, false, false);
+
+ box = manage (new HBox);
+ box->set_spacing (6);
+ box->pack_start (peak_picker_label, false, false);
+ box->pack_start (peak_picker_threshold_scale, true, true);
+ note_onset_packer.pack_start (*box, false, false);
+
+ box = manage (new HBox);
+ box->set_spacing (6);
+ box->pack_start (silence_label, false, false);
+ box->pack_start (silence_threshold_scale, true, true);
+ note_onset_packer.pack_start (*box, false, false);
- ferret_packer.pack_start (analyze_button, false, false);
+ analysis_mode_changed ();
- analyze_button.signal_clicked().connect (mem_fun (*this, &RhythmFerret::run_analysis));
-
ferret_frame.add (ferret_packer);
logo = manage (new Gtk::Image (::get_icon (X_("ferret_02"))));
}
}
+void
+RhythmFerret::analysis_mode_changed ()
+{
+ analysis_packer.children().clear ();
+
+ switch (get_analysis_mode()) {
+ case PercussionOnset:
+ analysis_packer.pack_start (perc_onset_packer);
+ break;
+
+ case NoteOnset:
+ analysis_packer.pack_start (note_onset_packer);
+ break;
+ }
+
+ analysis_packer.show_all ();
+}
+
RhythmFerret::AnalysisMode
RhythmFerret::get_analysis_mode () const
{
string str = analysis_mode_selector.get_active_text ();
- if (str == _(_analysis_mode_strings[(int) NoteOnset])) {
+ if (str == analysis_mode_strings[(int) NoteOnset]) {
return NoteOnset;
}
case PercussionOnset:
run_percussion_onset_analysis (rd, (*i)->region()->position(), current_results);
break;
+ case NoteOnset:
+ run_note_onset_analysis (rd, (*i)->region()->position(), current_results);
+ break;
default:
break;
}
return 0;
}
+int
+RhythmFerret::get_note_onset_function ()
+{
+ string txt = onset_detection_function_selector.get_active_text();
+
+ for (int n = 0; _onset_function_strings[n]; ++n) {
+ /* compare translated versions */
+ if (txt == onset_function_strings[n]) {
+ return n;
+ }
+ }
+ fatal << string_compose (_("programming error: %1 (%2)"), X_("illegal note onset function string"), txt)
+ << endmsg;
+ /*NOTREACHED*/
+ return -1;
+}
+
+int
+RhythmFerret::run_note_onset_analysis (boost::shared_ptr<Readable> readable, nframes64_t offset, AnalysisFeatureList& results)
+{
+ try {
+ OnsetDetector t (session->frame_rate());
+
+ for (uint32_t i = 0; i < readable->n_channels(); ++i) {
+
+ AnalysisFeatureList these_results;
+
+ t.reset ();
+
+ t.set_function (get_note_onset_function());
+ t.set_silence_threshold (silence_threshold_adjustment.get_value());
+ t.set_peak_threshold (peak_picker_threshold_adjustment.get_value());
+
+ if (t.run ("", readable.get(), i, these_results)) {
+ continue;
+ }
+
+ /* translate all transients to give absolute position */
+
+ for (AnalysisFeatureList::iterator x = these_results.begin(); x != these_results.end(); ++x) {
+ (*x) += offset;
+ }
+
+ /* merge */
+
+ results.insert (results.end(), these_results.begin(), these_results.end());
+ these_results.clear ();
+ }
+
+ } catch (failed_constructor& err) {
+ error << "Could not load note onset detection plugin" << endmsg;
+ return -1;
+ }
+
+ if (!results.empty()) {
+ OnsetDetector::cleanup_onsets (results, session->frame_rate(), trigger_gap_adjustment.get_value());
+ }
+
+ return 0;
+}
+
void
RhythmFerret::do_action ()
{
i = tmp;
}
+ session->commit_reversible_command ();
}
Gtk::VBox ferret_packer;
Gtk::ComboBoxText analysis_mode_selector;
Gtk::Label analysis_mode_label;
+
+ /* transient detection widgets */
+
Gtk::Adjustment detection_threshold_adjustment;
Gtk::HScale detection_threshold_scale;
Gtk::Label detection_threshold_label;
Gtk::HScale sensitivity_scale;
Gtk::Label sensitivity_label;
Gtk::Button analyze_button;
+ Gtk::VBox perc_onset_packer;
+
+ /* onset detection widgets */
+
+ Gtk::ComboBoxText onset_detection_function_selector;
+ Gtk::Label onset_function_label;
+ Gtk::Adjustment peak_picker_threshold_adjustment;
+ Gtk::HScale peak_picker_threshold_scale;
+ Gtk::Label peak_picker_label;
+ Gtk::Adjustment silence_threshold_adjustment;
+ Gtk::HScale silence_threshold_scale;
+ Gtk::Label silence_label;
+ Gtk::VBox note_onset_packer;
+
+ /* generic stuff */
+
Gtk::Adjustment trigger_gap_adjustment;
Gtk::SpinButton trigger_gap_spinner;
Gtk::Label trigger_gap_label;
+ Gtk::VBox analysis_packer;
+
Gtk::Label operation_clarification_label;
Gtk::Button action_button;
std::vector<std::string> analysis_mode_strings;
+ std::vector<std::string> onset_function_strings;
ARDOUR::AnalysisFeatureList current_results;
AnalysisMode get_analysis_mode () const;
Action get_action() const;
+ void analysis_mode_changed ();
+ int get_note_onset_function ();
void run_analysis ();
int run_percussion_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, nframes64_t offset, ARDOUR::AnalysisFeatureList& results);
+ int run_note_onset_analysis (boost::shared_ptr<ARDOUR::Readable> region, nframes64_t offset, ARDOUR::AnalysisFeatureList& results);
void do_action ();
void do_split_action ();
pre_redir_hpane.pack1 (*pre_insert_box);
post_redir_hpane.pack1 (*post_insert_box);
- pre_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
- pre_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
- post_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
- post_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
+ pre_insert_box->ProcessorSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
+ pre_insert_box->ProcessorUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
+ post_insert_box->ProcessorSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
+ post_insert_box->ProcessorUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
pre_redir_hpane.show_all();
post_redir_hpane.show_all();
Glib::RefPtr<Gdk::Pixbuf> RouteTimeAxisView::slider;
-int
+void
RouteTimeAxisView::setup_slider_pix ()
{
- slider = ::get_icon ("fader_belt_h");
- return 0;
+ if ((slider = ::get_icon ("fader_belt_h")) == 0) {
+ throw failed_constructor ();
+ }
}
RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
size_button (_("h")), // height
automation_button (_("a")),
visual_button (_("v")),
- lm (rt, sess),
- underlay_xml_node (0),
- gain_slider (0),
- gain_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1)
+ gm (rt, sess, slider, true)
{
- if (slider == 0) {
- setup_slider_pix ();
- }
+ gm.get_level_meter().set_no_show_all();
+ gm.get_level_meter().setup_meters(50);
- lm.set_no_show_all();
- lm.setup_meters(50);
_has_state = true;
playlist_menu = 0;
playlist_action_menu = 0;
destructive_track_mode_item = 0;
normal_track_mode_item = 0;
- gain_slider = manage (new HSliderController (slider, &gain_adjustment, *_route->gain_control().get(), false));
-
ignore_toggle = false;
edit_group_button.set_name ("TrackGroupButton");
}
- controls_hbox.pack_start(lm, false, false);
+ controls_hbox.pack_start(gm.get_level_meter(), false, false);
_route->meter_change.connect (mem_fun(*this, &RouteTimeAxisView::meter_changed));
_route->input_changed.connect (mem_fun(*this, &RouteTimeAxisView::io_changed));
_route->output_changed.connect (mem_fun(*this, &RouteTimeAxisView::io_changed));
controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
controls_table.attach (edit_group_button, 7, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
- controls_table.attach (*gain_slider, 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+ controls_table.attach (gm.get_gain_slider(), 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo"));
ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute"));
editor.ZoomChanged.connect (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
ColorsChanged.connect (mem_fun (*this, &RouteTimeAxisView::color_handler));
- gain_slider->signal_button_press_event().connect (mem_fun(*this, &RouteTimeAxisView::start_gain_touch));
- gain_slider->signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::end_gain_touch));
- gain_slider->set_name ("TrackGainFader");
-
- gain_adjustment.signal_value_changed().connect (mem_fun(*this, &RouteTimeAxisView::gain_adjusted));
- _route->gain_control()->Changed.connect (mem_fun(*this, &RouteTimeAxisView::gain_changed));
-
- gain_slider->show_all();
+ gm.get_gain_slider().signal_scroll_event().connect(mem_fun(*this, &RouteTimeAxisView::controls_ebox_scroll), false);
+ gm.get_gain_slider().set_name ("TrackGainFader");
}
RouteTimeAxisView::~RouteTimeAxisView ()
/* map current state of the route */
update_diskstream_display ();
+
subplugin_menu.items().clear ();
_route->foreach_processor (this, &RouteTimeAxisView::add_processor_to_subplugin_menu);
_route->foreach_processor (this, &RouteTimeAxisView::add_existing_processor_automation_curves);
{
}
-void
-RouteTimeAxisView::set_state (const XMLNode& node)
-{
- const XMLProperty *prop;
-
- TimeAxisView::set_state (node);
-
- if ((prop = node.property ("shown_editor")) != 0) {
- if (prop->value() == "no") {
- _marked_for_display = false;
- } else {
- _marked_for_display = true;
- }
- } else {
- _marked_for_display = true;
- }
-
- XMLNodeList nlist = node.children();
- XMLNodeConstIterator niter;
- XMLNode *child_node;
-
- _show_automation.clear();
-
- for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- child_node = *niter;
-
- if (child_node->name() == AutomationTimeAxisView::state_node_name) {
- XMLProperty* prop = child_node->property ("automation-id");
- if (!prop)
- continue;
-
- Parameter param(prop->value());
- if (!param)
- continue;
-
- bool show = false;
-
- prop = child_node->property ("shown");
-
- if (prop && prop->value() == "yes") {
- show = true;
- _show_automation.insert(param);
- }
-
- if (_automation_tracks.find(param) == _automation_tracks.end()) {
- create_automation_child(param, show);
- }
- }
- else if (child_node->name() == "Underlays") {
- underlay_xml_node = child_node;
-
- /* Wait for all gui tracks to be loaded as underlays are cross referencing tracks*/
- Glib::signal_idle().connect(mem_fun(*this, &RouteTimeAxisView::set_underlay_state));
- }
- }
-}
-
-XMLNode*
-RouteTimeAxisView::get_automation_child_xml_node (Parameter param)
-{
- return RouteUI::get_automation_child_xml_node (param);
-}
-
gint
RouteTimeAxisView::edit_click (GdkEventButton *ev)
{
route_active_menu_item->set_active (_route->active());
items.push_back (SeparatorElem());
+ items.push_back (MenuElem (_("Hide"), mem_fun(*this, &RouteTimeAxisView::hide_click)));
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
}
x1 = start / editor.get_current_zoom();
x2 = (end - 1) / editor.get_current_zoom();
- y2 = height - 2;
+ y2 = current_height() - 2;
timestretch_rect->property_x1() = x1;
timestretch_rect->property_y1() = 1.0;
}
void
-RouteTimeAxisView::set_height (TrackHeight h)
+RouteTimeAxisView::set_height (uint32_t h)
{
- int gmlen = (height_to_pixels (h)) - 5;
- bool height_changed = (height == 0) || (h != height_style);
- lm.setup_meters (gmlen);
+ int gmlen = h - 5;
+ bool height_changed = (height == 0) || (h != height);
+ gm.get_level_meter().setup_meters (gmlen);
+
TimeAxisView::set_height (h);
ensure_xml_node ();
if (_view) {
- _view->set_height ((double) height);
+ _view->set_height ((double) current_height());
}
- switch (height_style) {
- case Largest:
- xml_node->add_property ("track_height", "largest");
- break;
-
- case Large:
- xml_node->add_property ("track_height", "large");
- break;
-
- case Larger:
- xml_node->add_property ("track_height", "larger");
- break;
+ char buf[32];
+ snprintf (buf, sizeof (buf), "%u", height);
+ xml_node->add_property ("height", buf);
- case Normal:
- xml_node->add_property ("track_height", "normal");
- break;
-
- case Smaller:
- xml_node->add_property ("track_height", "smaller");
- break;
-
- case Small:
- xml_node->add_property ("track_height", "small");
- break;
- }
-
- switch (height_style) {
- case Largest:
- case Large:
- case Larger:
- case Normal:
+ if (height >= hNormal) {
reset_meter();
show_name_entry ();
hide_name_label ();
- gain_slider->show();
+ gm.get_gain_slider().show();
mute_button->show();
solo_button->show();
if (rec_enable_button)
if (is_track() && track()->mode() == ARDOUR::Normal) {
playlist_button.show();
}
- break;
- case Smaller:
+ } else if (height >= hSmaller) {
+
reset_meter();
show_name_entry ();
hide_name_label ();
- gain_slider->hide();
+ gm.get_gain_slider().hide();
mute_button->show();
solo_button->show();
if (rec_enable_button)
if (is_track() && track()->mode() == ARDOUR::Normal) {
playlist_button.hide ();
}
- break;
- case Small:
+ } else {
+
hide_name_entry ();
show_name_label ();
-
- gain_slider->hide();
+
+ gm.get_gain_slider().hide();
mute_button->hide();
solo_button->hide();
if (rec_enable_button)
automation_button.hide ();
playlist_button.hide ();
name_label.set_text (_route->name());
- break;
}
if (height_changed) {
ran->menu_item->set_active (false);
}
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
no_redraw = false;
-
/* Redraw */
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
void
}
no_redraw = false;
-
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
void
_show_automation.clear();
no_redraw = false;
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
i->mark_automation_visible (pan->what, false);
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
void
track->Hiding.connect (bind (mem_fun (*this, &RouteTimeAxisView::automation_track_hidden), param));
bool hideit = (!show);
-
+
XMLNode* node;
if ((node = track->get_state_node()) != 0) {
if (hideit) {
track->hide ();
} else {
- _show_automation.insert(param);
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _show_automation.insert (param);
+
+ if (!no_redraw) {
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
+ }
}
build_display_menu();
/* now trigger a redisplay */
- _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("visible_tracks", (void *) 0); /* EMIT_SIGNAL */
}
}
/* change in visibility was possible */
- _route->gui_changed ("track_height", this);
+ _route->gui_changed ("visible_tracks", this);
}
boost::shared_ptr<AutomationLine>
void
RouteTimeAxisView::fast_update ()
{
- lm.update_meters ();
+ gm.get_level_meter().update_meters ();
}
void
RouteTimeAxisView::hide_meter ()
{
clear_meter ();
- lm.hide_meters ();
+ gm.get_level_meter().hide_meters ();
}
void
RouteTimeAxisView::reset_meter ()
{
if (Config->get_show_track_meters()) {
- lm.setup_meters (height-5);
+ gm.get_level_meter().setup_meters (height-5);
} else {
hide_meter ();
}
void
RouteTimeAxisView::clear_meter ()
{
- lm.clear_meters ();
+ gm.get_level_meter().clear_meters ();
}
void
}
}
-gint
-RouteTimeAxisView::start_gain_touch (GdkEventButton* ev)
-{
- _route->gain_control()->list()->start_touch ();
- return FALSE;
-}
-
-gint
-RouteTimeAxisView::end_gain_touch (GdkEventButton* ev)
-{
- _route->gain_control()->list()->stop_touch ();
- return FALSE;
-}
-
-void
-RouteTimeAxisView::gain_adjusted ()
-{
- _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
-}
-
-void
-RouteTimeAxisView::gain_changed ()
-{
- Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::effective_gain_display));
-}
-
-void
-RouteTimeAxisView::effective_gain_display ()
-{
- gfloat value = gain_to_slider_position (_route->effective_gain());
- gain_adjustment.set_value (value);
-}
-
#include "enums.h"
#include "time_axis_view.h"
#include "canvas.h"
-#include "level_meter.h"
+#include "gain_meter.h"
namespace ARDOUR {
void show_selection (TimeSelection&);
void set_samples_per_unit (double);
- void set_height (TimeAxisView::TrackHeight);
+ void set_height (uint32_t h);
void show_timestretch (nframes_t start, nframes_t end);
void hide_timestretch ();
void selection_click (GdkEventButton*);
virtual void create_automation_child (ARDOUR::Parameter param, bool show) = 0;
+ /* make sure we get the right version of this */
+
+ XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param) { return RouteUI::get_automation_child_xml_node (param); }
+
typedef map<ARDOUR::Parameter, RouteAutomationNode*> AutomationTracks;
AutomationTracks automation_tracks() { return _automation_tracks; }
void clear_meter ();
void io_changed (ARDOUR::IOChange, void *);
void meter_changed (void *);
- void effective_gain_display ();
+ void effective_gain_display () { gm.effective_gain_display(); }
+
+ static void setup_slider_pix ();
protected:
friend class StreamView;
void post_construct ();
- void set_state (const XMLNode&);
-
- XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param);
+ GainMeterBase gm;
- LevelMeter lm;
+ static Glib::RefPtr<Gdk::Pixbuf> slider;
XMLNode* underlay_xml_node;
bool set_underlay_state();
UnderlayList _underlay_streams;
typedef list<RouteTimeAxisView*> UnderlayMirrorList;
UnderlayMirrorList _underlay_mirrors;
-
- Gtkmm2ext::HSliderController *gain_slider;
- Gtk::Adjustment gain_adjustment;
- static Glib::RefPtr<Gdk::Pixbuf> slider;
- static int setup_slider_pix ();
- void gain_adjusted();
-
- gint start_gain_touch (GdkEventButton*);
- gint end_gain_touch (GdkEventButton*);
- void gain_changed ();
};
#endif /* __ardour_route_time_axis_h__ */
_route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed));
- mute_button = manage (new BindableToggleButton (*_route->mute_control().get(), m_name ));
+ mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
mute_button->set_self_managed (true);
- solo_button = manage (new BindableToggleButton (*_route->solo_control().get(), s_name ));
+ solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
solo_button->set_self_managed (true);
mute_button->set_name ("MuteButton");
_session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
- rec_enable_button = manage (new BindableToggleButton (*t->rec_enable_control().get(), r_name ));
+ rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
rec_enable_button->set_name ("RecordEnableButton");
rec_enable_button->set_self_managed (true);
int set_color_from_route ();
- sigc::connection blink_connection;
-
- void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
-
void remove_this_route ();
static gint idle_remove_this_route (RouteUI *);
vbox.pack_start (hbox, false, false, false);
vbox.pack_start (panners, false,false);
- io = new IOSelector (se, s->io(), false);
+ io = manage (new IOSelector (se, s->io(), false));
pack_start (vbox, false, false);
SendUI::~SendUI ()
{
_send->set_metering (false);
-
+
/* XXX not clear that we need to do this */
screen_update_connection.disconnect();
add (vpacker);
set_name ("SendUIWindow");
-
- s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
+
+ going_away_connection = s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
signal_delete_event().connect (bind (ptr_fun (just_hide_it), reinterpret_cast<Window *> (this)));
{
ENSURE_GUI_THREAD (mem_fun (*this, &SendUIWindow::send_going_away));
delete_when_idle (this);
+ going_away_connection.disconnect ();
}
IOSelector* io;
+ boost::shared_ptr<ARDOUR::Send>& send() { return _send; }
+
private:
boost::shared_ptr<ARDOUR::Send> _send;
ARDOUR::Session& _session;
Gtk::HBox hpacker;
void send_going_away ();
+ sigc::connection going_away_connection;
};
#endif /* __ardour_gtk_send_ui_h__ */
found_list_view (found_list),
freesound_search_btn (_("Start Downloading")),
freesound_list_view (freesound_list)
-
{
resetting_ourselves = false;
gm = 0;
+ resetting_ourselves = false;
+ gm = 0;
+
if (ARDOUR::Profile->get_sae()) {
chooser.add_shortcut_folder_uri("file:///Library/GarageBand/Apple Loops");
chooser.add_shortcut_folder_uri("file:///Library/Application Support/GarageBand/Instrument Library/Sampler/Sampler Files");
}
+
//add the file chooser
{
chooser.set_border_width (12);
matchall_filter.add_pattern ("*.*");
matchall_filter.set_name (_("All files"));
-
+
chooser.add_filter (audio_filter);
chooser.add_filter (midi_filter);
chooser.add_filter (matchall_filter);
chooser.set_select_multiple (true);
chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
-
+
if (!persistent_folder.empty()) {
chooser.set_current_folder (persistent_folder);
}
VBox* vbox;
HBox* hbox;
- hpacker.set_spacing (6);
- hpacker.pack_start (notebook, true, true);
- hpacker.pack_start (preview, false, false);
-
- get_vbox()->pack_start (hpacker, true, true);
hbox = manage(new HBox);
hbox->pack_start (found_entry);
notebook.append_page (*vbox, _("Search Tags"));
}
-
//add freesound search
#ifdef FREESOUND
HBox* passbox;
Label* label;
- hpacker.set_spacing (6);
- hpacker.pack_start (notebook, true, true);
- hpacker.pack_start (preview, false, false);
-
- get_vbox()->pack_start (hpacker, true, true);
-
passbox = manage(new HBox);
passbox->set_border_width (12);
passbox->set_spacing (6);
//freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
freesound_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
-
freesound_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
freesound_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
-
notebook.append_page (*vbox, _("Search Freesound"));
}
#endif
for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) {
-
if (info.channels > 1) {
multichannel = true;
}
-
if (sz == 0) {
sz = info.length;
} else {
Gtk::FileFilter audio_filter;
Gtk::FileFilter midi_filter;
+ Gtk::FileFilter custom_filter;
Gtk::FileFilter matchall_filter;
Gtk::HBox hpacker;
canvas_rect->property_x1() = 0.0;
canvas_rect->property_y1() = 0.0;
canvas_rect->property_x2() = _trackview.editor.frame_to_pixel (max_frames);
- canvas_rect->property_y2() = (double) tv.height;
+ canvas_rect->property_y2() = (double) tv.current_height();
canvas_rect->property_outline_what() = (guint32) (0x2|0x8); // outline RHS and bottom
// (Fill/Outline colours set in derived classes)
void update_rec_box ();
//virtual void update_rec_regions () = 0;
- virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_data) = 0;
+ virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves, bool recording = false) = 0;
virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
//void remove_rec_region (boost::shared_ptr<ARDOUR::Region>); (unused)
double spu,
Gdk::Color& basic_color)
- : AudioRegionView (parent, tv, r, spu, basic_color,
+ : AudioRegionView (parent, tv, r, spu, basic_color, false,
TimeAxisViewItem::Visibility ((r->position() != 0) ? default_tape_visibility :
TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft)))
{
TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* rent, Canvas& canvas)
: AxisView (sess),
editor (ed),
- height_style(Small),
y_position(0),
order(0),
controls_table (2, 8)
_has_state = false;
last_name_entry_key_press_event = 0;
name_packing = NamePackingBits (0);
+ resize_drag_start = -1;
/*
Create the standard LHS Controls
controls_table.show_all ();
controls_table.set_no_show_all ();
+ resizer.set_size_request (10, 10);
+ resizer.set_name ("ResizeHandle");
+ resizer.signal_expose_event().connect (mem_fun (*this, &TimeAxisView::resizer_expose));
+ resizer.signal_button_press_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_press));
+ resizer.signal_button_release_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_release));
+ resizer.signal_motion_notify_event().connect (mem_fun (*this, &TimeAxisView::resizer_motion));
+ resizer.set_events (Gdk::BUTTON_PRESS_MASK|
+ Gdk::BUTTON_RELEASE_MASK|
+ Gdk::POINTER_MOTION_MASK|
+ Gdk::SCROLL_MASK);
+
+ resizer_box.pack_start (resizer, false, false);
+ resizer.show ();
+ resizer_box.show();
+
controls_vbox.pack_start (controls_table, false, false);
+ controls_vbox.pack_end (resizer_box, false, true);
controls_vbox.show ();
//controls_ebox.set_name ("TimeAxisViewControlsBaseUnselected");
_hidden = false;
/* height in pixels depends on _order, so update it now we've changed _order */
- set_height (height_style);
+ set_height (height);
- effective_height = height;
+ effective_height = current_height();
/* now show children */
if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
step_height (true);
return true;
+ } else if (Keyboard::no_modifiers_active (ev->state)) {
+ editor.scroll_tracks_up_line();
+ return true;
}
break;
if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
step_height (false);
return true;
+ } else if (Keyboard::no_modifiers_active (ev->state)) {
+ editor.scroll_tracks_down_line();
+ return true;
}
break;
void
TimeAxisView::step_height (bool bigger)
{
-
- if (height == hLargest) {
- if (!bigger) set_height (Large);
- return;
- }
- if (height == hLarge) {
- if (bigger) set_height (Largest);
- else set_height (Larger);
- return;
- }
- if (height == hLarger) {
- if (bigger) set_height (Large);
- else set_height (Normal);
- return;
- }
- if (height == hNormal) {
- if (bigger) set_height (Larger);
- else set_height (Smaller);
- return;
- }
- if (height == hSmaller) {
- if (bigger) set_height (Normal);
- else set_height (Small);
- return;
- }
- if (height == hSmall) {
- if (bigger) set_height (Smaller);
- return;
- }
+ static const uint32_t step = 20;
+
+ if (bigger) {
+ set_height (height + step);
+ } else {
+ if (height > step) {
+ set_height (std::max (height - step, hSmall));
+ } else if (height != hSmall) {
+ set_height (hSmall);
+ }
+ }
}
void
-TimeAxisView::set_heights (TrackHeight h)
+TimeAxisView::set_heights (uint32_t h)
{
TrackSelection& ts (editor.get_selection().tracks);
}
void
-TimeAxisView::set_height (TrackHeight h)
+TimeAxisView::set_height(uint32_t h)
{
- height_style = h;
- set_height_pixels (height_to_pixels (h));
+ height = h;
for (list<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
(*i)->set_height ();
}
-}
-void
-TimeAxisView::set_height_pixels (uint32_t h)
-{
- height = h;
- controls_hbox.set_size_request (-1, height + ((order == 0) ? 1 : 0));
- //cerr << "TimeAxisView::set_height_pixels() called h = " << h << endl;//DEBUG
if (canvas_item_visible (selection_group)) {
/* resize the selection rect */
show_selection (editor.get_selection().time);
}
-
+
+ reshow_feature_lines ();
}
bool
}
}
- if ((*i)->height_style == Small) {
- (*i)->set_height(Smaller);
+
+ /* resize to show editable name display */
+
+ if ((*i)->current_height() >= hSmall && (*i)->current_height() < hNormal) {
+ (*i)->set_height (hSmaller);
}
(*i)->name_entry.grab_focus();
Selection& s (editor.get_selection());
if (!s.selected (this)) {
- cerr << "set selected track\n";
editor.set_selected_track (*this, Selection::Set);
}
}
(*i)->set_selected (false);
}
}
+
+ resizer.queue_draw ();
}
void
size_menu->set_name ("ArdourContextMenu");
MenuList& items = size_menu->items();
- items.push_back (MenuElem (_("Largest"), bind (mem_fun (*this, &TimeAxisView::set_heights), Largest)));
- items.push_back (MenuElem (_("Large"), bind (mem_fun (*this, &TimeAxisView::set_heights), Large)));
- items.push_back (MenuElem (_("Larger"), bind (mem_fun (*this, &TimeAxisView::set_heights), Larger)));
- items.push_back (MenuElem (_("Normal"), bind (mem_fun (*this, &TimeAxisView::set_heights), Normal)));
- items.push_back (MenuElem (_("Smaller"), bind (mem_fun (*this, &TimeAxisView::set_heights),Smaller)));
- items.push_back (MenuElem (_("Small"), bind (mem_fun (*this, &TimeAxisView::set_heights), Small)));
+ items.push_back (MenuElem (_("Largest"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLargest)));
+ items.push_back (MenuElem (_("Large"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLarge)));
+ items.push_back (MenuElem (_("Larger"), bind (mem_fun (*this, &TimeAxisView::set_heights), hLarger)));
+ items.push_back (MenuElem (_("Normal"), bind (mem_fun (*this, &TimeAxisView::set_heights), hNormal)));
+ items.push_back (MenuElem (_("Smaller"), bind (mem_fun (*this, &TimeAxisView::set_heights),hSmaller)));
+ items.push_back (MenuElem (_("Small"), bind (mem_fun (*this, &TimeAxisView::set_heights), hSmall)));
}
void
x1 = editor.frame_to_unit (start);
x2 = editor.frame_to_unit (start + cnt - 1);
- y2 = height;
+ y2 = current_height();
rect->rect->property_x1() = x1;
rect->rect->property_y1() = 1.0;
y_position is the "origin" or "top" of the track.
*/
- double mybot = y_position + height;
+ double mybot = y_position + current_height();
return ((y_position <= bot && y_position >= top) ||
((mybot <= bot) && (top < mybot)) ||
return parent->get_parent_with_state ();
}
-void
+
+XMLNode&
+TimeAxisView::get_state ()
+{
+ XMLNode* node = new XMLNode ("TAV-" + name());
+ char buf[32];
+
+ snprintf (buf, sizeof(buf), "%u", height);
+ node->add_property ("height", buf);
+ node->add_property ("marked_for_display", (_marked_for_display ? "1" : "0"));
+ return *node;
+}
+
+int
TimeAxisView::set_state (const XMLNode& node)
{
const XMLProperty *prop;
+ if ((prop = node.property ("marked_for_display")) != 0) {
+ _marked_for_display = (prop->value() == "1");
+ }
+
if ((prop = node.property ("track_height")) != 0) {
if (prop->value() == "largest") {
- set_height (Largest);
+ set_height (hLargest);
} else if (prop->value() == "large") {
- set_height (Large);
+ set_height (hLarge);
} else if (prop->value() == "larger") {
- set_height (Larger);
+ set_height (hLarger);
} else if (prop->value() == "normal") {
- set_height (Normal);
+ set_height (hNormal);
} else if (prop->value() == "smaller") {
- set_height (Smaller);
+ set_height (hSmaller);
} else if (prop->value() == "small") {
- set_height (Small);
+ set_height (hSmall);
} else {
error << string_compose(_("unknown track height name \"%1\" in XML GUI information"), prop->value()) << endmsg;
set_height (Normal);
}
+ } else if ((prop = node.property ("height")) != 0) {
+
+ set_height (atoi (prop->value()));
+
} else {
- set_height (Normal);
+
+ set_height (hNormal);
}
+
+ return 0;
}
void
TimeAxisView::reset_height()
{
- set_height_pixels (height);
+ set_height (height);
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
- (*i)->set_height_pixels ((TrackHeight)(*i)->height);
+ (*i)->set_height ((*i)->height);
}
}
-uint32_t
-TimeAxisView::height_to_pixels (TrackHeight h)
-{
- switch (h) {
- case Largest:
- return hLargest;
- case Large:
- return hLarge;
- case Larger:
- return hLarger;
- case Normal:
- return hNormal;
- case Smaller:
- return hSmaller;
- case Small:
- return hSmall;
- }
-
- // what is wrong with gcc ?
-
- return hNormal;
-}
-
void
TimeAxisView::compute_controls_size_info ()
{
Gtk::Table one_row_table (1, 8);
Button* buttons[5];
const int border_width = 2;
- const int extra_height = (2 * border_width) + 2; // 2 pixels for the controls frame
+ const int extra_height = (2 * border_width) + 2 // 2 pixels for the controls frame
+ + 10; // resizer button
window.add (one_row_table);
while (feature_lines.size()< analysis_features.size()) {
ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*canvas_display);
l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();
- l->property_y1() = 0;
- l->property_y2() = height;
feature_lines.push_back (l);
}
for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) {
(*l)->property_x1() = editor.frame_to_pixel (*i);
(*l)->property_x2() = editor.frame_to_pixel (*i);
+ (*l)->property_y1() = 0;
+ (*l)->property_y2() = current_height();
(*l)->show ();
}
}
+bool
+TimeAxisView::resizer_button_press (GdkEventButton* event)
+{
+ resize_drag_start = event->y_root;
+ resize_idle_target = current_height();
+ editor.start_resize_line_ops ();
+ return true;
+}
+
+bool
+TimeAxisView::resizer_button_release (GdkEventButton* ev)
+{
+ resize_drag_start = -1;
+ editor.end_resize_line_ops ();
+ return true;
+}
+
+void
+TimeAxisView::idle_resize (uint32_t h)
+{
+ set_height (h);
+}
+
+bool
+TimeAxisView::resizer_motion (GdkEventMotion* ev)
+{
+ if (resize_drag_start < 0) {
+ return true;
+ }
+
+ int32_t delta = (int32_t) floor (resize_drag_start - ev->y_root);
+
+ resize_idle_target = std::max (resize_idle_target - delta, (int) hSmall);
+ editor.add_to_idle_resize (this, resize_idle_target);
+
+ resize_drag_start = ev->y_root;
+
+ return true;
+}
+
+bool
+TimeAxisView::resizer_expose (GdkEventExpose* event)
+{
+ int w, h, x, y, d;
+ Glib::RefPtr<Gdk::Window> win (resizer.get_window());
+ Glib::RefPtr<Gdk::GC> dark (resizer.get_style()->get_fg_gc (STATE_NORMAL));
+ Glib::RefPtr<Gdk::GC> light (resizer.get_style()->get_bg_gc (STATE_NORMAL));
+
+ win->draw_rectangle (controls_ebox.get_style()->get_bg_gc(STATE_NORMAL),
+ true,
+ event->area.x,
+ event->area.y,
+ event->area.width,
+ event->area.height);
+
+ win->get_geometry (x, y, w, h, d);
+
+ /* handle/line #1 */
+
+ win->draw_line (dark, 0, 0, w - 2, 0);
+ win->draw_point (dark, 0, 1);
+ win->draw_line (light, 1, 1, w - 1, 1);
+ win->draw_point (light, w - 1, 0);
+
+ /* handle/line #2 */
+
+ win->draw_line (dark, 0, 4, w - 2, 4);
+ win->draw_point (dark, 0, 5);
+ win->draw_line (light, 1, 5, w - 1, 5);
+ win->draw_point (light, w - 1, 4);
+
+ /* handle/line #3 */
+
+ win->draw_line (dark, 0, 8, w - 2, 8);
+ win->draw_point (dark, 0, 9);
+ win->draw_line (light, 1, 9, w - 1, 9);
+ win->draw_point (light, w - 1, 8);
+
+ return true;
+}
+
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
+#include <gtkmm/drawingarea.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/table.h>
#include <gtkmm/entry.h>
#include <gtkmm2ext/focus_entry.h>
+#include <pbd/stateful.h>
+
#include <ardour/types.h>
#include <ardour/region.h>
#include <ardour/parameter.h>
* This class provides the basic LHS controls and display methods. This should be
* extended to create functional time-axis based views.
*/
-class TimeAxisView : public virtual AxisView
+class TimeAxisView : public virtual AxisView, public PBD::Stateful
{
private:
enum NamePackingBits {
};
public:
- enum TrackHeight {
- Largest,
- Large,
- Larger,
- Normal,
- Smaller,
- Small
- };
-
static uint32_t hLargest;
static uint32_t hLarge;
static uint32_t hLarger;
static uint32_t hSmaller;
static uint32_t hSmall;
- static uint32_t height_to_pixels (TrackHeight);
-
TimeAxisView(ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* parent, ArdourCanvas::Canvas& canvas);
virtual ~TimeAxisView ();
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
/* public data: XXX create accessor/mutators for these ?? */
PublicEditor& editor;
- TrackHeight height_style;
- uint32_t height; /* in canvas units */
- uint32_t effective_height; /* in canvas units */
- double y_position;
- int order;
+ uint32_t effective_height; /* in canvas units */
+ double y_position;
+ int order;
- ArdourCanvas::Group *canvas_display;
- Gtk::VBox *control_parent;
+ uint32_t current_height() const { return height; }
+
+ ArdourCanvas::Group *canvas_display;
+ Gtk::VBox *control_parent;
/* The Standard LHS Controls */
Gtk::Frame controls_frame;
Gtk::Table controls_table;
Gtk::EventBox controls_ebox;
Gtk::VBox controls_vbox;
+ Gtk::DrawingArea resizer;
+ Gtk::HBox resizer_box;
Gtk::HBox name_hbox;
Gtk::Frame name_frame;
Gtkmm2ext::FocusEntry name_entry;
-
+
+ bool resizer_button_press (GdkEventButton*);
+ bool resizer_button_release (GdkEventButton*);
+ bool resizer_motion (GdkEventMotion*);
+ bool resizer_expose (GdkEventExpose*);
+
+ double resize_drag_start;
+ int32_t resize_idle_target;
+ void idle_resize (uint32_t);
+
void hide_name_label ();
void hide_name_entry ();
void show_name_label ();
virtual void entered () {}
virtual void exited () {}
- virtual void set_height (TrackHeight h);
+ virtual void set_height (uint32_t h);
void reset_height();
/**
void set_parent (TimeAxisView& p);
bool has_state () const;
- virtual void set_state (const XMLNode&);
- virtual XMLNode* get_state_node () { return 0; }
-
/* call this on the parent */
virtual XMLNode* get_automation_child_xml_node (ARDOUR::Parameter param) { return 0; }
typedef std::vector<boost::shared_ptr<TimeAxisView> > Children;
protected:
+ uint32_t height; /* in canvas units */
string controls_base_unselected_name;
string controls_base_selected_name;
static void compute_controls_size_info ();
static bool need_size_info;
- void set_heights (TrackHeight);
- void set_height_pixels (uint32_t h);
+ void set_heights (uint32_t h);
void color_handler ();
- list<ArdourCanvas::SimpleLine*> feature_lines;
+
+
+ std::list<ArdourCanvas::SimpleLine*> feature_lines;
ARDOUR::AnalysisFeatureList analysis_features;
void reshow_feature_lines ();
* @param duration the duration of this item
*/
TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color,
- nframes_t start, nframes_t duration,
+ nframes_t start, nframes_t duration, bool recording,
Visibility vis)
- : trackview (tv)
+ : trackview (tv), _recregion(recording)
{
if (!have_name_font) {
vestigial_frame->property_x1() = (double) 0.0;
vestigial_frame->property_y1() = (double) 1.0;
vestigial_frame->property_x2() = 2.0;
- vestigial_frame->property_y2() = (double) trackview.height;
+ vestigial_frame->property_y2() = (double) trackview.current_height();
vestigial_frame->property_outline_what() = 0xF;
vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
frame->property_x1() = (double) 0.0;
frame->property_y1() = (double) 1.0;
frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration);
- frame->property_y2() = (double) trackview.height;
+ frame->property_y2() = (double) trackview.current_height();
frame->property_outline_what() = 0xF;
frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
name_highlight->property_x1() = (double) 1.0;
name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)) - 1;
}
- name_highlight->property_y1() = (double) (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
- name_highlight->property_y2() = (double) (trackview.height - 1);
+ name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
+ name_highlight->property_y2() = (double) (trackview.current_height() - 1);
name_highlight->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightFill.get();
name_highlight->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightOutline.get();
if (visibility & ShowNameText) {
name_text = new ArdourCanvas::Text (*group);
name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
- /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
+ /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
then NAME_Y_OFFSET to position the text in the vertical center of the highlight
*/
- name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
+ name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
name_text->property_font_desc() = *NAME_FONT;
name_text->property_anchor() = Gtk::ANCHOR_NW;
UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
} else {
- UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
- frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+ if (_recregion) {
+ UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
+ frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
+ } else {
+ UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
+ frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
+ }
}
}
}
item = 0;
return false;
}
+
*/
void set_name_text(const Glib::ustring& new_name) ;
- virtual void set_y_position_and_height(double y, double h) ;
-
+ void set_y_position_and_height (double, double);
+
/**
*
*/
* the destructor, this allows us to capture the source of the deletion
* event
*/
+
sigc::signal<void,std::string,void*> ItemRemoved ;
/** Emitted when the name/Id of this item is changed */
/** Emitted when the mionimum item duration is changed */
sigc::signal<void,nframes_t,void*> MinDurationChanged ;
- protected:
-
enum Visibility {
ShowFrame = 0x1,
ShowNameHighlight = 0x2,
HideFrameTB = 0x40,
FullWidthNameHighlight = 0x80
};
-
+ protected:
/**
* Constructs a new TimeAxisViewItem.
*
* @param duration the duration of this item
*/
TimeAxisViewItem(const std::string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color,
- nframes_t start, nframes_t duration, Visibility v = Visibility (0));
+ nframes_t start, nframes_t duration, bool recording = false, Visibility v = Visibility (0));
TimeAxisViewItem (const TimeAxisViewItem& other);
std::map<Glib::ustring::size_type,int> name_text_size_cache;
Visibility visibility;
+ bool _recregion;
+
}; /* class TimeAxisViewItem */
#include <unistd.h>
#include <cstdio> /* for snprintf, grrr */
+#include <glibmm/miscutils.h>
+
#include <pbd/failed_constructor.h>
#include <pbd/xml++.h>
#include <pbd/filesystem.h>
{
XMLTree tree;
- try
- {
+ try {
sys::create_directories (user_config_directory ());
}
- catch (const sys::filesystem_error& ex)
- {
+ catch (const sys::filesystem_error& ex) {
error << "Could not create user configuration directory" << endmsg;
return -1;
}
#include <gtkmm2ext/utils.h>
#include <ardour/configuration.h>
+#include <ardour/configuration.h>
#include <ardour/filesystem_paths.h>
it does allow.
*/
- int fakekey = GDK_VoidSymbol;
- int ret = false;
-
- switch (ev->keyval) {
- case GDK_Tab:
- case GDK_ISO_Left_Tab:
- fakekey = GDK_nabla;
- break;
-
- case GDK_Up:
- fakekey = GDK_uparrow;
- break;
-
- case GDK_Down:
- fakekey = GDK_downarrow;
- break;
-
- case GDK_Right:
- fakekey = GDK_rightarrow;
- break;
-
- case GDK_Left:
- fakekey = GDK_leftarrow;
- break;
-
- default:
- break;
- }
+ uint32_t fakekey = ev->keyval;
- if (fakekey != GDK_VoidSymbol) {
- ret = gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state));
-
- if (ret) {
+ if (possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
+ if (gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
return true;
}
Glib::RefPtr<Gdk::Pixbuf>
get_xpm (std::string name)
{
- SearchPath spath(ARDOUR::ardour_search_path());
- spath += ARDOUR::system_data_search_path();
+ if (!xpm_map[name]) {
- spath.add_subdirectory_to_paths("pixmaps");
+ SearchPath spath(ARDOUR::ardour_search_path());
+ spath += ARDOUR::system_data_search_path();
+
+ spath.add_subdirectory_to_paths("pixmaps");
+
+ sys::path data_file_path;
+
+ if (!find_file_in_search_path (spath, name, data_file_path)) {
+ fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
+ /*NOTREACHED*/
+ }
- sys::path data_file_path;
+ try {
+ xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+ }
- if(!find_file_in_search_path (spath, name, data_file_path)) {
- fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
+ catch(const Glib::Error& e) {
+ warning << "Caught Glib::Error: " << e.what() << endmsg;
+ }
}
- return Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+ return xpm_map[name];
}
Glib::RefPtr<Gdk::Pixbuf>
DPIReset();//Emit Signal
}
+bool
+possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
+{
+ int fakekey = GDK_VoidSymbol;
+
+ switch (keyval) {
+ case GDK_Tab:
+ case GDK_ISO_Left_Tab:
+ fakekey = GDK_nabla;
+ break;
+
+ case GDK_Up:
+ fakekey = GDK_uparrow;
+ break;
+
+ case GDK_Down:
+ fakekey = GDK_downarrow;
+ break;
+
+ case GDK_Right:
+ fakekey = GDK_rightarrow;
+ break;
+
+ case GDK_Left:
+ fakekey = GDK_leftarrow;
+ break;
+
+ default:
+ break;
+ }
+
+ if (fakekey != GDK_VoidSymbol) {
+ keyval = fakekey;
+ return true;
+ }
+
+ return false;
+}
+
void set_color (Gdk::Color&, int);
bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev);
+bool possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval);
Glib::RefPtr<Gdk::Pixbuf> get_xpm (std::string);
Glib::RefPtr<Gdk::Pixbuf> get_icon (const char*);
hide_button.unset_flags(Gtk::CAN_FOCUS) ;
visual_button.unset_flags(Gtk::CAN_FOCUS) ;
- set_height(Normal) ;
+ set_height (hNormal) ;
}
/**
/**
* Sets the height of this TrackView to one of the defined TrackHeghts
*
- * @param h the TrackHeight value to set
+ * @param h
*/
void
-VisualTimeAxis::set_height(TrackHeight h)
+VisualTimeAxis::set_height(uint32_t h)
{
- TimeAxisView::set_height(h) ;
+ TimeAxisView::set_height(h);
- switch (height)
- {
- case Largest:
- case Large:
- case Larger:
- case Normal:
- {
- hide_name_label ();
- show_name_entry ();
- other_button_hbox.show_all() ;
- break;
- }
- case Smaller:
- {
- hide_name_label ();
- show_name_entry ();
- other_button_hbox.hide_all() ;
- break;
- }
- case Small:
- {
- hide_name_entry ();
- show_name_label ();
- other_button_hbox.hide_all() ;
- }
- break;
+ if (h >= hNormal) {
+ hide_name_label ();
+ show_name_entry ();
+ other_button_hbox.show_all() ;
+ } else if (h >= hSmaller) {
+ hide_name_label ();
+ show_name_entry ();
+ other_button_hbox.hide_all() ;
+ } else if (h >= hSmall) {
+ hide_name_entry ();
+ show_name_label ();
+ other_button_hbox.hide_all() ;
}
}
/**
* Sets the height of this TrackView to one of the defined TrackHeghts
*
- * @param h the TrackHeight value to set
+ * @param h the number of pixels to set the height to
*/
- virtual void set_height (TrackHeight h);
+ virtual void set_height (uint32_t);
//---------------------------------------------------------------------------------------//
// Selection Methods
return ValidateChannelPair (inChannelsIn, inChannelsOut, info.mChanInfo, (dataSize / sizeof (AUChannelInfo)));
}
+int CAAudioUnit::GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt)
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+
+ if (result)
+ {
+ if (Comp().Desc().IsEffect())
+ {
+ return 1;
+ }
+ else
+ {
+ // the au should either really tell us about this
+ // or we will assume the worst
+ return -1;
+ }
+ }
+
+ *chaninfo = (AUChannelInfo*) malloc (dataSize);
+ cnt = dataSize / sizeof (AUChannelInfo);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ *chaninfo, &dataSize);
+
+ if (result) { return -1; }
+ return 0;
+}
+
+
bool CAAudioUnit::ValidateChannelPair (int inChannelsIn,
int inChannelsOut,
const AUChannelInfo * info,
bool HasChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl) const;
+ int GetChannelInfo (AUChannelInfo** chaninfo, UInt32& cnt);
bool GetChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl,
ChannelTagVector &outChannelVector) const;
appleutility_files = glob.glob('*.cpp')
Import('env install_prefix')
-appleutility = env.Copy()
+appleutility = env.Clone()
appleutility.Append(LINKFLAGS='-framework AudioToolbox')
appleutility.Append(LINKFLAGS='-framework AudioUnit')
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-ardour = env.Copy()
+ardour = env.Clone()
#
# this defines the version number of libardour
midi_clock_slave.cc
named_selection.cc
note.cc
+onset_detector.cc
panner.cc
parameter.cc
pcm_utils.cc
always_sse_objects = []
-sse_env = ardour.Copy()
+sse_env = ardour.Clone()
sse_env.Append (CXXFLAGS="-msse")
if env['FPU_OPTIMIZATION']:
#include <ardour/configuration.h>
#include <ardour/types.h>
+// #include <jack/jack.h> need this to inline jack_get_microseconds
+
namespace MIDI {
class MachineControl;
class Port;
const layer_t max_layer = UCHAR_MAX;
microseconds_t get_microseconds ();
-
+/* {
+ JACK has exported this functionality for a long time now
+ but inlining this causes problems
+ return (microseconds_t) jack_get_time();
+ }
+*/
Change new_change ();
extern Change StartChanged;
void freeze (InterThreadInfo&);
void unfreeze ();
- void bounce (InterThreadInfo&);
- void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+ boost::shared_ptr<Region> bounce (InterThreadInfo&);
+ boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
int set_state(const XMLNode& node);
bool has_editor () const;
- bool fixed_io() const { return false; }
- int32_t can_support_input_configuration (int32_t in);
- int32_t compute_output_streams (int32_t nplugins);
- uint32_t output_streams() const;
- uint32_t input_streams() const;
+ bool reconfigurable_io() const { return true; }
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ int32_t count_for_configuration (const ChanCount& in, ChanCount out) const;
+ bool configure_io (ChanCount in, ChanCount& out);
+ ChanCount output_streams() const;
+ ChanCount input_streams() const;
boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
boost::shared_ptr<CAComponent> get_comp () const { return comp; }
boost::shared_ptr<CAComponent> comp;
boost::shared_ptr<CAAudioUnit> unit;
- AudioStreamBasicDescription streamFormat;
bool initialized;
- int format_set;
+ int32_t input_channels;
+ int32_t output_channels;
+ std::vector<std::pair<int,int> > io_configs;
AudioBufferList* buffers;
UInt32 global_elements;
UInt32 output_elements;
UInt32 input_elements;
- int set_output_format ();
- int set_input_format ();
- int set_stream_format (int scope, uint32_t cnt);
+ int set_output_format (AudioStreamBasicDescription&);
+ int set_input_format (AudioStreamBasicDescription&);
+ int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
int _set_block_size (nframes_t nframes);
void discover_parameters ();
std::vector<AUParameterDescriptor> descriptors;
void init ();
+
};
typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
+struct AUPluginCachedInfo {
+ std::vector<std::pair<int,int> > io_configs;
+};
+
class AUPluginInfo : public PluginInfo {
public:
AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
PluginPtr load (Session& session);
+ AUPluginCachedInfo cache;
+
static PluginInfoList discover ();
static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
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_by_description (PluginInfoList&, CAComponentDescription&);
+ static Glib::ustring au_cache_path ();
+
+ 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 ();
};
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
- uint32_t n_physical_outputs () const;
- uint32_t n_physical_inputs () const;
-
bool can_request_hardware_monitoring ();
- void get_physical_outputs (std::vector<std::string>&);
- void get_physical_inputs (std::vector<std::string>&);
+ uint32_t n_physical_outputs (DataType type) const;
+ uint32_t n_physical_inputs (DataType type) const;
+
+ void get_physical_outputs (DataType type, std::vector<std::string>&);
+ void get_physical_inputs (DataType type, std::vector<std::string>&);
std::string get_nth_physical_output (DataType type, uint32_t n) {
return get_nth_physical (type, n, JackPortIsInput);
/** Caller may not delete the object pointed to by the return value
*/
- Port *get_port_by_name (const std::string& name, bool keep = true) const;
+ Port *get_port_by_name (const std::string& name, bool keep = true);
enum TransportState {
TransportStopped = JackTransportStopped,
std::string make_port_name_non_relative (std::string);
private:
- ARDOUR::Session *session;
- jack_client_t *_jack;
- std::string jack_client_name;
- mutable Glib::Mutex _process_lock;
- Glib::Cond session_removed;
- bool session_remove_pending;
- bool _running;
- bool _has_run;
- nframes_t _buffer_size;
- nframes_t _frame_rate;
+ ARDOUR::Session* session;
+ jack_client_t* _jack;
+ std::string jack_client_name;
+ Glib::Mutex _process_lock;
+ Glib::Cond session_removed;
+ bool session_remove_pending;
+ bool _running;
+ bool _has_run;
+ nframes_t _buffer_size;
+ nframes_t _frame_rate;
/// number of frames between each check for changes in monitor input
- nframes_t monitor_check_interval;
+ nframes_t monitor_check_interval;
/// time of the last monitor check in frames
- nframes_t last_monitor_check;
+ nframes_t last_monitor_check;
/// the number of frames processed since start() was called
- nframes_t _processed_frames;
- bool _freewheeling;
- bool _freewheel_thread_registered;
- sigc::slot<int,nframes_t> freewheel_action;
- bool reconnect_on_halt;
- int _usecs_per_cycle;
+ nframes_t _processed_frames;
+ bool _freewheeling;
+ bool _freewheel_pending;
+ bool _freewheel_thread_registered;
+ sigc::slot<int,nframes_t> freewheel_action;
+ bool reconnect_on_halt;
+ int _usecs_per_cycle;
SerializedRCUManager<Ports> ports;
AutoBundle (bool i = true);
AutoBundle (std::string const &, bool i = true);
- uint32_t nchannels () const;
+ ChanCount nchannels () const;
const PortList& channel_ports (uint32_t) const;
void set_channels (uint32_t);
#include <cstdlib>
#include <cassert>
+#include <cstring>
#include <iostream>
#include <boost/utility.hpp>
+
#include <ardour/types.h>
#include <ardour/data_type.h>
#include <ardour/runtime_functions.h>
#include <string>
#include <sigc++/signal.h>
+
#include "ardour/data_type.h"
+#include "ardour/chan_count.h"
namespace ARDOUR {
Bundle () : _type (DataType::AUDIO) {}
Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
+
virtual ~Bundle() {}
/**
* @return Number of channels that this Bundle has.
*/
- virtual uint32_t nchannels () const = 0;
+ virtual ChanCount nchannels () const = 0;
virtual const PortList& channel_ports (uint32_t) const = 0;
void set_name (std::string const & n) {
CONFIG_VARIABLE (bool, primary_clock_delta_edit_cursor, "primary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, secondary_clock_delta_edit_cursor, "secondary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, show_track_meters, "show-track-meters", true)
+CONFIG_VARIABLE (bool, locate_while_waiting_for_sync, "locate-while-waiting-for-sync", false)
/* timecode and sync */
CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
+CONFIG_VARIABLE (bool, name_new_markers, "name-new-markers", false)
CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
int create_ports (const XMLNode&);
int make_connections (const XMLNode&);
+ boost::shared_ptr<Bundle> find_possible_bundle (const string &desired_name, const string &default_name, const string &connection_type_name);
void setup_peak_meters ();
void meter ();
void reset ();
void reset_max ();
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
bool configure_io (ChanCount in, ChanCount out);
/** Compute peaks */
void freeze (InterThreadInfo&);
void unfreeze ();
- void bounce (InterThreadInfo&);
- void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+ boost::shared_ptr<Region> bounce (InterThreadInfo&);
+ boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
int set_state(const XMLNode& node);
--- /dev/null
+/*
+ Copyright (C) 2008 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 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.
+
+*/
+
+#ifndef __ardour_onset_detector_h__
+#define __ardour_onset_detector_h__
+
+#include <ardour/audioanalyser.h>
+
+namespace ARDOUR {
+
+class AudioSource;
+class Session;
+
+class OnsetDetector : public AudioAnalyser
+{
+
+ public:
+ OnsetDetector (float sample_rate);
+ ~OnsetDetector();
+
+ static std::string operational_identifier();
+
+ 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);
+
+ static void cleanup_onsets (AnalysisFeatureList&, float sr, float gap_msecs);
+
+ protected:
+ AnalysisFeatureList* current_results;
+ int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
+
+ static std::string _op_id;
+};
+
+} /* namespace */
+
+#endif /* __ardour_audioanalyser_h__ */
lo_server _osc_server;
lo_server _osc_unix_server;
std::string _osc_unix_socket_path;
- std::string _osc_url_file;
+ std::string _osc_url_file;
pthread_t _osc_thread;
int _request_pipe[2];
static void * _osc_receiver(void * arg);
void osc_receiver();
+ void send(); // This should accept an OSC payload
bool init_osc_thread ();
void terminate_osc_thread ();
void session_going_away ();
+ // Handlers for "Application Hook" signals
+ void session_loaded( ARDOUR::Session& );
+ void session_exported( std::string, std::string );
+ // end "Application Hook" handles
+
std::string get_server_url ();
std::string get_unix_server_url ();
PATH_CALLBACK(rec_enable_toggle);
PATH_CALLBACK(toggle_all_rec_enables);
-#define PATH_CALLBACK1(name,type) \
+#define PATH_CALLBACK1(name,type,optional) \
static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
} \
int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
- if (argc > 0) { \
- name (argv[0]->type); \
- }\
- return 0; \
+ if (argc > 0) { \
+ name (optional argv[0]->type); \
+ } \
+ return 0; \
}
- PATH_CALLBACK1(set_transport_speed,f);
+ PATH_CALLBACK1(set_transport_speed,f,);
+ PATH_CALLBACK1(access_action,s,&);
};
}
virtual bool has_editor() const = 0;
+ sigc::signal<void,uint32_t,float> ParameterChanged;
+
+ /* NOTE: this block of virtual methods looks like the interface
+ to a Processor, but Plugin does not inherit from Processor.
+ It is therefore not required that these precisely match
+ the interface, but it is likely that they will evolve together.
+ */
+
+ /* this returns true if the plugin can change its inputs or outputs on demand.
+ LADSPA, LV2 and VST plugins cannot do this. AudioUnits can.
+ */
+
+ virtual bool reconfigurable_io() const { return false; }
+
+ /* this is only called if reconfigurable_io() returns true */
+ virtual bool configure_io (ChanCount in, ChanCount out) { return true; }
+
+ /* specific types of plugins can overload this. As of September 2008, only
+ AUPlugin does this.
+ */
+ virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return false; }
+ virtual ChanCount output_streams() const;
+ virtual ChanCount input_streams() const;
+
+ PBD::Controllable *get_nth_control (uint32_t, bool do_not_create = false);
+ void make_nth_control (uint32_t, const XMLNode&);
+
PluginInfoPtr get_info() { return _info; }
void set_info (const PluginInfoPtr inf) { _info = inf; }
bool set_count (uint32_t num);
uint32_t get_count () const { return _plugins.size(); }
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool configure_io (ChanCount in, ChanCount out);
bool is_generator() const;
- void set_parameter (Parameter param, float val);
+ void set_parameter (Parameter param, float val);
float get_parameter (Parameter param);
float default_parameter_value (Parameter param);
#include <list>
#include <map>
#include <string>
+#include <set>
#include <ardour/types.h>
#include <ardour/plugin.h>
static PluginManager* the_manager() { return _manager; }
+ void load_favorites ();
+ void save_favorites ();
+ void add_favorite (ARDOUR::PluginType type, std::string unique_id);
+ void remove_favorite (ARDOUR::PluginType type, std::string unique_id);
+ bool is_a_favorite_plugin (const PluginInfoPtr&);
+
private:
+ struct FavoritePlugin {
+ ARDOUR::PluginType type;
+ std::string unique_id;
+
+ FavoritePlugin (ARDOUR::PluginType t, std::string id)
+ : type (t), unique_id (id) {}
+
+ bool operator==(const FavoritePlugin& other) const {
+ return other.type == type && other.unique_id == unique_id;
+ }
+
+ bool operator<(const FavoritePlugin& other) const {
+ return other.type < type || other.unique_id < unique_id;
+ }
+ };
+ typedef std::set<FavoritePlugin> FavoritePluginList;
+ FavoritePluginList favorites;
+
ARDOUR::PluginInfoList _vst_plugin_info;
ARDOUR::PluginInfoList _ladspa_plugin_info;
ARDOUR::PluginInfoList _lv2_plugin_info;
#include <set>
#include <vector>
#include <string>
-
+#include <cstring>
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
ChanCount output_streams() const;
ChanCount input_streams() const;
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }
+ bool configure_io (ChanCount in, ChanCount out);
uint32_t bit_slot() const { return bitslot; }
virtual void activate () { _active = true; ActiveChanged.emit(); }
virtual void deactivate () { _active = false; ActiveChanged.emit(); }
- virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); }
+ virtual bool configure_io (ChanCount in, ChanCount out);
/* Derived classes should override these, or processor appears as an in-place pass-through */
* and write to their output parameter */
virtual bool is_out_of_place () const { return false; }
- virtual bool can_support_input_configuration (ChanCount in) const { return true; }
- virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; }
+ virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0;
virtual ChanCount output_streams() const { return _configured_input; }
virtual ChanCount input_streams () const { return _configured_input; }
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
- int reset_plugin_counts (ProcessorStreams*); /* locked */
- int _reset_plugin_counts (ProcessorStreams*); /* unlocked */
+ int reset_processor_counts (ProcessorStreams*); /* locked */
+ int _reset_processor_counts (ProcessorStreams*); /* unlocked */
/* processor I/O channels and plugin count handling */
ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {}
};
- int32_t apply_some_plugin_counts (std::list<ProcessorCount>& iclist);
- bool check_some_plugin_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
+ int32_t apply_some_processor_counts (std::list<ProcessorCount>& iclist);
+ bool check_some_processor_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
void set_deferred_state ();
void add_processor_from_xml (const XMLNode&);
int set_state(const XMLNode& node);
uint32_t pans_required() const { return _configured_input.n_audio(); }
+ void expect_inputs (const ChanCount&);
- virtual bool can_support_input_configuration (ChanCount in) const;
- virtual ChanCount output_for_input_configuration (ChanCount in) const;
- virtual bool configure_io (ChanCount in, ChanCount out);
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
+ bool configure_io (ChanCount in, ChanCount out);
static uint32_t how_many_sends();
private:
bool _metering;
- uint32_t bitslot;
+ ChanCount expected_inputs;
+ uint32_t bitslot;
};
} // namespace ARDOUR
nframes_t worst_input_latency () const { return _worst_input_latency; }
nframes_t worst_track_latency () const { return _worst_track_latency; }
- int save_state (string snapshot_name, bool pending = false);
- int restore_state (string snapshot_name);
- int save_template (string template_name);
- int save_history (string snapshot_name = "");
- int restore_history (string snapshot_name);
- void remove_state (string snapshot_name);
- void rename_state (string old_name, string new_name);
+ int save_state (std::string snapshot_name, bool pending = false);
+ int restore_state (std::string snapshot_name);
+ int save_template (std::string template_name);
+ int save_history (std::string snapshot_name = "");
+ int restore_history (std::string snapshot_name);
+ void remove_state (std::string snapshot_name);
+ void rename_state (std::string old_name, std::string new_name);
void remove_pending_capture_state ();
+ static int rename_template (std::string old_name, std::string new_name);
+ static int delete_template (std::string name);
+
sigc::signal<void,string> StateSaved;
sigc::signal<void> StateReady;
sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
- int region_name (string& result, string base = string(""), bool newlevel = false) const;
+ int region_name (string& result, string base = string(""), bool newlevel = false);
string new_region_name (string);
string path_from_region_name (DataType type, string name, string identifier);
SlaveSource post_export_slave;
nframes_t post_export_position;
- int start_export (ARDOUR::ExportSpecification&);
- int stop_export (ARDOUR::ExportSpecification&);
- void finalize_audio_export ();
+ int pre_export ();
+ int start_export (ARDOUR::ExportSpecification&);
+ int stop_export (ARDOUR::ExportSpecification&);
+ void finalize_export ();
+ static sigc::signal<void, std::string, std::string> Exported;
void add_source (boost::shared_ptr<Source>);
void remove_source (boost::weak_ptr<Source>);
/* flattening stuff */
- int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite,
- vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot);
-
+ boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end, bool overwrite, vector<boost::shared_ptr<Source> >&,
+ InterThreadInfo& wot);
int freeze (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
void reset_playback_load_min ();
void reset_capture_load_min ();
- float read_data_rate () const;
+ float read_data_rate () const; // in usec
float write_data_rate () const;
/* ranges */
void set_slave_source (SlaveSource);
bool _exporting;
+
int prepare_to_export (ARDOUR::ExportSpecification&);
void prepare_diskstreams ();
void set_play_loop (bool yn);
void overwrite_some_buffers (Diskstream*);
void flush_all_inserts ();
+ int micro_locate (nframes_t distance);
void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (nframes_t frame, bool with_roll = false);
/* REGION MANAGEMENT */
+ std::map<std::string,uint32_t> region_name_map;
+ void update_region_name_map (boost::shared_ptr<Region>);
+
mutable Glib::Mutex region_lock;
typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
RegionList regions;
virtual void freeze (InterThreadInfo&) = 0;
virtual void unfreeze () = 0;
- virtual void bounce (InterThreadInfo&) = 0;
- virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
+ virtual boost::shared_ptr<Region> bounce (InterThreadInfo&) = 0;
+ virtual boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
XMLNode& get_state();
XMLNode& get_template();
UserBundle (std::string const &);
UserBundle (XMLNode const &, bool);
- uint32_t nchannels () const;
+ ChanCount nchannels () const;
const ARDOUR::PortList& channel_ports (uint32_t) const;
void add_channel ();
/* if per-track or global rec-enable turned on while the other was already on, we've started recording */
if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) ||
- (((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled())))) {
+ ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
/* starting to record: compute first+last frames */
commit_should_unlock = false;
- if (!_io->active()) {
+ if (!_io || !_io->active()) {
_processed = true;
return 0;
}
{
bool need_butler = false;
- if (!_io->active()) {
+ if (!_io || !_io->active()) {
return false;
}
#include <libxml/uri.h>
#include <lrdf.h>
+#include <glibmm/miscutils.h>
#include <glibmm/convert.h>
// workaround for possible bug in raptor that crashes when saving to a
// non-existant file.
+
touch_file(sfdb_file_path.to_string());
lrdf_read_file(src.c_str());
return 0;
}
-void
+boost::shared_ptr<Region>
AudioTrack::bounce (InterThreadInfo& itt)
{
vector<boost::shared_ptr<Source> > srcs;
- _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
- itt.done = true;
+ return _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), false, srcs, itt);
}
-
-void
+boost::shared_ptr<Region>
AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
{
vector<boost::shared_ptr<Source> > srcs;
- _session.write_one_audio_track (*this, start, end, false, srcs, itt);
- itt.done = true;
+ return _session.write_one_track (*this, start, end, false, srcs, itt);
}
void
return;
}
- if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) {
+ boost::shared_ptr<Region> res;
+
+ if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
return;
}
#include <pbd/whitespace.h>
#include <glibmm/thread.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+#include <ardour/ardour.h>
#include <ardour/audioengine.h>
#include <ardour/io.h>
#include <ardour/audio_unit.h>
using namespace PBD;
using namespace ARDOUR;
+AUPluginInfo::CachedInfoMap AUPluginInfo::cached_info;
+
static OSStatus
_render_callback(void *userData,
AudioUnitRenderActionFlags *ioActionFlags,
unit->GetElementCount (kAudioUnitScope_Input, input_elements);
unit->GetElementCount (kAudioUnitScope_Output, output_elements);
- // set up the basic stream format. these fields do not change
-
- streamFormat.mSampleRate = _session.frame_rate();
- streamFormat.mFormatID = kAudioFormatLinearPCM;
- streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
-
-#ifdef __LITTLE_ENDIAN__
- /* relax */
-#else
- streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
-#endif
-
- streamFormat.mBitsPerChannel = 32;
- streamFormat.mFramesPerPacket = 1;
-
- // subject to later modification as we discover channel counts
-
- streamFormat.mBytesPerPacket = 4;
- streamFormat.mBytesPerFrame = 4;
- streamFormat.mChannelsPerFrame = 1;
+ /* these keep track of *configured* channel set up,
+ not potential set ups.
+ */
- format_set = 0;
+ input_channels = -1;
+ output_channels = -1;
if (_set_block_size (_session.get_block_size())) {
error << _("AUPlugin: cannot set processing block size") << endmsg;
return 0;
}
-int32_t
-AUPlugin::can_support_input_configuration (int32_t in)
-{
- streamFormat.mChannelsPerFrame = in;
+int32_t
+AUPlugin::configure_io (ChanCount in, ChanCount out)
+{
+ AudioStreamBasicDescription streamFormat;
+
+ streamFormat.mSampleRate = _session.frame_rate();
+ streamFormat.mFormatID = kAudioFormatLinearPCM;
+ streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
+
+#ifdef __LITTLE_ENDIAN__
+ /* relax */
+#else
+ streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+
+ streamFormat.mBitsPerChannel = 32;
+ streamFormat.mFramesPerPacket = 1;
+
/* apple says that for non-interleaved data, these
values always refer to a single channel.
*/
streamFormat.mBytesPerPacket = 4;
streamFormat.mBytesPerFrame = 4;
- if (set_input_format () == 0) {
- return 1;
- } else {
+ streamFormat.mChannelsPerFrame = in.n_audio();
+
+ if (set_input_format (streamFormat) != 0) {
+ return -1;
+ }
+
+ streamFormat.mChannelsPerFrame = out.n_audio();
+
+ if (set_output_format (streamFormat) != 0) {
return -1;
}
+
+ return Plugin::configure_io (in, out);
+}
+
+bool
+AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out)
+{
+ int32_t ret = count_for_configuration (in, out);
+ return ret >= 0;
+}
+
+int32_t
+AUPlugin::count_for_configuration(ChanCount cin, ChanCount& out) const
+{
+ // XXX as of May 13th 2008, AU plugin support returns a count of either 1 or -1. We never
+ // attempt to multiply-instantiate plugins to meet io configurations.
+
+ int32_t plugcnt = -1;
+ AUPluginInfoPtr pinfo = boost::dynamic_pointer_cast<AUPluginInfo>(get_info());
+ int32_t in = cin.n_audio(); /* XXX handle MIDI one day ??? */
+
+ vector<pair<int,int> >& io_configs = pinfo->cache.io_configs;
+
+ for (vector<pair<int,int> >::iterator i = io_configs.begin(); i != io_configs.end(); ++i) {
+
+ int32_t possible_in = i->first;
+ int32_t possible_out = i->second;
+
+ if (possible_out == 0) {
+ warning << string_compose (_("AU %1 has zero outputs - configuration ignored"), name()) << endmsg;
+ continue;
+ }
+
+ if (possible_in == 0) {
+
+ /* instrument plugin, always legal but throws away inputs ...
+ */
+
+ if (possible_out == -1) {
+ /* out much match in (UNLIKELY!!) */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == -1) {
+
+ /* wildcard for input */
+
+ if (possible_out == -1) {
+ /* out much match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == -2) {
+
+ if (possible_out == -1) {
+ /* any configuration possible, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+ << endmsg;
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in < -2) {
+
+ /* explicit variable number of inputs */
+
+ if (in > -possible_in) {
+ /* request is too large */
+ plugcnt = -1;
+ }
+
+ if (possible_out == -1) {
+ /* out must match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ error << string_compose (_("AU plugin %1 has illegal IO configuration (-2,-2)"), name())
+ << endmsg;
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ if (possible_in == in) {
+
+ /* exact number of inputs ... must match obviously */
+
+ if (possible_out == -1) {
+ /* out must match in */
+ out.set (DataType::AUDIO, in);
+ plugcnt = 1;
+ } else if (possible_out == -2) {
+ /* any output configuration, pick matching */
+ out.set (DataType::AUDIO, in);
+ plugcnt = -1;
+ } else if (possible_out < -2) {
+ /* explicit variable number of outputs, pick maximum */
+ out.set (DataType::AUDIO, -possible_out);
+ plugcnt = 1;
+ } else {
+ /* exact number of outputs */
+ out.set (DataType::AUDIO, possible_out);
+ plugcnt = 1;
+ }
+ }
+
+ }
+
+ /* no fit */
+ return plugcnt;
}
int
-AUPlugin::set_input_format ()
+AUPlugin::set_input_format (AudioStreamBasicDescription& fmt)
{
- return set_stream_format (kAudioUnitScope_Input, input_elements);
+ return set_stream_format (kAudioUnitScope_Input, input_elements, fmt);
}
int
-AUPlugin::set_output_format ()
+AUPlugin::set_output_format (AudioStreamBasicDescription& fmt)
{
- return set_stream_format (kAudioUnitScope_Output, output_elements);
+ if (set_stream_format (kAudioUnitScope_Output, output_elements, fmt) != 0) {
+ return -1;
+ }
+
+ if (buffers) {
+ free (buffers);
+ buffers = 0;
+ }
+
+ buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
+ fmt.mChannelsPerFrame * sizeof(AudioBuffer));
+
+ Glib::Mutex::Lock em (_session.engine().process_lock());
+ IO::PortCountChanged (ChanCount (DataType::AUDIO, fmt.mChannelsPerFrame));
+
+ return 0;
}
int
-AUPlugin::set_stream_format (int scope, uint32_t cnt)
+AUPlugin::set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription& fmt)
{
OSErr result;
for (uint32_t i = 0; i < cnt; ++i) {
- if ((result = unit->SetFormat (scope, i, streamFormat)) != 0) {
+ if ((result = unit->SetFormat (scope, i, fmt)) != 0) {
error << string_compose (_("AUPlugin: could not set stream format for %1/%2 (err = %3)"),
(scope == kAudioUnitScope_Input ? "input" : "output"), i, result) << endmsg;
return -1;
}
if (scope == kAudioUnitScope_Input) {
- format_set |= 0x1;
+ input_channels = fmt.mChannelsPerFrame;
} else {
- format_set |= 0x2;
+ output_channels = fmt.mChannelsPerFrame;
}
return 0;
}
-int32_t
-AUPlugin::compute_output_streams (int32_t nplugins)
-{
- /* we will never replicate AU plugins - either they can do the I/O we need
- or not. thus, we can ignore nplugins entirely.
- */
-
- if (set_output_format() == 0) {
- if (buffers) {
- free (buffers);
- buffers = 0;
- }
-
- buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) +
- streamFormat.mChannelsPerFrame * sizeof(AudioBuffer));
-
- Glib::Mutex::Lock em (_session.engine().process_lock());
- IO::MoreOutputs (streamFormat.mChannelsPerFrame);
+ChanCount
+AUPlugin::input_streams() const
+{
+ ChanCount in;
- return streamFormat.mChannelsPerFrame;
+ if (input_channels < 0) {
+ warning << string_compose (_("AUPlugin: %1 input_streams() called without any format set!"), name()) << endmsg;
+ in.set_audio (1);
} else {
- return -1;
+ in.set_audio (input_channels);
}
+
+ return in;
}
-uint32_t
+
+ChanCount
AUPlugin::output_streams() const
{
- if (!(format_set & 0x2)) {
+ ChanCount out;
+
+ if (output_channels < 0) {
warning << string_compose (_("AUPlugin: %1 output_streams() called without any format set!"), name()) << endmsg;
- return 1;
+ out.set_audio (1);
+ } else {
+ out.set_audio (output_channels);
}
- return streamFormat.mChannelsPerFrame;
-}
-
-
-uint32_t
-AUPlugin::input_streams() const
-{
- if (!(format_set & 0x1)) {
- warning << _("AUPlugin: input_streams() called without any format set!") << endmsg;
- return 1;
- }
- return streamFormat.mChannelsPerFrame;
+ return out;
}
OSStatus
}
catch (failed_constructor &err) {
- return PluginPtr ((Plugin*) 0);
+ return PluginPtr ();
}
}
+Glib::ustring
+AUPluginInfo::au_cache_path ()
+{
+ return Glib::build_filename (ARDOUR::get_user_ardour_path(), "au_cache");
+}
+
PluginInfoList
AUPluginInfo::discover ()
{
+ XMLTree tree;
+
+ if (!Glib::file_test (au_cache_path(), Glib::FILE_TEST_EXISTS)) {
+ ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
+ }
+
PluginInfoList plugs;
discover_fx (plugs);
info->type = ARDOUR::AudioUnit;
info->unique_id = stringify_descriptor (*info->descriptor);
- /* mark the plugin as having flexible i/o */
+ /* XXX not sure of the best way to handle plugin versioning yet
+ */
+
+ CAComponent cacomp (*info->descriptor);
+
+ if (cacomp.GetResourceVersion (info->version) != noErr) {
+ info->version = 0;
+ }
- info->n_inputs = -1;
- info->n_outputs = -1;
+ 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
+ of values.
+ */
+
+ info->n_inputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().first);
+ info->n_outputs = ChanCount (DataType::AUDIO, info->cache.io_configs.front().second);
+
+ if (info->cache.io_configs.size() > 1) {
+ cerr << "ODD: variable IO config for " << info->unique_id << endl;
+ }
+
+ plugs.push_back (info);
- plugs.push_back (info);
+ } 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,
+ UInt32 version,
+ CAComponent& comp,
+ AUPluginCachedInfo& cinfo,
+ const std::string& name)
+{
+ std::string id;
+ char buf[32];
+
+ /* concatenate unique ID with version to provide a key for cached info lookup.
+ this ensures we don't get stale information, or should if plugin developers
+ follow Apple "guidelines".
+ */
+
+ snprintf (buf, sizeof (buf), "%u", version);
+ id = unique_id;
+ id += '/';
+ id += buf;
+
+ CachedInfoMap::iterator cim = cached_info.find (id);
+
+ if (cim != cached_info.end()) {
+ cinfo = cim->second;
+ return true;
+ }
+
+ CAAudioUnit unit;
+ AUChannelInfo* channel_info;
+ UInt32 cnt;
+ int ret;
+
+ ARDOUR::BootMessage (string_compose (_("Checking AudioUnit: %1"), name));
+
+ if (CAAudioUnit::Open (comp, unit) != noErr) {
+ return false;
+ }
+
+ if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
+ return false;
+ }
+
+ if (ret > 0) {
+ /* no explicit info available */
+
+ 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));
+ }
+
+ free (channel_info);
+ }
+
+ add_cached_info (id, cinfo);
+ save_cached_info ();
+
+ return true;
+}
+
+void
+AUPluginInfo::add_cached_info (const std::string& id, AUPluginCachedInfo& cinfo)
+{
+ cached_info[id] = cinfo;
+}
+
+void
+AUPluginInfo::save_cached_info ()
+{
+ XMLNode* node;
+
+ node = new XMLNode (X_("AudioUnitPluginCache"));
+
+ 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);
+ node->add_child_nocopy (*parent);
+
+ for (vector<pair<int, int> >::iterator j = i->second.io_configs.begin(); j != i->second.io_configs.end(); ++j) {
+
+ XMLNode* child = new XMLNode (X_("io"));
+ char buf[32];
+
+ snprintf (buf, sizeof (buf), "%d", j->first);
+ child->add_property (X_("in"), buf);
+ snprintf (buf, sizeof (buf), "%d", j->second);
+ child->add_property (X_("out"), buf);
+ parent->add_child_nocopy (*child);
+ }
+
+ }
+
+ Glib::ustring path = au_cache_path ();
+ XMLTree tree;
+
+ tree.set_root (node);
+
+ if (!tree.write (path)) {
+ error << string_compose (_("could not save AU cache to %1"), path) << endmsg;
+ unlink (path.c_str());
+ }
+}
+
+int
+AUPluginInfo::load_cached_info ()
+{
+ Glib::ustring path = au_cache_path ();
+ XMLTree tree;
+
+ if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
+ return 0;
+ }
+
+ tree.read (path);
+ const XMLNode* root (tree.root());
+
+ if (root->name() != X_("AudioUnitPluginCache")) {
+ 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;
+ const XMLNodeList gchildren = child->children();
+ const XMLProperty* prop = child->property (X_("id"));
+
+ if (!prop) {
+ continue;
+ }
+
+ std::string id = prop->value();
+
+ for (XMLNodeConstIterator giter = gchildren.begin(); giter != gchildren.end(); giter++) {
+
+ gchild = *giter;
+
+ if (gchild->name() == X_("io")) {
+
+ int in;
+ int out;
+ const XMLProperty* iprop;
+ const XMLProperty* oprop;
+
+ if (((iprop = gchild->property (X_("in"))) != 0) &&
+ ((oprop = gchild->property (X_("out"))) != 0)) {
+ in = atoi (iprop->value());
+ out = atoi (iprop->value());
+
+ AUPluginCachedInfo cinfo;
+ cinfo.io_configs.push_back (pair<int,int> (in, out));
+ add_cached_info (id, cinfo);
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
void
AUPluginInfo::get_names (CAComponentDescription& comp_desc, std::string& name, Glib::ustring& maker)
{
last_monitor_check = 0;
monitor_check_interval = max_frames;
_processed_frames = 0;
- _freewheeling = false;
_usecs_per_cycle = 0;
_jack = 0;
_frame_rate = 0;
_buffer_size = 0;
- _freewheeling = false;
_freewheel_thread_registered = false;
+ _freewheeling = false;
m_meter_thread = 0;
g_atomic_int_set (&m_meter_exit, 0);
if (connect_to_jack (client_name)) {
throw NoBackendAvailable ();
}
+
Port::set_engine (this);
}
if (_freewheeling) {
/* emit the Freewheel signal and stop freewheeling in the event of trouble */
if (Freewheel (nframes)) {
- cerr << "Freewheeling returned non-zero!\n";
- _freewheeling = false;
jack_set_freewheel (_jack, false);
}
* Note this can return NULL, it will NOT create a port if it is not found (any more).
*/
Port *
-AudioEngine::get_port_by_name (const string& portname, bool keep) const
+AudioEngine::get_port_by_name (const string& portname, bool keep)
{
Glib::Mutex::Lock lm (_process_lock);
uint32_t
-AudioEngine::n_physical_outputs () const
+AudioEngine::n_physical_outputs (DataType type) const
{
const char ** ports;
uint32_t i = 0;
return 0;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
return 0;
}
}
uint32_t
-AudioEngine::n_physical_inputs () const
+AudioEngine::n_physical_inputs (DataType type) const
{
const char ** ports;
uint32_t i = 0;
return 0;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
return 0;
}
}
void
-AudioEngine::get_physical_inputs (vector<string>& ins)
+AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
{
const char ** ports;
uint32_t i = 0;
return;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsOutput)) == 0) {
return;
}
}
void
-AudioEngine::get_physical_outputs (vector<string>& outs)
+AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
{
const char ** ports;
uint32_t i = 0;
return;
}
- if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+ if ((ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|JackPortIsInput)) == 0) {
return;
}
{
if (_jack) {
- if (onoff) {
- _freewheel_thread_registered = false;
- }
+ if (onoff != _freewheeling) {
- return jack_set_freewheel (_jack, onoff);
+ if (onoff) {
+ _freewheel_thread_registered = false;
+ }
+
+ return jack_set_freewheel (_jack, onoff);
+
+ } else {
+ /* already doing what has been asked for */
+ return 0;
+ }
} else {
return -1;
void
AudioRegion::source_offset_changed ()
{
+ /* XXX this fixes a crash that should not occur. It does occur
+ becauses regions are not being deleted when a session
+ is unloaded. That bug must be fixed.
+ */
+
+ if (_sources.empty()) {
+ return;
+ }
+
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
if (afs && afs->destructive()) {
/* we found it in the peaks dir, so check it out */
- if (statbuf.st_size == 0 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
+ if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
// empty
_peaks_built = false;
} else {
}
-uint32_t
+ARDOUR::ChanCount
ARDOUR::AutoBundle::nchannels () const
{
Glib::Mutex::Lock lm (_ports_mutex);
- return _ports.size ();
+ return ChanCount (type(), _ports.size ());
}
const ARDOUR::PortList&
ARDOUR::AutoBundle::channel_ports (uint32_t c) const
{
- assert (c < nchannels());
+ assert (c < nchannels().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return _ports[c];
void
ARDOUR::AutoBundle::set_port (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
_ports[c].resize (1);
#include <glib.h>
#include <glib/gstdio.h> /* for g_stat() */
+#include <glibmm/miscutils.h>
#include <pbd/failed_constructor.h>
#include <pbd/xml++.h>
{
_in = in;
_out = out;
-
_anchor_point = ap;
_follow_overlap = false;
#include <fst.h>
#endif
+#ifdef HAVE_AUDIOUNITS
+#include <ardour/audio_unit.h>
+#endif
+
#ifdef __SSE__
#include <xmmintrin.h>
#endif
}
#endif
+#ifdef HAVE_AUDIOUNITS
+ AUPluginInfo::load_cached_info ();
+#endif
+
/* Make VAMP look in our library ahead of anything else */
char *p = getenv ("VAMP_PATH");
microseconds_t
ARDOUR::get_microseconds ()
{
- /* XXX need JACK to export its functionality */
-
- struct timeval now;
- gettimeofday (&now, 0);
- return now.tv_sec * 1000000ULL + now.tv_usec;
+ return (microseconds_t) jack_get_time ();
}
ARDOUR::Change
ARDOUR::find_bindings_files (map<string,string>& files)
{
vector<sys::path> found;
-
SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
if (getenv ("ARDOUR_SAE")) {
if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
afs->update_header(0, *now, xnow);
afs->done_with_peakfile_writes ();
- }
-
- /* now that there is data there, requeue the file for analysis */
- if (Config->get_auto_analyse_audio()) {
- Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+ /* now that there is data there, requeue the file for analysis */
+
+ if (Config->get_auto_analyse_audio()) {
+ Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
+ }
}
-
+
/* don't create tracks for empty MIDI sources (channels) */
+
if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
x = all_new_sources.erase(x);
} else {
#include <sigc++/bind.h>
+#include <glibmm.h>
#include <glibmm/thread.h>
#include <pbd/xml++.h>
for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) {
- uint32_t const N = i->bundle->nchannels ();
+ ChanCount const N = i->bundle->nchannels ();
- if (ports.num_ports() < N) {
+ if (ports.num_ports (default_type()) < N.get (default_type())) {
continue;
}
bool ok = true;
- for (uint32_t j = 0; j < N; ++j) {
+ uint32_t n = N.get (default_type());
+
+ for (uint32_t j = 0; j < n; ++j) {
/* Every port on bundle channel j must be connected to our input j */
PortList const pl = i->bundle->channel_ports (j);
for (uint32_t k = 0; k < pl.size(); ++k) {
{
Glib::Mutex::Lock lm (io_lock);
- if (n_inputs() >= _input_maximum) {
+ if (_input_maximum.get(type) >= 0 && n_inputs().get (type) >= _input_maximum.get (type)) {
return -1;
}
float version;
LocaleGuard lg (X_("POSIX"));
- fullpath = _session.automation_dir();
- fullpath += path;
+ fullpath = Glib::build_filename(_session.automation_dir(), path);
in.open (fullpath.c_str());
if (!in) {
- fullpath = _session.automation_dir();
- fullpath += _session.snap_name();
- fullpath += '-';
- fullpath += path;
+ fullpath = Glib::build_filename(_session.automation_dir(), _session.snap_name() + '-' + path);
in.open (fullpath.c_str());
return ret;
}
+boost::shared_ptr<Bundle>
+IO::find_possible_bundle (const string &desired_name, const string &default_name, const string &bundle_type_name)
+{
+ static const string digits = "0123456789";
+
+ boost::shared_ptr<Bundle> c = _session.bundle_by_name (desired_name);
+
+ if (!c) {
+ int bundle_number, mask;
+ string possible_name;
+ bool stereo = false;
+ string::size_type last_non_digit_pos;
+
+ error << string_compose(_("Unknown bundle \"%1\" listed for %2 of %3"), desired_name, bundle_type_name, _name)
+ << endmsg;
+
+ // find numeric suffix of desired name
+ bundle_number = 0;
+
+ last_non_digit_pos = desired_name.find_last_not_of(digits);
+
+ if (last_non_digit_pos != string::npos) {
+ stringstream s;
+ s << desired_name.substr(last_non_digit_pos);
+ s >> bundle_number;
+ }
+
+ // see if it's a stereo connection e.g. "in 3+4"
+
+ if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
+ int left_bundle_number = 0;
+ string::size_type left_last_non_digit_pos;
+
+ left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
+
+ if (left_last_non_digit_pos != string::npos) {
+ stringstream s;
+ s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
+ s >> left_bundle_number;
+
+ if (left_bundle_number > 0 && left_bundle_number + 1 == bundle_number) {
+ bundle_number--;
+ stereo = true;
+ }
+ }
+ }
+
+ // make 0-based
+ if (bundle_number)
+ bundle_number--;
+
+ // find highest set bit
+ mask = 1;
+ while ((mask <= bundle_number) && (mask <<= 1));
+
+ // "wrap" bundle number into largest possible power of 2
+ // that works...
+
+ while (mask) {
+
+ if (bundle_number & mask) {
+ bundle_number &= ~mask;
+
+ stringstream s;
+ s << default_name << " " << bundle_number + 1;
+
+ if (stereo) {
+ s << "+" << bundle_number + 2;
+ }
+
+ possible_name = s.str();
+
+ if ((c = _session.bundle_by_name (possible_name)) != 0) {
+ break;
+ }
+ }
+ mask >>= 1;
+ }
+ if (c) {
+ info << string_compose (_("Bundle %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+ << endmsg;
+ } else {
+ error << string_compose(_("No %1 bundles available as a replacement"), bundle_type_name)
+ << endmsg;
+ }
+
+ }
+
+ return c;
+
+}
+
int
IO::create_ports (const XMLNode& node)
{
XMLProperty const * prop;
- int num_inputs = 0;
- int num_outputs = 0;
+ ChanCount num_inputs;
+ ChanCount num_outputs;
+
+ if ((prop = node.property ("input-connection")) != 0) {
- if ((prop = node.property ("inputs")) != 0) {
- num_inputs = count (prop->value().begin(), prop->value().end(), '{');
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+
+ if (!c) {
+ return -1;
+ }
+
+ num_inputs = c->nchannels();
+
+ } else if ((prop = node.property ("inputs")) != 0) {
+
+ num_inputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
+ }
+
+ if ((prop = node.property ("output-connection")) != 0) {
+
+ boost::shared_ptr<Bundle> c = find_possible_bundle(prop->value(), _("out"), _("output"));
+
+ if (!c) {
+ return -1;
+ }
+
+ num_outputs = c->nchannels ();
+
} else if ((prop = node.property ("outputs")) != 0) {
- num_outputs = count (prop->value().begin(), prop->value().end(), '{');
+
+ num_outputs.set (default_type(), count (prop->value().begin(), prop->value().end(), '{'));
}
no_panner_reset = true;
- // FIXME: audio-only
- if (ensure_io (ChanCount(DataType::AUDIO, num_inputs), ChanCount(DataType::AUDIO, num_outputs), true, this)) {
+ if (ensure_io (num_inputs, num_outputs, true, this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
return -1;
}
int
IO::make_connections (const XMLNode& node)
{
- XMLProperty const * prop;
-
- if ((prop = node.property ("inputs")) != 0) {
+
+ const XMLProperty* prop;
+
+ if ((prop = node.property ("input-connection")) != 0) {
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
+
+ if (!c) {
+ return -1;
+ }
+
+ connect_input_ports_to_bundle (c, this);
+
+ } else if ((prop = node.property ("inputs")) != 0) {
if (set_inputs (prop->value())) {
error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
return -1;
}
}
-
- if ((prop = node.property ("outputs")) != 0) {
+ if ((prop = node.property ("output-connection")) != 0) {
+ boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
+
+ if (!c) {
+ return -1;
+ }
+
+ connect_output_ports_to_bundle (c, this);
+
+ } else if ((prop = node.property ("outputs")) != 0) {
if (set_outputs (prop->value())) {
error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg;
return -1;
if ((*i)->name() == "InputBundle") {
XMLProperty const * prop = (*i)->property ("name");
if (prop) {
- boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+ boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("in"), _("input"));
if (b) {
connect_input_ports_to_bundle (b, this);
- } else {
- error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
}
}
} else if ((*i)->name() == "OutputBundle") {
XMLProperty const * prop = (*i)->property ("name");
if (prop) {
- boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value());
+ boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value(), _("out"), _("output"));
if (b) {
connect_output_ports_to_bundle (b, this);
- } else {
- error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
- }
+ }
}
}
}
/* Connect to the bundle, not worrying about any connections
that are already made. */
- uint32_t const channels = c->nchannels ();
-
- for (uint32_t n = 0; n < channels; ++n) {
+ ChanCount const channels = c->nchannels ();
+ uint32_t cnt = channels.get (default_type());
+
+ for (uint32_t n = 0; n < cnt; ++n) {
const PortList& pl = c->channel_ports (n);
for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) {
/* Connect to the bundle, not worrying about any connections
that are already made. */
- uint32_t const channels = c->nchannels ();
+ ChanCount const channels = c->nchannels ();
+ uint32_t cnt = channels.get (default_type());
- for (uint32_t n = 0; n < channels; ++n) {
+ for (uint32_t n = 0; n < cnt; ++n) {
const PortList& pl = c->channel_ports (n);
void
IO::setup_peak_meters()
{
- ChanCount max_streams = std::max(_inputs.count(), _outputs.count());
- _meter->configure_io(max_streams, max_streams);
+ ChanCount max_streams = std::max (_inputs.count(), _outputs.count());
+ _meter->configure_io (max_streams, max_streams);
}
/**
IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles)
{
boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b);
+
if (ab == 0 || ab->ports_are_outputs() == false) {
return;
}
-
- if (ab->nchannels () != n_inputs().n_total ()) {
+
+ if (ab->nchannels().get (default_type()) != n_inputs().n_total ()) {
return;
}
return;
}
- if (ab->nchannels () != n_outputs().n_total ()) {
+ if (ab->nchannels ().get (default_type()) != n_outputs().n_total ()) {
return;
}
_end = s;
start_changed(this); /* EMIT SIGNAL */
+ end_changed(this); /* EMIT SIGNAL */
if ( is_start() ) {
if (_start != e) {
_start = e;
_end = e;
+ start_changed(this); /* EMIT SIGNAL */
end_changed(this); /* EMIT SIGNAL */
+
+ if ( is_start() ) {
+ Session::StartTimeChanged (); /* EMIT SIGNAL */
+ }
+
+ if ( is_end() ) {
+ Session::EndTimeChanged (); /* EMIT SIGNAL */
+ }
+
}
return 0;
}
#include <cstdlib>
#include <cmath>
+#include <cstring>
#include <pbd/compose.h>
#include <pbd/error.h>
PeakMeter::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
- if (out != in)
+ if (out != in) {
return false;
+ }
uint32_t limit = in.n_total();
assert(_visible_peak_power.size() == limit);
assert(_max_peak_power.size() == limit);
- Processor::configure_io(in, out);
-
- return true;
+ return Processor::configure_io (in, out);
}
/** To be driven by the Meter signal from IO.
_diskstream->set_roll_delay (_roll_delay);
}
-void
+boost::shared_ptr<Region>
MidiTrack::bounce (InterThreadInfo& itt)
{
throw;
- //vector<MidiSource*> srcs;
- //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+ // vector<MidiSource*> srcs;
+ // return _session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+ return boost::shared_ptr<Region> ();
}
-void
+boost::shared_ptr<Region>
MidiTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
{
throw;
//vector<MidiSource*> srcs;
- //_session.write_one_midi_track (*this, start, end, false, srcs, itt);
+ //return _session.write_one_track (*this, start, end, false, srcs, itt);
+ return boost::shared_ptr<Region> ();
}
void
size_t size = 3;
if ( ! _list->automation_playback()) {
- uint8_t ev[3] = { _list->parameter().channel(), int(val), 0.0 };
+ uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
switch(_list->parameter().type()) {
case MidiCCAutomation:
ev[0] += MIDI_CMD_CONTROL;
--- /dev/null
+#include <ardour/onset_detector.h>
+
+#include "i18n.h"
+
+using namespace Vamp;
+using namespace ARDOUR;
+using namespace std;
+
+/* need a static initializer function for this */
+
+string OnsetDetector::_op_id = X_("libardourvampplugins:aubioonset:2");
+
+OnsetDetector::OnsetDetector (float sr)
+ : AudioAnalyser (sr, X_("libardourvampplugins:aubioonset"))
+{
+ /* update the op_id */
+
+ _op_id = X_("libardourvampplugins:aubioonset");
+
+ // XXX this should load the above-named plugin and get the current version
+
+ _op_id += ":2";
+}
+
+OnsetDetector::~OnsetDetector()
+{
+}
+
+string
+OnsetDetector::operational_identifier()
+{
+ return _op_id;
+}
+
+int
+OnsetDetector::run (const std::string& path, Readable* src, uint32_t channel, AnalysisFeatureList& results)
+{
+ current_results = &results;
+ int ret = analyse (path, src, channel);
+
+ current_results = 0;
+ return ret;
+}
+
+int
+OnsetDetector::use_features (Plugin::FeatureSet& features, ostream* out)
+{
+ const Plugin::FeatureList& fl (features[0]);
+
+ for (Plugin::FeatureList::const_iterator f = fl.begin(); f != fl.end(); ++f) {
+
+ if ((*f).hasTimestamp) {
+
+ if (out) {
+ (*out) << (*f).timestamp.toString() << endl;
+ }
+
+ current_results->push_back (RealTime::realTime2Frame ((*f).timestamp, (nframes_t) floor(sample_rate)));
+ }
+ }
+
+ return 0;
+}
+
+void
+OnsetDetector::set_silence_threshold (float val)
+{
+ if (plugin) {
+ plugin->setParameter ("silencethreshold", val);
+ }
+}
+
+void
+OnsetDetector::set_peak_threshold (float val)
+{
+ if (plugin) {
+ plugin->setParameter ("peakpickthreshold", val);
+ }
+}
+
+void
+OnsetDetector::set_function (int val)
+{
+ if (plugin) {
+ plugin->setParameter ("onsettype", (float) val);
+ }
+}
+
+void
+OnsetDetector::cleanup_onsets (AnalysisFeatureList& t, float sr, float gap_msecs)
+{
+ if (t.empty()) {
+ return;
+ }
+
+ t.sort ();
+
+ /* remove duplicates or other things that are too close */
+
+ AnalysisFeatureList::iterator i = t.begin();
+ AnalysisFeatureList::iterator f, b;
+ const nframes64_t gap_frames = (nframes64_t) floor (gap_msecs * (sr / 1000.0));
+
+ while (i != t.end()) {
+
+ // move front iterator to just past i, and back iterator the same place
+
+ f = i;
+ ++f;
+ b = f;
+
+ // move f until we find a new value that is far enough away
+
+ while ((f != t.end()) && (((*f) - (*i)) < gap_frames)) {
+ ++f;
+ }
+
+ i = f;
+
+ // if f moved forward from b, we had duplicates/too-close points: get rid of them
+
+ if (b != f) {
+ t.erase (b, f);
+ }
+ }
+}
#include <unistd.h>
#include <fcntl.h>
+#include <glibmm/miscutils.h>
+
#include <pbd/pthread_utils.h>
#include <pbd/file_utils.h>
#define REGISTER_CALLBACK(serv,path,types, function) lo_server_add_method (serv, path, types, OSC::_ ## function, this)
REGISTER_CALLBACK (serv, "/ardour/add_marker", "", add_marker);
+ REGISTER_CALLBACK (serv, "/ardour/access_action", "s", access_action);
REGISTER_CALLBACK (serv, "/ardour/loop_toggle", "", loop_toggle);
REGISTER_CALLBACK (serv, "/ardour/goto_start", "", goto_start);
REGISTER_CALLBACK (serv, "/ardour/goto_end", "", goto_end);
{
session = &s;
session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away));
+
+ // "Application Hooks"
+ session_loaded( s );
+ session->Exported.connect( mem_fun( *this, &OSC::session_exported ) );
}
void
session = 0;
}
+// "Application Hook" Handlers //
+void
+OSC::session_loaded( Session& s ) {
+ lo_address listener = lo_address_new( NULL, "7770" );
+ lo_send( listener, "/session/loaded", "ss", s.path().c_str(), s.name().c_str() );
+}
+
+void
+OSC::session_exported( std::string path, std::string name ) {
+ lo_address listener = lo_address_new( NULL, "7770" );
+ lo_send( listener, "/session/exported", "ss", path.c_str(), name.c_str() );
+}
+
+// end "Application Hook" Handlers //
+
/* path callbacks */
int
/* automation path is relative */
- automation_path = _session.automation_dir();
- automation_path += prop->value ();
+ automation_path = Glib::build_filename(_session.automation_dir(), prop->value ());
}
return 0;
void
Panner::set_name (string str)
{
- automation_path = _session.automation_dir();
- automation_path += _session.snap_name();
- automation_path += "-pan-";
- automation_path += legalize_for_path (str);
- automation_path += ".automation";
+ automation_path = Glib::build_filename(_session.automation_dir(),
+ _session.snap_name() + "-pan-" + legalize_for_path (str) + ".automation");
}
int
return PluginPtr ((Plugin*) 0);
}
+ChanCount
+Plugin::output_streams () const
+{
+ /* LADSPA & VST should not get here because they do not
+ return "infinite" i/o counts.
+ */
+ return ChanCount::ZERO;
+}
+
+ChanCount
+Plugin::input_streams () const
+{
+ /* LADSPA & VST should not get here because they do not
+ return "infinite" i/o counts.
+ */
+ return ChanCount::ZERO;
+}
+
+
ChanCount
PluginInsert::output_streams() const
{
- if (_configured)
- return output_for_input_configuration(_configured_input);
- else
- return natural_output_streams();
+ ChanCount out = _plugins.front()->get_info()->n_outputs;
+
+ if (out == ChanCount::INFINITE) {
+
+ return _plugins.front()->output_streams ();
+
+ } else {
+
+ out.set_audio (out.n_audio() * _plugins.size());
+ out.set_midi (out.n_midi() * _plugins.size());
+
+ return out;
+ }
}
ChanCount
PluginInsert::input_streams() const
{
- if (_configured)
- return _configured_input;
- else
- return natural_input_streams();
+ ChanCount in = _plugins[0]->get_info()->n_inputs;
+
+ if (in == ChanCount::INFINITE) {
+ return _plugins[0]->input_streams ();
+ } else {
+ in.set_audio (in.n_audio() * _plugins.size());
+ in.set_midi (in.n_midi() * _plugins.size());
+
+ return in;
+ }
}
ChanCount
bool
PluginInsert::configure_io (ChanCount in, ChanCount out)
{
- ChanCount matching_out = output_for_input_configuration(out);
- if (matching_out != out) {
- _configured = false;
+ if (set_count (count_for_configuration (in, out)) < 0) {
+ return false;
+ }
+
+ /* if we're running replicated plugins, each plugin has
+ the same i/o configuration and we may need to announce how many
+ output streams there are.
+
+ if we running a single plugin, we need to configure it.
+ */
+
+ if (_plugins.front()->configure_io (in, out) < 0) {
return false;
- } else {
- bool success = set_count (count_for_configuration(in, out));
- if (success)
- Processor::configure_io(in, out);
- return success;
}
+
+ return Processor::configure_io (in, out);
}
bool
-PluginInsert::can_support_input_configuration (ChanCount in) const
+PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
+ if (_plugins.front()->reconfigurable_io()) {
+ /* plugin has flexible I/O, so delegate to it */
+ return _plugins.front()->can_support_io_configuration (in, out);
+ }
+
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
ChanCount inputs = _plugins[0]->get_info()->n_inputs;
- /* see output_for_input_configuration below */
if ((inputs.n_total() == 0)
|| (inputs.n_total() == 1 && outputs == inputs)
|| (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|| (inputs.n_midi() == 0 && in.n_midi() == 0)))
|| (inputs == in)) {
+ out = outputs;
return true;
}
}
}
- if (can_replicate && (in.n_total() % inputs.n_total() == 0)) {
- return true;
- } else {
+ if (!can_replicate || (in.n_total() % inputs.n_total() != 0)) {
return false;
}
-}
-
-ChanCount
-PluginInsert::output_for_input_configuration (ChanCount in) const
-{
- ChanCount outputs = _plugins[0]->get_info()->n_outputs;
- ChanCount inputs = _plugins[0]->get_info()->n_inputs;
if (inputs.n_total() == 0) {
/* instrument plugin, always legal, but throws away any existing streams */
- return outputs;
- }
-
- if (inputs.n_total() == 1 && outputs == inputs
+ out = outputs;
+ } else if (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
- || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
- /* mono plugin, replicate as needed to match in */
- return in;
- }
-
- if (inputs == in) {
+ || (inputs.n_midi() == 0 && in.n_midi() == 0))) {
+ /* mono, single-typed plugin, replicate as needed to match in */
+ out = in;
+ } else if (inputs == in) {
/* exact match */
- return outputs;
- }
-
- bool can_replicate = true;
-
- /* if number of inputs is a factor of the requested input
- configuration for every type, we can replicate.
- */
- for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- if (inputs.get(*t) >= in.get(*t) || (in.get(*t) % inputs.get(*t) != 0)) {
- can_replicate = false;
- break;
- }
- }
-
- if (can_replicate && (inputs.n_total() % in.n_total() == 0)) {
- ChanCount output;
-
+ out = outputs;
+ } else {
+ /* replicate - note that we've already verified that
+ the replication count is constant across all data types.
+ */
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- output.set(*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
+ out.set (*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
}
-
- return output;
}
-
- /* sorry */
- return ChanCount();
+
+ return true;
}
/* Number of plugin instances required to support a given channel configuration.
int32_t
PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const
{
+ if (_plugins.front()->reconfigurable_io()) {
+ /* plugin has flexible I/O, so the answer is always 1 */
+ /* this could change if we ever decide to replicate AU's */
+ return 1;
+ }
+
// FIXME: take 'out' into consideration
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
#include <cstdio>
#include <lrdf.h>
#include <dlfcn.h>
+#include <cstdlib>
+#include <fstream>
#ifdef VST_SUPPORT
#include <fst.h>
#include <pbd/basename.h>
-#include <string.h>
+#include <cstring>
#endif // VST_SUPPORT
+#include <glibmm/miscutils.h>
+
#include <pbd/pathscanner.h>
#include <ardour/ladspa.h>
#include <ardour/plugin_manager.h>
#include <ardour/plugin.h>
#include <ardour/ladspa_plugin.h>
+#include <ardour/filesystem_paths.h>
#ifdef HAVE_SLV2
#include <slv2/slv2.h>
#ifdef HAVE_AUDIOUNITS
#include <ardour/audio_unit.h>
+#include <Carbon/Carbon.h>
#endif
#include <pbd/error.h>
using namespace ARDOUR;
using namespace PBD;
+using namespace std;
PluginManager* PluginManager::_manager = 0;
char* s;
string lrdf_path;
+ load_favorites ();
+
+#ifdef GTKOSX
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
+ if( returnCode != 0) {
+ error << _("Cannot become GUI app") << endmsg;
+ }
+#endif
+
if ((s = getenv ("LADSPA_RDF_PATH"))){
lrdf_path = s;
}
}
#endif // VST_SUPPORT
+
+bool
+PluginManager::is_a_favorite_plugin (const PluginInfoPtr& pi)
+{
+ FavoritePlugin fp (pi->type, pi->unique_id);
+ return find (favorites.begin(), favorites.end(), fp) != favorites.end();
+}
+
+void
+PluginManager::save_favorites ()
+{
+ ofstream ofs;
+ sys::path path = user_config_directory();
+ path /= "favorite_plugins";
+
+ ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
+
+ if (!ofs) {
+ return;
+ }
+
+ for (FavoritePluginList::iterator i = favorites.begin(); i != favorites.end(); ++i) {
+ switch ((*i).type) {
+ case LADSPA:
+ ofs << "LADSPA";
+ break;
+ case AudioUnit:
+ ofs << "AudioUnit";
+ break;
+ case LV2:
+ ofs << "LV2";
+ break;
+ case VST:
+ ofs << "VST";
+ break;
+ }
+
+ ofs << ' ' << (*i).unique_id << endl;
+ }
+
+ ofs.close ();
+}
+
+void
+PluginManager::load_favorites ()
+{
+ sys::path path = user_config_directory();
+ path /= "favorite_plugins";
+ ifstream ifs (path.to_string().c_str());
+
+ if (!ifs) {
+ return;
+ }
+
+ std::string stype;
+ std::string id;
+ PluginType type;
+
+ while (ifs) {
+
+ ifs >> stype;
+ if (!ifs) {
+ break;
+
+ }
+ ifs >> id;
+ if (!ifs) {
+ break;
+ }
+
+ if (stype == "LADSPA") {
+ type = LADSPA;
+ } else if (stype == "AudioUnit") {
+ type = AudioUnit;
+ } else if (stype == "LV2") {
+ type = LV2;
+ } else if (stype == "VST") {
+ type = VST;
+ } else {
+ error << string_compose (_("unknown favorite plugin type \"%1\" - ignored"), stype)
+ << endmsg;
+ continue;
+ }
+
+ add_favorite (type, id);
+ }
+
+ ifs.close ();
+}
+
+void
+PluginManager::add_favorite (PluginType t, string id)
+{
+ FavoritePlugin fp (t, id);
+ pair<FavoritePluginList::iterator,bool> res = favorites.insert (fp);
+ cerr << "Added " << t << " " << id << " success ? " << res.second << endl;
+}
+
+void
+PluginManager::remove_favorite (PluginType t, string id)
+{
+ FavoritePlugin fp (t, id);
+ favorites.erase (fp);
+}
msgid "Slide Edit"
msgstr "Glidredigering"
+#: libs/ardour/utils.cc:372 libs/ardour/utils.cc:388
+msgid "Lock Edit"
+msgstr "LÃ¥st redigering"
+
#: libs/ardour/utils.cc:309
msgid "programming error: unknown edit mode string \"%1\""
msgstr ""
return _session.engine().frames_per_cycle() + _io->input_latency();
}
-bool
-PortInsert::can_support_input_configuration (ChanCount in) const
-{
- if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
-
- /* not configured yet */
-
- return true; /* we can support anything the first time we're asked */
-
- } else {
-
- /* the "input" config for a port insert corresponds to how
- many output ports it will have.
- */
-
- if (_io->output_maximum() == in) {
-
- return true;
- }
- }
-
- return false;
-}
-
-ChanCount
-PortInsert::output_for_input_configuration (ChanCount in) const
-{
- return in;
-}
-
bool
PortInsert::configure_io (ChanCount in, ChanCount out)
{
the last request config. or something like that.
*/
-
/* this is a bit odd:
the number of inputs we are required to handle corresponds
_io->set_input_maximum (out);
_io->set_input_minimum (out);
- bool success = (_io->ensure_io (out, in, false, this) == 0);
-
- if (success)
- return Processor::configure_io(in, out);
- else
+ if (_io->ensure_io (out, in, false, this) != 0) {
return false;
+ }
+
+ return Processor::configure_io (in, out);
}
ChanCount
return 0;
}
+bool
+Processor::configure_io (ChanCount in, ChanCount out)
+{
+ /* this class assumes static output stream count.
+ Derived classes must override, and must set "out"
+ to reflect "in" before calling this.
+ */
+
+ _configured_input = in;
+ _configured = true;
+
+ return true;
+}
nframes_t pos = 0;
int avail = 0;
- // note: this_time_fraction is a ratio of original length. 1.0 = no change,
- // 0.5 is half as long, 2.0 is twice as long, etc.
+ cerr << "RBEffect: source region: position = " << region->position()
+ << ", start = " << region->start()
+ << ", length = " << region->length()
+ << ", ancestral_start = " << region->ancestral_start()
+ << ", ancestral_length = " << region->ancestral_length()
+ << ", stretch " << region->stretch()
+ << ", shift " << region->shift() << endl;
+
+ /*
+ We have two cases to consider:
+
+ 1. The region has not been stretched before.
+
+ In this case, we just want to read region->length() frames
+ from region->start().
+
+ We will create a new region of region->length() *
+ tsr.time_fraction frames. The new region will have its
+ start set to 0 (because it has a new audio file that begins
+ at the start of the stretched area) and its ancestral_start
+ set to region->start() (so that we know where to begin
+ reading if we want to stretch it again).
+
+ 2. The region has been stretched before.
+
+ The region starts at region->start() frames into its
+ (possibly previously stretched) source file. But we don't
+ want to read from its source file; we want to read from the
+ file it was originally stretched from.
+
+ The region's source begins at region->ancestral_start()
+ frames into its master source file. Thus, we need to start
+ reading at region->ancestral_start() + (region->start() /
+ region->stretch()) frames into the master source. This
+ value will also become the ancestral_start for the new
+ region.
+
+ We cannot use region->ancestral_length() to establish how
+ many frames to read, because it won't be up to date if the
+ region has been trimmed since it was last stretched. We
+ must read region->length() / region->stretch() frames and
+ stretch them by tsr.time_fraction * region->stretch(), for
+ a new region of region->length() * tsr.time_fraction
+ frames.
+
+ Case 1 is of course a special case of 2, where
+ region->ancestral_start() == 0 and region->stretch() == 1.
+
+ When we ask to read from a region, we supply a position on
+ the global timeline. The read function calculates the
+ offset into the source as (position - region->position()) +
+ region->start(). This calculation is used regardless of
+ whether we are reading from a master or
+ previously-stretched region. In order to read from a point
+ n frames into the master source, we need to provide n -
+ region->start() + region->position() as our position
+ argument to master_read_at().
+
+ Note that region->ancestral_length() is not used.
+
+ I hope this is clear.
+ */
+
+ double stretch = region->stretch() * tsr.time_fraction;
+ double shift = region->shift() * tsr.pitch_fraction;
- double this_time_fraction = tsr.time_fraction * region->stretch ();
- double this_pitch_fraction = tsr.pitch_fraction * region->shift ();
+ nframes_t read_start = region->ancestral_start() +
+ nframes_t(region->start() / (double)region->stretch());
- RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(),
- (RubberBandStretcher::Options) tsr.opts,
- this_time_fraction, this_pitch_fraction);
+ nframes_t read_duration =
+ nframes_t(region->length() / (double)region->stretch());
+
+ uint32_t channels = region->n_channels();
+
+ RubberBandStretcher stretcher
+ (session.frame_rate(), channels,
+ (RubberBandStretcher::Options) tsr.opts, stretch, shift);
tsr.progress = 0.0f;
tsr.done = false;
- uint32_t channels = region->n_channels();
- nframes_t duration = region->ancestral_length();
+ stretcher.setExpectedInputDuration(read_duration);
+ stretcher.setDebugLevel(1);
stretcher.setExpectedInputDuration(duration);
stretcher.setDebugLevel(1);
digits just to disambiguate close but not identical FX
*/
- if (this_time_fraction == 1.0) {
- snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_pitch_fraction * 100.0f));
- } else if (this_pitch_fraction == 1.0) {
- snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_time_fraction * 100.0f));
+ if (stretch == 1.0) {
+ snprintf (suffix, sizeof (suffix), "@%d", (int) floor (shift * 100.0f));
+ } else if (shift == 1.0) {
+ snprintf (suffix, sizeof (suffix), "@%d", (int) floor (stretch * 100.0f));
} else {
snprintf (suffix, sizeof (suffix), "@%d-%d",
- (int) floor (this_time_fraction * 100.0f),
- (int) floor (this_pitch_fraction * 100.0f));
+ (int) floor (stretch * 100.0f),
+ (int) floor (shift * 100.0f));
}
/* create new sources */
done = 0;
try {
- while (pos < duration && !tsr.cancel) {
+ while (pos < read_duration && !tsr.cancel) {
nframes_t this_read = 0;
for (uint32_t i = 0; i < channels; ++i) {
this_read = 0;
+
nframes_t this_time;
+ this_time = min(bufsize, read_duration - pos);
- this_time = min(bufsize, duration - pos);
-
+ nframes_t this_position;
+ this_position = read_start + pos -
+ region->start() + region->position();
+
this_read = region->master_read_at
(buffers[i],
buffers[i],
gain_buffer,
- pos + region->position(),
+ this_position,
this_time,
i);
pos += this_read;
done += this_read;
- tsr.progress = ((float) done / duration) * 0.25;
+ tsr.progress = ((float) done / read_duration) * 0.25;
- stretcher.study(buffers, this_read, pos == duration);
+ stretcher.study(buffers, this_read, pos == read_duration);
}
done = 0;
pos = 0;
- while (pos < duration && !tsr.cancel) {
+ while (pos < read_duration && !tsr.cancel) {
nframes_t this_read = 0;
this_read = 0;
nframes_t this_time;
-
- this_time = min(bufsize, duration - pos);
+ this_time = min(bufsize, read_duration - pos);
+
+ nframes_t this_position;
+ this_position = read_start + pos -
+ region->start() + region->position();
this_read = region->master_read_at
(buffers[i],
buffers[i],
gain_buffer,
- pos + region->position(),
+ this_position,
this_time,
i);
pos += this_read;
done += this_read;
- tsr.progress = 0.25 + ((float) done / duration) * 0.75;
+ tsr.progress = 0.25 + ((float) done / read_duration) * 0.75;
- stretcher.process(buffers, this_read, pos == duration);
+ stretcher.process(buffers, this_read, pos == read_duration);
int avail = 0;
for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) {
- (*x)->set_ancestral_data (region->ancestral_start(),
- region->ancestral_length(),
- this_time_fraction,
- this_pitch_fraction );
+
+ (*x)->set_ancestral_data (read_start,
+ read_duration,
+ stretch,
+ shift);
(*x)->set_master_sources (region->get_master_sources());
}
#include <unistd.h>
#include <fstream>
#include <algorithm>
+
+#include <glibmm/miscutils.h>
+
#include <pbd/error.h>
+
#include <ardour/configuration.h>
#include <ardour/filesystem_paths.h>
#include <ardour/recent_sessions.h>
_sync_position = other->_sync_position;
}
+
for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) {
if (unique_srcs.find (*i) == unique_srcs.end()) {
(*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
void
Region::set_length (nframes_t len, void *src)
{
+ //cerr << "Region::set_length() len = " << len << endl;
if (_flags & Locked) {
return;
}
{
boost::shared_ptr<const AudioRegion> ar;
boost::shared_ptr<const MidiRegion> mr;
-
+
if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
boost::shared_ptr<Region> ret (new AudioRegion (ar));
/* pure copy constructor - no CheckNewRegion emitted */
RegionFactory::create (Session& session, XMLNode& node, bool yn)
{
boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn);
- CheckNewRegion (r);
+
+ if (r) {
+ CheckNewRegion (r);
+ }
+
return r;
}
int
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
//processor->set_default_type(_default_type);
+ _processors.push_back (processor);
+
+ if (_reset_processor_counts (err)) {
+ _processors.pop_back ();
+ _reset_processor_counts (0); // it worked before we tried to add it ...
+ return -1;
+ }
+
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
- pi->set_count (1);
if (pi->natural_input_streams() == ChanCount::ZERO) {
/* generator plugin */
// Set up processor list channels. This will set processor->[input|output]_streams(),
// configure redirect ports properly, etc.
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
_processors.pop_back ();
- _reset_plugin_counts (0); // it worked before we tried to add it ...
+ _reset_processor_counts (0); // it worked before we tried to add it ...
return -1;
}
// Ensure peak vector sizes before the plugin is activated
- ChanCount potential_max_streams = max(processor->input_streams(), processor->output_streams());
- _meter->configure_io(potential_max_streams, potential_max_streams);
+
+ ChanCount potential_max_streams;
+
+ potential_max_streams.set (DataType::AUDIO, max (processor->input_streams().n_audio(),
+ processor->output_streams().n_audio()));
+ potential_max_streams.set (DataType::MIDI, max (processor->input_streams().n_midi(),
+ processor->output_streams().n_midi()));
+
+ _meter->configure_io (potential_max_streams, potential_max_streams);
processor->activate ();
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
_user_latency = 0;
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
int
Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
}
// Ensure peak vector sizes before the plugin is activated
- _meter->configure_io(potential_max_streams, potential_max_streams);
+ _meter->configure_io (potential_max_streams, potential_max_streams);
_processors.push_back (*i);
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
++existing_end;
_processors.erase (existing_end, _processors.end());
- _reset_plugin_counts (0); // it worked before we tried to add it ...
+ _reset_processor_counts (0); // it worked before we tried to add it ...
return -1;
}
_user_latency = 0;
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
void
Route::clear_processors (Placement p)
{
- const ChanCount old_rmo = processor_max_outs;
+ const ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return;
}
/* FIXME: can't see how this test can ever fire */
- if (processor_max_outs != old_rmo) {
+ if (processor_max_outs != old_pmo) {
reset_panner ();
}
int
Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
return 1;
ProcessorList::iterator tmp;
- /* move along, see failure case for reset_plugin_counts()
+ /* move along, see failure case for reset_processor_counts()
where we may need to reprocessor the processor.
*/
return 1;
}
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
/* get back to where we where */
_processors.insert (i, processor);
/* we know this will work, because it worked before :) */
- _reset_plugin_counts (0);
+ _reset_processor_counts (0);
return -1;
}
- bool foo = false;
+ _have_internal_generator = false;
for (i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
if (pi->is_generator()) {
- foo = true;
+ _have_internal_generator = true;
+ break;
}
}
}
-
- _have_internal_generator = foo;
}
- if (old_rmo != processor_max_outs) {
+ if (old_pmo != processor_max_outs) {
reset_panner ();
}
}
int
-Route::reset_plugin_counts (ProcessorStreams* err)
+Route::reset_processor_counts (ProcessorStreams* err)
{
Glib::RWLock::WriterLock lm (_processor_lock);
- return _reset_plugin_counts (err);
+ return _reset_processor_counts (err);
}
int
-Route::_reset_plugin_counts (ProcessorStreams* err)
+Route::_reset_processor_counts (ProcessorStreams* err)
{
ProcessorList::iterator r;
- map<Placement,list<ProcessorCount> > processor_map;
- ChanCount initial_streams;
- ChanCount post_fader_input;
+ uint32_t insert_cnt = 0;
+ uint32_t send_cnt = 0;
+ map<Placement,list<ProcessorCount> > proc_map;
+ ProcessorList::iterator prev;
+ ChanCount initial_streams = n_inputs ();
+ ChanCount previous_initial_streams = n_inputs ();
int ret = -1;
+ uint32_t max_audio = 0;
+ uint32_t max_midi = 0;
- /* Process each placement in order, checking to see if we
- can really do what has been requested.
- */
+ processor_max_outs.reset ();
- /* divide processors up by placement so we get the signal flow
+ /* Step 1: build a map that links each insert to an in/out channel count
+
+ Divide inserts up by placement so we get the signal flow
properly modelled. we need to do this because the _processors
list is not sorted by placement, and because other reasons may
exist now or in the future for this separate treatment.
for (r = _processors.begin(); r != _processors.end(); ++r) {
- boost::shared_ptr<Processor> processor;
+ boost::shared_ptr<PluginInsert> plugin_insert;
+ boost::shared_ptr<PortInsert> port_insert;
+
+ if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert>(*r)) != 0) {
+
+ ++insert_cnt;
+ proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+ /* reset plugin counts back to one for now so
+ that we have a predictable, controlled
+ state to try to configure.
+ */
- if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
- processor_map[processor->placement()].push_back (ProcessorCount (processor));
+ plugin_insert->set_count (1);
+
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert>(*r)) != 0) {
+
+ ++insert_cnt;
+ proc_map[(*r)->placement()].push_back (ProcessorCount (*r));
+
+ } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
+ ++send_cnt;
}
}
+ if (insert_cnt == 0) {
+ if (send_cnt) {
+ goto recompute;
+ } else {
+ ret = 0;
+ goto streamcount;
+ }
+ }
+
+ /* Now process each placement in order, checking to see if we
+ can really do what has been requested.
+ */
+
/* A: PreFader */
- if ( ! check_some_plugin_counts (processor_map[PreFader], n_inputs (), err)) {
+ if (check_some_processor_counts (proc_map[PreFader], n_inputs (), err)) {
goto streamcount;
}
- post_fader_input = (err ? err->count : n_inputs());
+ if (!proc_map[PreFader].empty()) {
+ previous_initial_streams = n_inputs ();
+ for (list<ProcessorCount>::iterator i = proc_map[PreFader].begin(); i != proc_map[PreFader].end(); i++) {
+ if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+ goto streamcount;
+ }
+ previous_initial_streams = initial_streams;
+ }
+ }
/* B: PostFader */
- if ( ! check_some_plugin_counts (processor_map[PostFader], post_fader_input, err)) {
+ if (check_some_processor_counts (proc_map[PostFader], initial_streams, err)) {
goto streamcount;
}
+ if (!proc_map[PostFader].empty()) {
+ for (list<ProcessorCount>::iterator i = proc_map[PostFader].begin(); i != proc_map[PostFader].end(); i++) {
+ if (i->processor->can_support_io_configuration (previous_initial_streams, initial_streams) < 0) {
+ goto streamcount;
+ }
+ previous_initial_streams = initial_streams;
+ }
+ }
+
/* OK, everything can be set up correctly, so lets do it */
- apply_some_plugin_counts (processor_map[PreFader]);
- apply_some_plugin_counts (processor_map[PostFader]);
+ apply_some_processor_counts (proc_map[PreFader]);
+ apply_some_processor_counts (proc_map[PostFader]);
/* recompute max outs of any processor */
ret = 0;
- streamcount:
- processor_max_outs.reset();
+ recompute:
- for (r = _processors.begin(); r != _processors.end(); ++r) {
- processor_max_outs = max ((*r)->output_streams (), processor_max_outs);
+ processor_max_outs.reset ();
+ prev = _processors.end();
+
+ for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
+ boost::shared_ptr<Send> s;
+
+ if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
+ if (r == _processors.begin()) {
+ s->expect_inputs (n_inputs());
+ } else {
+ s->expect_inputs ((*prev)->output_streams());
+ }
+
+ } else {
+
+ /* don't pay any attention to send output configuration, since it doesn't
+ affect the route.
+ */
+
+ max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+ max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+ }
}
+ processor_max_outs.set (DataType::AUDIO, max_audio);
+ processor_max_outs.set (DataType::MIDI, max_midi);
+
+ /* we're done */
return 0;
+
+ streamcount:
+ for (r = _processors.begin(); r != _processors.end(); ++r) {
+ max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
+ max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
+ }
+
+ processor_max_outs.set (DataType::AUDIO, max_audio);
+ processor_max_outs.set (DataType::MIDI, max_midi);
+
+ return ret;
}
int32_t
-Route::apply_some_plugin_counts (list<ProcessorCount>& iclist)
+Route::apply_some_processor_counts (list<ProcessorCount>& iclist)
{
list<ProcessorCount>::iterator i;
-
+
for (i = iclist.begin(); i != iclist.end(); ++i) {
-
- cerr << "now applying for " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
- if ((*i).processor->configure_io ((*i).in, (*i).out)) {
+ ProcessorCount& pc (*i);
+
+ cerr << "now applying for " << (*i).processor->name() << " in = " << pc.in.n_audio() << " out = " << pc.out.n_audio() << endl;
+
+ if (pc.processor->configure_io (pc.in, pc.out)) {
return -1;
}
+
/* make sure that however many we have, they are all active */
- (*i).processor->activate ();
+
+ pc.processor->activate ();
}
return 0;
* Otherwise, \a err is set to the output of the list.
*/
bool
-Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
+Route::check_some_processor_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err)
{
list<ProcessorCount>::iterator i;
size_t index = 0;
err->count = required_inputs;
}
- for (i = iclist.begin(); i != iclist.end(); ++i) {
-
+ for (i = iclist.begin(); i != iclist.end(); ++i, ++index) {
cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n";
- if ((*i).processor->can_support_input_configuration (required_inputs) < 0) {
+ if (!(*i).processor->can_support_io_configuration (required_inputs, (*i).out)) {
if (err) {
err->index = index;
err->count = required_inputs;
}
(*i).in = required_inputs;
- (*i).out = (*i).processor->output_for_input_configuration (required_inputs);
-
- cerr << "config looks like " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl;
-
required_inputs = (*i).out;
-
- ++index;
- }
-
- if (err) {
- if (!iclist.empty()) {
- err->index = index;
- err->count = iclist.back().processor->output_for_input_configuration(required_inputs);
- }
}
return true;
int
Route::copy_processors (const Route& other, Placement placement, ProcessorStreams* err)
{
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
ProcessorList to_be_deleted;
/* reset plugin stream handling */
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
/* FAILED COPY ATTEMPT: we have to restore order */
/* restore the natural order */
_processors = the_copy;
- processor_max_outs = old_rmo;
+ processor_max_outs = old_pmo;
/* we failed, even though things are OK again */
}
}
- if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) {
+ if (processor_max_outs != old_pmo || old_pmo == ChanCount::ZERO) {
reset_panner ();
}
{
ProcessorSorter comparator;
Glib::RWLock::WriterLock lm (_processor_lock);
- ChanCount old_rmo = processor_max_outs;
+ ChanCount old_pmo = processor_max_outs;
/* the sweet power of C++ ... */
_processors.sort (comparator);
- if (_reset_plugin_counts (err)) {
+ if (_reset_processor_counts (err)) {
_processors = as_it_was_before;
- processor_max_outs = old_rmo;
+ processor_max_outs = old_pmo;
return -1;
}
}
Route::input_change_handler (IOChange change, void *ignored)
{
if (change & ConfigurationChanged) {
- reset_plugin_counts (0);
+ reset_processor_counts (0);
}
}
_control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().n_audio()), true, this);
}
- reset_plugin_counts (0);
+ reset_processor_counts (0);
}
}
}
}
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": internal redirect latency = " << _own_latency << endl;
+#endif
+
set_port_latency (_own_latency);
if (!_user_latency) {
signal_latency_changed (); /* EMIT SIGNAL */
}
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": input latency = " << input_latency() << " total = "
+ << _own_latency << endl;
+#endif
+
return _own_latency;
}
}
bool
-Send::can_support_input_configuration (ChanCount in) const
+Send::can_support_io_configuration (const ChanCount& in, ChanCount& out_is_ignored) const
{
if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
/* not configured yet */
- return true; /* we can support anything the first time we're asked */
+ return 1; /* we can support anything the first time we're asked */
} else {
*/
if (_io->output_maximum() == in) {
-
- return true;
+ return 1;
}
}
- return false;
-}
-
-ChanCount
-Send::output_for_input_configuration (ChanCount in) const
-{
- // from the internal (Insert) perspective a Send does not modify its input whatsoever
- return in;
+ return -1;
}
bool
Send::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
- if (out != in)
+
+ if (out != in) {
return false;
+ }
_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (ChanCount::ZERO);
_io->set_input_minimum (ChanCount::ZERO);
- bool success = _io->ensure_io (ChanCount::ZERO, in, false, this) == 0;
-
- if (success) {
- Processor::configure_io(in, out);
- _io->reset_panner();
- return true;
- } else {
+ if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
return false;
}
+
+ Processor::configure_io(in, out);
+ _io->reset_panner();
+
+ return true;
}
ChanCount
}
+void
+Send::expect_inputs (const ChanCount& expected)
+{
+ if (expected != expected_inputs) {
+ expected_inputs = expected;
+ _io->reset_panner ();
+ }
+}
sigc::signal<void> Session::SMPTEOffsetChanged;
sigc::signal<void> Session::StartTimeChanged;
sigc::signal<void> Session::EndTimeChanged;
-
sigc::signal<void> Session::AutoBindingOn;
sigc::signal<void> Session::AutoBindingOff;
+sigc::signal<void, std::string, std::string> Session::Exported;
Session::Session (AudioEngine &eng,
const string& fullpath,
diskstreams (new DiskstreamList),
routes (new RouteList),
auditioner ((Auditioner*) 0),
+ _total_free_4k_blocks (0),
_bundle_xml_node (0),
_click_io ((IO*) 0),
main_outs (0)
cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
- n_physical_outputs = _engine.n_physical_outputs();
- n_physical_inputs = _engine.n_physical_inputs();
+ n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
+ n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
first_stage_init (fullpath, snapshot_name);
midi_requests (16),
diskstreams (new DiskstreamList),
routes (new RouteList),
+ _total_free_4k_blocks (0),
_bundle_xml_node (0),
main_outs (0)
cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
- n_physical_outputs = _engine.n_physical_outputs();
- n_physical_inputs = _engine.n_physical_inputs();
+ n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
+ n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
if (n_physical_inputs) {
n_physical_inputs = max (requested_physical_in, n_physical_inputs);
set_loop = true;
}
+ if (location->is_start()) {
+ start_location = location;
+ }
+ if (location->is_end()) {
+ end_location = location;
+ }
}
if (!set_loop) {
}
}
- /*
+#if 0
vector<string> physinputs;
vector<string> physoutputs;
+
+ _engine.get_physical_outputs (DataType::MIDI, physoutputs);
+ _engine.get_physical_inputs (DataType::MIDI, physinputs);
uint32_t nphysical_in;
uint32_t nphysical_out;
-
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
- control_id = ntracks() + nbusses() + 1;
- */
+ control_id = ntracks() + nbusses();
+#endif
while (how_many) {
} while (track_id < (UINT_MAX-1));
/*
- if (Config->get_input_auto_connect() & AutoConnectPhysical) {
+ if (Config->get_input_auto_connect() & AutoConnectPhysical) {
nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
} else {
nphysical_in = 0;
uint32_t nphysical_in;
uint32_t nphysical_out;
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
+ _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+ _engine.get_physical_inputs (DataType::AUDIO, physinputs);
control_id = ntracks() + nbusses() + 1;
while (how_many) {
vector<string> physinputs;
vector<string> physoutputs;
- _engine.get_physical_outputs (physoutputs);
- _engine.get_physical_inputs (physinputs);
+ _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
+ _engine.get_physical_inputs (DataType::AUDIO, physinputs);
control_id = ntracks() + nbusses() + 1;
while (how_many) {
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ if ((*i)->destructive()) //ignore tape tracks when getting max extents
+ continue;
boost::shared_ptr<Playlist> pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
}
int
-Session::region_name (string& result, string base, bool newlevel) const
+Session::region_name (string& result, string base, bool newlevel)
{
char buf[16];
string subbase;
Glib::Mutex::Lock lm (region_lock);
snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
-
-
result = "region.";
result += buf;
} else {
- /* XXX this is going to be slow. optimize me later */
-
if (newlevel) {
subbase = base;
} else {
}
- bool name_taken = true;
-
{
Glib::Mutex::Lock lm (region_lock);
- for (int n = 1; n < 5000; ++n) {
-
- result = subbase;
- snprintf (buf, sizeof (buf), ".%d", n);
- result += buf;
+ map<string,uint32_t>::iterator x;
- name_taken = false;
+ result = subbase;
- for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- if (i->second->name() == result) {
- name_taken = true;
- break;
- }
- }
+ if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
+ result += ".1";
+ region_name_map[subbase] = 1;
+ } else {
+ x->second++;
+ snprintf (buf, sizeof (buf), ".%d", x->second);
- if (!name_taken) {
- break;
- }
+ result += buf;
}
}
-
- if (name_taken) {
- fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
- /*NOTREACHED*/
- }
}
+
return 0;
}
add the region to the region list.
*/
- set_dirty();
+ set_dirty ();
if (added) {
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
+
+ update_region_name_map (region);
}
if (!v.empty()) {
}
}
+void
+Session::update_region_name_map (boost::shared_ptr<Region> region)
+{
+ string::size_type last_period = region->name().find_last_of ('.');
+
+ if (last_period != string::npos && last_period < region->name().length() - 1) {
+
+ string base = region->name().substr (0, last_period);
+ string number = region->name().substr (last_period+1);
+ map<string,uint32_t>::iterator x;
+
+ /* note that if there is no number, we get zero from atoi,
+ which is just fine
+ */
+
+ region_name_map[base] = atoi (number);
+ }
+}
+
void
Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
{
/* relay hidden changes */
RegionHiddenChange (region);
}
+
+ if (what_changed & NameChanged) {
+ update_region_name_map (region);
+ }
}
void
return 0;
}
-int
-Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
- bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
+boost::shared_ptr<Region>
+Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
+ bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
{
- int ret = -1;
+ boost::shared_ptr<Region> result;
boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<AudioFileSource> fsource;
uint32_t x;
BufferSet buffers;
SessionDirectory sdir(get_best_session_directory_for_new_source ());
const string sound_dir = sdir.sound_path().to_string();
+ nframes_t len = end - start;
+
+ if (end <= start) {
+ error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
+ end, start) << endmsg;
+ return result;
+ }
// any bigger than this seems to cause stack overflows in called functions
const nframes_t chunk_size = (128 * 1024)/4;
/* construct a region to represent the bounced material */
- boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
- region_name_from_path (srcs.front()->name(), true));
-
- ret = 0;
+ result = RegionFactory::create (srcs, 0, srcs.front()->length(),
+ region_name_from_path (srcs.front()->name(), true));
}
out:
- if (ret) {
+ if (!result) {
for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
if (afs) {
afs->mark_for_remove ();
}
-
+
(*src)->drop_references ();
}
g_atomic_int_set (&processing_prohibited, 0);
- return ret;
+ return result;
}
BufferSet&
uint32_t err = 0;
int32_t bytes;
bool compute_io;
- struct timeval begin, end;
+ microseconds_t begin, end;
+
struct pollfd pfd[1];
bool disk_work_outstanding = false;
DiskstreamList::iterator i;
bytes = 0;
compute_io = true;
- gettimeofday (&begin, 0);
+ begin = get_microseconds();
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
}
if (compute_io) {
- gettimeofday (&end, 0);
-
- double b = begin.tv_sec + (begin.tv_usec/1000000.0);
- double e = end.tv_sec + (end.tv_usec / 1000000.0);
-
- _read_data_rate = bytes / (e - b);
+ end = get_microseconds();
+ if(end-begin > 0) {
+ _read_data_rate = (float) bytes / (float) (end - begin);
+ } else { _read_data_rate = 0; // infinity better
+ }
}
bytes = 0;
compute_io = true;
- gettimeofday (&begin, 0);
+ begin = get_microseconds();
for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
}
if (compute_io) {
- gettimeofday (&end, 0);
-
- double b = begin.tv_sec + (begin.tv_usec/1000000.0);
- double e = end.tv_sec + (end.tv_usec / 1000000.0);
-
- _write_data_rate = bytes / (e - b);
+ // there are no apparent users for this calculation?
+ end = get_microseconds();
+ if(end-begin > 0) {
+ _write_data_rate = (float) bytes / (float) (end - begin);
+ } else {
+ _write_data_rate = 0; // Well, infinity would be better
+ }
}
if (!disk_work_outstanding) {
/* disk i/o in excess of 10000MB/sec indicate the buffer cache
in action. ignore it.
*/
- return _read_data_rate > 10485760000.0f ? 0.0f : _read_data_rate;
+ return _read_data_rate > 10485.7600000f ? 0.0f : _read_data_rate;
}
float
/* disk i/o in excess of 10000MB/sec indicate the buffer cache
in action. ignore it.
*/
- return _write_data_rate > 10485760000.0f ? 0.0f : _write_data_rate;
+ return _write_data_rate > 10485.7600000f ? 0.0f : _write_data_rate;
}
uint32_t
before = new XMLNode(*n->children().front());
after = new XMLNode(*n->children().back());
child = before;
- }
+ }
if (!child)
{
output_data = (void*) malloc (sample_bytes * out_samples_max);
}
+ pos = start_frame;
+ end_frame = end_frame;
+ total_frames = end_frame - start_frame;
+ running = true;
+ do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
+
return 0;
}
return -1;
}
- spec.pos = spec.start_frame;
- spec.end_frame = spec.end_frame;
- spec.total_frames = spec.end_frame - spec.start_frame;
- spec.running = true;
- spec.do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
-
spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec));
+ cerr << "Start export at pos = " << spec.pos << endl;
+
return _engine.freewheel (true);
}
spec.freewheel_connection.disconnect ();
spec.clear (); /* resets running/stop etc */
+ Exported (spec.path, name());
+
return 0;
}
-int
-Session::prepare_to_export (ExportSpecification& spec)
+int
+Session::pre_export ()
{
- int ret = -1;
-
wait_till_butler_finished ();
/* take everyone out of awrite to avoid disasters */
}
}
+ /* make sure we are actually rolling */
+
+ if (get_record_enabled()) {
+ disable_record (false);
+ }
+
+ /* no slaving */
+
+ post_export_slave = Config->get_slave_source ();
+ post_export_position = _transport_frame;
+
+ Config->set_slave_source (None);
+
+ return 0;
+}
+
+int
+Session::prepare_to_export (ExportSpecification& spec)
+{
+ int ret = -1;
+
/* get everyone to the right position */
{
}
}
- /* make sure we are actually rolling */
+ cerr << "Everybdy is at " << spec.start_frame << endl;
- if (get_record_enabled()) {
- disable_record (false);
- }
+ /* we just did the core part of a locate() call above, but
+ for the sake of any GUI, put the _transport_frame in
+ the right place too.
+ */
+ _transport_frame = spec.start_frame;
_exporting = true;
-
- /* no slaving */
-
- post_export_slave = Config->get_slave_source ();
- post_export_position = _transport_frame;
-
- Config->set_slave_source (None);
- /* get transport ready */
+ /* get transport ready. note how this is calling butler functions
+ from a non-butler thread. we waited for the butler to stop
+ what it was doing earlier in Session::pre_export() and nothing
+ since then has re-awakened it.
+ */
set_transport_speed (1.0, false);
butler_transport_work ();
int ret = -1;
nframes_t this_nframes;
+ cerr << "Export process at pos = " << spec->pos << " _exporting = "
+ << _exporting << " running = " << spec->running << " stop = "
+ << spec->stop << endl;
+
/* This is not required to be RT-safe because we are running while freewheeling */
if (spec->do_freewheel == false) {
if (!_exporting) {
/* finished, but still freewheeling */
- process_without_events (nframes);
+ cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <<endl;
+ no_roll (nframes, 0);
return 0;
}
-
+
if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
- process_without_events (nframes);
+ cerr << "\tExport ... not running or at end, no_roll() for " << nframes <<endl;
+ no_roll (nframes, 0);
return stop_export (*spec);
}
}
}
+ cerr << "\tprocess " << nframes << endl;
+
if (spec->process (nframes)) {
goto out;
}
spec->pos += nframes;
spec->progress = 1.0 - (((float) spec->end_frame - spec->pos) / spec->total_frames);
+ cerr << "\t@ " << spec->pos << " prog = " << spec->progress << endl;
+
/* and we're good to go */
ret = 0;
}
void
-Session::finalize_audio_export ()
+Session::finalize_export ()
{
_engine.freewheel (false);
_exporting = false;
if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
+ /* generate silence up to the sync point, then
+ adjust nframes + offset to reflect whatever
+ is left to do.
+ */
+
no_roll (sync_offset, 0);
nframes -= sync_offset;
offset += sync_offset;
waiting_for_sync_offset = false;
if (nframes == 0) {
- return true; // done
+ return true; // done, nothing left to process
}
} else {
+
+ /* sync offset point is not within this process()
+ cycle, so just generate silence. and don't bother
+ with any fancy stuff here, just the minimal silence.
+ */
+
+ g_atomic_int_inc (&processing_prohibited);
no_roll (nframes, 0);
- return true; // done
+ g_atomic_int_dec_and_test (&processing_prohibited);
+
+ if (Config->get_locate_while_waiting_for_sync()) {
+ if (micro_locate (nframes)) {
+ /* XXX ERROR !!! XXX */
+ }
+ }
+
+ return true; // done, nothing left to process
}
return false;
AudioFileSource::set_search_path (sound_search_path.to_string ());
SMFSource::set_search_path (midi_search_path.to_string ());
+
// reset the round-robin soundfile path thingie
-
+
last_rr_session_dir = session_dirs.begin();
}
return 0;
}
+int
+Session::rename_template (string old_name, string new_name)
+{
+ sys::path old_path (user_template_directory());
+ old_path /= old_name + template_suffix;
+
+ sys::path new_path(user_template_directory());
+ new_path /= new_name + template_suffix;
+
+ if (sys::exists (new_path)) {
+ warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
+ new_path.to_string()) << endmsg;
+ return -1;
+ }
+
+ try {
+ sys::rename (old_path, new_path);
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+}
+
+int
+Session::delete_template (string name)
+{
+ sys::path path = user_template_directory();
+ path /= name + template_suffix;
+
+ try {
+ sys::remove (path);
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+}
+
void
Session::refresh_disk_space ()
{
string
Session::automation_dir () const
{
- string res = _path;
- res += "automation/";
- return res;
+ return Glib::build_filename (_path, "automation");
}
string
Session::analysis_dir () const
{
- string res = _path;
- res += "analysis/";
- return res;
+ return Glib::build_filename (_path, "analysis");
}
int
// FIXME: where should this really be? [DR]
//send_full_time_code();
- deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
+ deliver_mmc (MIDI::MachineControl::cmdStop, 0);
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
if (_transport_speed < 0.0f) {
}
}
+int
+Session::micro_locate (nframes_t distance)
+{
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ if (!(*i)->can_internal_playback_seek (distance)) {
+ return -1;
+ }
+ }
+
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
+ (*i)->internal_playback_seek (distance);
+ }
+
+ _transport_frame += distance;
+ return 0;
+}
+
void
Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
{
_worst_track_latency = 0;
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << "\n---------------------------------\nUPDATE LATENCY\n";
+#endif
+
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
_engine.update_total_latencies ();
}
+#ifdef DEBUG_LATENCY
+ cerr << "\tworst was " << _worst_track_latency << endl;
+#endif
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_latency_delay (_worst_track_latency);
}
#include <cstring>
#include <cerrno>
#include <climits>
+#include <cstdarg>
#include <pwd.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <glibmm/miscutils.h>
+
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/utils.h>
+#include <ardour/version.h>
#include "i18n.h"
AudioFileSource::Removable|
AudioFileSource::RemovableIfEmpty|
AudioFileSource::CanRename);
+
+static void
+snprintf_bounded_null_filled (char* target, size_t target_size, char* fmt, ...)
+{
+ char buf[target_size+1];
+ va_list ap;
+
+ va_start (ap, fmt);
+ vsnprintf (buf, target_size+1, fmt, ap);
+ va_end (ap);
+
+ memset (target, 0, target_size);
+ memcpy (target, buf, target_size);
+
+}
+
SndFileSource::SndFileSource (Session& s, const XMLNode& node)
: AudioFileSource (s, node)
{
_broadcast_info = new SF_BROADCAST_INFO;
memset (_broadcast_info, 0, sizeof (*_broadcast_info));
- snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
-
- struct utsname utsinfo;
-
- if (uname (&utsinfo)) {
- error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
- return;
- }
-
- snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)",
- Glib::get_real_name().c_str(),
- utsinfo.nodename,
- utsinfo.sysname,
- utsinfo.release,
- utsinfo.version);
+ snprintf_bounded_null_filled (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
+ snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %s)", Glib::get_real_name().c_str());
_broadcast_info->version = 1;
_broadcast_info->time_reference_low = 0;
/* XXX do something about this field */
- snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
+ snprintf_bounded_null_filled (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
/* coding history is added by libsndfile */
/* random code is 9 digits */
int random_code = random() % 999999999;
+
+ snprintf_bounded_null_filled (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
+ Config->get_bwf_country_code().c_str(),
+ Config->get_bwf_organization_code().c_str(),
+ bwf_serial_number,
+ now.tm_hour,
+ now.tm_min,
+ now.tm_sec,
+ random_code);
- snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
- Config->get_bwf_country_code().c_str(),
- Config->get_bwf_organization_code().c_str(),
- bwf_serial_number,
- now.tm_hour,
- now.tm_min,
- now.tm_sec,
- random_code);
-
- snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
- 1900 + now.tm_year,
- now.tm_mon,
- now.tm_mday);
+ snprintf_bounded_null_filled (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
+ 1900 + now.tm_year,
+ now.tm_mon + 1, // move from 0..11 to 1..12
+ now.tm_mday);
- snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
- now.tm_hour,
- now.tm_min,
- now.tm_sec);
+ snprintf_bounded_null_filled (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
+ now.tm_hour,
+ now.tm_min,
+ now.tm_sec);
/* now update header position taking header offset into account */
DataType type = DataType::AUDIO;
const XMLProperty* prop = node.property("type");
- if (prop) {
- type = DataType(prop->value());
+ if (!prop) {
+ return boost::shared_ptr<Source>();
}
+ type = DataType (prop->value());
+
if (type == DataType::AUDIO) {
try {
}
}
+#undef DEBUG_LATENCY
+#ifdef DEBUG_LATENCY
+ cerr << _name << ": internal redirect (final) latency = " << _own_latency << endl;
+#endif
+
set_port_latency (_own_latency);
if (old != _own_latency) {
}
}
-uint32_t
+ARDOUR::ChanCount
ARDOUR::UserBundle::nchannels () const
{
Glib::Mutex::Lock lm (_ports_mutex);
- return _ports.size ();
+ return ChanCount (type(), _ports.size ());
}
const ARDOUR::PortList&
ARDOUR::UserBundle::channel_ports (uint32_t n) const
{
- assert (n < nchannels ());
+ assert (n < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return _ports[n];
void
ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
PortsWillChange (c);
void
ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p)
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
PortsWillChange (c);
bool
ARDOUR::UserBundle::port_attached_to_channel (uint32_t c, std::string const & p) const
{
- assert (c < nchannels ());
+ assert (c < nchannels ().get (type()));
Glib::Mutex::Lock lm (_ports_mutex);
return std::find (_ports[c].begin(), _ports[c].end(), p) != _ports[c].end();
void
ARDOUR::UserBundle::remove_channel (uint32_t r)
{
- assert (r < nchannels ());
+ assert (r < nchannels ().get (type()));
ConfigurationWillChange ();
#include <cmath>
#include <cctype>
#include <string>
+#include <cstring>
#include <cerrno>
#include <iostream>
#include <sys/types.h>
#include <algorithm>
#include <vector>
#include <string>
-#include <ctype.h>
+#include <cctype>
#include <cstdlib>
#include <cstdio> // so libraptor doesn't complain
#include <cmath>
#include <dirent.h>
-#include <string.h> // for memmove
+#include <cstring> // for memmove
#include <sys/stat.h>
#include <cerrno>
+#include <glibmm/ustring.h>
+#include <glibmm/miscutils.h>
+
#include <lrdf.h>
#include <fst.h>
/* save it to a file */
- string path;
+ Glib::ustring path = Glib::build_filename (get_user_ardour_path (), "vst");
struct stat sbuf;
sys::path user_vst_directory(user_config_directory());
user_vst_directory /= "vst";
-
path = user_vst_directory.to_string();
if (stat (path.c_str(), &sbuf)) {
return *root;
}
- path += "something";
+ path = Glib::build_filename (path, "something");
/* store information */
Import('env libraries install_prefix')
-cairomm = env.Copy()
+cairomm = env.Clone()
cairomm.Merge([libraries['cairo']])
cairomm.Append(CXXFLAGS='-DHAVE_CONFIG_H')
Import ('env install_prefix')
-clearlooks = env.Copy()
+clearlooks = env.Clone()
clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0 cairo` ',
LINKFLAGS = ' `pkg-config --libs gtk+-2.0 cairo` ')
fst_src = glob.glob('*.c')
Import('env install_prefix')
-fst = env.Copy(CC="winegcc")
+fst = env.Clone(CC="winegcc")
fst.Append (CPPPATH=".")
if fst['VST']:
Import('env libraries install_prefix')
-glibmm2 = env.Copy()
+glibmm2 = env.Clone()
glibmm2.Merge([libraries['sigc2'], libraries['glib2']])
glibmm2.Append(LIBPATH='#libs/glibmm2',
CPPPATH='#libs/glibmm2/glib')
-/* glib/glibmmconfig.h. Generated from glibmmconfig.h.in by configure. */
+/* glib/glibmmconfig.h. Generated by configure. */
#ifndef _GLIBMM_CONFIG_H
#define _GLIBMM_CONFIG_H 1
#ifdef GLIBMM_DLL
#if defined(GLIBMM_BUILD) && defined(_WINDLL)
/* Do not dllexport as it is handled by gendef on MSVC */
- #define GLIBMM_API
+ #define GLIBMM_API
#elif !defined(GLIBMM_BUILD)
#define GLIBMM_API __declspec(dllimport)
#else
atkmm_files = glob.glob('atkmm/*.cc')
Import('env libraries install_prefix')
-atkmm = env.Copy()
+atkmm = env.Clone()
atkmm.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'] ])
libatkmm = atkmm.SharedLibrary('atkmm', atkmm_files)
gdkmm2_files = glob.glob('gdkmm/*.cc')
Import('env libraries install_prefix')
-gdkmm2 = env.Copy()
+gdkmm2 = env.Clone()
gdkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['cairomm']])
gdkmm2.Append(CXXFLAGS=["-Ilibs/gtkmm2/gtk", "-DGLIBMM_EXCEPTIONS_ENABLED"])
gtkmm2_files = glob.glob('gtkmm/*.cc')
Import('env libraries install_prefix')
-gtkmm2 = env.Copy()
+gtkmm2 = env.Clone()
gtkmm2.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['atkmm'], libraries['gdkmm2'], libraries['cairomm'], libraries['gtk2-unix-print'] ])
gtkmm2.Append(CXXFLAGS = ['-DGLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED', '-DGLIBMM_PROPERTIES_ENABLED', '-DGLIBMM_EXCEPTIONS_ENABLED'])
pangomm_files = glob.glob('pangomm/*.cc')
Import('env libraries install_prefix')
-pangomm = env.Copy()
+pangomm = env.Clone()
pangomm.Merge([libraries['glibmm2'], libraries['pango'], libraries['sigc2'], libraries['cairomm'], libraries['cairo'], libraries['pangocairo'] ])
if pangomm['IS_OSX']:
Import('env final_prefix install_prefix libraries i18n')
-gtkmm2ext = env.Copy()
+gtkmm2ext = env.Clone()
gtkmm2ext.Merge ([
libraries['sigc2'],
libraries['pbd'],
focus_entry.cc
grouped_buttons.cc
gtk_ui.cc
-hexentry.cc
idle_adjustment.cc
-pathlist.cc
pixfader.cc
pixscroller.cc
popup.cc
using namespace Gtkmm2ext;
BarController::BarController (Gtk::Adjustment& adj,
- PBD::Controllable& mc,
+ boost::shared_ptr<PBD::Controllable> mc,
sigc::slot<void,char*,unsigned int> lc)
: adjustment (adj),
using namespace std;
using namespace PBD;
-BindingProxy::BindingProxy (Controllable& c)
+BindingProxy::BindingProxy (boost::shared_ptr<Controllable> c)
: prompter (0),
controllable (c),
bind_button (2),
BindingProxy::button_press_handler (GdkEventButton *ev)
{
if ((ev->state & bind_statemask) && ev->button == bind_button) {
- if (Controllable::StartLearning (&controllable)) {
+ if (Controllable::StartLearning (controllable.get())) {
string prompt = _("operate controller now");
if (prompter == 0) {
prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false);
}
prompter->set_text (prompt);
prompter->touch (); // shows popup
- learning_connection = controllable.LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
+ learning_connection = controllable->LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
}
return true;
}
BindingProxy::prompter_hiding (GdkEventAny *ev)
{
learning_connection.disconnect ();
- Controllable::StopLearning (&controllable);
+ Controllable::StopLearning (controllable.get());
return false;
}
#include <gtkmm2ext/fastmeter.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm/style.h>
-#include <string.h>
+#include <cstring>
#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
: AbstractUI<UIRequest> (namestr, true)
{
theMain = new Main (argc, argv);
- tips = new Tooltips;
_active = false;
public:
typedef sigc::slot<void,char*,unsigned int> LabelCallback;
- BarController (Gtk::Adjustment& adj, PBD::Controllable&, LabelCallback lc = LabelCallback());
+ BarController (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable>, LabelCallback lc = LabelCallback());
virtual ~BarController () {}
/* export this to allow direct connection to button events */
Gtk::Widget& event_widget() { return darea; }
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
protected:
Gtk::Adjustment& adjustment;
class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
{
public:
- BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
+ BindableToggleButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
- explicit BindableToggleButton (PBD::Controllable& c, const std::string &label)
+ explicit BindableToggleButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
: Gtkmm2ext::StatefulToggleButton (label), binding_proxy (c) {}
virtual ~BindableToggleButton() {}
}
}
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
+
private:
BindingProxy binding_proxy;
};
class BindableButton : public Gtkmm2ext::StatefulButton
{
public:
- BindableButton (PBD::Controllable& c) : binding_proxy (c) {}
+ BindableButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
- explicit BindableButton (PBD::Controllable& c, const std::string &label)
+ explicit BindableButton (boost::shared_ptr<PBD::Controllable> c, const std::string &label)
: Gtkmm2ext::StatefulButton (label), binding_proxy (c) {}
~BindableButton() {}
}
}
- PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
private:
BindingProxy binding_proxy;
#include <string>
#include <gtkmm2ext/popup.h>
+#include <boost/shared_ptr.hpp>
namespace PBD {
class Controllable;
class BindingProxy : public sigc::trackable
{
public:
- BindingProxy (PBD::Controllable&);
+ BindingProxy (boost::shared_ptr<PBD::Controllable>);
virtual ~BindingProxy();
void set_bind_button_state (guint button, guint statemask);
bool button_press_handler (GdkEventButton *);
- PBD::Controllable* get_controllable() { return &controllable; }
- protected:
+ boost::shared_ptr<PBD::Controllable> get_controllable() { return controllable; }
+ protected:
Gtkmm2ext::PopUp* prompter;
- PBD::Controllable& controllable;
+ boost::shared_ptr<PBD::Controllable> controllable;
guint bind_button;
guint bind_statemask;
sigc::connection learning_connection;
#include <gtkmm/style.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/main.h>
-#include <gtkmm/tooltips.h>
#include <gdkmm/color.h>
#include <pbd/abstract_ui.h>
#include <pbd/ringbufferNPT.h>
static pthread_t gui_thread;
bool _active;
Gtk::Main *theMain;
- Gtk::Tooltips *tips;
TextViewer *errors;
Glib::RefPtr<Gtk::TextBuffer::Tag> error_ptag;
Glib::RefPtr<Gtk::TextBuffer::Tag> error_mtag;
+++ /dev/null
-/*
- Copyright (C) 1999 Paul Barton-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 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.
-
-*/
-
-#ifndef __gtkmm2ext_hexentry_h__
-#define __gtkmm2ext_hexentry_h__
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class HexEntry : public Gtk::Entry
-
-{
- public:
- /* Take a byte-level representation of a series of hexadecimal
- values and use them to set the displayed text of the entry.
- Eg. if hexbuf[0] = 0xff and hexbuf[1] = 0xa1 and buflen = 2,
- then the text will be set to "ff a1".
- */
-
- void set_hex (unsigned char *hexbuf, unsigned int buflen);
-
- /* puts byte-level representation of current entry text
- into hexbuf, and returns number of bytes written there.
-
- NOTE: this will release the existing memory pointed to
- by hexbuf if buflen indicates that it is not long enough
- to hold the new representation, and hexbuf is not zero.
-
- If the returned length is zero, the contents of hexbuf
- are undefined.
- */
-
- unsigned int get_hex (unsigned char *hexbuf, size_t buflen);
-
- private:
- bool on_key_press_event (GdkEventKey *);
-};
-
-} /* namespace */
-
-#endif /* __gtkmm2ext_hexentry_h__ */
+++ /dev/null
-/*
- Copyright (C) 2006 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 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.
-
-*/
-
-#ifndef __gtkmm2ext_pathlist_h__
-#define __gtkmm2ext_pathlist_h__
-
-#include <vector>
-#include <string>
-
-#include <gtkmm.h>
-
-namespace Gtkmm2ext {
-
-class PathList : public Gtk::VBox
-{
- public:
- PathList ();
- ~PathList () {};
-
- std::vector<std::string> get_paths ();
- void set_paths (std::vector<std::string> paths);
-
- sigc::signal<void> PathsUpdated;
-
- protected:
- Gtk::Button add_btn;
- Gtk::Button subtract_btn;
-
- void add_btn_clicked ();
- void subtract_btn_clicked ();
-
- private:
- struct PathColumns : public Gtk::TreeModel::ColumnRecord {
- PathColumns() { add (paths); }
- Gtk::TreeModelColumn<std::string> paths;
- };
- PathColumns path_columns;
-
- Glib::RefPtr<Gtk::ListStore> _store;
- Gtk::TreeView _view;
-
- void selection_changed ();
-};
-
-} // namespace Gtkmm2ext
-
-#endif // __gtkmm2ext_pathlist_h__
#include <gtkmm2ext/pixfader.h>
#include <gtkmm2ext/binding_proxy.h>
+#include <boost/shared_ptr.hpp>
+
namespace Gtkmm2ext {
class Pix;
}
public:
SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment* adj, int orientation,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
-
+
virtual ~SliderController () {}
void set_value (float);
public:
VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
};
public:
HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- PBD::Controllable&,
+ boost::shared_ptr<PBD::Controllable>,
bool with_numeric = true);
};
+++ /dev/null
-/*
- Copyright (C) 2000 Paul Barton-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 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.
-
- $Id$
-*/
-
-#include <stdio.h> /* for sprintf, sigh ... */
-#include <string>
-#include <ctype.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtkmm2ext/hexentry.h>
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-bool
-HexEntry::on_key_press_event (GdkEventKey *ev)
-
-{
- if ((ev->keyval >= GDK_a && ev->keyval <= GDK_f) ||
- (ev->keyval >= GDK_A && ev->keyval <= GDK_A) ||
- (ev->keyval >= GDK_0 && ev->keyval <= GDK_9) ||
- ev->keyval == GDK_space ||
- ev->keyval == GDK_Tab ||
- ev->keyval == GDK_Return ||
- ev->keyval == GDK_BackSpace ||
- ev->keyval == GDK_Delete) {
- return Gtk::Entry::on_key_press_event (ev);
- } else {
- gdk_beep ();
- return FALSE;
- }
-}
-
-
-void
-HexEntry::set_hex (unsigned char *msg, unsigned int len)
-
-{
- /* create a textual representation of the MIDI message */
-
- if (msg && len) {
- char *rep;
-
- rep = new char[(len * 3) + 1];
- for (size_t i = 0; i < len; i++) {
- sprintf (&rep[i*3], "%02x ", msg[i]);
- }
- rep[len * 3] = '\0';
- set_text (rep);
- delete [] rep;
- } else {
- set_text ("");
- }
-}
-
-unsigned int
-HexEntry::get_hex (unsigned char *hexbuf, size_t buflen)
-
-{
- int fetched_len;
- char buf[3];
- string text = get_text();
- string::size_type length = text.length ();
- string::size_type offset;
-
- fetched_len = 0;
- buf[2] = '\0';
- offset = 0;
-
- while (1) {
- offset = text.find_first_of ("abcdef0123456789", offset);
-
- if (offset == string::npos) {
- break;
- }
-
- /* grab two characters, but no more */
-
- buf[0] = text[offset];
-
- if (offset < length - 1) {
- buf[1] = text[offset+1];
- offset += 2;
- } else {
- buf[1] = '\0';
- offset += 1;
- }
-
- hexbuf[fetched_len++] = (char) strtol (buf, 0, 16);
- }
-
- return fetched_len;
-}
-
-
+++ /dev/null
-/*
- Copyright (C) 2006 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 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 <gtkmm2ext/pathlist.h>
-
-#include "i18n.h"
-
-using namespace std;
-using namespace Gtkmm2ext;
-
-PathList::PathList ()
- :
- add_btn(_("+")),
- subtract_btn(_("-")),
- path_columns(),
- _store(Gtk::ListStore::create(path_columns)),
- _view(_store)
-{
- _view.append_column(_("Paths"), path_columns.paths);
- _view.set_size_request(-1, 100);
- _view.set_headers_visible (false);
-
- Gtk::ScrolledWindow* scroll = manage(new Gtk::ScrolledWindow);
- scroll->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- scroll->add(_view);
-
- add (*scroll);
-
- Gtk::HBox* btn_box = manage(new Gtk::HBox);
- btn_box->add(add_btn);
- btn_box->add(subtract_btn);
-
- add (*btn_box);
-
- add_btn.signal_clicked().connect (mem_fun(*this, &PathList::add_btn_clicked));
- subtract_btn.signal_clicked().connect (mem_fun(*this, &PathList::subtract_btn_clicked));
- _view.get_selection()->signal_changed().connect (mem_fun(*this, &PathList::selection_changed));
-}
-
-vector<string>
-PathList::get_paths ()
-{
- vector<string> paths;
-
- Gtk::TreeModel::Children children(_store->children());
-
- for (Gtk::TreeIter iter = children.begin(); iter != children.end(); ++iter) {
- Gtk::ListStore::Row row = *iter;
-
- paths.push_back(row[path_columns.paths]);
- }
-
- return paths;
-}
-
-void
-PathList::set_paths (vector<string> paths)
-{
- _store->clear();
-
- for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) {
- Gtk::ListStore::iterator iter = _store->append();
- Gtk::ListStore::Row row = *iter;
- row[path_columns.paths] = *i;
- }
-}
-
-void
-PathList::add_btn_clicked ()
-{
- Gtk::FileChooserDialog path_chooser (_("Path Chooser"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
- path_chooser.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_OK);
- path_chooser.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-
- int result = path_chooser.run ();
-
- if (result == Gtk::RESPONSE_OK) {
- string pathname = path_chooser.get_filename();
-
- if (pathname.length ()) {
- Gtk::ListStore::iterator iter = _store->append ();
- Gtk::ListStore::Row row = *iter;
- row[path_columns.paths] = pathname;
-
- PathsUpdated (); // EMIT_SIGNAL
- }
- }
-}
-
-void
-PathList::subtract_btn_clicked ()
-{
- Gtk::ListStore::iterator iter = _view.get_selection()->get_selected();
- _store->erase (iter);
-
- PathsUpdated (); // EMIT_SIGNAL
-}
-
-void
-PathList::selection_changed ()
-{
- if (_view.get_selection()->count_selected_rows ()) {
- subtract_btn.set_sensitive (true);
- } else {
- subtract_btn.set_sensitive (false);
- }
-}
SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj, int orientation,
- Controllable& c,
+ boost::shared_ptr<Controllable> c,
bool with_numeric)
: PixFader (image, *adj, orientation),
VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- Controllable& control,
+ boost::shared_ptr<Controllable> control,
bool with_numeric)
: SliderController (image, adj, VERT, control, with_numeric)
HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> image,
Gtk::Adjustment *adj,
- Controllable& control,
+ boost::shared_ptr<Controllable> control,
bool with_numeric)
: SliderController (image, adj, HORIZ, control, with_numeric)
gnomecanvasmm_files = glob.glob('libgnomecanvasmm/*.cc')
Import('env libraries install_prefix')
-gnomecanvasmm = env.Copy()
+gnomecanvasmm = env.Clone()
gnomecanvasmm.Merge([libraries['glibmm2'],
libraries['gtk2'],
libraries['sigc2'],
sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
Import('env install_prefix libraries use_flac')
-sndfile = env.Copy()
+sndfile = env.Clone()
if use_flac:
sndfile.Merge([libraries['flac'] ])
Import('env libraries install_prefix')
-midi2 = env.Copy()
+midi2 = env.Clone()
midi2.Merge([ libraries['sigc2'],
libraries['xml'],
libraries['glibmm2'],
#include <cstring>
#include <string>
+#include <cstring>
#include <cstdlib>
#include <midi++/types.h>
Import('env libraries i18n install_prefix')
-pbd = env.Copy()
+pbd = env.Clone()
domain = 'libpbd'
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
-#include <errno.h>
+#include <cerrno>
+#include <cstring>
#include <pbd/base_ui.h>
#include <pbd/error.h>
*/
if (pipe (signal_pipe)) {
- error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) {
- error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, std::strerror (errno))
+ error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno))
<< endmsg;
return -1;
}
$Id$
*/
-#include <ctype.h>
+#include <cctype>
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
#include <pbd/enumwriter.h>
#include <pbd/error.h>
#define _XOPEN_SOURCE 600
-#include <stdlib.h>
+#include <cstdlib>
#include <stdint.h>
#include <pbd/fpu.h>
#include <cstdio>
#include <cstring>
#include <string>
+#include <cstring>
#include <limits.h>
#include <pbd/mountpoint.h>
#include <cstring>
#include <cstdlib>
#include <cstdio>
+#include <cstring>
#include <vector>
#include <dirent.h>
typedef typename FunctorMap::iterator FunctorMapIterator;
public:
- FunctorCommand(
- std::string functor,
- obj_type object,
- arg_type b,
- arg_type a
- ) : functor_name(functor),
- object(object),
- before(b),
- after(a)
+ FunctorCommand(std::string functor, obj_type& object, arg_type b, arg_type a)
+ : functor_name(functor)
+ , object(object)
+ , before(b)
+ , after(a)
{
method = find_functor(functor);
std::stringstream ss;
XMLNode *node = new XMLNode("FunctorCommand");
+ node->add_property("type_name", typeid(obj_type).name());
node->add_property("functor", functor_name);
ss << before;
node->add_property("before", ss.str());
#include <cstdlib>
#include <iostream>
#include <vector>
+#include <cstdlib>
#include <pbd/pool.h>
#include <pbd/error.h>
#ifdef HAVE_EXECINFO
#include <execinfo.h>
-#include <stdlib.h>
+#include <cstdlib>
void
PBD::stacktrace (std::ostream& out, int levels)
#include <iostream>
#include <string>
#include <sstream>
+#include <time.h>
#include <pbd/undo.h>
#include <pbd/xml++.h>
UndoTransaction::UndoTransaction ()
: _clearing(false)
{
+ gettimeofday (&_timestamp, 0);
}
UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
'configure', 'configure.ac', 'Makefile.am', 'SConscript',
+ 'config.sub', 'config.guess',
'sigc++/Makefile.in',
'sigc++config.h',
'sigc++config.h.in',
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
-scriptversion=2006-05-10.23
+scriptversion=2005-06-08.21
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
fi
run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
msg="missing on your system"
-case $1 in
+case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
-case $1 in
+case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
-case $1 in
+case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
- case $f in
+ case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
+ if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
- case $LASTARG in
+ case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
- if test ! -f y.tab.h; then
+ if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
- if test ! -f y.tab.c; then
+ if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
- if test $# -ne 1; then
+ if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
- case $LASTARG in
+ case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
+ if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
- if test ! -f lex.yy.c; then
+ if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
fi
firstarg="$1"
if shift; then
- case $firstarg in
+ case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
- case $firstarg in
+ case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
#include "AAFilter.h"
#include "FIRFilter.h"
//
////////////////////////////////////////////////////////////////////////////////
-#include <stdlib.h>
+#include <cstdlib>
#include <memory.h>
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
#include <stdexcept>
#include "FIFOSampleBuffer.h"
#ifndef FIFOSamplePipe_H
#define FIFOSamplePipe_H
-#include <assert.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cstdlib>
#include "STTypes.h"
namespace soundtouch
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
#include <stdexcept>
#include "FIRFilter.h"
#include "cpu_detect.h"
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
+#include <cassert>
+#include <cstdlib>
+#include <cstdio>
+#include <climits>
#include "RateTransposer.h"
#include "AAFilter.h"
""")
Import('env install_prefix')
-st = env.Copy()
+st = env.Clone()
st.Append(CCFLAGS="-DHAVE_CONFIG_H -D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
libst = st.SharedLibrary('soundtouch', soundtouch_files)
//
////////////////////////////////////////////////////////////////////////////////
-#include <string.h>
-#include <stdlib.h>
+#include <cstring>
+#include <cstdlib>
#include <memory.h>
-#include <limits.h>
-#include <math.h>
-#include <assert.h>
+#include <climits>
+#include <cmath>
+#include <cassert>
#include "STTypes.h"
#include "cpu_detect.h"
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-cp = env.Copy()
+cp = env.Clone()
#
# this defines the version number of libardour_cp
libraries['pbd'],
libraries['midi++2'],
libraries['xml'],
- libraries['usb'],
libraries['glib2'],
libraries['glibmm2']
])
using namespace ARDOUR;
using ARDOUR::nframes_t;
+sigc::signal<void,std::string,std::string> BasicUI::AccessAction;
+
BasicUI::BasicUI (Session& s)
: session (&s)
{
PBD::ThreadCreated (pthread_self(), name);
}
+
+void
+BasicUI::access_action ( std::string action_path )
+{
+ int split_at = action_path.find( "/" );
+ std::string group = action_path.substr( 0, split_at );
+ std::string item = action_path.substr( split_at + 1 );
+
+ AccessAction( group, item );
+}
+
void
BasicUI::loop_toggle ()
{
/* transport control */
void loop_toggle ();
+ void access_action ( std::string action_path );
+ static sigc::signal<void,std::string,std::string> AccessAction;
void goto_start ();
void goto_end ();
void rewind ();
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-tranzport = env.Copy()
+tranzport = env.Clone()
#
# this defines the version number of libardour_tranzport
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-genericmidi = env.Copy()
+genericmidi = env.Clone()
#
# this defines the version number of libardour_genericmidi
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-mackie = env.Copy()
+mackie = env.Clone()
#
# this defines the version number of libardour_mackie
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-powermate = env.Copy()
+powermate = env.Clone()
#
# this defines the version number of powermate
#include <linux/input.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
+#include <cstring>
+#include <cerrno>
+#include <cstdio>
#include <unistd.h>
#include <fcntl.h>
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
-tranzport = env.Copy()
+tranzport = env.Clone()
#
# this defines the version number of libardour_tranzport
*
* */
+#include <cstring>
#include <tranzport_control_protocol.h>
#include <cstring>
--- /dev/null
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+ Centre for Digital Music, Queen Mary, University of London.
+ This file copyright 2006 Chris Cannam.
+
+ 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. See the file
+ COPYING included with this distribution for more information.
+
+*/
+
+#include <math.h>
+#include "Onset.h"
+
+using std::string;
+using std::vector;
+using std::cerr;
+using std::endl;
+
+Onset::Onset(float inputSampleRate) :
+ Plugin(inputSampleRate),
+ m_ibuf(0),
+ m_fftgrain(0),
+ m_onset(0),
+ m_pv(0),
+ m_peakpick(0),
+ m_onsetdet(0),
+ m_onsettype(aubio_onset_complex),
+ m_threshold(0.3),
+ m_silence(-90),
+ m_channelCount(1)
+{
+}
+
+Onset::~Onset()
+{
+ if (m_onsetdet) aubio_onsetdetection_free(m_onsetdet);
+ if (m_ibuf) del_fvec(m_ibuf);
+ if (m_onset) del_fvec(m_onset);
+ if (m_fftgrain) del_cvec(m_fftgrain);
+ if (m_pv) del_aubio_pvoc(m_pv);
+ if (m_peakpick) del_aubio_peakpicker(m_peakpick);
+}
+
+string
+Onset::getIdentifier() const
+{
+ return "aubioonset";
+}
+
+string
+Onset::getName() const
+{
+ return "Aubio Onset Detector";
+}
+
+string
+Onset::getDescription() const
+{
+ return "Estimate note onset times";
+}
+
+string
+Onset::getMaker() const
+{
+ return "Paul Brossier (plugin by Chris Cannam)";
+}
+
+int
+Onset::getPluginVersion() const
+{
+ return 1;
+}
+
+string
+Onset::getCopyright() const
+{
+ return "GPL";
+}
+
+bool
+Onset::initialise(size_t channels, size_t stepSize, size_t blockSize)
+{
+ m_channelCount = channels;
+ m_stepSize = stepSize;
+ m_blockSize = blockSize;
+
+ m_ibuf = new_fvec(stepSize, channels);
+ m_onset = new_fvec(1, channels);
+ m_fftgrain = new_cvec(blockSize, channels);
+ m_pv = new_aubio_pvoc(blockSize, stepSize, channels);
+ m_peakpick = new_aubio_peakpicker(m_threshold);
+
+ m_onsetdet = new_aubio_onsetdetection(m_onsettype, blockSize, channels);
+
+ m_delay = Vamp::RealTime::frame2RealTime(4 * stepSize,
+ lrintf(m_inputSampleRate));
+
+ m_lastOnset = Vamp::RealTime::zeroTime - m_delay - m_delay;
+
+ return true;
+}
+
+void
+Onset::reset()
+{
+}
+
+size_t
+Onset::getPreferredStepSize() const
+{
+ return 512;
+}
+
+size_t
+Onset::getPreferredBlockSize() const
+{
+ return 2 * getPreferredStepSize();
+}
+
+Onset::ParameterList
+Onset::getParameterDescriptors() const
+{
+ ParameterList list;
+
+ ParameterDescriptor desc;
+ desc.identifier = "onsettype";
+ desc.name = "Onset Detection Function Type";
+ desc.minValue = 0;
+ desc.maxValue = 6;
+ desc.defaultValue = (int)aubio_onset_complex;
+ desc.isQuantized = true;
+ desc.quantizeStep = 1;
+ desc.valueNames.push_back("Energy Based");
+ desc.valueNames.push_back("Spectral Difference");
+ desc.valueNames.push_back("High-Frequency Content");
+ desc.valueNames.push_back("Complex Domain");
+ desc.valueNames.push_back("Phase Deviation");
+ desc.valueNames.push_back("Kullback-Liebler");
+ desc.valueNames.push_back("Modified Kullback-Liebler");
+ list.push_back(desc);
+
+ desc = ParameterDescriptor();
+ desc.identifier = "peakpickthreshold";
+ desc.name = "Peak Picker Threshold";
+ desc.minValue = 0;
+ desc.maxValue = 1;
+ desc.defaultValue = 0.3;
+ desc.isQuantized = false;
+ list.push_back(desc);
+
+ desc = ParameterDescriptor();
+ desc.identifier = "silencethreshold";
+ desc.name = "Silence Threshold";
+ desc.minValue = -120;
+ desc.maxValue = 0;
+ desc.defaultValue = -90;
+ desc.unit = "dB";
+ desc.isQuantized = false;
+ list.push_back(desc);
+
+ return list;
+}
+
+float
+Onset::getParameter(std::string param) const
+{
+ if (param == "onsettype") {
+ return m_onsettype;
+ } else if (param == "peakpickthreshold") {
+ return m_threshold;
+ } else if (param == "silencethreshold") {
+ return m_silence;
+ } else {
+ return 0.0;
+ }
+}
+
+void
+Onset::setParameter(std::string param, float value)
+{
+ if (param == "onsettype") {
+ switch (lrintf(value)) {
+ case 0: m_onsettype = aubio_onset_energy; break;
+ case 1: m_onsettype = aubio_onset_specdiff; break;
+ case 2: m_onsettype = aubio_onset_hfc; break;
+ case 3: m_onsettype = aubio_onset_complex; break;
+ case 4: m_onsettype = aubio_onset_phase; break;
+ case 5: m_onsettype = aubio_onset_kl; break;
+ case 6: m_onsettype = aubio_onset_mkl; break;
+ }
+ } else if (param == "peakpickthreshold") {
+ m_threshold = value;
+ } else if (param == "silencethreshold") {
+ m_silence = value;
+ }
+}
+
+Onset::OutputList
+Onset::getOutputDescriptors() const
+{
+ OutputList list;
+
+ OutputDescriptor d;
+ d.identifier = "onsets";
+ d.name = "Onsets";
+ d.unit = "";
+ d.hasFixedBinCount = true;
+ d.binCount = 0;
+ d.sampleType = OutputDescriptor::VariableSampleRate;
+ d.sampleRate = 0;
+ list.push_back(d);
+
+ d = OutputDescriptor();
+ d.identifier = "detectionfunction";
+ d.name = "Onset Detection Function";
+ d.unit = "";
+ d.hasFixedBinCount = true;
+ d.binCount = m_channelCount;
+ d.hasKnownExtents = false;
+ d.isQuantized = false;
+ d.sampleType = OutputDescriptor::OneSamplePerStep;
+ list.push_back(d);
+
+ return list;
+}
+
+Onset::FeatureSet
+Onset::process(const float *const *inputBuffers,
+ Vamp::RealTime timestamp)
+{
+ for (size_t i = 0; i < m_stepSize; ++i) {
+ for (size_t j = 0; j < m_channelCount; ++j) {
+ fvec_write_sample(m_ibuf, inputBuffers[j][i], j, i);
+ }
+ }
+
+ aubio_pvoc_do(m_pv, m_ibuf, m_fftgrain);
+ aubio_onsetdetection(m_onsetdet, m_fftgrain, m_onset);
+
+ bool isonset = aubio_peakpick_pimrt(m_onset, m_peakpick);
+
+ if (isonset) {
+ if (aubio_silence_detection(m_ibuf, m_silence)) {
+ isonset = false;
+ }
+ }
+
+ FeatureSet returnFeatures;
+
+ if (isonset) {
+ if (timestamp - m_lastOnset >= m_delay) {
+ Feature onsettime;
+ onsettime.hasTimestamp = true;
+ if (timestamp < m_delay) timestamp = m_delay;
+ onsettime.timestamp = timestamp - m_delay;
+ returnFeatures[0].push_back(onsettime);
+ m_lastOnset = timestamp;
+ }
+ }
+ Feature feature;
+ for (size_t j = 0; j < m_channelCount; ++j) {
+ feature.values.push_back(m_onset->data[j][0]);
+ }
+ returnFeatures[1].push_back(feature);
+
+ return returnFeatures;
+}
+
+Onset::FeatureSet
+Onset::getRemainingFeatures()
+{
+ return FeatureSet();
+}
+
--- /dev/null
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Vamp feature extraction plugins using Paul Brossier's Aubio library.
+
+ Centre for Digital Music, Queen Mary, University of London.
+ This file copyright 2006 Chris Cannam.
+
+ 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. See the file
+ COPYING included with this distribution for more information.
+
+*/
+
+#ifndef _ONSET_PLUGIN_H_
+#define _ONSET_PLUGIN_H_
+
+#include <vamp-sdk/Plugin.h>
+#include <aubio/aubio.h>
+
+class Onset : public Vamp::Plugin
+{
+public:
+ Onset(float inputSampleRate);
+ virtual ~Onset();
+
+ bool initialise(size_t channels, size_t stepSize, size_t blockSize);
+ void reset();
+
+ InputDomain getInputDomain() const { return TimeDomain; }
+
+ std::string getIdentifier() const;
+ std::string getName() const;
+ std::string getDescription() const;
+ std::string getMaker() const;
+ int getPluginVersion() const;
+ std::string getCopyright() const;
+
+ ParameterList getParameterDescriptors() const;
+ float getParameter(std::string) const;
+ void setParameter(std::string, float);
+
+ size_t getPreferredStepSize() const;
+ size_t getPreferredBlockSize() const;
+
+ OutputList getOutputDescriptors() const;
+
+ FeatureSet process(const float *const *inputBuffers,
+ Vamp::RealTime timestamp);
+
+ FeatureSet getRemainingFeatures();
+
+protected:
+ fvec_t *m_ibuf;
+ cvec_t *m_fftgrain;
+ fvec_t *m_onset;
+ aubio_pvoc_t *m_pv;
+ aubio_pickpeak_t *m_peakpick;
+ aubio_onsetdetection_t *m_onsetdet;
+ aubio_onsetdetection_type m_onsettype;
+ float m_threshold;
+ float m_silence;
+ size_t m_stepSize;
+ size_t m_blockSize;
+ size_t m_channelCount;
+ Vamp::RealTime m_delay;
+ Vamp::RealTime m_lastOnset;
+};
+
+
+#endif
import os.path
import glob
-plugin_files = glob.glob ("*.cpp")
+plugin_files = Split("""
+plugins.cpp
+AmplitudeFollower.cpp
+PercussionOnsetDetector.cpp
+SpectralCentroid.cpp
+ZeroCrossing.cpp
+""")
+
+aubio_files = Split ("""
+Onset.cpp
+""")
Import('env install_prefix libraries')
-vampplugs = env.Copy()
+vampplugs = env.Clone()
vampplugs.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk")
vampplugs.Merge ([libraries['vamp'],
libraries['vamphost']
])
-libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', plugin_files)
+sources = plugin_files
+
+if vampplugs['AUBIO']:
+ sources += aubio_files
+ vampplugs.Merge ([libraries['aubio']])
+
+libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', sources)
Default(libvampplugins)
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript' ] +
- plugin_files +
+ plugin_files + aubio_files +
glob.glob('*.h')))
#include "SpectralCentroid.h"
#include "PercussionOnsetDetector.h"
#include "AmplitudeFollower.h"
+#include "Onset.h"
static Vamp::PluginAdapter<ZeroCrossing> zeroCrossingAdapter;
static Vamp::PluginAdapter<SpectralCentroid> spectralCentroidAdapter;
static Vamp::PluginAdapter<PercussionOnsetDetector> percussionOnsetAdapter;
static Vamp::PluginAdapter<AmplitudeFollower> amplitudeAdapter;
+static Vamp::PluginAdapter<Onset> onsetAdapter;
const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
unsigned int index)
case 1: return spectralCentroidAdapter.getDescriptor();
case 2: return percussionOnsetAdapter.getDescriptor();
case 3: return amplitudeAdapter.getDescriptor();
+ case 4: return onsetAdapter.getDescriptor();
default: return 0;
}
}
""")
Import('env install_prefix libraries')
-vampsdk = env.Copy()
+vampsdk = env.Clone()
vampsdk.Merge ([libraries['fftw3'], libraries['fftw3f']])
authorization.
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "PluginHostAdapter.h"
namespace Vamp
#include "PluginChannelAdapter.h"
#include "PluginBufferingAdapter.h"
+#include <string>
+#include <cstring>
#include <fstream>
#include <cctype> // tolower
#include <cstring>
<tbody>
<row>
<entry>
- <keycombo><keycap>a</keycap> </keycombo>
+ <keycombo><keycap>a</keycap></keycombo>
</entry>
<entry>
- relative alignment of region sync points or starts
+ align regions using sync points and keeping relative positions
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Meta</keycap><keycap>a</keycap> </keycombo>
+ <keycombo><keycap>Alt</keycap><keycap>a</keycap></keycombo>
</entry>
<entry>
- absolute alignment of region sync points or starts
+ align region ends
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>a</keycap>
- </keycombo>
+ <keycombo><keycap>Shift</keycap><keycap>a</keycap></keycombo>
</entry>
<entry>
- relative alignment of region ends
+ align region sync points without keeping relative positions
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>Meta</keycap><keycap>a</keycap>
- </keycombo>
+ <keycombo><keycap>Mod4</keycap><keycap>a</keycap></keycombo>
</entry>
<entry>
- align region ends
+ align region starts and keeping relative positions
</entry>
</row>
</tbody>
<tbody>
<row>
<entry>
- <keycombo><keycap>left arrow</keycap> </keycombo>
+ <keycombo><keycap>f</keycap></keycombo>
</entry>
<entry>
- move editor timeline earlier
+ fit tracks
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>b</keycap> </keycombo>
+ <keycombo><keycap>Up</keycap></keycombo>
</entry>
<entry>
- move editor timeline earlier
+ step tracks up
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>right arrow</keycap> </keycombo>
+ <keycombo><keycap>Down</keycap></keycombo>
</entry>
<entry>
- move editor timeline later
+ step tracks down
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>f</keycap> </keycombo>
+ <keycombo><keycap>Page_Down</keycap></keycombo>
</entry>
<entry>
- move editor timeline later
+ scroll tracks down
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Page_Up</keycap> </keycombo>
+ <keycombo><keycap>Page_Up</keycap></keycombo>
</entry>
<entry>
- scroll track display up
+ scroll tracks up
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Page_Down</keycap> </keycombo>
+ <keycombo><keycap>Shift</keycap><keycap>e</keycap></keycombo>
</entry>
<entry>
- scroll track display down
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Up arrow</keycap> </keycombo>
- </entry>
-
- <entry>
- step track display up
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Down arrow</keycap> </keycombo>
- </entry>
-
- <entry>
- step track display down
+ show editor mixer
</entry>
</row>
</tbody>
</row>
</thead>
<tbody>
+ <row>
+ <entry>
+ <keycombo><keycap>`</keycap></keycombo>
+ </entry>
+
+ <entry>
+ cycle-edit-point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>~</keycap></keycombo>
+ </entry>
+
+ <entry>
+ cycle-edit-point-with-marker
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>e</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set-edit-point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>Return</keycap></keycombo>
+ </entry>
+
+ <entry>
+ edit-to-playhead
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>F1</keycap></keycombo>
+ </entry>
+
+ <entry>
+ edit-cursor-to-range-start
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>F2</keycap></keycombo>
+ </entry>
+
+ <entry>
+ edit-cursor-to-range-end
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>'</keycap></keycombo>
+ </entry>
+
+ <entry>
+ edit-cursor-to-previous-region-sync
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>;</keycap></keycombo>
+ </entry>
+
+ <entry>
+ edit-cursor-to-next-region-sync
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Left</keycap></keycombo>
+ </entry>
+
+ <entry>
+ selected-marker-to-previous-region-boundary
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Right</keycap></keycombo>
+ </entry>
+
+ <entry>
+ selected-marker-to-next-region-boundary
+ </entry>
+ </row>
+
<row>
<entry>
<keycombo><keycap>e</keycap> </keycombo>
</entry>
<entry>
- position edit cursor at mouse pointer
+ position selected marker at mouse pointer
</entry>
</row>
</entry>
<entry>
- move edit cursor to playhead
+ move selected marker to playhead
</entry>
</row>
</entry>
<entry>
- move edit cursor to earlier region start
+ move selected marker to earlier region start
</entry>
</row>
</entry>
<entry>
- move edit cursor to earlier region end
+ move selected marker to earlier region end
</entry>
</row>
</entry>
<entry>
- move edit cursor to next region start
+ move selected marker to next region start
</entry>
</row>
</entry>
<entry>
- move edit cursor to next region end
+ move selected marker to next region end
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>””’</keycap> </keycombo>
+ <keycombo><keycap>'</keycap> </keycombo>
</entry>
<entry>
- move edit cursor to next region sync
+ move selected marker to next region sync
</entry>
</row>
</entry>
<entry>
- moved edit cursor to previous region sync
+ moved selected marker to previous region sync
</entry>
</row>
</entry>
<entry>
- move edit cursor to start of range selection (if defined)
+ move selected marker to start of range selection (if defined)
</entry>
</row>
</entry>
<entry>
- move edit cursor to end of range selection (if defined)
+ move selected marker to end of range selection (if defined)
</entry>
</row>
</tbody>
<row>
<entry>
- <keycombo><keycap>Keypad ></keycap> </keycombo>
+ <keycombo><keycap>]</keycap></keycombo>
</entry>
<entry>
- move playhead to next marker
+ set loop range from edit range
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Keypad <</keycap> </keycombo>
+ <keycombo><keycap>Alt</keycap><keycap>]</keycap></keycombo>
</entry>
<entry>
- move playhead to previous marker
+ set loop range from selected region(s)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>[</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set punch range from edit range
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>[</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set punch range from selected region(s)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_1</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 1
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_2</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 2
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_3</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 3
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_4</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 4
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_5</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 5
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_6</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 6
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_7</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 7
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_8</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 8
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>KP_9</keycap></keycombo>
+ </entry>
+
+ <entry>
+ goto mark 9
</entry>
</row>
</tbody>
--- /dev/null
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-editor-canvas-key-bindings">
+ <title>Mark & Range Key Bindings</title>
+ <table id="tbl-editor-canvas-key-bindings">
+ <title>Editor Canvas Key Bindings</title>
+ <tgroup cols = "2">
+ <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+ <colspec colnum="2" colname="Action" colwidth= "2"/>
+ <thead>
+ <row>
+ <entry>
+ Key Binding
+ </entry>
+
+ <entry>
+ Action
+ </entry>
+ </row>
+ </thead>
+ <tbody></tbody>
+ </tgroup>
+ </table>
+<!--
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="Some_Subsection.xml" />
+ -->
+</section>
<tbody>
<row>
<entry>
- <keycombo><keycap>l</keycap> </keycombo>
+ <keycombo><keycap>1</keycap></keycombo>
</entry>
<entry>
- toggle auto loop
+ toggle edit mode
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>f</keycap> </keycombo>
+ <keycombo><keycap>2</keycap></keycombo>
+ </entry>
+
+ <entry>
+ cycle snap mode
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>3</keycap></keycombo>
+ </entry>
+
+ <entry>
+ cycle snap choice
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>f</keycap> </keycombo>
</entry>
<entry>
toggle follow playhead
</entry>
</row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>9</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set tempo from region
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>0</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set tempo from edit range
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>t</keycap></keycombo>
+ </entry>
+
+ <entry>
+ insert time
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Delete</keycap></keycombo>
+ </entry>
+
+ <entry>
+ remove last capture
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
<section id="sn-editor-nudging-key-bindings">
<title>Nudging Key Bindings</title>
+ <para>
+ Nudging will move selected regions if there are any, otherwise the
+ playhead.
+ </para>
+
<table id="tbl-editor-nudging-key-bindings">
<title>Nudging Key Bindings</title>
<tgroup cols = "2">
<tbody>
<row>
<entry>
- <keycombo><keycap>+</keycap> </keycombo> (keypad)
+ <keycombo><keycap>Keypad +</keycap></keycombo>
</entry>
<entry>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>+</keycap> </keycombo>
- (keypad)
- </entry>
-
- <entry>
- nudge next forward
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>-</keycap> </keycombo> (keypad)
+ <keycombo><keycap>Keypad -</keycap></keycombo>
</entry>
<entry>
nudge backward
</entry>
</row>
-
- <row>
- <entry>
- <keycombo><keycap>Ctrl</keycap><keycap>-</keycap> </keycombo>
- </entry>
-
- <entry>
- nudge next backward
- </entry>
- </row>
</tbody>
</tgroup>
</table>
</row>
</thead>
<tbody>
+ <row>
+ <entry>
+ <keycombo><keycap>Home</keycap></keycombo>
+ </entry>
+
+ <entry>
+ Move playhead to session start
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>End</keycap></keycombo>
+ </entry>
+
+ <entry>
+ Move playhead to session end
+ </entry>
+ </row>
+
<row>
<entry>
<keycombo><keycap>p</keycap> </keycombo>
</entry>
<entry>
- move playhead to edit cursor
+ move playhead to selected marker (if any)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>Return</keycap>
+ </keycombo>
+ </entry>
+
+ <entry>
+ move selected marker (if any) to playhead
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>.</keycap></keycombo>
+ </entry>
+
+ <entry>
+ playhead to next region boundary
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>.</keycap></keycombo>
+ </entry>
+
+ <entry>
+ playhead to next region sync
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>,</keycap></keycombo>
+ </entry>
+
+ <entry>
+ playhead to previous region boundary
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>,</keycap></keycombo>
+ </entry>
+
+ <entry>
+ playhead to previous region sync
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Right</keycap></keycombo>
+ </entry>
+
+ <entry>
+ tab to transient forwards
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Tab</keycap> </keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>Left</keycap></keycombo>
</entry>
<entry>
- move playhead to later region start
+ tab to transient backwards
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>Tab</keycap> </keycombo>
+ <keycombo><keycap>Left</keycap></keycombo>
</entry>
<entry>
- move playhead to later region end
+ playhead to previous region boundary
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>`</keycap> </keycombo>
+ <keycombo><keycap>Alt</keycap><keycap>Left</keycap></keycombo>
</entry>
<entry>
- move playhead to earlier region start
+ nudge playhead backward
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>`</keycap> </keycombo>
+ <keycombo><keycap>Right</keycap></keycombo>
</entry>
<entry>
- move playhead to next mark
+ playhead to next region boundary
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>|</keycap> </keycombo> (keypad)
+ <keycombo><keycap>Alt</keycap><keycap>Right</keycap></keycombo>
</entry>
<entry>
- move playhead to previous mark
+ nudge playhead forward
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>l</keycap> </keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>Keypad
+ Right</keycap></keycombo>
</entry>
<entry>
- center screen around playhead
+ jump forward to mark
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>g</keycap> </keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>Keypad
+ Left</keycap></keycombo>
</entry>
<entry>
- goto
+ jump backward to mark
</entry>
</row>
</tbody>
<tbody>
<row>
<entry>
- <keycombo><keycap>Keypad Down arrow</keycap> </keycombo>
+ <keycombo><keycap>F6</keycap></keycombo>
</entry>
<entry>
- begin range definition while transport rolls
+ select range using edit range
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Keypad Up arrow</keycap> </keycombo>
- </entry>
-
- <entry>
- end range definition while transport rolls
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Shift</keycap><keycap>Tab</keycap> </keycombo>
+ <keycombo><keycap>></keycap></keycombo>
</entry>
<entry>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>Tab</keycap>
- </keycombo>
+ <keycombo><keycap><</keycap></keycombo>
</entry>
<entry>
extend range to start of region
</entry>
</row>
-
- <row>
- <entry>
- <keycombo><keycap>Meta</keycap><keycap>s</keycap> </keycombo>
- </entry>
-
- <entry>
- duplicate range
- </entry>
- </row>
</tbody>
</tgroup>
</table>
<section id="sn-editor-region-operation-key-bindings">
<title>Region Operations Key Bindings</title>
+ <para>
+ Region operations generally operate on the currently selected regions,
+ if any. If none are selected but 1 or more tracks are selected then
+ regions in those tracks at the edit point will be used. If no tracks are
+ selected, then any region at the edit point will be used.
+ </para>
+
<table id="tbl-editor-region-operation-key-bindings">
<title>Region Operation Key Bindings</title>
<tgroup cols = "2">
</entry>
<entry>
- split region(s) at mouse
+ split region(s) at edit point
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Alt</keycap><keycap>s</keycap> </keycombo>
+ <keycombo><keycap>i</keycap></keycombo>
</entry>
<entry>
- split region(s) at edit cursor
+ insert region (from region list)
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Insert</keycap> </keycombo>
+ <keycombo><keycap>d</keycap></keycombo>
</entry>
<entry>
- insert selected region (from region list)
+ duplicate region
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Meta</keycap><keycap>d</keycap> </keycombo>
+ <keycombo><keycap>n</keycap></keycombo>
</entry>
<entry>
- duplicate region
+ normalize region
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Alt</keycap><keycap>r</keycap> </keycombo>
+ <keycombo><keycap>m</keycap></keycombo>
</entry>
<entry>
- reverse region
+ mute/unmute region
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Alt</keycap><keycap>n</keycap> </keycombo>
+ <keycombo><keycap>~</keycap></keycombo>
</entry>
<entry>
- normalize region
+ boost region gain
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>&</keycap></keycombo>
+ </entry>
+
+ <entry>
+ cut region gain
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>h</keycap></keycombo>
+ </entry>
+
+ <entry>
+ play selected regions
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>j</keycap></keycombo>
+ </entry>
+
+ <entry>
+ trim to start at edit point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>k</keycap></keycombo>
+ </entry>
+
+ <entry>
+ trim to end at edit point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>/</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set fade in length (via edit point)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>\</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set fade out length (via edit point)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>{</keycap></keycombo>
+ </entry>
+
+ <entry>
+ trim from start to edit point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>}</keycap></keycombo>
+ </entry>
+
+ <entry>
+ trim from edit point to end
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>F3</keycap></keycombo>
+ </entry>
+
+ <entry>
+ crop (to edit range)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>F4</keycap></keycombo>
+ </entry>
+
+ <entry>
+ separate (using edit range)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>v</keycap></keycombo>
+ </entry>
+
+ <entry>
+ set region sync point(s) at edit point
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>F5</keycap></keycombo>
+ </entry>
+
+ <entry>
+ pitch shift region
</entry>
</row>
</tbody>
--- /dev/null
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-editor-selection-key-bindings">
+ <title>Selection Key Bindings</title>
+ <table id="tbl-selection-key-bindings">
+ <title>Selection Key Bindings</title>
+ <tgroup cols = "2">
+ <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+ <colspec colnum="2" colname="Action" colwidth= "2"/>
+ <thead>
+ <row>
+ <entry>
+ Key Binding
+ </entry>
+
+ <entry>
+ Action
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>a</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>p</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all before playhead
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>Ctrl</keycap><keycap>p</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all after playhead
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>u</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all within edit range
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>i</keycap></keycombo>
+ </entry>
+
+ <entry>
+ invert selection
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>Ctrl</keycap><keycap>e</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all after edit cursor
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>e</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all before edit cursor
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>d</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all in punch range
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>l</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select all in loop range
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>Up</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select prev route
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>Down</keycap></keycombo>
+ </entry>
+
+ <entry>
+ select next route
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+<!--
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="Some_Subsection.xml" />
+ -->
+</section>
]>
<section id="sn-editor-zoom-key-bindings">
- <title>Zoom Key Bindings</title>
+ <title>Zoom and Visual State Key Bindings</title>
+ <para>
+ By default, 12 function keys (F1-F12) are assigned to visual state
+ management. All of them are represented in the table as "Fn".
+ </para>
+
<table id="tbl-editor-zoom-key-bindings">
<title>Editor Zoom Key Bindings</title>
<tgroup cols = "2">
<row>
<entry>
- <keycombo><keycap>Z</keycap> </keycombo>
+ <keycombo><keycap>z</keycap> </keycombo>
</entry>
<entry>
switch zoom focus to playhead
</entry>
</row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Alt</keycap><keycap>z</keycap>
+ </keycombo>
+ </entry>
+
+ <entry>
+ Zoom to fit selected region(s) (time axis only)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>z</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Zoom to fit selected region(s) (time axis & vertical axis)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Shift</keycap><keycap>z</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Undo zoom change
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Fn</keycap></keycombo>
+ </entry>
+
+ <entry>
+ Save current visual state as VS #n (hold for 2 secs)
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Ctrl</keycap><keycap>Fn</keycap></keycombo>
+ </entry>
+
+ <entry>
+ Restore visual state #n (occurs on key release)
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
</entry>
</row>
- <row>
- <entry>
- <keycombo><keycap>Alt</keycap><keycap>e</keycap> </keycombo>
- </entry>
-
- <entry>
- Raise the Editor Window
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Alt</keycap><keycap>m</keycap> </keycombo>
- </entry>
-
- <entry>
- Toggle display of the locations window
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Alt</keycap><keycap>c</keycap> </keycombo>
- </entry>
-
- <entry>
- Toggle display of the options editor
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Ctrl</keycap><keycap>t</keycap> </keycombo>
- </entry>
-
- <entry>
- Add a track or bus
- </entry>
- </row>
-
<row>
<entry>
<keycombo><keycap>Ctrl</keycap><keycap>s</keycap> </keycombo>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>q</keycap> </keycombo>
- </entry>
-
- <entry>
- Quit
- </entry>
- </row>
-
- <row>
- <entry>
- <keycombo><keycap>Ctrl</keycap><keycap>u</keycap> </keycombo>
+ <keycombo><keycap>Alt</keycap><keycap>i</keycap> </keycombo>
</entry>
<entry>
- Starts a prefix entry sequence
+ Import existing files into a session.
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>m</keycap> </keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>q</keycap> </keycombo>
</entry>
<entry>
- Toggle sending MIDI feedback
+ Quit
</entry>
</row>
</tbody>
<title>Key Bindings</title>
<para>
Note that all keyboard bindings can be changed in either the system or
- the user's Ardour configuration file
- (<filename>$HOME/.ardour/ardour.rc</filename>).
+ the user's Ardour key bindings file
+ (<filename>$HOME/.ardour2/ardour.bindings</filename>).
</para>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="general_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="transport_key_bindings.xml" />
+ href="window_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="mixer_window_key_bindings.xml" />
+ href="transport_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="editor_window_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="editor_aligning_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="editor_standard_editing_key_bindings.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="editor_selection_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="editor_range_operations_key_bindings.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
<row>
<entry>
- <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>space</keycap></keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>space</keycap></keycombo>
</entry>
<entry>
- Raise the Editor Window
+ One-touch record (start transport & recording)
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Shift</keycap><keycap>r</keycap></keycombo>
+ <keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>space</keycap></keycombo>
</entry>
<entry>
- Toggle transport record-enable state
+ Toggle transport motion, deleting any recorded material if
+ recording
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>Home</keycap></keycombo>
+ <keycombo><keycap>Shift</keycap><keycap>r</keycap></keycombo>
</entry>
<entry>
- Move playhead to start
+ Toggle transport record-enable state
</entry>
</row>
<row>
<entry>
- <keycombo><keycap>End</keycap></keycombo>
+ <keycombo><keycap>l</keycap> </keycombo>
</entry>
<entry>
- Move playhead to end
+ toggle looping
</entry>
</row>
</tbody>
--- /dev/null
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+]>
+
+<section id="sn-window-key-bindings">
+ <title>Window Visibility Key Bindings</title>
+ <table id="tbl-window-key-bindings">
+ <title>Window Visibility Key Bindings</title>
+ <tgroup cols = "2">
+ <colspec colnum="1" colname="Key Binding" colwidth="1"/>
+ <colspec colnum="2" colname="Action" colwidth= "2"/>
+ <thead>
+ <row>
+ <entry>
+ Key Binding
+ </entry>
+
+ <entry>
+ Action
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>e</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Raise editor window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>m</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Raise mixer window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>l</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle locations window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>b</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle "big clock" window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>k</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle key bindings window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>f</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle Rhythm Ferret window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>o</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle preferences window
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <keycombo><keycap>Alt</keycap><keycap>c</keycap> </keycombo>
+ </entry>
+
+ <entry>
+ Toggle color manager window
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+<!--
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="Some_Subsection.xml" />
+ -->
+</section>
#ifndef __ardour_svn_revision_h__
#define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "3201";
+static const char* ardour_svn_revision = "3530";
#endif
#!/usr/bin/env perl
# Ardour session synthesizer
-# (c)Sampo Savolainen 2007
+# (c)Sampo Savolainen 2007-2008
#
# GPL
# This reads an Ardour session file and creates zero-signal source files
use ARDOUR::SourceInfoLoader;
+my $usage = "usage: synthesize_sources.pl samplerate [session name, the name must match the directory and the .ardour file in it] [options: -sine for 440hz sine waves in wave files]\n";
-my ($samplerate, $sessionName) = @ARGV;
+my ($samplerate, $sessionName, @options) = @ARGV;
if ( ! -d $sessionName || ! -f $sessionName."/".$sessionName.".ardour" ) {
- print "usage: synthesize_sources.pl samplerate [session name, the name must match the directory and the .ardour file in it]\n";
+ print $usage;
exit;
}
+my $waveType = "silent";
+
+foreach my $o (@options) {
+ if ($o eq "-sine") {
+ $waveType = "sine";
+ } elsif ($o eq "-silent") {
+ $waveType = "silent";
+ } else {
+ print "unknown parameter ".$o."\n";
+ print $usage;
+ exit;
+
+ }
+
+}
+
my $sessionFile = $sessionName."/".$sessionName.".ardour";
foreach my $tmp (keys %sources) {
- print "Generating ".$audioFileDirectory."/".$sources{$tmp}->{name}.".wav\n";
+ print "Generating ".$audioFileDirectory."/".$sources{$tmp}->{name}."\n";
- system("sox",
+ my @cmd =
+ ("sox",
"-t", "raw", # /dev/zero is raw :)
"-r", $samplerate, # set sample rate
"-c", "1", # 1 channel
"trim", "0", $sources{$tmp}->{calculated_length}."s" # trim silence to wanted sample amount
);
+ if ($waveType eq "sine") {
+ @cmd = (@cmd, "synth","sin","%0", "vol", "0.2", "fade","q","0.01s", $sources{$tmp}->{calculated_length}."s" , "0.01s");
+ }
+ system(@cmd);
}
Import('env install_prefix final_prefix config_prefix subst_dict libraries')
-ardour_vst = env.Copy()
+ardour_vst = env.Clone()
sources = Split ("""
winmain.c