diff --git a/example/microphone.c b/example/microphone.c index 7f05a6d..36efd88 100644 --- a/example/microphone.c +++ b/example/microphone.c @@ -13,6 +13,28 @@ #include #include +static enum SoundIoFormat prioritized_formats[] = { + SoundIoFormatFloat32NE, + SoundIoFormatFloat32FE, + SoundIoFormatS32NE, + SoundIoFormatS32FE, + SoundIoFormatS24NE, + SoundIoFormatS24FE, + SoundIoFormatS16NE, + SoundIoFormatS16FE, + SoundIoFormatFloat64NE, + SoundIoFormatFloat64FE, + SoundIoFormatU32NE, + SoundIoFormatU32FE, + SoundIoFormatU24NE, + SoundIoFormatU24FE, + SoundIoFormatU16NE, + SoundIoFormatU16FE, + SoundIoFormatS8, + SoundIoFormatU8, + SoundIoFormatInvalid, +}; + __attribute__ ((cold)) __attribute__ ((noreturn)) __attribute__ ((format (printf, 1, 2))) @@ -75,11 +97,29 @@ int main(int argc, char **argv) { if (!layout) panic("channel layouts not compatible"); + + int sample_rate = 48000; + if (in_device->sample_rate_max < sample_rate) sample_rate = in_device->sample_rate_max; + if (out_device->sample_rate_max < sample_rate) sample_rate = out_device->sample_rate_max; + if (in_device->sample_rate_min > sample_rate || out_device->sample_rate_min > sample_rate) + panic("incompatible sample rates"); + + enum SoundIoFormat *fmt; + for (fmt = prioritized_formats; *fmt != SoundIoFormatInvalid; fmt += 1) { + if (soundio_device_supports_format(in_device, *fmt) && + soundio_device_supports_format(out_device, *fmt)) + { + break; + } + } + if (*fmt == SoundIoFormatInvalid) + panic("incompatible sample formats"); + struct SoundIoInStream *instream = soundio_instream_create(in_device); if (!instream) panic("out of memory"); - instream->format = SoundIoFormatFloat32NE; // TODO pick compatible ones - instream->sample_rate = 48000; // TODO pick compatible ones + instream->format = *fmt; + instream->sample_rate = sample_rate; instream->layout = *layout; instream->latency = 0.1; instream->read_callback = read_callback; @@ -90,8 +130,8 @@ int main(int argc, char **argv) { struct SoundIoOutStream *outstream = soundio_outstream_create(out_device); if (!outstream) panic("out of memory"); - outstream->format = SoundIoFormatFloat32NE; - outstream->sample_rate = 48000; + outstream->format = *fmt; + outstream->sample_rate = sample_rate; outstream->layout = *layout; outstream->latency = 0.1; outstream->write_callback = write_callback; diff --git a/example/sine.c b/example/sine.c index da1aafb..e6e800f 100644 --- a/example/sine.c +++ b/example/sine.c @@ -27,9 +27,9 @@ static void panic(const char *format, ...) { static const float PI = 3.1415926535f; static float seconds_offset = 0.0f; +static int target_sample_rate = 48000; static void write_callback(struct SoundIoOutStream *outstream, int requested_frame_count) { - //device->bytes_per_frame; float float_sample_rate = outstream->sample_rate; float seconds_per_frame = 1.0f / float_sample_rate; @@ -89,7 +89,8 @@ int main(int argc, char **argv) { struct SoundIoOutStream *outstream = soundio_outstream_create(device); outstream->format = SoundIoFormatFloat32NE; - outstream->sample_rate = 48000; // TODO let this be anything + outstream->sample_rate = (device->sample_rate_min <= target_sample_rate && + target_sample_rate <= device->sample_rate_max) ? target_sample_rate : device->sample_rate_max; outstream->layout = device->layouts[0]; outstream->latency = 0.1; outstream->write_callback = write_callback; diff --git a/src/soundio.cpp b/src/soundio.cpp index 9647d79..f74cc4e 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -535,3 +535,11 @@ void soundio_sort_channel_layouts(struct SoundIoChannelLayout *layouts, int layo void soundio_device_sort_channel_layouts(struct SoundIoDevice *device) { soundio_sort_channel_layouts(device->layouts, device->layout_count); } + +bool soundio_device_supports_format(struct SoundIoDevice *device, enum SoundIoFormat format) { + for (int i = 0; i < device->format_count; i += 1) { + if (device->formats[i] == format) + return true; + } + return false; +} diff --git a/src/soundio.h b/src/soundio.h index 5df6db9..8c5408a 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -131,6 +131,9 @@ enum SoundIoFormat { SoundIoFormatFloat64BE, // Float 64 bit Big Endian, Range -1.0 to 1.0 }; +// For your convenience, Native Endian and Foreign Endian constants are defined +// which point to the respective SoundIoFormat values. + #if defined(SOUNDIO_OS_BIG_ENDIAN) #define SoundIoFormatS16NE SoundIoFormatS16BE #define SoundIoFormatU16NE SoundIoFormatU16BE @@ -140,7 +143,18 @@ enum SoundIoFormat { #define SoundIoFormatU32NE SoundIoFormatU32BE #define SoundIoFormatFloat32NE SoundIoFormatFloat32BE #define SoundIoFormatFloat64NE SoundIoFormatFloat64BE + +#define SoundIoFormatS16FE SoundIoFormatS16LE +#define SoundIoFormatU16FE SoundIoFormatU16LE +#define SoundIoFormatS24FE SoundIoFormatS24LE +#define SoundIoFormatU24FE SoundIoFormatU24LE +#define SoundIoFormatS32FE SoundIoFormatS32LE +#define SoundIoFormatU32FE SoundIoFormatU32LE +#define SoundIoFormatFloat32FE SoundIoFormatFloat32LE +#define SoundIoFormatFloat64FE SoundIoFormatFloat64LE + #elif defined(SOUNDIO_OS_LITTLE_ENDIAN) + #define SoundIoFormatS16NE SoundIoFormatS16LE #define SoundIoFormatU16NE SoundIoFormatU16LE #define SoundIoFormatS24NE SoundIoFormatS24LE @@ -149,6 +163,16 @@ enum SoundIoFormat { #define SoundIoFormatU32NE SoundIoFormatU32LE #define SoundIoFormatFloat32NE SoundIoFormatFloat32LE #define SoundIoFormatFloat64NE SoundIoFormatFloat64LE + +#define SoundIoFormatS16FE SoundIoFormatS16BE +#define SoundIoFormatU16FE SoundIoFormatU16BE +#define SoundIoFormatS24FE SoundIoFormatS24BE +#define SoundIoFormatU24FE SoundIoFormatU24BE +#define SoundIoFormatS32FE SoundIoFormatS32BE +#define SoundIoFormatU32FE SoundIoFormatU32BE +#define SoundIoFormatFloat32FE SoundIoFormatFloat32BE +#define SoundIoFormatFloat64FE SoundIoFormatFloat64BE + #else #error unknown byte order #endif @@ -388,6 +412,9 @@ enum SoundIoDevicePurpose soundio_device_purpose(const struct SoundIoDevice *dev // Sorts channel layouts by channel count, descending. void soundio_device_sort_channel_layouts(struct SoundIoDevice *device); +// Returns whether `format` is included in the devices supported formats. +bool soundio_device_supports_format(struct SoundIoDevice *device, enum SoundIoFormat format); + // Output Streams