Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions example/sio_microphone.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static enum SoundIoFormat prioritized_formats[] = {
SoundIoFormatS32FE,
SoundIoFormatS24NE,
SoundIoFormatS24FE,
SoundIoFormatS24PLE,
SoundIoFormatS16NE,
SoundIoFormatS16FE,
SoundIoFormatFloat64NE,
Expand Down
1 change: 1 addition & 0 deletions example/sio_record.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ static enum SoundIoFormat prioritized_formats[] = {
SoundIoFormatS32NE,
SoundIoFormatS32FE,
SoundIoFormatS24NE,
SoundIoFormatS24PLE,
SoundIoFormatS24FE,
SoundIoFormatS16NE,
SoundIoFormatS16FE,
Expand Down
52 changes: 51 additions & 1 deletion example/sio_sine.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <math.h>

static int usage(char *exe) {
Expand All @@ -33,6 +34,49 @@ static void write_sample_s16ne(char *ptr, double sample) {
*buf = val;
}

/**
* Construct a signed 24 bit integer from three bytes into a int32_t.
*/
static int32_t construct_s24(uint8_t low, uint8_t mid, uint8_t high)
{
return (int32_t)low | ((int32_t)mid << 8) | ((int32_t)high << 16) |
/* extend the sign bit */
(high & 0x80 ? ~(int32_t)0xffffff : 0);
}

/**
* Read a packed signed native-endian 24 bit integer.
*/
static int32_t read_s24(const uint8_t *src)
{
#if defined(SOUNDIO_OS_BIG_ENDIAN)
return construct_s24(src[2], src[1], src[0]);
#elif defined(SOUNDIO_OS_LITTLE_ENDIAN)
return construct_s24(src[0], src[1], src[2]);
#endif
}

static void write_sample_s24ne(char *ptr, double sample) {
const double range = (double)0xFFFFFF;
const double val = sample * range / 2.0;
const int32_t src0 = val;
const int32_t src = read_s24((const uint8_t *)&src0);
int32_t *dest = (int32_t *)ptr;
*dest = src;
}

static void write_sample_s24ple(char *ptr, double sample) {
const double range = 0xFFFFFF;
const double val = sample * range / 2.0;
const int32_t src0 = val;
const uint8_t *src = (const uint8_t *)&src0;
uint8_t *dest = (uint8_t *)ptr;

*dest++ = *src++;
*dest++ = *src++;
*dest++ = *src++;
}

static void write_sample_s32ne(char *ptr, double sample) {
int32_t *buf = (int32_t *)ptr;
double range = (double)INT32_MAX - (double)INT32_MIN;
Expand Down Expand Up @@ -232,7 +276,13 @@ int main(int argc, char **argv) {
} else if (soundio_device_supports_format(device, SoundIoFormatS16NE)) {
outstream->format = SoundIoFormatS16NE;
write_sample = write_sample_s16ne;
} else {
} else if (soundio_device_supports_format(device, SoundIoFormatS24NE)) {
outstream->format = SoundIoFormatS24NE;
write_sample = write_sample_s24ne;
} else if (soundio_device_supports_format(device, SoundIoFormatS24PLE)) {
outstream->format = SoundIoFormatS24PLE;
write_sample = write_sample_s24ple;
}else {
fprintf(stderr, "No suitable device format available.\n");
return 1;
}
Expand Down
1 change: 1 addition & 0 deletions soundio/soundio.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ enum SoundIoFormat {
SoundIoFormatU16BE, ///< Unsigned 16 bit Big 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
SoundIoFormatS24PLE, ///< Signed 24 bit Little Endian packed into 3 bytes
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
Expand Down
5 changes: 4 additions & 1 deletion src/alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ static snd_pcm_format_t to_alsa_fmt(enum SoundIoFormat fmt) {
case SoundIoFormatS24BE: return SND_PCM_FORMAT_S24_BE;
case SoundIoFormatU24LE: return SND_PCM_FORMAT_U24_LE;
case SoundIoFormatU24BE: return SND_PCM_FORMAT_U24_BE;
case SoundIoFormatS24PLE: return SND_PCM_FORMAT_S24_3LE;
case SoundIoFormatS32LE: return SND_PCM_FORMAT_S32_LE;
case SoundIoFormatS32BE: return SND_PCM_FORMAT_S32_BE;
case SoundIoFormatU32LE: return SND_PCM_FORMAT_U32_LE;
Expand Down Expand Up @@ -350,6 +351,7 @@ static int probe_open_device(struct SoundIoDevice *device, snd_pcm_t *handle, in
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_S24_BE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_U24_LE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_U24_BE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_S24_3LE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_S32_LE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_S32_BE);
snd_pcm_format_mask_set(fmt_mask, SND_PCM_FORMAT_U32_LE);
Expand All @@ -364,7 +366,7 @@ static int probe_open_device(struct SoundIoDevice *device, snd_pcm_t *handle, in

if (!device->formats) {
snd_pcm_hw_params_get_format_mask(hwparams, fmt_mask);
device->formats = ALLOCATE(enum SoundIoFormat, 18);
device->formats = ALLOCATE(enum SoundIoFormat, 19);
if (!device->formats)
return SoundIoErrorNoMem;

Expand All @@ -379,6 +381,7 @@ static int probe_open_device(struct SoundIoDevice *device, snd_pcm_t *handle, in
test_fmt_mask(device, fmt_mask, SoundIoFormatS24BE);
test_fmt_mask(device, fmt_mask, SoundIoFormatU24LE);
test_fmt_mask(device, fmt_mask, SoundIoFormatU24BE);
test_fmt_mask(device, fmt_mask, SoundIoFormatS24PLE);
test_fmt_mask(device, fmt_mask, SoundIoFormatS32LE);
test_fmt_mask(device, fmt_mask, SoundIoFormatS32BE);
test_fmt_mask(device, fmt_mask, SoundIoFormatU32LE);
Expand Down
19 changes: 10 additions & 9 deletions src/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int instream_get_latency_dummy(struct SoundIoPrivate *si, struct SoundIoI
}

static int set_all_device_formats(struct SoundIoDevice *device) {
device->format_count = 18;
device->format_count = 19;
device->formats = ALLOCATE(enum SoundIoFormat, device->format_count);
if (!device->formats)
return SoundIoErrorNoMem;
Expand All @@ -395,14 +395,15 @@ static int set_all_device_formats(struct SoundIoDevice *device) {
device->formats[7] = SoundIoFormatS24FE;
device->formats[8] = SoundIoFormatU24NE;
device->formats[9] = SoundIoFormatU24FE;
device->formats[10] = SoundIoFormatFloat64NE;
device->formats[11] = SoundIoFormatFloat64FE;
device->formats[12] = SoundIoFormatS16NE;
device->formats[13] = SoundIoFormatS16FE;
device->formats[14] = SoundIoFormatU16NE;
device->formats[15] = SoundIoFormatU16FE;
device->formats[16] = SoundIoFormatS8;
device->formats[17] = SoundIoFormatU8;
device->formats[10] = SoundIoFormatS24PLE;
device->formats[11] = SoundIoFormatFloat64NE;
device->formats[12] = SoundIoFormatFloat64FE;
device->formats[13] = SoundIoFormatS16NE;
device->formats[14] = SoundIoFormatS16FE;
device->formats[15] = SoundIoFormatU16NE;
device->formats[16] = SoundIoFormatU16FE;
device->formats[11] = SoundIoFormatS8;
device->formats[18] = SoundIoFormatU8;

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/pulseaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ static pa_sample_format_t to_pulseaudio_format(enum SoundIoFormat format) {
case SoundIoFormatS24BE: return PA_SAMPLE_S24_32BE;
case SoundIoFormatS32LE: return PA_SAMPLE_S32LE;
case SoundIoFormatS32BE: return PA_SAMPLE_S32BE;
case SoundIoFormatS24PLE: return PA_SAMPLE_S24LE;
case SoundIoFormatFloat32LE: return PA_SAMPLE_FLOAT32LE;
case SoundIoFormatFloat32BE: return PA_SAMPLE_FLOAT32BE;

Expand Down
2 changes: 2 additions & 0 deletions src/soundio.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ int soundio_get_bytes_per_sample(enum SoundIoFormat format) {
case SoundIoFormatU16BE: return 2;
case SoundIoFormatS24LE: return 4;
case SoundIoFormatS24BE: return 4;
case SoundIoFormatS24PLE: return 3;
case SoundIoFormatU24LE: return 4;
case SoundIoFormatU24BE: return 4;
case SoundIoFormatS32LE: return 4;
Expand All @@ -131,6 +132,7 @@ const char * soundio_format_string(enum SoundIoFormat format) {
case SoundIoFormatU16BE: return "unsigned 16-bit LE";
case SoundIoFormatS24LE: return "signed 24-bit LE";
case SoundIoFormatS24BE: return "signed 24-bit BE";
case SoundIoFormatS24PLE: return "signed 24-bit packed LE";
case SoundIoFormatU24LE: return "unsigned 24-bit LE";
case SoundIoFormatU24BE: return "unsigned 24-bit BE";
case SoundIoFormatS32LE: return "signed 32-bit LE";
Expand Down
1 change: 1 addition & 0 deletions test/overflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static enum SoundIoFormat prioritized_formats[] = {
SoundIoFormatFloat64FE,
SoundIoFormatU32NE,
SoundIoFormatU32FE,
SoundIoFormatS24PLE,
SoundIoFormatU24NE,
SoundIoFormatU24FE,
SoundIoFormatU16NE,
Expand Down