WASAPI: fix device cleanup segfault

This commit is contained in:
Andrew Kelley 2015-08-21 13:08:11 -07:00
parent aef877fe48
commit a05e0e283e
5 changed files with 36 additions and 19 deletions

View file

@ -14,7 +14,7 @@
// list or keep a watch on audio devices // list or keep a watch on audio devices
static int usage(char *exe) { static int usage(char *exe) {
fprintf(stderr, "Usage: %s [--watch] [--dummy] [--alsa] [--pulseaudio] [--jack]\n", exe); fprintf(stderr, "Usage: %s [--watch] [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi]\n", exe);
return 1; return 1;
} }
@ -114,14 +114,30 @@ int main(int argc, char **argv) {
char *arg = argv[i]; char *arg = argv[i];
if (strcmp("--watch", arg) == 0) { if (strcmp("--watch", arg) == 0) {
watch = true; watch = true;
} else if (strcmp("--dummy", arg) == 0) { } else if (arg[0] == '-' && arg[1] == '-') {
i += 1;
if (i >= argc) {
return usage(exe);
} else if (strcmp(arg, "--backend") == 0) {
if (strcmp("-dummy", argv[i]) == 0) {
backend = SoundIoBackendDummy; backend = SoundIoBackendDummy;
} else if (strcmp("--alsa", arg) == 0) { } else if (strcmp("alsa", argv[i]) == 0) {
backend = SoundIoBackendAlsa; backend = SoundIoBackendAlsa;
} else if (strcmp("--pulseaudio", arg) == 0) { } else if (strcmp("pulseaudio", argv[i]) == 0) {
backend = SoundIoBackendPulseAudio; backend = SoundIoBackendPulseAudio;
} else if (strcmp("--jack", arg) == 0) { } else if (strcmp("jack", argv[i]) == 0) {
backend = SoundIoBackendJack; backend = SoundIoBackendJack;
} else if (strcmp("coreaudio", argv[i]) == 0) {
backend = SoundIoBackendCoreAudio;
} else if (strcmp("wasapi", argv[i]) == 0) {
backend = SoundIoBackendWasapi;
} else {
fprintf(stderr, "Invalid backend: %s\n", argv[i]);
return 1;
}
} else {
return usage(exe);
}
} else { } else {
return usage(exe); return usage(exe);
} }

View file

@ -375,8 +375,12 @@ void soundio_device_unref(struct SoundIoDevice *device) {
free(device->id); free(device->id);
free(device->name); free(device->name);
if (device->sample_rates != &dev->prealloc_sample_rate_range) if (device->sample_rates != &dev->prealloc_sample_rate_range &&
device->sample_rates != dev->sample_rates.items)
{
free(device->sample_rates); free(device->sample_rates);
}
dev->sample_rates.deinit();
if (device->formats != &dev->prealloc_format) if (device->formats != &dev->prealloc_format)
free(device->formats); free(device->formats);

View file

@ -164,6 +164,7 @@ struct SoundIoDevicePrivate {
SoundIoDeviceBackendData backend_data; SoundIoDeviceBackendData backend_data;
void (*destruct)(SoundIoDevicePrivate *); void (*destruct)(SoundIoDevicePrivate *);
SoundIoSampleRateRange prealloc_sample_rate_range; SoundIoSampleRateRange prealloc_sample_rate_range;
SoundIoList<SoundIoSampleRateRange> sample_rates;
SoundIoFormat prealloc_format; SoundIoFormat prealloc_format;
}; };

View file

@ -295,7 +295,6 @@ static void destruct_device(SoundIoDevicePrivate *dev) {
SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi;
if (dw->mm_device) if (dw->mm_device)
IMMDevice_Release(dw->mm_device); IMMDevice_Release(dw->mm_device);
dw->sample_rates.deinit();
} }
struct RefreshDevices { struct RefreshDevices {
@ -438,7 +437,6 @@ static int add_sample_rate(SoundIoList<SoundIoSampleRateRange> *sample_rates, in
static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WAVEFORMATEXTENSIBLE *wave_format, static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WAVEFORMATEXTENSIBLE *wave_format,
int test_sample_rate, AUDCLNT_SHAREMODE share_mode, int *current_min, int *last_success_rate) int test_sample_rate, AUDCLNT_SHAREMODE share_mode, int *current_min, int *last_success_rate)
{ {
SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi;
WAVEFORMATEX *closest_match = nullptr; WAVEFORMATEX *closest_match = nullptr;
int err; int err;
@ -456,7 +454,7 @@ static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WA
*last_success_rate = test_sample_rate; *last_success_rate = test_sample_rate;
} else if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == S_FALSE || hr == E_INVALIDARG) { } else if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == S_FALSE || hr == E_INVALIDARG) {
if (*current_min != -1) { if (*current_min != -1) {
if ((err = add_sample_rate(&dw->sample_rates, current_min, *last_success_rate))) if ((err = add_sample_rate(&dev->sample_rates, current_min, *last_success_rate)))
return err; return err;
*current_min = -1; *current_min = -1;
} }
@ -470,12 +468,11 @@ static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WA
static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format,
SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode)
{ {
SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi;
int err; int err;
DWORD orig_sample_rate = wave_format->Format.nSamplesPerSec; DWORD orig_sample_rate = wave_format->Format.nSamplesPerSec;
assert(dw->sample_rates.length == 0); assert(dev->sample_rates.length == 0);
int current_min = -1; int current_min = -1;
int last_success_rate = -1; int last_success_rate = -1;
@ -492,7 +489,7 @@ static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *w
} }
if (current_min != -1) { if (current_min != -1) {
if ((err = add_sample_rate(&dw->sample_rates, &current_min, last_success_rate))) { if ((err = add_sample_rate(&dev->sample_rates, &current_min, last_success_rate))) {
wave_format->Format.nSamplesPerSec = orig_sample_rate; wave_format->Format.nSamplesPerSec = orig_sample_rate;
return err; return err;
} }
@ -500,8 +497,8 @@ static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *w
SoundIoDevice *device = &dev->pub; SoundIoDevice *device = &dev->pub;
device->sample_rate_count = dw->sample_rates.length; device->sample_rate_count = dev->sample_rates.length;
device->sample_rates = dw->sample_rates.items; device->sample_rates = dev->sample_rates.items;
wave_format->Format.nSamplesPerSec = orig_sample_rate; wave_format->Format.nSamplesPerSec = orig_sample_rate;
return 0; return 0;

View file

@ -27,7 +27,6 @@
int soundio_wasapi_init(struct SoundIoPrivate *si); int soundio_wasapi_init(struct SoundIoPrivate *si);
struct SoundIoDeviceWasapi { struct SoundIoDeviceWasapi {
SoundIoList<SoundIoSampleRateRange> sample_rates;
double period_duration; double period_duration;
IMMDevice *mm_device; IMMDevice *mm_device;
}; };