AlsaBridge.cpp
branchv_0
changeset 11 5b351628a377
parent 9 ee976a1d1f0a
child 12 15d87fdd6e6c
     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