mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 17:55:37 +00:00
add JACK backend skeleton
This commit is contained in:
parent
5906bc93d9
commit
3dd9e513bc
|
@ -23,6 +23,16 @@ else(Threads_FOUND)
|
|||
set(STATUS_THREADS "not found")
|
||||
endif(Threads_FOUND)
|
||||
|
||||
find_package(JACK)
|
||||
if(JACK_FOUND)
|
||||
set(STATUS_JACK "OK")
|
||||
set(SOUNDIO_HAVE_JACK true)
|
||||
include_directories(${JACK_INCLUDE_DIR})
|
||||
else()
|
||||
set(STATUS_JACK "not found")
|
||||
set(SOUNDIO_HAVE_JACK false)
|
||||
set(JACK_LIBRARY "")
|
||||
endif()
|
||||
|
||||
find_package(PulseAudio)
|
||||
if(PULSEAUDIO_FOUND)
|
||||
|
@ -71,6 +81,14 @@ set(TEST_SOURCES
|
|||
"${CMAKE_SOURCE_DIR}/src/ring_buffer.cpp"
|
||||
)
|
||||
|
||||
if(SOUNDIO_HAVE_JACK)
|
||||
set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/jack.cpp"
|
||||
)
|
||||
set(TEST_SOURCES ${TEST_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/jack.cpp"
|
||||
)
|
||||
endif()
|
||||
if(SOUNDIO_HAVE_PULSEAUDIO)
|
||||
set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/pulseaudio.cpp"
|
||||
|
@ -132,6 +150,7 @@ include_directories(
|
|||
${ALSA_INCLUDE_DIRS}
|
||||
)
|
||||
target_link_libraries(libsoundio_shared LINK_PUBLIC
|
||||
${JACK_LIBRARY}
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${ALSA_LIBRARIES}
|
||||
m
|
||||
|
@ -182,6 +201,7 @@ enable_testing()
|
|||
add_executable(unit_tests ${TEST_SOURCES})
|
||||
target_link_libraries(unit_tests LINK_PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${JACK_LIBRARY}
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${ALSA_LIBRARIES}
|
||||
m
|
||||
|
@ -218,6 +238,7 @@ message(
|
|||
"System Dependencies\n"
|
||||
"-------------------\n"
|
||||
"* threads : ${STATUS_THREADS}\n"
|
||||
"* pulseaudio : ${STATUS_PULSEAUDIO}\n"
|
||||
"* ALSA : ${STATUS_ALSA}\n"
|
||||
"* JACK (optional) : ${STATUS_JACK}\n"
|
||||
"* PulseAudio (optional) : ${STATUS_PULSEAUDIO}\n"
|
||||
"* ALSA (optional) : ${STATUS_ALSA}\n"
|
||||
)
|
||||
|
|
20
README.md
20
README.md
|
@ -232,25 +232,37 @@ view `coverage/index.html` in a browser.
|
|||
|
||||
## Roadmap
|
||||
|
||||
0. pipe record to playback example working with ALSA linux
|
||||
0. implement JACK backend, get examples working
|
||||
0. why does pulseaudio microphone use up all the CPU?
|
||||
0. merge in/out stream structures and functions?
|
||||
0. implement JACK backend, get examples working
|
||||
0. implement CoreAudio (OSX) backend, get examples working
|
||||
0. implement WASAPI (Windows) backend, get examples working
|
||||
0. implement ASIO (Windows) backend, get examples working
|
||||
0. Avoid calling `panic` in PulseAudio.
|
||||
0. Figure out a way to test prebuf. I suspect prebuf not working for ALSA
|
||||
which is why we have to pre-fill the ring buffer with silence for
|
||||
the microphone example.
|
||||
0. PulseAudio: when prebuf gets set to 0 need to pass `PA_STREAM_START_CORKED`.
|
||||
0. In ALSA do we need to wake up the poll when destroying the in or out stream?
|
||||
0. Create a test for clearing the playback buffer.
|
||||
0. Create a test for pausing and resuming input and output streams.
|
||||
0. implement ASIO (Windows) backend, get examples working
|
||||
0. Create a test for the latency / synchronization API.
|
||||
- Input is an audio file and some events indexed at particular frame - when
|
||||
listening the events should line up exactly with a beat or visual
|
||||
indicator, even when the latency is large.
|
||||
- Play the audio file, have the user press an input right at the beat. Find
|
||||
out what the frame index it thinks the user pressed it at and make sure
|
||||
that is correct.
|
||||
0. Expose JACK options in `jack_client_open`
|
||||
0. Allow calling functions from outside the callbacks as long as they first
|
||||
call lock and then unlock when done.
|
||||
0. Should pause/resume be callable from outside the callbacks?
|
||||
0. clean up API and improve documentation
|
||||
- make sure every function which can return an error documents which errors
|
||||
it can return
|
||||
0. use a documentation generator and host the docs somewhere
|
||||
0. -fvisibility=hidden and then explicitly export stuff
|
||||
0. -fvisibility=hidden and then explicitly export stuff, or
|
||||
explicitly make the unexported stuff private
|
||||
0. Integrate into libgroove and test with Groove Basin
|
||||
0. look at microphone example and determine if fewer memcpys can be done
|
||||
with the audio data
|
||||
|
|
16
cmake/FindJACK.cmake
Normal file
16
cmake/FindJACK.cmake
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2015 Andrew Kelley
|
||||
# This file is MIT licensed.
|
||||
# See http://opensource.org/licenses/MIT
|
||||
|
||||
# JACK_FOUND
|
||||
# JACK_INCLUDE_DIR
|
||||
# JACK_LIBRARY
|
||||
|
||||
find_path(JACK_INCLUDE_DIR NAMES jack/jack.h)
|
||||
|
||||
find_library(JACK_LIBRARY NAMES jack)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(JACK DEFAULT_MSG JACK_LIBRARY JACK_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(JACK_INCLUDE_DIR JACK_LIBRARY)
|
|
@ -49,15 +49,22 @@ static void panic(const char *format, ...) {
|
|||
|
||||
struct SoundIoRingBuffer *ring_buffer = NULL;
|
||||
|
||||
static int min_int(int a, int b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
static void read_callback(struct SoundIoInStream *instream, int available_frame_count) {
|
||||
int err;
|
||||
struct SoundIoChannelArea *areas;
|
||||
char *write_ptr = soundio_ring_buffer_write_ptr(ring_buffer);
|
||||
int frames_left = available_frame_count;
|
||||
int free_bytes = soundio_ring_buffer_free_count(ring_buffer);
|
||||
int free_count = free_bytes / instream->bytes_per_frame;
|
||||
int write_count = min_int(available_frame_count, free_count);
|
||||
int frames_left = write_count;
|
||||
|
||||
for (;;) {
|
||||
int frame_count = frames_left;
|
||||
|
||||
struct SoundIoChannelArea *areas;
|
||||
if ((err = soundio_instream_begin_read(instream, &areas, &frame_count)))
|
||||
panic("begin read error: %s", soundio_strerror(err));
|
||||
|
||||
|
@ -68,6 +75,7 @@ static void read_callback(struct SoundIoInStream *instream, int available_frame_
|
|||
// Due to an overflow there is a hole. Fill the ring buffer with
|
||||
// silence for the size of the hole.
|
||||
memset(write_ptr, 0, frame_count * instream->bytes_per_frame);
|
||||
fprintf(stderr, "Dropped %d frames due to internal overflow\n", frame_count);
|
||||
} else {
|
||||
for (int frame = 0; frame < frame_count; frame += 1) {
|
||||
for (int ch = 0; ch < instream->layout.channel_count; ch += 1) {
|
||||
|
@ -87,12 +95,12 @@ static void read_callback(struct SoundIoInStream *instream, int available_frame_
|
|||
break;
|
||||
}
|
||||
|
||||
int advance_bytes = available_frame_count * instream->bytes_per_frame;
|
||||
int advance_bytes = write_count * instream->bytes_per_frame;
|
||||
soundio_ring_buffer_advance_write_ptr(ring_buffer, advance_bytes);
|
||||
}
|
||||
|
||||
static int min_int(int a, int b) {
|
||||
return (a < b) ? a : b;
|
||||
int dropped_frames = available_frame_count - write_count;
|
||||
if (dropped_frames > 0)
|
||||
fprintf(stderr, "Dropped %d frames due to overflow\n", dropped_frames);
|
||||
}
|
||||
|
||||
static void write_callback(struct SoundIoOutStream *outstream, int requested_frame_count) {
|
||||
|
@ -134,10 +142,8 @@ static void write_callback(struct SoundIoOutStream *outstream, int requested_fra
|
|||
}
|
||||
|
||||
static void underflow_callback(struct SoundIoOutStream *outstream) {
|
||||
char *write_ptr = soundio_ring_buffer_write_ptr(ring_buffer);
|
||||
int bytes_to_fill = outstream->buffer_duration * outstream->sample_rate * outstream->bytes_per_frame;
|
||||
memset(write_ptr, 0, bytes_to_fill);
|
||||
soundio_ring_buffer_advance_write_ptr(ring_buffer, bytes_to_fill);
|
||||
static int count = 0;
|
||||
fprintf(stderr, "underflow %d\n", ++count);
|
||||
}
|
||||
|
||||
static int usage(char *exe) {
|
||||
|
@ -279,8 +285,8 @@ int main(int argc, char **argv) {
|
|||
outstream->format = *fmt;
|
||||
outstream->sample_rate = sample_rate;
|
||||
outstream->layout = *layout;
|
||||
outstream->buffer_duration = 0.1;
|
||||
outstream->period_duration = 0.25;
|
||||
outstream->buffer_duration = 0.2;
|
||||
outstream->period_duration = 0.1;
|
||||
outstream->write_callback = write_callback;
|
||||
outstream->underflow_callback = underflow_callback;
|
||||
|
||||
|
|
|
@ -1013,11 +1013,13 @@ void outstream_thread_run(void *arg) {
|
|||
}
|
||||
continue;
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
{
|
||||
if ((err = snd_pcm_start(osa->handle)) < 0) {
|
||||
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
{
|
||||
if ((err = wait_for_poll(osa)) < 0) {
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
#cmakedefine SOUNDIO_OS_BIG_ENDIAN
|
||||
#cmakedefine SOUNDIO_OS_LITTLE_ENDIAN
|
||||
|
||||
#cmakedefine SOUNDIO_HAVE_ALSA
|
||||
#cmakedefine SOUNDIO_HAVE_JACK
|
||||
#cmakedefine SOUNDIO_HAVE_PULSEAUDIO
|
||||
#cmakedefine SOUNDIO_HAVE_ALSA
|
||||
|
||||
#endif
|
||||
|
|
157
src/jack.cpp
Normal file
157
src/jack.cpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of libsoundio, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "jack.hpp"
|
||||
#include "soundio.hpp"
|
||||
|
||||
#include <jack/jack.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct SoundIoJack {
|
||||
jack_client_t *client;
|
||||
};
|
||||
|
||||
static void flush_events_jack(struct SoundIoPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void wait_events_jack(struct SoundIoPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void wakeup_jack(struct SoundIoPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
|
||||
static int outstream_open_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void outstream_destroy_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int outstream_start_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int outstream_begin_write_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *,
|
||||
SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int outstream_end_write_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, int frame_count) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int outstream_clear_buffer_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int outstream_pause_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, bool pause) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int instream_open_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static void instream_destroy_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int instream_start_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int instream_begin_read_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *,
|
||||
SoundIoChannelArea **out_areas, int *frame_count)
|
||||
{
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int instream_end_read_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
static int instream_pause_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, bool pause) {
|
||||
soundio_panic("TODO");
|
||||
}
|
||||
|
||||
|
||||
static void destroy_jack(SoundIoPrivate *si) {
|
||||
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||
if (!sij)
|
||||
return;
|
||||
|
||||
destroy(sij);
|
||||
si->backend_data = nullptr;
|
||||
}
|
||||
|
||||
static void error_callback(const char *msg) {
|
||||
//fprintf(stderr, "JACK error: %s\n", msg);
|
||||
}
|
||||
|
||||
static void info_callback(const char *msg) {
|
||||
//fprintf(stderr, "JACK info: %s\n", msg);
|
||||
}
|
||||
|
||||
int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||
SoundIo *soundio = &si->pub;
|
||||
assert(!si->backend_data);
|
||||
SoundIoJack *sij = create<SoundIoJack>();
|
||||
if (!sij) {
|
||||
destroy_jack(si);
|
||||
return SoundIoErrorNoMem;
|
||||
}
|
||||
si->backend_data = sij;
|
||||
|
||||
jack_set_error_function(error_callback);
|
||||
jack_set_info_function(info_callback);
|
||||
|
||||
jack_status_t status;
|
||||
sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status);
|
||||
if (!sij->client) {
|
||||
destroy_jack(si);
|
||||
assert(!(status & JackInvalidOption));
|
||||
if (status & JackNameNotUnique)
|
||||
return SoundIoErrorNameNotUnique;
|
||||
if (status & JackShmFailure)
|
||||
return SoundIoErrorSystemResources;
|
||||
if (status & JackNoSuchClient)
|
||||
return SoundIoErrorNoSuchClient;
|
||||
|
||||
return SoundIoErrorInitAudioBackend;
|
||||
}
|
||||
|
||||
|
||||
si->destroy = destroy_jack;
|
||||
si->flush_events = flush_events_jack;
|
||||
si->wait_events = wait_events_jack;
|
||||
si->wakeup = wakeup_jack;
|
||||
|
||||
si->outstream_open = outstream_open_jack;
|
||||
si->outstream_destroy = outstream_destroy_jack;
|
||||
si->outstream_start = outstream_start_jack;
|
||||
si->outstream_begin_write = outstream_begin_write_jack;
|
||||
si->outstream_end_write = outstream_end_write_jack;
|
||||
si->outstream_clear_buffer = outstream_clear_buffer_jack;
|
||||
si->outstream_pause = outstream_pause_jack;
|
||||
|
||||
si->instream_open = instream_open_jack;
|
||||
si->instream_destroy = instream_destroy_jack;
|
||||
si->instream_start = instream_start_jack;
|
||||
si->instream_begin_read = instream_begin_read_jack;
|
||||
si->instream_end_read = instream_end_read_jack;
|
||||
si->instream_pause = instream_pause_jack;
|
||||
|
||||
return 0;
|
||||
}
|
14
src/jack.hpp
Normal file
14
src/jack.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of libsoundio, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef SOUNDIO_JACK_HPP
|
||||
#define SOUNDIO_JACK_HPP
|
||||
|
||||
int soundio_jack_init(struct SoundIoPrivate *si);
|
||||
|
||||
#endif
|
||||
|
|
@ -11,6 +11,10 @@
|
|||
#include "os.hpp"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef SOUNDIO_HAVE_JACK
|
||||
#include "jack.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
#include "pulseaudio.hpp"
|
||||
#endif
|
||||
|
@ -23,6 +27,9 @@
|
|||
#include <assert.h>
|
||||
|
||||
static const SoundIoBackend available_backends[] = {
|
||||
#ifdef SOUNDIO_HAVE_JACK
|
||||
SoundIoBackendJack,
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
SoundIoBackendPulseAudio,
|
||||
#endif
|
||||
|
@ -32,6 +39,26 @@ static const SoundIoBackend available_backends[] = {
|
|||
SoundIoBackendDummy,
|
||||
};
|
||||
|
||||
static int (*backend_init_fns[])(SoundIoPrivate *) = {
|
||||
nullptr, // SoundIoBackendNone
|
||||
#ifdef SOUNDIO_HAVE_JACK
|
||||
soundio_jack_init,
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
soundio_pulseaudio_init,
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
#ifdef SOUNDIO_HAVE_ALSA
|
||||
soundio_alsa_init,
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
soundio_dummy_init,
|
||||
};
|
||||
|
||||
const char *soundio_strerror(int error) {
|
||||
switch ((enum SoundIoError)error) {
|
||||
case SoundIoErrorNone: return "(no error)";
|
||||
|
@ -43,6 +70,8 @@ const char *soundio_strerror(int error) {
|
|||
case SoundIoErrorBackendUnavailable: return "backend unavailable";
|
||||
case SoundIoErrorStreaming: return "unrecoverable streaming failure";
|
||||
case SoundIoErrorIncompatibleDevice: return "incompatible device";
|
||||
case SoundIoErrorNameNotUnique: return "name not unique";
|
||||
case SoundIoErrorNoSuchClient: return "no such client";
|
||||
}
|
||||
soundio_panic("invalid error enum value: %d", error);
|
||||
}
|
||||
|
@ -105,6 +134,7 @@ const char * soundio_format_string(enum SoundIoFormat format) {
|
|||
const char *soundio_backend_name(enum SoundIoBackend backend) {
|
||||
switch (backend) {
|
||||
case SoundIoBackendNone: return "(none)";
|
||||
case SoundIoBackendJack: return "JACK";
|
||||
case SoundIoBackendPulseAudio: return "PulseAudio";
|
||||
case SoundIoBackendAlsa: return "ALSA";
|
||||
case SoundIoBackendDummy: return "Dummy";
|
||||
|
@ -158,41 +188,20 @@ int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) {
|
|||
if (si->current_backend)
|
||||
return SoundIoErrorInvalid;
|
||||
|
||||
int err;
|
||||
switch (backend) {
|
||||
case SoundIoBackendPulseAudio:
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
si->current_backend = SoundIoBackendPulseAudio;
|
||||
if ((err = soundio_pulseaudio_init(si))) {
|
||||
soundio_disconnect(soundio);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return SoundIoErrorBackendUnavailable;
|
||||
#endif
|
||||
case SoundIoBackendAlsa:
|
||||
#ifdef SOUNDIO_HAVE_ALSA
|
||||
si->current_backend = SoundIoBackendAlsa;
|
||||
if ((err = soundio_alsa_init(si))) {
|
||||
soundio_disconnect(soundio);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return SoundIoErrorBackendUnavailable;
|
||||
#endif
|
||||
case SoundIoBackendDummy:
|
||||
si->current_backend = SoundIoBackendDummy;
|
||||
if ((err = soundio_dummy_init(si))) {
|
||||
soundio_disconnect(soundio);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
case SoundIoBackendNone:
|
||||
if (backend <= 0 || backend > SoundIoBackendDummy)
|
||||
return SoundIoErrorInvalid;
|
||||
|
||||
int (*fn)(SoundIoPrivate *) = backend_init_fns[backend];
|
||||
|
||||
if (!fn)
|
||||
return SoundIoErrorBackendUnavailable;
|
||||
|
||||
int err;
|
||||
if ((err = backend_init_fns[backend](si))) {
|
||||
soundio_disconnect(soundio);
|
||||
return err;
|
||||
}
|
||||
return SoundIoErrorInvalid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void soundio_disconnect(struct SoundIo *soundio) {
|
||||
|
@ -528,25 +537,9 @@ void soundio_destroy_devices_info(SoundIoDevicesInfo *devices_info) {
|
|||
}
|
||||
|
||||
bool soundio_have_backend(SoundIoBackend backend) {
|
||||
switch (backend) {
|
||||
case SoundIoBackendPulseAudio:
|
||||
#ifdef SOUNDIO_HAVE_PULSEAUDIO
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
case SoundIoBackendAlsa:
|
||||
#ifdef SOUNDIO_HAVE_ALSA
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
case SoundIoBackendDummy:
|
||||
return true;
|
||||
case SoundIoBackendNone:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
assert(backend > 0);
|
||||
assert(backend <= SoundIoBackendDummy);
|
||||
return backend_init_fns[backend];
|
||||
}
|
||||
|
||||
int soundio_backend_count(struct SoundIo *soundio) {
|
||||
|
|
|
@ -26,6 +26,8 @@ enum SoundIoError {
|
|||
SoundIoErrorBackendUnavailable,
|
||||
SoundIoErrorStreaming,
|
||||
SoundIoErrorIncompatibleDevice,
|
||||
SoundIoErrorNameNotUnique,
|
||||
SoundIoErrorNoSuchClient,
|
||||
};
|
||||
|
||||
enum SoundIoChannelId {
|
||||
|
@ -98,6 +100,7 @@ enum SoundIoChannelLayoutId {
|
|||
|
||||
enum SoundIoBackend {
|
||||
SoundIoBackendNone,
|
||||
SoundIoBackendJack,
|
||||
SoundIoBackendPulseAudio,
|
||||
SoundIoBackendAlsa,
|
||||
SoundIoBackendDummy,
|
||||
|
@ -205,7 +208,9 @@ struct SoundIo {
|
|||
// variable to wake up. Called when soundio_wait_events would be woken up.
|
||||
void (*on_events_signal)(struct SoundIo *);
|
||||
|
||||
// Optional: Application name. Used by PulseAudio. Defaults to "SoundIo".
|
||||
// Optional: Application name.
|
||||
// PulseAudio uses this for "application name".
|
||||
// JACK uses this for `client_name`.
|
||||
const char *app_name;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue