Committed filthy mess of a working copy solely for moving between machines.
authorDavid Robillard <d@drobilla.net>
Thu, 8 Jun 2006 23:46:42 +0000 (23:46 +0000)
committerDavid Robillard <d@drobilla.net>
Thu, 8 Jun 2006 23:46:42 +0000 (23:46 +0000)
Nothing to see here, move along now...

git-svn-id: svn://localhost/trunk/ardour2midi@575 d708f5d6-7413-0410-9779-e7cbd77b26cf

51 files changed:
SConstruct
ardour.dox
gtk2_ardour/ardev_common.sh
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_rulers.cc
gtk2_ardour/main.cc
gtk2_ardour/mixer_strip.cc
libs/ardour/SConscript
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/session.h
libs/ardour/ardour/types.h
libs/ardour/audioengine.cc
libs/ardour/globals.cc
libs/ardour/mtc_slave.cc
libs/ardour/session.cc
libs/ardour/session_events.cc
libs/ardour/session_midi.cc
libs/ardour/session_process.cc
libs/ardour/session_state.cc
libs/ardour/session_time.cc
libs/ardour/session_transport.cc
libs/midi++2/SConscript
libs/midi++2/alsa_sequencer_midiport.cc
libs/midi++2/coremidi_midiport.cc
libs/midi++2/fd_midiport.cc
libs/midi++2/midi++/alsa_rawmidi.h
libs/midi++2/midi++/alsa_sequencer.h
libs/midi++2/midi++/channel.h
libs/midi++2/midi++/controllable.h
libs/midi++2/midi++/coremidi_midiport.h
libs/midi++2/midi++/factory.h
libs/midi++2/midi++/fd_midiport.h
libs/midi++2/midi++/manager.h
libs/midi++2/midi++/nullmidi.h
libs/midi++2/midi++/port.h
libs/midi++2/midi++/types.h
libs/midi++2/midichannel.cc
libs/midi++2/midicontrollable.cc
libs/midi++2/midifactory.cc
libs/midi++2/midimanager.cc
libs/midi++2/midiport.cc
libs/midi++2/port_request.cc
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/generic_midi/generic_midi_control_protocol.cc

index af89a24a2d963485e1a12ed3535a1fe6d6510683..fbe018d80cfaccc90325f3ae9ea8dbe51ba0e2c0 100644 (file)
@@ -11,6 +11,8 @@ import platform
 from sets import Set
 import SCons.Node.FS
 
+#import pickle
+
 SConsignFile()
 EnsureSConsVersion(0, 96)
 
@@ -459,7 +461,12 @@ libraries['dmalloc'] = conf.Finish ()
 
 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')
     env['SYSMIDI'] = 'ALSA Sequencer'
     subst_dict['%MIDITAG%'] = "seq"
@@ -587,6 +594,12 @@ Help(opts.GenerateHelpText(env))
 if os.environ.has_key('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'):
     env.Append(PKG_CONFIG_PATH = os.environ['PKG_CONFIG_PATH'])
 
@@ -859,7 +872,9 @@ for subdir in coredirs:
 for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
     for subdir in sublistdir:
         SConscript (subdir + '/SConscript')
-            
+
+#pickle.dump(env, open('.scons_env', 'w'), pickle.HIGHEST_PROTOCOL)
+
 # cleanup
 env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
 
index bd9d6a34dbc3e4344a6fa6671742769af2d2a127..ad694477c4df57afe265b1e03f89f5f97ffd3e33 100644 (file)
@@ -202,7 +202,7 @@ OPTIMIZE_OUTPUT_JAVA   = NO
 # func(std::string) {}). This also make the inheritance and collaboration 
 # 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 
 # 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 
 # 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 
 # 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) 
 # 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 
 # 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 
 # 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 
 # commands in the documentation.
 
-GENERATE_TODOLIST      = NO
+GENERATE_TODOLIST      = YES
 
 # The GENERATE_TESTLIST tag can be used to enable (YES) or 
 # 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 
 # commands in the documentation.
 
-GENERATE_BUGLIST       = NO
+GENERATE_BUGLIST       = YES
 
 # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
 # disable (NO) the deprecated list. This list is created by putting 
 # \deprecated commands in the documentation.
 
-GENERATE_DEPRECATEDLIST= NO
+GENERATE_DEPRECATEDLIST= YES
 
 # The ENABLED_SECTIONS tag can be used to enable conditional 
 # documentation sections, marked by \if sectionname ... \endif.
@@ -459,7 +459,7 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories 
 # 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 
 # 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 
 # 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 
 # available from the path. This tool is part of Graphviz, a graph visualization 
index a705101adb3a8f435610f2a3cd1b59120cf99eba..9483ae29719835522efb6043a8bd030f31289683 100755 (executable)
@@ -1,6 +1,6 @@
 #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
 
index 0e3f067b578e9ecf50125c049eb5bde84e6b3487..ac4f055df6ffb812da0291c6c5de4fc4db1e32f6 100644 (file)
@@ -81,16 +81,20 @@ style "time_axis_view_item_name"
 style "default_base" = "medium_text"
 {
   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[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[SELECTED] = { 0.80, 0.80, 0.80 }  
   
   bg[NORMAL] = { 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[SELECTED] = { 0, 0.40, 0.60 }
   
@@ -105,6 +109,13 @@ style "default_base" = "medium_text"
   base[PRELIGHT]     = { 0.20, 0.20, 0.20 }
   base[INSENSITIVE]  = "#4c5159"
   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"
@@ -131,11 +142,11 @@ style "black_mackie_menu_bar" = "medium_bold_text"
 style "default_buttons_menus" 
 {
   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[ACTIVE] = { 0.50, 1.0, 1.0 }
-  bg[PRELIGHT] = { 0.15, 0.15, 0.15 }
+  bg[NORMAL] = { 0.35, 0.35, 0.35 }
+  bg[ACTIVE] = "#565690"
+  bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
   bg[INSENSITIVE] = { 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"
 {
        bg[ACTIVE] = { 0.50, 1.0, 0.50 }
+       fg[ACTIVE] = { 0, 0, 0 }
 }
 
 style "transport_rec_button"
@@ -853,8 +865,8 @@ style "region_list_whole_file"
 
 style "ardour_button" ="default_buttons_menus"
 {
-       xthickness = 0
-       ythickness = 2
+       xthickness = 1
+       ythickness = 1
 }
 
 #---------------------------------------------------------------
index 3baa9ede185a6d8e4a026a9fe12829b137a6d452..146d4d2ffe85ed22d2a409873d726704a9b2dbbc 100644 (file)
@@ -409,7 +409,7 @@ If you still wish to quit, please use the\n\n\
                        break;
                }
        }
-
+       Config->save_state();
        quit ();
 }
 
index 826823885c1d727ca66b1f869af905a834701580..dbdcd6ae4582dc97800efd814689ab2e6c1ffbf5 100644 (file)
@@ -39,24 +39,48 @@ using namespace ARDOUR;
 void
 ARDOUR_UI::setup_config_options ()
 {
+       std::vector<Glib::ustring> groups;
+       groups.push_back("options");
+       groups.push_back("Editor");
+       
        struct { 
            char* name;
            bool (Configuration::*method)(void) const;
+           char act_type;  // (t)oggle or (r)adio
        } options[] = {
-               { "ToggleTimeMaster", &Configuration::get_jack_time_master },
-               { "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport },
-               { "LatchedRecordEnable", &Configuration::get_latched_record_enable },
-               { "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture },
-               { "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun },
-               { "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end },
-               { 0, 0 }
+               { "ToggleTimeMaster", &Configuration::get_jack_time_master, 't' },
+               { "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport, 't' },
+               { "LatchedRecordEnable", &Configuration::get_latched_record_enable, 't' },
+               { "VerifyRemoveLastCapture", &Configuration::get_verify_remove_last_capture, 't' },
+               { "StopRecordingOnXrun", &Configuration::get_stop_recording_on_xrun, 't' },
+               { "StopTransportAtEndOfSession", &Configuration::get_stop_at_session_end, 't' },
+               { "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) {
-               Glib::RefPtr<Action> act = ActionManager::get_action ("options", options[n].name);
-               if (act) {
-                       Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
-                       tact->set_active ((Config->*(options[n].method))());
+               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) {
+                               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))());
+                               continue;
+                       }
                }
        }
 }
@@ -230,12 +254,14 @@ ARDOUR_UI::toggle_editing_space()
 void
 ARDOUR_UI::toggle_UseHardwareMonitoring()
 {
-       Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseSoftwareMonitoring");
+       Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseHardwareMonitoring");
        if (act) {
                Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               cerr << "get_active() cond = " << tact->get_active() << endl;//DEBUG
                if (tact->get_active()) {
                        Config->set_use_hardware_monitoring (true);
                        Config->set_use_sw_monitoring (false);
+                       Config->set_use_external_monitoring (false);
                        if (session) {
                                session->reset_input_monitor_state();
                        }
@@ -252,6 +278,7 @@ ARDOUR_UI::toggle_UseSoftwareMonitoring()
                if (tact->get_active()) {
                        Config->set_use_hardware_monitoring (false);
                        Config->set_use_sw_monitoring (true);
+                       Config->set_use_external_monitoring (false);
                        if (session) {
                                session->reset_input_monitor_state();
                        }
@@ -268,6 +295,7 @@ ARDOUR_UI::toggle_UseExternalMonitoring()
                if (tact->get_active()) {
                        Config->set_use_hardware_monitoring (false);
                        Config->set_use_sw_monitoring (false);
+                       Config->set_use_external_monitoring (true);
                        if (session) {
                                session->reset_input_monitor_state();
                        }
index 506b082b53538a25f7db7260775893e69080a12b..cd974891204c3bc7f7e6edb7e877e5d82c2ff6ae 100644 (file)
@@ -435,7 +435,7 @@ void
 AudioClock::set_smpte (jack_nframes_t when, bool force)
 {
        char buf[32];
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        
        if (is_duration) {
                session->smpte_duration (when, smpte);
@@ -1259,7 +1259,7 @@ AudioClock::smpte_frame_from_display () const
                return 0;
        }
        
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        jack_nframes_t sample;
        
        smpte.hours = atoi (hours_label.get_text());
@@ -1280,19 +1280,19 @@ AudioClock::smpte_frame_from_display () const
 #define SMPTE_SAMPLE_TEST_7
 
        // Testcode for smpte<->sample conversions (P.S.)
-       SMPTE_Time smpte1;
+       SMPTE::Time smpte1;
        jack_nframes_t sample1;
        jack_nframes_t oldsample = 0;
-       SMPTE_Time smpte2;
+       SMPTE::Time smpte2;
        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
        // Test 1: use_offset = false, use_subframes = false
        cout << "use_offset = false, use_subframes = false" << endl;
        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 */ );
 
                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;
                }
                oldsample = sample1;
-               session->smpte_increment( smpte1 );
+               SMPTE::increment( smpte1 );
        }
 
        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;
 
        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 */ );
 
 //     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;
                }
                oldsample = sample1;
-               session->smpte_increment( smpte1 );
+               SMPTE::increment( smpte1 );
        }
 
        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;
 
        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 */ );
 
 //     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;
                }
                oldsample = sample1;
-               session->smpte_decrement( smpte1 );
+               SMPTE::decrement( smpte1 );
        }
 
        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;
     
                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 */ );
       
                        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;
                        }
                        oldsample = sample1;
