Documentation work

add pkg-config support for GLIB main loop


git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@133 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
Lennart Poettering 2004-08-17 17:17:22 +00:00
parent f693aa4c88
commit ca2265f372
36 changed files with 326 additions and 151 deletions

View file

@ -24,7 +24,7 @@ MAINTAINERCLEANFILES=README
noinst_DATA = README
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = polyplib.pc polyplib-simple.pc polyplib-error.pc polyplib-mainloop.pc
pkgconfig_DATA = polyplib.pc polyplib-simple.pc polyplib-error.pc polyplib-mainloop.pc polyplib-glib-mainloop.pc
README:
rm -f README

View file

@ -20,7 +20,7 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
AC_PREREQ(2.57)
AC_INIT([polypaudio],[0.1],[mzcbylcnhqvb (at) 0pointer (dot) de])
AC_INIT([polypaudio],[0.2],[mzcbylcnhqvb (at) 0pointer (dot) de])
AC_CONFIG_SRCDIR([polyp/main.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign -Wall])
@ -84,5 +84,5 @@ AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes])
AM_CONDITIONAL(BUILD_LIBPOLYPCORE, false)
AC_CONFIG_FILES([Makefile polyp/Makefile polyplib.pc polyplib-simple.pc polyplib-mainloop.pc polyplib-error.pc doc/Makefile doc/README.html doc/cli.html doc/daemon.html doc/modules.html doxygen/Makefile doxygen/doxygen.conf])
AC_CONFIG_FILES([Makefile polyp/Makefile polyplib.pc polyplib-simple.pc polyplib-mainloop.pc polyplib-error.pc polyplib-glib-mainloop.pc doc/Makefile doc/README.html doc/cli.html doc/daemon.html doc/modules.html doxygen/Makefile doxygen/doxygen.conf])
AC_OUTPUT

View file

@ -5,6 +5,7 @@
- future cancellation
- make mcalign merge chunks
- ref counting foo
- pacat quit() ?
- doxygen

View file

@ -417,7 +417,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../polyp/polyplib-context.h ../polyp/polyplib-stream.h ../polyp/polyplib.h ../polyp/sample.h ../polyp/polyplib-def.h ../polyp/polyplib-subscribe.h ../polyp/polyplib-introspect.h ../polyp/polyplib-scache.h ../polyp/mainloop-api.h ../polyp/cdecl.h ../polyp/glib-mainloop.h ../polyp/mainloop.h ../polyp/mainloop-signal.h ../polyp/native-common.h ../polyp/polyplib-error.h ../polyp/polyplib-operation.h ../polyp/polyplib-simple.h
INPUT = ../polyp/polyplib-context.h ../polyp/polyplib-stream.h ../polyp/polyplib.h ../polyp/sample.h ../polyp/polyplib-def.h ../polyp/polyplib-subscribe.h ../polyp/polyplib-introspect.h ../polyp/polyplib-scache.h ../polyp/mainloop-api.h ../polyp/cdecl.h ../polyp/glib-mainloop.h ../polyp/mainloop.h ../polyp/mainloop-signal.h ../polyp/polyplib-error.h ../polyp/polyplib-operation.h ../polyp/polyplib-simple.h
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -455,7 +455,7 @@ EXCLUDE_PATTERNS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
EXAMPLE_PATH = ../polyp/
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp

View file

@ -84,7 +84,6 @@ lib_LTLIBRARIES=libpolyp.la \
libpolyp-mainloop-glib.la \
libpolyp-simple.la
polypaudio_SOURCES = idxset.c idxset.h \
queue.c queue.h \
strbuf.c strbuf.h \

View file

@ -12,7 +12,7 @@
PA_C_DECL_BEGIN
/** \struct pa_glib_mainloop
* A GLIB main loop object */
* An opaque GLIB main loop object */
struct pa_glib_mainloop;
/** Create a new GLIB main loop object for the specified GLIB main loop context. If c is NULL the default context is used. */

View file

@ -54,15 +54,15 @@ enum pa_io_event_flags {
};
/** \struct pa_io_event
* An IO event source object */
* An opaque IO event source object */
struct pa_io_event;
/** \struct pa_defer_event
* A deferred event source object. Events of this type are triggered once in every main loop iteration */
* An opaque deferred event source object. Events of this type are triggered once in every main loop iteration */
struct pa_defer_event;
/** \struct pa_time_event
* A timer event source object */
* An opaque timer event source object */
struct pa_time_event;
/** An abstract mainloop API vtable */

View file

@ -43,7 +43,7 @@ int pa_signal_init(struct pa_mainloop_api *api);
void pa_signal_done(void);
/** \struct pa_signal_event
* A UNIX signal event source object */
* An opaque UNIX signal event source object */
struct pa_signal_event;
/** Create a new UNIX signal event source object */

View file

