X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/4fd3886810d93a7d3d2c2505e8b9ac38df2430d1..16b0fea8ae1a581d568dbee2efa2932aa4e6fcce:/lib/uaudio.h diff --git a/lib/uaudio.h b/lib/uaudio.h index ac88b3f..bcb4e94 100644 --- a/lib/uaudio.h +++ b/lib/uaudio.h @@ -1,6 +1,6 @@ /* * This file is part of DisOrder. - * Copyright (C) 2009 Richard Kettlewell + * Copyright (C) 2009, 2013 Richard Kettlewell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,17 +23,29 @@ #ifndef UAUDIO_H #define UAUDIO_H +struct sockaddr_storage; + extern int uaudio_rate; extern int uaudio_bits; extern int uaudio_channels; extern int uaudio_signed; extern size_t uaudio_sample_size; +extern int uaudio_buffer; /** @brief Callback to get audio data * @param buffer Where to put audio data * @param max_samples How many samples to supply * @param userdata As passed to uaudio_open() * @return Number of samples filled + * + * This function should not block if possible (better to fill the buffer with + * 0s) and should definitely not block indefinitely. This great caution with + * any locks or syscalls! In particular avoid it taking a lock that may be + * held while any of the @ref uaudio members are called. + * + * If it's more convenient, it's OK to return less than the maximum number of + * samples (including 0) provided you expect to be called again for more + * samples immediately. */ typedef size_t uaudio_callback(void *buffer, size_t max_samples, @@ -42,11 +54,33 @@ typedef size_t uaudio_callback(void *buffer, /** @brief Callback to play audio data * @param buffer Pointer to audio buffer * @param samples Number of samples to play + * @param flags Flags word * @return Number of samples played * * Used with uaudio_thread_start() etc. + * + * @p flags is a bitmap giving the current pause state and transitions: + * - @ref UAUDIO_PAUSE if this is the first call of a pause + * - @ref UAUDIO_RESUME if this is the first call of a resumse + * - @ref UAUDIO_PLAYING if this is outside a pause + * - @ref UAUDIO_PAUSED if this is in a pause + * + * During a pause, the sample data is guaranteed to be 0. */ -typedef size_t uaudio_playcallback(void *buffer, size_t samples); +typedef size_t uaudio_playcallback(void *buffer, size_t samples, + unsigned flags); + +/** @brief Start of a pause */ +#define UAUDIO_PAUSE 0x0001 + +/** @brief End of a pause */ +#define UAUDIO_RESUME 0x0002 + +/** @brief Currently playing */ +#define UAUDIO_PLAYING 0x0004 + +/** @brief Currently paused */ +#define UAUDIO_PAUSED 0x0008 /** @brief Audio API definition */ struct uaudio { @@ -90,19 +124,69 @@ struct uaudio { */ void (*deactivate)(void); + /** @brief Open mixer device */ + void (*open_mixer)(void); + + /** @brief Closer mixer device */ + void (*close_mixer)(void); + + /** @brief Get volume + * @param left Where to put the left-channel value + * @param right Where to put the right-channel value + * + * 0 is silent and 100 is maximum volume. + */ + void (*get_volume)(int *left, int *right); + + /** @brief Set volume + * @param left Pointer to left-channel value (updated) + * @param right Pointer to right-channel value (updated) + * + * The values are updated with those actually set by the underlying system + * call. + * + * 0 is silent and 100 is maximum volume. + */ + void (*set_volume)(int *left, int *right); + + /** @brief Set configuration */ + void (*configure)(void); + + /** @brief Descriptive flags */ + unsigned flags; }; +/** @brief API is suitable for clients */ +#define UAUDIO_API_CLIENT 0x0001 + +/** @brief API is suitable for servers */ +#define UAUDIO_API_SERVER 0x0002 + void uaudio_set_format(int rate, int channels, int samplesize, int signed_); void uaudio_set(const char *name, const char *value); -const char *uaudio_get(const char *name); +char *uaudio_get(const char *name, const char *default_value); void uaudio_thread_start(uaudio_callback *callback, void *userdata, uaudio_playcallback *playcallback, size_t min, - size_t max); + size_t max, + unsigned flags); + void uaudio_thread_stop(void); void uaudio_thread_activate(void); void uaudio_thread_deactivate(void); +uint32_t uaudio_schedule_sync(void); +void uaudio_schedule_sent(size_t nsamples_sent); +void uaudio_schedule_init(void); +const struct uaudio *uaudio_find(const char *name); +const struct uaudio *uaudio_default(const struct uaudio *const *apis, + unsigned context); + +int rtp_add_recipient(const struct sockaddr_storage *sa); +int rtp_remove_recipient(const struct sockaddr_storage *sa); + +extern uint64_t uaudio_schedule_timestamp; +extern int uaudio_schedule_reactivated; #if HAVE_COREAUDIO_AUDIOHARDWARE_H extern const struct uaudio uaudio_coreaudio; @@ -116,9 +200,15 @@ extern const struct uaudio uaudio_alsa; extern const struct uaudio uaudio_oss; #endif +#if HAVE_PULSEAUDIO +extern const struct uaudio uaudio_pulseaudio; +#endif + extern const struct uaudio uaudio_rtp; -extern const struct uaudio *uaudio_apis[]; +extern const struct uaudio uaudio_command; + +extern const struct uaudio *const uaudio_apis[]; #endif /* UAUDIO_H */