libsoundio-sys 0.2.0

Native bindings to the libsoundio library
Documentation
#![allow(dead_code)]

extern crate libc;

use std::os::raw::{c_char, c_void, c_int, c_double};

// There is no c_bool, but you can use Rust's i8 or bool instead.
// See https://github.com/rust-lang/rfcs/pull/954#issuecomment-169820630
#[allow(non_camel_case_types)]
type c_bool = i8;

/** \mainpage
 *
 * \section intro_sec Overview
 *
 * libsoundio is a C library for cross-platform audio input and output. It is
 * suitable for real-time and consumer software.
 *
 * Documentation: soundio.h
 */


/** \example sio_list_devices.c
 * List the available input and output devices on the system and their
 * properties. Supports watching for changes and specifying backend to use.
 */

/** \example sio_sine.c
 * Play a sine wave over the default output device.
 * Supports specifying device and backend to use.
 */

/** \example sio_record.c
 * Record audio to an output file.
 * Supports specifying device and backend to use.
 */

/** \example sio_microphone.c
 * Stream the default input device over the default output device.
 * Supports specifying device and backend to use.
 */

/** \example backend_disconnect_recover.c
 * Demonstrates recovering from a backend disconnecting.
 */

// See also ::soundio_strerror
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoError {
    SoundIoErrorNone,
    // Out of memory.
    SoundIoErrorNoMem,
    // The backend does not appear to be active or running.
    SoundIoErrorInitAudioBackend,
    // A system resource other than memory was not available.
    SoundIoErrorSystemResources,
    // Attempted to open a device and failed.
    SoundIoErrorOpeningDevice,
    SoundIoErrorNoSuchDevice,
    // The programmer did not comply with the API.
    SoundIoErrorInvalid,
    // libsoundio was compiled without support for that backend.
    SoundIoErrorBackendUnavailable,
    // An open stream had an error that can only be recovered from by
    // destroying the stream and creating it again.
    SoundIoErrorStreaming,
    // Attempted to use a device with parameters it cannot support.
    SoundIoErrorIncompatibleDevice,
    // When JACK returns `JackNoSuchClient`
    SoundIoErrorNoSuchClient,
    // Attempted to use parameters that the backend cannot support.
    SoundIoErrorIncompatibleBackend,
    // Backend server shutdown or became inactive.
    SoundIoErrorBackendDisconnected,
    SoundIoErrorInterrupted,
    // Buffer underrun occurred.
    SoundIoErrorUnderflow,
    // Unable to convert to or from UTF-8 to the native string format.
    SoundIoErrorEncodingString,
}

// Specifies where a channel is physically located.
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoChannelId {
    SoundIoChannelIdInvalid,

    SoundIoChannelIdFrontLeft, // First of the more commonly supported ids.
    SoundIoChannelIdFrontRight,
    SoundIoChannelIdFrontCenter,
    SoundIoChannelIdLfe,
    SoundIoChannelIdBackLeft,
    SoundIoChannelIdBackRight,
    SoundIoChannelIdFrontLeftCenter,
    SoundIoChannelIdFrontRightCenter,
    SoundIoChannelIdBackCenter,
    SoundIoChannelIdSideLeft,
    SoundIoChannelIdSideRight,
    SoundIoChannelIdTopCenter,
    SoundIoChannelIdTopFrontLeft,
    SoundIoChannelIdTopFrontCenter,
    SoundIoChannelIdTopFrontRight,
    SoundIoChannelIdTopBackLeft,
    SoundIoChannelIdTopBackCenter,
    SoundIoChannelIdTopBackRight, // Last of the more commonly supported ids.

    SoundIoChannelIdBackLeftCenter, // First of the less commonly supported ids.
    SoundIoChannelIdBackRightCenter,
    SoundIoChannelIdFrontLeftWide,
    SoundIoChannelIdFrontRightWide,
    SoundIoChannelIdFrontLeftHigh,
    SoundIoChannelIdFrontCenterHigh,
    SoundIoChannelIdFrontRightHigh,
    SoundIoChannelIdTopFrontLeftCenter,
    SoundIoChannelIdTopFrontRightCenter,
    SoundIoChannelIdTopSideLeft,
    SoundIoChannelIdTopSideRight,
    SoundIoChannelIdLeftLfe,
    SoundIoChannelIdRightLfe,
    SoundIoChannelIdLfe2,
    SoundIoChannelIdBottomCenter,
    SoundIoChannelIdBottomLeftCenter,
    SoundIoChannelIdBottomRightCenter,

    // Mid/side recording
    SoundIoChannelIdMsMid,
    SoundIoChannelIdMsSide,

    // first order ambisonic channels
    SoundIoChannelIdAmbisonicW,
    SoundIoChannelIdAmbisonicX,
    SoundIoChannelIdAmbisonicY,
    SoundIoChannelIdAmbisonicZ,

    // X-Y Recording
    SoundIoChannelIdXyX,
    SoundIoChannelIdXyY,

    SoundIoChannelIdHeadphonesLeft, // First of the "other" channel ids
    SoundIoChannelIdHeadphonesRight,
    SoundIoChannelIdClickTrack,
    SoundIoChannelIdForeignLanguage,
    SoundIoChannelIdHearingImpaired,
    SoundIoChannelIdNarration,
    SoundIoChannelIdHaptic,
    SoundIoChannelIdDialogCentricMix, // Last of the "other" channel ids

    SoundIoChannelIdAux,
    SoundIoChannelIdAux0,
    SoundIoChannelIdAux1,
    SoundIoChannelIdAux2,
    SoundIoChannelIdAux3,
    SoundIoChannelIdAux4,
    SoundIoChannelIdAux5,
    SoundIoChannelIdAux6,
    SoundIoChannelIdAux7,
    SoundIoChannelIdAux8,
    SoundIoChannelIdAux9,
    SoundIoChannelIdAux10,
    SoundIoChannelIdAux11,
    SoundIoChannelIdAux12,
    SoundIoChannelIdAux13,
    SoundIoChannelIdAux14,
    SoundIoChannelIdAux15,
}

// Built-in channel layouts for convenience.
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoChannelLayoutId {
    SoundIoChannelLayoutIdMono,
    SoundIoChannelLayoutIdStereo,
    SoundIoChannelLayoutId2Point1,
    SoundIoChannelLayoutId3Point0,
    SoundIoChannelLayoutId3Point0Back,
    SoundIoChannelLayoutId3Point1,
    SoundIoChannelLayoutId4Point0,
    SoundIoChannelLayoutIdQuad,
    SoundIoChannelLayoutIdQuadSide,
    SoundIoChannelLayoutId4Point1,
    SoundIoChannelLayoutId5Point0Back,
    SoundIoChannelLayoutId5Point0Side,
    SoundIoChannelLayoutId5Point1,
    SoundIoChannelLayoutId5Point1Back,
    SoundIoChannelLayoutId6Point0Side,
    SoundIoChannelLayoutId6Point0Front,
    SoundIoChannelLayoutIdHexagonal,
    SoundIoChannelLayoutId6Point1,
    SoundIoChannelLayoutId6Point1Back,
    SoundIoChannelLayoutId6Point1Front,
    SoundIoChannelLayoutId7Point0,
    SoundIoChannelLayoutId7Point0Front,
    SoundIoChannelLayoutId7Point1,
    SoundIoChannelLayoutId7Point1Wide,
    SoundIoChannelLayoutId7Point1WideBack,
    SoundIoChannelLayoutIdOctagonal,
}

#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoBackend {
    SoundIoBackendNone,
    SoundIoBackendJack,
    SoundIoBackendPulseAudio,
    SoundIoBackendAlsa,
    SoundIoBackendCoreAudio,
    SoundIoBackendWasapi,
    SoundIoBackendDummy,
}

#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoDeviceAim {
    SoundIoDeviceAimInput,  // capture / recording
    SoundIoDeviceAimOutput, // playback
}

// For your convenience, Native Endian and Foreign Endian constants are defined
// which point to the respective SoundIoFormat values.
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum SoundIoFormat {
    SoundIoFormatInvalid,
    SoundIoFormatS8,        // Signed 8 bit
    SoundIoFormatU8,        // Unsigned 8 bit
    SoundIoFormatS16LE,     // Signed 16 bit Little Endian
    SoundIoFormatS16BE,     // Signed 16 bit Big Endian
    SoundIoFormatU16LE,     // Unsigned 16 bit Little Endian
    SoundIoFormatU16BE,     // Unsigned 16 bit Little Endian
    SoundIoFormatS24LE,     // Signed 24 bit Little Endian using low three bytes in 32-bit word
    SoundIoFormatS24BE,     // Signed 24 bit Big Endian using low three bytes in 32-bit word
    SoundIoFormatU24LE,     // Unsigned 24 bit Little Endian using low three bytes in 32-bit word
    SoundIoFormatU24BE,     // Unsigned 24 bit Big Endian using low three bytes in 32-bit word
    SoundIoFormatS32LE,     // Signed 32 bit Little Endian
    SoundIoFormatS32BE,     // Signed 32 bit Big Endian
    SoundIoFormatU32LE,     // Unsigned 32 bit Little Endian
    SoundIoFormatU32BE,     // Unsigned 32 bit Big Endian
    SoundIoFormatFloat32LE, // Float 32 bit Little Endian, Range -1.0 to 1.0
    SoundIoFormatFloat32BE, // Float 32 bit Big Endian, Range -1.0 to 1.0
    SoundIoFormatFloat64LE, // Float 64 bit Little Endian, Range -1.0 to 1.0
    SoundIoFormatFloat64BE, // Float 64 bit Big Endian, Range -1.0 to 1.0
}

pub const SOUNDIO_MAX_CHANNELS: usize = 24;

// The size of this struct is OK to use.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct SoundIoChannelLayout {
    pub name: *const c_char, // Note that Copy and Clone are ok because this normally points to an internal static string. I think.
    pub channel_count: c_int,
    pub channels: [SoundIoChannelId; SOUNDIO_MAX_CHANNELS],
}

// The size of this struct is OK to use.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct SoundIoSampleRateRange {
    pub min: c_int,
    pub max: c_int,
}

// The size of this struct is OK to use.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct SoundIoChannelArea {
    // Base address of buffer.
    pub ptr: *mut c_char,
    // How many bytes it takes to get from the beginning of one sample to
    // the beginning of the next sample.
    pub step: c_int,
}

// The size of this struct is not part of the API or ABI.
#[repr(C)]
pub struct SoundIo {
    // Optional. Put whatever you want here. Defaults to NULL.
    pub userdata: *mut c_void,
    // Optional callback. Called when the list of devices change. Only called
    // during a call to ::soundio_flush_events or ::soundio_wait_events.
	pub on_devices_change: *mut extern fn(sio: *mut SoundIo),
    // Optional callback. Called when the backend disconnects. For example,
    // when the JACK server shuts down. When this happens, listing devices
    // and opening streams will always fail with
    // SoundIoErrorBackendDisconnected. This callback is only called during a
    // call to ::soundio_flush_events or ::soundio_wait_events.
    // If you do not supply a callback, the default will crash your program
    // with an error message. This callback is also called when the thread
    // that retrieves device information runs into an unrecoverable condition
    // such as running out of memory.
    //
    // Possible errors:
    // * #SoundIoErrorBackendDisconnected
    // * #SoundIoErrorNoMem
    // * #SoundIoErrorSystemResources
    // * #SoundIoErrorOpeningDevice - unexpected problem accessing device
    //   information
	pub on_backend_disconnect: *mut extern fn(sio: *mut SoundIo, err: c_int),
    // Optional callback. Called from an unknown thread that you should not use
    // to call any soundio functions. You may use this to signal a condition
    // variable to wake up. Called when ::soundio_wait_events would be woken up.
	pub on_events_signal: *mut extern fn(sio: *mut SoundIo),

    // Read-only. After calling ::soundio_connect or ::soundio_connect_backend,
    // this field tells which backend is currently connected.
    pub current_backend: SoundIoBackend,

    // Optional: Application name.
    // PulseAudio uses this for "application name".
    // JACK uses this for `client_name`.
    // Must not contain a colon (":").
    pub app_name: *mut c_char,

    // Optional: Real time priority warning.
    // This callback is fired when making thread real-time priority failed. By
    // default, it will print to stderr only the first time it is called
    // a message instructing the user how to configure their system to allow
    // real-time priority threads. This must be set to a function not NULL.
    // To silence the warning, assign this to a function that does nothing.
	pub emit_rtprio_warning: *mut extern fn(),

    // Optional: JACK info callback.
    // By default, libsoundio sets this to an empty function in order to
    // silence stdio messages from JACK. You may override the behavior by
    // setting this to `NULL` or providing your own function. This is
    // registered with JACK regardless of whether ::soundio_connect_backend
    // succeeds.
	pub jack_info_callback: *mut extern fn(msg: *const c_char),
    // Optional: JACK error callback.
    // See SoundIo::jack_info_callback
	pub jack_error_callback: *mut extern fn(msg: *const c_char),
}

// The size of this struct is not part of the API or ABI.
#[repr(C)]
pub struct SoundIoDevice {
    // Read-only. Set automatically.
    pub soundio: *mut SoundIo,

    // A string of bytes that uniquely identifies this device.
    // If the same physical device supports both input and output, that makes
    // one SoundIoDevice for the input and one SoundIoDevice for the output.
    // In this case, the id of each SoundIoDevice will be the same, and
    // SoundIoDevice::aim will be different. Additionally, if the device
    // supports raw mode, there may be up to four devices with the same id:
    // one for each value of SoundIoDevice::is_raw and one for each value of
    // SoundIoDevice::aim.
    pub id: *mut c_char,
    // User-friendly UTF-8 encoded text to describe the device.
    pub name: *mut c_char,

    // Tells whether this device is an input device or an output device.
    pub aim: SoundIoDeviceAim,

    // Channel layouts are handled similarly to SoundIoDevice::formats.
    // If this information is missing due to a SoundIoDevice::probe_error,
    // layouts will be NULL. It's OK to modify this data, for example calling
    // ::soundio_sort_channel_layouts on it.
    // Devices are guaranteed to have at least 1 channel layout.
    pub layouts: *mut SoundIoChannelLayout,
    pub layout_count: c_int,
    // See SoundIoDevice::current_format
    pub current_layout: SoundIoChannelLayout,

    // List of formats this device supports. See also
    // SoundIoDevice::current_format.
    pub formats: *mut SoundIoFormat,
    // How many formats are available in SoundIoDevice::formats.
    pub format_count: c_int,
    // A device is either a raw device or it is a virtual device that is
    // provided by a software mixing service such as dmix or PulseAudio (see
    // SoundIoDevice::is_raw). If it is a raw device,
    // current_format is meaningless;
    // the device has no current format until you open it. On the other hand,
    // if it is a virtual device, current_format describes the
    // destination sample format that your audio will be converted to. Or,
    // if you're the lucky first application to open the device, you might
    // cause the current_format to change to your format.
    // Generally, you want to ignore current_format and use
    // whatever format is most convenient
    // for you which is supported by the device, because when you are the only
    // application left, the mixer might decide to switch
    // current_format to yours. You can learn the supported formats via
    // formats and SoundIoDevice::format_count. If this information is missing
    // due to a probe error, formats will be `NULL`. If current_format is
    // unavailable, it will be set to #SoundIoFormatInvalid.
    // Devices are guaranteed to have at least 1 format available.
    pub current_format: SoundIoFormat,

    // Sample rate is the number of frames per second.
    // Sample rate is handled very similar to SoundIoDevice::formats.
    // If sample rate information is missing due to a probe error, the field
    // will be set to NULL.
    // Devices which have SoundIoDevice::probe_error set to #SoundIoErrorNone are
    // guaranteed to have at least 1 sample rate available.
    pub sample_rates: *mut SoundIoSampleRateRange,
    // How many sample rate ranges are available in
    // SoundIoDevice::sample_rates. 0 if sample rate information is missing
    // due to a probe error.
    pub sample_rate_count: c_int,
    // See SoundIoDevice::current_format
    // 0 if sample rate information is missing due to a probe error.
    pub sample_rate_current: c_int,

    // Software latency minimum in seconds. If this value is unknown or
    // irrelevant, it is set to 0.0.
    // For PulseAudio and WASAPI this value is unknown until you open a
    // stream.
    pub software_latency_min: c_double,
    // Software latency maximum in seconds. If this value is unknown or
    // irrelevant, it is set to 0.0.
    // For PulseAudio and WASAPI this value is unknown until you open a
    // stream.
    pub software_latency_max: c_double,
    // Software latency in seconds. If this value is unknown or
    // irrelevant, it is set to 0.0.
    // For PulseAudio and WASAPI this value is unknown until you open a
    // stream.
    // See SoundIoDevice::current_format
    pub software_latency_current: c_double,

    // Raw means that you are directly opening the hardware device and not
    // going through a proxy such as dmix, PulseAudio, or JACK. When you open a
    // raw device, other applications on the computer are not able to
    // simultaneously access the device. Raw devices do not perform automatic
    // resampling and thus tend to have fewer formats available.
    pub is_raw: c_bool,

    // Devices are reference counted. See ::soundio_device_ref and
    // ::soundio_device_unref.
    pub ref_count: c_int,

    // This is set to a SoundIoError representing the result of the device
    // probe. Ideally this will be SoundIoErrorNone in which case all the
    // fields of the device will be populated. If there is an error code here
    // then information about formats, sample rates, and channel layouts might
    // be missing.
    //
    // Possible errors:
    // * #SoundIoErrorOpeningDevice
    // * #SoundIoErrorNoMem
    pub probe_error: c_int,
}

// The size of this struct is not part of the API or ABI.
#[repr(C)]
pub struct SoundIoOutStream {
    // Populated automatically when you call ::soundio_outstream_create.
    pub device: *mut SoundIoDevice,

    // Defaults to #SoundIoFormatFloat32NE, followed by the first one
    // supported.
    pub format: SoundIoFormat,

    // Sample rate is the number of frames per second.
    // Defaults to 48000 (and then clamped into range).
    pub sample_rate: c_int,

    // Defaults to Stereo, if available, followed by the first layout
    // supported.
    pub layout: SoundIoChannelLayout,

