91 } |
98 } |
92 } |
99 } |
93 public: |
100 public: |
94 |
101 |
95 AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& cardNamePattern, djmfix::logging::Logger* logger) : djmFix(djmFix), logger(logger ? logger : djmfix::logging::blackhole()) { |
102 AlsaBridgeImpl(djmfix::DJMFix* djmFix, const std::string& cardNamePattern, djmfix::logging::Logger* logger) : djmFix(djmFix), logger(logger ? logger : djmfix::logging::blackhole()) { |
96 if (djmFix == nullptr) throw std::invalid_argument("need a djmFix for AlsaBridge"); |
103 if (djmFix == nullptr) throw std::invalid_argument("Need a djmFix for AlsaBridge."); |
97 |
104 |
98 std::string deviceName = findDeviceName(std::regex(cardNamePattern)); |
105 std::string deviceName = findDeviceName(std::regex(cardNamePattern)); |
99 |
106 |
100 int error = snd_rawmidi_open(&input, &output, deviceName.c_str(), SND_RAWMIDI_NONBLOCK); |
107 int error = snd_rawmidi_open(&input, &output, deviceName.c_str(), SND_RAWMIDI_NONBLOCK); |
101 if (error) throw std::invalid_argument("unable to open ALSA device"); |
108 if (error) throw std::invalid_argument("Unable to open ALSA device."); |
102 |
109 |
103 |
110 |
104 djmFix->setMidiSender(this); |
111 djmFix->setMidiSender(this); |
105 } |
112 } |
106 |
113 |
107 virtual ~AlsaBridgeImpl() { |
114 virtual ~AlsaBridgeImpl() { |
108 // TODO: do not use raw/exclusive access to the MIDI device |
115 // TODO: do not use raw/exclusive access to the MIDI device |
109 snd_rawmidi_close(input); |
116 snd_rawmidi_close(input); |
110 snd_rawmidi_close(output); |
117 snd_rawmidi_close(output); |
111 logger->log(L::FINE, "~AlsaBridgeImpl()"); |
118 logger->log(L::FINER, "~AlsaBridgeImpl()"); |
112 } |
119 } |
113 |
120 |
114 virtual void start() override { |
121 virtual void start() override { |
115 djmFix->start(); |
122 djmFix->start(); |
116 receivingThread = std::thread(&AlsaBridgeImpl::run, this); |
123 receivingThread = std::thread(&AlsaBridgeImpl::run, this); |
123 } |
130 } |
124 |
131 |
125 virtual void send(MidiMessage midiMessage) override { |
132 virtual void send(MidiMessage midiMessage) override { |
126 std::lock_guard<std::recursive_mutex> lock(midiMutex); |
133 std::lock_guard<std::recursive_mutex> lock(midiMutex); |
127 ssize_t length = snd_rawmidi_write(output, midiMessage.data(), midiMessage.size()); |
134 ssize_t length = snd_rawmidi_write(output, midiMessage.data(), midiMessage.size()); |
128 logger->log(L::INFO, "AlsaBridgeImpl::send(): length = " + std::to_string(length)); |
135 logger->log(L::FINE, "Sent message: length = " + std::to_string(length) + " data = " + toString(midiMessage)); |
129 } |
136 } |
130 |
137 |
131 }; |
138 }; |
132 |
139 |
133 AlsaBridge* create(djmfix::DJMFix* djmFix, const std::string& deviceName, djmfix::logging::Logger* logger) { |
140 AlsaBridge* create(djmfix::DJMFix* djmFix, const std::string& deviceName, djmfix::logging::Logger* logger) { |