1.1 --- a/AlsaBridge.cpp Mon Jan 04 00:15:56 2021 +0100
1.2 +++ b/AlsaBridge.cpp Mon Jan 04 13:38:08 2021 +0100
1.3 @@ -19,6 +19,7 @@
1.4 #include <thread>
1.5 #include <mutex>
1.6 #include <atomic>
1.7 +#include <regex>
1.8
1.9 #include <alsa/asoundlib.h>
1.10
1.11 @@ -36,6 +37,34 @@
1.12 std::recursive_mutex midiMutex;
1.13 std::atomic<bool> stopped{false};
1.14
1.15 + std::string findDeviceName(std::regex cardNamePattern) {
1.16 +
1.17 + std::vector<int> cardNumbers;
1.18 +
1.19 + std::cerr << "Looking for available cards:" << std::endl; // TODO: do not mess STDIO
1.20 +
1.21 + for (int card = -1; snd_card_next(&card) == 0 && card >= 0;) {
1.22 + char* longName = nullptr;
1.23 + snd_card_get_longname(card, &longName);
1.24 + std::cerr << "card: #" << card << ": '" << longName << "'"; // TODO: do not mess STDIO
1.25 + if (std::regex_match(longName, cardNamePattern)) {
1.26 + cardNumbers.push_back(card);
1.27 + std::cerr << " [matches]"; // TODO: do not mess STDIO
1.28 + }
1.29 + std::cerr << std::endl;
1.30 + free(longName);
1.31 + }
1.32 +
1.33 + if (cardNumbers.size() == 1) {
1.34 + std::cerr << "Going to fix card #" << cardNumbers[0] << std::endl; // TODO: do not mess STDIO
1.35 + return "hw:" + std::to_string(cardNumbers[0]);
1.36 + } else if (cardNumbers.empty()) {
1.37 + throw std::invalid_argument("No card with matching name found. Is the card connected? Maybe try to provide different name pattern.");
1.38 + } else {
1.39 + throw std::invalid_argument("Multiple cards with matching name found. Please provide a name pattern that matches only one card");
1.40 + }
1.41 + }
1.42 +
1.43 void run() {
1.44 while (!stopped) {
1.45 {
1.46 @@ -53,9 +82,11 @@
1.47 }
1.48 public:
1.49
1.50 - AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& deviceName) : djmFix(djmFix) {
1.51 + AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& cardNamePattern) : djmFix(djmFix) {
1.52 if (djmFix == nullptr) throw std::invalid_argument("need a djmFix for AlsaBridge");
1.53
1.54 + std::string deviceName = findDeviceName(std::regex(cardNamePattern));
1.55 +
1.56 int error = snd_rawmidi_open(&input, &output, deviceName.c_str(), SND_RAWMIDI_NONBLOCK);
1.57 if (error) throw std::invalid_argument("unable to open ALSA device");
1.58