X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/7a2c706849ecf6cee19d9e502f8491ffac3322e0..67895023d60fc492720d2f575045ed0173948947:/lib/uaudio.c diff --git a/lib/uaudio.c b/lib/uaudio.c index aa00f66..7f506ee 100644 --- a/lib/uaudio.c +++ b/lib/uaudio.c @@ -28,42 +28,73 @@ /** @brief Options for chosen uaudio API */ static hash *uaudio_options; +/** @brief Sample rate (Hz) */ +int uaudio_rate; + +/** @brief Bits per channel */ +int uaudio_bits; + +/** @brief Number of channels */ +int uaudio_channels; + +/** @brief Whether samples are signed or unsigned */ +int uaudio_signed; + +/** @brief Sample size in bytes + * + * NB one sample is a single point sample; up to @c uaudio_channels samples may + * play at the same time through different speakers. Thus this value is + * independent of @ref uaudio_channels. + */ +size_t uaudio_sample_size; + /** @brief Set a uaudio option */ void uaudio_set(const char *name, const char *value) { + if(!value) { + if(uaudio_options) + hash_remove(uaudio_options, name); + return; + } if(!uaudio_options) uaudio_options = hash_new(sizeof(char *)); value = xstrdup(value); hash_add(uaudio_options, name, &value, HASH_INSERT_OR_REPLACE); } -/** @brief Set a uaudio option */ -const char *uaudio_get(const char *name) { - const char *value = (uaudio_options ? - *(char **)hash_find(uaudio_options, name) - : NULL); - return value ? xstrdup(value) : NULL; +/** @brief Get a uaudio option */ +char *uaudio_get(const char *name, const char *default_value) { + if(!uaudio_options) + return default_value ? xstrdup(default_value) : 0; + char **valuep = hash_find(uaudio_options, name); + if(!valuep) + return default_value ? xstrdup(default_value) : 0; + return xstrdup(*valuep); } -/** @brief List of known APIs +/** @brief Set sample format + * @param rate Sample rate in KHz + * @param channels Number of channels (i.e. 2 for stereo) + * @param bits Number of bits per channel (typically 8 or 16) + * @param signed_ True for signed samples, false for unsigned * - * Terminated by a null pointer. + * Sets @ref uaudio_rate, @ref uaudio_channels, @ref uaudio_bits, @ref + * uaudio_signed and @ref uaudio_sample_size. * - * The first one will be used as a default, so putting ALSA before OSS - * constitutes a policy decision. + * Currently there is no way to specify non-native endian formats even if the + * underlying API can conveniently handle them. Actually this would be quite + * convenient for playrtp, so it might be added at some point. + * + * Not all APIs can support all sample formats. Generally the @c start + * function will do some error checking but some may be deferred to the point + * the device is opened (which might be @c activate). */ -const struct uaudio *uaudio_apis[] = { -#if HAVE_COREAUDIO_AUDIOHARDWARE_H - &uaudio_coreaudio, -#endif -#if HAVE_ALSA_ASOUNDLIB_H - &uaudio_alsa, -#endif -#if HAVE_SYS_SOUNDCARD_H || EMPEG_HOST - &uaudio_oss, -#endif - &uaudio_rtp, - NULL, -}; +void uaudio_set_format(int rate, int channels, int bits, int signed_) { + uaudio_rate = rate; + uaudio_channels = channels; + uaudio_bits = bits; + uaudio_signed = signed_; + uaudio_sample_size = bits / CHAR_BIT; +} /* Local Variables: