diff -r 4d95b089457d -r 5b351628a377 AlsaBridge.cpp --- a/AlsaBridge.cpp Mon Jan 04 00:15:56 2021 +0100 +++ b/AlsaBridge.cpp Mon Jan 04 13:38:08 2021 +0100 @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -36,6 +37,34 @@ std::recursive_mutex midiMutex; std::atomic stopped{false}; + std::string findDeviceName(std::regex cardNamePattern) { + + std::vector cardNumbers; + + std::cerr << "Looking for available cards:" << std::endl; // TODO: do not mess STDIO + + for (int card = -1; snd_card_next(&card) == 0 && card >= 0;) { + char* longName = nullptr; + snd_card_get_longname(card, &longName); + std::cerr << "card: #" << card << ": '" << longName << "'"; // TODO: do not mess STDIO + if (std::regex_match(longName, cardNamePattern)) { + cardNumbers.push_back(card); + std::cerr << " [matches]"; // TODO: do not mess STDIO + } + std::cerr << std::endl; + free(longName); + } + + if (cardNumbers.size() == 1) { + std::cerr << "Going to fix card #" << cardNumbers[0] << std::endl; // TODO: do not mess STDIO + return "hw:" + std::to_string(cardNumbers[0]); + } else if (cardNumbers.empty()) { + throw std::invalid_argument("No card with matching name found. Is the card connected? Maybe try to provide different name pattern."); + } else { + throw std::invalid_argument("Multiple cards with matching name found. Please provide a name pattern that matches only one card"); + } + } + void run() { while (!stopped) { { @@ -53,9 +82,11 @@ } public: - AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& deviceName) : djmFix(djmFix) { + AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& cardNamePattern) : djmFix(djmFix) { if (djmFix == nullptr) throw std::invalid_argument("need a djmFix for AlsaBridge"); + std::string deviceName = findDeviceName(std::regex(cardNamePattern)); + int error = snd_rawmidi_open(&input, &output, deviceName.c_str(), SND_RAWMIDI_NONBLOCK); if (error) throw std::invalid_argument("unable to open ALSA device");