diff options
author | Chun-Min Chang <[email protected]> | 2022-03-21 17:31:13 -0700 |
---|---|---|
committer | Matthew Gregan <[email protected]> | 2022-03-22 14:15:59 +1300 |
commit | 5a2a20c6055d26e0a30fae8f1cf6f6cb975c5c97 (patch) | |
tree | d9d8f63a153ac8b81aafc10a500dec4ee907087a | |
parent | 70d18726e42f75c83426544d8fb631b618d21a4e (diff) | |
download | cubeb-5a2a20c6055d26e0a30fae8f1cf6f6cb975c5c97.tar.gz cubeb-5a2a20c6055d26e0a30fae8f1cf6f6cb975c5c97.zip |
Add device selection to cubeb-test
It's a lot easier to develop/debug device-related features/issues if we
can select input or/and output device for the audio stream in cubeb-test
-rw-r--r-- | tools/cubeb-test.cpp | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/tools/cubeb-test.cpp b/tools/cubeb-test.cpp index 863e9ee..ab17123 100644 --- a/tools/cubeb-test.cpp +++ b/tools/cubeb-test.cpp @@ -7,6 +7,7 @@ #include <cstring> #include <inttypes.h> #include <iostream> +#include <vector> #ifdef _WIN32 #include <objbase.h> // Used by CoInitialize() #endif @@ -35,6 +36,32 @@ static const char* state_to_string(cubeb_state state) { } } +static const char* device_type_to_string(cubeb_device_type type) { + switch (type) { + case CUBEB_DEVICE_TYPE_INPUT: + return "input"; + case CUBEB_DEVICE_TYPE_OUTPUT: + return "output"; + case CUBEB_DEVICE_TYPE_UNKNOWN: + return "unknown"; + default: + assert(false); + } +} + +static const char* device_state_to_string(cubeb_device_state state) { + switch (state) { + case CUBEB_DEVICE_STATE_DISABLED: + return "disabled"; + case CUBEB_DEVICE_STATE_UNPLUGGED: + return "unplugged"; + case CUBEB_DEVICE_STATE_ENABLED: + return "enabled"; + default: + assert(false); + } +} + void print_log(const char* msg, ...) { va_list args; va_start(args, msg); @@ -48,6 +75,7 @@ public: ~cubeb_client() {} bool init(char const * backend_name = nullptr); + cubeb_devid select_device(cubeb_device_type type) const; bool init_stream(); bool start_stream(); bool stop_stream(); @@ -70,7 +98,10 @@ public: bool unregister_device_collection_changed(cubeb_device_type devtype) const; cubeb_stream_params output_params = {}; + cubeb_devid output_device = nullptr; + cubeb_stream_params input_params = {}; + cubeb_devid input_device = nullptr; void force_drain() { _force_drain = true; } @@ -81,8 +112,6 @@ private: cubeb* context = nullptr; cubeb_stream* stream = nullptr; - cubeb_devid output_device = nullptr; - cubeb_devid input_device = nullptr; /* Accessed only from client and audio thread. */ std::atomic<uint32_t> _rate = {0}; @@ -492,6 +521,56 @@ bool choose_action(cubeb_client& cl, operation_data * op, int c) { return true; // Loop up } +cubeb_devid cubeb_client::select_device(cubeb_device_type type) const +{ + assert(type == CUBEB_DEVICE_TYPE_INPUT || type == CUBEB_DEVICE_TYPE_OUTPUT); + + cubeb_device_collection collection; + if (cubeb_enumerate_devices(context, type, &collection) == + CUBEB_ERROR_NOT_SUPPORTED) { + fprintf(stderr, + "Not support %s device selection. Force to use default device\n", + device_type_to_string(type)); + return nullptr; + } + + assert(collection.count); + fprintf(stderr, "Found %zu %s devices. Choose one:\n", collection.count, + device_type_to_string(type)); + + std::vector<cubeb_devid> devices; + devices.emplace_back(nullptr); + fprintf(stderr, "# 0\n\tname: system default device\n"); + for (size_t i = 0; i < collection.count; i++) { + assert(collection.device[i].type == type); + fprintf(stderr, + "# %zu %s\n" + "\tname: %s\n" + "\tdevice id: %s\n" + "\tmax channels: %u\n" + "\tstate: %s\n", + devices.size(), + collection.device[i].preferred ? " (PREFERRED)" : "", + collection.device[i].friendly_name, collection.device[i].device_id, + collection.device[i].max_channels, + device_state_to_string(collection.device[i].state)); + devices.emplace_back(collection.device[i].devid); + } + + cubeb_device_collection_destroy(context, &collection); + + size_t number; + std::cout << "Enter device number: "; + std::cin >> number; + while (!std::cin || number >= devices.size()) { + std::cin.clear(); + std::cin.ignore(100, '\n'); + std::cout << "Error: Please enter a valid numeric input. Enter again: "; + std::cin >> number; + } + return devices[number]; +} + int main(int argc, char* argv[]) { #ifdef _WIN32 CoInitialize(nullptr); @@ -523,7 +602,7 @@ int main(int argc, char* argv[]) { bool res = false; cubeb_client cl; - cl.activate_log(CUBEB_LOG_DISABLED); + cl.activate_log(CUBEB_LOG_NORMAL); fprintf(stderr, "Log level is DISABLED\n"); cl.init(/* default backend */); @@ -540,10 +619,12 @@ int main(int argc, char* argv[]) { } } else { if (op.pm == PLAYBACK || op.pm == DUPLEX || op.pm == LATENCY_TESTING) { + cl.output_device = cl.select_device(CUBEB_DEVICE_TYPE_OUTPUT); cl.output_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_OUTPUT_CHANNELS, CUBEB_LAYOUT_STEREO, CUBEB_STREAM_PREF_NONE}; } if (op.pm == RECORD || op.pm == DUPLEX || op.pm == LATENCY_TESTING) { + cl.input_device = cl.select_device(CUBEB_DEVICE_TYPE_INPUT); cl.input_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_INPUT_CHANNELS, CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE}; } if (op.pm == LATENCY_TESTING) { |