mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 16:24:57 +01:00
Merge with 2.0-ongoing R2885.
Fix loading of 2.0 sessions. git-svn-id: svn://localhost/ardour2/trunk@2904 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
bf256c1681
commit
e92c1669c1
64 changed files with 7929 additions and 1269 deletions
47
SConstruct
47
SConstruct
|
|
@ -231,6 +231,7 @@ def i18n (buildenv, sources, installenv):
|
||||||
buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
|
buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
|
||||||
mo_file = po_file.replace (".po", ".mo")
|
mo_file = po_file.replace (".po", ".mo")
|
||||||
installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
|
installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
|
||||||
|
installenv.Alias ('msgupdate', buildenv.MoBuild (mo_file, po_file))
|
||||||
|
|
||||||
for lang in languages:
|
for lang in languages:
|
||||||
modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
|
modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
|
||||||
|
|
@ -363,7 +364,7 @@ def distcopy (target, source, env):
|
||||||
return p.close ()
|
return p.close ()
|
||||||
|
|
||||||
def tarballer (target, source, env):
|
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, ' ... '
|
print 'running ', cmd, ' ... '
|
||||||
p = os.popen (cmd)
|
p = os.popen (cmd)
|
||||||
return p.close ()
|
return p.close ()
|
||||||
|
|
@ -766,34 +767,32 @@ def prep_libcheck(topenv, libinfo):
|
||||||
|
|
||||||
prep_libcheck(env, env)
|
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
|
env['RUBBERBAND'] = False
|
||||||
|
|
||||||
#conf = env.Configure (custom_tests = { 'CheckPKGExists' : CheckPKGExists } )
|
#conf = Configure (env)
|
||||||
#
|
#
|
||||||
#if conf.CheckPKGExists('vamp-sdk'):
|
#if conf.CheckHeader ('fftw3.h'):
|
||||||
# have_vamp = True
|
# env['RUBBERBAND'] = True
|
||||||
# libraries['vamp'].ParseConfig('pkg-config --cflags --libs vamp-sdk')
|
# libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
|
||||||
|
# LIBPATH='#libs/rubberband',
|
||||||
|
# CPPPATH='#libs/rubberband',
|
||||||
|
# CCFLAGS='-DUSE_RUBBERBAND')
|
||||||
#else:
|
#else:
|
||||||
# have_vamp = False
|
# 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 ""
|
||||||
#
|
#
|
||||||
#libraries['vamp'] = conf.Finish ()
|
#conf.Finish()
|
||||||
#
|
|
||||||
#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 ()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for libusb
|
# Check for libusb
|
||||||
|
|
@ -995,6 +994,7 @@ if env['SYSLIBS']:
|
||||||
'libs/pbd',
|
'libs/pbd',
|
||||||
'libs/midi++2',
|
'libs/midi++2',
|
||||||
'libs/ardour',
|
'libs/ardour',
|
||||||
|
'libs/vamp-sdk',
|
||||||
# these are unconditionally included but have
|
# these are unconditionally included but have
|
||||||
# tests internally to avoid compilation etc
|
# tests internally to avoid compilation etc
|
||||||
# if VST is not set
|
# if VST is not set
|
||||||
|
|
@ -1068,6 +1068,7 @@ else:
|
||||||
'libs/pbd',
|
'libs/pbd',
|
||||||
'libs/midi++2',
|
'libs/midi++2',
|
||||||
'libs/ardour',
|
'libs/ardour',
|
||||||
|
'libs/vamp-sdk',
|
||||||
# these are unconditionally included but have
|
# these are unconditionally included but have
|
||||||
# tests internally to avoid compilation etc
|
# tests internally to avoid compilation etc
|
||||||
# if VST is not set
|
# if VST is not set
|
||||||
|
|
@ -1132,7 +1133,7 @@ else:
|
||||||
timefx_subdirs = ['libs/soundtouch']
|
timefx_subdirs = ['libs/soundtouch']
|
||||||
#if env['RUBBERBAND']:
|
#if env['RUBBERBAND']:
|
||||||
# timefx_subdirs += ['libs/rubberband']
|
# timefx_subdirs += ['libs/rubberband']
|
||||||
|
|
||||||
opts.Save('scache.conf', env)
|
opts.Save('scache.conf', env)
|
||||||
Help(opts.GenerateHelpText(env))
|
Help(opts.GenerateHelpText(env))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,9 @@
|
||||||
<Option name="destructive-xfade-msecs" value="20"/>
|
<Option name="destructive-xfade-msecs" value="20"/>
|
||||||
<Option name="periodic-safety-backups" value="1"/>
|
<Option name="periodic-safety-backups" value="1"/>
|
||||||
<Option name="periodic-safety-backup-interval" value="120"/>
|
<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>
|
</Config>
|
||||||
<extra>
|
<extra>
|
||||||
<Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
|
<Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
|
||||||
|
|
|
||||||
|
|
@ -1341,7 +1341,6 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...) {
|
catch (...) {
|
||||||
cerr << "About to complain about JACK\n";
|
|
||||||
MessageDialog msg (*editor,
|
MessageDialog msg (*editor,
|
||||||
_("There are insufficient JACK ports available\n\
|
_("There are insufficient JACK ports available\n\
|
||||||
to create a new track or bus.\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] == '/' ||
|
if (session_name[0] == '/' ||
|
||||||
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
|
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
|
||||||
(session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
|
(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)) {
|
if (load_session (Glib::path_get_dirname (session_name), session_name)) {
|
||||||
response = Gtk::RESPONSE_NONE;
|
response = Gtk::RESPONSE_NONE;
|
||||||
goto try_again;
|
goto try_again;
|
||||||
|
|
|
||||||
|
|
@ -900,19 +900,6 @@ Editor::show_window ()
|
||||||
present ();
|
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
|
void
|
||||||
Editor::instant_save ()
|
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);
|
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
|
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)
|
||||||
{
|
{
|
||||||
build_track_context_menu (frame)->popup (button, time);
|
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*
|
Menu*
|
||||||
Editor::build_track_context_menu (nframes_t frame)
|
Editor::build_track_context_menu (nframes_t ignored)
|
||||||
{
|
{
|
||||||
using namespace Menu_Helpers;
|
using namespace Menu_Helpers;
|
||||||
|
|
||||||
Menu* menu = manage (new Menu);
|
MenuList& edit_items = track_context_menu.items();
|
||||||
MenuList& edit_items = menu->items();
|
|
||||||
edit_items.clear();
|
edit_items.clear();
|
||||||
|
|
||||||
/* Build the general `track' context menu, adding what is appropriate given
|
add_dstream_context_items (edit_items);
|
||||||
the current selection */
|
return &track_context_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu*
|
||||||
|
Editor::build_track_bus_context_menu (nframes_t ignored)
|
||||||
|
{
|
||||||
|
using namespace Menu_Helpers;
|
||||||
|
|
||||||
|
MenuList& edit_items = track_context_menu.items();
|
||||||
|
edit_items.clear();
|
||||||
|
|
||||||
|
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);
|
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_axisview);
|
||||||
|
|
||||||
if (atv) {
|
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)) {
|
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;
|
AudioPlaylist::Crossfades xfades;
|
||||||
|
|
||||||
apl->crossfades_at (frame, xfades);
|
apl->crossfades_at (frame, xfades);
|
||||||
|
|
||||||
bool many = xfades.size() > 1;
|
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) {
|
for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) {
|
||||||
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
|
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||||
|
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete regions;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!selection->time.empty()) {
|
|
||||||
add_selection_context_items (edit_items);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selection->regions.empty()) {
|
add_dstream_context_items (edit_items);
|
||||||
add_region_context_items (edit_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selection->tracks.empty()) {
|
return &track_crossfade_context_menu;
|
||||||
add_bus_or_audio_track_context_items (edit_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu->set_name ("ArdourContextMenu");
|
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FFT_ANALYSIS
|
#ifdef FFT_ANALYSIS
|
||||||
|
|
@ -1528,6 +1662,19 @@ Editor::analyze_range_selection()
|
||||||
}
|
}
|
||||||
#endif /* FFT_ANALYSIS */
|
#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.
|
/** Add context menu items relevant to crossfades.
|
||||||
* @param edit_items List to add the items to.
|
* @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
|
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;
|
using namespace Menu_Helpers;
|
||||||
sigc::connection fooc;
|
Menu *region_menu = manage (new Menu);
|
||||||
Menu *region_menu = manage (new Menu);
|
MenuList& items = region_menu->items();
|
||||||
MenuList& items = region_menu->items();
|
|
||||||
region_menu->set_name ("ArdourContextMenu");
|
region_menu->set_name ("ArdourContextMenu");
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Edit..."), mem_fun(*this, &Editor::edit_region)));
|
boost::shared_ptr<AudioRegion> ar;
|
||||||
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
|
boost::shared_ptr<MidiRegion> mr;
|
||||||
items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun (*this, &Editor::lower_region_to_bottom)));
|
|
||||||
|
|
||||||
Menu* sync_point_menu = manage (new Menu);
|
if (region) {
|
||||||
MenuList& sync_point_items = sync_point_menu->items();
|
ar = boost::dynamic_pointer_cast<AudioRegion> (region);
|
||||||
sync_point_menu->set_name("ArdourContextMenu");
|
mr = boost::dynamic_pointer_cast<MidiRegion> (region);
|
||||||
|
}
|
||||||
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)));
|
|
||||||
|
|
||||||
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);
|
region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
|
||||||
|
|
||||||
add_item_with_sensitivity (items, MenuElem (_("Export"), mem_fun(*this, &Editor::export_region)), selection->regions.size() == 1);
|
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
|
items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
|
||||||
items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
|
items.push_back (MenuElem (_("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)));
|
items.push_back (MenuElem (_("Bounce"), mem_fun(*this, &Editor::bounce_region_selection)));
|
||||||
|
|
||||||
#ifdef FFT_ANALYSIS
|
#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
|
#endif
|
||||||
|
|
||||||
items.push_back (SeparatorElem());
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
items.push_back (CheckMenuElem (_("Lock")));
|
sigc::connection fooc;
|
||||||
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
|
items.push_back (CheckMenuElem (_("Lock")));
|
||||||
|
CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
|
||||||
|
fooc = region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
|
||||||
if (region->locked()) {
|
if (region->locked()) {
|
||||||
fooc.block (true);
|
fooc.block (true);
|
||||||
region_lock_item->set_active();
|
region_lock_item->set_active();
|
||||||
fooc.block (false);
|
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")));
|
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));
|
fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
|
||||||
#if FIXUP_REGION_MENU
|
|
||||||
if (region->muted()) {
|
if (region->muted()) {
|
||||||
fooc.block (true);
|
fooc.block (true);
|
||||||
region_mute_item->set_active();
|
region_mute_item->set_active();
|
||||||
fooc.block (false);
|
fooc.block (false);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!Profile->get_sae()) {
|
if (!Profile->get_sae()) {
|
||||||
items.push_back (CheckMenuElem (_("Opaque")));
|
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));
|
fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
|
||||||
#if FIXUP_REGION_MENU
|
|
||||||
if (region->opaque()) {
|
if (region->opaque()) {
|
||||||
fooc.block (true);
|
fooc.block (true);
|
||||||
region_opaque_item->set_active();
|
region_opaque_item->set_active();
|
||||||
fooc.block (false);
|
fooc.block (false);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We allow "Original position" if at least one region is not at its
|
items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
|
||||||
natural position
|
if (region->at_natural_position()) {
|
||||||
*/
|
items.back().set_sensitive (false);
|
||||||
RegionSelection::iterator i = selection->regions.begin();
|
|
||||||
while (i != selection->regions.end() && (*i)->region()->at_natural_position() == true) {
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_with_sensitivity (items, MenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)), i != selection->regions.end());
|
|
||||||
|
|
||||||
items.push_back (SeparatorElem());
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
/* Find out if we have a selected audio region */
|
if (ar) {
|
||||||
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
|
|
||||||
|
|
||||||
MenuList& envelopes_items = envelopes_menu->items();
|
|
||||||
|
|
||||||
RegionView* rv = sv->find_view (ar);
|
RegionView* rv = sv->find_view (ar);
|
||||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
|
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
|
||||||
|
|
||||||
if (!Profile->get_sae()) {
|
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")));
|
items.push_back (CheckMenuElem (_("Envelope Visible")));
|
||||||
region_envelope_visible_item = static_cast<CheckMenuItem*> (&items.back());
|
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));
|
fooc = region_envelope_visible_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_gain_envelope_visibility));
|
||||||
if (arv->envelope_visible()) {
|
if (arv->envelope_visible()) {
|
||||||
fooc.block (true);
|
fooc.block (true);
|
||||||
|
|
@ -1744,8 +1846,8 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
|
||||||
fooc.block (false);
|
fooc.block (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
envelopes_items.push_back (CheckMenuElem (_("Envelope Active")));
|
items.push_back (CheckMenuElem (_("Envelope Active")));
|
||||||
region_envelope_active_item = static_cast<CheckMenuItem*> (&items.back());
|
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));
|
fooc = region_envelope_active_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_gain_envelope_active));
|
||||||
|
|
||||||
if (ar->envelope_active()) {
|
if (ar->envelope_active()) {
|
||||||
|
|
@ -1756,39 +1858,25 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
|
||||||
|
|
||||||
items.push_back (SeparatorElem());
|
items.push_back (SeparatorElem());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Envelopes"), *envelopes_menu));
|
|
||||||
|
|
||||||
#if FIXUP_REGION_MENU
|
|
||||||
if (ar->scale_amplitude() != 1.0f) {
|
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 {
|
} 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 (SeparatorElem());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items.push_back (MenuElem (_("Reverse"), mem_fun(*this, &Editor::reverse_region)));
|
||||||
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
/* range related stuff */
|
/* 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);
|
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)));
|
||||||
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 (SeparatorElem());
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
/* Nudge region */
|
/* Nudge region */
|
||||||
|
|
@ -1797,12 +1885,13 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
|
||||||
MenuList& nudge_items = nudge_menu->items();
|
MenuList& nudge_items = nudge_menu->items();
|
||||||
nudge_menu->set_name ("ArdourContextMenu");
|
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 fwd"), (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 bwd"), (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 fwd 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 bwd by capture offset"), (mem_fun(*this, &Editor::nudge_backward_capture_offset))));
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Nudge"), *nudge_menu));
|
items.push_back (MenuElem (_("Nudge"), *nudge_menu));
|
||||||
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
Menu *trim_menu = manage (new Menu);
|
Menu *trim_menu = manage (new Menu);
|
||||||
MenuList& trim_items = trim_menu->items();
|
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)));
|
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 (MenuElem (_("Trim"), *trim_menu));
|
||||||
|
items.push_back (SeparatorElem());
|
||||||
|
|
||||||
items.push_back (MenuElem (_("Split"), (mem_fun(*this, &Editor::split_region))));
|
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))));
|
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 (_("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 (_("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 (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
|
/* OK, stick the region submenu at the top of the list, and then add
|
||||||
the standard items.
|
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 (MenuElem (menu_item_name, *region_menu));
|
||||||
|
edit_items.push_back (SeparatorElem());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add context menu items relevant to selection ranges.
|
/** 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)));
|
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
|
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;
|
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 */
|
/* Playback */
|
||||||
|
|
||||||
Menu *play_menu = manage (new Menu);
|
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 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)));
|
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);
|
play_items.push_back (MenuElem (_("Play region"), mem_fun(*this, &Editor::play_selected_region)));
|
||||||
|
play_items.push_back (SeparatorElem());
|
||||||
add_item_with_sensitivity (play_items, MenuElem (_("Loop region"), mem_fun(*this, &Editor::loop_selected_region)), one_selected_region);
|
play_items.push_back (MenuElem (_("Loop Region"), mem_fun(*this, &Editor::loop_selected_region)));
|
||||||
|
|
||||||
edit_items.push_back (MenuElem (_("Play"), *play_menu));
|
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);
|
Menu *select_menu = manage (new Menu);
|
||||||
MenuList& select_items = select_menu->items();
|
MenuList& select_items = select_menu->items();
|
||||||
select_menu->set_name ("ArdourContextMenu");
|
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 (MenuElem (_("Invert selection"), mem_fun(*this, &Editor::invert_selection)));
|
||||||
select_items.push_back (SeparatorElem());
|
select_items.push_back (SeparatorElem());
|
||||||
|
select_items.push_back (MenuElem (_("Set range to loop range"), mem_fun(*this, &Editor::set_selection_from_loop)));
|
||||||
if (n_audio_tracks) {
|
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 (SeparatorElem());
|
||||||
select_items.push_back (MenuElem (_("Set range to punch range"), mem_fun(*this, &Editor::set_selection_from_punch)));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 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 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);
|
Menu *cutnpaste_menu = manage (new Menu);
|
||||||
MenuList& cutnpaste_items = cutnpaste_menu->items();
|
MenuList& cutnpaste_items = cutnpaste_menu->items();
|
||||||
cutnpaste_menu->set_name ("ArdourContextMenu");
|
cutnpaste_menu->set_name ("ArdourContextMenu");
|
||||||
|
|
||||||
cutnpaste_items.push_back (MenuElem (_("Cut"), mem_fun(*this, &Editor::cut)));
|
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 (_("Copy"), mem_fun(*this, &Editor::copy)));
|
||||||
cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f)));
|
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 ());
|
cutnpaste_items.push_back (SeparatorElem());
|
||||||
|
|
||||||
add_item_with_sensitivity (cutnpaste_items, MenuElem (_("Copy"), mem_fun(*this, &Editor::copy)), can_cut_copy ());
|
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)));
|
||||||
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 (SeparatorElem());
|
||||||
cutnpaste_items.push_back (MenuElem (_("Paste at mouse"), mem_fun(*this, &Editor::mouse_paste)));
|
|
||||||
|
cutnpaste_items.push_back (MenuElem (_("Insert chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f)));
|
||||||
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 (_("Edit"), *cutnpaste_menu));
|
edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu));
|
||||||
|
|
||||||
if (n_audio_tracks) {
|
/* Adding new material */
|
||||||
|
|
||||||
Menu *track_menu = manage (new Menu);
|
|
||||||
MenuList& track_items = track_menu->items();
|
|
||||||
track_menu->set_name ("ArdourContextMenu");
|
|
||||||
|
|
||||||
/* Adding new material */
|
|
||||||
|
|
||||||
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);
|
edit_items.push_back (SeparatorElem());
|
||||||
add_item_with_sensitivity (track_items, MenuElem (_("Insert Existing Audio"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack)), n_audio_tracks == 1);
|
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 */
|
|
||||||
|
|
||||||
Menu *nudge_menu = manage (new Menu());
|
/* Nudge track */
|
||||||
MenuList& nudge_items = nudge_menu->items();
|
|
||||||
nudge_menu->set_name ("ArdourContextMenu");
|
|
||||||
|
|
||||||
str = selection->tracks.size() == 1 ? _("Nudge track after edit cursor forward") : _("Nudge tracks after edit cursor forward");
|
Menu *nudge_menu = manage (new Menu());
|
||||||
|
MenuList& nudge_items = nudge_menu->items();
|
||||||
nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), true, true))));
|
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))));
|
||||||
|
|
||||||
str = selection->tracks.size() == 1 ? _("Nudge track backward") : _("Nudge tracks backward");
|
edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
|
||||||
|
}
|
||||||
nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), false, false))));
|
|
||||||
|
|
||||||
str = selection->tracks.size() == 1 ? _("Nudge track after edit cursor backward") : _("Nudge tracks after edit cursor backward");
|
void
|
||||||
|
Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
|
||||||
nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), true, false))));
|
{
|
||||||
|
using namespace Menu_Helpers;
|
||||||
track_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
|
|
||||||
|
|
||||||
/* Freeze */
|
/* Playback */
|
||||||
track_items.push_back (MenuElem (_("Freeze"), mem_fun(*this, &Editor::freeze_routes)));
|
|
||||||
track_items.push_back (MenuElem (_("Unfreeze"), mem_fun(*this, &Editor::unfreeze_routes)));
|
|
||||||
|
|
||||||
str = selection->tracks.size() == 1 ? _("Track") : _("Tracks");
|
Menu *play_menu = manage (new Menu);
|
||||||
edit_items.push_back (MenuElem (str, *track_menu));
|
MenuList& play_items = play_menu->items();
|
||||||
}
|
play_menu->set_name ("ArdourContextMenu");
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* Selection */
|
||||||
|
|
||||||
|
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)));
|
||||||
|
|
||||||
|
edit_items.push_back (MenuElem (_("Select"), *select_menu));
|
||||||
|
|
||||||
|
/* Cut-n-Paste */
|
||||||
|
|
||||||
|
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)));
|
||||||
|
|
||||||
|
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 */
|
/* CURSOR SETTING AND MARKS AND STUFF */
|
||||||
|
|
|
||||||
|
|
@ -239,9 +239,9 @@ class Editor : public PublicEditor
|
||||||
bool extend_selection_to_track (TimeAxisView&);
|
bool extend_selection_to_track (TimeAxisView&);
|
||||||
|
|
||||||
void play_selection ();
|
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 select_all (Selection::Operation op);
|
||||||
void invert_selection_in_selected_tracks ();
|
void invert_selection_in_track ();
|
||||||
void invert_selection ();
|
void invert_selection ();
|
||||||
void deselect_all ();
|
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);
|
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);
|
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_new_region_view (RegionView *);
|
||||||
void collect_and_select_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_item;
|
||||||
Gtk::MenuItem* region_edit_menu_split_multichannel_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);
|
Gtk::Menu* build_track_context_menu (nframes_t);
|
||||||
void add_bus_or_audio_track_context_items (Gtk::Menu_Helpers::MenuList&);
|
Gtk::Menu* build_track_bus_context_menu (nframes_t);
|
||||||
void add_region_context_items (Gtk::Menu_Helpers::MenuList&);
|
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_crossfade_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Crossfade>, Gtk::Menu_Helpers::MenuList&, bool many);
|
||||||
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
|
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_standalone (boost::shared_ptr<ARDOUR::Region>);
|
||||||
void audition_playlist_region_via_route (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Route&);
|
void audition_playlist_region_via_route (boost::shared_ptr<ARDOUR::Region>, ARDOUR::Route&);
|
||||||
void split_multichannel_region();
|
void split_multichannel_region();
|
||||||
void reverse_regions ();
|
void reverse_region ();
|
||||||
void normalize_regions ();
|
void normalize_region ();
|
||||||
void denormalize_regions ();
|
void denormalize_region ();
|
||||||
void quantize_regions ();
|
void quantize_region ();
|
||||||
|
|
||||||
void audition_region_from_region_list ();
|
void audition_region_from_region_list ();
|
||||||
void hide_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_range (ARDOUR::Location&);
|
||||||
void set_selection_from_punch ();
|
void set_selection_from_punch ();
|
||||||
void set_selection_from_loop ();
|
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_mark (nframes64_t where);
|
||||||
void add_location_from_audio_region ();
|
void add_location_from_audio_region ();
|
||||||
|
|
@ -1901,8 +1915,8 @@ class Editor : public PublicEditor
|
||||||
static void* _freeze_thread (void*);
|
static void* _freeze_thread (void*);
|
||||||
void* freeze_thread ();
|
void* freeze_thread ();
|
||||||
|
|
||||||
void freeze_routes ();
|
void freeze_route ();
|
||||||
void unfreeze_routes ();
|
void unfreeze_route ();
|
||||||
|
|
||||||
/* edit-group solo + mute */
|
/* edit-group solo + mute */
|
||||||
|
|
||||||
|
|
@ -1990,7 +2004,7 @@ class Editor : public PublicEditor
|
||||||
|
|
||||||
/* nudging tracks */
|
/* nudging tracks */
|
||||||
|
|
||||||
void nudge_selected_tracks (bool use_edit_cursor, bool forwards);
|
void nudge_track (bool use_edit_point, bool forwards);
|
||||||
|
|
||||||
/* xfades */
|
/* xfades */
|
||||||
|
|
||||||
|
|
@ -2101,13 +2115,6 @@ class Editor : public PublicEditor
|
||||||
void toggle_gain_envelope_active ();
|
void toggle_gain_envelope_active ();
|
||||||
void reset_region_gain_envelopes ();
|
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_press_event (GdkEventKey*);
|
||||||
bool on_key_release_event (GdkEventKey*);
|
bool on_key_release_event (GdkEventKey*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -352,11 +352,11 @@ Editor::register_actions ()
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
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));
|
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);
|
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);
|
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);
|
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);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
act = ActionManager::register_action (editor_actions, "crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection));
|
act = ActionManager::register_action (editor_actions, "crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection));
|
||||||
ActionManager::session_sensitive_actions.push_back (act);
|
ActionManager::session_sensitive_actions.push_back (act);
|
||||||
|
|
|
||||||
|
|
@ -335,51 +335,27 @@ Editor::track_canvas_size_allocated ()
|
||||||
reset_scrolling_region ();
|
reset_scrolling_region ();
|
||||||
|
|
||||||
if (playhead_cursor) playhead_cursor->set_length (canvas_height);
|
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) {
|
for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {
|
||||||
(*x)->set_line_length (full_canvas_height);
|
(*x)->set_line_vpos (y1, canvas_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (range_marker_drag_rect) {
|
range_marker_drag_rect->property_y1() = 0.0;
|
||||||
range_marker_drag_rect->property_y1() = 0.0;
|
range_marker_drag_rect->property_y2() = canvas_height;
|
||||||
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;
|
||||||
if (transport_loop_range_rect) {
|
transport_punch_range_rect->property_y2() = canvas_height;
|
||||||
transport_loop_range_rect->property_y1() = 0.0;
|
transport_punchin_line->property_y1() = 0.0;
|
||||||
transport_loop_range_rect->property_y2() = canvas_height;
|
transport_punchin_line->property_y2() = canvas_height;
|
||||||
}
|
transport_punchout_line->property_y1() = 0.0;
|
||||||
|
transport_punchout_line->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
update_fixed_rulers();
|
update_fixed_rulers();
|
||||||
redisplay_tempo (true);
|
redisplay_tempo (true);
|
||||||
|
|
||||||
if (logo_item) {
|
|
||||||
// logo_item->property_height() = full_canvas_height;
|
|
||||||
// logo_item->property_width() = canvas_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resized (); /* EMIT_SIGNAL */
|
Resized (); /* EMIT_SIGNAL */
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -723,6 +699,38 @@ Editor::left_track_canvas (GdkEventCrossing *ev)
|
||||||
return FALSE;
|
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
|
void
|
||||||
Editor::canvas_horizontally_scrolled ()
|
Editor::canvas_horizontally_scrolled ()
|
||||||
|
|
|
||||||
|
|
@ -1172,7 +1172,7 @@ Editor::marker_selection_changed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {
|
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 ();
|
(*x)->show_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -967,24 +967,23 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
case FadeOutHandleItem:
|
case FadeOutHandleItem:
|
||||||
popup_fade_context_menu (1, event->button.time, item, item_type);
|
popup_fade_context_menu (1, event->button.time, item, item_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StreamItem:
|
case StreamItem:
|
||||||
popup_track_context_menu (1, event->button.time, where);
|
popup_track_context_menu (1, event->button.time, item_type, false, where);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RegionItem:
|
case RegionItem:
|
||||||
case RegionViewNameHighlight:
|
case RegionViewNameHighlight:
|
||||||
case RegionViewName:
|
case RegionViewName:
|
||||||
popup_track_context_menu (1, event->button.time, where);
|
popup_track_context_menu (1, event->button.time, item_type, false, where);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionItem:
|
case SelectionItem:
|
||||||
popup_track_context_menu (1, event->button.time, where);
|
popup_track_context_menu (1, event->button.time, item_type, true, where);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AutomationTrackItem:
|
case AutomationTrackItem:
|
||||||
case CrossfadeViewItem:
|
popup_track_context_menu (1, event->button.time, item_type, false, where);
|
||||||
popup_track_context_menu (1, event->button.time, where);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MarkerBarItem:
|
case MarkerBarItem:
|
||||||
|
|
@ -1007,6 +1006,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||||
case MeterMarkerItem:
|
case MeterMarkerItem:
|
||||||
tm_marker_context_menu (&event->button, item);
|
tm_marker_context_menu (&event->button, item);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CrossfadeViewItem:
|
||||||
|
popup_track_context_menu (1, event->button.time, item_type, false, where);
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef WITH_CMT
|
#ifdef WITH_CMT
|
||||||
case ImageFrameItem:
|
case ImageFrameItem:
|
||||||
|
|
@ -3680,7 +3683,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||||
|
|
||||||
if (regionview_y_movement) {
|
if (regionview_y_movement) {
|
||||||
|
|
||||||
/* moved to a different audio track. */
|
/* moved to a different track. */
|
||||||
|
|
||||||
vector<RegionView*> new_selection;
|
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));
|
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();
|
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()) {
|
if (! to_playlist->frozen()) {
|
||||||
/*
|
/*
|
||||||
|
|
@ -3720,35 +3727,26 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||||
to_playlist->freeze();
|
to_playlist->freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
where = (nframes_t) (unit_to_frame (ix1) * speed);
|
/* undo the previous hide_dependent_views so that xfades don't
|
||||||
boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
|
disappear on copying regions
|
||||||
|
*/
|
||||||
|
|
||||||
|
rv->get_time_axis_view().reveal_dependent_views (*rv);
|
||||||
|
|
||||||
if (!drag_info.copy) {
|
if (!drag_info.copy) {
|
||||||
|
|
||||||
|
|
||||||
/* the region that used to be in the old playlist is not
|
/* 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,
|
moved to the new one - we make a copy of it. as a result,
|
||||||
any existing editor for the region should no longer be
|
any existing editor for the region should no longer be
|
||||||
visible.
|
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->hide_region_editor();
|
||||||
rv->fake_set_opaque (false);
|
rv->fake_set_opaque (false);
|
||||||
|
|
||||||
|
session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
|
||||||
from_playlist->remove_region ((rv->region()));
|
from_playlist->remove_region ((rv->region()));
|
||||||
|
session->add_command (new MementoCommand<Playlist>(*from_playlist, 0, &from_playlist->get_state()));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2595,6 +2595,9 @@ Editor::separate_regions_between (const TimeSelection& ts)
|
||||||
|
|
||||||
sort_track_selection (&tmptracks);
|
sort_track_selection (&tmptracks);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) {
|
for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) {
|
||||||
|
|
||||||
RouteTimeAxisView* rtv;
|
RouteTimeAxisView* rtv;
|
||||||
|
|
@ -3298,16 +3301,14 @@ Editor::trim_region_from_edit_point ()
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unfreeze selected routes */
|
|
||||||
void
|
void
|
||||||
Editor::unfreeze_routes ()
|
Editor::unfreeze_route ()
|
||||||
{
|
{
|
||||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
|
||||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i);
|
return;
|
||||||
if (atv && atv->is_audio_track()) {
|
|
||||||
atv->audio_track()->unfreeze ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clicked_routeview->audio_track()->unfreeze ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
|
|
@ -3320,15 +3321,7 @@ Editor::_freeze_thread (void* arg)
|
||||||
void*
|
void*
|
||||||
Editor::freeze_thread ()
|
Editor::freeze_thread ()
|
||||||
{
|
{
|
||||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
clicked_routeview->audio_track()->freeze (*current_interthread_info);
|
||||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i);
|
|
||||||
if (atv && atv->is_audio_track()) {
|
|
||||||
atv->audio_track()->freeze (*current_interthread_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_interthread_info->done = true;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3339,10 +3332,13 @@ Editor::freeze_progress_timeout (void *arg)
|
||||||
return !(current_interthread_info->done || current_interthread_info->cancel);
|
return !(current_interthread_info->done || current_interthread_info->cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Freeze selected routes */
|
|
||||||
void
|
void
|
||||||
Editor::freeze_routes ()
|
Editor::freeze_route ()
|
||||||
{
|
{
|
||||||
|
if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InterThreadInfo itt;
|
InterThreadInfo itt;
|
||||||
|
|
||||||
if (interthread_progress_window == 0) {
|
if (interthread_progress_window == 0) {
|
||||||
|
|
@ -3991,7 +3987,7 @@ Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::nudge_selected_tracks (bool use_edit, bool forwards)
|
Editor::nudge_track (bool use_edit, bool forwards)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Playlist> playlist;
|
boost::shared_ptr<Playlist> playlist;
|
||||||
nframes_t distance;
|
nframes_t distance;
|
||||||
|
|
@ -4058,7 +4054,7 @@ Editor::remove_last_capture ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::normalize_regions ()
|
Editor::normalize_region ()
|
||||||
{
|
{
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -4088,7 +4084,7 @@ Editor::normalize_regions ()
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::denormalize_regions ()
|
Editor::denormalize_region ()
|
||||||
{
|
{
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -4114,7 +4110,7 @@ Editor::denormalize_regions ()
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::reverse_regions ()
|
Editor::reverse_region ()
|
||||||
{
|
{
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -4126,7 +4122,7 @@ Editor::reverse_regions ()
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::quantize_regions ()
|
Editor::quantize_region ()
|
||||||
{
|
{
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -4270,10 +4266,7 @@ Editor::toggle_gain_envelope_visibility ()
|
||||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||||
if (arv) {
|
if (arv) {
|
||||||
bool x = region_envelope_visible_item->get_active();
|
arv->set_envelope_visible (!arv->envelope_visible());
|
||||||
if (x != arv->envelope_visible()) {
|
|
||||||
arv->set_envelope_visible (x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4284,28 +4277,7 @@ Editor::toggle_gain_envelope_active ()
|
||||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||||
if (arv) {
|
if (arv) {
|
||||||
bool x = region_envelope_active_item->get_active();
|
arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4313,45 +4285,24 @@ Editor::toggle_region_position_lock ()
|
||||||
void
|
void
|
||||||
Editor::toggle_region_lock ()
|
Editor::toggle_region_lock ()
|
||||||
{
|
{
|
||||||
bool x = region_lock_item->get_active();
|
|
||||||
|
|
||||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
(*i)->region()->set_locked (!(*i)->region()->locked());
|
||||||
if (arv) {
|
|
||||||
if (x != arv->audio_region()->locked()) {
|
|
||||||
arv->audio_region()->set_locked (x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::toggle_region_mute ()
|
Editor::toggle_region_mute ()
|
||||||
{
|
{
|
||||||
bool x = region_mute_item->get_active();
|
|
||||||
|
|
||||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
(*i)->region()->set_muted (!(*i)->region()->muted());
|
||||||
if (arv) {
|
|
||||||
if (x != arv->audio_region()->muted()) {
|
|
||||||
arv->audio_region()->set_muted (x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::toggle_region_opaque ()
|
Editor::toggle_region_opaque ()
|
||||||
{
|
{
|
||||||
bool x = region_opaque_item->get_active();
|
|
||||||
|
|
||||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
(*i)->region()->set_opaque (!(*i)->region()->opaque());
|
||||||
if (arv) {
|
|
||||||
if (x != arv->audio_region()->opaque()) {
|
|
||||||
arv->audio_region()->set_opaque (x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -713,6 +713,37 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
|
||||||
commit_reversible_command () ;
|
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
|
void
|
||||||
Editor::track_selection_changed ()
|
Editor::track_selection_changed ()
|
||||||
{
|
{
|
||||||
|
|
@ -776,17 +807,16 @@ Editor::point_selection_changed ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Select everything in the selected tracks
|
|
||||||
* @param Selection operation to apply.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
Editor::select_all_in_selected_tracks (Selection::Operation op)
|
Editor::select_all_in_track (Selection::Operation op)
|
||||||
{
|
{
|
||||||
list<Selectable *> touched;
|
list<Selectable *> touched;
|
||||||
|
|
||||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
if (!clicked_routeview) {
|
||||||
(*i)->get_selectables (0, max_frames, 0, DBL_MAX, touched);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clicked_routeview->get_selectables (0, max_frames, 0, DBL_MAX, touched);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Selection::Toggle:
|
case Selection::Toggle:
|
||||||
|
|
@ -832,17 +862,16 @@ Editor::select_all (Selection::Operation op)
|
||||||
}
|
}
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Invert the selection in the selected tracks */
|
|
||||||
void
|
void
|
||||||
Editor::invert_selection_in_selected_tracks ()
|
Editor::invert_selection_in_track ()
|
||||||
{
|
{
|
||||||
list<Selectable *> touched;
|
list<Selectable *> touched;
|
||||||
|
|
||||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
if (!clicked_routeview) {
|
||||||
(*i)->get_inverted_selectables (*selection, touched);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clicked_routeview->get_inverted_selectables (*selection, touched);
|
||||||
selection->set (touched);
|
selection->set (touched);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -926,7 +955,7 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::set_selection_from_audio_region ()
|
Editor::set_selection_from_region ()
|
||||||
{
|
{
|
||||||
if (selection->regions.empty()) {
|
if (selection->regions.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
|
#include <gtkmm/messagedialog.h>
|
||||||
#include <pbd/xml++.h>
|
#include <pbd/xml++.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
@ -427,11 +428,11 @@ EngineControl::build_command_line (vector<string>& cmd)
|
||||||
cmd.push_back ("netjack");
|
cmd.push_back ("netjack");
|
||||||
} else if (driver == X_("FFADO")) {
|
} else if (driver == X_("FFADO")) {
|
||||||
using_ffado = true;
|
using_ffado = true;
|
||||||
cmd.push_back ("firewire");
|
cmd.push_back ("ffado");
|
||||||
} else if ( driver == X_("Dummy")) {
|
} else if ( driver == X_("Dummy")) {
|
||||||
using_dummy = true;
|
using_dummy = true;
|
||||||
cmd.push_back ("dummy");
|
cmd.push_back ("dummy");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* driver arguments */
|
/* driver arguments */
|
||||||
|
|
||||||
|
|
@ -621,10 +622,29 @@ EngineControl::enumerate_coreaudio_devices ()
|
||||||
// Look for the CoreAudio device name...
|
// Look for the CoreAudio device name...
|
||||||
char coreDeviceName[256];
|
char coreDeviceName[256];
|
||||||
size_t nameSize;
|
size_t nameSize;
|
||||||
|
|
||||||
for (int i = 0; i < numCoreDevices; i++) {
|
for (int i = 0; i < numCoreDevices; i++) {
|
||||||
|
|
||||||
nameSize = sizeof (coreDeviceName);
|
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],
|
err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i],
|
||||||
0, true, kAudioDevicePropertyDeviceName,
|
0, true, kAudioDevicePropertyDeviceName,
|
||||||
&outSize, &isWritable);
|
&outSize, &isWritable);
|
||||||
|
|
@ -649,6 +669,26 @@ EngineControl::enumerate_coreaudio_devices ()
|
||||||
delete [] coreDeviceIDs;
|
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;
|
return devs;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
@ -869,7 +909,7 @@ EngineControl::find_jack_servers (vector<string>& strings)
|
||||||
std::map<string,int> un;
|
std::map<string,int> un;
|
||||||
|
|
||||||
path = getenv ("PATH");
|
path = getenv ("PATH");
|
||||||
|
|
||||||
jack_servers = scanner (path, jack_server_filter, 0, false, true);
|
jack_servers = scanner (path, jack_server_filter, 0, false, true);
|
||||||
|
|
||||||
vector<string *>::iterator iter;
|
vector<string *>::iterator iter;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "canvas_impl.h"
|
#include "canvas_impl.h"
|
||||||
#include "ardour_ui.h"
|
#include "ardour_ui.h"
|
||||||
|
#include "simpleline.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -269,7 +270,6 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
|
||||||
}
|
}
|
||||||
|
|
||||||
line = 0;
|
line = 0;
|
||||||
line_points = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,7 +285,6 @@ Marker::~Marker ()
|
||||||
|
|
||||||
if (line) {
|
if (line) {
|
||||||
delete line;
|
delete line;
|
||||||
delete line_points;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,35 +294,28 @@ void Marker::reparent(ArdourCanvas::Group & parent)
|
||||||
_parent = &parent;
|
_parent = &parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Marker::set_line_length (double len)
|
Marker::set_line_vpos (double pos, double height)
|
||||||
{
|
{
|
||||||
if (line) {
|
if (line) {
|
||||||
line_points->back().set_y (len);
|
line->property_y1() = pos;
|
||||||
line->property_points() = *line_points;
|
line->property_y2() = pos + height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Marker::add_line (ArdourCanvas::Group* group, double initial_height)
|
Marker::add_line (ArdourCanvas::Group* group, double y_origin, double initial_height)
|
||||||
{
|
{
|
||||||
if (!line) {
|
if (!line) {
|
||||||
|
|
||||||
line_points = new ArdourCanvas::Points ();
|
line = new ArdourCanvas::SimpleLine (*group);
|
||||||
line_points->push_back (Gnome::Art::Point (unit_position + shift, 0.0));
|
line->property_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get();
|
||||||
line_points->push_back (Gnome::Art::Point (unit_position + shift, initial_height));
|
line->property_x1() = unit_position + shift;
|
||||||
|
line->property_y1() = y_origin;
|
||||||
line = new ArdourCanvas::Line (*group);
|
line->property_x2() = unit_position + shift;
|
||||||
line->property_width_pixels() = 1;
|
line->property_y2() = y_origin + initial_height;
|
||||||
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->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
|
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;
|
unit_position = new_unit_position;
|
||||||
|
|
||||||
if (line) {
|
if (line) {
|
||||||
(*line_points)[0].set_x (unit_position + shift);
|
line->property_x1() = unit_position + shift;
|
||||||
(*line_points)[1].set_x (unit_position + shift);
|
line->property_x2() = unit_position + shift;
|
||||||
line->property_points() = *line_points;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,10 @@ class Marker : public PBD::Destructible
|
||||||
|
|
||||||
ArdourCanvas::Item& the_item() const;
|
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 show_line ();
|
||||||
void hide_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_position (nframes_t);
|
||||||
void set_name (const string&);
|
void set_name (const string&);
|
||||||
|
|
@ -84,7 +84,7 @@ class Marker : public PBD::Destructible
|
||||||
ArdourCanvas::Polygon *mark;
|
ArdourCanvas::Polygon *mark;
|
||||||
ArdourCanvas::Text *text;
|
ArdourCanvas::Text *text;
|
||||||
ArdourCanvas::Points *points;
|
ArdourCanvas::Points *points;
|
||||||
ArdourCanvas::Line *line;
|
ArdourCanvas::SimpleLine *line;
|
||||||
ArdourCanvas::Points *line_points;
|
ArdourCanvas::Points *line_points;
|
||||||
|
|
||||||
double unit_position;
|
double unit_position;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
|
||||||
|
|
||||||
if (strip->width_owner() != strip) {
|
if (strip->width_owner() != strip) {
|
||||||
strip->set_width (_strip_width, this);
|
strip->set_width (_strip_width, this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "new_session_dialog.h"
|
#include "new_session_dialog.h"
|
||||||
|
|
||||||
|
#include <pbd/error.h>
|
||||||
|
|
||||||
#include <ardour/recent_sessions.h>
|
#include <ardour/recent_sessions.h>
|
||||||
#include <ardour/session_state_utils.h>
|
#include <ardour/session_state_utils.h>
|
||||||
#include <ardour/template_utils.h>
|
#include <ardour/template_utils.h>
|
||||||
|
|
@ -38,8 +40,8 @@
|
||||||
#include <gtkmm2ext/window_title.h>
|
#include <gtkmm2ext/window_title.h>
|
||||||
|
|
||||||
using namespace Gtkmm2ext;
|
using namespace Gtkmm2ext;
|
||||||
using namespace ARDOUR;
|
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
using namespace ARDOUR;
|
||||||
|
|
||||||
#include "opts.h"
|
#include "opts.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
@ -526,7 +528,49 @@ NewSessionDialog::set_session_name (const Glib::ustring& name)
|
||||||
void
|
void
|
||||||
NewSessionDialog::set_session_folder(const Glib::ustring& dir)
|
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
|
std::string
|
||||||
|
|
@ -547,40 +591,54 @@ NewSessionDialog::session_name() const
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int page = m_notebook->get_current_page();
|
switch (which_page()) {
|
||||||
|
case NewPage:
|
||||||
if (page == 0 || page == 2) {
|
case EnginePage:
|
||||||
/* new or audio setup pages */
|
/* new or audio setup pages */
|
||||||
return Glib::filename_from_utf8(m_name->get_text());
|
return Glib::filename_from_utf8(m_name->get_text());
|
||||||
} else {
|
default:
|
||||||
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
break;
|
||||||
return Glib::filename_from_utf8(str);
|
}
|
||||||
}
|
|
||||||
Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected();
|
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
||||||
return (*i)[recent_columns.visible_name];
|
return Glib::filename_from_utf8(str);
|
||||||
}
|
}
|
||||||
|
Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected();
|
||||||
|
return (*i)[recent_columns.visible_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
NewSessionDialog::session_folder() const
|
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());
|
return Glib::filename_from_utf8(m_folder->get_filename());
|
||||||
} else {
|
|
||||||
|
case EnginePage:
|
||||||
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
if (page_set == EnginePage) {
|
||||||
const string filename(Glib::filename_from_utf8(m_open_filechooser->get_filename()));
|
/* just engine page, nothing else : use m_folder since it should be set */
|
||||||
return Glib::path_get_dirname(filename);
|
return Glib::filename_from_utf8(m_folder->get_filename());
|
||||||
}
|
}
|
||||||
Gtk::TreeModel::iterator i = m_treeview->get_selection()->get_selected();
|
break;
|
||||||
return (*i)[recent_columns.fullpath];
|
|
||||||
|
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
|
bool
|
||||||
NewSessionDialog::use_session_template() const
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -663,13 +721,13 @@ NewSessionDialog::connect_outs_to_physical() const
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NewSessionDialog::get_current_page() const
|
NewSessionDialog::get_current_page()
|
||||||
{
|
{
|
||||||
return m_notebook->get_current_page();
|
return m_notebook->get_current_page();
|
||||||
}
|
}
|
||||||
|
|
||||||
NewSessionDialog::Pages
|
NewSessionDialog::Pages
|
||||||
NewSessionDialog::which_page ()
|
NewSessionDialog::which_page () const
|
||||||
{
|
{
|
||||||
int num = m_notebook->get_current_page();
|
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_label(_("Open"));
|
||||||
m_okbutton->set_image (*(manage (new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON))));
|
m_okbutton->set_image (*(manage (new Gtk::Image (Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON))));
|
||||||
set_response_sensitive (Gtk::RESPONSE_NONE, false);
|
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) {
|
if (m_treeview->get_selection()->count_selected_rows() == 0) {
|
||||||
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
set_response_sensitive (Gtk::RESPONSE_OK, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -772,8 +829,7 @@ NewSessionDialog::notebook_page_changed (GtkNotebookPage* np, uint pagenum)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_okbutton->set_label(_("New"));
|
on_new_session_page = true;
|
||||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
|
|
||||||
m_okbutton->set_label(_("New"));
|
m_okbutton->set_label(_("New"));
|
||||||
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
|
m_okbutton->set_image (*(new Gtk::Image (Gtk::Stock::NEW, Gtk::ICON_SIZE_BUTTON)));
|
||||||
if (m_name->get_text() == "") {
|
if (m_name->get_text() == "") {
|
||||||
|
|
@ -893,7 +949,7 @@ NewSessionDialog::monitor_bus_button_clicked ()
|
||||||
void
|
void
|
||||||
NewSessionDialog::reset_template()
|
NewSessionDialog::reset_template()
|
||||||
{
|
{
|
||||||
m_template->set_filename("");
|
m_template->unselect_all ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -92,9 +92,9 @@ public:
|
||||||
|
|
||||||
bool connect_outs_to_master() const;
|
bool connect_outs_to_master() const;
|
||||||
bool connect_outs_to_physical() 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 set_current_page (int);
|
||||||
void reset_recent();
|
void reset_recent();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6854,7 +6854,7 @@ msgstr "som nya bandspår"
|
||||||
|
|
||||||
#: gtk2_ardour/sfdb_ui.cc:109
|
#: gtk2_ardour/sfdb_ui.cc:109
|
||||||
msgid "Auto-play"
|
msgid "Auto-play"
|
||||||
msgstr "Spela automatiskt"
|
msgstr "Spela autom."
|
||||||
|
|
||||||
#: gtk2_ardour/sfdb_ui.cc:994 gtk2_ardour/sfdb_ui.cc:1129
|
#: gtk2_ardour/sfdb_ui.cc:994 gtk2_ardour/sfdb_ui.cc:1129
|
||||||
msgid "use file timestamp"
|
msgid "use file timestamp"
|
||||||
|
|
@ -7062,3 +7062,39 @@ msgstr "Bra"
|
||||||
#: gtk2_ardour/sfdb_ui.cc:1069 gtk2_ardour/sfdb_ui.cc:1149
|
#: gtk2_ardour/sfdb_ui.cc:1069 gtk2_ardour/sfdb_ui.cc:1149
|
||||||
msgid "Quick"
|
msgid "Quick"
|
||||||
msgstr "Snabb"
|
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"
|
||||||
|
|
|
||||||
|
|
@ -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);
|
int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
|
||||||
|
|
||||||
std::set<uint32_t> automatable() const;
|
std::set<uint32_t> automatable() const;
|
||||||
void store_state (ARDOUR::PluginState&);
|
|
||||||
void restore_state (ARDOUR::PluginState&);
|
|
||||||
string describe_parameter (uint32_t);
|
string describe_parameter (uint32_t);
|
||||||
string state_node_name () const { return "audiounit"; }
|
string state_node_name () const { return "audiounit"; }
|
||||||
void print_parameter (uint32_t, char*, uint32_t len) const;
|
void print_parameter (uint32_t, char*, uint32_t len) const;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
#include <jack/types.h>
|
#include <jack/types.h>
|
||||||
#include <ardour/ladspa.h>
|
#include <ardour/ladspa.h>
|
||||||
#include <ardour/plugin_state.h>
|
|
||||||
#include <ardour/plugin.h>
|
#include <ardour/plugin.h>
|
||||||
#include <ardour/ladspa_plugin.h>
|
#include <ardour/ladspa_plugin.h>
|
||||||
|
|
||||||
|
|
@ -54,53 +53,47 @@ class LadspaPlugin : public ARDOUR::Plugin
|
||||||
/* Plugin interface */
|
/* Plugin interface */
|
||||||
|
|
||||||
std::string unique_id() const;
|
std::string unique_id() const;
|
||||||
const char * label() const { return descriptor->Label; }
|
const char* label() const { return _descriptor->Label; }
|
||||||
const char * name() const { return descriptor->Name; }
|
const char* name() const { return _descriptor->Name; }
|
||||||
const char * maker() const { return descriptor->Maker; }
|
const char* maker() const { return _descriptor->Maker; }
|
||||||
uint32_t parameter_count() const { return descriptor->PortCount; }
|
uint32_t parameter_count() const { return _descriptor->PortCount; }
|
||||||
float default_value (uint32_t port);
|
float default_value (uint32_t port);
|
||||||
nframes_t signal_latency() const;
|
nframes_t signal_latency() const;
|
||||||
void set_parameter (uint32_t port, float val);
|
void set_parameter (uint32_t port, float val);
|
||||||
float get_parameter (uint32_t port) const;
|
float get_parameter (uint32_t port) const;
|
||||||
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) 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;
|
std::set<Parameter> automatable() const;
|
||||||
uint32_t nth_parameter (uint32_t port, bool& ok) const;
|
|
||||||
void activate () {
|
void activate () {
|
||||||
if (was_activated)
|
if (!_was_activated && _descriptor->activate)
|
||||||
return;
|
_descriptor->activate (_handle);
|
||||||
|
|
||||||
if (descriptor->activate) {
|
_was_activated = true;
|
||||||
descriptor->activate (handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
was_activated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deactivate () {
|
void deactivate () {
|
||||||
if (!was_activated)
|
if (_was_activated && _descriptor->deactivate)
|
||||||
return;
|
_descriptor->deactivate (_handle);
|
||||||
|
|
||||||
if (descriptor->deactivate) {
|
_was_activated = false;
|
||||||
descriptor->deactivate (handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
was_activated = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup () {
|
void cleanup () {
|
||||||
activate();
|
activate();
|
||||||
deactivate();
|
deactivate();
|
||||||
|
|
||||||
if (descriptor->cleanup) {
|
if (_descriptor->cleanup)
|
||||||
descriptor->cleanup (handle);
|
_descriptor->cleanup (_handle);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_block_size (nframes_t nframes) {}
|
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);
|
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 describe_parameter (Parameter);
|
||||||
string state_node_name() const { return "ladspa"; }
|
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_audio(uint32_t) const;
|
||||||
bool parameter_is_control(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;
|
bool parameter_is_toggled(uint32_t) const;
|
||||||
|
|
||||||
XMLNode& get_state();
|
XMLNode& get_state();
|
||||||
int set_state(const XMLNode& node);
|
int set_state(const XMLNode& node);
|
||||||
bool save_preset(string name);
|
bool save_preset(string name);
|
||||||
|
|
||||||
bool has_editor() const { return false; }
|
bool has_editor() const { return false; }
|
||||||
|
|
||||||
|
|
@ -118,32 +111,27 @@ class LadspaPlugin : public ARDOUR::Plugin
|
||||||
|
|
||||||
/* LADSPA extras */
|
/* LADSPA extras */
|
||||||
|
|
||||||
LADSPA_Properties properties() const { return descriptor->Properties; }
|
LADSPA_Properties properties() const { return _descriptor->Properties; }
|
||||||
uint32_t index() const { return _index; }
|
uint32_t index() const { return _index; }
|
||||||
const char * copyright() const { return descriptor->Copyright; }
|
const char * copyright() const { return _descriptor->Copyright; }
|
||||||
LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return descriptor->PortDescriptors[i]; }
|
LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return _descriptor->PortDescriptors[i]; }
|
||||||
const LADSPA_PortRangeHint * port_range_hints() const { return descriptor->PortRangeHints; }
|
const LADSPA_PortRangeHint* port_range_hints() const { return _descriptor->PortRangeHints; }
|
||||||
const char * const * port_names() const { return descriptor->PortNames; }
|
const char * const * port_names() const { return _descriptor->PortNames; }
|
||||||
void set_gain (float gain) {
|
|
||||||
descriptor->set_run_adding_gain (handle, gain);
|
void set_gain (float gain) { _descriptor->set_run_adding_gain (_handle, gain); }
|
||||||
}
|
void run_adding (uint32_t nsamples) { _descriptor->run_adding (_handle, nsamples); }
|
||||||
void run_adding (uint32_t nsamples) {
|
void connect_port (uint32_t port, float *ptr) { _descriptor->connect_port (_handle, port, ptr); }
|
||||||
descriptor->run_adding (handle, nsamples);
|
|
||||||
}
|
|
||||||
void connect_port (uint32_t port, float *ptr) {
|
|
||||||
descriptor->connect_port (handle, port, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *module;
|
void* _module;
|
||||||
const LADSPA_Descriptor *descriptor;
|
const LADSPA_Descriptor* _descriptor;
|
||||||
LADSPA_Handle handle;
|
LADSPA_Handle _handle;
|
||||||
nframes_t sample_rate;
|
nframes_t _sample_rate;
|
||||||
LADSPA_Data *control_data;
|
LADSPA_Data* _control_data;
|
||||||
LADSPA_Data *shadow_data;
|
LADSPA_Data* _shadow_data;
|
||||||
LADSPA_Data *latency_control_port;
|
LADSPA_Data* _latency_control_port;
|
||||||
uint32_t _index;
|
uint32_t _index;
|
||||||
bool was_activated;
|
bool _was_activated;
|
||||||
|
|
||||||
void init (void *mod, uint32_t index, nframes_t rate);
|
void init (void *mod, uint32_t index, nframes_t rate);
|
||||||
void run_in_place (nframes_t nsamples);
|
void run_in_place (nframes_t nsamples);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#include <jack/types.h>
|
#include <jack/types.h>
|
||||||
#include <ardour/types.h>
|
#include <ardour/types.h>
|
||||||
#include <ardour/chan_count.h>
|
#include <ardour/chan_count.h>
|
||||||
#include <ardour/plugin_state.h>
|
|
||||||
#include <ardour/cycles.h>
|
#include <ardour/cycles.h>
|
||||||
#include <ardour/latent.h>
|
#include <ardour/latent.h>
|
||||||
#include <ardour/parameter.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 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 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 describe_parameter (Parameter) = 0;
|
||||||
virtual string state_node_name() const = 0;
|
virtual string state_node_name() const = 0;
|
||||||
virtual void print_parameter (uint32_t, char*, uint32_t len) const = 0;
|
virtual void print_parameter (uint32_t, char*, uint32_t len) const = 0;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
#include <ardour/plugin_state.h>
|
|
||||||
#include <ardour/types.h>
|
#include <ardour/types.h>
|
||||||
#include <ardour/processor.h>
|
#include <ardour/processor.h>
|
||||||
#include <ardour/automation_event.h>
|
#include <ardour/automation_event.h>
|
||||||
|
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
#include <ardour/io_processor.h>
|
#include <ardour/io_processor.h>
|
||||||
#include <ardour/plugin_state.h>
|
|
||||||
#include <ardour/types.h>
|
#include <ardour/types.h>
|
||||||
|
|
||||||
class XMLNode;
|
class XMLNode;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include <ardour/types.h>
|
#include <ardour/types.h>
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
#include <ardour/plugin_state.h>
|
|
||||||
#include <ardour/buffer_set.h>
|
#include <ardour/buffer_set.h>
|
||||||
#include <ardour/automatable.h>
|
#include <ardour/automatable.h>
|
||||||
#include <ardour/latent.h>
|
#include <ardour/latent.h>
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef __ardour_rbeffect_h__
|
#ifndef __ardour_rbeffect_h__
|
||||||
#define __ardour_rbeffect_h__
|
#define __ardour_rbeffect_h__
|
||||||
|
|
||||||
#include <ardour/audiofilter.h>
|
#include <ardour/filter.h>
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,6 @@ class VSTPlugin : public ARDOUR::Plugin
|
||||||
void deactivate ();
|
void deactivate ();
|
||||||
void set_block_size (nframes_t nframes);
|
void set_block_size (nframes_t nframes);
|
||||||
int connect_and_run (BufferSet&, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
|
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 describe_parameter (uint32_t);
|
||||||
string state_node_name() const { return "vst"; }
|
string state_node_name() const { return "vst"; }
|
||||||
void print_parameter (uint32_t, char*, uint32_t len) const;
|
void print_parameter (uint32_t, char*, uint32_t len) const;
|
||||||
|
|
|
||||||
|
|
@ -401,18 +401,6 @@ AUPlugin::automatable() const
|
||||||
return automates;
|
return automates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AUPlugin::store_state (ARDOUR::PluginState&)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AUPlugin::restore_state (ARDOUR::PluginState&)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
string
|
||||||
AUPlugin::describe_parameter (uint32_t)
|
AUPlugin::describe_parameter (uint32_t)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -636,7 +636,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen
|
||||||
set_fade_out_active (false);
|
set_fade_out_active (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,11 +62,11 @@ LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_
|
||||||
LadspaPlugin::LadspaPlugin (const LadspaPlugin &other)
|
LadspaPlugin::LadspaPlugin (const LadspaPlugin &other)
|
||||||
: Plugin (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) {
|
for (uint32_t i = 0; i < parameter_count(); ++i) {
|
||||||
control_data[i] = other.shadow_data[i];
|
_control_data[i] = other._shadow_data[i];
|
||||||
shadow_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;
|
uint32_t i, port_cnt;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
|
||||||
module = mod;
|
_module = mod;
|
||||||
control_data = 0;
|
_control_data = 0;
|
||||||
shadow_data = 0;
|
_shadow_data = 0;
|
||||||
latency_control_port = 0;
|
_latency_control_port = 0;
|
||||||
was_activated = false;
|
_was_activated = false;
|
||||||
|
|
||||||
dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
|
dfunc = (LADSPA_Descriptor_Function) dlsym (_module, "ladspa_descriptor");
|
||||||
|
|
||||||
if ((errstr = dlerror()) != NULL) {
|
if ((errstr = dlerror()) != NULL) {
|
||||||
error << _("LADSPA: module has no descriptor function.") << endmsg;
|
error << _("LADSPA: module has no descriptor function.") << endmsg;
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((descriptor = dfunc (index)) == 0) {
|
if ((_descriptor = dfunc (index)) == 0) {
|
||||||
error << _("LADSPA: plugin has gone away since discovery!") << endmsg;
|
error << _("LADSPA: plugin has gone away since discovery!") << endmsg;
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
_index = index;
|
_index = index;
|
||||||
|
|
||||||
if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties)) {
|
if (LADSPA_IS_INPLACE_BROKEN(_descriptor->Properties)) {
|
||||||
error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), descriptor->Name) << endmsg;
|
error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), _descriptor->Name) << endmsg;
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_rate = rate;
|
_sample_rate = rate;
|
||||||
|
|
||||||
if (descriptor->instantiate == 0) {
|
if (_descriptor->instantiate == 0) {
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((handle = descriptor->instantiate (descriptor, rate)) == 0) {
|
if ((_handle = _descriptor->instantiate (_descriptor, rate)) == 0) {
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
port_cnt = parameter_count();
|
port_cnt = parameter_count();
|
||||||
|
|
||||||
control_data = new LADSPA_Data[port_cnt];
|
_control_data = new LADSPA_Data[port_cnt];
|
||||||
shadow_data = new LADSPA_Data[port_cnt];
|
_shadow_data = new LADSPA_Data[port_cnt];
|
||||||
|
|
||||||
for (i = 0; i < port_cnt; ++i) {
|
for (i = 0; i < port_cnt; ++i) {
|
||||||
if (LADSPA_IS_PORT_CONTROL(port_descriptor (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)) &&
|
if (LADSPA_IS_PORT_OUTPUT(port_descriptor (i)) &&
|
||||||
strcmp (port_names()[i], X_("latency")) == 0) {
|
strcmp (port_names()[i], X_("latency")) == 0) {
|
||||||
latency_control_port = &control_data[i];
|
_latency_control_port = &_control_data[i];
|
||||||
*latency_control_port = 0;
|
*_latency_control_port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LADSPA_IS_PORT_INPUT(port_descriptor (i))) {
|
if (!LADSPA_IS_PORT_INPUT(port_descriptor (i))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow_data[i] = default_value (i);
|
_shadow_data[i] = default_value (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,39 +149,12 @@ LadspaPlugin::~LadspaPlugin ()
|
||||||
|
|
||||||
// dlclose (module);
|
// dlclose (module);
|
||||||
|
|
||||||
if (control_data) {
|
if (_control_data) {
|
||||||
delete [] control_data;
|
delete [] _control_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shadow_data) {
|
if (_shadow_data) {
|
||||||
delete [] 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,7 +162,7 @@ string
|
||||||
LadspaPlugin::unique_id() const
|
LadspaPlugin::unique_id() const
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
|
snprintf (buf, sizeof (buf), "%lu", _descriptor->UniqueID);
|
||||||
return string (buf);
|
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 (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor) && !earlier_hint) {
|
||||||
if (bounds_given) {
|
if (bounds_given) {
|
||||||
if (sr_scaling) {
|
if (sr_scaling) {
|
||||||
ret *= sample_rate;
|
ret *= _sample_rate;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = sample_rate;
|
ret = _sample_rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,8 +294,8 @@ LadspaPlugin::default_value (uint32_t port)
|
||||||
void
|
void
|
||||||
LadspaPlugin::set_parameter (uint32_t which, float val)
|
LadspaPlugin::set_parameter (uint32_t which, float val)
|
||||||
{
|
{
|
||||||
if (which < descriptor->PortCount) {
|
if (which < _descriptor->PortCount) {
|
||||||
shadow_data[which] = (LADSPA_Data) val;
|
_shadow_data[which] = (LADSPA_Data) val;
|
||||||
#if 0
|
#if 0
|
||||||
ParameterChanged (Parameter(PluginAutomation, which), val); /* EMIT SIGNAL */
|
ParameterChanged (Parameter(PluginAutomation, which), val); /* EMIT SIGNAL */
|
||||||
|
|
||||||
|
|
@ -343,9 +316,9 @@ float
|
||||||
LadspaPlugin::get_parameter (uint32_t which) const
|
LadspaPlugin::get_parameter (uint32_t which) const
|
||||||
{
|
{
|
||||||
if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) {
|
if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) {
|
||||||
return (float) shadow_data[which];
|
return (float) _shadow_data[which];
|
||||||
} else {
|
} 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;
|
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 (LADSPA_IS_PORT_CONTROL (port_descriptor (x))) {
|
||||||
if (c++ == n) {
|
if (c++ == n) {
|
||||||
ok = true;
|
ok = true;
|
||||||
|
|
@ -383,7 +356,7 @@ LadspaPlugin::get_state()
|
||||||
child = new XMLNode("port");
|
child = new XMLNode("port");
|
||||||
snprintf(buf, sizeof(buf), "%u", i);
|
snprintf(buf, sizeof(buf), "%u", i);
|
||||||
child->add_property("number", string(buf));
|
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));
|
child->add_property("value", string(buf));
|
||||||
root->add_child_nocopy (*child);
|
root->add_child_nocopy (*child);
|
||||||
}
|
}
|
||||||
|
|
@ -515,8 +488,8 @@ LadspaPlugin::signal_latency () const
|
||||||
return _user_latency;
|
return _user_latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (latency_control_port) {
|
if (_latency_control_port) {
|
||||||
return (nframes_t) floor (*latency_control_port);
|
return (nframes_t) floor (*_latency_control_port);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -617,16 +590,16 @@ LadspaPlugin::run_in_place (nframes_t nframes)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < parameter_count(); ++i) {
|
for (uint32_t i = 0; i < parameter_count(); ++i) {
|
||||||
if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (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
|
void
|
||||||
LadspaPlugin::latency_compute_run ()
|
LadspaPlugin::latency_compute_run ()
|
||||||
{
|
{
|
||||||
if (!latency_control_port) {
|
if (!_latency_control_port) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,7 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern.subject = matches1->object;
|
pattern.subject = matches1->object;
|
||||||
pattern.predicate = (char*)LADSPA_BASE "hasLabel";
|
pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
|
||||||
pattern.object = 0;
|
pattern.object = 0;
|
||||||
pattern.object_type = lrdf_literal;
|
pattern.object_type = lrdf_literal;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,6 @@ Session::Session (AudioEngine &eng,
|
||||||
|
|
||||||
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
|
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
|
||||||
|
|
||||||
|
|
||||||
Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
|
Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -711,7 +710,7 @@ Session::when_engine_running ()
|
||||||
|
|
||||||
osc->set_session (*this);
|
osc->set_session (*this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -716,7 +716,7 @@ Session::save_state (string snapshot_name, bool pending)
|
||||||
bool was_dirty = dirty();
|
bool was_dirty = dirty();
|
||||||
|
|
||||||
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
|
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
|
||||||
|
|
||||||
if (was_dirty) {
|
if (was_dirty) {
|
||||||
DirtyChanged (); /* EMIT SIGNAL */
|
DirtyChanged (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
@ -1270,8 +1270,8 @@ Session::set_state (const XMLNode& node)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((child = find_named_node (node, "Bundles")) == 0) {
|
if ((child = find_named_node (node, "Bundles")) == 0) {
|
||||||
error << _("Session: XML state has no bundles section") << endmsg;
|
warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
|
||||||
goto out;
|
//goto out;
|
||||||
} else {
|
} else {
|
||||||
/* We can't load Bundles yet as they need to be able
|
/* 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
|
to convert from port names to Port objects, which can't happen until
|
||||||
|
|
|
||||||
|
|
@ -510,15 +510,3 @@ VSTPluginInfo::load (Session& session)
|
||||||
return PluginPtr ((Plugin*) 0);
|
return PluginPtr ((Plugin*) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
VSTPlugin::store_state (ARDOUR::PluginState& s)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VSTPlugin::restore_state (ARDOUR::PluginState& s)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,8 @@ Glib::RefPtr<Gdk::Pixbuf> FastMeter::request_vertical_meter(int width, int heigh
|
||||||
height = min_v_pixbuf_size;
|
height = min_v_pixbuf_size;
|
||||||
if (height > max_v_pixbuf_size)
|
if (height > max_v_pixbuf_size)
|
||||||
height = max_v_pixbuf_size;
|
height = max_v_pixbuf_size;
|
||||||
|
|
||||||
|
//int index = height - 1;
|
||||||
|
|
||||||
//if (v_pixbuf_cache == 0) {
|
//if (v_pixbuf_cache == 0) {
|
||||||
// v_pixbuf_cache = (Glib::RefPtr<Gdk::Pixbuf>*) malloc(sizeof(Glib::RefPtr<Gdk::Pixbuf>) * max_v_pixbuf_size);
|
// 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.width = pixrect.width;
|
||||||
background.height = pixheight - top_of_meter;
|
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,
|
get_window()->draw_rectangle (get_style()->get_black_gc(), true,
|
||||||
intersection.x, intersection.y,
|
intersection.x, intersection.y,
|
||||||
intersection.width, intersection.height);
|
intersection.width, intersection.height);
|
||||||
|
|
@ -408,7 +410,7 @@ FastMeter::horizontal_expose (GdkEventExpose* ev)
|
||||||
background.width = pixwidth - right_of_meter;
|
background.width = pixwidth - right_of_meter;
|
||||||
background.height = pixrect.height;
|
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,
|
get_window()->draw_rectangle (get_style()->get_black_gc(), true,
|
||||||
intersection.x + right_of_meter, intersection.y,
|
intersection.x + right_of_meter, intersection.y,
|
||||||
intersection.width, intersection.height);
|
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,
|
get_window()->draw_pixbuf(get_style()->get_fg_gc(get_state()), pixbuf,
|
||||||
intersection.x, intersection.y,
|
intersection.x, intersection.y,
|
||||||
intersection.x, intersection.y,
|
intersection.x, intersection.y,
|
||||||
intersection.width, intersection.height,
|
pixrect.width, intersection.height,
|
||||||
Gdk::RGB_DITHER_NONE, 0, 0);
|
Gdk::RGB_DITHER_NONE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
26
libs/vamp-sdk/COPYING
Normal file
26
libs/vamp-sdk/COPYING
Normal file
|
|
@ -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.
|
||||||
|
|
||||||
240
libs/vamp-sdk/README
Normal file
240
libs/vamp-sdk/README
Normal file
|
|
@ -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).
|
||||||
|
|
||||||
39
libs/vamp-sdk/SConscript
Normal file
39
libs/vamp-sdk/SConscript
Normal file
|
|
@ -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')))
|
||||||
405
libs/vamp-sdk/vamp-sdk/Plugin.h
Normal file
405
libs/vamp-sdk/vamp-sdk/Plugin.h
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
851
libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp
Normal file
851
libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp
Normal file
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
117
libs/vamp-sdk/vamp-sdk/PluginAdapter.h
Normal file
117
libs/vamp-sdk/vamp-sdk/PluginAdapter.h
Normal file
|
|
@ -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
|
||||||
|
|
||||||
252
libs/vamp-sdk/vamp-sdk/PluginBase.h
Normal file
252
libs/vamp-sdk/vamp-sdk/PluginBase.h
Normal file
|
|
@ -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
|
||||||
418
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
Normal file
418
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
117
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h
Normal file
117
libs/vamp-sdk/vamp-sdk/PluginHostAdapter.h
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
254
libs/vamp-sdk/vamp-sdk/RealTime.cpp
Normal file
254
libs/vamp-sdk/vamp-sdk/RealTime.cpp
Normal file
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
154
libs/vamp-sdk/vamp-sdk/RealTime.h
Normal file
154
libs/vamp-sdk/vamp-sdk/RealTime.h
Normal file
|
|
@ -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
|
||||||
228
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp
Normal file
228
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.cpp
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
128
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h
Normal file
128
libs/vamp-sdk/vamp-sdk/hostext/PluginChannelAdapter.h
Normal file
|
|
@ -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
|
||||||
458
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
Normal file
458
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.cpp
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
103
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h
Normal file
103
libs/vamp-sdk/vamp-sdk/hostext/PluginInputDomainAdapter.h
Normal file
|
|
@ -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
|
||||||
601
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
Normal file
601
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.cpp
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
218
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h
Normal file
218
libs/vamp-sdk/vamp-sdk/hostext/PluginLoader.h
Normal file
|
|
@ -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
|
||||||
|
|
||||||
201
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp
Normal file
201
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.cpp
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
106
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h
Normal file
106
libs/vamp-sdk/vamp-sdk/hostext/PluginWrapper.h
Normal file
|
|
@ -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
|
||||||
9
libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in
Normal file
9
libs/vamp-sdk/vamp-sdk/libvamp-hostsdk.la.in
Normal file
|
|
@ -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%'
|
||||||
9
libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in
Normal file
9
libs/vamp-sdk/vamp-sdk/libvamp-sdk.la.in
Normal file
|
|
@ -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%'
|
||||||
339
libs/vamp-sdk/vamp/vamp.h
Normal file
339
libs/vamp-sdk/vamp/vamp.h
Normal file
|
|
@ -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
|
||||||
10
libs/vamp-sdk/vamp/vamp.pc.in
Normal file
10
libs/vamp-sdk/vamp/vamp.pc.in
Normal file
|
|
@ -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}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __ardour_svn_revision_h__
|
#ifndef __ardour_svn_revision_h__
|
||||||
#define __ardour_svn_revision_h__
|
#define __ardour_svn_revision_h__
|
||||||
static const char* ardour_svn_revision = "2885";
|
static const char* ardour_svn_revision = "2884";
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,260 +1,617 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Session version="0.821.0">
|
<Session version="2.0.0" id-counter="1191241714">
|
||||||
<Options>
|
<Config>
|
||||||
<recording-plugins val="no"/>
|
<Option name="output-auto-connect" value="2"/>
|
||||||
<slave type="none"/>
|
<Option name="input-auto-connect" value="1"/>
|
||||||
<send-midi-timecode val="no"/>
|
<Option name="mtc-port-name" value="control"/>
|
||||||
<send-midi-machine-control val="no"/>
|
<Option name="mmc-port-name" value="control"/>
|
||||||
<input-auto-connect val="1"/>
|
<Option name="midi-port-name" value="control"/>
|
||||||
<output-auto-connect val="2"/>
|
<Option name="mmc-control" value="0"/>
|
||||||
<max-level val="0"/>
|
<Option name="midi-feedback" value="0"/>
|
||||||
<min-level val="0"/>
|
<Option name="xfade-model" value="0"/>
|
||||||
<meter-hold val="10.000000"/>
|
<Option name="edit-mode" value="0"/>
|
||||||
<long-over-length val="10"/>
|
<Option name="layer-model" value="0"/>
|
||||||
<short-over-length val="2"/>
|
<Option name="solo-model" value="0"/>
|
||||||
<shuttle-speed-factor val="1.000000"/>
|
<Option name="all-safe" value="0"/>
|
||||||
<shuttle-speed-threshold val="5.000000"/>
|
<Option name="auto-play" value="0"/>
|
||||||
<rf-speed val="2.000000"/>
|
<Option name="auto-return" value="0"/>
|
||||||
<smpte-frames-per-second val="30.000000"/>
|
<Option name="auto-input" value="1"/>
|
||||||
<edit-mode val="slide"/>
|
<Option name="punch-in" value="0"/>
|
||||||
<auto-play val="no"/>
|
<Option name="punch-out" value="0"/>
|
||||||
<auto-input val="no"/>
|
<Option name="seamless-loop" value="0"/>
|
||||||
<seamless-loop val="no"/>
|
<Option name="rf-speed" value="2"/>
|
||||||
<punch-in val="no"/>
|
<Option name="shuttle-speed-factor" value="1"/>
|
||||||
<punch-out val="no"/>
|
<Option name="shuttle-speed-threshold" value="5"/>
|
||||||
<all-safe val="no"/>
|
<Option name="meter-hold" value="10"/>
|
||||||
<auto-return val="no"/>
|
<Option name="meter-falloff" value="1.5"/>
|
||||||
<mmc-control val="no"/>
|
<end-marker-is-free val="no"/>
|
||||||
<recording-plugins val="no"/>
|
</Config>
|
||||||
<auto-crossfade val="no"/>
|
|
||||||
<audible-click val="no"/>
|
|
||||||
<align-style val="existing"/>
|
|
||||||
</Options>
|
|
||||||
<Sources/>
|
<Sources/>
|
||||||
<Regions/>
|
<Regions/>
|
||||||
<DiskStreams>
|
<DiskStreams>
|
||||||
<DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" 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 2.1" speed="1" name="Audio 2" id="1088698381722129"/>
|
||||||
<DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" 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 4.1" speed="1" name="Audio 4" id="1088698419943526"/>
|
||||||
<DiskStream channels="2" playlist="Audio 5.1" speed="1.000000" name="Audio 5" id="1088698450528071"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 5.1" speed="1" name="Audio 5" id="1088698450528071"/>
|
||||||
<DiskStream channels="2" playlist="Audio 6.1" speed="1.000000" name="Audio 6" id="1088698450754348"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 6.1" speed="1" name="Audio 6" id="1088698450754348"/>
|
||||||
<DiskStream channels="2" playlist="Audio 7.1" speed="1.000000" name="Audio 7" id="1088698450937150"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 7.1" speed="1" 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 8.1" speed="1" name="Audio 8" id="1088698451167172"/>
|
||||||
<DiskStream channels="2" playlist="Audio 9.1" speed="1.000000" name="Audio 9" id="1088698483525991"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 9.1" speed="1" name="Audio 9" id="1088698483525991"/>
|
||||||
<DiskStream channels="2" playlist="Audio 10.1" speed="1.000000" name="Audio 10" id="1088698483801345"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 10.1" speed="1" name="Audio 10" id="1088698483801345"/>
|
||||||
<DiskStream channels="2" playlist="Audio 11.1" speed="1.000000" name="Audio 11" id="1088698484086727"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 11.1" speed="1" name="Audio 11" id="1088698484086727"/>
|
||||||
<DiskStream channels="2" playlist="Audio 12.1" speed="1.000000" name="Audio 12" id="1088698484325738"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 12.1" speed="1" name="Audio 12" id="1088698484325738"/>
|
||||||
<DiskStream channels="2" playlist="Audio 13.1" speed="1.000000" name="Audio 13" id="1088698484576054"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 13.1" speed="1" name="Audio 13" id="1088698484576054"/>
|
||||||
<DiskStream channels="2" playlist="Audio 14.1" speed="1.000000" name="Audio 14" id="1088698484839332"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 14.1" speed="1" name="Audio 14" id="1088698484839332"/>
|
||||||
<DiskStream channels="2" playlist="Audio 15.1" speed="1.000000" name="Audio 15" id="1088698485116518"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 15.1" speed="1" 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 16.1" speed="1" name="Audio 16" id="1088698485412133"/>
|
||||||
</DiskStreams>
|
</DiskStreams>
|
||||||
<Locations>
|
<Locations>
|
||||||
<Location name="end" start="14400000" end="14400000" flags="33"/>
|
<Location id="1191241715" name="start" start="0" end="0" flags="IsMark,IsStart"/>
|
||||||
<Location name="Loop" start="0" end="14400000" flags="12"/>
|
<Location id="1191241716" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/>
|
||||||
<Location name="Punch" start="0" end="14400000" flags="10"/>
|
|
||||||
</Locations>
|
</Locations>
|
||||||
<Connections/>
|
<Connections/>
|
||||||
<Routes>
|
<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">
|
<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="{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">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241256"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241265"/>
|
||||||
|
<controllable name="mute" id="1191241266"/>
|
||||||
|
<remote_control id="1"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241268"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241277"/>
|
||||||
|
<controllable name="mute" id="1191241278"/>
|
||||||
|
<remote_control id="2"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241279"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241281"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241290"/>
|
||||||
|
<controllable name="mute" id="1191241291"/>
|
||||||
|
<remote_control id="3"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241292"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241294"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241303"/>
|
||||||
|
<controllable name="mute" id="1191241304"/>
|
||||||
|
<remote_control id="4"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241305"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241307"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241316"/>
|
||||||
|
<controllable name="mute" id="1191241317"/>
|
||||||
|
<remote_control id="5"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241318"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241320"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241329"/>
|
||||||
|
<controllable name="mute" id="1191241330"/>
|
||||||
|
<remote_control id="6"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241331"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241333"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241342"/>
|
||||||
|
<controllable name="mute" id="1191241343"/>
|
||||||
|
<remote_control id="7"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241344"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241346"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241355"/>
|
||||||
|
<controllable name="mute" id="1191241356"/>
|
||||||
|
<remote_control id="8"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241357"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241359"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241368"/>
|
||||||
|
<controllable name="mute" id="1191241369"/>
|
||||||
|
<remote_control id="9"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241370"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241372"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241381"/>
|
||||||
|
<controllable name="mute" id="1191241382"/>
|
||||||
|
<remote_control id="10"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241383"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241385"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241394"/>
|
||||||
|
<controllable name="mute" id="1191241395"/>
|
||||||
|
<remote_control id="11"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241396"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241398"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241407"/>
|
||||||
|
<controllable name="mute" id="1191241408"/>
|
||||||
|
<remote_control id="12"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241409"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241411"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241420"/>
|
||||||
|
<controllable name="mute" id="1191241421"/>
|
||||||
|
<remote_control id="13"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241422"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241424"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241433"/>
|
||||||
|
<controllable name="mute" id="1191241434"/>
|
||||||
|
<remote_control id="14"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241435"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241437"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241446"/>
|
||||||
|
<controllable name="mute" id="1191241447"/>
|
||||||
|
<remote_control id="15"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241448"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241450"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241459"/>
|
||||||
|
<controllable name="mute" id="1191241460"/>
|
||||||
|
<remote_control id="16"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241461"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241463"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241472"/>
|
||||||
|
<controllable name="mute" id="1191241473"/>
|
||||||
|
<remote_control id="17"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241474"/>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
<EditGroups/>
|
<EditGroups/>
|
||||||
<MixGroups/>
|
<MixGroups/>
|
||||||
<Playlists/>
|
<Playlists/>
|
||||||
|
<UnusedPlaylists/>
|
||||||
<Click>
|
<Click>
|
||||||
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1">
|
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1">
|
||||||
<Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/>
|
<Panner linked="no" link_direction="SameDirection" bypassed="no"/>
|
||||||
|
<controllable name="gaincontrol" id="1191241476"/>
|
||||||
</IO>
|
</IO>
|
||||||
</Click>
|
</Click>
|
||||||
<TempoMap>
|
<TempoMap>
|
||||||
<Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/>
|
<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"/>
|
<Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/>
|
||||||
</TempoMap>
|
</TempoMap>
|
||||||
|
<ControlProtocols>
|
||||||
|
<Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes">
|
||||||
|
<controls/>
|
||||||
|
</Protocol>
|
||||||
|
</ControlProtocols>
|
||||||
</Session>
|
</Session>
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,155 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Session version="0.821.0">
|
<Session version="2.0.0" id-counter="1191241115">
|
||||||
<Options>
|
<Config>
|
||||||
<recording-plugins val="no"/>
|
<Option name="output-auto-connect" value="2"/>
|
||||||
<slave type="none"/>
|
<Option name="input-auto-connect" value="1"/>
|
||||||
<send-midi-timecode val="no"/>
|
<Option name="mtc-port-name" value="control"/>
|
||||||
<send-midi-machine-control val="no"/>
|
<Option name="mmc-port-name" value="control"/>
|
||||||
<input-auto-connect val="1"/>
|
<Option name="midi-port-name" value="control"/>
|
||||||
<output-auto-connect val="2"/>
|
<Option name="mmc-control" value="0"/>
|
||||||
<max-level val="0"/>
|
<Option name="midi-feedback" value="0"/>
|
||||||
<min-level val="0"/>
|
<Option name="xfade-model" value="0"/>
|
||||||
<meter-hold val="10.000000"/>
|
<Option name="edit-mode" value="0"/>
|
||||||
<long-over-length val="10"/>
|
<Option name="layer-model" value="0"/>
|
||||||
<short-over-length val="2"/>
|
<Option name="solo-model" value="0"/>
|
||||||
<shuttle-speed-factor val="1.000000"/>
|
<Option name="all-safe" value="0"/>
|
||||||
<shuttle-speed-threshold val="5.000000"/>
|
<Option name="auto-play" value="0"/>
|
||||||
<rf-speed val="2.000000"/>
|
<Option name="auto-return" value="0"/>
|
||||||
<smpte-frames-per-second val="30.000000"/>
|
<Option name="auto-input" value="1"/>
|
||||||
<edit-mode val="slide"/>
|
<Option name="punch-in" value="0"/>
|
||||||
<auto-play val="no"/>
|
<Option name="punch-out" value="0"/>
|
||||||
<auto-input val="no"/>
|
<Option name="seamless-loop" value="0"/>
|
||||||
<seamless-loop val="no"/>
|
<Option name="rf-speed" value="2"/>
|
||||||
<punch-in val="no"/>
|
<Option name="shuttle-speed-factor" value="1"/>
|
||||||
<punch-out val="no"/>
|
<Option name="shuttle-speed-threshold" value="5"/>
|
||||||
<all-safe val="no"/>
|
<Option name="meter-hold" value="10"/>
|
||||||
<auto-return val="no"/>
|
<Option name="meter-falloff" value="1.5"/>
|
||||||
<mmc-control val="no"/>
|
<end-marker-is-free val="no"/>
|
||||||
<recording-plugins val="no"/>
|
</Config>
|
||||||
<auto-crossfade val="no"/>
|
|
||||||
<audible-click val="no"/>
|
|
||||||
<align-style val="existing"/>
|
|
||||||
</Options>
|
|
||||||
<Sources/>
|
<Sources/>
|
||||||
<Regions/>
|
<Regions/>
|
||||||
<DiskStreams>
|
<DiskStreams>
|
||||||
<DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" 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 2.1" speed="1" name="Audio 2" id="1088698381722129"/>
|
||||||
</DiskStreams>
|
</DiskStreams>
|
||||||
<Locations>
|
<Locations>
|
||||||
<Location name="end" start="14400000" end="14400000" flags="33"/>
|
<Location id="1191241116" name="start" start="0" end="0" flags="IsMark,IsStart"/>
|
||||||
<Location name="Loop" start="0" end="14400000" flags="12"/>
|
<Location id="1191241117" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/>
|
||||||
<Location name="Punch" start="0" end="14400000" flags="10"/>
|
|
||||||
</Locations>
|
</Locations>
|
||||||
<Connections/>
|
<Connections/>
|
||||||
<Routes>
|
<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">
|
<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="{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">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241021"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241030"/>
|
||||||
|
<controllable name="mute" id="1191241031"/>
|
||||||
|
<remote_control id="1"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241033"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241042"/>
|
||||||
|
<controllable name="mute" id="1191241043"/>
|
||||||
|
<remote_control id="2"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241044"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241046"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241055"/>
|
||||||
|
<controllable name="mute" id="1191241056"/>
|
||||||
|
<remote_control id="3"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241057"/>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
<EditGroups/>
|
<EditGroups/>
|
||||||
<MixGroups/>
|
<MixGroups/>
|
||||||
<Playlists/>
|
<Playlists/>
|
||||||
|
<UnusedPlaylists/>
|
||||||
<Click>
|
<Click>
|
||||||
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1">
|
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1">
|
||||||
<Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/>
|
<Panner linked="no" link_direction="SameDirection" bypassed="no"/>
|
||||||
|
<controllable name="gaincontrol" id="1191241059"/>
|
||||||
</IO>
|
</IO>
|
||||||
</Click>
|
</Click>
|
||||||
<TempoMap>
|
<TempoMap>
|
||||||
<Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/>
|
<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"/>
|
<Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/>
|
||||||
</TempoMap>
|
</TempoMap>
|
||||||
|
<ControlProtocols>
|
||||||
|
<Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes">
|
||||||
|
<controls/>
|
||||||
|
</Protocol>
|
||||||
|
</ControlProtocols>
|
||||||
</Session>
|
</Session>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,116 +1,221 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Session version="0.821.0">
|
<Session version="2.0.0" id-counter="1191241255">
|
||||||
<Options>
|
<Config>
|
||||||
<recording-plugins val="no"/>
|
<Option name="output-auto-connect" value="2"/>
|
||||||
<slave type="none"/>
|
<Option name="input-auto-connect" value="1"/>
|
||||||
<send-midi-timecode val="no"/>
|
<Option name="mtc-port-name" value="control"/>
|
||||||
<send-midi-machine-control val="no"/>
|
<Option name="mmc-port-name" value="control"/>
|
||||||
<input-auto-connect val="1"/>
|
<Option name="midi-port-name" value="control"/>
|
||||||
<output-auto-connect val="2"/>
|
<Option name="mmc-control" value="0"/>
|
||||||
<max-level val="0"/>
|
<Option name="midi-feedback" value="0"/>
|
||||||
<min-level val="0"/>
|
<Option name="xfade-model" value="0"/>
|
||||||
<meter-hold val="10.000000"/>
|
<Option name="edit-mode" value="0"/>
|
||||||
<long-over-length val="10"/>
|
<Option name="layer-model" value="0"/>
|
||||||
<short-over-length val="2"/>
|
<Option name="solo-model" value="0"/>
|
||||||
<shuttle-speed-factor val="1.000000"/>
|
<Option name="all-safe" value="0"/>
|
||||||
<shuttle-speed-threshold val="5.000000"/>
|
<Option name="auto-play" value="0"/>
|
||||||
<rf-speed val="2.000000"/>
|
<Option name="auto-return" value="0"/>
|
||||||
<smpte-frames-per-second val="30.000000"/>
|
<Option name="auto-input" value="1"/>
|
||||||
<edit-mode val="slide"/>
|
<Option name="punch-in" value="0"/>
|
||||||
<auto-play val="no"/>
|
<Option name="punch-out" value="0"/>
|
||||||
<auto-input val="no"/>
|
<Option name="seamless-loop" value="0"/>
|
||||||
<seamless-loop val="no"/>
|
<Option name="rf-speed" value="2"/>
|
||||||
<punch-in val="no"/>
|
<Option name="shuttle-speed-factor" value="1"/>
|
||||||
<punch-out val="no"/>
|
<Option name="shuttle-speed-threshold" value="5"/>
|
||||||
<all-safe val="no"/>
|
<Option name="meter-hold" value="10"/>
|
||||||
<auto-return val="no"/>
|
<Option name="meter-falloff" value="1.5"/>
|
||||||
<mmc-control val="no"/>
|
<end-marker-is-free val="no"/>
|
||||||
<recording-plugins val="no"/>
|
</Config>
|
||||||
<auto-crossfade val="no"/>
|
|
||||||
<audible-click val="no"/>
|
|
||||||
<align-style val="existing"/>
|
|
||||||
</Options>
|
|
||||||
<Sources/>
|
<Sources/>
|
||||||
<Regions/>
|
<Regions/>
|
||||||
<DiskStreams>
|
<DiskStreams>
|
||||||
<DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" 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 2.1" speed="1" name="Audio 2" id="1088698381722129"/>
|
||||||
<DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" 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 4.1" speed="1" name="Audio 4" id="1088698419943526"/>
|
||||||
</DiskStreams>
|
</DiskStreams>
|
||||||
<Locations>
|
<Locations>
|
||||||
<Location name="end" start="14400000" end="14400000" flags="33"/>
|
<Location id="1191241256" name="start" start="0" end="0" flags="IsMark,IsStart"/>
|
||||||
<Location name="Loop" start="0" end="14400000" flags="12"/>
|
<Location id="1191241257" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/>
|
||||||
<Location name="Punch" start="0" end="14400000" flags="10"/>
|
|
||||||
</Locations>
|
</Locations>
|
||||||
<Connections/>
|
<Connections/>
|
||||||
<Routes>
|
<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">
|
<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="{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">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241109"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241118"/>
|
||||||
|
<controllable name="mute" id="1191241119"/>
|
||||||
|
<remote_control id="1"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241121"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241130"/>
|
||||||
|
<controllable name="mute" id="1191241131"/>
|
||||||
|
<remote_control id="2"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241132"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241134"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241143"/>
|
||||||
|
<controllable name="mute" id="1191241144"/>
|
||||||
|
<remote_control id="3"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241145"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241147"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241156"/>
|
||||||
|
<controllable name="mute" id="1191241157"/>
|
||||||
|
<remote_control id="4"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241158"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241160"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241169"/>
|
||||||
|
<controllable name="mute" id="1191241170"/>
|
||||||
|
<remote_control id="5"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241171"/>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
<EditGroups/>
|
<EditGroups/>
|
||||||
<MixGroups/>
|
<MixGroups/>
|
||||||
<Playlists/>
|
<Playlists/>
|
||||||
|
<UnusedPlaylists/>
|
||||||
<Click>
|
<Click>
|
||||||
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1">
|
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1">
|
||||||
<Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/>
|
<Panner linked="no" link_direction="SameDirection" bypassed="no"/>
|
||||||
|
<controllable name="gaincontrol" id="1191241173"/>
|
||||||
</IO>
|
</IO>
|
||||||
</Click>
|
</Click>
|
||||||
<TempoMap>
|
<TempoMap>
|
||||||
<Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/>
|
<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"/>
|
<Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/>
|
||||||
</TempoMap>
|
</TempoMap>
|
||||||
|
<ControlProtocols>
|
||||||
|
<Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes">
|
||||||
|
<controls/>
|
||||||
|
</Protocol>
|
||||||
|
</ControlProtocols>
|
||||||
</Session>
|
</Session>
|
||||||
|
|
|
||||||
|
|
@ -1,164 +1,353 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Session version="0.821.0">
|
<Session version="2.0.0" id-counter="1191241420">
|
||||||
<Options>
|
<Config>
|
||||||
<recording-plugins val="no"/>
|
<Option name="output-auto-connect" value="2"/>
|
||||||
<slave type="none"/>
|
<Option name="input-auto-connect" value="1"/>
|
||||||
<send-midi-timecode val="no"/>
|
<Option name="mtc-port-name" value="control"/>
|
||||||
<send-midi-machine-control val="no"/>
|
<Option name="mmc-port-name" value="control"/>
|
||||||
<input-auto-connect val="1"/>
|
<Option name="midi-port-name" value="control"/>
|
||||||
<output-auto-connect val="2"/>
|
<Option name="mmc-control" value="0"/>
|
||||||
<max-level val="0"/>
|
<Option name="midi-feedback" value="0"/>
|
||||||
<min-level val="0"/>
|
<Option name="xfade-model" value="0"/>
|
||||||
<meter-hold val="10.000000"/>
|
<Option name="edit-mode" value="0"/>
|
||||||
<long-over-length val="10"/>
|
<Option name="layer-model" value="0"/>
|
||||||
<short-over-length val="2"/>
|
<Option name="solo-model" value="0"/>
|
||||||
<shuttle-speed-factor val="1.000000"/>
|
<Option name="all-safe" value="0"/>
|
||||||
<shuttle-speed-threshold val="5.000000"/>
|
<Option name="auto-play" value="0"/>
|
||||||
<rf-speed val="2.000000"/>
|
<Option name="auto-return" value="0"/>
|
||||||
<smpte-frames-per-second val="30.000000"/>
|
<Option name="auto-input" value="1"/>
|
||||||
<edit-mode val="slide"/>
|
<Option name="punch-in" value="0"/>
|
||||||
<auto-play val="no"/>
|
<Option name="punch-out" value="0"/>
|
||||||
<auto-input val="no"/>
|
<Option name="seamless-loop" value="0"/>
|
||||||
<seamless-loop val="no"/>
|
<Option name="rf-speed" value="2"/>
|
||||||
<punch-in val="no"/>
|
<Option name="shuttle-speed-factor" value="1"/>
|
||||||
<punch-out val="no"/>
|
<Option name="shuttle-speed-threshold" value="5"/>
|
||||||
<all-safe val="no"/>
|
<Option name="meter-hold" value="10"/>
|
||||||
<auto-return val="no"/>
|
<Option name="meter-falloff" value="1.5"/>
|
||||||
<mmc-control val="no"/>
|
<end-marker-is-free val="no"/>
|
||||||
<recording-plugins val="no"/>
|
</Config>
|
||||||
<auto-crossfade val="no"/>
|
|
||||||
<audible-click val="no"/>
|
|
||||||
<align-style val="existing"/>
|
|
||||||
</Options>
|
|
||||||
<Sources/>
|
<Sources/>
|
||||||
<Regions/>
|
<Regions/>
|
||||||
<DiskStreams>
|
<DiskStreams>
|
||||||
<DiskStream channels="2" playlist="Audio 1.1" speed="1.000000" name="Audio 1" id="1088698381595945"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 1.1" speed="1" 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 2.1" speed="1" name="Audio 2" id="1088698381722129"/>
|
||||||
<DiskStream channels="2" playlist="Audio 3.1" speed="1.000000" name="Audio 3" id="1088698419793849"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 3.1" speed="1" 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 4.1" speed="1" name="Audio 4" id="1088698419943526"/>
|
||||||
<DiskStream channels="2" playlist="Audio 5.1" speed="1.000000" name="Audio 5" id="1088698450528071"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 5.1" speed="1" name="Audio 5" id="1088698450528071"/>
|
||||||
<DiskStream channels="2" playlist="Audio 6.1" speed="1.000000" name="Audio 6" id="1088698450754348"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 6.1" speed="1" name="Audio 6" id="1088698450754348"/>
|
||||||
<DiskStream channels="2" playlist="Audio 7.1" speed="1.000000" name="Audio 7" id="1088698450937150"/>
|
<AudioDiskstream flags="Recordable" channels="2" playlist="Audio 7.1" speed="1" 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 8.1" speed="1" name="Audio 8" id="1088698451167172"/>
|
||||||
</DiskStreams>
|
</DiskStreams>
|
||||||
<Locations>
|
<Locations>
|
||||||
<Location name="end" start="14400000" end="14400000" flags="33"/>
|
<Location id="1191241421" name="start" start="0" end="0" flags="IsMark,IsStart"/>
|
||||||
<Location name="Loop" start="0" end="14400000" flags="12"/>
|
<Location id="1191241422" name="end" start="14400000" end="14400000" flags="IsMark,IsEnd"/>
|
||||||
<Location name="Punch" start="0" end="14400000" flags="10"/>
|
|
||||||
</Locations>
|
</Locations>
|
||||||
<Connections/>
|
<Connections/>
|
||||||
<Routes>
|
<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">
|
<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="{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">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241170"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241179"/>
|
||||||
|
<controllable name="mute" id="1191241180"/>
|
||||||
|
<remote_control id="1"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241182"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241191"/>
|
||||||
|
<controllable name="mute" id="1191241192"/>
|
||||||
|
<remote_control id="2"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241193"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241195"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241204"/>
|
||||||
|
<controllable name="mute" id="1191241205"/>
|
||||||
|
<remote_control id="3"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241206"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241208"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241217"/>
|
||||||
|
<controllable name="mute" id="1191241218"/>
|
||||||
|
<remote_control id="4"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241219"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241221"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241230"/>
|
||||||
|
<controllable name="mute" id="1191241231"/>
|
||||||
|
<remote_control id="5"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241232"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241234"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241243"/>
|
||||||
|
<controllable name="mute" id="1191241244"/>
|
||||||
|
<remote_control id="6"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241245"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241247"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241256"/>
|
||||||
|
<controllable name="mute" id="1191241257"/>
|
||||||
|
<remote_control id="7"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241258"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241260"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241269"/>
|
||||||
|
<controllable name="mute" id="1191241270"/>
|
||||||
|
<remote_control id="8"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241271"/>
|
||||||
</Route>
|
</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">
|
<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="{ardour:master/in 1}{ardour:master/in 2}" gain="1" iolimits="1,-1,-1,-1" automation-state="0x0" automation-style="0x1">
|
<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="0">
|
<Panner linked="no" link_direction="SameDirection" bypassed="no">
|
||||||
<StreamPanner x="0.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<Output x="0" y="0"/>
|
||||||
<StreamPanner x="1.000000" type="Equal Power Stereo" automation-state="0x0" automation-style="0x1" bypassed="no" muted="no"/>
|
<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>
|
</Panner>
|
||||||
|
<controllable name="gaincontrol" id="1191241273"/>
|
||||||
</IO>
|
</IO>
|
||||||
|
<controllable name="solo" id="1191241282"/>
|
||||||
|
<controllable name="mute" id="1191241283"/>
|
||||||
|
<remote_control id="9"/>
|
||||||
<extra>
|
<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>
|
</extra>
|
||||||
|
<alignment style="ExistingMaterial"/>
|
||||||
|
<controllable name="recenable" id="1191241284"/>
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
<EditGroups/>
|
<EditGroups/>
|
||||||
<MixGroups/>
|
<MixGroups/>
|
||||||
<Playlists/>
|
<Playlists/>
|
||||||
|
<UnusedPlaylists/>
|
||||||
<Click>
|
<Click>
|
||||||
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1" iolimits="0,0,-1,-1" automation-state="0x0" automation-style="0x1">
|
<IO name="click" id="1088698373994975" inputs="" outputs="{%JACK_INPUT%1}" gain="1.000000000000" iolimits="0,0,-1,-1">
|
||||||
<Panner linked="no" link_direction="0" automation="t1-pan-click.automation"/>
|
<Panner linked="no" link_direction="SameDirection" bypassed="no"/>
|
||||||
|
<controllable name="gaincontrol" id="1191241286"/>
|
||||||
</IO>
|
</IO>
|
||||||
</Click>
|
</Click>
|
||||||
<TempoMap>
|
<TempoMap>
|
||||||
<Tempo start="1|1|0" beats-per-minute="120.000000" movable="no"/>
|
<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"/>
|
<Meter start="1|1|0" note-type="4.000000" beats-per-bar="4.000000" movable="no"/>
|
||||||
</TempoMap>
|
</TempoMap>
|
||||||
|
<ControlProtocols>
|
||||||
|
<Protocol name="Generic MIDI" feedback="0" feedback_interval="10000" active="yes">
|
||||||
|
<controls/>
|
||||||
|
</Protocol>
|
||||||
|
</ControlProtocols>
|
||||||
</Session>
|
</Session>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue