|
Boost : |
Subject: [boost] Fwd: [asio]Extension for audio device service
From: adrien courdavault (adrien.courdavault_at_[hidden])
Date: 2013-04-23 16:39:15
Hello.
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
Introduction
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.
Motivation
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
Foreword
An audio device correspond to 1 audio interface with 1 or more audio
endpoints.
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
needed.
OS
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
mode.
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
Design
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.
Questions
* 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 ?
References
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk