(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)
{
int channels, format;
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
if (!rsd)
return NULL;
@ -72,8 +73,8 @@ static void *rs_init(const char *device, unsigned rate, unsigned latency)
rsd->buffer = fifo_new(1024 * 4);
int channels = 2;
int format = RSD_S16_NE;
channels = 2;
format = RSD_S16_NE;
rsd_set_param(rd, RSD_CHANNELS, &channels);
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)
{
size_t avail, write_amt;
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);
rsd_callback_unlock(rsd->rd);
return write_amt;
@ -118,8 +123,10 @@ static ssize_t rs_write(void *data, const void *buf, size_t size)
size_t written = 0;
while (written < size && !rsd->has_error)
{
size_t avail;
rsd_callback_lock(rsd->rd);
size_t avail = fifo_write_avail(rsd->buffer);
avail = fifo_write_avail(rsd->buffer);
if (avail == 0)
{

View File

@ -87,247 +87,239 @@ extern "C" {
#define RSD_SET_CALLBACK RSD_SET_CALLBACK
#define RSD_CALLBACK_LOCK RSD_CALLBACK_LOCK
#define RSD_CALLBACK_UNLOCK RSD_CALLBACK_UNLOCK
/* End feature tests */
/* Defines sample formats available. Defaults to S16_LE should it never be set. */
enum rsd_format
{
RSD_NO_FMT = 0x0000,
RSD_S16_LE = 0x0001,
RSD_S16_BE = 0x0002,
RSD_U16_LE = 0x0004,
RSD_U16_BE = 0x0008,
RSD_U8 = 0x0010,
RSD_S8 = 0x0020,
RSD_S16_NE = 0x0040,
RSD_U16_NE = 0x0080,
RSD_ALAW = 0x0100,
RSD_MULAW = 0x0200,
RSD_S32_LE = 0x0400,
RSD_S32_BE = 0x0800,
RSD_S32_NE = 0x1000,
RSD_U32_LE = 0x2000,
RSD_U32_BE = 0x4000,
RSD_U32_NE = 0x8000,
};
/* Defines operations that can be used with rsd_set_param() */
enum rsd_settings
{
RSD_SAMPLERATE = 0,
RSD_CHANNELS,
RSD_HOST,
RSD_PORT,
RSD_BUFSIZE,
RSD_LATENCY,
RSD_FORMAT,
RSD_IDENTITY
};
/* Defines sample formats available. Defaults to S16_LE should it never be set. */
enum rsd_format
/* 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);
/* Error callback. Signals caller that stream has been stopped,
* 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. */
typedef struct rsound
{
struct
{
RSD_NO_FMT = 0x0000,
RSD_S16_LE = 0x0001,
RSD_S16_BE = 0x0002,
RSD_U16_LE = 0x0004,
RSD_U16_BE = 0x0008,
RSD_U8 = 0x0010,
RSD_S8 = 0x0020,
RSD_S16_NE = 0x0040,
RSD_U16_NE = 0x0080,
RSD_ALAW = 0x0100,
RSD_MULAW = 0x0200,
RSD_S32_LE = 0x0400,
RSD_S32_BE = 0x0800,
RSD_S32_NE = 0x1000,
RSD_U32_LE = 0x2000,
RSD_U32_BE = 0x4000,
RSD_U32_NE = 0x8000,
};
volatile int socket;
volatile int ctl_socket;
} conn;
/* Defines operations that can be used with rsd_set_param() */
enum rsd_settings
char *host;
char *port;
char *buffer; /* Obsolete, but kept for backwards header compatibility. */
int conn_type;
volatile int buffer_pointer; /* Obsolete, but kept for backwards header compatibility. */
size_t buffer_size;
fifo_buffer_t *fifo_buffer;
volatile int thread_active;
int64_t total_written;
int64_t start_time;
volatile int has_written;
int bytes_in_buffer;
int delay_offset;
int max_latency;
struct
{
RSD_SAMPLERATE = 0,
RSD_CHANNELS,
RSD_HOST,
RSD_PORT,
RSD_BUFSIZE,
RSD_LATENCY,
RSD_FORMAT,
RSD_IDENTITY
};
uint32_t latency;
uint32_t chunk_size;
} backend_info;
/* 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);
volatile int ready_for_data;
/* Error callback. Signals caller that stream has been stopped, either by audio callback returning -1 or stream was hung up. */
typedef void (*rsd_error_callback_t)(void *userdata);
uint32_t rate;
uint32_t channels;
uint16_t format;
int samplesize;
/* Defines the main structure for use with the API. */
typedef struct rsound
struct
{
struct {
volatile int socket;
volatile int ctl_socket;
} conn;
sthread_t *thread;
slock_t *mutex;
slock_t *cond_mutex;
scond_t *cond;
} thread;
char *host;
char *port;
char *buffer; /* Obsolete, but kept for backwards header compatibility. */
int conn_type;
char identity[256];
volatile int buffer_pointer; /* Obsolete, but kept for backwards header compatibility. */
size_t buffer_size;
fifo_buffer_t *fifo_buffer;
rsd_audio_callback_t audio_callback;
rsd_error_callback_t error_callback;
size_t cb_max_size;
void *cb_data;
slock_t *cb_lock;
} rsound_t;
volatile int thread_active;
/* -- API --
All functions (except for rsd_write() return 0 for success, and -1 for error. errno is currently not set. */
int64_t total_written;
int64_t start_time;
volatile int has_written;
int bytes_in_buffer;
int delay_offset;
int max_latency;
struct {
uint32_t latency;
uint32_t chunk_size;
} backend_info;
volatile int ready_for_data;
uint32_t rate;
uint32_t channels;
uint16_t format;
int samplesize;
struct {
sthread_t *thread;
slock_t *mutex;
slock_t *cond_mutex;
scond_t *cond;
} thread;
char identity[256];
rsd_audio_callback_t audio_callback;
rsd_error_callback_t error_callback;
size_t cb_max_size;
void *cb_data;
slock_t *cb_lock;
} rsound_t;
/* -- API --
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:
rsound_t *rd;
rsd_init(&rd);
rsd_set_param(rd, RSD_HOST, "foohost");
*sets more params*
rsd_start(rd);
rsd_write(rd, buf, size);
rsd_stop(rd);
rsd_free(rd);
*/
int rsd_init (rsound_t **rd);
rsound_t *rd;
rsd_init(&rd);
rsd_set_param(rd, RSD_HOST, "foohost");
*sets more params*
rsd_start(rd);
rsd_write(rd, buf, size);
rsd_stop(rd);
rsd_free(rd);
*/
int rsd_init (rsound_t **rd);
/* 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.
Should NULL be passed in either host, port or ident, defaults will be used. */
/* 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.
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 rate, int channels, enum rsd_format format);
int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const char* ident,
int rate, int channels, enum rsd_format format);
/* 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".
/* Sets params associated with an rsound_t. These options (int options) include:
RSD_PORT: Set port. Expects (char *) in param.
If not set, will default to environmental variable RSD_PORT or "12345".
RSD_HOST: Server to connect to. Expects (char *) in param.
If not set, will default to environmental variable RSD_SERVER or "localhost".
RSD_CHANNELS: Set number of audio channels. Expects (int *) in param. Mandatory.
RSD_PORT: Set port. Expects (char *) in param.
If not set, will default to environmental variable RSD_PORT or "12345".
RSD_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory.
RSD_CHANNELS: Set number of audio channels. 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_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory.
RSD_LATENCY: Sets maximum audio latency in milliseconds,
(must be used with rsd_delay_wait() or this will have no effect).
Most applications do not need this.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_BUFSIZE: Sets internal buffersize for the stream.
Might be overridden if too small.
Expects (int *) in param. Optional.
RSD_FORMAT: Sets sample format.
It defaults to S16_LE, so you probably will not use this.
Expects (int *) in param, with available values found in the format enum.
If invalid format is given, param might be changed to reflect the sample format the library will use.
RSD_LATENCY: Sets maximum audio latency in milliseconds,
(must be used with rsd_delay_wait() or this will have no effect).
Most applications do not need this.
Might be overridden if too small.
Expects (int *) in param. Optional.
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.
RSD_FORMAT: Sets sample format.
It defaults to S16_LE, so you probably will not use this.
Expects (int *) in param, with available values found in the format enum.
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);
*/
/* 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.
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.
If not enough data can be given to the callback, librsound will fill the rest of the callback data with silence.
librsound will attempt to obey latency information given with RSD_LATENCY as given before calling rsd_start().
max_size signifies the maximum size that will ever be requested by librsound. Set this to 0 to let librsound decide the maximum size.
Should an error occur to the stream, err_callback will be called, and the stream will be stopped. The stream can be started again.
int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param);
Callbacks can be disabled by setting callbacks to NULL. */
/* 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.
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.
If not enough data can be given to the callback, librsound will fill the rest of the callback data with silence.
librsound will attempt to obey latency information given with RSD_LATENCY as given before calling rsd_start().
max_size signifies the maximum size that will ever be requested by librsound. Set this to 0 to let librsound decide the maximum size.
Should an error occur to the stream, err_callback will be called, and the stream will be stopped. The stream can be started again.
void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_callback_t err_callback, size_t max_size, void *userdata);
Callbacks can be disabled by setting callbacks to NULL. */
/* 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.
Attemping to call several rsd_callback_lock() in succession might cause a deadlock.
The lock should be held for as short period as possible.
Try to avoid calling code that may block when holding the lock. */
void rsd_callback_lock (rsound_t *rd);
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_callback_unlock (rsound_t *rd);
/* 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.
Attemping to call several rsd_callback_lock() in succession might cause a deadlock.
The lock should be held for as short period as possible.
Try to avoid calling code that may block when holding the lock. */
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
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(). */
int rsd_start (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
with rsd_set_param(), and before rsd_write(). */
int rsd_start (rsound_t *rd);
/* 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,
but the data structures will not be teared down.
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. */
int rsd_exec (rsound_t *rd);
/* 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,
but the data structures will not be teared down.
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. */
int rsd_exec (rsound_t *rd);
/* 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. */
int rsd_stop (rsound_t *rd);
/* 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. */
int rsd_stop (rsound_t *rd);
/* 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
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. */
size_t rsd_write (rsound_t *rd, const void* buf, size_t size);
/* 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
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. */
size_t rsd_write (rsound_t *rd, const void* buf, size_t size);
/* Gets the position of the buffer pointer.
Not really interesting for normal applications.
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. */
size_t rsd_pointer (rsound_t *rd);
/* Gets the position of the buffer pointer.
Not really interesting for normal applications.
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. */
size_t rsd_pointer (rsound_t *rd);
/* Aquires how much data can be written to the buffer without blocking */
size_t rsd_get_avail (rsound_t *rd);
/* Aquires how much data can be written to the buffer without blocking */
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. */
size_t rsd_delay (rsound_t *rd);
/* 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);
/* Utility for returning latency in milliseconds. */
size_t rsd_delay_ms (rsound_t *rd);
/* Utility for returning latency in milliseconds. */
size_t rsd_delay_ms (rsound_t *rd);
/* Returns bytes per sample */
int rsd_samplesize(rsound_t *rd);
/* Returns bytes per sample */
int rsd_samplesize(rsound_t *rd);
/* 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
with RSD_LATENCY, this function will do nothing. */
void rsd_delay_wait(rsound_t *rd);
/* 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
with RSD_LATENCY, this function will do nothing. */
void rsd_delay_wait(rsound_t *rd);
/* Pauses or unpauses a stream. pause -> enable = 1
This function essentially calls on start() and stop(). This behavior might be changed later. */
int rsd_pause (rsound_t *rd, int enable);
/* Pauses or unpauses a stream. pause -> enable = 1
This function essentially calls on start() and stop(). This behavior might be changed later. */
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(). */
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
/* 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);
#ifdef __cplusplus
}

View File

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