@ -36,7 +36,7 @@ PA_C_DECL_BEGIN
* as long as you access the main loop object from a single thread only.*/
/** \struct pa_mainloop
* A main loop object
* An opaque main loop object
*/
struct pa_mainloop;

View file

@ -23,6 +23,7 @@
***/
#include "cdecl.h"
#include "polyplib-def.h"
PA_C_DECL_BEGIN
@ -78,56 +79,9 @@ enum {
PA_COMMAND_MAX
};
enum {
PA_ERROR_OK,
PA_ERROR_ACCESS,
PA_ERROR_COMMAND,
PA_ERROR_INVALID,
PA_ERROR_EXIST,
PA_ERROR_NOENTITY,
PA_ERROR_CONNECTIONREFUSED,
PA_ERROR_PROTOCOL,
PA_ERROR_TIMEOUT,
PA_ERROR_AUTHKEY,
PA_ERROR_INTERNAL,
PA_ERROR_CONNECTIONTERMINATED,
PA_ERROR_KILLED,
PA_ERROR_INVALIDSERVER,
PA_ERROR_MAX
};
#define PA_NATIVE_COOKIE_LENGTH 256
#define PA_NATIVE_COOKIE_FILE ".polypaudio-cookie"
enum pa_subscription_mask {
PA_SUBSCRIPTION_MASK_NULL = 0,
PA_SUBSCRIPTION_MASK_SINK = 1,
PA_SUBSCRIPTION_MASK_SOURCE = 2,
PA_SUBSCRIPTION_MASK_SINK_INPUT = 4,
PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 8,
PA_SUBSCRIPTION_MASK_MODULE = 16,
PA_SUBSCRIPTION_MASK_CLIENT = 32,
PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64,
};
enum pa_subscription_event_type {
PA_SUBSCRIPTION_EVENT_SINK = 0,
PA_SUBSCRIPTION_EVENT_SOURCE = 1,
PA_SUBSCRIPTION_EVENT_SINK_INPUT = 2,
PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 3,
PA_SUBSCRIPTION_EVENT_MODULE = 4,
PA_SUBSCRIPTION_EVENT_CLIENT = 5,
PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 6,
PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 7,
PA_SUBSCRIPTION_EVENT_NEW = 0,
PA_SUBSCRIPTION_EVENT_CHANGE = 16,
PA_SUBSCRIPTION_EVENT_REMOVE = 32,
PA_SUBSCRIPTION_EVENT_TYPE_MASK = 16+32,
};
#define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK))))
PA_C_DECL_END
#endif

View file

