mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 08:45:37 +00:00
support stream names (used for PulseAudio)
This commit is contained in:
parent
de5bb99d1f
commit
be2675e551
|
@ -235,6 +235,7 @@ view `coverage/index.html` in a browser.
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
0. implement ALSA (Linux) backend, get examples working
|
0. implement ALSA (Linux) backend, get examples working
|
||||||
|
0. ALSA: poll instead of callback
|
||||||
0. fix pulseaudio backend since I broke it
|
0. fix pulseaudio backend since I broke it
|
||||||
0. pipe record to playback example working with dummy linux, osx, windows
|
0. pipe record to playback example working with dummy linux, osx, windows
|
||||||
0. pipe record to playback example working with pulseaudio linux
|
0. pipe record to playback example working with pulseaudio linux
|
||||||
|
|
|
@ -39,15 +39,12 @@ static void playback_thread_run(void *arg) {
|
||||||
SoundIoOutStream *outstream = &os->pub;
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||||
|
|
||||||
double start_time = soundio_os_get_time();
|
|
||||||
long frames_consumed = 0;
|
long frames_consumed = 0;
|
||||||
|
double start_time = soundio_os_get_time();
|
||||||
double time_per_frame = 1.0 / (double)outstream->sample_rate;
|
|
||||||
|
|
||||||
while (osd->abort_flag.test_and_set()) {
|
while (osd->abort_flag.test_and_set()) {
|
||||||
double now = soundio_os_get_time();
|
double now = soundio_os_get_time();
|
||||||
double total_time = now - start_time;
|
double total_time = now - start_time;
|
||||||
long total_frames = total_time / time_per_frame;
|
long total_frames = total_time * outstream->sample_rate;
|
||||||
int frames_to_kill = total_frames - frames_consumed;
|
int frames_to_kill = total_frames - frames_consumed;
|
||||||
int fill_count = soundio_ring_buffer_fill_count(&osd->ring_buffer);
|
int fill_count = soundio_ring_buffer_fill_count(&osd->ring_buffer);
|
||||||
int frames_in_buffer = fill_count / outstream->bytes_per_frame;
|
int frames_in_buffer = fill_count / outstream->bytes_per_frame;
|
||||||
|
@ -59,6 +56,9 @@ static void playback_thread_run(void *arg) {
|
||||||
|
|
||||||
if (frames_left > 0) {
|
if (frames_left > 0) {
|
||||||
outstream->error_callback(outstream, SoundIoErrorUnderflow);
|
outstream->error_callback(outstream, SoundIoErrorUnderflow);
|
||||||
|
// simulate filling with silence
|
||||||
|
int free_count = soundio_ring_buffer_free_count(&osd->ring_buffer);
|
||||||
|
soundio_ring_buffer_advance_write_ptr(&osd->ring_buffer, free_count);
|
||||||
} else if (read_count > 0) {
|
} else if (read_count > 0) {
|
||||||
outstream->write_callback(outstream, read_count);
|
outstream->write_callback(outstream, read_count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
// safe to call from any thread(s) multiple times, but
|
// safe to call from any thread(s) multiple times, but
|
||||||
// must be called at least once before calling any other os functions
|
// must be called at least once before calling any other os functions
|
||||||
|
// soundio_create calls this function.
|
||||||
void soundio_os_init(void);
|
void soundio_os_init(void);
|
||||||
|
|
||||||
double soundio_os_get_time(void);
|
double soundio_os_get_time(void);
|
||||||
|
|
|
@ -627,8 +627,7 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||||
|
|
||||||
// TODO handle period_duration
|
// TODO handle period_duration
|
||||||
|
|
||||||
// TODO make this value ("SoundIo") configurable
|
ospa->stream = pa_stream_new(sipa->pulse_context, outstream->name, &sample_spec, &channel_map);
|
||||||
ospa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
|
||||||
if (!ospa->stream) {
|
if (!ospa->stream) {
|
||||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||||
outstream_destroy_pa(si, os);
|
outstream_destroy_pa(si, os);
|
||||||
|
@ -806,8 +805,7 @@ static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||||
|
|
||||||
// TODO handle period_duration
|
// TODO handle period_duration
|
||||||
|
|
||||||
// TODO make this value ("SoundIo") private
|
ispa->stream = pa_stream_new(sipa->pulse_context, instream->name, &sample_spec, &channel_map);
|
||||||
ispa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
|
|
||||||
if (!ispa->stream) {
|
if (!ispa->stream) {
|
||||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||||
instream_destroy_pa(si, is);
|
instream_destroy_pa(si, is);
|
||||||
|
|
|
@ -389,6 +389,7 @@ struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device)
|
||||||
outstream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
outstream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
||||||
outstream->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
|
outstream->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
|
||||||
outstream->period_duration = -1.0;
|
outstream->period_duration = -1.0;
|
||||||
|
outstream->name = "SoundIo";
|
||||||
|
|
||||||
return outstream;
|
return outstream;
|
||||||
}
|
}
|
||||||
|
@ -457,6 +458,7 @@ struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) {
|
||||||
instream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
instream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
||||||
instream->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
|
instream->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
|
||||||
instream->period_duration = -1.0;
|
instream->period_duration = -1.0;
|
||||||
|
instream->name = "SoundIo";
|
||||||
|
|
||||||
return instream;
|
return instream;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,6 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct SoundIo;
|
|
||||||
struct SoundIoDevicesInfo;
|
|
||||||
|
|
||||||
enum SoundIoError {
|
enum SoundIoError {
|
||||||
SoundIoErrorNone,
|
SoundIoErrorNone,
|
||||||
SoundIoErrorNoMem,
|
SoundIoErrorNoMem,
|
||||||
|
@ -197,6 +194,19 @@ struct SoundIoChannelArea {
|
||||||
int step;
|
int step;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The size of this struct is not part of the API or ABI.
|
||||||
|
struct SoundIo {
|
||||||
|
// Defaults to NULL. Put whatever you want here.
|
||||||
|
void *userdata;
|
||||||
|
// Optional callback. Called when the list of devices change. Only called
|
||||||
|
// during a call to soundio_flush_events or soundio_wait_events.
|
||||||
|
void (*on_devices_change)(struct SoundIo *);
|
||||||
|
// Optional callback. Called from an unknown thread that you should not use
|
||||||
|
// to call any soundio functions. You may use this to signal a condition
|
||||||
|
// variable to wake up. Called when soundio_wait_events would be woken up.
|
||||||
|
void (*on_events_signal)(struct SoundIo *);
|
||||||
|
};
|
||||||
|
|
||||||
// The size of this struct is not part of the API or ABI.
|
// The size of this struct is not part of the API or ABI.
|
||||||
struct SoundIoDevice {
|
struct SoundIoDevice {
|
||||||
// Read-only. Set automatically.
|
// Read-only. Set automatically.
|
||||||
|
@ -314,6 +324,9 @@ struct SoundIoOutStream {
|
||||||
void (*error_callback)(struct SoundIoOutStream *, int err);
|
void (*error_callback)(struct SoundIoOutStream *, int err);
|
||||||
void (*write_callback)(struct SoundIoOutStream *, int requested_frame_count);
|
void (*write_callback)(struct SoundIoOutStream *, int requested_frame_count);
|
||||||
|
|
||||||
|
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
||||||
|
const char *name;
|
||||||
|
|
||||||
// computed automatically when you call soundio_outstream_open
|
// computed automatically when you call soundio_outstream_open
|
||||||
int bytes_per_frame;
|
int bytes_per_frame;
|
||||||
int bytes_per_sample;
|
int bytes_per_sample;
|
||||||
|
@ -347,24 +360,14 @@ struct SoundIoInStream {
|
||||||
void *userdata;
|
void *userdata;
|
||||||
void (*read_callback)(struct SoundIoInStream *);
|
void (*read_callback)(struct SoundIoInStream *);
|
||||||
|
|
||||||
|
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
||||||
|
const char *name;
|
||||||
|
|
||||||
// computed automatically when you call soundio_instream_open
|
// computed automatically when you call soundio_instream_open
|
||||||
int bytes_per_frame;
|
int bytes_per_frame;
|
||||||
int bytes_per_sample;
|
int bytes_per_sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The size of this struct is not part of the API or ABI.
|
|
||||||
struct SoundIo {
|
|
||||||
// Defaults to NULL. Put whatever you want here.
|
|
||||||
void *userdata;
|
|
||||||
// Optional callback. Called when the list of devices change. Only called
|
|
||||||
// during a call to soundio_flush_events or soundio_wait_events.
|
|
||||||
void (*on_devices_change)(struct SoundIo *);
|
|
||||||
// Optional callback. Called from an unknown thread that you should not use
|
|
||||||
// to call any soundio functions. You may use this to signal a condition
|
|
||||||
// variable to wake up. Called when soundio_wait_events would be woken up.
|
|
||||||
void (*on_events_signal)(struct SoundIo *);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Main Context
|
// Main Context
|
||||||
|
|
||||||
// Create a SoundIo context. You may create multiple instances of this to
|
// Create a SoundIo context. You may create multiple instances of this to
|
||||||
|
|
Loading…
Reference in a new issue