mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 22:38:34 +00:00
(rsound) Cleanups
This commit is contained in:
parent
67867311d9
commit
9a989462f1
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user