diff --git a/example/microphone.c b/example/microphone.c index 48e4e6c..6c09a3f 100644 --- a/example/microphone.c +++ b/example/microphone.c @@ -79,11 +79,11 @@ int main(int argc, char **argv) { double latency = 0.1; struct SoundIoInputDevice *input_device; - soundio_input_device_create(in_device, SoundIoSampleFormatFloat, 48000, latency, NULL, + soundio_input_device_create(in_device, SoundIoSampleFormatFloat32NE, 48000, latency, NULL, read_callback, &input_device); struct SoundIoOutputDevice *output_device; - soundio_output_device_create(out_device, SoundIoSampleFormatFloat, 48000, latency, NULL, + soundio_output_device_create(out_device, SoundIoSampleFormatFloat32NE, 48000, latency, NULL, write_callback, underrun_callback, &output_device); if ((err = soundio_input_device_start(input_device))) diff --git a/example/sine.c b/example/sine.c index 8e2c0f8..586a3d0 100644 --- a/example/sine.c +++ b/example/sine.c @@ -90,7 +90,7 @@ int main(int argc, char **argv) { soundio_device_description(device)); struct SoundIoOutputDevice *output_device; - soundio_output_device_create(device, SoundIoSampleFormatFloat, 48000, + soundio_output_device_create(device, SoundIoSampleFormatFloat32NE, 48000, 0.1, NULL, write_callback, underrun_callback, &output_device); if ((err = soundio_output_device_start(output_device))) diff --git a/src/dummy.cpp b/src/dummy.cpp index abc6ece..d1ed371 100644 --- a/src/dummy.cpp +++ b/src/dummy.cpp @@ -295,7 +295,7 @@ int soundio_dummy_init(SoundIo *soundio) { return SoundIoErrorNoMem; } device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono); - device->default_sample_format = SoundIoSampleFormatFloat; + device->default_sample_format = SoundIoSampleFormatFloat32NE; device->default_latency = 0.01; device->sample_rate_default = 48000; device->purpose = SoundIoDevicePurposeOutput; @@ -325,7 +325,7 @@ int soundio_dummy_init(SoundIo *soundio) { return SoundIoErrorNoMem; } device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono); - device->default_sample_format = SoundIoSampleFormatFloat; + device->default_sample_format = SoundIoSampleFormatFloat32NE; device->default_latency = 0.01; device->sample_rate_default = 48000; device->purpose = SoundIoDevicePurposeInput; diff --git a/src/os.hpp b/src/os.hpp index b86554a..7e105e2 100644 --- a/src/os.hpp +++ b/src/os.hpp @@ -11,7 +11,6 @@ #include #include - // safe to call from any thread(s) multiple times, but // must be called at least once before calling any other os functions void soundio_os_init(void); diff --git a/src/pulseaudio.cpp b/src/pulseaudio.cpp index 2b6d536..032991f 100644 --- a/src/pulseaudio.cpp +++ b/src/pulseaudio.cpp @@ -138,14 +138,28 @@ static double usec_to_sec(pa_usec_t usec) { return (double)usec / (double)PA_USEC_PER_SEC; } + static SoundIoSampleFormat sample_format_from_pulseaudio(pa_sample_spec sample_spec) { switch (sample_spec.format) { - case PA_SAMPLE_U8: return SoundIoSampleFormatUInt8; - case PA_SAMPLE_S16NE: return SoundIoSampleFormatInt16; - case PA_SAMPLE_S32NE: return SoundIoSampleFormatInt32; - case PA_SAMPLE_FLOAT32NE: return SoundIoSampleFormatFloat; - default: return SoundIoSampleFormatInvalid; + case PA_SAMPLE_U8: return SoundIoSampleFormatU8; + case PA_SAMPLE_S16LE: return SoundIoSampleFormatS16LE; + case PA_SAMPLE_S16BE: return SoundIoSampleFormatS16BE; + case PA_SAMPLE_FLOAT32LE: return SoundIoSampleFormatFloat32LE; + case PA_SAMPLE_FLOAT32BE: return SoundIoSampleFormatFloat32BE; + case PA_SAMPLE_S32LE: return SoundIoSampleFormatS32LE; + case PA_SAMPLE_S32BE: return SoundIoSampleFormatS32BE; + case PA_SAMPLE_S24_32LE: return SoundIoSampleFormatS24LE; + case PA_SAMPLE_S24_32BE: return SoundIoSampleFormatS24BE; + + case PA_SAMPLE_MAX: + case PA_SAMPLE_INVALID: + case PA_SAMPLE_ALAW: + case PA_SAMPLE_ULAW: + case PA_SAMPLE_S24LE: + case PA_SAMPLE_S24BE: + return SoundIoSampleFormatInvalid; } + return SoundIoSampleFormatInvalid; } static int sample_rate_from_pulseaudio(pa_sample_spec sample_spec) { @@ -425,22 +439,29 @@ static void wakeup(SoundIo *soundio) { static pa_sample_format_t to_pulseaudio_sample_format(SoundIoSampleFormat sample_format) { switch (sample_format) { - case SoundIoSampleFormatUInt8: - return PA_SAMPLE_U8; - case SoundIoSampleFormatInt16: - return PA_SAMPLE_S16NE; - case SoundIoSampleFormatInt24: - return PA_SAMPLE_S24NE; - case SoundIoSampleFormatInt32: - return PA_SAMPLE_S32NE; - case SoundIoSampleFormatFloat: - return PA_SAMPLE_FLOAT32NE; - case SoundIoSampleFormatDouble: - soundio_panic("cannot use double sample format with pulseaudio"); + case SoundIoSampleFormatU8: return PA_SAMPLE_U8; + case SoundIoSampleFormatS16LE: return PA_SAMPLE_S16LE; + case SoundIoSampleFormatS16BE: return PA_SAMPLE_S16BE; + case SoundIoSampleFormatS24LE: return PA_SAMPLE_S24_32LE; + case SoundIoSampleFormatS24BE: return PA_SAMPLE_S24_32BE; + case SoundIoSampleFormatS32LE: return PA_SAMPLE_S32LE; + case SoundIoSampleFormatS32BE: return PA_SAMPLE_S32BE; + case SoundIoSampleFormatFloat32LE: return PA_SAMPLE_FLOAT32LE; + case SoundIoSampleFormatFloat32BE: return PA_SAMPLE_FLOAT32BE; + case SoundIoSampleFormatInvalid: - soundio_panic("invalid sample format"); + case SoundIoSampleFormatS8: + case SoundIoSampleFormatU16LE: + case SoundIoSampleFormatU16BE: + case SoundIoSampleFormatU24LE: + case SoundIoSampleFormatU24BE: + case SoundIoSampleFormatU32LE: + case SoundIoSampleFormatU32BE: + case SoundIoSampleFormatFloat64LE: + case SoundIoSampleFormatFloat64BE: + return PA_SAMPLE_INVALID; } - soundio_panic("invalid sample format"); + return PA_SAMPLE_INVALID; } static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_id) { diff --git a/src/soundio.cpp b/src/soundio.cpp index 2c1f2b0..0b58840 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -35,32 +35,55 @@ const char *soundio_error_string(int error) { int soundio_get_bytes_per_sample(enum SoundIoSampleFormat sample_format) { switch (sample_format) { - case SoundIoSampleFormatUInt8: return 1; - case SoundIoSampleFormatInt16: return 2; - case SoundIoSampleFormatInt24: return 3; - case SoundIoSampleFormatInt32: return 4; - case SoundIoSampleFormatFloat: return 4; - case SoundIoSampleFormatDouble: return 8; - case SoundIoSampleFormatInvalid: soundio_panic("invalid sample format"); + case SoundIoSampleFormatInvalid: soundio_panic("invalid sample format"); + case SoundIoSampleFormatU8: return 1; + case SoundIoSampleFormatS8: return 1; + case SoundIoSampleFormatS16LE: return 2; + case SoundIoSampleFormatS16BE: return 2; + case SoundIoSampleFormatU16LE: return 2; + case SoundIoSampleFormatU16BE: return 2; + case SoundIoSampleFormatS24LE: return 4; + case SoundIoSampleFormatS24BE: return 4; + case SoundIoSampleFormatU24LE: return 4; + case SoundIoSampleFormatU24BE: return 4; + case SoundIoSampleFormatS32LE: return 4; + case SoundIoSampleFormatS32BE: return 4; + case SoundIoSampleFormatU32LE: return 4; + case SoundIoSampleFormatU32BE: return 4; + case SoundIoSampleFormatFloat32LE: return 4; + case SoundIoSampleFormatFloat32BE: return 4; + case SoundIoSampleFormatFloat64LE: return 8; + case SoundIoSampleFormatFloat64BE: return 8; } soundio_panic("invalid sample format"); } const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format) { switch (sample_format) { - case SoundIoSampleFormatUInt8: return "unsigned 8-bit integer"; - case SoundIoSampleFormatInt16: return "signed 16-bit integer"; - case SoundIoSampleFormatInt24: return "signed 24-bit integer"; - case SoundIoSampleFormatInt32: return "signed 32-bit integer"; - case SoundIoSampleFormatFloat: return "32-bit float"; - case SoundIoSampleFormatDouble: return "64-bit float"; - case SoundIoSampleFormatInvalid: return "invalid sample format"; + case SoundIoSampleFormatInvalid: return "(invalid sample format)"; + case SoundIoSampleFormatU8: return "signed 8-bit"; + case SoundIoSampleFormatS8: return "unsigned 8-bit"; + case SoundIoSampleFormatS16LE: return "signed 16-bit LE"; + case SoundIoSampleFormatS16BE: return "signed 16-bit BE"; + case SoundIoSampleFormatU16LE: return "unsigned 16-bit LE"; + case SoundIoSampleFormatU16BE: return "unsigned 16-bit LE"; + case SoundIoSampleFormatS24LE: return "signed 24-bit LE"; + case SoundIoSampleFormatS24BE: return "signed 24-bit BE"; + case SoundIoSampleFormatU24LE: return "unsigned 24-bit LE"; + case SoundIoSampleFormatU24BE: return "unsigned 24-bit BE"; + case SoundIoSampleFormatS32LE: return "signed 32-bit LE"; + case SoundIoSampleFormatS32BE: return "signed 32-bit BE"; + case SoundIoSampleFormatU32LE: return "unsigned 32-bit LE"; + case SoundIoSampleFormatU32BE: return "unsigned 32-bit BE"; + case SoundIoSampleFormatFloat32LE: return "float 32-bit LE"; + case SoundIoSampleFormatFloat32BE: return "float 32-bit BE"; + case SoundIoSampleFormatFloat64LE: return "float 64-bit LE"; + case SoundIoSampleFormatFloat64BE: return "float 64-bit BE"; } - soundio_panic("invalid sample format"); + return "(invalid sample format)"; } - const char *soundio_backend_name(enum SoundIoBackend backend) { switch (backend) { case SoundIoBackendNone: return "(none)"; diff --git a/src/soundio.h b/src/soundio.h index 35826b9..7cfb880 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -11,6 +11,30 @@ #include "config.h" #include +#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ + defined(__BIG_ENDIAN__) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) + +#define SOUNDIO_OS_BIG_ENDIAN + +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + defined(__LITTLE_ENDIAN__) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ + defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \ + defined(_WIN32) + +#define SOUNDIO_OS_LITTLE_ENDIAN + +#else +#error unknown byte order +#endif + + #ifdef __cplusplus extern "C" { @@ -116,17 +140,48 @@ enum SoundIoDevicePurpose { SoundIoDevicePurposeOutput, }; -// always native-endian enum SoundIoSampleFormat { - SoundIoSampleFormatUInt8, - SoundIoSampleFormatInt16, - SoundIoSampleFormatInt24, - SoundIoSampleFormatInt32, - SoundIoSampleFormatFloat, - SoundIoSampleFormatDouble, SoundIoSampleFormatInvalid, + SoundIoSampleFormatU8, // Signed 8 bit + SoundIoSampleFormatS8, // Unsigned 8 bit + SoundIoSampleFormatS16LE, // Signed 16 bit Little Endian + SoundIoSampleFormatS16BE, // Signed 16 bit Big Endian + SoundIoSampleFormatU16LE, // Unsigned 16 bit Little Endian + SoundIoSampleFormatU16BE, // Unsigned 16 bit Little Endian + SoundIoSampleFormatS24LE, // Signed 24 bit Little Endian using low three bytes in 32-bit word + SoundIoSampleFormatS24BE, // Signed 24 bit Big Endian using low three bytes in 32-bit word + SoundIoSampleFormatU24LE, // Unsigned 24 bit Little Endian using low three bytes in 32-bit word + SoundIoSampleFormatU24BE, // Unsigned 24 bit Big Endian using low three bytes in 32-bit word + SoundIoSampleFormatS32LE, // Signed 32 bit Little Endian + SoundIoSampleFormatS32BE, // Signed 32 bit Big Endian + SoundIoSampleFormatU32LE, // Unsigned 32 bit Little Endian + SoundIoSampleFormatU32BE, // Unsigned 32 bit Big Endian + SoundIoSampleFormatFloat32LE, // Float 32 bit Little Endian, Range -1.0 to 1.0 + SoundIoSampleFormatFloat32BE, // Float 32 bit Big Endian, Range -1.0 to 1.0 + SoundIoSampleFormatFloat64LE, // Float 64 bit Little Endian, Range -1.0 to 1.0 + SoundIoSampleFormatFloat64BE, // Float 64 bit Big Endian, Range -1.0 to 1.0 }; +#if defined(SOUNDIO_OS_BIG_ENDIAN) +#define SoundIoSampleFormatS16NE SoundIoSampleFormatS16BE +#define SoundIoSampleFormatU16NE SoundIoSampleFormatU16BE +#define SoundIoSampleFormatS24NE SoundIoSampleFormatS24BE +#define SoundIoSampleFormatU24NE SoundIoSampleFormatU24BE +#define SoundIoSampleFormatS32NE SoundIoSampleFormatS32BE +#define SoundIoSampleFormatU32NE SoundIoSampleFormatU32BE +#define SoundIoSampleFormatFloat32NE SoundIoSampleFormatFloat32BE +#define SoundIoSampleFormatFloat64NE SoundIoSampleFormatFloat64BE +#elif defined(SOUNDIO_OS_LITTLE_ENDIAN) +#define SoundIoSampleFormatS16NE SoundIoSampleFormatS16LE +#define SoundIoSampleFormatU16NE SoundIoSampleFormatU16LE +#define SoundIoSampleFormatS24NE SoundIoSampleFormatS24LE +#define SoundIoSampleFormatU24NE SoundIoSampleFormatU24LE +#define SoundIoSampleFormatS32NE SoundIoSampleFormatS32LE +#define SoundIoSampleFormatU32NE SoundIoSampleFormatU32LE +#define SoundIoSampleFormatFloat32NE SoundIoSampleFormatFloat32LE +#define SoundIoSampleFormatFloat64NE SoundIoSampleFormatFloat64LE +#endif + struct SoundIoDevice { struct SoundIo *soundio; char *name; @@ -276,6 +331,7 @@ const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format + // Devices // returns -1 on error diff --git a/test/unit_tests.cpp b/test/unit_tests.cpp index ec58133..962d721 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.cpp @@ -37,7 +37,7 @@ static void test_create_output_device(void) { soundio_device_name(device); soundio_device_description(device); struct SoundIoOutputDevice *output_device; - soundio_output_device_create(device, SoundIoSampleFormatFloat, 48000, 0.1, NULL, + soundio_output_device_create(device, SoundIoSampleFormatFloat32NE, 48000, 0.1, NULL, write_callback, underrun_callback, &output_device); soundio_output_device_destroy(output_device); soundio_device_unref(device);