1 |
/* |
---|
2 |
* Copyright (C) 2005-2009 by Pieter Palmers |
---|
3 |
* Copyright (C) 2005-2008 by Daniel Wagner |
---|
4 |
* |
---|
5 |
* This file is part of FFADO |
---|
6 |
* FFADO = Free Firewire (pro-)audio drivers for linux |
---|
7 |
* |
---|
8 |
* FFADO is based upon FreeBoB |
---|
9 |
* |
---|
10 |
* This program is free software: you can redistribute it and/or modify |
---|
11 |
* it under the terms of the GNU General Public License as published by |
---|
12 |
* the Free Software Foundation, either version 2 of the License, or |
---|
13 |
* (at your option) version 3 of the License. |
---|
14 |
* |
---|
15 |
* This program is distributed in the hope that it will be useful, |
---|
16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 |
* GNU General Public License for more details. |
---|
19 |
* |
---|
20 |
* You should have received a copy of the GNU General Public License |
---|
21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
22 |
* |
---|
23 |
*/ |
---|
24 |
|
---|
25 |
#include <libraw1394/raw1394.h> |
---|
26 |
#include <libiec61883/iec61883.h> |
---|
27 |
|
---|
28 |
#include "debugmodule/debugmodule.h" |
---|
29 |
|
---|
30 |
#include "devicemanager.h" |
---|
31 |
|
---|
32 |
#include "libieee1394/configrom.h" |
---|
33 |
#include "libieee1394/ieee1394service.h" |
---|
34 |
#include "libutil/Configuration.h" |
---|
35 |
#include "libutil/SystemTimeSource.h" |
---|
36 |
|
---|
37 |
#include "genericavc/stanton/scs.h" |
---|
38 |
using namespace GenericAVC; |
---|
39 |
using namespace GenericAVC::Stanton; |
---|
40 |
|
---|
41 |
#include <argp.h> |
---|
42 |
#include <iostream> |
---|
43 |
#include <cstdlib> |
---|
44 |
#include <cstring> |
---|
45 |
#include <string> |
---|
46 |
|
---|
47 |
#include <signal.h> |
---|
48 |
|
---|
49 |
#include <alsa/asoundlib.h> |
---|
50 |
#define ALSA_SEQ_BUFF_SIZE 32 |
---|
51 |
#define MIDI_TRANSMIT_BUFFER_SIZE 512 |
---|
52 |
|
---|
53 |
using namespace std; |
---|
54 |
using namespace Util; |
---|
55 |
|
---|
56 |
DECLARE_GLOBAL_DEBUG_MODULE; |
---|
57 |
|
---|
58 |
#define MAX_ARGS 1000 |
---|
59 |
|
---|
60 |
int run; |
---|
61 |
snd_seq_t *m_seq_handle = NULL; |
---|
62 |
|
---|
63 |
static void sighandler(int sig) |
---|
64 |
{ |
---|
65 |
run = 0; |
---|
66 |
|
---|
67 |
// send an event to wake the iterator loop |
---|
68 |
if(m_seq_handle) { |
---|
69 |
snd_seq_nonblock(m_seq_handle, 1); |
---|
70 |
} |
---|
71 |
} |
---|
72 |
|
---|
73 |
//////////////////////////////////////////////// |
---|
74 |
// arg parsing |
---|
75 |
//////////////////////////////////////////////// |
---|
76 |
const char *argp_program_version = "test-scs 0.1"; |
---|
77 |
const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; |
---|
78 |
static char doc[] = "test-avccmd -- test program to test the Stanton SCS code."; |
---|
79 |
static char args_doc[] = "NODE_ID"; |
---|
80 |
static struct argp_option options[] = { |
---|
81 |
{"verbose", 'v', "LEVEL", 0, "Produce verbose output" }, |
---|
82 |
{"port", 'p', "PORT", 0, "Set port" }, |
---|
83 |
{"node", 'n', "NODE", 0, "Set node" }, |
---|
84 |
{ 0 } |
---|
85 |
}; |
---|
86 |
|
---|
87 |
struct arguments |
---|
88 |
{ |
---|
89 |
arguments() |
---|
90 |
: nargs ( 0 ) |
---|
91 |
, verbose( DEBUG_LEVEL_NORMAL ) |
---|
92 |
, test( false ) |
---|
93 |
, port( -1 ) |
---|
94 |
, node( -1 ) |
---|
95 |
{ |
---|
96 |
args[0] = 0; |
---|
97 |
} |
---|
98 |
|
---|
99 |
char* args[MAX_ARGS]; |
---|
100 |
int nargs; |
---|
101 |
int verbose; |
---|
102 |
bool test; |
---|
103 |
int port; |
---|
104 |
int node; |
---|
105 |
} arguments; |
---|
106 |
|
---|
107 |
// Parse a single option. |
---|
108 |
static error_t |
---|
109 |
parse_opt( int key, char* arg, struct argp_state* state ) |
---|
110 |
{ |
---|
111 |
// Get the input argument from `argp_parse', which we |
---|
112 |
// know is a pointer to our arguments structure. |
---|
113 |
struct arguments* arguments = ( struct arguments* ) state->input; |
---|
114 |
|
---|
115 |
char* tail; |
---|
116 |
errno = 0; |
---|
117 |
switch (key) { |
---|
118 |
case 'v': |
---|
119 |
arguments->verbose = strtol(arg, &tail, 0); |
---|
120 |
break; |
---|
121 |
case 't': |
---|
122 |
arguments->test = true; |
---|
123 |
break; |
---|
124 |
case 'p': |
---|
125 |
arguments->port = strtol(arg, &tail, 0); |
---|
126 |
if (errno) { |
---|
127 |
perror("argument parsing failed:"); |
---|
128 |
return errno; |
---|
129 |
} |
---|
130 |
break; |
---|
131 |
case 'n': |
---|
132 |
arguments->node = strtol(arg, &tail, 0); |
---|
133 |
if (errno) { |
---|
134 |
perror("argument parsing failed:"); |
---|
135 |
return errno; |
---|
136 |
} |
---|
137 |
break; |
---|
138 |
case ARGP_KEY_ARG: |
---|
139 |
if (state->arg_num >= MAX_ARGS) { |
---|
140 |
// Too many arguments. |
---|
141 |
argp_usage (state); |
---|
142 |
} |
---|
143 |
arguments->args[state->arg_num] = arg; |
---|
144 |
arguments->nargs++; |
---|
145 |
break; |
---|
146 |
case ARGP_KEY_END: |
---|
147 |
if(arguments->nargs<0) { |
---|
148 |
printf("not enough arguments\n"); |
---|
149 |
return -1; |
---|
150 |
} |
---|
151 |
|
---|
152 |
break; |
---|
153 |
default: |
---|
154 |
return ARGP_ERR_UNKNOWN; |
---|
155 |
} |
---|
156 |
return 0; |
---|
157 |
} |
---|
158 |
|
---|
159 |
static struct argp argp = { options, parse_opt, args_doc, doc }; |
---|
160 |
|
---|
161 |
class HSS1394AlsaSeqMidiBridge { |
---|
162 |
class HSS1394UserDataHandler; |
---|
163 |
|
---|
164 |
public: |
---|
165 |
HSS1394AlsaSeqMidiBridge(snd_seq_t *seq_handle, GenericAVC::Stanton::ScsDevice &device) |
---|
166 |
: m_seq_handle (seq_handle) |
---|
167 |
, m_device( device ) |
---|
168 |
, m_name( "UNSPECIFIED" ) |
---|
169 |
, m_out_port_nr( -1 ) |
---|
170 |
, m_out_parser( NULL ) |
---|
171 |
, m_input_handler( NULL ) |
---|
172 |
{}; |
---|
173 |
|
---|
174 |
virtual ~HSS1394AlsaSeqMidiBridge() { |
---|
175 |
if(m_input_handler) { |
---|
176 |
// remove the handler |
---|
177 |
if(!m_device.m_hss1394handler->removeMessageHandler(GenericAVC::Stanton::ScsDevice::eMT_UserData, m_input_handler)) { |
---|
178 |
debugError("Could not register input message handler\n"); |
---|
179 |
} |
---|
180 |
delete m_input_handler; |
---|
181 |
m_input_handler = NULL; |
---|
182 |
} |
---|
183 |
if(m_out_port_nr >= 0) { |
---|
184 |
snd_seq_delete_simple_port(m_seq_handle, m_out_port_nr); |
---|
185 |
m_out_port_nr = -1; |
---|
186 |
} |
---|
187 |
if(m_out_parser) { |
---|
188 |
snd_midi_event_free(m_out_parser); |
---|
189 |
m_out_parser = NULL; |
---|
190 |
} |
---|
191 |
}; |
---|
192 |
|
---|
193 |
bool init() { |
---|
194 |
// need local copy as the nickname can change |
---|
195 |
m_name = m_device.getNickname(); |
---|
196 |
|
---|
197 |
// create the output port |
---|
198 |
m_out_port_nr = snd_seq_create_simple_port(m_seq_handle, m_name.c_str(), |
---|
199 |
SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, |
---|
200 |
SND_SEQ_PORT_TYPE_MIDI_GENERIC); |
---|
201 |
if(m_out_port_nr < 0) { |
---|
202 |
debugError("Could not create ALSA Sequencer port\n"); |
---|
203 |
return false; |
---|
204 |
} |
---|
205 |
|
---|
206 |
// create the output message encoder |
---|
207 |
if(snd_midi_event_new( ALSA_SEQ_BUFF_SIZE, &m_out_parser) < 0) { |
---|
208 |
debugError("could not init output event encoder"); |
---|
209 |
return false; |
---|
210 |
} |
---|
211 |
|
---|
212 |
// disable running-status |
---|
213 |
snd_midi_event_no_status(m_out_parser, 1); |
---|
214 |
|
---|
215 |
// create a handler |
---|
216 |
HSS1394UserDataHandler *m_input_handler = new HSS1394UserDataHandler(*this); |
---|
217 |
if(m_input_handler == NULL) { |
---|
218 |
debugError("Error creating handler."); |
---|
219 |
return false; |
---|
220 |
} |
---|
221 |
if(!m_input_handler->init(m_name)) { |
---|
222 |
debugError("Could not init input message handler\n"); |
---|
223 |
return false; |
---|
224 |
} |
---|
225 |
if(!m_device.m_hss1394handler->addMessageHandler(GenericAVC::Stanton::ScsDevice::eMT_UserData, m_input_handler)) { |
---|
226 |
debugError("Could not register input message handler\n"); |
---|
227 |
return false; |
---|
228 |
} |
---|
229 |
return true; |
---|
230 |
}; |
---|
231 |
|
---|
232 |
bool sendAlsaSeqEvent(snd_seq_event_t *ev) { |
---|
233 |
int bytes_to_send = 0; |
---|
234 |
|
---|
235 |
// decode it to the work buffer |
---|
236 |
if((bytes_to_send = snd_midi_event_decode ( m_out_parser, |
---|
237 |
m_work_buffer, |
---|
238 |
MIDI_TRANSMIT_BUFFER_SIZE, |
---|
239 |
ev)) < 0) { // failed to decode |
---|
240 |
debugError(" Error decoding event for port %d (errcode=%d)", ev->dest.port, bytes_to_send); |
---|
241 |
return false; |
---|
242 |
} else { |
---|
243 |
if(!m_device.writeHSS1394Message(GenericAVC::Stanton::ScsDevice::eMT_UserData, |
---|
244 |
m_work_buffer, bytes_to_send)) { |
---|
245 |
debugError("Failed to send message\n"); |
---|
246 |
return false; |
---|
247 |
} |
---|
248 |
} |
---|
249 |
return true; |
---|
250 |
}; |
---|
251 |
|
---|
252 |
int getAlsaSeqOutputPortNumber() { |
---|
253 |
return m_out_port_nr; |
---|
254 |
} |
---|
255 |
int getAlsaSeqInputPortNumber() { |
---|
256 |
if (m_input_handler) { |
---|
257 |
return m_input_handler->getAlsaSeqPortNumber(); |
---|
258 |
} else { |
---|
259 |
debugError("input handler not initialized yet"); |
---|
260 |
return -1; |
---|
261 |
} |
---|
262 |
} |
---|
263 |
|
---|
264 |
void setVerboseLevel(int i) { |
---|
265 |
setDebugLevel(i); |
---|
266 |
}; |
---|
267 |
|
---|
268 |
private: |
---|
269 |
snd_seq_t *m_seq_handle; |
---|
270 |
GenericAVC::Stanton::ScsDevice &m_device; |
---|
271 |
std::string m_name; |
---|
272 |
int m_out_port_nr; |
---|
273 |
snd_midi_event_t *m_out_parser; |
---|
274 |
|
---|
275 |
HSS1394UserDataHandler *m_input_handler; |
---|
276 |
|
---|
277 |
unsigned char m_work_buffer[MIDI_TRANSMIT_BUFFER_SIZE]; |
---|
278 |
|
---|
279 |
DECLARE_DEBUG_MODULE; |
---|
280 |
|
---|
281 |
private: // the class that handles the async messages from the HSS1394 node |
---|
282 |
class HSS1394UserDataHandler : public GenericAVC::Stanton::ScsDevice::HSS1394Handler::MessageFunctor { |
---|
283 |
public: |
---|
284 |
HSS1394UserDataHandler(HSS1394AlsaSeqMidiBridge &parent) |
---|
285 |
: m_parent( parent ) |
---|
286 |
, m_ready(false) |
---|
287 |
, m_seq_port_nr( -1 ) |
---|
288 |
, m_parser( NULL ) |
---|
289 |
, m_debugModule(parent.m_debugModule) |
---|
290 |
{}; |
---|
291 |
|
---|
292 |
virtual ~HSS1394UserDataHandler() { |
---|
293 |
if(m_seq_port_nr >= 0) { |
---|
294 |
snd_seq_delete_simple_port(m_parent.m_seq_handle, m_seq_port_nr); |
---|
295 |
m_seq_port_nr = -1; |
---|
296 |
} |
---|
297 |
if(m_parser) { |
---|
298 |
snd_midi_event_free(m_parser); |
---|
299 |
m_parser = NULL; |
---|
300 |
} |
---|
301 |
m_ready = false; |
---|
302 |
} |
---|
303 |
|
---|
304 |
bool init(std::string name) { |
---|
305 |
m_seq_port_nr = snd_seq_create_simple_port(m_parent.m_seq_handle, name.c_str(), |
---|
306 |
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, |
---|
307 |
SND_SEQ_PORT_TYPE_MIDI_GENERIC); |
---|
308 |
if(m_seq_port_nr < 0) { |
---|
309 |
debugError("Could not create ALSA Sequencer port\n"); |
---|
310 |
return false; |
---|
311 |
} |
---|
312 |
|
---|
313 |
if(snd_midi_event_new( ALSA_SEQ_BUFF_SIZE, &m_parser) < 0) { |
---|
314 |
debugError("could not init parser"); |
---|
315 |
return false; |
---|
316 |
} |
---|
317 |
m_ready = true; |
---|
318 |
return m_ready; |
---|
319 |
} |
---|
320 |
|
---|
321 |
int getAlsaSeqPortNumber() { |
---|
322 |
return m_seq_port_nr; |
---|
323 |
} |
---|
324 |
|
---|
325 |
virtual void operator() (byte_t *buff, size_t len) { |
---|
326 |
if (m_ready) { |
---|
327 |
debugOutput(DEBUG_LEVEL_NORMAL, "got message len %d\n", len); |
---|
328 |
|
---|
329 |
for (size_t s=0; s < len; s++) { |
---|
330 |
byte_t *byte = (buff+s); |
---|
331 |
snd_seq_event_t ev; |
---|
332 |
if ((snd_midi_event_encode_byte(m_parser, (*byte) & 0xFF, &ev)) > 0) { |
---|
333 |
// a midi message is complete, send it out to ALSA |
---|
334 |
snd_seq_ev_set_subs(&ev); |
---|
335 |
snd_seq_ev_set_direct(&ev); |
---|
336 |
snd_seq_ev_set_source(&ev, m_seq_port_nr); |
---|
337 |
snd_seq_event_output_direct(m_parent.m_seq_handle, &ev); |
---|
338 |
} |
---|
339 |
} |
---|
340 |
} else { |
---|
341 |
debugError("Not ready\n"); |
---|
342 |
} |
---|
343 |
}; |
---|
344 |
private: |
---|
345 |
HSS1394AlsaSeqMidiBridge &m_parent; |
---|
346 |
bool m_ready; |
---|
347 |
int m_seq_port_nr; |
---|
348 |
snd_midi_event_t *m_parser; |
---|
349 |
DECLARE_DEBUG_MODULE_REFERENCE; |
---|
350 |
}; |
---|
351 |
}; |
---|
352 |
IMPL_DEBUG_MODULE( HSS1394AlsaSeqMidiBridge, HSS1394AlsaSeqMidiBridge, DEBUG_LEVEL_NORMAL ); |
---|
353 |
|
---|
354 |
/////////////////////////// |
---|
355 |
// main |
---|
356 |
////////////////////////// |
---|
357 |
int |
---|
358 |
main(int argc, char **argv) |
---|
359 |
{ |
---|
360 |
// arg parsing |
---|
361 |
if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) { |
---|
362 |
printMessage("Could not parse command line\n" ); |
---|
363 |
exit(-1); |
---|
364 |
} |
---|
365 |
errno = 0; |
---|
366 |
|
---|
367 |
run=1; |
---|
368 |
|
---|
369 |
signal (SIGINT, sighandler); |
---|
370 |
signal (SIGPIPE, sighandler); |
---|
371 |
|
---|
372 |
DeviceManager *m_deviceManager = new DeviceManager(); |
---|
373 |
if ( !m_deviceManager ) { |
---|
374 |
printMessage("Could not allocate device manager\n" ); |
---|
375 |
return -1; |
---|
376 |
} |
---|
377 |
|
---|
378 |
if ( arguments.verbose ) { |
---|
379 |
setDebugLevel(arguments.verbose); |
---|
380 |
m_deviceManager->setVerboseLevel(arguments.verbose); |
---|
381 |
} |
---|
382 |
|
---|
383 |
if ( !m_deviceManager->initialize() ) { |
---|
384 |
printMessage("Could not initialize device manager\n" ); |
---|
385 |
delete m_deviceManager; |
---|
386 |
return -1; |
---|
387 |
} |
---|
388 |
|
---|
389 |
char s[1024]; |
---|
390 |
if(arguments.port > -1 && arguments.node > -1) { |
---|
391 |
snprintf(s, 1024, "hw:%d,%d", arguments.port, arguments.node); |
---|
392 |
if ( !m_deviceManager->addSpecString(s) ) { |
---|
393 |
printMessage("Could not add spec string %s to device manager\n", s ); |
---|
394 |
delete m_deviceManager; |
---|
395 |
return -1; |
---|
396 |
} |
---|
397 |
} else if (arguments.port > -1) { |
---|
398 |
snprintf(s, 1024, "hw:%d", arguments.port); |
---|
399 |
if ( !m_deviceManager->addSpecString(s) ) { |
---|
400 |
printMessage("Could not add spec string %s to device manager\n", s ); |
---|
401 |
delete m_deviceManager; |
---|
402 |
return -1; |
---|
403 |
} |
---|
404 |
} |
---|
405 |
|
---|
406 |
if ( !m_deviceManager->discover(false) ) { |
---|
407 |
printMessage("Could not discover devices\n" ); |
---|
408 |
delete m_deviceManager; |
---|
409 |
return -1; |
---|
410 |
} |
---|
411 |
|
---|
412 |
// loop over all discovered devices and extract the SCS devices |
---|
413 |
int nb_devices = m_deviceManager->getAvDeviceCount(); |
---|
414 |
if(nb_devices == 0) { |
---|
415 |
printMessage("No devices found\n"); |
---|
416 |
delete m_deviceManager; |
---|
417 |
return -1; |
---|
418 |
} |
---|
419 |
|
---|
420 |
typedef std::vector<ScsDevice*> ScsDeviceVector; |
---|
421 |
typedef std::vector<ScsDevice*>::iterator ScsDeviceVectorIterator; |
---|
422 |
|
---|
423 |
ScsDeviceVector scsDevices; |
---|
424 |
for(int i=0; i<nb_devices; i++) { |
---|
425 |
FFADODevice *device = m_deviceManager->getAvDeviceByIndex(i); |
---|
426 |
GenericAVC::Stanton::ScsDevice* scsDevice = dynamic_cast<GenericAVC::Stanton::ScsDevice*>(device); |
---|
427 |
if(scsDevice == NULL) { |
---|
428 |
printMessage("Device %d (GUID: %s) is not a Stanton SCS device\n", i, device->getConfigRom().getGuidString().c_str() ); |
---|
429 |
} else { |
---|
430 |
printMessage("Device %d (GUID: %s) is a Stanton SCS device\n", i, device->getConfigRom().getGuidString().c_str() ); |
---|
431 |
scsDevices.push_back(scsDevice); |
---|
432 |
} |
---|
433 |
} |
---|
434 |
|
---|
435 |
if(scsDevices.size() == 0) { |
---|
436 |
printMessage("No SCS devices found\n"); |
---|
437 |
delete m_deviceManager; |
---|
438 |
return -1; |
---|
439 |
} |
---|
440 |
|
---|
441 |
// open the alsa sequencer |
---|
442 |
if (snd_seq_open(&m_seq_handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { |
---|
443 |
debugError("Error opening ALSA sequencer."); |
---|
444 |
delete m_deviceManager; |
---|
445 |
return -1; |
---|
446 |
} |
---|
447 |
|
---|
448 |
snd_seq_set_client_name(m_seq_handle, "SCS MIDI"); |
---|
449 |
|
---|
450 |
// this maps the alsa sequencer ports to the corresponding bridges |
---|
451 |
typedef std::map<int, HSS1394AlsaSeqMidiBridge*> BridgeMap; |
---|
452 |
typedef std::map<int, HSS1394AlsaSeqMidiBridge*>::iterator BridgeMapIterator; |
---|
453 |
BridgeMap seqport2bridgemap; |
---|
454 |
|
---|
455 |
for ( ScsDeviceVectorIterator it = scsDevices.begin(); |
---|
456 |
it != scsDevices.end(); |
---|
457 |
++it ) |
---|
458 |
{ |
---|
459 |
HSS1394AlsaSeqMidiBridge *bridge = new HSS1394AlsaSeqMidiBridge(m_seq_handle, **it); |
---|
460 |
if(bridge == NULL) { |
---|
461 |
debugError("Could not allocate HSS1394 <=> ALSA bridge\n"); |
---|
462 |
delete m_deviceManager; |
---|
463 |
return -1; |
---|
464 |
} |
---|
465 |
bridge->setVerboseLevel(arguments.verbose); |
---|
466 |
if(!bridge->init()) { |
---|
467 |
debugError("Could not init HSS1394 <=> ALSA bridge\n"); |
---|
468 |
delete m_deviceManager; |
---|
469 |
return -1; |
---|
470 |
} |
---|
471 |
int portNumber = bridge->getAlsaSeqOutputPortNumber(); |
---|
472 |
#ifdef DEBUG |
---|
473 |
if(portNumber < -1) { |
---|
474 |
debugError("BUG: port should be >= 0 after init\n"); |
---|
475 |
} |
---|
476 |
#endif |
---|
477 |
|
---|
478 |
BridgeMapIterator it = seqport2bridgemap.find(portNumber); |
---|
479 |
if(it == seqport2bridgemap.end()) { |
---|
480 |
seqport2bridgemap[portNumber] = bridge; |
---|
481 |
} else { |
---|
482 |
debugError("BUG: port already present in bridge map, duplicate port.\n"); |
---|
483 |
delete bridge; |
---|
484 |
} |
---|
485 |
} |
---|
486 |
|
---|
487 |
// enter a wait loop |
---|
488 |
printMessage(" >>> Entering wait loop, use CTRL-C to exit... \n" ); |
---|
489 |
while(run) { |
---|
490 |
snd_seq_event_t *ev; |
---|
491 |
int err = 0; |
---|
492 |
|
---|
493 |
// get next event, if one is present, blocks until an event is received |
---|
494 |
err = snd_seq_event_input(m_seq_handle, &ev); |
---|
495 |
if(err > 0 && ev) { |
---|
496 |
debugOutput(DEBUG_LEVEL_VERBOSE, "Got event...\n"); |
---|
497 |
if (ev->source.client == SND_SEQ_CLIENT_SYSTEM) |
---|
498 |
continue; |
---|
499 |
|
---|
500 |
// figure out what bridge this is intended for |
---|
501 |
BridgeMapIterator it = seqport2bridgemap.find(ev->dest.port); |
---|
502 |
if(it != seqport2bridgemap.end()) { |
---|
503 |
HSS1394AlsaSeqMidiBridge *bridge = (*it).second; |
---|
504 |
if(bridge) { |
---|
505 |
if(!bridge->sendAlsaSeqEvent(ev)) { |
---|
506 |
debugError("Failed to send event to HSS1394 node\n"); |
---|
507 |
} |
---|
508 |
} else { |
---|
509 |
debugError("Bogus bridge in seqport2bridgemap\n"); |
---|
510 |
} |
---|
511 |
} else { |
---|
512 |
debugWarning("Received message for unknown port\n"); |
---|
513 |
} |
---|
514 |
|
---|
515 |
} else { |
---|
516 |
switch(err) { |
---|
517 |
case -EAGAIN: |
---|
518 |
debugOutput(DEBUG_LEVEL_VERBOSE, "no events in ALSA-SEQ FIFO\n"); |
---|
519 |
break; |
---|
520 |
case -ENOSPC: |
---|
521 |
debugWarning("ALSA-SEQ FIFO overrun, events dropped!\n"); |
---|
522 |
break; |
---|
523 |
default: |
---|
524 |
debugError("Failed to receive ALSA-SEQ event (%d)\n", err); |
---|
525 |
} |
---|
526 |
} |
---|
527 |
} |
---|
528 |
printMessage(" <<< Exit wait loop... \n" ); |
---|
529 |
|
---|
530 |
// cleanup |
---|
531 |
for ( BridgeMapIterator it = seqport2bridgemap.begin(); |
---|
532 |
it != seqport2bridgemap.end(); |
---|
533 |
++it ) |
---|
534 |
{ |
---|
535 |
HSS1394AlsaSeqMidiBridge *bridge = (*it).second; |
---|
536 |
delete bridge; |
---|
537 |
} |
---|
538 |
seqport2bridgemap.clear(); |
---|
539 |
|
---|
540 |
snd_seq_close(m_seq_handle); |
---|
541 |
delete m_deviceManager; |
---|
542 |
|
---|
543 |
printMessage("Bye... \n" ); |
---|
544 |
return 0; |
---|
545 |
} |
---|
546 |
|
---|