aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChun-Min Chang <[email protected]>2022-03-21 17:31:13 -0700
committerMatthew Gregan <[email protected]>2022-03-22 14:15:59 +1300
commit5a2a20c6055d26e0a30fae8f1cf6f6cb975c5c97 (patch)
treed9d8f63a153ac8b81aafc10a500dec4ee907087a
parent70d18726e42f75c83426544d8fb631b618d21a4e (diff)
downloadcubeb-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.cpp87
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) {