@ -34,15 +34,19 @@
#define BUFSIZE 1024
int main(int argc, char*argv[]) {
/* The Sample format to use */
static const struct pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 44100,
.channels = 2
};
struct pa_simple *s = NULL;
int ret = 1;
int error;
/* Create a new playback stream */
if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
@ -51,22 +55,24 @@ int main(int argc, char*argv[]) {
for (;;) {
uint8_t buf[BUFSIZE];
ssize_t r;
/* Read some data ... */
if ((r = read(STDIN_FILENO, buf, sizeof(buf))) <= 0) {
if (r == 0) /* eof */
if (r == 0) /* EOF */
break;
fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
goto finish;
}
/* ... and play it */
if (pa_simple_write(s, buf, r, &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
goto finish;
}
}
/* Make sure that every single sample way played */
/* Make sure that every single sample was played */
if (pa_simple_drain(s, &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
goto finish;

View file

@ -47,11 +47,13 @@ static size_t buffer_length = 0, buffer_index = 0;
static struct pa_io_event* stdio_event = NULL;
/* A shortcut for terminating the application */
static void quit(int ret) {
assert(mainloop_api);
mainloop_api->quit(mainloop_api, ret);
}
/* Write some data to the stream */
static void do_stream_write(size_t length) {
size_t l;
assert(length);
@ -74,6 +76,7 @@ static void do_stream_write(size_t length) {
}
}
/* This is called whenever new data may be written to the stream */
static void stream_write_callback(struct pa_stream *s, size_t length, void *userdata) {
assert(s && length);
@ -86,6 +89,7 @@ static void stream_write_callback(struct pa_stream *s, size_t length, void *user
do_stream_write(length);
}
/* This is called whenever new data may is available */
static void stream_read_callback(struct pa_stream *s, const void*data, size_t length, void *userdata) {
assert(s && data && length);
@ -103,6 +107,7 @@ static void stream_read_callback(struct pa_stream *s, const void*data, size_t le
buffer_index = 0;
}
/* This routine is called whenever the stream state changes */
static void stream_state_callback(struct pa_stream *s, void *userdata) {
assert(s);
@ -125,6 +130,7 @@ static void stream_state_callback(struct pa_stream *s, void *userdata) {
}
}
/* This is called whenever the context status changes */
static void context_state_callback(struct pa_context *c, void *userdata) {
static const struct pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
@ -170,10 +176,12 @@ static void context_state_callback(struct pa_context *c, void *userdata) {
}
}
/* Connection draining complete */
static void context_drain_complete(struct pa_context*c, void *userdata) {
pa_context_disconnect(c);
}
/* Stream draining complete */
static void stream_drain_complete(struct pa_stream*s, int success, void *userdata) {
struct pa_operation *o;
@ -196,6 +204,7 @@ static void stream_drain_complete(struct pa_stream*s, int success, void *userdat
}
}
/* New data on STDIN **/
static void stdin_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
size_t l, w = 0;
ssize_t r;
@ -232,6 +241,7 @@ static void stdin_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int
do_stream_write(w);
}
/* Some data may be written to STDOUT */
static void stdout_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
ssize_t r;
assert(a == mainloop_api && e && stdio_event == e);
@ -262,12 +272,14 @@ static void stdout_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int
}
}
/* UNIX signal to quit recieved */
static void exit_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
fprintf(stderr, "Got SIGINT, exiting.\n");
quit(0);
}
/* Show the current playback latency */
static void stream_get_latency_callback(struct pa_stream *s, uint32_t latency, void *userdata) {
assert(s);
@ -280,6 +292,7 @@ static void stream_get_latency_callback(struct pa_stream *s, uint32_t latency, v
fprintf(stderr, "Current latency is %u usecs.\n", latency);
}
/* Someone requested that the latency is shown */
static void sigusr1_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
if (mode != PLAYBACK)
return;
@ -295,6 +308,8 @@ int main(int argc, char *argv[]) {
if (!(bn = strrchr(argv[0], '/')))
bn = argv[0];
else
bn++;
if (strstr(bn, "rec") || strstr(bn, "mon"))
mode = RECORD;
@ -302,7 +317,8 @@ int main(int argc, char *argv[]) {
mode = PLAYBACK;
fprintf(stderr, "Opening a %s stream.\n", mode == RECORD ? "recording" : "playback");
/* Set up a new main loop */
if (!(m = pa_mainloop_new())) {
fprintf(stderr, "pa_mainloop_new() failed.\n");
goto quit;
@ -323,16 +339,19 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "source_io() failed.\n");
goto quit;
}
if (!(context = pa_context_new(mainloop_api, argv[0]))) {
/* Create a new connection context */
if (!(context = pa_context_new(mainloop_api, bn))) {
fprintf(stderr, "pa_context_new() failed.\n");
goto quit;
}
pa_context_set_state_callback(context, context_state_callback, NULL);
/* Connect the context */
pa_context_connect(context, NULL);
/* Run the main loop */
if (pa_mainloop_run(m, &ret) < 0) {
fprintf(stderr, "pa_mainloop_run() failed.\n");
goto quit;

View file

@ -33,6 +33,7 @@
#define BUFSIZE 1024
/* A simple routine calling UNIX write() in a loop */
static ssize_t loop_write(int fd, const void*data, size_t size) {
ssize_t ret = 0;
@ -54,6 +55,7 @@ static ssize_t loop_write(int fd, const void*data, size_t size) {
}
int main(int argc, char*argv[]) {
/* The sample type to use */
static const struct pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 44100,
@ -63,6 +65,7 @@ int main(int argc, char*argv[]) {
int ret = 1;
int error;
/* Create the recording stream */
if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
@ -72,11 +75,13 @@ int main(int argc, char*argv[]) {
uint8_t buf[BUFSIZE];
ssize_t r;
/* Record some data ... */
if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
goto finish;
}
/* And write it to STDOUT */
if ((r = loop_write(STDOUT_FILENO, buf, sizeof(buf))) <= 0) {
fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
goto finish;

View file

@ -29,23 +29,25 @@
#include "polyplib-operation.h"
/** \file
* Connection contexts */
* Connection contexts for asynchrononous communication with a
* server. A pa_context object wraps a connection to a polypaudio
* server using its native protocol. A context may be used to issue
* commands on the server or to create playback or recording
* streams. Multiple playback streams may be piped through a single
* connection context. Operations on the contect involving
* communication with the server are executed asynchronously: i.e. the
* client function do not implicitely wait for completion of the
* operation on the server. Instead the caller specifies a call back
* function that is called when the operation is completed. Currently
* running operations may be canceled using pa_operation_cancel(). */
/** \example pacat.c
* A playback and recording tool using the asynchronous API */
PA_C_DECL_BEGIN
/** The state of a connection context */
enum pa_context_state {
PA_CONTEXT_UNCONNECTED, /**< The context hasn't been connected yet */
PA_CONTEXT_CONNECTING, /**< A connection is being established */
PA_CONTEXT_AUTHORIZING, /**< The client is authorizing itself to the daemon */
PA_CONTEXT_SETTING_NAME, /**< The client is passing its application name to the daemon */
PA_CONTEXT_READY, /**< The connection is established, the context is ready to execute operations */
PA_CONTEXT_FAILED, /**< The connection failed or was disconnected */
PA_CONTEXT_TERMINATED /**< The connect was terminated cleanly */
};
/** \struct pa_context
* A connection context to a daemon */
* An opaque connection context to a daemon */
struct pa_context;
/** Instantiate a new connection context with an abstract mainloop API

View file

@ -23,28 +23,111 @@
***/
#include <inttypes.h>
#include "native-common.h"
#include "cdecl.h"
/** \file
* Global definitions */
PA_C_DECL_BEGIN
enum pa_stream_direction {
PA_STREAM_NODIRECTION,
PA_STREAM_PLAYBACK,
PA_STREAM_RECORD,
PA_STREAM_UPLOAD
/** The state of a connection context */
enum pa_context_state {
PA_CONTEXT_UNCONNECTED, /**< The context hasn't been connected yet */
PA_CONTEXT_CONNECTING, /**< A connection is being established */
PA_CONTEXT_AUTHORIZING, /**< The client is authorizing itself to the daemon */
PA_CONTEXT_SETTING_NAME, /**< The client is passing its application name to the daemon */
PA_CONTEXT_READY, /**< The connection is established, the context is ready to execute operations */
PA_CONTEXT_FAILED, /**< The connection failed or was disconnected */
PA_CONTEXT_TERMINATED /**< The connection was terminated cleanly */
};
struct pa_buffer_attr {
uint32_t maxlength;
uint32_t tlength;
uint32_t prebuf;
uint32_t minreq;
uint32_t fragsize;
/** The state of a stream */
enum pa_stream_state {
PA_STREAM_DISCONNECTED, /**< The stream is not yet connected to any sink or source */
PA_STREAM_CREATING, /**< The stream is being created */
PA_STREAM_READY, /**< The stream is established, you may pass audio data to it now */
PA_STREAM_FAILED, /**< An error occured that made the stream invalid */
PA_STREAM_TERMINATED, /**< The stream has been terminated cleanly */
};
/** The state of an operation */
enum pa_operation_state {
PA_OPERATION_RUNNING, /**< The operation is still running */
PA_OPERATION_DONE, /**< The operation has been completed */
PA_OPERATION_CANCELED, /**< The operation has been canceled */
};
/** An invalid index */
#define PA_INVALID_INDEX ((uint32_t) -1)
/** The direction of a pa_stream object */
enum pa_stream_direction {
PA_STREAM_NODIRECTION, /**< Invalid direction */
PA_STREAM_PLAYBACK, /**< Playback stream */
PA_STREAM_RECORD, /**< Record stream */
PA_STREAM_UPLOAD /**< Sample upload stream */
};
/** Playback and record buffer metrics */
struct pa_buffer_attr{
uint32_t maxlength; /**< Maximum length of the buffer */
uint32_t tlength; /**< Playback only: target length of the buffer. The server tries to assure that at least tlength bytes are always available in the buffer */
uint32_t prebuf; /**< Playback only: pre-buffering. The server does not start with playback before at least prebug bytes are available in the buffer */
uint32_t minreq; /**< Playback only: minimum request. The server does not request less than minreq bytes from the client, instead waints until the buffer is free enough to request more bytes at once */
uint32_t fragsize; /**< Recording only: fragment size. The server sends data in blocks of fragsize bytes size. Large values deminish interactivity with other operations on the connection context but decrease control overhead. */
};
/** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */
enum {
PA_ERROR_OK, /**< No error */
PA_ERROR_ACCESS, /**< Access failure */
PA_ERROR_COMMAND, /**< Unknown command */
PA_ERROR_INVALID, /**< Invalid argument */
PA_ERROR_EXIST, /**< Entity exists */
PA_ERROR_NOENTITY, /**< No such entity */
PA_ERROR_CONNECTIONREFUSED, /**< Connection refused */
PA_ERROR_PROTOCOL, /**< Protocol error */
PA_ERROR_TIMEOUT, /**< Timeout */
PA_ERROR_AUTHKEY, /**< No authorization key */
PA_ERROR_INTERNAL, /**< Internal error */
PA_ERROR_CONNECTIONTERMINATED, /**< Connection terminated */
PA_ERROR_KILLED, /**< Entity killed */
PA_ERROR_INVALIDSERVER, /**< Invalid server */
PA_ERROR_MAX /**< Not really an error but the first invalid error code */
};
/** Subscription event mask, as used by pa_context_subscribe() */
enum pa_subscription_mask {
PA_SUBSCRIPTION_MASK_NULL = 0, /**< No events */
PA_SUBSCRIPTION_MASK_SINK = 1, /**< Sink events */
PA_SUBSCRIPTION_MASK_SOURCE = 2, /**< Source events */
PA_SUBSCRIPTION_MASK_SINK_INPUT = 4, /**< Sink input events */
PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 8, /**< Source output events */
PA_SUBSCRIPTION_MASK_MODULE = 16, /**< Module events */
PA_SUBSCRIPTION_MASK_CLIENT = 32, /**< Client events */
PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64, /**< Sample cache events */
};
/** Subscription event types, as used by pa_context_subscribe() */
enum pa_subscription_event_type {
PA_SUBSCRIPTION_EVENT_SINK = 0, /**< Event type: Sink */
PA_SUBSCRIPTION_EVENT_SOURCE = 1, /**< Event type: Source */
PA_SUBSCRIPTION_EVENT_SINK_INPUT = 2, /**< Event type: Sink input */
PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 3, /**< Event type: Source output */
PA_SUBSCRIPTION_EVENT_MODULE = 4, /**< Event type: Module */
PA_SUBSCRIPTION_EVENT_CLIENT = 5, /**< Event type: Client */
PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 6, /**< Event type: Sample cache item */
PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 7, /**< A mask to extract the event type from an event value */
PA_SUBSCRIPTION_EVENT_NEW = 0, /**< A new object was created */
PA_SUBSCRIPTION_EVENT_CHANGE = 16, /**< A property of the object was modified */
PA_SUBSCRIPTION_EVENT_REMOVE = 32, /**< An object was removed */
PA_SUBSCRIPTION_EVENT_TYPE_MASK = 16+32, /**< A mask to extract the event operation from an event value */
};
/** Return one if an event type t matches an event mask bitfield */
#define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK))))
PA_C_DECL_END
#endif

View file

@ -37,12 +37,13 @@ static const char* const errortab[PA_ERROR_MAX] = {
[PA_ERROR_EXIST] = "Entity exists",
[PA_ERROR_NOENTITY] = "No such entity",
[PA_ERROR_CONNECTIONREFUSED] = "Connection refused",
[PA_ERROR_PROTOCOL] = "Protocol corrupt",
[PA_ERROR_PROTOCOL] = "Protocol error",
[PA_ERROR_TIMEOUT] = "Timeout",
[PA_ERROR_AUTHKEY] = "Not authorization key",
[PA_ERROR_AUTHKEY] = "No authorization key",
[PA_ERROR_INTERNAL] = "Internal error",
[PA_ERROR_CONNECTIONTERMINATED] = "Connection terminated",
[PA_ERROR_KILLED] = "Entity killed",
[PA_ERROR_INVALIDSERVER] = "Invalid server",
};
const char*pa_strerror(uint32_t error) {

View file

@ -25,6 +25,9 @@
#include <inttypes.h>
#include "cdecl.h"
/** \file
* Error management */
PA_C_DECL_BEGIN
/** Return a human readable error message for the specified numeric error code */

View file

@ -32,6 +32,7 @@
#include "polyplib-stream.h"
#include "polyplib-operation.h"
#include "llist.h"
#include "native-common.h"
#define DEFAULT_MAXLENGTH 204800
#define DEFAULT_TLENGTH 10240

View file

@ -514,7 +514,7 @@ struct pa_operation* pa_context_get_source_output_info_list(struct pa_context *c
/*** Volume manipulation ***/
struct pa_operation* pa_context_set_sink_volume_by_index(struct pa_context *c, uint32_t index, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation* pa_context_set_sink_volume_by_index(struct pa_context *c, uint32_t index, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation *o;
struct pa_tagstruct *t;
uint32_t tag;
@ -536,7 +536,7 @@ struct pa_operation* pa_context_set_sink_volume_by_index(struct pa_context *c, u
return pa_operation_ref(o);
}
struct pa_operation* pa_context_set_sink_volume_by_name(struct pa_context *c, const char *name, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation* pa_context_set_sink_volume_by_name(struct pa_context *c, const char *name, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation *o;
struct pa_tagstruct *t;
uint32_t tag;
@ -558,7 +558,7 @@ struct pa_operation* pa_context_set_sink_volume_by_name(struct pa_context *c, co
return pa_operation_ref(o);
}
struct pa_operation* pa_context_set_sink_input_volume(struct pa_context *c, uint32_t index, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation* pa_context_set_sink_input_volume(struct pa_context *c, uint32_t index, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata) {
struct pa_operation *o;
struct pa_tagstruct *t;
uint32_t tag;

View file

@ -28,6 +28,9 @@
#include "polyplib-context.h"
#include "cdecl.h"
/** \file
* Routines for daemon introspection. */
PA_C_DECL_BEGIN
struct pa_sink_info {
@ -36,7 +39,7 @@ struct pa_sink_info {
const char *description;
struct pa_sample_spec sample_spec;
uint32_t owner_module;
uint32_t volume;
pa_volume_t volume;
uint32_t monitor_source;
const char *monitor_source_name;
uint32_t latency;
@ -60,12 +63,13 @@ struct pa_operation* pa_context_get_source_info_by_name(struct pa_context *c, co
struct pa_operation* pa_context_get_source_info_by_index(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata);
struct pa_operation* pa_context_get_source_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata);
/** Server information */
struct pa_server_info {
const char *user_name;
const char *host_name;
const char *server_version;
const char *server_name;
struct pa_sample_spec sample_spec;
const char *user_name; /**< User name of the daemon process */
const char *host_name; /**< Host name the daemon is running on */
const char *server_version; /**< Version string of the daemon */
const char *server_name; /**< Server package name (usually "polypaudio") */
struct pa_sample_spec sample_spec; /**< Default sample specification */
};
struct pa_operation* pa_context_get_server_info(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_server_info*i, void *userdata), void *userdata);
@ -96,7 +100,7 @@ struct pa_sink_input_info {
uint32_t client;
uint32_t sink;
struct pa_sample_spec sample_spec;
uint32_t volume;
pa_volume_t volume;
uint32_t latency;
};
@ -115,15 +119,22 @@ struct pa_source_output_info {
struct pa_operation* pa_context_get_source_output_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_source_output_info*i, int is_last, void *userdata), void *userdata);
struct pa_operation* pa_context_get_source_output_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_output_info*i, int is_last, void *userdata), void *userdata);
struct pa_operation* pa_context_set_sink_volume_by_index(struct pa_context *c, uint32_t index, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
struct pa_operation* pa_context_set_sink_volume_by_name(struct pa_context *c, const char *name, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
struct pa_operation* pa_context_set_sink_input_volume(struct pa_context *c, uint32_t index, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
/** Set the volume of a sink device specified by its index */
struct pa_operation* pa_context_set_sink_volume_by_index(struct pa_context *c, uint32_t index, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
/** Set the volume of a sink device specified by its name */
struct pa_operation* pa_context_set_sink_volume_by_name(struct pa_context *c, const char *name, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
/** Set the volume of a sink input stream */
struct pa_operation* pa_context_set_sink_input_volume(struct pa_context *c, uint32_t index, pa_volume_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
/** Memory block statistics */
struct pa_stat_info {
uint32_t memblock_count;
uint32_t memblock_total;
uint32_t memblock_count; /**< Allocated memory blocks */
uint32_t memblock_total; /**< Total size of allocated memory blocks */
};
/** Get daemon memory block statistics */
struct pa_operation* pa_context_stat(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_stat_info *i, void *userdata), void *userdata);
PA_C_DECL_END

View file

@ -29,12 +29,6 @@
PA_C_DECL_BEGIN
enum pa_operation_state {
PA_OPERATION_RUNNING, /**< The operation is still running */
PA_OPERATION_DONE, /**< The operation has been completed */
PA_OPERATION_CANCELED, /**< The operation has been canceled */
};
/** \struct pa_operation
* An asynchronous operation object */
struct pa_operation;

View file

@ -29,12 +29,20 @@
#include "cdecl.h"
/** \file
* A simple but limited synchronous playback and recording API. */
* A simple but limited synchronous playback and recording
* API. This is synchronouse, simplified wrapper around the standard
* asynchronous API. */
/** \example pacat-simple.c
* A simple playback tool using the simple API */
/** \example parec-simple.c
* A simple recording tool using the simple API */
PA_C_DECL_BEGIN
/** \struct pa_simple
* A simple connection object */
* An opaque simple connection object */
struct pa_simple;
/** Create a new connection to the server */

View file

@ -34,17 +34,8 @@
PA_C_DECL_BEGIN
/** The state of a stream */
enum pa_stream_state {
PA_STREAM_DISCONNECTED, /**< The stream is not yet connected to any sink or source */
PA_STREAM_CREATING, /**< The stream is being created */
PA_STREAM_READY, /**< The stream is established, you may pass audio data to it now */
PA_STREAM_FAILED, /**< An error occured that made the stream invalid */
PA_STREAM_TERMINATED, /**< The stream has been terminated cleanly */
};
/** \struct pa_stream
* A stream for playback or recording */
* An opaque stream for playback or recording */
struct pa_stream;
/** Create a new, unconnected stream with the specified name and sample type */

View file

@ -28,9 +28,18 @@
#include "polyplib-context.h"
#include "cdecl.h"
/** \file
* Daemon introspection event subscription subsystem. Use this
* to be notified whenever the internal layout of daemon changes:
* i.e. entities such as sinks or sources are create, removed or
* modified. */
PA_C_DECL_BEGIN
/** Enable event notification */
struct pa_operation* pa_context_subscribe(struct pa_context *c, enum pa_subscription_mask m, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
/** Set the context specific call back function that is called whenever the state of the daemon changes */
void pa_context_set_subscribe_callback(struct pa_context *c, void (*cb)(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata), void *userdata);
PA_C_DECL_END

View file

@ -31,4 +31,54 @@
#include "polyplib-subscribe.h"
#include "polyplib-scache.h"
/** \file
* Include all polyplib header file at once. The following files are included: \ref mainloop-api.h, \ref sample.h,
* \ref polyplib-def.h, \ref polyplib-context.h, \ref polyplib-stream.h,
* \ref polyplib-introspect.h, \ref polyplib-subscribe.h and \ref polyplib-scache.h
* at once */
/** \mainpage
*
* \section intro_sec Introduction
*
* This document describes the client API for the polypaudio sound
* server. The API comes in two flavours:
*
* \li The complete but somewhat complicated to use asynchronous API
* \li And the simplified, easy to use, but limited synchronous API
*
* The polypaudio client libraries are thread safe as long as all
* objects created by any library function are accessed from the thread
* that created them only.
*
* \section simple_sec Simple API
*
* Use this if you develop your program in synchronous style and just
* need a way to play or record data on the sound server. See
* \ref polyplib-simple.h for more details.
*
* \section async_api Asynchronous API
*
* Use this if you develop your programs in asynchronous, main loop
* based style or want to use advanced features of the polypaudio
* API. A good starting point is \ref polyplib-context.h
*
* The asynchronous API relies on an abstract main loop API that is
* described in \ref mainloop-api.h. Two distinct implementations are
* available:
*
* \li \ref mainloop.h: a minimal but fast implementation based on poll()
* \li \ref glib-mainloop.h: a wrapper around GLIB's main loop
*
* UNIX signals may be hooked to a main loop using the functions from
* \ref mainloop-signal.h
*
* \section pkgconfig pkg-config
*
* The polypaudio libraries provide pkg-config snippets for the different modules. To use the
* asynchronous API use "polyplib" as pkg-config file. GLIB main loop
* support is available as "polyplib-glib-mainloop". The simple
* synchronous API is available as "polyplib-simple".
*/
#endif

View file

@ -33,12 +33,12 @@ void pa_silence_memory(void *p, size_t length, const struct pa_sample_spec *spec
struct pa_mix_info {
struct pa_memchunk chunk;
uint32_t volume;
pa_volume_t volume;
void *userdata;
};
size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, size_t length, const struct pa_sample_spec *spec, uint32_t volume);
size_t pa_mix(struct pa_mix_info channels[], unsigned nchannels, void *data, size_t length, const struct pa_sample_spec *spec, pa_volume_t volume);
void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec, uint32_t volume);
void pa_volume_memchunk(struct pa_memchunk*c, const struct pa_sample_spec *spec, pa_volume_t volume);
#endif

View file

@ -82,7 +82,7 @@ int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_s
return (a->format == b->format) && (a->rate == b->rate) && (a->channels == b->channels);
}
void pa_sample_snprint(char *s, size_t l, const struct pa_sample_spec *spec) {
void pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec) {
static const char* const table[]= {
[PA_SAMPLE_U8] = "U8",
[PA_SAMPLE_ALAW] = "ALAW",
@ -97,10 +97,10 @@ void pa_sample_snprint(char *s, size_t l, const struct pa_sample_spec *spec) {
snprintf(s, l, "%s %uch %uHz", table[spec->format], spec->channels, spec->rate);
}
uint32_t pa_volume_multiply(uint32_t a, uint32_t b) {
pa_volume_t pa_volume_multiply(pa_volume_t a, pa_volume_t b) {
uint64_t p = a;
p *= b;
p /= PA_VOLUME_NORM;
return (uint32_t) p;
return (pa_volume_t) p;
}

View file

@ -27,26 +27,36 @@
#include "cdecl.h"
/** \file
* Constants and routines for sample type handling */
PA_C_DECL_BEGIN
/** Sample format */
enum pa_sample_format {
PA_SAMPLE_U8,
PA_SAMPLE_ALAW,
PA_SAMPLE_ULAW,
PA_SAMPLE_S16LE,
PA_SAMPLE_S16BE,
PA_SAMPLE_FLOAT32LE,
PA_SAMPLE_FLOAT32BE,
PA_SAMPLE_MAX
PA_SAMPLE_U8, /**< Unsigned 8 Bit PCM */
PA_SAMPLE_ALAW, /**< 8 Bit a-Law */
PA_SAMPLE_ULAW, /**< 8 Bit mu-Law */
PA_SAMPLE_S16LE, /**< Signed 16 Bit PCM, little endian (PC) */
PA_SAMPLE_S16BE, /**< Signed 16 Bit PCM, big endian */
PA_SAMPLE_FLOAT32LE, /**< 32 Bit IEEE floating point, little endian, range -1..1 */
PA_SAMPLE_FLOAT32BE, /**< 32 Bit IEEE floating point, big endian, range -1..1 */
PA_SAMPLE_MAX /**< Upper limit of valid sample types */
};
#ifdef WORDS_BIGENDIAN
/** Signed 16 Bit PCM, native endian */
#define PA_SAMPLE_S16NE PA_SAMPLE_S16BE
/** 32 Bit IEEE floating point, native endian */
#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32BE
#else
/** Signed 16 Bit PCM, native endian */
#define PA_SAMPLE_S16NE PA_SAMPLE_S16LE
/** 32 Bit IEEE floating point, native endian */
#define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE
#endif
/** A Shortcut for PA_SAMPLE_FLOAT32NE */
#define PA_SAMPLE_FLOAT32 PA_SAMPLE_FLOAT32NE
/** A sample format and attribute specification */
@ -56,23 +66,38 @@ struct pa_sample_spec {
uint8_t channels; /**< Audio channels. (1 for mono, 2 for stereo, ...) */
};
/** Return the amount of bytes playback of a second of audio with the speicified sample type takes */
size_t pa_bytes_per_second(const struct pa_sample_spec *spec);
/** Return the size of a frame with the specific sample type */
size_t pa_frame_size(const struct pa_sample_spec *spec);
/** Calculate the time the specified bytes take to play with the specified sample type */
uint32_t pa_bytes_to_usec(size_t length, const struct pa_sample_spec *spec);
/** Return non-zero when the sample type specification is valid */
int pa_sample_spec_valid(const struct pa_sample_spec *spec);
/** Return non-zero when the two sample type specifications match */
int pa_sample_spec_equal(const struct pa_sample_spec*a, const struct pa_sample_spec*b);
/** Maximum required string length for pa_sample_spec_snprint() */
#define PA_SAMPLE_SNPRINT_MAX_LENGTH 32
void pa_sample_snprint(char *s, size_t l, const struct pa_sample_spec *spec);
/** Pretty print a sample type specification to a string */
void pa_sample_spec_snprint(char *s, size_t l, const struct pa_sample_spec *spec);
/** Volume specification: 0: silence; < 256: diminished volume; 256: normal volume; > 256 amplified volume */
typedef uint32_t pa_volume_t;
/** Normal volume (100%) */
#define PA_VOLUME_NORM (0x100)
/** Muted volume (0%) */
#define PA_VOLUME_MUTE (0)
#define PA_VOLUME_MUTED (0)
/** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. */
uint32_t pa_volume_multiply(uint32_t a, uint32_t b);
pa_volume_t pa_volume_multiply(pa_volume_t a, pa_volume_t b);
PA_C_DECL_END

View file

@ -169,7 +169,7 @@ void pa_sink_input_drop(struct pa_sink_input *i, size_t length) {
}
}
void pa_sink_input_set_volume(struct pa_sink_input *i, uint32_t volume) {
void pa_sink_input_set_volume(struct pa_sink_input *i, pa_volume_t volume) {
assert(i && i->sink && i->sink->core);
if (i->volume != volume) {

View file

@ -64,6 +64,6 @@ uint32_t pa_sink_input_get_latency(struct pa_sink_input *i);
int pa_sink_input_peek(struct pa_sink_input *i, struct pa_memchunk *chunk);
void pa_sink_input_drop(struct pa_sink_input *i, size_t length);
void pa_sink_input_set_volume(struct pa_sink_input *i, uint32_t volume);
void pa_sink_input_set_volume(struct pa_sink_input *i, pa_volume_t volume);
#endif

View file

@ -283,7 +283,7 @@ void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m) {
pa_source_set_owner(sink->monitor_source, m);
}
void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume) {
void pa_sink_set_volume(struct pa_sink *sink, pa_volume_t volume) {
assert(sink);
if (sink->volume != volume) {

View file

@ -42,7 +42,7 @@ struct pa_sink {
struct pa_source *monitor_source;
uint32_t volume;
pa_volume_t volume;
void (*notify)(struct pa_sink*sink);
uint32_t (*get_latency)(struct pa_sink *s);
@ -62,6 +62,6 @@ void pa_sink_notify(struct pa_sink*s);
void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m);
void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume);
void pa_sink_set_volume(struct pa_sink *sink, pa_volume_t volume);
#endif

View file

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: polyplib-glib-mainloop
Description: GLIB main loop wrapper for polypaudio
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpolyp-mainloop-glib
Cflags: -D_REENTRANT -I${includedir}
Requires: polyplib-mainloop

View file

@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: polyplib-mainloop
Description: Mainloop API of the polypaudio sound daemon
Description: Main loop support for polypaudio
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpolyp-mainloop
Cflags: -D_REENTRANT -I${includedir}

View file

@ -4,7 +4,8 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: polyplib-simple
Description: Simplistic client interface to polypaudio sound daemon
Description: Simplified synchronous client interface to polypaudio
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpolyp-simple
Cflags: -D_REENTRANT -I${includedir}
Requires: polyplib polyplib-mainloop polyplib-error

View file

@ -4,7 +4,8 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: polyplib
Description: Client interface to polypaudio sound daemon
Description: Client interface to polypaudio
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpolyp
Cflags: -D_REENTRANT -I${includedir}
Requires: polyplib-error polyplib-mainloop