    // Ignoring hardware latency, this is the number of seconds it takes for
    // the last sample in a full buffer to be played.
    // After you call ::soundio_outstream_open, this value is replaced with the
    // actual software latency, as near to this value as possible.
    // 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. On systems that do not support clearing the buffer,
    // this defaults to a reasonable lower latency value.
    //
    // On backends with high latencies (such as 2 seconds), `frame_count_min`
    // will be 0, meaning you don't have to fill the entire buffer. In this
    // case, the large buffer is there if you want it; you only have to fill
    // as much as you want. On backends like JACK, `frame_count_min` will be
    // equal to `frame_count_max` and if you don't fill that many frames, you
    // will get glitches.
    //
    // If the device has unknown software latency min and max values, you may
    // still set this, but you might not get the value you requested.
    // For PulseAudio, if you set this value to non-default, it sets
    // `PA_STREAM_ADJUST_LATENCY` and is the value used for `maxlength` and
    // `tlength`.
    //
    // For JACK, this value is always equal to
    // SoundIoDevice::software_latency_current of the device.
    pub software_latency: c_double,

    // Defaults to NULL. Put whatever you want here.
    pub userdata: *mut c_void,
    // In this callback, you call ::soundio_outstream_begin_write and
    // ::soundio_outstream_end_write as many times as necessary to write
    // at minimum `frame_count_min` frames and at maximum `frame_count_max`
    // frames. `frame_count_max` will always be greater than 0. Note that you
    // should write as many frames as you can; `frame_count_min` might be 0 and
    // you can still get a buffer underflow if you always write
    // `frame_count_min` frames.
    //
    // For Dummy, ALSA, and PulseAudio, `frame_count_min` will be 0. For JACK
    // and CoreAudio `frame_count_min` will be equal to `frame_count_max`.
    //
    // The code in the supplied function must be suitable for real-time
    // execution. That means that it cannot call functions that might block
    // for a long time. This includes all I/O functions (disk, TTY, network),
    // malloc, free, printf, pthread_mutex_lock, sleep, wait, poll, select,
    // pthread_join, pthread_cond_wait, etc.
	pub write_callback: *mut extern fn(stream: *mut SoundIoOutStream, frame_count_min: c_int, frame_count_max: c_int),
    // This optional callback happens when the sound device runs out of
    // buffered audio data to play. After this occurs, the outstream waits
    // until the buffer is full to resume playback.
    // This is called from the SoundIoOutStream::write_callback thread context.
	pub underflow_callback: *mut extern fn(stream: *mut SoundIoOutStream),
    // Optional callback. `err` is always SoundIoErrorStreaming.
    // SoundIoErrorStreaming is an unrecoverable error. The stream is in an
    // invalid state and must be destroyed.
    // If you do not supply error_callback, the default callback will print
    // a message to stderr and then call `abort`.
    // This is called from the SoundIoOutStream::write_callback thread context.
	pub error_callback: *mut extern fn(stream: *mut SoundIoOutStream, err: c_int),

    // Optional: Name of the stream. Defaults to "SoundIoOutStream"
    // PulseAudio uses this for the stream name.
    // JACK uses this for the client name of the client that connects when you
    // open the stream.
    // WASAPI uses this for the session display name.
    // Must not contain a colon (":").
    pub name: *const c_char,

    // Optional: Hint that this output stream is nonterminal. This is used by
    // JACK and it means that the output stream data originates from an input
    // stream. Defaults to `false`.
    pub non_terminal_hint: c_bool,


    // computed automatically when you call ::soundio_outstream_open
    pub bytes_per_frame: c_int,
    // computed automatically when you call ::soundio_outstream_open
    pub bytes_per_sample: c_int,

    // If setting the channel layout fails for some reason, this field is set
    // to an error code. Possible error codes are:
    // * #SoundIoErrorIncompatibleDevice
    pub layout_error: c_int,
}

// The size of this struct is not part of the API or ABI.
#[repr(C)]
pub struct SoundIoInStream {
    // Populated automatically when you call ::soundio_outstream_create.
    pub device: *mut SoundIoDevice,

    // Defaults to #SoundIoFormatFloat32NE, followed by the first one
    // supported.
    pub format: SoundIoFormat,

    // Sample rate is the number of frames per second.
    // Defaults to max(sample_rate_min, min(sample_rate_max, 48000))
    pub sample_rate: c_int,

    // Defaults to Stereo, if available, followed by the first layout
    // supported.
    pub layout: SoundIoChannelLayout,

    // Ignoring hardware latency, this is the number of seconds it takes for a
    // captured sample to become available for reading.
    // After you call ::soundio_instream_open, this value is replaced with the
    // actual software latency, as near to this value as possible.
    // A higher value means less CPU usage. Defaults to a large value,
    // potentially upwards of 2 seconds.
    // If the device has unknown software latency min and max values, you may
    // still set this, but you might not get the value you requested.
    // For PulseAudio, if you set this value to non-default, it sets
    // `PA_STREAM_ADJUST_LATENCY` and is the value used for `fragsize`.
    // For JACK, this value is always equal to
    // SoundIoDevice::software_latency_current
    pub software_latency: c_double,

    // Defaults to NULL. Put whatever you want here.
    pub userdata: *mut c_void,
    // In this function call ::soundio_instream_begin_read and
    // ::soundio_instream_end_read as many times as necessary to read at
    // minimum `frame_count_min` frames and at maximum `frame_count_max`
    // frames. If you return from read_callback without having read
    // `frame_count_min`, the frames will be dropped. `frame_count_max` is how
    // many frames are available to read.
    //
    // The code in the supplied function must be suitable for real-time
    // execution. That means that it cannot call functions that might block
    // for a long time. This includes all I/O functions (disk, TTY, network),
    // malloc, free, printf, pthread_mutex_lock, sleep, wait, poll, select,
    // pthread_join, pthread_cond_wait, etc.
	pub read_callback: *mut extern fn(stream: *mut SoundIoInStream, frame_count_min: c_int, frame_count_max: c_int),
    // This optional callback happens when the sound device buffer is full,
    // yet there is more captured audio to put in it.
    // This is never fired for PulseAudio.
    // This is called from the SoundIoInStream::read_callback thread context.
	pub overflow_callback: *mut extern fn(stream: *mut SoundIoInStream),
    // Optional callback. `err` is always SoundIoErrorStreaming.
    // SoundIoErrorStreaming is an unrecoverable error. The stream is in an
    // invalid state and must be destroyed.
    // If you do not supply `error_callback`, the default callback will print
    // a message to stderr and then abort().
    // This is called from the SoundIoInStream::read_callback thread context.
	pub error_callback: *mut extern fn(stream: *mut SoundIoInStream, err: c_int),

