Simple API Implemntation
Client libraries - simple API implementation
After giving a quick overview of how a PulseAudio application communicates with the daemon using the PA client libraries, let's delve into the implementation of the PA client simple API.
pa_simple* pa_simple_new(
const char *server,
const char *name,
pa_stream_direction_t dir,
const char *dev,
const char *stream_name,
const pa_sample_spec *ss,
const pa_channel_map *map,
const pa_buffer_attr *attr,
int *rerror) {
pa_simple *p;
int error = PA_ERR_INTERNAL, r;
p = pa_xnew0(pa_simple, 1);
p->direction = dir;
if (!(p->mainloop = pa_threaded_mainloop_new()))
goto fail;
if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
goto fail;
pa_context_set_state_callback(p->context, context_state_cb, p);
The first thing we notice is that PulseAudio "simple" APIs are just an abstraction above its threaded mainloop API. PulseAudio provides an asynchronus mainloop API by default. The threaded event loop API "spawns a new thread that runs the real main loop. This allows a synchronous application to use the asynchronous API", thus offering default asychronus PulseAudio APIs in a synchronus manner.
This is exactly what the simple APIs provide: a simple synchronus abstraction over event-loop based PA APIs. Thus, the threaded mainloop API is built.