Merge branch 'master' into cairocanvas
[ardour.git] / libs / backends / jack / jack_audiobackend.cc
index 397ba0e49884dd93b20605e74805b52e8f224d30..1ceb794dc569558bf41224b9f9f33fc26dc21321 100644 (file)
@@ -155,11 +155,11 @@ JACKAudioBackend::enumerate_devices () const
 }
 
 vector<float>
-JACKAudioBackend::available_sample_rates (const string& /*device*/) const
+JACKAudioBackend::available_sample_rates (const string& device) const
 {
        vector<float> f;
        
-       if (available()) {
+       if (device == _target_device && available()) {
                f.push_back (sample_rate());
                return f;
        }
@@ -183,11 +183,11 @@ JACKAudioBackend::available_sample_rates (const string& /*device*/) const
 }
 
 vector<uint32_t>
-JACKAudioBackend::available_buffer_sizes (const string& /*device*/) const
+JACKAudioBackend::available_buffer_sizes (const string& device) const
 {
        vector<uint32_t> s;
-       
-       if (available()) {
+               
+       if (device == _target_device && available()) {
                s.push_back (buffer_size());
                return s;
        }
@@ -409,6 +409,12 @@ JACKAudioBackend::interleaved () const
        return false;
 }
 
+string
+JACKAudioBackend::midi_option () const
+{
+       return _target_midi_option;
+}
+
 uint32_t
 JACKAudioBackend::input_channels () const
 {
@@ -465,7 +471,7 @@ JACKAudioBackend::raw_buffer_size(DataType t)
 }
 
 void
-JACKAudioBackend::setup_jack_startup_command ()
+JACKAudioBackend::setup_jack_startup_command (bool for_latency_measurement)
 {
        /* first we map the parameters that have been set onto a
         * JackCommandLineOptions object.
@@ -499,10 +505,11 @@ JACKAudioBackend::setup_jack_startup_command ()
 
        string cmdline;
 
-       if (!get_jack_command_line_string (options, cmdline)) {
+       if (!get_jack_command_line_string (options, cmdline, for_latency_measurement)) {
                /* error, somehow - we will still try to start JACK
                 * automatically but it will be without our preferred options
                 */
+               std::cerr << "get_jack_command_line_string () failed: using default settings." << std::endl;
                return;
        }
 
@@ -514,7 +521,7 @@ JACKAudioBackend::setup_jack_startup_command ()
 /* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */
 
 int
-JACKAudioBackend::start ()
+JACKAudioBackend::_start (bool for_latency_measurement)
 {
        if (!available()) {
 
@@ -522,7 +529,7 @@ JACKAudioBackend::start ()
                        /* we will be starting JACK, so set up the 
                           command that JACK will use when it (auto-)starts
                        */
-                       setup_jack_startup_command ();
+                       setup_jack_startup_command (for_latency_measurement);
                }
 
                if (_jack_connection->open ()) {
@@ -540,8 +547,11 @@ JACKAudioBackend::start ()
        /* Now that we have buffer size and sample rate established, the engine 
           can go ahead and do its stuff
        */
-       
-       engine.reestablish_ports ();
+
+       if (engine.reestablish_ports ()) {
+               error << _("Could not re-establish ports after connecting to JACK") << endmsg;
+               return -1;
+       }
 
        if (!jack_port_type_get_buffer_size) {
                warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
@@ -575,18 +585,6 @@ JACKAudioBackend::stop ()
        return 0;
 }
 
-int
-JACKAudioBackend::pause ()
-{
-       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
-
-       if (_priv_jack) {
-               jack_deactivate (_priv_jack);
-       }
-
-       return 0;
-}
-
 int
 JACKAudioBackend::freewheel (bool onoff)
 {
@@ -599,7 +597,7 @@ JACKAudioBackend::freewheel (bool onoff)
        }
 
        if (jack_set_freewheel (_priv_jack, onoff) == 0) {
-               _freewheeling = true;
+               _freewheeling = onoff;
                return 0;
        }
 
@@ -769,9 +767,6 @@ JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_positio
        TransportState tstate;
 
        switch (state) {
-       case JackTransportStopped:
-               tstate = TransportStopped;
-               break;
        case JackTransportRolling:
                tstate = TransportRolling;
                break;
@@ -781,6 +776,10 @@ JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_positio
        case JackTransportStarting:
                tstate = TransportStarting;
                break;
+       case JackTransportStopped:
+       default:
+               tstate = TransportStopped;
+               break;
        }
 
        return engine.sync_callback (tstate, pos->frame);
@@ -1017,7 +1016,7 @@ JACKAudioBackend::disconnected (const char* why)
 }
 
 float 
-JACKAudioBackend::cpu_load() const 
+JACKAudioBackend::dsp_load() const 
 {
        GET_PRIVATE_JACK_POINTER_RET(_priv_jack,0);
        return jack_cpu_load (_priv_jack);
@@ -1125,3 +1124,46 @@ JACKAudioBackend::set_midi_option (const string& opt)
        _target_midi_option = opt;
        return 0;
 }
+
+bool
+JACKAudioBackend::speed_and_position (double& speed, framepos_t& position)
+{
+       jack_position_t pos;
+       jack_transport_state_t state;
+       bool starting;
+
+       /* this won't be called if the port engine in use is not JACK, so we do 
+          not have to worry about the type of PortEngine::private_handle()
+       */
+
+       speed = 0;
+       position = 0;
+
+       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, true);
+
+       state = jack_transport_query (_priv_jack, &pos);
+
+       switch (state) {
+       case JackTransportStopped:
+               speed = 0;
+               starting = false;
+               break;
+       case JackTransportRolling:
+               speed = 1.0;
+               starting = false;
+               break;
+       case JackTransportLooping:
+               speed = 1.0;
+               starting = false;
+               break;
+       case JackTransportStarting:
+               starting = true;
+               // don't adjust speed here, just leave it as it was
+               break;
+       default:
+               std::cerr << "WARNING: Unknown JACK transport state: " << state << std::endl;
+       }
+
+       position = pos.frame;
+       return starting;
+}