mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 03:05:37 +00:00
WASAPI: fix device cleanup segfault
This commit is contained in:
parent
aef877fe48
commit
a05e0e283e
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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, ¤t_min, last_success_rate))) {
|
if ((err = add_sample_rate(&dev->sample_rates, ¤t_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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue