mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Committed filthy mess of a working copy solely for moving between machines.
Nothing to see here, move along now... git-svn-id: svn://localhost/trunk/ardour2midi@575 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
0c1b9afc63
commit
74dd5bd706
51 changed files with 829 additions and 1033 deletions
17
SConstruct
17
SConstruct
|
|
@ -11,6 +11,8 @@ import platform
|
||||||
from sets import Set
|
from sets import Set
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
|
|
||||||
|
#import pickle
|
||||||
|
|
||||||
SConsignFile()
|
SConsignFile()
|
||||||
EnsureSConsVersion(0, 96)
|
EnsureSConsVersion(0, 96)
|
||||||
|
|
||||||
|
|
@ -459,7 +461,12 @@ libraries['dmalloc'] = conf.Finish ()
|
||||||
|
|
||||||
conf = Configure(env)
|
conf = Configure(env)
|
||||||
|
|
||||||
if conf.CheckCHeader('alsa/asoundlib.h'):
|
if conf.CheckCHeader('jack/midiport.h'):
|
||||||
|
libraries['sysmidi'] = LibraryInfo (LIBS='jack')
|
||||||
|
env['SYSMIDI'] = 'JACK MIDI'
|
||||||
|
subst_dict['%MIDITAG%'] = "control"
|
||||||
|
subst_dict['%MIDITYPE%'] = "jack"
|
||||||
|
elif conf.CheckCHeader('alsa/asoundlib.h'):
|
||||||
libraries['sysmidi'] = LibraryInfo (LIBS='asound')
|
libraries['sysmidi'] = LibraryInfo (LIBS='asound')
|
||||||
env['SYSMIDI'] = 'ALSA Sequencer'
|
env['SYSMIDI'] = 'ALSA Sequencer'
|
||||||
subst_dict['%MIDITAG%'] = "seq"
|
subst_dict['%MIDITAG%'] = "seq"
|
||||||
|
|
@ -587,6 +594,12 @@ Help(opts.GenerateHelpText(env))
|
||||||
if os.environ.has_key('PATH'):
|
if os.environ.has_key('PATH'):
|
||||||
env.Append(PATH = os.environ['PATH'])
|
env.Append(PATH = os.environ['PATH'])
|
||||||
|
|
||||||
|
if os.environ.has_key('TERM'):
|
||||||
|
env.Append(PATH = os.environ['TERM'])
|
||||||
|
|
||||||
|
if os.environ.has_key('HOME'):
|
||||||
|
env.Append(HOME = os.environ['HOME'])
|
||||||
|
|
||||||
if os.environ.has_key('PKG_CONFIG_PATH'):
|
if os.environ.has_key('PKG_CONFIG_PATH'):
|
||||||
env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
|
env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
|
||||||
|
|
||||||
|
|
@ -860,6 +873,8 @@ for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
|
||||||
for subdir in sublistdir:
|
for subdir in sublistdir:
|
||||||
SConscript (subdir + '/SConscript')
|
SConscript (subdir + '/SConscript')
|
||||||
|
|
||||||
|
#pickle.dump(env, open('.scons_env', 'w'), pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
|
env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
|
||||||
|
|
||||||
|
|
|
||||||
18
ardour.dox
18
ardour.dox
|
|
@ -202,7 +202,7 @@ OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
# func(std::string) {}). This also make the inheritance and collaboration
|
# func(std::string) {}). This also make the inheritance and collaboration
|
||||||
# diagrams that involve STL classes more complete and accurate.
|
# diagrams that involve STL classes more complete and accurate.
|
||||||
|
|
||||||
BUILTIN_STL_SUPPORT = YES
|
BUILTIN_STL_SUPPORT = NO
|
||||||
|
|
||||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||||
|
|
@ -233,12 +233,12 @@ EXTRACT_ALL = YES
|
||||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
||||||
# will be included in the documentation.
|
# will be included in the documentation.
|
||||||
|
|
||||||
EXTRACT_PRIVATE = NO
|
EXTRACT_PRIVATE = YES
|
||||||
|
|
||||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
||||||
# will be included in the documentation.
|
# will be included in the documentation.
|
||||||
|
|
||||||
EXTRACT_STATIC = NO
|
EXTRACT_STATIC = YES
|
||||||
|
|
||||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
|
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
|
||||||
# defined locally in source files will be included in the documentation.
|
# defined locally in source files will be included in the documentation.
|
||||||
|
|
@ -295,7 +295,7 @@ INTERNAL_DOCS = NO
|
||||||
# in case and if your file system supports case sensitive file names. Windows
|
# in case and if your file system supports case sensitive file names. Windows
|
||||||
# and Mac users are advised to set this option to NO.
|
# and Mac users are advised to set this option to NO.
|
||||||
|
|
||||||
CASE_SENSE_NAMES = NO
|
CASE_SENSE_NAMES = YES
|
||||||
|
|
||||||
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
||||||
# will show members with their full class and namespace scopes in the
|
# will show members with their full class and namespace scopes in the
|
||||||
|
|
@ -342,7 +342,7 @@ SORT_BY_SCOPE_NAME = NO
|
||||||
# disable (NO) the todo list. This list is created by putting \todo
|
# disable (NO) the todo list. This list is created by putting \todo
|
||||||
# commands in the documentation.
|
# commands in the documentation.
|
||||||
|
|
||||||
GENERATE_TODOLIST = NO
|
GENERATE_TODOLIST = YES
|
||||||
|
|
||||||
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
||||||
# disable (NO) the test list. This list is created by putting \test
|
# disable (NO) the test list. This list is created by putting \test
|
||||||
|
|
@ -354,13 +354,13 @@ GENERATE_TESTLIST = NO
|
||||||
# disable (NO) the bug list. This list is created by putting \bug
|
# disable (NO) the bug list. This list is created by putting \bug
|
||||||
# commands in the documentation.
|
# commands in the documentation.
|
||||||
|
|
||||||
GENERATE_BUGLIST = NO
|
GENERATE_BUGLIST = YES
|
||||||
|
|
||||||
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
|
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
|
||||||
# disable (NO) the deprecated list. This list is created by putting
|
# disable (NO) the deprecated list. This list is created by putting
|
||||||
# \deprecated commands in the documentation.
|
# \deprecated commands in the documentation.
|
||||||
|
|
||||||
GENERATE_DEPRECATEDLIST= NO
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
|
||||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
# The ENABLED_SECTIONS tag can be used to enable conditional
|
||||||
# documentation sections, marked by \if sectionname ... \endif.
|
# documentation sections, marked by \if sectionname ... \endif.
|
||||||
|
|
@ -459,7 +459,7 @@ WARN_LOGFILE =
|
||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = libs/pbd3 libs/midi++2 libs/ardour libs/gtkmm2ext gtk2_ardour
|
INPUT = libs/pbd3 libs/midi++2 libs/ardour #libs/gtkmm2ext gtk2_ardour
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
|
|
@ -1082,7 +1082,7 @@ CLASS_DIAGRAMS = YES
|
||||||
# inheritance and usage relations if the target is undocumented
|
# inheritance and usage relations if the target is undocumented
|
||||||
# or is not a class.
|
# or is not a class.
|
||||||
|
|
||||||
HIDE_UNDOC_RELATIONS = YES
|
HIDE_UNDOC_RELATIONS = NO
|
||||||
|
|
||||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||||
# available from the path. This tool is part of Graphviz, a graph visualization
|
# available from the path. This tool is part of Graphviz, a graph visualization
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#export G_DEBUG=fatal_criticals
|
#export G_DEBUG=fatal_criticals
|
||||||
|
|
||||||
export ARDOUR_PATH=./glade:./pixmaps:.:..
|
export ARDOUR_PATH=./glade:./pixmaps:.
|
||||||
|
|
||||||
export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libglademm:$LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libglademm:$LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,16 +81,20 @@ style "time_axis_view_item_name"
|
||||||
style "default_base" = "medium_text"
|
style "default_base" = "medium_text"
|
||||||
{
|
{
|
||||||
GtkWidget::cursor_color = {1.0, 1.0, 1.0 }
|
GtkWidget::cursor_color = {1.0, 1.0, 1.0 }
|
||||||
|
GtkButton::default_border = { 0, 0, 0, 0 }
|
||||||
|
GtkButton::default_outside_border = { 0, 0, 0, 0 }
|
||||||
|
GtkTreeView::vertical-padding = 0
|
||||||
|
GtkTreeView::horizontal-padding = 0
|
||||||
|
|
||||||
fg[NORMAL] = { 0.80, 0.80, 0.80 }
|
fg[NORMAL] = { 0.80, 0.80, 0.80 }
|
||||||
fg[ACTIVE] = { 0.80, 0.80, 0.80 }
|
fg[ACTIVE] = { 0.80, 0.80, 0.80 }
|
||||||
fg[PRELIGHT] = { 0.50, 1.0, 1.0 }
|
fg[PRELIGHT] = { 1.0, 1.0, 1.0 }
|
||||||
fg[INSENSITIVE] = { 0.80, 0.80, 0.80 }
|
fg[INSENSITIVE] = { 0.80, 0.80, 0.80 }
|
||||||
fg[SELECTED] = { 0.80, 0.80, 0.80 }
|
fg[SELECTED] = { 0.80, 0.80, 0.80 }
|
||||||
|
|
||||||
bg[NORMAL] = { 0.40, 0.40, 0.40 }
|
bg[NORMAL] = { 0.40, 0.40, 0.40 }
|
||||||
bg[ACTIVE] = { 0.40, 0.40, 0.40 }
|
bg[ACTIVE] = { 0.40, 0.40, 0.40 }
|
||||||
bg[PRELIGHT] = { 0.40, 0.40, 0.40 }
|
bg[PRELIGHT] = "#565690"
|
||||||
bg[INSENSITIVE] = { 0.10, 0.10, 0.10 }
|
bg[INSENSITIVE] = { 0.10, 0.10, 0.10 }
|
||||||
bg[SELECTED] = { 0, 0.40, 0.60 }
|
bg[SELECTED] = { 0, 0.40, 0.60 }
|
||||||
|
|
||||||
|
|
@ -105,6 +109,13 @@ style "default_base" = "medium_text"
|
||||||
base[PRELIGHT] = { 0.20, 0.20, 0.20 }
|
base[PRELIGHT] = { 0.20, 0.20, 0.20 }
|
||||||
base[INSENSITIVE] = "#4c5159"
|
base[INSENSITIVE] = "#4c5159"
|
||||||
base[SELECTED] = { 0.25, 0.25, 0.25 }
|
base[SELECTED] = { 0.25, 0.25, 0.25 }
|
||||||
|
|
||||||
|
engine "clearlooks" {
|
||||||
|
menubarstyle = 2 # 0 = flat, 1 = sunken, 2 = flat gradient
|
||||||
|
menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient), 2 = 3d-ish (button)
|
||||||
|
listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient)
|
||||||
|
progressbarstyle = 0 # 0 = candy bar, 1 = flat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
style "base_frame"
|
style "base_frame"
|
||||||
|
|
@ -131,11 +142,11 @@ style "black_mackie_menu_bar" = "medium_bold_text"
|
||||||
style "default_buttons_menus"
|
style "default_buttons_menus"
|
||||||
{
|
{
|
||||||
font_name = "sans 8"
|
font_name = "sans 8"
|
||||||
fg[ACTIVE] = { 0, 0, 0 }
|
fg[ACTIVE] = { 1.0, 1.0, 1.0 }
|
||||||
|
|
||||||
bg[NORMAL] = { 0.25, 0.25, 0.25 }
|
bg[NORMAL] = { 0.35, 0.35, 0.35 }
|
||||||
bg[ACTIVE] = { 0.50, 1.0, 1.0 }
|
bg[ACTIVE] = "#565690"
|
||||||
bg[PRELIGHT] = { 0.15, 0.15, 0.15 }
|
bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
|
||||||
bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
|
bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
|
||||||
bg[SELECTED] = { 0.20, 0.20, 0.20 }
|
bg[SELECTED] = { 0.20, 0.20, 0.20 }
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +250,7 @@ style "time_button" = "default_buttons_menus"
|
||||||
style "transport_button"
|
style "transport_button"
|
||||||
{
|
{
|
||||||
bg[ACTIVE] = { 0.50, 1.0, 0.50 }
|
bg[ACTIVE] = { 0.50, 1.0, 0.50 }
|
||||||
|
fg[ACTIVE] = { 0, 0, 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
style "transport_rec_button"
|
style "transport_rec_button"
|
||||||
|
|
@ -853,8 +865,8 @@ style "region_list_whole_file"
|
||||||
|
|
||||||
style "ardour_button" ="default_buttons_menus"
|
style "ardour_button" ="default_buttons_menus"
|
||||||
{
|
{
|
||||||
xthickness = 0
|
xthickness = 1
|
||||||
ythickness = 2
|
ythickness = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
#---------------------------------------------------------------
|
#---------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ If you still wish to quit, please use the\n\n\
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Config->save_state();
|
||||||
quit ();
|
quit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,24 +39,48 @@ using namespace ARDOUR;
|
||||||
void
|
void
|
||||||
ARDOUR_UI::setup_config_options ()
|
ARDOUR_UI::setup_config_options ()
|
||||||
{
|
{
|
||||||
|
std::vector<Glib::ustring> groups;
|
||||||
|
groups.push_back("options");
|
||||||
|
groups.push_back("Editor");
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char* name;
|
char* name;
|
||||||
bool (Configuration::*method)(void) const;
|
bool (Configuration::*method)(void) const;
|
||||||
|
char act_type; // (t)oggle or (r)adio
|
||||||
} options[] = {
|
} options[] = {
|
||||||
{ "ToggleTimeMaster", &Configuration::get_jack_time_master },
|
{ "ToggleTimeMaster", &Configuration::get_jack_time_master, 't' },
|
||||||
{ "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport },
|
{ "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport, 't' },
|
||||||
{ "LatchedRecordEnable", &Configuration::get_latched_record_enable },
|
{ "LatchedRecordEnable", &Configuration::get_latched_record_enable, 't' },
|
||||||
{ "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture },
|
{ "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture, 't' },
|
||||||
{ "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun },
|
{ "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun, 't' },
|
||||||
{ "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end },
|
{ "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end, 't' },
|
||||||
{ 0, 0 }
|
{ "UseHardwareMonitoring", &Configuration::get_use_hardware_monitoring, 'r' },
|
||||||
|
{ "UseSoftwareMonitoring", &Configuration::get_use_sw_monitoring, 'r' },
|
||||||
|
{ "UseExternalMonitoring", &Configuration::get_use_external_monitoring, 'r' },
|
||||||
|
{ "MeterFalloffOff", &Configuration::get_meter_falloff_off, 'r' },
|
||||||
|
{ "MeterFalloffSlowest", &Configuration::get_meter_falloff_slowest, 'r' },
|
||||||
|
{ "MeterFalloffSlow", &Configuration::get_meter_falloff_slow, 'r' },
|
||||||
|
{ "MeterFalloffMedium", &Configuration::get_meter_falloff_medium, 'r' },
|
||||||
|
{ "MeterFalloffFast", &Configuration::get_meter_falloff_fast, 'r' },
|
||||||
|
{ "MeterFalloffFaster", &Configuration::get_meter_falloff_faster, 'r' },
|
||||||
|
{ "MeterFalloffFastest", &Configuration::get_meter_falloff_fastest, 'r' },
|
||||||
|
{ "MeterHoldOff", &Configuration::get_meter_hold_off, 'r' },
|
||||||
|
{ "MeterHoldShort", &Configuration::get_meter_hold_short, 'r' },
|
||||||
|
{ "MeterHoldMedium", &Configuration::get_meter_hold_medium, 'r' },
|
||||||
|
{ "MeterHoldLong", &Configuration::get_meter_hold_long, 'r' },
|
||||||
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint32_t n = 0; options[n].name; ++n) {
|
for (uint32_t n = 0; options[n].name; ++n) {
|
||||||
Glib::RefPtr<Action> act = ActionManager::get_action ("options", options[n].name);
|
for (std::vector<Glib::ustring>::iterator i = groups.begin(); i != groups.end(); i++) {
|
||||||
|
Glib::RefPtr<Action> act = ActionManager::get_action (i->c_str(), options[n].name);
|
||||||
if (act) {
|
if (act) {
|
||||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
||||||
|
cerr << "action = " << (options[n].name) << " val = " << (Config->*(options[n].method))() << endl;//DEBUG
|
||||||
|
if (options[n].act_type == 't' || (options[n].act_type == 'r' && (Config->*(options[n].method))()))
|
||||||
tact->set_active ((Config->*(options[n].method))());
|
tact->set_active ((Config->*(options[n].method))());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -230,12 +254,14 @@ ARDOUR_UI::toggle_editing_space()
|
||||||
void
|
void
|
||||||
ARDOUR_UI::toggle_UseHardwareMonitoring()
|
ARDOUR_UI::toggle_UseHardwareMonitoring()
|
||||||
{
|
{
|
||||||
Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseSoftwareMonitoring");
|
Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseHardwareMonitoring");
|
||||||
if (act) {
|
if (act) {
|
||||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
|
||||||
|
cerr << "get_active() cond = " << tact->get_active() << endl;//DEBUG
|
||||||
if (tact->get_active()) {
|
if (tact->get_active()) {
|
||||||
Config->set_use_hardware_monitoring (true);
|
Config->set_use_hardware_monitoring (true);
|
||||||
Config->set_use_sw_monitoring (false);
|
Config->set_use_sw_monitoring (false);
|
||||||
|
Config->set_use_external_monitoring (false);
|
||||||
if (session) {
|
if (session) {
|
||||||
session->reset_input_monitor_state();
|
session->reset_input_monitor_state();
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +278,7 @@ ARDOUR_UI::toggle_UseSoftwareMonitoring()
|
||||||
if (tact->get_active()) {
|
if (tact->get_active()) {
|
||||||
Config->set_use_hardware_monitoring (false);
|
Config->set_use_hardware_monitoring (false);
|
||||||
Config->set_use_sw_monitoring (true);
|
Config->set_use_sw_monitoring (true);
|
||||||
|
Config->set_use_external_monitoring (false);
|
||||||
if (session) {
|
if (session) {
|
||||||
session->reset_input_monitor_state();
|
session->reset_input_monitor_state();
|
||||||
}
|
}
|
||||||
|
|
@ -268,6 +295,7 @@ ARDOUR_UI::toggle_UseExternalMonitoring()
|
||||||
if (tact->get_active()) {
|
if (tact->get_active()) {
|
||||||
Config->set_use_hardware_monitoring (false);
|
Config->set_use_hardware_monitoring (false);
|
||||||
Config->set_use_sw_monitoring (false);
|
Config->set_use_sw_monitoring (false);
|
||||||
|
Config->set_use_external_monitoring (true);
|
||||||
if (session) {
|
if (session) {
|
||||||
session->reset_input_monitor_state();
|
session->reset_input_monitor_state();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -435,7 +435,7 @@ void
|
||||||
AudioClock::set_smpte (jack_nframes_t when, bool force)
|
AudioClock::set_smpte (jack_nframes_t when, bool force)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
if (is_duration) {
|
if (is_duration) {
|
||||||
session->smpte_duration (when, smpte);
|
session->smpte_duration (when, smpte);
|
||||||
|
|
@ -1259,7 +1259,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
jack_nframes_t sample;
|
jack_nframes_t sample;
|
||||||
|
|
||||||
smpte.hours = atoi (hours_label.get_text());
|
smpte.hours = atoi (hours_label.get_text());
|
||||||
|
|
@ -1280,19 +1280,19 @@ AudioClock::smpte_frame_from_display () const
|
||||||
#define SMPTE_SAMPLE_TEST_7
|
#define SMPTE_SAMPLE_TEST_7
|
||||||
|
|
||||||
// Testcode for smpte<->sample conversions (P.S.)
|
// Testcode for smpte<->sample conversions (P.S.)
|
||||||
SMPTE_Time smpte1;
|
SMPTE::Time smpte1;
|
||||||
jack_nframes_t sample1;
|
jack_nframes_t sample1;
|
||||||
jack_nframes_t oldsample = 0;
|
jack_nframes_t oldsample = 0;
|
||||||
SMPTE_Time smpte2;
|
SMPTE::Time smpte2;
|
||||||
jack_nframes_t sample_increment;
|
jack_nframes_t sample_increment;
|
||||||
|
|
||||||
sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);
|
sample_increment = (long)rint(session->frame_rate() / SMPTE::frames_per_second);
|
||||||
|
|
||||||
#ifdef SMPTE_SAMPLE_TEST_1
|
#ifdef SMPTE_SAMPLE_TEST_1
|
||||||
// Test 1: use_offset = false, use_subframes = false
|
// Test 1: use_offset = false, use_subframes = false
|
||||||
cout << "use_offset = false, use_subframes = false" << endl;
|
cout << "use_offset = false, use_subframes = false" << endl;
|
||||||
for (int i = 0; i < 108003; i++) {
|
for (int i = 0; i < 108003; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, false /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, false /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
|
if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
|
||||||
|
|
@ -1313,7 +1313,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment( smpte1 );
|
SMPTE::increment( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
@ -1337,7 +1337,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 108003; i++) {
|
for (int i = 0; i < 108003; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
||||||
|
|
@ -1363,7 +1363,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment( smpte1 );
|
SMPTE::increment( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
@ -1380,7 +1380,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 108003; i++) {
|
for (int i = 0; i < 108003; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
||||||
|
|
@ -1406,7 +1406,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_decrement( smpte1 );
|
SMPTE::decrement( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_decrement: " << sample_increment << endl;
|
cout << "sample_decrement: " << sample_increment << endl;
|
||||||
|
|
@ -1433,7 +1433,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 108003; i++) {
|
for (int i = 0; i < 108003; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
|
||||||
|
|
||||||
if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
|
if ((i > 0) && ( ((sample1 - oldsample) != sample_increment) && ((sample1 - oldsample) != (sample_increment + 1)) && ((sample1 - oldsample) != (sample_increment - 1)))) {
|
||||||
|
|
@ -1454,7 +1454,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment( smpte1 );
|
SMPTE::increment( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
@ -1462,7 +1462,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
|
cout << "smpte: " << (smpte2.negative ? "-" : "") << smpte2.hours << ":" << smpte2.minutes << ":" << smpte2.seconds << ":" << smpte2.frames << "::" << smpte2.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 108003; i++) {
|
for (int i = 0; i < 108003; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, true /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, true /* use_subframes */ );
|
||||||
|
|
||||||
if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
|
if ((i > 0) && ( ((oldsample - sample1) != sample_increment) && ((oldsample - sample1) != (sample_increment + 1)) && ((oldsample - sample1) != (sample_increment - 1)))) {
|
||||||
|
|
@ -1483,7 +1483,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_decrement( smpte1 );
|
SMPTE::decrement( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_decrement: " << sample_increment << endl;
|
cout << "sample_decrement: " << sample_increment << endl;
|
||||||
|
|
@ -1510,7 +1510,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 3600; i++) {
|
for (int i = 0; i < 3600; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
||||||
|
|
@ -1533,7 +1533,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment_seconds( smpte1 );
|
SMPTE::increment_seconds( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
@ -1559,7 +1559,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 60; i++) {
|
for (int i = 0; i < 60; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
||||||
|
|
@ -1582,7 +1582,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment_minutes( smpte1 );
|
SMPTE::increment_minutes( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
@ -1607,7 +1607,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << endl;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
session->smpte_to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
SMPTE::to_sample( smpte1, sample1, true /* use_offset */, false /* use_subframes */ );
|
||||||
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte( sample1, smpte2, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
||||||
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
// cout << "smpte: " << (smpte1.negative ? "-" : "") << smpte1.hours << ":" << smpte1.minutes << ":" << smpte1.seconds << ":" << smpte1.frames << "::" << smpte1.subframes << " -> ";
|
||||||
|
|
@ -1630,7 +1630,7 @@ AudioClock::smpte_frame_from_display () const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oldsample = sample1;
|
oldsample = sample1;
|
||||||
session->smpte_increment_hours( smpte1 );
|
SMPTE::increment_hours( smpte1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sample_increment: " << sample_increment << endl;
|
cout << "sample_increment: " << sample_increment << endl;
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ class Editor : public PublicEditor
|
||||||
void toggle_waveforms_while_recording ();
|
void toggle_waveforms_while_recording ();
|
||||||
void toggle_measure_visibility ();
|
void toggle_measure_visibility ();
|
||||||
|
|
||||||
void set_meter_falloff (float);
|
void set_meter_falloff (int);
|
||||||
void set_meter_hold (int32_t);
|
void set_meter_hold (int32_t);
|
||||||
|
|
||||||
/* xfades */
|
/* xfades */
|
||||||
|
|
|
||||||
|
|
@ -371,13 +371,13 @@ Editor::register_actions ()
|
||||||
Slow = 6.8dB/sec falloff at update rate of 40ms
|
Slow = 6.8dB/sec falloff at update rate of 40ms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffOff"), _("Off"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.0f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffOff"), _("Off"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffSlowest"), _("Slowest"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.266f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffSlowest"), _("Slowest"), bind (mem_fun (*this, &Editor::set_meter_falloff), 1));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffSlow"), _("Slow"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.342f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffSlow"), _("Slow"), bind (mem_fun (*this, &Editor::set_meter_falloff), 2));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffMedium"), _("Medium"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.7f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffMedium"), _("Medium"), bind (mem_fun (*this, &Editor::set_meter_falloff), 3));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFast"), _("Fast"), bind (mem_fun (*this, &Editor::set_meter_falloff), 1.1f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFast"), _("Fast"), bind (mem_fun (*this, &Editor::set_meter_falloff), 4));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFaster"), _("Faster"), bind (mem_fun (*this, &Editor::set_meter_falloff), 1.5f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFaster"), _("Faster"), bind (mem_fun (*this, &Editor::set_meter_falloff), 5));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFastest"), _("Fastest"), bind (mem_fun (*this, &Editor::set_meter_falloff), 2.5f));
|
ActionManager::register_radio_action (editor_actions, meter_falloff_group, X_("MeterFalloffFastest"), _("Fastest"), bind (mem_fun (*this, &Editor::set_meter_falloff), 6));
|
||||||
|
|
||||||
ActionManager::register_radio_action (editor_actions, meter_hold_group, X_("MeterHoldOff"), _("Off"), bind (mem_fun (*this, &Editor::set_meter_hold), 0));
|
ActionManager::register_radio_action (editor_actions, meter_hold_group, X_("MeterHoldOff"), _("Off"), bind (mem_fun (*this, &Editor::set_meter_hold), 0));
|
||||||
ActionManager::register_radio_action (editor_actions, meter_hold_group, X_("MeterHoldShort"), _("Short"), bind (mem_fun (*this, &Editor::set_meter_hold), 40));
|
ActionManager::register_radio_action (editor_actions, meter_hold_group, X_("MeterHoldShort"), _("Short"), bind (mem_fun (*this, &Editor::set_meter_hold), 40));
|
||||||
|
|
|
||||||
|
|
@ -3417,7 +3417,7 @@ void
|
||||||
Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xpos, double ypos)
|
Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xpos, double ypos)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
BBT_Time bbt;
|
BBT_Time bbt;
|
||||||
float secs;
|
float secs;
|
||||||
|
|
||||||
|
|
@ -3461,7 +3461,7 @@ void
|
||||||
Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, double offset, double xpos, double ypos)
|
Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, double offset, double xpos, double ypos)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
BBT_Time sbbt;
|
BBT_Time sbbt;
|
||||||
BBT_Time ebbt;
|
BBT_Time ebbt;
|
||||||
float secs;
|
float secs;
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,78 @@ Editor::redo (uint32_t n)
|
||||||
void
|
void
|
||||||
Editor::set_meter_hold (int32_t cnt)
|
Editor::set_meter_hold (int32_t cnt)
|
||||||
{
|
{
|
||||||
|
Config->set_meter_hold_off(false);
|
||||||
|
Config->set_meter_hold_short(false);
|
||||||
|
Config->set_meter_hold_medium(false);
|
||||||
|
Config->set_meter_hold_long(false);
|
||||||
|
|
||||||
|
switch (cnt)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Config->set_meter_hold_off(true);
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
Config->set_meter_hold_short(true);
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
Config->set_meter_hold_medium(true);
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
Config->set_meter_hold_long(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
session->set_meter_hold (cnt);
|
session->set_meter_hold (cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::set_meter_falloff (float val)
|
Editor::set_meter_falloff (int intval)
|
||||||
{
|
{
|
||||||
|
float val;
|
||||||
|
std::string str;
|
||||||
|
cerr << "set_meter_falloff () called: intval = " << intval << endl;
|
||||||
|
Config->set_meter_falloff_off(false);
|
||||||
|
Config->set_meter_falloff_slowest(false);
|
||||||
|
Config->set_meter_falloff_slow(false);
|
||||||
|
Config->set_meter_falloff_medium(false);
|
||||||
|
Config->set_meter_falloff_fast(false);
|
||||||
|
Config->set_meter_falloff_faster(false);
|
||||||
|
Config->set_meter_falloff_fastest(false);
|
||||||
|
|
||||||
|
switch (intval)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
val = 0.0f;
|
||||||
|
Config->set_meter_falloff_off(true);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
val = 0.266f;
|
||||||
|
Config->set_meter_falloff_slowest(true);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
val = 0.342f;
|
||||||
|
Config->set_meter_falloff_slow(true);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
val = 0.7f;
|
||||||
|
Config->set_meter_falloff_medium(true);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
val = 1.1f;
|
||||||
|
Config->set_meter_falloff_fast(true);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
val = 1.5f;
|
||||||
|
Config->set_meter_falloff_faster(true);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
val = 2.5f;
|
||||||
|
Config->set_meter_falloff_fastest(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
session->set_meter_falloff (val);
|
session->set_meter_falloff (val);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <ardour/tempo.h>
|
#include <ardour/tempo.h>
|
||||||
|
#include <ardour/smpte.h>
|
||||||
#include <gtkmm2ext/gtk_ui.h>
|
#include <gtkmm2ext/gtk_ui.h>
|
||||||
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
@ -798,7 +799,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
jack_nframes_t pos;
|
jack_nframes_t pos;
|
||||||
jack_nframes_t spacer;
|
jack_nframes_t spacer;
|
||||||
jack_nframes_t fr;
|
jack_nframes_t fr;
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
gchar buf[16];
|
gchar buf[16];
|
||||||
gint nmarks = 0;
|
gint nmarks = 0;
|
||||||
gint n;
|
gint n;
|
||||||
|
|
@ -927,13 +928,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
(*marks)[n].position = pos;
|
(*marks)[n].position = pos;
|
||||||
|
|
||||||
// Increment subframes by one
|
// Increment subframes by one
|
||||||
session->smpte_increment_subframes( smpte );
|
SMPTE::increment_subframes( smpte );
|
||||||
}
|
}
|
||||||
} else if (show_seconds) {
|
} else if (show_seconds) {
|
||||||
// Find smpte time of this sample (pos)
|
// Find smpte time of this sample (pos)
|
||||||
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
||||||
// Go to next whole second down
|
// Go to next whole second down
|
||||||
session->smpte_seconds_floor( smpte );
|
SMPTE::seconds_floor( smpte );
|
||||||
|
|
||||||
for (n = 0; n < nmarks; n++) {
|
for (n = 0; n < nmarks; n++) {
|
||||||
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
@ -953,13 +954,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
|
|
||||||
}
|
}
|
||||||
(*marks)[n].label = g_strdup (buf);
|
(*marks)[n].label = g_strdup (buf);
|
||||||
session->smpte_increment_seconds( smpte );
|
SMPTE::increment_seconds( smpte );
|
||||||
}
|
}
|
||||||
} else if (show_minutes) {
|
} else if (show_minutes) {
|
||||||
// Find smpte time of this sample (pos)
|
// Find smpte time of this sample (pos)
|
||||||
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
||||||
// Go to next whole minute down
|
// Go to next whole minute down
|
||||||
session->smpte_minutes_floor( smpte );
|
SMPTE::minutes_floor( smpte );
|
||||||
|
|
||||||
for (n = 0; n < nmarks; n++) {
|
for (n = 0; n < nmarks; n++) {
|
||||||
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
@ -977,13 +978,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
}
|
}
|
||||||
(*marks)[n].label = g_strdup (buf);
|
(*marks)[n].label = g_strdup (buf);
|
||||||
(*marks)[n].position = pos;
|
(*marks)[n].position = pos;
|
||||||
session->smpte_increment_minutes( smpte );
|
SMPTE::increment_minutes( smpte );
|
||||||
}
|
}
|
||||||
} else if (show_hours) {
|
} else if (show_hours) {
|
||||||
// Find smpte time of this sample (pos)
|
// Find smpte time of this sample (pos)
|
||||||
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
||||||
// Go to next whole hour down
|
// Go to next whole hour down
|
||||||
session->smpte_hours_floor( smpte );
|
SMPTE::hours_floor( smpte );
|
||||||
|
|
||||||
for (n = 0; n < nmarks; n++) {
|
for (n = 0; n < nmarks; n++) {
|
||||||
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
@ -998,13 +999,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
(*marks)[n].label = g_strdup (buf);
|
(*marks)[n].label = g_strdup (buf);
|
||||||
(*marks)[n].position = pos;
|
(*marks)[n].position = pos;
|
||||||
|
|
||||||
session->smpte_increment_hours( smpte );
|
SMPTE::increment_hours( smpte );
|
||||||
}
|
}
|
||||||
} else { // show_frames
|
} else { // show_frames
|
||||||
// Find smpte time of this sample (pos)
|
// Find smpte time of this sample (pos)
|
||||||
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
|
||||||
// Go to next whole frame down
|
// Go to next whole frame down
|
||||||
session->smpte_frames_floor( smpte );
|
SMPTE::frames_floor( smpte );
|
||||||
|
|
||||||
for (n = 0; n < nmarks; n++) {
|
for (n = 0; n < nmarks; n++) {
|
||||||
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
|
||||||
|
|
@ -1019,7 +1020,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
|
||||||
|
|
||||||
}
|
}
|
||||||
(*marks)[n].label = g_strdup (buf);
|
(*marks)[n].label = g_strdup (buf);
|
||||||
session->smpte_increment( smpte );
|
SMPTE::increment( smpte );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,8 @@ which_ui_rcfile ()
|
||||||
|
|
||||||
if (rcfile.empty()) {
|
if (rcfile.empty()) {
|
||||||
warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR2_UI_RC to point to a valid UI style file") << endmsg;
|
warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR2_UI_RC to point to a valid UI style file") << endmsg;
|
||||||
|
} else {
|
||||||
|
cerr << "Loading ui configuration file " << rcfile << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rcfile;
|
return rcfile;
|
||||||
|
|
|
||||||
|
|
@ -414,14 +414,14 @@ MixerStrip::set_width (Width w)
|
||||||
set_size_request (-1, -1);
|
set_size_request (-1, -1);
|
||||||
xml_node->add_property ("strip_width", "wide");
|
xml_node->add_property ("strip_width", "wide");
|
||||||
|
|
||||||
rec_enable_button->set_label (_("Record"));
|
rec_enable_button->set_label (_("record"));
|
||||||
mute_button->set_label (_("Mute"));
|
mute_button->set_label (_("mute"));
|
||||||
solo_button->set_label (_("Solo"));
|
solo_button->set_label (_("solo"));
|
||||||
|
|
||||||
if (_route.comment() == "") {
|
if (_route.comment() == "") {
|
||||||
comment_button.set_label (_("Comments"));
|
comment_button.set_label (_("comments"));
|
||||||
} else {
|
} else {
|
||||||
comment_button.set_label (_("*Comments*"));
|
comment_button.set_label (_("*comments*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route.gain_automation_curve().automation_style()));
|
gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route.gain_automation_curve().automation_style()));
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ tempo.cc
|
||||||
utils.cc
|
utils.cc
|
||||||
version.cc
|
version.cc
|
||||||
mix.cc
|
mix.cc
|
||||||
|
smpte.cc
|
||||||
""")
|
""")
|
||||||
|
|
||||||
arch_specific_objects = [ ]
|
arch_specific_objects = [ ]
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,13 @@ CONFIG_VARIABLE(bool, mute_affects_post_fader, "mute-affects-post-fader", true)
|
||||||
CONFIG_VARIABLE(bool, mute_affects_control_outs, "mute-affects-control-outs", true)
|
CONFIG_VARIABLE(bool, mute_affects_control_outs, "mute-affects-control-outs", true)
|
||||||
CONFIG_VARIABLE(bool, mute_affects_main_outs, "mute-affects-main-outs", true)
|
CONFIG_VARIABLE(bool, mute_affects_main_outs, "mute-affects-main-outs", true)
|
||||||
CONFIG_VARIABLE(bool, solo_latch, "solo-latch", true)
|
CONFIG_VARIABLE(bool, solo_latch, "solo-latch", true)
|
||||||
CONFIG_VARIABLE(bool, use_hardware_monitoring, "use-hardware-monitoring", true)
|
CONFIG_VARIABLE(bool, use_hardware_monitoring, "use-hardware-monitoring", false)
|
||||||
|
CONFIG_VARIABLE(bool, use_sw_monitoring, "use-sw-monitoring", false)
|
||||||
|
CONFIG_VARIABLE(bool, use_external_monitoring, "use-external-monitoring", true)
|
||||||
CONFIG_VARIABLE(bool, jack_time_master, "jack-time-master", true)
|
CONFIG_VARIABLE(bool, jack_time_master, "jack-time-master", true)
|
||||||
CONFIG_VARIABLE(bool, trace_midi_input, "trace-midi-input", false)
|
CONFIG_VARIABLE(bool, trace_midi_input, "trace-midi-input", false)
|
||||||
CONFIG_VARIABLE(bool, trace_midi_output, "trace-midi-output", false)
|
CONFIG_VARIABLE(bool, trace_midi_output, "trace-midi-output", false)
|
||||||
CONFIG_VARIABLE(bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
|
CONFIG_VARIABLE(bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
|
||||||
CONFIG_VARIABLE(bool, use_sw_monitoring, "use-sw-monitoring", true)
|
|
||||||
CONFIG_VARIABLE(bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
|
CONFIG_VARIABLE(bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
|
||||||
CONFIG_VARIABLE(bool, verify_remove_last_capture, "verify-remove-last-capture", true)
|
CONFIG_VARIABLE(bool, verify_remove_last_capture, "verify-remove-last-capture", true)
|
||||||
CONFIG_VARIABLE(bool, stop_at_session_end, "stop-at-session-end", true)
|
CONFIG_VARIABLE(bool, stop_at_session_end, "stop-at-session-end", true)
|
||||||
|
|
@ -41,6 +42,19 @@ CONFIG_VARIABLE(HeaderFormat, native_file_header_format, "native-file-header-fo
|
||||||
CONFIG_VARIABLE(bool, use_tranzport, "use-tranzport", false)
|
CONFIG_VARIABLE(bool, use_tranzport, "use-tranzport", false)
|
||||||
CONFIG_VARIABLE(uint32_t, osc_port, "osc-port", 3819)
|
CONFIG_VARIABLE(uint32_t, osc_port, "osc-port", 3819)
|
||||||
CONFIG_VARIABLE(bool, use_osc, "use-osc", true)
|
CONFIG_VARIABLE(bool, use_osc, "use-osc", true)
|
||||||
|
CONFIG_VARIABLE(bool, use_overlap_equivalency, "use-overlap-equivalency", true)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_off, "meter-falloff-off", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_slowest, "meter-falloff-slowest", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_slower, "meter-falloff-slower", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_slow, "meter-falloff-slow", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_medium, "meter-falloff-medium", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_fast, "meter-falloff-fast", true)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_faster, "meter-falloff-faster", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_falloff_fastest, "meter-falloff-fastest", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_hold_off, "meter-hold-off", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_hold_short, "meter-hold-short", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_hold_medium, "meter-hold-medium", false)
|
||||||
|
CONFIG_VARIABLE(bool, meter_hold_long, "meter-hold-long", false)
|
||||||
|
|
||||||
/* these variables have custom set() methods */
|
/* these variables have custom set() methods */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -585,24 +585,13 @@ class Session : public sigc::trackable, public Stateful
|
||||||
|
|
||||||
void bbt_time (jack_nframes_t when, BBT_Time&);
|
void bbt_time (jack_nframes_t when, BBT_Time&);
|
||||||
|
|
||||||
ARDOUR::smpte_wrap_t smpte_increment( SMPTE_Time& smpte ) const;
|
void smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const;
|
||||||
ARDOUR::smpte_wrap_t smpte_decrement( SMPTE_Time& smpte ) const;
|
void sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const;
|
||||||
ARDOUR::smpte_wrap_t smpte_increment_subframes( SMPTE_Time& smpte ) const;
|
void smpte_time (SMPTE::Time &);
|
||||||
ARDOUR::smpte_wrap_t smpte_decrement_subframes( SMPTE_Time& smpte ) const;
|
void smpte_time (jack_nframes_t when, SMPTE::Time&);
|
||||||
ARDOUR::smpte_wrap_t smpte_increment_seconds( SMPTE_Time& smpte ) const;
|
void smpte_time_subframes (jack_nframes_t when, SMPTE::Time&);
|
||||||
ARDOUR::smpte_wrap_t smpte_increment_minutes( SMPTE_Time& smpte ) const;
|
|
||||||
ARDOUR::smpte_wrap_t smpte_increment_hours( SMPTE_Time& smpte ) const;
|
|
||||||
void smpte_frames_floor( SMPTE_Time& smpte ) const;
|
|
||||||
void smpte_seconds_floor( SMPTE_Time& smpte ) const;
|
|
||||||
void smpte_minutes_floor( SMPTE_Time& smpte ) const;
|
|
||||||
void smpte_hours_floor( SMPTE_Time& smpte ) const;
|
|
||||||
void smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const;
|
|
||||||
void sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const;
|
|
||||||
void smpte_time (SMPTE_Time &);
|
|
||||||
void smpte_time (jack_nframes_t when, SMPTE_Time&);
|
|
||||||
void smpte_time_subframes (jack_nframes_t when, SMPTE_Time&);
|
|
||||||
|
|
||||||
void smpte_duration (jack_nframes_t, SMPTE_Time&) const;
|
void smpte_duration (jack_nframes_t, SMPTE::Time&) const;
|
||||||
void smpte_duration_string (char *, jack_nframes_t) const;
|
void smpte_duration_string (char *, jack_nframes_t) const;
|
||||||
|
|
||||||
void set_smpte_offset (jack_nframes_t);
|
void set_smpte_offset (jack_nframes_t);
|
||||||
|
|
@ -1271,7 +1260,7 @@ class Session : public sigc::trackable, public Stateful
|
||||||
void remove_empty_sounds ();
|
void remove_empty_sounds ();
|
||||||
|
|
||||||
void setup_midi_control ();
|
void setup_midi_control ();
|
||||||
int midi_read (MIDI::Port *);
|
//int midi_read (MIDI::Port *);
|
||||||
|
|
||||||
void enable_record ();
|
void enable_record ();
|
||||||
|
|
||||||
|
|
@ -1297,13 +1286,13 @@ class Session : public sigc::trackable, public Stateful
|
||||||
void *do_work();
|
void *do_work();
|
||||||
|
|
||||||
void set_next_event ();
|
void set_next_event ();
|
||||||
void process_event (Event *);
|
void process_event (Event *ev);
|
||||||
|
|
||||||
/* MIDI Machine Control */
|
/* MIDI Machine Control */
|
||||||
|
|
||||||
void deliver_mmc (MIDI::MachineControl::Command, jack_nframes_t);
|
void deliver_mmc (MIDI::MachineControl::Command, jack_nframes_t);
|
||||||
void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
|
//void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
|
||||||
void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
|
//void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
|
||||||
|
|
||||||
void spp_start (MIDI::Parser&);
|
void spp_start (MIDI::Parser&);
|
||||||
void spp_continue (MIDI::Parser&);
|
void spp_continue (MIDI::Parser&);
|
||||||
|
|
@ -1338,7 +1327,7 @@ class Session : public sigc::trackable, public Stateful
|
||||||
MIDI::byte mtc_smpte_bits; /* encoding of SMTPE type for MTC */
|
MIDI::byte mtc_smpte_bits; /* encoding of SMTPE type for MTC */
|
||||||
MIDI::byte midi_msg[16];
|
MIDI::byte midi_msg[16];
|
||||||
jack_nframes_t outbound_mtc_smpte_frame;
|
jack_nframes_t outbound_mtc_smpte_frame;
|
||||||
SMPTE_Time transmitting_smpte_time;
|
SMPTE::Time transmitting_smpte_time;
|
||||||
int next_quarter_frame_to_send;
|
int next_quarter_frame_to_send;
|
||||||
|
|
||||||
double _frames_per_smpte_frame; /* has to be floating point because of drop frame */
|
double _frames_per_smpte_frame; /* has to be floating point because of drop frame */
|
||||||
|
|
@ -1347,22 +1336,18 @@ class Session : public sigc::trackable, public Stateful
|
||||||
jack_nframes_t _smpte_offset;
|
jack_nframes_t _smpte_offset;
|
||||||
bool _smpte_offset_negative;
|
bool _smpte_offset_negative;
|
||||||
|
|
||||||
/* cache the most-recently requested time conversions.
|
/* cache the most-recently requested time conversions. This helps when we
|
||||||
this helps when we have multiple clocks showing the
|
* have multiple clocks showing the same time (e.g. the transport frame) */
|
||||||
same time (e.g. the transport frame)
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool last_smpte_valid;
|
bool last_smpte_valid;
|
||||||
jack_nframes_t last_smpte_when;
|
jack_nframes_t last_smpte_when;
|
||||||
SMPTE_Time last_smpte;
|
SMPTE::Time last_smpte;
|
||||||
|
|
||||||
int send_full_time_code ();
|
bool _send_smpte_update; ///< Send a full MTC timecode this cycle
|
||||||
int send_midi_time_code ();
|
|
||||||
|
|
||||||
void send_full_time_code_in_another_thread ();
|
int send_full_time_code(jack_nframes_t nframes);
|
||||||
void send_midi_time_code_in_another_thread ();
|
int send_midi_time_code_for_cycle(jack_nframes_t nframes);
|
||||||
void send_time_code_in_another_thread (bool full);
|
|
||||||
void send_mmc_in_another_thread (MIDI::MachineControl::Command, jack_nframes_t frame = 0);
|
//void send_mmc_in_another_thread (MIDI::MachineControl::Command, jack_nframes_t frame = 0);
|
||||||
|
|
||||||
jack_nframes_t adjust_apparent_position (jack_nframes_t frames);
|
jack_nframes_t adjust_apparent_position (jack_nframes_t frames);
|
||||||
|
|
||||||
|
|
@ -1417,17 +1402,17 @@ class Session : public sigc::trackable, public Stateful
|
||||||
static MultiAllocSingleReleasePool pool;
|
static MultiAllocSingleReleasePool pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
PBD::Lock midi_lock;
|
//PBD::Lock midi_lock;
|
||||||
pthread_t midi_thread;
|
//pthread_t midi_thread;
|
||||||
int midi_request_pipe[2];
|
//int midi_request_pipe[2];
|
||||||
atomic_t butler_active;
|
atomic_t butler_active;
|
||||||
RingBuffer<MIDIRequest*> midi_requests;
|
//RingBuffer<MIDIRequest*> midi_requests;
|
||||||
|
/*
|
||||||
int start_midi_thread ();
|
int start_midi_thread ();
|
||||||
void terminate_midi_thread ();
|
void terminate_midi_thread ();
|
||||||
void poke_midi_thread ();
|
void poke_midi_thread ();
|
||||||
static void *_midi_thread_work (void *arg);
|
static void *_midi_thread_work (void *arg);
|
||||||
void midi_thread_work ();
|
void midi_thread_work ();*/
|
||||||
void change_midi_ports ();
|
void change_midi_ports ();
|
||||||
int use_config_midi_ports ();
|
int use_config_midi_ports ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <jack/types.h>
|
#include <jack/types.h>
|
||||||
|
#include <ardour/smpte.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#if __GNUC__ < 3
|
#if __GNUC__ < 3
|
||||||
|
|
@ -99,33 +100,6 @@ namespace ARDOUR {
|
||||||
Destructive
|
Destructive
|
||||||
};
|
};
|
||||||
|
|
||||||
enum smpte_wrap_t {
|
|
||||||
smpte_wrap_none = 0,
|
|
||||||
smpte_wrap_frames,
|
|
||||||
smpte_wrap_seconds,
|
|
||||||
smpte_wrap_minutes,
|
|
||||||
smpte_wrap_hours
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SMPTE_Time {
|
|
||||||
bool negative;
|
|
||||||
uint32_t hours;
|
|
||||||
uint32_t minutes;
|
|
||||||
uint32_t seconds;
|
|
||||||
uint32_t frames;
|
|
||||||
uint32_t subframes; // mostly not used
|
|
||||||
|
|
||||||
SMPTE_Time() {
|
|
||||||
negative = false;
|
|
||||||
hours = 0;
|
|
||||||
minutes = 0;
|
|
||||||
seconds = 0;
|
|
||||||
frames = 0;
|
|
||||||
subframes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BBT_Time {
|
struct BBT_Time {
|
||||||
uint32_t bars;
|
uint32_t bars;
|
||||||
uint32_t beats;
|
uint32_t beats;
|
||||||
|
|
@ -164,7 +138,7 @@ namespace ARDOUR {
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
BBT_Time bbt;
|
BBT_Time bbt;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,7 @@ AudioEngine::_graph_order_callback (void *arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @callgraph */
|
||||||
int
|
int
|
||||||
AudioEngine::_process_callback (jack_nframes_t nframes, void *arg)
|
AudioEngine::_process_callback (jack_nframes_t nframes, void *arg)
|
||||||
{
|
{
|
||||||
|
|
@ -224,6 +225,7 @@ AudioEngine::_freewheel_callback (int onoff, void *arg)
|
||||||
static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
|
static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @callgraph */
|
||||||
int
|
int
|
||||||
AudioEngine::process_callback (jack_nframes_t nframes)
|
AudioEngine::process_callback (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <midi++/mmc.h>
|
#include <midi++/mmc.h>
|
||||||
|
|
||||||
#include <ardour/ardour.h>
|
#include <ardour/ardour.h>
|
||||||
|
#include <ardour/audioengine.h>
|
||||||
#include <ardour/audio_library.h>
|
#include <ardour/audio_library.h>
|
||||||
#include <ardour/configuration.h>
|
#include <ardour/configuration.h>
|
||||||
#include <ardour/plugin_manager.h>
|
#include <ardour/plugin_manager.h>
|
||||||
|
|
@ -91,7 +92,7 @@ setup_osc ()
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setup_midi ()
|
setup_midi (AudioEngine& engine)
|
||||||
{
|
{
|
||||||
std::map<string,Configuration::MidiPortDescriptor*>::iterator i;
|
std::map<string,Configuration::MidiPortDescriptor*>::iterator i;
|
||||||
int nports;
|
int nports;
|
||||||
|
|
@ -101,6 +102,8 @@ setup_midi ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIDI::Manager::instance()->set_api_data(engine.jack());
|
||||||
|
|
||||||
for (i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
|
for (i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
|
||||||
Configuration::MidiPortDescriptor* port_descriptor;
|
Configuration::MidiPortDescriptor* port_descriptor;
|
||||||
|
|
||||||
|
|
@ -112,7 +115,9 @@ setup_midi ()
|
||||||
port_descriptor->type);
|
port_descriptor->type);
|
||||||
|
|
||||||
if (request.status != MIDI::PortRequest::OK) {
|
if (request.status != MIDI::PortRequest::OK) {
|
||||||
error << string_compose(_("MIDI port specifications for \"%1\" are not understandable."), port_descriptor->tag) << endmsg;
|
error << string_compose(
|
||||||
|
_("MIDI port specifications for \"%1\" (%2, %3) are not understandable."),
|
||||||
|
port_descriptor->tag, port_descriptor->mode, port_descriptor->type) << endmsg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,12 +168,15 @@ setup_midi ()
|
||||||
if (default_mmc_port == 0) {
|
if (default_mmc_port == 0) {
|
||||||
warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name())
|
warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name())
|
||||||
<< endmsg;
|
<< endmsg;
|
||||||
return 0;
|
//return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_mtc_port == 0) {
|
if (default_mtc_port == 0) {
|
||||||
warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name())
|
warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name())
|
||||||
<< endmsg;
|
<< endmsg;
|
||||||
|
} else {
|
||||||
|
// [DR]
|
||||||
|
warning << "MTC port available" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_midi_port == 0) {
|
if (default_midi_port == 0) {
|
||||||
|
|
@ -194,7 +202,7 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization, void (*s
|
||||||
|
|
||||||
Config->set_use_vst (use_vst);
|
Config->set_use_vst (use_vst);
|
||||||
|
|
||||||
if (setup_midi ()) {
|
if (setup_midi (engine)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ void
|
||||||
MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
|
MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
|
||||||
{
|
{
|
||||||
jack_nframes_t now = session.engine().frame_time();
|
jack_nframes_t now = session.engine().frame_time();
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
smpte.hours = msg[3];
|
smpte.hours = msg[3];
|
||||||
smpte.minutes = msg[2];
|
smpte.minutes = msg[2];
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,8 @@ Session::Session (AudioEngine &eng,
|
||||||
_mtc_port (default_mtc_port),
|
_mtc_port (default_mtc_port),
|
||||||
_midi_port (default_midi_port),
|
_midi_port (default_midi_port),
|
||||||
pending_events (2048),
|
pending_events (2048),
|
||||||
midi_requests (128), // the size of this should match the midi request pool size
|
//midi_requests (128), // the size of this should match the midi request pool size
|
||||||
|
_send_smpte_update (false),
|
||||||
main_outs (0)
|
main_outs (0)
|
||||||
{
|
{
|
||||||
bool new_session;
|
bool new_session;
|
||||||
|
|
@ -294,7 +295,7 @@ Session::Session (AudioEngine &eng,
|
||||||
_mtc_port (default_mtc_port),
|
_mtc_port (default_mtc_port),
|
||||||
_midi_port (default_midi_port),
|
_midi_port (default_midi_port),
|
||||||
pending_events (2048),
|
pending_events (2048),
|
||||||
midi_requests (16),
|
//midi_requests (16),
|
||||||
main_outs (0)
|
main_outs (0)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -360,7 +361,7 @@ Session::~Session ()
|
||||||
going_away (); /* EMIT SIGNAL */
|
going_away (); /* EMIT SIGNAL */
|
||||||
|
|
||||||
terminate_butler_thread ();
|
terminate_butler_thread ();
|
||||||
terminate_midi_thread ();
|
//terminate_midi_thread ();
|
||||||
|
|
||||||
if (click_data && click_data != default_click) {
|
if (click_data && click_data != default_click) {
|
||||||
delete [] click_data;
|
delete [] click_data;
|
||||||
|
|
@ -1250,7 +1251,8 @@ Session::enable_record ()
|
||||||
if (atomic_read (&_record_status) != Recording) {
|
if (atomic_read (&_record_status) != Recording) {
|
||||||
atomic_set (&_record_status, Recording);
|
atomic_set (&_record_status, Recording);
|
||||||
_last_record_location = _transport_frame;
|
_last_record_location = _transport_frame;
|
||||||
send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
|
// FIXME
|
||||||
|
//send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
|
||||||
|
|
||||||
if (Config->get_use_hardware_monitoring() && auto_input) {
|
if (Config->get_use_hardware_monitoring() && auto_input) {
|
||||||
/* Even though this can be called from RT context we are using
|
/* Even though this can be called from RT context we are using
|
||||||
|
|
@ -1285,7 +1287,8 @@ Session::disable_record (bool rt_context, bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
|
// FIXME
|
||||||
|
//send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
|
||||||
|
|
||||||
if (Config->get_use_hardware_monitoring() && auto_input) {
|
if (Config->get_use_hardware_monitoring() && auto_input) {
|
||||||
/* Even though this can be called from RT context we are using
|
/* Even though this can be called from RT context we are using
|
||||||
|
|
@ -1346,7 +1349,8 @@ Session::maybe_enable_record ()
|
||||||
enable_record ();
|
enable_record ();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
|
// FIXME
|
||||||
|
//send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
|
||||||
RecordStateChanged (); /* EMIT SIGNAL */
|
RecordStateChanged (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ Session::queue_event (Event* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [DR] Always called from audio thread? */
|
||||||
void
|
void
|
||||||
Session::merge_event (Event* ev)
|
Session::merge_event (Event* ev)
|
||||||
{
|
{
|
||||||
|
|
@ -171,10 +172,10 @@ Session::merge_event (Event* ev)
|
||||||
set_next_event ();
|
set_next_event ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true when @a ev is deleted. */
|
||||||
bool
|
bool
|
||||||
Session::_replace_event (Event* ev)
|
Session::_replace_event (Event* ev)
|
||||||
{
|
{
|
||||||
// returns true when we deleted the passed in event
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
Events::iterator i;
|
Events::iterator i;
|
||||||
|
|
||||||
|
|
@ -203,10 +204,10 @@ Session::_replace_event (Event* ev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true when @a ev is deleted. */
|
||||||
bool
|
bool
|
||||||
Session::_remove_event (Session::Event* ev)
|
Session::_remove_event (Session::Event* ev)
|
||||||
{
|
{
|
||||||
// returns true when we deleted the passed in event
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
Events::iterator i;
|
Events::iterator i;
|
||||||
|
|
||||||
|
|
@ -310,6 +311,9 @@ Session::process_event (Event* ev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME [DR]
|
||||||
|
printf("Processing event: %s\n", event_names[ev->type]);
|
||||||
|
|
||||||
switch (ev->type) {
|
switch (ev->type) {
|
||||||
case Event::SetLoop:
|
case Event::SetLoop:
|
||||||
set_auto_loop (ev->yes_or_no);
|
set_auto_loop (ev->yes_or_no);
|
||||||
|
|
@ -323,6 +327,7 @@ Session::process_event (Event* ev)
|
||||||
// cerr << "soft locate to " << ev->target_frame << endl;
|
// cerr << "soft locate to " << ev->target_frame << endl;
|
||||||
start_locate (ev->target_frame, false, true, false);
|
start_locate (ev->target_frame, false, true, false);
|
||||||
}
|
}
|
||||||
|
_send_smpte_update = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::LocateRoll:
|
case Event::LocateRoll:
|
||||||
|
|
@ -333,6 +338,7 @@ Session::process_event (Event* ev)
|
||||||
// cerr << "soft locate to+roll " << ev->target_frame << endl;
|
// cerr << "soft locate to+roll " << ev->target_frame << endl;
|
||||||
start_locate (ev->target_frame, true, true, false);
|
start_locate (ev->target_frame, true, true, false);
|
||||||
}
|
}
|
||||||
|
_send_smpte_update = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::SetTransportSpeed:
|
case Event::SetTransportSpeed:
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <ardour/diskstream.h>
|
#include <ardour/diskstream.h>
|
||||||
#include <ardour/slave.h>
|
#include <ardour/slave.h>
|
||||||
#include <ardour/cycles.h>
|
#include <ardour/cycles.h>
|
||||||
|
#include <ardour/smpte.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -87,6 +88,7 @@ Session::use_config_midi_ports ()
|
||||||
void
|
void
|
||||||
Session::set_mmc_control (bool yn)
|
Session::set_mmc_control (bool yn)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (mmc_control == yn) {
|
if (mmc_control == yn) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -94,13 +96,14 @@ Session::set_mmc_control (bool yn)
|
||||||
mmc_control = yn;
|
mmc_control = yn;
|
||||||
set_dirty();
|
set_dirty();
|
||||||
poke_midi_thread ();
|
poke_midi_thread ();
|
||||||
|
#endif
|
||||||
ControlChanged (MMCControl); /* EMIT SIGNAL */
|
ControlChanged (MMCControl); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::set_midi_control (bool yn)
|
Session::set_midi_control (bool yn)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (midi_control == yn) {
|
if (midi_control == yn) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +118,7 @@ Session::set_midi_control (bool yn)
|
||||||
(*i)->reset_midi_control (_midi_port, midi_control);
|
(*i)->reset_midi_control (_midi_port, midi_control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
ControlChanged (MidiControl); /* EMIT SIGNAL */
|
ControlChanged (MidiControl); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,7 +471,7 @@ void
|
||||||
Session::setup_midi_control ()
|
Session::setup_midi_control ()
|
||||||
{
|
{
|
||||||
outbound_mtc_smpte_frame = 0;
|
outbound_mtc_smpte_frame = 0;
|
||||||
next_quarter_frame_to_send = -1;
|
next_quarter_frame_to_send = 0;
|
||||||
|
|
||||||
/* setup the MMC buffer */
|
/* setup the MMC buffer */
|
||||||
|
|
||||||
|
|
@ -508,6 +511,7 @@ Session::setup_midi_control ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
int
|
int
|
||||||
Session::midi_read (MIDI::Port* port)
|
Session::midi_read (MIDI::Port* port)
|
||||||
{
|
{
|
||||||
|
|
@ -545,6 +549,7 @@ Session::midi_read (MIDI::Port* port)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::spp_start (Parser& ignored)
|
Session::spp_start (Parser& ignored)
|
||||||
|
|
@ -724,7 +729,7 @@ Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
|
||||||
}
|
}
|
||||||
|
|
||||||
jack_nframes_t target_frame;
|
jack_nframes_t target_frame;
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
smpte.hours = mmc_tc[0] & 0xf;
|
smpte.hours = mmc_tc[0] & 0xf;
|
||||||
smpte.minutes = mmc_tc[1];
|
smpte.minutes = mmc_tc[1];
|
||||||
|
|
@ -798,67 +803,33 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Session::send_full_time_code_in_another_thread ()
|
|
||||||
{
|
|
||||||
send_time_code_in_another_thread (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Session::send_midi_time_code_in_another_thread ()
|
|
||||||
{
|
|
||||||
send_time_code_in_another_thread (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Session::send_time_code_in_another_thread (bool full)
|
|
||||||
{
|
|
||||||
jack_nframes_t two_smpte_frames_duration;
|
|
||||||
jack_nframes_t quarter_frame_duration;
|
|
||||||
|
|
||||||
/* Duration of two smpte frames */
|
|
||||||
two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
|
|
||||||
|
|
||||||
/* Duration of one quarter frame */
|
|
||||||
quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
|
|
||||||
|
|
||||||
if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
|
|
||||||
{
|
|
||||||
/* There is no work to do.
|
|
||||||
We throttle this here so that we don't overload
|
|
||||||
the transport thread with requests.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIDIRequest* request = new MIDIRequest;
|
|
||||||
|
|
||||||
if (full) {
|
|
||||||
request->type = MIDIRequest::SendFullMTC;
|
|
||||||
} else {
|
|
||||||
request->type = MIDIRequest::SendMTC;
|
|
||||||
}
|
|
||||||
|
|
||||||
midi_requests.write (&request, 1);
|
|
||||||
poke_midi_thread ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::change_midi_ports ()
|
Session::change_midi_ports ()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
MIDIRequest* request = new MIDIRequest;
|
MIDIRequest* request = new MIDIRequest;
|
||||||
|
|
||||||
request->type = MIDIRequest::PortChange;
|
request->type = MIDIRequest::PortChange;
|
||||||
midi_requests.write (&request, 1);
|
midi_requests.write (&request, 1);
|
||||||
poke_midi_thread ();
|
poke_midi_thread ();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
|
||||||
|
* Audio thread only, realtime safe. MIDI::Manager::cycle_start must
|
||||||
|
* have been called with the appropriate nframes parameter this cycle.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
Session::send_full_time_code ()
|
Session::send_full_time_code(jack_nframes_t nframes)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
/* This function could easily send at a given frame offset, but would
|
||||||
|
* that be useful? [DR] */
|
||||||
|
|
||||||
MIDI::byte msg[10];
|
MIDI::byte msg[10];
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
|
_send_smpte_update = false;
|
||||||
|
|
||||||
if (_mtc_port == 0 || !send_mtc) {
|
if (_mtc_port == 0 || !send_mtc) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -868,6 +839,7 @@ Session::send_full_time_code ()
|
||||||
sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
|
sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
|
||||||
|
|
||||||
// Check for negative smpte time and prepare for quarter frame transmission
|
// Check for negative smpte time and prepare for quarter frame transmission
|
||||||
|
assert(!smpte.negative); // this shouldn't happen
|
||||||
if (smpte.negative) {
|
if (smpte.negative) {
|
||||||
// Negative mtc is not defined, so sync slave to smpte zero.
|
// Negative mtc is not defined, so sync slave to smpte zero.
|
||||||
// When _transport_frame gets there we will start transmitting quarter frames
|
// When _transport_frame gets there we will start transmitting quarter frames
|
||||||
|
|
@ -884,7 +856,7 @@ Session::send_full_time_code ()
|
||||||
outbound_mtc_smpte_frame = _transport_frame;
|
outbound_mtc_smpte_frame = _transport_frame;
|
||||||
if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
|
if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
|
||||||
// start MTC quarter frame transmission on an even frame
|
// start MTC quarter frame transmission on an even frame
|
||||||
smpte_increment( transmitting_smpte_time );
|
SMPTE::increment( transmitting_smpte_time );
|
||||||
outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
|
outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -907,42 +879,87 @@ Session::send_full_time_code ()
|
||||||
msg[7] = smpte.seconds;
|
msg[7] = smpte.seconds;
|
||||||
msg[8] = smpte.frames;
|
msg[8] = smpte.frames;
|
||||||
|
|
||||||
{
|
// Send message at offset 0, sent time is for the start of this cycle
|
||||||
LockMonitor lm (midi_lock, __LINE__, __FILE__);
|
if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
|
||||||
|
|
||||||
if (_mtc_port->midimsg (msg, sizeof (msg))) {
|
|
||||||
error << _("Session: could not send full MIDI time code") << endmsg;
|
error << _("Session: could not send full MIDI time code") << endmsg;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends all time code messages for this cycle.
|
||||||
|
* Must be called exactly once per cycle from the audio thread. Realtime safe.
|
||||||
|
* This function assumes the state of full SMPTE is sane, eg. the slave is
|
||||||
|
* expecting quarter frame messages and has the right frame of reference (any
|
||||||
|
* full MTC SMPTE time messages that needed to be sent should have been sent
|
||||||
|
* earlier in the cycle).
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
Session::send_midi_time_code ()
|
Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
|
//cerr << "----------------------" << endl;
|
||||||
|
|
||||||
|
// FIXME: remove, just for debug print statement
|
||||||
|
static jack_nframes_t last_time = 0;
|
||||||
|
|
||||||
|
assert (next_quarter_frame_to_send >= 0);
|
||||||
|
|
||||||
|
if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative
|
||||||
|
/*|| (next_quarter_frame_to_send < 0)*/ ) {
|
||||||
|
printf("Not sending MTC\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
jack_nframes_t two_smpte_frames_duration;
|
|
||||||
jack_nframes_t quarter_frame_duration;
|
|
||||||
|
|
||||||
/* Duration of two smpte frames */
|
|
||||||
two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
|
|
||||||
|
|
||||||
/* Duration of one quarter frame */
|
/* Duration of one quarter frame */
|
||||||
quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
|
jack_nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
|
||||||
|
|
||||||
while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
|
// FIXME: what was transmitting_smpte_time before??
|
||||||
|
//smpte_time(_transport_frame, transmitting_smpte_time);
|
||||||
|
//smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
|
||||||
|
|
||||||
// Send quarter frames up to current time
|
|
||||||
{
|
|
||||||
LockMonitor lm (midi_lock, __LINE__, __FILE__);
|
|
||||||
|
|
||||||
switch(next_quarter_frame_to_send) {
|
#if 0
|
||||||
|
if (_send_smpte_update) {
|
||||||
|
// Send full SMPTE time and reset quarter frames
|
||||||
|
cerr << "[DR] Sending full SMTPE update" << endl;
|
||||||
|
// Re-calculate timing of first quarter frame
|
||||||
|
smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
|
||||||
|
// Compensate for audio latency
|
||||||
|
//outbound_mtc_smpte_frame += _worst_output_latency;
|
||||||
|
send_full_time_code(nframes);
|
||||||
|
_send_smpte_update = false;
|
||||||
|
next_quarter_frame_to_send = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//cerr << "A - " << _transport_frame << " - " << outbound_mtc_smpte_frame
|
||||||
|
//<< " - " << next_quarter_frame_to_send << " - " << quarter_frame_duration << endl;
|
||||||
|
|
||||||
|
// Note: Unlike the previous implementation of this function (for slow MIDI I/O),
|
||||||
|
// this now sends all MTC messages for _this_ frame, not messages from the past
|
||||||
|
// up until the start of the current frame (any messages in the past must have
|
||||||
|
// been sent last cycle). This assertion enforces this:
|
||||||
|
//assert(outbound_mtc_smpte_frame >= _transport_frame
|
||||||
|
// && (outbound_mtc_smpte_frame - _transport_frame) < nframes);
|
||||||
|
/*if ( ! (outbound_mtc_smpte_frame >= _transport_frame
|
||||||
|
&& (outbound_mtc_smpte_frame - _transport_frame) < nframes)) { */
|
||||||
|
if (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)
|
||||||
|
< _transport_frame) {
|
||||||
|
cerr << "[MTC] ERROR: MTC message stamped " << outbound_mtc_smpte_frame
|
||||||
|
<< " in cycle starting " << _transport_frame << endl;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
//cerr << "[MTC] OK" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send quarter frames for this cycle
|
||||||
|
while (_transport_frame + nframes > (outbound_mtc_smpte_frame +
|
||||||
|
(next_quarter_frame_to_send * quarter_frame_duration))) {
|
||||||
|
|
||||||
|
//cerr << "B: Next frame to send: " << next_quarter_frame_to_send << endl;
|
||||||
|
|
||||||
|
switch (next_quarter_frame_to_send) {
|
||||||
case 0:
|
case 0:
|
||||||
mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
|
mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
|
||||||
break;
|
break;
|
||||||
|
|
@ -969,14 +986,29 @@ Session::send_midi_time_code ()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mtc_port->midimsg (mtc_msg, 2)) {
|
jack_nframes_t msg_time = (outbound_mtc_smpte_frame
|
||||||
|
+ (quarter_frame_duration * next_quarter_frame_to_send));
|
||||||
|
assert(msg_time >= _transport_frame);
|
||||||
|
assert(msg_time < _transport_frame + nframes);
|
||||||
|
|
||||||
|
jack_nframes_t out_stamp = msg_time - _transport_frame;
|
||||||
|
assert(out_stamp < nframes);
|
||||||
|
|
||||||
|
if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
|
||||||
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
||||||
<< endmsg;
|
<< endmsg;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cout << "smpte = " << transmitting_smpte_time.hours << ":" << transmitting_smpte_time.minutes << ":" << transmitting_smpte_time.seconds << ":" << transmitting_smpte_time.frames << ", qfm = " << next_quarter_frame_to_send << endl;
|
/*cerr << "smpte = " << transmitting_smpte_time.hours
|
||||||
|
<< ":" << transmitting_smpte_time.minutes
|
||||||
|
<< ":" << transmitting_smpte_time.seconds
|
||||||
|
<< ":" << transmitting_smpte_time.frames
|
||||||
|
<< ", qfm = " << next_quarter_frame_to_send
|
||||||
|
<< ", stamp = " << out_stamp
|
||||||
|
<< ", delta = " << _transport_frame + out_stamp - last_time << endl;*/
|
||||||
|
|
||||||
|
last_time = _transport_frame + out_stamp;
|
||||||
|
|
||||||
// Increment quarter frame counter
|
// Increment quarter frame counter
|
||||||
next_quarter_frame_to_send++;
|
next_quarter_frame_to_send++;
|
||||||
|
|
@ -985,22 +1017,23 @@ Session::send_midi_time_code ()
|
||||||
// Wrap quarter frame counter
|
// Wrap quarter frame counter
|
||||||
next_quarter_frame_to_send = 0;
|
next_quarter_frame_to_send = 0;
|
||||||
// Increment smpte time twice
|
// Increment smpte time twice
|
||||||
smpte_increment( transmitting_smpte_time );
|
SMPTE::increment( transmitting_smpte_time );
|
||||||
smpte_increment( transmitting_smpte_time );
|
SMPTE::increment( transmitting_smpte_time );
|
||||||
// Re-calculate timing of first quarter frame
|
// Re-calculate timing of first quarter frame
|
||||||
smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
|
//smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
|
||||||
|
outbound_mtc_smpte_frame += 8 * quarter_frame_duration;
|
||||||
// Compensate for audio latency
|
// Compensate for audio latency
|
||||||
outbound_mtc_smpte_frame += _worst_output_latency;
|
outbound_mtc_smpte_frame += _worst_output_latency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
OUTBOUND MMC STUFF
|
OUTBOUND MMC STUFF
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
/*
|
||||||
void
|
void
|
||||||
Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
|
Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
|
||||||
{
|
{
|
||||||
|
|
@ -1018,13 +1051,14 @@ Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nfr
|
||||||
midi_requests.write (&request, 1);
|
midi_requests.write (&request, 1);
|
||||||
poke_midi_thread ();
|
poke_midi_thread ();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
|
Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
int nbytes = 4;
|
int nbytes = 4;
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
if (_mmc_port == 0 || !send_mmc) {
|
if (_mmc_port == 0 || !send_mmc) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1081,6 +1115,8 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
|
||||||
error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
|
error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
cout << "MMC support broken." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1117,7 +1153,7 @@ void
|
||||||
Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
||||||
{
|
{
|
||||||
// in another thread, really
|
// in another thread, really
|
||||||
|
/*
|
||||||
MIDIRequest* request = new MIDIRequest;
|
MIDIRequest* request = new MIDIRequest;
|
||||||
|
|
||||||
request->type = MIDIRequest::SendMessage;
|
request->type = MIDIRequest::SendMessage;
|
||||||
|
|
@ -1128,13 +1164,14 @@ Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel
|
||||||
|
|
||||||
midi_requests.write (&request, 1);
|
midi_requests.write (&request, 1);
|
||||||
poke_midi_thread ();
|
poke_midi_thread ();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
|
Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
|
||||||
{
|
{
|
||||||
// in another thread, really
|
// in another thread, really
|
||||||
|
/*
|
||||||
MIDIRequest* request = new MIDIRequest;
|
MIDIRequest* request = new MIDIRequest;
|
||||||
|
|
||||||
request->type = MIDIRequest::Deliver;
|
request->type = MIDIRequest::Deliver;
|
||||||
|
|
@ -1144,8 +1181,10 @@ Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
|
||||||
|
|
||||||
midi_requests.write (&request, 1);
|
midi_requests.write (&request, 1);
|
||||||
poke_midi_thread ();
|
poke_midi_thread ();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void
|
void
|
||||||
Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
|
||||||
{
|
{
|
||||||
|
|
@ -1171,11 +1210,14 @@ Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
|
||||||
|
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
MIDI THREAD
|
MIDI THREAD
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
int
|
int
|
||||||
Session::start_midi_thread ()
|
Session::start_midi_thread ()
|
||||||
{
|
{
|
||||||
|
|
@ -1456,6 +1498,7 @@ Session::midi_thread_work ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Session::get_mmc_control () const
|
Session::get_mmc_control () const
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
#include <ardour/cycles.h>
|
#include <ardour/cycles.h>
|
||||||
#include <ardour/cycle_timer.h>
|
#include <ardour/cycle_timer.h>
|
||||||
|
|
||||||
|
#include <midi++/manager.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
|
@ -47,6 +49,10 @@ using namespace std;
|
||||||
void
|
void
|
||||||
Session::process (jack_nframes_t nframes)
|
Session::process (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
cerr << "CYCLE START " << _transport_frame << "-------------------" << endl;
|
||||||
|
|
||||||
|
MIDI::Manager::instance()->cycle_start(nframes);
|
||||||
|
|
||||||
if (synced_to_jack() && waiting_to_start) {
|
if (synced_to_jack() && waiting_to_start) {
|
||||||
if ( _engine.transport_state() == AudioEngine::TransportRolling) {
|
if ( _engine.transport_state() == AudioEngine::TransportRolling) {
|
||||||
actually_start_transport ();
|
actually_start_transport ();
|
||||||
|
|
@ -60,6 +66,10 @@ Session::process (jack_nframes_t nframes)
|
||||||
}
|
}
|
||||||
|
|
||||||
(this->*process_function) (nframes);
|
(this->*process_function) (nframes);
|
||||||
|
|
||||||
|
MIDI::Manager::instance()->cycle_end();
|
||||||
|
|
||||||
|
cerr << "CYCLE END " << _transport_frame << "-----------------------" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -77,6 +87,8 @@ Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool declick = get_transport_declick_required();
|
bool declick = get_transport_declick_required();
|
||||||
|
|
||||||
|
cerr << "[DR] no_roll\n";
|
||||||
|
|
||||||
if (_click_io) {
|
if (_click_io) {
|
||||||
_click_io->silence (nframes, offset);
|
_click_io->silence (nframes, offset);
|
||||||
}
|
}
|
||||||
|
|
@ -237,6 +249,7 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::process_with_events (jack_nframes_t nframes)
|
Session::process_with_events (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
|
@ -244,9 +257,11 @@ Session::process_with_events (jack_nframes_t nframes)
|
||||||
jack_nframes_t this_nframes;
|
jack_nframes_t this_nframes;
|
||||||
jack_nframes_t end_frame;
|
jack_nframes_t end_frame;
|
||||||
jack_nframes_t offset;
|
jack_nframes_t offset;
|
||||||
bool session_needs_butler = false;
|
|
||||||
jack_nframes_t stop_limit;
|
jack_nframes_t stop_limit;
|
||||||
long frames_moved;
|
long frames_moved;
|
||||||
|
bool session_needs_butler = false;
|
||||||
|
|
||||||
|
cerr << "[DR] with events" << endl;
|
||||||
|
|
||||||
if (auditioner) {
|
if (auditioner) {
|
||||||
auditioner->silence (nframes, 0);
|
auditioner->silence (nframes, 0);
|
||||||
|
|
@ -267,6 +282,13 @@ Session::process_with_events (jack_nframes_t nframes)
|
||||||
process_event (ev);
|
process_event (ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Events caused a transport change and we need to send MTC
|
||||||
|
* [DR] FIXME: best place for this? */
|
||||||
|
if (_send_smpte_update) {
|
||||||
|
cerr << "[DR] TIME CHANGE\n" << endl;
|
||||||
|
send_full_time_code(nframes);
|
||||||
|
}
|
||||||
|
|
||||||
if (!process_can_proceed()) {
|
if (!process_can_proceed()) {
|
||||||
no_roll (nframes, 0);
|
no_roll (nframes, 0);
|
||||||
return;
|
return;
|
||||||
|
|
@ -400,16 +422,10 @@ Session::process_with_events (jack_nframes_t nframes)
|
||||||
|
|
||||||
} /* implicit release of route lock */
|
} /* implicit release of route lock */
|
||||||
|
|
||||||
|
if (session_needs_butler)
|
||||||
if (session_needs_butler) {
|
|
||||||
summon_butler ();
|
summon_butler ();
|
||||||
}
|
|
||||||
|
|
||||||
if (!_engine.freewheeling() && send_mtc) {
|
send_midi_time_code_for_cycle(nframes);
|
||||||
send_midi_time_code_in_another_thread ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -725,6 +741,8 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
|
||||||
void
|
void
|
||||||
Session::process_without_events (jack_nframes_t nframes)
|
Session::process_without_events (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
cerr << "[DR] without events" << endl;
|
||||||
|
|
||||||
bool session_needs_butler = false;
|
bool session_needs_butler = false;
|
||||||
jack_nframes_t stop_limit;
|
jack_nframes_t stop_limit;
|
||||||
long frames_moved;
|
long frames_moved;
|
||||||
|
|
@ -788,15 +806,10 @@ Session::process_without_events (jack_nframes_t nframes)
|
||||||
|
|
||||||
} /* implicit release of route lock */
|
} /* implicit release of route lock */
|
||||||
|
|
||||||
if (session_needs_butler) {
|
send_midi_time_code_for_cycle(nframes);
|
||||||
|
|
||||||
|
if (session_needs_butler)
|
||||||
summon_butler ();
|
summon_butler ();
|
||||||
}
|
|
||||||
|
|
||||||
if (!_engine.freewheeling() && send_mtc) {
|
|
||||||
send_midi_time_code_in_another_thread ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||||
state_was_pending = false;
|
state_was_pending = false;
|
||||||
set_next_event ();
|
set_next_event ();
|
||||||
outbound_mtc_smpte_frame = 0;
|
outbound_mtc_smpte_frame = 0;
|
||||||
next_quarter_frame_to_send = -1;
|
next_quarter_frame_to_send = 0;
|
||||||
current_block_size = 0;
|
current_block_size = 0;
|
||||||
_solo_latched = true;
|
_solo_latched = true;
|
||||||
_solo_model = InverseMute;
|
_solo_model = InverseMute;
|
||||||
|
|
@ -297,9 +297,11 @@ Session::second_stage_init (bool new_session)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME
|
||||||
if (start_midi_thread ()) {
|
if (start_midi_thread ()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (state_tree) {
|
if (state_tree) {
|
||||||
if (set_state (*state_tree->root())) {
|
if (set_state (*state_tree->root())) {
|
||||||
|
|
@ -336,10 +338,11 @@ Session::second_stage_init (bool new_session)
|
||||||
first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
|
first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
|
||||||
}
|
}
|
||||||
|
|
||||||
send_full_time_code ();
|
// FIXME
|
||||||
|
//send_full_time_code ();
|
||||||
_engine.transport_locate (0);
|
_engine.transport_locate (0);
|
||||||
deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
|
//deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
|
||||||
deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
|
//deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
|
||||||
|
|
||||||
ControlProtocolManager::instance().set_session (*this);
|
ControlProtocolManager::instance().set_session (*this);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,18 +63,22 @@ Session::set_smpte_type (float fps, bool drop_frames)
|
||||||
switch ((int) ceil (fps)) {
|
switch ((int) ceil (fps)) {
|
||||||
case 24:
|
case 24:
|
||||||
mtc_smpte_bits = 0;
|
mtc_smpte_bits = 0;
|
||||||
|
SMPTE::Time::default_rate = SMPTE::MTC_24_FPS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 25:
|
case 25:
|
||||||
mtc_smpte_bits = 0x20;
|
mtc_smpte_bits = 0x20;
|
||||||
|
SMPTE::Time::default_rate = SMPTE::MTC_25_FPS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30:
|
case 30:
|
||||||
default:
|
default:
|
||||||
if (drop_frames) {
|
if (drop_frames) {
|
||||||
mtc_smpte_bits = 0x40;
|
mtc_smpte_bits = 0x40;
|
||||||
|
SMPTE::Time::default_rate = SMPTE::MTC_30_FPS_DROP;
|
||||||
} else {
|
} else {
|
||||||
mtc_smpte_bits = 0x60;
|
mtc_smpte_bits = 0x60;
|
||||||
|
SMPTE::Time::default_rate = SMPTE::MTC_30_FPS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
@ -102,377 +106,9 @@ Session::set_smpte_offset_negative (bool neg)
|
||||||
SMPTEOffsetChanged (); /* EMIT SIGNAL */
|
SMPTEOffsetChanged (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SMPTE_IS_AROUND_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours)
|
|
||||||
#define SMPTE_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes))
|
|
||||||
|
|
||||||
// Increment by exactly one frame (keep subframes value)
|
|
||||||
// Return true if seconds wrap
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_increment( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
|
|
||||||
// We have a zero transition involving only subframes
|
|
||||||
smpte.subframes = 80 - smpte.subframes;
|
|
||||||
smpte.negative = false;
|
|
||||||
return smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
smpte.negative = false;
|
|
||||||
wrap = smpte_decrement( smpte );
|
|
||||||
if (!SMPTE_IS_ZERO( smpte )) {
|
|
||||||
smpte.negative = true;
|
|
||||||
}
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mtc_smpte_bits >> 5) {
|
|
||||||
case MIDI::MTC_24_FPS:
|
|
||||||
if (smpte.frames == 23) {
|
|
||||||
smpte.frames = 0;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_25_FPS:
|
|
||||||
if (smpte.frames == 24) {
|
|
||||||
smpte.frames = 0;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS_DROP:
|
|
||||||
if (smpte.frames == 29) {
|
|
||||||
if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
|
|
||||||
smpte.frames = 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
smpte.frames = 0;
|
|
||||||
}
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS:
|
|
||||||
if (smpte.frames == 29) {
|
|
||||||
smpte.frames = 0;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wrap == smpte_wrap_seconds) {
|
|
||||||
if (smpte.seconds == 59) {
|
|
||||||
smpte.seconds = 0;
|
|
||||||
wrap = smpte_wrap_minutes;
|
|
||||||
if (smpte.minutes == 59) {
|
|
||||||
smpte.minutes = 0;
|
|
||||||
wrap = smpte_wrap_hours;
|
|
||||||
smpte.hours++;
|
|
||||||
} else {
|
|
||||||
smpte.minutes++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smpte.seconds++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smpte.frames++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decrement by exactly one frame (keep subframes value)
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_decrement( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
|
|
||||||
if (smpte.negative || SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
wrap = smpte_increment( smpte );
|
|
||||||
smpte.negative = true;
|
|
||||||
return wrap;
|
|
||||||
} else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
|
|
||||||
// We have a zero transition involving only subframes
|
|
||||||
smpte.subframes = 80 - smpte.subframes;
|
|
||||||
smpte.negative = true;
|
|
||||||
return smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mtc_smpte_bits >> 5) {
|
|
||||||
case MIDI::MTC_24_FPS:
|
|
||||||
if (smpte.frames == 0) {
|
|
||||||
smpte.frames = 23;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_25_FPS:
|
|
||||||
if (smpte.frames == 0) {
|
|
||||||
smpte.frames = 24;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS_DROP:
|
|
||||||
if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
|
|
||||||
if (smpte.frames <= 2) {
|
|
||||||
smpte.frames = 29;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
} else if (smpte.frames == 0) {
|
|
||||||
smpte.frames = 29;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS:
|
|
||||||
if (smpte.frames == 0) {
|
|
||||||
smpte.frames = 29;
|
|
||||||
wrap = smpte_wrap_seconds;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wrap == smpte_wrap_seconds) {
|
|
||||||
if (smpte.seconds == 0) {
|
|
||||||
smpte.seconds = 59;
|
|
||||||
wrap = smpte_wrap_minutes;
|
|
||||||
if (smpte.minutes == 0) {
|
|
||||||
smpte.minutes = 59;
|
|
||||||
wrap = smpte_wrap_hours;
|
|
||||||
smpte.hours--;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
smpte.minutes--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smpte.seconds--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smpte.frames--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SMPTE_IS_ZERO( smpte )) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to lowest absolute subframe value in this frame (set to 0 :-)
|
|
||||||
void
|
|
||||||
Session::smpte_frames_floor( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte.subframes = 0;
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment by one subframe
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_increment_subframes( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
smpte.negative = false;
|
|
||||||
wrap = smpte_decrement_subframes( smpte );
|
|
||||||
if (!SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = true;
|
|
||||||
}
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
smpte.subframes++;
|
|
||||||
if (smpte.subframes >= 80) {
|
|
||||||
smpte.subframes = 0;
|
|
||||||
smpte_increment( smpte );
|
|
||||||
return smpte_wrap_frames;
|
|
||||||
}
|
|
||||||
return smpte_wrap_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Decrement by one subframe
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_decrement_subframes( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
smpte.negative = false;
|
|
||||||
wrap = smpte_increment_subframes( smpte );
|
|
||||||
smpte.negative = true;
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smpte.subframes <= 0) {
|
|
||||||
smpte.subframes = 0;
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = true;
|
|
||||||
smpte.subframes = 1;
|
|
||||||
return smpte_wrap_frames;
|
|
||||||
} else {
|
|
||||||
smpte_decrement( smpte );
|
|
||||||
smpte.subframes = 79;
|
|
||||||
return smpte_wrap_frames;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smpte.subframes--;
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
return smpte_wrap_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Go to next whole second (frames == 0 or frames == 2)
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_increment_seconds( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
// Clear subframes
|
|
||||||
smpte_frames_floor( smpte );
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
// Wrap second if on second boundary
|
|
||||||
wrap = smpte_increment(smpte);
|
|
||||||
// Go to lowest absolute frame value
|
|
||||||
smpte_seconds_floor( smpte );
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Go to highest possible frame in this second
|
|
||||||
switch (mtc_smpte_bits >> 5) {
|
|
||||||
case MIDI::MTC_24_FPS:
|
|
||||||
smpte.frames = 23;
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_25_FPS:
|
|
||||||
smpte.frames = 24;
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS_DROP:
|
|
||||||
case MIDI::MTC_30_FPS:
|
|
||||||
smpte.frames = 29;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment by one frame
|
|
||||||
wrap = smpte_increment( smpte );
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to lowest (absolute) frame value in this second
|
|
||||||
// Doesn't care about positive/negative
|
|
||||||
void
|
|
||||||
Session::smpte_seconds_floor( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
// Clear subframes
|
|
||||||
smpte_frames_floor( smpte );
|
|
||||||
|
|
||||||
// Go to lowest possible frame in this second
|
|
||||||
switch (mtc_smpte_bits >> 5) {
|
|
||||||
case MIDI::MTC_24_FPS:
|
|
||||||
case MIDI::MTC_25_FPS:
|
|
||||||
case MIDI::MTC_30_FPS:
|
|
||||||
smpte.frames = 0;
|
|
||||||
break;
|
|
||||||
case MIDI::MTC_30_FPS_DROP:
|
|
||||||
if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
|
|
||||||
smpte.frames = 2;
|
|
||||||
} else {
|
|
||||||
smpte.frames = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Go to next whole minute (seconds == 0, frames == 0 or frames == 2)
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_increment_minutes( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
// Clear subframes
|
|
||||||
smpte_frames_floor( smpte );
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
// Wrap if on minute boundary
|
|
||||||
wrap = smpte_increment_seconds( smpte );
|
|
||||||
// Go to lowest possible value in this minute
|
|
||||||
smpte_minutes_floor( smpte );
|
|
||||||
} else {
|
|
||||||
// Go to highest possible second
|
|
||||||
smpte.seconds = 59;
|
|
||||||
// Wrap minute by incrementing second
|
|
||||||
wrap = smpte_increment_seconds( smpte );
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to lowest absolute value in this minute
|
|
||||||
void
|
|
||||||
Session::smpte_minutes_floor( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
// Go to lowest possible second
|
|
||||||
smpte.seconds = 0;
|
|
||||||
// Go to lowest possible frame
|
|
||||||
smpte_seconds_floor( smpte );
|
|
||||||
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to next whole hour (minute = 0, second = 0, frame = 0)
|
|
||||||
smpte_wrap_t
|
|
||||||
Session::smpte_increment_hours( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte_wrap_t wrap = smpte_wrap_none;
|
|
||||||
|
|
||||||
// Clear subframes
|
|
||||||
smpte_frames_floor(smpte);
|
|
||||||
|
|
||||||
if (smpte.negative) {
|
|
||||||
// Wrap if on hour boundary
|
|
||||||
wrap = smpte_increment_minutes( smpte );
|
|
||||||
// Go to lowest possible value in this hour
|
|
||||||
smpte_hours_floor( smpte );
|
|
||||||
} else {
|
|
||||||
smpte.minutes = 59;
|
|
||||||
wrap = smpte_increment_minutes( smpte );
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to lowest absolute value in this hour
|
|
||||||
void
|
|
||||||
Session::smpte_hours_floor( SMPTE_Time& smpte ) const
|
|
||||||
{
|
|
||||||
smpte.minutes = 0;
|
|
||||||
smpte.seconds = 0;
|
|
||||||
smpte.frames = 0;
|
|
||||||
smpte.subframes = 0;
|
|
||||||
|
|
||||||
if (SMPTE_IS_ZERO(smpte)) {
|
|
||||||
smpte.negative = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const
|
Session::smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const
|
||||||
{
|
{
|
||||||
if (smpte_drop_frames) {
|
if (smpte_drop_frames) {
|
||||||
// The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997....
|
// The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997....
|
||||||
|
|
@ -555,7 +191,7 @@ Session::smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_of
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const
|
Session::sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const
|
||||||
{
|
{
|
||||||
jack_nframes_t offset_sample;
|
jack_nframes_t offset_sample;
|
||||||
|
|
||||||
|
|
@ -649,7 +285,7 @@ Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_off
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::smpte_time (jack_nframes_t when, SMPTE_Time& smpte)
|
Session::smpte_time (jack_nframes_t when, SMPTE::Time& smpte)
|
||||||
{
|
{
|
||||||
if (last_smpte_valid && when == last_smpte_when) {
|
if (last_smpte_valid && when == last_smpte_when) {
|
||||||
smpte = last_smpte;
|
smpte = last_smpte;
|
||||||
|
|
@ -664,7 +300,7 @@ Session::smpte_time (jack_nframes_t when, SMPTE_Time& smpte)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::smpte_time_subframes (jack_nframes_t when, SMPTE_Time& smpte)
|
Session::smpte_time_subframes (jack_nframes_t when, SMPTE::Time& smpte)
|
||||||
{
|
{
|
||||||
if (last_smpte_valid && when == last_smpte_when) {
|
if (last_smpte_valid && when == last_smpte_when) {
|
||||||
smpte = last_smpte;
|
smpte = last_smpte;
|
||||||
|
|
@ -679,7 +315,7 @@ Session::smpte_time_subframes (jack_nframes_t when, SMPTE_Time& smpte)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::smpte_duration (jack_nframes_t when, SMPTE_Time& smpte) const
|
Session::smpte_duration (jack_nframes_t when, SMPTE::Time& smpte) const
|
||||||
{
|
{
|
||||||
sample_to_smpte( when, smpte, false /* use_offset */, true /* use_subframes */ );
|
sample_to_smpte( when, smpte, false /* use_offset */, true /* use_subframes */ );
|
||||||
}
|
}
|
||||||
|
|
@ -687,14 +323,14 @@ Session::smpte_duration (jack_nframes_t when, SMPTE_Time& smpte) const
|
||||||
void
|
void
|
||||||
Session::smpte_duration_string (char* buf, jack_nframes_t when) const
|
Session::smpte_duration_string (char* buf, jack_nframes_t when) const
|
||||||
{
|
{
|
||||||
SMPTE_Time smpte;
|
SMPTE::Time smpte;
|
||||||
|
|
||||||
smpte_duration (when, smpte);
|
smpte_duration (when, smpte);
|
||||||
snprintf (buf, sizeof (buf), "%02ld:%02ld:%02ld:%02ld", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
|
snprintf (buf, sizeof (buf), "%02ld:%02ld:%02ld:%02ld", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Session::smpte_time (SMPTE_Time &t)
|
Session::smpte_time (SMPTE::Time &t)
|
||||||
|
|
||||||
{
|
{
|
||||||
smpte_time (_transport_frame, t);
|
smpte_time (_transport_frame, t);
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,8 @@ Session::non_realtime_stop (bool abort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
|
//FIXME
|
||||||
|
//deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
|
||||||
|
|
||||||
#ifdef LEAVE_TRANSPORT_UNADJUSTED
|
#ifdef LEAVE_TRANSPORT_UNADJUSTED
|
||||||
}
|
}
|
||||||
|
|
@ -383,9 +384,11 @@ Session::non_realtime_stop (bool abort)
|
||||||
|
|
||||||
last_stop_frame = _transport_frame;
|
last_stop_frame = _transport_frame;
|
||||||
|
|
||||||
send_full_time_code ();
|
/* FIXME
|
||||||
|
send_full_time_code();
|
||||||
deliver_mmc (MIDI::MachineControl::cmdStop, 0);
|
deliver_mmc (MIDI::MachineControl::cmdStop, 0);
|
||||||
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
|
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
|
||||||
|
*/
|
||||||
|
|
||||||
if (did_record) {
|
if (did_record) {
|
||||||
|
|
||||||
|
|
@ -594,6 +597,15 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
|
||||||
}
|
}
|
||||||
|
|
||||||
_transport_frame = target_frame;
|
_transport_frame = target_frame;
|
||||||
|
smpte_time(_transport_frame, transmitting_smpte_time);
|
||||||
|
outbound_mtc_smpte_frame = _transport_frame;
|
||||||
|
next_quarter_frame_to_send = 0;
|
||||||
|
cerr << "[DR] LOCATE ----------" << endl;
|
||||||
|
cerr << "\t_transport_frame = " << _transport_frame << endl;
|
||||||
|
cerr << "\ttransmitting_smpte_time = " << string_compose("%1:%2:%3:%4",
|
||||||
|
transmitting_smpte_time.hours,transmitting_smpte_time.minutes,
|
||||||
|
transmitting_smpte_time.seconds,transmitting_smpte_time.frames) << endl;
|
||||||
|
cerr << "-------------" << endl;
|
||||||
|
|
||||||
if (_transport_speed && (!with_loop || loop_changing)) {
|
if (_transport_speed && (!with_loop || loop_changing)) {
|
||||||
/* schedule a declick. we'll be called again when its done */
|
/* schedule a declick. we'll be called again when its done */
|
||||||
|
|
@ -680,6 +692,8 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_changing = false;
|
loop_changing = false;
|
||||||
|
|
||||||
|
_send_smpte_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -875,11 +889,28 @@ Session::actually_start_transport ()
|
||||||
(*i)->realtime_set_speed ((*i)->speed(), true);
|
(*i)->realtime_set_speed ((*i)->speed(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME
|
||||||
send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
|
send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// [DR] Update SMPTE time from transport frame
|
||||||
|
smpte_time(_transport_frame, transmitting_smpte_time);
|
||||||
|
outbound_mtc_smpte_frame = _transport_frame;
|
||||||
|
next_quarter_frame_to_send = 0;
|
||||||
|
|
||||||
|
cerr << "[DR] ACTUALLY START TRANSPORT ----------" << endl;
|
||||||
|
cerr << "\t_transport_frame = " << _transport_frame << endl;
|
||||||
|
cerr << "\ttransmitting_smpte_time = " << string_compose("%1:%2:%3:%4",
|
||||||
|
transmitting_smpte_time.hours,transmitting_smpte_time.minutes,
|
||||||
|
transmitting_smpte_time.seconds,transmitting_smpte_time.frames) << endl;
|
||||||
|
cerr << "-------------" << endl;
|
||||||
|
|
||||||
TransportStateChange (); /* EMIT SIGNAL */
|
TransportStateChange (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Do any transport work in the audio thread that needs to be done after the
|
||||||
|
* transport thread is finished. Audio thread, realtime safe.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Session::post_transport ()
|
Session::post_transport ()
|
||||||
{
|
{
|
||||||
|
|
@ -910,6 +941,18 @@ Session::post_transport ()
|
||||||
set_next_event ();
|
set_next_event ();
|
||||||
|
|
||||||
post_transport_work = PostTransportWork (0);
|
post_transport_work = PostTransportWork (0);
|
||||||
|
|
||||||
|
// [DR] Update SMPTE time from transport frame
|
||||||
|
smpte_time(_transport_frame, transmitting_smpte_time);
|
||||||
|
outbound_mtc_smpte_frame = _transport_frame;
|
||||||
|
next_quarter_frame_to_send = 0;
|
||||||
|
|
||||||
|
cerr << "[DR] POST TRANSPORT ----------" << endl;
|
||||||
|
cerr << "\t_transport_frame = " << _transport_frame << endl;
|
||||||
|
cerr << "\ttransmitting_smpte_time = " << string_compose("%1:%2:%3:%4",
|
||||||
|
transmitting_smpte_time.hours,transmitting_smpte_time.minutes,
|
||||||
|
transmitting_smpte_time.seconds,transmitting_smpte_time.frames) << endl;
|
||||||
|
cerr << "-------------" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -30,18 +30,24 @@ version.cc
|
||||||
""")
|
""")
|
||||||
|
|
||||||
sysdep_sources = Split ("""
|
sysdep_sources = Split ("""
|
||||||
|
jack_midiport.cc
|
||||||
alsa_sequencer_midiport.cc
|
alsa_sequencer_midiport.cc
|
||||||
coremidi_midiport.cc
|
coremidi_midiport.cc
|
||||||
""")
|
""")
|
||||||
|
|
||||||
if env['SYSMIDI'] == 'CoreMIDI':
|
if env['SYSMIDI'] == 'JACK MIDI':
|
||||||
|
sysdep_src = [ 'jack_midiport.cc' ]
|
||||||
|
midi2.Append (CCFLAGS="-DWITH_JACK_MIDI")
|
||||||
|
elif env['SYSMIDI'] == 'ALSA Sequencer':
|
||||||
|
sysdep_src = [ 'alsa_sequencer_midiport.cc' ]
|
||||||
|
midi2.Append (CCFLAGS="-DWITH_ALSA")
|
||||||
|
elif env['SYSMIDI'] == 'CoreMIDI':
|
||||||
sysdep_src = [ 'coremidi_midiport.cc' ]
|
sysdep_src = [ 'coremidi_midiport.cc' ]
|
||||||
midi2.Append (CCFLAGS="-DWITH_COREMIDI")
|
midi2.Append (CCFLAGS="-DWITH_COREMIDI")
|
||||||
midi2.Append (LINKFLAGS="-framework CoreMIDI")
|
midi2.Append (LINKFLAGS="-framework CoreMIDI")
|
||||||
midi2.Append (LINKFLAGS="-framework CoreFoundation")
|
midi2.Append (LINKFLAGS="-framework CoreFoundation")
|
||||||
else:
|
|
||||||
sysdep_src = [ 'alsa_sequencer_midiport.cc' ]
|
|
||||||
midi2.Append (CCFLAGS="-DWITH_ALSA")
|
|
||||||
|
|
||||||
midi2.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
|
midi2.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
|
||||||
midi2.Append(CCFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
|
midi2.Append(CCFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ int ALSA_SequencerMidiPort::selectable () const
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen)
|
int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
TR_FN ();
|
TR_FN ();
|
||||||
int R;
|
int R;
|
||||||
|
|
@ -118,7 +118,7 @@ int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen)
|
||||||
return totwritten;
|
return totwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ALSA_SequencerMidiPort::read (byte *buf, size_t max)
|
int ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
TR_FN();
|
TR_FN();
|
||||||
int err;
|
int err;
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void CoreMidi_MidiPort::Close ()
|
||||||
if (midi_client) MIDIClientDispose(midi_client);
|
if (midi_client) MIDIClientDispose(midi_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CoreMidi_MidiPort::write (byte *msg, size_t msglen)
|
int CoreMidi_MidiPort::write (byte *msg, size_t msglen, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
|
MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
FD_MidiPort::read (byte* buf, size_t max)
|
FD_MidiPort::read (byte* buf, size_t max, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
int nread;
|
int nread;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#include <midi++/port.h>
|
#include <midi++/port.h>
|
||||||
#include <midi++/fd_midiport.h>
|
#include <midi++/fd_midiport.h>
|
||||||
|
|
||||||
|
namespace MIDI {
|
||||||
|
|
||||||
class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -38,6 +40,7 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort
|
||||||
virtual ~ALSA_RawMidiPort () {}
|
virtual ~ALSA_RawMidiPort () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace MIDI
|
||||||
|
|
||||||
#endif // __alsa_rawmidi_h__
|
#endif // __alsa_rawmidi_h__
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,8 @@ class ALSA_SequencerMidiPort : public Port
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
|
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
int write (byte *msg, size_t msglen);
|
int read (byte *buf, size_t max, timestamp_t timestamp);
|
||||||
int read (byte *buf, size_t max);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
snd_seq_t *seq;
|
snd_seq_t *seq;
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,22 @@ namespace MIDI {
|
||||||
|
|
||||||
class Port;
|
class Port;
|
||||||
|
|
||||||
|
/** Stateful MIDI channel class.
|
||||||
|
*
|
||||||
|
* This remembers various useful information about the current 'state' of a
|
||||||
|
* MIDI channel (eg current pitch bend value).
|
||||||
|
*/
|
||||||
class Channel : public sigc::trackable {
|
class Channel : public sigc::trackable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Channel (byte channel_number, Port &);
|
Channel (byte channel_number, Port &);
|
||||||
|
|
||||||
Port &midi_port() { return port; }
|
Port &midi_port() { return _port; }
|
||||||
byte channel() { return channel_number; }
|
byte channel() { return _channel_number; }
|
||||||
byte program() { return program_number; }
|
byte program() { return _program_number; }
|
||||||
byte bank() { return bank_number; }
|
byte bank() { return _bank_number; }
|
||||||
byte pressure () { return chanpress; }
|
byte pressure () { return _chanpress; }
|
||||||
byte poly_pressure (byte n) { return polypress[n]; }
|
byte poly_pressure (byte n) { return _polypress[n]; }
|
||||||
|
|
||||||
byte last_note_on () {
|
byte last_note_on () {
|
||||||
return _last_note_on;
|
return _last_note_on;
|
||||||
|
|
@ -58,53 +63,52 @@ class Channel : public sigc::trackable {
|
||||||
}
|
}
|
||||||
|
|
||||||
pitchbend_t pitchbend () {
|
pitchbend_t pitchbend () {
|
||||||
return pitch_bend;
|
return _pitch_bend;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_value_t controller_value (byte n) {
|
controller_value_t controller_value (byte n) {
|
||||||
return controller_val[n%128];
|
return _controller_val[n%128];
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_value_t *controller_addr (byte n) {
|
controller_value_t *controller_addr (byte n) {
|
||||||
return &controller_val[n%128];
|
return &_controller_val[n%128];
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_controller (byte n, byte val) {
|
void set_controller (byte n, byte val) {
|
||||||
controller_val[n%128] = val;
|
_controller_val[n%128] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool channel_msg (byte id, byte val1, byte val2);
|
bool channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp);
|
||||||
|
bool all_notes_off (timestamp_t timestamp) {
|
||||||
bool all_notes_off () {
|
return channel_msg (MIDI::controller, 123, 0, timestamp);
|
||||||
return channel_msg (MIDI::controller, 123, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool control (byte id, byte value) {
|
bool control (byte id, byte value, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::controller, id, value);
|
return channel_msg (MIDI::controller, id, value, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool note_on (byte note, byte velocity) {
|
bool note_on (byte note, byte velocity, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::on, note, velocity);
|
return channel_msg (MIDI::on, note, velocity, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool note_off (byte note, byte velocity) {
|
bool note_off (byte note, byte velocity, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::off, note, velocity);
|
return channel_msg (MIDI::off, note, velocity, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aftertouch (byte value) {
|
bool aftertouch (byte value, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::chanpress, value, 0);
|
return channel_msg (MIDI::chanpress, value, 0, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool poly_aftertouch (byte note, byte value) {
|
bool poly_aftertouch (byte note, byte value, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::polypress, note, value);
|
return channel_msg (MIDI::polypress, note, value, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool program_change (byte value) {
|
bool program_change (byte value, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::program, value, 0);
|
return channel_msg (MIDI::program, value, 0, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pitchbend (byte msb, byte lsb) {
|
bool pitchbend (byte msb, byte lsb, timestamp_t timestamp) {
|
||||||
return channel_msg (MIDI::pitchbend, lsb, msb);
|
return channel_msg (MIDI::pitchbend, lsb, msb, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -113,34 +117,33 @@ class Channel : public sigc::trackable {
|
||||||
void connect_output_signals ();
|
void connect_output_signals ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Port &port;
|
Port & _port;
|
||||||
|
|
||||||
/* Current channel values */
|
/* Current channel values */
|
||||||
|
byte _channel_number;
|
||||||
byte channel_number;
|
byte _bank_number;
|
||||||
byte bank_number;
|
byte _program_number;
|
||||||
byte program_number;
|
byte _rpn_msb;
|
||||||
byte rpn_msb;
|
byte _rpn_lsb;
|
||||||
byte rpn_lsb;
|
byte _nrpn_msb;
|
||||||
byte nrpn_msb;
|
byte _nrpn_lsb;
|
||||||
byte nrpn_lsb;
|
byte _chanpress;
|
||||||
byte chanpress;
|
byte _polypress[128];
|
||||||
byte polypress[128];
|
bool _controller_14bit[128];
|
||||||
bool controller_14bit[128];
|
controller_value_t _controller_val[128];
|
||||||
controller_value_t controller_val[128];
|
byte _controller_msb[128];
|
||||||
byte controller_msb[128];
|
byte _controller_lsb[128];
|
||||||
byte controller_lsb[128];
|
|
||||||
byte _last_note_on;
|
byte _last_note_on;
|
||||||
byte _last_on_velocity;
|
byte _last_on_velocity;
|
||||||
byte _last_note_off;
|
byte _last_note_off;
|
||||||
byte _last_off_velocity;
|
byte _last_off_velocity;
|
||||||
pitchbend_t pitch_bend;
|
pitchbend_t _pitch_bend;
|
||||||
bool _omni;
|
bool _omni;
|
||||||
bool _poly;
|
bool _poly;
|
||||||
bool _mono;
|
bool _mono;
|
||||||
size_t _notes_on;
|
size_t _notes_on;
|
||||||
|
|
||||||
void reset (bool notes_off = true);
|
void reset (timestamp_t timestamp, nframes_t nframes, bool notes_off = true);
|
||||||
|
|
||||||
void process_note_off (Parser &, EventTwoBytes *);
|
void process_note_off (Parser &, EventTwoBytes *);
|
||||||
void process_note_on (Parser &, EventTwoBytes *);
|
void process_note_on (Parser &, EventTwoBytes *);
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class Controllable : public sigc::trackable
|
||||||
|
|
||||||
std::string control_description() const { return _control_description; }
|
std::string control_description() const { return _control_description; }
|
||||||
|
|
||||||
void send_midi_feedback (float);
|
void send_midi_feedback (float val, timestamp_t timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool bistate;
|
bool bistate;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
class CoreMidi_MidiPort:public Port {
|
class CoreMidi_MidiPort:public Port {
|
||||||
public:
|
public:
|
||||||
CoreMidi_MidiPort(PortRequest & req);
|
CoreMidi_MidiPort(PortRequest & req);
|
||||||
virtual ~ CoreMidi_MidiPort();
|
virtual ~ CoreMidi_MidiPort();
|
||||||
|
|
@ -42,10 +42,10 @@ namespace MIDI {
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
int write(byte * msg, size_t msglen);
|
int write (byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
int read(byte * buf, size_t max) {
|
int read (byte *buf, size_t max, timestamp_t timestamp);
|
||||||
return 0;
|
|
||||||
} /* CoreMidi callback */
|
/* CoreMidi callback */
|
||||||
static void read_proc(const MIDIPacketList * pktlist,
|
static void read_proc(const MIDIPacketList * pktlist,
|
||||||
void *refCon, void *connRefCon);
|
void *refCon, void *connRefCon);
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ namespace MIDI {
|
||||||
static MIDITimeStamp MIDIGetCurrentHostTime();
|
static MIDITimeStamp MIDIGetCurrentHostTime();
|
||||||
|
|
||||||
bool firstrecv;
|
bool firstrecv;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /* namespace MIDI */
|
}; /* namespace MIDI */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace MIDI {
|
||||||
|
|
||||||
class PortFactory {
|
class PortFactory {
|
||||||
public:
|
public:
|
||||||
Port *create_port (PortRequest &req);
|
Port *create_port (PortRequest &req, void* data);
|
||||||
|
|
||||||
static void add_port_request (std::vector<PortRequest *> &reqs,
|
static void add_port_request (std::vector<PortRequest *> &reqs,
|
||||||
const std::string &reqstr);
|
const std::string &reqstr);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,10 @@ class FD_MidiPort : public Port
|
||||||
int _fd;
|
int _fd;
|
||||||
virtual void open (PortRequest &req);
|
virtual void open (PortRequest &req);
|
||||||
|
|
||||||
virtual int write (byte *msg, size_t msglen) {
|
/* Direct I/O */
|
||||||
|
|
||||||
|
virtual int write (byte *msg, size_t msglen,
|
||||||
|
timestamp_t timestamp) {
|
||||||
int nwritten;
|
int nwritten;
|
||||||
|
|
||||||
if ((_mode & O_ACCMODE) == O_RDONLY) {
|
if ((_mode & O_ACCMODE) == O_RDONLY) {
|
||||||
|
|
@ -80,7 +83,8 @@ class FD_MidiPort : public Port
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int read (byte *buf, size_t max);
|
virtual int read (byte *buf, size_t max,
|
||||||
|
timestamp_t timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string *midi_dirpath;
|
static std::string *midi_dirpath;
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,27 @@
|
||||||
|
|
||||||
namespace MIDI {
|
namespace MIDI {
|
||||||
|
|
||||||
|
/** Creates, stores, and manages system MIDI ports.
|
||||||
|
*/
|
||||||
class Manager {
|
class Manager {
|
||||||
public:
|
public:
|
||||||
~Manager ();
|
~Manager ();
|
||||||
|
|
||||||
|
void set_api_data(void* data) { api_data = data; }
|
||||||
|
|
||||||
|
/** Signal the start of an audio cycle.
|
||||||
|
* This MUST be called before any reading/writing for this cycle.
|
||||||
|
* Realtime safe.
|
||||||
|
*/
|
||||||
|
void cycle_start(nframes_t nframes);
|
||||||
|
|
||||||
|
/** Signal the end of an audio cycle.
|
||||||
|
* This signifies that the cycle began with @ref cycle_start has ended.
|
||||||
|
* This MUST be called at the end of each cycle.
|
||||||
|
* Realtime safe.
|
||||||
|
*/
|
||||||
|
void cycle_end();
|
||||||
|
|
||||||
Port *add_port (PortRequest &);
|
Port *add_port (PortRequest &);
|
||||||
int remove_port (std::string port);
|
int remove_port (std::string port);
|
||||||
|
|
||||||
|
|
@ -41,20 +58,6 @@ class Manager {
|
||||||
|
|
||||||
size_t nports () { return ports_by_device.size(); }
|
size_t nports () { return ports_by_device.size(); }
|
||||||
|
|
||||||
/* defaults for clients who are not picky */
|
|
||||||
|
|
||||||
Port *inputPort;
|
|
||||||
Port *outputPort;
|
|
||||||
channel_t inputChannelNumber;
|
|
||||||
channel_t outputChannelNumber;
|
|
||||||
|
|
||||||
int set_input_port (size_t port);
|
|
||||||
int set_input_port (std::string);
|
|
||||||
int set_output_port (size_t port);
|
|
||||||
int set_output_port (std::string);
|
|
||||||
int set_input_channel (channel_t);
|
|
||||||
int set_output_channel (channel_t);
|
|
||||||
|
|
||||||
int foreach_port (int (*func)(const Port &, size_t n, void *),
|
int foreach_port (int (*func)(const Port &, size_t n, void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
|
|
@ -80,6 +83,8 @@ class Manager {
|
||||||
PortMap ports_by_device; /* canonical */
|
PortMap ports_by_device; /* canonical */
|
||||||
PortMap ports_by_tag; /* may contain duplicate Ports */
|
PortMap ports_by_tag; /* may contain duplicate Ports */
|
||||||
|
|
||||||
|
void *api_data;
|
||||||
|
|
||||||
void close_ports ();
|
void close_ports ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,12 @@ class Null_MidiPort : public Port
|
||||||
|
|
||||||
virtual ~Null_MidiPort () {};
|
virtual ~Null_MidiPort () {};
|
||||||
|
|
||||||
virtual int write (byte *msg, size_t msglen) {
|
/* Direct I/O */
|
||||||
|
int write (byte *msg, size_t msglen, timestamp_t timestamp) {
|
||||||
return msglen;
|
return msglen;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int read (byte *buf, size_t max) {
|
int read (byte *buf, size_t max, timestamp_t timestamp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class Port : public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
Unknown,
|
Unknown,
|
||||||
|
JACK_Midi,
|
||||||
ALSA_RawMidi,
|
ALSA_RawMidi,
|
||||||
ALSA_Sequencer,
|
ALSA_Sequencer,
|
||||||
CoreMidi_MidiPort,
|
CoreMidi_MidiPort,
|
||||||
|
|
@ -44,36 +45,58 @@ class Port : public sigc::trackable {
|
||||||
FIFO,
|
FIFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Port (PortRequest &);
|
Port (PortRequest &);
|
||||||
virtual ~Port ();
|
virtual ~Port ();
|
||||||
|
|
||||||
|
// FIXME: make Manager a friend of port so these can be hidden?
|
||||||
|
|
||||||
|
/* Only for use by MidiManager. Don't ever call this. */
|
||||||
|
virtual void cycle_start(nframes_t nframes);
|
||||||
|
|
||||||
|
/* Only for use by MidiManager. Don't ever call this. */
|
||||||
|
virtual void cycle_end();
|
||||||
|
|
||||||
/* Direct I/O */
|
/* Direct I/O */
|
||||||
|
|
||||||
/** \return number of bytes successfully written */
|
/** Read a message from port.
|
||||||
virtual int write (byte *msg, size_t msglen) = 0;
|
* @param buf Raw MIDI message to send
|
||||||
|
* @param max Max size to write to @a buf
|
||||||
|
* @param timestamp Time stamp in frames of this message (relative to cycle start)
|
||||||
|
* @return number of bytes successfully written to \a buf
|
||||||
|
*/
|
||||||
|
virtual int read(byte *buf, size_t max, timestamp_t timestamp) = 0;
|
||||||
|
|
||||||
/** \return number of bytes successfully written to \a buf */
|
/** Write a message to port.
|
||||||
virtual int read (byte *buf, size_t max) = 0;
|
* @param msg Raw MIDI message to send
|
||||||
|
* @param msglen Size of @a msg
|
||||||
|
* @param timestamp Time stamp in frames of this message (relative to cycle start)
|
||||||
|
* @return number of bytes successfully written
|
||||||
|
*/
|
||||||
|
virtual int write(byte *msg, size_t msglen, timestamp_t timestamp) = 0;
|
||||||
|
|
||||||
|
/** Write a message to port.
|
||||||
|
* @return true on success.
|
||||||
|
* FIXME: describe semantics here
|
||||||
|
*/
|
||||||
|
bool midimsg (byte *msg, size_t len, timestamp_t timestamp) {
|
||||||
|
return !(write (msg, len, timestamp) == (int) len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool clock (timestamp_t timestamp);
|
||||||
|
|
||||||
/** Slow down I/O to a loop of single byte emissions
|
/** Slow down I/O to a loop of single byte emissions
|
||||||
interspersed with a busy loop of 10000 * this value.
|
* interspersed with a busy loop of 10000 * this value.
|
||||||
|
*
|
||||||
This may be ignored by a particular instance of this virtual
|
* This may be ignored by a particular instance of this virtual
|
||||||
class. See FD_MidiPort for an example of where it used. */
|
* class. See FD_MidiPort for an example of where it used. */
|
||||||
void set_slowdown (size_t n) { slowdown = n; }
|
void set_slowdown (size_t n) { slowdown = n; }
|
||||||
|
|
||||||
/* select(2)/poll(2)-based I/O */
|
/* select(2)/poll(2)-based I/O */
|
||||||
|
|
||||||
|
/** Get the file descriptor for port.
|
||||||
|
* @return File descriptor, or -1 if not selectable. */
|
||||||
virtual int selectable() const = 0;
|
virtual int selectable() const = 0;
|
||||||
|
|
||||||
void selector_read_callback (Select::Selectable *, Select::Condition);
|
|
||||||
|
|
||||||
static void xforms_read_callback (int cond, int fd, void *ptr);
|
|
||||||
static void gtk_read_callback (void *ptr, int fd, int cond);
|
|
||||||
|
|
||||||
static void write_callback (byte *msg, unsigned int len, void *);
|
|
||||||
|
|
||||||
Channel *channel (channel_t chn) {
|
Channel *channel (channel_t chn) {
|
||||||
return _channel[chn&0x7F];
|
return _channel[chn&0x7F];
|
||||||
}
|
}
|
||||||
|
|
@ -99,24 +122,6 @@ class Port : public sigc::trackable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a message.
|
|
||||||
* \return true on success. */
|
|
||||||
bool midimsg (byte *msg, size_t len) {
|
|
||||||
return !(write (msg, len) == (int) len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write a 3-byte message.
|
|
||||||
* \return true on success. */
|
|
||||||
bool three_byte_msg (byte a, byte b, byte c) {
|
|
||||||
byte msg[3];
|
|
||||||
|
|
||||||
msg[0] = a;
|
|
||||||
msg[1] = b;
|
|
||||||
msg[2] = c;
|
|
||||||
|
|
||||||
return !(write (msg, 3) == 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clock ();
|
bool clock ();
|
||||||
|
|
||||||
const char *device () const { return _devname.c_str(); }
|
const char *device () const { return _devname.c_str(); }
|
||||||
|
|
@ -128,6 +133,8 @@ class Port : public sigc::trackable {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _ok;
|
bool _ok;
|
||||||
|
bool _currently_in_cycle;
|
||||||
|
nframes_t _nframes_this_cycle;
|
||||||
Type _type;
|
Type _type;
|
||||||
std::string _devname;
|
std::string _devname;
|
||||||
std::string _tagname;
|
std::string _tagname;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ namespace MIDI {
|
||||||
typedef float controller_value_t;
|
typedef float controller_value_t;
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef unsigned short pitchbend_t;
|
typedef unsigned short pitchbend_t;
|
||||||
|
typedef unsigned int timestamp_t;
|
||||||
|
typedef unsigned int nframes_t;
|
||||||
|
|
||||||
enum eventType {
|
enum eventType {
|
||||||
none = 0x0,
|
none = 0x0,
|
||||||
|
|
|
||||||
|
|
@ -25,61 +25,61 @@
|
||||||
using namespace sigc;
|
using namespace sigc;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
|
||||||
Channel::Channel (byte channelnum, Port &p) : port (p)
|
Channel::Channel (byte channelnum, Port &p) : _port (p)
|
||||||
{
|
{
|
||||||
channel_number = channelnum;
|
_channel_number = channelnum;
|
||||||
|
|
||||||
reset (false);
|
reset (0, 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::connect_input_signals ()
|
Channel::connect_input_signals ()
|
||||||
|
|
||||||
{
|
{
|
||||||
port.input()->channel_pressure[channel_number].connect
|
_port.input()->channel_pressure[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_chanpress));
|
(mem_fun (*this, &Channel::process_chanpress));
|
||||||
port.input()->channel_note_on[channel_number].connect
|
_port.input()->channel_note_on[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_note_on));
|
(mem_fun (*this, &Channel::process_note_on));
|
||||||
port.input()->channel_note_off[channel_number].connect
|
_port.input()->channel_note_off[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_note_off));
|
(mem_fun (*this, &Channel::process_note_off));
|
||||||
port.input()->channel_poly_pressure[channel_number].connect
|
_port.input()->channel_poly_pressure[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_polypress));
|
(mem_fun (*this, &Channel::process_polypress));
|
||||||
port.input()->channel_program_change[channel_number].connect
|
_port.input()->channel_program_change[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_program_change));
|
(mem_fun (*this, &Channel::process_program_change));
|
||||||
port.input()->channel_controller[channel_number].connect
|
_port.input()->channel_controller[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_controller));
|
(mem_fun (*this, &Channel::process_controller));
|
||||||
port.input()->channel_pitchbend[channel_number].connect
|
_port.input()->channel_pitchbend[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_pitchbend));
|
(mem_fun (*this, &Channel::process_pitchbend));
|
||||||
port.input()->reset.connect (mem_fun (*this, &Channel::process_reset));
|
_port.input()->reset.connect (mem_fun (*this, &Channel::process_reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::connect_output_signals ()
|
Channel::connect_output_signals ()
|
||||||
|
|
||||||
{
|
{
|
||||||
port.output()->channel_pressure[channel_number].connect
|
_port.output()->channel_pressure[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_chanpress));
|
(mem_fun (*this, &Channel::process_chanpress));
|
||||||
port.output()->channel_note_on[channel_number].connect
|
_port.output()->channel_note_on[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_note_on));
|
(mem_fun (*this, &Channel::process_note_on));
|
||||||
port.output()->channel_note_off[channel_number].connect
|
_port.output()->channel_note_off[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_note_off));
|
(mem_fun (*this, &Channel::process_note_off));
|
||||||
port.output()->channel_poly_pressure[channel_number].connect
|
_port.output()->channel_poly_pressure[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_polypress));
|
(mem_fun (*this, &Channel::process_polypress));
|
||||||
port.output()->channel_program_change[channel_number].connect
|
_port.output()->channel_program_change[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_program_change));
|
(mem_fun (*this, &Channel::process_program_change));
|
||||||
port.output()->channel_controller[channel_number].connect
|
_port.output()->channel_controller[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_controller));
|
(mem_fun (*this, &Channel::process_controller));
|
||||||
port.output()->channel_pitchbend[channel_number].connect
|
_port.output()->channel_pitchbend[_channel_number].connect
|
||||||
(mem_fun (*this, &Channel::process_pitchbend));
|
(mem_fun (*this, &Channel::process_pitchbend));
|
||||||
port.output()->reset.connect (mem_fun (*this, &Channel::process_reset));
|
_port.output()->reset.connect (mem_fun (*this, &Channel::process_reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::reset (bool notes_off)
|
Channel::reset (timestamp_t timestamp, nframes_t nframes, bool notes_off)
|
||||||
{
|
{
|
||||||
program_number = channel_number;
|
_program_number = _channel_number;
|
||||||
bank_number = 0;
|
_bank_number = 0;
|
||||||
pitch_bend = 0;
|
_pitch_bend = 0;
|
||||||
|
|
||||||
_last_note_on = 0;
|
_last_note_on = 0;
|
||||||
_last_note_off = 0;
|
_last_note_off = 0;
|
||||||
|
|
@ -87,25 +87,25 @@ Channel::reset (bool notes_off)
|
||||||
_last_off_velocity = 0;
|
_last_off_velocity = 0;
|
||||||
|
|
||||||
if (notes_off) {
|
if (notes_off) {
|
||||||
all_notes_off ();
|
all_notes_off (timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (polypress, 0, sizeof (polypress));
|
memset (_polypress, 0, sizeof (_polypress));
|
||||||
memset (controller_msb, 0, sizeof (controller_msb));
|
memset (_controller_msb, 0, sizeof (_controller_msb));
|
||||||
memset (controller_lsb, 0, sizeof (controller_lsb));
|
memset (_controller_lsb, 0, sizeof (_controller_lsb));
|
||||||
|
|
||||||
/* zero all controllers XXX not necessarily the right thing */
|
/* zero all controllers XXX not necessarily the right thing */
|
||||||
|
|
||||||
memset (controller_val, 0, sizeof (controller_val));
|
memset (_controller_val, 0, sizeof (_controller_val));
|
||||||
|
|
||||||
for (int n = 0; n < 128; n++) {
|
for (int n = 0; n < 128; n++) {
|
||||||
controller_14bit[n] = false;
|
_controller_14bit[n] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpn_msb = 0;
|
_rpn_msb = 0;
|
||||||
rpn_lsb = 0;
|
_rpn_lsb = 0;
|
||||||
nrpn_msb = 0;
|
_nrpn_msb = 0;
|
||||||
nrpn_lsb = 0;
|
_nrpn_lsb = 0;
|
||||||
|
|
||||||
_omni = true;
|
_omni = true;
|
||||||
_poly = false;
|
_poly = false;
|
||||||
|
|
@ -155,20 +155,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
|
||||||
it directly.
|
it directly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cv = (unsigned short) controller_val[tb->controller_number];
|
cv = (unsigned short) _controller_val[tb->controller_number];
|
||||||
|
|
||||||
if (controller_14bit[tb->controller_number]) {
|
if (_controller_14bit[tb->controller_number]) {
|
||||||
cv = ((tb->value << 7) | (cv & 0x7f));
|
cv = ((tb->value << 7) | (cv & 0x7f));
|
||||||
} else {
|
} else {
|
||||||
cv = tb->value;
|
cv = tb->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_val[tb->controller_number] = (controller_value_t)cv;
|
_controller_val[tb->controller_number] = (controller_value_t)cv;
|
||||||
|
|
||||||
} else if ((tb->controller_number >= 32 &&
|
} else if ((tb->controller_number >= 32 &&
|
||||||
tb->controller_number <= 63)) {
|
tb->controller_number <= 63)) {
|
||||||
|
|
||||||
cv = (unsigned short) controller_val[tb->controller_number];
|
cv = (unsigned short) _controller_val[tb->controller_number];
|
||||||
|
|
||||||
/* LSB for CC 0-31 arrived.
|
/* LSB for CC 0-31 arrived.
|
||||||
|
|
||||||
|
|
@ -183,20 +183,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
|
||||||
|
|
||||||
int cn = tb->controller_number - 32;
|
int cn = tb->controller_number - 32;
|
||||||
|
|
||||||
if (controller_14bit[cn] == false) {
|
if (_controller_14bit[cn] == false) {
|
||||||
controller_14bit[cn] = true;
|
_controller_14bit[cn] = true;
|
||||||
cv = (cv << 7) | (tb->value & 0x7f);
|
cv = (cv << 7) | (tb->value & 0x7f);
|
||||||
} else {
|
} else {
|
||||||
cv = (cv & 0x3f80) | (tb->value & 0x7f);
|
cv = (cv & 0x3f80) | (tb->value & 0x7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_val[tb->controller_number] =
|
_controller_val[tb->controller_number] =
|
||||||
(controller_value_t) cv;
|
(controller_value_t) cv;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* controller can only take 7 bit values */
|
/* controller can only take 7 bit values */
|
||||||
|
|
||||||
controller_val[tb->controller_number] =
|
_controller_val[tb->controller_number] =
|
||||||
(controller_value_t) tb->value;
|
(controller_value_t) tb->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,11 +204,11 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (tb->controller_number == 0) {
|
if (tb->controller_number == 0) {
|
||||||
bank_number = (unsigned short) controller_val[0];
|
_bank_number = (unsigned short) _controller_val[0];
|
||||||
if (port.input()) {
|
if (_port.input()) {
|
||||||
port.input()->bank_change (*port.input(), bank_number);
|
_port.input()->bank_change (*_port.input(), _bank_number);
|
||||||
port.input()->channel_bank_change[channel_number]
|
_port.input()->channel_bank_change[_channel_number]
|
||||||
(*port.input(), bank_number);
|
(*_port.input(), _bank_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,47 +218,47 @@ void
|
||||||
Channel::process_program_change (Parser &parser, byte val)
|
Channel::process_program_change (Parser &parser, byte val)
|
||||||
|
|
||||||
{
|
{
|
||||||
program_number = val;
|
_program_number = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::process_chanpress (Parser &parser, byte val)
|
Channel::process_chanpress (Parser &parser, byte val)
|
||||||
|
|
||||||
{
|
{
|
||||||
chanpress = val;
|
_chanpress = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::process_polypress (Parser &parser, EventTwoBytes *tb)
|
Channel::process_polypress (Parser &parser, EventTwoBytes *tb)
|
||||||
|
|
||||||
{
|
{
|
||||||
polypress[tb->note_number] = tb->value;
|
_polypress[tb->note_number] = tb->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::process_pitchbend (Parser &parser, pitchbend_t val)
|
Channel::process_pitchbend (Parser &parser, pitchbend_t val)
|
||||||
|
|
||||||
{
|
{
|
||||||
pitch_bend = val;
|
_pitch_bend = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Channel::process_reset (Parser &parser)
|
Channel::process_reset (Parser &parser)
|
||||||
|
|
||||||
{
|
{
|
||||||
reset ();
|
reset (0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a message to a channel.
|
/** Write a message to a channel.
|
||||||
* \return true if success
|
* \return true if success
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
Channel::channel_msg (byte id, byte val1, byte val2)
|
Channel::channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
unsigned char msg[3];
|
unsigned char msg[3];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
msg[0] = id | (channel_number & 0xf);
|
msg[0] = id | (_channel_number & 0xf);
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case off:
|
case off:
|
||||||
|
|
@ -302,5 +302,5 @@ Channel::channel_msg (byte id, byte val1, byte val2)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return port.midimsg (msg, len);
|
return _port.midimsg (msg, len, timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ Controllable::get_control_info (channel_t& chn, eventType& ev, byte& additional)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Controllable::send_midi_feedback (float val)
|
Controllable::send_midi_feedback (float val, timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
byte msg[3];
|
byte msg[3];
|
||||||
|
|
||||||
|
|
@ -320,6 +320,6 @@ Controllable::send_midi_feedback (float val)
|
||||||
msg[1] = control_additional;
|
msg[1] = control_additional;
|
||||||
msg[2] = (byte) (val * 127.0f);
|
msg[2] = (byte) (val * 127.0f);
|
||||||
|
|
||||||
port->write (msg, 3);
|
port->write (msg, 3, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,16 @@
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <midi++/types.h>
|
#include <midi++/types.h>
|
||||||
#include <midi++/factory.h>
|
#include <midi++/factory.h>
|
||||||
#include <midi++/nullmidi.h>
|
#include <midi++/nullmidi.h>
|
||||||
#include <midi++/fifomidi.h>
|
#include <midi++/fifomidi.h>
|
||||||
|
|
||||||
|
#ifdef WITH_JACK_MIDI
|
||||||
|
#include <midi++/jack.h>
|
||||||
|
#endif // WITH_JACK_MIDI
|
||||||
|
|
||||||
#ifdef WITH_ALSA
|
#ifdef WITH_ALSA
|
||||||
#include <midi++/alsa_sequencer.h>
|
#include <midi++/alsa_sequencer.h>
|
||||||
#include <midi++/alsa_rawmidi.h>
|
#include <midi++/alsa_rawmidi.h>
|
||||||
|
|
@ -35,13 +40,21 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MIDI;
|
using namespace MIDI;
|
||||||
|
|
||||||
|
// FIXME: void* data pointer, filthy
|
||||||
Port *
|
Port *
|
||||||
PortFactory::create_port (PortRequest &req)
|
PortFactory::create_port (PortRequest &req, void* data)
|
||||||
|
|
||||||
{
|
{
|
||||||
Port *port;
|
Port *port;
|
||||||
|
|
||||||
switch (req.type) {
|
switch (req.type) {
|
||||||
|
#ifdef WITH_JACK_MIDI
|
||||||
|
case Port::JACK_Midi:
|
||||||
|
assert(data != NULL);
|
||||||
|
port = new JACK_MidiPort (req, (jack_client_t*)data);
|
||||||
|
break;
|
||||||
|
#endif // WITH_JACK_MIDI
|
||||||
|
|
||||||
#ifdef WITH_ALSA
|
#ifdef WITH_ALSA
|
||||||
case Port::ALSA_RawMidi:
|
case Port::ALSA_RawMidi:
|
||||||
port = new ALSA_RawMidiPort (req);
|
port = new ALSA_RawMidiPort (req);
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,8 @@ using namespace MIDI;
|
||||||
Manager *Manager::theManager = 0;
|
Manager *Manager::theManager = 0;
|
||||||
|
|
||||||
Manager::Manager ()
|
Manager::Manager ()
|
||||||
|
: api_data(NULL)
|
||||||
{
|
{
|
||||||
inputPort = 0;
|
|
||||||
outputPort = 0;
|
|
||||||
inputChannelNumber = 0;
|
|
||||||
outputChannelNumber = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager ()
|
Manager::~Manager ()
|
||||||
|
|
@ -102,8 +98,7 @@ Manager::add_port (PortRequest &req)
|
||||||
/* modes must be different or complementary */
|
/* modes must be different or complementary */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port = factory.create_port (req, api_data);
|
||||||
port = factory.create_port (req);
|
|
||||||
|
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -122,18 +117,6 @@ Manager::add_port (PortRequest &req)
|
||||||
newpair.second = port;
|
newpair.second = port;
|
||||||
ports_by_device.insert (newpair);
|
ports_by_device.insert (newpair);
|
||||||
|
|
||||||
/* first port added becomes the default input
|
|
||||||
port.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (inputPort == 0) {
|
|
||||||
inputPort = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputPort == 0) {
|
|
||||||
outputPort = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,92 +137,6 @@ Manager::remove_port (string name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_input_port (string tag)
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if (tag == (*res).first) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inputPort = (*res).second;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_input_port (size_t portnum)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if ((*res).second->number() == portnum) {
|
|
||||||
inputPort = (*res).second;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_output_port (string tag)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if (tag == (*res).first) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX send a signal to say we're about to change output ports
|
|
||||||
|
|
||||||
if (outputPort) {
|
|
||||||
for (channel_t chan = 0; chan < 16; chan++) {
|
|
||||||
outputPort->channel (chan)->all_notes_off ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outputPort = (*res).second;
|
|
||||||
|
|
||||||
// XXX send a signal to say we've changed output ports
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Manager::set_output_port (size_t portnum)
|
|
||||||
|
|
||||||
{
|
|
||||||
PortMap::iterator res;
|
|
||||||
|
|
||||||
for (res = ports_by_tag.begin(); res != ports_by_tag.end(); res++) {
|
|
||||||
if ((*res).second->number() == portnum) {
|
|
||||||
outputPort = (*res).second;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
Manager::port (string name)
|
Manager::port (string name)
|
||||||
{
|
{
|
||||||
|
|
@ -372,3 +269,20 @@ Manager::parse_port_request (string str, Port::Type type)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::cycle_start(nframes_t nframes)
|
||||||
|
{
|
||||||
|
for (PortMap::iterator i = ports_by_device.begin();
|
||||||
|
i != ports_by_device.end(); i++)
|
||||||
|
(*i).second->cycle_start(nframes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::cycle_end()
|
||||||
|
{
|
||||||
|
for (PortMap::iterator i = ports_by_device.begin();
|
||||||
|
i != ports_by_device.end(); i++)
|
||||||
|
(*i).second->cycle_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ using namespace MIDI;
|
||||||
size_t Port::nports = 0;
|
size_t Port::nports = 0;
|
||||||
|
|
||||||
Port::Port (PortRequest &req)
|
Port::Port (PortRequest &req)
|
||||||
|
: _currently_in_cycle(false)
|
||||||
|
, _nframes_this_cycle(0)
|
||||||
{
|
{
|
||||||
_ok = false; /* derived class must set to true if constructor
|
_ok = false; /* derived class must set to true if constructor
|
||||||
succeeds.
|
succeeds.
|
||||||
|
|
@ -87,48 +88,28 @@ Port::~Port ()
|
||||||
* \return true on success.
|
* \return true on success.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
Port::clock ()
|
Port::clock (timestamp_t timestamp)
|
||||||
|
|
||||||
{
|
{
|
||||||
static byte clockmsg = 0xf8;
|
static byte clockmsg = 0xf8;
|
||||||
|
|
||||||
if (_mode != O_RDONLY) {
|
if (_mode != O_RDONLY) {
|
||||||
return midimsg (&clockmsg, 1);
|
return midimsg (&clockmsg, 1, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Port::selector_read_callback (Selectable *s, Select::Condition cond)
|
Port::cycle_start (nframes_t nframes)
|
||||||
|
|
||||||
{
|
{
|
||||||
byte buf[64];
|
_currently_in_cycle = true;
|
||||||
read (buf, sizeof (buf));
|
_nframes_this_cycle = nframes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Port::xforms_read_callback (int cond, int fd, void *ptr)
|
Port::cycle_end ()
|
||||||
|
|
||||||
{
|
{
|
||||||
byte buf[64];
|
_currently_in_cycle = false;
|
||||||
|
_nframes_this_cycle = 0;
|
||||||
((Port *)ptr)->read (buf, sizeof (buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Port::gtk_read_callback (void *ptr, int fd, int cond)
|
|
||||||
|
|
||||||
{
|
|
||||||
byte buf[64];
|
|
||||||
|
|
||||||
((Port *)ptr)->read (buf, sizeof (buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Port::write_callback (byte *msg, unsigned int len, void *ptr)
|
|
||||||
|
|
||||||
{
|
|
||||||
((Port *)ptr)->write (msg, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,10 @@ PortRequest::PortRequest (const string &xdev,
|
||||||
status = Unknown;
|
status = Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xtype == "ALSA/RAW" ||
|
if (xtype == "JACK" ||
|
||||||
|
xtype == "jack") {
|
||||||
|
type = Port::JACK_Midi;
|
||||||
|
} else if (xtype == "ALSA/RAW" ||
|
||||||
xtype == "alsa/raw") {
|
xtype == "alsa/raw") {
|
||||||
type = Port::ALSA_RawMidi;
|
type = Port::ALSA_RawMidi;
|
||||||
} else if (xtype == "ALSA/SEQUENCER" ||
|
} else if (xtype == "ALSA/SEQUENCER" ||
|
||||||
|
|
|
||||||
|
|
@ -265,17 +265,17 @@ BasicUI::smpte_frames_per_hour ()
|
||||||
void
|
void
|
||||||
BasicUI::smpte_time (jack_nframes_t where, SMPTE_t& smpte)
|
BasicUI::smpte_time (jack_nframes_t where, SMPTE_t& smpte)
|
||||||
{
|
{
|
||||||
session->smpte_time (where, *((SMPTE_Time *) &smpte));
|
session->smpte_time (where, *((SMPTE::Time *) &smpte));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicUI::smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const
|
BasicUI::smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const
|
||||||
{
|
{
|
||||||
session->smpte_to_sample (*((SMPTE_Time*)&smpte), sample, use_offset, use_subframes);
|
session->smpte_to_sample (*((SMPTE::Time*)&smpte), sample, use_offset, use_subframes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicUI::sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const
|
BasicUI::sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const
|
||||||
{
|
{
|
||||||
session->sample_to_smpte (sample, *((SMPTE_Time*)&smpte), use_offset, use_subframes);
|
session->sample_to_smpte (sample, *((SMPTE::Time*)&smpte), use_offset, use_subframes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_port->write (buf, (int32_t) (end - buf));
|
// FIXME
|
||||||
|
//_port->write (buf, (int32_t) (end - buf));
|
||||||
//cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n";
|
//cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue