Merge with 2.0-ongoing R2885.
authorDavid Robillard <d@drobilla.net>
Sat, 12 Jan 2008 23:45:50 +0000 (23:45 +0000)
committerDavid Robillard <d@drobilla.net>
Sat, 12 Jan 2008 23:45:50 +0000 (23:45 +0000)
Fix loading of 2.0 sessions.

git-svn-id: svn://localhost/ardour2/trunk@2904 d708f5d6-7413-0410-9779-e7cbd77b26cf

64 files changed:
SConstruct
ardour.rc.in
gtk2_ardour/ardour_ui.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_selection.cc
gtk2_ardour/engine_dialog.cc
gtk2_ardour/marker.cc
gtk2_ardour/marker.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/new_session_dialog.cc
gtk2_ardour/new_session_dialog.h
gtk2_ardour/po/sv_SE.po
libs/ardour/ardour/audio_unit.h
libs/ardour/ardour/ladspa_plugin.h
libs/ardour/ardour/plugin.h
libs/ardour/ardour/plugin_insert.h
libs/ardour/ardour/plugin_state.h [deleted file]
libs/ardour/ardour/port_insert.h
libs/ardour/ardour/processor.h
libs/ardour/ardour/rb_effect.h
libs/ardour/ardour/vst_plugin.h
libs/ardour/audio_unit.cc
libs/ardour/audioregion.cc
libs/ardour/ladspa_plugin.cc
libs/ardour/plugin_manager.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/vst_plugin.cc
libs/gtkmm2ext/fastmeter.cc
libs/vamp-sdk/COPYING [new file with mode: 0644]
libs/vamp-sdk/README [new file with mode: 0644]
libs/vamp-sdk/SConscript [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/Plugin.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/PluginAdapter.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/PluginBase.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/RealTime.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/RealTime.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in [new file with mode: 0644]
libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in [new file with mode: 0644]
libs/vamp-sdk/vamp/vamp.h [new file with mode: 0644]
libs/vamp-sdk/vamp/vamp.pc.in [new file with mode: 0644]
svn_revision.h
templates/16 Tracks.template.in
templates/2 Track.template.in
templates/32 Tracks.template.in
templates/4 Tracks.template.in
templates/8 Tracks.template.in

index 8a7364b7c1ad3aa0cfe4552b2b5935fce1a5aefe..651a6a3eab3607205d5e576fab578956d1026f8a 100644 (file)
@@ -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))
 
index bbc0f091ec0ba480eaf4d05fae1a065ac554226c..ed40ac465a2d07a0af085447aa2d4de4ca98df96 100644 (file)
@@ -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"/>
index 70dac73a59fdeff0aff8e692fb5af707da459471..ca77ccb90316826a36059215d92d7ae481b80647 100644 (file)
@@ -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;
index 325584f7ed7405d8baacaa12a11e41279f690a1e..41261b7079b868813b56a7aad44f64f3b627e67a 100644 (file)
@@ -900,19 +900,6 @@ Editor::show_window ()
        present ();
 }
 
-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 ()
 {
@@ -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 */
index 14ed3a46a8d1178ae3901c1dbd501b7c47184f9b..bfdbcd4a6c216656c3d3dea8ea56b8f58d6a32bc 100644 (file)
@@ -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*);
 
index e881b02a4eacd081a49ed613c05115dd7a7b360c..c8cde42754a0a812d76245fa02db43b823fea6c9 100644 (file)
@@ -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);
index 68e0f62be463bc2985c494f881cb2a0403b57fe0..e526d2d0db8ea019543cc8d4e30dbdd51d6d54b7 100644 (file)
@@ -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 ()
index e6fb32feca19000ac3fa91a3cc0b64fdb29cf97a..13e8f49d61be9fd0462e4969ed51c069f6f42c36 100644 (file)
@@ -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 ();
        }
 