    // Optional: Name of the stream. Defaults to "SoundIoInStream";
    // PulseAudio uses this for the stream name.
    // JACK uses this for the client name of the client that connects when you
    // open the stream.
    // WASAPI uses this for the session display name.
    // Must not contain a colon (":").
    pub name: *const c_char,

    // Optional: Hint that this input stream is nonterminal. This is used by
    // JACK and it means that the data received by the stream will be
    // passed on or made available to another stream. Defaults to `false`.
    pub non_terminal_hint: c_bool,

    // computed automatically when you call ::soundio_instream_open
    pub bytes_per_frame: c_int,
    // computed automatically when you call ::soundio_instream_open
    pub bytes_per_sample: c_int,

    // If setting the channel layout fails for some reason, this field is set
    // to an error code. Possible error codes are: #SoundIoErrorIncompatibleDevice
    pub layout_error: c_int,
}

pub enum SoundIoRingBuffer {
}

extern {
		
	// See also ::soundio_version_major, ::soundio_version_minor, ::soundio_version_patch
	pub fn soundio_version_string() -> *const c_char;
	// See also ::soundio_version_string, ::soundio_version_minor, ::soundio_version_patch
	pub fn soundio_version_major() -> c_int;
	// See also ::soundio_version_major, ::soundio_version_string, ::soundio_version_patch
	pub fn soundio_version_minor() -> c_int;
	// See also ::soundio_version_major, ::soundio_version_minor, ::soundio_version_string
	pub fn soundio_version_patch() -> c_int;

	// Create a SoundIo context. You may create multiple instances of this to
	// connect to multiple backends. Sets all fields to defaults.
	// Returns `NULL` if and only if memory could not be allocated.
	// See also ::soundio_destroy
	pub fn soundio_create() -> *mut SoundIo;
	pub fn soundio_destroy(soundio: *mut SoundIo);


	// Tries ::soundio_connect_backend on all available backends in order.
	// Possible errors:
	// * #SoundIoErrorInvalid - already connected
	// * #SoundIoErrorNoMem
	// * #SoundIoErrorSystemResources
	// * #SoundIoErrorNoSuchClient - when JACK returns `JackNoSuchClient`
	// See also ::soundio_disconnect
	pub fn soundio_connect(soundio: *mut SoundIo) -> c_int;
	// Instead of calling ::soundio_connect you may call this function to try a
	// specific backend.
	// Possible errors:
	// * #SoundIoErrorInvalid - already connected or invalid backend parameter
	// * #SoundIoErrorNoMem
	// * #SoundIoErrorBackendUnavailable - backend was not compiled in
	// * #SoundIoErrorSystemResources
	// * #SoundIoErrorNoSuchClient - when JACK returns `JackNoSuchClient`
	// * #SoundIoErrorInitAudioBackend - requested `backend` is not active
	// * #SoundIoErrorBackendDisconnected - backend disconnected while connecting
	// See also ::soundio_disconnect
	pub fn soundio_connect_backend(soundio: *mut SoundIo, backend: SoundIoBackend) -> c_int;
	pub fn soundio_disconnect(soundio: *mut SoundIo);

	// Get a string representation of a #SoundIoError
	pub fn soundio_strerror(error: c_int) -> *const c_char;
	// Get a string representation of a #SoundIoBackend
	pub fn soundio_backend_name(backend: SoundIoBackend) -> *const c_char;

	// Returns the number of available backends.
	pub fn soundio_backend_count(soundio: *mut SoundIo) -> c_int;
	// get the available backend at the specified index
	// (0 <= index < ::soundio_backend_count)
	pub fn soundio_get_backend(soundio: *mut SoundIo, index: c_int) -> SoundIoBackend;

	// Returns whether libsoundio was compiled with backend.
	pub fn soundio_have_backend(backend: SoundIoBackend) -> c_bool;

	// Atomically update information for all connected devices. Note that calling
	// this function merely flips a pointer; the actual work of collecting device
	// information is done elsewhere. It is performant to call this function many
	// times per second.
	//
	// When you call this, the following callbacks might be called:
	// * SoundIo::on_devices_change
	// * SoundIo::on_backend_disconnect
	// This is the only time those callbacks can be called.
	//
	// This must be called from the same thread as the thread in which you call
	// these functions:
	// * ::soundio_input_device_count
	// * ::soundio_output_device_count
	// * ::soundio_get_input_device
	// * ::soundio_get_output_device
	// * ::soundio_default_input_device_index
	// * ::soundio_default_output_device_index
	//
	// Note that if you do not care about learning about updated devices, you
	// might call this function only once ever and never call
	// ::soundio_wait_events.
	pub fn soundio_flush_events(soundio: *mut SoundIo);

	// This function calls ::soundio_flush_events then blocks until another event
	// is ready or you call ::soundio_wakeup. Be ready for spurious wakeups.
	pub fn soundio_wait_events(soundio: *mut SoundIo);

	// Makes ::soundio_wait_events stop blocking.
	pub fn soundio_wakeup(soundio: *mut SoundIo);


	// If necessary you can manually trigger a device rescan. Normally you will
	// not ever have to call this function, as libsoundio listens to system events
	// for device changes and responds to them by rescanning devices and preparing
	// the new device information for you to be atomically replaced when you call
	// ::soundio_flush_events. However you might run into cases where you want to
	// force trigger a device rescan, for example if an ALSA device has a
	// SoundIoDevice::probe_error.
	//
	// After you call this you still have to use ::soundio_flush_events or
	// ::soundio_wait_events and then wait for the
	// SoundIo::on_devices_change callback.
	//
	// This can be called from any thread context except for
	// SoundIoOutStream::write_callback and SoundIoInStream::read_callback
	pub fn soundio_force_device_scan(soundio: *mut SoundIo);


	// Channel Layouts

	// Returns whether the channel count field and each channel id matches in
	// the supplied channel layouts.
	pub fn soundio_channel_layout_equal(
			a: *mut SoundIoChannelLayout,
			b: *mut SoundIoChannelLayout) -> c_bool;

	pub fn soundio_get_channel_name(id: SoundIoChannelId) -> *const c_char;
	// 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.
	pub fn soundio_parse_channel_id(str: *const c_char, str_len: c_int) -> SoundIoChannelId;

	// Returns the number of builtin channel layouts.
	pub fn soundio_channel_layout_builtin_count() -> c_int;
	// Returns a builtin channel layout. 0 <= `index` < ::soundio_channel_layout_builtin_count
	//
	// Although `index` is of type `int`, it should be a valid
	// #SoundIoChannelLayoutId enum value.
	pub fn soundio_channel_layout_get_builtin(index: c_int) -> *const SoundIoChannelLayout;

	// Get the default builtin channel layout for the given number of channels.
	pub fn soundio_channel_layout_get_default(channel_count: c_int) -> *const SoundIoChannelLayout;

	// Return the index of `channel` in `layout`, or `-1` if not found.
	pub fn soundio_channel_layout_find_channel(
			layout: *const SoundIoChannelLayout, channel: SoundIoChannelId) -> c_int;

	// Populates the name field of layout if it matches a builtin one.
	// returns whether it found a match
	pub fn soundio_channel_layout_detect_builtin(layout: *mut SoundIoChannelLayout) -> c_bool;

	// 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.
	pub fn soundio_best_matching_channel_layout(
			preferred_layouts: *const SoundIoChannelLayout, preferred_layout_count: c_int,
			available_layouts: *const SoundIoChannelLayout, available_layout_count: c_int) -> *const SoundIoChannelLayout;

	// Sorts by channel count, descending.
	pub fn soundio_sort_channel_layouts(layout: *mut SoundIoChannelLayout, layout_count: c_int);

	// Sample Formats

	// Returns -1 on invalid format.
	pub fn soundio_get_bytes_per_sample(format: SoundIoFormat) -> c_int;

	// A frame is one sample per channel.
	// static inline int soundio_get_bytes_per_frame(enum SoundIoFormat format, channel_count: c_int) {
	// 	return soundio_get_bytes_per_sample(format) * channel_count;
	// }

	// Sample rate is the number of frames per second.
	// static inline int soundio_get_bytes_per_second(enum SoundIoFormat format,
	// 		channel_count: c_int, int sample_rate)
	// {
	// 	return soundio_get_bytes_per_frame(format, channel_count) * sample_rate;
	// }

	// Returns string representation of `format`.
	pub fn soundio_format_string(format: SoundIoFormat) -> *const c_char;




	// Devices

	// When you call ::soundio_flush_events, a snapshot of all device state is
	// saved and these functions merely access the snapshot data. When you want
	// to check for new devices, call ::soundio_flush_events. Or you can call
	// ::soundio_wait_events to block until devices change. If an error occurs
	// scanning devices in a background thread, SoundIo::on_backend_disconnect is called
	// with the error code.

	// Get the number of input devices.
	// Returns -1 if you never called ::soundio_flush_events.
	pub fn soundio_input_device_count(soundio: *mut SoundIo) -> c_int;
	// Get the number of output devices.
	// Returns -1 if you never called ::soundio_flush_events.
	pub fn soundio_output_device_count(soundio: *mut SoundIo) -> c_int;

	// 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.
	pub fn soundio_get_input_device(soundio: *mut SoundIo, index: c_int) -> *mut SoundIoDevice;
	// 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.
	pub fn soundio_get_output_device(soundio: *mut SoundIo, index: c_int) -> *mut SoundIoDevice;

	// returns the index of the default input device
	// returns -1 if there are no devices or if you never called
	// ::soundio_flush_events.
	pub fn soundio_default_input_device_index(soundio: *mut SoundIo) -> c_int;

	// returns the index of the default output device
	// returns -1 if there are no devices or if you never called
	// ::soundio_flush_events.
	pub fn soundio_default_output_device_index(soundio: *mut SoundIo) -> c_int;

	// Add 1 to the reference count of `device`.
	pub fn soundio_device_ref(device: *mut SoundIoDevice);
	// Remove 1 to the reference count of `device`. Clean up if it was the last
	// reference.
	pub fn soundio_device_unref(device: *mut SoundIoDevice);

	// Return `true` if and only if the devices have the same SoundIoDevice::id,
	// SoundIoDevice::is_raw, and SoundIoDevice::aim are the same.
	pub fn soundio_device_equal(
			a: *const SoundIoDevice,
			b: *const SoundIoDevice) -> c_bool;

	// Sorts channel layouts by channel count, descending.
	pub fn soundio_device_sort_channel_layouts(device: *mut SoundIoDevice);

	// Convenience function. Returns whether `format` is included in the device's
	// supported formats.
	pub fn soundio_device_supports_format(device: *mut SoundIoDevice,
			format: SoundIoFormat) -> c_bool;

	// Convenience function. Returns whether `layout` is included in the device's
	// supported channel layouts.
	pub fn soundio_device_supports_layout(device: *mut SoundIoDevice,
			layout: *const SoundIoChannelLayout) -> c_bool;

	// Convenience function. Returns whether `sample_rate` is included in the
	// device's supported sample rates.
	pub fn soundio_device_supports_sample_rate(device: *mut SoundIoDevice,
			sample_rate: c_int) -> c_bool;

	// Convenience function. Returns the available sample rate nearest to
	// `sample_rate`, rounding up.
	pub fn soundio_device_nearest_sample_rate(device: *mut SoundIoDevice,
			sample_rate: c_int) -> c_int;



	// Output Streams
	// Allocates memory and sets defaults. Next you should fill out the struct fields
	// and then call ::soundio_outstream_open. Sets all fields to defaults.
	// Returns `NULL` if and only if memory could not be allocated.
	// See also ::soundio_outstream_destroy
	pub fn soundio_outstream_create(device: *mut SoundIoDevice) -> *mut SoundIoOutStream;
	// You may not call this function from the SoundIoOutStream::write_callback thread context.
	pub fn soundio_outstream_destroy(outstream: *mut SoundIoOutStream);

	// After you call this function, SoundIoOutStream::software_latency is set to
	// the correct value.
	//
	// The next thing to do is call ::soundio_instream_start.
	// If this function returns an error, the outstream is in an invalid state and
	// you must call ::soundio_outstream_destroy on it.
	//
	// Possible errors:
	// * #SoundIoErrorInvalid
	//   * SoundIoDevice::aim is not #SoundIoDeviceAimOutput
	//   * SoundIoOutStream::format is not valid
	//   * SoundIoOutStream::channel_count is greater than #SOUNDIO_MAX_CHANNELS
	// * #SoundIoErrorNoMem
	// * #SoundIoErrorOpeningDevice
	// * #SoundIoErrorBackendDisconnected
	// * #SoundIoErrorSystemResources
	// * #SoundIoErrorNoSuchClient - when JACK returns `JackNoSuchClient`
	// * #SoundIoErrorOpeningDevice
	// * #SoundIoErrorIncompatibleBackend - SoundIoOutStream::channel_count is
	//   greater than the number of channels the backend can handle.
	// * #SoundIoErrorIncompatibleDevice - stream parameters requested are not
	//   compatible with the chosen device.
	pub fn soundio_outstream_open(outstream: *mut SoundIoOutStream) -> c_int;

	// After you call this function, SoundIoOutStream::write_callback will be called.
	//
	// This function might directly call SoundIoOutStream::write_callback.
	//
	// Possible errors:
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorNoMem
	// * #SoundIoErrorSystemResources
	// * #SoundIoErrorBackendDisconnected
	pub fn soundio_outstream_start(outstream: *mut SoundIoOutStream) -> c_int;

	// Call this function when you are ready to begin writing to the device buffer.
	//  * `outstream` - (in) The output stream you want to write to.
	//  * `areas` - (out) The memory addresses you can write data to, one per
	//    channel. It is OK to modify the pointers if that helps you iterate.
	//  * `frame_count` - (in/out) Provide the number of frames you want to write.
	//    Returned will be the number of frames you can actually write, which is
	//    also the number of frames that will be written when you call
	//    ::soundio_outstream_end_write. The value returned will always be less
	//    than or equal to the value provided.
	// It is your responsibility to call this function exactly as many times as
	// necessary to meet the `frame_count_min` and `frame_count_max` criteria from
	// SoundIoOutStream::write_callback.
	// You must call this function only from the SoundIoOutStream::write_callback thread context.
	// After calling this function, write data to `areas` and then call
	// ::soundio_outstream_end_write.
	// If this function returns an error, do not call ::soundio_outstream_end_write.
	//
	// Possible errors:
	// * #SoundIoErrorInvalid
	//   * `*frame_count` <= 0
	//   * `*frame_count` < `frame_count_min` or `*frame_count` > `frame_count_max`
	//   * function called too many times without respecting `frame_count_max`
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorUnderflow - an underflow caused this call to fail. You might
	//   also get a SoundIoOutStream::underflow_callback, and you might not get
	//   this error code when an underflow occurs. Unlike #SoundIoErrorStreaming,
	//   the outstream is still in a valid state and streaming can continue.
	// * #SoundIoErrorIncompatibleDevice - in rare cases it might just now
	//   be discovered that the device uses non-byte-aligned access, in which
	//   case this error code is returned.
	pub fn soundio_outstream_begin_write(outstream: *mut SoundIoOutStream,
			areas: *mut *mut SoundIoChannelArea, frame_count: *mut c_int) -> c_int;

	// Commits the write that you began with ::soundio_outstream_begin_write.
	// You must call this function only from the SoundIoOutStream::write_callback thread context.
	//
	// Possible errors:
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorUnderflow - an underflow caused this call to fail. You might
	//   also get a SoundIoOutStream::underflow_callback, and you might not get
	//   this error code when an underflow occurs. Unlike #SoundIoErrorStreaming,
	//   the outstream is still in a valid state and streaming can continue.
	pub fn soundio_outstream_end_write(outstream: *mut SoundIoOutStream) -> c_int;

	// Clears the output stream buffer.
	// This function can be called from any thread.
	// This function can be called regardless of whether the outstream is paused
	// or not.
	// Some backends do not support clearing the buffer. On these backends this
	// function will return SoundIoErrorIncompatibleBackend.
	// Some devices do not support clearing the buffer. On these devices this
	// function might return SoundIoErrorIncompatibleDevice.
	// Possible errors:
	//
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorIncompatibleBackend
	// * #SoundIoErrorIncompatibleDevice
	pub fn soundio_outstream_clear_buffer(outstream: *mut SoundIoOutStream) -> c_int;

	// If the underlying backend and device support pausing, this pauses the
	// stream. SoundIoOutStream::write_callback may be called a few more times if
	// the buffer is not full.
	// Pausing might put the hardware into a low power state which is ideal if your
	// software is silent for some time.
	// This function may be called from any thread context, including
	// SoundIoOutStream::write_callback.
	// Pausing when already paused or unpausing when already unpaused has no
	// effect and returns #SoundIoErrorNone.
	//
	// Possible errors:
	// * #SoundIoErrorBackendDisconnected
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorIncompatibleDevice - device does not support
	//   pausing/unpausing. This error code might not be returned even if the
	//   device does not support pausing/unpausing.
	// * #SoundIoErrorIncompatibleBackend - backend does not support
	//   pausing/unpausing.
	// * #SoundIoErrorInvalid - outstream not opened and started
	pub fn soundio_outstream_pause(outstream: *mut SoundIoOutStream, pause: c_bool) -> c_int;

	// Obtain the total number of seconds that the next frame written after the
	// last frame written with ::soundio_outstream_end_write will take to become
	// audible. This includes both software and hardware latency. In other words,
	// if you call this function directly after calling ::soundio_outstream_end_write,
	// this gives you the number of seconds that the next frame written will take
	// to become audible.
	//
	// This function must be called only from within SoundIoOutStream::write_callback.
	//
	// Possible errors:
	// * #SoundIoErrorStreaming
	pub fn soundio_outstream_get_latency(outstream: *mut SoundIoOutStream,
			out_latency: *mut c_double) -> c_int;



	// Input Streams
	// Allocates memory and sets defaults. Next you should fill out the struct fields
	// and then call ::soundio_instream_open. Sets all fields to defaults.
	// Returns `NULL` if and only if memory could not be allocated.
	// See also ::soundio_instream_destroy
	pub fn soundio_instream_create(device: *mut SoundIoDevice) -> *mut SoundIoInStream;
	// You may not call this function from SoundIoInStream::read_callback.
	pub fn soundio_instream_destroy(instream: *mut SoundIoInStream);

	// After you call this function, SoundIoInStream::software_latency is set to the correct
	// value.
	// The next thing to do is call ::soundio_instream_start.
	// If this function returns an error, the instream is in an invalid state and
	// you must call ::soundio_instream_destroy on it.
	//
	// Possible errors:
	// * #SoundIoErrorInvalid
	//   * device aim is not #SoundIoDeviceAimInput
	//   * format is not valid
	//   * requested layout channel count > #SOUNDIO_MAX_CHANNELS
	// * #SoundIoErrorOpeningDevice
	// * #SoundIoErrorNoMem
	// * #SoundIoErrorBackendDisconnected
	// * #SoundIoErrorSystemResources
	// * #SoundIoErrorNoSuchClient
	// * #SoundIoErrorIncompatibleBackend
	// * #SoundIoErrorIncompatibleDevice
	pub fn soundio_instream_open(instream: *mut SoundIoInStream) -> c_int;

	// After you call this function, SoundIoInStream::read_callback will be called.
	//
	// Possible errors:
	// * #SoundIoErrorBackendDisconnected
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorOpeningDevice
	// * #SoundIoErrorSystemResources
	pub fn soundio_instream_start(instream: *mut SoundIoInStream) -> c_int;

	// Call this function when you are ready to begin reading from the device
	// buffer.
	// * `instream` - (in) The input stream you want to read from.
	// * `areas` - (out) The memory addresses you can read data from. It is OK
	//   to modify the pointers if that helps you iterate. There might be a "hole"
	//   in the buffer. To indicate this, `areas` will be `NULL` and `frame_count`
	//   tells how big the hole is in frames.
	// * `frame_count` - (in/out) - Provide the number of frames you want to read;
	//   returns the number of frames you can actually read. The returned value
	//   will always be less than or equal to the provided value. If the provided
	//   value is less than `frame_count_min` from SoundIoInStream::read_callback this function
	//   returns with #SoundIoErrorInvalid.
	// It is your responsibility to call this function no more and no fewer than the
	// correct number of times according to the `frame_count_min` and
	// `frame_count_max` criteria from SoundIoInStream::read_callback.
	// You must call this function only from the SoundIoInStream::read_callback thread context.
	// After calling this function, read data from `areas` and then use
	// ::soundio_instream_end_read` to actually remove the data from the buffer
	// 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.
	//
	// Possible errors:
	// * #SoundIoErrorInvalid
	//   * `*frame_count` < `frame_count_min` or `*frame_count` > `frame_count_max`
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorIncompatibleDevice - in rare cases it might just now
	//   be discovered that the device uses non-byte-aligned access, in which
	//   case this error code is returned.
	pub fn soundio_instream_begin_read(instream: *mut SoundIoInStream,
			areas: *mut *mut SoundIoChannelArea, frame_count: *mut c_int) -> c_int;
	// This will drop all of the frames from when you called
	// ::soundio_instream_begin_read.
	// You must call this function only from the SoundIoInStream::read_callback thread context.
	// You must call this function only after a successful call to
	// ::soundio_instream_begin_read.
	//
	// Possible errors:
	// * #SoundIoErrorStreaming
	pub fn soundio_instream_end_read(instream: *mut SoundIoInStream) -> c_int;

	// If the underyling device supports pausing, this pauses the stream and
	// prevents SoundIoInStream::read_callback from being called. Otherwise this returns
	// #SoundIoErrorIncompatibleDevice.
	// This function may be called from any thread.
	// Pausing when already paused or unpausing when already unpaused has no
	// effect and always returns #SoundIoErrorNone.
	//
	// Possible errors:
	// * #SoundIoErrorBackendDisconnected
	// * #SoundIoErrorStreaming
	// * #SoundIoErrorIncompatibleDevice - device does not support pausing/unpausing
	pub fn soundio_instream_pause(instream: *mut SoundIoInStream, pause: c_bool) -> c_int;

	// Obtain the number of seconds that the next frame of sound being
	// captured will take to arrive in the buffer, plus the amount of time that is
	// represented in the buffer. This includes both software and hardware latency.
	//
	// This function must be called only from within SoundIoInStream::read_callback.
	//
	// Possible errors:
	// * #SoundIoErrorStreaming
	pub fn soundio_instream_get_latency(instream: *mut SoundIoInStream,
			out_latency: *mut c_double) -> c_int;


	// 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.

	// Enum is defined above. See https://github.com/rust-lang/rust/issues/27303
	// struct SoundIoRingBuffer;

	// `requested_capacity` in bytes.
	// Returns `NULL` if and only if memory could not be allocated.
	// Use ::soundio_ring_buffer_capacity to get the actual capacity, which might
	// be greater for alignment purposes.
	// See also ::soundio_ring_buffer_destroy
	pub fn soundio_ring_buffer_create(soundio: *mut SoundIo, requested_capacity: c_int) -> *mut SoundIoRingBuffer;
	pub fn soundio_ring_buffer_destroy(ring_buffer: *mut SoundIoRingBuffer);

	// When you create a ring buffer, capacity might be more than the requested
	// capacity for alignment purposes. This function returns the actual capacity.
	pub fn soundio_ring_buffer_capacity(ring_buffer: *mut SoundIoRingBuffer) -> c_int;

	// Do not write more than capacity.
	pub fn soundio_ring_buffer_write_ptr(ring_buffer: *mut SoundIoRingBuffer) -> *mut c_char;
	// `count` in bytes.
	pub fn soundio_ring_buffer_advance_write_ptr(ring_buffer: *mut SoundIoRingBuffer, count: c_int);

	// Do not read more than capacity.
	pub fn soundio_ring_buffer_read_ptr(ring_buffer: *mut SoundIoRingBuffer) -> *mut c_char;
	// `count` in bytes.
	pub fn soundio_ring_buffer_advance_read_ptr(ring_buffer: *mut SoundIoRingBuffer, count: c_int);

	// Returns how many bytes of the buffer is used, ready for reading.
	pub fn soundio_ring_buffer_fill_count(ring_buffer: *mut SoundIoRingBuffer) -> c_int;

	// Returns how many bytes of the buffer is free, ready for writing.
	pub fn soundio_ring_buffer_free_count(ring_buffer: *mut SoundIoRingBuffer) -> c_int;

	// Must be called by the writer.
	pub fn soundio_ring_buffer_clear(ring_buffer: *mut SoundIoRingBuffer);

}