sample formats: take into account ALSA

This commit is contained in:
Andrew Kelley 2015-07-10 00:46:03 -07:00
parent fe2040da7c
commit 8887a528ef
8 changed files with 148 additions and 49 deletions

View file

@ -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)))

View file

@ -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)))

View file

@ -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;

View file

@ -11,7 +11,6 @@
#include <stdbool.h>
#include <stddef.h>
// 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);

View file

@ -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) {

View file

@ -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 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)";

View file

@ -11,6 +11,30 @@
#include "config.h"
#include <stdbool.h>
#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

View file

@ -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);