examples are smarter about device parameters

This commit is contained in:
Andrew Kelley 2015-07-13 09:59:42 -07:00
parent 5b3fd175f8
commit 59026ccba7
4 changed files with 82 additions and 6 deletions

View file

@ -13,6 +13,28 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
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__ ((cold))
__attribute__ ((noreturn)) __attribute__ ((noreturn))
__attribute__ ((format (printf, 1, 2))) __attribute__ ((format (printf, 1, 2)))
@ -75,11 +97,29 @@ int main(int argc, char **argv) {
if (!layout) if (!layout)
panic("channel layouts not compatible"); 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); struct SoundIoInStream *instream = soundio_instream_create(in_device);
if (!instream) if (!instream)
panic("out of memory"); panic("out of memory");
instream->format = SoundIoFormatFloat32NE; // TODO pick compatible ones instream->format = *fmt;
instream->sample_rate = 48000; // TODO pick compatible ones instream->sample_rate = sample_rate;
instream->layout = *layout; instream->layout = *layout;
instream->latency = 0.1; instream->latency = 0.1;
instream->read_callback = read_callback; instream->read_callback = read_callback;
@ -90,8 +130,8 @@ int main(int argc, char **argv) {
struct SoundIoOutStream *outstream = soundio_outstream_create(out_device); struct SoundIoOutStream *outstream = soundio_outstream_create(out_device);
if (!outstream) if (!outstream)
panic("out of memory"); panic("out of memory");
outstream->format = SoundIoFormatFloat32NE; outstream->format = *fmt;
outstream->sample_rate = 48000; outstream->sample_rate = sample_rate;
outstream->layout = *layout; outstream->layout = *layout;
outstream->latency = 0.1; outstream->latency = 0.1;
outstream->write_callback = write_callback; outstream->write_callback = write_callback;

View file

@ -27,9 +27,9 @@ static void panic(const char *format, ...) {
static const float PI = 3.1415926535f; static const float PI = 3.1415926535f;
static float seconds_offset = 0.0f; static float seconds_offset = 0.0f;
static int target_sample_rate = 48000;
static void write_callback(struct SoundIoOutStream *outstream, int requested_frame_count) { static void write_callback(struct SoundIoOutStream *outstream, int requested_frame_count) {
//device->bytes_per_frame;
float float_sample_rate = outstream->sample_rate; float float_sample_rate = outstream->sample_rate;
float seconds_per_frame = 1.0f / float_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); struct SoundIoOutStream *outstream = soundio_outstream_create(device);
outstream->format = SoundIoFormatFloat32NE; 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->layout = device->layouts[0];
outstream->latency = 0.1; outstream->latency = 0.1;
outstream->write_callback = write_callback; outstream->write_callback = write_callback;

View file

@ -535,3 +535,11 @@ void soundio_sort_channel_layouts(struct SoundIoChannelLayout *layouts, int layo
void soundio_device_sort_channel_layouts(struct SoundIoDevice *device) { void soundio_device_sort_channel_layouts(struct SoundIoDevice *device) {
soundio_sort_channel_layouts(device->layouts, device->layout_count); 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;
}

View file

@ -131,6 +131,9 @@ enum SoundIoFormat {
SoundIoFormatFloat64BE, // Float 64 bit Big Endian, Range -1.0 to 1.0 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) #if defined(SOUNDIO_OS_BIG_ENDIAN)
#define SoundIoFormatS16NE SoundIoFormatS16BE #define SoundIoFormatS16NE SoundIoFormatS16BE
#define SoundIoFormatU16NE SoundIoFormatU16BE #define SoundIoFormatU16NE SoundIoFormatU16BE
@ -140,7 +143,18 @@ enum SoundIoFormat {
#define SoundIoFormatU32NE SoundIoFormatU32BE #define SoundIoFormatU32NE SoundIoFormatU32BE
#define SoundIoFormatFloat32NE SoundIoFormatFloat32BE #define SoundIoFormatFloat32NE SoundIoFormatFloat32BE
#define SoundIoFormatFloat64NE SoundIoFormatFloat64BE #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) #elif defined(SOUNDIO_OS_LITTLE_ENDIAN)
#define SoundIoFormatS16NE SoundIoFormatS16LE #define SoundIoFormatS16NE SoundIoFormatS16LE
#define SoundIoFormatU16NE SoundIoFormatU16LE #define SoundIoFormatU16NE SoundIoFormatU16LE
#define SoundIoFormatS24NE SoundIoFormatS24LE #define SoundIoFormatS24NE SoundIoFormatS24LE
@ -149,6 +163,16 @@ enum SoundIoFormat {
#define SoundIoFormatU32NE SoundIoFormatU32LE #define SoundIoFormatU32NE SoundIoFormatU32LE
#define SoundIoFormatFloat32NE SoundIoFormatFloat32LE #define SoundIoFormatFloat32NE SoundIoFormatFloat32LE
#define SoundIoFormatFloat64NE SoundIoFormatFloat64LE #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 #else
#error unknown byte order #error unknown byte order
#endif #endif
@ -388,6 +412,9 @@ enum SoundIoDevicePurpose soundio_device_purpose(const struct SoundIoDevice *dev
// Sorts channel layouts by channel count, descending. // Sorts channel layouts by channel count, descending.
void soundio_device_sort_channel_layouts(struct SoundIoDevice *device); 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 // Output Streams