AlsaBridge.cpp
branchv_0
changeset 11 5b351628a377
parent 9 ee976a1d1f0a
child 12 15d87fdd6e6c
--- 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 <thread>
 #include <mutex>
 #include <atomic>
+#include <regex>
 
 #include <alsa/asoundlib.h>
 
@@ -36,6 +37,34 @@
 	std::recursive_mutex midiMutex;
 	std::atomic<bool> stopped{false};
 
+	std::string findDeviceName(std::regex cardNamePattern) {
+
+		std::vector<int> 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");