185 metadata.push_back({L"midi", TypeId::BOOLEAN}); |
185 metadata.push_back({L"midi", TypeId::BOOLEAN}); |
186 metadata.push_back({L"type", TypeId::STRING}); |
186 metadata.push_back({L"type", TypeId::STRING}); |
187 writer->startRelation(L"port", metadata, true); |
187 writer->startRelation(L"port", metadata, true); |
188 |
188 |
189 const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0); |
189 const char** portNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, 0); |
190 |
190 |
191 std::regex midiTypePattern(".*midi$"); |
191 std::regex midiTypePattern(".*midi$"); |
192 |
192 |
193 for (const char** portName = portNames; *portName; portName++) { |
193 for (const char** portName = portNames; *portName; portName++) { |
194 jack_port_t* port = jack_port_by_name(realTimeContext.jackClient, *portName); |
194 jack_port_t* port = jack_port_by_name(realTimeContext.jackClient, *portName); |
195 |
195 |
214 } |
214 } |
215 |
215 |
216 jack_free(portNames); |
216 jack_free(portNames); |
217 } |
217 } |
218 |
218 |
|
219 void listConnections(std::shared_ptr<relpipe::writer::RelationalWriter> writer) { |
|
220 using namespace relpipe::writer; |
|
221 vector<AttributeMetadata> metadata; |
|
222 |
|
223 metadata.push_back({L"event", TypeId::STRING}); |
|
224 metadata.push_back({L"source_port", TypeId::STRING}); |
|
225 metadata.push_back({L"destination_port", TypeId::STRING}); |
|
226 writer->startRelation(L"connection", metadata, true); |
|
227 |
|
228 const relpipe::common::type::StringX event = L"connect"; |
|
229 |
|
230 const char** sourcePortNames = jack_get_ports(realTimeContext.jackClient, nullptr, nullptr, JackPortFlags::JackPortIsOutput); |
|
231 |
|
232 for (const char** sourcePortName = sourcePortNames; *sourcePortName; sourcePortName++) { |
|
233 jack_port_t* sourcePort = jack_port_by_name(realTimeContext.jackClient, *sourcePortName); |
|
234 |
|
235 const char** destinationPortNames = jack_port_get_all_connections(realTimeContext.jackClient, sourcePort); |
|
236 |
|
237 for (const char** destinationPortName = destinationPortNames; destinationPortNames && *destinationPortName; destinationPortName++) { |
|
238 writer->writeAttribute(event); |
|
239 writer->writeAttribute(convertor.from_bytes(*sourcePortName)); |
|
240 writer->writeAttribute(convertor.from_bytes(*destinationPortName)); |
|
241 } |
|
242 |
|
243 jack_free(destinationPortNames); |
|
244 } |
|
245 |
|
246 jack_free(sourcePortNames); |
|
247 } |
|
248 |
219 static void jackErrorCallback(const char * message) { |
249 static void jackErrorCallback(const char * message) { |
220 std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding |
250 std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor; // TODO: local system encoding |
221 std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl; |
251 std::wcerr << L"JACK: " << convertor.from_bytes(message) << std::endl; |
222 } |
252 } |
223 |
253 |
280 // Relation headers: |
310 // Relation headers: |
281 using namespace relpipe::writer; |
311 using namespace relpipe::writer; |
282 vector<AttributeMetadata> metadata; |
312 vector<AttributeMetadata> metadata; |
283 |
313 |
284 if (configuration.listPorts) listPorts(writer); |
314 if (configuration.listPorts) listPorts(writer); |
|
315 if (configuration.listConnections) listConnections(writer); |
285 if (!configuration.listMidiMessages) return; |
316 if (!configuration.listMidiMessages) return; |
286 |
317 |
287 metadata.push_back({L"event", TypeId::STRING}); |
318 metadata.push_back({L"event", TypeId::STRING}); |
288 metadata.push_back({L"channel", TypeId::INTEGER}); |
319 metadata.push_back({L"channel", TypeId::INTEGER}); |
289 metadata.push_back({L"note_on", TypeId::BOOLEAN}); |
320 metadata.push_back({L"note_on", TypeId::BOOLEAN}); |