Implement new AudioBackend API in PA backend to choose between callback and blocking API
authorTim Mayberry <mojofunk@gmail.com>
Fri, 5 Feb 2016 13:29:53 +0000 (23:29 +1000)
committerTim Mayberry <mojofunk@gmail.com>
Thu, 11 Feb 2016 02:15:07 +0000 (12:15 +1000)
libs/backends/portaudio/portaudio_backend.cc
libs/backends/portaudio/portaudio_backend.h

index 0f816c991fb9f4814a5e1061c5507378dd08668c..616ee1d145e8d5d8c49127e50ee619ccd251dfc6 100644 (file)
@@ -66,6 +66,7 @@ PortAudioBackend::PortAudioBackend (AudioEngine& e, AudioBackendInfo& info)
        , _pcmio (0)
        , _run (false)
        , _active (false)
+       , _use_blocking_api(false)
        , _freewheel (false)
        , _freewheeling (false)
        , _freewheel_ack (false)
@@ -160,6 +161,18 @@ PortAudioBackend::update_devices ()
        return _pcmio->update_devices();
 }
 
+void
+PortAudioBackend::set_use_buffered_io (bool use_buffered_io)
+{
+       DEBUG_AUDIO (string_compose ("Portaudio: use_buffered_io %1 \n", use_buffered_io));
+
+       if (running()) {
+               return;
+       }
+
+       _use_blocking_api = use_buffered_io;
+}
+
 std::string
 PortAudioBackend::driver_name () const
 {
@@ -572,21 +585,21 @@ PortAudioBackend::_start (bool for_latency_measurement)
 
        PaErrorCode err = paNoError;
 
-#ifdef USE_BLOCKING_API
-       err = _pcmio->open_blocking_stream(name_to_id(_input_audio_device),
-                                          name_to_id(_output_audio_device),
-                                          _samplerate,
-                                          _samples_per_period);
-
-#else
-       err = _pcmio->open_callback_stream(name_to_id(_input_audio_device),
-                                          name_to_id(_output_audio_device),
-                                          _samplerate,
-                                          _samples_per_period,
-                                          portaudio_callback,
-                                          this);
-
-#endif
+       if (_use_blocking_api) {
+               DEBUG_AUDIO("Opening blocking audio stream\n");
+               err = _pcmio->open_blocking_stream(name_to_id(_input_audio_device),
+                                                  name_to_id(_output_audio_device),
+                                                  _samplerate,
+                                                  _samples_per_period);
+       } else {
+               DEBUG_AUDIO("Opening callback audio stream\n");
+               err = _pcmio->open_callback_stream(name_to_id(_input_audio_device),
+                                                  name_to_id(_output_audio_device),
+                                                  _samplerate,
+                                                  _samples_per_period,
+                                                  portaudio_callback,
+                                                  this);
+       }
 
        // reintepret Portaudio error messages
        switch (err) {
@@ -669,22 +682,22 @@ PortAudioBackend::_start (bool for_latency_measurement)
        _run = true;
        _port_change_flag = false;
 
-#ifdef USE_BLOCKING_API
-       if (!start_blocking_process_thread()) {
-               return ProcessThreadStartError;
-       }
-#else
-       if (_pcmio->start_stream() != paNoError) {
-               DEBUG_AUDIO("Unable to start stream\n");
-               return AudioDeviceOpenError;
-       }
+       if (_use_blocking_api) {
+               if (!start_blocking_process_thread()) {
+                       return ProcessThreadStartError;
+               }
+       } else {
+               if (_pcmio->start_stream() != paNoError) {
+                       DEBUG_AUDIO("Unable to start stream\n");
+                       return AudioDeviceOpenError;
+               }
 
-       if (!start_freewheel_process_thread()) {
-               DEBUG_AUDIO("Unable to start freewheel thread\n");
-               stop();
-               return ProcessThreadStartError;
+               if (!start_freewheel_process_thread()) {
+                       DEBUG_AUDIO("Unable to start freewheel thread\n");
+                       stop();
+                       return ProcessThreadStartError;
+               }
        }
-#endif
 
        return NoError;
 }
@@ -814,20 +827,19 @@ PortAudioBackend::stop ()
 
        _run = false;
 
-#ifdef USE_BLOCKING_API
-       if (!stop_blocking_process_thread ()) {
-               return -1;
-       }
-#else
-       _pcmio->close_stream ();
-       _active = false;
+       if (_use_blocking_api) {
+               if (!stop_blocking_process_thread()) {
+                       return -1;
+               }
+       } else {
+               _pcmio->close_stream();
+               _active = false;
 
-       if (!stop_freewheel_process_thread ()) {
-               return -1;
+               if (!stop_freewheel_process_thread()) {
+                       return -1;
+               }
        }
 
-#endif
-
        unregister_ports();
 
        return (_active == false) ? 0 : -1;
@@ -1127,16 +1139,15 @@ PortAudioBackend::join_process_threads ()
 bool
 PortAudioBackend::in_process_thread ()
 {
-#ifdef USE_BLOCKING_API
-       if (pthread_equal (_main_blocking_thread, pthread_self()) != 0) {
-               return true;
-       }
-#else
-       if (pthread_equal (_main_thread, pthread_self()) != 0) {
-               return true;
+       if (_use_blocking_api) {
+               if (pthread_equal(_main_blocking_thread, pthread_self()) != 0) {
+                       return true;
+               }
+       } else {
+               if (pthread_equal(_main_thread, pthread_self()) != 0) {
+                       return true;
+               }
        }
-#endif
-
        for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
        {
                if (pthread_equal (*i, pthread_self ()) != 0) {
index b028dc212bd5265fa8cfd782eff2fa7ad9502292..3e329a42e02fdf75f1a09a1e340990f2654a885a 100644 (file)
@@ -174,6 +174,10 @@ class PortAudioBackend : public AudioBackend {
                bool can_request_update_devices () { return true; }
                bool update_devices ();
 
+               bool can_use_buffered_io () { return true; }
+               void set_use_buffered_io (bool);
+               bool get_use_buffered_io () { return _use_blocking_api; }
+
                bool use_separate_input_and_output_devices () const;
                std::vector<DeviceStatus> enumerate_devices () const;
                std::vector<DeviceStatus> enumerate_input_devices () const;
@@ -356,6 +360,7 @@ class PortAudioBackend : public AudioBackend {
 
                bool  _run; /* keep going or stop, ardour thread */
                bool  _active; /* is running, process thread */
+               bool  _use_blocking_api;
                bool  _freewheel;
                bool  _freewheeling;
                bool  _freewheel_ack;