mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 18:15:36 +00:00
list_devices example works with dummy backend
This commit is contained in:
parent
18a37da848
commit
6a5db549f5
|
@ -32,7 +32,7 @@ set(LIBSOUNDIO_HEADERS
|
|||
)
|
||||
|
||||
set(TEST_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/test/unit_tests.c"
|
||||
"${CMAKE_SOURCE_DIR}/test/unit_tests.cpp"
|
||||
)
|
||||
|
||||
find_package(Threads)
|
||||
|
|
|
@ -18,6 +18,35 @@ static int usage(char *exe) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void print_channel_layout(const struct SoundIoChannelLayout *layout) {
|
||||
if (layout->name) {
|
||||
fprintf(stderr, "%s", layout->name);
|
||||
} else {
|
||||
fprintf(stderr, "%s", soundio_get_channel_name(layout->channels[0]));
|
||||
for (int i = 1; i < layout->channel_count; i += 1) {
|
||||
fprintf(stderr, ", %s", soundio_get_channel_name(layout->channels[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void print_device(struct SoundIoDevice *device, bool is_default) {
|
||||
const char *purpose_str;
|
||||
const char *default_str;
|
||||
if (soundio_device_purpose(device) == SoundIoDevicePurposeOutput) {
|
||||
purpose_str = "playback";
|
||||
default_str = is_default ? " (default)" : "";
|
||||
} else {
|
||||
purpose_str = "recording";
|
||||
default_str = is_default ? " (default)" : "";
|
||||
}
|
||||
const char *description = soundio_device_description(device);
|
||||
int sample_rate = soundio_device_sample_rate(device);
|
||||
fprintf(stderr, "%s device: ", purpose_str);
|
||||
print_channel_layout(soundio_device_channel_layout(device));
|
||||
fprintf(stderr, " %d Hz %s%s\n", sample_rate, description, default_str);
|
||||
}
|
||||
|
||||
static int list_devices(struct SoundIo *soundio) {
|
||||
int output_count = soundio_get_output_device_count(soundio);
|
||||
int input_count = soundio_get_input_device_count(soundio);
|
||||
|
@ -27,21 +56,12 @@ static int list_devices(struct SoundIo *soundio) {
|
|||
|
||||
for (int i = 0; i < input_count; i += 1) {
|
||||
struct SoundIoDevice *device = soundio_get_input_device(soundio, i);
|
||||
const char *purpose_str = "input";
|
||||
const char *default_str = (i == default_input) ? " (default)" : "";
|
||||
const char *description = soundio_device_description(device);
|
||||
int sample_rate = soundio_device_sample_rate(device);
|
||||
fprintf(stderr, "%s device: %d Hz %s%s\n", purpose_str, sample_rate, description, default_str);
|
||||
print_device(device, default_input == i);
|
||||
soundio_device_unref(device);
|
||||
}
|
||||
for (int i = 0; i < output_count; i += 1) {
|
||||
struct SoundIoDevice *device = soundio_get_output_device(soundio, i);
|
||||
|
||||
const char *purpose_str = "output";
|
||||
const char *default_str = (i == default_output) ? " (default)" : "";
|
||||
const char *description = soundio_device_description(device);
|
||||
int sample_rate = soundio_device_sample_rate(device);
|
||||
fprintf(stderr, "%s device: %d Hz %s%s\n", purpose_str, sample_rate, description, default_str);
|
||||
print_device(device, default_output == i);
|
||||
soundio_device_unref(device);
|
||||
}
|
||||
|
||||
|
|
102
src/dummy.cpp
102
src/dummy.cpp
|
@ -7,9 +7,33 @@
|
|||
|
||||
#include "dummy.hpp"
|
||||
#include "soundio.hpp"
|
||||
#include "dummy_ring_buffer.hpp"
|
||||
#include "os.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <atomic>
|
||||
using std::atomic_flag;
|
||||
|
||||
struct SoundIoOutputDeviceDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsMutex *mutex;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int buffer_size;
|
||||
double period;
|
||||
struct SoundIoDummyRingBuffer ring_buffer;
|
||||
};
|
||||
|
||||
struct SoundIoInputDeviceDummy {
|
||||
// TODO
|
||||
};
|
||||
|
||||
struct SoundIoDummy {
|
||||
SoundIoOsMutex *mutex;
|
||||
SoundIoOsCond *cond;
|
||||
bool devices_emitted;
|
||||
};
|
||||
|
||||
static void playback_thread_run(void *arg) {
|
||||
SoundIoOutputDevice *output_device = (SoundIoOutputDevice *)arg;
|
||||
|
@ -55,11 +79,49 @@ static void recording_thread_run(void *arg) {
|
|||
*/
|
||||
|
||||
static void destroy_dummy(SoundIo *soundio) {
|
||||
destroy(soundio->safe_devices_info);
|
||||
soundio->safe_devices_info = nullptr;
|
||||
SoundIoDummy *sid = (SoundIoDummy *)soundio->backend_data;
|
||||
if (!sid)
|
||||
return;
|
||||
|
||||
if (sid->cond)
|
||||
soundio_os_cond_destroy(sid->cond);
|
||||
|
||||
if (sid->mutex)
|
||||
soundio_os_mutex_destroy(sid->mutex);
|
||||
|
||||
if (soundio->safe_devices_info) {
|
||||
for (int i = 0; i < soundio->safe_devices_info->input_devices.length; i += 1)
|
||||
soundio_device_unref(soundio->safe_devices_info->input_devices.at(i));
|
||||
for (int i = 0; i < soundio->safe_devices_info->output_devices.length; i += 1)
|
||||
soundio_device_unref(soundio->safe_devices_info->output_devices.at(i));
|
||||
destroy(soundio->safe_devices_info);
|
||||
soundio->safe_devices_info = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void flush_events(SoundIo *soundio) { }
|
||||
static void flush_events(SoundIo *soundio) {
|
||||
SoundIoDummy *sid = (SoundIoDummy *)soundio->backend_data;
|
||||
if (sid->devices_emitted)
|
||||
return;
|
||||
sid->devices_emitted = true;
|
||||
soundio->on_devices_change(soundio);
|
||||
}
|
||||
|
||||
static void wait_events(SoundIo *soundio) {
|
||||
SoundIoDummy *sid = (SoundIoDummy *)soundio->backend_data;
|
||||
flush_events(soundio);
|
||||
soundio_os_mutex_lock(sid->mutex);
|
||||
soundio_os_cond_wait(sid->cond, sid->mutex);
|
||||
soundio_os_mutex_unlock(sid->mutex);
|
||||
}
|
||||
|
||||
static void wakeup(SoundIo *soundio) {
|
||||
SoundIoDummy *sid = (SoundIoDummy *)soundio->backend_data;
|
||||
soundio_os_mutex_lock(sid->mutex);
|
||||
soundio_os_cond_signal(sid->cond);
|
||||
soundio_os_mutex_unlock(sid->mutex);
|
||||
}
|
||||
|
||||
static void refresh_devices(SoundIo *soundio) { }
|
||||
|
||||
|
@ -201,6 +263,26 @@ static void input_device_clear_buffer_dummy(SoundIo *soundio,
|
|||
}
|
||||
|
||||
int soundio_dummy_init(SoundIo *soundio) {
|
||||
assert(!soundio->backend_data);
|
||||
SoundIoDummy *sid = create<SoundIoDummy>();
|
||||
if (!sid) {
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
soundio->backend_data = sid;
|
||||
|
||||
sid->mutex = soundio_os_mutex_create();
|
||||
if (!sid->mutex) {
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
sid->cond = soundio_os_cond_create();
|
||||
if (!sid->cond) {
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
assert(!soundio->safe_devices_info);
|
||||
soundio->safe_devices_info = create<SoundIoDevicesInfo>();
|
||||
if (!soundio->safe_devices_info) {
|
||||
|
@ -214,8 +296,10 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
// create output device
|
||||
{
|
||||
SoundIoDevice *device = create<SoundIoDevice>();
|
||||
if (!device)
|
||||
if (!device) {
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
device->ref_count = 1;
|
||||
device->soundio = soundio;
|
||||
|
@ -224,6 +308,7 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
if (!device->name || !device->description) {
|
||||
free(device->name);
|
||||
free(device->description);
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono);
|
||||
|
@ -234,6 +319,7 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
|
||||
if (soundio->safe_devices_info->output_devices.append(device)) {
|
||||
soundio_device_unref(device);
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
}
|
||||
|
@ -241,8 +327,10 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
// create input device
|
||||
{
|
||||
SoundIoDevice *device = create<SoundIoDevice>();
|
||||
if (!device)
|
||||
if (!device) {
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
|
||||
device->ref_count = 1;
|
||||
device->soundio = soundio;
|
||||
|
@ -251,6 +339,7 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
if (!device->name || !device->description) {
|
||||
free(device->name);
|
||||
free(device->description);
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono);
|
||||
|
@ -261,6 +350,7 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
|
||||
if (soundio->safe_devices_info->input_devices.append(device)) {
|
||||
soundio_device_unref(device);
|
||||
destroy_dummy(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +358,8 @@ int soundio_dummy_init(SoundIo *soundio) {
|
|||
|
||||
soundio->destroy = destroy_dummy;
|
||||
soundio->flush_events = flush_events;
|
||||
soundio->wait_events = wait_events;
|
||||
soundio->wakeup = wakeup;
|
||||
soundio->refresh_devices = refresh_devices;
|
||||
|
||||
soundio->output_device_init = output_device_init_dummy;
|
||||
|
|
|
@ -8,27 +8,6 @@
|
|||
#ifndef SOUNDIO_DUMMY_HPP
|
||||
#define SOUNDIO_DUMMY_HPP
|
||||
|
||||
#include "os.hpp"
|
||||
#include "dummy_ring_buffer.hpp"
|
||||
#include <atomic>
|
||||
using std::atomic_flag;
|
||||
|
||||
struct SoundIoOutputDeviceDummy {
|
||||
struct SoundIoOsThread *thread;
|
||||
struct SoundIoOsMutex *mutex;
|
||||
struct SoundIoOsCond *cond;
|
||||
atomic_flag abort_flag;
|
||||
int buffer_size;
|
||||
double period;
|
||||
struct SoundIoDummyRingBuffer ring_buffer;
|
||||
};
|
||||
|
||||
struct SoundIoInputDeviceDummy {
|
||||
// TODO
|
||||
};
|
||||
|
||||
int soundio_dummy_init(struct SoundIo *soundio);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
47
src/list.hpp
47
src/list.hpp
|
@ -70,49 +70,6 @@ struct SoundIoList {
|
|||
return 0;
|
||||
}
|
||||
|
||||
T swap_remove(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < length);
|
||||
if (index == length - 1)
|
||||
return pop();
|
||||
|
||||
T last = pop();
|
||||
T item = items[index];
|
||||
items[index] = last;
|
||||
return item;
|
||||
}
|
||||
|
||||
void remove_range(int start, int end) {
|
||||
assert(0 <= start);
|
||||
assert(start <= end);
|
||||
assert(end <= length);
|
||||
int del_count = end - start;
|
||||
for (int i = start; i < length - del_count; i += 1) {
|
||||
items[i] = items[i + del_count];
|
||||
}
|
||||
length -= del_count;
|
||||
}
|
||||
|
||||
int __attribute__((warn_unused_result)) insert_space(int pos, int size) {
|
||||
int old_length = length;
|
||||
assert(pos >= 0 && pos <= old_length);
|
||||
int err = resize(old_length + size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
for (int i = old_length - 1; i >= pos; i -= 1) {
|
||||
items[i + size] = items[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fill(T value) {
|
||||
for (int i = 0; i < length; i += 1) {
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
length = 0;
|
||||
}
|
||||
|
@ -131,10 +88,6 @@ struct SoundIoList {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int allocated_size() const {
|
||||
return capacity * sizeof(T);
|
||||
}
|
||||
|
||||
T * items;
|
||||
int length;
|
||||
int capacity;
|
||||
|
|
10
src/os.cpp
10
src/os.cpp
|
@ -249,3 +249,13 @@ void soundio_os_cond_timed_wait(struct SoundIoOsCond *cond,
|
|||
assert(err != EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
void soundio_os_cond_wait(struct SoundIoOsCond *cond,
|
||||
struct SoundIoOsMutex *mutex)
|
||||
{
|
||||
int err;
|
||||
if ((err = pthread_cond_wait(&cond->id, &mutex->id))) {
|
||||
assert(err != EPERM);
|
||||
assert(err != EINVAL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,5 +35,7 @@ void soundio_os_cond_broadcast(struct SoundIoOsCond *cond);
|
|||
|
||||
void soundio_os_cond_timed_wait(struct SoundIoOsCond *cond,
|
||||
struct SoundIoOsMutex *mutex, double seconds);
|
||||
void soundio_os_cond_wait(struct SoundIoOsCond *cond,
|
||||
struct SoundIoOsMutex *mutex);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,48 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <atomic>
|
||||
using std::atomic_bool;
|
||||
|
||||
struct SoundIoOutputDevicePulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
};
|
||||
|
||||
struct SoundIoInputDevicePulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
};
|
||||
|
||||
struct SoundIoPulseAudio {
|
||||
bool connection_refused;
|
||||
|
||||
pa_context *pulse_context;
|
||||
atomic_bool device_scan_queued;
|
||||
|
||||
// the one that we're working on building
|
||||
struct SoundIoDevicesInfo *current_devices_info;
|
||||
char * default_sink_name;
|
||||
char * default_source_name;
|
||||
|
||||
// this one is ready to be read with flush_events. protected by mutex
|
||||
struct SoundIoDevicesInfo *ready_devices_info;
|
||||
|
||||
bool have_sink_list;
|
||||
bool have_source_list;
|
||||
bool have_default_sink;
|
||||
|
||||
atomic_bool ready_flag;
|
||||
atomic_bool have_devices_flag;
|
||||
|
||||
pa_threaded_mainloop *main_loop;
|
||||
pa_proplist *props;
|
||||
};
|
||||
|
||||
|
||||
static void subscribe_callback(pa_context *context,
|
||||
pa_subscription_event_type_t event_bits, uint32_t index, void *userdata)
|
||||
{
|
||||
|
@ -87,6 +129,9 @@ static void destroy_ready_devices_info(SoundIo *soundio) {
|
|||
|
||||
static void destroy_pa(SoundIo *soundio) {
|
||||
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
if (!ah)
|
||||
return;
|
||||
|
||||
if (ah->main_loop)
|
||||
pa_threaded_mainloop_stop(ah->main_loop);
|
||||
|
||||
|
@ -104,6 +149,9 @@ static void destroy_pa(SoundIo *soundio) {
|
|||
|
||||
free(ah->default_sink_name);
|
||||
free(ah->default_source_name);
|
||||
|
||||
destroy(ah);
|
||||
soundio->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static double usec_to_sec(pa_usec_t usec) {
|
||||
|
@ -797,7 +845,13 @@ static void refresh_devices(SoundIo *soundio) {
|
|||
}
|
||||
|
||||
int soundio_pulseaudio_init(SoundIo *soundio) {
|
||||
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
|
||||
assert(!soundio->backend_data);
|
||||
SoundIoPulseAudio *ah = create<SoundIoPulseAudio>();
|
||||
if (!ah) {
|
||||
destroy_pa(soundio);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
soundio->backend_data = ah;
|
||||
|
||||
ah->connection_refused = false;
|
||||
ah->device_scan_queued = false;
|
||||
|
|
|
@ -8,47 +8,6 @@
|
|||
#ifndef SOUNDIO_PULSEAUDIO_HPP
|
||||
#define SOUNDIO_PULSEAUDIO_HPP
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <atomic>
|
||||
using std::atomic_bool;
|
||||
|
||||
struct SoundIoOutputDevicePulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
};
|
||||
|
||||
struct SoundIoInputDevicePulseAudio {
|
||||
pa_stream *stream;
|
||||
atomic_bool stream_ready;
|
||||
pa_buffer_attr buffer_attr;
|
||||
};
|
||||
|
||||
struct SoundIoPulseAudio {
|
||||
bool connection_refused;
|
||||
|
||||
pa_context *pulse_context;
|
||||
atomic_bool device_scan_queued;
|
||||
|
||||
// the one that we're working on building
|
||||
struct SoundIoDevicesInfo *current_devices_info;
|
||||
char * default_sink_name;
|
||||
char * default_source_name;
|
||||
|
||||
// this one is ready to be read with flush_events. protected by mutex
|
||||
struct SoundIoDevicesInfo *ready_devices_info;
|
||||
|
||||
bool have_sink_list;
|
||||
bool have_source_list;
|
||||
bool have_default_sink;
|
||||
|
||||
atomic_bool ready_flag;
|
||||
atomic_bool have_devices_flag;
|
||||
|
||||
pa_threaded_mainloop *main_loop;
|
||||
pa_proplist *props;
|
||||
};
|
||||
|
||||
int soundio_pulseaudio_init(struct SoundIo *soundio);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "dummy.hpp"
|
||||
#include "pulseaudio.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
const char *soundio_error_string(int error) {
|
||||
|
@ -138,3 +139,85 @@ struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int ind
|
|||
soundio_device_ref(device);
|
||||
return device;
|
||||
}
|
||||
|
||||
void soundio_device_ref(struct SoundIoDevice *device);
|
||||
void soundio_device_unref(struct SoundIoDevice *device);
|
||||
|
||||
// the name is the identifier for the device. UTF-8 encoded
|
||||
const char *soundio_device_name(const struct SoundIoDevice *device) {
|
||||
return device->name;
|
||||
}
|
||||
|
||||
// UTF-8 encoded
|
||||
const char *soundio_device_description(const struct SoundIoDevice *device) {
|
||||
return device->description;
|
||||
}
|
||||
|
||||
enum SoundIoDevicePurpose soundio_device_purpose(const struct SoundIoDevice *device) {
|
||||
return device->purpose;
|
||||
}
|
||||
|
||||
const struct SoundIoChannelLayout *soundio_device_channel_layout(const struct SoundIoDevice *device) {
|
||||
return &device->channel_layout;
|
||||
}
|
||||
|
||||
int soundio_device_sample_rate(const struct SoundIoDevice *device) {
|
||||
return device->default_sample_rate;
|
||||
}
|
||||
|
||||
void soundio_device_unref(struct SoundIoDevice *device) {
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
device->ref_count -= 1;
|
||||
assert(device->ref_count >= 0);
|
||||
|
||||
if (device->ref_count == 0) {
|
||||
free(device->name);
|
||||
free(device->description);
|
||||
destroy(device);
|
||||
}
|
||||
}
|
||||
|
||||
void soundio_device_ref(struct SoundIoDevice *device) {
|
||||
device->ref_count += 1;
|
||||
}
|
||||
|
||||
void soundio_wait_events(struct SoundIo *soundio) {
|
||||
soundio->wait_events(soundio);
|
||||
}
|
||||
|
||||
void soundio_wakeup(struct SoundIo *soundio) {
|
||||
soundio->wakeup(soundio);
|
||||
}
|
||||
|
||||
void soundio_output_device_fill_with_silence(struct SoundIoOutputDevice *output_device) {
|
||||
char *buffer;
|
||||
int requested_frame_count = soundio_output_device_free_count(output_device);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
void soundio_output_device_begin_write(struct SoundIoOutputDevice *output_device,
|
||||
char **data, int *frame_count)
|
||||
{
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
soundio->output_device_begin_write(soundio, output_device, data, frame_count);
|
||||
}
|
||||
|
||||
void soundio_output_device_write(struct SoundIoOutputDevice *output_device,
|
||||
char *data, int frame_count)
|
||||
{
|
||||
SoundIo *soundio = output_device->device->soundio;
|
||||
soundio->output_device_write(soundio, output_device, data, frame_count);
|
||||
}
|
||||
|
|
|
@ -156,6 +156,8 @@ struct SoundIo {
|
|||
|
||||
void (*destroy)(struct SoundIo *);
|
||||
void (*flush_events)(struct SoundIo *);
|
||||
void (*wait_events)(struct SoundIo *);
|
||||
void (*wakeup)(struct SoundIo *);
|
||||
void (*refresh_devices)(struct SoundIo *);
|
||||
|
||||
int (*output_device_init)(struct SoundIo *, struct SoundIoOutputDevice *);
|
||||
|
|
Loading…
Reference in a new issue