diff --git a/Makefile.ps3 b/Makefile.ps3
index 96daa6c994..d290571656 100644
--- a/Makefile.ps3
+++ b/Makefile.ps3
@@ -39,7 +39,7 @@ INCDIRS = -I. -Icommon
MKFSELF_NPDRM = $(CELL_SDK)/$(HOST_DIR)/bin/make_fself_npdrm
MKPKG_NPDRM = $(CELL_SDK)/$(HOST_DIR)/bin/make_package_npdrm
-OBJ = getopt.o ssnes.o driver.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o gfx/gl.c gfx/shader_cg.c gfx/snes_state.c ups.o bps.o strl.o screenshot.o thread.o audio/hermite.o
+OBJ = ps3/buffer.o ps3/ps3_audio.o ps3/resampler.o getopt.o ssnes.o driver.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o gfx/gl.c gfx/shader_cg.c gfx/snes_state.c ups.o bps.o strl.o screenshot.o thread.o audio/hermite.o
LIBS = -ldbgfont -lPSGL -lgcm_cmd -lgcm_sys_stub -lresc_stub libsnes.a -lm -lio_stub -lfs_stub -lsysutil_stub -lsysmodule_stub -laudio_stub -lnet_stub -lpthread
diff --git a/config.def.h b/config.def.h
index 8e8aa7777a..0df3eb5815 100644
--- a/config.def.h
+++ b/config.def.h
@@ -50,6 +50,7 @@
#define AUDIO_EXT 15
#define AUDIO_DSOUND 16
#define AUDIO_COREAUDIO 17
+#define AUDIO_PS3 18
////////////////////////
#define INPUT_SDL 7
#define INPUT_X 12
diff --git a/driver.c b/driver.c
index 6cf71584e0..e4dde30760 100644
--- a/driver.c
+++ b/driver.c
@@ -29,6 +29,9 @@
#endif
static const audio_driver_t *audio_drivers[] = {
+#ifdef __CELLOS_LV2__
+ &audio_ps3,
+#endif
#ifdef HAVE_ALSA
&audio_alsa,
#endif
diff --git a/driver.h b/driver.h
index bc66a8dee7..08742596f8 100644
--- a/driver.h
+++ b/driver.h
@@ -167,6 +167,9 @@ extern const audio_driver_t audio_pulse;
extern const audio_driver_t audio_ext;
extern const audio_driver_t audio_dsound;
extern const audio_driver_t audio_coreaudio;
+#ifdef __CELLOS_LV2__
+extern const audio_driver_t audio_ps3;
+#endif
extern const video_driver_t video_gl;
extern const video_driver_t video_xvideo;
extern const video_driver_t video_sdl;
diff --git a/ps3/buffer.c b/ps3/buffer.c
new file mode 100644
index 0000000000..576cd14841
--- /dev/null
+++ b/ps3/buffer.c
@@ -0,0 +1,101 @@
+/* RSound - A PCM audio client/server
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * RSound is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RSound is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RSound.
+ * If not, see .
+ */
+
+#include "buffer.h"
+
+struct fifo_buffer
+{
+ char *buffer;
+ size_t bufsize;
+ size_t first;
+ size_t end;
+};
+
+fifo_buffer_t* fifo_new(size_t size)
+{
+ fifo_buffer_t *buf = calloc(1, sizeof(*buf));
+ if (buf == NULL)
+ return NULL;
+
+ buf->buffer = calloc(1, size + 1);
+ if (buf->buffer == NULL)
+ {
+ free(buf);
+ return NULL;
+ }
+ buf->bufsize = size + 1;
+
+ return buf;
+}
+
+void fifo_free(fifo_buffer_t* buffer)
+{
+ free(buffer->buffer);
+ free(buffer);
+}
+
+size_t fifo_read_avail(fifo_buffer_t* buffer)
+{
+ size_t first = buffer->first;
+ size_t end = buffer->end;
+ if (end < first)
+ end += buffer->bufsize;
+ return end - first;
+}
+
+size_t fifo_write_avail(fifo_buffer_t* buffer)
+{
+ size_t first = buffer->first;
+ size_t end = buffer->end;
+ if (end < first)
+ end += buffer->bufsize;
+
+ return (buffer->bufsize - 1) - (end - first);
+}
+
+void fifo_write(fifo_buffer_t* buffer, const void* in_buf, size_t size)
+{
+ size_t first_write = size;
+ size_t rest_write = 0;
+ if (buffer->end + size > buffer->bufsize)
+ {
+ first_write = buffer->bufsize - buffer->end;
+ rest_write = size - first_write;
+ }
+
+ memcpy(buffer->buffer + buffer->end, in_buf, first_write);
+ if (rest_write > 0)
+ memcpy(buffer->buffer, (const char*)in_buf + first_write, rest_write);
+
+ buffer->end = (buffer->end + size) % buffer->bufsize;
+}
+
+
+void fifo_read(fifo_buffer_t* buffer, void* in_buf, size_t size)
+{
+ size_t first_read = size;
+ size_t rest_read = 0;
+ if (buffer->first + size > buffer->bufsize)
+ {
+ first_read = buffer->bufsize - buffer->first;
+ rest_read = size - first_read;
+ }
+
+ memcpy(in_buf, (const char*)buffer->buffer + buffer->first, first_read);
+ if (rest_read > 0)
+ memcpy((char*)in_buf + first_read, buffer->buffer, rest_read);
+
+ buffer->first = (buffer->first + size) % buffer->bufsize;
+}
diff --git a/ps3/buffer.h b/ps3/buffer.h
new file mode 100644
index 0000000000..e7cb3497f1
--- /dev/null
+++ b/ps3/buffer.h
@@ -0,0 +1,32 @@
+/* RSound - A PCM audio client/server
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * RSound is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RSound is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RSound.
+ * If not, see .
+ */
+
+#ifndef __BUFFER_H
+#define __BUFFER_H
+
+#include
+#include
+#include
+
+typedef struct fifo_buffer fifo_buffer_t;
+
+fifo_buffer_t* fifo_new(size_t size);
+void fifo_write(fifo_buffer_t* buffer, const void* in_buf, size_t size);
+void fifo_read(fifo_buffer_t* buffer, void* in_buf, size_t size);
+void fifo_free(fifo_buffer_t* buffer);
+size_t fifo_read_avail(fifo_buffer_t* buffer);
+size_t fifo_write_avail(fifo_buffer_t* buffer);
+
+#endif
diff --git a/ps3/ps3_audio.c b/ps3/ps3_audio.c
new file mode 100644
index 0000000000..1fe74a7542
--- /dev/null
+++ b/ps3/ps3_audio.c
@@ -0,0 +1,205 @@
+/* SSNES - A Super Ninteno Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+#include "../driver.h"
+#include
+#include
+#include
+#include
+#include
+#include "buffer.h"
+#include "resampler.h"
+#include
+
+#define AUDIO_BLOCKS 8 // 8 or 16. Guess what we choose? :)
+#define AUDIO_CHANNELS 2 // All hail glorious stereo!
+#define AUDIO_OUT_RATE (48000.0)
+
+typedef struct
+{
+ float tmp_data[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS];
+ uint32_t audio_port;
+ bool nonblocking;
+ volatile bool quit_thread;
+ fifo_buffer_t *buffer;
+ uint64_t input_rate;
+
+ pthread_t thread;
+ pthread_mutex_t lock;
+ pthread_mutex_t cond_lock;
+ pthread_cond_t cond;
+} ps3_audio_t;
+
+static size_t drain_fifo(void *cb_data, float **data)
+{
+ ps3_audio_t *aud = cb_data;
+
+ int16_t tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS];
+
+ if (fifo_read_avail(aud->buffer) >= sizeof(tmp))
+ {
+ pthread_mutex_lock(&aud->lock);
+ fifo_read(aud->buffer, tmp, sizeof(tmp));
+ pthread_mutex_unlock(&aud->lock);
+ resampler_s16_to_float(aud->tmp_data, tmp, CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS);
+ }
+ else
+ {
+ memset(aud->tmp_data, 0, sizeof(aud->tmp_data));
+ }
+ *data = aud->tmp_data;
+ return CELL_AUDIO_BLOCK_SAMPLES;
+}
+
+static void *event_loop(void *data)
+{
+ ps3_audio_t *aud = data;
+ sys_event_queue_t id;
+ sys_ipc_key_t key;
+ sys_event_t event;
+
+ cellAudioCreateNotifyEventQueue(&id, &key);
+ cellAudioSetNotifyEventQueue(key);
+
+ resampler_t *resampler = resampler_new(drain_fifo, AUDIO_OUT_RATE/aud->input_rate, 2, data);
+
+ float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS] __attribute__((aligned(16)));
+
+ while (!aud->quit_thread)
+ {
+ sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT);
+ resampler_cb_read(resampler, CELL_AUDIO_BLOCK_SAMPLES, out_tmp);
+ cellAudioAddData(aud->audio_port, out_tmp, CELL_AUDIO_BLOCK_SAMPLES, 1.0);
+ pthread_cond_signal(&aud->cond);
+ }
+
+ cellAudioRemoveNotifyEventQueue(key);
+ resampler_free(resampler);
+ pthread_exit(NULL);
+ return NULL;
+}
+
+static void* __ps3_init(const char* device, int rate, int latency)
+{
+ (void)latency;
+ (void)device;
+
+ ps3_audio_t *data = calloc(1, sizeof(*data));
+ if (data == NULL)
+ return NULL;
+
+ CellAudioPortParam params;
+
+ cellAudioInit();
+
+ params.nChannel = AUDIO_CHANNELS;
+ params.nBlock = AUDIO_BLOCKS;
+ params.attr = 0;
+
+ if (cellAudioPortOpen(¶ms, &data->audio_port) != CELL_OK)
+ {
+ cellAudioQuit();
+ return NULL;
+ }
+
+ // Create a small fifo buffer. :)
+ data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(int16_t));
+ data->input_rate = rate;
+
+ pthread_mutex_init(&data->lock, NULL);
+ pthread_mutex_init(&data->cond_lock, NULL);
+ pthread_cond_init(&data->cond, NULL);
+
+ cellAudioPortStart(data->audio_port);
+ pthread_create(&data->thread, NULL, event_loop, data);
+ return data;
+}
+
+// Should make some noise at least. :)
+static ssize_t __ps3_write(void* data, const void* buf, size_t size) // Recieve exactly 1024 bytes at a time.
+{
+ ps3_audio_t *aud = data;
+
+ // We will continuously write slightly more data than we should per second, and rely on blocking mechanisms to ensure we don't write too much.
+ if (aud->nonblocking)
+ {
+ if (fifo_write_avail(aud->buffer) < size)
+ return 0;
+ }
+ else
+ {
+ while (fifo_write_avail(aud->buffer) < size)
+ {
+ pthread_mutex_lock(&aud->cond_lock);
+ pthread_cond_wait(&aud->cond, &aud->lock);
+ pthread_mutex_unlock(&aud->cond_lock);
+ }
+ }
+
+ pthread_mutex_lock(&aud->lock);
+ fifo_write(aud->buffer, buf, size);
+ pthread_mutex_unlock(&aud->lock);
+ return size;
+}
+
+static bool __ps3_stop(void *data)
+{
+ //ps3_audio_t *aud = data;
+ //cellAudioPortStop(aud->audio_port);
+ return true;
+}
+
+static bool __ps3_start(void *data)
+{
+ //ps3_audio_t *aud = data;
+ //cellAudioPortStart(aud->audio_port);
+ return false;
+}
+
+static void __ps3_set_nonblock_state(void *data, bool state)
+{
+ ps3_audio_t *aud = data;
+ aud->nonblocking = state;
+}
+
+static void __ps3_free(void *data)
+{
+ ps3_audio_t *aud = data;
+
+ aud->quit_thread = true;
+ pthread_join(aud->thread, NULL);
+
+ cellAudioPortStop(aud->audio_port);
+ cellAudioPortClose(aud->audio_port);
+ cellAudioQuit();
+ fifo_free(aud->buffer);
+
+ pthread_mutex_destroy(&aud->lock);
+ pthread_mutex_destroy(&aud->cond_lock);
+ pthread_cond_destroy(&aud->cond);
+
+ free(data);
+}
+
+const audio_driver_t audio_ps3 = {
+ .init = __ps3_init,
+ .write = __ps3_write,
+ .stop = __ps3_stop,
+ .start = __ps3_start,
+ .set_nonblock_state = __ps3_set_nonblock_state,
+ .free = __ps3_free
+};
diff --git a/ps3/resampler.c b/ps3/resampler.c
new file mode 100644
index 0000000000..9d07430272
--- /dev/null
+++ b/ps3/resampler.c
@@ -0,0 +1,225 @@
+/* RSound - A PCM audio client/server
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * RSound is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RSound is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RSound.
+ * If not, see .
+ */
+
+
+#include "resampler.h"
+#include
+#include
+#include
+#include
+
+#define SAMPLES_TO_FRAMES(x,y) ((x)/(y)->channels)
+#define FRAMES_TO_SAMPLES(x,y) ((x)*(y)->channels)
+
+struct resampler
+{
+ float *data;
+ double ratio;
+ size_t data_ptr;
+ size_t data_size;
+ void *cb_data;
+ int channels;
+ resampler_cb_t func;
+ uint64_t sum_output_frames;
+ uint64_t sum_input_frames;
+};
+
+resampler_t* resampler_new(resampler_cb_t func, double ratio, int channels, void* cb_data)
+{
+ if (func == NULL)
+ return NULL;
+
+ if (channels < 1)
+ return NULL;
+
+ resampler_t* state = calloc(1, sizeof(resampler_t));
+ if (state == NULL)
+ return NULL;
+
+ state->func = func;
+ state->ratio = ratio;
+ state->channels = channels;
+ state->cb_data = cb_data;
+
+ return state;
+}
+
+void resampler_free(resampler_t* state)
+{
+ if (state && state->data)
+ free(state->data);
+ if (state)
+ free(state);
+}
+
+void resampler_float_to_s16(int16_t * restrict out, const float * restrict in, size_t samples)
+{
+ for (int i = 0; i < (int)samples; i++)
+ {
+ int32_t temp = in[i] * 0x7FFF;
+ if (temp > 0x7FFE)
+ out[i] = 0x7FFE;
+ else if (temp < -0x7FFF)
+ out[i] = -0x7FFF;
+ else
+ out[i] = (int16_t)temp;
+ }
+}
+
+void resampler_s16_to_float(float * restrict out, const int16_t * restrict in, size_t samples)
+{
+ for (int i = 0; i < (int)samples; i++)
+ out[i] = (float)in[i]/0x7FFF;
+}
+
+static size_t resampler_get_required_frames(resampler_t* state, size_t frames)
+{
+ assert(state);
+
+ size_t after_sum = state->sum_output_frames + frames;
+
+ size_t min_input_frames = (size_t)((after_sum / state->ratio) + 2.0);
+ return min_input_frames - state->sum_input_frames;
+}
+
+static void poly_create_3(float *poly, float *y)
+{
+ poly[2] = (y[0] - 2*y[1] + y[2])/2;
+ poly[1] = -1.5*y[0] + 2*y[1] - 0.5*y[2];
+ poly[0] = y[0];
+}
+
+static size_t resampler_process(resampler_t *state, size_t frames, float *out_data)
+{
+ size_t frames_used = 0;
+ uint64_t pos_out;
+ double pos_in = 0.0;
+
+#if 0
+ fprintf(stderr, "=========================================\n");
+ fprintf(stderr, "Output: %zu frames.\n", frames);
+ fprintf(stderr, "Output frames: %zu - %zu\n", state->sum_output_frames, state->sum_output_frames + frames);
+ fprintf(stderr, "Needed input frames: %zu - %zu\n", (size_t)(state->sum_output_frames/state->ratio), (size_t)((state->sum_output_frames + frames)/state->ratio + 1.0));
+ fprintf(stderr, "Current input frames: %zu - %zu\n", state->sum_input_frames, state->sum_input_frames + SAMPLES_TO_FRAMES(state->data_ptr, state));
+ fprintf(stderr, "=========================================\n");
+
+ assert(state->sum_input_frames <= (size_t)(state->sum_output_frames/state->ratio));
+ assert(state->sum_input_frames + SAMPLES_TO_FRAMES(state->data_ptr, state) - 1 >= (size_t)((state->sum_output_frames + frames - 1)/state->ratio + 1.0));
+#endif
+
+ for (uint64_t x = state->sum_output_frames; x < state->sum_output_frames + frames; x++)
+ {
+ pos_out = x - state->sum_output_frames;
+ pos_in = ((double)x / state->ratio) - (double)state->sum_input_frames;
+ //pos_in = pos_out / state->ratio;
+ //fprintf(stderr, "pos_in: %15.7lf\n", pos_in + state->sum_input_frames);
+ for (int c = 0; c < state->channels; c++)
+ {
+
+
+ float poly[3];
+ float data[3];
+ float x_val;
+
+ if ((int)pos_in == 0)
+ {
+ data[0] = state->data[0 * state->channels + c];
+ data[1] = state->data[1 * state->channels + c];
+ data[2] = state->data[2 * state->channels + c];
+ x_val = pos_in;
+ }
+ else
+ {
+ data[0] = state->data[((int)pos_in - 1) * state->channels + c];
+ data[1] = state->data[((int)pos_in + 0) * state->channels + c];
+ data[2] = state->data[((int)pos_in + 1) * state->channels + c];
+ x_val = pos_in - (int)pos_in + 1.0;
+ }
+
+ poly_create_3(poly, data);
+
+ out_data[pos_out * state->channels + c] = poly[2] * x_val * x_val + poly[1] * x_val + poly[0];
+ }
+ }
+ frames_used = (int)pos_in;
+ return frames_used;
+}
+
+ssize_t resampler_cb_read(resampler_t *state, size_t frames, float *data)
+{
+ assert(state);
+ assert(data);
+
+
+ // How many frames must we have to resample?
+ size_t req_frames = resampler_get_required_frames(state, frames);
+
+ // Do we need to read more data?
+ if (SAMPLES_TO_FRAMES(state->data_ptr, state) < req_frames)
+ {
+ size_t must_read = req_frames - SAMPLES_TO_FRAMES(state->data_ptr, state);
+ float temp_buf[FRAMES_TO_SAMPLES(must_read, state)];
+
+ size_t has_read = 0;
+
+ size_t copy_size = 0;
+ size_t ret = 0;
+ float *ptr = NULL;
+ while (has_read < must_read)
+ {
+ ret = state->func(state->cb_data, &ptr);
+
+ if (ret == 0 || ptr == NULL) // We're done.
+ return -1;
+
+ copy_size = (ret > must_read - has_read) ? (must_read - has_read) : ret;
+ memcpy(temp_buf + FRAMES_TO_SAMPLES(has_read, state), ptr, FRAMES_TO_SAMPLES(copy_size, state) * sizeof(float));
+
+ has_read += ret;
+ }
+
+ // We might have gotten a lot of data from the callback. We should realloc our buffer if needed.
+ size_t req_buffer_frames = SAMPLES_TO_FRAMES(state->data_ptr, state) + has_read;
+
+ if (req_buffer_frames > SAMPLES_TO_FRAMES(state->data_size, state))
+ {
+ state->data = realloc(state->data, FRAMES_TO_SAMPLES(req_buffer_frames, state) * sizeof(float));
+ if (state->data == NULL)
+ return -1;
+
+ state->data_size = FRAMES_TO_SAMPLES(req_buffer_frames, state);
+ }
+
+ memcpy(state->data + state->data_ptr, temp_buf, FRAMES_TO_SAMPLES(must_read, state) * sizeof(float));
+ state->data_ptr += FRAMES_TO_SAMPLES(must_read, state);
+
+ // We have some data from the callback we need to copy over as well.
+ if (ret > copy_size)
+ {
+ memcpy(state->data + state->data_ptr, ptr + FRAMES_TO_SAMPLES(copy_size, state), FRAMES_TO_SAMPLES(ret - copy_size, state) * sizeof(float));
+ state->data_ptr += FRAMES_TO_SAMPLES(ret - copy_size, state);
+ }
+ }
+
+ // Phew. We should have enough data in our buffer now to be able to process the data we need.
+
+ size_t frames_used = resampler_process(state, frames, data);
+ state->sum_input_frames += frames_used;
+ memmove(state->data, state->data + FRAMES_TO_SAMPLES(frames_used, state), (state->data_ptr - FRAMES_TO_SAMPLES(frames_used, state)) * sizeof(float));
+ state->data_ptr -= FRAMES_TO_SAMPLES(frames_used, state);
+ state->sum_output_frames += frames;
+
+ return frames;
+}
diff --git a/ps3/resampler.h b/ps3/resampler.h
new file mode 100644
index 0000000000..e96fb42eda
--- /dev/null
+++ b/ps3/resampler.h
@@ -0,0 +1,42 @@
+/* RSound - A PCM audio client/server
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * RSound is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RSound is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RSound.
+ * If not, see .
+ */
+
+#ifndef RSD_RESAMPLER
+#define RSD_RESAMPLER
+
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef size_t (*resampler_cb_t) (void *cb_data, float **data);
+
+typedef struct resampler resampler_t;
+
+resampler_t* resampler_new(resampler_cb_t func, double ratio, int channels, void* cb_data);
+ssize_t resampler_cb_read(resampler_t *state, size_t frames, float *data);
+void resampler_free(resampler_t* state);
+
+void resampler_float_to_s16(int16_t * restrict out, const float * restrict in, size_t samples);
+void resampler_s16_to_float(float * restrict out, const int16_t * restrict in, size_t samples);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/settings.c b/settings.c
index 3f55cae17f..3a693fe6b1 100644
--- a/settings.c
+++ b/settings.c
@@ -62,6 +62,11 @@ static void set_defaults(void)
switch (AUDIO_DEFAULT_DRIVER)
{
+ #ifdef __CELLOS_LV2__
+ case AUDIO_PS3:
+ def_audio = "ps3";
+ break;
+ #endif
case AUDIO_RSOUND:
def_audio = "rsound";
break;
|