support stream names (used for PulseAudio)

This commit is contained in:
Andrew Kelley 2015-07-20 20:13:35 -07:00
parent de5bb99d1f
commit be2675e551
6 changed files with 30 additions and 25 deletions

View file

@ -235,6 +235,7 @@ view `coverage/index.html` in a browser.
## Roadmap
0. implement ALSA (Linux) backend, get examples working
0. ALSA: poll instead of callback
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 pulseaudio linux

View file

@ -39,15 +39,12 @@ static void playback_thread_run(void *arg) {
SoundIoOutStream *outstream = &os->pub;
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
double start_time = soundio_os_get_time();
long frames_consumed = 0;
double time_per_frame = 1.0 / (double)outstream->sample_rate;
double start_time = soundio_os_get_time();
while (osd->abort_flag.test_and_set()) {
double now = soundio_os_get_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 fill_count = soundio_ring_buffer_fill_count(&osd->ring_buffer);
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) {
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) {
outstream->write_callback(outstream, read_count);
}

View file

@ -13,6 +13,7 @@
// safe to call from any thread(s) multiple times, but
// must be called at least once before calling any other os functions
// soundio_create calls this function.
void soundio_os_init(void);
double soundio_os_get_time(void);

View file

@ -627,8 +627,7 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
// TODO handle period_duration
// TODO make this value ("SoundIo") configurable
ospa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
ospa->stream = pa_stream_new(sipa->pulse_context, outstream->name, &sample_spec, &channel_map);
if (!ospa->stream) {
pa_threaded_mainloop_unlock(sipa->main_loop);
outstream_destroy_pa(si, os);
@ -806,8 +805,7 @@ static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
// TODO handle period_duration
// TODO make this value ("SoundIo") private
ispa->stream = pa_stream_new(sipa->pulse_context, "SoundIo", &sample_spec, &channel_map);
ispa->stream = pa_stream_new(sipa->pulse_context, instream->name, &sample_spec, &channel_map);
if (!ispa->stream) {
pa_threaded_mainloop_unlock(sipa->main_loop);
instream_destroy_pa(si, is);

View file

@ -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->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
outstream->period_duration = -1.0;
outstream->name = "SoundIo";
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->buffer_duration = clamp(device->buffer_duration_min, 1.0, device->buffer_duration_max);
instream->period_duration = -1.0;
instream->name = "SoundIo";
return instream;
}

View file

@ -16,9 +16,6 @@ extern "C"
{
#endif
struct SoundIo;
struct SoundIoDevicesInfo;
enum SoundIoError {
SoundIoErrorNone,
SoundIoErrorNoMem,
@ -197,6 +194,19 @@ struct SoundIoChannelArea {
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.
struct SoundIoDevice {
// Read-only. Set automatically.
@ -314,6 +324,9 @@ struct SoundIoOutStream {
void (*error_callback)(struct SoundIoOutStream *, int err);
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
int bytes_per_frame;
int bytes_per_sample;
@ -347,24 +360,14 @@ struct SoundIoInStream {
void *userdata;
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
int bytes_per_frame;
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
// Create a SoundIo context. You may create multiple instances of this to