index 35f410eb25590bcba6af10f67b4ff2fbd38be966..048277fea7ab09bae5d7ff35cb7d649a7279a4e6 100644 (file)
@@ -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 {
 
index 4919091a620b0625c10a9854a98603fc7048d25b..7df3d1dfe999baf53cc8657f462efcc4d41ef348 100644 (file)
@@ -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());
        }
 }
 
index 87b9eba6f72e1ca49de140af38c2dc59fe7bed5d..7c7570127012ac0e20f4960305b63d3d09b87b21 100644 (file)
@@ -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;
index e511e59af2f8e1037b111008be929f2623ffcf98..c1ffcefb2b9306f1f0bc8da92fe67bb6495af9cc 100644 (file)
@@ -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;
index 6e37908d1b3b1e01efee1c4b5eb2b070a740d785..771683d80efa6a74ac37967983f9dba0f4502e78 100644 (file)
@@ -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;
        }
 }
 
index fa252571fb95796116e7fa7b988818e1b147c229..1a53726ede0992833ce38f438a06b335b2dcd0b2 100644 (file)
@@ -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;
index 94c687f829ef71caf24de848843b4659257906e9..f7a1d48a50037aee4702d1c6ab21a42d2df0c2f9 100644 (file)
@@ -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);
                }
index 820a614ecc793906ee62aeba98ae6befd3eb2688..db970b4d460033f9cd31df53b674ceab2c350cb6 100644 (file)
@@ -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
index 6f0820168b97fc8a939e15d48f5708e3f537b182..aa6911f36075c1da68c9190d2d9d82f8ab8054aa 100644 (file)
@@ -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();
 
index 9804869d9510956f1b40ffc7f24981a966268c1f..b6c4a01b1bdb0b5b584d2a1a07c1582b194dcc4f 100644 (file)
@@ -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"
index b0e4d34c2804afe948ba4c09faf08b201b1ed066..115e008a54050d13c0a777dd827d60c18b73bf44 100644 (file)
@@ -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;
index 7c0b0b2abed2695e699f303db0ff97e9ff43e900..976584b68798494f959f8ef967c0baeeedc80a70 100644 (file)
@@ -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);
index d721476db7b51f3b3473168f6373303b8d9a60f1..73f89f1a918f6221ab70b0f81c94d76cd701f4d3 100644 (file)
@@ -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;
index 2038153d8601ed6a8d0d8076520cf6f5783c9e31..42c53c487c8663e6b1c27ab2f62fd4365f3be7bf 100644 (file)
@@ -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 (file)
index bd499e2..0000000
+++ /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__ */
index 114d196750234ea11bc7c5e7241ebca5e6bfdbb5..1743040bf57945415308c92a93d8c277b5ba9ed0 100644 (file)
@@ -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;
index bf9dfe0430945a1f80c3f3e740a3181b74daf8f2..d3e95e8ebffb553cfbd4fee4c70a69ba976b8006 100644 (file)
@@ -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>
index bde04223357c567be9ce5f285562fd7f1ee0c388..a536a309b3a0cdf82a3277524159de6d246d70d0 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef __ardour_rbeffect_h__
 #define __ardour_rbeffect_h__
 
-#include <ardour/audiofilter.h>
+#include <ardour/filter.h>
 
 namespace ARDOUR {
 
index 3a05360f157923a7917ac982b6a0ebbdfa3dc1a6..e41d000f9cf0581abac9a1e71a9ba3f58d5ce289 100644 (file)
@@ -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;
index f86e78416955b5f8ed71c5739c85a59631af7ad2..9f19a21865ee21326286a02ac7468107026da6da 100644 (file)
@@ -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)
 {
index f1534827fde2cf232736373c08812a78289b695b..86abd4beaa0f1fb3c339c425f81022e7ad4e3308 100644 (file)
@@ -636,7 +636,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
                                        set_fade_out_active (false);
                                }
                        }
-               
+
                } 
        }
 
