Skip to content

Commit

Permalink
Add device selection to cubeb-test
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ChunMinChang authored and kinetiknz committed Mar 22, 2022
1 parent 70d1872 commit 5a2a20c
Showing 1 changed file with 84 additions and 3 deletions.
87 changes: 84 additions & 3 deletions tools/cubeb-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cstring>
#include <inttypes.h>
#include <iostream>
#include <vector>
#ifdef _WIN32
#include <objbase.h> // Used by CoInitialize()
#endif
Expand Down Expand Up @@ -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);
Expand All @@ -48,6 +75,7 @@ class cubeb_client final {
~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();
Expand All @@ -70,7 +98,10 @@ class cubeb_client final {
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; }

Expand All @@ -81,8 +112,6 @@ class cubeb_client final {
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};
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 */);

Expand All @@ -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) {
Expand Down

0 comments on commit 5a2a20c

Please sign in to comment.