diff options
64 files changed, 7925 insertions, 1265 deletions
diff --git a/SConstruct b/SConstruct index 8a7364b7c1..651a6a3eab 100644 --- a/SConstruct +++ b/SConstruct @@ -231,6 +231,7 @@ def i18n (buildenv, sources, installenv): buildenv.PoBuild(po_file, ['po/'+po_file, potfile]) mo_file = po_file.replace (".po", ".mo") installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file)) + installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file)) for lang in languages: modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/')) @@ -363,7 +364,7 @@ def distcopy (target, source, env): return p.close () def tarballer (target, source, env): - cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'" + " --exclude .svn --exclude '.svn/*'" print 'running ', cmd, ' ... ' p = os.popen (cmd) return p.close () @@ -766,34 +767,32 @@ def prep_libcheck(topenv, libinfo): prep_libcheck(env, env) -# -# check for VAMP and rubberband (currently optional) -# -libraries['vamp'] = LibraryInfo() +libraries['vamp'] = LibraryInfo (LIBS='vampsdk', + LIBPATH='#libs/vamp-sdk', + CPPPATH='#libs/vamp-sdk/vamp') env['RUBBERBAND'] = False -#conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } ) +#conf = Configure (env) # -#if conf.CheckPKGExists('vamp-sdk'): -# have_vamp = True -# libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk') +#if conf.CheckHeader ('fftw3.h'): +# env['RUBBERBAND'] = True +# libraries['rubberband'] = LibraryInfo (LIBS='rubberband', +# LIBPATH='#libs/rubberband', +# CPPPATH='#libs/rubberband', +# CCFLAGS='-DUSE_RUBBERBAND') #else: -# have_vamp = False -# -#libraries['vamp'] = conf.Finish () +# print "" +# print "-------------------------------------------------------------------------" +# print "You do not have the FFTW single-precision development package installed." +# print "This prevents Ardour from using the Rubberband library for timestretching" +# print "and pitchshifting. It will fall back on SoundTouch for timestretch, and " +# print "pitchshifting will not be available." +# print "-------------------------------------------------------------------------" +# print "" # -#if have_vamp: -# if os.path.exists ('libs/rubberband/src'): -# conf = Configure (libraries['vamp']) -# if conf.CheckHeader ('fftw3.h'): -# env['RUBBERBAND'] = True -# libraries['rubberband'] = LibraryInfo (LIBS='rubberband', -# LIBPATH='#libs/rubberband', -# CPPPATH='#libs/rubberband', -# CCFLAGS='-DUSE_RUBBERBAND') -# libraries['vamp'] = conf.Finish () +#conf.Finish() # # Check for libusb @@ -995,6 +994,7 @@ if env['SYSLIBS']: 'libs/pbd', 'libs/midi++2', 'libs/ardour', + 'libs/vamp-sdk', # these are unconditionally included but have # tests internally to avoid compilation etc # if VST is not set @@ -1068,6 +1068,7 @@ else: 'libs/pbd', 'libs/midi++2', 'libs/ardour', + 'libs/vamp-sdk', # these are unconditionally included but have # tests internally to avoid compilation etc # if VST is not set @@ -1132,7 +1133,7 @@ else: timefx_subdirs = ['libs/soundtouch'] #if env['RUBBERBAND']: # timefx_subdirs += ['libs/rubberband'] - + opts.Save('scache.conf', env) Help(opts.GenerateHelpText(env)) diff --git a/ardour.rc.in b/ardour.rc.in index bbc0f091ec..ed40ac465a 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -37,7 +37,9 @@ <Option name="destructive-xfade-msecs" value="20"/> <Option name="periodic-safety-backups" value="1"/> <Option name="periodic-safety-backup-interval" value="120"/> - <Option name="show-track-meters" value="1"/> + <Option name="show-track-meters" value="1"/> + <Option name="default-narrow_ms" value="0"/> + <Option name="smpte-format" value="6"/> </Config> <extra> <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/> diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 70dac73a59..ca77ccb903 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1341,7 +1341,6 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t } catch (...) { - cerr << "About to complain about JACK\n"; MessageDialog msg (*editor, _("There are insufficient JACK ports available\n\ to create a new track or bus.\n\ @@ -2270,7 +2269,7 @@ ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_e if (session_name[0] == '/' || (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') || (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) { - cerr << "here\n"; + if (load_session (Glib::path_get_dirname (session_name), session_name)) { response = Gtk::RESPONSE_NONE; goto try_again; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 325584f7ed..41261b7079 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -901,19 +901,6 @@ Editor::show_window () } void -Editor::tie_vertical_scrolling () -{ - double y1 = vertical_adjustment.get_value(); - - playhead_cursor->set_y_axis (y1); - if (logo_item) { - logo_item->property_y() = y1; - } - - controls_layout.get_vadjustment()->set_value (y1); -} - -void Editor::instant_save () { if (!constructed || !ARDOUR_UI::instance()->session_loaded) { @@ -1431,28 +1418,179 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i fade_context_menu.popup (button, time); } -/* Pop up the general track context menu for when the user clicks pretty much anywhere in a track or bus */ void -Editor::popup_track_context_menu (int button, int32_t time, nframes_t frame) +Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection, nframes_t frame) +{ + using namespace Menu_Helpers; + Menu* (Editor::*build_menu_function)(nframes_t); + Menu *menu; + + switch (item_type) { + case RegionItem: + case RegionViewName: + case RegionViewNameHighlight: + if (with_selection) { + build_menu_function = &Editor::build_track_selection_context_menu; + } else { + build_menu_function = &Editor::build_track_region_context_menu; + } + break; + + case SelectionItem: + if (with_selection) { + build_menu_function = &Editor::build_track_selection_context_menu; + } else { + build_menu_function = &Editor::build_track_context_menu; + } + break; + + case CrossfadeViewItem: + build_menu_function = &Editor::build_track_crossfade_context_menu; + break; + + case StreamItem: + if (clicked_routeview->get_diskstream()) { + build_menu_function = &Editor::build_track_context_menu; + } else { + build_menu_function = &Editor::build_track_bus_context_menu; + } + break; + + default: + /* probably shouldn't happen but if it does, we don't care */ + return; + } + + menu = (this->*build_menu_function)(frame); + menu->set_name ("ArdourContextMenu"); + + /* now handle specific situations */ + + switch (item_type) { + case RegionItem: + case RegionViewName: + case RegionViewNameHighlight: + if (!with_selection) { + if (region_edit_menu_split_item) { + if (clicked_regionview && clicked_regionview->region()->covers (get_preferred_edit_position())) { + ActionManager::set_sensitive (ActionManager::edit_point_in_region_sensitive_actions, true); + } else { + ActionManager::set_sensitive (ActionManager::edit_point_in_region_sensitive_actions, false); + } + } + /* + if (region_edit_menu_split_multichannel_item) { + if (clicked_regionview && clicked_regionview->region().n_channels() > 1) { + // GTK2FIX find the action, change its sensitivity + // region_edit_menu_split_multichannel_item->set_sensitive (true); + } else { + // GTK2FIX see above + // region_edit_menu_split_multichannel_item->set_sensitive (false); + } + }*/ + } + break; + + case SelectionItem: + break; + + case CrossfadeViewItem: + break; + + case StreamItem: + break; + + default: + /* probably shouldn't happen but if it does, we don't care */ + return; + } + + if (item_type != SelectionItem && clicked_routeview && clicked_routeview->audio_track()) { + + /* Bounce to disk */ + + using namespace Menu_Helpers; + MenuList& edit_items = menu->items(); + + edit_items.push_back (SeparatorElem()); + + switch (clicked_routeview->audio_track()->freeze_state()) { + case AudioTrack::NoFreeze: + edit_items.push_back (MenuElem (_("Freeze"), mem_fun(*this, &Editor::freeze_route))); + break; + + case AudioTrack::Frozen: + edit_items.push_back (MenuElem (_("Unfreeze"), mem_fun(*this, &Editor::unfreeze_route))); + break; + + case AudioTrack::UnFrozen: + edit_items.push_back (MenuElem (_("Freeze"), mem_fun(*this, &Editor::freeze_route))); + break; + } + + } + + menu->popup (button, time); +} + +Menu* +Editor::build_track_context_menu (nframes_t ignored) { - build_track_context_menu (frame)->popup (button, time); + using namespace Menu_Helpers; + + MenuList& edit_items = track_context_menu.items(); + edit_items.clear(); + + add_dstream_context_items (edit_items); + return &track_context_menu; } Menu* -Editor::build_track_context_menu (nframes_t frame) +Editor::build_track_bus_context_menu (nframes_t ignored) { using namespace Menu_Helpers; - Menu* menu = manage (new Menu); - MenuList& edit_items = menu->items(); + MenuList& edit_items = track_context_menu.items(); edit_items.clear(); - /* Build the general `track' context menu, adding what is appropriate given - the current selection */ + add_bus_context_items (edit_items); + return &track_context_menu; +} + +Menu* +Editor::build_track_region_context_menu (nframes_t frame) +{ + using namespace Menu_Helpers; + MenuList& edit_items = track_region_context_menu.items(); + edit_items.clear(); + + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (clicked_axisview); + + if (rtv) { + boost::shared_ptr<Diskstream> ds; + 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); + } + delete regions; + } + } + + add_dstream_context_items (edit_items); + + return &track_region_context_menu; +} + +Menu* +Editor::build_track_crossfade_context_menu (nframes_t frame) +{ + using namespace Menu_Helpers; + MenuList& edit_items = track_crossfade_context_menu.items(); + edit_items.clear (); - /* XXX: currently crossfades can't be selected, so we can't use the selection - to decide which crossfades to mention in the menu. I believe this will - change at some point. For now we have to use clicked_trackview to decide. */ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_axisview); if (atv) { @@ -1462,7 +1600,9 @@ Editor::build_track_context_menu (nframes_t frame) if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) != 0)) { + Playlist::RegionList* regions = pl->regions_at (frame); AudioPlaylist::Crossfades xfades; + apl->crossfades_at (frame, xfades); bool many = xfades.size() > 1; @@ -1470,24 +1610,18 @@ Editor::build_track_context_menu (nframes_t frame) for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) { add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many); } - } - } - if (!selection->time.empty()) { - add_selection_context_items (edit_items); - } + for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) { + add_region_context_items (atv->audio_view(), (*i), edit_items); + } - if (!selection->regions.empty()) { - add_region_context_items (edit_items); + delete regions; + } } - if (!selection->tracks.empty()) { - add_bus_or_audio_track_context_items (edit_items); - } - - menu->set_name ("ArdourContextMenu"); + add_dstream_context_items (edit_items); - return menu; + return &track_crossfade_context_menu; } #ifdef FFT_ANALYSIS @@ -1528,6 +1662,19 @@ Editor::analyze_range_selection() } #endif /* FFT_ANALYSIS */ +Menu* +Editor::build_track_selection_context_menu (nframes_t ignored) +{ + using namespace Menu_Helpers; + MenuList& edit_items = track_selection_context_menu.items(); + edit_items.clear (); + + add_selection_context_items (edit_items); + // edit_items.push_back (SeparatorElem()); + // add_dstream_context_items (edit_items); + + return &track_selection_context_menu; +} /** Add context menu items relevant to crossfades. * @param edit_items List to add the items to. @@ -1603,34 +1750,27 @@ Editor::add_item_with_sensitivity (Menu_Helpers::MenuList& m, Menu_Helpers::Menu } } -/** Add context menu items relevant to regions. - * @param edit_items List to add the items to. - */ void -Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) +Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> region, Menu_Helpers::MenuList& edit_items) { using namespace Menu_Helpers; - sigc::connection fooc; - Menu *region_menu = manage (new Menu); - MenuList& items = region_menu->items(); + Menu *region_menu = manage (new Menu); + MenuList& items = region_menu->items(); region_menu->set_name ("ArdourContextMenu"); - items.push_back (MenuElem (_("Edit..."), 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))); + boost::shared_ptr<AudioRegion> ar; + boost::shared_ptr<MidiRegion> mr; - Menu* sync_point_menu = manage (new Menu); - MenuList& sync_point_items = sync_point_menu->items(); - sync_point_menu->set_name("ArdourContextMenu"); - - sync_point_items.push_back (MenuElem (_("Define"), mem_fun(*this, &Editor::set_region_sync_from_edit_point))); - sync_point_items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_region_sync))); + if (region) { + ar = boost::dynamic_pointer_cast<AudioRegion> (region); + mr = boost::dynamic_pointer_cast<MidiRegion> (region); + } - items.push_back (MenuElem (_("Sync points"), *sync_point_menu)); + /* when this particular menu pops up, make the relevant region + become selected. + */ - //add_item_with_sensitivity (items, MenuElem (_("Audition"), mem_fun(*this, &Editor::audition_selected_region)), selection->regions.size() == 1); - - add_item_with_sensitivity (items, MenuElem (_("Export"), mem_fun(*this, &Editor::export_region)), selection->regions.size() == 1); + 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))); @@ -1646,97 +1786,59 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (MenuElem (_("Bounce"), mem_fun(*this, &Editor::bounce_region_selection))); #ifdef FFT_ANALYSIS - items.push_back (MenuElem (_("Analyze region"), mem_fun(*this, &Editor::analyze_region_selection))); + if (ar) + items.push_back (MenuElem (_("Analyze region"), mem_fun(*this, &Editor::analyze_region_selection))); #endif items.push_back (SeparatorElem()); + sigc::connection fooc; + items.push_back (CheckMenuElem (_("Lock"))); - region_lock_item = static_cast<CheckMenuItem*>(&items.back()); + CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back()); fooc = region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock)); - -#if FIXUP_REGION_MENU if (region->locked()) { fooc.block (true); region_lock_item->set_active(); fooc.block (false); } -#endif - - items.push_back (CheckMenuElem (_("Lock Position"))); - region_lock_position_item = static_cast<CheckMenuItem*>(&items.back()); - fooc = region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_position_lock)); -#if FIXUP_REGION_MENU - if (region->locked()) { - fooc.block (true); - region_lock_position_item->set_active(); - fooc.block (false); - } -#endif - items.push_back (CheckMenuElem (_("Mute"))); - region_mute_item = static_cast<CheckMenuItem*>(&items.back()); + CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back()); fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute)); -#if FIXUP_REGION_MENU if (region->muted()) { fooc.block (true); region_mute_item->set_active(); fooc.block (false); } -#endif if (!Profile->get_sae()) { items.push_back (CheckMenuElem (_("Opaque"))); - region_opaque_item = static_cast<CheckMenuItem*>(&items.back()); + CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back()); fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque)); -#if FIXUP_REGION_MENU if (region->opaque()) { fooc.block (true); region_opaque_item->set_active(); fooc.block (false); } -#endif } - /* We allow "Original position" if at least one region is not at its - natural position - */ - RegionSelection::iterator i = selection->regions.begin(); - while (i != selection->regions.end() && (*i)->region()->at_natural_position() == true) { - ++i; + items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize))); + if (region->at_natural_position()) { + items.back().set_sensitive (false); } - - add_item_with_sensitivity (items, MenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)), i != selection->regions.end()); items.push_back (SeparatorElem()); - - /* Find out if we have a selected audio region */ - i = selection->regions.begin(); - while (i != selection->regions.end() && boost::dynamic_pointer_cast<AudioRegion>((*i)->region()) == 0) { - ++i; - } - const bool have_selected_audio_region = (i != selection->regions.end()); - - if (have_selected_audio_region) { - - Menu* envelopes_menu = manage (new Menu); - - envelopes_menu->set_name ("ArdourContextMenu"); - -#if FIXUP_REGION_MENU - - XXX NEED TO RESOLVE ONE v. MANY REGION ISSUE + + if (ar) { - MenuList& envelopes_items = envelopes_menu->items(); - RegionView* rv = sv->find_view (ar); AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv); - + if (!Profile->get_sae()) { - envelopes_items.push_back (MenuElem (_("Reset Envelope"), mem_fun(*this, &Editor::reset_region_gain_envelopes))); + items.push_back (MenuElem (_("Reset Envelope"), mem_fun(*this, &Editor::reset_region_gain_envelopes))); - envelopes_items.push_back (CheckMenuElem (_("Envelope Visible"))); - region_envelope_visible_item = static_cast<CheckMenuItem*> (&items.back()); + items.push_back (CheckMenuElem (_("Envelope Visible"))); + CheckMenuItem* region_envelope_visible_item = static_cast<CheckMenuItem*> (&items.back()); fooc = region_envelope_visible_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_gain_envelope_visibility)); if (arv->envelope_visible()) { fooc.block (true); @@ -1744,8 +1846,8 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) fooc.block (false); } - envelopes_items.push_back (CheckMenuElem (_("Envelope Active"))); - region_envelope_active_item = static_cast<CheckMenuItem*> (&items.back()); + items.push_back (CheckMenuElem (_("Envelope Active"))); + CheckMenuItem* region_envelope_active_item = static_cast<CheckMenuItem*> (&items.back()); fooc = region_envelope_active_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_gain_envelope_active)); if (ar->envelope_active()) { @@ -1756,39 +1858,25 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (SeparatorElem()); } -#endif - items.push_back (MenuElem (_("Envelopes"), *envelopes_menu)); - -#if FIXUP_REGION_MENU if (ar->scale_amplitude() != 1.0f) { - items.push_back (MenuElem (_("DeNormalize"), mem_fun(*this, &Editor::denormalize_regions))); + items.push_back (MenuElem (_("DeNormalize"), mem_fun(*this, &Editor::denormalize_region))); } else { - items.push_back (MenuElem (_("Normalize"), mem_fun(*this, &Editor::normalize_regions))); + items.push_back (MenuElem (_("Normalize"), mem_fun(*this, &Editor::normalize_region))); } -#endif - } - - /* Find out if we have a selected MIDI region */ - i = selection->regions.begin(); - while (i != selection->regions.end() && boost::dynamic_pointer_cast<MidiRegion>((*i)->region()) == 0) { - ++i; - } - const bool have_selected_midi_region = (i != selection->regions.end()); - - if (have_selected_midi_region) { - items.push_back (MenuElem (_("Quantize"), mem_fun(*this, &Editor::quantize_regions))); + } else if (mr) { + items.push_back (MenuElem (_("Quantize"), mem_fun(*this, &Editor::quantize_region))); items.push_back (SeparatorElem()); - } + items.push_back (MenuElem (_("Reverse"), mem_fun(*this, &Editor::reverse_region))); + items.push_back (SeparatorElem()); + /* range related stuff */ - - add_item_with_sensitivity (items, MenuElem (_("Add range markers"), mem_fun (*this, &Editor::add_location_from_audio_region)), selection->regions.size() == 1); - - add_item_with_sensitivity (items, MenuElem (_("Set range selection"), mem_fun (*this, &Editor::set_selection_from_audio_region)), selection->regions.size() == 1); - + + items.push_back (MenuElem (_("Add Range Markers"), mem_fun (*this, &Editor::add_location_from_audio_region))); + items.push_back (MenuElem (_("Set Range Selection"), mem_fun (*this, &Editor::set_selection_from_region))); items.push_back (SeparatorElem()); /* Nudge region */ @@ -1797,12 +1885,13 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) MenuList& nudge_items = nudge_menu->items(); nudge_menu->set_name ("ArdourContextMenu"); - nudge_items.push_back (MenuElem (_("Nudge forward"), (bind (mem_fun(*this, &Editor::nudge_forward), false)))); - nudge_items.push_back (MenuElem (_("Nudge backward"), (bind (mem_fun(*this, &Editor::nudge_backward), false)))); - nudge_items.push_back (MenuElem (_("Nudge forward by capture offset"), (mem_fun(*this, &Editor::nudge_forward_capture_offset)))); - nudge_items.push_back (MenuElem (_("Nudge backward by capture offset"), (mem_fun(*this, &Editor::nudge_backward_capture_offset)))); + nudge_items.push_back (MenuElem (_("Nudge fwd"), (bind (mem_fun(*this, &Editor::nudge_forward), false)))); + nudge_items.push_back (MenuElem (_("Nudge bwd"), (bind (mem_fun(*this, &Editor::nudge_backward), false)))); + nudge_items.push_back (MenuElem (_("Nudge fwd by capture offset"), (mem_fun(*this, &Editor::nudge_forward_capture_offset)))); + nudge_items.push_back (MenuElem (_("Nudge bwd by capture offset"), (mem_fun(*this, &Editor::nudge_backward_capture_offset)))); items.push_back (MenuElem (_("Nudge"), *nudge_menu)); + items.push_back (SeparatorElem()); Menu *trim_menu = manage (new Menu); MenuList& trim_items = trim_menu->items(); @@ -1814,20 +1903,38 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) trim_items.push_back (MenuElem (_("Trim To Punch"), mem_fun(*this, &Editor::trim_region_to_punch))); items.push_back (MenuElem (_("Trim"), *trim_menu)); + items.push_back (SeparatorElem()); + items.push_back (MenuElem (_("Split"), (mem_fun(*this, &Editor::split_region)))); + region_edit_menu_split_item = &items.back(); + items.push_back (MenuElem (_("Make mono regions"), (mem_fun(*this, &Editor::split_multichannel_region)))); + region_edit_menu_split_multichannel_item = &items.back(); + items.push_back (MenuElem (_("Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), 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 (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track)))); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_selected_regions))); + items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region))); /* OK, stick the region submenu at the top of the list, and then add the standard items. */ - string const menu_item_name = selection->regions.size() > 1 ? _("Regions") : _("Region"); + /* we have to hack up the region name because "_" has a special + meaning for menu titles. + */ + + string::size_type pos = 0; + string menu_item_name = region->name(); + + while ((pos = menu_item_name.find ("_", pos)) != string::npos) { + menu_item_name.replace (pos, 1, "__"); + pos += 2; + } + edit_items.push_back (MenuElem (menu_item_name, *region_menu)); + edit_items.push_back (SeparatorElem()); } /** Add context menu items relevant to selection ranges. @@ -1876,33 +1983,12 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection))); } -/** Add context menu items relevant to busses or audio tracks. - * @param edit_items List to add the items to. - */ + void -Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items) +Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items) { using namespace Menu_Helpers; - /* We add every possible action here, and de-sensitize things - that aren't allowed. The sensitivity logic is a bit spread out; - on the one hand I'm using things like can_cut_copy (), which is - reasonably complicated and so perhaps better near the function that - it expresses sensitivity for, and on the other hand checks - in this function as well. You can't really have can_* for everything - or the number of methods would get silly. */ - - bool const one_selected_region = selection->regions.size() == 1; - - /* Count the number of selected audio tracks */ - int n_audio_tracks = 0; - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - RouteTimeAxisView const * r = dynamic_cast<RouteTimeAxisView*>(*i); - if (r && r->is_audio_track()) { - n_audio_tracks++; - } - } - /* Playback */ Menu *play_menu = manage (new Menu); @@ -1911,9 +1997,9 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items play_items.push_back (MenuElem (_("Play from edit point"), mem_fun(*this, &Editor::play_from_edit_point))); play_items.push_back (MenuElem (_("Play from start"), mem_fun(*this, &Editor::play_from_start))); - add_item_with_sensitivity (play_items, MenuElem (_("Play region"), mem_fun(*this, &Editor::play_selected_region)), one_selected_region); - - add_item_with_sensitivity (play_items, MenuElem (_("Loop region"), mem_fun(*this, &Editor::loop_selected_region)), one_selected_region); + play_items.push_back (MenuElem (_("Play region"), mem_fun(*this, &Editor::play_selected_region))); + play_items.push_back (SeparatorElem()); + play_items.push_back (MenuElem (_("Loop Region"), mem_fun(*this, &Editor::loop_selected_region))); edit_items.push_back (MenuElem (_("Play"), *play_menu)); @@ -1922,25 +2008,15 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items Menu *select_menu = manage (new Menu); MenuList& select_items = select_menu->items(); select_menu->set_name ("ArdourContextMenu"); - - string str = selection->tracks.size() == 1 ? _("Select all in track") : _("Select all in tracks"); - - select_items.push_back (MenuElem (str, bind (mem_fun(*this, &Editor::select_all_in_selected_tracks), Selection::Set))); - - select_items.push_back (MenuElem (_("Select all"), bind (mem_fun(*this, &Editor::select_all), Selection::Set))); - - str = selection->tracks.size() == 1 ? _("Invert selection in track") : _("Invert selection in tracks"); - - select_items.push_back (MenuElem (str, mem_fun(*this, &Editor::invert_selection_in_selected_tracks))); + select_items.push_back (MenuElem (_("Select All in track"), bind (mem_fun(*this, &Editor::select_all_in_track), Selection::Set))); + select_items.push_back (MenuElem (_("Select All"), bind (mem_fun(*this, &Editor::select_all), Selection::Set))); + select_items.push_back (MenuElem (_("Invert selection in track"), mem_fun(*this, &Editor::invert_selection_in_track))); select_items.push_back (MenuElem (_("Invert selection"), mem_fun(*this, &Editor::invert_selection))); select_items.push_back (SeparatorElem()); - - if (n_audio_tracks) { - select_items.push_back (MenuElem (_("Set range to loop range"), mem_fun(*this, &Editor::set_selection_from_loop))); - select_items.push_back (MenuElem (_("Set range to punch range"), mem_fun(*this, &Editor::set_selection_from_punch))); - } - + select_items.push_back (MenuElem (_("Set range to loop range"), mem_fun(*this, &Editor::set_selection_from_loop))); + select_items.push_back (MenuElem (_("Set range to punch range"), mem_fun(*this, &Editor::set_selection_from_punch))); + select_items.push_back (SeparatorElem()); select_items.push_back (MenuElem (_("Select All After Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true))); select_items.push_back (MenuElem (_("Select All Before Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false))); select_items.push_back (MenuElem (_("Select All After Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true))); @@ -1958,69 +2034,97 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items Menu *cutnpaste_menu = manage (new Menu); MenuList& cutnpaste_items = cutnpaste_menu->items(); cutnpaste_menu->set_name ("ArdourContextMenu"); - + cutnpaste_items.push_back (MenuElem (_("Cut"), mem_fun(*this, &Editor::cut))); cutnpaste_items.push_back (MenuElem (_("Copy"), mem_fun(*this, &Editor::copy))); cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f))); - add_item_with_sensitivity (cutnpaste_items, MenuElem (_("Cut"), mem_fun(*this, &Editor::cut)), can_cut_copy ()); - - add_item_with_sensitivity (cutnpaste_items, MenuElem (_("Copy"), mem_fun(*this, &Editor::copy)), can_cut_copy ()); + cutnpaste_items.push_back (SeparatorElem()); + + cutnpaste_items.push_back (MenuElem (_("Align"), bind (mem_fun(*this, &Editor::align), ARDOUR::SyncPoint))); + cutnpaste_items.push_back (MenuElem (_("Align Relative"), bind (mem_fun(*this, &Editor::align_relative), ARDOUR::SyncPoint))); + + cutnpaste_items.push_back (SeparatorElem()); + + cutnpaste_items.push_back (MenuElem (_("Insert chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f))); + + edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu)); + + /* Adding new material */ - if (n_audio_tracks) { - cutnpaste_items.push_back (MenuElem (_("Paste at edit cursor"), bind (mem_fun(*this, &Editor::paste), 1.0f))); - cutnpaste_items.push_back (MenuElem (_("Paste at mouse"), mem_fun(*this, &Editor::mouse_paste))); - - cutnpaste_items.push_back (SeparatorElem()); - - cutnpaste_items.push_back (MenuElem (_("Align"), bind (mem_fun(*this, &Editor::align), ARDOUR::SyncPoint))); - cutnpaste_items.push_back (MenuElem (_("Align relative"), bind (mem_fun(*this, &Editor::align_relative), ARDOUR::SyncPoint))); - cutnpaste_items.push_back (MenuElem (_("Insert chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f))); - } else { - cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f))); - } + edit_items.push_back (SeparatorElem()); + edit_items.push_back (MenuElem (_("Insert Selected Region"), bind (mem_fun(*this, &Editor::insert_region_list_selection), 1.0f))); + edit_items.push_back (MenuElem (_("Insert Existing Audio"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack))); + + /* Nudge track */ + Menu *nudge_menu = manage (new Menu()); + MenuList& nudge_items = nudge_menu->items(); + nudge_menu->set_name ("ArdourContextMenu"); + edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu)); + nudge_items.push_back (MenuElem (_("Nudge entire track fwd"), (bind (mem_fun(*this, &Editor::nudge_track), false, true)))); + nudge_items.push_back (MenuElem (_("Nudge track after edit point fwd"), (bind (mem_fun(*this, &Editor::nudge_track), true, true)))); + nudge_items.push_back (MenuElem (_("Nudge entire track bwd"), (bind (mem_fun(*this, &Editor::nudge_track), false, false)))); + nudge_items.push_back (MenuElem (_("Nudge track after edit point bwd"), (bind (mem_fun(*this, &Editor::nudge_track), true, false)))); - if (n_audio_tracks) { + edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu)); +} - Menu *track_menu = manage (new Menu); - MenuList& track_items = track_menu->items(); - track_menu->set_name ("ArdourContextMenu"); - - /* Adding new material */ +void +Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items) +{ + using namespace Menu_Helpers; + + /* Playback */ + + Menu *play_menu = manage (new Menu); + MenuList& play_items = play_menu->items(); + play_menu->set_name ("ArdourContextMenu"); - add_item_with_sensitivity (track_items, MenuElem (_("Insert Selected Region"), bind (mem_fun(*this, &Editor::insert_region_list_selection), 1.0f)), n_audio_tracks == 1); - add_item_with_sensitivity (track_items, MenuElem (_("Insert Existing Audio"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack)), n_audio_tracks == 1); - - /* Nudge */ + play_items.push_back (MenuElem (_("Play from edit point"), mem_fun(*this, &Editor::play_from_edit_point))); + play_items.push_back (MenuElem (_("Play from start"), mem_fun(*this, &Editor::play_from_start))); + edit_items.push_back (MenuElem (_("Play"), *play_menu)); - Menu *nudge_menu = manage (new Menu()); - MenuList& nudge_items = nudge_menu->items(); - nudge_menu->set_name ("ArdourContextMenu"); + /* Selection */ - str = selection->tracks.size() == 1 ? _("Nudge track after edit cursor forward") : _("Nudge tracks after edit cursor forward"); - - nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), true, true)))); + Menu *select_menu = manage (new Menu); + MenuList& select_items = select_menu->items(); + select_menu->set_name ("ArdourContextMenu"); + + select_items.push_back (MenuElem (_("Select All in track"), bind (mem_fun(*this, &Editor::select_all_in_track), Selection::Set))); + select_items.push_back (MenuElem (_("Select All"), bind (mem_fun(*this, &Editor::select_all), Selection::Set))); + select_items.push_back (MenuElem (_("Invert selection in track"), mem_fun(*this, &Editor::invert_selection_in_track))); + select_items.push_back (MenuElem (_("Invert selection"), mem_fun(*this, &Editor::invert_selection))); + select_items.push_back (SeparatorElem()); + select_items.push_back (MenuElem (_("Select all after edit point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true))); + select_items.push_back (MenuElem (_("Select all before edit point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false))); + select_items.push_back (MenuElem (_("Select all after playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true))); + select_items.push_back (MenuElem (_("Select all before playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false))); - str = selection->tracks.size() == 1 ? _("Nudge track backward") : _("Nudge tracks backward"); - - nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), false, false)))); + edit_items.push_back (MenuElem (_("Select"), *select_menu)); - str = selection->tracks.size() == 1 ? _("Nudge track after edit cursor backward") : _("Nudge tracks after edit cursor backward"); - - nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), true, false)))); - - track_items.push_back (MenuElem (_("Nudge"), *nudge_menu)); + /* Cut-n-Paste */ - /* Freeze */ - track_items.push_back (MenuElem (_("Freeze"), mem_fun(*this, &Editor::freeze_routes))); - track_items.push_back (MenuElem (_("Unfreeze"), mem_fun(*this, &Editor::unfreeze_routes))); + Menu *cutnpaste_menu = manage (new Menu); + MenuList& cutnpaste_items = cutnpaste_menu->items(); + cutnpaste_menu->set_name ("ArdourContextMenu"); + + cutnpaste_items.push_back (MenuElem (_("Cut"), mem_fun(*this, &Editor::cut))); + cutnpaste_items.push_back (MenuElem (_("Copy"), mem_fun(*this, &Editor::copy))); + cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f))); - str = selection->tracks.size() == 1 ? _("Track") : _("Tracks"); - edit_items.push_back (MenuElem (str, *track_menu)); - } + Menu *nudge_menu = manage (new Menu()); + MenuList& nudge_items = nudge_menu->items(); + nudge_menu->set_name ("ArdourContextMenu"); + + edit_items.push_back (SeparatorElem()); + nudge_items.push_back (MenuElem (_("Nudge entire track fwd"), (bind (mem_fun(*this, &Editor::nudge_track), false, true)))); + nudge_items.push_back (MenuElem (_("Nudge track after edit point fwd"), (bind (mem_fun(*this, &Editor::nudge_track), true, true)))); + nudge_items.push_back (MenuElem (_("Nudge entire track bwd"), (bind (mem_fun(*this, &Editor::nudge_track), false, false)))); + nudge_items.push_back (MenuElem (_("Nudge track after edit point bwd"), (bind (mem_fun(*this, &Editor::nudge_track), true, false)))); + + edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu)); } /* CURSOR SETTING AND MARKS AND STUFF */ diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 14ed3a46a8..bfdbcd4a6c 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -239,9 +239,9 @@ class Editor : public PublicEditor bool extend_selection_to_track (TimeAxisView&); void play_selection (); - void select_all_in_selected_tracks (Selection::Operation op); + void select_all_in_track (Selection::Operation op); void select_all (Selection::Operation op); - void invert_selection_in_selected_tracks (); + void invert_selection_in_track (); void invert_selection (); void deselect_all (); @@ -511,16 +511,30 @@ class Editor : public PublicEditor bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set, bool no_track_remove=false); void set_selected_regionview_from_region_list (boost::shared_ptr<ARDOUR::Region> region, Selection::Operation op = Selection::Set); + bool set_selected_regionview_from_map_event (GdkEventAny*, StreamView*, boost::weak_ptr<ARDOUR::Region>); void collect_new_region_view (RegionView *); void collect_and_select_new_region_view (RegionView *); + + Gtk::Menu track_context_menu; + Gtk::Menu track_region_context_menu; + Gtk::Menu track_selection_context_menu; + Gtk::Menu track_crossfade_context_menu; Gtk::MenuItem* region_edit_menu_split_item; Gtk::MenuItem* region_edit_menu_split_multichannel_item; + Gtk::Menu * track_region_edit_playlist_menu; + Gtk::Menu * track_edit_playlist_submenu; + Gtk::Menu * track_selection_edit_playlist_submenu; - void popup_track_context_menu (int, int, nframes_t); + void popup_track_context_menu (int, int, ItemType, bool, nframes_t); Gtk::Menu* build_track_context_menu (nframes_t); - void add_bus_or_audio_track_context_items (Gtk::Menu_Helpers::MenuList&); - void add_region_context_items (Gtk::Menu_Helpers::MenuList&); + 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 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&); void add_crossfade_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Crossfade>, Gtk::Menu_Helpers::MenuList&, bool many); void add_selection_context_items (Gtk::Menu_Helpers::MenuList&); @@ -1031,10 +1045,10 @@ class Editor : public PublicEditor void audition_playlist_region_standalone (boost::shared_ptr<ARDOUR::Region>); void audition_playlist_region_via_route (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Route&); void split_multichannel_region(); - void reverse_regions (); - void normalize_regions (); - void denormalize_regions (); - void quantize_regions (); + void reverse_region (); + void normalize_region (); + void denormalize_region (); + void quantize_region (); void audition_region_from_region_list (); void hide_region_from_region_list (); @@ -1176,7 +1190,7 @@ class Editor : public PublicEditor void set_selection_from_range (ARDOUR::Location&); void set_selection_from_punch (); void set_selection_from_loop (); - void set_selection_from_audio_region (); + void set_selection_from_region (); void add_location_mark (nframes64_t where); void add_location_from_audio_region (); @@ -1901,8 +1915,8 @@ class Editor : public PublicEditor static void* _freeze_thread (void*); void* freeze_thread (); - void freeze_routes (); - void unfreeze_routes (); + void freeze_route (); + void unfreeze_route (); /* edit-group solo + mute */ @@ -1990,7 +2004,7 @@ class Editor : public PublicEditor /* nudging tracks */ - void nudge_selected_tracks (bool use_edit_cursor, bool forwards); + void nudge_track (bool use_edit_point, bool forwards); /* xfades */ @@ -2101,13 +2115,6 @@ class Editor : public PublicEditor void toggle_gain_envelope_active (); void reset_region_gain_envelopes (); - Gtk::CheckMenuItem* region_envelope_visible_item; - Gtk::CheckMenuItem* region_envelope_active_item; - Gtk::CheckMenuItem* region_mute_item; - Gtk::CheckMenuItem* region_lock_item; - Gtk::CheckMenuItem* region_lock_position_item; - Gtk::CheckMenuItem* region_opaque_item; - bool on_key_press_event (GdkEventKey*); bool on_key_release_event (GdkEventKey*); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index e881b02a4e..c8cde42754 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -352,11 +352,11 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "insert-region", _("Insert Region"), mem_fun(*this, &Editor::keyboard_insert_region_list_selection)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "reverse-region", _("Reverse Regions"), mem_fun(*this, &Editor::reverse_regions)); + act = ActionManager::register_action (editor_actions, "reverse-region", _("Reverse Region"), mem_fun(*this, &Editor::reverse_region)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "normalize-region", _("Normalize Regions"), mem_fun(*this, &Editor::normalize_regions)); + act = ActionManager::register_action (editor_actions, "normalize-region", _("Normalize Region"), mem_fun(*this, &Editor::normalize_region)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "quantize-region", _("Quantize Regions"), mem_fun(*this, &Editor::quantize_regions)); + act = ActionManager::register_action (editor_actions, "quantize-region", _("Quantize Region"), mem_fun(*this, &Editor::quantize_region)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection)); ActionManager::session_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 68e0f62be4..e526d2d0db 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -335,51 +335,27 @@ Editor::track_canvas_size_allocated () reset_scrolling_region (); if (playhead_cursor) playhead_cursor->set_length (canvas_height); + + double y1 = vertical_adjustment.get_value (); for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { - (*x)->set_line_length (full_canvas_height); - } - - if (range_marker_drag_rect) { - range_marker_drag_rect->property_y1() = 0.0; - range_marker_drag_rect->property_y2() = canvas_height; - } - - if (transport_loop_range_rect) { - transport_loop_range_rect->property_y1() = 0.0; - transport_loop_range_rect->property_y2() = canvas_height; - } - - if (transport_punch_range_rect) { - transport_punch_range_rect->property_y1() = 0.0; - transport_punch_range_rect->property_y2() = canvas_height; - } - - if (transport_punchin_line) { - transport_punchin_line->property_y1() = 0.0; - transport_punchin_line->property_y2() = canvas_height; + (*x)->set_line_vpos (y1, canvas_height); } - if (transport_punchout_line) { - transport_punchout_line->property_y1() = 0.0; - transport_punchout_line->property_y2() = canvas_height; - } - compute_fixed_ruler_scale (); - - range_marker_drag_rect->property_y2() = full_canvas_height; - transport_loop_range_rect->property_y2() = full_canvas_height; - transport_punch_range_rect->property_y2() = full_canvas_height; - transport_punchin_line->property_y2() = full_canvas_height; - transport_punchout_line->property_y2() = full_canvas_height; + range_marker_drag_rect->property_y1() = 0.0; + range_marker_drag_rect->property_y2() = canvas_height; + transport_loop_range_rect->property_y1() = 0.0; + transport_loop_range_rect->property_y2() = canvas_height; + transport_punch_range_rect->property_y1() = 0.0; + transport_punch_range_rect->property_y2() = canvas_height; + transport_punchin_line->property_y1() = 0.0; + transport_punchin_line->property_y2() = canvas_height; + transport_punchout_line->property_y1() = 0.0; + transport_punchout_line->property_y2() = canvas_height; update_fixed_rulers(); redisplay_tempo (true); - if (logo_item) { - // logo_item->property_height() = full_canvas_height; - // logo_item->property_width() = canvas_width; - } - Resized (); /* EMIT_SIGNAL */ return false; @@ -723,6 +699,38 @@ Editor::left_track_canvas (GdkEventCrossing *ev) return FALSE; } +void +Editor::tie_vertical_scrolling () +{ + double y1 = vertical_adjustment.get_value(); + + playhead_cursor->set_y_axis (y1); + + range_marker_drag_rect->property_y1() = y1; + range_marker_drag_rect->property_y2() = y1 + canvas_height; + transport_loop_range_rect->property_y1() = y1; + transport_loop_range_rect->property_y2() = y1 + canvas_height; + transport_punch_range_rect->property_y1() = y1; + transport_punch_range_rect->property_y2() = y1 + canvas_height; + transport_punchin_line->property_y1() = y1; + transport_punchin_line->property_y2() = y1 + canvas_height; + transport_punchout_line->property_y1() = y1; + transport_punchout_line->property_y2() = y1 + canvas_height; + + if (!selection->markers.empty()) { + for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { + (*x)->set_line_vpos (y1, canvas_height); + } + } + + if (logo_item) { + logo_item->property_y() = y1; + } + + /* this will do an immediate redraw */ + + controls_layout.get_vadjustment()->set_value (y1); +} void Editor::canvas_horizontally_scrolled () diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index e6fb32feca..13e8f49d61 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -1172,7 +1172,7 @@ Editor::marker_selection_changed () } for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { - (*x)->add_line (cursor_group, full_canvas_height); + (*x)->add_line (cursor_group, vertical_adjustment.get_value(), canvas_height); (*x)->show_line (); } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 35f410eb25..048277fea7 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -967,24 +967,23 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case FadeOutHandleItem: popup_fade_context_menu (1, event->button.time, item, item_type); break; - + case StreamItem: - popup_track_context_menu (1, event->button.time, where); + popup_track_context_menu (1, event->button.time, item_type, false, where); break; case RegionItem: case RegionViewNameHighlight: case RegionViewName: - popup_track_context_menu (1, event->button.time, where); + popup_track_context_menu (1, event->button.time, item_type, false, where); break; case SelectionItem: - popup_track_context_menu (1, event->button.time, where); + popup_track_context_menu (1, event->button.time, item_type, true, where); break; case AutomationTrackItem: - case CrossfadeViewItem: - popup_track_context_menu (1, event->button.time, where); + popup_track_context_menu (1, event->button.time, item_type, false, where); break; case MarkerBarItem: @@ -1007,6 +1006,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MeterMarkerItem: tm_marker_context_menu (&event->button, item); break; + + case CrossfadeViewItem: + popup_track_context_menu (1, event->button.time, item_type, false, where); + break; #ifdef WITH_CMT case ImageFrameItem: @@ -3680,7 +3683,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event if (regionview_y_movement) { - /* moved to a different audio track. */ + /* moved to a different track. */ vector<RegionView*> new_selection; @@ -3695,7 +3698,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(trackview_by_y_position (iy1)); + boost::shared_ptr<Playlist> from_playlist = rv->region()->playlist(); boost::shared_ptr<Playlist> to_playlist = rtv2->playlist(); + + where = (nframes_t) (unit_to_frame (ix1) * speed); + boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region())); if (! to_playlist->frozen()) { /* @@ -3720,35 +3727,26 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event to_playlist->freeze(); } - where = (nframes_t) (unit_to_frame (ix1) * speed); - boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region())); - - if (!drag_info.copy) { + /* undo the previous hide_dependent_views so that xfades don't + disappear on copying regions + */ + rv->get_time_axis_view().reveal_dependent_views (*rv); + if (!drag_info.copy) { + /* the region that used to be in the old playlist is not moved to the new one - we make a copy of it. as a result, any existing editor for the region should no longer be visible. */ - - RouteTimeAxisView* from_playlist_rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_trackview()); - boost::shared_ptr<Playlist> from_playlist = from_playlist_rtv->playlist(); - - if (! from_playlist->frozen()) { - from_playlist->freeze(); - used_playlists.push_back(from_playlist); - - sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_and_select_new_region_view)); - used_connections.push_back (c); - - session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0)); - } - + rv->hide_region_editor(); rv->fake_set_opaque (false); + session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0)); from_playlist->remove_region ((rv->region())); + session->add_command (new MementoCommand<Playlist>(*from_playlist, 0, &from_playlist->get_state())); } else { diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 4919091a62..7df3d1dfe9 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2595,6 +2595,9 @@ Editor::separate_regions_between (const TimeSelection& ts) sort_track_selection (&tmptracks); + + + for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) { RouteTimeAxisView* rtv; @@ -3298,16 +3301,14 @@ Editor::trim_region_from_edit_point () commit_reversible_command (); } -/** Unfreeze selected routes */ void -Editor::unfreeze_routes () +Editor::unfreeze_route () { - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i); - if (atv && atv->is_audio_track()) { - atv->audio_track()->unfreeze (); - } + if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) { + return; } + + clicked_routeview->audio_track()->unfreeze (); } void* @@ -3320,15 +3321,7 @@ Editor::_freeze_thread (void* arg) void* Editor::freeze_thread () { - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i); - if (atv && atv->is_audio_track()) { - atv->audio_track()->freeze (*current_interthread_info); - } - } - - current_interthread_info->done = true; - + clicked_routeview->audio_track()->freeze (*current_interthread_info); return 0; } @@ -3339,10 +3332,13 @@ Editor::freeze_progress_timeout (void *arg) return !(current_interthread_info->done || current_interthread_info->cancel); } -/** Freeze selected routes */ void -Editor::freeze_routes () +Editor::freeze_route () { + if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) { + return; + } + InterThreadInfo itt; if (interthread_progress_window == 0) { @@ -3991,7 +3987,7 @@ Editor::clear_playlist (boost::shared_ptr<Playlist> playlist) } void -Editor::nudge_selected_tracks (bool use_edit, bool forwards) +Editor::nudge_track (bool use_edit, bool forwards) { boost::shared_ptr<Playlist> playlist; nframes_t distance; @@ -4058,7 +4054,7 @@ Editor::remove_last_capture () } void -Editor::normalize_regions () +Editor::normalize_region () { if (!session) { return; @@ -4088,7 +4084,7 @@ Editor::normalize_regions () void -Editor::denormalize_regions () +Editor::denormalize_region () { if (!session) { return; @@ -4114,7 +4110,7 @@ Editor::denormalize_regions () void -Editor::reverse_regions () +Editor::reverse_region () { if (!session) { return; @@ -4126,7 +4122,7 @@ Editor::reverse_regions () void -Editor::quantize_regions () +Editor::quantize_region () { if (!session) { return; @@ -4270,10 +4266,7 @@ Editor::toggle_gain_envelope_visibility () for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); if (arv) { - bool x = region_envelope_visible_item->get_active(); - if (x != arv->envelope_visible()) { - arv->set_envelope_visible (x); - } + arv->set_envelope_visible (!arv->envelope_visible()); } } } @@ -4284,28 +4277,7 @@ Editor::toggle_gain_envelope_active () for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); if (arv) { - bool x = region_envelope_active_item->get_active(); - if (x != arv->audio_region()->envelope_active()) { - arv->audio_region()->set_envelope_active (x); - } - } - } -} - -/** Set the position-locked state of all selected regions to a particular value. - * @param yn true to make locked, false to make unlocked. - */ -void -Editor::toggle_region_position_lock () -{ - bool x = region_lock_position_item->get_active(); - - for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); - if (arv) { - if (x != arv->audio_region()->locked()) { - arv->audio_region()->set_position_locked (x); - } + arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_active()); } } } @@ -4313,45 +4285,24 @@ Editor::toggle_region_position_lock () void Editor::toggle_region_lock () { - bool x = region_lock_item->get_active(); - for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); - if (arv) { - if (x != arv->audio_region()->locked()) { - arv->audio_region()->set_locked (x); - } - } + (*i)->region()->set_locked (!(*i)->region()->locked()); } } void Editor::toggle_region_mute () { - bool x = region_mute_item->get_active(); - for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); - if (arv) { - if (x != arv->audio_region()->muted()) { - arv->audio_region()->set_muted (x); - } - } + (*i)->region()->set_muted (!(*i)->region()->muted()); } } void Editor::toggle_region_opaque () { - bool x = region_opaque_item->get_active(); - for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); - if (arv) { - if (x != arv->audio_region()->opaque()) { - arv->audio_region()->set_opaque (x); - } - } + (*i)->region()->set_opaque (!(*i)->region()->opaque()); } } diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 87b9eba6f7..7c75701270 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -713,6 +713,37 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi commit_reversible_command () ; } +bool +Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, boost::weak_ptr<Region> weak_r) +{ + RegionView* rv; + boost::shared_ptr<Region> r (weak_r.lock()); + + if (!r) { + return true; + } + + if ((rv = sv->find_view (r)) == 0) { + return true; + } + + /* don't reset the selection if its something other than + a single other region. + */ + + if (selection->regions.size() > 1) { + return true; + } + + begin_reversible_command (_("set selected regions")); + + selection->set (rv); + + commit_reversible_command () ; + + return true; +} + void Editor::track_selection_changed () { @@ -776,17 +807,16 @@ Editor::point_selection_changed () } } -/** Select everything in the selected tracks - * @param Selection operation to apply. - */ void -Editor::select_all_in_selected_tracks (Selection::Operation op) +Editor::select_all_in_track (Selection::Operation op) { list<Selectable *> touched; - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - (*i)->get_selectables (0, max_frames, 0, DBL_MAX, touched); + if (!clicked_routeview) { + return; } + + clicked_routeview->get_selectables (0, max_frames, 0, DBL_MAX, touched); switch (op) { case Selection::Toggle: @@ -832,17 +862,16 @@ Editor::select_all (Selection::Operation op) } commit_reversible_command (); } - -/** Invert the selection in the selected tracks */ void -Editor::invert_selection_in_selected_tracks () +Editor::invert_selection_in_track () { list<Selectable *> touched; - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - (*i)->get_inverted_selectables (*selection, touched); + if (!clicked_routeview) { + return; } + clicked_routeview->get_inverted_selectables (*selection, touched); selection->set (touched); } @@ -926,7 +955,7 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo } void -Editor::set_selection_from_audio_region () +Editor::set_selection_from_region () { if (selection->regions.empty()) { return; diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index e511e59af2..c1ffcefb2b 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -4,6 +4,7 @@ #include <map> #include <glibmm.h> +#include <gtkmm/messagedialog.h> #include <pbd/xml++.h> #ifdef __APPLE__ @@ -427,11 +428,11 @@ EngineControl::build_command_line (vector<string>& cmd) cmd.push_back ("netjack"); } else if (driver == X_("FFADO")) { using_ffado = true; - cmd.push_back ("firewire"); + cmd.push_back ("ffado"); } else if ( driver == X_("Dummy")) { using_dummy = true; cmd.push_back ("dummy"); - } + } /* driver arguments */ @@ -621,10 +622,29 @@ EngineControl::enumerate_coreaudio_devices () // Look for the CoreAudio device name... char coreDeviceName[256]; size_t nameSize; + for (int i = 0; i < numCoreDevices; i++) { nameSize = sizeof (coreDeviceName); + /* enforce duplex devices only */ + + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], + 0, true, kAudioDevicePropertyStreams, + &outSize, &isWritable); + + if (err != noErr || outSize == 0) { + continue; + } + + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], + 0, false, kAudioDevicePropertyStreams, + &outSize, &isWritable); + + if (err != noErr || outSize == 0) { + continue; + } + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], 0, true, kAudioDevicePropertyDeviceName, &outSize, &isWritable); @@ -649,6 +669,26 @@ EngineControl::enumerate_coreaudio_devices () delete [] coreDeviceIDs; } + if (devs.size() == 0) { + MessageDialog msg (_("\ +You do not have any audio devices capable of\n\ +simultaneous playback and recording.\n\n\ +Please use Applications -> Utilities -> Audio MIDI Setup\n\ +to create an \"aggregrate\" device, or install a suitable\n\ +audio interface.\n\n\ +Please send email to Apple and ask them why new Macs\n\ +have no duplex audio device.\n\n\ +Alternatively, if you really want just playback\n\ +or recording but not both, start JACK before running\n\ +Ardour and choose the relevant device then." + ), + true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK); + msg.set_title (_("No suitable audio devices")); + msg.set_position (Gtk::WIN_POS_MOUSE); + msg.run (); + exit (1); + } + return devs; } #else @@ -869,7 +909,7 @@ EngineControl::find_jack_servers (vector<string>& strings) std::map<string,int> un; path = getenv ("PATH"); - + jack_servers = scanner (path, jack_server_filter, 0, false, true); vector<string *>::iterator iter; diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 6e37908d1b..771683d80e 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -25,6 +25,7 @@ #include "utils.h" #include "canvas_impl.h" #include "ardour_ui.h" +#include "simpleline.h" #include "i18n.h" @@ -269,7 +270,6 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con } line = 0; - line_points = 0; } @@ -285,7 +285,6 @@ Marker::~Marker () if (line) { delete line; - delete line_points; } } @@ -295,35 +294,28 @@ void Marker::reparent(ArdourCanvas::Group & parent) _parent = &parent; } + void -Marker::set_line_length (double len) +Marker::set_line_vpos (double pos, double height) { if (line) { - line_points->back().set_y (len); - line->property_points() = *line_points; + line->property_y1() = pos; + line->property_y2() = pos + height; } } void -Marker::add_line (ArdourCanvas::Group* group, double initial_height) +Marker::add_line (ArdourCanvas::Group* group, double y_origin, double initial_height) { if (!line) { - line_points = new ArdourCanvas::Points (); - line_points->push_back (Gnome::Art::Point (unit_position + shift, 0.0)); - line_points->push_back (Gnome::Art::Point (unit_position + shift, initial_height)); - - line = new ArdourCanvas::Line (*group); - line->property_width_pixels() = 1; - line->property_points() = *line_points; - line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get(); -#if 0 - line->property_first_arrowhead() = TRUE; - line->property_last_arrowhead() = TRUE; - line->property_arrow_shape_a() = 11.0; - line->property_arrow_shape_b() = 0.0; - line->property_arrow_shape_c() = 9.0; -#endif + line = new ArdourCanvas::SimpleLine (*group); + line->property_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get(); + line->property_x1() = unit_position + shift; + line->property_y1() = y_origin; + line->property_x2() = unit_position + shift; + line->property_y2() = y_origin + initial_height; + line->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this)); } @@ -372,9 +364,8 @@ Marker::set_position (nframes_t frame) unit_position = new_unit_position; if (line) { - (*line_points)[0].set_x (unit_position + shift); - (*line_points)[1].set_x (unit_position + shift); - line->property_points() = *line_points; + line->property_x1() = unit_position + shift; + line->property_x2() = unit_position + shift; } } diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index fa252571fb..1a53726ede 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -57,10 +57,10 @@ class Marker : public PBD::Destructible ArdourCanvas::Item& the_item() const; - void add_line (ArdourCanvas::Group*, double initial_height); + void add_line (ArdourCanvas::Group*, double y_origin, double initial_height); void show_line (); void hide_line (); - void set_line_length (double); + void set_line_vpos (double y_origin, double height); void set_position (nframes_t); void set_name (const string&); @@ -84,7 +84,7 @@ class Marker : public PBD::Destructible ArdourCanvas::Polygon *mark; ArdourCanvas::Text *text; ArdourCanvas::Points *points; - ArdourCanvas::Line *line; + ArdourCanvas::SimpleLine *line; ArdourCanvas::Points *line_points; double unit_position; diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 94c687f829..f7a1d48a50 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -311,6 +311,8 @@ Mixer_UI::add_strip (Session::RouteList& routes) Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide; + Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide; + if (strip->width_owner() != strip) { strip->set_width (_strip_width, this); } diff --git a/gtk2_ardour/new_session_dialog.cc b/gtk2_ardour/new_session_dialog.cc index 820a614ecc..db970b4d46 100644 --- a/gtk2_ardour/new_session_dialog.cc +++ b/gtk2_ardour/new_session_dialog.cc @@ -20,6 +20,8 @@ #include "i18n.h" #include "new_session_dialog.h" +#include <pbd/error.h> + #include <ardour/recent_sessions.h> #include <ardour/session_state_utils.h> #include <ardour/template_utils.h> @@ -38,8 +40,8 @@ #include <gtkmm2ext/window_title.h> using namespace Gtkmm2ext; -using namespace ARDOUR; using namespace PBD; +using namespace ARDOUR; #include "opts.h" #include "utils.h" @@ -526,7 +528,49 @@ NewSessionDialog::set_session_name (const Glib::ustring& name) void NewSessionDialog::set_session_folder(const Glib::ustring& dir) { - m_folder->set_current_folder (dir); + Glib::ustring realdir = dir; + char* res; + + /* this little tangled mess is a result of 4 things: + + 1) GtkFileChooser vomits when given a non-absolute directory + argument to set_current_folder() + 2) canonicalize_file_name() doesn't exist on OS X + 3) linux man page for realpath() says "do not use this function" + 4) canonicalize_file_name() & realpath() have entirely + different semantics on OS X and Linux when given + a non-existent path. + + as result of all this, we take two distinct pathways through the code. + */ + + +#ifdef __APPLE__ + + char buf[PATH_MAX]; + + if((res = realpath (dir.c_str(), buf)) != 0) { + if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) { + realdir = Glib::path_get_dirname (realdir); + } + m_folder->set_current_folder (realdir); + } + + +#else + if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) { + realdir = Glib::path_get_dirname (realdir); + cerr << "didn't exist, use " << realdir << endl; + } + + if ((res = canonicalize_file_name (realdir.c_str())) != 0) { + cerr << "canonical, use " << res << endl; + m_folder->set_current_folder (res); + free (res); + } + +#endif + } std::string @@ -547,40 +591,54 @@ NewSessionDialog::session_name() const } */ - int page = m_notebook->get_current_page(); - - if (page == 0 || page == 2) { + switch (which_page()) { + case NewPage: + case EnginePage: /* new or audio setup pages */ return Glib::filename_from_utf8(m_name->get_text()); - } else { - if (m_treeview->get_selection()->count_selected_rows() == 0) { - return Glib::filename_from_utf8(str); - } - Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected(); - return (*i)[recent_columns.visible_name]; + default: + break; + } + + if (m_treeview->get_selection()->count_selected_rows() == 0) { + return Glib::filename_from_utf8(str); } + Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected(); + return (*i)[recent_columns.visible_name]; } std::string NewSessionDialog::session_folder() const { - if (m_notebook->get_current_page() == 0) { + switch (which_page()) { + case NewPage: return Glib::filename_from_utf8(m_folder->get_filename()); - } else { - - if (m_treeview->get_selection()->count_selected_rows() == 0) { - const string filename(Glib::filename_from_utf8(m_open_filechooser->get_filename())); - return Glib::path_get_dirname(filename); + + case EnginePage: + if (page_set == EnginePage) { + /* just engine page, nothing else : use m_folder since it should be set */ + return Glib::filename_from_utf8(m_folder->get_filename()); } - Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected(); - return (*i)[recent_columns.fullpath]; + break; + + default: + break; } + + if (m_treeview->get_selection()->count_selected_rows() == 0) { + const string filename(Glib::filename_from_utf8(m_open_filechooser->get_filename())); + return Glib::path_get_dirname(filename); + } + + Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected(); + return (*i)[recent_columns.fullpath]; } bool NewSessionDialog::use_session_template() const { - if(m_template->get_filename().empty() && (m_notebook->get_current_page() == 0)) return false; + if (m_template->get_filename().empty() && (which_page() == NewPage)) + return false; return true; } @@ -663,13 +721,13 @@ NewSessionDialog::connect_outs_to_physical() const } int -NewSessionDialog::get_current_page() const +NewSessionDialog::get_current_page() { return m_notebook->get_current_page(); } NewSessionDialog::Pages -NewSessionDialog::which_page () +NewSessionDialog::which_page () const { int num = m_notebook->get_current_page(); @@ -755,7 +813,6 @@ NewSessionDialog::notebook_page_changed (GtkNotebookPage* np, uint pagenum) m_okbutton->set_label(_("Open")); m_okbutton->set_image (*(manage (new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON)))); set_response_sensitive (Gtk::RESPONSE_NONE, false); - m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON))); if (m_treeview->get_selection()->count_selected_rows() == 0) { set_response_sensitive (Gtk::RESPONSE_OK, false); } else { @@ -772,8 +829,7 @@ NewSessionDialog::notebook_page_changed (GtkNotebookPage* np, uint pagenum) break; default: - m_okbutton->set_label(_("New")); - m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON))); + on_new_session_page = true; m_okbutton->set_label(_("New")); m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON))); if (m_name->get_text() == "") { @@ -893,7 +949,7 @@ NewSessionDialog::monitor_bus_button_clicked () void NewSessionDialog::reset_template() { - m_template->set_filename(""); + m_template->unselect_all (); } void diff --git a/gtk2_ardour/new_session_dialog.h b/gtk2_ardour/new_session_dialog.h index 6f0820168b..aa6911f360 100644 --- a/gtk2_ardour/new_session_dialog.h +++ b/gtk2_ardour/new_session_dialog.h @@ -92,9 +92,9 @@ public: bool connect_outs_to_master() const; bool connect_outs_to_physical() const ; - Pages which_page (); + Pages which_page () const; - int get_current_page() const; + int get_current_page(); void set_current_page (int); void reset_recent(); diff --git a/gtk2_ardour/po/sv_SE.po b/gtk2_ardour/po/sv_SE.po index 9804869d95..b6c4a01b1b 100644 --- a/gtk2_ardour/po/sv_SE.po +++ b/gtk2_ardour/po/sv_SE.po @@ -6854,7 +6854,7 @@ msgstr "som nya bandspår" #: gtk2_ardour/sfdb_ui.cc:109 msgid "Auto-play" -msgstr "Spela automatiskt" +msgstr "Spela autom." #: gtk2_ardour/sfdb_ui.cc:994 gtk2_ardour/sfdb_ui.cc:1129 msgid "use file timestamp" @@ -7062,3 +7062,39 @@ msgstr "Bra" #: gtk2_ardour/sfdb_ui.cc:1069 gtk2_ardour/sfdb_ui.cc:1149 msgid "Quick" msgstr "Snabb" + +#: gtk2_ardour/editor_timefx.cc:74 +msgid "Strict Linear" +msgstr "Strikt linjär" + +#: gtk2_ardour/editor_timefx.cc:84 +msgid "Time Stretch" +msgstr "Förläng/förkorta" + +#: gtk2_ardour/editor.cc:156 +msgid "Mushy" +msgstr "Mossig" + +#: gtk2_ardour/editor.cc:157 +msgid "Smooth" +msgstr "Mjuk" + +#: gtk2_ardour/editor.cc:158 +msgid "Balanced multitimbral mixture" +msgstr "Balanserad flerröstig mix" + +#: gtk2_ardour/editor.cc:159 +msgid "Unpitched percussion with stable notes" +msgstr "Ej tonhöjdsändrat slagverk med stabila noter" + +#: gtk2_ardour/editor.cc:160 +msgid "Crisp monophonic instrumental" +msgstr "Skarpt monofoniskt" + +#: gtk2_ardour/editor.cc:161 +msgid "Unpitched solo percussion" +msgstr "EJ tonhöjdsändrat soloslagverk" + +#: gtk2_ardour/editor_timefx.cc:73 +msgid "Contents:" +msgstr "Innehåll" diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index b0e4d34c28..115e008a54 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -70,8 +70,6 @@ class AUPlugin : public ARDOUR::Plugin int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); std::set<uint32_t> automatable() const; - void store_state (ARDOUR::PluginState&); - void restore_state (ARDOUR::PluginState&); string describe_parameter (uint32_t); string state_node_name () const { return "audiounit"; } void print_parameter (uint32_t, char*, uint32_t len) const; diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index 7c0b0b2abe..976584b687 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -32,7 +32,6 @@ #include <jack/types.h> #include <ardour/ladspa.h> -#include <ardour/plugin_state.h> #include <ardour/plugin.h> #include <ardour/ladspa_plugin.h> @@ -54,53 +53,47 @@ class LadspaPlugin : public ARDOUR::Plugin /* Plugin interface */ std::string unique_id() const; - const char * label() const { return descriptor->Label; } - const char * name() const { return descriptor->Name; } - const char * maker() const { return descriptor->Maker; } - uint32_t parameter_count() const { return descriptor->PortCount; } - float default_value (uint32_t port); - nframes_t signal_latency() const; - void set_parameter (uint32_t port, float val); - float get_parameter (uint32_t port) const; - int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; + const char* label() const { return _descriptor->Label; } + const char* name() const { return _descriptor->Name; } + const char* maker() const { return _descriptor->Maker; } + uint32_t parameter_count() const { return _descriptor->PortCount; } + float default_value (uint32_t port); + nframes_t signal_latency() const; + void set_parameter (uint32_t port, float val); + float get_parameter (uint32_t port) const; + int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; + uint32_t nth_parameter (uint32_t port, bool& ok) const; + std::set<Parameter> automatable() const; - uint32_t nth_parameter (uint32_t port, bool& ok) const; - void activate () { - if (was_activated) - return; - if (descriptor->activate) { - descriptor->activate (handle); - } + void activate () { + if (!_was_activated && _descriptor->activate) + _descriptor->activate (_handle); - was_activated = true; + _was_activated = true; } - void deactivate () { - if (!was_activated) - return; - if (descriptor->deactivate) { - descriptor->deactivate (handle); - } + void deactivate () { + if (_was_activated && _descriptor->deactivate) + _descriptor->deactivate (_handle); - was_activated = false; + _was_activated = false; } + void cleanup () { activate(); deactivate(); - if (descriptor->cleanup) { - descriptor->cleanup (handle); - } + if (_descriptor->cleanup) + _descriptor->cleanup (_handle); } + void set_block_size (nframes_t nframes) {} int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - void store_state (ARDOUR::PluginState&); - void restore_state (ARDOUR::PluginState&); string describe_parameter (Parameter); string state_node_name() const { return "ladspa"; } - void print_parameter (uint32_t, char*, uint32_t len) const; + void print_parameter (uint32_t, char*, uint32_t len) const; bool parameter_is_audio(uint32_t) const; bool parameter_is_control(uint32_t) const; @@ -109,8 +102,8 @@ class LadspaPlugin : public ARDOUR::Plugin bool parameter_is_toggled(uint32_t) const; XMLNode& get_state(); - int set_state(const XMLNode& node); - bool save_preset(string name); + int set_state(const XMLNode& node); + bool save_preset(string name); bool has_editor() const { return false; } @@ -118,32 +111,27 @@ class LadspaPlugin : public ARDOUR::Plugin /* LADSPA extras */ - LADSPA_Properties properties() const { return descriptor->Properties; } - uint32_t index() const { return _index; } - const char * copyright() const { return descriptor->Copyright; } - LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return descriptor->PortDescriptors[i]; } - const LADSPA_PortRangeHint * port_range_hints() const { return descriptor->PortRangeHints; } - const char * const * port_names() const { return descriptor->PortNames; } - void set_gain (float gain) { - descriptor->set_run_adding_gain (handle, gain); - } - void run_adding (uint32_t nsamples) { - descriptor->run_adding (handle, nsamples); - } - void connect_port (uint32_t port, float *ptr) { - descriptor->connect_port (handle, port, ptr); - } + LADSPA_Properties properties() const { return _descriptor->Properties; } + uint32_t index() const { return _index; } + const char * copyright() const { return _descriptor->Copyright; } + LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return _descriptor->PortDescriptors[i]; } + const LADSPA_PortRangeHint* port_range_hints() const { return _descriptor->PortRangeHints; } + const char * const * port_names() const { return _descriptor->PortNames; } + + void set_gain (float gain) { _descriptor->set_run_adding_gain (_handle, gain); } + void run_adding (uint32_t nsamples) { _descriptor->run_adding (_handle, nsamples); } + void connect_port (uint32_t port, float *ptr) { _descriptor->connect_port (_handle, port, ptr); } private: - void *module; - const LADSPA_Descriptor *descriptor; - LADSPA_Handle handle; - nframes_t sample_rate; - LADSPA_Data *control_data; - LADSPA_Data *shadow_data; - LADSPA_Data *latency_control_port; - uint32_t _index; - bool was_activated; + void* _module; + const LADSPA_Descriptor* _descriptor; + LADSPA_Handle _handle; + nframes_t _sample_rate; + LADSPA_Data* _control_data; + LADSPA_Data* _shadow_data; + LADSPA_Data* _latency_control_port; + uint32_t _index; + bool _was_activated; void init (void *mod, uint32_t index, nframes_t rate); void run_in_place (nframes_t nsamples); diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index d721476db7..73f89f1a91 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -30,7 +30,6 @@ #include <jack/types.h> #include <ardour/types.h> #include <ardour/chan_count.h> -#include <ardour/plugin_state.h> #include <ardour/cycles.h> #include <ardour/latent.h> #include <ardour/parameter.h> @@ -131,8 +130,6 @@ class Plugin : public PBD::StatefulDestructible, public Latent virtual int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset) = 0; virtual std::set<Parameter> automatable() const = 0; - virtual void store_state (ARDOUR::PluginState&) = 0; - virtual void restore_state (ARDOUR::PluginState&) = 0; virtual string describe_parameter (Parameter) = 0; virtual string state_node_name() const = 0; virtual void print_parameter (uint32_t, char*, uint32_t len) const = 0; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 2038153d86..42c53c487c 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -25,7 +25,6 @@ #include <sigc++/signal.h> #include <ardour/ardour.h> -#include <ardour/plugin_state.h> #include <ardour/types.h> #include <ardour/processor.h> #include <ardour/automation_event.h> diff --git a/libs/ardour/ardour/plugin_state.h b/libs/ardour/ardour/plugin_state.h deleted file mode 100644 index bd499e2b90..0000000000 --- a/libs/ardour/ardour/plugin_state.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ardour_plugin_state_h__ -#define __ardour_plugin_state_h__ - -#include <map> - -namespace ARDOUR { - -struct PluginState { - std::map<uint32_t,float> parameters; -}; - -} - -#endif /* __ardour_plugin_state_h__ */ diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h index 114d196750..1743040bf5 100644 --- a/libs/ardour/ardour/port_insert.h +++ b/libs/ardour/ardour/port_insert.h @@ -27,7 +27,6 @@ #include <sigc++/signal.h> #include <ardour/ardour.h> #include <ardour/io_processor.h> -#include <ardour/plugin_state.h> #include <ardour/types.h> class XMLNode; diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index bf9dfe0430..d3e95e8ebf 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -30,7 +30,6 @@ #include <ardour/types.h> #include <ardour/ardour.h> -#include <ardour/plugin_state.h> #include <ardour/buffer_set.h> #include <ardour/automatable.h> #include <ardour/latent.h> diff --git a/libs/ardour/ardour/rb_effect.h b/libs/ardour/ardour/rb_effect.h index bde0422335..a536a309b3 100644 --- a/libs/ardour/ardour/rb_effect.h +++ b/libs/ardour/ardour/rb_effect.h @@ -20,7 +20,7 @@ #ifndef __ardour_rbeffect_h__ #define __ardour_rbeffect_h__ -#include <ardour/audiofilter.h> +#include <ardour/filter.h> namespace ARDOUR { diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h index 3a05360f15..e41d000f9c 100644 --- a/libs/ardour/ardour/vst_plugin.h +++ b/libs/ardour/ardour/vst_plugin.h @@ -72,8 +72,6 @@ class VSTPlugin : public ARDOUR::Plugin void deactivate (); void set_block_size (nframes_t nframes); int connect_and_run (BufferSet&, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - void store_state (ARDOUR::PluginState&); - void restore_state (ARDOUR::PluginState&); string describe_parameter (uint32_t); string state_node_name() const { return "vst"; } void print_parameter (uint32_t, char*, uint32_t len) const; diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index f86e784169..9f19a21865 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -401,18 +401,6 @@ AUPlugin::automatable() const return automates; } -void -AUPlugin::store_state (ARDOUR::PluginState&) -{ - -} - -void -AUPlugin::restore_state (ARDOUR::PluginState&) -{ - -} - string AUPlugin::describe_parameter (uint32_t) { diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index f1534827fd..86abd4beaa 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -636,7 +636,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen set_fade_out_active (false); } } - + } } diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 696ada3b81..ccc12f8cf8 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -62,11 +62,11 @@ LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_ LadspaPlugin::LadspaPlugin (const LadspaPlugin &other) : Plugin (other) { - init (other.module, other._index, other.sample_rate); + init (other._module, other._index, other._sample_rate); for (uint32_t i = 0; i < parameter_count(); ++i) { - control_data[i] = other.shadow_data[i]; - shadow_data[i] = other.shadow_data[i]; + _control_data[i] = other._shadow_data[i]; + _shadow_data[i] = other._shadow_data[i]; } } @@ -77,61 +77,61 @@ LadspaPlugin::init (void *mod, uint32_t index, nframes_t rate) uint32_t i, port_cnt; const char *errstr; - module = mod; - control_data = 0; - shadow_data = 0; - latency_control_port = 0; - was_activated = false; + _module = mod; + _control_data = 0; + _shadow_data = 0; + _latency_control_port = 0; + _was_activated = false; - dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor"); + dfunc = (LADSPA_Descriptor_Function) dlsym (_module, "ladspa_descriptor"); if ((errstr = dlerror()) != NULL) { error << _("LADSPA: module has no descriptor function.") << endmsg; throw failed_constructor(); } - if ((descriptor = dfunc (index)) == 0) { + if ((_descriptor = dfunc (index)) == 0) { error << _("LADSPA: plugin has gone away since discovery!") << endmsg; throw failed_constructor(); } _index = index; - if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties)) { - error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), descriptor->Name) << endmsg; + if (LADSPA_IS_INPLACE_BROKEN(_descriptor->Properties)) { + error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), _descriptor->Name) << endmsg; throw failed_constructor(); } - sample_rate = rate; + _sample_rate = rate; - if (descriptor->instantiate == 0) { + if (_descriptor->instantiate == 0) { throw failed_constructor(); } - if ((handle = descriptor->instantiate (descriptor, rate)) == 0) { + if ((_handle = _descriptor->instantiate (_descriptor, rate)) == 0) { throw failed_constructor(); } port_cnt = parameter_count(); - control_data = new LADSPA_Data[port_cnt]; - shadow_data = new LADSPA_Data[port_cnt]; + _control_data = new LADSPA_Data[port_cnt]; + _shadow_data = new LADSPA_Data[port_cnt]; for (i = 0; i < port_cnt; ++i) { if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { - connect_port (i, &control_data[i]); + connect_port (i, &_control_data[i]); if (LADSPA_IS_PORT_OUTPUT(port_descriptor (i)) && strcmp (port_names()[i], X_("latency")) == 0) { - latency_control_port = &control_data[i]; - *latency_control_port = 0; + _latency_control_port = &_control_data[i]; + *_latency_control_port = 0; } if (!LADSPA_IS_PORT_INPUT(port_descriptor (i))) { continue; } - shadow_data[i] = default_value (i); + _shadow_data[i] = default_value (i); } } @@ -149,39 +149,12 @@ LadspaPlugin::~LadspaPlugin () // dlclose (module); - if (control_data) { - delete [] control_data; + if (_control_data) { + delete [] _control_data; } - if (shadow_data) { - delete [] shadow_data; - } -} - -void -LadspaPlugin::store_state (PluginState& state) -{ - state.parameters.clear (); - - for (uint32_t i = 0; i < parameter_count(); ++i){ - - if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && - LADSPA_IS_PORT_CONTROL(port_descriptor (i))){ - pair<uint32_t,float> datum; - - datum.first = i; - datum.second = shadow_data[i]; - - state.parameters.insert (datum); - } - } -} - -void -LadspaPlugin::restore_state (PluginState& state) -{ - for (map<uint32_t,float>::iterator i = state.parameters.begin(); i != state.parameters.end(); ++i) { - set_parameter (i->first, i->second); + if (_shadow_data) { + delete [] _shadow_data; } } @@ -189,7 +162,7 @@ string LadspaPlugin::unique_id() const { char buf[32]; - snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID); + snprintf (buf, sizeof (buf), "%lu", _descriptor->UniqueID); return string (buf); } @@ -308,10 +281,10 @@ LadspaPlugin::default_value (uint32_t port) if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor) && !earlier_hint) { if (bounds_given) { if (sr_scaling) { - ret *= sample_rate; + ret *= _sample_rate; } } else { - ret = sample_rate; + ret = _sample_rate; } } @@ -321,8 +294,8 @@ LadspaPlugin::default_value (uint32_t port) void LadspaPlugin::set_parameter (uint32_t which, float val) { - if (which < descriptor->PortCount) { - shadow_data[which] = (LADSPA_Data) val; + if (which < _descriptor->PortCount) { + _shadow_data[which] = (LADSPA_Data) val; #if 0 ParameterChanged (Parameter(PluginAutomation, which), val); /* EMIT SIGNAL */ @@ -343,9 +316,9 @@ float LadspaPlugin::get_parameter (uint32_t which) const { if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) { - return (float) shadow_data[which]; + return (float) _shadow_data[which]; } else { - return (float) control_data[which]; + return (float) _control_data[which]; } } @@ -356,7 +329,7 @@ LadspaPlugin::nth_parameter (uint32_t n, bool& ok) const ok = false; - for (c = 0, x = 0; x < descriptor->PortCount; ++x) { + for (c = 0, x = 0; x < _descriptor->PortCount; ++x) { if (LADSPA_IS_PORT_CONTROL (port_descriptor (x))) { if (c++ == n) { ok = true; @@ -383,7 +356,7 @@ LadspaPlugin::get_state() child = new XMLNode("port"); snprintf(buf, sizeof(buf), "%u", i); child->add_property("number", string(buf)); - snprintf(buf, sizeof(buf), "%+f", shadow_data[i]); + snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]); child->add_property("value", string(buf)); root->add_child_nocopy (*child); } @@ -515,8 +488,8 @@ LadspaPlugin::signal_latency () const return _user_latency; } - if (latency_control_port) { - return (nframes_t) floor (*latency_control_port); + if (_latency_control_port) { + return (nframes_t) floor (*_latency_control_port); } else { return 0; } @@ -617,16 +590,16 @@ LadspaPlugin::run_in_place (nframes_t nframes) { for (uint32_t i = 0; i < parameter_count(); ++i) { if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { - control_data[i] = shadow_data[i]; + _control_data[i] = _shadow_data[i]; } } - descriptor->run (handle, nframes); + _descriptor->run (_handle, nframes); } void LadspaPlugin::latency_compute_run () { - if (!latency_control_port) { + if (!_latency_control_port) { return; } diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index f0465d0ad5..d321d6f259 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -328,7 +328,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id) } pattern.subject = matches1->object; - pattern.predicate = (char*)LADSPA_BASE "hasLabel"; + pattern.predicate = (char*)(LADSPA_BASE "hasLabel"); pattern.object = 0; pattern.object_type = lrdf_literal; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index cef5c7df48..19d562f844 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -273,7 +273,6 @@ Session::Session (AudioEngine &eng, _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed)); } @@ -711,7 +710,7 @@ Session::when_engine_running () osc->set_session (*this); #endif - + } void diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index a08d09d949..d8d3d82810 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -716,7 +716,7 @@ Session::save_state (string snapshot_name, bool pending) bool was_dirty = dirty(); _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - + if (was_dirty) { DirtyChanged (); /* EMIT SIGNAL */ } @@ -1270,8 +1270,8 @@ Session::set_state (const XMLNode& node) } if ((child = find_named_node (node, "Bundles")) == 0) { - error << _("Session: XML state has no bundles section") << endmsg; - goto out; + warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg; + //goto out; } else { /* We can't load Bundles yet as they need to be able to convert from port names to Port objects, which can't happen until diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 5969d91982..47b5cb4fba 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -510,15 +510,3 @@ VSTPluginInfo::load (Session& session) return PluginPtr ((Plugin*) 0); } } - -void -VSTPlugin::store_state (ARDOUR::PluginState& s) -{ - -} - -void -VSTPlugin::restore_state (ARDOUR::PluginState& s) -{ - -} diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc index 60fb35b969..1b440aaac9 100644 --- a/libs/gtkmm2ext/fastmeter.cc +++ b/libs/gtkmm2ext/fastmeter.cc @@ -97,6 +97,8 @@ Glib::RefPtr<Gdk::Pixbuf> FastMeter::request_vertical_meter(int width, int heigh height = min_v_pixbuf_size; if (height > max_v_pixbuf_size) height = max_v_pixbuf_size; + + //int index = height - 1; //if (v_pixbuf_cache == 0) { // v_pixbuf_cache = (Glib::RefPtr<Gdk::Pixbuf>*) malloc(sizeof(Glib::RefPtr<Gdk::Pixbuf>) * max_v_pixbuf_size); @@ -363,7 +365,7 @@ FastMeter::vertical_expose (GdkEventExpose* ev) background.width = pixrect.width; background.height = pixheight - top_of_meter; - if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) { + if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) { get_window()->draw_rectangle (get_style()->get_black_gc(), true, intersection.x, intersection.y, intersection.width, intersection.height); @@ -408,7 +410,7 @@ FastMeter::horizontal_expose (GdkEventExpose* ev) background.width = pixwidth - right_of_meter; background.height = pixrect.height; - if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) { + if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) { get_window()->draw_rectangle (get_style()->get_black_gc(), true, intersection.x + right_of_meter, intersection.y, intersection.width, intersection.height); @@ -419,7 +421,7 @@ FastMeter::horizontal_expose (GdkEventExpose* ev) get_window()->draw_pixbuf(get_style()->get_fg_gc(get_state()), pixbuf, intersection.x, intersection.y, intersection.x, intersection.y, - intersection.width, intersection.height, + pixrect.width, intersection.height, Gdk::RGB_DITHER_NONE, 0, 0); } diff --git a/libs/vamp-sdk/COPYING b/libs/vamp-sdk/COPYING new file mode 100644 index 0000000000..19fa472218 --- /dev/null +++ b/libs/vamp-sdk/COPYING @@ -0,0 +1,26 @@ + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. + diff --git a/libs/vamp-sdk/README b/libs/vamp-sdk/README new file mode 100644 index 0000000000..9454038260 --- /dev/null +++ b/libs/vamp-sdk/README @@ -0,0 +1,240 @@ + +Vamp +==== + +An API for audio analysis and feature extraction plugins. + + http://www.vamp-plugins.org/ + +Vamp is an API for C and C++ plugins that process sampled audio data +to produce descriptive output (measurements or semantic observations). + +The principal differences between Vamp and a real-time audio +processing plugin system such as VST are: + + * Vamp plugins may output complex multidimensional data with labels. + As a consequence, they are likely to work best when the output + data has a much lower sampling rate than the input. (This also + means it is usually desirable to implement them in C++ using the + high-level base class provided rather than use the raw C API.) + + * While Vamp plugins receive data block-by-block, they are not + required to return output immediately on receiving the input. + A Vamp plugin may be non-causal, preferring to store up data + based on its input until the end of a processing run and then + return all results at once. + + * Vamp plugins have more control over their inputs than a typical + real-time processing plugin. For example, they can indicate to + the host their preferred processing block and step sizes, and these + may differ. + + * Vamp plugins may ask to receive data in the frequency domain + instead of the time domain. The host takes the responsibility + for converting the input data using an FFT of windowed frames. + This simplifies plugins that do straightforward frequency-domain + processing and permits the host to cache frequency-domain data + when possible. + + * A Vamp plugin is configured once before each processing run, and + receives no further parameter changes during use -- unlike real- + time plugin APIs in which the input parameters may change at any + time. This also means that fundamental properties such as the + number of values per output or the preferred processing block + size may depend on the input parameters. + + * Vamp plugins do not have to be able to run in real time. + + +About this SDK +============== + +This is version 1.1b of the Vamp plugin Software Development Kit. +Plugins and hosts built with this SDK are binary compatible with those +built using version 1.0 of the SDK. + +This SDK contains the following: + + * vamp/vamp.h + +The formal C language plugin API for Vamp plugins. + +A Vamp plugin is a dynamic library (.so, .dll or .dylib depending on +platform) exposing one C-linkage entry point (vampGetPluginDescriptor) +which returns data defined in the rest of this C header. + +Although the C API is the official API for Vamp, we don't recommend +that you program directly to it. The C++ abstraction found in the +vamp-sdk directory (below) is preferable for most purposes and is +more thoroughly documented. + + * vamp-sdk + +C++ classes for straightforwardly implementing Vamp plugins and hosts. + +Plugins should subclass Vamp::Plugin and then use Vamp::PluginAdapter +to expose the correct C API for the plugin. Plugin authors should +read vamp-sdk/PluginBase.h and Plugin.h for code documentation, and +refer to the example plugin code in the examples directory. Plugins +should link with -lvampsdk. [*NOTE: this has changed from vamp-sdk in +previous versions, to avoid conflict with the use of hyphens for +library versioning schemes on some platforms.] + +Hosts may use the Vamp::PluginHostAdapter to convert the loaded +plugin's C API back into a Vamp::Plugin object. Host authors should +refer to the example host code in the host directory. Hosts should +link with -lvamphostsdk. [*NOTE: this has changed from vamp-hostsdk +in previous versions, to avoid conflict with the use of hyphens for +library versioning schemes on some platforms.] + + * vamp-sdk/hostext + +Additional C++ classes to make a host's life easier (introduced in +version 1.1 of the Vamp SDK). + +Vamp::HostExt::PluginLoader provides a very easy interface for a host +to discover, load, and find out category information about the +available plugins. Most "casual" Vamp hosts will probably want to use +this class. + +Vamp::HostExt::PluginInputDomainAdapter provides a means for hosts to +handle plugins that expect frequency-domain input, without having to +convert the input themselves. + +Vamp::HostExt::PluginChannelAdapter provides a means for hosts to use +plugins that do not necessarily support the same number of audio +channels as they have available, without having to worry about +applying a channel management / mixdown policy themselves. + +The PluginLoader class can also use the input domain and channel +adapters automatically to make the entire conversion process +transparent to the host if required. + + * examples + +Example plugins implemented using the C++ classes. ZeroCrossing +calculates the positions and density of zero-crossing points in an +audio waveform. SpectralCentroid calculates the centre of gravity of +the frequency domain representation of each block of audio. +AmplitudeFollower tracks the amplitude of a signal based on a method +from the SuperCollider real-time audio system. +PercussionOnsetDetector estimates the locations of percussive onsets +using a simple method described in "Drum Source Separation using +Percussive Feature Detection and Spectral Modulation" by Dan Barry, +Derry Fitzgerald, Eugene Coyle and Bob Lawlor, ISSC 2005. + + * host + +A simple command-line Vamp host, capable of loading a plugin and using +it to process a complete audio file, with its default parameters. +Requires libsndfile (http://www.mega-nerd.com/libsndfile/). + +If you don't have libsndfile, you may want to edit the Makefile to +change the default build target from "all" to "sdk", so as to compile +only the SDK and not the host. + + +Plugin Lookup and Categorisation +================================ + +The Vamp API does not officially specify how to load plugin libraries +or where to find them. However, the SDK does include a function +(Vamp::PluginHostAdapter::getPluginPath()) that returns a recommended +directory search path that hosts may use for plugin libraries, and a +class (Vamp::HostExt::PluginLoader) that implements a sensible +cross-platform lookup policy using this path. We recommend using this +class in your host unless you have a good reason not to want to. This +implementation also permits the user to set the environment variable +VAMP_PATH to override the default path if desired. + +The policy used by Vamp::HostExt::PluginLoader -- and our +recommendation for any host -- is to search each directory in the path +returned by getPluginPath for .DLL (on Windows), .so (on Linux, +Solaris, BSD etc) or .dylib (on OS/X) files, then to load each one and +perform a dynamic name lookup on the vampGetPluginDescriptor function +to enumerate the plugins in the library. This operation will +necessarily be system-dependent. + +Vamp also has an informal convention for sorting plugins into +functional categories. In addition to the library file itself, a +plugin library may install a category file with the same name as the +library but .cat extension. The existence and format of this file are +not specified by the Vamp API, but by convention the file may contain +lines of the format + +vamp:pluginlibrary:pluginname::General Category > Specific Category + +which a host may read and use to assign plugins a location within a +category tree for display to the user. The expectation is that +advanced users may also choose to set up their own preferred category +trees, which is why this information is not queried as part of the +Vamp plugin's API itself. The Vamp::HostExt::PluginLoader class also +provides support for plugin category lookup using this scheme. + + +Building and Installing the SDK and Examples +============================================ + +To build the SDK, the simple host, and the example plugins, edit the +Makefile to suit your platform according to the comments in it, then +run "make". + +To use an IDE to build a plugin or host using the Vamp SDK, simply add +the .cpp files in the vamp-sdk directory to your project. + +Installing the example plugins so that they can be found by other Vamp +hosts depends on your platform: + + * Windows: copy the files + examples/vamp-example-plugins.dll + examples/vamp-example-plugins.cat + to + C:\Program Files\Vamp Plugins + + * Linux: copy the files + examples/vamp-example-plugins.so + examples/vamp-example-plugins.cat + to + /usr/local/lib/vamp/ + + * OS/X: copy the files + examples/vamp-example-plugins.dylib + examples/vamp-example-plugins.cat + to + /Library/Audio/Plug-Ins/Vamp + + +Licensing +========= + +This plugin SDK is freely redistributable under a "new-style BSD" +licence. See the file COPYING for more details. In short, you may +modify and redistribute the SDK and example plugins within any +commercial or non-commercial, proprietary or open-source plugin or +application under almost any conditions, with no obligation to provide +source code, provided you retain the original copyright note. + + +See Also +======== + +Sonic Visualiser, an interactive open-source graphical audio +inspection, analysis and visualisation tool supporting Vamp plugins. +http://www.sonicvisualiser.org/ + + +Authors +======= + +Vamp and the Vamp SDK were designed and made at the Centre for Digital +Music at Queen Mary, University of London. + +The SDK was written by Chris Cannam, copyright (c) 2005-2007 +Chris Cannam and QMUL. + +Mark Sandler and Christian Landone provided ideas and direction, and +Mark Levy, Dan Stowell, Martin Gasser and Craig Sapp provided testing +and other input for the 1.0 API and SDK. The API also uses some ideas +from prior plugin systems, notably DSSI (http://dssi.sourceforge.net) +and FEAPI (http://feapi.sourceforge.net). + diff --git a/libs/vamp-sdk/SConscript b/libs/vamp-sdk/SConscript new file mode 100644 index 0000000000..ddd3d8ebbc --- /dev/null +++ b/libs/vamp-sdk/SConscript @@ -0,0 +1,39 @@ +# -*- python -*- + +import os +import os.path +import glob + +vampsdk_files = Split (""" +vamp-sdk/PluginAdapter.cpp +vamp-sdk/RealTime.cpp +""") + +vamphostsdk_files = Split (""" +vamp-sdk/PluginHostAdapter.cpp +vamp-sdk/hostext/PluginChannelAdapter.cpp +vamp-sdk/hostext/PluginInputDomainAdapter.cpp +vamp-sdk/hostext/PluginLoader.cpp +vamp-sdk/hostext/PluginWrapper.cpp +vamp-sdk/RealTime.cpp +""") + +Import('env install_prefix libraries') +vampsdk = env.Copy() + +vampsdk.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk") + +libvampsdk = vampsdk.SharedLibrary('vampsdk', vampsdk_files) +libvamphostsdk = vampsdk.SharedLibrary('vamphostsdk', vamphostsdk_files) + +Default(libvampsdk) +Default(libvamphostsdk) + +env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2'), libvampsdk)) +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'COPYING', 'README' ] + + vampsdk_files + + vamphostsdk_files + + glob.glob('vamp/*.h') + + glob.glob('vamp-sdk/*.h') + + glob.glob('vamp-sdk/hostext/*.h'))) diff --git a/libs/vamp-sdk/vamp-sdk/Plugin.h b/libs/vamp-sdk/vamp-sdk/Plugin.h new file mode 100644 index 0000000000..159bf4fac6 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/Plugin.h @@ -0,0 +1,405 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_H_ +#define _VAMP_PLUGIN_H_ + +#include "PluginBase.h" +#include "RealTime.h" + +#include <string> +#include <vector> +#include <map> + +namespace Vamp { + +/** + * \class Plugin Plugin.h <vamp-sdk/Plugin.h> + * + * Vamp::Plugin is a base class for plugin instance classes + * that provide feature extraction from audio or related data. + * + * In most cases, the input will be audio and the output will be a + * stream of derived data at a lower sampling resolution than the + * input. + * + * Note that this class inherits several abstract methods from + * PluginBase. These must be implemented by the subclass. + * + * + * PLUGIN LIFECYCLE + * + * Feature extraction plugins are managed differently from real-time + * plugins (such as VST effects). The main difference is that the + * parameters for a feature extraction plugin are configured before + * the plugin is used, and do not change during use. + * + * 1. Host constructs the plugin, passing it the input sample rate. + * The plugin may do basic initialisation, but should not do anything + * computationally expensive at this point. You must make sure your + * plugin is cheap to construct, otherwise you'll seriously affect the + * startup performance of almost all hosts. If you have serious + * initialisation to do, the proper place is in initialise() (step 5). + * + * 2. Host may query the plugin's available outputs. + * + * 3. Host queries programs and parameter descriptors, and may set + * some or all of them. Parameters that are not explicitly set should + * take their default values as specified in the parameter descriptor. + * When a program is set, the parameter values may change and the host + * will re-query them to check. + * + * 4. Host queries the preferred step size, block size and number of + * channels. These may all vary depending on the parameter values. + * (Note however that you cannot make the number of distinct outputs + * dependent on parameter values.) + * + * 5. Plugin is properly initialised with a call to initialise. This + * fixes the step size, block size, and number of channels, as well as + * all of the parameter and program settings. If the values passed in + * to initialise do not match the plugin's advertised preferred values + * from step 4, the plugin may refuse to initialise and return false + * (although if possible it should accept the new values). Any + * computationally expensive setup code should take place here. + * + * 6. Host finally checks the number of values, resolution, extents + * etc per output (which may vary depending on the number of channels, + * step size and block size as well as the parameter values). + * + * 7. Host will repeatedly call the process method to pass in blocks + * of input data. This method may return features extracted from that + * data (if the plugin is causal). + * + * 8. Host will call getRemainingFeatures exactly once, after all the + * input data has been processed. This may return any non-causal or + * leftover features. + * + * 9. At any point after initialise was called, the host may + * optionally call the reset method and restart processing. (This + * does not mean it can change the parameters, which are fixed from + * initialise until destruction.) + * + * A plugin does not need to handle the case where setParameter or + * selectProgram is called after initialise has been called. It's the + * host's responsibility not to do that. Similarly, the plugin may + * safely assume that initialise is called no more than once. + */ + +class Plugin : public PluginBase +{ +public: + virtual ~Plugin() { } + + /** + * Initialise a plugin to prepare it for use with the given number + * of input channels, step size (window increment, in sample + * frames) and block size (window size, in sample frames). + * + * The input sample rate should have been already specified at + * construction time. + * + * Return true for successful initialisation, false if the number + * of input channels, step size and/or block size cannot be + * supported. + */ + virtual bool initialise(size_t inputChannels, + size_t stepSize, + size_t blockSize) = 0; + + /** + * Reset the plugin after use, to prepare it for another clean + * run. Not called for the first initialisation (i.e. initialise + * must also do a reset). + */ + virtual void reset() = 0; + + enum InputDomain { TimeDomain, FrequencyDomain }; + + /** + * Get the plugin's required input domain. If this is TimeDomain, + * the samples provided to the process() function (below) will be + * in the time domain, as for a traditional audio processing + * plugin. If this is FrequencyDomain, the host will carry out a + * windowed FFT of size equal to the negotiated block size on the + * data before passing the frequency bin data in to process(). + * The plugin does not get to choose the window type -- the host + * will either let the user do so, or will use a Hanning window. + */ + virtual InputDomain getInputDomain() const = 0; + + /** + * Get the preferred block size (window size -- the number of + * sample frames passed in each block to the process() function). + * This should be called before initialise(). + * + * A plugin that can handle any block size may return 0. The + * final block size will be set in the initialise() call. + */ + virtual size_t getPreferredBlockSize() const { return 0; } + + /** + * Get the preferred step size (window increment -- the distance + * in sample frames between the start frames of consecutive blocks + * passed to the process() function) for the plugin. This should + * be called before initialise(). + * + * A plugin may return 0 if it has no particular interest in the + * step size. In this case, the host should make the step size + * equal to the block size if the plugin is accepting input in the + * time domain. If the plugin is accepting input in the frequency + * domain, the host may use any step size. The final step size + * will be set in the initialise() call. + */ + virtual size_t getPreferredStepSize() const { return 0; } + + /** + * Get the minimum supported number of input channels. + */ + virtual size_t getMinChannelCount() const { return 1; } + + /** + * Get the maximum supported number of input channels. + */ + virtual size_t getMaxChannelCount() const { return 1; } + + struct OutputDescriptor + { + /** + * The name of the output, in computer-usable form. Should be + * reasonably short and without whitespace or punctuation, using + * the characters [a-zA-Z0-9_] only. + * Example: "zero_crossing_count" + */ + std::string identifier; + + /** + * The human-readable name of the output. + * Example: "Zero Crossing Counts" + */ + std::string name; + + /** + * A human-readable short text describing the output. May be + * empty if the name has said it all already. + * Example: "The number of zero crossing points per processing block" + */ + std::string description; + + /** + * The unit of the output, in human-readable form. + */ + std::string unit; + + /** + * True if the output has the same number of values per sample + * for every output sample. Outputs for which this is false + * are unlikely to be very useful in a general-purpose host. + */ + bool hasFixedBinCount; + + /** + * The number of values per result of the output. Undefined + * if hasFixedBinCount is false. If this is zero, the output + * is point data (i.e. only the time of each output is of + * interest, the value list will be empty). + */ + size_t binCount; + + /** + * The (human-readable) names of each of the bins, if + * appropriate. This is always optional. + */ + std::vector<std::string> binNames; + + /** + * True if the results in each output bin fall within a fixed + * numeric range (minimum and maximum values). Undefined if + * binCount is zero. + */ + bool hasKnownExtents; + + /** + * Minimum value of the results in the output. Undefined if + * hasKnownExtents is false or binCount is zero. + */ + float minValue; + + /** + * Maximum value of the results in the output. Undefined if + * hasKnownExtents is false or binCount is zero. + */ + float maxValue; + + /** + * True if the output values are quantized to a particular + * resolution. Undefined if binCount is zero. + */ + bool isQuantized; + + /** + * Quantization resolution of the output values (e.g. 1.0 if + * they are all integers). Undefined if isQuantized is false + * or binCount is zero. + */ + float quantizeStep; + + enum SampleType { + + /// Results from each process() align with that call's block start + OneSamplePerStep, + + /// Results are evenly spaced in time (sampleRate specified below) + FixedSampleRate, + + /// Results are unevenly spaced and have individual timestamps + VariableSampleRate + }; + + /** + * Positioning in time of the output results. + */ + SampleType sampleType; + + /** + * Sample rate of the output results, as samples per second. + * Undefined if sampleType is OneSamplePerStep. + * + * If sampleType is VariableSampleRate and this value is + * non-zero, then it may be used to calculate a resolution for + * the output (i.e. the "duration" of each sample, in time, + * will be 1/sampleRate seconds). It's recommended to set + * this to zero if that behaviour is not desired. + */ + float sampleRate; + }; + + typedef std::vector<OutputDescriptor> OutputList; + + /** + * Get the outputs of this plugin. An output's index in this list + * is used as its numeric index when looking it up in the + * FeatureSet returned from the process() call. + */ + virtual OutputList getOutputDescriptors() const = 0; + + struct Feature + { + /** + * True if an output feature has its own timestamp. This is + * mandatory if the output has VariableSampleRate, and is + * likely to be disregarded otherwise. + */ + bool hasTimestamp; + + /** + * Timestamp of the output feature. This is mandatory if the + * output has VariableSampleRate, and is likely to be + * disregarded otherwise. Undefined if hasTimestamp is false. + */ + RealTime timestamp; + + /** + * Results for a single sample of this feature. If the output + * hasFixedBinCount, there must be the same number of values + * as the output's binCount count. + */ + std::vector<float> values; + + /** + * Label for the sample of this feature. + */ + std::string label; + }; + + typedef std::vector<Feature> FeatureList; + typedef std::map<int, FeatureList> FeatureSet; // key is output no + + /** + * Process a single block of input data. + * + * If the plugin's inputDomain is TimeDomain, inputBuffers will + * point to one array of floats per input channel, and each of + * these arrays will contain blockSize consecutive audio samples + * (the host will zero-pad as necessary). The timestamp will be + * the real time in seconds of the start of the supplied block of + * samples. + * + * If the plugin's inputDomain is FrequencyDomain, inputBuffers + * will point to one array of floats per input channel, and each + * of these arrays will contain blockSize/2+1 consecutive pairs of + * real and imaginary component floats corresponding to bins + * 0..(blockSize/2) of the FFT output. That is, bin 0 (the first + * pair of floats) contains the DC output, up to bin blockSize/2 + * which contains the Nyquist-frequency output. There will + * therefore be blockSize+2 floats per channel in total. The + * timestamp will be the real time in seconds of the centre of the + * FFT input window (i.e. the very first block passed to process + * might contain the FFT of half a block of zero samples and the + * first half-block of the actual data, with a timestamp of zero). + * + * Return any features that have become available after this + * process call. (These do not necessarily have to fall within + * the process block, except for OneSamplePerStep outputs.) + */ + virtual FeatureSet process(const float *const *inputBuffers, + RealTime timestamp) = 0; + + /** + * After all blocks have been processed, calculate and return any + * remaining features derived from the complete input. + */ + virtual FeatureSet getRemainingFeatures() = 0; + + /** + * Used to distinguish between Vamp::Plugin and other potential + * sibling subclasses of PluginBase. Do not reimplement this + * function in your subclass. + */ + virtual std::string getType() const { return "Feature Extraction Plugin"; } + +protected: + Plugin(float inputSampleRate) : + m_inputSampleRate(inputSampleRate) { } + + float m_inputSampleRate; +}; + +} + +#endif + + + diff --git a/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp b/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp new file mode 100644 index 0000000000..1549b4f3aa --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp @@ -0,0 +1,851 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginAdapter.h" + +//#define DEBUG_PLUGIN_ADAPTER 1 + + +namespace Vamp { + +class PluginAdapterBase::Impl +{ +public: + Impl(PluginAdapterBase *); + ~Impl(); + + const VampPluginDescriptor *getDescriptor(); + +protected: + PluginAdapterBase *m_base; + + static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc, + float inputSampleRate); + + static void vampCleanup(VampPluginHandle handle); + + static int vampInitialise(VampPluginHandle handle, unsigned int channels, + unsigned int stepSize, unsigned int blockSize); + + static void vampReset(VampPluginHandle handle); + + static float vampGetParameter(VampPluginHandle handle, int param); + static void vampSetParameter(VampPluginHandle handle, int param, float value); + + static unsigned int vampGetCurrentProgram(VampPluginHandle handle); + static void vampSelectProgram(VampPluginHandle handle, unsigned int program); + + static unsigned int vampGetPreferredStepSize(VampPluginHandle handle); + static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle); + static unsigned int vampGetMinChannelCount(VampPluginHandle handle); + static unsigned int vampGetMaxChannelCount(VampPluginHandle handle); + + static unsigned int vampGetOutputCount(VampPluginHandle handle); + + static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle, + unsigned int i); + + static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc); + + static VampFeatureList *vampProcess(VampPluginHandle handle, + const float *const *inputBuffers, + int sec, + int nsec); + + static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle); + + static void vampReleaseFeatureSet(VampFeatureList *fs); + + void cleanup(Plugin *plugin); + void checkOutputMap(Plugin *plugin); + unsigned int getOutputCount(Plugin *plugin); + VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, + unsigned int i); + VampFeatureList *process(Plugin *plugin, + const float *const *inputBuffers, + int sec, int nsec); + VampFeatureList *getRemainingFeatures(Plugin *plugin); + VampFeatureList *convertFeatures(Plugin *plugin, + const Plugin::FeatureSet &features); + + // maps both plugins and descriptors to adapters + typedef std::map<const void *, Impl *> AdapterMap; + static AdapterMap *m_adapterMap; + static Impl *lookupAdapter(VampPluginHandle); + + bool m_populated; + VampPluginDescriptor m_descriptor; + Plugin::ParameterList m_parameters; + Plugin::ProgramList m_programs; + + typedef std::map<Plugin *, Plugin::OutputList *> OutputMap; + OutputMap m_pluginOutputs; + + std::map<Plugin *, VampFeatureList *> m_fs; + std::map<Plugin *, std::vector<size_t> > m_fsizes; + std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes; + void resizeFS(Plugin *plugin, int n); + void resizeFL(Plugin *plugin, int n, size_t sz); + void resizeFV(Plugin *plugin, int n, int j, size_t sz); +}; + +PluginAdapterBase::PluginAdapterBase() +{ + m_impl = new Impl(this); +} + +PluginAdapterBase::~PluginAdapterBase() +{ + delete m_impl; +} + +const VampPluginDescriptor * +PluginAdapterBase::getDescriptor() +{ + return m_impl->getDescriptor(); +} + +PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) : + m_base(base), + m_populated(false) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl; +#endif +} + +const VampPluginDescriptor * +PluginAdapterBase::Impl::getDescriptor() +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl; +#endif + + if (m_populated) return &m_descriptor; + + Plugin *plugin = m_base->createPlugin(48000); + + if (plugin->getVampApiVersion() != VAMP_API_VERSION) { + std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: " + << "Plugin object API version " + << plugin->getVampApiVersion() + << " does not match actual API version " + << VAMP_API_VERSION << std::endl; + delete plugin; + return 0; + } + + m_parameters = plugin->getParameterDescriptors(); + m_programs = plugin->getPrograms(); + + m_descriptor.vampApiVersion = plugin->getVampApiVersion(); + m_descriptor.identifier = strdup(plugin->getIdentifier().c_str()); + m_descriptor.name = strdup(plugin->getName().c_str()); + m_descriptor.description = strdup(plugin->getDescription().c_str()); + m_descriptor.maker = strdup(plugin->getMaker().c_str()); + m_descriptor.pluginVersion = plugin->getPluginVersion(); + m_descriptor.copyright = strdup(plugin->getCopyright().c_str()); + + m_descriptor.parameterCount = m_parameters.size(); + m_descriptor.parameters = (const VampParameterDescriptor **) + malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); + + unsigned int i; + + for (i = 0; i < m_parameters.size(); ++i) { + VampParameterDescriptor *desc = (VampParameterDescriptor *) + malloc(sizeof(VampParameterDescriptor)); + desc->identifier = strdup(m_parameters[i].identifier.c_str()); + desc->name = strdup(m_parameters[i].name.c_str()); + desc->description = strdup(m_parameters[i].description.c_str()); + desc->unit = strdup(m_parameters[i].unit.c_str()); + desc->minValue = m_parameters[i].minValue; + desc->maxValue = m_parameters[i].maxValue; + desc->defaultValue = m_parameters[i].defaultValue; + desc->isQuantized = m_parameters[i].isQuantized; + desc->quantizeStep = m_parameters[i].quantizeStep; + desc->valueNames = 0; + if (desc->isQuantized && !m_parameters[i].valueNames.empty()) { + desc->valueNames = (const char **) + malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *)); + for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) { + desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str()); + } + desc->valueNames[m_parameters[i].valueNames.size()] = 0; + } + m_descriptor.parameters[i] = desc; + } + + m_descriptor.programCount = m_programs.size(); + m_descriptor.programs = (const char **) + malloc(m_programs.size() * sizeof(const char *)); + + for (i = 0; i < m_programs.size(); ++i) { + m_descriptor.programs[i] = strdup(m_programs[i].c_str()); + } + + if (plugin->getInputDomain() == Plugin::FrequencyDomain) { + m_descriptor.inputDomain = vampFrequencyDomain; + } else { + m_descriptor.inputDomain = vampTimeDomain; + } + + m_descriptor.instantiate = vampInstantiate; + m_descriptor.cleanup = vampCleanup; + m_descriptor.initialise = vampInitialise; + m_descriptor.reset = vampReset; + m_descriptor.getParameter = vampGetParameter; + m_descriptor.setParameter = vampSetParameter; + m_descriptor.getCurrentProgram = vampGetCurrentProgram; + m_descriptor.selectProgram = vampSelectProgram; + m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; + m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; + m_descriptor.getMinChannelCount = vampGetMinChannelCount; + m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; + m_descriptor.getOutputCount = vampGetOutputCount; + m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; + m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; + m_descriptor.process = vampProcess; + m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; + m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; + + if (!m_adapterMap) { + m_adapterMap = new AdapterMap; + } + (*m_adapterMap)[&m_descriptor] = this; + + delete plugin; + + m_populated = true; + return &m_descriptor; +} + +PluginAdapterBase::Impl::~Impl() +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl; +#endif + + if (!m_populated) return; + + free((void *)m_descriptor.identifier); + free((void *)m_descriptor.name); + free((void *)m_descriptor.description); + free((void *)m_descriptor.maker); + free((void *)m_descriptor.copyright); + + for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { + const VampParameterDescriptor *desc = m_descriptor.parameters[i]; + free((void *)desc->identifier); + free((void *)desc->name); + free((void *)desc->description); + free((void *)desc->unit); + if (desc->valueNames) { + for (unsigned int j = 0; desc->valueNames[j]; ++j) { + free((void *)desc->valueNames[j]); + } + free((void *)desc->valueNames); + } + } + free((void *)m_descriptor.parameters); + + for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { + free((void *)m_descriptor.programs[i]); + } + free((void *)m_descriptor.programs); + + if (m_adapterMap) { + + m_adapterMap->erase(&m_descriptor); + + if (m_adapterMap->empty()) { + delete m_adapterMap; + m_adapterMap = 0; + } + } +} + +PluginAdapterBase::Impl * +PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl; +#endif + + if (!m_adapterMap) return 0; + AdapterMap::const_iterator i = m_adapterMap->find(handle); + if (i == m_adapterMap->end()) return 0; + return i->second; +} + +VampPluginHandle +PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc, + float inputSampleRate) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl; +#endif + + if (!m_adapterMap) { + m_adapterMap = new AdapterMap(); + } + + if (m_adapterMap->find(desc) == m_adapterMap->end()) { + std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl; + return 0; + } + + Impl *adapter = (*m_adapterMap)[desc]; + if (desc != &adapter->m_descriptor) return 0; + + Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate); + if (plugin) { + (*m_adapterMap)[plugin] = adapter; + } + +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; +#endif + + return plugin; +} + +void +PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) { + delete ((Plugin *)handle); + return; + } + adapter->cleanup(((Plugin *)handle)); +} + +int +PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle, + unsigned int channels, + unsigned int stepSize, + unsigned int blockSize) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; +#endif + + bool result = ((Plugin *)handle)->initialise + (channels, stepSize, blockSize); + return result ? 1 : 0; +} + +void +PluginAdapterBase::Impl::vampReset(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl; +#endif + + ((Plugin *)handle)->reset(); +} + +float +PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle, + int param) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return 0.0; + Plugin::ParameterList &list = adapter->m_parameters; + return ((Plugin *)handle)->getParameter(list[param].identifier); +} + +void +PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle, + int param, float value) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return; + Plugin::ParameterList &list = adapter->m_parameters; + ((Plugin *)handle)->setParameter(list[param].identifier, value); +} + +unsigned int +PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return 0; + Plugin::ProgramList &list = adapter->m_programs; + std::string program = ((Plugin *)handle)->getCurrentProgram(); + for (unsigned int i = 0; i < list.size(); ++i) { + if (list[i] == program) return i; + } + return 0; +} + +void +PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle, + unsigned int program) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return; + Plugin::ProgramList &list = adapter->m_programs; + ((Plugin *)handle)->selectProgram(list[program]); +} + +unsigned int +PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl; +#endif + + return ((Plugin *)handle)->getPreferredStepSize(); +} + +unsigned int +PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl; +#endif + + return ((Plugin *)handle)->getPreferredBlockSize(); +} + +unsigned int +PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl; +#endif + + return ((Plugin *)handle)->getMinChannelCount(); +} + +unsigned int +PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl; +#endif + + return ((Plugin *)handle)->getMaxChannelCount(); +} + +unsigned int +PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + +// std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; + + if (!adapter) return 0; + return adapter->getOutputCount((Plugin *)handle); +} + +VampOutputDescriptor * +PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle, + unsigned int i) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + +// std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; + + if (!adapter) return 0; + return adapter->getOutputDescriptor((Plugin *)handle, i); +} + +void +PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; +#endif + + if (desc->identifier) free((void *)desc->identifier); + if (desc->name) free((void *)desc->name); + if (desc->description) free((void *)desc->description); + if (desc->unit) free((void *)desc->unit); + if (desc->hasFixedBinCount && desc->binNames) { + for (unsigned int i = 0; i < desc->binCount; ++i) { + if (desc->binNames[i]) { + free((void *)desc->binNames[i]); + } + } + } + if (desc->binNames) free((void *)desc->binNames); + free((void *)desc); +} + +VampFeatureList * +PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle, + const float *const *inputBuffers, + int sec, + int nsec) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->process((Plugin *)handle, + inputBuffers, sec, nsec); +} + +VampFeatureList * +PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl; +#endif + + Impl *adapter = lookupAdapter(handle); + if (!adapter) return 0; + return adapter->getRemainingFeatures((Plugin *)handle); +} + +void +PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs) +{ +#ifdef DEBUG_PLUGIN_ADAPTER + std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl; +#endif +} + +void +PluginAdapterBase::Impl::cleanup(Plugin *plugin) +{ + if (m_fs.find(plugin) != m_fs.end()) { + size_t outputCount = 0; + if (m_pluginOutputs[plugin]) { + outputCount = m_pluginOutputs[plugin]->size(); + } + VampFeatureList *list = m_fs[plugin]; + for (unsigned int i = 0; i < outputCount; ++i) { + for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { + if (list[i].features[j].label) { + free(list[i].features[j].label); + } + if (list[i].features[j].values) { + free(list[i].features[j].values); + } + } + if (list[i].features) free(list[i].features); + } + m_fs.erase(plugin); + m_fsizes.erase(plugin); + m_fvsizes.erase(plugin); + } + + if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { + delete m_pluginOutputs[plugin]; + m_pluginOutputs.erase(plugin); + } + + if (m_adapterMap) { + m_adapterMap->erase(plugin); + + if (m_adapterMap->empty()) { + delete m_adapterMap; + m_adapterMap = 0; + } + } + + delete ((Plugin *)plugin); +} + +void +PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin) +{ + if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() || + !m_pluginOutputs[plugin]) { + m_pluginOutputs[plugin] = new Plugin::OutputList + (plugin->getOutputDescriptors()); +// std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl; + } +} + +unsigned int +PluginAdapterBase::Impl::getOutputCount(Plugin *plugin) +{ + checkOutputMap(plugin); + return m_pluginOutputs[plugin]->size(); +} + +VampOutputDescriptor * +PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin, + unsigned int i) +{ + checkOutputMap(plugin); + Plugin::OutputDescriptor &od = + (*m_pluginOutputs[plugin])[i]; + + VampOutputDescriptor *desc = (VampOutputDescriptor *) + malloc(sizeof(VampOutputDescriptor)); + + desc->identifier = strdup(od.identifier.c_str()); + desc->name = strdup(od.name.c_str()); + desc->description = strdup(od.description.c_str()); + desc->unit = strdup(od.unit.c_str()); + desc->hasFixedBinCount = od.hasFixedBinCount; + desc->binCount = od.binCount; + + if (od.hasFixedBinCount && od.binCount > 0) { + desc->binNames = (const char **) + malloc(od.binCount * sizeof(const char *)); + + for (unsigned int i = 0; i < od.binCount; ++i) { + if (i < od.binNames.size()) { + desc->binNames[i] = strdup(od.binNames[i].c_str()); + } else { + desc->binNames[i] = 0; + } + } + } else { + desc->binNames = 0; + } + + desc->hasKnownExtents = od.hasKnownExtents; + desc->minValue = od.minValue; + desc->maxValue = od.maxValue; + desc->isQuantized = od.isQuantized; + desc->quantizeStep = od.quantizeStep; + + switch (od.sampleType) { + case Plugin::OutputDescriptor::OneSamplePerStep: + desc->sampleType = vampOneSamplePerStep; break; + case Plugin::OutputDescriptor::FixedSampleRate: + desc->sampleType = vampFixedSampleRate; break; + case Plugin::OutputDescriptor::VariableSampleRate: + desc->sampleType = vampVariableSampleRate; break; + } + + desc->sampleRate = od.sampleRate; + + return desc; +} + +VampFeatureList * +PluginAdapterBase::Impl::process(Plugin *plugin, + const float *const *inputBuffers, + int sec, int nsec) +{ +// std::cerr << "PluginAdapterBase::Impl::process" << std::endl; + RealTime rt(sec, nsec); + checkOutputMap(plugin); + return convertFeatures(plugin, plugin->process(inputBuffers, rt)); +} + +VampFeatureList * +PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin) +{ +// std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl; + checkOutputMap(plugin); + return convertFeatures(plugin, plugin->getRemainingFeatures()); +} + +VampFeatureList * +PluginAdapterBase::Impl::convertFeatures(Plugin *plugin, + const Plugin::FeatureSet &features) +{ + int lastN = -1; + + int outputCount = 0; + if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); + + resizeFS(plugin, outputCount); + VampFeatureList *fs = m_fs[plugin]; + + for (Plugin::FeatureSet::const_iterator fi = features.begin(); + fi != features.end(); ++fi) { + + int n = fi->first; + +// std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl; + + if (n >= int(outputCount)) { + std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; + continue; + } + + if (n > lastN + 1) { + for (int i = lastN + 1; i < n; ++i) { + fs[i].featureCount = 0; + } + } + + const Plugin::FeatureList &fl = fi->second; + + size_t sz = fl.size(); + if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); + fs[n].featureCount = sz; + + for (size_t j = 0; j < sz; ++j) { + +// std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl; + + VampFeature *feature = &fs[n].features[j]; + + feature->hasTimestamp = fl[j].hasTimestamp; + feature->sec = fl[j].timestamp.sec; + feature->nsec = fl[j].timestamp.nsec; + feature->valueCount = fl[j].values.size(); + + if (feature->label) free(feature->label); + + if (fl[j].label.empty()) { + feature->label = 0; + } else { + feature->label = strdup(fl[j].label.c_str()); + } + + if (feature->valueCount > m_fvsizes[plugin][n][j]) { + resizeFV(plugin, n, j, feature->valueCount); + } + + for (unsigned int k = 0; k < feature->valueCount; ++k) { +// std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl; + feature->values[k] = fl[j].values[k]; + } + } + + lastN = n; + } + + if (lastN == -1) return 0; + + if (int(outputCount) > lastN + 1) { + for (int i = lastN + 1; i < int(outputCount); ++i) { + fs[i].featureCount = 0; + } + } + + return fs; +} + +void +PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n) +{ +// std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl; + + int i = m_fsizes[plugin].size(); + if (i >= n) return; + +// std::cerr << "resizing from " << i << std::endl; + + m_fs[plugin] = (VampFeatureList *)realloc + (m_fs[plugin], n * sizeof(VampFeatureList)); + + while (i < n) { + m_fs[plugin][i].featureCount = 0; + m_fs[plugin][i].features = 0; + m_fsizes[plugin].push_back(0); + m_fvsizes[plugin].push_back(std::vector<size_t>()); + i++; + } +} + +void +PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz) +{ +// std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", " +// << sz << ")" << std::endl; + + size_t i = m_fsizes[plugin][n]; + if (i >= sz) return; + +// std::cerr << "resizing from " << i << std::endl; + + m_fs[plugin][n].features = (VampFeature *)realloc + (m_fs[plugin][n].features, sz * sizeof(VampFeature)); + + while (m_fsizes[plugin][n] < sz) { + m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0; + m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0; + m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0; + m_fvsizes[plugin][n].push_back(0); + m_fsizes[plugin][n]++; + } +} + +void +PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz) +{ +// std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", " +// << j << ", " << sz << ")" << std::endl; + + size_t i = m_fvsizes[plugin][n][j]; + if (i >= sz) return; + +// std::cerr << "resizing from " << i << std::endl; + + m_fs[plugin][n].features[j].values = (float *)realloc + (m_fs[plugin][n].features[j].values, sz * sizeof(float)); + + m_fvsizes[plugin][n][j] = sz; +} + +PluginAdapterBase::Impl::AdapterMap * +PluginAdapterBase::Impl::m_adapterMap = 0; + +} + diff --git a/libs/vamp-sdk/vamp-sdk/PluginAdapter.h b/libs/vamp-sdk/vamp-sdk/PluginAdapter.h new file mode 100644 index 0000000000..bfc97508eb --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/PluginAdapter.h @@ -0,0 +1,117 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_ADAPTER_H_ +#define _VAMP_PLUGIN_ADAPTER_H_ + +#include <vamp/vamp.h> + +#include "Plugin.h" + +#include <map> + +namespace Vamp { + +/** + * \class PluginAdapterBase PluginAdapter.h <vamp-sdk/PluginAdapter.h> + * + * PluginAdapter and PluginAdapterBase provide a wrapper class that a + * plugin library can use to make its C++ Vamp::Plugin objects + * available through the Vamp C API. + * + * Almost all Vamp plugin libraries will want to make use of this. To + * do so, all they need to do is declare a PluginAdapter<T> for each + * plugin class T in their library. It's very simple, and you need to + * know absolutely nothing about how it works in order to use it. + * Just cut and paste from an existing plugin's discovery function. + * \see vampGetPluginDescriptor + */ + +class PluginAdapterBase +{ +public: + virtual ~PluginAdapterBase(); + + /** + * Return a VampPluginDescriptor describing the plugin that is + * wrapped by this adapter. + */ + const VampPluginDescriptor *getDescriptor(); + +protected: + PluginAdapterBase(); + + virtual Plugin *createPlugin(float inputSampleRate) = 0; + + class Impl; + Impl *m_impl; +}; + +/** + * \class PluginAdapter PluginAdapter.h <vamp-sdk/PluginAdapter.h> + * + * PluginAdapter turns a PluginAdapterBase into a specific wrapper for + * a particular plugin implementation. + * + * See PluginAdapterBase. + */ + +template <typename P> +class PluginAdapter : public PluginAdapterBase +{ +public: + PluginAdapter() : PluginAdapterBase() { } + virtual ~PluginAdapter() { } + +protected: + Plugin *createPlugin(float inputSampleRate) { + P *p = new P(inputSampleRate); + Plugin *plugin = dynamic_cast<Plugin *>(p); + if (!plugin) { + std::cerr << "ERROR: PluginAdapter::createPlugin: " + << "Template type is not a plugin!" + << std::endl; + delete p; + return 0; + } + return plugin; + } +}; + +} + +#endif + diff --git a/libs/vamp-sdk/vamp-sdk/PluginBase.h b/libs/vamp-sdk/vamp-sdk/PluginBase.h new file mode 100644 index 0000000000..38d2b49904 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/PluginBase.h @@ -0,0 +1,252 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_BASE_H_ +#define _VAMP_PLUGIN_BASE_H_ + +#include <string> +#include <vector> + +#define VAMP_SDK_VERSION "1.1" + +namespace Vamp { + +/** + * A base class for plugins with optional configurable parameters, + * programs, etc. The Vamp::Plugin is derived from this, and + * individual Vamp plugins should derive from that. + * + * This class does not provide the necessary interfaces to instantiate + * or run a plugin. It only specifies an interface for retrieving + * those controls that the host may wish to show to the user for + * editing. It could meaningfully be subclassed by real-time plugins + * or other sorts of plugin as well as Vamp plugins. + */ + +class PluginBase +{ +public: + virtual ~PluginBase() { } + + /** + * Get the Vamp API compatibility level of the plugin. + */ + virtual unsigned int getVampApiVersion() const { return 1; } + + /** + * Get the computer-usable name of the plugin. This should be + * reasonably short and contain no whitespace or punctuation + * characters. It may only contain the characters [a-zA-Z0-9_]. + * This is the authoritative way for a program to identify a + * plugin within a given library. + * + * This text may be visible to the user, but it should not be the + * main text used to identify a plugin to the user (that will be + * the name, below). + * + * Example: "zero_crossings" + */ + virtual std::string getIdentifier() const = 0; + + /** + * Get a human-readable name or title of the plugin. This + * should be brief and self-contained, as it may be used to + * identify the plugin to the user in isolation (i.e. without also + * showing the plugin's "identifier"). + * + * Example: "Zero Crossings" + */ + virtual std::string getName() const = 0; + + /** + * Get a human-readable description for the plugin, typically + * a line of text that may optionally be displayed in addition + * to the plugin's "name". May be empty if the name has said + * it all already. + * + * Example: "Detect and count zero crossing points" + */ + virtual std::string getDescription() const = 0; + + /** + * Get the name of the author or vendor of the plugin in + * human-readable form. This should be a short identifying text, + * as it may be used to label plugins from the same source in a + * menu or similar. + */ + virtual std::string getMaker() const = 0; + + /** + * Get the copyright statement or licensing summary for the + * plugin. This can be an informative text, without the same + * presentation constraints as mentioned for getMaker above. + */ + virtual std::string getCopyright() const = 0; + + /** + * Get the version number of the plugin. + */ + virtual int getPluginVersion() const = 0; + + + struct ParameterDescriptor + { + /** + * The name of the parameter, in computer-usable form. Should + * be reasonably short, and may only contain the characters + * [a-zA-Z0-9_]. + */ + std::string identifier; + + /** + * The human-readable name of the parameter. + */ + std::string name; + + /** + * A human-readable short text describing the parameter. May be + * empty if the name has said it all already. + */ + std::string description; + + /** + * The unit of the parameter, in human-readable form. + */ + std::string unit; + + /** + * The minimum value of the parameter. + */ + float minValue; + + /** + * The maximum value of the parameter. + */ + float maxValue; + + /** + * The default value of the parameter. The plugin should + * ensure that parameters have this value on initialisation + * (i.e. the host is not required to explicitly set parameters + * if it wants to use their default values). + */ + float defaultValue; + + /** + * True if the parameter values are quantized to a particular + * resolution. + */ + bool isQuantized; + + /** + * Quantization resolution of the parameter values (e.g. 1.0 + * if they are all integers). Undefined if isQuantized is + * false. + */ + float quantizeStep; + + /** + * Names for the quantized values. If isQuantized is true, + * this may either be empty or contain one string for each of + * the quantize steps from minValue up to maxValue inclusive. + * Undefined if isQuantized is false. + * + * If these names are provided, they should be shown to the + * user in preference to the values themselves. The user may + * never see the actual numeric values unless they are also + * encoded in the names. + */ + std::vector<std::string> valueNames; + }; + + typedef std::vector<ParameterDescriptor> ParameterList; + + /** + * Get the controllable parameters of this plugin. + */ + virtual ParameterList getParameterDescriptors() const { + return ParameterList(); + } + + /** + * Get the value of a named parameter. The argument is the identifier + * field from that parameter's descriptor. + */ + virtual float getParameter(std::string) const { return 0.0; } + + /** + * Set a named parameter. The first argument is the identifier field + * from that parameter's descriptor. + */ + virtual void setParameter(std::string, float) { } + + + typedef std::vector<std::string> ProgramList; + + /** + * Get the program settings available in this plugin. A program + * is a named shorthand for a set of parameter values; changing + * the program may cause the plugin to alter the values of its + * published parameters (and/or non-public internal processing + * parameters). The host should re-read the plugin's parameter + * values after setting a new program. + * + * The programs must have unique names. + */ + virtual ProgramList getPrograms() const { return ProgramList(); } + + /** + * Get the current program. + */ + virtual std::string getCurrentProgram() const { return ""; } + + /** + * Select a program. (If the given program name is not one of the + * available programs, do nothing.) + */ + virtual void selectProgram(std::string) { } + + /** + * Get the type of plugin. This is to be implemented by the + * immediate subclass, not by actual plugins. Do not attempt to + * implement this in plugin code. + */ + virtual std::string getType() const = 0; +}; + +} + +#endif diff --git a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp new file mode 100644 index 0000000000..12e15393fc --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp @@ -0,0 +1,418 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginHostAdapter.h" + +namespace Vamp +{ + +PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate) : + Plugin(inputSampleRate), + m_descriptor(descriptor) +{ +// std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; + m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); + if (!m_handle) { +// std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl; + } +} + +PluginHostAdapter::~PluginHostAdapter() +{ +// std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl; + if (m_handle) m_descriptor->cleanup(m_handle); +} + +std::vector<std::string> +PluginHostAdapter::getPluginPath() +{ + std::vector<std::string> path; + std::string envPath; + + char *cpath = getenv("VAMP_PATH"); + if (cpath) envPath = cpath; + +#ifdef _WIN32 +#define PATH_SEPARATOR ';' +#define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins" +#else +#define PATH_SEPARATOR ':' +#ifdef __APPLE__ +#define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp" +#else +#define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp" +#endif +#endif + + if (envPath == "") { + envPath = DEFAULT_VAMP_PATH; + char *chome = getenv("HOME"); + if (chome) { + std::string home(chome); + std::string::size_type f; + while ((f = envPath.find("$HOME")) != std::string::npos && + f < envPath.length()) { + envPath.replace(f, 5, home); + } + } +#ifdef _WIN32 + char *cpfiles = getenv("ProgramFiles"); + if (!cpfiles) cpfiles = "C:\\Program Files"; + std::string pfiles(cpfiles); + std::string::size_type f; + while ((f = envPath.find("%ProgramFiles%")) != std::string::npos && + f < envPath.length()) { + envPath.replace(f, 14, pfiles); + } +#endif + } + + std::string::size_type index = 0, newindex = 0; + + while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) { + path.push_back(envPath.substr(index, newindex - index)); + index = newindex + 1; + } + + path.push_back(envPath.substr(index)); + + return path; +} + +bool +PluginHostAdapter::initialise(size_t channels, + size_t stepSize, + size_t blockSize) +{ + if (!m_handle) return false; + return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? + true : false; +} + +void +PluginHostAdapter::reset() +{ + if (!m_handle) return; + m_descriptor->reset(m_handle); +} + +PluginHostAdapter::InputDomain +PluginHostAdapter::getInputDomain() const +{ + if (m_descriptor->inputDomain == vampFrequencyDomain) { + return FrequencyDomain; + } else { + return TimeDomain; + } +} + +unsigned int +PluginHostAdapter::getVampApiVersion() const +{ + return m_descriptor->vampApiVersion; +} + +std::string +PluginHostAdapter::getIdentifier() const +{ + return m_descriptor->identifier; +} + +std::string +PluginHostAdapter::getName() const +{ + return m_descriptor->name; +} + +std::string +PluginHostAdapter::getDescription() const +{ + return m_descriptor->description; +} + +std::string +PluginHostAdapter::getMaker() const +{ + return m_descriptor->maker; +} + +int +PluginHostAdapter::getPluginVersion() const +{ + return m_descriptor->pluginVersion; +} + +std::string +PluginHostAdapter::getCopyright() const +{ + return m_descriptor->copyright; +} + +PluginHostAdapter::ParameterList +PluginHostAdapter::getParameterDescriptors() const +{ + ParameterList list; + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + const VampParameterDescriptor *spd = m_descriptor->parameters[i]; + ParameterDescriptor pd; + pd.identifier = spd->identifier; + pd.name = spd->name; + pd.description = spd->description; + pd.unit = spd->unit; + pd.minValue = spd->minValue; + pd.maxValue = spd->maxValue; + pd.defaultValue = spd->defaultValue; + pd.isQuantized = spd->isQuantized; + pd.quantizeStep = spd->quantizeStep; + if (pd.isQuantized && spd->valueNames) { + for (unsigned int j = 0; spd->valueNames[j]; ++j) { + pd.valueNames.push_back(spd->valueNames[j]); + } + } + list.push_back(pd); + } + return list; +} + +float +PluginHostAdapter::getParameter(std::string param) const +{ + if (!m_handle) return 0.0; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->identifier) { + return m_descriptor->getParameter(m_handle, i); + } + } + + return 0.0; +} + +void +PluginHostAdapter::setParameter(std::string param, + float value) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { + if (param == m_descriptor->parameters[i]->identifier) { + m_descriptor->setParameter(m_handle, i, value); + return; + } + } +} + +PluginHostAdapter::ProgramList +PluginHostAdapter::getPrograms() const +{ + ProgramList list; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + list.push_back(m_descriptor->programs[i]); + } + + return list; +} + +std::string +PluginHostAdapter::getCurrentProgram() const +{ + if (!m_handle) return ""; + + int pn = m_descriptor->getCurrentProgram(m_handle); + return m_descriptor->programs[pn]; +} + +void +PluginHostAdapter::selectProgram(std::string program) +{ + if (!m_handle) return; + + for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { + if (program == m_descriptor->programs[i]) { + m_descriptor->selectProgram(m_handle, i); + return; + } + } +} + +size_t +PluginHostAdapter::getPreferredStepSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredStepSize(m_handle); +} + +size_t +PluginHostAdapter::getPreferredBlockSize() const +{ + if (!m_handle) return 0; + return m_descriptor->getPreferredBlockSize(m_handle); +} + +size_t +PluginHostAdapter::getMinChannelCount() const +{ + if (!m_handle) return 0; + return m_descriptor->getMinChannelCount(m_handle); +} + +size_t +PluginHostAdapter::getMaxChannelCount() const +{ + if (!m_handle) return 0; + return m_descriptor->getMaxChannelCount(m_handle); +} + +PluginHostAdapter::OutputList +PluginHostAdapter::getOutputDescriptors() const +{ + OutputList list; + if (!m_handle) { +// std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl; + return list; + } + + unsigned int count = m_descriptor->getOutputCount(m_handle); + + for (unsigned int i = 0; i < count; ++i) { + VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); + OutputDescriptor d; + d.identifier = sd->identifier; + d.name = sd->name; + d.description = sd->description; + d.unit = sd->unit; + d.hasFixedBinCount = sd->hasFixedBinCount; + d.binCount = sd->binCount; + if (d.hasFixedBinCount) { + for (unsigned int j = 0; j < sd->binCount; ++j) { + d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : ""); + } + } + d.hasKnownExtents = sd->hasKnownExtents; + d.minValue = sd->minValue; + d.maxValue = sd->maxValue; + d.isQuantized = sd->isQuantized; + d.quantizeStep = sd->quantizeStep; + + switch (sd->sampleType) { + case vampOneSamplePerStep: + d.sampleType = OutputDescriptor::OneSamplePerStep; break; + case vampFixedSampleRate: + d.sampleType = OutputDescriptor::FixedSampleRate; break; + case vampVariableSampleRate: + d.sampleType = OutputDescriptor::VariableSampleRate; break; + } + + d.sampleRate = sd->sampleRate; + + list.push_back(d); + + m_descriptor->releaseOutputDescriptor(sd); + } + + return list; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::process(const float *const *inputBuffers, + RealTime timestamp) +{ + FeatureSet fs; + if (!m_handle) return fs; + + int sec = timestamp.sec; + int nsec = timestamp.nsec; + + VampFeatureList *features = m_descriptor->process(m_handle, + inputBuffers, + sec, nsec); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +PluginHostAdapter::FeatureSet +PluginHostAdapter::getRemainingFeatures() +{ + FeatureSet fs; + if (!m_handle) return fs; + + VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); + + convertFeatures(features, fs); + m_descriptor->releaseFeatureSet(features); + return fs; +} + +void +PluginHostAdapter::convertFeatures(VampFeatureList *features, + FeatureSet &fs) +{ + if (!features) return; + + unsigned int outputs = m_descriptor->getOutputCount(m_handle); + + for (unsigned int i = 0; i < outputs; ++i) { + + VampFeatureList &list = features[i]; + + if (list.featureCount > 0) { + + for (unsigned int j = 0; j < list.featureCount; ++j) { + + Feature feature; + feature.hasTimestamp = list.features[j].hasTimestamp; + feature.timestamp = RealTime(list.features[j].sec, + list.features[j].nsec); + + for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { + feature.values.push_back(list.features[j].values[k]); + } + + if (list.features[j].label) { + feature.label = list.features[j].label; + } + + fs[i].push_back(feature); + } + } + } +} + +} diff --git a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h new file mode 100644 index 0000000000..80ae6208a4 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h @@ -0,0 +1,117 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_HOST_ADAPTER_H_ +#define _VAMP_PLUGIN_HOST_ADAPTER_H_ + +#include <vamp/vamp.h> +#include <vamp-sdk/Plugin.h> + +#include <vector> + +namespace Vamp { + +/** + * \class PluginHostAdapter PluginHostAdapter.h <vamp-sdk/PluginHostAdapter.h> + * + * PluginHostAdapter is a wrapper class that a Vamp host can use to + * make the C-language VampPluginDescriptor object appear as a C++ + * Vamp::Plugin object. + * + * The Vamp API is defined in vamp/vamp.h as a C API. The C++ objects + * used for convenience by plugins and hosts actually communicate + * using the C low-level API, but the details of this communication + * are handled seamlessly by the Vamp SDK implementation provided the + * plugin and host use the proper C++ wrapper objects. + * + * See also PluginAdapter, the plugin-side wrapper that makes a C++ + * plugin object available using the C query API. + */ + +class PluginHostAdapter : public Plugin +{ +public: + PluginHostAdapter(const VampPluginDescriptor *descriptor, + float inputSampleRate); + virtual ~PluginHostAdapter(); + + static std::vector<std::string> getPluginPath(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + unsigned int getVampApiVersion() const; + 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); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + size_t getMinChannelCount() const; + size_t getMaxChannelCount() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + void convertFeatures(VampFeatureList *, FeatureSet &); + + const VampPluginDescriptor *m_descriptor; + VampPluginHandle m_handle; +}; + +} + +#endif + + diff --git a/libs/vamp-sdk/vamp-sdk/RealTime.cpp b/libs/vamp-sdk/vamp-sdk/RealTime.cpp new file mode 100644 index 0000000000..0b541cc33e --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/RealTime.cpp @@ -0,0 +1,254 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2006 Chris Cannam. + Relicensed by the author as detailed above. +*/ + +#include <iostream> + +#if (__GNUC__ < 3) +#include <strstream> +#define stringstream strstream +#else +#include <sstream> +#endif + +using std::cerr; +using std::endl; + +#include "RealTime.h" + +#ifndef _WIN32 +#include <sys/time.h> +#endif + +namespace Vamp { + +// A RealTime consists of two ints that must be at least 32 bits each. +// A signed 32-bit int can store values exceeding +/- 2 billion. This +// means we can safely use our lower int for nanoseconds, as there are +// 1 billion nanoseconds in a second and we need to handle double that +// because of the implementations of addition etc that we use. +// +// The maximum valid RealTime on a 32-bit system is somewhere around +// 68 years: 999999999 nanoseconds longer than the classic Unix epoch. + +#define ONE_BILLION 1000000000 + +RealTime::RealTime(int s, int n) : + sec(s), nsec(n) +{ + if (sec == 0) { + while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } + while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } + } else if (sec < 0) { + while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } + while (nsec > 0) { nsec -= ONE_BILLION; ++sec; } + } else { + while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } + while (nsec < 0) { nsec += ONE_BILLION; --sec; } + } +} + +RealTime +RealTime::fromSeconds(double sec) +{ + return RealTime(int(sec), int((sec - int(sec)) * ONE_BILLION + 0.5)); +} + +RealTime +RealTime::fromMilliseconds(int msec) +{ + return RealTime(msec / 1000, (msec % 1000) * 1000000); +} + +#ifndef _WIN32 +RealTime +RealTime::fromTimeval(const struct timeval &tv) +{ + return RealTime(tv.tv_sec, tv.tv_usec * 1000); +} +#endif + +std::ostream &operator<<(std::ostream &out, const RealTime &rt) +{ + if (rt < RealTime::zeroTime) { + out << "-"; + } else { + out << " "; + } + + int s = (rt.sec < 0 ? -rt.sec : rt.sec); + int n = (rt.nsec < 0 ? -rt.nsec : rt.nsec); + + out << s << "."; + + int nn(n); + if (nn == 0) out << "00000000"; + else while (nn < (ONE_BILLION / 10)) { + out << "0"; + nn *= 10; + } + + out << n << "R"; + return out; +} + +std::string +RealTime::toString() const +{ + std::stringstream out; + out << *this; + +#if (__GNUC__ < 3) + out << std::ends; +#endif + + std::string s = out.str(); + + // remove trailing R + return s.substr(0, s.length() - 1); +} + +std::string +RealTime::toText(bool fixedDp) const +{ + if (*this < RealTime::zeroTime) return "-" + (-*this).toText(); + + std::stringstream out; + + if (sec >= 3600) { + out << (sec / 3600) << ":"; + } + + if (sec >= 60) { + out << (sec % 3600) / 60 << ":"; + } + + if (sec >= 10) { + out << ((sec % 60) / 10); + } + + out << (sec % 10); + + int ms = msec(); + + if (ms != 0) { + out << "."; + out << (ms / 100); + ms = ms % 100; + if (ms != 0) { + out << (ms / 10); + ms = ms % 10; + } else if (fixedDp) { + out << "0"; + } + if (ms != 0) { + out << ms; + } else if (fixedDp) { + out << "0"; + } + } else if (fixedDp) { + out << ".000"; + } + +#if (__GNUC__ < 3) + out << std::ends; +#endif + + std::string s = out.str(); + + return s; +} + + +RealTime +RealTime::operator/(int d) const +{ + int secdiv = sec / d; + int secrem = sec % d; + + double nsecdiv = (double(nsec) + ONE_BILLION * double(secrem)) / d; + + return RealTime(secdiv, int(nsecdiv + 0.5)); +} + +double +RealTime::operator/(const RealTime &r) const +{ + double lTotal = double(sec) * ONE_BILLION + double(nsec); + double rTotal = double(r.sec) * ONE_BILLION + double(r.nsec); + + if (rTotal == 0) return 0.0; + else return lTotal/rTotal; +} + +long +RealTime::realTime2Frame(const RealTime &time, unsigned int sampleRate) +{ + if (time < zeroTime) return -realTime2Frame(-time, sampleRate); + + // We like integers. The last term is always zero unless the + // sample rate is greater than 1MHz, but hell, you never know... + + long frame = + time.sec * sampleRate + + (time.msec() * sampleRate) / 1000 + + ((time.usec() - 1000 * time.msec()) * sampleRate) / 1000000 + + ((time.nsec - 1000 * time.usec()) * sampleRate) / 1000000000; + + return frame; +} + +RealTime +RealTime::frame2RealTime(long frame, unsigned int sampleRate) +{ + if (frame < 0) return -frame2RealTime(-frame, sampleRate); + + RealTime rt; + rt.sec = frame / long(sampleRate); + frame -= rt.sec * long(sampleRate); + rt.nsec = (int)(((float(frame) * 1000000) / long(sampleRate)) * 1000); + return rt; +} + +const RealTime RealTime::zeroTime(0,0); + +} diff --git a/libs/vamp-sdk/vamp-sdk/RealTime.h b/libs/vamp-sdk/vamp-sdk/RealTime.h new file mode 100644 index 0000000000..4dd78fd209 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/RealTime.h @@ -0,0 +1,154 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2006 Chris Cannam. + Relicensed by the author as detailed above. +*/ + +#ifndef _VAMP_REAL_TIME_H_ +#define _VAMP_REAL_TIME_H_ + +#include <iostream> +#include <string> + +#ifndef _WIN32 +struct timeval; +#endif + +namespace Vamp { + +/** + * \class RealTime RealTime.h <vamp-sdk/RealTime.h> + * + * RealTime represents time values to nanosecond precision + * with accurate arithmetic and frame-rate conversion functions. + */ + +struct RealTime +{ + int sec; + int nsec; + + int usec() const { return nsec / 1000; } + int msec() const { return nsec / 1000000; } + + RealTime(): sec(0), nsec(0) {} + RealTime(int s, int n); + + RealTime(const RealTime &r) : + sec(r.sec), nsec(r.nsec) { } + + static RealTime fromSeconds(double sec); + static RealTime fromMilliseconds(int msec); + +#ifndef _WIN32 + static RealTime fromTimeval(const struct timeval &); +#endif + + RealTime &operator=(const RealTime &r) { + sec = r.sec; nsec = r.nsec; return *this; + } + + RealTime operator+(const RealTime &r) const { + return RealTime(sec + r.sec, nsec + r.nsec); + } + RealTime operator-(const RealTime &r) const { + return RealTime(sec - r.sec, nsec - r.nsec); + } + RealTime operator-() const { + return RealTime(-sec, -nsec); + } + + bool operator <(const RealTime &r) const { + if (sec == r.sec) return nsec < r.nsec; + else return sec < r.sec; + } + + bool operator >(const RealTime &r) const { + if (sec == r.sec) return nsec > r.nsec; + else return sec > r.sec; + } + + bool operator==(const RealTime &r) const { + return (sec == r.sec && nsec == r.nsec); + } + + bool operator!=(const RealTime &r) const { + return !(r == *this); + } + + bool operator>=(const RealTime &r) const { + if (sec == r.sec) return nsec >= r.nsec; + else return sec >= r.sec; + } + + bool operator<=(const RealTime &r) const { + if (sec == r.sec) return nsec <= r.nsec; + else return sec <= r.sec; + } + + RealTime operator/(int d) const; + + // Find the fractional difference between times + // + double operator/(const RealTime &r) const; + + // Return a human-readable debug-type string to full precision + // (probably not a format to show to a user directly) + // + std::string toString() const; + + // Return a user-readable string to the nearest millisecond + // in a form like HH:MM:SS.mmm + // + std::string toText(bool fixedDp = false) const; + + // Convenience functions for handling sample frames + // + static long realTime2Frame(const RealTime &r, unsigned int sampleRate); + static RealTime frame2RealTime(long frame, unsigned int sampleRate); + + static const RealTime zeroTime; +}; + +std::ostream &operator<<(std::ostream &out, const RealTime &rt); + +} + +#endif diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp new file mode 100644 index 0000000000..3ce51cedd2 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp @@ -0,0 +1,228 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginChannelAdapter.h" + +namespace Vamp { + +namespace HostExt { + +class PluginChannelAdapter::Impl +{ +public: + Impl(Plugin *plugin); + ~Impl(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + +protected: + Plugin *m_plugin; + size_t m_blockSize; + size_t m_inputChannels; + size_t m_pluginChannels; + float **m_buffer; + const float **m_forwardPtrs; +}; + +PluginChannelAdapter::PluginChannelAdapter(Plugin *plugin) : + PluginWrapper(plugin) +{ + m_impl = new Impl(plugin); +} + +PluginChannelAdapter::~PluginChannelAdapter() +{ + delete m_impl; +} + +bool +PluginChannelAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + return m_impl->initialise(channels, stepSize, blockSize); +} + +PluginChannelAdapter::FeatureSet +PluginChannelAdapter::process(const float *const *inputBuffers, + RealTime timestamp) +{ + return m_impl->process(inputBuffers, timestamp); +} + +PluginChannelAdapter::Impl::Impl(Plugin *plugin) : + m_plugin(plugin), + m_blockSize(0), + m_inputChannels(0), + m_pluginChannels(0), + m_buffer(0), + m_forwardPtrs(0) +{ +} + +PluginChannelAdapter::Impl::~Impl() +{ + // the adapter will delete the plugin + + if (m_buffer) { + if (m_inputChannels > m_pluginChannels) { + delete[] m_buffer[0]; + } else { + for (size_t i = 0; i < m_pluginChannels - m_inputChannels; ++i) { + delete[] m_buffer[i]; + } + } + delete[] m_buffer; + m_buffer = 0; + } + + if (m_forwardPtrs) { + delete[] m_forwardPtrs; + m_forwardPtrs = 0; + } +} + +bool +PluginChannelAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + m_blockSize = blockSize; + + size_t minch = m_plugin->getMinChannelCount(); + size_t maxch = m_plugin->getMaxChannelCount(); + + m_inputChannels = channels; + + if (m_inputChannels < minch) { + + m_forwardPtrs = new const float *[minch]; + + if (m_inputChannels > 1) { + // We need a set of zero-valued buffers to add to the + // forwarded pointers + m_buffer = new float*[minch - channels]; + for (size_t i = 0; i < minch; ++i) { + m_buffer[i] = new float[blockSize]; + for (size_t j = 0; j < blockSize; ++j) { + m_buffer[i][j] = 0.f; + } + } + } + + m_pluginChannels = minch; + + std::cerr << "PluginChannelAdapter::initialise: expanding " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl; + + } else if (m_inputChannels > maxch) { + + // We only need m_buffer if we are mixing down to a single + // channel -- otherwise we can just forward the same float* as + // passed in to process(), expecting the excess to be ignored + + if (maxch == 1) { + m_buffer = new float *[1]; + m_buffer[0] = new float[blockSize]; + + std::cerr << "PluginChannelAdapter::initialise: mixing " << m_inputChannels << " to mono for plugin" << std::endl; + + } else { + + std::cerr << "PluginChannelAdapter::initialise: reducing " << m_inputChannels << " to " << m_pluginChannels << " for plugin" << std::endl; + } + + m_pluginChannels = maxch; + + } else { + + std::cerr << "PluginChannelAdapter::initialise: accepting given number of channels (" << m_inputChannels << ")" << std::endl; + m_pluginChannels = m_inputChannels; + } + + return m_plugin->initialise(m_pluginChannels, stepSize, blockSize); +} + +PluginChannelAdapter::FeatureSet +PluginChannelAdapter::Impl::process(const float *const *inputBuffers, + RealTime timestamp) +{ +// std::cerr << "PluginChannelAdapter::process: " << m_inputChannels << " -> " << m_pluginChannels << " channels" << std::endl; + + if (m_inputChannels < m_pluginChannels) { + + if (m_inputChannels == 1) { + for (size_t i = 0; i < m_pluginChannels; ++i) { + m_forwardPtrs[i] = inputBuffers[0]; + } + } else { + for (size_t i = 0; i < m_inputChannels; ++i) { + m_forwardPtrs[i] = inputBuffers[i]; + } + for (size_t i = m_inputChannels; i < m_pluginChannels; ++i) { + m_forwardPtrs[i] = m_buffer[i - m_inputChannels]; + } + } + + return m_plugin->process(m_forwardPtrs, timestamp); + + } else if (m_inputChannels > m_pluginChannels) { + + if (m_pluginChannels == 1) { + for (size_t j = 0; j < m_blockSize; ++j) { + m_buffer[0][j] = inputBuffers[0][j]; + } + for (size_t i = 1; i < m_inputChannels; ++i) { + for (size_t j = 0; j < m_blockSize; ++j) { + m_buffer[0][j] += inputBuffers[i][j]; + } + } + for (size_t j = 0; j < m_blockSize; ++j) { + m_buffer[0][j] /= m_inputChannels; + } + return m_plugin->process(m_buffer, timestamp); + } else { + return m_plugin->process(inputBuffers, timestamp); + } + + } else { + + return m_plugin->process(inputBuffers, timestamp); + } +} + +} + +} + + diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h b/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h new file mode 100644 index 0000000000..a2b4d89aee --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h @@ -0,0 +1,128 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_CHANNEL_ADAPTER_H_ +#define _VAMP_PLUGIN_CHANNEL_ADAPTER_H_ + +#include "PluginWrapper.h" + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginChannelAdapter PluginChannelAdapter.h <vamp-sdk/hostext/PluginChannelAdapter.h> + * + * PluginChannelAdapter is a Vamp plugin adapter that implements a + * policy for management of plugins that expect a different number of + * input channels from the number actually available in the source + * audio data. + * + * A host using PluginChannelAdapter may ignore the getMinChannelCount + * and getMaxChannelCount reported by the plugin, and still expect the + * plugin to run. + * + * PluginChannelAdapter implements the following policy: + * + * - If the plugin supports the provided number of channels directly, + * PluginChannelAdapter will just run the plugin as normal. + * + * - If the plugin only supports exactly one channel but more than + * one channel is provided, PluginChannelAdapter will use the mean of + * the channels. This ensures that the resulting values remain + * within the same magnitude range as expected for mono data. + * + * - If the plugin requires more than one channel but exactly one is + * provided, the provided channel will be duplicated across all the + * plugin input channels. + * + * If none of the above apply: + * + * - If the plugin requires more channels than are provided, the + * minimum acceptable number of channels will be produced by adding + * empty (zero valued) channels to those provided. + * + * - If the plugin requires fewer channels than are provided, the + * maximum acceptable number of channels will be produced by + * discarding the excess channels. + * + * Hosts requiring a different channel policy from the above will need + * to implement it themselves, instead of using PluginChannelAdapter. + * + * Note that PluginChannelAdapter does not override the minimum and + * maximum channel counts returned by the wrapped plugin. The host + * will need to be aware that it is using a PluginChannelAdapter, and + * be prepared to ignore these counts as necessary. (This contrasts + * with the approach used in PluginInputDomainAdapter, which aims to + * make the host completely unaware of which underlying input domain + * is in fact in use.) + * + * (The rationale for this is that a host may wish to use the + * PluginChannelAdapter but still discriminate in some way on the + * basis of the number of channels actually supported. For example, a + * simple stereo audio host may prefer to reject plugins that require + * more than two channels on the grounds that doesn't actually + * understand what they are for, rather than allow the channel adapter + * to make a potentially meaningless channel conversion for them.) + * + * In every respect other than its management of channels, the + * PluginChannelAdapter behaves identically to the plugin that it + * wraps. The wrapped plugin will be deleted when the wrapper is + * deleted. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginChannelAdapter : public PluginWrapper +{ +public: + PluginChannelAdapter(Plugin *plugin); // I take ownership of plugin + virtual ~PluginChannelAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +#endif diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp new file mode 100644 index 0000000000..3fc0d74720 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp @@ -0,0 +1,458 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginInputDomainAdapter.h" + +#include <cmath> + +namespace Vamp { + +namespace HostExt { + +class PluginInputDomainAdapter::Impl +{ +public: + Impl(Plugin *plugin, float inputSampleRate); + ~Impl(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + +protected: + Plugin *m_plugin; + float m_inputSampleRate; + size_t m_channels; + size_t m_blockSize; + float **m_freqbuf; + double *m_ri; + double *m_ro; + double *m_io; + + void fft(unsigned int n, bool inverse, + double *ri, double *ii, double *ro, double *io); + + size_t makeBlockSizeAcceptable(size_t) const; +}; + +PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : + PluginWrapper(plugin) +{ + m_impl = new Impl(plugin, m_inputSampleRate); +} + +PluginInputDomainAdapter::~PluginInputDomainAdapter() +{ + delete m_impl; +} + +bool +PluginInputDomainAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + return m_impl->initialise(channels, stepSize, blockSize); +} + +Plugin::InputDomain +PluginInputDomainAdapter::getInputDomain() const +{ + return TimeDomain; +} + +size_t +PluginInputDomainAdapter::getPreferredStepSize() const +{ + return m_impl->getPreferredStepSize(); +} + +size_t +PluginInputDomainAdapter::getPreferredBlockSize() const +{ + return m_impl->getPreferredBlockSize(); +} + +Plugin::FeatureSet +PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime timestamp) +{ + return m_impl->process(inputBuffers, timestamp); +} + + PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : + m_plugin(plugin), + m_inputSampleRate(inputSampleRate), + m_channels(0), + m_blockSize(0), + m_freqbuf(0) +{ +} + +PluginInputDomainAdapter::Impl::~Impl() +{ + // the adapter will delete the plugin + + if (m_channels > 0) { + for (size_t c = 0; c < m_channels; ++c) { + delete[] m_freqbuf[c]; + } + delete[] m_freqbuf; + delete[] m_ri; + delete[] m_ro; + delete[] m_io; + } +} + +bool +PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + if (m_plugin->getInputDomain() == TimeDomain) { + + m_blockSize = blockSize; + m_channels = channels; + + return m_plugin->initialise(channels, stepSize, blockSize); + } + + if (blockSize < 2) { + std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not supported" << std::endl; + return false; + } + + if (blockSize & (blockSize-1)) { + std::cerr << "ERROR: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported" << std::endl; + return false; + } + + if (m_channels > 0) { + for (size_t c = 0; c < m_channels; ++c) { + delete[] m_freqbuf[c]; + } + delete[] m_freqbuf; + delete[] m_ri; + delete[] m_ro; + delete[] m_io; + } + + m_blockSize = blockSize; + m_channels = channels; + + m_freqbuf = new float *[m_channels]; + for (size_t c = 0; c < m_channels; ++c) { + m_freqbuf[c] = new float[m_blockSize + 2]; + } + m_ri = new double[m_blockSize]; + m_ro = new double[m_blockSize]; + m_io = new double[m_blockSize]; + + return m_plugin->initialise(channels, stepSize, blockSize); +} + +size_t +PluginInputDomainAdapter::Impl::getPreferredStepSize() const +{ + size_t step = m_plugin->getPreferredStepSize(); + + if (step == 0 && (m_plugin->getInputDomain() == FrequencyDomain)) { + step = getPreferredBlockSize() / 2; + } + + return step; +} + +size_t +PluginInputDomainAdapter::Impl::getPreferredBlockSize() const +{ + size_t block = m_plugin->getPreferredBlockSize(); + + if (m_plugin->getInputDomain() == FrequencyDomain) { + if (block == 0) { + block = 1024; + } else { + block = makeBlockSizeAcceptable(block); + } + } + + return block; +} + +size_t +PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const +{ + if (blockSize < 2) { + + std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: blocksize < 2 not" << std::endl + << "supported, increasing from " << blockSize << " to 2" << std::endl; + blockSize = 2; + + } else if (blockSize & (blockSize-1)) { + + // not a power of two, can't handle that with our current fft + // implementation + + size_t nearest = blockSize; + size_t power = 0; + while (nearest > 1) { + nearest >>= 1; + ++power; + } + nearest = 1; + while (power) { + nearest <<= 1; + --power; + } + + if (blockSize - nearest > (nearest*2) - blockSize) { + nearest = nearest*2; + } + + std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl; + blockSize = nearest; + } + + return blockSize; +} + +// for some visual studii apparently +#ifndef M_PI +#define M_PI 3.14159265358979232846 +#endif + +Plugin::FeatureSet +PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers, + RealTime timestamp) +{ + if (m_plugin->getInputDomain() == TimeDomain) { + return m_plugin->process(inputBuffers, timestamp); + } + + // The timestamp supplied should be (according to the Vamp::Plugin + // spec) the time of the start of the time-domain input block. + // However, we want to pass to the plugin an FFT output calculated + // from the block of samples _centred_ on that timestamp. + // + // We have two options: + // + // 1. Buffer the input, calculating the fft of the values at the + // passed-in block minus blockSize/2 rather than starting at the + // passed-in block. So each time we call process on the plugin, + // we are passing in the same timestamp as was passed to our own + // process plugin, but not (the frequency domain representation + // of) the same set of samples. Advantages: avoids confusion in + // the host by ensuring the returned values have timestamps + // comparable with that passed in to this function (in fact this + // is pretty much essential for one-value-per-block outputs); + // consistent with hosts such as SV that deal with the + // frequency-domain transform themselves. Disadvantages: means + // making the not necessarily correct assumption that the samples + // preceding the first official block are all zero (or some other + // known value). + // + // 2. Increase the passed-in timestamps by half the blocksize. So + // when we call process, we are passing in the frequency domain + // representation of the same set of samples as passed to us, but + // with a different timestamp. Advantages: simplicity; avoids + // iffy assumption mentioned above. Disadvantages: inconsistency + // with SV in cases where stepSize != blockSize/2; potential + // confusion arising from returned timestamps being calculated + // from the adjusted input timestamps rather than the original + // ones (and inaccuracy where the returned timestamp is implied, + // as in one-value-per-block). + // + // Neither way is ideal, but I don't think either is strictly + // incorrect either. I think this is just a case where the same + // plugin can legitimately produce differing results from the same + // input data, depending on how that data is packaged. + // + // We'll go for option 2, adjusting the timestamps. Note in + // particular that this means some results can differ from those + // produced by SV. + +// std::cerr << "PluginInputDomainAdapter: sampleRate " << m_inputSampleRate << ", blocksize " << m_blockSize << ", adjusting time from " << timestamp; + + timestamp = timestamp + RealTime::frame2RealTime + (m_blockSize/2, int(m_inputSampleRate + 0.5)); + +// std::cerr << " to " << timestamp << std::endl; + + for (size_t c = 0; c < m_channels; ++c) { + + for (size_t i = 0; i < m_blockSize; ++i) { + // Hanning window + m_ri[i] = double(inputBuffers[c][i]) + * (0.50 - 0.50 * cos((2 * M_PI * i) + / m_blockSize)); + } + + for (size_t i = 0; i < m_blockSize/2; ++i) { + // FFT shift + double value = m_ri[i]; + m_ri[i] = m_ri[i + m_blockSize/2]; + m_ri[i + m_blockSize/2] = value; + } + + fft(m_blockSize, false, m_ri, 0, m_ro, m_io); + + for (size_t i = 0; i <= m_blockSize/2; ++i) { + m_freqbuf[c][i * 2] = m_ro[i]; + m_freqbuf[c][i * 2 + 1] = m_io[i]; + } + } + + return m_plugin->process(m_freqbuf, timestamp); +} + +void +PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse, + double *ri, double *ii, double *ro, double *io) +{ + if (!ri || !ro || !io) return; + + unsigned int bits; + unsigned int i, j, k, m; + unsigned int blockSize, blockEnd; + + double tr, ti; + + if (n < 2) return; + if (n & (n-1)) return; + + double angle = 2.0 * M_PI; + if (inverse) angle = -angle; + + for (i = 0; ; ++i) { + if (n & (1 << i)) { + bits = i; + break; + } + } + + static unsigned int tableSize = 0; + static int *table = 0; + + if (tableSize != n) { + + delete[] table; + + table = new int[n]; + + for (i = 0; i < n; ++i) { + + m = i; + + for (j = k = 0; j < bits; ++j) { + k = (k << 1) | (m & 1); + m >>= 1; + } + + table[i] = k; + } + + tableSize = n; + } + + if (ii) { + for (i = 0; i < n; ++i) { + ro[table[i]] = ri[i]; + io[table[i]] = ii[i]; + } + } else { + for (i = 0; i < n; ++i) { + ro[table[i]] = ri[i]; + io[table[i]] = 0.0; + } + } + + blockEnd = 1; + + for (blockSize = 2; blockSize <= n; blockSize <<= 1) { + + double delta = angle / (double)blockSize; + double sm2 = -sin(-2 * delta); + double sm1 = -sin(-delta); + double cm2 = cos(-2 * delta); + double cm1 = cos(-delta); + double w = 2 * cm1; + double ar[3], ai[3]; + + for (i = 0; i < n; i += blockSize) { + + ar[2] = cm2; + ar[1] = cm1; + + ai[2] = sm2; + ai[1] = sm1; + + for (j = i, m = 0; m < blockEnd; j++, m++) { + + ar[0] = w * ar[1] - ar[2]; + ar[2] = ar[1]; + ar[1] = ar[0]; + + ai[0] = w * ai[1] - ai[2]; + ai[2] = ai[1]; + ai[1] = ai[0]; + + k = j + blockEnd; + tr = ar[0] * ro[k] - ai[0] * io[k]; + ti = ar[0] * io[k] + ai[0] * ro[k]; + + ro[k] = ro[j] - tr; + io[k] = io[j] - ti; + + ro[j] += tr; + io[j] += ti; + } + } + + blockEnd = blockSize; + } + + if (inverse) { + + double denom = (double)n; + + for (i = 0; i < n; i++) { + ro[i] /= denom; + io[i] /= denom; + } + } +} + +} + +} + diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h new file mode 100644 index 0000000000..73da053149 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h @@ -0,0 +1,103 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_ +#define _VAMP_PLUGIN_INPUT_DOMAIN_ADAPTER_H_ + +#include "PluginWrapper.h" + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginInputDomainAdapter PluginInputDomainAdapter.h <vamp-sdk/hostext/PluginInputDomainAdapter.h> + * + * PluginInputDomainAdapter is a Vamp plugin adapter that converts + * time-domain input into frequency-domain input for plugins that need + * it. This permits a host to use time- and frequency-domain plugins + * interchangeably without needing to handle the conversion itself. + * + * This adapter uses a basic Hanning windowed FFT that supports + * power-of-two block sizes only. If a frequency domain plugin + * requests a non-power-of-two blocksize, the adapter will adjust it + * to a nearby power of two instead. Thus, getPreferredBlockSize() + * will always return a power of two if the wrapped plugin is a + * frequency domain one. If the plugin doesn't accept the adjusted + * power of two block size, initialise() will fail. + * + * The adapter provides no way for the host to discover whether the + * underlying plugin is actually a time or frequency domain plugin + * (except that if the preferred block size is not a power of two, it + * must be a time domain plugin). + * + * The FFT implementation is simple and self-contained, but unlikely + * to be the fastest available: a host can usually do better if it + * cares enough. + * + * In every respect other than its input domain handling, the + * PluginInputDomainAdapter behaves identically to the plugin that it + * wraps. The wrapped plugin will be deleted when the wrapper is + * deleted. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginInputDomainAdapter : public PluginWrapper +{ +public: + PluginInputDomainAdapter(Plugin *plugin); // I take ownership of plugin + virtual ~PluginInputDomainAdapter(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + + InputDomain getInputDomain() const; + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + +protected: + class Impl; + Impl *m_impl; +}; + +} + +} + +#endif diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp new file mode 100644 index 0000000000..cb71fc4750 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp @@ -0,0 +1,601 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "vamp-sdk/PluginHostAdapter.h" +#include "PluginLoader.h" +#include "PluginInputDomainAdapter.h" +#include "PluginChannelAdapter.h" + +#include <fstream> +#include <cctype> // tolower + +#ifdef _WIN32 + +#include <windows.h> +#include <tchar.h> +#define PLUGIN_SUFFIX "dll" + +#else /* ! _WIN32 */ + +#include <dirent.h> +#include <dlfcn.h> + +#ifdef __APPLE__ +#define PLUGIN_SUFFIX "dylib" +#else /* ! __APPLE__ */ +#define PLUGIN_SUFFIX "so" +#endif /* ! __APPLE__ */ + +#endif /* ! _WIN32 */ + +using namespace std; + +namespace Vamp { + +namespace HostExt { + +class PluginLoader::Impl +{ +public: + Impl(); + virtual ~Impl(); + + PluginKeyList listPlugins(); + + Plugin *loadPlugin(PluginKey key, + float inputSampleRate, + int adapterFlags); + + PluginKey composePluginKey(string libraryName, string identifier); + + PluginCategoryHierarchy getPluginCategory(PluginKey key); + + string getLibraryPathForPlugin(PluginKey key); + +protected: + class PluginDeletionNotifyAdapter : public PluginWrapper { + public: + PluginDeletionNotifyAdapter(Plugin *plugin, Impl *loader); + virtual ~PluginDeletionNotifyAdapter(); + protected: + Impl *m_loader; + }; + + virtual void pluginDeleted(PluginDeletionNotifyAdapter *adapter); + + map<PluginKey, string> m_pluginLibraryNameMap; + bool m_allPluginsEnumerated; + void enumeratePlugins(PluginKey forPlugin = ""); + + map<PluginKey, PluginCategoryHierarchy> m_taxonomy; + void generateTaxonomy(); + + map<Plugin *, void *> m_pluginLibraryHandleMap; + + bool decomposePluginKey(PluginKey key, + string &libraryName, string &identifier); + + void *loadLibrary(string path); + void unloadLibrary(void *handle); + void *lookupInLibrary(void *handle, const char *symbol); + + string splicePath(string a, string b); + vector<string> listFiles(string dir, string ext); +}; + +PluginLoader * +PluginLoader::m_instance = 0; + +PluginLoader::PluginLoader() +{ + m_impl = new Impl(); +} + +PluginLoader::~PluginLoader() +{ + delete m_impl; +} + +PluginLoader * +PluginLoader::getInstance() +{ + if (!m_instance) m_instance = new PluginLoader(); + return m_instance; +} + +vector<PluginLoader::PluginKey> +PluginLoader::listPlugins() +{ + return m_impl->listPlugins(); +} + +Plugin * +PluginLoader::loadPlugin(PluginKey key, + float inputSampleRate, + int adapterFlags) +{ + return m_impl->loadPlugin(key, inputSampleRate, adapterFlags); +} + +PluginLoader::PluginKey +PluginLoader::composePluginKey(string libraryName, string identifier) +{ + return m_impl->composePluginKey(libraryName, identifier); +} + +PluginLoader::PluginCategoryHierarchy +PluginLoader::getPluginCategory(PluginKey key) +{ + return m_impl->getPluginCategory(key); +} + +string +PluginLoader::getLibraryPathForPlugin(PluginKey key) +{ + return m_impl->getLibraryPathForPlugin(key); +} + +PluginLoader::Impl::Impl() : + m_allPluginsEnumerated(false) +{ +} + +PluginLoader::Impl::~Impl() +{ +} + +vector<PluginLoader::PluginKey> +PluginLoader::Impl::listPlugins() +{ + if (!m_allPluginsEnumerated) enumeratePlugins(); + + vector<PluginKey> plugins; + for (map<PluginKey, string>::iterator mi = m_pluginLibraryNameMap.begin(); + mi != m_pluginLibraryNameMap.end(); ++mi) { + plugins.push_back(mi->first); + } + + return plugins; +} + +void +PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin) +{ + vector<string> path = PluginHostAdapter::getPluginPath(); + + string libraryName, identifier; + if (forPlugin != "") { + if (!decomposePluginKey(forPlugin, libraryName, identifier)) { + std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \"" + << forPlugin << "\" in enumerate" << std::endl; + return; + } + } + + for (size_t i = 0; i < path.size(); ++i) { + + vector<string> files = listFiles(path[i], PLUGIN_SUFFIX); + + for (vector<string>::iterator fi = files.begin(); + fi != files.end(); ++fi) { + + if (libraryName != "") { + // libraryName is lowercased and lacking an extension, + // as it came from the plugin key + string temp = *fi; + for (size_t i = 0; i < temp.length(); ++i) { + temp[i] = tolower(temp[i]); + } + string::size_type pi = temp.find('.'); + if (pi == string::npos) { + if (libraryName != temp) continue; + } else { + if (libraryName != temp.substr(0, pi)) continue; + } + } + + string fullPath = path[i]; + fullPath = splicePath(fullPath, *fi); + void *handle = loadLibrary(fullPath); + if (!handle) continue; + + VampGetPluginDescriptorFunction fn = + (VampGetPluginDescriptorFunction)lookupInLibrary + (handle, "vampGetPluginDescriptor"); + + if (!fn) { + unloadLibrary(handle); + continue; + } + + int index = 0; + const VampPluginDescriptor *descriptor = 0; + + while ((descriptor = fn(VAMP_API_VERSION, index))) { + ++index; + if (identifier != "") { + if (descriptor->identifier != identifier) continue; + } + PluginKey key = composePluginKey(*fi, descriptor->identifier); +// std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl; + if (m_pluginLibraryNameMap.find(key) == + m_pluginLibraryNameMap.end()) { + m_pluginLibraryNameMap[key] = fullPath; + } + } + + unloadLibrary(handle); + } + } + + if (forPlugin == "") m_allPluginsEnumerated = true; +} + +PluginLoader::PluginKey +PluginLoader::Impl::composePluginKey(string libraryName, string identifier) +{ + string basename = libraryName; + + string::size_type li = basename.rfind('/'); + if (li != string::npos) basename = basename.substr(li + 1); + + li = basename.find('.'); + if (li != string::npos) basename = basename.substr(0, li); + + for (size_t i = 0; i < basename.length(); ++i) { + basename[i] = tolower(basename[i]); + } + + return basename + ":" + identifier; +} + +bool +PluginLoader::Impl::decomposePluginKey(PluginKey key, + string &libraryName, + string &identifier) +{ + string::size_type ki = key.find(':'); + if (ki == string::npos) { + return false; + } + + libraryName = key.substr(0, ki); + identifier = key.substr(ki + 1); + return true; +} + +PluginLoader::PluginCategoryHierarchy +PluginLoader::Impl::getPluginCategory(PluginKey plugin) +{ + if (m_taxonomy.empty()) generateTaxonomy(); + if (m_taxonomy.find(plugin) == m_taxonomy.end()) { + return PluginCategoryHierarchy(); + } + return m_taxonomy[plugin]; +} + +string +PluginLoader::Impl::getLibraryPathForPlugin(PluginKey plugin) +{ + if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { + if (m_allPluginsEnumerated) return ""; + enumeratePlugins(plugin); + } + if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { + return ""; + } + return m_pluginLibraryNameMap[plugin]; +} + +Plugin * +PluginLoader::Impl::loadPlugin(PluginKey key, + float inputSampleRate, int adapterFlags) +{ + string libname, identifier; + if (!decomposePluginKey(key, libname, identifier)) { + std::cerr << "Vamp::HostExt::PluginLoader: Invalid plugin key \"" + << key << "\" in loadPlugin" << std::endl; + return 0; + } + + string fullPath = getLibraryPathForPlugin(key); + if (fullPath == "") return 0; + + void *handle = loadLibrary(fullPath); + if (!handle) return 0; + + VampGetPluginDescriptorFunction fn = + (VampGetPluginDescriptorFunction)lookupInLibrary + (handle, "vampGetPluginDescriptor"); + + if (!fn) { + unloadLibrary(handle); + return 0; + } + + int index = 0; + const VampPluginDescriptor *descriptor = 0; + + while ((descriptor = fn(VAMP_API_VERSION, index))) { + + if (string(descriptor->identifier) == identifier) { + + Vamp::PluginHostAdapter *plugin = + new Vamp::PluginHostAdapter(descriptor, inputSampleRate); + + Plugin *adapter = new PluginDeletionNotifyAdapter(plugin, this); + + m_pluginLibraryHandleMap[adapter] = handle; + + if (adapterFlags & ADAPT_INPUT_DOMAIN) { + if (adapter->getInputDomain() == Plugin::FrequencyDomain) { + adapter = new PluginInputDomainAdapter(adapter); + } + } + + if (adapterFlags & ADAPT_CHANNEL_COUNT) { + adapter = new PluginChannelAdapter(adapter); + } + + return adapter; + } + + ++index; + } + + cerr << "Vamp::HostExt::PluginLoader: Plugin \"" + << identifier << "\" not found in library \"" + << fullPath << "\"" << endl; + + return 0; +} + +void +PluginLoader::Impl::generateTaxonomy() +{ +// cerr << "PluginLoader::Impl::generateTaxonomy" << endl; + + vector<string> path = PluginHostAdapter::getPluginPath(); + string libfragment = "/lib/"; + vector<string> catpath; + + string suffix = "cat"; + + for (vector<string>::iterator i = path.begin(); + i != path.end(); ++i) { + + // It doesn't matter that we're using literal forward-slash in + // this bit, as it's only relevant if the path contains + // "/lib/", which is only meaningful and only plausible on + // systems with forward-slash delimiters + + string dir = *i; + string::size_type li = dir.find(libfragment); + + if (li != string::npos) { + catpath.push_back + (dir.substr(0, li) + + "/share/" + + dir.substr(li + libfragment.length())); + } + + catpath.push_back(dir); + } + + char buffer[1024]; + + for (vector<string>::iterator i = catpath.begin(); + i != catpath.end(); ++i) { + + vector<string> files = listFiles(*i, suffix); + + for (vector<string>::iterator fi = files.begin(); + fi != files.end(); ++fi) { + + string filepath = splicePath(*i, *fi); + ifstream is(filepath.c_str(), ifstream::in | ifstream::binary); + + if (is.fail()) { +// cerr << "failed to open: " << filepath << endl; + continue; + } + +// cerr << "opened: " << filepath << endl; + + while (!!is.getline(buffer, 1024)) { + + string line(buffer); + +// cerr << "line = " << line << endl; + + string::size_type di = line.find("::"); + if (di == string::npos) continue; + + string id = line.substr(0, di); + string encodedCat = line.substr(di + 2); + + if (id.substr(0, 5) != "vamp:") continue; + id = id.substr(5); + + while (encodedCat.length() >= 1 && + encodedCat[encodedCat.length()-1] == '\r') { + encodedCat = encodedCat.substr(0, encodedCat.length()-1); + } + +// cerr << "id = " << id << ", cat = " << encodedCat << endl; + + PluginCategoryHierarchy category; + string::size_type ai; + while ((ai = encodedCat.find(" > ")) != string::npos) { + category.push_back(encodedCat.substr(0, ai)); + encodedCat = encodedCat.substr(ai + 3); + } + if (encodedCat != "") category.push_back(encodedCat); + + m_taxonomy[id] = category; + } + } + } +} + +void * +PluginLoader::Impl::loadLibrary(string path) +{ + void *handle = 0; +#ifdef _WIN32 + handle = LoadLibrary(path.c_str()); + if (!handle) { + cerr << "Vamp::HostExt::PluginLoader: Unable to load library \"" + << path << "\"" << endl; + } +#else + handle = dlopen(path.c_str(), RTLD_LAZY); + if (!handle) { + cerr << "Vamp::HostExt::PluginLoader: Unable to load library \"" + << path << "\": " << dlerror() << endl; + } +#endif + return handle; +} + +void +PluginLoader::Impl::unloadLibrary(void *handle) +{ +#ifdef _WIN32 + FreeLibrary((HINSTANCE)handle); +#else + dlclose(handle); +#endif +} + +void * +PluginLoader::Impl::lookupInLibrary(void *handle, const char *symbol) +{ +#ifdef _WIN32 + return (void *)GetProcAddress((HINSTANCE)handle, symbol); +#else + return (void *)dlsym(handle, symbol); +#endif +} + +string +PluginLoader::Impl::splicePath(string a, string b) +{ +#ifdef _WIN32 + return a + "\\" + b; +#else + return a + "/" + b; +#endif +} + +vector<string> +PluginLoader::Impl::listFiles(string dir, string extension) +{ + vector<string> files; + +#ifdef _WIN32 + + string expression = dir + "\\*." + extension; + WIN32_FIND_DATA data; + HANDLE fh = FindFirstFile(expression.c_str(), &data); + if (fh == INVALID_HANDLE_VALUE) return files; + + bool ok = true; + while (ok) { + files.push_back(data.cFileName); + ok = FindNextFile(fh, &data); + } + + FindClose(fh); + +#else + + size_t extlen = extension.length(); + DIR *d = opendir(dir.c_str()); + if (!d) return files; + + struct dirent *e = 0; + while ((e = readdir(d))) { + + if (!(e->d_type & DT_REG) || !e->d_name) continue; + + size_t len = strlen(e->d_name); + if (len < extlen + 2 || + e->d_name + len - extlen - 1 != "." + extension) { + continue; + } + + files.push_back(e->d_name); + } + + closedir(d); +#endif + + return files; +} + +void +PluginLoader::Impl::pluginDeleted(PluginDeletionNotifyAdapter *adapter) +{ + void *handle = m_pluginLibraryHandleMap[adapter]; + if (handle) unloadLibrary(handle); + m_pluginLibraryHandleMap.erase(adapter); +} + +PluginLoader::Impl::PluginDeletionNotifyAdapter::PluginDeletionNotifyAdapter(Plugin *plugin, + Impl *loader) : + PluginWrapper(plugin), + m_loader(loader) +{ +} + +PluginLoader::Impl::PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() +{ + // We need to delete the plugin before calling pluginDeleted, as + // the delete call may require calling through to the descriptor + // (for e.g. cleanup) but pluginDeleted may unload the required + // library for the call. To prevent a double deletion when our + // parent's destructor runs (after this one), be sure to set + // m_plugin to 0 after deletion. + delete m_plugin; + m_plugin = 0; + + if (m_loader) m_loader->pluginDeleted(this); +} + +} + +} diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h new file mode 100644 index 0000000000..82ae22b930 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h @@ -0,0 +1,218 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_LOADER_H_ +#define _VAMP_PLUGIN_LOADER_H_ + +#include <vector> +#include <string> +#include <map> + +#include "PluginWrapper.h" + +namespace Vamp { + +class Plugin; + +namespace HostExt { + +/** + * \class PluginLoader PluginLoader.h <vamp-sdk/hostext/PluginLoader.h> + * + * Vamp::HostExt::PluginLoader is a convenience class for discovering + * and loading Vamp plugins using the typical plugin-path, library + * naming, and categorisation conventions described in the Vamp SDK + * documentation. This class is intended to greatly simplify the task + * of becoming a Vamp plugin host for any C++ application. + * + * Hosts are not required by the Vamp specification to use the same + * plugin search path and naming conventions as implemented by this + * class, and are certainly not required to use this actual class. + * But we do strongly recommend it. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginLoader +{ +public: + /** + * Obtain a pointer to the singleton instance of PluginLoader. + * Use this to obtain your loader object. + */ + static PluginLoader *getInstance(); + + /** + * PluginKey is a string type that is used to identify a plugin + * uniquely within the scope of "the current system". It consists + * of the lower-cased base name of the plugin library, a colon + * separator, and the identifier string for the plugin. It is + * only meaningful in the context of a given plugin path (the one + * returned by PluginHostAdapter::getPluginPath()). + * + * Use composePluginKey() to construct a plugin key from a known + * plugin library name and identifier. + * + * Note: the fact that the library component of the key is + * lower-cased implies that library names are matched + * case-insensitively by the PluginLoader class, regardless of the + * case sensitivity of the underlying filesystem. (Plugin + * identifiers _are_ case sensitive, however.) Also, it is not + * possible to portably extract a working library name from a + * plugin key, as the result may fail on case-sensitive + * filesystems. Use getLibraryPathForPlugin() instead. + */ + typedef std::string PluginKey; + + /** + * PluginKeyList is a sequence of plugin keys, such as returned by + * listPlugins(). + */ + typedef std::vector<PluginKey> PluginKeyList; + + /** + * PluginCategoryHierarchy is a sequence of general->specific + * category names, as may be associated with a single plugin. + * This sequence describes the location of a plugin within a + * category forest, containing the human-readable names of the + * plugin's category tree root, followed by each of the nodes down + * to the leaf containing the plugin. + * + * \see getPluginCategory() + */ + typedef std::vector<std::string> PluginCategoryHierarchy; + + /** + * Search for all available Vamp plugins, and return a list of + * them in the order in which they were found. + */ + PluginKeyList listPlugins(); + + /** + * AdapterFlags contains a set of values that may be OR'd together + * to indicate in which circumstances PluginLoader should use a + * plugin adapter to make a plugin easier to use for a host that + * does not want to cater for complex features. + * + * The available flags are: + * + * ADAPT_INPUT_DOMAIN - If the plugin expects frequency domain + * input, wrap it in a PluginInputDomainAdapter that automatically + * converts the plugin to one that expects time-domain input. + * This enables a host to accommodate time- and frequency-domain + * plugins without needing to do any conversion itself. + * + * ADAPT_CHANNEL_COUNT - Wrap the plugin in a PluginChannelAdapter + * to handle any mismatch between the number of channels of audio + * the plugin can handle and the number available in the host. + * This enables a host to use plugins that may require the input + * to be mixed down to mono, etc., without having to worry about + * doing that itself. + * + * ADAPT_ALL - Perform all available adaptations, where meaningful. + * + * See PluginInputDomainAdapter and PluginChannelAdapter for more + * details of the classes that the loader may use if these flags + * are set. + */ + enum AdapterFlags { + ADAPT_INPUT_DOMAIN = 0x01, + ADAPT_CHANNEL_COUNT = 0x02, + ADAPT_ALL = 0xff + }; + + /** + * Load a Vamp plugin, given its identifying key. If the plugin + * could not be loaded, returns 0. + * + * The returned plugin should be deleted (using the standard C++ + * delete keyword) after use. + * + * \param adapterFlags a bitwise OR of the values in the AdapterFlags + * enumeration, indicating under which circumstances an adapter should be + * used to wrap the original plugin. If adapterFlags is 0, no + * optional adapters will be used. Otherwise, the returned plugin + * may be of an adapter class type which will behave identically + * to the original plugin, apart from any particular features + * implemented by the adapter itself. + * + * \see AdapterFlags, PluginInputDomainAdapter, PluginChannelAdapter + */ + Plugin *loadPlugin(PluginKey key, + float inputSampleRate, + int adapterFlags = 0); + + /** + * Given a Vamp plugin library name and plugin identifier, return + * the corresponding plugin key in a form suitable for passing in to + * loadPlugin(). + */ + PluginKey composePluginKey(std::string libraryName, + std::string identifier); + + /** + * Return the category hierarchy for a Vamp plugin, given its + * identifying key. + * + * If the plugin has no category information, return an empty + * hierarchy. + * + * \see PluginCategoryHierarchy + */ + PluginCategoryHierarchy getPluginCategory(PluginKey plugin); + + /** + * Return the file path of the dynamic library from which the + * given plugin will be loaded (if available). + */ + std::string getLibraryPathForPlugin(PluginKey plugin); + +protected: + PluginLoader(); + virtual ~PluginLoader(); + + class Impl; + Impl *m_impl; + + static PluginLoader *m_instance; +}; + +} + +} + +#endif + diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp b/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp new file mode 100644 index 0000000000..dcbdf5b73a --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp @@ -0,0 +1,201 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "PluginWrapper.h" + +namespace Vamp { + +namespace HostExt { + +class PluginRateExtractor : public Plugin +{ +public: + PluginRateExtractor() : Plugin(0) { } + float getRate() const { return m_inputSampleRate; } +}; + +PluginWrapper::PluginWrapper(Plugin *plugin) : + Plugin(((PluginRateExtractor *)plugin)->getRate()), + m_plugin(plugin) +{ +} + +PluginWrapper::~PluginWrapper() +{ + delete m_plugin; +} + +bool +PluginWrapper::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + return m_plugin->initialise(channels, stepSize, blockSize); +} + +void +PluginWrapper::reset() +{ + m_plugin->reset(); +} + +Plugin::InputDomain +PluginWrapper::getInputDomain() const +{ + return m_plugin->getInputDomain(); +} + +unsigned int +PluginWrapper::getVampApiVersion() const +{ + return m_plugin->getVampApiVersion(); +} + +std::string +PluginWrapper::getIdentifier() const +{ + return m_plugin->getIdentifier(); +} + +std::string +PluginWrapper::getName() const +{ + return m_plugin->getName(); +} + +std::string +PluginWrapper::getDescription() const +{ + return m_plugin->getDescription(); +} + +std::string +PluginWrapper::getMaker() const +{ + return m_plugin->getMaker(); +} + +int +PluginWrapper::getPluginVersion() const +{ + return m_plugin->getPluginVersion(); +} + +std::string +PluginWrapper::getCopyright() const +{ + return m_plugin->getCopyright(); +} + +PluginBase::ParameterList +PluginWrapper::getParameterDescriptors() const +{ + return m_plugin->getParameterDescriptors(); +} + +float +PluginWrapper::getParameter(std::string parameter) const +{ + return m_plugin->getParameter(parameter); +} + +void +PluginWrapper::setParameter(std::string parameter, float value) +{ + m_plugin->setParameter(parameter, value); +} + +PluginBase::ProgramList +PluginWrapper::getPrograms() const +{ + return m_plugin->getPrograms(); +} + +std::string +PluginWrapper::getCurrentProgram() const +{ + return m_plugin->getCurrentProgram(); +} + +void +PluginWrapper::selectProgram(std::string program) +{ + m_plugin->selectProgram(program); +} + +size_t +PluginWrapper::getPreferredStepSize() const +{ + return m_plugin->getPreferredStepSize(); +} + +size_t +PluginWrapper::getPreferredBlockSize() const +{ + return m_plugin->getPreferredBlockSize(); +} + +size_t +PluginWrapper::getMinChannelCount() const +{ + return m_plugin->getMinChannelCount(); +} + +size_t PluginWrapper::getMaxChannelCount() const +{ + return m_plugin->getMaxChannelCount(); +} + +Plugin::OutputList +PluginWrapper::getOutputDescriptors() const +{ + return m_plugin->getOutputDescriptors(); +} + +Plugin::FeatureSet +PluginWrapper::process(const float *const *inputBuffers, RealTime timestamp) +{ + return m_plugin->process(inputBuffers, timestamp); +} + +Plugin::FeatureSet +PluginWrapper::getRemainingFeatures() +{ + return m_plugin->getRemainingFeatures(); +} + +} + +} + diff --git a/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h b/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h new file mode 100644 index 0000000000..d5ec1da0e8 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h @@ -0,0 +1,106 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006-2007 Chris Cannam and QMUL. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _VAMP_PLUGIN_WRAPPER_H_ +#define _VAMP_PLUGIN_WRAPPER_H_ + +#include <vamp-sdk/Plugin.h> + +namespace Vamp { + +namespace HostExt { + +/** + * \class PluginWrapper PluginWrapper.h <vamp-sdk/hostext/PluginWrapper.h> + * + * PluginWrapper is a simple base class for adapter plugins. It takes + * a pointer to a "to be wrapped" Vamp plugin on construction, and + * provides implementations of all the Vamp plugin methods that simply + * delegate through to the wrapped plugin. A subclass can therefore + * override only the methods that are meaningful for the particular + * adapter. + * + * \note This class was introduced in version 1.1 of the Vamp plugin SDK. + */ + +class PluginWrapper : public Plugin +{ +public: + virtual ~PluginWrapper(); + + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + void reset(); + + InputDomain getInputDomain() const; + + unsigned int getVampApiVersion() const; + 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); + + ProgramList getPrograms() const; + std::string getCurrentProgram() const; + void selectProgram(std::string); + + size_t getPreferredStepSize() const; + size_t getPreferredBlockSize() const; + + size_t getMinChannelCount() const; + size_t getMaxChannelCount() const; + + OutputList getOutputDescriptors() const; + + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); + + FeatureSet getRemainingFeatures(); + +protected: + PluginWrapper(Plugin *plugin); // I take ownership of plugin + Plugin *m_plugin; +}; + +} + +} + +#endif diff --git a/libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in b/libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in new file mode 100644 index 0000000000..83362dc39c --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in @@ -0,0 +1,9 @@ +dlname='%LINK_ABI%' +library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%' +old_library='%STATIC%' +dependency_libs='' +current=2 +age=0 +revision=0 +installed=yes +libdir='%LIBS%' diff --git a/libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in b/libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in new file mode 100644 index 0000000000..1674afe3e4 --- /dev/null +++ b/libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in @@ -0,0 +1,9 @@ +dlname='%LINK_ABI%' +library_names='%LIBNAME% %LINK_ABI% %LINK_DEV%' +old_library='%STATIC%' +dependency_libs='' +current=1 +age=1 +revision=0 +installed=yes +libdir='%LIBS%' diff --git a/libs/vamp-sdk/vamp/vamp.h b/libs/vamp-sdk/vamp/vamp.h new file mode 100644 index 0000000000..4f0145ab59 --- /dev/null +++ b/libs/vamp-sdk/vamp/vamp.h @@ -0,0 +1,339 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Vamp + + An API for audio analysis and feature extraction plugins. + + Centre for Digital Music, Queen Mary, University of London. + Copyright 2006 Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef VAMP_HEADER_INCLUDED +#define VAMP_HEADER_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Plugin API version. This is incremented when a change is made that + * changes the binary layout of the descriptor records. When this + * happens, there should be a mechanism for retaining compatibility + * with older hosts and/or plugins. + * + * See also the vampApiVersion field in the plugin descriptor, and the + * hostApiVersion argument to the vampGetPluginDescriptor function. + */ +#define VAMP_API_VERSION 1 + +/** + * C language API for Vamp plugins. + * + * This is the formal plugin API for Vamp. Plugin authors may prefer + * to use the C++ classes provided in the Vamp plugin SDK, instead of + * using this API directly. There is an adapter class provided that + * makes C++ plugins available using this C API with relatively little + * work, and the C++ headers are more thoroughly documented. + * + * IMPORTANT: The comments in this file summarise the purpose of each + * of the declared fields and functions, but do not provide a complete + * guide to their permitted values and expected usage. Please refer + * to the C++ headers in the Vamp plugin SDK for further details and + * plugin lifecycle documentation. + */ + +typedef struct _VampParameterDescriptor +{ + /** Computer-usable name of the parameter. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the parameter. May be translatable. */ + const char *name; + + /** Human-readable short text about the parameter. May be translatable. */ + const char *description; + + /** Human-readable unit of the parameter. */ + const char *unit; + + /** Minimum value. */ + float minValue; + + /** Maximum value. */ + float maxValue; + + /** Default value. Plugin is responsible for setting this on initialise. */ + float defaultValue; + + /** 1 if parameter values are quantized to a particular resolution. */ + int isQuantized; + + /** Quantization resolution, if isQuantized. */ + float quantizeStep; + + /** Human-readable names of the values, if isQuantized. May be NULL. */ + const char **valueNames; + +} VampParameterDescriptor; + +typedef enum +{ + /** Each process call returns results aligned with call's block start. */ + vampOneSamplePerStep, + + /** Returned results are evenly spaced at samplerate specified below. */ + vampFixedSampleRate, + + /** Returned results have their own individual timestamps. */ + vampVariableSampleRate + +} VampSampleType; + +typedef struct _VampOutputDescriptor +{ + /** Computer-usable name of the output. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the output. May be translatable. */ + const char *name; + + /** Human-readable short text about the output. May be translatable. */ + const char *description; + + /** Human-readable name of the unit of the output. */ + const char *unit; + + /** 1 if output has equal number of values for each returned result. */ + int hasFixedBinCount; + + /** Number of values per result, if hasFixedBinCount. */ + unsigned int binCount; + + /** Names of returned value bins, if hasFixedBinCount. May be NULL. */ + const char **binNames; + + /** 1 if each returned value falls within the same fixed min/max range. */ + int hasKnownExtents; + + /** Minimum value for a returned result in any bin, if hasKnownExtents. */ + float minValue; + + /** Maximum value for a returned result in any bin, if hasKnownExtents. */ + float maxValue; + + /** 1 if returned results are quantized to a particular resolution. */ + int isQuantized; + + /** Quantization resolution for returned results, if isQuantized. */ + float quantizeStep; + + /** Time positioning method for returned results (see VampSampleType). */ + VampSampleType sampleType; + + /** Sample rate of returned results, if sampleType is vampFixedSampleRate. + "Resolution" of result, if sampleType is vampVariableSampleRate. */ + float sampleRate; + +} VampOutputDescriptor; + +typedef struct _VampFeature +{ + /** 1 if the feature has a timestamp (i.e. if vampVariableSampleRate). */ + int hasTimestamp; + + /** Seconds component of timestamp. */ + int sec; + + /** Nanoseconds component of timestamp. */ + int nsec; + + /** Number of values. Must be binCount if hasFixedBinCount. */ + unsigned int valueCount; + + /** Values for this returned sample. */ + float *values; + + /** Label for this returned sample. May be NULL. */ + char *label; + +} VampFeature; + +typedef struct _VampFeatureList +{ + /** Number of features in this feature list. */ + unsigned int featureCount; + + /** Features in this feature list. May be NULL if featureCount is zero. */ + VampFeature *features; + +} VampFeatureList; + +typedef enum +{ + vampTimeDomain, + vampFrequencyDomain + +} VampInputDomain; + +typedef void *VampPluginHandle; + +typedef struct _VampPluginDescriptor +{ + /** API version with which this descriptor is compatible. */ + unsigned int vampApiVersion; + + /** Computer-usable name of the plugin. Must not change. [a-zA-Z0-9_] */ + const char *identifier; + + /** Human-readable name of the plugin. May be translatable. */ + const char *name; + + /** Human-readable short text about the plugin. May be translatable. */ + const char *description; + + /** Human-readable name of plugin's author or vendor. */ + const char *maker; + + /** Version number of the plugin. */ + int pluginVersion; + + /** Human-readable summary of copyright or licensing for plugin. */ + const char *copyright; + + /** Number of parameter inputs. */ + unsigned int parameterCount; + + /** Fixed descriptors for parameter inputs. */ + const VampParameterDescriptor **parameters; + + /** Number of programs. */ + unsigned int programCount; + + /** Fixed names for programs. */ + const char **programs; + + /** Preferred input domain for audio input (time or frequency). */ + VampInputDomain inputDomain; + + /** Create and return a new instance of this plugin. */ + VampPluginHandle (*instantiate)(const struct _VampPluginDescriptor *, + float inputSampleRate); + + /** Destroy an instance of this plugin. */ + void (*cleanup)(VampPluginHandle); + + /** Initialise an instance following parameter configuration. */ + int (*initialise)(VampPluginHandle, + unsigned int inputChannels, + unsigned int stepSize, + unsigned int blockSize); + + /** Reset an instance, ready to use again on new input data. */ + void (*reset)(VampPluginHandle); + + /** Get a parameter value. */ + float (*getParameter)(VampPluginHandle, int); + + /** Set a parameter value. May only be called before initialise. */ + void (*setParameter)(VampPluginHandle, int, float); + + /** Get the current program (if programCount > 0). */ + unsigned int (*getCurrentProgram)(VampPluginHandle); + + /** Set the current program. May only be called before initialise. */ + void (*selectProgram)(VampPluginHandle, unsigned int); + + /** Get the plugin's preferred processing window increment in samples. */ + unsigned int (*getPreferredStepSize)(VampPluginHandle); + + /** Get the plugin's preferred processing window size in samples. */ + unsigned int (*getPreferredBlockSize)(VampPluginHandle); + + /** Get the minimum number of input channels this plugin can handle. */ + unsigned int (*getMinChannelCount)(VampPluginHandle); + + /** Get the maximum number of input channels this plugin can handle. */ + unsigned int (*getMaxChannelCount)(VampPluginHandle); + + /** Get the number of feature outputs (distinct sets of results). */ + unsigned int (*getOutputCount)(VampPluginHandle); + + /** Get a descriptor for a given feature output. Returned pointer + is valid only until next call to getOutputDescriptor for this + handle, or releaseOutputDescriptor for this descriptor. Host + must call releaseOutputDescriptor after use. */ + VampOutputDescriptor *(*getOutputDescriptor)(VampPluginHandle, + unsigned int); + + /** Destroy a descriptor for a feature output. */ + void (*releaseOutputDescriptor)(VampOutputDescriptor *); + + /** Process an input block and return a set of features. Returned + pointer is valid only until next call to process, + getRemainingFeatures, or cleanup for this handle, or + releaseFeatureSet for this feature set. Host must call + releaseFeatureSet after use. */ + VampFeatureList *(*process)(VampPluginHandle, + const float *const *inputBuffers, + int sec, + int nsec); + + /** Return any remaining features at the end of processing. */ + VampFeatureList *(*getRemainingFeatures)(VampPluginHandle); + + /** Release a feature set returned from process or getRemainingFeatures. */ + void (*releaseFeatureSet)(VampFeatureList *); + +} VampPluginDescriptor; + +/** Get the descriptor for a given plugin index in this library. + Return NULL if the index is outside the range of valid indices for + this plugin library. + + The hostApiVersion argument tells the library code the highest + Vamp API version supported by the host. The function should + return a plugin descriptor compatible with the highest API version + supported by the library that is no higher than that supported by + the host. Provided the descriptor has the correct vampApiVersion + field for its actual compatibility level, the host should be able + to do the right thing with it: use it if possible, discard it + otherwise. +*/ +const VampPluginDescriptor *vampGetPluginDescriptor + (unsigned int hostApiVersion, unsigned int index); + +/** Function pointer type for vampGetPluginDescriptor. */ +typedef const VampPluginDescriptor *(*VampGetPluginDescriptorFunction) + (unsigned int, unsigned int); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/vamp-sdk/vamp/vamp.pc.in b/libs/vamp-sdk/vamp/vamp.pc.in new file mode 100644 index 0000000000..82d4decd34 --- /dev/null +++ b/libs/vamp-sdk/vamp/vamp.pc.in @@ -0,0 +1,10 @@ +prefix=%PREFIX% +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: vamp +Version: 1.0 +Description: An API for audio analysis and feature extraction plugins +Libs: +Cflags: -I${includedir} diff --git a/svn_revision.h b/svn_revision.h index cb5597281d..fc376f4016 100644 --- a/svn_revision.h +++ b/svn_revision.h @@ -1,4 +1,4 @@ #ifndef __ardour_svn_revision_h__ #define __ardour_svn_revision_h__ -static const char* ardour_svn_revision = "2885"; +static const char* ardour_svn_revision = "2884"; #endif diff --git a/templates/16 Tracks.template.in b/templates/16 Tracks.template.in index 786f41e0e2..e427d2b970 100644 --- a/templates/16 Tracks.template.in +++ b/templates/16 Tracks.template.in @@ -1,260 +1,617 @@ -<?xml version="1.0"?> -<Session version="0.821.0"> - <Options> - <recording-plugins val="no"/> - <slave type="none"/> - <send-midi-timecode val="no"/> - <send-midi-machine-control val="no"/> - <input-auto-connect val="1"/> - <output-auto-connect val="2"/> - <max-level val="0"/> - <min-level val="0"/> - <meter-hold val="10.000000"/> - <long-over-length val="10"/> - <short-over-length val="2"/> - <shuttle-speed-factor val="1.000000"/> - <shuttle-speed-threshold val="5.000000"/> - <rf-speed val="2.000000"/> - <smpte-frames-per-second val="30.000000"/> - <edit-mode val="slide"/> - <auto-play val="no"/> - <auto-input val="no"/> - <seamless-loop val="no"/> - <punch-in val="no"/> - <punch-out val="no"/> - <all-safe val="no"/> - <auto-return val="no"/> - <mmc-control val="no"/> - <recording-plugins val="no"/> - <auto-crossfade val="no"/> - <audible-click val="no"/> - <align-style val="existing"/> - </Options> +<?xml version="1.0" encoding="UTF-8"?> +<Session version="2.0.0" id-counter="1191241714"> + <Config> + <Option name="output-auto-connect" value="2"/> + <Option name="input-auto-connect" value="1"/> + <Option name="mtc-port-name" value="control"/> + <Option name="mmc-port-name" value="control"/> + <Option name="midi-port-name" value="control"/> + <Option name="mmc-control" value="0"/> + <Option name="midi-feedback" value="0"/> + <Option name="xfade-model" value="0"/> + <Option name="edit-mode" value="0"/> + <Option name="layer-model" value="0"/> + <Option name="solo-model" value="0"/> + <Option name="all-safe" value="0"/> + <Option name="auto-play" value="0"/> + <Option name="auto-return" value="0"/> + <Option name="auto-input" value="1"/> + <Option name="punch-in" value="0"/> + <Option name="punch-out" value="0"/> + <Option name="seamless-loop" value="0"/> + <Option name="rf-speed" value="2"/> + <Option name="shuttle-speed-factor" value="1"/> + <Option name="shuttle-speed-threshold" value="5"/> + <Option name="meter-hold" value="10"/> + <Option name="meter-falloff" value="1.5"/> + <end-marker-is-free val="no"/> + </Config> <Sources/> <Regions/> <DiskStreams> - <DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/> - <DiskStream channels="2" playlist="Audio 2.1" speed="1.000000" name="Audio 2" id="1088698381722129"/> - <DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/> - <DiskStream channels="2" playlist="Audio 4.1" speed="1.000000" name="Audio 4" id="1088698419943526"/> - <DiskStream channels="2" playlist="Audio 5.1" speed="1.000000" name="Audio 5" id="1088698450528071"/> - <DiskStream channels="2" playlist="Audio 6.1" speed="1.000000" name="Audio 6" id="1088698450754348"/> - <DiskStream channels="2" playlist="Audio 7.1" speed="1.000000" name="Audio 7" id="1088698450937150"/> - <DiskStream channels="2" playlist="Audio 8.1" speed="1.000000" name="Audio 8" id="1088698451167172"/> - <DiskStream channels="2" playlist="Audio 9.1" speed="1.000000" name="Audio 9" id="1088698483525991"/> - <DiskStream channels="2" playlist="Audio 10.1" speed="1.000000" name="Audio 10" id="1088698483801345"/> - <DiskStream channels="2" playlist="Audio 11.1" speed="1.000000" name="Audio 11" id="1088698484086727"/> - <DiskStream channels="2" playlist="Audio 12.1" speed="1.000000" name="Audio 12" id="1088698484325738"/> - <DiskStream channels="2" playlist="Audio 13.1" speed="1.000000" name="Audio 13" id="1088698484576054"/> - <DiskStream channels="2" playlist="Audio 14.1" speed="1.000000" name="Audio 14" id="1088698484839332"/> - <DiskStream channels="2" playlist="Audio 15.1" speed="1.000000" name="Audio 15" id="1088698485116518"/> - <DiskStream channels="2" playlist="Audio 16.1" speed="1.000000" name="Audio 16" id="1088698485412133"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" name="Audio 1" id="1088698381595945"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 2.1" speed="1" name="Audio 2" id="1088698381722129"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" name="Audio 3" id="1088698419793849"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 4.1" speed="1" name="Audio 4" id="1088698419943526"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 5.1" speed="1" name="Audio 5" id="1088698450528071"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 6.1" speed="1" name="Audio 6" id="1088698450754348"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 7.1" speed="1" name="Audio 7" id="1088698450937150"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 8.1" speed="1" name="Audio 8" id="1088698451167172"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 9.1" speed="1" name="Audio 9" id="1088698483525991"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 10.1" speed="1" name="Audio 10" id="1088698483801345"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 11.1" speed="1" name="Audio 11" id="1088698484086727"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 12.1" speed="1" name="Audio 12" id="1088698484325738"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 13.1" speed="1" name="Audio 13" id="1088698484576054"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 14.1" speed="1" name="Audio 14" id="1088698484839332"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 15.1" speed="1" name="Audio 15" id="1088698485116518"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 16.1" speed="1" name="Audio 16" id="1088698485412133"/> </DiskStreams> <Locations> - <Location name="end" start="14400000" end="14400000" flags="33"/> - <Location name="Loop" start="0" end="14400000" flags="12"/> - <Location name="Punch" start="0" end="14400000" flags="10"/> + <Location id="1191241715" name="start" start="0" end="0" flags="IsMark,IsStart"/> + <Location id="1191241716" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/> </Locations> <Connections/> <Routes> - <Route flags="0x2" muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> - <IO name="master" id="1088698373992392" inputs="{ardour:Audio 16/out 1,ardour:Audio 15/out 1,ardour:Audio 14/out 1,ardour:Audio 13/out 1,ardour:Audio 12/out 1,ardour:Audio 11/out 1,ardour:Audio 10/out 1,ardour:Audio 9/out 1,ardour:Audio 8/out 1,ardour:Audio 7/out 1,ardour:Audio 6/out 1,ardour:Audio 5/out 1,ardour:Audio 4/out 1,ardour:Audio 3/out 1,ardour:Audio 2/out 1,ardour:Audio 1/out 1}{ardour:Audio 16/out 2,ardour:Audio 15/out 2,ardour:Audio 14/out 2,ardour:Audio 13/out 2,ardour:Audio 12/out 2,ardour:Audio 11/out 2,ardour:Audio 10/out 2,ardour:Audio 9/out 2,ardour:Audio 8/out 2,ardour:Audio 7/out 2,ardour:Audio 6/out 2,ardour:Audio 5/out 2,ardour:Audio 4/out 2,ardour:Audio 3/out 2,ardour:Audio 2/out 2,ardour:Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1" iolimits="-1,2,-1,2" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route flags="MasterOut" default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> + <IO name="master" id="1088698373992392" inputs="{Audio 16/out 1,Audio 15/out 1,Audio 14/out 1,Audio 13/out 1,Audio 12/out 1,Audio 11/out 1,Audio 10/out 1,Audio 9/out 1,Audio 8/out 1,Audio 7/out 1,Audio 6/out 1,Audio 5/out 1,Audio 4/out 1,Audio 3/out 1,Audio 2/out 1,Audio 1/out 1}{Audio 16/out 2,Audio 15/out 2,Audio 14/out 2,Audio 13/out 2,Audio 12/out 2,Audio 11/out 2,Audio 10/out 2,Audio 9/out 2,Audio 8/out 2,Audio 7/out 2,Audio 6/out 2,Audio 5/out 2,Audio 4/out 2,Audio 3/out 2,Audio 2/out 2,Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1.000000000000" iolimits="-1,2,-1,2"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241498" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241497"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241501" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241500"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241256"/> </IO> + <controllable name="solo" id="1191241265"/> + <controllable name="mute" id="1191241266"/> + <remote_control id="1"/> <extra> - <GUI color="3746:15634:28532" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="3746:15634:28532" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" diskstream-id="1088698381595945"> - <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" mode="Normal" diskstream-id="1088698381595945"> + <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241504" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241503"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241507" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241506"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241268"/> </IO> + <controllable name="solo" id="1191241277"/> + <controllable name="mute" id="1191241278"/> + <remote_control id="2"/> <extra> - <GUI color="25329:39287:16285" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="25329:39287:16285" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241279"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" diskstream-id="1088698381722129"> - <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" mode="Normal" diskstream-id="1088698381722129"> + <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241510" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241509"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241513" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241512"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241281"/> </IO> + <controllable name="solo" id="1191241290"/> + <controllable name="mute" id="1191241291"/> + <remote_control id="3"/> <extra> - <GUI color="6057:31092:43721" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6057:31092:43721" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241292"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" diskstream-id="1088698419793849"> - <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" mode="Normal" diskstream-id="1088698419793849"> + <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241516" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241515"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241519" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241518"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241294"/> </IO> + <controllable name="solo" id="1191241303"/> + <controllable name="mute" id="1191241304"/> + <remote_control id="4"/> <extra> - <GUI color="21964:7276:28849" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21964:7276:28849" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241305"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" diskstream-id="1088698419943526"> - <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" mode="Normal" diskstream-id="1088698419943526"> + <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241522" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241521"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241525" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241524"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241307"/> </IO> + <controllable name="solo" id="1191241316"/> + <controllable name="mute" id="1191241317"/> + <remote_control id="5"/> <extra> - <GUI color="46694:21380:28653" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="46694:21380:28653" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241318"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" diskstream-id="1088698450528071"> - <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" mode="Normal" diskstream-id="1088698450528071"> + <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241528" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241527"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241531" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241530"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241320"/> </IO> + <controllable name="solo" id="1191241329"/> + <controllable name="mute" id="1191241330"/> + <remote_control id="6"/> <extra> - <GUI color="29643:15912:24582" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="29643:15912:24582" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241331"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" diskstream-id="1088698450754348"> - <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" mode="Normal" diskstream-id="1088698450754348"> + <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241534" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241533"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241537" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241536"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241333"/> </IO> + <controllable name="solo" id="1191241342"/> + <controllable name="mute" id="1191241343"/> + <remote_control id="7"/> <extra> - <GUI color="32959:22941:32677" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="32959:22941:32677" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241344"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" diskstream-id="1088698450937150"> - <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" mode="Normal" diskstream-id="1088698450937150"> + <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241540" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241539"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241543" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241542"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241346"/> </IO> + <controllable name="solo" id="1191241355"/> + <controllable name="mute" id="1191241356"/> + <remote_control id="8"/> <extra> - <GUI color="44734:28458:19344" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="44734:28458:19344" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241357"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" diskstream-id="1088698451167172"> - <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" mode="Normal" diskstream-id="1088698451167172"> + <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241546" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241545"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241549" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241548"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241359"/> </IO> + <controllable name="solo" id="1191241368"/> + <controllable name="mute" id="1191241369"/> + <remote_control id="9"/> <extra> - <GUI color="21903:23957:19369" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21903:23957:19369" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241370"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=9:signal=9" diskstream-id="1088698483525991"> - <IO name="Audio 9" id="1088698483525928" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=9:signal=9" mode="Normal" diskstream-id="1088698483525991"> + <IO name="Audio 9" id="1088698483525928" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241552" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241551"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241555" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241554"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241372"/> </IO> + <controllable name="solo" id="1191241381"/> + <controllable name="mute" id="1191241382"/> + <remote_control id="10"/> <extra> - <GUI color="33035:25949:38549" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="33035:25949:38549" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241383"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=10:signal=10" diskstream-id="1088698483801345"> - <IO name="Audio 10" id="1088698483801234" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=10:signal=10" mode="Normal" diskstream-id="1088698483801345"> + <IO name="Audio 10" id="1088698483801234" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241558" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241557"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241561" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241560"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241385"/> </IO> + <controllable name="solo" id="1191241394"/> + <controllable name="mute" id="1191241395"/> + <remote_control id="11"/> <extra> - <GUI color="2516:42834:42296" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="2516:42834:42296" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241396"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=11:signal=11" diskstream-id="1088698484086727"> - <IO name="Audio 11" id="1088698484086663" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=11:signal=11" mode="Normal" diskstream-id="1088698484086727"> + <IO name="Audio 11" id="1088698484086663" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241564" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241563"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241567" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241566"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241398"/> </IO> + <controllable name="solo" id="1191241407"/> + <controllable name="mute" id="1191241408"/> + <remote_control id="12"/> <extra> - <GUI color="6503:47471:19625" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6503:47471:19625" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241409"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=12:signal=12" diskstream-id="1088698484325738"> - <IO name="Audio 12" id="1088698484325672" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=12:signal=12" mode="Normal" diskstream-id="1088698484325738"> + <IO name="Audio 12" id="1088698484325672" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241570" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241569"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241573" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241572"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241411"/> </IO> + <controllable name="solo" id="1191241420"/> + <controllable name="mute" id="1191241421"/> + <remote_control id="13"/> <extra> - <GUI color="45790:43192:14035" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="45790:43192:14035" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241422"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=13:signal=13" diskstream-id="1088698484576054"> - <IO name="Audio 13" id="1088698484575978" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=13:signal=13" mode="Normal" diskstream-id="1088698484576054"> + <IO name="Audio 13" id="1088698484575978" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241576" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241575"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241579" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241578"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241424"/> </IO> + <controllable name="solo" id="1191241433"/> + <controllable name="mute" id="1191241434"/> + <remote_control id="14"/> <extra> - <GUI color="17234:12393:35999" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="17234:12393:35999" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241435"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=14:signal=14" diskstream-id="1088698484839332"> - <IO name="Audio 14" id="1088698484839137" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=14:signal=14" mode="Normal" diskstream-id="1088698484839332"> + <IO name="Audio 14" id="1088698484839137" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241582" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241581"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241585" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241584"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241437"/> </IO> + <controllable name="solo" id="1191241446"/> + <controllable name="mute" id="1191241447"/> + <remote_control id="15"/> <extra> - <GUI color="12863:41046:23045" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="12863:41046:23045" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241448"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=15:signal=15" diskstream-id="1088698485116518"> - <IO name="Audio 15" id="1088698485116451" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=15:signal=15" mode="Normal" diskstream-id="1088698485116518"> + <IO name="Audio 15" id="1088698485116451" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241588" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241587"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241591" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241590"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241450"/> </IO> + <controllable name="solo" id="1191241459"/> + <controllable name="mute" id="1191241460"/> + <remote_control id="16"/> <extra> - <GUI color="34243:17628:4689" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="34243:17628:4689" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241461"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=16:signal=16" diskstream-id="1088698485412133"> - <IO name="Audio 16" id="1088698485412068" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=16:signal=16" mode="Normal" diskstream-id="1088698485412133"> + <IO name="Audio 16" id="1088698485412068" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241594" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241593"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241597" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241596"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241463"/> </IO> + <controllable name="solo" id="1191241472"/> + <controllable name="mute" id="1191241473"/> + <remote_control id="17"/> <extra> - <GUI color="2155:38658:37648" strip_width="wide" shown_mixer="yes" track_height="normal" shown_editor="yes"/> + <GUI color="2155:38658:37648" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241474"/> </Route> </Routes> <EditGroups/> <MixGroups/> <Playlists/> + <UnusedPlaylists/> <Click> - <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/> + <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"/> + <controllable name="gaincontrol" id="1191241476"/> </IO> </Click> <TempoMap> <Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/> <Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/> </TempoMap> + <ControlProtocols> + <Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes"> + <controls/> + </Protocol> + </ControlProtocols> </Session> diff --git a/templates/2 Track.template.in b/templates/2 Track.template.in index 3d798d77b4..c9f70455f7 100644 --- a/templates/2 Track.template.in +++ b/templates/2 Track.template.in @@ -1,92 +1,155 @@ -<?xml version="1.0"?> -<Session version="0.821.0"> - <Options> - <recording-plugins val="no"/> - <slave type="none"/> - <send-midi-timecode val="no"/> - <send-midi-machine-control val="no"/> - <input-auto-connect val="1"/> - <output-auto-connect val="2"/> - <max-level val="0"/> - <min-level val="0"/> - <meter-hold val="10.000000"/> - <long-over-length val="10"/> - <short-over-length val="2"/> - <shuttle-speed-factor val="1.000000"/> - <shuttle-speed-threshold val="5.000000"/> - <rf-speed val="2.000000"/> - <smpte-frames-per-second val="30.000000"/> - <edit-mode val="slide"/> - <auto-play val="no"/> - <auto-input val="no"/> - <seamless-loop val="no"/> - <punch-in val="no"/> - <punch-out val="no"/> - <all-safe val="no"/> - <auto-return val="no"/> - <mmc-control val="no"/> - <recording-plugins val="no"/> - <auto-crossfade val="no"/> - <audible-click val="no"/> - <align-style val="existing"/> - </Options> +<?xml version="1.0" encoding="UTF-8"?> +<Session version="2.0.0" id-counter="1191241115"> + <Config> + <Option name="output-auto-connect" value="2"/> + <Option name="input-auto-connect" value="1"/> + <Option name="mtc-port-name" value="control"/> + <Option name="mmc-port-name" value="control"/> + <Option name="midi-port-name" value="control"/> + <Option name="mmc-control" value="0"/> + <Option name="midi-feedback" value="0"/> + <Option name="xfade-model" value="0"/> + <Option name="edit-mode" value="0"/> + <Option name="layer-model" value="0"/> + <Option name="solo-model" value="0"/> + <Option name="all-safe" value="0"/> + <Option name="auto-play" value="0"/> + <Option name="auto-return" value="0"/> + <Option name="auto-input" value="1"/> + <Option name="punch-in" value="0"/> + <Option name="punch-out" value="0"/> + <Option name="seamless-loop" value="0"/> + <Option name="rf-speed" value="2"/> + <Option name="shuttle-speed-factor" value="1"/> + <Option name="shuttle-speed-threshold" value="5"/> + <Option name="meter-hold" value="10"/> + <Option name="meter-falloff" value="1.5"/> + <end-marker-is-free val="no"/> + </Config> <Sources/> <Regions/> <DiskStreams> - <DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/> - <DiskStream channels="2" playlist="Audio 2.1" speed="1.000000" name="Audio 2" id="1088698381722129"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" name="Audio 1" id="1088698381595945"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 2.1" speed="1" name="Audio 2" id="1088698381722129"/> </DiskStreams> <Locations> - <Location name="end" start="14400000" end="14400000" flags="33"/> - <Location name="Loop" start="0" end="14400000" flags="12"/> - <Location name="Punch" start="0" end="14400000" flags="10"/> + <Location id="1191241116" name="start" start="0" end="0" flags="IsMark,IsStart"/> + <Location id="1191241117" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/> </Locations> <Connections/> <Routes> - <Route flags="0x2" muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> - <IO name="master" id="1088698373992392" inputs="{ardour:Audio 2/out 1,ardour:Audio 1/out 1}{ardour:Audio 2/out 2,ardour:Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1" iolimits="-1,2,-1,2" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route flags="MasterOut" default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> + <IO name="master" id="1088698373992392" inputs="{Audio 2/out 1,Audio 1/out 1}{Audio 2/out 2,Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1.000000000000" iolimits="-1,2,-1,2"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241081" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241080"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241084" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241083"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241021"/> </IO> + <controllable name="solo" id="1191241030"/> + <controllable name="mute" id="1191241031"/> + <remote_control id="1"/> <extra> - <GUI color="3746:15634:28532" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="3746:15634:28532" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" diskstream-id="1088698381595945"> - <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" mode="Normal" diskstream-id="1088698381595945"> + <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241087" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241086"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241090" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241089"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241033"/> </IO> + <controllable name="solo" id="1191241042"/> + <controllable name="mute" id="1191241043"/> + <remote_control id="2"/> <extra> - <GUI color="25329:39287:16285" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="25329:39287:16285" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241044"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" diskstream-id="1088698381722129"> - <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" mode="Normal" diskstream-id="1088698381722129"> + <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241093" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241092"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241096" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241095"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241046"/> </IO> + <controllable name="solo" id="1191241055"/> + <controllable name="mute" id="1191241056"/> + <remote_control id="3"/> <extra> - <GUI color="6057:31092:43721" strip_width="wide" shown_mixer="yes" track_height="normal" shown_editor="yes"/> + <GUI color="6057:31092:43721" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241057"/> </Route> </Routes> <EditGroups/> <MixGroups/> <Playlists/> + <UnusedPlaylists/> <Click> - <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/> + <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"/> + <controllable name="gaincontrol" id="1191241059"/> </IO> </Click> <TempoMap> <Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/> <Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/> </TempoMap> + <ControlProtocols> + <Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes"> + <controls/> + </Protocol> + </ControlProtocols> </Session> diff --git a/templates/32 Tracks.template.in b/templates/32 Tracks.template.in index 65f325bcc8..8b95ef7629 100644 --- a/templates/32 Tracks.template.in +++ b/templates/32 Tracks.template.in @@ -1,356 +1,881 @@ -<?xml version="1.0"?> -<Session version="0.821.0"> - <Options> - <recording-plugins val="no"/> - <slave type="none"/> - <send-midi-timecode val="no"/> - <send-midi-machine-control val="no"/> - <input-auto-connect val="1"/> - <output-auto-connect val="2"/> - <max-level val="0"/> - <min-level val="0"/> - <meter-hold val="10.000000"/> - <long-over-length val="10"/> - <short-over-length val="2"/> - <shuttle-speed-factor val="1.000000"/> - <shuttle-speed-threshold val="5.000000"/> - <rf-speed val="2.000000"/> - <smpte-frames-per-second val="30.000000"/> - <edit-mode val="slide"/> - <auto-play val="no"/> - <auto-input val="no"/> - <seamless-loop val="no"/> - <punch-in val="no"/> - <punch-out val="no"/> - <all-safe val="no"/> - <auto-return val="no"/> - <mmc-control val="no"/> - <recording-plugins val="no"/> - <auto-crossfade val="no"/> - <audible-click val="no"/> - <align-style val="existing"/> - </Options> +<?xml version="1.0" encoding="UTF-8"?> +<Session version="2.0.0" id-counter="1191242242"> + <Config> + <Option name="output-auto-connect" value="2"/> + <Option name="input-auto-connect" value="1"/> + <Option name="mtc-port-name" value="control"/> + <Option name="mmc-port-name" value="control"/> + <Option name="midi-port-name" value="control"/> + <Option name="mmc-control" value="0"/> + <Option name="midi-feedback" value="0"/> + <Option name="xfade-model" value="0"/> + <Option name="edit-mode" value="0"/> + <Option name="layer-model" value="0"/> + <Option name="solo-model" value="0"/> + <Option name="all-safe" value="0"/> + <Option name="auto-play" value="0"/> + <Option name="auto-return" value="0"/> + <Option name="auto-input" value="1"/> + <Option name="punch-in" value="0"/> + <Option name="punch-out" value="0"/> + <Option name="seamless-loop" value="0"/> + <Option name="rf-speed" value="2"/> + <Option name="shuttle-speed-factor" value="1"/> + <Option name="shuttle-speed-threshold" value="5"/> + <Option name="meter-hold" value="10"/> + <Option name="meter-falloff" value="1.5"/> + <end-marker-is-free val="no"/> + </Config> <Sources/> <Regions/> <DiskStreams> - <DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/> - <DiskStream channels="2" playlist="Audio 2.1" speed="1.000000" name="Audio 2" id="1088698381722129"/> - <DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/> - <DiskStream channels="2" playlist="Audio 4.1" speed="1.000000" name="Audio 4" id="1088698419943526"/> - <DiskStream channels="2" playlist="Audio 5.1" speed="1.000000" name="Audio 5" id="1088698450528071"/> - <DiskStream channels="2" playlist="Audio 6.1" speed="1.000000" name="Audio 6" id="1088698450754348"/> - <DiskStream channels="2" playlist="Audio 7.1" speed="1.000000" name="Audio 7" id="1088698450937150"/> - <DiskStream channels="2" playlist="Audio 8.1" speed="1.000000" name="Audio 8" id="1088698451167172"/> - <DiskStream channels="2" playlist="Audio 9.1" speed="1.000000" name="Audio 9" id="1088698483525991"/> - <DiskStream channels="2" playlist="Audio 10.1" speed="1.000000" name="Audio 10" id="1088698483801345"/> - <DiskStream channels="2" playlist="Audio 11.1" speed="1.000000" name="Audio 11" id="1088698484086727"/> - <DiskStream channels="2" playlist="Audio 12.1" speed="1.000000" name="Audio 12" id="1088698484325738"/> - <DiskStream channels="2" playlist="Audio 13.1" speed="1.000000" name="Audio 13" id="1088698484576054"/> - <DiskStream channels="2" playlist="Audio 14.1" speed="1.000000" name="Audio 14" id="1088698484839332"/> - <DiskStream channels="2" playlist="Audio 15.1" speed="1.000000" name="Audio 15" id="1088698485116518"/> - <DiskStream channels="2" playlist="Audio 16.1" speed="1.000000" name="Audio 16" id="1088698485412133"/> - <DiskStream channels="2" playlist="Audio 17.1" speed="1.000000" name="Audio 17" id="1088698520418087"/> - <DiskStream channels="2" playlist="Audio 18.1" speed="1.000000" name="Audio 18" id="1088698520803734"/> - <DiskStream channels="2" playlist="Audio 19.1" speed="1.000000" name="Audio 19" id="1088698521138071"/> - <DiskStream channels="2" playlist="Audio 20.1" speed="1.000000" name="Audio 20" id="1088698521481727"/> - <DiskStream channels="2" playlist="Audio 21.1" speed="1.000000" name="Audio 21" id="1088698521848332"/> - <DiskStream channels="2" playlist="Audio 22.1" speed="1.000000" name="Audio 22" id="1088698522224190"/> - <DiskStream channels="2" playlist="Audio 23.1" speed="1.000000" name="Audio 23" id="1088698522620517"/> - <DiskStream channels="2" playlist="Audio 24.1" speed="1.000000" name="Audio 24" id="1088698523020752"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" name="Audio 1" id="1088698381595945"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 2.1" speed="1" name="Audio 2" id="1088698381722129"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" name="Audio 3" id="1088698419793849"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 4.1" speed="1" name="Audio 4" id="1088698419943526"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 5.1" speed="1" name="Audio 5" id="1088698450528071"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 6.1" speed="1" name="Audio 6" id="1088698450754348"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 7.1" speed="1" name="Audio 7" id="1088698450937150"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 8.1" speed="1" name="Audio 8" id="1088698451167172"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 9.1" speed="1" name="Audio 9" id="1088698483525991"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 10.1" speed="1" name="Audio 10" id="1088698483801345"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 11.1" speed="1" name="Audio 11" id="1088698484086727"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 12.1" speed="1" name="Audio 12" id="1088698484325738"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 13.1" speed="1" name="Audio 13" id="1088698484576054"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 14.1" speed="1" name="Audio 14" id="1088698484839332"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 15.1" speed="1" name="Audio 15" id="1088698485116518"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 16.1" speed="1" name="Audio 16" id="1088698485412133"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 17.1" speed="1" name="Audio 17" id="1088698520418087"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 18.1" speed="1" name="Audio 18" id="1088698520803734"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 19.1" speed="1" name="Audio 19" id="1088698521138071"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 20.1" speed="1" name="Audio 20" id="1088698521481727"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 21.1" speed="1" name="Audio 21" id="1088698521848332"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 22.1" speed="1" name="Audio 22" id="1088698522224190"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 23.1" speed="1" name="Audio 23" id="1088698522620517"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 24.1" speed="1" name="Audio 24" id="1088698523020752"/> </DiskStreams> <Locations> - <Location name="end" start="14400000" end="14400000" flags="33"/> - <Location name="Loop" start="0" end="14400000" flags="12"/> - <Location name="Punch" start="0" end="14400000" flags="10"/> + <Location id="1191242243" name="start" start="0" end="0" flags="IsMark,IsStart"/> + <Location id="1191242244" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/> </Locations> <Connections/> <Routes> - <Route flags="0x2" muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> - <IO name="master" id="1088698373992392" inputs="{ardour:Audio 24/out 1,ardour:Audio 23/out 1,ardour:Audio 22/out 1,ardour:Audio 21/out 1,ardour:Audio 20/out 1,ardour:Audio 19/out 1,ardour:Audio 18/out 1,ardour:Audio 17/out 1,ardour:Audio 16/out 1,ardour:Audio 15/out 1,ardour:Audio 14/out 1,ardour:Audio 13/out 1,ardour:Audio 12/out 1,ardour:Audio 11/out 1,ardour:Audio 10/out 1,ardour:Audio 9/out 1,ardour:Audio 8/out 1,ardour:Audio 7/out 1,ardour:Audio 6/out 1,ardour:Audio 5/out 1,ardour:Audio 4/out 1,ardour:Audio 3/out 1,ardour:Audio 2/out 1,ardour:Audio 1/out 1}{ardour:Audio 24/out 2,ardour:Audio 23/out 2,ardour:Audio 22/out 2,ardour:Audio 21/out 2,ardour:Audio 20/out 2,ardour:Audio 19/out 2,ardour:Audio 18/out 2,ardour:Audio 17/out 2,ardour:Audio 16/out 2,ardour:Audio 15/out 2,ardour:Audio 14/out 2,ardour:Audio 13/out 2,ardour:Audio 12/out 2,ardour:Audio 11/out 2,ardour:Audio 10/out 2,ardour:Audio 9/out 2,ardour:Audio 8/out 2,ardour:Audio 7/out 2,ardour:Audio 6/out 2,ardour:Audio 5/out 2,ardour:Audio 4/out 2,ardour:Audio 3/out 2,ardour:Audio 2/out 2,ardour:Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1" iolimits="-1,2,-1,2" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route flags="MasterOut" default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> + <IO name="master" id="1088698373992392" inputs="{Audio 24/out 1,Audio 23/out 1,Audio 22/out 1,Audio 21/out 1,Audio 20/out 1,Audio 19/out 1,Audio 18/out 1,Audio 17/out 1,Audio 16/out 1,Audio 15/out 1,Audio 14/out 1,Audio 13/out 1,Audio 12/out 1,Audio 11/out 1,Audio 10/out 1,Audio 9/out 1,Audio 8/out 1,Audio 7/out 1,Audio 6/out 1,Audio 5/out 1,Audio 4/out 1,Audio 3/out 1,Audio 2/out 1,Audio 1/out 1}{Audio 24/out 2,Audio 23/out 2,Audio 22/out 2,Audio 21/out 2,Audio 20/out 2,Audio 19/out 2,Audio 18/out 2,Audio 17/out 2,Audio 16/out 2,Audio 15/out 2,Audio 14/out 2,Audio 13/out 2,Audio 12/out 2,Audio 11/out 2,Audio 10/out 2,Audio 9/out 2,Audio 8/out 2,Audio 7/out 2,Audio 6/out 2,Audio 5/out 2,Audio 4/out 2,Audio 3/out 2,Audio 2/out 2,Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1.000000000000" iolimits="-1,2,-1,2"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241922" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241921"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241925" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241924"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241576"/> </IO> + <controllable name="solo" id="1191241585"/> + <controllable name="mute" id="1191241586"/> + <remote_control id="1"/> <extra> - <GUI color="3746:15634:28532" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="3746:15634:28532" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" diskstream-id="1088698381595945"> - <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" mode="Normal" diskstream-id="1088698381595945"> + <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241928" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241927"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241931" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241930"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241588"/> </IO> + <controllable name="solo" id="1191241597"/> + <controllable name="mute" id="1191241598"/> + <remote_control id="2"/> <extra> - <GUI color="25329:39287:16285" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="25329:39287:16285" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241599"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" diskstream-id="1088698381722129"> - <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" mode="Normal" diskstream-id="1088698381722129"> + <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241934" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241933"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241937" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241936"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241601"/> </IO> + <controllable name="solo" id="1191241610"/> + <controllable name="mute" id="1191241611"/> + <remote_control id="3"/> <extra> - <GUI color="6057:31092:43721" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6057:31092:43721" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241612"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" diskstream-id="1088698419793849"> - <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" mode="Normal" diskstream-id="1088698419793849"> + <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241940" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241939"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241943" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241942"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241614"/> </IO> + <controllable name="solo" id="1191241623"/> + <controllable name="mute" id="1191241624"/> + <remote_control id="4"/> <extra> - <GUI color="21964:7276:28849" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21964:7276:28849" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241625"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" diskstream-id="1088698419943526"> - <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" mode="Normal" diskstream-id="1088698419943526"> + <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241946" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241945"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241949" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241948"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241627"/> </IO> + <controllable name="solo" id="1191241636"/> + <controllable name="mute" id="1191241637"/> + <remote_control id="5"/> <extra> - <GUI color="46694:21380:28653" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="46694:21380:28653" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241638"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" diskstream-id="1088698450528071"> - <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" mode="Normal" diskstream-id="1088698450528071"> + <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241952" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241951"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241955" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241954"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241640"/> </IO> + <controllable name="solo" id="1191241649"/> + <controllable name="mute" id="1191241650"/> + <remote_control id="6"/> <extra> - <GUI color="29643:15912:24582" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="29643:15912:24582" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241651"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" diskstream-id="1088698450754348"> - <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" mode="Normal" diskstream-id="1088698450754348"> + <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241958" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241957"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241961" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241960"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241653"/> </IO> + <controllable name="solo" id="1191241662"/> + <controllable name="mute" id="1191241663"/> + <remote_control id="7"/> <extra> - <GUI color="32959:22941:32677" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="32959:22941:32677" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241664"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" diskstream-id="1088698450937150"> - <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" mode="Normal" diskstream-id="1088698450937150"> + <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241964" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241963"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241967" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241966"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241666"/> </IO> + <controllable name="solo" id="1191241675"/> + <controllable name="mute" id="1191241676"/> + <remote_control id="8"/> <extra> - <GUI color="44734:28458:19344" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="44734:28458:19344" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241677"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" diskstream-id="1088698451167172"> - <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" mode="Normal" diskstream-id="1088698451167172"> + <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241970" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241969"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241973" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241972"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241679"/> </IO> + <controllable name="solo" id="1191241688"/> + <controllable name="mute" id="1191241689"/> + <remote_control id="9"/> <extra> - <GUI color="21903:23957:19369" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21903:23957:19369" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241690"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=9:signal=9" diskstream-id="1088698483525991"> - <IO name="Audio 9" id="1088698483525928" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=9:signal=9" mode="Normal" diskstream-id="1088698483525991"> + <IO name="Audio 9" id="1088698483525928" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241976" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241975"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241979" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241978"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241692"/> </IO> + <controllable name="solo" id="1191241701"/> + <controllable name="mute" id="1191241702"/> + <remote_control id="10"/> <extra> - <GUI color="33035:25949:38549" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="33035:25949:38549" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241703"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=10:signal=10" diskstream-id="1088698483801345"> - <IO name="Audio 10" id="1088698483801234" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=10:signal=10" mode="Normal" diskstream-id="1088698483801345"> + <IO name="Audio 10" id="1088698483801234" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241982" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241981"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241985" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241984"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241705"/> </IO> + <controllable name="solo" id="1191241714"/> + <controllable name="mute" id="1191241715"/> + <remote_control id="11"/> <extra> - <GUI color="2516:42834:42296" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="2516:42834:42296" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241716"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=11:signal=11" diskstream-id="1088698484086727"> - <IO name="Audio 11" id="1088698484086663" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=11:signal=11" mode="Normal" diskstream-id="1088698484086727"> + <IO name="Audio 11" id="1088698484086663" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241988" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241987"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241991" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241990"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241718"/> </IO> + <controllable name="solo" id="1191241727"/> + <controllable name="mute" id="1191241728"/> + <remote_control id="12"/> <extra> - <GUI color="6503:47471:19625" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6503:47471:19625" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241729"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=12:signal=12" diskstream-id="1088698484325738"> - <IO name="Audio 12" id="1088698484325672" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=12:signal=12" mode="Normal" diskstream-id="1088698484325738"> + <IO name="Audio 12" id="1088698484325672" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241994" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241993"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241997" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241996"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241731"/> </IO> + <controllable name="solo" id="1191241740"/> + <controllable name="mute" id="1191241741"/> + <remote_control id="13"/> <extra> - <GUI color="45790:43192:14035" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="45790:43192:14035" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241742"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=13:signal=13" diskstream-id="1088698484576054"> - <IO name="Audio 13" id="1088698484575978" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=13:signal=13" mode="Normal" diskstream-id="1088698484576054"> + <IO name="Audio 13" id="1088698484575978" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242000" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241999"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242003" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242002"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241744"/> </IO> + <controllable name="solo" id="1191241753"/> + <controllable name="mute" id="1191241754"/> + <remote_control id="14"/> <extra> - <GUI color="17234:12393:35999" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="17234:12393:35999" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241755"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=14:signal=14" diskstream-id="1088698484839332"> - <IO name="Audio 14" id="1088698484839137" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=14:signal=14" mode="Normal" diskstream-id="1088698484839332"> + <IO name="Audio 14" id="1088698484839137" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242006" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242005"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242009" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242008"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241757"/> </IO> + <controllable name="solo" id="1191241766"/> + <controllable name="mute" id="1191241767"/> + <remote_control id="15"/> <extra> - <GUI color="12863:41046:23045" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="12863:41046:23045" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241768"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=15:signal=15" diskstream-id="1088698485116518"> - <IO name="Audio 15" id="1088698485116451" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=15:signal=15" mode="Normal" diskstream-id="1088698485116518"> + <IO name="Audio 15" id="1088698485116451" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242012" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242011"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242015" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242014"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241770"/> </IO> + <controllable name="solo" id="1191241779"/> + <controllable name="mute" id="1191241780"/> + <remote_control id="16"/> <extra> - <GUI color="34243:17628:4689" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="34243:17628:4689" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241781"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=16:signal=16" diskstream-id="1088698485412133"> - <IO name="Audio 16" id="1088698485412068" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=16:signal=16" mode="Normal" diskstream-id="1088698485412133"> + <IO name="Audio 16" id="1088698485412068" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242018" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242017"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242021" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242020"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241783"/> </IO> + <controllable name="solo" id="1191241792"/> + <controllable name="mute" id="1191241793"/> + <remote_control id="17"/> <extra> - <GUI color="2155:38658:37648" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="2155:38658:37648" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241794"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=17:signal=17" diskstream-id="1088698520418087"> - <IO name="Audio 17" id="1088698520418023" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=17:signal=17" mode="Normal" diskstream-id="1088698520418087"> + <IO name="Audio 17" id="1088698520418023" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242024" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242023"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242027" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242026"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241796"/> </IO> + <controllable name="solo" id="1191241805"/> + <controllable name="mute" id="1191241806"/> + <remote_control id="18"/> <extra> - <GUI color="13448:46354:22734" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="13448:46354:22734" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241807"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=18:signal=18" diskstream-id="1088698520803734"> - <IO name="Audio 18" id="1088698520803668" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=18:signal=18" mode="Normal" diskstream-id="1088698520803734"> + <IO name="Audio 18" id="1088698520803668" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242030" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242029"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242033" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242032"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241809"/> </IO> + <controllable name="solo" id="1191241818"/> + <controllable name="mute" id="1191241819"/> + <remote_control id="19"/> <extra> - <GUI color="30258:17723:44638" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="30258:17723:44638" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241820"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=19:signal=19" diskstream-id="1088698521138071"> - <IO name="Audio 19" id="1088698521138004" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=19:signal=19" mode="Normal" diskstream-id="1088698521138071"> + <IO name="Audio 19" id="1088698521138004" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242036" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242035"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242039" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242038"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241822"/> </IO> + <controllable name="solo" id="1191241831"/> + <controllable name="mute" id="1191241832"/> + <remote_control id="20"/> <extra> - <GUI color="6216:8272:18025" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6216:8272:18025" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241833"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=20:signal=20" diskstream-id="1088698521481727"> - <IO name="Audio 20" id="1088698521481661" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=20:signal=20" mode="Normal" diskstream-id="1088698521481727"> + <IO name="Audio 20" id="1088698521481661" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242042" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242041"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242045" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242044"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241835"/> </IO> + <controllable name="solo" id="1191241844"/> + <controllable name="mute" id="1191241845"/> + <remote_control id="21"/> <extra> - <GUI color="32165:38920:20541" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="32165:38920:20541" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241846"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=21:signal=21" diskstream-id="1088698521848332"> - <IO name="Audio 21" id="1088698521848267" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=21:signal=21" mode="Normal" diskstream-id="1088698521848332"> + <IO name="Audio 21" id="1088698521848267" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242048" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242047"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242051" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242050"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241848"/> </IO> + <controllable name="solo" id="1191241857"/> + <controllable name="mute" id="1191241858"/> + <remote_control id="22"/> <extra> - <GUI color="15351:46898:27044" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="15351:46898:27044" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241859"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=22:signal=22" diskstream-id="1088698522224190"> - <IO name="Audio 22" id="1088698522224124" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=22:signal=22" mode="Normal" diskstream-id="1088698522224190"> + <IO name="Audio 22" id="1088698522224124" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242054" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242053"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242057" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242056"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241861"/> </IO> + <controllable name="solo" id="1191241870"/> + <controllable name="mute" id="1191241871"/> + <remote_control id="23"/> <extra> - <GUI color="14822:1285:13186" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="14822:1285:13186" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241872"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=23:signal=23" diskstream-id="1088698522620517"> - <IO name="Audio 23" id="1088698522620452" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=23:signal=23" mode="Normal" diskstream-id="1088698522620517"> + <IO name="Audio 23" id="1088698522620452" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242060" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242059"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242063" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242062"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241874"/> </IO> + <controllable name="solo" id="1191241883"/> + <controllable name="mute" id="1191241884"/> + <remote_control id="24"/> <extra> - <GUI color="46366:37284:30421" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="46366:37284:30421" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241885"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=24:signal=24" diskstream-id="1088698523020752"> - <IO name="Audio 24" id="1088698523020686" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=24:signal=24" mode="Normal" diskstream-id="1088698523020752"> + <IO name="Audio 24" id="1088698523020686" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242066" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242065"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191242069" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191242068"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241887"/> </IO> + <controllable name="solo" id="1191241896"/> + <controllable name="mute" id="1191241897"/> + <remote_control id="25"/> <extra> - <GUI color="10759:12329:43284" strip_width="wide" shown_mixer="yes" track_height="normal" shown_editor="yes"/> + <GUI color="10759:12329:43284" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241898"/> </Route> </Routes> <EditGroups/> <MixGroups/> <Playlists/> + <UnusedPlaylists/> <Click> - <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/> + <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"/> + <controllable name="gaincontrol" id="1191241900"/> </IO> </Click> <TempoMap> <Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/> <Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/> </TempoMap> + <ControlProtocols> + <Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes"> + <controls/> + </Protocol> + </ControlProtocols> </Session> diff --git a/templates/4 Tracks.template.in b/templates/4 Tracks.template.in index d01ef1aa7d..41369d6b25 100644 --- a/templates/4 Tracks.template.in +++ b/templates/4 Tracks.template.in @@ -1,116 +1,221 @@ -<?xml version="1.0"?> -<Session version="0.821.0"> - <Options> - <recording-plugins val="no"/> - <slave type="none"/> - <send-midi-timecode val="no"/> - <send-midi-machine-control val="no"/> - <input-auto-connect val="1"/> - <output-auto-connect val="2"/> - <max-level val="0"/> - <min-level val="0"/> - <meter-hold val="10.000000"/> - <long-over-length val="10"/> - <short-over-length val="2"/> - <shuttle-speed-factor val="1.000000"/> - <shuttle-speed-threshold val="5.000000"/> - <rf-speed val="2.000000"/> - <smpte-frames-per-second val="30.000000"/> - <edit-mode val="slide"/> - <auto-play val="no"/> - <auto-input val="no"/> - <seamless-loop val="no"/> - <punch-in val="no"/> - <punch-out val="no"/> - <all-safe val="no"/> - <auto-return val="no"/> - <mmc-control val="no"/> - <recording-plugins val="no"/> - <auto-crossfade val="no"/> - <audible-click val="no"/> - <align-style val="existing"/> - </Options> +<?xml version="1.0" encoding="UTF-8"?> +<Session version="2.0.0" id-counter="1191241255"> + <Config> + <Option name="output-auto-connect" value="2"/> + <Option name="input-auto-connect" value="1"/> + <Option name="mtc-port-name" value="control"/> + <Option name="mmc-port-name" value="control"/> + <Option name="midi-port-name" value="control"/> + <Option name="mmc-control" value="0"/> + <Option name="midi-feedback" value="0"/> + <Option name="xfade-model" value="0"/> + <Option name="edit-mode" value="0"/> + <Option name="layer-model" value="0"/> + <Option name="solo-model" value="0"/> + <Option name="all-safe" value="0"/> + <Option name="auto-play" value="0"/> + <Option name="auto-return" value="0"/> + <Option name="auto-input" value="1"/> + <Option name="punch-in" value="0"/> + <Option name="punch-out" value="0"/> + <Option name="seamless-loop" value="0"/> + <Option name="rf-speed" value="2"/> + <Option name="shuttle-speed-factor" value="1"/> + <Option name="shuttle-speed-threshold" value="5"/> + <Option name="meter-hold" value="10"/> + <Option name="meter-falloff" value="1.5"/> + <end-marker-is-free val="no"/> + </Config> <Sources/> <Regions/> <DiskStreams> - <DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/> - <DiskStream channels="2" playlist="Audio 2.1" speed="1.000000" name="Audio 2" id="1088698381722129"/> - <DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/> - <DiskStream channels="2" playlist="Audio 4.1" speed="1.000000" name="Audio 4" id="1088698419943526"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" name="Audio 1" id="1088698381595945"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 2.1" speed="1" name="Audio 2" id="1088698381722129"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" name="Audio 3" id="1088698419793849"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 4.1" speed="1" name="Audio 4" id="1088698419943526"/> </DiskStreams> <Locations> - <Location name="end" start="14400000" end="14400000" flags="33"/> - <Location name="Loop" start="0" end="14400000" flags="12"/> - <Location name="Punch" start="0" end="14400000" flags="10"/> + <Location id="1191241256" name="start" start="0" end="0" flags="IsMark,IsStart"/> + <Location id="1191241257" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/> </Locations> <Connections/> <Routes> - <Route flags="0x2" muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> - <IO name="master" id="1088698373992392" inputs="{ardour:Audio 4/out 1,ardour:Audio 3/out 1,ardour:Audio 2/out 1,ardour:Audio 1/out 1}{ardour:Audio 4/out 2,ardour:Audio 3/out 2,ardour:Audio 2/out 2,ardour:Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1" iolimits="-1,2,-1,2" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route flags="MasterOut" default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> + <IO name="master" id="1088698373992392" inputs="{Audio 4/out 1,Audio 3/out 1,Audio 2/out 1,Audio 1/out 1}{Audio 4/out 2,Audio 3/out 2,Audio 2/out 2,Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1.000000000000" iolimits="-1,2,-1,2"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241195" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241194"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241198" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241197"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241109"/> </IO> + <controllable name="solo" id="1191241118"/> + <controllable name="mute" id="1191241119"/> + <remote_control id="1"/> <extra> - <GUI color="3746:15634:28532" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="3746:15634:28532" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" diskstream-id="1088698381595945"> - <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" mode="Normal" diskstream-id="1088698381595945"> + <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241201" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241200"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241204" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241203"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241121"/> </IO> + <controllable name="solo" id="1191241130"/> + <controllable name="mute" id="1191241131"/> + <remote_control id="2"/> <extra> - <GUI color="25329:39287:16285" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="25329:39287:16285" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241132"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" diskstream-id="1088698381722129"> - <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" mode="Normal" diskstream-id="1088698381722129"> + <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241207" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241206"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241210" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241209"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241134"/> </IO> + <controllable name="solo" id="1191241143"/> + <controllable name="mute" id="1191241144"/> + <remote_control id="3"/> <extra> - <GUI color="6057:31092:43721" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6057:31092:43721" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241145"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" diskstream-id="1088698419793849"> - <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" mode="Normal" diskstream-id="1088698419793849"> + <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241213" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241212"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241216" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241215"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241147"/> </IO> + <controllable name="solo" id="1191241156"/> + <controllable name="mute" id="1191241157"/> + <remote_control id="4"/> <extra> - <GUI color="21964:7276:28849" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21964:7276:28849" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241158"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" diskstream-id="1088698419943526"> - <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" mode="Normal" diskstream-id="1088698419943526"> + <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241219" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241218"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241222" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241221"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241160"/> </IO> + <controllable name="solo" id="1191241169"/> + <controllable name="mute" id="1191241170"/> + <remote_control id="5"/> <extra> - <GUI color="46694:21380:28653" shown_mixer="yes" track_height="normal" shown_editor="yes" strip_width="wide"/> + <GUI color="46694:21380:28653" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241171"/> </Route> </Routes> <EditGroups/> <MixGroups/> <Playlists/> + <UnusedPlaylists/> <Click> - <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/> + <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"/> + <controllable name="gaincontrol" id="1191241173"/> </IO> </Click> <TempoMap> <Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/> <Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/> </TempoMap> + <ControlProtocols> + <Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes"> + <controls/> + </Protocol> + </ControlProtocols> </Session> diff --git a/templates/8 Tracks.template.in b/templates/8 Tracks.template.in index 027ab59b38..1afe411390 100644 --- a/templates/8 Tracks.template.in +++ b/templates/8 Tracks.template.in @@ -1,164 +1,353 @@ -<?xml version="1.0"?> -<Session version="0.821.0"> - <Options> - <recording-plugins val="no"/> - <slave type="none"/> - <send-midi-timecode val="no"/> - <send-midi-machine-control val="no"/> - <input-auto-connect val="1"/> - <output-auto-connect val="2"/> - <max-level val="0"/> - <min-level val="0"/> - <meter-hold val="10.000000"/> - <long-over-length val="10"/> - <short-over-length val="2"/> - <shuttle-speed-factor val="1.000000"/> - <shuttle-speed-threshold val="5.000000"/> - <rf-speed val="2.000000"/> - <smpte-frames-per-second val="30.000000"/> - <edit-mode val="slide"/> - <auto-play val="no"/> - <auto-input val="no"/> - <seamless-loop val="no"/> - <punch-in val="no"/> - <punch-out val="no"/> - <all-safe val="no"/> - <auto-return val="no"/> - <mmc-control val="no"/> - <recording-plugins val="no"/> - <auto-crossfade val="no"/> - <audible-click val="no"/> - <align-style val="existing"/> - </Options> +<?xml version="1.0" encoding="UTF-8"?> +<Session version="2.0.0" id-counter="1191241420"> + <Config> + <Option name="output-auto-connect" value="2"/> + <Option name="input-auto-connect" value="1"/> + <Option name="mtc-port-name" value="control"/> + <Option name="mmc-port-name" value="control"/> + <Option name="midi-port-name" value="control"/> + <Option name="mmc-control" value="0"/> + <Option name="midi-feedback" value="0"/> + <Option name="xfade-model" value="0"/> + <Option name="edit-mode" value="0"/> + <Option name="layer-model" value="0"/> + <Option name="solo-model" value="0"/> + <Option name="all-safe" value="0"/> + <Option name="auto-play" value="0"/> + <Option name="auto-return" value="0"/> + <Option name="auto-input" value="1"/> + <Option name="punch-in" value="0"/> + <Option name="punch-out" value="0"/> + <Option name="seamless-loop" value="0"/> + <Option name="rf-speed" value="2"/> + <Option name="shuttle-speed-factor" value="1"/> + <Option name="shuttle-speed-threshold" value="5"/> + <Option name="meter-hold" value="10"/> + <Option name="meter-falloff" value="1.5"/> + <end-marker-is-free val="no"/> + </Config> <Sources/> <Regions/> <DiskStreams> - <DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/> - <DiskStream channels="2" playlist="Audio 2.1" speed="1.000000" name="Audio 2" id="1088698381722129"/> - <DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/> - <DiskStream channels="2" playlist="Audio 4.1" speed="1.000000" name="Audio 4" id="1088698419943526"/> - <DiskStream channels="2" playlist="Audio 5.1" speed="1.000000" name="Audio 5" id="1088698450528071"/> - <DiskStream channels="2" playlist="Audio 6.1" speed="1.000000" name="Audio 6" id="1088698450754348"/> - <DiskStream channels="2" playlist="Audio 7.1" speed="1.000000" name="Audio 7" id="1088698450937150"/> - <DiskStream channels="2" playlist="Audio 8.1" speed="1.000000" name="Audio 8" id="1088698451167172"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" name="Audio 1" id="1088698381595945"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 2.1" speed="1" name="Audio 2" id="1088698381722129"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" name="Audio 3" id="1088698419793849"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 4.1" speed="1" name="Audio 4" id="1088698419943526"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 5.1" speed="1" name="Audio 5" id="1088698450528071"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 6.1" speed="1" name="Audio 6" id="1088698450754348"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 7.1" speed="1" name="Audio 7" id="1088698450937150"/> + <AudioDiskstream flags="Recordable" channels="2" playlist="Audio 8.1" speed="1" name="Audio 8" id="1088698451167172"/> </DiskStreams> <Locations> - <Location name="end" start="14400000" end="14400000" flags="33"/> - <Location name="Loop" start="0" end="14400000" flags="12"/> - <Location name="Punch" start="0" end="14400000" flags="10"/> + <Location id="1191241421" name="start" start="0" end="0" flags="IsMark,IsStart"/> + <Location id="1191241422" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/> </Locations> <Connections/> <Routes> - <Route flags="0x2" muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> - <IO name="master" id="1088698373992392" inputs="{ardour:Audio 8/out 1,ardour:Audio 7/out 1,ardour:Audio 6/out 1,ardour:Audio 5/out 1,ardour:Audio 4/out 1,ardour:Audio 3/out 1,ardour:Audio 2/out 1,ardour:Audio 1/out 1}{ardour:Audio 8/out 2,ardour:Audio 7/out 2,ardour:Audio 6/out 2,ardour:Audio 5/out 2,ardour:Audio 4/out 2,ardour:Audio 3/out 2,ardour:Audio 2/out 2,ardour:Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1" iolimits="-1,2,-1,2" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route flags="MasterOut" default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=0:signal=0"> + <IO name="master" id="1088698373992392" inputs="{Audio 8/out 1,Audio 7/out 1,Audio 6/out 1,Audio 5/out 1,Audio 4/out 1,Audio 3/out 1,Audio 2/out 1,Audio 1/out 1}{Audio 8/out 2,Audio 7/out 2,Audio 6/out 2,Audio 5/out 2,Audio 4/out 2,Audio 3/out 2,Audio 2/out 2,Audio 1/out 2}" outputs="{%JACK_INPUT%1}{%JACK_INPUT%2}" gain="1.000000000000" iolimits="-1,2,-1,2"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241308" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241307"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241311" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241310"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241170"/> </IO> + <controllable name="solo" id="1191241179"/> + <controllable name="mute" id="1191241180"/> + <remote_control id="1"/> <extra> - <GUI color="3746:15634:28532" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="3746:15634:28532" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" diskstream-id="1088698381595945"> - <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=1:signal=1" mode="Normal" diskstream-id="1088698381595945"> + <IO name="Audio 1" id="1088698381595877" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241314" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241313"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241317" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241316"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241182"/> </IO> + <controllable name="solo" id="1191241191"/> + <controllable name="mute" id="1191241192"/> + <remote_control id="2"/> <extra> - <GUI color="25329:39287:16285" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="25329:39287:16285" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241193"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" diskstream-id="1088698381722129"> - <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=2:signal=2" mode="Normal" diskstream-id="1088698381722129"> + <IO name="Audio 2" id="1088698381722065" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241320" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241319"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241323" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241322"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241195"/> </IO> + <controllable name="solo" id="1191241204"/> + <controllable name="mute" id="1191241205"/> + <remote_control id="3"/> <extra> - <GUI color="6057:31092:43721" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="6057:31092:43721" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241206"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" diskstream-id="1088698419793849"> - <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=3:signal=3" mode="Normal" diskstream-id="1088698419793849"> + <IO name="Audio 3" id="1088698419793786" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241326" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241325"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241329" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241328"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241208"/> </IO> + <controllable name="solo" id="1191241217"/> + <controllable name="mute" id="1191241218"/> + <remote_control id="4"/> <extra> - <GUI color="21964:7276:28849" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="21964:7276:28849" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241219"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" diskstream-id="1088698419943526"> - <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=4:signal=4" mode="Normal" diskstream-id="1088698419943526"> + <IO name="Audio 4" id="1088698419943460" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241332" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241331"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241335" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241334"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241221"/> </IO> + <controllable name="solo" id="1191241230"/> + <controllable name="mute" id="1191241231"/> + <remote_control id="5"/> <extra> - <GUI color="46694:21380:28653" track_height="normal" strip_width="wide" shown_mixer="yes" shown_editor="yes"/> + <GUI color="46694:21380:28653" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241232"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" diskstream-id="1088698450528071"> - <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=5:signal=5" mode="Normal" diskstream-id="1088698450528071"> + <IO name="Audio 5" id="1088698450528006" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241338" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241337"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241341" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241340"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241234"/> </IO> + <controllable name="solo" id="1191241243"/> + <controllable name="mute" id="1191241244"/> + <remote_control id="6"/> <extra> - <GUI color="29643:15912:24582" track_height="normal" shown_mixer="yes" shown_editor="yes" strip_width="wide"/> + <GUI color="29643:15912:24582" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241245"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" diskstream-id="1088698450754348"> - <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=6:signal=6" mode="Normal" diskstream-id="1088698450754348"> + <IO name="Audio 6" id="1088698450754242" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241344" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241343"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241347" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241346"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241247"/> </IO> + <controllable name="solo" id="1191241256"/> + <controllable name="mute" id="1191241257"/> + <remote_control id="7"/> <extra> - <GUI color="32959:22941:32677" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="32959:22941:32677" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241258"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" diskstream-id="1088698450937150"> - <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=7:signal=7" mode="Normal" diskstream-id="1088698450937150"> + <IO name="Audio 7" id="1088698450937083" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241350" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241349"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241353" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241352"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241260"/> </IO> + <controllable name="solo" id="1191241269"/> + <controllable name="mute" id="1191241270"/> + <remote_control id="8"/> <extra> - <GUI color="44734:28458:19344" strip_width="wide" track_height="normal" shown_mixer="yes" shown_editor="yes"/> + <GUI color="44734:28458:19344" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241271"/> </Route> - <Route muted="no" soloed="no" phase-invert="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" diskstream-id="1088698451167172"> - <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0"> - <StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> - <StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/> + <Route default-type="audio" active="yes" muted="no" soloed="no" phase-invert="no" denormal-protection="no" mute-affects-pre-fader="yes" mute-affects-post-fader="yes" mute-affects-control-outs="yes" mute-affects-main-outs="yes" order-keys="editor=8:signal=8" mode="Normal" diskstream-id="1088698451167172"> + <IO name="Audio 8" id="1088698451167106" inputs="{%JACK_OUTPUT%1}{%JACK_OUTPUT%2}" outputs="{master/in 1}{master/in 2}" gain="1.000000000000" iolimits="1,-1,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"> + <Output x="0" y="0"/> + <Output x="1" y="0"/> + <StreamPanner x="0" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241356" default="0" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241355"/> + </StreamPanner> + <StreamPanner x="1" type="Equal Power Stereo" muted="no"> + <Automation> + <AutomationList id="1191241359" default="1" min_yval="0" max_yval="1" max_xval="0" state="Off" style="Absolute"/> + </Automation> + <controllable name="panner" id="1191241358"/> + </StreamPanner> </Panner> + <controllable name="gaincontrol" id="1191241273"/> </IO> + <controllable name="solo" id="1191241282"/> + <controllable name="mute" id="1191241283"/> + <remote_control id="9"/> <extra> - <GUI color="21903:23957:19369" strip_width="wide" shown_mixer="yes" track_height="normal" shown_editor="yes"/> + <GUI color="21903:23957:19369" strip_width="Wide" shown_mixer="yes" shown_editor="yes" track_height="normal"> + <gain track_height="normal" shown="no"/> + <pan track_height="normal" shown="no"/> + </GUI> </extra> + <alignment style="ExistingMaterial"/> + <controllable name="recenable" id="1191241284"/> </Route> </Routes> <EditGroups/> <MixGroups/> <Playlists/> + <UnusedPlaylists/> <Click> - <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1"> - <Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/> + <IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1"> + <Panner linked="no" link_direction="SameDirection" bypassed="no"/> + <controllable name="gaincontrol" id="1191241286"/> </IO> </Click> <TempoMap> <Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/> <Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/> </TempoMap> + <ControlProtocols> + <Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes"> + <controls/> + </Protocol> + </ControlProtocols> </Session> |