mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 23:25:34 +00:00
parent
debab8e70f
commit
59fca8cb75
|
@ -147,57 +147,51 @@ set(LIBSOUNDIO_HEADERS
|
|||
${CONFIGURE_OUT_FILE}
|
||||
)
|
||||
|
||||
set(TEST_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/test/unit_tests.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/os.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/soundio.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/dummy.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/channel_layout.cpp"
|
||||
"${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"
|
||||
)
|
||||
set(TEST_SOURCES ${TEST_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/pulseaudio.cpp"
|
||||
)
|
||||
endif()
|
||||
if(SOUNDIO_HAVE_ALSA)
|
||||
set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/alsa.cpp"
|
||||
)
|
||||
set(TEST_SOURCES ${TEST_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/alsa.cpp"
|
||||
)
|
||||
endif()
|
||||
if(SOUNDIO_HAVE_COREAUDIO)
|
||||
set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/coreaudio.cpp"
|
||||
)
|
||||
set(TEST_SOURCES ${TEST_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/coreaudio.cpp"
|
||||
)
|
||||
endif()
|
||||
if(SOUNDIO_HAVE_WASAPI)
|
||||
set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/wasapi.cpp"
|
||||
)
|
||||
set(TEST_SOURCES ${TEST_SOURCES}
|
||||
"${CMAKE_SOURCE_DIR}/src/wasapi.cpp"
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_SOURCE_DIR}/test"
|
||||
"${CMAKE_SOURCE_DIR}/src"
|
||||
)
|
||||
|
||||
set(LIBSOUNDIO_LIBS
|
||||
${JACK_LIBRARY}
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${ALSA_LIBRARIES}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${AUDIOUNIT_LIBRARY}
|
||||
m
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
|
||||
|
||||
# GTFO, -lstdc++ !!
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
|
@ -209,10 +203,8 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -pedantic")
|
|||
|
||||
set(LIB_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -fvisibility=hidden -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes -Wno-c99-extensions")
|
||||
set(EXAMPLE_CFLAGS "-std=c99 -Wall")
|
||||
set(EXAMPLE_INCLUDES "${CMAKE_SOURCE_DIR}/src")
|
||||
set(TEST_CFLAGS "${LIB_CFLAGS} -fprofile-arcs -ftest-coverage")
|
||||
set(TEST_LDFLAGS "-fprofile-arcs -ftest-coverage")
|
||||
set(TEST_INCLUDES "${CMAKE_SOURCE_DIR}/test")
|
||||
|
||||
include(TestBigEndian)
|
||||
test_big_endian(IS_BIG_ENDIAN)
|
||||
|
@ -241,20 +233,7 @@ set_target_properties(libsoundio_shared PROPERTIES
|
|||
COMPILE_FLAGS ${LIB_CFLAGS}
|
||||
LINKER_LANGUAGE C
|
||||
)
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
target_link_libraries(libsoundio_shared LINK_PUBLIC
|
||||
${JACK_LIBRARY}
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${ALSA_LIBRARIES}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${AUDIOUNIT_LIBRARY}
|
||||
m
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
target_link_libraries(libsoundio_shared LINK_PUBLIC ${LIBSOUNDIO_LIBS})
|
||||
install(TARGETS libsoundio_shared DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
|
||||
|
@ -276,7 +255,6 @@ add_executable(sio_sine example/sio_sine.c)
|
|||
set_target_properties(sio_sine PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(sio_sine libsoundio_shared)
|
||||
install(TARGETS sio_sine DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
@ -284,7 +262,6 @@ add_executable(sio_list_devices example/sio_list_devices.c)
|
|||
set_target_properties(sio_list_devices PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(sio_list_devices libsoundio_shared)
|
||||
install(TARGETS sio_list_devices DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
@ -292,7 +269,6 @@ add_executable(sio_microphone example/sio_microphone.c)
|
|||
set_target_properties(sio_microphone PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(sio_microphone libsoundio_shared)
|
||||
install(TARGETS sio_microphone DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
@ -300,49 +276,41 @@ add_executable(sio_record example/sio_record.c)
|
|||
set_target_properties(sio_record PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(sio_record libsoundio_shared)
|
||||
install(TARGETS sio_record DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
|
||||
|
||||
add_executable(unit_tests ${TEST_SOURCES})
|
||||
target_link_libraries(unit_tests LINK_PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${JACK_LIBRARY}
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${ALSA_LIBRARIES}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${AUDIOUNIT_LIBRARY}
|
||||
m
|
||||
)
|
||||
add_executable(unit_tests "${CMAKE_SOURCE_DIR}/test/unit_tests.cpp" ${LIBSOUNDIO_SOURCES})
|
||||
target_link_libraries(unit_tests LINK_PUBLIC ${LIBSOUNDIO_LIBS})
|
||||
set_target_properties(unit_tests PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${TEST_CFLAGS}
|
||||
LINK_FLAGS ${TEST_LDFLAGS}
|
||||
)
|
||||
include_directories(${TEST_INCLUDES})
|
||||
|
||||
add_executable(latency "${CMAKE_SOURCE_DIR}/test/latency.cpp" ${LIBSOUNDIO_SOURCES})
|
||||
target_link_libraries(latency LINK_PUBLIC ${LIBSOUNDIO_LIBS})
|
||||
set_target_properties(latency PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${LIB_CFLAGS}
|
||||
)
|
||||
|
||||
add_executable(underflow test/underflow.c)
|
||||
set_target_properties(underflow PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(underflow libsoundio_shared)
|
||||
|
||||
add_executable(backend_disconnect_recover test/backend_disconnect_recover.c)
|
||||
set_target_properties(backend_disconnect_recover PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(backend_disconnect_recover libsoundio_shared)
|
||||
|
||||
add_executable(overflow test/overflow.c)
|
||||
set_target_properties(overflow PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
COMPILE_FLAGS ${EXAMPLE_CFLAGS})
|
||||
include_directories(${EXAMPLE_INCLUDES})
|
||||
target_link_libraries(overflow libsoundio_shared)
|
||||
|
||||
|
||||
|
|
|
@ -1115,7 +1115,10 @@ SOUNDIO_EXPORT int soundio_instream_get_latency(struct SoundIoInStream *instream
|
|||
double *out_latency);
|
||||
|
||||
|
||||
// Ring Buffer
|
||||
/// A ring buffer is a single-reader single-writer lock-free fixed-size queue.
|
||||
/// libsoundio ring buffers use memory mapping techniques to enable a
|
||||
/// contiguous buffer when reading or writing across the boundary of the ring
|
||||
/// buffer's capacity.
|
||||
struct SoundIoRingBuffer;
|
||||
/// `requested_capacity` in bytes.
|
||||
/// Returns `NULL` if and only if memory could not be allocated.
|
||||
|
@ -1129,12 +1132,12 @@ SOUNDIO_EXPORT void soundio_ring_buffer_destroy(struct SoundIoRingBuffer *ring_b
|
|||
/// capacity for alignment purposes. This function returns the actual capacity.
|
||||
SOUNDIO_EXPORT int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *ring_buffer);
|
||||
|
||||
/// don't write more than capacity
|
||||
/// Do not write more than capacity.
|
||||
SOUNDIO_EXPORT char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *ring_buffer);
|
||||
/// `count` in bytes.
|
||||
SOUNDIO_EXPORT void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *ring_buffer, int count);
|
||||
|
||||
/// don't read more than capacity
|
||||
/// Do not read more than capacity.
|
||||
SOUNDIO_EXPORT char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *ring_buffer);
|
||||
/// `count` in bytes.
|
||||
SOUNDIO_EXPORT void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *ring_buffer, int count);
|
||||
|
|
206
test/latency.cpp
Normal file
206
test/latency.cpp
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of libsoundio, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "soundio.hpp"
|
||||
#include "os.h"
|
||||
#include "util.hpp"
|
||||
#include "atomics.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
static int usage(char *exe) {
|
||||
fprintf(stderr, "Usage: %s [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi]\n", exe);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void write_sample_s16ne(char *ptr, double sample) {
|
||||
int16_t *buf = (int16_t *)ptr;
|
||||
double range = (double)INT16_MAX - (double)INT16_MIN;
|
||||
double val = sample * range / 2.0;
|
||||
*buf = val;
|
||||
}
|
||||
|
||||
static void write_sample_s32ne(char *ptr, double sample) {
|
||||
int32_t *buf = (int32_t *)ptr;
|
||||
double range = (double)INT32_MAX - (double)INT32_MIN;
|
||||
double val = sample * range / 2.0;
|
||||
*buf = val;
|
||||
}
|
||||
|
||||
static void write_sample_float32ne(char *ptr, double sample) {
|
||||
float *buf = (float *)ptr;
|
||||
*buf = sample;
|
||||
}
|
||||
|
||||
static void write_sample_float64ne(char *ptr, double sample) {
|
||||
double *buf = (double *)ptr;
|
||||
*buf = sample;
|
||||
}
|
||||
|
||||
static void (*write_sample)(char *ptr, double sample);
|
||||
|
||||
static int frames_until_pulse = 0;
|
||||
static int pulse_frames_left = 0;
|
||||
static const double PI = 3.14159265358979323846264338328;
|
||||
static double seconds_offset = 0.0;
|
||||
|
||||
static SoundIoRingBuffer pulse_rb;
|
||||
|
||||
static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max) {
|
||||
double float_sample_rate = outstream->sample_rate;
|
||||
double seconds_per_frame = 1.0f / float_sample_rate;
|
||||
struct SoundIoChannelArea *areas;
|
||||
int err;
|
||||
|
||||
int frames_left = frame_count_max;
|
||||
|
||||
while (frames_left > 0) {
|
||||
int frame_count = frames_left;
|
||||
|
||||
if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count)))
|
||||
soundio_panic("begin write: %s", soundio_strerror(err));
|
||||
|
||||
if (!frame_count)
|
||||
break;
|
||||
|
||||
const struct SoundIoChannelLayout *layout = &outstream->layout;
|
||||
|
||||
double pitch = 440.0;
|
||||
double radians_per_second = pitch * 2.0 * PI;
|
||||
for (int frame = 0; frame < frame_count; frame += 1) {
|
||||
double sample;
|
||||
if (frames_until_pulse <= 0) {
|
||||
if (pulse_frames_left <= 0) {
|
||||
frames_until_pulse = (1.0 + (rand() / (double)RAND_MAX) * 3.0) * float_sample_rate;
|
||||
pulse_frames_left = 0.05 * float_sample_rate;
|
||||
sample = 0.0;
|
||||
} else {
|
||||
pulse_frames_left -= 1;
|
||||
sample = sinf((seconds_offset + frame * seconds_per_frame) * radians_per_second);
|
||||
}
|
||||
} else {
|
||||
frames_until_pulse -= 1;
|
||||
sample = 0.0;
|
||||
}
|
||||
for (int channel = 0; channel < layout->channel_count; channel += 1) {
|
||||
write_sample(areas[channel].ptr, sample);
|
||||
areas[channel].ptr += areas[channel].step;
|
||||
}
|
||||
}
|
||||
|
||||
seconds_offset += seconds_per_frame * frame_count;
|
||||
|
||||
if ((err = soundio_outstream_end_write(outstream)))
|
||||
soundio_panic("end write: %s", soundio_strerror(err));
|
||||
|
||||
frames_left -= frame_count;
|
||||
}
|
||||
}
|
||||
|
||||
static void underflow_callback(struct SoundIoOutStream *outstream) {
|
||||
static int count = 0;
|
||||
fprintf(stderr, "underflow %d\n", count++);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *exe = argv[0];
|
||||
enum SoundIoBackend backend = SoundIoBackendNone;
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
char *arg = argv[i];
|
||||
if (arg[0] == '-' && arg[1] == '-') {
|
||||
i += 1;
|
||||
if (i >= argc) {
|
||||
return usage(exe);
|
||||
} else if (strcmp(arg, "--backend") == 0) {
|
||||
if (strcmp("dummy", argv[i]) == 0) {
|
||||
backend = SoundIoBackendDummy;
|
||||
} else if (strcmp("alsa", argv[i]) == 0) {
|
||||
backend = SoundIoBackendAlsa;
|
||||
} else if (strcmp("pulseaudio", argv[i]) == 0) {
|
||||
backend = SoundIoBackendPulseAudio;
|
||||
} else if (strcmp("jack", argv[i]) == 0) {
|
||||
backend = SoundIoBackendJack;
|
||||
} else if (strcmp("coreaudio", argv[i]) == 0) {
|
||||
backend = SoundIoBackendCoreAudio;
|
||||
} else if (strcmp("wasapi", argv[i]) == 0) {
|
||||
backend = SoundIoBackendWasapi;
|
||||
} else {
|
||||
fprintf(stderr, "Invalid backend: %s\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return usage(exe);
|
||||
}
|
||||
} else {
|
||||
return usage(exe);
|
||||
}
|
||||
}
|
||||
|
||||
struct SoundIo *soundio;
|
||||
if (!(soundio = soundio_create()))
|
||||
soundio_panic("out of memory");
|
||||
|
||||
int err = (backend == SoundIoBackendNone) ?
|
||||
soundio_connect(soundio) : soundio_connect_backend(soundio, backend);
|
||||
|
||||
if (err)
|
||||
soundio_panic("error connecting: %s", soundio_strerror(err));
|
||||
|
||||
soundio_flush_events(soundio);
|
||||
|
||||
int default_out_device_index = soundio_default_output_device_index(soundio);
|
||||
if (default_out_device_index < 0)
|
||||
soundio_panic("no output device found");
|
||||
|
||||
struct SoundIoDevice *device = soundio_get_output_device(soundio, default_out_device_index);
|
||||
if (!device)
|
||||
soundio_panic("out of memory");
|
||||
|
||||
fprintf(stderr, "Output device: %s\n", device->name);
|
||||
|
||||
struct SoundIoOutStream *outstream = soundio_outstream_create(device);
|
||||
outstream->format = SoundIoFormatFloat32NE;
|
||||
outstream->write_callback = write_callback;
|
||||
outstream->underflow_callback = underflow_callback;
|
||||
|
||||
if (soundio_device_supports_format(device, SoundIoFormatFloat32NE)) {
|
||||
outstream->format = SoundIoFormatFloat32NE;
|
||||
write_sample = write_sample_float32ne;
|
||||
} else if (soundio_device_supports_format(device, SoundIoFormatFloat64NE)) {
|
||||
outstream->format = SoundIoFormatFloat64NE;
|
||||
write_sample = write_sample_float64ne;
|
||||
} else if (soundio_device_supports_format(device, SoundIoFormatS32NE)) {
|
||||
outstream->format = SoundIoFormatS32NE;
|
||||
write_sample = write_sample_s32ne;
|
||||
} else if (soundio_device_supports_format(device, SoundIoFormatS16NE)) {
|
||||
outstream->format = SoundIoFormatS16NE;
|
||||
write_sample = write_sample_s16ne;
|
||||
} else {
|
||||
soundio_panic("No suitable device format available.\n");
|
||||
}
|
||||
|
||||
if ((err = soundio_outstream_open(outstream)))
|
||||
soundio_panic("unable to open device: %s", soundio_strerror(err));
|
||||
|
||||
if (outstream->layout_error)
|
||||
fprintf(stderr, "unable to set channel layout: %s\n", soundio_strerror(outstream->layout_error));
|
||||
|
||||
if ((err = soundio_outstream_start(outstream)))
|
||||
soundio_panic("unable to start device: %s", soundio_strerror(err));
|
||||
|
||||
for (;;)
|
||||
soundio_wait_events(soundio);
|
||||
|
||||
soundio_outstream_destroy(outstream);
|
||||
soundio_device_unref(device);
|
||||
soundio_destroy(soundio);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ int main(int argc, char **argv) {
|
|||
if (i >= argc) {
|
||||
return usage(exe);
|
||||
} else if (strcmp(arg, "--backend") == 0) {
|
||||
if (strcmp("-dummy", argv[i]) == 0) {
|
||||
if (strcmp("dummy", argv[i]) == 0) {
|
||||
backend = SoundIoBackendDummy;
|
||||
} else if (strcmp("alsa", argv[i]) == 0) {
|
||||
backend = SoundIoBackendAlsa;
|
||||
|
|
Loading…
Reference in a new issue