86
//---------------------------------------------------------
88
//---------------------------------------------------------
90
void getCapabilities()
93
const char* napp = getenv("GIVERTCAP");
94
system(napp ? napp : "givertcap");
99
110
//---------------------------------------------------------
101
112
//---------------------------------------------------------
103
114
void Mess::midiRun()
106
extern void getCapabilities();
109
doSetuid(euid, ruid);
111
struct sched_param sp;
116
#define BIG_ENOUGH_STACK (1024*1024*1)
117
char buf[BIG_ENOUGH_STACK];
118
for (int i = 0; i < BIG_ENOUGH_STACK; i++)
120
#undef BIG_ENOUGH_STACK
112
122
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
113
123
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
115
sp.sched_priority = 20;
116
if (sched_setscheduler(0, SCHED_RR, &sp) == 0) {
117
fprintf(stderr, "mess: %s: running as realtime process now (priority %d)\n",
121
fprintf(stderr, "mess: %s: Can't get realtime priority: %s\n",
122
_name, strerror(errno));
124
if (mlockall(MCL_FUTURE))
125
perror("mess: Cannot lock memory");
127
undoSetuid(euid, ruid);
126
if ((policy = sched_getscheduler (0)) < 0) {
127
printf("Cannot get current client scheduler: %s\n", strerror(errno));
130
printf("Mess: MidiThread set to %s priority 60\n",
131
policy == SCHED_FIFO ? "SCHED_FIFO" : "SCHED_OTHER");
133
pthread_mutex_lock(&messLock);
134
pthread_cond_signal(&messReady);
135
pthread_mutex_unlock(&messLock);
132
139
int n = poll(pfd, npfd, -1); // wait infinite for event
141
perror("MusE Mess: poll failed");
145
fprintf(stderr, "MusE: Mess: poll return zero\n");
136
150
snd_seq_event_t* event;
137
151
int rv = snd_seq_event_input(alsaSeq, &event);
219
244
Mess::Mess(const char* cn, int chn)
220
245
: _className(strdup(cn))
223
outputPorts = new float*[_channels];
247
realTimePriority = 60;
251
outputPorts = new float*[_channels];
257
_sampleRate = 44100; // default
230
258
pthread_mutex_init(&lock, 0);
259
pthread_mutex_init(&messLock, 0);
260
pthread_cond_init(&messReady, 0);
233
263
//---------------------------------------------------------
235
265
//---------------------------------------------------------
237
#if (SND_LIB_MAJOR==0) && (SND_LIB_MINOR==9)
269
pthread_cancel(midiThread);
270
pthread_join(midiThread, 0);
271
pthread_mutex_destroy(&lock);
272
pthread_mutex_destroy(&messLock);
240
281
delete[] outputPorts;
244
285
delete _className;
246
#ifdef snd_seq_port_info_alloca
247
int error = snd_seq_delete_port(alsaSeq, _alsaPort.port);
249
snd_seq_port_info_t *pinfo;
250
pinfo = (snd_seq_port_info_t*)alloca(sizeof(*pinfo));
251
memset(pinfo, 0, sizeof(*pinfo));
252
pinfo->client = _alsaPort.client;
253
pinfo->port = _alsaPort.port;
254
int error = snd_seq_delete_port(alsaSeq, pinfo);
257
fprintf(stderr, "ALSA: cannot delete port: %s\n",
258
snd_strerror(error));
264
//---------------------------------------------------------
266
//---------------------------------------------------------
268
#if (SND_LIB_MAJOR==0) && (SND_LIB_MINOR==5)
277
snd_seq_port_info_t* pinfo = new snd_seq_port_info_t;
278
memset(pinfo, 0, sizeof(*pinfo));
279
pinfo->client = _alsaPort.client;
280
pinfo->port = _alsaPort.port;
281
int error = snd_seq_delete_port(alsaSeq, pinfo);
283
fprintf(stderr, "ALSA: cannot delete port: %s\n",
284
snd_strerror(error));
291
//---------------------------------------------------------
293
//---------------------------------------------------------
295
void Mess::setName(const char* s)
287
printf("~Mess(): no seq!\n");
290
int error = snd_seq_delete_port(alsaSeq, _alsaPort.port);
292
fprintf(stderr, "ALSA: cannot delete port: %s\n",
293
snd_strerror(error));
295
// why does this not remove client from client table?:
296
error = snd_seq_close(alsaSeq);
298
fprintf(stderr, "ALSA: cannot close seq: %s\n",
299
snd_strerror(error));
303
//---------------------------------------------------------
305
//---------------------------------------------------------
309
Chunk* n = new Chunk;
313
char* start = n->mem;
314
char* last = &start[(nelem-1)*sizeof(MEvent)];
316
for (char* p = start; p < last; p += sizeof(MEvent)) {
317
reinterpret_cast<Verweis*>(p)->next
318
= reinterpret_cast<Verweis*>(p + sizeof(MEvent));
320
reinterpret_cast<Verweis*>(last)->next = 0;
321
head = reinterpret_cast<Verweis*>(start);
300
324
//---------------------------------------------------------
302
326
//---------------------------------------------------------
304
#if (SND_LIB_MAJOR==0) && (SND_LIB_MINOR==9)
305
328
void Mess::registerAlsa()
307
330
//-----------------------------------------
331
354
//-----------------------------------------
332
355
// find an unused alsa port name
333
357
//-----------------------------------------
359
bool museFound = false;
335
360
char buffer[256];
336
361
for (int i = 1;; ++i) {
337
362
bool found = false;
338
363
sprintf(buffer, "%s-%d", _className, i);
340
365
snd_seq_client_info_t* cinfo;
341
#ifdef snd_seq_client_info_alloca
342
366
snd_seq_client_info_alloca(&cinfo);
343
367
snd_seq_client_info_set_client(cinfo, -1);
345
cinfo = (snd_seq_client_info_t*)alloca(sizeof(*cinfo));
346
memset(cinfo, 0, sizeof(*cinfo));
349
368
while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
350
#ifdef SND_SEQ_GROUP_SYSTEM
351
if (strcmp(cinfo->group, SND_SEQ_GROUP_SYSTEM) == 0)
354
369
snd_seq_port_info_t *pinfo;
355
#ifdef snd_seq_port_info_alloca
356
370
snd_seq_port_info_alloca(&pinfo);
357
371
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
358
372
snd_seq_port_info_set_port(pinfo, -1);
360
pinfo = (snd_seq_port_info_t*)alloca(sizeof(*pinfo));
361
memset(pinfo, 0, sizeof(*pinfo));
362
pinfo->client = cinfo->client;
365
373
while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
366
374
const char* portname;
367
#ifdef snd_seq_port_info_alloca
368
375
portname = snd_seq_port_info_get_name(pinfo);
370
portname = pinfo->name;
372
// printf("compare port <%s> <%s>\n", portname, buffer);
373
if (strcmp(portname, buffer) == 0) {
384
_name = strdup(buffer);
388
snd_seq_client_info_t* cinfo;
389
#ifdef snd_seq_client_info_alloca
390
snd_seq_client_info_alloca(&cinfo);
391
snd_seq_client_info_set_client(cinfo, -1);
393
cinfo = (snd_seq_client_info_t*)alloca(sizeof(*cinfo));
394
memset(cinfo, 0, sizeof(*cinfo));
397
while (snd_seq_query_next_client(alsaSeq, cinfo) >= 0) {
399
snd_seq_port_info_t *pinfo;
400
#ifdef snd_seq_port_info_alloca
401
snd_seq_port_info_alloca(&pinfo);
402
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
403
snd_seq_port_info_set_port(pinfo, -1);
405
pinfo = (snd_seq_port_info_t*)alloca(sizeof(*pinfo));
406
memset(pinfo, 0, sizeof(*pinfo));
407
pinfo->client = cinfo->client;
410
while (snd_seq_query_next_port(alsaSeq, pinfo) >= 0) {
411
const char* portname;
412
#ifdef snd_seq_port_info_alloca
413
portname = snd_seq_port_info_get_name(pinfo);
415
portname = pinfo->name;
417
if (strcmp(portname, "MusE Port 0") == 0) {
419
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
421
_musePort.port = snd_seq_port_info_get_port(pinfo);
422
_musePort.client = snd_seq_client_info_get_client(cinfo);
430
printf("muse port not found!\n");
433
//-----------------------------------------
434
// create port to alsa sequencer
435
//-----------------------------------------
437
int port = snd_seq_create_simple_port(alsaSeq, _name,
438
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
439
SND_SEQ_PORT_TYPE_APPLICATION);
440
// printf("create new alsa port <%s>\n", _name);
442
perror("create port");
445
_alsaPort.port = port;
446
_alsaPort.client = snd_seq_client_id(alsaSeq);
448
// create the midi thread
449
int err = pthread_create(&midiThread, 0, midi_run, this);
451
printf("Mess: Couldn't create midi thread: %s\n",
457
#if (SND_LIB_MAJOR==0) && (SND_LIB_MINOR==5)
458
//---------------------------------------------------------
461
//---------------------------------------------------------
463
void Mess::registerAlsa()
465
//-----------------------------------------
466
// connect to ALSA and get poll
468
//-----------------------------------------
470
int error = snd_seq_open(&alsaSeq, SND_SEQ_OPEN|SND_SEQ_NONBLOCK);
472
fprintf(stderr, "Could not open ALSA sequencer: %s\n",
473
snd_strerror(error));
478
int alsaSeqFd = snd_seq_file_descriptor(alsaSeq);
482
pfd->events = POLLIN;
485
//-----------------------------------------
486
// find an unused alsa port name
487
//-----------------------------------------
489
snd_seq_system_info_t sysinfo;
490
int error = snd_seq_system_info(alsaSeq, &sysinfo);
492
fprintf(stderr, "Cound not get ALSA sequencer info: %s\n",
493
snd_strerror(error));
499
for (int i = 1;; ++i) {
501
sprintf(buffer, "%s-%d", _className, i);
502
for (int client = 0; client < sysinfo.clients; ++client) {
503
snd_seq_client_info_t cinfo;
504
if (snd_seq_get_any_client_info(alsaSeq, client, &cinfo) < 0)
507
for (int port = 0; port < sysinfo.ports; port++) {
508
snd_seq_port_info_t pinfo;
510
if (snd_seq_get_any_port_info(alsaSeq, client, port, &pinfo) < 0)
512
const char* portname = pinfo.name;
513
if (strcmp(portname, buffer) == 0) {
524
_name = strdup(buffer);
528
for (int client = 0; client < sysinfo.clients; ++client) {
530
snd_seq_client_info_t cinfo;
531
if (snd_seq_get_any_client_info(alsaSeq, client, &cinfo) < 0)
533
for (int port = 0; port < sysinfo.ports; port++) {
534
snd_seq_port_info_t pinfo;
536
if (snd_seq_get_any_port_info(alsaSeq, client, port, &pinfo) < 0)
538
const char* portname = pinfo.name;
539
if (strcmp(portname, "MusE Port 0") == 0) {
541
_musePort.port = pinfo.port;
542
_musePort.client = cinfo.client;
550
printf("muse port not found!\n");
553
//-----------------------------------------
554
// create port to alsa sequencer
555
//-----------------------------------------
557
int port = snd_seq_create_simple_port(alsaSeq, _name,
558
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
559
SND_SEQ_PORT_TYPE_APPLICATION);
560
// printf("create new alsa port <%s>\n", _name);
562
perror("create port");
565
_alsaPort.port = port;
566
_alsaPort.client = snd_seq_client_id(alsaSeq);
568
// create the midi thread
569
int err = pthread_create(&midiThread, 0, midi_run, this);
571
printf("Mess: Couldn't create midi thread: %s\n",
376
if (strcmp(portname, buffer) == 0) {
380
if (strcmp(portname, "MusE Port 0") == 0) {
382
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
383
_musePort.port = snd_seq_port_info_get_port(pinfo);
384
_musePort.client = snd_seq_client_info_get_client(cinfo);
394
printf("Mess: muse port not found!\n");
397
_name = strdup(buffer);
399
//-----------------------------------------
400
// create port to alsa sequencer
401
//-----------------------------------------
403
int port = snd_seq_create_simple_port(alsaSeq, _name,
404
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
405
SND_SEQ_PORT_TYPE_APPLICATION);
407
perror("create port");
410
_alsaPort.port = port;
411
_alsaPort.client = snd_seq_client_id(alsaSeq);
413
//----------------------------------------------
414
// create the midi thread
415
// with SCHED_FIFO and priority 60
417
pthread_attr_t* attributes = 0;
418
doSetuid(euid, ruid);
419
if (realTimePriority) {
420
struct sched_param rt_param;
421
memset(&rt_param, 0, sizeof(rt_param));
422
rt_param.sched_priority = 60;
424
attributes = new pthread_attr_t;
425
pthread_attr_init(attributes);
427
if (pthread_attr_setschedpolicy(attributes, SCHED_FIFO)) {
428
printf("Mess: cannot set FIFO scheduling class for RT thread\n");
430
if (pthread_attr_setschedparam(attributes, &rt_param)) {
431
printf("Mess: Cannot set scheduling priority for RT thread (%s)\n", strerror(errno));
433
if (pthread_attr_setscope(attributes, PTHREAD_SCOPE_SYSTEM)) {
434
printf("Mess: Cannot set scheduling scope for RT thread\n");
437
pthread_mutex_lock(&messLock);
439
int err = pthread_create(&midiThread, attributes, midi_run, this);
442
printf("Mess: Couldn't create midi thread: %s\n",
445
pthread_cond_wait(&messReady, &messLock);
446
pthread_mutex_unlock(&messLock);
449
pthread_attr_destroy(attributes);
452
undoSetuid(euid, ruid);
577
455
//---------------------------------------------------------