C library for cross-platform real-time audio input and output

Related tags

Audio libsoundio
Overview

libsoundio

C library providing cross-platform audio input and output. The API is suitable for real-time software such as digital audio workstations as well as consumer software such as music players.

This library is an abstraction; however in the delicate balance between performance and power, and API convenience, the scale is tipped closer to the former. Features that only exist in some sound backends are exposed.

Features and Limitations

  • Supported operating systems:
    • Windows 7+
    • MacOS 10.10+
    • Linux 3.7+
  • Supported backends:
  • Exposes both raw devices and shared devices. Raw devices give you the best performance but prevent other applications from using them. Shared devices are default and usually provide sample rate conversion and format conversion.
  • Exposes both device id and friendly name. id you could save in a config file because it persists between devices becoming plugged and unplugged, while friendly name is suitable for exposing to users.
  • Supports optimal usage of each supported backend. The same API does the right thing whether the backend has a fixed buffer size, such as on JACK and CoreAudio, or whether it allows directly managing the buffer, such as on ALSA, PulseAudio, and WASAPI.
  • C library. Depends only on the respective backend API libraries and libc. Does not depend on libstdc++, and does not have exceptions, run-time type information, or setjmp.
  • Errors are communicated via return codes, not logging to stdio.
  • Supports channel layouts (also known as channel maps), important for surround sound applications.
  • Ability to monitor devices and get an event when available devices change.
  • Ability to get an event when the backend is disconnected, for example when the JACK server or PulseAudio server shuts down.
  • Detects which input device is default and which output device is default.
  • Ability to connect to multiple backends at once. For example you could have an ALSA device open and a JACK device open at the same time.
  • Meticulously checks all return codes and memory allocations and uses meaningful error codes.
  • Exposes extra API that is only available on some backends. For example you can provide application name and stream names which is used by JACK and PulseAudio.

Synopsis

Complete program to emit a sine wave over the default device using the best backend:

#include <soundio/soundio.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

static const float PI = 3.1415926535f;
static float seconds_offset = 0.0f;
static void write_callback(struct SoundIoOutStream *outstream,
        int frame_count_min, int frame_count_max)
{
    const struct SoundIoChannelLayout *layout = &outstream->layout;
    float float_sample_rate = outstream->sample_rate;
    float seconds_per_frame = 1.0f / float_sample_rate;
    struct SoundIoChannelArea *areas;
    int frames_left = frame_count_max;
    int err;

    while (frames_left > 0) {
        int frame_count = frames_left;

        if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count))) {
            fprintf(stderr, "%s\n", soundio_strerror(err));
            exit(1);
        }

        if (!frame_count)
            break;

        float pitch = 440.0f;
        float radians_per_second = pitch * 2.0f * PI;
        for (int frame = 0; frame < frame_count; frame += 1) {
            float sample = sinf((seconds_offset + frame * seconds_per_frame) * radians_per_second);
            for (int channel = 0; channel < layout->channel_count; channel += 1) {
                float *ptr = (float*)(areas[channel].ptr + areas[channel].step * frame);
                *ptr = sample;
            }
        }
        seconds_offset = fmodf(seconds_offset +
            seconds_per_frame * frame_count, 1.0f);

        if ((err = soundio_outstream_end_write(outstream))) {
            fprintf(stderr, "%s\n", soundio_strerror(err));
            exit(1);
        }

        frames_left -= frame_count;
    }
}

int main(int argc, char **argv) {
    int err;
    struct SoundIo *soundio = soundio_create();
    if (!soundio) {
        fprintf(stderr, "out of memory\n");
        return 1;
    }

    if ((err = soundio_connect(soundio))) {
        fprintf(stderr, "error connecting: %s", soundio_strerror(err));
        return 1;
    }

    soundio_flush_events(soundio);

    int default_out_device_index = soundio_default_output_device_index(soundio);
    if (default_out_device_index < 0) {
        fprintf(stderr, "no output device found");
        return 1;
    }

    struct SoundIoDevice *device = soundio_get_output_device(soundio, default_out_device_index);
    if (!device) {
        fprintf(stderr, "out of memory");
        return 1;
    }

    fprintf(stderr, "Output device: %s\n", device->name);

    struct SoundIoOutStream *outstream = soundio_outstream_create(device);
    outstream->format = SoundIoFormatFloat32NE;
    outstream->write_callback = write_callback;

    if ((err = soundio_outstream_open(outstream))) {
        fprintf(stderr, "unable to open device: %s", soundio_strerror(err));
        return 1;
    }

    if (outstream->layout_error)
        fprintf(stderr, "unable to set channel layout: %s\n", soundio_strerror(outstream->layout_error));

    if ((err = soundio_outstream_start(outstream))) {
        fprintf(stderr, "unable to start device: %s", soundio_strerror(err));
        return 1;
    }

    for (;;)
        soundio_wait_events(soundio);

    soundio_outstream_destroy(outstream);
    soundio_device_unref(device);
    soundio_destroy(soundio);
    return 0;
}

Backend Priority

When you use soundio_connect, libsoundio tries these backends in order. If unable to connect to that backend, due to the backend not being installed, or the server not running, or the platform is wrong, the next backend is tried.

  1. JACK
  2. PulseAudio
  3. ALSA (Linux)
  4. CoreAudio (OSX)
  5. WASAPI (Windows)
  6. Dummy

If you don't like this order, you can use soundio_connect_backend to explicitly choose a backend to connect to. You can use soundio_backend_count and soundio_get_backend to get the list of available backends.

API Documentation

Building

Install the dependencies:

  • cmake
  • ALSA library (optional)
  • libjack2 (optional)
  • libpulseaudio (optional)
mkdir build
cd build
cmake ..
make
sudo make install

Building for Windows

You can build libsoundio with mxe. Follow the requirements section to install the packages necessary on your system. Then somewhere on your file system:

git clone https://github.com/mxe/mxe
cd mxe
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-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

Testing

