Boost logo

Boost :

Subject: [boost] Fwd: [asio]Extension for audio device service
From: adrien courdavault (adrien.courdavault_at_[hidden])
Date: 2013-04-23 16:39:15


I make this new thread to be clearer.
There is currently no way to manage audio endpoints cconnection easily.
It looks like some people might find this usefull (as I do), and I've
been suggested on the boost dev list to try to detail this, as an
extension to Boost.ASIO.

For this reason I create this thread.

I'm trying to make a very basic first draft of the concepts and see if
this may be a good idea.

I attached here the first things I've written. This is very short and general.

I would like to know:
* do you think I'm going in the right direction by seing this as
Boost.ASIO extension.
* do you have suggestions
* would someone like to participate ?

Thank you

Boost.ASIO extension with an audio device service

   Author: Adrien Courdavault
   Date: 04/23/2013


   The goal is to provide a simple way to open an audio device and connect it
   to an audio callback function.

   Currently the implementation of the push mode of an audio device is not
   planned, but should be possible in a future version.


   There is currently no way to connect to an audio device using Standard c++
   lib or Boost.

   There is however several libraries that have this as a feature but which
   don't have a license like Boost, or which do much more than audio device
   connection, or are not designed for generic c++ usage, or are hard to
   integrate in a c++ project.

  Integration in Boost.ASIO

   The current Boost.ASIO library seems to be a good place to start this
   implementation which in concept is a bit like the serial port service of
   this library.

   However considering the differences with the other existing services of
   Boost.ASIO it seems to be better to make a separate service for this use.

  State of the Art


   An audio device correspond to 1 audio interface with 1 or more audio

   Very often there is 2 ways to play audio:
     * the program implements a callback which will be called by the OS when
       audio is needed. This is a streaming API.
     * the program pushes audio data to the audio system which plays it when


   The problem of opening audio devices and connecting programs with these
   devices is different on the different families of OS.
     * on MacOS, the audio devices are managed by [1]CoreAudio API only.
       CoreAudio support a streaming interface with very low latency.
     * on Windows, there is several driver families :
          + WASAPI: the audio system since Vista has an exclusive and a shared
               o The exclusive mode is like the kernel streaming mode but in
                 the user layer, required for low latency professional audio
               o The shared mode is like the DirectSound, a push mode
          + DirectSound and Wavexxx API receives the audio buffer of all
            applications, and then mix and send that to the audio device
            driver. This is a push mode.
          + Steinberg ASIO: this is a format for drivers to implement streaming
            API on windows. This exists mainly because there was no low latency
            streaming API before WASAPI.
     * on Linux
          + ALSA Advanced Linux Audio Architecture supports up to 8 audio
            devices at the same time. This is used as a **streaming
            API.available on Linux>2.5.
          + PulseAudio : is a POSIX compliant audio network system which uses
            ALSA or OSS to open the audio device.
          + OSS is a legacy audio system with read write functions (like a
            file) this is push mode


    Compiler portability

   There is a lot of combinations possible here, one of the main issues is the
   specificity of the platforms and the compatibility with various compilers.

   For instance on Windows, several headers needed to build the WASAPI API
   implementation requires to build or with the Visual SDK, which doesn't work
   without several workarounds to build with MinGW.

   In the first steps there is no use to use workarounds, but it might be an
   issue in long term.

    Synchrounous and async connection

   Obviously we should implement both sync and async connection using handler,
   like the general ASIO design specifies it.

  Proposed API

   audio_service, provides is an io_service::service

   This service can creates audio_ports by choosing the targeted audio device
   using its audio_device_id a port can be initialized with a given
   audio_format and audio_direction, to initialize the port you call errcode
   audio_port::open(audio_format &,const audio_direction, audio_device_mode ).
   The audio_device mode is an enum that can be set to streaming or push mode.

   The program which should implement an audio_callback function can request
   the opened port to connect the callback, and start the processing by calling
errcode audio_port::connect(audio_callback &);
errcode audio_port::start();

   The audio processing can also be stopped, and the device closed. This is by
   default done in the DTOR of the audio_port.


     * Should'nt we implement a device listing API for convenience. This would
       be a static function of the service to call before to open a port ?



Boost list run by bdawes at, gregod at, cpdaniel at, john at