-                       session->smpte_increment( smpte1 );
+                       SMPTE::increment( smpte1 );
                }
     
                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;
 
                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 */ );
       
                        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;
                        }
                        oldsample = sample1;
-                       session->smpte_decrement( smpte1 );
+                       SMPTE::decrement( smpte1 );
                }
     
                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;
 
        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 */ );
 
 //     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;
                }
                oldsample = sample1;
-               session->smpte_increment_seconds( smpte1 );
+               SMPTE::increment_seconds( smpte1 );
        }
 
        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;
 
        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 */ );
 
 //     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;
                }
                oldsample = sample1;
-               session->smpte_increment_minutes( smpte1 );
+               SMPTE::increment_minutes( smpte1 );
        }
 
        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;
 
        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 */ );
 
 //     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;
                }
                oldsample = sample1;
-               session->smpte_increment_hours( smpte1 );
+               SMPTE::increment_hours( smpte1 );
        }
 
        cout << "sample_increment: " << sample_increment << endl;
index 6d834ef7a4b90b1033ce9b6c2a0600b9fe1f1eca..307cd71799462f049a4ccf624b2bae83ba1d9e0b 100644 (file)
@@ -296,7 +296,7 @@ class Editor : public PublicEditor
        void toggle_waveforms_while_recording ();
        void toggle_measure_visibility ();
 
-       void set_meter_falloff (float);
+       void set_meter_falloff (int);
        void set_meter_hold (int32_t);
 
        /* xfades */
index 161d015583db38f31a1328b0b46b93b97394047d..d88cda61e64ef85c7b5237238d9ed472a435ed1b 100644 (file)
@@ -371,13 +371,13 @@ Editor::register_actions ()
            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_("MeterFalloffSlowest"), _("Slowest"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.266f)); 
-       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_("MeterFalloffMedium"), _("Medium"), bind (mem_fun (*this, &Editor::set_meter_falloff), 0.7f));
-       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_("MeterFalloffFaster"), _("Faster"), bind (mem_fun (*this, &Editor::set_meter_falloff), 1.5f));
-       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_("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), 1)); 
+       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), 3));
+       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), 5));
+       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_("MeterHoldShort"), _("Short"), bind (mem_fun (*this, &Editor::set_meter_hold), 40));
index 1409da77a9f04404205efa320a588d300667275d..bca0942841cba936257b7770cefe1b7fe0c6feb1 100644 (file)
@@ -3417,7 +3417,7 @@ void
 Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xpos, double ypos) 
 {
        char buf[128];
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        BBT_Time bbt;
        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) 
 {
        char buf[128];
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        BBT_Time sbbt;
        BBT_Time ebbt;
        float secs;
index bccdce27c18e3ea613f1b4e93e87c5ef5247bd75..acf205d06f926e2b1c56dae7ac31e0ea5273a1d2 100644 (file)
@@ -93,14 +93,78 @@ Editor::redo (uint32_t n)
 void
 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) {
                session->set_meter_hold (cnt);
        }
 }
 
 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) {
                session->set_meter_falloff (val);
        }
index 1fe4e0711cad625dc3cee7957d329d8f61d2f98a..d3a1e9670b98d7c7b332034e392ccb580155ae33 100644 (file)
@@ -24,6 +24,7 @@
 #include <string>
 
 #include <ardour/tempo.h>
+#include <ardour/smpte.h>
 #include <gtkmm2ext/gtk_ui.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 spacer;
        jack_nframes_t fr;
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        gchar buf[16];
        gint nmarks = 0;
        gint n;
@@ -927,13 +928,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
                        (*marks)[n].position = pos;
 
                        // Increment subframes by one
-                       session->smpte_increment_subframes( smpte );
+                       SMPTE::increment_subframes( smpte );
                }
        } else if (show_seconds) {
                // Find smpte time of this sample (pos)
                session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
                // Go to next whole second down
-               session->smpte_seconds_floor( smpte );
+               SMPTE::seconds_floor( smpte );
 
                for (n = 0; n < nmarks; n++) {
                        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);
-                       session->smpte_increment_seconds( smpte );
+                       SMPTE::increment_seconds( smpte );
                }
        } else if (show_minutes) {
                // Find smpte time of this sample (pos)
                session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
                // Go to next whole minute down
-               session->smpte_minutes_floor( smpte );
+               SMPTE::minutes_floor( smpte );
 
                for (n = 0; n < nmarks; n++) {
                        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].position = pos;
-                       session->smpte_increment_minutes( smpte );
+                       SMPTE::increment_minutes( smpte );
                }
        } else if (show_hours) {
                // Find smpte time of this sample (pos)
                session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
                // Go to next whole hour down
-               session->smpte_hours_floor( smpte );
+               SMPTE::hours_floor( smpte );
 
                for (n = 0; n < nmarks; n++) {
                        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].position = pos;
 
-                       session->smpte_increment_hours( smpte );
+                       SMPTE::increment_hours( smpte );
                }
        } else { // show_frames
                // Find smpte time of this sample (pos)
                session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
                // Go to next whole frame down
-               session->smpte_frames_floor( smpte );
+               SMPTE::frames_floor( smpte );
 
                for (n = 0; n < nmarks; n++) {
                        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);
-                       session->smpte_increment( smpte );
+                       SMPTE::increment( smpte );
                }
        }
   
index b4eb2df9e90d7f2176f46958056651fe139a5f85..20630e4f1cb3cb4fad3b2e6cb428340d73f42306 100644 (file)
@@ -251,8 +251,10 @@ which_ui_rcfile ()
        
        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;
+       } else {
+               cerr << "Loading ui configuration file " << rcfile << endl;
        }
-
+       
        return rcfile;
 }
 
index 2e4c3a6ae791d6dbe7067e2ef75f0707703113a5..9bdc8c340aa025601d1026f72b7cea0b390ccc68 100644 (file)
@@ -414,14 +414,14 @@ MixerStrip::set_width (Width w)
                set_size_request (-1, -1);
                xml_node->add_property ("strip_width", "wide");
 
-               rec_enable_button->set_label (_("Record"));
-               mute_button->set_label  (_("Mute"));
-               solo_button->set_label (_("Solo"));
+               rec_enable_button->set_label (_("record"));
+               mute_button->set_label  (_("mute"));
+               solo_button->set_label (_("solo"));
 
                if (_route.comment() == "") {
-                      comment_button.set_label (_("Comments"));
+                      comment_button.set_label (_("comments"));
                } 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()));
