a) fix special button press handling for solo+mute buttons
[ardour.git] / libs / ardour / session_midi.cc
index a8ed4bc0f7cd0d47f74adc5a3a51b72c5f8fd515..1ac7d9e300e2b3c57043c7e2c533781b21ed6207 100644 (file)
@@ -51,7 +51,7 @@ using namespace MIDI;
 MachineControl::CommandSignature MMC_CommandSignature;
 MachineControl::ResponseSignature MMC_ResponseSignature;
 
-MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 256);
+MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
 
 int
 Session::use_config_midi_ports ()
@@ -110,7 +110,7 @@ Session::set_midi_control (bool yn)
        poke_midi_thread ();
 
        if (_midi_port) {
-               LockMonitor lm (route_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
                for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
                        (*i)->reset_midi_control (_midi_port, midi_control);
                }
@@ -201,7 +201,7 @@ Session::set_mtc_port (string port_tag)
        MIDI::Port* port;
 
        if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
-               error << compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
+               error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
                return -1;
        }
 
@@ -478,7 +478,7 @@ Session::send_all_midi_feedback ()
 {
        if (midi_feedback) {
                // send out current state of all routes
-               LockMonitor lm (route_lock, __LINE__, __FILE__);
+               RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
                for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
                        (*i)->send_all_midi_feedback ();
                }
@@ -559,7 +559,7 @@ Session::midi_read (MIDI::Port* port)
                } else if (errno == EAGAIN) {
                        break;
                } else {
-                       fatal << compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
+                       fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
                        /*NOTREACHED*/
                }
        }
@@ -623,7 +623,7 @@ Session::mmc_record_strobe (MIDI::MachineControl &mmc)
                
                save_state ("", true);
                atomic_set (&_record_status, Enabled);
-               RecordEnabled (); /* EMIT SIGNAL */
+               RecordStateChanged (); /* EMIT SIGNAL */
                
                request_transport_speed (1.0);
 
@@ -637,7 +637,7 @@ void
 Session::mmc_record_exit (MIDI::MachineControl &mmc)
 {
        if (mmc_control) {
-               disable_record ();
+               disable_record (false);
        }
 }
 
@@ -803,19 +803,14 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
 {
        if (mmc_control) {
 
-               /* don't take route or diskstream lock: if using dynamic punch,
-                  this could cause a dropout. XXX is that really OK?
-                  or should we queue a rec-enable request?
-               */
-
-               size_t n;
                RouteList::iterator i;
-
-               for (n = 0, i = routes.begin(); i != routes.end(); ++i) {
+               RWLockMonitor (route_lock, false, __LINE__, __FILE__);
+               
+               for (i = routes.begin(); i != routes.end(); ++i) {
                        AudioTrack *at;
 
                        if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
-                               if (n++ == trk) {
+                               if (trk == at->remote_control_id()) {
                                        at->set_record_enable (enabled, &mmc);
                                        break;
                                }
@@ -915,6 +910,9 @@ Session::send_full_time_code ()
                }
        }
 
+       // Compensate for audio latency
+       outbound_mtc_smpte_frame += _worst_output_latency;
+
        next_quarter_frame_to_send = 0;
 
        // Sync slave to the same smpte time as we are on (except if negative, see above)
@@ -993,7 +991,7 @@ Session::send_midi_time_code ()
                        }                       
                        
                        if (_mtc_port->midimsg (mtc_msg, 2)) {
-                               error << compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno)) 
+                               error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno)) 
                                      << endmsg;
                                
                                return -1;
@@ -1012,6 +1010,8 @@ Session::send_midi_time_code ()
                                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;
                        }
                }
        }
@@ -1099,7 +1099,7 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
                LockMonitor lm (midi_lock, __LINE__, __FILE__);
 
                if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
-                       error << compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
+                       error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
                }
        }
 }
@@ -1201,17 +1201,17 @@ int
 Session::start_midi_thread ()
 {
        if (pipe (midi_request_pipe)) {
-               error << compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
+               error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
                return -1;
        }
 
        if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
-               error << compose(_("UI: cannot set O_NONBLOCK on "    "signal read pipe (%1)"), strerror (errno)) << endmsg;
+               error << string_compose(_("UI: cannot set O_NONBLOCK on "    "signal read pipe (%1)"), strerror (errno)) << endmsg;
                return -1;
        }
 
        if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
-               error << compose(_("UI: cannot set O_NONBLOCK on "    "signal write pipe (%1)"), strerror (errno)) << endmsg;
+               error << string_compose(_("UI: cannot set O_NONBLOCK on "    "signal write pipe (%1)"), strerror (errno)) << endmsg;
                return -1;
        }
 
@@ -1245,7 +1245,7 @@ Session::poke_midi_thread ()
        char c;
 
        if (write (midi_request_pipe[1], &c, 1) != 1) {
-               error << compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
+               error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
        }
 }
 
@@ -1272,7 +1272,7 @@ Session::midi_thread_work ()
        bool restart;
        vector<MIDI::Port*> ports;
 
-       PBD::ThreadCreated (pthread_self(), X_("MIDI"));
+       PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
 
        memset (&rtparam, 0, sizeof (rtparam));
        rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
@@ -1340,7 +1340,7 @@ Session::midi_thread_work ()
                                goto again;
                        }
 
-                       error << compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
+                       error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
 
                        break;
                }
@@ -1448,7 +1448,7 @@ Session::midi_thread_work ()
 
                for (int p = 1; p < nfds; ++p) {
                        if ((pfd[p].revents & ~POLLIN)) {
-                               // error << compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
+                               // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
                                break;
                        }
                        
@@ -1468,7 +1468,7 @@ Session::midi_thread_work ()
                                tmp = i;
                                ++tmp;
                                
-                               if (!(*i)) {
+                               if (!(*i)()) {
                                        midi_timeouts.erase (i);
                                }