For each backend, do the following:

  1. Run the unit tests: ./unit_tests. To see test coverage, install lcov, run make coverage, and then view coverage/index.html in a browser.
  2. Run the example ./sio_list_devices and make sure it does not crash, and the output looks good. If valgrind is available, use it.
  3. Run ./sio_list_devices --watch and make sure it detects when you plug and unplug a USB microphone.
  4. Run ./sio_sine and make sure you hear a sine wave. For backends with raw devices, run ./sio_sine --device id --raw (where 'id' is a device id you got from sio_list_devices and make sure you hear a sine wave.
    • Use 'p' to test pausing, 'u' to test unpausing, 'q' to test cleanup.
    • 'c' for clear buffer. Clear buffer should not pause the stream and it should also not cause an underflow.
    • Use 'P' to test pausing from the callback, and then 'u' to unpause.
  5. Run ./underflow and read the testing instructions that it prints.
  6. Run ./sio_microphone and ensure that it is both recording and playing back correctly. If possible use the --in-device and --out-device parameters to test a USB microphone in raw mode.
  7. Run ./backend_disconnect_recover and read the testing instructions that it prints.
  8. Run ./latency and make sure the printed beeps line up with the beeps that you hear.

Building the Documentation

Ensure that doxygen is installed, then:

make doc

Then look at html/index.html in a browser.

Comments
  •  examples are hard-coded to use the shared form of the library

    examples are hard-coded to use the shared form of the library

    I see that the CMakeLists.txt file for libsoundio has two separate options for building dynamic vs. static libraries.

    I take it this was inspired by Libtool, which in its usual way of working compiles both static and shared libraries in one pass.

    However, in CMake, it is conventional to build either one or the other, controlled by the special variable BUILD_SHARED_LIBS. I've put together a patch that simplifies the listfile accordingly.

    (I don't currently have a proper setup to prepare a Git pull request, and I see that GitHub still doesn't allow issue attachments, so I've uploaded my patch here.)

    The immediate issue that spurred this was breakage when I disabled the dynamic lib and attempted to build the examples. The examples are hard-coded to use the shared form of the library. It would be possible to code the listfile so the examples/tests link with one or the other as appropriate, but because this approach is foreign to CMake anyway, I believe reducing the complexity is preferable.

    Oh, and as an extra, I added a bit to set CMAKE_INSTALL_RPATH. This allows the executables linked to a shared libsoundio to work in the install tree (without needing to set LD_LIBRARY_PATH) as well as the build tree.

    bug 
    opened by iskunk 48
  • MacOS 10.9: non-default latency and non-current sample rate prevent sound output

    MacOS 10.9: non-default latency and non-current sample rate prevent sound output

    I built libsoundio on a Macbook Pro (OS X 10.9.5). The output of sio_list_devices is

    $ ./sio_list_devices
    --------Input Devices--------
    
    Built-in Microphone (default)
      id: AppleHDAEngineInput:1B,0,1,0:1
      channel layouts:
        Stereo
      current layout: Stereo
      sample rates:
        44100 - 44100
      current sample rate: 44100
      formats: float 32-bit LE
      min software latency: 0.00031746 sec
      max software latency: 0.20897959 sec
      current software latency: 0.01160998 sec
    
    
    --------Output Devices--------
    
    Built-in Output (default)
      id: AppleHDAEngineOutput:1B,0,1,1:0
      channel layouts:
        Stereo
      current layout: Stereo
      sample rates:
        44100 - 44100
        48000 - 48000
        88200 - 88200
        96000 - 96000
      current sample rate: 44100
      formats: float 32-bit LE
      min software latency: 0.00031746 sec
      max software latency: 0.41795918 sec
      current software latency: 0.01160998 sec
    
    
    2 devices found
    

    When I run sio_sine, the program runs, but there is no sound generated. Here's the output shown when I try the various keyboard commands:

    $ ./sio_sine 
    Backend: CoreAudio
    Output device: Built-in Output
    'p\n' - pause
    'u\n' - unpause
    'c\n' - clear buffer
    'q\n' - quit
    p
    pausing result: (no error)
    u
    unpausing result: (no error)
    c
    clear buffer result: incompatible backend
    q
    

    I assume I have to configure something, but I don't know what it is.

    bug CoreAudio 
    opened by WarrenWeckesser 17
  • mingw support

    mingw support

    I've started this via: https://github.com/andrewrk/libsoundio/compare/master...tresf:master

    cd libsoundio
    mkdir build out; cd build
    export MINGW_ARCH=32 # defaults to 64
    cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/MingwToolchain.cmake \
    -DCMAKE_INSTALL_PREFIX=../out
    make install
    

    I'm not a C/C++ programmer, so I'm having difficulties with the compilation issues. I'm sure these are all very basic. Help appreciated...

    Scanning dependencies of target libsoundio_shared
    [  3%] Building C object CMakeFiles/libsoundio_shared.dir/src/soundio.c.obj
    [  6%] Building C object CMakeFiles/libsoundio_shared.dir/src/util.c.obj
    [  9%] Building C object CMakeFiles/libsoundio_shared.dir/src/os.c.obj
    [ 12%] Building C object CMakeFiles/libsoundio_shared.dir/src/dummy.c.obj
    [ 15%] Building C object CMakeFiles/libsoundio_shared.dir/src/channel_layout.c.obj
    [ 18%] Building C object CMakeFiles/libsoundio_shared.dir/src/ring_buffer.c.obj
    Linking C shared library libsoundio.dll
    CMakeFiles/libsoundio_shared.dir/objects.a(soundio.c.obj):soundio.c:(.data+0x14): undefined reference to `soundio_wasapi_init'
    collect2: error: ld returned 1 exit status
    make[2]: *** [libsoundio.dll] Error 1
    make[1]: *** [CMakeFiles/libsoundio_shared.dir/all] Error 2
    make: *** [all] Error 2
    
    enhancement 
    opened by tresf 16
  • C99 compatibility

    C99 compatibility

    In the interests of greater compatibility, accommodation of long upgrade cycles, and wider adoption of libsoundio in general, I would like the library to be compatible with a C99 build environment.

    This means addressing src/atomics.h.

    I reviewed issue #48, and I believe the proposal there was not the right approach. It brought in a whole implementation of stdatomic.h adapted from FreeBSD, and not only would have imposed a new maintenance burden on libsoundio, it required either Clang, GCC 4.7+, or some non-standard compiler builtins. And at any rate, it was overkill for what was needed: a C99-friendly implementation of the SOUNDIO_ATOMIC_* macros, no more and no less.

    Here I submit a patch with a first-draft cut of these macros built on POSIX-thread mutexes. This kinda-sorta works on Linux as-is, but there are three issues I'd like to address that will require changes elsewhere:

    1. This should use SoundIoOsMutex instead of pthread_mutex_t, so that it can work outside of POSIX. But that brings us to...

    2. These atomic types need initialization. Straight pthread_mutex_t allows static initialization, and at least on Linux, PTHREAD_MUTEX_INITIALIZER is all zeroes, so starting with zeroed-out memory is enough. But that's not always going to be the case, and of course a SoundIoOsMutex needs to come from soundio_os_mutex_create().

      The initialization, and destruction, can be wrapped up in new macros consistent with the existing ones. Something like

         SOUNDIO_ATOMIC_INIT(rb->write_offset, 0);
         /* ... */
         SOUNDIO_ATOMIC_DESTROY(rb->write_offset);
      
    3. This implementation makes use of GCC-specific statement expressions, as well as typeof(). I found this to be a necessary evil to reproduce the type-agnostic nature of the macros (i.e. the same macro works with a long, int, bool or flag).

      I'd like to suggest redrawing these macros to include the type (so e.g. SOUNDIO_ATOMIC_LOAD() becomes SOUNDIO_ATOMIC_INT_LOAD(), SOUNDIO_ATOMIC_BOOL_LOAD() and so on). This would allow implementing the macros using [static inline] functions, with which compiler compatibility will no longer be an issue.

      (A possible alternative approach is to do an OO-in-C thing, placing function pointers with appropriate argument/return types inside the atomic-type structs, and then the macros expand to a call to the appropriate function pointer. That should allow the macros to remain type-agnostic. But I'd prefer the simpler approach enabled by going with type-specific macros.)

    In addition to all that, I put in some better feature-test logic, since this kind of thing really needs it. (The C++ case would need an external check for the <atomic> header, so it is left commented out for now.) Better to give a clear #error instead of a confusing syntax error.

    opened by iskunk 15
  • Android backend (input and output)

    Android backend (input and output)

    A.K.A. make libsoundio work on all major OSes (does the CoreAudio backend work on iOS?) A.K.A. better than SDL A.K.A. 500 lines and some hard work gets you surprisingly far A.K.A. The Cubs are still going to win the World Series, I just know it

    Couple points:

    • Android has a special audio state it calls the "fast track," which skips software mixing and ties to reduce latency as much as possible. The keys to this are matching the device's natural sample rate and buffer size.

      Unfortunately, there's no officially supported way to get this information outside of a JVM running inside an Android Activity. There are varying degrees of hacks around this, but they could be disappeared anytime or, worse, crash the entire process (ex. calling JNI_GetCreatedJavaVMs on Android without a pre-existing JVM raises an assertion error, so you can't easily opportunistically attach to a JVM. Even if you did get around it, there's still no officially supported way to get an Activity handle from the global context.)

      In an ideal world, the backend would default to the fastest sample rate and a proper multiple of buffer size. Failing that, sample rate can be set manually and buffer size can be requested proportional to latency and sample rate.

    • I only implemented support for output devices. If that's a deal-breaker, I can go read-up on how input devices work on Android. They have some quirks that make them different from output devices and might possibly need JVM access (with the problems inherent in that, as described above).

    • This backend does not support calling soundio_outstream_begin_write/soundio_outstream_end_write multiple times in a single write callback. This part of the libsoundio API has always seemed weird to me, and it doesn't map well onto OpenSL ES. If you do call the functions more than once, you'll get an error because the backend buffers are full.

    • No underflow callbacks. I couldn't figure this one out. There's an interface called SLPrefetchStatusItf that looks like it could be handy here, but in local testing it only raised events when a write callback was not in the process of being called, which made it pretty much useless (since by the time the callback ends, the underflow state has been "fixed"). It also seems to randomly cause assertion errors when used with Android's buffer queue implementation, and nobody on the Internet knows why.

      I thought about implementing an additional thread to intercept write callbacks from OpenSL ES, but then you'd lose out on the special thread priority that audio callbacks get and it complicates the code.

    • Requires API level 21 / Android 5.0 Lollipop or greater. The main feature this brings is floating-point support. The rest of the codebase doesn't work with API levels lower than that anyways.

    • Android doesn't have a /tmp folder, but it does follow the POSIX convention of pointing the TMPDIR environment variable to an appropriate location. I just added this location to os.c for the sake of simplicity, though ideally it would read the right environment variables.

    • Testing this out is a little hairy depending on your system, but something like this plopped in at the top of CMakeLists.txt (before project(...)) did the trick for me:

    set(BUILD_DYNAMIC_LIBS OFF CACHE BOOL "" FORCE) set(CMAKE_SYSROOT /usr/local/Cellar/android-ndk/r13/platforms/android-24/arch-arm) set(CMAKE_C_COMPILER /usr/local/Cellar/android-ndk/r13/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")

    
       Follow that up with a
    
       ```bash
    adb push sio_sine /data/local/tmp && adb shell /data/local/tmp/sio_sine
    

    and you'll hear the sweet dulcet tones of a sine wave coming from your device's speakers.

    • Overall, the libsoundio API was a pleasure to work with! It's verbose in many places, but I never ran into any problems mapping OpenSL ES onto the abstraction model or figuring out where things belonged.

    • I took a look at the v2 branch, I think the only change that affect this is the int to enum SoundIoError change in function prototypes.

    EDIT: Added support for input devices.

    • Supposedly, not all devices support all sample rates. However, on my LG G4 all sample rates seem to be supported. I'm not sure what will happen if you try to open a device with an unsupported sample rate. Anecdotal evidence on the internet says sometimes it immediately fails and sometimes it just returns corrupted audio.

    • Is it useful to know if a device is currently unavailable due to permissions problems? I'm leaning towards yes, though it's not straightforward to figure out from the backend. On my device, the error code for lacking permissions was SL_RESULT_CONTENT_UNSUPPORTED, but according to the spec it should probably be SL_RESULT_PERMISSION_DENIED.

    • Android lets you make requests for different recording profiles: GENERIC, CAMCORDER, VOICE_COMMUNICATION, and VOICE_RECOGNITION. The camcorder request could be exposed as a separate device (and probably should, though it's not guaranteed to actually be different), but what about the VOICE_* options? They might be too high-level for this project, and more appropriate for an effects layer.

    • Recording floating-point data is supported starting in API level 23 / Android 6.0 Marshmallow. I put a check into the backend init function to try opening a device in that format, which seems to work (tested on an emulator running API level 21).

    • Recording is much more difficult to test, because command-line processes don't have permissions to access input devices. To try this out I ended up creating a NativeActivity with copy-pasted code from sio_record. This worked on my real device, but not on the emulator because I couldn't figure out where I had permission to write files. Should there be a small sample app for testing (probably similar to sio_microphone), or is that too complicated?

    opened by ligfx 13
  • Use symbol versioning

    Use symbol versioning

    If libsoundio is to become a widely used library, it would be great if symbol versioning was provided. Symbol versioning is a more fine grained version of allowing multiple (ABI-incompatible) libraries to coexist in the same system.

    Under the current scheme, you have libsoundio.so.1. If an ABI-breaking change needed to be made, then libsoundio.so.2 would be able to exist side by side with libsoundio.so.1. However, there is still potential for trouble:

    1. App foo is compiled against version 2.
    2. foo loads a plugin bar, which is linked to version 1.
    3. Errors occur as the linker somehow determines it needs to use only one version of the library for any given symbol that exists in both libraries, but it can only choose one.

    Using a version script tags each function with a trailing string (arbitrary). If a version 2 is released that changes that string, then the runtime linker can use that trailing string to disambiguate between the versions, and so both libraries can coexist in the same process. The version can be inspected via objdump -T $library. You can check eg libpulse has all functions tagged with PULSE_0

    Symbol versioning can also be used to avoid bumping the version even while making ABI-breaking changes. This is a more advanced usage that is overkill in many cases, but is eg used by glibc (check out objdump -T /lib/x86_64-linux-gnu/libc.so.6|grep strtod on a debian system).

    The basic usage is fairly simple. All that is needed is that a list of all the exported symbols be listed in a file that then is passed to the linker via the -Wl,--version-script=$file flag:

    LIBSOUNDIO_1 {
    global:
        soundio_backend_count;
        soundio_backend_name;
        soundio_best_matching_channel_layout;
        soundio_channel_layout_builtin_count;
        soundio_channel_layout_detect_builtin;
        soundio_channel_layout_equal;
        soundio_channel_layout_find_channel;
        soundio_channel_layout_get_builtin;
        soundio_channel_layout_get_default;
        soundio_connect;
        soundio_connect_backend;
        soundio_create;
        soundio_default_input_device_index;
        soundio_default_output_device_index;
        soundio_destroy;
        soundio_device_equal;
        soundio_device_nearest_sample_rate;
        soundio_device_ref;
        soundio_device_sort_channel_layouts;
        soundio_device_supports_format;
        soundio_device_supports_layout;
        soundio_device_supports_sample_rate;
        soundio_device_unref;
        soundio_disconnect;
        soundio_flush_events;
        soundio_force_device_scan;
        soundio_format_string;
        soundio_get_backend;
        soundio_get_bytes_per_sample;
        soundio_get_channel_name;
        soundio_get_input_device;
        soundio_get_output_device;
        soundio_have_backend;
        soundio_input_device_count;
        soundio_instream_begin_read;
        soundio_instream_create;
        soundio_instream_destroy;
        soundio_instream_end_read;
        soundio_instream_get_latency;
        soundio_instream_open;
        soundio_instream_pause;
        soundio_instream_start;
        soundio_output_device_count;
        soundio_outstream_begin_write;
        soundio_outstream_clear_buffer;
        soundio_outstream_create;
        soundio_outstream_destroy;
        soundio_outstream_end_write;
        soundio_outstream_get_latency;
        soundio_outstream_open;
        soundio_outstream_pause;
        soundio_outstream_start;
        soundio_parse_channel_id;
        soundio_ring_buffer_advance_read_ptr;
        soundio_ring_buffer_advance_write_ptr;
        soundio_ring_buffer_capacity;
        soundio_ring_buffer_clear;
        soundio_ring_buffer_create;
        soundio_ring_buffer_destroy;
        soundio_ring_buffer_fill_count;
        soundio_ring_buffer_free_count;
        soundio_ring_buffer_read_ptr;
        soundio_ring_buffer_write_ptr;
        soundio_sort_channel_layouts;
        soundio_strerror;
        soundio_wait_events;
        soundio_wakeup;
    local: *;
    };
    

    Then, if a change is made that requires bumping SONAME, all you need to do is change the version script to LIBSOUNDIO_2.

    More information in the ld manual

    enhancement 
    opened by fsateler 13
  • Compatibility with older ALSA

    Compatibility with older ALSA

    Hi,

    Older ALSA (Ubuntu 10) does not have support for channel mapping. Could we have an #ifdef for that? A runtime check would be even better if at all possible.

    Thanks.

    enhancement wontfix ALSA 
    opened by capr 12
  • Always false on CFStringGetCString on MacOS

    Always false on CFStringGetCString on MacOS

    it seems always return a error here:

    (System is MacOS, Mac OS X 10.12.5)

    coreaudio.c

    // Possible errors:
    //  * SoundIoErrorNoMem
    //  * SoundIoErrorEncodingString
    static int from_cf_string(CFStringRef string_ref, char **out_str, int *out_str_len) {
        assert(string_ref);
        CFIndex length = CFStringGetLength(string_ref);
        CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
        char *buf = ALLOCATE_NONZERO(char, max_size);
        if (!buf)
            return SoundIoErrorNoMem;
    //    comment it then the demo of list devices works well other wise always return SoundIoErrorEncodingString error
    //    if (!CFStringGetCString(string_ref, buf, max_size, kCFStringEncodingUTF8)) {
    //        free(buf);
    //        return SoundIoErrorEncodingString;
    //    }
     
        *out_str = buf; 
        *out_str_len = strlen(buf);
        return 0;
    }
    
    opened by qiukeren 11
  • Support older versions of GCC

    Support older versions of GCC

    libsoundio-older-gcc.patch.txt

    This patch against the Git v2 branch contains the following:

    • New implementation of SOUNDIO_ATOMIC_* based on GCC's __sync_*() builtins
    • Better feature-macro test logic in atomics.h to select the appropriate implementation of SOUNDIO_ATOMIC_*
    • CMake logic to determine support for -std=c11, as well as some warning flags that older GCC versions don't know about
    let's talk about this over a pull request 
    opened by iskunk 10
  • Build recommendations for portability on linux

    Build recommendations for portability on linux

    This is not really an issue, but as there is no mention of it in the docs ...

    When building against the three available linux backends (alsa, pulseaudio and jack), the binaries have de facto a dependency to these libraries.

    I'm about to try to build them statically to avoid package dependencies and/or different builds for every linux distribution flavor. But would you recommend it ?

    I could also try to dlopen those, which would have the benefit of using the packaged version, but at the risk of a mismatch of ABIs.

    Also, what are you planning to do for your other project Genesis ?

    question 
    opened by hotgloupi 10
  • Build obstacle on debian stable

    Build obstacle on debian stable

    Here, I will describe a build problem that happens when I try to compile libsoundio under a debian stable environment.

    = Background

    Here's my system: memlab$ uname -a Linux memlab 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux memlab$ apt-cache show clang | grep Version Version: 1:3.5-25 memlab$

    I downloaded libsoundio-1.1.0.tar.gz and unpacked it.

    = Cmake steps

    $ cd libsoundio-1.1.0; mkdir build; cd build; cmake .. -- The C compiler identification is Clang 3.5.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done Configuring libsoundio version 1.1.0 -- Looking for include file pthread.h -- Looking for include file pthread.h - found -- Looking for pthread_create -- Looking for pthread_create - not found -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for pthread_create in pthread - found -- Found Threads: TRUE
    -- Found JACK: /usr/lib/x86_64-linux-gnu/libjack.so
    -- Found PULSEAUDIO: /usr/lib/x86_64-linux-gnu/libpulse.so
    -- Found ALSA: /usr/lib/x86_64-linux-gnu/libasound.so (found version "1.0.28") -- Could NOT find COREAUDIO (missing: COREAUDIO_LIBRARY COREAUDIO_INCLUDE_DIR) -- Could NOT find WASAPI (missing: WASAPI_INCLUDE_DIR)

    Installation Summary

    • Install Directory : /usr/local
    • Build Type : Debug
    • Build static libs : ON
    • Build examples : ON
    • Build tests : ON

    System Dependencies

    • threads : OK
    • JACK (optional) : OK
    • PulseAudio (optional) : OK
    • ALSA (optional) : OK
    • CoreAudio (optional) : not found
    • WASAPI (optional) : not found

    -- Configuring done -- Generating done -- Build files have been written to: /home/cturner/saga/20160304.memlab.cturner.ad.libsoundio/000.poc/libsoundio-1.1.0/build $

    = Make

    memlab$ make Scanning dependencies of target libsoundio_shared [ 2%] Building C object CMakeFiles/libsoundio_shared.dir/src/soundio.c.o /home/cturner/saga/20160304.memlab.cturner.ad.libsoundio/000.poc/libsoundio-1.1.0/src/soundio.c:180:47: error: illegal initializer type 'atomic_flag' (aka '_Atomic(struct (anonymous struct at /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/include/stdatomic.h:232:17))') static struct SoundIoAtomicFlag rtprio_seen = SOUNDIO_ATOMIC_FLAG_INIT; ^ /home/cturner/saga/20160304.memlab.cturner.ad.libsoundio/000.poc/libsoundio-1.1.0/src/atomics.h:68:35: note: expanded from macro 'SOUNDIO_ATOMIC_FLAG_INIT'

    define SOUNDIO_ATOMIC_FLAG_INIT {ATOMIC_FLAG_INIT}

                                  ^
    

    /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/include/stdatomic.h:241:26: note: expanded from macro 'ATOMIC_FLAG_INIT'

    define ATOMIC_FLAG_INIT { 0 }

                                ^
    

    1 error generated. CMakeFiles/libsoundio_shared.dir/build.make:54: recipe for target 'CMakeFiles/libsoundio_shared.dir/src/soundio.c.o' failed make[2]: *** [CMakeFiles/libsoundio_shared.dir/src/soundio.c.o] Error 1 CMakeFiles/Makefile2:192: recipe for target 'CMakeFiles/libsoundio_shared.dir/all' failed make[1]: *** [CMakeFiles/libsoundio_shared.dir/all] Error 2 Makefile:117: recipe for target 'all' failed make: *** [all] Error 2 memlab$

    = Notes

    I'd be happy to be a part of the solution for this, but I'm not particularly skilled with compiler tool-chains and would benefit from guidance.

    Shortly after building this, I also tried to build zig language. Zig failed because debian stable is running an older version of LLVM than is required by zig.

    This makes me think - an approach to fixing this might be for me to create a compiler toolchain in isolation. For example, a barebones linux under qemu, and then install tools from source towards being able to build this. I could put some towards this, but - again - would appreciate guidance on what to focus on.

    bug 
    opened by cratuki 9
  • Add vcpkg installation instructions

    Add vcpkg installation instructions

    libsoundio is available as a port in vcpkg, a C++ library manager that simplifies installation for libsoundio and other project dependencies. Documenting the install process here will help users get started by providing a single set of commands to build libsoundio, ready to be included in their projects.

    We also test whether our library ports build in various configurations (dynamic, static) on various platforms (OSX, Linux, Windows: x86, x64) to keep a wide coverage for users.

    I'm a maintainer for vcpkg, and here is what the port script looks like. We try to keep the library maintained as close as possible to the original library. :)

    opened by JonLiu1993 0
  • MinGW build broke

    MinGW build broke

    This is up to date arch linux with mingw-w64-binutils 2.38-3, mingw-w64-cmake 1-39, mingw-w64-configure 0.1.1-1,1mingw-w64-crt 10.0.0-1, mingw-w64-environment 1-4, mingw-w64-gcc 12.1.0-1, mingw-w64-headers 10.0.0-1

    2.0.0 and b810bf2e9c4afc822c4843322cd08f7b36668109 compile without issues. Current 8ab36069123a8b38e247ace55f8a6b3e6ee14f5f fails due to error: redefinition of ‘IID_IMMDeviceEnumerator’ and others which could be fixed by defining __IMMDeviceEnumerator_INTERFACE_DEFINED__, __ISimpleAudioVolume_INTERFACE_DEFINED__, __MMDeviceAPILib_LIBRARY_DEFINED__ etc:

    full compile output
    $ x86_64-w64-mingw32-cmake -D BUILD_TESTS=OFF -D BUILD_STATIC_LIBS=ON -D ENABLE_JACK=OFF .. && make
    CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
      Compatibility with CMake < 2.8.12 will be removed from a future version of
      CMake.
    
      Update the VERSION argument <min> value or use a ...<max> suffix to tell
      CMake that the project does not need compatibility with older versions.
    
    
    -- The C compiler identification is GNU 12.1.0
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc - skipped
    -- Detecting C compile features
    -- Detecting C compile features - done
    Configuring libsoundio version 2.0.0
    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD
    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
    -- Found Threads: TRUE
    CMake Warning (dev) at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
      The package name passed to `find_package_handle_standard_args` (PULSEAUDIO)
      does not match the name of the calling package (PulseAudio).  This can lead
      to problems in calling code that expects `find_package` result variables
      (e.g., `_FOUND`) to follow a certain pattern.
    Call Stack (most recent call first):
      cmake/FindPulseAudio.cmake:14 (find_package_handle_standard_args)
      CMakeLists.txt:65 (find_package)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Could NOT find PULSEAUDIO (missing: PULSEAUDIO_LIBRARY PULSEAUDIO_INCLUDE_DIR)
    -- Could NOT find ALSA (missing: ALSA_LIBRARY ALSA_INCLUDE_DIR)
    CMake Warning (dev) at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
      The package name passed to `find_package_handle_standard_args` (COREAUDIO)
      does not match the name of the calling package (CoreAudio).  This can lead
      to problems in calling code that expects `find_package` result variables
      (e.g., `_FOUND`) to follow a certain pattern.
    Call Stack (most recent call first):
      cmake/FindCoreAudio.cmake:14 (find_package_handle_standard_args)
      CMakeLists.txt:99 (find_package)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Could NOT find COREAUDIO (missing: COREAUDIO_LIBRARY COREAUDIO_INCLUDE_DIR)
    -- Looking for audioclient.h
    -- Looking for audioclient.h - found
    -- Found WASAPI: 1
    
    Installation Summary
    --------------------
    * Install Directory            : /usr/x86_64-w64-mingw32
    * Build Type                   : Debug
    * Build static libs            : ON
    * Build examples               : ON
    * Build tests                  : OFF
    
    System Dependencies
    -------------------
    * threads                      : OK
    * JACK       (optional)        : disabled
    * PulseAudio (optional)        : not found
    * ALSA       (optional)        : not found
    * CoreAudio  (optional)        : not found
    * WASAPI     (optional)        : OK
    
    -- Configuring done
    -- Generating done
    CMake Warning:
      Manually-specified variables were not used by the project:
    
        CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
    
    
    -- Build files have been written to: /tmp/lsio0/libsoundio/build
    [  4%] Building C object CMakeFiles/libsoundio_shared.dir/src/soundio.c.obj
    [  8%] Building C object CMakeFiles/libsoundio_shared.dir/src/util.c.obj
    [ 12%] Building C object CMakeFiles/libsoundio_shared.dir/src/os.c.obj
    [ 16%] Building C object CMakeFiles/libsoundio_shared.dir/src/dummy.c.obj
    [ 20%] Building C object CMakeFiles/libsoundio_shared.dir/src/channel_layout.c.obj
    [ 25%] Building C object CMakeFiles/libsoundio_shared.dir/src/ring_buffer.c.obj
    [ 29%] Building C object CMakeFiles/libsoundio_shared.dir/src/wasapi.c.obj
    /tmp/lsio0/libsoundio/src/wasapi.c:34:20: error: redefinition of ‘CLSID_MMDeviceEnumerator’
       34 | static const CLSID CLSID_MMDeviceEnumerator = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~~
    In file included from /usr/x86_64-w64-mingw32/include/combaseapi.h:156,
                     from /usr/x86_64-w64-mingw32/include/objbase.h:14,
                     from /usr/x86_64-w64-mingw32/include/ole2.h:17,
                     from /usr/x86_64-w64-mingw32/include/audioclient.h:13,
                     from /tmp/lsio0/libsoundio/src/wasapi.c:17:
    /usr/x86_64-w64-mingw32/include/mmdeviceapi.h:965:1: note: previous definition of ‘CLSID_MMDeviceEnumerator’ with type ‘GUID’
      965 | DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:37:20: error: redefinition of ‘IID_IMMDeviceEnumerator’
       37 | static const IID   IID_IMMDeviceEnumerator   = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/mmdeviceapi.h:582:1: note: previous definition of ‘IID_IMMDeviceEnumerator’ with type ‘GUID’
      582 | DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:41:20: error: redefinition of ‘IID_IMMNotificationClient’
       41 | static const IID   IID_IMMNotificationClient = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/mmdeviceapi.h:168:1: note: previous definition of ‘IID_IMMNotificationClient’ with type ‘GUID’
      168 | DEFINE_GUID(IID_IMMNotificationClient, 0x7991eec9, 0x7e89, 0x4d85, 0x83,0x90, 0x6c,0x70,0x3c,0xec,0x60,0xc0);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:45:20: error: redefinition of ‘IID_IAudioClient’
       45 | static const IID   IID_IAudioClient = {
          |                    ^~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audioclient.h:201:1: note: previous definition of ‘IID_IAudioClient’ with type ‘GUID’
      201 | DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:49:20: error: redefinition of ‘IID_IAudioRenderClient’
       49 | static const IID   IID_IAudioRenderClient    = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audioclient.h:879:1: note: previous definition of ‘IID_IAudioRenderClient’ with type ‘GUID’
      879 | DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:53:20: error: redefinition of ‘IID_IAudioSessionControl’
       53 | static const IID   IID_IAudioSessionControl  = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audiopolicy.h:276:1: note: previous definition of ‘IID_IAudioSessionControl’ with type ‘GUID’
      276 | DEFINE_GUID(IID_IAudioSessionControl, 0xf4b1a599, 0x7266, 0x4319, 0xa8,0xca, 0xe7,0x0a,0xcb,0x11,0xe8,0xcd);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:57:20: error: redefinition of ‘IID_IAudioSessionEvents’
       57 | static const IID   IID_IAudioSessionEvents   = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audiopolicy.h:116:1: note: previous definition of ‘IID_IAudioSessionEvents’ with type ‘GUID’
      116 | DEFINE_GUID(IID_IAudioSessionEvents, 0x24918acc, 0x64b3, 0x37c1, 0x8c,0xa9, 0x74,0xa6,0x6e,0x99,0x57,0xa8);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:61:18: error: redefinition of ‘IID_IMMEndpoint’
       61 | static const IID IID_IMMEndpoint = {
          |                  ^~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/mmdeviceapi.h:505:1: note: previous definition of ‘IID_IMMEndpoint’ with type ‘GUID’
      505 | DEFINE_GUID(IID_IMMEndpoint, 0x1be09788, 0x6894, 0x4089, 0x85,0x86, 0x9a,0x2a,0x6c,0x26,0x5a,0xc5);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:65:18: error: redefinition of ‘IID_IAudioClockAdjustment’
       65 | static const IID IID_IAudioClockAdjustment = {
          |                  ^~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audioclient.h:1266:1: note: previous definition of ‘IID_IAudioClockAdjustment’ with type ‘GUID’
     1266 | DEFINE_GUID(IID_IAudioClockAdjustment, 0xf6e4c0a0, 0x46d9, 0x4fb8, 0xbe,0x21, 0x57,0xa3,0xef,0x2b,0x62,0x6c);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:69:18: error: redefinition of ‘IID_IAudioCaptureClient’
       69 | static const IID IID_IAudioCaptureClient = {
          |                  ^~~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audioclient.h:972:1: note: previous definition of ‘IID_IAudioCaptureClient’ with type ‘GUID’
      972 | DEFINE_GUID(IID_IAudioCaptureClient, 0xc8adbd64, 0xe71e, 0x48a0, 0xa4,0xde, 0x18,0x5c,0x39,0x5c,0xd3,0x17);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:73:18: error: redefinition of ‘IID_ISimpleAudioVolume’
       73 | static const IID IID_ISimpleAudioVolume = {
          |                  ^~~~~~~~~~~~~~~~~~~~~~
    /usr/x86_64-w64-mingw32/include/audioclient.h:1346:1: note: previous definition of ‘IID_ISimpleAudioVolume’ with type ‘GUID’
     1346 | DEFINE_GUID(IID_ISimpleAudioVolume, 0x87ce5498, 0x68d6, 0x44e5, 0x92,0x15, 0x6d,0xa4,0x7e,0xf8,0x83,0xd8);
          | ^~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c: In function ‘deinit_refresh_devices’:
    /tmp/lsio0/libsoundio/src/wasapi.c:489:5: error: this ‘if’ clause does not guard... [-Werror=misleading-indentation]
      489 |     if (rd->mm_device)
          |     ^~
    /tmp/lsio0/libsoundio/src/wasapi.c:491:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
      491 |         if (rd->default_render_device)
          |         ^~
    /tmp/lsio0/libsoundio/src/wasapi.c: At top level:
    /tmp/lsio0/libsoundio/src/wasapi.c:65:18: error: ‘IID_IAudioClockAdjustment’ defined but not used [-Werror=unused-const-variable=]
       65 | static const IID IID_IAudioClockAdjustment = {
          |                  ^~~~~~~~~~~~~~~~~~~~~~~~~
    /tmp/lsio0/libsoundio/src/wasapi.c:57:20: error: ‘IID_IAudioSessionEvents’ defined but not used [-Werror=unused-const-variable=]
       57 | static const IID   IID_IAudioSessionEvents   = {
          |                    ^~~~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    make[2]: *** [CMakeFiles/libsoundio_shared.dir/build.make:167: CMakeFiles/libsoundio_shared.dir/src/wasapi.c.obj] Error 1
    make[1]: *** [CMakeFiles/Makefile2:94: CMakeFiles/libsoundio_shared.dir/all] Error 2
    make: *** [Makefile:136: all] Error 2
    

    a46b0f21c397cd095319f8c9feccf0f1e50e31ba fails due to -Werror=misleading-indentation which should be fixed by indenting properly in src/wasapi.c:

    full compile output ``` $ x86_64-w64-mingw32-cmake -D BUILD_TESTS=OFF -D BUILD_STATIC_LIBS=ON -D ENABLE_JACK=OFF .. && make CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 2.8.12 will be removed from a future version of CMake.

    Update the VERSION argument value or use a ... suffix to tell CMake that the project does not need compatibility with older versions.

    Configuring libsoundio version 2.0.0 CMake Warning (dev) at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message): The package name passed to find_package_handle_standard_args (PULSEAUDIO) does not match the name of the calling package (PulseAudio). This can lead to problems in calling code that expects find_package result variables (e.g., _FOUND) to follow a certain pattern. Call Stack (most recent call first): cmake/FindPulseAudio.cmake:14 (find_package_handle_standard_args) CMakeLists.txt:65 (find_package) This warning is for project developers. Use -Wno-dev to suppress it.

    -- Could NOT find PULSEAUDIO (missing: PULSEAUDIO_LIBRARY PULSEAUDIO_INCLUDE_DIR) -- Could NOT find ALSA (missing: ALSA_LIBRARY ALSA_INCLUDE_DIR) CMake Warning (dev) at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message): The package name passed to find_package_handle_standard_args (COREAUDIO) does not match the name of the calling package (CoreAudio). This can lead to problems in calling code that expects find_package result variables (e.g., _FOUND) to follow a certain pattern. Call Stack (most recent call first): cmake/FindCoreAudio.cmake:14 (find_package_handle_standard_args) CMakeLists.txt:99 (find_package) This warning is for project developers. Use -Wno-dev to suppress it.

    -- Could NOT find COREAUDIO (missing: COREAUDIO_LIBRARY COREAUDIO_INCLUDE_DIR)

    Installation Summary

    • Install Directory : /usr/x86_64-w64-mingw32
    • Build Type : Debug
    • Build static libs : ON
    • Build examples : ON
    • Build tests : OFF

    System Dependencies

    • threads : OK
    • JACK (optional) : disabled
    • PulseAudio (optional) : not found
    • ALSA (optional) : not found
    • CoreAudio (optional) : not found
    • WASAPI (optional) : OK

    -- Configuring done -- Generating done -- Build files have been written to: /tmp/lsio0/libsoundio/build Consolidate compiler generated dependencies of target libsoundio_shared [ 4%] Building C object CMakeFiles/libsoundio_shared.dir/src/wasapi.c.obj /tmp/lsio0/libsoundio/src/wasapi.c: In function ‘deinit_refresh_devices’: /tmp/lsio0/libsoundio/src/wasapi.c:487:5: error: this ‘if’ clause does not guard... [-Werror=misleading-indentation] 487 | if (rd->mm_device) | ^~ /tmp/lsio0/libsoundio/src/wasapi.c:489:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’ 489 | if (rd->default_render_device) | ^~ cc1: all warnings being treated as errors make[2]: *** [CMakeFiles/libsoundio_shared.dir/build.make:167: CMakeFiles/libsoundio_shared.dir/src/wasapi.c.obj] Error 1 make[1]: *** [CMakeFiles/Makefile2:94: CMakeFiles/libsoundio_shared.dir/all] Error 2 make: *** [Makefile:136: all] Error 2

    </details>
    opened by krumelmonster 0
  • layout name can be null

    layout name can be null

    If a layout is not in builtin_channel_layouts, the corresponding char* SoundIoDevice::name will be NULL which should either be documented here: https://github.com/andrewrk/libsoundio/blob/8ab36069123a8b38e247ace55f8a6b3e6ee14f5f/soundio/soundio.h#L307 or changed to a generic name like "unknown layout" here: https://github.com/andrewrk/libsoundio/blob/8ab36069123a8b38e247ace55f8a6b3e6ee14f5f/src/channel_layout.c#L435

    opened by krumelmonster 0
  • Jack: unable to open device

    Jack: unable to open device

    When using the sio_sine example while running Jack I get:

    Output device: system: playback_1, playback_2, playback_3, playback_4, playback_5, playback_6, playback_7, playback_8, playback_9, playback_10, playback_11, playback_12, playback_13, playback_14, playback_15, playback_16, playback_17, playback_18 unable to open device: unable to open device%

    Looking at the messages in Qjackctl I get the following error:

    port_name "SoundIoOutStream:(Invalid Channel)" already exists

    running the sio_list_devices, I get a lot of (Invalid Channel) messages in the channel layouts section.

    Interestingly enough, I can run and use the official jack example code without a problem. The sio_sine example also runs perfectly fine on my laptop with the exact same setup. (arch linux with jack using a RME FirefaceUCX)

    When switching my backend to pulse audio all of that works perfectly fine.

    Thanks in advance!

    opened by dycide 0
  • Always use WASAPI's callback mode

    Always use WASAPI's callback mode

    TLDR

    This PR modifies the WASAPI backend to use event based callbacks, fixing a problem where small buffers would unnecessarily underflow due to issues with how Windows handles timer resolution.

    Full Explanation

    Presently, the WASAPI backend when running in shared mode defaults to a 4 second buffer, and uses a sleep condition variable to time the write call back, the intention being that you don't have to use the whole buffer.

    Unfortunately, if you only use ~23-40ms of the buffer, you'll get underflows because sleep condition variables are subject to Windows' timer interval. If you use timeBeginPeriod to lower the interval, or if someone else has already lowered it (it's kind of global ish maybe), the problem goes away. WASAPI appears to lower the interval itself automatically, but not enough, even when modifying libsoundio to request a smaller buffer. To check the current timer interval, see ClockRes.

    This PR solves this problem by modifying the WASAPI backend to use AUDCLNT_STREAMFLAGS_EVENTCALLBACK mode. The code changes are minimal since this mode was already used for raw devices. In this mode, WaitForSingleObject is used to time the callbacks instead of SleepConditionVariableCS. I'm under the impression that WaitForSingleObject doesn't rely on the timer period unless it times out, but regardless, WASAPI does a better job of setting the timer period low enough for you in this mode.

    With these changes, I experience no underflows at the lowest interval Windows is willing to give me (23.49ms.)

    WIP

    Clearing The Buffer

    "On systems that support clearing the buffer, this defaults to a large latency, potentially upwards of 2 seconds, with the understanding that you will call soundio_outstream_clear_buffer when you want to reduce the latency to 0."

    libsoundio docs

    There's nothing stopping me from continuing to support clearing the outstream in shared mode, and adding support for clearing it in exclusive mode, despite neither defaulting to a large buffer size with these changes.

    I could add support for this, and modify the docs accordingly, or I could remove support and leave the docs alone.

    It's not clear to me which is better because I don't understand the reason for defaulting to a large buffer on some backends to begin with--is there a use case where it's beneficial to give the user a significantly larger buffer than they asked for?

    If you want, we can punt on this--I can do the safe thing by implementing this according to the current docs, and then we can revisit this later, I'm planning on suggesting a change to this API anyway and can bring it up again then.

    Min Frame Counts

    I left the min frame count calculation alone. I noticed that for exclusive mode, the min frame count and max frame count are the same--I'm not sure if I should do the same thing here. Presumably there's no reason to not fill the entire buffer with this change in place?

    opened by MasonRemaley 0
Owner
Andrew Kelley
Lead developer & president of Zig Software Foundation
Andrew Kelley
PortAudio is a portable audio I/O library designed for cross-platform support of audio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.

PortAudio 704 Sep 15, 2022
Libsio - A runtime library for Speech Input (stt) & Output (tts)

libsio A runtime library for Speech Input (stt) & Output (tts) Speech To Text unified CTC and WFST decoding via beam search online(streaming) decoding

null 23 Sep 6, 2022
Input-overlay - Show keyboard, gamepad and mouse input on stream

Show keyboard, mouse and gamepad input on stream. Available for OBS Studio 19.0.3+ on windows (32bit/64bit) and linux (64bit). Head over to releases f

Alex 1.3k Sep 22, 2022
PyFLAC - Real-time lossless audio compression in Python

A simple Pythonic interface for libFLAC. FLAC stands for Free Lossless Audio Codec, an audio format similar to MP3, but lossless, meaning that audio i

Sonos, Inc. 92 Aug 4, 2022
A command line and keyboard based strategy-game written in c++, where audio-input determines the AI-strategy and lays the seed for the map-generation.

Table of contents Dissonance Premise Installation Requirements Installation Quick-guide Detailed installation guide Usage Logfiles Tests Uninstall Kno

fux 24 Sep 19, 2022
Cross platform C++11 library for decoding audio (mp3, wav, ogg, opus, flac, etc)

Libnyquist is a small C++11 library for reading sampled audio data from disk or memory. It is intended to be used an audio loading frontend for games, audio sequencers, music players, and more.

Dimitri Diakopoulos 414 Sep 26, 2022
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework for creating high quality desktop and mobile applications, including VST, VST3, AU, AU

JUCE 4.5k Sep 17, 2022
Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux

Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux and other operating systems and is developed by a group of volunteers as open source software.

null 7.2k Sep 20, 2022
C++ audio time-stretching implementation

Time Stretcher C++ audio time-stretching implementation, based on the algorithms presented in: Audio Time Stretching with an Adaptive Phase Vocoder, N

null 47 Sep 22, 2022
By controlling the frequency at which the output Pins of MSP430 are turned off and on, we can make music.

By controlling the frequency at which the output Pins of MSP430 are turned off and on, we can make music.

Premkumar Vincent 1 Nov 9, 2021
PendulumSynth is an on-going and open-source project, running on Arduino platform with the goal of mixing real-world physics into music composition and musical performance.

PendulumSynth PendulumSynth is an on-going and open-source project, running on Arduino platform with the goal of mixing real-world physics into music

Mohammadreza Anvari 4 Jun 19, 2022
Cross-platform silk codec wrap library depends on ploverlake/silk.

libSilkCodec Cross-platform silk codec wrap library depends on ploverlake/silk. Clone & Build Linux/Unix like # clone $ git clone https://github.c

KonataDev 8 Sep 9, 2022
🎵 A cross-platform media playback library for C/C++ with good number of features (only Windows & Linux).

libwinmedia A cross-platform media playback library for C/C++ & Flutter with good number of features. Example A very simple example can be as follows.

Harmonoid 37 Sep 5, 2022
projectM - cross-platform music visualization. Open-source and Milkdrop-compatible

projectM - cross-platform music visualization. Open-source and Milkdrop-compatible

projectM Visualizer 2.3k Sep 16, 2022
A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene.

TDAW A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene. This header enables

kbx 12 Sep 17, 2022
C++ library for audio and music analysis, description and synthesis, including Python bindings

Essentia Essentia is an open-source C++ library for audio analysis and audio-based music information retrieval released under the Affero GPL license.

Music Technology Group - Universitat Pompeu Fabra 2.2k Sep 20, 2022
A simple C++ library for reading and writing audio files.

AudioFile A simple header-only C++ library for reading and writing audio files. Current supported formats: WAV AIFF Author AudioFile is written and ma

Adam Stark 644 Sep 16, 2022
A C library for reading and writing sound files containing sampled audio data.

libsndfile libsndfile is a C library for reading and writing files containing sampled audio data. Authors The libsndfile project was originally develo

null 1k Sep 15, 2022
C++ Audio and Music DSP Library

_____ _____ ___ __ _ _____ __ __ __ ____ ____ / \\_ \\ \/ / |/ \| | | | \_ \/ \ | Y Y \/ /_ \> <| | Y Y \ | |_|

Mick Grierson 1.3k Sep 24, 2022