fix and add test for soundio_device_nearest_sample_rate

This commit is contained in:
Andrew Kelley 2015-09-18 22:08:36 -07:00
parent a9e455aec8
commit be6e654098
2 changed files with 46 additions and 10 deletions

View file

@ -763,21 +763,29 @@ bool soundio_device_supports_sample_rate(struct SoundIoDevice *device, int sampl
return false; return false;
} }
static int abs_diff_int(int a, int b) {
int x = a - b;
return (x >= 0) ? x : -x;
}
int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, int sample_rate) { int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, int sample_rate) {
int best_rate = -1; int best_rate = -1;
int best_delta = -1; int best_delta = -1;
for (int i = 0; i < device->sample_rate_count; i += 1) { for (int i = 0; i < device->sample_rate_count; i += 1) {
SoundIoSampleRateRange *range = &device->sample_rates[i]; SoundIoSampleRateRange *range = &device->sample_rates[i];
if (sample_rate < range->min) { int candidate_rate = clamp(range->min, sample_rate, range->max);
int delta = range->min - sample_rate; if (candidate_rate == sample_rate)
if (best_delta == -1 || delta < best_delta) { return candidate_rate;
int delta = abs_diff_int(candidate_rate, sample_rate);
bool best_rate_too_small = best_rate < sample_rate;
bool candidate_rate_too_small = candidate_rate < sample_rate;
if (best_rate == -1 ||
(best_rate_too_small && !candidate_rate_too_small) ||
((best_rate_too_small || !candidate_rate_too_small) && delta < best_delta))
{
best_rate = candidate_rate;
best_delta = delta; best_delta = delta;
best_rate = range->min;
}
} else if (best_rate == -1 && sample_rate > range->max) {
best_rate = range->max;
} else {
return sample_rate;
} }
} }
return best_rate; return best_rate;

View file

@ -183,6 +183,33 @@ static void test_mirrored_memory(void) {
soundio_os_deinit_mirrored_memory(&mem); soundio_os_deinit_mirrored_memory(&mem);
} }
static void test_nearest_sample_rate(void) {
struct SoundIoDevice device;
struct SoundIoSampleRateRange sample_rates[2] = {
{
44100,
48000
},
{
96000,
96000,
},
};
device.sample_rate_count = 2;
device.sample_rates = sample_rates;
assert(soundio_device_nearest_sample_rate(&device, 100) == 44100);
assert(soundio_device_nearest_sample_rate(&device, 44099) == 44100);
assert(soundio_device_nearest_sample_rate(&device, 44100) == 44100);
assert(soundio_device_nearest_sample_rate(&device, 45000) == 45000);
assert(soundio_device_nearest_sample_rate(&device, 48000) == 48000);
assert(soundio_device_nearest_sample_rate(&device, 48001) == 96000);
assert(soundio_device_nearest_sample_rate(&device, 90000) == 96000);
assert(soundio_device_nearest_sample_rate(&device, 96001) == 96000);
assert(soundio_device_nearest_sample_rate(&device, 9999999) == 96000);
}
struct Test { struct Test {
const char *name; const char *name;
void (*fn)(void); void (*fn)(void);
@ -194,6 +221,7 @@ static struct Test tests[] = {
{"ring buffer basic", test_ring_buffer_basic}, {"ring buffer basic", test_ring_buffer_basic},
{"ring buffer threaded", test_ring_buffer_threaded}, {"ring buffer threaded", test_ring_buffer_threaded},
{"mirrored memory", test_mirrored_memory}, {"mirrored memory", test_mirrored_memory},
{"soundio_device_nearest_sample_rate", test_nearest_sample_rate},
{NULL, NULL}, {NULL, NULL},
}; };