1 /// Translated from C to D 2 module sio_list_devices; 3 4 extern(C): @nogc: nothrow: __gshared: 5 6 import soundio.api; 7 import soundio.util: printf_stderr; 8 9 import core.stdc.stdio; 10 import core.stdc.string; 11 12 // list or keep a watch on audio devices 13 private extern(D) int usage(char* exe) { 14 printf_stderr("Usage: %s [options]\n" 15 ~ "Options:\n" 16 ~ " [--watch]\n" 17 ~ " [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi]\n" 18 ~ " [--short]\n", exe); 19 return 1; 20 } 21 22 private extern(D) void print_channel_layout(const(SoundIoChannelLayout)* layout) { 23 if (layout.name) { 24 printf_stderr("%s", layout.name); 25 } else { 26 printf_stderr("%s", soundio_get_channel_name(layout.channels[0])); 27 for (int i = 1; i < layout.channel_count; i += 1) { 28 printf_stderr(", %s", soundio_get_channel_name(layout.channels[i])); 29 } 30 } 31 } 32 33 private extern(D) bool short_output = false; 34 35 private extern(D) void print_device(SoundIoDevice* device, bool is_default) { 36 const(char)* default_str = is_default ? " (default)" : ""; 37 const(char)* raw_str = device.is_raw ? " (raw)" : ""; 38 printf_stderr("%s%s%s\n", device.name, default_str, raw_str); 39 if (short_output) 40 return; 41 printf_stderr(" id: %s\n", device.id); 42 43 if (device.probe_error) { 44 printf_stderr(" probe error: %s\n", soundio_strerror(device.probe_error)); 45 } else { 46 printf_stderr(" channel layouts:\n"); 47 for (int i = 0; i < device.layout_count; i += 1) { 48 printf_stderr(" "); 49 print_channel_layout(&device.layouts[i]); 50 printf_stderr("\n"); 51 } 52 if (device.current_layout.channel_count > 0) { 53 printf_stderr(" current layout: "); 54 print_channel_layout(&device.current_layout); 55 printf_stderr("\n"); 56 } 57 58 printf_stderr(" sample rates:\n"); 59 for (int i = 0; i < device.sample_rate_count; i += 1) { 60 SoundIoSampleRateRange* range = &device.sample_rates[i]; 61 printf_stderr(" %d - %d\n", range.min, range.max); 62 63 } 64 if (device.sample_rate_current) 65 printf_stderr(" current sample rate: %d\n", device.sample_rate_current); 66 printf_stderr(" formats: "); 67 for (int i = 0; i < device.format_count; i += 1) { 68 const(char)* comma = (i == device.format_count - 1) ? "" : ", "; 69 printf_stderr("%s%s", soundio_format_string(device.formats[i]), comma); 70 } 71 printf_stderr("\n"); 72 if (device.current_format != SoundIoFormat.Invalid) 73 printf_stderr(" current format: %s\n", soundio_format_string(device.current_format)); 74 75 printf_stderr(" min software latency: %0.8f sec\n", device.software_latency_min); 76 printf_stderr(" max software latency: %0.8f sec\n", device.software_latency_max); 77 if (device.software_latency_current != 0.0) 78 printf_stderr(" current software latency: %0.8f sec\n", device.software_latency_current); 79 80 } 81 printf_stderr("\n"); 82 } 83 84 private extern(D) int list_devices(SoundIo* soundio) { 85 const int output_count = soundio_output_device_count(soundio); 86 const int input_count = soundio_input_device_count(soundio); 87 88 int default_output = soundio_default_output_device_index(soundio); 89 int default_input = soundio_default_input_device_index(soundio); 90 91 printf_stderr("--------Input Devices--------\n\n"); 92 for (int i = 0; i < input_count; i += 1) { 93 SoundIoDevice* device = soundio_get_input_device(soundio, i); 94 print_device(device, default_input == i); 95 soundio_device_unref(device); 96 } 97 printf_stderr("\n--------Output Devices--------\n\n"); 98 for (int i = 0; i < output_count; i += 1) { 99 SoundIoDevice* device = soundio_get_output_device(soundio, i); 100 print_device(device, default_output == i); 101 soundio_device_unref(device); 102 } 103 104 printf_stderr("\n%d devices found\n", input_count + output_count); 105 return 0; 106 } 107 108 private extern(C) void on_devices_change(SoundIo* soundio) { 109 printf_stderr("devices changed\n"); 110 list_devices(soundio); 111 } 112 113 int main(int argc, char** argv) { 114 char* exe = argv[0]; 115 bool watch = false; 116 SoundIoBackend backend = SoundIoBackend.None; 117 118 for (int i = 1; i < argc; i += 1) { 119 char* arg = argv[i]; 120 if (strcmp("--watch", arg) == 0) { 121 watch = true; 122 } else if (strcmp("--short", arg) == 0) { 123 short_output = true; 124 } else if (arg[0] == '-' && arg[1] == '-') { 125 i += 1; 126 if (i >= argc) { 127 return usage(exe); 128 } else if (strcmp(arg, "--backend") == 0) { 129 if (strcmp("dummy", argv[i]) == 0) { 130 backend = SoundIoBackend.Dummy; 131 } else if (strcmp("alsa", argv[i]) == 0) { 132 backend = SoundIoBackend.Alsa; 133 } else if (strcmp("pulseaudio", argv[i]) == 0) { 134 backend = SoundIoBackend.PulseAudio; 135 } else if (strcmp("jack", argv[i]) == 0) { 136 backend = SoundIoBackend.Jack; 137 } else if (strcmp("coreaudio", argv[i]) == 0) { 138 backend = SoundIoBackend.CoreAudio; 139 } else if (strcmp("wasapi", argv[i]) == 0) { 140 backend = SoundIoBackend.Wasapi; 141 } else { 142 printf_stderr("Invalid backend: %s\n", argv[i]); 143 return 1; 144 } 145 } else { 146 return usage(exe); 147 } 148 } else { 149 return usage(exe); 150 } 151 } 152 153 SoundIo* soundio = soundio_create(); 154 if (!soundio) { 155 printf_stderr("out of memory\n"); 156 return 1; 157 } 158 159 if (int err = (backend == SoundIoBackend.None) ? 160 soundio_connect(soundio) : soundio_connect_backend(soundio, backend)) { 161 printf_stderr("%s\n", soundio_strerror(err)); 162 return err; 163 } 164 165 if (watch) { 166 soundio.on_devices_change = &on_devices_change; 167 for (;;) { 168 soundio_wait_events(soundio); 169 } 170 } else { 171 soundio_flush_events(soundio); 172 const err = list_devices(soundio); 173 soundio_destroy(soundio); 174 return err; 175 } 176 }