diff --git a/.gitignore b/.gitignore index 04029d7..a2bcaac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ -build-win/ +build-win32/ +build-win64/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cb03b7..c81d811 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,6 @@ set(LIBSOUNDIO_SOURCES set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h") set(LIBSOUNDIO_HEADERS "${CMAKE_SOURCE_DIR}/soundio/soundio.h" - "${CMAKE_SOURCE_DIR}/soundio/os.h" ${CONFIGURE_OUT_FILE} ) @@ -163,7 +162,7 @@ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -pedantic") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -pedantic") -set(LIB_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes") +set(LIB_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -fvisibility=hidden -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes") set(EXAMPLE_CFLAGS "-std=c99 -Wall") set(EXAMPLE_INCLUDES "${CMAKE_SOURCE_DIR}/src") set(TEST_CFLAGS "${LIB_CFLAGS} -fprofile-arcs -ftest-coverage") diff --git a/README.md b/README.md index cf9fd46..a9a74a1 100644 --- a/README.md +++ b/README.md @@ -225,19 +225,26 @@ packages necessary on your system. Then somewhere on your file system: ``` git clone https://github.com/mxe/mxe cd mxe -make gcc +make MXE_TARGETS='x86_64-w64-mingw32.static i686-w64-mingw32.static' gcc ``` Then in the libsoundio source directory (replace "/path/to/mxe" with the appropriate path): ``` -mkdir build-win -cd build-win +mkdir build-win32 +cd build-win32 cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/mxe/usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake make ``` +``` +mkdir build-win64 +cd build-win64 +cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/mxe/usr/x86_64-w64-mingw32.static/share/cmake/mxe-conf.cmake +make +``` + #### Running the Tests ``` @@ -257,8 +264,9 @@ view `coverage/index.html` in a browser. ## Roadmap 0. implement WASAPI (Windows) backend, get examples working - - sine wave + - sine wave (raw device) - microphone + - set display name of output stream 0. Make sure PulseAudio can handle refresh devices crashing before block_until_have_devices 0. Integrate into libgroove and test with Groove Basin @@ -283,8 +291,6 @@ view `coverage/index.html` in a browser. - 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, or - explicitly make the unexported stuff private 0. add len arguments to APIs that have char * - replace strdup with `soundio_str_dupe` 0. Support PulseAudio proplist properties for main context and streams @@ -298,6 +304,10 @@ view `coverage/index.html` in a browser. 0. In ALSA do we need to wake up the poll when destroying the in or out stream? 0. Detect PulseAudio server going offline and emit `on_backend_disconnect`. 0. Add [sndio](http://www.sndio.org/) backend to support OpenBSD. + 0. Support for stream icon. + - PulseAudio: XDG icon name + - WASAPI: path to .exe, .dll, or .ico + - CoreAudio: CFURLRef image file ## Planned Uses for libsoundio diff --git a/soundio/soundio.h b/soundio/soundio.h index e5065d9..dfd601c 100644 --- a/soundio/soundio.h +++ b/soundio/soundio.h @@ -12,8 +12,19 @@ #include #ifdef __cplusplus -extern "C" -{ +#define SOUNDIO_EXTERN_C extern "C" +#else +#define SOUNDIO_EXTERN_C +#endif + +#if defined(_WIN32) +#if defined(SOUNDIO_BUILDING_LIBRARY) +#define SOUNDIO_EXPORT SOUNDIO_EXTERN_C __declspec(dllexport) +#else +#define SOUNDIO_EXPORT SOUNDIO_EXTERN_C __declspec(dllimport) +#endif +#else +#define SOUNDIO_EXPORT SOUNDIO_EXTERN_C __attribute__((visibility ("default"))) #endif enum SoundIoError { @@ -532,29 +543,29 @@ struct SoundIoInStream { // Create a SoundIo context. You may create multiple instances of this to // connect to multiple backends. -struct SoundIo * soundio_create(void); -void soundio_destroy(struct SoundIo *soundio); +SOUNDIO_EXPORT struct SoundIo * soundio_create(void); +SOUNDIO_EXPORT void soundio_destroy(struct SoundIo *soundio); // This is a convenience function you could implement yourself if you wanted // to. It tries `soundio_connect_backend` on all available backends in order. -int soundio_connect(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_connect(struct SoundIo *soundio); // Instead of calling `soundio_connect` you may call this function to try a // specific backend. -int soundio_connect_backend(struct SoundIo *soundio, enum SoundIoBackend backend); -void soundio_disconnect(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_connect_backend(struct SoundIo *soundio, enum SoundIoBackend backend); +SOUNDIO_EXPORT void soundio_disconnect(struct SoundIo *soundio); -const char *soundio_strerror(int error); -const char *soundio_backend_name(enum SoundIoBackend backend); +SOUNDIO_EXPORT const char *soundio_strerror(int error); +SOUNDIO_EXPORT const char *soundio_backend_name(enum SoundIoBackend backend); // Returns the number of available backends. -int soundio_backend_count(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_backend_count(struct SoundIo *soundio); // get the available backend at the specified index // (0 <= index < `soundio_backend_count`) -enum SoundIoBackend soundio_get_backend(struct SoundIo *soundio, int index); +SOUNDIO_EXPORT enum SoundIoBackend soundio_get_backend(struct SoundIo *soundio, int index); // Returns whether libsoundio was compiled with `backend`. -bool soundio_have_backend(enum SoundIoBackend backend); +SOUNDIO_EXPORT bool soundio_have_backend(enum SoundIoBackend backend); // When you call this, the `on_devices_change` and `on_events_signal` callbacks // might be called. This is the only time those callbacks will be called. @@ -566,14 +577,14 @@ bool soundio_have_backend(enum SoundIoBackend backend); // * `soundio_get_output_device` // * `soundio_default_input_device_index` // * `soundio_default_output_device_index` -void soundio_flush_events(struct SoundIo *soundio); +SOUNDIO_EXPORT void soundio_flush_events(struct SoundIo *soundio); // This function calls `soundio_flush_events` then blocks until another event // is ready or you call `soundio_wakeup`. Be ready for spurious wakeups. -void soundio_wait_events(struct SoundIo *soundio); +SOUNDIO_EXPORT void soundio_wait_events(struct SoundIo *soundio); // Makes `soundio_wait_events` stop blocking. -void soundio_wakeup(struct SoundIo *soundio); +SOUNDIO_EXPORT void soundio_wakeup(struct SoundIo *soundio); @@ -581,44 +592,44 @@ void soundio_wakeup(struct SoundIo *soundio); // Returns whether the channel count field and each channel id matches in // the supplied channel layouts. -bool soundio_channel_layout_equal( +SOUNDIO_EXPORT bool soundio_channel_layout_equal( const struct SoundIoChannelLayout *a, const struct SoundIoChannelLayout *b); -const char *soundio_get_channel_name(enum SoundIoChannelId id); +SOUNDIO_EXPORT const char *soundio_get_channel_name(enum SoundIoChannelId id); // Given UTF-8 encoded text which is the name of a channel such as // "Front Left", "FL", or "front-left", return the corresponding // SoundIoChannelId. Returns SoundIoChannelIdInvalid for no match. -enum SoundIoChannelId soundio_parse_channel_id(const char *str, int str_len); +SOUNDIO_EXPORT enum SoundIoChannelId soundio_parse_channel_id(const char *str, int str_len); -int soundio_channel_layout_builtin_count(void); -const struct SoundIoChannelLayout *soundio_channel_layout_get_builtin(int index); +SOUNDIO_EXPORT int soundio_channel_layout_builtin_count(void); +SOUNDIO_EXPORT const struct SoundIoChannelLayout *soundio_channel_layout_get_builtin(int index); // Get the default builtin channel layout for the given number of channels. -const struct SoundIoChannelLayout *soundio_channel_layout_get_default(int channel_count); +SOUNDIO_EXPORT const struct SoundIoChannelLayout *soundio_channel_layout_get_default(int channel_count); -int soundio_channel_layout_find_channel( +SOUNDIO_EXPORT int soundio_channel_layout_find_channel( const struct SoundIoChannelLayout *layout, enum SoundIoChannelId channel); // Populates the name field of layout if it matches a builtin one. // returns whether it found a match -bool soundio_channel_layout_detect_builtin(struct SoundIoChannelLayout *layout); +SOUNDIO_EXPORT bool soundio_channel_layout_detect_builtin(struct SoundIoChannelLayout *layout); // Iterates over preferred_layouts. Returns the first channel layout in // preferred_layouts which matches one of the channel layouts in // available_layouts. Returns NULL if none matches. -const struct SoundIoChannelLayout *soundio_best_matching_channel_layout( +SOUNDIO_EXPORT const struct SoundIoChannelLayout *soundio_best_matching_channel_layout( const struct SoundIoChannelLayout *preferred_layouts, int preferred_layout_count, const struct SoundIoChannelLayout *available_layouts, int available_layout_count); // Sorts by channel count, descending. -void soundio_sort_channel_layouts(struct SoundIoChannelLayout *layouts, int layout_count); +SOUNDIO_EXPORT void soundio_sort_channel_layouts(struct SoundIoChannelLayout *layouts, int layout_count); // Sample Formats // Returns -1 on invalid format. -int soundio_get_bytes_per_sample(enum SoundIoFormat format); +SOUNDIO_EXPORT int soundio_get_bytes_per_sample(enum SoundIoFormat format); static inline int soundio_get_bytes_per_frame(enum SoundIoFormat format, int channel_count) { return soundio_get_bytes_per_sample(format) * channel_count; @@ -631,7 +642,7 @@ static inline int soundio_get_bytes_per_second(enum SoundIoFormat format, return soundio_get_bytes_per_frame(format, channel_count) * sample_rate; } -const char * soundio_format_string(enum SoundIoFormat format); +SOUNDIO_EXPORT const char * soundio_format_string(enum SoundIoFormat format); @@ -647,60 +658,60 @@ const char * soundio_format_string(enum SoundIoFormat format); // Get the number of input devices. // Returns -1 if you never called `soundio_flush_events`. -int soundio_input_device_count(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_input_device_count(struct SoundIo *soundio); // Get the number of output devices. // Returns -1 if you never called `soundio_flush_events`. -int soundio_output_device_count(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_output_device_count(struct SoundIo *soundio); // Always returns a device. Call soundio_device_unref when done. // `index` must be 0 <= index < soundio_input_device_count // Returns NULL if you never called `soundio_flush_events` or if you provide // invalid parameter values. -struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index); +SOUNDIO_EXPORT struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index); // Always returns a device. Call soundio_device_unref when done. // `index` must be 0 <= index < soundio_output_device_count // Returns NULL if you never called `soundio_flush_events` or if you provide // invalid parameter values. -struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index); +SOUNDIO_EXPORT struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index); // returns the index of the default input device // returns -1 if there are no devices or if you never called // `soundio_flush_events`. -int soundio_default_input_device_index(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_default_input_device_index(struct SoundIo *soundio); // returns the index of the default output device // returns -1 if there are no devices or if you never called // `soundio_flush_events`. -int soundio_default_output_device_index(struct SoundIo *soundio); +SOUNDIO_EXPORT int soundio_default_output_device_index(struct SoundIo *soundio); -void soundio_device_ref(struct SoundIoDevice *device); -void soundio_device_unref(struct SoundIoDevice *device); +SOUNDIO_EXPORT void soundio_device_ref(struct SoundIoDevice *device); +SOUNDIO_EXPORT void soundio_device_unref(struct SoundIoDevice *device); -bool soundio_device_equal( +SOUNDIO_EXPORT bool soundio_device_equal( const struct SoundIoDevice *a, const struct SoundIoDevice *b); // Sorts channel layouts by channel count, descending. -void soundio_device_sort_channel_layouts(struct SoundIoDevice *device); +SOUNDIO_EXPORT void soundio_device_sort_channel_layouts(struct SoundIoDevice *device); // Convenience function. Returns whether `format` is included in the device's // supported formats. -bool soundio_device_supports_format(struct SoundIoDevice *device, +SOUNDIO_EXPORT bool soundio_device_supports_format(struct SoundIoDevice *device, enum SoundIoFormat format); // Convenience function. Returns whether `layout` is included in the device's // supported channel layouts. -bool soundio_device_supports_layout(struct SoundIoDevice *device, +SOUNDIO_EXPORT bool soundio_device_supports_layout(struct SoundIoDevice *device, const struct SoundIoChannelLayout *layout); // Convenience function. Returns whether `sample_rate` is included in the // device's supported sample rates. -bool soundio_device_supports_sample_rate(struct SoundIoDevice *device, +SOUNDIO_EXPORT bool soundio_device_supports_sample_rate(struct SoundIoDevice *device, int sample_rate); // Convenience function. Returns the available sample rate nearest to // `sample_rate`, rounding up. -int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, +SOUNDIO_EXPORT int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, int sample_rate); @@ -708,17 +719,17 @@ int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, // Output Streams // Allocates memory and sets defaults. Next you should fill out the struct fields // and then call `soundio_outstream_open`. -struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device); +SOUNDIO_EXPORT struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device); // You may not call this function from the `write_callback` thread context. -void soundio_outstream_destroy(struct SoundIoOutStream *outstream); +SOUNDIO_EXPORT void soundio_outstream_destroy(struct SoundIoOutStream *outstream); // After you call this function, `software_latency` is set to the correct // value. // The next thing to do is call `soundio_instream_start`. -int soundio_outstream_open(struct SoundIoOutStream *outstream); +SOUNDIO_EXPORT int soundio_outstream_open(struct SoundIoOutStream *outstream); // After you call this function, `write_callback` will be called. -int soundio_outstream_start(struct SoundIoOutStream *outstream); +SOUNDIO_EXPORT int soundio_outstream_start(struct SoundIoOutStream *outstream); // Call this function when you are ready to begin writing to the device buffer. // * `outstream` - (in) The output stream you want to write to. @@ -738,23 +749,23 @@ int soundio_outstream_start(struct SoundIoOutStream *outstream); // If you call this function with `frame_count` less than the `frame_count_min` // parameter from `write_callback` it returns SoundIoErrorInvalid. // If this function returns an error, do not call `soundio_outstream_end_write`. -int soundio_outstream_begin_write(struct SoundIoOutStream *outstream, +SOUNDIO_EXPORT int soundio_outstream_begin_write(struct SoundIoOutStream *outstream, struct SoundIoChannelArea **areas, int *frame_count); // Commits the write that you began with `soundio_outstream_begin_write`. // You must call this function only from the `write_callback` thread context. // This function might return `SoundIoErrorUnderflow` but don't count on it. -int soundio_outstream_end_write(struct SoundIoOutStream *outstream); +SOUNDIO_EXPORT int soundio_outstream_end_write(struct SoundIoOutStream *outstream); // Clears the output stream buffer. // You must call this function only from the `write_callback` thread context. -int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream); +SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream); // If the underyling device supports pausing, this pauses the stream and // prevents `write_callback` from being called. Otherwise this returns // `SoundIoErrorIncompatibleDevice`. // You must call this function only from the `write_callback` thread context. -int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause); +SOUNDIO_EXPORT int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause); @@ -762,17 +773,17 @@ int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause); // Input Streams // Allocates memory and sets defaults. Next you should fill out the struct fields // and then call `soundio_instream_open`. -struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device); +SOUNDIO_EXPORT struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device); // You may not call this function from `read_callback`. -void soundio_instream_destroy(struct SoundIoInStream *instream); +SOUNDIO_EXPORT void soundio_instream_destroy(struct SoundIoInStream *instream); // After you call this function, `software_latency` is set to the correct // value. // The next thing to do is call `soundio_instream_start`. -int soundio_instream_open(struct SoundIoInStream *instream); +SOUNDIO_EXPORT int soundio_instream_open(struct SoundIoInStream *instream); // After you call this function, `read_callback` will be called. -int soundio_instream_start(struct SoundIoInStream *instream); +SOUNDIO_EXPORT int soundio_instream_start(struct SoundIoInStream *instream); // Call this function when you are ready to begin reading from the device // buffer. @@ -796,51 +807,46 @@ int soundio_instream_start(struct SoundIoInStream *instream); // and move the read index forward. `soundio_instream_end_read` should not be // called if the buffer is empty (`frame_count` == 0), but it should be called // if there is a hole. -int soundio_instream_begin_read(struct SoundIoInStream *instream, +SOUNDIO_EXPORT int soundio_instream_begin_read(struct SoundIoInStream *instream, struct SoundIoChannelArea **areas, int *frame_count); // This will drop all of the frames from when you called // `soundio_instream_begin_read`. // You must call this function only from the `read_callback` thread context. // You must call this function only after a successful call to // `soundio_instream_begin_read`. -int soundio_instream_end_read(struct SoundIoInStream *instream); +SOUNDIO_EXPORT int soundio_instream_end_read(struct SoundIoInStream *instream); // If the underyling device supports pausing, this pauses the stream and // prevents `read_callback` from being called. Otherwise this returns // `SoundIoErrorIncompatibleDevice`. // You must call this function only from the `read_callback` thread context. -int soundio_instream_pause(struct SoundIoInStream *instream, bool pause); +SOUNDIO_EXPORT int soundio_instream_pause(struct SoundIoInStream *instream, bool pause); // Ring Buffer struct SoundIoRingBuffer; // `requested_capacity` in bytes. -struct SoundIoRingBuffer *soundio_ring_buffer_create(struct SoundIo *soundio, int requested_capacity); -void soundio_ring_buffer_destroy(struct SoundIoRingBuffer *ring_buffer); -int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT struct SoundIoRingBuffer *soundio_ring_buffer_create(struct SoundIo *soundio, int requested_capacity); +SOUNDIO_EXPORT void soundio_ring_buffer_destroy(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *ring_buffer); // don't write more than capacity -char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *ring_buffer); // `count` in bytes. -void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *ring_buffer, int count); +SOUNDIO_EXPORT void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *ring_buffer, int count); // don't read more than capacity -char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *ring_buffer); // `count` in bytes. -void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *ring_buffer, int count); +SOUNDIO_EXPORT void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *ring_buffer, int count); // Returns how many bytes of the buffer is used, ready for reading. -int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *ring_buffer); // Returns how many bytes of the buffer is free, ready for writing. -int soundio_ring_buffer_free_count(struct SoundIoRingBuffer *ring_buffer); +SOUNDIO_EXPORT int soundio_ring_buffer_free_count(struct SoundIoRingBuffer *ring_buffer); // Must be called by the writer. -void soundio_ring_buffer_clear(struct SoundIoRingBuffer *ring_buffer); - - -#ifdef __cplusplus -} -#endif +SOUNDIO_EXPORT void soundio_ring_buffer_clear(struct SoundIoRingBuffer *ring_buffer); #endif diff --git a/src/alsa.hpp b/src/alsa.hpp index baf7009..bac9ea8 100644 --- a/src/alsa.hpp +++ b/src/alsa.hpp @@ -8,8 +8,8 @@ #ifndef SOUNDIO_ALSA_HPP #define SOUNDIO_ALSA_HPP -#include "soundio/soundio.h" -#include "soundio/os.h" +#include "soundio_private.h" +#include "os.h" #include "atomics.hpp" #include diff --git a/src/coreaudio.hpp b/src/coreaudio.hpp index 45df501..ff3c988 100644 --- a/src/coreaudio.hpp +++ b/src/coreaudio.hpp @@ -8,8 +8,8 @@ #ifndef SOUNDIO_COREAUDIO_HPP #define SOUNDIO_COREAUDIO_HPP -#include "soundio/soundio.h" -#include "soundio/os.h" +#include "soundio_private.h" +#include "os.h" #include "atomics.hpp" #include "list.hpp" diff --git a/src/dummy.hpp b/src/dummy.hpp index b4e40b4..118716c 100644 --- a/src/dummy.hpp +++ b/src/dummy.hpp @@ -8,8 +8,8 @@ #ifndef SOUNDIO_DUMMY_HPP #define SOUNDIO_DUMMY_HPP -#include "soundio/soundio.h" -#include "soundio/os.h" +#include "soundio_private.h" +#include "os.h" #include "atomics.hpp" #include "ring_buffer.hpp" diff --git a/src/jack.hpp b/src/jack.hpp index f4783c5..4b6b17d 100644 --- a/src/jack.hpp +++ b/src/jack.hpp @@ -8,8 +8,8 @@ #ifndef SOUNDIO_JACK_HPP #define SOUNDIO_JACK_HPP -#include "soundio/soundio.h" -#include "soundio/os.h" +#include "soundio_private.h" +#include "os.h" #include "atomics.hpp" #include diff --git a/src/list.hpp b/src/list.hpp index 4f3dccd..31e0f27 100644 --- a/src/list.hpp +++ b/src/list.hpp @@ -9,7 +9,7 @@ #define SOUNDIO_LIST_HPP #include "util.hpp" -#include "soundio/soundio.h" +#include "soundio_private.h" #include diff --git a/src/os.cpp b/src/os.cpp index 58ae7dd..2511bd5 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -5,8 +5,8 @@ * See http://opensource.org/licenses/MIT */ -#include "soundio/os.h" -#include "soundio/soundio.h" +#include "os.h" +#include "soundio_private.h" #include "util.hpp" #include "atomics.hpp" diff --git a/soundio/os.h b/src/os.h similarity index 96% rename from soundio/os.h rename to src/os.h index da350b3..444a050 100644 --- a/soundio/os.h +++ b/src/os.h @@ -11,12 +11,6 @@ #include #include -#ifdef __cplusplus -extern "C" -{ -#endif - - // safe to call from any thread(s) multiple times, but // must be called at least once before calling any other os functions // soundio_create calls this function. @@ -69,8 +63,4 @@ struct SoundIoOsMirroredMemory { int soundio_os_init_mirrored_memory(struct SoundIoOsMirroredMemory *mem, size_t capacity); void soundio_os_deinit_mirrored_memory(struct SoundIoOsMirroredMemory *mem); -#ifdef __cplusplus -} -#endif - #endif diff --git a/src/pulseaudio.hpp b/src/pulseaudio.hpp index 8ea0c4a..46a72f2 100644 --- a/src/pulseaudio.hpp +++ b/src/pulseaudio.hpp @@ -8,7 +8,7 @@ #ifndef SOUNDIO_PULSEAUDIO_HPP #define SOUNDIO_PULSEAUDIO_HPP -#include "soundio/soundio.h" +#include "soundio_private.h" #include "atomics.hpp" #include diff --git a/src/ring_buffer.hpp b/src/ring_buffer.hpp index 9ae7f4f..a34a322 100644 --- a/src/ring_buffer.hpp +++ b/src/ring_buffer.hpp @@ -9,7 +9,7 @@ #define SOUNDIO_RING_BUFFER_HPP #include "atomics.hpp" -#include "soundio/os.h" +#include "os.h" struct SoundIoRingBuffer { SoundIoOsMirroredMemory mem; diff --git a/src/soundio.cpp b/src/soundio.cpp index cda86fe..f3cea3e 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -7,7 +7,7 @@ #include "soundio.hpp" #include "util.hpp" -#include "soundio/os.h" +#include "os.h" #include "config.h" #include diff --git a/src/soundio.hpp b/src/soundio.hpp index 40c6ea4..7378d93 100644 --- a/src/soundio.hpp +++ b/src/soundio.hpp @@ -8,7 +8,7 @@ #ifndef SOUNDIO_SOUNDIO_HPP #define SOUNDIO_SOUNDIO_HPP -#include "soundio/soundio.h" +#include "soundio_private.h" #include "list.hpp" #ifdef SOUNDIO_HAVE_JACK diff --git a/src/soundio_private.h b/src/soundio_private.h new file mode 100644 index 0000000..1016a15 --- /dev/null +++ b/src/soundio_private.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of libsoundio, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef SOUNDIO_SOUNDIO_PRIVATE_H +#define SOUNDIO_SOUNDIO_PRIVATE_H + +// This exists for __declspec(dllexport) and __declspec(dllimport) to be +// defined correctly without the library user having to do anything. +#define SOUNDIO_BUILDING_LIBRARY +#include "soundio/soundio.h" + +#endif diff --git a/src/util.hpp b/src/util.hpp index 06a8b6e..a34eae8 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -52,7 +52,7 @@ static inline bool soundio_streql(const char *str1, int str1_len, const char *st template -constexpr long array_length(const T (&)[n]) { +static constexpr long array_length(const T (&)[n]) { return n; } diff --git a/src/wasapi.cpp b/src/wasapi.cpp index dbc28ff..49bb14b 100644 --- a/src/wasapi.cpp +++ b/src/wasapi.cpp @@ -1176,8 +1176,11 @@ void outstream_shared_run(void *arg) { return; } osw->writable_frame_count = osw->buffer_frame_count - frames_used; - if (osw->writable_frame_count > 0) + if (osw->writable_frame_count > 0) { + if (frames_used == 0) + outstream->underflow_callback(outstream); outstream->write_callback(outstream, 0, osw->writable_frame_count); + } } } diff --git a/src/wasapi.hpp b/src/wasapi.hpp index 603212c..003ed47 100644 --- a/src/wasapi.hpp +++ b/src/wasapi.hpp @@ -8,8 +8,8 @@ #ifndef SOUNDIO_WASAPI_HPP #define SOUNDIO_WASAPI_HPP -#include "soundio/soundio.h" -#include "soundio/os.h" +#include "soundio_private.h" +#include "os.h" #include "atomics.hpp" #include "list.hpp" diff --git a/test/underflow.c b/test/underflow.c index 9886a49..e469ccf 100644 --- a/test/underflow.c +++ b/test/underflow.c @@ -6,13 +6,13 @@ */ #include -#include #include #include #include #include #include +#include __attribute__ ((cold)) __attribute__ ((noreturn)) @@ -34,7 +34,6 @@ static int usage(char *exe) { static const float PI = 3.1415926535f; static float seconds_offset = 0.0f; static bool caused_underflow = false; -static struct SoundIoOsCond *cond = NULL; static struct SoundIo *soundio = NULL; static float seconds_end = 9.0f; @@ -46,7 +45,7 @@ static void write_callback(struct SoundIoOutStream *outstream, int frame_count_m if (!caused_underflow && seconds_offset >= 3.0f) { caused_underflow = true; - soundio_os_cond_timed_wait(cond, NULL, 3.0); + sleep(3); } if (seconds_offset >= seconds_end) { @@ -137,10 +136,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Output device: %s\n", device->name); - cond = soundio_os_cond_create(); - if (!cond) - panic("out of memory"); - struct SoundIoOutStream *outstream = soundio_outstream_create(device); outstream->format = SoundIoFormatFloat32NE; outstream->write_callback = write_callback; @@ -160,7 +155,6 @@ int main(int argc, char **argv) { soundio_outstream_destroy(outstream); soundio_device_unref(device); - soundio_os_cond_destroy(cond); soundio_destroy(soundio); return 0; } diff --git a/test/unit_tests.cpp b/test/unit_tests.cpp index cd04bc4..45b1cb6 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.cpp @@ -1,7 +1,7 @@ #undef NDEBUG #include "soundio.hpp" -#include "soundio/os.h" +#include "os.h" #include "util.hpp" #include "atomics.hpp"