mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 18:55:38 +00:00
rename SoundIoOutputDevice to SoundIoOutStream
and SoundIoInputDevice to SoundIoInStream
This commit is contained in:
parent
3b8d896c8e
commit
7d45b15036
|
@ -25,18 +25,18 @@ static void panic(const char *format, ...) {
|
|||
abort();
|
||||
}
|
||||
|
||||
static void read_callback(struct SoundIoInputDevice *input_device) {
|
||||
static void read_callback(struct SoundIoInStream *in_stream) {
|
||||
fprintf(stderr, "read_callback\n");
|
||||
}
|
||||
|
||||
static void write_callback(struct SoundIoOutputDevice *output_device, int requested_frame_count) {
|
||||
static void write_callback(struct SoundIoOutStream *out_stream, int requested_frame_count) {
|
||||
fprintf(stderr, "write_callback\n");
|
||||
}
|
||||
|
||||
static void underrun_callback(struct SoundIoOutputDevice *output_device) {
|
||||
static void underrun_callback(struct SoundIoOutStream *out_stream) {
|
||||
static int count = 0;
|
||||
fprintf(stderr, "underrun %d\n", count++);
|
||||
soundio_output_device_fill_with_silence(output_device);
|
||||
soundio_out_stream_fill_with_silence(out_stream);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -75,25 +75,25 @@ int main(int argc, char **argv) {
|
|||
|
||||
double latency = 0.1;
|
||||
|
||||
struct SoundIoInputDevice *input_device;
|
||||
soundio_input_device_create(in_device, SoundIoFormatFloat32NE, 48000, latency, NULL,
|
||||
read_callback, &input_device);
|
||||
struct SoundIoInStream *in_stream;
|
||||
soundio_in_stream_create(in_device, SoundIoFormatFloat32NE, 48000, latency, NULL,
|
||||
read_callback, &in_stream);
|
||||
|
||||
struct SoundIoOutputDevice *output_device;
|
||||
soundio_output_device_create(out_device, SoundIoFormatFloat32NE, 48000, latency, NULL,
|
||||
write_callback, underrun_callback, &output_device);
|
||||
struct SoundIoOutStream *out_stream;
|
||||
soundio_out_stream_create(out_device, SoundIoFormatFloat32NE, 48000, latency, NULL,
|
||||
write_callback, underrun_callback, &out_stream);
|
||||
|
||||
if ((err = soundio_input_device_start(input_device)))
|
||||
if ((err = soundio_in_stream_start(in_stream)))
|
||||
panic("unable to start input device: %s", soundio_strerror(err));
|
||||
|
||||
if ((err = soundio_output_device_start(output_device)))
|
||||
if ((err = soundio_out_stream_start(out_stream)))
|
||||
panic("unable to start output device: %s", soundio_strerror(err));
|
||||
|
||||
for (;;)
|
||||
soundio_wait_events(soundio);
|
||||
|
||||
soundio_output_device_destroy(output_device);
|
||||
soundio_input_device_destroy(input_device);
|
||||
soundio_out_stream_destroy(out_stream);
|
||||
soundio_in_stream_destroy(in_stream);
|
||||
soundio_device_unref(in_device);
|
||||
soundio_device_unref(out_device);
|
||||
soundio_destroy(soundio);
|
||||
|
|
|
@ -28,20 +28,20 @@ static void panic(const char *format, ...) {
|
|||
static const float PI = 3.1415926535f;
|
||||
static float seconds_offset = 0.0f;
|
||||
|
||||
static void write_callback(struct SoundIoOutputDevice *output_device, int requested_frame_count) {
|
||||
static void write_callback(struct SoundIoOutStream *out_stream, int requested_frame_count) {
|
||||
//device->bytes_per_frame;
|
||||
float float_sample_rate = output_device->sample_rate;
|
||||
float float_sample_rate = out_stream->sample_rate;
|
||||
float seconds_per_frame = 1.0f / float_sample_rate;
|
||||
|
||||
while (requested_frame_count > 0) {
|
||||
char *data;
|
||||
int frame_count = requested_frame_count;
|
||||
soundio_output_device_begin_write(output_device, &data, &frame_count);
|
||||
soundio_out_stream_begin_write(out_stream, &data, &frame_count);
|
||||
|
||||
// clear everything to 0
|
||||
memset(data, 0, frame_count * output_device->bytes_per_frame);
|
||||
memset(data, 0, frame_count * out_stream->bytes_per_frame);
|
||||
|
||||
const struct SoundIoChannelLayout *channel_layout = &output_device->device->channel_layout;
|
||||
const struct SoundIoChannelLayout *channel_layout = &out_stream->device->channel_layout;
|
||||
|
||||
float *ptr = (float *)data;
|
||||
|
||||
|
@ -57,13 +57,13 @@ static void write_callback(struct SoundIoOutputDevice *output_device, int reques
|
|||
}
|
||||
seconds_offset += seconds_per_frame * frame_count;
|
||||
|
||||
soundio_output_device_write(output_device, data, frame_count);
|
||||
soundio_out_stream_write(out_stream, data, frame_count);
|
||||
requested_frame_count -= frame_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void underrun_callback(struct SoundIoOutputDevice *device) {
|
||||
static void underrun_callback(struct SoundIoOutStream *device) {
|
||||
static int count = 0;
|
||||
fprintf(stderr, "underrun %d\n", count++);
|
||||
}
|
||||
|
@ -89,17 +89,17 @@ int main(int argc, char **argv) {
|
|||
soundio_device_name(device),
|
||||
soundio_device_description(device));
|
||||
|
||||
struct SoundIoOutputDevice *output_device;
|
||||
soundio_output_device_create(device, SoundIoFormatFloat32NE, 48000,
|
||||
0.1, NULL, write_callback, underrun_callback, &output_device);
|
||||
struct SoundIoOutStream *out_stream;
|
||||
soundio_out_stream_create(device, SoundIoFormatFloat32NE, 48000,
|
||||
0.1, NULL, write_callback, underrun_callback, &out_stream);
|
||||
|
||||
if ((err = soundio_output_device_start(output_device)))
|
||||
if ((err = soundio_out_stream_start(out_stream)))
|
||||
panic("unable to start device: %s", soundio_strerror(err));
|
||||
|
||||
for (;;)
|
||||
soundio_wait_events(soundio);
|
||||
|
||||
soundio_output_device_destroy(output_device);
|
||||
soundio_out_stream_destroy(out_stream);
|
||||
soundio_device_unref(device);
|
||||
soundio_destroy(soundio);
|
||||
return 0;
|
||||
|
|
78
src/alsa.cpp
78
src/alsa.cpp
|
@ -719,80 +719,80 @@ static void wakeup(SoundIo *soundio) {
|
|||
soundio_os_mutex_unlock(sia->mutex);
|
||||
}
|
||||
|
||||
static void output_device_destroy_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_destroy_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int output_device_init_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_init_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int output_device_start_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_start_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int output_device_free_count_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_free_count_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void output_device_begin_write_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char **data, int *frame_count)
|
||||
static void out_stream_begin_write_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char **data, int *frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void output_device_write_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char *data, int frame_count)
|
||||
static void out_stream_write_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char *data, int frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void output_device_clear_buffer_alsa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_clear_buffer_alsa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int input_device_init_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_init_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_destroy_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_destroy_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int input_device_start_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_start_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_peek_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device, const char **data, int *frame_count)
|
||||
static void in_stream_peek_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream, const char **data, int *frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_drop_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_drop_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_clear_buffer_alsa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_clear_buffer_alsa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
@ -876,20 +876,20 @@ int soundio_alsa_init(SoundIo *soundio) {
|
|||
soundio->wait_events = wait_events;
|
||||
soundio->wakeup = wakeup;
|
||||
|
||||
soundio->output_device_init = output_device_init_alsa;
|
||||
soundio->output_device_destroy = output_device_destroy_alsa;
|
||||
soundio->output_device_start = output_device_start_alsa;
|
||||
soundio->output_device_free_count = output_device_free_count_alsa;
|
||||
soundio->output_device_begin_write = output_device_begin_write_alsa;
|
||||
soundio->output_device_write = output_device_write_alsa;
|
||||
soundio->output_device_clear_buffer = output_device_clear_buffer_alsa;
|
||||
soundio->out_stream_init = out_stream_init_alsa;
|
||||
soundio->out_stream_destroy = out_stream_destroy_alsa;
|
||||
soundio->out_stream_start = out_stream_start_alsa;
|
||||
soundio->out_stream_free_count = out_stream_free_count_alsa;
|
||||
soundio->out_stream_begin_write = out_stream_begin_write_alsa;
|
||||
soundio->out_stream_write = out_stream_write_alsa;
|
||||
soundio->out_stream_clear_buffer = out_stream_clear_buffer_alsa;
|
||||
|
||||
soundio->input_device_init = input_device_init_alsa;
|
||||
soundio->input_device_destroy = input_device_destroy_alsa;
|
||||
soundio->input_device_start = input_device_start_alsa;
|
||||
soundio->input_device_peek = input_device_peek_alsa;
|
||||
soundio->input_device_drop = input_device_drop_alsa;
|
||||
soundio->input_device_clear_buffer = input_device_clear_buffer_alsa;
|
||||
soundio->in_stream_init = in_stream_init_alsa;
|
||||
soundio->in_stream_destroy = in_stream_destroy_alsa;
|
||||
soundio->in_stream_start = in_stream_start_alsa;
|
||||
soundio->in_stream_peek = in_stream_peek_alsa;
|
||||
soundio->in_stream_drop = in_stream_drop_alsa;
|
||||
soundio->in_stream_clear_buffer = in_stream_clear_buffer_alsa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
194
src/dummy.cpp
194
src/dummy.cpp
|
@ -14,7 +14,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct SoundIoOutputDeviceDummy {
|
||||
struct SoundIoOutStreamDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
|
@ -23,7 +23,7 @@ struct SoundIoOutputDeviceDummy {
|
|||
struct SoundIoRingBuffer ring_buffer;
|
||||
};
|
||||
|
||||
struct SoundIoInputDeviceDummy {
|
||||
struct SoundIoInStreamDummy {
|
||||
// TODO
|
||||
};
|
||||
|
||||
|
@ -34,40 +34,40 @@ struct SoundIoDummy {
|
|||
};
|
||||
|
||||
static void playback_thread_run(void *arg) {
|
||||
SoundIoOutputDevice *output_device = (SoundIoOutputDevice *)arg;
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
SoundIoOutStream *out_stream = (SoundIoOutStream *)arg;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
|
||||
double start_time = soundio_os_get_time();
|
||||
long frames_consumed = 0;
|
||||
|
||||
double time_per_frame = 1.0 / (double)output_device->sample_rate;
|
||||
while (opd->abort_flag.test_and_set()) {
|
||||
soundio_os_cond_timed_wait(opd->cond, nullptr, opd->period);
|
||||
double time_per_frame = 1.0 / (double)out_stream->sample_rate;
|
||||
while (osd->abort_flag.test_and_set()) {
|
||||
soundio_os_cond_timed_wait(osd->cond, nullptr, osd->period);
|
||||
|
||||
double now = soundio_os_get_time();
|
||||
double total_time = now - start_time;
|
||||
long total_frames = total_time / time_per_frame;
|
||||
int frames_to_kill = total_frames - frames_consumed;
|
||||
int fill_count = soundio_ring_buffer_fill_count(&opd->ring_buffer);
|
||||
int frames_in_buffer = fill_count / output_device->bytes_per_frame;
|
||||
int fill_count = soundio_ring_buffer_fill_count(&osd->ring_buffer);
|
||||
int frames_in_buffer = fill_count / out_stream->bytes_per_frame;
|
||||
int read_count = min(frames_to_kill, frames_in_buffer);
|
||||
int frames_left = frames_to_kill - read_count;
|
||||
int byte_count = read_count * output_device->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_read_ptr(&opd->ring_buffer, byte_count);
|
||||
int byte_count = read_count * out_stream->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_read_ptr(&osd->ring_buffer, byte_count);
|
||||
frames_consumed += read_count;
|
||||
|
||||
if (frames_left > 0) {
|
||||
output_device->underrun_callback(output_device);
|
||||
out_stream->underrun_callback(out_stream);
|
||||
} else if (read_count > 0) {
|
||||
output_device->write_callback(output_device, read_count);
|
||||
out_stream->write_callback(out_stream, read_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void recording_thread_run(void *arg) {
|
||||
SoundIoInputDevice *input_device = (SoundIoInputDevice *)arg;
|
||||
SoundIoDevice *device = input_device->device;
|
||||
SoundIoInStream *in_stream = (SoundIoInStream *)arg;
|
||||
SoundIoDevice *device = in_stream->device;
|
||||
SoundIo *soundio = device->soundio;
|
||||
// TODO
|
||||
}
|
||||
|
@ -107,140 +107,140 @@ static void wakeup(SoundIo *soundio) {
|
|||
soundio_os_cond_signal(sid->cond, nullptr);
|
||||
}
|
||||
|
||||
static void output_device_destroy_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_destroy_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
if (!opd)
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
if (!osd)
|
||||
return;
|
||||
|
||||
if (opd->thread) {
|
||||
if (opd->thread) {
|
||||
opd->abort_flag.clear();
|
||||
soundio_os_cond_signal(opd->cond, nullptr);
|
||||
soundio_os_thread_destroy(opd->thread);
|
||||
opd->thread = nullptr;
|
||||
if (osd->thread) {
|
||||
if (osd->thread) {
|
||||
osd->abort_flag.clear();
|
||||
soundio_os_cond_signal(osd->cond, nullptr);
|
||||
soundio_os_thread_destroy(osd->thread);
|
||||
osd->thread = nullptr;
|
||||
}
|
||||
}
|
||||
soundio_os_cond_destroy(opd->cond);
|
||||
opd->cond = nullptr;
|
||||
soundio_os_cond_destroy(osd->cond);
|
||||
osd->cond = nullptr;
|
||||
|
||||
soundio_ring_buffer_deinit(&opd->ring_buffer);
|
||||
soundio_ring_buffer_deinit(&osd->ring_buffer);
|
||||
|
||||
destroy(opd);
|
||||
output_device->backend_data = nullptr;
|
||||
destroy(osd);
|
||||
out_stream->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int output_device_init_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_init_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
|
||||
SoundIoOutputDeviceDummy *opd = create<SoundIoOutputDeviceDummy>();
|
||||
if (!opd) {
|
||||
output_device_destroy_dummy(soundio, output_device);
|
||||
SoundIoOutStreamDummy *osd = create<SoundIoOutStreamDummy>();
|
||||
if (!osd) {
|
||||
out_stream_destroy_dummy(soundio, out_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
output_device->backend_data = opd;
|
||||
out_stream->backend_data = osd;
|
||||
|
||||
int buffer_frame_count = output_device->latency * output_device->sample_rate;
|
||||
opd->buffer_size = output_device->bytes_per_frame * buffer_frame_count;
|
||||
opd->period = output_device->latency * 0.5;
|
||||
int buffer_frame_count = out_stream->latency * out_stream->sample_rate;
|
||||
osd->buffer_size = out_stream->bytes_per_frame * buffer_frame_count;
|
||||
osd->period = out_stream->latency * 0.5;
|
||||
|
||||
soundio_ring_buffer_init(&opd->ring_buffer, opd->buffer_size);
|
||||
soundio_ring_buffer_init(&osd->ring_buffer, osd->buffer_size);
|
||||
|
||||
opd->cond = soundio_os_cond_create();
|
||||
if (!opd->cond) {
|
||||
output_device_destroy_dummy(soundio, output_device);
|
||||
osd->cond = soundio_os_cond_create();
|
||||
if (!osd->cond) {
|
||||
out_stream_destroy_dummy(soundio, out_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_device_start_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_start_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
|
||||
soundio_output_device_fill_with_silence(output_device);
|
||||
assert(soundio_ring_buffer_fill_count(&opd->ring_buffer) == opd->buffer_size);
|
||||
soundio_out_stream_fill_with_silence(out_stream);
|
||||
assert(soundio_ring_buffer_fill_count(&osd->ring_buffer) == osd->buffer_size);
|
||||
|
||||
opd->abort_flag.test_and_set();
|
||||
osd->abort_flag.test_and_set();
|
||||
int err;
|
||||
if ((err = soundio_os_thread_create(playback_thread_run, output_device, true, &opd->thread))) {
|
||||
if ((err = soundio_os_thread_create(playback_thread_run, out_stream, true, &osd->thread))) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_device_free_count_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_free_count_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
int fill_count = soundio_ring_buffer_fill_count(&opd->ring_buffer);
|
||||
int bytes_free_count = opd->buffer_size - fill_count;
|
||||
return bytes_free_count / output_device->bytes_per_frame;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
int fill_count = soundio_ring_buffer_fill_count(&osd->ring_buffer);
|
||||
int bytes_free_count = osd->buffer_size - fill_count;
|
||||
return bytes_free_count / out_stream->bytes_per_frame;
|
||||
}
|
||||
|
||||
static void output_device_begin_write_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char **data, int *frame_count)
|
||||
static void out_stream_begin_write_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char **data, int *frame_count)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
|
||||
int byte_count = *frame_count * output_device->bytes_per_frame;
|
||||
assert(byte_count <= opd->buffer_size);
|
||||
*data = opd->ring_buffer.address;
|
||||
int byte_count = *frame_count * out_stream->bytes_per_frame;
|
||||
assert(byte_count <= osd->buffer_size);
|
||||
*data = osd->ring_buffer.address;
|
||||
}
|
||||
|
||||
static void output_device_write_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char *data, int frame_count)
|
||||
static void out_stream_write_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char *data, int frame_count)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
assert(data == opd->ring_buffer.address);
|
||||
int byte_count = frame_count * output_device->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_write_ptr(&opd->ring_buffer, byte_count);
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
assert(data == osd->ring_buffer.address);
|
||||
int byte_count = frame_count * out_stream->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_write_ptr(&osd->ring_buffer, byte_count);
|
||||
}
|
||||
|
||||
static void output_device_clear_buffer_dummy(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_clear_buffer_dummy(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDeviceDummy *opd = (SoundIoOutputDeviceDummy *)output_device->backend_data;
|
||||
soundio_ring_buffer_clear(&opd->ring_buffer);
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)out_stream->backend_data;
|
||||
soundio_ring_buffer_clear(&osd->ring_buffer);
|
||||
}
|
||||
|
||||
static int input_device_init_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_init_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_destroy_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_destroy_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int input_device_start_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_start_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_peek_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device, const char **data, int *frame_count)
|
||||
static void in_stream_peek_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream, const char **data, int *frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_drop_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_drop_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void input_device_clear_buffer_dummy(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_clear_buffer_dummy(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
@ -385,20 +385,20 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
soundio->wait_events = wait_events;
|
||||
soundio->wakeup = wakeup;
|
||||
|
||||
soundio->output_device_init = output_device_init_dummy;
|
||||
soundio->output_device_destroy = output_device_destroy_dummy;
|
||||
soundio->output_device_start = output_device_start_dummy;
|
||||
soundio->output_device_free_count = output_device_free_count_dummy;
|
||||
soundio->output_device_begin_write = output_device_begin_write_dummy;
|
||||
soundio->output_device_write = output_device_write_dummy;
|
||||
soundio->output_device_clear_buffer = output_device_clear_buffer_dummy;
|
||||
soundio->out_stream_init = out_stream_init_dummy;
|
||||
soundio->out_stream_destroy = out_stream_destroy_dummy;
|
||||
soundio->out_stream_start = out_stream_start_dummy;
|
||||
soundio->out_stream_free_count = out_stream_free_count_dummy;
|
||||
soundio->out_stream_begin_write = out_stream_begin_write_dummy;
|
||||
soundio->out_stream_write = out_stream_write_dummy;
|
||||
soundio->out_stream_clear_buffer = out_stream_clear_buffer_dummy;
|
||||
|
||||
soundio->input_device_init = input_device_init_dummy;
|
||||
soundio->input_device_destroy = input_device_destroy_dummy;
|
||||
soundio->input_device_start = input_device_start_dummy;
|
||||
soundio->input_device_peek = input_device_peek_dummy;
|
||||
soundio->input_device_drop = input_device_drop_dummy;
|
||||
soundio->input_device_clear_buffer = input_device_clear_buffer_dummy;
|
||||
soundio->in_stream_init = in_stream_init_dummy;
|
||||
soundio->in_stream_destroy = in_stream_destroy_dummy;
|
||||
soundio->in_stream_start = in_stream_start_dummy;
|
||||
soundio->in_stream_peek = in_stream_peek_dummy;
|
||||
soundio->in_stream_drop = in_stream_drop_dummy;
|
||||
soundio->in_stream_clear_buffer = in_stream_clear_buffer_dummy;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
struct SoundIoOutputDevicePulseAudio {
|
||||
struct SoundIoOutStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
};
|
||||
|
||||
struct SoundIoInputDevicePulseAudio {
|
||||
struct SoundIoInStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
|
@ -524,17 +524,17 @@ static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *chan
|
|||
}
|
||||
|
||||
static void playback_stream_state_callback(pa_stream *stream, void *userdata) {
|
||||
SoundIoOutputDevice *output_device = (SoundIoOutputDevice*) userdata;
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
SoundIoOutStream *out_stream = (SoundIoOutStream*) userdata;
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
switch (pa_stream_get_state(stream)) {
|
||||
case PA_STREAM_UNCONNECTED:
|
||||
case PA_STREAM_CREATING:
|
||||
case PA_STREAM_TERMINATED:
|
||||
break;
|
||||
case PA_STREAM_READY:
|
||||
opd->stream_ready = true;
|
||||
ospa->stream_ready = true;
|
||||
pa_threaded_mainloop_signal(sipa->main_loop, 0);
|
||||
break;
|
||||
case PA_STREAM_FAILED:
|
||||
|
@ -544,26 +544,26 @@ static void playback_stream_state_callback(pa_stream *stream, void *userdata) {
|
|||
}
|
||||
|
||||
static void playback_stream_underflow_callback(pa_stream *stream, void *userdata) {
|
||||
SoundIoOutputDevice *output_device = (SoundIoOutputDevice*)userdata;
|
||||
output_device->underrun_callback(output_device);
|
||||
SoundIoOutStream *out_stream = (SoundIoOutStream*)userdata;
|
||||
out_stream->underrun_callback(out_stream);
|
||||
}
|
||||
|
||||
|
||||
static void playback_stream_write_callback(pa_stream *stream, size_t nbytes, void *userdata) {
|
||||
SoundIoOutputDevice *output_device = (SoundIoOutputDevice*)(userdata);
|
||||
int frame_count = ((int)nbytes) / output_device->bytes_per_frame;
|
||||
output_device->write_callback(output_device, frame_count);
|
||||
SoundIoOutStream *out_stream = (SoundIoOutStream*)(userdata);
|
||||
int frame_count = ((int)nbytes) / out_stream->bytes_per_frame;
|
||||
out_stream->write_callback(out_stream, frame_count);
|
||||
}
|
||||
|
||||
static void output_device_destroy_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_destroy_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
if (!opd)
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
if (!ospa)
|
||||
return;
|
||||
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_stream *stream = opd->stream;
|
||||
pa_stream *stream = ospa->stream;
|
||||
if (stream) {
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
|
@ -576,127 +576,127 @@ static void output_device_destroy_pa(SoundIo *soundio,
|
|||
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
|
||||
opd->stream = nullptr;
|
||||
ospa->stream = nullptr;
|
||||
}
|
||||
|
||||
destroy(opd);
|
||||
output_device->backend_data = nullptr;
|
||||
destroy(ospa);
|
||||
out_stream->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int output_device_init_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_init_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = create<SoundIoOutputDevicePulseAudio>();
|
||||
if (!opd) {
|
||||
output_device_destroy_pa(soundio, output_device);
|
||||
SoundIoOutStreamPulseAudio *ospa = create<SoundIoOutStreamPulseAudio>();
|
||||
if (!ospa) {
|
||||
out_stream_destroy_pa(soundio, out_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
output_device->backend_data = opd;
|
||||
out_stream->backend_data = ospa;
|
||||
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
SoundIoDevice *device = output_device->device;
|
||||
opd->stream_ready = false;
|
||||
SoundIoDevice *device = out_stream->device;
|
||||
ospa->stream_ready = false;
|
||||
|
||||
assert(sipa->pulse_context);
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
pa_sample_spec sample_spec;
|
||||
sample_spec.format = to_pulseaudio_format(output_device->format);
|
||||
sample_spec.rate = output_device->sample_rate;
|
||||
sample_spec.format = to_pulseaudio_format(out_stream->format);
|
||||
sample_spec.rate = out_stream->sample_rate;
|
||||
sample_spec.channels = device->channel_layout.channel_count;
|
||||
pa_channel_map channel_map = to_pulseaudio_channel_map(&device->channel_layout);
|
||||
|
||||
opd->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
||||
if (!opd->stream) {
|
||||
ospa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
||||
if (!ospa->stream) {
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
output_device_destroy_pa(soundio, output_device);
|
||||
out_stream_destroy_pa(soundio, out_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
pa_stream_set_state_callback(opd->stream, playback_stream_state_callback, output_device);
|
||||
pa_stream_set_write_callback(opd->stream, playback_stream_write_callback, output_device);
|
||||
pa_stream_set_underflow_callback(opd->stream, playback_stream_underflow_callback, output_device);
|
||||
pa_stream_set_state_callback(ospa->stream, playback_stream_state_callback, out_stream);
|
||||
pa_stream_set_write_callback(ospa->stream, playback_stream_write_callback, out_stream);
|
||||
pa_stream_set_underflow_callback(ospa->stream, playback_stream_underflow_callback, out_stream);
|
||||
|
||||
int bytes_per_second = output_device->bytes_per_frame * output_device->sample_rate;
|
||||
int buffer_length = output_device->bytes_per_frame *
|
||||
ceil(output_device->latency * bytes_per_second / (double)output_device->bytes_per_frame);
|
||||
int bytes_per_second = out_stream->bytes_per_frame * out_stream->sample_rate;
|
||||
int buffer_length = out_stream->bytes_per_frame *
|
||||
ceil(out_stream->latency * bytes_per_second / (double)out_stream->bytes_per_frame);
|
||||
|
||||
opd->buffer_attr.maxlength = buffer_length;
|
||||
opd->buffer_attr.tlength = buffer_length;
|
||||
opd->buffer_attr.prebuf = 0;
|
||||
opd->buffer_attr.minreq = UINT32_MAX;
|
||||
opd->buffer_attr.fragsize = UINT32_MAX;
|
||||
ospa->buffer_attr.maxlength = buffer_length;
|
||||
ospa->buffer_attr.tlength = buffer_length;
|
||||
ospa->buffer_attr.prebuf = 0;
|
||||
ospa->buffer_attr.minreq = UINT32_MAX;
|
||||
ospa->buffer_attr.fragsize = UINT32_MAX;
|
||||
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_device_start_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_start_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
|
||||
int err = pa_stream_connect_playback(opd->stream,
|
||||
output_device->device->name, &opd->buffer_attr,
|
||||
int err = pa_stream_connect_playback(ospa->stream,
|
||||
out_stream->device->name, &ospa->buffer_attr,
|
||||
PA_STREAM_ADJUST_LATENCY, nullptr, nullptr);
|
||||
if (err) {
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
return SoundIoErrorOpeningDevice;
|
||||
}
|
||||
|
||||
while (!opd->stream_ready)
|
||||
while (!ospa->stream_ready)
|
||||
pa_threaded_mainloop_wait(sipa->main_loop);
|
||||
|
||||
soundio_output_device_fill_with_silence(output_device);
|
||||
soundio_out_stream_fill_with_silence(out_stream);
|
||||
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_device_free_count_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static int out_stream_free_count_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
return pa_stream_writable_size(opd->stream) / output_device->bytes_per_frame;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
return pa_stream_writable_size(ospa->stream) / out_stream->bytes_per_frame;
|
||||
}
|
||||
|
||||
|
||||
static void output_device_begin_write_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char **data, int *frame_count)
|
||||
static void out_stream_begin_write_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char **data, int *frame_count)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_stream *stream = opd->stream;
|
||||
size_t byte_count = *frame_count * output_device->bytes_per_frame;
|
||||
pa_stream *stream = ospa->stream;
|
||||
size_t byte_count = *frame_count * out_stream->bytes_per_frame;
|
||||
if (pa_stream_begin_write(stream, (void**)data, &byte_count))
|
||||
soundio_panic("pa_stream_begin_write error: %s", pa_strerror(pa_context_errno(sipa->pulse_context)));
|
||||
|
||||
*frame_count = byte_count / output_device->bytes_per_frame;
|
||||
*frame_count = byte_count / out_stream->bytes_per_frame;
|
||||
}
|
||||
|
||||
static void output_device_write_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device, char *data, int frame_count)
|
||||
static void out_stream_write_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream, char *data, int frame_count)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_stream *stream = opd->stream;
|
||||
size_t byte_count = frame_count * output_device->bytes_per_frame;
|
||||
pa_stream *stream = ospa->stream;
|
||||
size_t byte_count = frame_count * out_stream->bytes_per_frame;
|
||||
if (pa_stream_write(stream, data, byte_count, NULL, 0, PA_SEEK_RELATIVE))
|
||||
soundio_panic("pa_stream_write error: %s", pa_strerror(pa_context_errno(sipa->pulse_context)));
|
||||
}
|
||||
|
||||
static void output_device_clear_buffer_pa(SoundIo *soundio,
|
||||
SoundIoOutputDevice *output_device)
|
||||
static void out_stream_clear_buffer_pa(SoundIo *soundio,
|
||||
SoundIoOutStream *out_stream)
|
||||
{
|
||||
SoundIoOutputDevicePulseAudio *opd = (SoundIoOutputDevicePulseAudio *)output_device->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)out_stream->backend_data;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_stream *stream = opd->stream;
|
||||
pa_stream *stream = ospa->stream;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
pa_operation *op = pa_stream_flush(stream, NULL, NULL);
|
||||
if (!op)
|
||||
|
@ -706,15 +706,15 @@ static void output_device_clear_buffer_pa(SoundIo *soundio,
|
|||
}
|
||||
|
||||
static void recording_stream_state_callback(pa_stream *stream, void *userdata) {
|
||||
SoundIoInputDevice *input_device = (SoundIoInputDevice*)userdata;
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
SoundIoInStream *in_stream = (SoundIoInStream*)userdata;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
switch (pa_stream_get_state(stream)) {
|
||||
case PA_STREAM_UNCONNECTED:
|
||||
case PA_STREAM_CREATING:
|
||||
case PA_STREAM_TERMINATED:
|
||||
break;
|
||||
case PA_STREAM_READY:
|
||||
ord->stream_ready = true;
|
||||
ispa->stream_ready = true;
|
||||
break;
|
||||
case PA_STREAM_FAILED:
|
||||
soundio_panic("pulseaudio stream error: %s",
|
||||
|
@ -724,19 +724,19 @@ static void recording_stream_state_callback(pa_stream *stream, void *userdata) {
|
|||
}
|
||||
|
||||
static void recording_stream_read_callback(pa_stream *stream, size_t nbytes, void *userdata) {
|
||||
SoundIoInputDevice *input_device = (SoundIoInputDevice*)userdata;
|
||||
input_device->read_callback(input_device);
|
||||
SoundIoInStream *in_stream = (SoundIoInStream*)userdata;
|
||||
in_stream->read_callback(in_stream);
|
||||
}
|
||||
|
||||
static void input_device_destroy_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_destroy_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
if (!ord)
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
if (!ispa)
|
||||
return;
|
||||
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_stream *stream = ord->stream;
|
||||
pa_stream *stream = ispa->stream;
|
||||
if (stream) {
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
|
@ -747,70 +747,70 @@ static void input_device_destroy_pa(SoundIo *soundio,
|
|||
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
|
||||
ord->stream = nullptr;
|
||||
ispa->stream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static int input_device_init_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_init_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = create<SoundIoInputDevicePulseAudio>();
|
||||
if (!ord) {
|
||||
input_device_destroy_pa(soundio, input_device);
|
||||
SoundIoInStreamPulseAudio *ispa = create<SoundIoInStreamPulseAudio>();
|
||||
if (!ispa) {
|
||||
in_stream_destroy_pa(soundio, in_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
input_device->backend_data = ord;
|
||||
in_stream->backend_data = ispa;
|
||||
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
SoundIoDevice *device = input_device->device;
|
||||
ord->stream_ready = false;
|
||||
SoundIoDevice *device = in_stream->device;
|
||||
ispa->stream_ready = false;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
pa_sample_spec sample_spec;
|
||||
sample_spec.format = to_pulseaudio_format(input_device->format);
|
||||
sample_spec.rate = input_device->sample_rate;
|
||||
sample_spec.format = to_pulseaudio_format(in_stream->format);
|
||||
sample_spec.rate = in_stream->sample_rate;
|
||||
sample_spec.channels = device->channel_layout.channel_count;
|
||||
|
||||
pa_channel_map channel_map = to_pulseaudio_channel_map(&device->channel_layout);
|
||||
|
||||
ord->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
||||
if (!input_device) {
|
||||
ispa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
||||
if (!in_stream) {
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
input_device_destroy_pa(soundio, input_device);
|
||||
in_stream_destroy_pa(soundio, in_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
pa_stream *stream = ord->stream;
|
||||
pa_stream *stream = ispa->stream;
|
||||
|
||||
pa_stream_set_state_callback(stream, recording_stream_state_callback, input_device);
|
||||
pa_stream_set_read_callback(stream, recording_stream_read_callback, input_device);
|
||||
pa_stream_set_state_callback(stream, recording_stream_state_callback, in_stream);
|
||||
pa_stream_set_read_callback(stream, recording_stream_read_callback, in_stream);
|
||||
|
||||
int bytes_per_second = input_device->bytes_per_frame * input_device->sample_rate;
|
||||
int buffer_length = input_device->bytes_per_frame *
|
||||
ceil(input_device->latency * bytes_per_second / (double)input_device->bytes_per_frame);
|
||||
int bytes_per_second = in_stream->bytes_per_frame * in_stream->sample_rate;
|
||||
int buffer_length = in_stream->bytes_per_frame *
|
||||
ceil(in_stream->latency * bytes_per_second / (double)in_stream->bytes_per_frame);
|
||||
|
||||
ord->buffer_attr.maxlength = UINT32_MAX;
|
||||
ord->buffer_attr.tlength = UINT32_MAX;
|
||||
ord->buffer_attr.prebuf = 0;
|
||||
ord->buffer_attr.minreq = UINT32_MAX;
|
||||
ord->buffer_attr.fragsize = buffer_length;
|
||||
ispa->buffer_attr.maxlength = UINT32_MAX;
|
||||
ispa->buffer_attr.tlength = UINT32_MAX;
|
||||
ispa->buffer_attr.prebuf = 0;
|
||||
ispa->buffer_attr.minreq = UINT32_MAX;
|
||||
ispa->buffer_attr.fragsize = buffer_length;
|
||||
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int input_device_start_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static int in_stream_start_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
int err = pa_stream_connect_record(ord->stream,
|
||||
input_device->device->name,
|
||||
&ord->buffer_attr, PA_STREAM_ADJUST_LATENCY);
|
||||
int err = pa_stream_connect_record(ispa->stream,
|
||||
in_stream->device->name,
|
||||
&ispa->buffer_attr, PA_STREAM_ADJUST_LATENCY);
|
||||
if (err) {
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
return SoundIoErrorOpeningDevice;
|
||||
|
@ -820,39 +820,39 @@ static int input_device_start_pa(SoundIo *soundio,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void input_device_peek_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device, const char **data, int *frame_count)
|
||||
static void in_stream_peek_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream, const char **data, int *frame_count)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
pa_stream *stream = ord->stream;
|
||||
if (ord->stream_ready) {
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
pa_stream *stream = ispa->stream;
|
||||
if (ispa->stream_ready) {
|
||||
size_t nbytes;
|
||||
if (pa_stream_peek(stream, (const void **)data, &nbytes))
|
||||
soundio_panic("pa_stream_peek error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
|
||||
*frame_count = ((int)nbytes) / input_device->bytes_per_frame;
|
||||
*frame_count = ((int)nbytes) / in_stream->bytes_per_frame;
|
||||
} else {
|
||||
*data = nullptr;
|
||||
*frame_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void input_device_drop_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_drop_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
pa_stream *stream = ord->stream;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
pa_stream *stream = ispa->stream;
|
||||
if (pa_stream_drop(stream))
|
||||
soundio_panic("pa_stream_drop error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
|
||||
}
|
||||
|
||||
static void input_device_clear_buffer_pa(SoundIo *soundio,
|
||||
SoundIoInputDevice *input_device)
|
||||
static void in_stream_clear_buffer_pa(SoundIo *soundio,
|
||||
SoundIoInStream *in_stream)
|
||||
{
|
||||
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
|
||||
if (!ord->stream_ready)
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)in_stream->backend_data;
|
||||
if (!ispa->stream_ready)
|
||||
return;
|
||||
|
||||
pa_stream *stream = ord->stream;
|
||||
pa_stream *stream = ispa->stream;
|
||||
SoundIoPulseAudio *sipa = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
@ -936,20 +936,20 @@ int soundio_pulseaudio_init(SoundIo *soundio) {
|
|||
soundio->wait_events = wait_events;
|
||||
soundio->wakeup = wakeup;
|
||||
|
||||
soundio->output_device_init = output_device_init_pa;
|
||||
soundio->output_device_destroy = output_device_destroy_pa;
|
||||
soundio->output_device_start = output_device_start_pa;
|
||||
soundio->output_device_free_count = output_device_free_count_pa;
|
||||
soundio->output_device_begin_write = output_device_begin_write_pa;
|
||||
soundio->output_device_write = output_device_write_pa;
|
||||
soundio->output_device_clear_buffer = output_device_clear_buffer_pa;
|
||||
soundio->out_stream_init = out_stream_init_pa;
|
||||
soundio->out_stream_destroy = out_stream_destroy_pa;
|
||||
soundio->out_stream_start = out_stream_start_pa;
|
||||
soundio->out_stream_free_count = out_stream_free_count_pa;
|
||||
soundio->out_stream_begin_write = out_stream_begin_write_pa;
|
||||
soundio->out_stream_write = out_stream_write_pa;
|
||||
soundio->out_stream_clear_buffer = out_stream_clear_buffer_pa;
|
||||
|
||||
soundio->input_device_init = input_device_init_pa;
|
||||
soundio->input_device_destroy = input_device_destroy_pa;
|
||||
soundio->input_device_start = input_device_start_pa;
|
||||
soundio->input_device_peek = input_device_peek_pa;
|
||||
soundio->input_device_drop = input_device_drop_pa;
|
||||
soundio->input_device_clear_buffer = input_device_clear_buffer_pa;
|
||||
soundio->in_stream_init = in_stream_init_pa;
|
||||
soundio->in_stream_destroy = in_stream_destroy_pa;
|
||||
soundio->in_stream_start = in_stream_start_pa;
|
||||
soundio->in_stream_peek = in_stream_peek_pa;
|
||||
soundio->in_stream_drop = in_stream_drop_pa;
|
||||
soundio->in_stream_clear_buffer = in_stream_clear_buffer_pa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
150
src/soundio.cpp
150
src/soundio.cpp
|
@ -172,20 +172,20 @@ void soundio_disconnect(struct SoundIo *soundio) {
|
|||
soundio->wait_events = nullptr;
|
||||
soundio->wakeup = nullptr;
|
||||
|
||||
soundio->output_device_init = nullptr;
|
||||
soundio->output_device_destroy = nullptr;
|
||||
soundio->output_device_start = nullptr;
|
||||
soundio->output_device_free_count = nullptr;
|
||||
soundio->output_device_begin_write = nullptr;
|
||||
soundio->output_device_write = nullptr;
|
||||
soundio->output_device_clear_buffer = nullptr;
|
||||
soundio->out_stream_init = nullptr;
|
||||
soundio->out_stream_destroy = nullptr;
|
||||
soundio->out_stream_start = nullptr;
|
||||
soundio->out_stream_free_count = nullptr;
|
||||
soundio->out_stream_begin_write = nullptr;
|
||||
soundio->out_stream_write = nullptr;
|
||||
soundio->out_stream_clear_buffer = nullptr;
|
||||
|
||||
soundio->input_device_init = nullptr;
|
||||
soundio->input_device_destroy = nullptr;
|
||||
soundio->input_device_start = nullptr;
|
||||
soundio->input_device_peek = nullptr;
|
||||
soundio->input_device_drop = nullptr;
|
||||
soundio->input_device_clear_buffer = nullptr;
|
||||
soundio->in_stream_init = nullptr;
|
||||
soundio->in_stream_destroy = nullptr;
|
||||
soundio->in_stream_start = nullptr;
|
||||
soundio->in_stream_peek = nullptr;
|
||||
soundio->in_stream_drop = nullptr;
|
||||
soundio->in_stream_clear_buffer = nullptr;
|
||||
}
|
||||
|
||||
void soundio_flush_events(struct SoundIo *soundio) {
|
||||
|
@ -281,104 +281,104 @@ void soundio_wakeup(struct SoundIo *soundio) {
|
|||
soundio->wakeup(soundio);
|
||||
}
|
||||
|
||||
void soundio_output_device_fill_with_silence(struct SoundIoOutputDevice *output_device) {
|
||||
void soundio_out_stream_fill_with_silence(struct SoundIoOutStream *out_stream) {
|
||||
char *buffer;
|
||||
int requested_frame_count = soundio_output_device_free_count(output_device);
|
||||
int requested_frame_count = soundio_out_stream_free_count(out_stream);
|
||||
while (requested_frame_count > 0) {
|
||||
int frame_count = requested_frame_count;
|
||||
soundio_output_device_begin_write(output_device, &buffer, &frame_count);
|
||||
memset(buffer, 0, frame_count * output_device->bytes_per_frame);
|
||||
soundio_output_device_write(output_device, buffer, frame_count);
|
||||
soundio_out_stream_begin_write(out_stream, &buffer, &frame_count);
|
||||
memset(buffer, 0, frame_count * out_stream->bytes_per_frame);
|
||||
soundio_out_stream_write(out_stream, buffer, frame_count);
|
||||
requested_frame_count -= frame_count;
|
||||
}
|
||||
}
|
||||
|
||||
int soundio_output_device_free_count(struct SoundIoOutputDevice *output_device) {
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
return soundio->output_device_free_count(soundio, output_device);
|
||||
int soundio_out_stream_free_count(struct SoundIoOutStream *out_stream) {
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
return soundio->out_stream_free_count(soundio, out_stream);
|
||||
}
|
||||
|
||||
void soundio_output_device_begin_write(struct SoundIoOutputDevice *output_device,
|
||||
void soundio_out_stream_begin_write(struct SoundIoOutStream *out_stream,
|
||||
char **data, int *frame_count)
|
||||
{
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
soundio->output_device_begin_write(soundio, output_device, data, frame_count);
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
soundio->out_stream_begin_write(soundio, out_stream, data, frame_count);
|
||||
}
|
||||
|
||||
void soundio_output_device_write(struct SoundIoOutputDevice *output_device,
|
||||
void soundio_out_stream_write(struct SoundIoOutStream *out_stream,
|
||||
char *data, int frame_count)
|
||||
{
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
soundio->output_device_write(soundio, output_device, data, frame_count);
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
soundio->out_stream_write(soundio, out_stream, data, frame_count);
|
||||
}
|
||||
|
||||
|
||||
int soundio_output_device_create(struct SoundIoDevice *device,
|
||||
int soundio_out_stream_create(struct SoundIoDevice *device,
|
||||
enum SoundIoFormat format, int sample_rate,
|
||||
double latency, void *userdata,
|
||||
void (*write_callback)(struct SoundIoOutputDevice *, int frame_count),
|
||||
void (*underrun_callback)(struct SoundIoOutputDevice *),
|
||||
struct SoundIoOutputDevice **out_output_device)
|
||||
void (*write_callback)(struct SoundIoOutStream *, int frame_count),
|
||||
void (*underrun_callback)(struct SoundIoOutStream *),
|
||||
struct SoundIoOutStream **out_out_stream)
|
||||
{
|
||||
*out_output_device = nullptr;
|
||||
*out_out_stream = nullptr;
|
||||
|
||||
SoundIoOutputDevice *output_device = create<SoundIoOutputDevice>();
|
||||
if (!output_device) {
|
||||
soundio_output_device_destroy(output_device);
|
||||
SoundIoOutStream *out_stream = create<SoundIoOutStream>();
|
||||
if (!out_stream) {
|
||||
soundio_out_stream_destroy(out_stream);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
soundio_device_ref(device);
|
||||
output_device->device = device;
|
||||
output_device->userdata = userdata;
|
||||
output_device->write_callback = write_callback;
|
||||
output_device->underrun_callback = underrun_callback;
|
||||
output_device->format = format;
|
||||
output_device->sample_rate = sample_rate;
|
||||
output_device->latency = latency;
|
||||
output_device->bytes_per_frame = soundio_get_bytes_per_frame(format,
|
||||
out_stream->device = device;
|
||||
out_stream->userdata = userdata;
|
||||
out_stream->write_callback = write_callback;
|
||||
out_stream->underrun_callback = underrun_callback;
|
||||
out_stream->format = format;
|
||||
out_stream->sample_rate = sample_rate;
|
||||
out_stream->latency = latency;
|
||||
out_stream->bytes_per_frame = soundio_get_bytes_per_frame(format,
|
||||
device->channel_layout.channel_count);
|
||||
|
||||
SoundIo *soundio = device->soundio;
|
||||
int err = soundio->output_device_init(soundio, output_device);
|
||||
int err = soundio->out_stream_init(soundio, out_stream);
|
||||
if (err) {
|
||||
soundio_output_device_destroy(output_device);
|
||||
soundio_out_stream_destroy(out_stream);
|
||||
return err;
|
||||
}
|
||||
|
||||
*out_output_device = output_device;
|
||||
*out_out_stream = out_stream;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void soundio_output_device_destroy(SoundIoOutputDevice *output_device) {
|
||||
if (!output_device)
|
||||
void soundio_out_stream_destroy(SoundIoOutStream *out_stream) {
|
||||
if (!out_stream)
|
||||
return;
|
||||
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
|
||||
if (soundio->output_device_destroy)
|
||||
soundio->output_device_destroy(soundio, output_device);
|
||||
if (soundio->out_stream_destroy)
|
||||
soundio->out_stream_destroy(soundio, out_stream);
|
||||
|
||||
soundio_device_unref(output_device->device);
|
||||
destroy(output_device);
|
||||
soundio_device_unref(out_stream->device);
|
||||
destroy(out_stream);
|
||||
}
|
||||
|
||||
int soundio_output_device_start(struct SoundIoOutputDevice *output_device) {
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
return soundio->output_device_start(soundio, output_device);
|
||||
int soundio_out_stream_start(struct SoundIoOutStream *out_stream) {
|
||||
SoundIo *soundio = out_stream->device->soundio;
|
||||
return soundio->out_stream_start(soundio, out_stream);
|
||||
}
|
||||
|
||||
int soundio_input_device_create(struct SoundIoDevice *device,
|
||||
int soundio_in_stream_create(struct SoundIoDevice *device,
|
||||
enum SoundIoFormat format, int sample_rate,
|
||||
double latency, void *userdata,
|
||||
void (*read_callback)(struct SoundIoInputDevice *),
|
||||
struct SoundIoInputDevice **out_input_device)
|
||||
void (*read_callback)(struct SoundIoInStream *),
|
||||
struct SoundIoInStream **out_in_stream)
|
||||
{
|
||||
*out_input_device = nullptr;
|
||||
*out_in_stream = nullptr;
|
||||
|
||||
SoundIoInputDevice *sid = create<SoundIoInputDevice>();
|
||||
SoundIoInStream *sid = create<SoundIoInStream>();
|
||||
if (!sid) {
|
||||
soundio_input_device_destroy(sid);
|
||||
soundio_in_stream_destroy(sid);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
|
@ -393,32 +393,32 @@ int soundio_input_device_create(struct SoundIoDevice *device,
|
|||
device->channel_layout.channel_count);
|
||||
|
||||
SoundIo *soundio = device->soundio;
|
||||
int err = soundio->input_device_init(soundio, sid);
|
||||
int err = soundio->in_stream_init(soundio, sid);
|
||||
if (err) {
|
||||
soundio_input_device_destroy(sid);
|
||||
soundio_in_stream_destroy(sid);
|
||||
return err;
|
||||
}
|
||||
|
||||
*out_input_device = sid;
|
||||
*out_in_stream = sid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int soundio_input_device_start(struct SoundIoInputDevice *input_device) {
|
||||
SoundIo *soundio = input_device->device->soundio;
|
||||
return soundio->input_device_start(soundio, input_device);
|
||||
int soundio_in_stream_start(struct SoundIoInStream *in_stream) {
|
||||
SoundIo *soundio = in_stream->device->soundio;
|
||||
return soundio->in_stream_start(soundio, in_stream);
|
||||
}
|
||||
|
||||
void soundio_input_device_destroy(struct SoundIoInputDevice *input_device) {
|
||||
if (!input_device)
|
||||
void soundio_in_stream_destroy(struct SoundIoInStream *in_stream) {
|
||||
if (!in_stream)
|
||||
return;
|
||||
|
||||
SoundIo *soundio = input_device->device->soundio;
|
||||
SoundIo *soundio = in_stream->device->soundio;
|
||||
|
||||
if (soundio->input_device_destroy)
|
||||
soundio->input_device_destroy(soundio, input_device);
|
||||
if (soundio->in_stream_destroy)
|
||||
soundio->in_stream_destroy(soundio, in_stream);
|
||||
|
||||
soundio_device_unref(input_device->device);
|
||||
destroy(input_device);
|
||||
soundio_device_unref(in_stream->device);
|
||||
destroy(in_stream);
|
||||
}
|
||||
|
||||
void soundio_destroy_devices_info(SoundIoDevicesInfo *devices_info) {
|
||||
|
|
|
@ -244,8 +244,7 @@ struct SoundIoDevice {
|
|||
int probe_error;
|
||||
};
|
||||
|
||||
// TODO rename this to SoundIoOutStream
|
||||
struct SoundIoOutputDevice {
|
||||
struct SoundIoOutStream {
|
||||
void *backend_data;
|
||||
struct SoundIoDevice *device;
|
||||
enum SoundIoFormat format;
|
||||
|
@ -254,12 +253,11 @@ struct SoundIoOutputDevice {
|
|||
int bytes_per_frame;
|
||||
|
||||
void *userdata;
|
||||
void (*underrun_callback)(struct SoundIoOutputDevice *);
|
||||
void (*write_callback)(struct SoundIoOutputDevice *, int frame_count);
|
||||
void (*underrun_callback)(struct SoundIoOutStream *);
|
||||
void (*write_callback)(struct SoundIoOutStream *, int frame_count);
|
||||
};
|
||||
|
||||
// TODO rename this to SoundIoInStream
|
||||
struct SoundIoInputDevice {
|
||||
struct SoundIoInStream {
|
||||
void *backend_data;
|
||||
struct SoundIoDevice *device;
|
||||
enum SoundIoFormat format;
|
||||
|
@ -268,7 +266,7 @@ struct SoundIoInputDevice {
|
|||
int bytes_per_frame;
|
||||
|
||||
void *userdata;
|
||||
void (*read_callback)(struct SoundIoInputDevice *);
|
||||
void (*read_callback)(struct SoundIoInStream *);
|
||||
};
|
||||
|
||||
struct SoundIo {
|
||||
|
@ -288,24 +286,24 @@ struct SoundIo {
|
|||
void (*wait_events)(struct SoundIo *);
|
||||
void (*wakeup)(struct SoundIo *);
|
||||
|
||||
int (*output_device_init)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
void (*output_device_destroy)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
int (*output_device_start)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
int (*output_device_free_count)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
void (*output_device_begin_write)(struct SoundIo *, struct SoundIoOutputDevice *,
|
||||
int (*out_stream_init)(struct SoundIo *, struct SoundIoOutStream *);
|
||||
void (*out_stream_destroy)(struct SoundIo *, struct SoundIoOutStream *);
|
||||
int (*out_stream_start)(struct SoundIo *, struct SoundIoOutStream *);
|
||||
int (*out_stream_free_count)(struct SoundIo *, struct SoundIoOutStream *);
|
||||
void (*out_stream_begin_write)(struct SoundIo *, struct SoundIoOutStream *,
|
||||
char **data, int *frame_count);
|
||||
void (*output_device_write)(struct SoundIo *, struct SoundIoOutputDevice *,
|
||||
void (*out_stream_write)(struct SoundIo *, struct SoundIoOutStream *,
|
||||
char *data, int frame_count);
|
||||
void (*output_device_clear_buffer)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
void (*out_stream_clear_buffer)(struct SoundIo *, struct SoundIoOutStream *);
|
||||
|
||||
|
||||
int (*input_device_init)(struct SoundIo *, struct SoundIoInputDevice *);
|
||||
void (*input_device_destroy)(struct SoundIo *, struct SoundIoInputDevice *);
|
||||
int (*input_device_start)(struct SoundIo *, struct SoundIoInputDevice *);
|
||||
void (*input_device_peek)(struct SoundIo *, struct SoundIoInputDevice *,
|
||||
int (*in_stream_init)(struct SoundIo *, struct SoundIoInStream *);
|
||||
void (*in_stream_destroy)(struct SoundIo *, struct SoundIoInStream *);
|
||||
int (*in_stream_start)(struct SoundIo *, struct SoundIoInStream *);
|
||||
void (*in_stream_peek)(struct SoundIo *, struct SoundIoInStream *,
|
||||
const char **data, int *frame_count);
|
||||
void (*input_device_drop)(struct SoundIo *, struct SoundIoInputDevice *);
|
||||
void (*input_device_clear_buffer)(struct SoundIo *, struct SoundIoInputDevice *);
|
||||
void (*in_stream_drop)(struct SoundIo *, struct SoundIoInStream *);
|
||||
void (*in_stream_clear_buffer)(struct SoundIo *, struct SoundIoInStream *);
|
||||
};
|
||||
|
||||
// Main Context
|
||||
|
@ -411,47 +409,47 @@ enum SoundIoDevicePurpose soundio_device_purpose(const struct SoundIoDevice *dev
|
|||
|
||||
// Output Devices
|
||||
|
||||
int soundio_output_device_create(struct SoundIoDevice *device,
|
||||
int soundio_out_stream_create(struct SoundIoDevice *device,
|
||||
enum SoundIoFormat format, int sample_rate,
|
||||
double latency, void *userdata,
|
||||
void (*write_callback)(struct SoundIoOutputDevice *, int frame_count),
|
||||
void (*underrun_callback)(struct SoundIoOutputDevice *),
|
||||
struct SoundIoOutputDevice **out_output_device);
|
||||
void soundio_output_device_destroy(struct SoundIoOutputDevice *output_device);
|
||||
void (*write_callback)(struct SoundIoOutStream *, int frame_count),
|
||||
void (*underrun_callback)(struct SoundIoOutStream *),
|
||||
struct SoundIoOutStream **out_out_stream);
|
||||
void soundio_out_stream_destroy(struct SoundIoOutStream *out_stream);
|
||||
|
||||
int soundio_output_device_start(struct SoundIoOutputDevice *output_device);
|
||||
int soundio_out_stream_start(struct SoundIoOutStream *out_stream);
|
||||
|
||||
void soundio_output_device_fill_with_silence(struct SoundIoOutputDevice *output_device);
|
||||
void soundio_out_stream_fill_with_silence(struct SoundIoOutStream *out_stream);
|
||||
|
||||
|
||||
// number of frames available to write
|
||||
int soundio_output_device_free_count(struct SoundIoOutputDevice *output_device);
|
||||
void soundio_output_device_begin_write(struct SoundIoOutputDevice *output_device,
|
||||
int soundio_out_stream_free_count(struct SoundIoOutStream *out_stream);
|
||||
void soundio_out_stream_begin_write(struct SoundIoOutStream *out_stream,
|
||||
char **data, int *frame_count);
|
||||
void soundio_output_device_write(struct SoundIoOutputDevice *output_device,
|
||||
void soundio_out_stream_write(struct SoundIoOutStream *out_stream,
|
||||
char *data, int frame_count);
|
||||
|
||||
void soundio_output_device_clear_buffer(struct SoundIoOutputDevice *output_device);
|
||||
void soundio_out_stream_clear_buffer(struct SoundIoOutStream *out_stream);
|
||||
|
||||
|
||||
|
||||
// Input Devices
|
||||
|
||||
int soundio_input_device_create(struct SoundIoDevice *device,
|
||||
int soundio_in_stream_create(struct SoundIoDevice *device,
|
||||
enum SoundIoFormat format, int sample_rate,
|
||||
double latency, void *userdata,
|
||||
void (*read_callback)(struct SoundIoInputDevice *),
|
||||
struct SoundIoInputDevice **out_input_device);
|
||||
void soundio_input_device_destroy(struct SoundIoInputDevice *input_device);
|
||||
void (*read_callback)(struct SoundIoInStream *),
|
||||
struct SoundIoInStream **out_in_stream);
|
||||
void soundio_in_stream_destroy(struct SoundIoInStream *in_stream);
|
||||
|
||||
int soundio_input_device_start(struct SoundIoInputDevice *input_device);
|
||||
int soundio_in_stream_start(struct SoundIoInStream *in_stream);
|
||||
|
||||
void soundio_input_device_peek(struct SoundIoInputDevice *input_device,
|
||||
void soundio_in_stream_peek(struct SoundIoInStream *in_stream,
|
||||
const char **data, int *out_frame_count);
|
||||
// this will drop all of the frames from when you called soundio_input_device_peek
|
||||
void soundio_input_device_drop(struct SoundIoInputDevice *input_device);
|
||||
// this will drop all of the frames from when you called soundio_in_stream_peek
|
||||
void soundio_in_stream_drop(struct SoundIoInStream *in_stream);
|
||||
|
||||
void soundio_input_device_clear_buffer(struct SoundIoInputDevice *input_device);
|
||||
void soundio_in_stream_clear_buffer(struct SoundIoInStream *in_stream);
|
||||
|
||||
|
||||
// Ring Buffer
|
||||
|
|
|
@ -23,10 +23,10 @@ static void test_os_get_time(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void write_callback(struct SoundIoOutputDevice *device, int frame_count) { }
|
||||
static void underrun_callback(struct SoundIoOutputDevice *device) { }
|
||||
static void write_callback(struct SoundIoOutStream *device, int frame_count) { }
|
||||
static void underrun_callback(struct SoundIoOutStream *device) { }
|
||||
|
||||
static void test_create_output_device(void) {
|
||||
static void test_create_out_stream(void) {
|
||||
struct SoundIo *soundio = soundio_create();
|
||||
assert(soundio);
|
||||
ok_or_panic(soundio_connect(soundio));
|
||||
|
@ -36,10 +36,10 @@ static void test_create_output_device(void) {
|
|||
assert(device);
|
||||
soundio_device_name(device);
|
||||
soundio_device_description(device);
|
||||
struct SoundIoOutputDevice *output_device;
|
||||
soundio_output_device_create(device, SoundIoFormatFloat32NE, 48000, 0.1, NULL,
|
||||
write_callback, underrun_callback, &output_device);
|
||||
soundio_output_device_destroy(output_device);
|
||||
struct SoundIoOutStream *out_stream;
|
||||
soundio_out_stream_create(device, SoundIoFormatFloat32NE, 48000, 0.1, NULL,
|
||||
write_callback, underrun_callback, &out_stream);
|
||||
soundio_out_stream_destroy(out_stream);
|
||||
soundio_device_unref(device);
|
||||
soundio_destroy(soundio);
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ struct Test {
|
|||
|
||||
static struct Test tests[] = {
|
||||
{"os_get_time", test_os_get_time},
|
||||
{"create output device", test_create_output_device},
|
||||
{"create output stream", test_create_out_stream},
|
||||
{"ring buffer basic", test_ring_buffer_basic},
|
||||
{"ring buffer threaded", test_ring_buffer_threaded},
|
||||
{NULL, NULL},
|
||||
|
|
Loading…
Reference in a new issue