mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 22:35:28 +00:00
SoundIoOutStream, SoundIoInStream: void * -> union
For better cache locality and lower mlock requirements.
This commit is contained in:
parent
db1195877a
commit
70decb39f5
|
@ -280,8 +280,6 @@ view `coverage/index.html` in a browser.
|
|||
0. Support PulseAudio proplist properties for main context and streams
|
||||
0. custom allocator support
|
||||
0. mlock memory which is accessed in the real time path
|
||||
0. instead of `void *backend_data` use a union for better cache locality
|
||||
and smaller mlock requirements
|
||||
0. Consider testing on FreeBSD
|
||||
0. make rtprio warning a callback and have existing behavior be the default callback
|
||||
0. write detailed docs on buffer underflows explaining when they occur, what state
|
||||
|
|
104
src/alsa.cpp
104
src/alsa.cpp
|
@ -8,7 +8,6 @@
|
|||
#include "alsa.hpp"
|
||||
#include "soundio.hpp"
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <math.h>
|
||||
|
||||
|
@ -23,39 +22,6 @@ static snd_pcm_access_t prioritized_access_types[] = {
|
|||
};
|
||||
|
||||
|
||||
struct SoundIoOutStreamAlsa {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_chmap_t *chmap;
|
||||
int chmap_size;
|
||||
snd_pcm_uframes_t offset;
|
||||
snd_pcm_access_t access;
|
||||
int sample_buffer_size;
|
||||
char *sample_buffer;
|
||||
int poll_fd_count;
|
||||
struct pollfd *poll_fds;
|
||||
SoundIoOsThread *thread;
|
||||
atomic_flag thread_exit_flag;
|
||||
int period_size;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamAlsa {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_chmap_t *chmap;
|
||||
int chmap_size;
|
||||
snd_pcm_uframes_t offset;
|
||||
snd_pcm_access_t access;
|
||||
int sample_buffer_size;
|
||||
char *sample_buffer;
|
||||
int poll_fd_count;
|
||||
struct pollfd *poll_fds;
|
||||
SoundIoOsThread *thread;
|
||||
atomic_flag thread_exit_flag;
|
||||
int period_size;
|
||||
int read_frame_count;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
static void wakeup_device_poll(SoundIoAlsa *sia) {
|
||||
ssize_t amt = write(sia->notify_pipe_fd[1], "a", 1);
|
||||
if (amt == -1) {
|
||||
|
@ -881,9 +847,7 @@ static void wakeup(SoundIoPrivate *si) {
|
|||
}
|
||||
|
||||
static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
if (!osa)
|
||||
return;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
|
||||
if (osa->thread) {
|
||||
osa->thread_exit_flag.clear();
|
||||
|
@ -898,14 +862,11 @@ static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *
|
|||
deallocate(osa->chmap, osa->chmap_size);
|
||||
|
||||
deallocate(osa->sample_buffer, osa->sample_buffer_size);
|
||||
|
||||
destroy(osa);
|
||||
os->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int xrun_recovery(SoundIoOutStreamPrivate *os, int err) {
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *)os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
if (err == -EPIPE) {
|
||||
err = snd_pcm_prepare(osa->handle);
|
||||
if (err >= 0)
|
||||
|
@ -924,7 +885,7 @@ static int xrun_recovery(SoundIoOutStreamPrivate *os, int err) {
|
|||
}
|
||||
|
||||
static int instream_xrun_recovery(SoundIoInStreamPrivate *is, int err) {
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *)is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
if (err == -EPIPE) {
|
||||
err = snd_pcm_prepare(isa->handle);
|
||||
} else if (err == -ESTRPIPE) {
|
||||
|
@ -977,7 +938,7 @@ static int instream_wait_for_poll(SoundIoInStreamAlsa *isa) {
|
|||
void outstream_thread_run(void *arg) {
|
||||
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *) arg;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
|
||||
int err;
|
||||
|
||||
|
@ -1046,37 +1007,37 @@ void outstream_thread_run(void *arg) {
|
|||
static void instream_thread_run(void *arg) {
|
||||
SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *) arg;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoInStreamAlsa *osa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
|
||||
int err;
|
||||
|
||||
for (;;) {
|
||||
snd_pcm_state_t state = snd_pcm_state(osa->handle);
|
||||
snd_pcm_state_t state = snd_pcm_state(isa->handle);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_SETUP:
|
||||
if ((err = snd_pcm_prepare(osa->handle)) < 0) {
|
||||
if ((err = snd_pcm_prepare(isa->handle)) < 0) {
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
if ((err = snd_pcm_start(osa->handle)) < 0) {
|
||||
if ((err = snd_pcm_start(isa->handle)) < 0) {
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
{
|
||||
if ((err = instream_wait_for_poll(osa)) < 0) {
|
||||
if (!osa->thread_exit_flag.test_and_set())
|
||||
if ((err = instream_wait_for_poll(isa)) < 0) {
|
||||
if (!isa->thread_exit_flag.test_and_set())
|
||||
return;
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
if (!osa->thread_exit_flag.test_and_set())
|
||||
if (!isa->thread_exit_flag.test_and_set())
|
||||
return;
|
||||
|
||||
snd_pcm_sframes_t avail = snd_pcm_avail_update(osa->handle);
|
||||
snd_pcm_sframes_t avail = snd_pcm_avail_update(isa->handle);
|
||||
if (avail < 0) {
|
||||
if ((err = instream_xrun_recovery(is, avail)) < 0) {
|
||||
instream->error_callback(instream, SoundIoErrorStreaming);
|
||||
|
@ -1111,6 +1072,7 @@ static void instream_thread_run(void *arg) {
|
|||
}
|
||||
|
||||
static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoDevice *device = outstream->device;
|
||||
|
||||
|
@ -1123,13 +1085,6 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
|
|||
if (outstream->prebuf_duration == -1.0)
|
||||
outstream->prebuf_duration = outstream->buffer_duration;
|
||||
|
||||
SoundIoOutStreamAlsa *osa = create<SoundIoOutStreamAlsa>();
|
||||
if (!osa) {
|
||||
outstream_destroy_alsa(si, os);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
os->backend_data = osa;
|
||||
|
||||
int ch_count = outstream->layout.channel_count;
|
||||
|
||||
osa->chmap_size = sizeof(int) + sizeof(int) * ch_count;
|
||||
|
@ -1284,7 +1239,7 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
|
|||
}
|
||||
|
||||
static int outstream_start_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
|
||||
assert(!osa->thread);
|
||||
|
||||
|
@ -1302,7 +1257,7 @@ int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os,
|
|||
struct SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
*out_areas = nullptr;
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
|
||||
if (osa->access == SND_PCM_ACCESS_RW_INTERLEAVED) {
|
||||
|
@ -1345,7 +1300,7 @@ int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os,
|
|||
}
|
||||
|
||||
static int outstream_end_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, int frame_count) {
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
|
||||
snd_pcm_sframes_t commitres;
|
||||
|
@ -1373,7 +1328,7 @@ static int outstream_end_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate
|
|||
static int outstream_clear_buffer_alsa(SoundIoPrivate *si,
|
||||
SoundIoOutStreamPrivate *os)
|
||||
{
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
int err;
|
||||
if ((err = snd_pcm_reset(osa->handle)) < 0)
|
||||
return SoundIoErrorStreaming;
|
||||
|
@ -1381,7 +1336,7 @@ static int outstream_clear_buffer_alsa(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||
SoundIoOutStreamAlsa *osa = (SoundIoOutStreamAlsa *) os->backend_data;
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
int err;
|
||||
if ((err = snd_pcm_pause(osa->handle, pause)) < 0)
|
||||
return SoundIoErrorIncompatibleDevice;
|
||||
|
@ -1389,9 +1344,7 @@ static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStre
|
|||
}
|
||||
|
||||
static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
if (!isa)
|
||||
return;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
|
||||
if (isa->thread) {
|
||||
isa->thread_exit_flag.clear();
|
||||
|
@ -1404,12 +1357,10 @@ static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is
|
|||
deallocate(isa->poll_fds, isa->poll_fd_count);
|
||||
deallocate(isa->chmap, isa->chmap_size);
|
||||
deallocate(isa->sample_buffer, isa->sample_buffer_size);
|
||||
|
||||
destroy(isa);
|
||||
is->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoDevice *device = instream->device;
|
||||
|
||||
|
@ -1420,13 +1371,6 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
|||
instream->buffer_duration / 8.0, device->period_duration_max);
|
||||
}
|
||||
|
||||
SoundIoInStreamAlsa *isa = create<SoundIoInStreamAlsa>();
|
||||
if (!isa) {
|
||||
instream_destroy_alsa(si, is);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
is->backend_data = isa;
|
||||
|
||||
int ch_count = instream->layout.channel_count;
|
||||
|
||||
isa->chmap_size = sizeof(int) + sizeof(int) * ch_count;
|
||||
|
@ -1568,7 +1512,7 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
|||
}
|
||||
|
||||
static int instream_start_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
|
||||
assert(!isa->thread);
|
||||
|
||||
|
@ -1586,7 +1530,7 @@ static int instream_begin_read_alsa(SoundIoPrivate *si,
|
|||
SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
*out_areas = nullptr;
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
|
||||
if (isa->access == SND_PCM_ACCESS_RW_INTERLEAVED) {
|
||||
|
@ -1646,7 +1590,7 @@ static int instream_begin_read_alsa(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int instream_end_read_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
|
||||
if (isa->access == SND_PCM_ACCESS_RW_INTERLEAVED) {
|
||||
return 0;
|
||||
|
@ -1665,7 +1609,7 @@ static int instream_end_read_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is
|
|||
}
|
||||
|
||||
static int instream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) {
|
||||
SoundIoInStreamAlsa *isa = (SoundIoInStreamAlsa *) is->backend_data;
|
||||
SoundIoInStreamAlsa *isa = &is->backend_data.alsa;
|
||||
int err;
|
||||
if ((err = snd_pcm_pause(isa->handle, pause)) < 0)
|
||||
return SoundIoErrorIncompatibleDevice;
|
||||
|
|
36
src/alsa.hpp
36
src/alsa.hpp
|
@ -8,9 +8,12 @@
|
|||
#ifndef SOUNDIO_ALSA_HPP
|
||||
#define SOUNDIO_ALSA_HPP
|
||||
|
||||
#include "soundio.h"
|
||||
#include "os.hpp"
|
||||
#include "atomics.hpp"
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
int soundio_alsa_init(struct SoundIoPrivate *si);
|
||||
|
||||
struct SoundIoDeviceAlsa {
|
||||
|
@ -32,4 +35,37 @@ struct SoundIoAlsa {
|
|||
struct SoundIoDevicesInfo *ready_devices_info;
|
||||
};
|
||||
|
||||
struct SoundIoOutStreamAlsa {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_chmap_t *chmap;
|
||||
int chmap_size;
|
||||
snd_pcm_uframes_t offset;
|
||||
snd_pcm_access_t access;
|
||||
int sample_buffer_size;
|
||||
char *sample_buffer;
|
||||
int poll_fd_count;
|
||||
struct pollfd *poll_fds;
|
||||
SoundIoOsThread *thread;
|
||||
atomic_flag thread_exit_flag;
|
||||
int period_size;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamAlsa {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_chmap_t *chmap;
|
||||
int chmap_size;
|
||||
snd_pcm_uframes_t offset;
|
||||
snd_pcm_access_t access;
|
||||
int sample_buffer_size;
|
||||
char *sample_buffer;
|
||||
int poll_fd_count;
|
||||
struct pollfd *poll_fds;
|
||||
SoundIoOsThread *thread;
|
||||
atomic_flag thread_exit_flag;
|
||||
int period_size;
|
||||
int read_frame_count;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,41 +7,15 @@
|
|||
|
||||
#include "dummy.hpp"
|
||||
#include "soundio.hpp"
|
||||
#include "atomics.hpp"
|
||||
#include "ring_buffer.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct SoundIoOutStreamDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int buffer_frame_count;
|
||||
struct SoundIoRingBuffer ring_buffer;
|
||||
int prebuf_frame_count;
|
||||
int prebuf_frames_left;
|
||||
long frames_consumed;
|
||||
double playback_start_time;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int read_frame_count;
|
||||
int buffer_frame_count;
|
||||
struct SoundIoRingBuffer ring_buffer;
|
||||
int hole_size;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
static void playback_thread_run(void *arg) {
|
||||
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
|
||||
double start_time = soundio_os_get_time();
|
||||
osd->playback_start_time = start_time;
|
||||
|
@ -90,7 +64,7 @@ static void playback_thread_run(void *arg) {
|
|||
static void capture_thread_run(void *arg) {
|
||||
SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoInStreamDummy *isd = (SoundIoInStreamDummy *)is->backend_data;
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
|
||||
long frames_consumed = 0;
|
||||
double start_time = soundio_os_get_time();
|
||||
|
@ -150,9 +124,7 @@ static void wakeup(SoundIoPrivate *si) {
|
|||
}
|
||||
|
||||
static void outstream_destroy_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
if (!osd)
|
||||
return;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
|
||||
if (osd->thread) {
|
||||
osd->abort_flag.clear();
|
||||
|
@ -164,12 +136,10 @@ static void outstream_destroy_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate
|
|||
osd->cond = nullptr;
|
||||
|
||||
soundio_ring_buffer_deinit(&osd->ring_buffer);
|
||||
|
||||
destroy(osd);
|
||||
os->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoDevice *device = outstream->device;
|
||||
|
||||
|
@ -180,13 +150,6 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
|
|||
outstream->buffer_duration / 2.0, device->period_duration_max);
|
||||
}
|
||||
|
||||
SoundIoOutStreamDummy *osd = create<SoundIoOutStreamDummy>();
|
||||
if (!osd) {
|
||||
outstream_destroy_dummy(si, os);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
os->backend_data = osd;
|
||||
|
||||
int err;
|
||||
int buffer_size = outstream->bytes_per_frame * outstream->sample_rate * outstream->buffer_duration;
|
||||
if ((err = soundio_ring_buffer_init(&osd->ring_buffer, buffer_size))) {
|
||||
|
@ -212,7 +175,7 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
|
|||
}
|
||||
|
||||
static int outstream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
if (pause) {
|
||||
if (osd->thread) {
|
||||
osd->abort_flag.clear();
|
||||
|
@ -242,7 +205,7 @@ static int outstream_begin_write_dummy(SoundIoPrivate *si,
|
|||
*out_areas = nullptr;
|
||||
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
|
||||
assert(*frame_count >= 0);
|
||||
assert(*frame_count <= osd->buffer_frame_count);
|
||||
|
@ -264,7 +227,7 @@ static int outstream_begin_write_dummy(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int outstream_end_write_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, int frame_count) {
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
int byte_count = frame_count * outstream->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_write_ptr(&osd->ring_buffer, byte_count);
|
||||
|
@ -279,16 +242,14 @@ static int outstream_end_write_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate
|
|||
}
|
||||
|
||||
static int outstream_clear_buffer_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamDummy *osd = (SoundIoOutStreamDummy *)os->backend_data;
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
soundio_ring_buffer_clear(&osd->ring_buffer);
|
||||
osd->prebuf_frames_left = osd->prebuf_frame_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void instream_destroy_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamDummy *isd = (SoundIoInStreamDummy *)is->backend_data;
|
||||
if (!isd)
|
||||
return;
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
|
||||
if (isd->thread) {
|
||||
isd->abort_flag.clear();
|
||||
|
@ -300,12 +261,10 @@ static void instream_destroy_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *i
|
|||
isd->cond = nullptr;
|
||||
|
||||
soundio_ring_buffer_deinit(&isd->ring_buffer);
|
||||
|
||||
destroy(isd);
|
||||
is->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoDevice *device = instream->device;
|
||||
|
||||
|
@ -316,13 +275,6 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
|||
instream->buffer_duration / 8.0, instream->device->period_duration_max);
|
||||
}
|
||||
|
||||
SoundIoInStreamDummy *isd = create<SoundIoInStreamDummy>();
|
||||
if (!isd) {
|
||||
instream_destroy_dummy(si, is);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
is->backend_data = isd;
|
||||
|
||||
int err;
|
||||
int buffer_size = instream->bytes_per_frame * instream->sample_rate * instream->buffer_duration;
|
||||
if ((err = soundio_ring_buffer_init(&isd->ring_buffer, buffer_size))) {
|
||||
|
@ -344,7 +296,7 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
|||
}
|
||||
|
||||
static int instream_pause_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) {
|
||||
SoundIoInStreamDummy *isd = (SoundIoInStreamDummy *)is->backend_data;
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
if (pause) {
|
||||
if (isd->thread) {
|
||||
isd->abort_flag.clear();
|
||||
|
@ -372,7 +324,7 @@ static int instream_begin_read_dummy(SoundIoPrivate *si,
|
|||
SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoInStreamDummy *isd = (SoundIoInStreamDummy *)is->backend_data;
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
|
||||
assert(*frame_count >= 0);
|
||||
assert(*frame_count <= isd->buffer_frame_count);
|
||||
|
@ -403,7 +355,7 @@ static int instream_begin_read_dummy(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int instream_end_read_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamDummy *isd = (SoundIoInStreamDummy *)is->backend_data;
|
||||
SoundIoInStreamDummy *isd = &is->backend_data.dummy;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
|
||||
if (isd->hole_size > 0) {
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
#ifndef SOUNDIO_DUMMY_HPP
|
||||
#define SOUNDIO_DUMMY_HPP
|
||||
|
||||
#include "soundio.h"
|
||||
#include "os.hpp"
|
||||
#include "atomics.hpp"
|
||||
#include "ring_buffer.hpp"
|
||||
|
||||
int soundio_dummy_init(struct SoundIoPrivate *si);
|
||||
|
||||
|
@ -22,4 +25,28 @@ struct SoundIoDeviceDummy {
|
|||
|
||||
};
|
||||
|
||||
struct SoundIoOutStreamDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int buffer_frame_count;
|
||||
struct SoundIoRingBuffer ring_buffer;
|
||||
int prebuf_frame_count;
|
||||
int prebuf_frames_left;
|
||||
long frames_consumed;
|
||||
double playback_start_time;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int read_frame_count;
|
||||
int buffer_frame_count;
|
||||
struct SoundIoRingBuffer ring_buffer;
|
||||
int hole_size;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
22
src/jack.cpp
22
src/jack.cpp
|
@ -14,11 +14,6 @@
|
|||
|
||||
static atomic_flag global_msg_callback_flag = ATOMIC_FLAG_INIT;
|
||||
|
||||
struct SoundIoOutStreamJack {
|
||||
jack_client_t *client;
|
||||
jack_port_t *ports[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoJackPort {
|
||||
const char *name;
|
||||
int name_len;
|
||||
|
@ -80,17 +75,13 @@ static int outstream_process_callback(jack_nframes_t nframes, void *arg) {
|
|||
}
|
||||
|
||||
static void outstream_destroy_jack(struct SoundIoPrivate *is, struct SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamJack *osj = (SoundIoOutStreamJack *) os->backend_data;
|
||||
if (!osj)
|
||||
return;
|
||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||
|
||||
jack_client_close(osj->client);
|
||||
|
||||
destroy(osj);
|
||||
os->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
//TODO SoundIoDevice *device = outstream->device;
|
||||
|
||||
|
@ -98,13 +89,6 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
|
|||
outstream->period_duration = 0.0; // TODO
|
||||
outstream->prebuf_duration = 0.0; // TODO
|
||||
|
||||
SoundIoOutStreamJack *osj = create<SoundIoOutStreamJack>();
|
||||
if (!osj) {
|
||||
outstream_destroy_jack(si, os);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
os->backend_data = osj;
|
||||
|
||||
outstream->layout_error = SoundIoErrorIncompatibleBackend;
|
||||
|
||||
jack_status_t status;
|
||||
|
@ -145,7 +129,7 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
|
|||
}
|
||||
|
||||
static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||
SoundIoOutStreamJack *osj = (SoundIoOutStreamJack *) os->backend_data;
|
||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
int err;
|
||||
if (pause) {
|
||||
|
|
11
src/jack.hpp
11
src/jack.hpp
|
@ -8,6 +8,7 @@
|
|||
#ifndef SOUNDIO_JACK_HPP
|
||||
#define SOUNDIO_JACK_HPP
|
||||
|
||||
#include "soundio.h"
|
||||
#include "os.hpp"
|
||||
|
||||
#include <jack/jack.h>
|
||||
|
@ -29,5 +30,13 @@ struct SoundIoJack {
|
|||
int buffer_size;
|
||||
};
|
||||
|
||||
#endif
|
||||
struct SoundIoOutStreamJack {
|
||||
jack_client_t *client;
|
||||
jack_port_t *ports[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamJack {
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,21 +13,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
|
||||
struct SoundIoOutStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
char *write_ptr;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
static void subscribe_callback(pa_context *context,
|
||||
pa_subscription_event_type_t event_bits, uint32_t index, void *userdata)
|
||||
{
|
||||
|
@ -570,7 +555,7 @@ static void playback_stream_state_callback(pa_stream *stream, void *userdata) {
|
|||
SoundIo *soundio = outstream->device->soundio;
|
||||
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
switch (pa_stream_get_state(stream)) {
|
||||
case PA_STREAM_UNCONNECTED:
|
||||
case PA_STREAM_CREATING:
|
||||
|
@ -598,9 +583,7 @@ static void playback_stream_write_callback(pa_stream *stream, size_t nbytes, voi
|
|||
}
|
||||
|
||||
static void outstream_destroy_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
if (!ospa)
|
||||
return;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_stream *stream = ospa->stream;
|
||||
|
@ -618,21 +601,12 @@ static void outstream_destroy_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os
|
|||
|
||||
ospa->stream = nullptr;
|
||||
}
|
||||
|
||||
destroy(ospa);
|
||||
os->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
|
||||
SoundIoOutStreamPulseAudio *ospa = create<SoundIoOutStreamPulseAudio>();
|
||||
if (!ospa) {
|
||||
outstream_destroy_pa(si, os);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
os->backend_data = ospa;
|
||||
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
ospa->stream_ready = false;
|
||||
|
||||
|
@ -686,7 +660,7 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
|||
static int outstream_start_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
|
@ -720,7 +694,7 @@ static int outstream_begin_write_pa(SoundIoPrivate *si,
|
|||
*out_areas = nullptr;
|
||||
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
pa_stream *stream = ospa->stream;
|
||||
size_t byte_count = *frame_count * outstream->bytes_per_frame;
|
||||
if (pa_stream_begin_write(stream, (void**)&ospa->write_ptr, &byte_count))
|
||||
|
@ -739,7 +713,7 @@ static int outstream_begin_write_pa(SoundIoPrivate *si,
|
|||
|
||||
static int outstream_end_write_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, int frame_count) {
|
||||
SoundIoOutStream *outstream = &os->pub;
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
pa_stream *stream = ospa->stream;
|
||||
assert(frame_count > 0);
|
||||
size_t byte_count = frame_count * outstream->bytes_per_frame;
|
||||
|
@ -752,7 +726,7 @@ static int outstream_end_write_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *o
|
|||
static int outstream_clear_buffer_pa(SoundIoPrivate *si,
|
||||
SoundIoOutStreamPrivate *os)
|
||||
{
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_stream *stream = ospa->stream;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
@ -765,7 +739,7 @@ static int outstream_clear_buffer_pa(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int outstream_pause_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, bool pause) {
|
||||
SoundIoOutStreamPulseAudio *ospa = (SoundIoOutStreamPulseAudio *)os->backend_data;
|
||||
SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
@ -784,7 +758,7 @@ static int outstream_pause_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, b
|
|||
|
||||
static void recording_stream_state_callback(pa_stream *stream, void *userdata) {
|
||||
SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate*)userdata;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)is->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIo *soundio = instream->device->soundio;
|
||||
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
||||
|
@ -814,11 +788,8 @@ static void recording_stream_read_callback(pa_stream *stream, size_t nbytes, voi
|
|||
instream->read_callback(instream, available_frame_count);
|
||||
}
|
||||
|
||||
static void instream_destroy_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *instream) {
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)instream->backend_data;
|
||||
if (!ispa)
|
||||
return;
|
||||
|
||||
static void instream_destroy_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_stream *stream = ispa->stream;
|
||||
if (stream) {
|
||||
|
@ -836,15 +807,9 @@ static void instream_destroy_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *inst
|
|||
}
|
||||
|
||||
static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
|
||||
SoundIoInStreamPulseAudio *ispa = create<SoundIoInStreamPulseAudio>();
|
||||
if (!ispa) {
|
||||
instream_destroy_pa(si, is);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
is->backend_data = ispa;
|
||||
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
ispa->stream_ready = false;
|
||||
|
||||
|
@ -889,7 +854,7 @@ static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
|||
|
||||
static int instream_start_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)is->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
||||
|
@ -918,7 +883,7 @@ static int instream_begin_read_pa(SoundIoPrivate *si,
|
|||
SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
SoundIoInStream *instream = &is->pub;
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)is->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
pa_stream *stream = ispa->stream;
|
||||
|
||||
assert(ispa->stream_ready);
|
||||
|
@ -948,7 +913,7 @@ static int instream_begin_read_pa(SoundIoPrivate *si,
|
|||
}
|
||||
|
||||
static int instream_end_read_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)is->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
pa_stream *stream = ispa->stream;
|
||||
if (pa_stream_drop(stream))
|
||||
return SoundIoErrorStreaming;
|
||||
|
@ -957,7 +922,7 @@ static int instream_end_read_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is)
|
|||
}
|
||||
|
||||
static int instream_pause_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) {
|
||||
SoundIoInStreamPulseAudio *ispa = (SoundIoInStreamPulseAudio *)is->backend_data;
|
||||
SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef SOUNDIO_PULSEAUDIO_HPP
|
||||
#define SOUNDIO_PULSEAUDIO_HPP
|
||||
|
||||
#include "soundio.h"
|
||||
#include "atomics.hpp"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
@ -43,4 +44,19 @@ struct SoundIoPulseAudio {
|
|||
pa_proplist *props;
|
||||
};
|
||||
|
||||
struct SoundIoOutStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
char *write_ptr;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
struct SoundIoInStreamPulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -186,8 +186,6 @@ int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) {
|
|||
if (!fn)
|
||||
return SoundIoErrorBackendUnavailable;
|
||||
|
||||
memset(&si->backend_data, 0, sizeof(SoundIoBackendData));
|
||||
|
||||
int err;
|
||||
if ((err = backend_init_fns[backend](si))) {
|
||||
soundio_disconnect(soundio);
|
||||
|
@ -201,10 +199,12 @@ void soundio_disconnect(struct SoundIo *soundio) {
|
|||
|
||||
if (si->destroy)
|
||||
si->destroy(si);
|
||||
memset(&si->backend_data, 0, sizeof(SoundIoBackendData));
|
||||
|
||||
soundio->current_backend = SoundIoBackendNone;
|
||||
|
||||
soundio_destroy_devices_info(si->safe_devices_info);
|
||||
|
||||
si->safe_devices_info = nullptr;
|
||||
|
||||
si->destroy = nullptr;
|
||||
|
|
|
@ -51,6 +51,32 @@ union SoundIoDeviceBackendData {
|
|||
SoundIoDeviceDummy dummy;
|
||||
};
|
||||
|
||||
union SoundIoOutStreamBackendData {
|
||||
#ifdef SOUNDIO_HAVE_JACK
|
||||
SoundIoOutStreamJack jack;
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
SoundIoOutStreamPulseAudio pulseaudio;
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_ALSA
|
||||
SoundIoOutStreamAlsa alsa;
|
||||
#endif
|
||||
SoundIoOutStreamDummy dummy;
|
||||
};
|
||||
|
||||
union SoundIoInStreamBackendData {
|
||||
#ifdef SOUNDIO_HAVE_JACK
|
||||
SoundIoInStreamJack jack;
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
SoundIoInStreamPulseAudio pulseaudio;
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_ALSA
|
||||
SoundIoInStreamAlsa alsa;
|
||||
#endif
|
||||
SoundIoInStreamDummy dummy;
|
||||
};
|
||||
|
||||
struct SoundIoDevicesInfo {
|
||||
SoundIoList<SoundIoDevice *> input_devices;
|
||||
SoundIoList<SoundIoDevice *> output_devices;
|
||||
|
@ -60,13 +86,13 @@ struct SoundIoDevicesInfo {
|
|||
};
|
||||
|
||||
struct SoundIoOutStreamPrivate {
|
||||
struct SoundIoOutStream pub;
|
||||
void *backend_data;
|
||||
SoundIoOutStream pub;
|
||||
SoundIoOutStreamBackendData backend_data;
|
||||
};
|
||||
|
||||
struct SoundIoInStreamPrivate {
|
||||
struct SoundIoInStream pub;
|
||||
void *backend_data;
|
||||
SoundIoInStream pub;
|
||||
SoundIoInStreamBackendData backend_data;
|
||||
};
|
||||
|
||||
struct SoundIoPrivate {
|
||||
|
|
Loading…
Reference in a new issue