index 696ada3b81faf8488f0efdc9e66b8253c9b30221..ccc12f8cf8a394dc80fd1a5c3718e2d5f2b52aad 100644 (file)
@@ -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;
        }
 
index f0465d0ad5c4ffc6ea1691c4e143e67dc76916d1..d321d6f259804c2eaeb43b23c212c20f703d4054 100644 (file)
@@ -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;
 
index cef5c7df485fddd9becf38585663d1a3872b8330..19d562f84421beb4974ef574828641db9c98cda4 100644 (file)
@@ -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
index a08d09d94946f56d50b1dae12ca2dbcbf9ec6363..d8d3d828105b4cea83f1aa1df4e1092d81dd2a8b 100644 (file)
@@ -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
index 5969d91982f0e94215fd37974cef59e23ae6714d..47b5cb4fba792f011af025b1ab5fbf18b5cec9ad 100644 (file)
@@ -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)
-{
-
-}
index 60fb35b969bccc4a03d0d70e72561a59702efbd0..1b440aaac9780224f21b8a6931e3627ed480f7e3 100644 (file)
@@ -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 (file)
index 0000000..19fa472
--- /dev/null
@@ -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 (file)
index 0000000..9454038
--- /dev/null
@@ -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 (file)
index 0000000..ddd3d8e
--- /dev/null
@@ -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 (file)
index 0000000..159bf4f
--- /dev/null
@@ -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 (file)
index 0000000..1549b4f
--- /dev/null
@@ -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 (file)
index 0000000..bfc9750
--- /dev/null
@@ -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 (file)
index 0000000..38d2b49
--- /dev/null
@@ -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 (file)
index 0000000..12e1539
--- /dev/null
@@ -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 (file)
index 0000000..80ae620
--- /dev/null
@@ -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 (file)
index 0000000..0b541cc
--- /dev/null
@@ -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 (file)
index 0000000..4dd78fd
--- /dev/null
@@ -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 (file)
index 0000000..3ce51ce
--- /dev/null
@@ -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 (file)
index 0000000..a2b4d89
--- /dev/null
@@ -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 (file)
index 0000000..3fc0d74
--- /dev/null
@@ -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 (file)
index 0000000..73da053
--- /dev/null
@@ -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 (file)
index 0000000..cb71fc4
--- /dev/null
@@ -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 (file)
index 0000000..82ae22b
--- /dev/null
@@ -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 (file)
index 0000000..dcbdf5b
--- /dev/null
@@ -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 (file)
index 0000000..d5ec1da
--- /dev/null
@@ -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 (file)
index 0000000..83362dc
--- /dev/null
@@ -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 (file)
index 0000000..1674afe
--- /dev/null
@@ -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 (file)
index 0000000..4f0145a
--- /dev/null
@@ -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 (file)
index 0000000..82d4dec
--- /dev/null
@@ -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} 
index cb5597281db62defd4ab2e14461ef323e2636b50..fc376f40160f4864274a30979206f38b0aa07968 100644 (file)
@@ -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
index 786f41e0e29dbc056217ee8eed96498314c80cd5..e427d2b9702c92a54bf52a136dab7e4f16653ca6 100644 (file)
-<?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>
index 3d798d77b4b8c61bda1c6a5c00c5741684ccbdf1..c9f70455f79682a4a593919e0c8fa0c628359da5 100644 (file)
-<?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>
index 65f325bcc82fd555deef0fe232df56f480ff2c5e..8b95ef76296ba5c22d862c6e18ee140c84fd48a6 100644 (file)
-<?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>
index d01ef1aa7de1bb02c48d873ffbac6f95300f901a..41369d6b25d0e6b4a7ab536a2efd4bc5ad48ca19 100644 (file)
-<?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>
index 027ab59b3823ccd9554d23406c2f925f3b09ef6e..1afe411390cdc944ad6f75df0b54e12393f1a649 100644 (file)
-<?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>