index 93593bad188023b5c75215c165f17375bf328bb0..a9d5daab1d501bb00ec5c0eff108285e10d1b934 100644 (file)
@@ -93,6 +93,7 @@ tempo.cc
 utils.cc
 version.cc
 mix.cc
+smpte.cc
 """)
 
 arch_specific_objects = [ ]
index 9a45fd3c7cf12d5719b84409223cf3e025a85f60..85c78970260fb91e063044e89bcd6408b903dc0c 100644 (file)
@@ -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_main_outs, "mute-affects-main-outs", 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, trace_midi_input, "trace-midi-input", 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, use_sw_monitoring, "use-sw-monitoring", true)
 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, 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(uint32_t, osc_port, "osc-port", 3819)
 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 */
 
index 0d968fcff109fb665a1d6647d0fd7bdc0347ed50..189cf77ac9eb4587fdf043b7fa9a48475388565a 100644 (file)
@@ -585,24 +585,13 @@ class Session : public sigc::trackable, public Stateful
 
        void bbt_time (jack_nframes_t when, BBT_Time&);
 
-       ARDOUR::smpte_wrap_t smpte_increment( SMPTE_Time& smpte ) const;
-       ARDOUR::smpte_wrap_t smpte_decrement( SMPTE_Time& smpte ) const;
-       ARDOUR::smpte_wrap_t smpte_increment_subframes( SMPTE_Time& smpte ) const;
-       ARDOUR::smpte_wrap_t smpte_decrement_subframes( SMPTE_Time& smpte ) const;
-       ARDOUR::smpte_wrap_t smpte_increment_seconds( SMPTE_Time& smpte ) const;
-       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_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_string (char *, jack_nframes_t) const;
 
        void           set_smpte_offset (jack_nframes_t);
@@ -1271,7 +1260,7 @@ class Session : public sigc::trackable, public Stateful
        void remove_empty_sounds ();
 
        void setup_midi_control ();
-       int  midi_read (MIDI::Port *);
+       //int  midi_read (MIDI::Port *);
 
        void enable_record ();
        
@@ -1297,13 +1286,13 @@ class Session : public sigc::trackable, public Stateful
        void *do_work();
 
        void set_next_event ();
-       void process_event (Event *);
+       void process_event (Event *ev);
 
        /* MIDI Machine Control */
 
        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_data (MIDI::Port* port, MIDI::byte*, int32_t size);
+       //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 spp_start (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 midi_msg[16];
        jack_nframes_t  outbound_mtc_smpte_frame;
-       SMPTE_Time transmitting_smpte_time;
+       SMPTE::Time transmitting_smpte_time;
        int next_quarter_frame_to_send;
        
        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;
        bool _smpte_offset_negative;
        
-       /* cache the most-recently requested time conversions.
-          this helps when we have multiple clocks showing the
-          same time (e.g. the transport frame)
-       */
-
-       bool       last_smpte_valid;
-       jack_nframes_t  last_smpte_when;
-       SMPTE_Time last_smpte;
+       /* cache the most-recently requested time conversions. This helps when we
+        * have multiple clocks showing the same time (e.g. the transport frame) */
+       bool           last_smpte_valid;
+       jack_nframes_t last_smpte_when;
+       SMPTE::Time    last_smpte;
+       
+       bool _send_smpte_update; ///< Send a full MTC timecode this cycle
 
-       int send_full_time_code ();
-       int send_midi_time_code ();
+       int send_full_time_code(jack_nframes_t nframes);
+       int send_midi_time_code_for_cycle(jack_nframes_t nframes);
 
-       void send_full_time_code_in_another_thread ();
-       void send_midi_time_code_in_another_thread ();
-       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);
        
@@ -1417,17 +1402,17 @@ class Session : public sigc::trackable, public Stateful
            static MultiAllocSingleReleasePool pool;
        };
 
-       PBD::Lock       midi_lock;
-       pthread_t       midi_thread;
-       int             midi_request_pipe[2];
+       //PBD::Lock       midi_lock;
+       //pthread_t       midi_thread;
+       //int             midi_request_pipe[2];
        atomic_t        butler_active;
-       RingBuffer<MIDIRequest*> midi_requests;
-
+       //RingBuffer<MIDIRequest*> midi_requests;
+/*
        int           start_midi_thread ();
        void          terminate_midi_thread ();
        void          poke_midi_thread ();
        static void *_midi_thread_work (void *arg);
-       void          midi_thread_work ();
+       void          midi_thread_work ();*/
        void          change_midi_ports ();
        int           use_config_midi_ports ();
 
index 3d7ab4b59a35be30d89187b9da92d56c9b053c8e..9cfe9d3a278eb6eca0b4e1ff3625b7905d3ca286 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <inttypes.h>
 #include <jack/types.h>
+#include <ardour/smpte.h>
 #include <map>
 
 #if __GNUC__ < 3
@@ -99,33 +100,6 @@ namespace ARDOUR {
                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 {
            uint32_t bars;
            uint32_t beats;
@@ -164,7 +138,7 @@ namespace ARDOUR {
 
            Type type;
 
-           SMPTE_Time     smpte;
+           SMPTE::Time    smpte;
            BBT_Time       bbt;
 
            union { 
index 9d736f765e27430bd9ab0a63b13eae7d6701e566..a0cf29eb89a730549ee90a7d59379012e09a436a 100644 (file)
@@ -212,6 +212,7 @@ AudioEngine::_graph_order_callback (void *arg)
        return 0;
 }
 
+/** @callgraph */
 int
 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;
 }
 
+/** @callgraph */
 int
 AudioEngine::process_callback (jack_nframes_t nframes)
 {
index 4879e373d5ffed2b80210c4823bd1a45d49157d5..82310b356448da718605b02b57a5a52084223b9e 100644 (file)
@@ -40,6 +40,7 @@
 #include <midi++/mmc.h>
 
 #include <ardour/ardour.h>
+#include <ardour/audioengine.h>
 #include <ardour/audio_library.h>
 #include <ardour/configuration.h>
 #include <ardour/plugin_manager.h>
@@ -91,7 +92,7 @@ setup_osc ()
 }
 
 static int 
-setup_midi ()
+setup_midi (AudioEngine& engine)
 {
        std::map<string,Configuration::MidiPortDescriptor*>::iterator i;
        int nports;
@@ -101,6 +102,8 @@ setup_midi ()
                return 0;
        }
 
+       MIDI::Manager::instance()->set_api_data(engine.jack());
+
        for (i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) {
                Configuration::MidiPortDescriptor* port_descriptor;
 
@@ -112,7 +115,9 @@ setup_midi ()
                                           port_descriptor->type);
 
                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;
                }
                
@@ -163,12 +168,15 @@ setup_midi ()
        if (default_mmc_port == 0) {
                warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name()) 
                        << endmsg;
-               return 0;
+               //return 0;
        } 
 
        if (default_mtc_port == 0) {
                warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name()) 
                        << endmsg;
+       } else {
+               // [DR]
+               warning << "MTC port available" << endl;
        }
 
        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);
 
-       if (setup_midi ()) {
+       if (setup_midi (engine)) {
                return -1;
        }
 
index cb35c0c7858eef717b6a557af931ce8fb04c9a24..c1f87bf36d5944e922f90c7e66ce8075ee301fca 100644 (file)
@@ -87,7 +87,7 @@ void
 MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
 {
        jack_nframes_t now = session.engine().frame_time();
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
        
        smpte.hours = msg[3];
        smpte.minutes = msg[2];
index a8ab2204dc4aabcd0a855484af1e42d489389a39..569060fe65633057d16c8ef81fba69c81fad5980 100644 (file)
@@ -247,7 +247,8 @@ Session::Session (AudioEngine &eng,
          _mtc_port (default_mtc_port),
          _midi_port (default_midi_port),
          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)
 {
        bool new_session;
@@ -294,7 +295,7 @@ Session::Session (AudioEngine &eng,
          _mtc_port (default_mtc_port),
          _midi_port (default_midi_port),
          pending_events (2048),
-         midi_requests (16),
+         //midi_requests (16),
          main_outs (0)
 
 {
@@ -360,7 +361,7 @@ Session::~Session ()
        going_away (); /* EMIT SIGNAL */
        
        terminate_butler_thread ();
-       terminate_midi_thread ();
+       //terminate_midi_thread ();
        
        if (click_data && click_data != default_click) {
                delete [] click_data;
@@ -1250,7 +1251,8 @@ Session::enable_record ()
        if (atomic_read (&_record_status) != Recording) {
                atomic_set (&_record_status, Recording);
                _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) {
                        /* 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) {
                        /* Even though this can be called from RT context we are using
@@ -1346,7 +1349,8 @@ Session::maybe_enable_record ()
                        enable_record ();
                } 
        } else {
-               send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
+               // FIXME
+               //send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
                RecordStateChanged (); /* EMIT SIGNAL */
        }
 
index 2aeace81f4317d1d14df567237047c34d4904c44..5687e3f733ed583f9feea4c963f23f5faa88c521 100644 (file)
@@ -120,6 +120,7 @@ Session::queue_event (Event* ev)
        }
 }
 
+/* [DR] Always called from audio thread? */
 void
 Session::merge_event (Event* ev)
 {
@@ -171,10 +172,10 @@ Session::merge_event (Event* ev)
        set_next_event ();
 }
 
+/** @return true when @a ev is deleted. */
 bool
 Session::_replace_event (Event* ev)
 {
-       // returns true when we deleted the passed in event
        bool ret = false;
        Events::iterator i;
 
@@ -203,10 +204,10 @@ Session::_replace_event (Event* ev)
        return ret;
 }
 
+/** @return true when @a ev is deleted. */
 bool
 Session::_remove_event (Session::Event* ev)
 {
-       // returns true when we deleted the passed in event
        bool ret = false;
        Events::iterator i;
        
@@ -310,6 +311,9 @@ Session::process_event (Event* ev)
                return;
        }
 
+       // FIXME [DR]
+       printf("Processing event: %s\n", event_names[ev->type]);
+
        switch (ev->type) {
        case Event::SetLoop:
                set_auto_loop (ev->yes_or_no);
@@ -323,6 +327,7 @@ Session::process_event (Event* ev)
                        // cerr << "soft locate to " << ev->target_frame << endl;
                        start_locate (ev->target_frame, false, true, false);
                }
+               _send_smpte_update = true;
                break;
 
        case Event::LocateRoll:
@@ -333,6 +338,7 @@ Session::process_event (Event* ev)
                        // cerr << "soft locate to+roll " << ev->target_frame << endl;
                        start_locate (ev->target_frame, true, true, false);
                }
+               _send_smpte_update = true;
                break;
 
        case Event::SetTransportSpeed:
index aa079f88278e4b9070ccc77e7116d6b4c94a2a58..95d6d02f39cc052682e0fa29d38fc927d0acc5c8 100644 (file)
@@ -40,6 +40,7 @@
 #include <ardour/diskstream.h>
 #include <ardour/slave.h>
 #include <ardour/cycles.h>
+#include <ardour/smpte.h>
 
 #include "i18n.h"
 
@@ -87,6 +88,7 @@ Session::use_config_midi_ports ()
 void
 Session::set_mmc_control (bool yn)
 {
+#if 0
        if (mmc_control == yn) {
                return;
        }
@@ -94,13 +96,14 @@ Session::set_mmc_control (bool yn)
        mmc_control = yn;
        set_dirty();
        poke_midi_thread ();
-       
+#endif
        ControlChanged (MMCControl); /* EMIT SIGNAL */
 }
 
 void
 Session::set_midi_control (bool yn)
 {
+#if 0
        if (midi_control == yn) {
                return;
        }
@@ -115,7 +118,7 @@ Session::set_midi_control (bool yn)
                        (*i)->reset_midi_control (_midi_port, midi_control);
                }
        }
-
+#endif
        ControlChanged (MidiControl); /* EMIT SIGNAL */
 }
 
@@ -468,7 +471,7 @@ void
 Session::setup_midi_control ()
 {
        outbound_mtc_smpte_frame = 0;
-       next_quarter_frame_to_send = -1;
+       next_quarter_frame_to_send = 0;
 
        /* setup the MMC buffer */
        
@@ -508,6 +511,7 @@ Session::setup_midi_control ()
        }
 }
 
+#if 0
 int
 Session::midi_read (MIDI::Port* port)
 {
@@ -545,6 +549,7 @@ Session::midi_read (MIDI::Port* port)
 
        return 0;
 }
+#endif
 
 void
 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;
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
 
        smpte.hours = mmc_tc[0] & 0xf;
        smpte.minutes = mmc_tc[1];
@@ -798,76 +803,43 @@ 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
 Session::change_midi_ports ()
 {
+/*
        MIDIRequest* request = new MIDIRequest;
 
        request->type = MIDIRequest::PortChange;
        midi_requests.write (&request, 1);
        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
-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];
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
+
+       _send_smpte_update = false;
 
        if (_mtc_port == 0 || !send_mtc) {
                return 0;
        }
-
+       
        // Get smpte time for this transport frame
        sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
 
        // Check for negative smpte time and prepare for quarter frame transmission
+       assert(!smpte.negative); // this shouldn't happen
        if (smpte.negative) {
                // Negative mtc is not defined, so sync slave to smpte zero.
                // 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;
                if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
                        // 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;
                }
        }
@@ -907,42 +879,87 @@ Session::send_full_time_code ()
        msg[7] = smpte.seconds;
        msg[8] = smpte.frames;
 
-       {
-               LockMonitor lm (midi_lock, __LINE__, __FILE__);
-    
-               if (_mtc_port->midimsg (msg, sizeof (msg))) {
-                       error << _("Session: could not send full MIDI time code") << endmsg;
-                       
-                       return -1;
-               }
+       // Send message at offset 0, sent time is for the start of this cycle
+       if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
+               error << _("Session: could not send full MIDI time code") << endmsg;
+               return -1;
        }
 
        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
-Session::send_midi_time_code ()
-{
-       if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) )  {
-               return 0;
-       }
+Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
+{      
+       //cerr << "----------------------" << endl;
 
-       jack_nframes_t two_smpte_frames_duration;
-       jack_nframes_t quarter_frame_duration;
+       // FIXME: remove, just for debug print statement
+       static jack_nframes_t last_time = 0;
 
-       /* Duration of two smpte frames */
-       two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
+       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;
+       }
+       
        /* 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;
+       
+       // 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 );
+       
 
-       while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
+#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))) {
 
-               // Send quarter frames up to current time
-               {
-                       LockMonitor lm (midi_lock, __LINE__, __FILE__);
+               //cerr << "B: Next frame to send: " << next_quarter_frame_to_send << endl;
 
-                       switch(next_quarter_frame_to_send) {
+               switch (next_quarter_frame_to_send) {
                        case 0:
                                mtc_msg[1] =  0x00 | (transmitting_smpte_time.frames & 0xf);
                                break;
@@ -967,40 +984,56 @@ Session::send_midi_time_code ()
                        case 7:
                                mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
                                break;
-                       }                       
-                       
-                       if (_mtc_port->midimsg (mtc_msg, 2)) {
-                               error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno)) 
-                                     << endmsg;
-                               
-                               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;
-
-                       // Increment quarter frame counter
-                       next_quarter_frame_to_send++;
-      
-                       if (next_quarter_frame_to_send >= 8) {
-                               // Wrap quarter frame counter
-                               next_quarter_frame_to_send = 0;
-                               // Increment smpte time twice
-                               smpte_increment( transmitting_smpte_time );
-                               smpte_increment( transmitting_smpte_time );        
-                               // 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;
-                       }
+               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)) 
+                               << endmsg;
+                       return -1;
+               }
+
+               /*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
+               next_quarter_frame_to_send++;
+
+               if (next_quarter_frame_to_send >= 8) {
+                       // Wrap quarter frame counter
+                       next_quarter_frame_to_send = 0;
+                       // Increment smpte time twice
+                       SMPTE::increment( transmitting_smpte_time );
+                       SMPTE::increment( transmitting_smpte_time );        
+                       // Re-calculate timing of first quarter frame
+                       //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
+                       outbound_mtc_smpte_frame += _worst_output_latency;
                }
        }
+
        return 0;
 }
 
 /***********************************************************************
  OUTBOUND MMC STUFF
 **********************************************************************/
-
+/*
 void
 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);
        poke_midi_thread ();
 }
-
+*/
 void
 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
 {
+#if 0
        using namespace MIDI;
        int nbytes = 4;
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
 
        if (_mmc_port == 0 || !send_mmc) {
                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;
                }
        }
+#endif
+       cout << "MMC support broken." << endl;
 }
 
 bool
@@ -1117,7 +1153,7 @@ void
 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
 {
        // in another thread, really
-       
+       /*
        MIDIRequest* request = new MIDIRequest;
 
        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);
        poke_midi_thread ();
+       */
 }
 
 void
 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
 {
        // in another thread, really
-       
+       /*
        MIDIRequest* request = new MIDIRequest;
 
        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);
        poke_midi_thread ();
+       */
 }
 
+#if 0
 void
 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;
 }
+#endif
+
 
 /*---------------------------------------------------------------------------
   MIDI THREAD 
   ---------------------------------------------------------------------------*/
 
+#if 0
 int
 Session::start_midi_thread ()
 {
@@ -1456,6 +1498,7 @@ Session::midi_thread_work ()
                }
        }
 }
+#endif
 
 bool
 Session::get_mmc_control () const
index 3280a5f4bb49ec81940e2580be30dfc5771f3c7d..bbd35a9055d799515c55a8554f59e25f204fcc35 100644 (file)
@@ -38,6 +38,8 @@
 #include <ardour/cycles.h>
 #include <ardour/cycle_timer.h>
 
+#include <midi++/manager.h>
+
 #include "i18n.h"
 
 using namespace ARDOUR;
@@ -47,6 +49,10 @@ using namespace std;
 void
 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 ( _engine.transport_state() == AudioEngine::TransportRolling) {
                        actually_start_transport ();
@@ -60,6 +66,10 @@ Session::process (jack_nframes_t nframes)
        } 
        
        (this->*process_function) (nframes);
+       
+       MIDI::Manager::instance()->cycle_end();
+       
+       cerr << "CYCLE END " << _transport_frame << "-----------------------" << endl;
 }
 
 void
@@ -77,6 +87,8 @@ Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
        int ret = 0;
        bool declick = get_transport_declick_required();
 
+       cerr << "[DR] no_roll\n";
+
        if (_click_io) {
                _click_io->silence (nframes, offset);
        }
@@ -237,16 +249,19 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
        }
 }
 
+
 void
 Session::process_with_events (jack_nframes_t nframes)
 {
-       Event* ev;
+       Event*         ev;
        jack_nframes_t this_nframes;
        jack_nframes_t end_frame;
        jack_nframes_t offset;
-       bool session_needs_butler = false;
        jack_nframes_t stop_limit;
        long           frames_moved;
+       bool           session_needs_butler = false;
+
+       cerr << "[DR] with events" << endl;
 
        if (auditioner) {
                auditioner->silence (nframes, 0);
@@ -267,6 +282,13 @@ Session::process_with_events (jack_nframes_t nframes)
                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()) {
                no_roll (nframes, 0);
                return;
@@ -400,17 +422,11 @@ Session::process_with_events (jack_nframes_t nframes)
 
        } /* implicit release of route lock */
 
-
-       if (session_needs_butler) {
+       if (session_needs_butler)
                summon_butler ();
-       } 
        
-       if (!_engine.freewheeling() && send_mtc) {
-               send_midi_time_code_in_another_thread ();
-       }
-
-       return;
-}              
+       send_midi_time_code_for_cycle(nframes);
+}
 
 void
 Session::reset_slave_state ()
@@ -725,6 +741,8 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
 void
 Session::process_without_events (jack_nframes_t nframes)
 {
+       cerr << "[DR] without events" << endl;
+
        bool session_needs_butler = false;
        jack_nframes_t stop_limit;
        long frames_moved;
@@ -788,16 +806,11 @@ Session::process_without_events (jack_nframes_t nframes)
 
        } /* implicit release of route lock */
 
-       if (session_needs_butler) {
-               summon_butler ();
-       } 
-       
-       if (!_engine.freewheeling() && send_mtc) {
-               send_midi_time_code_in_another_thread ();
-       }
+       send_midi_time_code_for_cycle(nframes);
 
-       return;
-}              
+       if (session_needs_butler)
+               summon_butler ();
+}
 
 void
 Session::process_audition (jack_nframes_t nframes)
index eaadec0fd3aefea5316a6eb021d1693c0f404624..602ac943149fc845080a1a36035c40e4112bce43 100644 (file)
@@ -150,7 +150,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        state_was_pending = false;
        set_next_event ();
        outbound_mtc_smpte_frame = 0;
-       next_quarter_frame_to_send = -1;
+       next_quarter_frame_to_send = 0;
        current_block_size = 0;
        _solo_latched = true;
        _solo_model = InverseMute;
@@ -297,9 +297,11 @@ Session::second_stage_init (bool new_session)
                return -1;
        }
 
+       /* FIXME
        if (start_midi_thread ()) {
                return -1;
        }
+       */
 
        if (state_tree) {
                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));
        }
 
-       send_full_time_code ();
+       // FIXME
+       //send_full_time_code ();
        _engine.transport_locate (0);
-       deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
-       deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
+       //deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
+       //deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
 
        ControlProtocolManager::instance().set_session (*this);
 
index e3badc5b114b0cf448d32eddc4bf42a609ad9671..453f5d6d27452853a18c4d3b27d9e8c175dd8c54 100644 (file)
@@ -63,18 +63,22 @@ Session::set_smpte_type (float fps, bool drop_frames)
        switch ((int) ceil (fps)) {
        case 24:
                mtc_smpte_bits = 0;
+               SMPTE::Time::default_rate = SMPTE::MTC_24_FPS;
                break;
 
        case 25:
                mtc_smpte_bits = 0x20;
+               SMPTE::Time::default_rate = SMPTE::MTC_25_FPS;
                break;
 
        case 30:
        default:
                if (drop_frames) {
                        mtc_smpte_bits = 0x40;
+                       SMPTE::Time::default_rate = SMPTE::MTC_30_FPS_DROP;
                } else {
                        mtc_smpte_bits =  0x60;
+                       SMPTE::Time::default_rate = SMPTE::MTC_30_FPS;
                }
                break;
        };
@@ -102,377 +106,9 @@ Session::set_smpte_offset_negative (bool neg)
        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
-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) {
                // 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
-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;
   
@@ -649,7 +285,7 @@ Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_off
 }
 
 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) {
                smpte = last_smpte;
@@ -664,7 +300,7 @@ Session::smpte_time (jack_nframes_t when, SMPTE_Time& smpte)
 }
 
 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) {
                smpte = last_smpte;
@@ -679,7 +315,7 @@ Session::smpte_time_subframes (jack_nframes_t when, SMPTE_Time& smpte)
 }
 
 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 */ );
 }
@@ -687,14 +323,14 @@ Session::smpte_duration (jack_nframes_t when, SMPTE_Time& smpte) const
 void
 Session::smpte_duration_string (char* buf, jack_nframes_t when) const
 {
-       SMPTE_Time smpte;
+       SMPTE::Time smpte;
 
        smpte_duration (when, smpte);
        snprintf (buf, sizeof (buf), "%02ld:%02ld:%02ld:%02ld", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
 }
 
 void
-Session::smpte_time (SMPTE_Time &t)
+Session::smpte_time (SMPTE::Time &t)
 
 {
        smpte_time (_transport_frame, t);
index 6e756b28b7bc08e2cdb5bf32bff5a4f79cc6e542..313e56ed2049c3f876ec0c9e582778ea6f69351d 100644 (file)
@@ -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
        }
@@ -383,9 +384,11 @@ Session::non_realtime_stop (bool abort)
 
        last_stop_frame = _transport_frame;
 
-       send_full_time_code ();
+       /* FIXME
+       send_full_time_code();
        deliver_mmc (MIDI::MachineControl::cmdStop, 0);
        deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
+       */
 
        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;
+       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)) {
                /* 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;
+
+       _send_smpte_update = true;
 }
 
 void
@@ -875,11 +889,28 @@ Session::actually_start_transport ()
                (*i)->realtime_set_speed ((*i)->speed(), true);
        }
 
+       /* FIXME
        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 */
 }
 
+/** Do any transport work in the audio thread that needs to be done after the
+ * transport thread is finished.  Audio thread, realtime safe.
+ */
 void
 Session::post_transport ()
 {
@@ -910,6 +941,18 @@ Session::post_transport ()
        set_next_event ();
 
        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
index 7c3267a6c7d6728ab6d62711839a0bff707a0332..5230bfc391a2dec726670f9ed398d411cde87875 100644 (file)
@@ -30,18 +30,24 @@ version.cc
 """)
 
 sysdep_sources = Split ("""
+jack_midiport.cc
 alsa_sequencer_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' ]
    midi2.Append (CCFLAGS="-DWITH_COREMIDI")
    midi2.Append (LINKFLAGS="-framework CoreMIDI")
    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="-DLIBSIGC_DISABLE_DEPRECATED")
index fca6707efdacbbad72c06b1e3a9a8123f6ec9df4..1a758b275dfc714aed8066eecaa5e81a1a036a34 100644 (file)
@@ -79,7 +79,7 @@ int ALSA_SequencerMidiPort::selectable () const
        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 ();
        int R;
@@ -118,7 +118,7 @@ int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen)
        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();
        int err;
index 8d1d927b7b89b57d2a27a8a4aea2da36a7fa5d0a..2cd98239ece74b4edb2aae7ec5e81f6c26c93d35 100644 (file)
@@ -56,7 +56,7 @@ void CoreMidi_MidiPort::Close ()
        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;
     MIDIPacketList* pktlist = (MIDIPacketList*)midi_buffer;
index 2ced63c25915293bb7e86d991c5c02c1ca54ae5b..ef387e7c49745cf477baf06ebd7bbd11ea5267f2 100644 (file)
@@ -151,7 +151,7 @@ FD_MidiPort::do_slow_write (byte *msg, unsigned int msglen)
 }
 
 int
-FD_MidiPort::read (byte* buf, size_t max)
+FD_MidiPort::read (byte* buf, size_t max, timestamp_t timestamp)
 {
        int nread;
        
index 655b673174362de0adcd30f50a439c7b7eb2e065..f6c17541c20edeb51655d6f2d44550fc22b78e44 100644 (file)
@@ -29,6 +29,8 @@
 #include <midi++/port.h>
 #include <midi++/fd_midiport.h>
 
+namespace MIDI {
+
 class ALSA_RawMidiPort : public MIDI::FD_MidiPort
 
 {
@@ -38,6 +40,7 @@ class ALSA_RawMidiPort : public MIDI::FD_MidiPort
        virtual ~ALSA_RawMidiPort () {}
 };
 
+} // namespace MIDI
 
 #endif // __alsa_rawmidi_h__
 
index 8ddb2a7dd7539011962a6e8df475b741d700a9db..cb02ed961c0ad1df9f471fe5ad1f1709747f2ee4 100644 (file)
@@ -44,9 +44,8 @@ class ALSA_SequencerMidiPort : public Port
 
   protected:
        /* Direct I/O */
-       
-       int write (byte *msg, size_t msglen);   
-       int read (byte *buf, size_t max);
+       int write (byte *msg, size_t msglen, timestamp_t timestamp);    
+       int read (byte *buf, size_t max, timestamp_t timestamp);
 
   private:
        snd_seq_t *seq;
index f534f7e6dac8da770ca79630f444f5f98b9210ad..0d24bf8bbe8128bb9a2131b7065ecf28fdff8b91 100644 (file)
@@ -32,17 +32,22 @@ namespace MIDI {
 
 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 {
 
   public:
        Channel (byte channel_number, Port &);
 
-       Port &midi_port()               { return port; }
-       byte channel()                  { return channel_number; }
-       byte program()                  { return program_number; }
-       byte bank()                     { return bank_number; }
-       byte pressure ()                { return chanpress; }
-       byte poly_pressure (byte n)     { return polypress[n]; }
+       Port &midi_port()               { return _port; }
+       byte channel()                  { return _channel_number; }
+       byte program()                  { return _program_number; }
+       byte bank()                     { return _bank_number; }
+       byte pressure ()                { return _chanpress; }
+       byte poly_pressure (byte n)     { return _polypress[n]; }
 
        byte last_note_on () { 
                return _last_note_on;
@@ -58,53 +63,52 @@ class Channel : public sigc::trackable {
        }
 
        pitchbend_t pitchbend () { 
-               return pitch_bend;
+               return _pitch_bend;
        }
 
        controller_value_t controller_value (byte n) { 
-               return controller_val[n%128];
+               return _controller_val[n%128];
        }
 
        controller_value_t *controller_addr (byte n) {
-               return &controller_val[n%128];
+               return &_controller_val[n%128];
        }
 
        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 all_notes_off () {
-               return channel_msg (MIDI::controller, 123, 0);
+       bool channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp);
+       bool all_notes_off (timestamp_t timestamp) {
+               return channel_msg (MIDI::controller, 123, 0, timestamp);
        }
        
-       bool control (byte id, byte value) {
-               return channel_msg (MIDI::controller, id, value);
+       bool control (byte id, byte value, timestamp_t timestamp) {
+               return channel_msg (MIDI::controller, id, value, timestamp);
        }
        
-       bool note_on (byte note, byte velocity) {
-               return channel_msg (MIDI::on, note, velocity);
+       bool note_on (byte note, byte velocity, timestamp_t timestamp) {
+               return channel_msg (MIDI::on, note, velocity, timestamp);
        }
        
-       bool note_off (byte note, byte velocity) {
-               return channel_msg (MIDI::off, note, velocity);
+       bool note_off (byte note, byte velocity, timestamp_t timestamp) {
+               return channel_msg (MIDI::off, note, velocity, timestamp);
        }
        
-       bool aftertouch (byte value) {
-               return channel_msg (MIDI::chanpress, value, 0);
+       bool aftertouch (byte value, timestamp_t timestamp) {
+               return channel_msg (MIDI::chanpress, value, 0, timestamp);
        }
 
-       bool poly_aftertouch (byte note, byte value) {
-               return channel_msg (MIDI::polypress, note, value);
+       bool poly_aftertouch (byte note, byte value, timestamp_t timestamp) {
+               return channel_msg (MIDI::polypress, note, value, timestamp);
        }
 
-       bool program_change (byte value) {
-               return channel_msg (MIDI::program, value, 0);
+       bool program_change (byte value, timestamp_t timestamp) {
+               return channel_msg (MIDI::program, value, 0, timestamp);
        }
 
-       bool pitchbend (byte msb, byte lsb) {
-               return channel_msg (MIDI::pitchbend, lsb, msb);
+       bool pitchbend (byte msb, byte lsb, timestamp_t timestamp) {
+               return channel_msg (MIDI::pitchbend, lsb, msb, timestamp);
        }
 
   protected:
@@ -113,34 +117,33 @@ class Channel : public sigc::trackable {
        void connect_output_signals ();
 
   private:
-       Port &port;
+       Port & _port;
 
        /* Current channel values */
-
-       byte     channel_number;
-        byte     bank_number;
-       byte     program_number;
-       byte     rpn_msb;
-       byte     rpn_lsb;
-       byte     nrpn_msb;
-       byte     nrpn_lsb;
-       byte     chanpress;
-       byte     polypress[128];
-       bool         controller_14bit[128];
-       controller_value_t  controller_val[128];
-       byte     controller_msb[128];
-       byte     controller_lsb[128];
-       byte     _last_note_on;
-       byte     _last_on_velocity;
-       byte     _last_note_off;
-       byte     _last_off_velocity;
-       pitchbend_t  pitch_bend;
-       bool         _omni;
-       bool         _poly;
-       bool         _mono;
-       size_t       _notes_on;
-
-       void reset (bool notes_off = true);
+       byte               _channel_number;
+       byte               _bank_number;
+       byte               _program_number;
+       byte               _rpn_msb;
+       byte               _rpn_lsb;
+       byte               _nrpn_msb;
+       byte               _nrpn_lsb;
+       byte               _chanpress;
+       byte               _polypress[128];
+       bool               _controller_14bit[128];
+       controller_value_t _controller_val[128];
+       byte               _controller_msb[128];
+       byte               _controller_lsb[128];
+       byte               _last_note_on;
+       byte               _last_on_velocity;
+       byte               _last_note_off;
+       byte               _last_off_velocity;
+       pitchbend_t        _pitch_bend;
+       bool               _omni;
+       bool               _poly;
+       bool               _mono;
+       size_t             _notes_on;
+
+       void reset (timestamp_t timestamp, nframes_t nframes, bool notes_off = true);
        
        void process_note_off (Parser &, EventTwoBytes *);
        void process_note_on (Parser &, EventTwoBytes *);
index 3fa108bb4692590fc5a4da74baa185ea2dc9b8f0..44249cfa4f0e85a863d064d65b8efcc40955698e 100644 (file)
@@ -60,7 +60,7 @@ class Controllable : public sigc::trackable
        
        std::string control_description() const { return _control_description; }
 
-       void send_midi_feedback (float);
+       void send_midi_feedback (float val, timestamp_t timestamp);
        
   private:
        bool             bistate;
index e02a22578492cf34d34c19b80bd0a6d1c92910b7..046b170bce93b81a0dfd71e1398d635db3120244 100644 (file)
 
 namespace MIDI {
 
-    class CoreMidi_MidiPort:public Port {
-      public:
-       CoreMidi_MidiPort(PortRequest & req);
-       virtual ~ CoreMidi_MidiPort();
+class CoreMidi_MidiPort:public Port {
+       public:
+               CoreMidi_MidiPort(PortRequest & req);
+               virtual ~ CoreMidi_MidiPort();
 
-       virtual int selectable() const {
-           return -1;
-       }
-      protected:
-       /* Direct I/O */
-       int write(byte * msg, size_t msglen);
-       int read(byte * buf, size_t max) {
-           return 0;
-       } /* CoreMidi callback */
-           static void read_proc(const MIDIPacketList * pktlist,
-                                 void *refCon, void *connRefCon);
+               virtual int selectable() const {
+                       return -1;
+               }
+       protected:
+               /* Direct I/O */
+               int write (byte *msg, size_t msglen, timestamp_t timestamp);    
+               int read (byte *buf, size_t max, timestamp_t timestamp);
 
-      private:
-       byte midi_buffer[1024];
-       MIDIClientRef midi_client;
-       MIDIEndpointRef midi_destination;
-       MIDIEndpointRef midi_source;
+               /* CoreMidi callback */
+               static void read_proc(const MIDIPacketList * pktlist,
+                               void *refCon, void *connRefCon);
 
-       int Open(PortRequest & req);
-       void Close();
-       static MIDITimeStamp MIDIGetCurrentHostTime();
+       private:
+               byte midi_buffer[1024];
+               MIDIClientRef midi_client;
+               MIDIEndpointRef midi_destination;
+               MIDIEndpointRef midi_source;
 
-       bool firstrecv;
-    };
+               int Open(PortRequest & req);
+               void Close();
+               static MIDITimeStamp MIDIGetCurrentHostTime();
+
+               bool firstrecv;
+};
 
 }; /* namespace MIDI */
 
index 1543f68cdc7c7dbbc78afc66eee6ab71847fdc48..3fa57b667681f7a4e901f875da6a59f326701a35 100644 (file)
@@ -29,7 +29,7 @@ namespace MIDI {
 
 class PortFactory {
   public:
-       Port *create_port (PortRequest &req);
+       Port *create_port (PortRequest &req, void* data);
        
        static void add_port_request (std::vector<PortRequest *> &reqs,
                                      const std::string &reqstr);
index 853af9d7b4eb7507750f24b9f6fc8f2e5c866954..e84dc47794bd5b2a2b1fbccc9fce5bb2359666fa 100644 (file)
@@ -53,7 +53,10 @@ class FD_MidiPort : public Port
        int _fd;
        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;
                
                if ((_mode & O_ACCMODE) == O_RDONLY) {
@@ -80,7 +83,8 @@ class FD_MidiPort : public Port
                return nwritten;
        }
 
-       virtual int read (byte *buf, size_t max);
+       virtual int read (byte *buf, size_t max,
+                         timestamp_t timestamp);
 
   private:
        static std::string *midi_dirpath;
index 4889aad8c92bb6e4c0d312ebd79c5fb854debe07..ddf5c0f8cd827a865b37b902e9f45ecf40524116 100644 (file)
 
 namespace MIDI {
 
+/** Creates, stores, and manages system MIDI ports.
+ */
 class Manager {
   public:
        ~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 &);
        int   remove_port (std::string port);
 
@@ -41,20 +58,6 @@ class Manager {
 
        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 *), 
                          void *arg);
 
@@ -80,6 +83,8 @@ class Manager {
        PortMap         ports_by_device; /* canonical */
        PortMap         ports_by_tag;    /* may contain duplicate Ports */
 
+       void *api_data;
+
        void close_ports ();
 };
 
index a94b1015b092df417d27ae83c2bb95c80b207bec..04c7d438bfda7c5e42c3bca84ed142a0f2831140 100644 (file)
@@ -46,11 +46,12 @@ class Null_MidiPort : public Port
 
        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;
        }
 
-       virtual int read (byte *buf, size_t max) {
+       int read (byte *buf, size_t max, timestamp_t timestamp) {
                return 0;
        }
        
index 442cc4e5ed88a720a543651013501859bd6e246c..919afb3755688d3172d9bd46e6c0ca78ff057e34 100644 (file)
@@ -37,6 +37,7 @@ class Port : public sigc::trackable {
   public:
        enum Type {
                Unknown,
+               JACK_Midi,
                ALSA_RawMidi,
                ALSA_Sequencer,
                CoreMidi_MidiPort,
@@ -44,42 +45,64 @@ class Port : public sigc::trackable {
                FIFO,
        };
 
-
        Port (PortRequest &);
        virtual ~Port ();
 
-       /* Direct I/O */
+       // 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);
 
-       /** \return number of bytes successfully written */
-       virtual int write (byte *msg, size_t msglen) = 0;       
+       /* Only for use by MidiManager.  Don't ever call this. */
+       virtual void cycle_end();
 
-       /** \return number of bytes successfully written to \a buf */
-       virtual int read (byte *buf, size_t max) = 0;
+       /* Direct I/O */
+       
+       /** Read a message from port.
+        * @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;
+       
+       /** Write a message to port.
+        * @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);
+       }
 
-       /** Slow down I/O to a loop of single byte emissions
-          interspersed with a busy loop of 10000 * this value.
+       bool clock (timestamp_t timestamp);
 
-          This may be ignored by a particular instance of this virtual
-          class. See FD_MidiPort for an example of where it used.  */
+       /** Slow down I/O to a loop of single byte emissions
+         * interspersed with a busy loop of 10000 * this value.
+         *
+         * This may be ignored by a particular instance of this virtual
+         * class. See FD_MidiPort for an example of where it used. */
        void set_slowdown (size_t n) { slowdown = n; }
 
        /* 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;
 
-       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) { 
                return _channel[chn&0x7F];
        }
        
-       Parser *input()     { return input_parser; }
-       Parser *output()    { return output_parser; }
+       Parser *input()  { return input_parser; }
+       Parser *output() { return output_parser; }
 
        void iostat (int *written, int *read, 
                     const size_t **in_counts,
@@ -99,47 +122,31 @@ 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 ();
        
        const char *device () const { return _devname.c_str(); }
-       const char *name () const   { return _tagname.c_str(); }
-       Type   type () const        { return _type; }
-       int    mode () const        { return _mode; }
-       bool   ok ()   const        { return _ok; }
-       size_t number () const      { return _number; }
+       const char *name ()   const { return _tagname.c_str(); }
+       Type        type ()   const { return _type; }
+       int         mode ()   const { return _mode; }
+       bool        ok ()     const { return _ok; }
+       size_t      number () const { return _number; }
 
   protected:
-       bool _ok;
-       Type _type;
-       std::string _devname;
-       std::string _tagname;
-       int _mode;
-       size_t _number;
-       Channel *_channel[16];
+       bool             _ok;
+       bool             _currently_in_cycle;
+       nframes_t        _nframes_this_cycle;
+       Type             _type;
+       std::string      _devname;
+       std::string      _tagname;
+       int              _mode;
+       size_t           _number;
+       Channel          *_channel[16];
        sigc::connection thru_connection;
-       unsigned int bytes_written;
-       unsigned int bytes_read;
-       Parser *input_parser;
-       Parser *output_parser;
-       size_t slowdown;
+       unsigned int     bytes_written;
+       unsigned int     bytes_read;
+       Parser           *input_parser;
+       Parser           *output_parser;
+       size_t           slowdown;
 
   private:
        static size_t nports;
index b9d9bf33e7c4d6f7abb5e3bee7395e41f9a8f0ae..dc70381d5b7a5f127da42db87eeef0bcf1ebda13 100644 (file)
@@ -4,9 +4,11 @@
 namespace MIDI {
 
        typedef char           channel_t;
-       typedef float controller_value_t;
+       typedef float          controller_value_t;
        typedef unsigned char  byte;
        typedef unsigned short pitchbend_t;
+       typedef unsigned int   timestamp_t;
+       typedef unsigned int   nframes_t;
 
        enum eventType {
            none = 0x0,
index 42949591fe4b379aac29934a6eb1023e2234307c..fe4f4afeb2be4ded28364dfd555e79b5eaf9ae1b 100644 (file)
 using namespace sigc;
 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
 Channel::connect_input_signals ()
 
 {
-       port.input()->channel_pressure[channel_number].connect
+       _port.input()->channel_pressure[_channel_number].connect
                (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));
-       port.input()->channel_note_off[channel_number].connect
+       _port.input()->channel_note_off[_channel_number].connect
                (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));
-       port.input()->channel_program_change[channel_number].connect
+       _port.input()->channel_program_change[_channel_number].connect
                (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));
-       port.input()->channel_pitchbend[channel_number].connect
+       _port.input()->channel_pitchbend[_channel_number].connect
                (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
 Channel::connect_output_signals ()
 
 {
-       port.output()->channel_pressure[channel_number].connect
+       _port.output()->channel_pressure[_channel_number].connect
                (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));
-       port.output()->channel_note_off[channel_number].connect
+       _port.output()->channel_note_off[_channel_number].connect
                (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));
-       port.output()->channel_program_change[channel_number].connect
+       _port.output()->channel_program_change[_channel_number].connect
                (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));
-       port.output()->channel_pitchbend[channel_number].connect
+       _port.output()->channel_pitchbend[_channel_number].connect
                (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
-Channel::reset (bool notes_off)
+Channel::reset (timestamp_t timestamp, nframes_t nframes, bool notes_off)
 {
-       program_number = channel_number;
-       bank_number = 0;
-       pitch_bend = 0;
+       _program_number = _channel_number;
+       _bank_number = 0;
+       _pitch_bend = 0;
 
        _last_note_on = 0;
        _last_note_off = 0;
@@ -87,25 +87,25 @@ Channel::reset (bool notes_off)
        _last_off_velocity = 0;
 
        if (notes_off) {
-               all_notes_off ();
+               all_notes_off (timestamp);
        }
 
-       memset (polypress, 0, sizeof (polypress));
-       memset (controller_msb, 0, sizeof (controller_msb));
-       memset (controller_lsb, 0, sizeof (controller_lsb));
+       memset (_polypress, 0, sizeof (_polypress));
+       memset (_controller_msb, 0, sizeof (_controller_msb));
+       memset (_controller_lsb, 0, sizeof (_controller_lsb));
        
        /* 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++) {
-               controller_14bit[n] = false;
+               _controller_14bit[n] = false;
        }
 
-       rpn_msb = 0;
-       rpn_lsb = 0;
-       nrpn_msb = 0;
-       nrpn_lsb = 0;
+       _rpn_msb = 0;
+       _rpn_lsb = 0;
+       _nrpn_msb = 0;
+       _nrpn_lsb = 0;
 
        _omni = true;
        _poly = false;
@@ -155,20 +155,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
                   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));
                } else {
                        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 && 
                    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. 
 
@@ -183,20 +183,20 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
 
                int cn = tb->controller_number - 32;
                   
-               if (controller_14bit[cn] == false) {
-                       controller_14bit[cn] = true;
+               if (_controller_14bit[cn] == false) {
+                       _controller_14bit[cn] = true;
                        cv = (cv << 7) | (tb->value & 0x7f);
                } else {
                        cv = (cv & 0x3f80) | (tb->value & 0x7f);
                }
 
-               controller_val[tb->controller_number] = 
+               _controller_val[tb->controller_number] = 
                        (controller_value_t) cv;
        } else {
 
                /* controller can only take 7 bit values */
                
-               controller_val[tb->controller_number] = 
+               _controller_val[tb->controller_number] = 
                        (controller_value_t) tb->value;
        }
 
@@ -204,11 +204,11 @@ Channel::process_controller (Parser &parser, EventTwoBytes *tb)
         */
 
        if (tb->controller_number == 0) {
-               bank_number = (unsigned short) controller_val[0];
-               if (port.input()) {
-                       port.input()->bank_change (*port.input(), bank_number);
-                       port.input()->channel_bank_change[channel_number] 
-                               (*port.input(), bank_number);
+               _bank_number = (unsigned short) _controller_val[0];
+               if (_port.input()) {
+                       _port.input()->bank_change (*_port.input(), _bank_number);
+                       _port.input()->channel_bank_change[_channel_number] 
+                               (*_port.input(), _bank_number);
                }
        }
 
@@ -218,47 +218,47 @@ void
 Channel::process_program_change (Parser &parser, byte val) 
 
 {
-       program_number = val;
+       _program_number = val;
 }
 
 void
 Channel::process_chanpress (Parser &parser, byte val) 
 
 {
-       chanpress = val;
+       _chanpress = val;
 }
 
 void
 Channel::process_polypress (Parser &parser, EventTwoBytes *tb) 
 
 {
-       polypress[tb->note_number] = tb->value;
+       _polypress[tb->note_number] = tb->value;
 }
 
 void
 Channel::process_pitchbend (Parser &parser, pitchbend_t val) 
 
 {
-       pitch_bend = val;
+       _pitch_bend = val;
 }
 
 void
 Channel::process_reset (Parser &parser) 
 
 {
-       reset ();
+       reset (0, 1);
 }
 
 /** Write a message to a channel.
  * \return true if success
  */
 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];
        int len = 0;
 
-       msg[0] = id | (channel_number & 0xf);
+       msg[0] = id | (_channel_number & 0xf);
 
        switch (id) {
        case off:
@@ -302,5 +302,5 @@ Channel::channel_msg (byte id, byte val1, byte val2)
                break;
        }
 
-       return port.midimsg (msg, len);
+       return _port.midimsg (msg, len, timestamp);
 }
index f17782f3c4a2bcd8a36c760a8049a715f221c315..24bc38125500d7352fad5a6875b7b75aa8304cd9 100644 (file)
@@ -308,7 +308,7 @@ Controllable::get_control_info (channel_t& chn, eventType& ev, byte& additional)
 
 
 void
-Controllable::send_midi_feedback (float val)
+Controllable::send_midi_feedback (float val, timestamp_t timestamp)
 {
        byte msg[3];
 
@@ -320,6 +320,6 @@ Controllable::send_midi_feedback (float val)
        msg[1] = control_additional;
        msg[2] = (byte) (val * 127.0f);
 
-       port->write (msg, 3);
+       port->write (msg, 3, timestamp);
 }
 
index 38baada2042ae547f5b8d28d364018b801ef31ef..d8119e362eefcddfc6af3f5e39145298f856b9bc 100644 (file)
     $Id$
 */
 
+#include <cassert>
 #include <midi++/types.h>
 #include <midi++/factory.h>
 #include <midi++/nullmidi.h>
 #include <midi++/fifomidi.h>
 
+#ifdef WITH_JACK_MIDI
+#include <midi++/jack.h>
+#endif // WITH_JACK_MIDI
+
 #ifdef WITH_ALSA
 #include <midi++/alsa_sequencer.h>
 #include <midi++/alsa_rawmidi.h>
 using namespace std;
 using namespace MIDI;
 
+// FIXME: void* data pointer, filthy
 Port *
-PortFactory::create_port (PortRequest &req)
+PortFactory::create_port (PortRequest &req, void* data)
 
 {
        Port *port;
        
        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
        case Port::ALSA_RawMidi:
                port = new ALSA_RawMidiPort (req);
index 7b3ed7d336d07beb6f99634540ff325c7155be2a..bcdcddf7a4c754b01baf2ba37611c0f11422e9ac 100644 (file)
@@ -33,12 +33,8 @@ using namespace MIDI;
 Manager *Manager::theManager = 0;
 
 Manager::Manager () 
-      
+       : api_data(NULL)
 {
-       inputPort = 0;
-       outputPort = 0;
-       inputChannelNumber = 0;
-       outputChannelNumber = 0;
 }
 
 Manager::~Manager ()
@@ -102,8 +98,7 @@ Manager::add_port (PortRequest &req)
                /* modes must be different or complementary */
        }
                        
-       
-       port = factory.create_port (req);
+       port = factory.create_port (req, api_data);
        
        if (port == 0) {
                return 0;
@@ -122,18 +117,6 @@ Manager::add_port (PortRequest &req)
        newpair.second = port;
        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;
 }
 
@@ -154,92 +137,6 @@ Manager::remove_port (string name)
        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 *
 Manager::port (string name)
 {
@@ -372,3 +269,20 @@ Manager::parse_port_request (string str, Port::Type type)
 
        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();
+}
+
index a7c4ba09401f6ea333f0092321c041dbe670b6f3..7f31b909d377f985b71471e03abc1cf195040847 100644 (file)
@@ -32,7 +32,8 @@ using namespace MIDI;
 size_t Port::nports = 0;
 
 Port::Port (PortRequest &req)
-
+       : _currently_in_cycle(false)
+       , _nframes_this_cycle(0)
 {
        _ok = false;  /* derived class must set to true if constructor
                         succeeds.
@@ -87,48 +88,28 @@ Port::~Port ()
  * \return true on success.
  */
 bool
-Port::clock ()
-       
+Port::clock (timestamp_t timestamp)
 {
        static byte clockmsg = 0xf8;
        
        if (_mode != O_RDONLY) {
-               return midimsg (&clockmsg, 1);
+               return midimsg (&clockmsg, 1, timestamp);
        }
        
        return false;
 }
 
 void
-Port::selector_read_callback (Selectable *s, Select::Condition cond) 
-
-{
-       byte buf[64];
-       read (buf, sizeof (buf));
-}
-
-void
-Port::xforms_read_callback (int cond, int fd, void *ptr) 
-
-{
-       byte buf[64];
-       
-       ((Port *)ptr)->read (buf, sizeof (buf));
-}
-
-void
-Port::gtk_read_callback (void *ptr, int fd, int cond)
-
+Port::cycle_start (nframes_t nframes)
 {
-       byte buf[64];
-       
-       ((Port *)ptr)->read (buf, sizeof (buf));
+       _currently_in_cycle = true;
+       _nframes_this_cycle = nframes;
 }
 
 void
-Port::write_callback (byte *msg, unsigned int len, void *ptr)
-       
+Port::cycle_end ()
 {
-       ((Port *)ptr)->write (msg, len);
+       _currently_in_cycle = false;
+       _nframes_this_cycle = 0;
 }
 
index d081bdb570c2690bdf836808f73138de0a80e4cb..d209f02574d8ba59b46dbfe3410b160cd0bd3fc4 100644 (file)
@@ -36,7 +36,7 @@ PortRequest::PortRequest (const string &xdev,
        
        devname = strdup (xdev.c_str());
        tagname = strdup (xtag.c_str());
-
+       
        if (xmode == "output" ||
            xmode == "out" || 
            xmode == "OUTPUT" ||
@@ -58,7 +58,10 @@ PortRequest::PortRequest (const string &xdev,
                status = Unknown;
        }
 
-       if (xtype == "ALSA/RAW" ||
+       if (xtype == "JACK" ||
+                  xtype == "jack") {
+               type = Port::JACK_Midi;
+       } else if (xtype == "ALSA/RAW" ||
                   xtype == "alsa/raw") {
                type = Port::ALSA_RawMidi;
        } else if (xtype == "ALSA/SEQUENCER" ||
index 8cf157c26c7c698a205108d4b36ea434bdf40fa8..27133ba94cbd12d5d1939e7fb2e62a3b215f1213 100644 (file)
@@ -265,17 +265,17 @@ BasicUI::smpte_frames_per_hour ()
 void
 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 
 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 
 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);
 }
index 95b9d223931d0f3fc1a25589081922efea6b1556..fd669314abcb7f3dad2cf68f5ded6f84ec9afc2d 100644 (file)
@@ -58,7 +58,8 @@ GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes)
                        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";
        }
 }