(rsound) Cleanups

This commit is contained in:
twinaphex 2015-04-03 16:06:57 +02:00
parent 67867311d9
commit 9a989462f1
3 changed files with 200 additions and 200 deletions

View File

@ -55,6 +55,7 @@ static void err_cb(void *userdata)
static void *rs_init(const char *device, unsigned rate, unsigned latency) static void *rs_init(const char *device, unsigned rate, unsigned latency)
{ {
int channels, format;
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t)); rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
if (!rsd) if (!rsd)
return NULL; return NULL;
@ -72,8 +73,8 @@ static void *rs_init(const char *device, unsigned rate, unsigned latency)
rsd->buffer = fifo_new(1024 * 4); rsd->buffer = fifo_new(1024 * 4);
int channels = 2; channels = 2;
int format = RSD_S16_NE; format = RSD_S16_NE;
rsd_set_param(rd, RSD_CHANNELS, &channels); rsd_set_param(rd, RSD_CHANNELS, &channels);
rsd_set_param(rd, RSD_SAMPLERATE, &rate); rsd_set_param(rd, RSD_SAMPLERATE, &rate);
@ -106,9 +107,13 @@ static ssize_t rs_write(void *data, const void *buf, size_t size)
if (rsd->nonblock) if (rsd->nonblock)
{ {
size_t avail, write_amt;
rsd_callback_lock(rsd->rd); rsd_callback_lock(rsd->rd);
size_t avail = fifo_write_avail(rsd->buffer);
size_t write_amt = avail > size ? size : avail; avail = fifo_write_avail(rsd->buffer);
write_amt = avail > size ? size : avail;
fifo_write(rsd->buffer, buf, write_amt); fifo_write(rsd->buffer, buf, write_amt);
rsd_callback_unlock(rsd->rd); rsd_callback_unlock(rsd->rd);
return write_amt; return write_amt;
@ -118,8 +123,10 @@ static ssize_t rs_write(void *data, const void *buf, size_t size)
size_t written = 0; size_t written = 0;
while (written < size && !rsd->has_error) while (written < size && !rsd->has_error)
{ {
size_t avail;
rsd_callback_lock(rsd->rd); rsd_callback_lock(rsd->rd);
size_t avail = fifo_write_avail(rsd->buffer);
avail = fifo_write_avail(rsd->buffer);
if (avail == 0) if (avail == 0)
{ {

View File

@ -87,13 +87,12 @@ extern "C" {
#define RSD_SET_CALLBACK RSD_SET_CALLBACK #define RSD_SET_CALLBACK RSD_SET_CALLBACK
#define RSD_CALLBACK_LOCK RSD_CALLBACK_LOCK #define RSD_CALLBACK_LOCK RSD_CALLBACK_LOCK
#define RSD_CALLBACK_UNLOCK RSD_CALLBACK_UNLOCK #define RSD_CALLBACK_UNLOCK RSD_CALLBACK_UNLOCK
/* End feature tests */ /* End feature tests */
/* Defines sample formats available. Defaults to S16_LE should it never be set. */
enum rsd_format
/* Defines sample formats available. Defaults to S16_LE should it never be set. */ {
enum rsd_format
{
RSD_NO_FMT = 0x0000, RSD_NO_FMT = 0x0000,
RSD_S16_LE = 0x0001, RSD_S16_LE = 0x0001,
RSD_S16_BE = 0x0002, RSD_S16_BE = 0x0002,
@ -111,11 +110,11 @@ extern "C" {
RSD_U32_LE = 0x2000, RSD_U32_LE = 0x2000,
RSD_U32_BE = 0x4000, RSD_U32_BE = 0x4000,
RSD_U32_NE = 0x8000, RSD_U32_NE = 0x8000,
}; };
/* Defines operations that can be used with rsd_set_param() */ /* Defines operations that can be used with rsd_set_param() */
enum rsd_settings enum rsd_settings
{ {
RSD_SAMPLERATE = 0, RSD_SAMPLERATE = 0,
RSD_CHANNELS, RSD_CHANNELS,
RSD_HOST, RSD_HOST,
@ -124,18 +123,20 @@ extern "C" {
RSD_LATENCY, RSD_LATENCY,
RSD_FORMAT, RSD_FORMAT,
RSD_IDENTITY RSD_IDENTITY
}; };
/* Audio callback for rsd_set_callback. Return -1 to trigger an error in the stream. */ /* Audio callback for rsd_set_callback. Return -1 to trigger an error in the stream. */
typedef ssize_t (*rsd_audio_callback_t)(void *data, size_t bytes, void *userdata); typedef ssize_t (*rsd_audio_callback_t)(void *data, size_t bytes, void *userdata);
/* Error callback. Signals caller that stream has been stopped, either by audio callback returning -1 or stream was hung up. */ /* Error callback. Signals caller that stream has been stopped,
typedef void (*rsd_error_callback_t)(void *userdata); * either by audio callback returning -1 or stream was hung up. */
typedef void (*rsd_error_callback_t)(void *userdata);
/* Defines the main structure for use with the API. */ /* Defines the main structure for use with the API. */
typedef struct rsound typedef struct rsound
{
struct
{ {
struct {
volatile int socket; volatile int socket;
volatile int ctl_socket; volatile int ctl_socket;
} conn; } conn;
@ -158,7 +159,8 @@ extern "C" {
int delay_offset; int delay_offset;
int max_latency; int max_latency;
struct { struct
{
uint32_t latency; uint32_t latency;
uint32_t chunk_size; uint32_t chunk_size;
} backend_info; } backend_info;
@ -170,7 +172,8 @@ extern "C" {
uint16_t format; uint16_t format;
int samplesize; int samplesize;
struct { struct
{
sthread_t *thread; sthread_t *thread;
slock_t *mutex; slock_t *mutex;
slock_t *cond_mutex; slock_t *cond_mutex;
@ -184,12 +187,12 @@ extern "C" {
size_t cb_max_size; size_t cb_max_size;
void *cb_data; void *cb_data;
slock_t *cb_lock; slock_t *cb_lock;
} rsound_t; } rsound_t;
/* -- API -- /* -- API --
All functions (except for rsd_write() return 0 for success, and -1 for error. errno is currently not set. */ All functions (except for rsd_write() return 0 for success, and -1 for error. errno is currently not set. */
/* Initializes an rsound_t structure. To make sure no memory leaks occur, you need to rsd_free() it after use. /* Initializes an rsound_t structure. To make sure no memory leaks occur, you need to rsd_free() it after use.
A typical use of the API is as follows: A typical use of the API is as follows:
rsound_t *rd; rsound_t *rd;
rsd_init(&rd); rsd_init(&rd);
@ -200,53 +203,51 @@ extern "C" {
rsd_stop(rd); rsd_stop(rd);
rsd_free(rd); rsd_free(rd);
*/ */
int rsd_init (rsound_t **rd); int rsd_init (rsound_t **rd);
/* This is a simpler function that initializes an rsound struct, sets params as given,
/* This is a simpler function that initializes an rsound struct, sets params as given,
and starts the stream. Should this function fail, the structure will stay uninitialized. and starts the stream. Should this function fail, the structure will stay uninitialized.
Should NULL be passed in either host, port or ident, defaults will be used. */ Should NULL be passed in either host, port or ident, defaults will be used. */
int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const char* ident, int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const char* ident,
int rate, int channels, enum rsd_format format); int rate, int channels, enum rsd_format format);
/* Sets params associated with an rsound_t. These options (int options) include:
/* Sets params associated with an rsound_t. These options (int options) include: RSD_HOST: Server to connect to. Expects (char *) in param.
If not set, will default to environmental variable RSD_SERVER or "localhost".
RSD_HOST: Server to connect to. Expects (char *) in param. RSD_PORT: Set port. Expects (char *) in param.
If not set, will default to environmental variable RSD_SERVER or "localhost". If not set, will default to environmental variable RSD_PORT or "12345".
RSD_PORT: Set port. Expects (char *) in param. RSD_CHANNELS: Set number of audio channels. Expects (int *) in param. Mandatory.
If not set, will default to environmental variable RSD_PORT or "12345".
RSD_CHANNELS: Set number of audio channels. Expects (int *) in param. Mandatory. RSD_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory.
RSD_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory. RSD_BUFSIZE: Sets internal buffersize for the stream.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_BUFSIZE: Sets internal buffersize for the stream. RSD_LATENCY: Sets maximum audio latency in milliseconds,
Might be overridden if too small. (must be used with rsd_delay_wait() or this will have no effect).
Expects (int *) in param. Optional. Most applications do not need this.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_LATENCY: Sets maximum audio latency in milliseconds, RSD_FORMAT: Sets sample format.
(must be used with rsd_delay_wait() or this will have no effect). It defaults to S16_LE, so you probably will not use this.
Most applications do not need this. Expects (int *) in param, with available values found in the format enum.
Might be overridden if too small. If invalid format is given, param might be changed to reflect the sample format the library will use.
Expects (int *) in param. Optional.
RSD_FORMAT: Sets sample format. RSD_IDENTITY: Sets an identity string associated with the client.
It defaults to S16_LE, so you probably will not use this. Takes a (char *) parameter with the stream name.
Expects (int *) in param, with available values found in the format enum. Will be truncated if longer than 256 bytes.
If invalid format is given, param might be changed to reflect the sample format the library will use.
RSD_IDENTITY: Sets an identity string associated with the client. */
Takes a (char *) parameter with the stream name.
Will be truncated if longer than 256 bytes.
*/ int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param);
int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param); /* Enables use of the callback interface. This must be set when stream is not active.
/* Enables use of the callback interface. This must be set when stream is not active.
When callback is active, use of the blocking interface is disabled. When callback is active, use of the blocking interface is disabled.
Only valid functions to call after rsd_start() is stopping the stream with either rsd_pause() or rsd_stop(). Calling any other function is undefined. Only valid functions to call after rsd_start() is stopping the stream with either rsd_pause() or rsd_stop(). Calling any other function is undefined.
The callback is called at regular intervals and is asynchronous, so thread safety must be ensured by the caller. The callback is called at regular intervals and is asynchronous, so thread safety must be ensured by the caller.
@ -257,77 +258,68 @@ extern "C" {
Callbacks can be disabled by setting callbacks to NULL. */ Callbacks can be disabled by setting callbacks to NULL. */
void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_callback_t err_callback, size_t max_size, void *userdata); void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_callback_t err_callback, size_t max_size, void *userdata);
/* Lock and unlock the callback. When the callback lock is aquired, the callback is guaranteed to not be executing. /* Lock and unlock the callback. When the callback lock is aquired, the callback is guaranteed to not be executing.
The lock has to be unlocked afterwards. The lock has to be unlocked afterwards.
Attemping to call several rsd_callback_lock() in succession might cause a deadlock. Attemping to call several rsd_callback_lock() in succession might cause a deadlock.
The lock should be held for as short period as possible. The lock should be held for as short period as possible.
Try to avoid calling code that may block when holding the lock. */ Try to avoid calling code that may block when holding the lock. */
void rsd_callback_lock (rsound_t *rd); void rsd_callback_lock (rsound_t *rd);
void rsd_callback_unlock (rsound_t *rd);
/* Establishes connection to server. Might fail if connection can't be established or that one of void rsd_callback_unlock (rsound_t *rd);
/* Establishes connection to server. Might fail if connection can't be established or that one of
the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set
with rsd_set_param(), and before rsd_write(). */ with rsd_set_param(), and before rsd_write(). */
int rsd_start (rsound_t *rd); int rsd_start (rsound_t *rd);
/* Shuts down the rsound data structures, but returns the file descriptor associated with the connection. /* Shuts down the rsound data structures, but returns the file descriptor associated with the connection.
The control socket will be shut down. If this function returns a negative number, the exec failed, The control socket will be shut down. If this function returns a negative number, the exec failed,
but the data structures will not be teared down. but the data structures will not be teared down.
Should a valid file descriptor be returned, it will always be blocking. Should a valid file descriptor be returned, it will always be blocking.
This call will block until all internal buffers have been sent to the network. */ This call will block until all internal buffers have been sent to the network. */
int rsd_exec (rsound_t *rd); int rsd_exec (rsound_t *rd);
/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped. /* Disconnects from server. All audio data still in network buffer and other buffers will be dropped.
To continue playing, you will need to rsd_start() again. */ To continue playing, you will need to rsd_start() again. */
int rsd_stop (rsound_t *rd); int rsd_stop (rsound_t *rd);
/* Writes from buf to the internal buffer. Might fail if no connection is established, /* Writes from buf to the internal buffer. Might fail if no connection is established,
or there was an unexpected error. This function will block until all data has or there was an unexpected error. This function will block until all data has
been written to the buffer. This function will return the number of bytes written to the buffer, been written to the buffer. This function will return the number of bytes written to the buffer,
or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */ or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */
size_t rsd_write (rsound_t *rd, const void* buf, size_t size); size_t rsd_write (rsound_t *rd, const void* buf, size_t size);
/* Gets the position of the buffer pointer. /* Gets the position of the buffer pointer.
Not really interesting for normal applications. Not really interesting for normal applications.
Might be useful for implementing rsound on top of other blocking APIs. Might be useful for implementing rsound on top of other blocking APIs.
*NOTE* This function is deprecated, it should not be used in new applications. */ *NOTE* This function is deprecated, it should not be used in new applications. */
size_t rsd_pointer (rsound_t *rd); size_t rsd_pointer (rsound_t *rd);
/* Aquires how much data can be written to the buffer without blocking */ /* Aquires how much data can be written to the buffer without blocking */
size_t rsd_get_avail (rsound_t *rd); size_t rsd_get_avail (rsound_t *rd);
/* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */ /* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */
size_t rsd_delay (rsound_t *rd); size_t rsd_delay (rsound_t *rd);
/* Utility for returning latency in milliseconds. */ /* Utility for returning latency in milliseconds. */
size_t rsd_delay_ms (rsound_t *rd); size_t rsd_delay_ms (rsound_t *rd);
/* Returns bytes per sample */ /* Returns bytes per sample */
int rsd_samplesize(rsound_t *rd); int rsd_samplesize(rsound_t *rd);
/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY /* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY
Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set
with RSD_LATENCY, this function will do nothing. */ with RSD_LATENCY, this function will do nothing. */
void rsd_delay_wait(rsound_t *rd); void rsd_delay_wait(rsound_t *rd);
/* Pauses or unpauses a stream. pause -> enable = 1
/* Pauses or unpauses a stream. pause -> enable = 1
This function essentially calls on start() and stop(). This behavior might be changed later. */ This function essentially calls on start() and stop(). This behavior might be changed later. */
int rsd_pause (rsound_t *rd, int enable); int rsd_pause (rsound_t *rd, int enable);
/* Frees an rsound_t struct. Make sure that the stream is properly closed down with rsd_stop() before calling rsd_free(). */ /* Frees an rsound_t struct. Make sure that the stream is properly closed down with rsd_stop() before calling rsd_free(). */
int rsd_free (rsound_t *rd); int rsd_free (rsound_t *rd);
#ifndef HAVE_STRL
// Avoid possible naming collisions during link since we prefer to use the actual name.
#define strlcpy(dst, src, size) strlcpy_rarch__(dst, src, size)
#define strlcat(dst, src, size) strlcat_rarch__(dst, src, size)
size_t strlcpy(char *dest, const char *source, size_t size);
size_t strlcat(char *dest, const char *source, size_t size);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -69,6 +69,7 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <compat/strl.h>
#include <retro_inline.h> #include <retro_inline.h>
/* /*