~ubuntu-branches/ubuntu/oneiric/muse/oneiric

« back to all changes in this revision

Viewing changes to muse/driver/jackmidi.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2010-11-17 21:43:38 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20101117214338-1hvfl7oo2dsqnvrb
Tags: 1.1-0ubuntu1
* New upstream release (LP: #668631)
* Switch to dpkg-source 3.0 (quilt) format
* Switch to dh7 short form
* debian/rules:
  - added --enable-dssi and --enable-osc to conf flags for dssi support
  - added -ljackserver to LDFLAGS to fix a FTBFS because of --as-needed
* debian/control:
  - added build build dependency on liblo-dev and dssi-dev for dssi support
  - bump Standards-version to 3.9.1. No changes required.
* debian/muse.desktop, debian/muse.xpm: dropped as desktop file and icon is
  now shipped upstream.
* fix-desktop-categories.patch: fix Categories tag in upstream desktop file
* 10_es_locale_fix.dpatch: refreshed and converted to quilt as
  fix_es_locale.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//  $Id: jackmidi.cpp,v 1.1.1.1 2010/01/27 09:06:43 terminator356 Exp $
 
5
//  (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)
 
6
//=========================================================
 
7
 
 
8
#include <qt.h>
 
9
#include <qstring.h>
 
10
#include <stdio.h>
 
11
 
 
12
#include <jack/jack.h>
 
13
//#include <jack/midiport.h>
 
14
 
 
15
#include "jackmidi.h"
 
16
#include "song.h"
 
17
#include "globals.h"
 
18
#include "midi.h"
 
19
#include "mididev.h"
 
20
#include "../midiport.h"
 
21
#include "../midiseq.h"
 
22
#include "../midictrl.h"
 
23
#include "../audio.h"
 
24
#include "mpevent.h"
 
25
//#include "sync.h"
 
26
#include "audiodev.h"
 
27
#include "../mplugins/midiitransform.h"
 
28
#include "../mplugins/mitplugin.h"
 
29
#include "xml.h"
 
30
 
 
31
// Turn on debug messages.
 
32
//#define JACK_MIDI_DEBUG
 
33
 
 
34
extern unsigned int volatile lastExtMidiSyncTick;
 
35
 
 
36
///int jackmidi_pi[2];
 
37
///int jackmidi_po[2];
 
38
 
 
39
//extern muse_jack_midi_buffer jack_midi_out_data[JACK_MIDI_CHANNELS];
 
40
//extern muse_jack_midi_buffer jack_midi_in_data[JACK_MIDI_CHANNELS];
 
41
///extern jack_port_t *midi_port_in[JACK_MIDI_CHANNELS];
 
42
///extern jack_port_t *midi_port_out[JACK_MIDI_CHANNELS];
 
43
 
 
44
///MidiJackDevice* gmdev = NULL;
 
45
 
 
46
///int* jackSeq;
 
47
//static snd_seq_addr_t musePort;
 
48
 
 
49
//int MidiJackDevice::_nextOutIdNum = 0;
 
50
//int MidiJackDevice::_nextInIdNum = 0;
 
51
 
 
52
//int JackMidiPortList::_nextOutIdNum = 0;
 
53
//int JackMidiPortList::_nextInIdNum = 0;
 
54
 
 
55
//JackMidiPortList jackMidiClientPorts;
 
56
 
 
57
 
 
58
/*
 
59
//---------------------------------------------------------
 
60
//   JackMidiPortList
 
61
//---------------------------------------------------------
 
62
 
 
63
JackMidiPortList::JackMidiPortList()
 
64
{
 
65
 
 
66
}
 
67
 
 
68
JackMidiPortList::~JackMidiPortList()
 
69
{
 
70
 
 
71
}
 
72
 
 
73
iJackMidiPort JackMidiPortList::createClientPort(int flags) // 1 = writable, 2 = readable - do not mix
 
74
{
 
75
  if(flags & 1)
 
76
  {
 
77
    char buf[80];
 
78
    snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
 
79
    jack_port_t* _client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
 
80
    if(_client_jackport == NULL)
 
81
    {
 
82
      fprintf(stderr, "JackMidiPortList::createClientPort failed to register jack-midi-out\n");
 
83
      //return QString("Could not register jack-midi-out client port");
 
84
      return end();
 
85
    }
 
86
    else
 
87
    {
 
88
      JackMidiPort jmp(_client_jackport, QString(buf), flags);
 
89
      _nextOutIdNum++;
 
90
      return insert(begin(), std::pair<jack_port_t*, JackMidiPort>(_client_jackport, jmp));
 
91
    }
 
92
  }
 
93
  else 
 
94
  if(flags & 2)
 
95
  {  
 
96
    char buf[80];
 
97
    snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
 
98
    jack_port_t* _client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
 
99
    if(_client_jackport == NULL)
 
100
    {
 
101
      fprintf(stderr, "JackMidiPortList::createClientPort failed to register jack-midi-in\n");
 
102
      return end();
 
103
    }
 
104
    else
 
105
    {
 
106
      JackMidiPort jmp(_client_jackport, QString(buf), flags);
 
107
      _nextInIdNum++;
 
108
      return insert(begin(), std::pair<jack_port_t*, JackMidiPort>(_client_jackport, jmp));
 
109
    }
 
110
  }
 
111
  return end();
 
112
}
 
113
 
 
114
// Return true if removed.
 
115
bool JackMidiPortList::removeClientPort(jack_port_t* port) 
 
116
{
 
117
  iJackMidiPort ijp = find(port);
 
118
  if(ijp == end())
 
119
    return false;
 
120
    
 
121
  // Is output?
 
122
  if(ijp->second._flags & 1)
 
123
    _nextOutIdNum--;
 
124
  // Is input?
 
125
  if(ijp->second._flags & 2)
 
126
    _nextInIdNum--;
 
127
  
 
128
  erase(ijp);
 
129
  
 
130
  audioDevice->unregisterPort(port);
 
131
  
 
132
  return true;
 
133
}
 
134
*/
 
135
 
 
136
//---------------------------------------------------------
 
137
//   MidiJackDevice
 
138
//---------------------------------------------------------
 
139
 
 
140
//MidiJackDevice::MidiJackDevice(const int& a, const QString& n)
 
141
MidiJackDevice::MidiJackDevice(jack_port_t* jack_port, const QString& n)
 
142
   : MidiDevice(n)
 
143
{
 
144
  //_client_jackport = 0;
 
145
  _client_jackport = jack_port;
 
146
  //adr = a;
 
147
  init();
 
148
}
 
149
 
 
150
MidiJackDevice::~MidiJackDevice()
 
151
{
 
152
  #ifdef JACK_MIDI_DEBUG
 
153
    printf("MidiJackDevice::~MidiJackDevice()\n");
 
154
  #endif  
 
155
  if(_client_jackport)
 
156
    audioDevice->unregisterPort(_client_jackport);
 
157
    //close();
 
158
}
 
159
            
 
160
/*
 
161
//---------------------------------------------------------
 
162
//   select[RW]fd
 
163
//---------------------------------------------------------
 
164
 
 
165
int MidiJackDevice::selectRfd()
 
166
{
 
167
  return jackmidi_pi[0];
 
168
}
 
169
 
 
170
int MidiJackDevice::selectWfd()
 
171
{
 
172
  return jackmidi_po[0];
 
173
}
 
174
*/
 
175
 
 
176
//---------------------------------------------------------
 
177
//   createJackMidiDevice
 
178
//   If name parameter is blank, creates a new (locally) unique one.
 
179
//---------------------------------------------------------
 
180
 
 
181
//QString MidiJackDevice::createJackMidiDevice(int rwflags) // 1:Writable 2: Readable. Do not mix.
 
182
MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1:Writable 2: Readable. Do not mix.
 
183
{
 
184
///  _openFlags &= _rwFlags; // restrict to available bits
 
185
  
 
186
///  #ifdef JACK_MIDI_DEBUG
 
187
///  printf("MidiJackDevice::open %s\n", name.latin1());
 
188
///  #endif  
 
189
  
 
190
  //jack_port_t* jp = jack_port_by_name(_client, name().latin1());
 
191
///  jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().latin1());
 
192
  
 
193
///  if(!jp)
 
194
///  {
 
195
///    printf("MidiJackDevice::open: Jack midi port %s not found!\n", name().latin1());
 
196
///    _writeEnable = false;
 
197
///    _readEnable = false;
 
198
///    return QString("Jack midi port not found");
 
199
///  }
 
200
    
 
201
///  int pf = jack_port_flags(jp);
 
202
  
 
203
  //if(!name.isEmpty())
 
204
  //{
 
205
  //  Does not work.
 
206
  //  if(audioDevice->findPort(name.latin1()))
 
207
  //  {
 
208
  //    fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Given port name %s already exists!\n", name.latin1());
 
209
  //    return 0;  
 
210
  //  }  
 
211
  //}
 
212
  
 
213
  jack_port_t* client_jackport = NULL;
 
214
  //char buf[80];
 
215
    
 
216
  
 
217
  // If Jack port can receive data from us and we actually want to...
 
218
  //if((pf & JackPortIsInput) && (_openFlags & 1))
 
219
  if(rwflags & 1)
 
220
  {
 
221
    if(name.isEmpty())
 
222
    {
 
223
      //snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
 
224
      for(int i = 0; ; ++i)
 
225
      {
 
226
        //snprintf(buf, 80, "midi-out-%d", i);
 
227
        name.sprintf("midi-out-%d", i);
 
228
        
 
229
        if(!midiDevices.find(name))
 
230
        {
 
231
          // Does not work.
 
232
          //if(!audioDevice->findPort(buf))
 
233
          //  break;
 
234
          //client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
 
235
          if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)   // p3.3.52
 
236
          {
 
237
            client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
 
238
            if(client_jackport)
 
239
              break;
 
240
          }
 
241
          else
 
242
            break;    
 
243
        }    
 
244
          
 
245
        if(i == 65535)
 
246
        {
 
247
          fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused output port name!\n");
 
248
          return 0;
 
249
        }
 
250
      }
 
251
      //name = QString(buf);
 
252
    }
 
253
    else
 
254
    {
 
255
      if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)       // p3.3.52
 
256
      {
 
257
        client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
 
258
        if(!client_jackport)
 
259
        {
 
260
          fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating output port name %s\n", name.latin1());
 
261
          return 0;
 
262
        }
 
263
      }  
 
264
    }
 
265
    /*
 
266
    else
 
267
    {
 
268
      client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
 
269
      if(!client_jackport)
 
270
      {
 
271
        for(int i = 0; ; ++i)
 
272
        {
 
273
          snprintf(buf, 80, "midi-out-%d", i);
 
274
          // Does not work!
 
275
          //if(!audioDevice->findPort(buf))
 
276
          //  break;
 
277
          client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
 
278
          if(client_jackport)
 
279
            break;
 
280
            
 
281
          if(i == 65535)
 
282
          {
 
283
            fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused output port name!\n");
 
284
            return 0;
 
285
          }
 
286
        }
 
287
        name = QString(buf);
 
288
      }    
 
289
    }
 
290
    */
 
291
    
 
292
    //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.latin1(), true);
 
293
    //if(client_jackport == NULL)
 
294
    //{
 
295
    //  fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed to register jack midi client output port %s\n", name.latin1());
 
296
    //  return 0;
 
297
    //}
 
298
    //else
 
299
    //  _nextOutIdNum++;
 
300
    
 
301
  }
 
302
  else // Note docs say it can't be both input and output.
 
303
  // If Jack port can send data to us and we actually want it...
 
304
  //if((pf & JackPortIsOutput) && (_openFlags & 2))
 
305
  if(rwflags & 2)
 
306
  {  
 
307
    if(name.isEmpty())
 
308
    {
 
309
      //snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
 
310
      for(int i = 0; ; ++i)
 
311
      {
 
312
        //snprintf(buf, 80, "midi-in-%d", i);
 
313
        name.sprintf("midi-in-%d", i); 
 
314
        
 
315
        if(!midiDevices.find(name))
 
316
        {
 
317
          // Does not work.
 
318
          //if(!audioDevice->findPort(buf))
 
319
          //  break;
 
320
          //client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
 
321
          if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)       // p3.3.52
 
322
          {
 
323
            client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
 
324
            if(client_jackport)
 
325
              break;
 
326
          }
 
327
          else
 
328
            break;    
 
329
        }    
 
330
          
 
331
        if(i == 65535)
 
332
        {
 
333
          fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused input port name!\n");
 
334
          return 0;
 
335
        }
 
336
      }
 
337
      //name = QString(buf);
 
338
    }
 
339
    else
 
340
    {
 
341
      if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO)       // p3.3.52
 
342
      {
 
343
        client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
 
344
        if(!client_jackport)
 
345
        {
 
346
          fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating input port name %s\n", name.latin1());
 
347
          return 0;
 
348
        }  
 
349
      }
 
350
    }
 
351
      
 
352
    //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.latin1(), true);
 
353
    
 
354
    //if(client_jackport == NULL)
 
355
    //{
 
356
    //  fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed to register jack midi client input port %s\n", name.latin1());
 
357
      //_readEnable = false;
 
358
      //return QString("Could not register jack-midi-in client port");
 
359
    //  return 0;
 
360
    //}
 
361
    //else
 
362
    //  _nextInIdNum++;
 
363
    
 
364
  }
 
365
    
 
366
  //if(client_jackport == NULL)  // p3.3.52 Removed. Allow the device to be created even if Jack isn't running.
 
367
  //  return 0;
 
368
    
 
369
  MidiJackDevice* dev = new MidiJackDevice(client_jackport, name);
 
370
  dev->setrwFlags(rwflags);
 
371
  midiDevices.add(dev);
 
372
  return dev;
 
373
}
 
374
 
 
375
//---------------------------------------------------------
 
376
//   setName
 
377
//---------------------------------------------------------
 
378
 
 
379
void MidiJackDevice::setName(const QString& s)
 
380
 
381
  #ifdef JACK_MIDI_DEBUG
 
382
  printf("MidiJackDevice::setName %s new name:%s\n", name().latin1(), s.latin1());
 
383
  #endif  
 
384
  _name = s; 
 
385
  if(clientPort())  // p3.3.52 Added check.
 
386
    audioDevice->setPortName(clientPort(), s.latin1());
 
387
}
 
388
 
 
389
//---------------------------------------------------------
 
390
//   open
 
391
//---------------------------------------------------------
 
392
 
 
393
QString MidiJackDevice::open()
 
394
{
 
395
  _openFlags &= _rwFlags; // restrict to available bits
 
396
  
 
397
  #ifdef JACK_MIDI_DEBUG
 
398
  printf("MidiJackDevice::open %s\n", name().latin1());
 
399
  #endif  
 
400
  
 
401
  /*
 
402
  //jack_port_t* jp = jack_port_by_name(_client, name().latin1());
 
403
  jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().latin1());
 
404
  
 
405
  if(!jp)
 
406
  {
 
407
    printf("MidiJackDevice::open: Jack midi port %s not found!\n", name().latin1());
 
408
    _writeEnable = false;
 
409
    _readEnable = false;
 
410
    return QString("Jack midi port not found");
 
411
  }
 
412
    
 
413
  int pf = jack_port_flags(jp);
 
414
  
 
415
  // If Jack port can receive data from us and we actually want to...
 
416
  if((pf & JackPortIsInput) && (_openFlags & 1))
 
417
  {
 
418
    char buf[80];
 
419
    snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
 
420
    _client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
 
421
    if(_client_jackport == NULL)
 
422
    {
 
423
      fprintf(stderr, "MidiJackDevice::open failed to register jack-midi-out\n");
 
424
      _writeEnable = false;
 
425
      return QString("Could not register jack-midi-out client port");
 
426
    }
 
427
    else
 
428
    {
 
429
      _nextOutIdNum++;
 
430
      // src, dest
 
431
      ///audioDevice->connect(_client_jackport, jp);
 
432
      _writeEnable = true;
 
433
    }
 
434
  }
 
435
  else // Note docs say it can't be both input and output.
 
436
  // If Jack port can send data to us and we actually want it...
 
437
  if((pf & JackPortIsOutput) && (_openFlags & 2))
 
438
  {  
 
439
    char buf[80];
 
440
    snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
 
441
    _client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
 
442
    if(_client_jackport == NULL)
 
443
    {
 
444
      fprintf(stderr, "MidiJackDevice::open failed to register jack-midi-in\n");
 
445
      _readEnable = false;
 
446
      return QString("Could not register jack-midi-in client port");
 
447
    }
 
448
    else
 
449
    {
 
450
      _nextInIdNum++;
 
451
      ///audioDevice->connect(jp, _client_jackport);
 
452
      _readEnable = true;
 
453
    }
 
454
  }
 
455
  */
 
456
  
 
457
  _writeEnable = bool(_openFlags & 1);
 
458
  _readEnable = bool(_openFlags & 2);
 
459
  
 
460
  return QString("OK");
 
461
}
 
462
 
 
463
//---------------------------------------------------------
 
464
//   close
 
465
//---------------------------------------------------------
 
466
 
 
467
void MidiJackDevice::close()
 
468
{
 
469
  #ifdef JACK_MIDI_DEBUG
 
470
  printf("MidiJackDevice::close %s\n", name().latin1());
 
471
  #endif  
 
472
  
 
473
  /*
 
474
  if(_client_jackport)
 
475
  {
 
476
    int pf = jack_port_flags(_client_jackport);
 
477
 
 
478
    if(pf & JackPortIsOutput)
 
479
      _nextOutIdNum--;
 
480
    else
 
481
    if(pf & JackPortIsInput)
 
482
      _nextInIdNum--;
 
483
    audioDevice->unregisterPort(_client_jackport);
 
484
    _client_jackport = 0;
 
485
    _writeEnable = false;
 
486
    _readEnable = false;
 
487
    return;
 
488
  }  
 
489
  */
 
490
    
 
491
  _writeEnable = false;
 
492
  _readEnable = false;
 
493
  
 
494
  /*
 
495
  //jack_port_t* jp = jack_port_by_name(_client, name().latin1());
 
496
  jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().latin1());
 
497
  
 
498
  if(!jp)
 
499
  {
 
500
    printf("MidiJackDevice::close: Jack midi port %s not found!\n", name().latin1());
 
501
    _writeEnable = false;
 
502
    _readEnable = false;
 
503
    return;
 
504
  }
 
505
    
 
506
  //int pf = jack_port_flags(jp);
 
507
  
 
508
  // If Jack port can receive data from us and we actually want to...
 
509
  //if((pf & JackPortIsInput) && (_openFlags & 1))
 
510
  if(jack_port_connected_to(midi_port_out[0], name().latin1()))
 
511
  {
 
512
    // src, dest
 
513
///    audioDevice->disconnect(midi_port_out[0], jp);
 
514
    _writeEnable = false;
 
515
  }
 
516
  else // Note docs say it can't be both input and output.  
 
517
  // If Jack port can send data to us and we actually want it...
 
518
  //if((pf & JackPortIsOutput) && (_openFlags & 2))
 
519
  if(jack_port_connected_to(midi_port_in[0], name().latin1()))
 
520
  {  
 
521
///    audioDevice->disconnect(jp, midi_port_in[0]);
 
522
    _readEnable = false;
 
523
  }
 
524
  */
 
525
}
 
526
 
 
527
//---------------------------------------------------------
 
528
//   writeRouting
 
529
//---------------------------------------------------------
 
530
 
 
531
void MidiJackDevice::writeRouting(int level, Xml& xml) const
 
532
{
 
533
      // p3.3.45
 
534
      // If this device is not actually in use by the song, do not write any routes.
 
535
      // This prevents bogus routes from being saved and propagated in the med file.
 
536
      if(midiPort() == -1)
 
537
        return;
 
538
      
 
539
      QString s;
 
540
      if(rwFlags() & 2)  // Readable
 
541
      {
 
542
        //RouteList* rl = _inRoutes;
 
543
        //for (ciRoute r = rl->begin(); r != rl->end(); ++r) 
 
544
        for (ciRoute r = _inRoutes.begin(); r != _inRoutes.end(); ++r) 
 
545
        {
 
546
          if(!r->name().isEmpty())
 
547
          {
 
548
            xml.tag(level++, "Route");
 
549
            
 
550
            //xml.strTag(level, "srcNode", r->name());
 
551
            //xml.tag(level, "source type=\"%d\" name=\"%s\"/", r->type, r->name().latin1());
 
552
            s = QT_TR_NOOP("source");
 
553
            if(r->type != Route::TRACK_ROUTE)
 
554
              s += QString(QT_TR_NOOP(" type=\"%1\"")).arg(r->type);
 
555
 
 
556
            //s += QString(QT_TR_NOOP(" name=\"%1\"/")).arg(r->name());
 
557
            s += QString(QT_TR_NOOP(" name=\"%1\"/")).arg(Xml::xmlString(r->name()));
 
558
            xml.tag(level, s);
 
559
            
 
560
            //xml.strTag(level, "dstNode", name());
 
561
            //xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().latin1());
 
562
            //xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, name().latin1());
 
563
            //xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, name().latin1());
 
564
            xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).latin1());
 
565
            
 
566
            xml.etag(level--, "Route");
 
567
          }
 
568
        }  
 
569
      } 
 
570
      
 
571
      for (ciRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) 
 
572
      {
 
573
        if(!r->name().isEmpty())
 
574
        {
 
575
          s = QT_TR_NOOP("Route");
 
576
          if(r->channel != -1)
 
577
            s += QString(QT_TR_NOOP(" channel=\"%1\"")).arg(r->channel);
 
578
          
 
579
          //xml.tag(level++, "Route");
 
580
          xml.tag(level++, s);
 
581
          
 
582
          /*
 
583
          //xml.strTag(level, "srcNode", name());
 
584
          if(r->channel != -1)  
 
585
            //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, r->channel, name().latin1());
 
586
            //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, r->channel, name().latin1());
 
587
            xml.tag(level, "source devtype=\"%d\" channel=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, r->channel, name().latin1());
 
588
          else  
 
589
            //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().latin1());
 
590
            //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, name().latin1());
 
591
          */  
 
592
            //xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, name().latin1());
 
593
            xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).latin1());
 
594
          
 
595
          /*
 
596
          //xml.strTag(level, "dstNode", r->name());
 
597
          if(r->channel != -1)
 
598
          {  
 
599
            if(r->type == Route::MIDI_DEVICE_ROUTE)
 
600
              xml.tag(level, "dest devtype=\"%d\" channel=\"%d\" name=\"%s\"/", r->device->deviceType(), r->channel, r->name().latin1());
 
601
            else  
 
602
              xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", r->type, r->channel, r->name().latin1());
 
603
          }
 
604
          else  
 
605
          {
 
606
            if(r->type == Route::MIDI_DEVICE_ROUTE)
 
607
              xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", r->device->deviceType(), r->name().latin1());
 
608
            else  
 
609
              xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().latin1());
 
610
          }
 
611
          */
 
612
          
 
613
          s = QT_TR_NOOP("dest");
 
614
          if(r->type == Route::MIDI_DEVICE_ROUTE)
 
615
            s += QString(QT_TR_NOOP(" devtype=\"%1\"")).arg(r->device->deviceType());
 
616
          else
 
617
          if(r->type != Route::TRACK_ROUTE)
 
618
            s += QString(QT_TR_NOOP(" type=\"%1\"")).arg(r->type);
 
619
 
 
620
          //s += QString(QT_TR_NOOP(" name=\"%1\"/")).arg(r->name());
 
621
          s += QString(QT_TR_NOOP(" name=\"%1\"/")).arg(Xml::xmlString(r->name()));
 
622
          xml.tag(level, s);
 
623
          
 
624
          
 
625
          xml.etag(level--, "Route");
 
626
        }
 
627
      }
 
628
      
 
629
      /*
 
630
      else
 
631
      if(rwFlags() & 1)  // Writable
 
632
      {
 
633
        //RouteList* rl = _outRoutes;
 
634
        //for (ciRoute r = rl->begin(); r != rl->end(); ++r) 
 
635
        for (ciRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) 
 
636
        {
 
637
          if(!r->name().isEmpty())
 
638
          {
 
639
            xml.tag(level++, "Route");
 
640
            
 
641
            //xml.strTag(level, "srcNode", name());
 
642
            //if(r->channel != -1)  
 
643
            //  xml.tag(level, "srcNode type=\"%d\" channel=\"%d\" name=\"%s\"", Route::JACK_MIDI_ROUTE, r->channel, name().latin1());
 
644
            //else  
 
645
              xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().latin1());
 
646
            
 
647
            //xml.strTag(level, "dstNode", r->name());
 
648
            xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().latin1());
 
649
            
 
650
            xml.etag(level--, "Route");
 
651
          }
 
652
        }  
 
653
      }
 
654
      */      
 
655
}
 
656
    
 
657
//---------------------------------------------------------
 
658
//   putEvent
 
659
//---------------------------------------------------------
 
660
 
 
661
/* FIX: if we fail to transmit the event,
 
662
 *      we return false (indicating OK). Otherwise
 
663
 *      it seems muse will retry forever
 
664
 */
 
665
bool MidiJackDevice::putMidiEvent(const MidiPlayEvent& /*event*/)
 
666
{
 
667
  /*
 
668
  int give, channel = event.channel();
 
669
  int x;
 
670
 
 
671
  if(channel >= JACK_MIDI_CHANNELS) return false;
 
672
 
 
673
  // buffer up events, because jack eats them in chunks, if
 
674
   // the buffer is full, there isn't so much to do, than
 
675
   // drop the event
 
676
   
 
677
  give = jack_midi_out_data[channel].give;
 
678
  if(jack_midi_out_data[channel].buffer[give*4+3]){
 
679
    fprintf(stderr, "WARNING: muse-to-jack midi-buffer is full, channel=%u\n", channel);
 
680
    return false;
 
681
  }
 
682
  // copy event(note-on etc..), pitch and volume 
 
683
  // see http://www.midi.org/techspecs/midimessages.php 
 
684
  switch(event.type()){
 
685
    case ME_NOTEOFF:
 
686
      jack_midi_out_data[channel].buffer[give*4+0] = 0x80;
 
687
      jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
 
688
      jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
 
689
      break;
 
690
    case ME_NOTEON:
 
691
      jack_midi_out_data[channel].buffer[give*4+0] = 0x90;
 
692
      jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
 
693
      jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
 
694
      break;
 
695
    case ME_CONTROLLER:
 
696
      jack_midi_out_data[channel].buffer[give*4+0] = 0xb0;
 
697
      jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
 
698
      jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
 
699
      break;
 
700
    case ME_PROGRAM:
 
701
      jack_midi_out_data[channel].buffer[give*4+0] = 0xc0;
 
702
      jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
 
703
      jack_midi_out_data[channel].buffer[give*4+2] = 0;
 
704
      break;
 
705
    case ME_PITCHBEND:
 
706
      jack_midi_out_data[channel].buffer[give*4+0] = 0xE0;
 
707
      // convert muse pitch-bend to midi standard 
 
708
      x = 0x2000 + event.dataA();
 
709
      jack_midi_out_data[channel].buffer[give*4+1] = x & 0x7f;
 
710
      jack_midi_out_data[channel].buffer[give*4+2] = (x >> 8) & 0x7f;
 
711
      break;
 
712
    default:
 
713
      fprintf(stderr, "jack-midi-out %u WARNING: unknown event %x\n", channel, event.type());
 
714
      return false;
 
715
  }
 
716
  jack_midi_out_data[channel].buffer[give*4+3] = 1; // mark state of this slot 
 
717
  // finally increase give position 
 
718
  give++;
 
719
  if(give >= JACK_MIDI_BUFFER_SIZE){
 
720
    give = 0;
 
721
  }
 
722
  jack_midi_out_data[channel].give = give;
 
723
  return false;
 
724
  */
 
725
  
 
726
  return false;
 
727
}
 
728
 
 
729
/*
 
730
//---------------------------------------------------------
 
731
//   putEvent
 
732
//    return false if event is delivered
 
733
//---------------------------------------------------------
 
734
 
 
735
bool MidiJackDevice::putEvent(int* event)
 
736
{
 
737
  int *y; y = event;
 
738
  return false;
 
739
}
 
740
*/
 
741
 
 
742
//---------------------------------------------------------
 
743
//   recordEvent
 
744
//---------------------------------------------------------
 
745
 
 
746
void MidiJackDevice::recordEvent(MidiRecordEvent& event)
 
747
      {
 
748
      // Set the loop number which the event came in at.
 
749
      //if(audio->isRecording())
 
750
      if(audio->isPlaying())
 
751
        event.setLoopNum(audio->loopCount());
 
752
      
 
753
      if (midiInputTrace) {
 
754
            printf("Jack MidiInput: ");
 
755
            event.dump();
 
756
            }
 
757
 
 
758
      int typ = event.type();
 
759
      
 
760
      if(_port != -1)
 
761
      {
 
762
        int idin = midiPorts[_port].syncInfo().idIn();
 
763
        
 
764
        //---------------------------------------------------
 
765
        // filter some SYSEX events
 
766
        //---------------------------------------------------
 
767
  
 
768
        if (typ == ME_SYSEX) {
 
769
              const unsigned char* p = event.data();
 
770
              int n = event.len();
 
771
              if (n >= 4) {
 
772
                    if ((p[0] == 0x7f)
 
773
                      //&& ((p[1] == 0x7f) || (p[1] == rxDeviceId))) {
 
774
                      && ((p[1] == 0x7f) || (idin == 0x7f) || (p[1] == idin))) {
 
775
                          if (p[2] == 0x06) {
 
776
                                //mmcInput(p, n);
 
777
                                midiSeq->mmcInput(_port, p, n);
 
778
                                return;
 
779
                                }
 
780
                          if (p[2] == 0x01) {
 
781
                                //mtcInputFull(p, n);
 
782
                                midiSeq->mtcInputFull(_port, p, n);
 
783
                                return;
 
784
                                }
 
785
                          }
 
786
                    else if (p[0] == 0x7e) {
 
787
                          //nonRealtimeSystemSysex(p, n);
 
788
                          midiSeq->nonRealtimeSystemSysex(_port, p, n);
 
789
                          return;
 
790
                          }
 
791
                    }
 
792
              }
 
793
          else    
 
794
            // Trigger general activity indicator detector. Sysex has no channel, don't trigger.
 
795
            midiPorts[_port].syncInfo().trigActDetect(event.channel());
 
796
      }
 
797
      
 
798
      //
 
799
      //  process midi event input filtering and
 
800
      //    transformation
 
801
      //
 
802
 
 
803
      processMidiInputTransformPlugins(event);
 
804
 
 
805
      if (filterEvent(event, midiRecordType, false))
 
806
            return;
 
807
      
 
808
      if (!applyMidiInputTransformation(event)) {
 
809
            if (midiInputTrace)
 
810
                  printf("   midi input transformation: event filtered\n");
 
811
            return;
 
812
            }
 
813
 
 
814
      //
 
815
      // transfer noteOn events to gui for step recording and keyboard
 
816
      // remote control
 
817
      //
 
818
      if (typ == ME_NOTEON) {
 
819
            int pv = ((event.dataA() & 0xff)<<8) + (event.dataB() & 0xff);
 
820
            song->putEvent(pv);
 
821
            }
 
822
      
 
823
      //if(_recordFifo.put(MidiPlayEvent(event)))
 
824
      //  printf("MidiJackDevice::recordEvent: fifo overflow\n");
 
825
      
 
826
      // p3.3.38
 
827
      // Do not bother recording if it is NOT actually being used by a port.
 
828
      // Because from this point on, process handles things, by selected port.
 
829
      if(_port == -1)
 
830
        return;
 
831
      
 
832
      // Split the events up into channel fifos. Special 'channel' number 17 for sysex events.
 
833
      unsigned int ch = (typ == ME_SYSEX)? MIDI_CHANNELS : event.channel();
 
834
      if(_recordFifo[ch].put(MidiPlayEvent(event)))
 
835
        printf("MidiJackDevice::recordEvent: fifo channel %d overflow\n", ch);
 
836
      }
 
837
 
 
838
//---------------------------------------------------------
 
839
//   midiReceived
 
840
//---------------------------------------------------------
 
841
 
 
842
void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
 
843
      {
 
844
      MidiRecordEvent event;
 
845
      event.setB(0);
 
846
 
 
847
      // NOTE: From MusE-2. Not done here in Muse-1 (yet).
 
848
      // move all events 2*segmentSize into the future to get
 
849
      // jitterfree playback
 
850
      //
 
851
      //  cycle   n-1         n          n+1
 
852
      //          -+----------+----------+----------+-
 
853
      //               ^          ^          ^
 
854
      //               catch      process    play
 
855
      //
 
856
//      const SeqTime* st = audio->seqTime();
 
857
 
 
858
      //unsigned curFrame = st->startFrame() + segmentSize;
 
859
//      unsigned curFrame = st->lastFrameTime;
 
860
      //int frameOffset = audio->getFrameOffset();
 
861
      unsigned pos = audio->pos().frame();
 
862
      
 
863
      //event.setTime(pos + ev->time);
 
864
      event.setTime(extSyncFlag.value() ? lastExtMidiSyncTick : (pos + ev->time));
 
865
 
 
866
      event.setChannel(*(ev->buffer) & 0xf);
 
867
      int type = *(ev->buffer) & 0xf0;
 
868
      int a    = *(ev->buffer + 1) & 0x7f;
 
869
      int b    = *(ev->buffer + 2) & 0x7f;
 
870
      event.setType(type);
 
871
      switch(type) {
 
872
            case ME_NOTEON:
 
873
            case ME_NOTEOFF:
 
874
            case ME_CONTROLLER:
 
875
                  event.setA(*(ev->buffer + 1));
 
876
                  event.setB(*(ev->buffer + 2));
 
877
                  break;
 
878
            case ME_PROGRAM:
 
879
            case ME_AFTERTOUCH:
 
880
                  event.setA(*(ev->buffer + 1));
 
881
                  break;
 
882
 
 
883
            case ME_PITCHBEND:
 
884
                  event.setA(((b << 7) + a) - 8192);
 
885
                  break;
 
886
 
 
887
            case ME_SYSEX:
 
888
                  {
 
889
                    int type = *(ev->buffer) & 0xff;
 
890
                    switch(type) 
 
891
                    {
 
892
                          case ME_SYSEX:
 
893
                                
 
894
                                // TODO: Deal with large sysex, which are broken up into chunks!
 
895
                                // For now, do not accept if the last byte is not EOX, meaning it's a chunk with more chunks to follow.
 
896
                                if(*(((unsigned char*)ev->buffer) + ev->size - 1) != ME_SYSEX_END)
 
897
                                {
 
898
                                  printf("MidiJackDevice::eventReceived sysex chunks not supported!\n");
 
899
                                  return;
 
900
                                }
 
901
                                
 
902
                                //event.setTime(0);      // mark as used
 
903
                                event.setType(ME_SYSEX);
 
904
                                event.setData((unsigned char*)(ev->buffer + 1), ev->size - 2);
 
905
                                break;
 
906
                          case ME_MTC_QUARTER:
 
907
                                if(_port != -1)
 
908
                                  midiSeq->mtcInputQuarter(_port, *(ev->buffer + 1)); 
 
909
                                return;
 
910
                          case ME_SONGPOS:    
 
911
                                if(_port != -1)
 
912
                                  midiSeq->setSongPosition(_port, *(ev->buffer + 1) | (*(ev->buffer + 2) >> 2 )); // LSB then MSB
 
913
                                return;
 
914
                          //case ME_SONGSEL:    
 
915
                          //case ME_TUNE_REQ:   
 
916
                          //case ME_SENSE:
 
917
                          case ME_CLOCK:      
 
918
                          case ME_TICK:       
 
919
                          case ME_START:      
 
920
                          case ME_CONTINUE:   
 
921
                          case ME_STOP:       
 
922
                                if(_port != -1)
 
923
                                  midiSeq->realtimeSystemInput(_port, type);
 
924
                                return;
 
925
                          //case ME_SYSEX_END:  
 
926
                                //break;
 
927
                          //      return;
 
928
                          default:
 
929
                                printf("MidiJackDevice::eventReceived unsupported system event 0x%02x\n", type);
 
930
                                return;
 
931
                    }
 
932
                  }
 
933
                  //return;
 
934
                  break;
 
935
            default:
 
936
              printf("MidiJackDevice::eventReceived unknown event 0x%02x\n", type);
 
937
              //printf("MidiJackDevice::eventReceived unknown event 0x%02x size:%d buf:0x%02x 0x%02x 0x%02x ...0x%02x\n", type, ev->size, *(ev->buffer), *(ev->buffer + 1), *(ev->buffer + 2), *(ev->buffer + (ev->size - 1)));
 
938
              return;
 
939
            }
 
940
 
 
941
      if (midiInputTrace) {
 
942
            printf("MidiInput<%s>: ", name().latin1());
 
943
            event.dump();
 
944
            }
 
945
            
 
946
      #ifdef JACK_MIDI_DEBUG
 
947
      printf("MidiJackDevice::eventReceived time:%d type:%d ch:%d A:%d B:%d\n", event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
 
948
      #endif  
 
949
      
 
950
      // Let recordEvent handle it from here, with timestamps, filtering, gui triggering etc.
 
951
      recordEvent(event);      
 
952
      }
 
953
 
 
954
//---------------------------------------------------------
 
955
//   collectMidiEvents
 
956
//---------------------------------------------------------
 
957
 
 
958
void MidiJackDevice::collectMidiEvents()
 
959
{
 
960
  if(!_readEnable)
 
961
    return;
 
962
  
 
963
  if(!_client_jackport)
 
964
    return;
 
965
  void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
 
966
  
 
967
  jack_midi_event_t event;
 
968
  jack_nframes_t eventCount = jack_midi_get_event_count(port_buf);
 
969
  for (jack_nframes_t i = 0; i < eventCount; ++i) 
 
970
  {
 
971
    jack_midi_event_get(&event, port_buf, i);
 
972
    
 
973
    #ifdef JACK_MIDI_DEBUG
 
974
    printf("MidiJackDevice::collectMidiEvents number:%d time:%d\n", i, event.time);
 
975
    #endif  
 
976
 
 
977
    eventReceived(&event);
 
978
  }
 
979
}
 
980
 
 
981
//---------------------------------------------------------
 
982
//   putEvent
 
983
//    return true if event cannot be delivered
 
984
//---------------------------------------------------------
 
985
 
 
986
bool MidiJackDevice::putEvent(const MidiPlayEvent& ev)
 
987
{
 
988
  if(!_writeEnable)
 
989
    //return true;
 
990
    return false;
 
991
    
 
992
  #ifdef JACK_MIDI_DEBUG
 
993
  printf("MidiJackDevice::putEvent time:%d type:%d ch:%d A:%d B:%d\n", ev.time(), ev.type(), ev.channel(), ev.dataA(), ev.dataB());
 
994
  #endif  
 
995
      
 
996
  bool rv = eventFifo.put(ev);
 
997
  if(rv)
 
998
    printf("MidiJackDevice::putEvent: port overflow\n");
 
999
  
 
1000
  return rv;
 
1001
}
 
1002
 
 
1003
//---------------------------------------------------------
 
1004
//   queueEvent
 
1005
//   return true if successful
 
1006
//---------------------------------------------------------
 
1007
 
 
1008
//void JackAudioDevice::putEvent(Port port, const MidiEvent& e)
 
1009
bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
 
1010
//bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
 
1011
{
 
1012
      // Perhaps we can find use for this value later, together with the Jack midi MusE port(s).
 
1013
      // No big deal if not. Not used for now.
 
1014
      //int port = e.port();
 
1015
      
 
1016
      //if(port >= JACK_MIDI_CHANNELS)
 
1017
      //  return false;
 
1018
        
 
1019
      //if (midiOutputTrace) {
 
1020
      //      printf("MidiOut<%s>: jackMidi: ", portName(port).toLatin1().data());
 
1021
      //      e.dump();
 
1022
      //      }
 
1023
      
 
1024
      //if(debugMsg)
 
1025
      //  printf("MidiJackDevice::queueEvent\n");
 
1026
    
 
1027
      if(!_client_jackport)
 
1028
        return false;
 
1029
      void* pb = jack_port_get_buffer(_client_jackport, segmentSize);
 
1030
    
 
1031
      //unsigned frameCounter = ->frameTime();
 
1032
      int frameOffset = audio->getFrameOffset();
 
1033
      unsigned pos = audio->pos().frame();
 
1034
      int ft = e.time() - frameOffset - pos;
 
1035
      
 
1036
      if (ft < 0)
 
1037
            ft = 0;
 
1038
      if (ft >= (int)segmentSize) {
 
1039
            printf("MidiJackDevice::queueEvent: Event time:%d out of range. offset:%d ft:%d (seg=%d)\n", e.time(), frameOffset, ft, segmentSize);
 
1040
            if (ft > (int)segmentSize)
 
1041
                  ft = segmentSize - 1;
 
1042
            }
 
1043
      
 
1044
      #ifdef JACK_MIDI_DEBUG
 
1045
      printf("MidiJackDevice::queueEvent time:%d type:%d ch:%d A:%d B:%d\n", e.time(), e.type(), e.channel(), e.dataA(), e.dataB());
 
1046
      #endif  
 
1047
      
 
1048
      switch(e.type()) {
 
1049
            case ME_NOTEON:
 
1050
            case ME_NOTEOFF:
 
1051
            case ME_POLYAFTER:
 
1052
            case ME_CONTROLLER:
 
1053
            case ME_PITCHBEND:
 
1054
                  {
 
1055
                  #ifdef JACK_MIDI_DEBUG
 
1056
                  printf("MidiJackDevice::queueEvent note on/off polyafter controller or pitch\n");
 
1057
                  #endif  
 
1058
                    
 
1059
                  unsigned char* p = jack_midi_event_reserve(pb, ft, 3);
 
1060
                  if (p == 0) {
 
1061
                        fprintf(stderr, "MidiJackDevice::queueEvent #1: buffer overflow, event lost\n");
 
1062
                        return false;
 
1063
                        }
 
1064
                  p[0] = e.type() | e.channel();
 
1065
                  p[1] = e.dataA();
 
1066
                  p[2] = e.dataB();
 
1067
                  }
 
1068
                  break;
 
1069
 
 
1070
            case ME_PROGRAM:
 
1071
            case ME_AFTERTOUCH:
 
1072
                  {
 
1073
                  #ifdef JACK_MIDI_DEBUG
 
1074
                  printf("MidiJackDevice::queueEvent program or aftertouch\n");
 
1075
                  #endif  
 
1076
                    
 
1077
                  unsigned char* p = jack_midi_event_reserve(pb, ft, 2);
 
1078
                  if (p == 0) {
 
1079
                        fprintf(stderr, "MidiJackDevice::queueEvent #2: buffer overflow, event lost\n");
 
1080
                        return false;
 
1081
                        }
 
1082
                  p[0] = e.type() | e.channel();
 
1083
                  p[1] = e.dataA();
 
1084
                  }
 
1085
                  break;
 
1086
            case ME_SYSEX:
 
1087
                  {
 
1088
                  #ifdef JACK_MIDI_DEBUG
 
1089
                  printf("MidiJackDevice::queueEvent sysex\n");
 
1090
                  #endif  
 
1091
                  
 
1092
                  const unsigned char* data = e.data();
 
1093
                  int len = e.len();
 
1094
                  unsigned char* p = jack_midi_event_reserve(pb, ft, len+2);
 
1095
                  if (p == 0) {
 
1096
                        fprintf(stderr, "MidiJackDevice::queueEvent #3: buffer overflow, event lost\n");
 
1097
                        return false;
 
1098
                        }
 
1099
                  p[0] = 0xf0;
 
1100
                  p[len+1] = 0xf7;
 
1101
                  memcpy(p+1, data, len);
 
1102
                  }
 
1103
                  break;
 
1104
            case ME_SONGPOS:
 
1105
            case ME_CLOCK:
 
1106
            case ME_START:
 
1107
            case ME_CONTINUE:
 
1108
            case ME_STOP:
 
1109
                  printf("MidiJackDevice::queueEvent: event type %x not supported\n", e.type());
 
1110
                  return false;
 
1111
                  break;
 
1112
            }
 
1113
            
 
1114
            return true;
 
1115
}
 
1116
      
 
1117
//---------------------------------------------------------
 
1118
//    processEvent
 
1119
//---------------------------------------------------------
 
1120
 
 
1121
void MidiJackDevice::processEvent(const MidiPlayEvent& event)
 
1122
{    
 
1123
  //int frameOffset = audio->getFrameOffset();
 
1124
  //unsigned pos = audio->pos().frame();
 
1125
 
 
1126
  int chn    = event.channel();
 
1127
  unsigned t = event.time();
 
1128
  int a      = event.dataA();
 
1129
  int b      = event.dataB();
 
1130
  // Perhaps we can find use for this value later, together with the Jack midi MusE port(s).
 
1131
  // No big deal if not. Not used for now.
 
1132
  int port   = event.port();
 
1133
  
 
1134
  // TODO: No sub-tick playback resolution yet, with external sync.
 
1135
  // Just do this 'standard midi 64T timing thing' for now until we figure out more precise external timings. 
 
1136
  // Does require relatively short audio buffers, in order to catch the resolution, but buffer <= 256 should be OK... 
 
1137
  // Tested OK so far with 128. 
 
1138
  if(extSyncFlag.value()) 
 
1139
    t = audio->getFrameOffset() + audio->pos().frame();
 
1140
    //t = frameOffset + pos;
 
1141
      
 
1142
  #ifdef JACK_MIDI_DEBUG
 
1143
  printf("MidiJackDevice::processEvent time:%d type:%d ch:%d A:%d B:%d\n", event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
 
1144
  #endif  
 
1145
      
 
1146
  if(event.type() == ME_PROGRAM) 
 
1147
  {
 
1148
    // don't output program changes for GM drum channel
 
1149
    //if (!(song->mtype() == MT_GM && chn == 9)) {
 
1150
          int hb = (a >> 16) & 0xff;
 
1151
          int lb = (a >> 8) & 0xff;
 
1152
          int pr = a & 0x7f;
 
1153
          
 
1154
          // p3.3.44
 
1155
          //printf("MidiJackDevice::processEvent ME_PROGRAM time:%d type:%d ch:%d A:%d B:%d hb:%d lb:%d pr:%d\n", 
 
1156
          //       event.time(), event.type(), event.channel(), event.dataA(), event.dataB(), hb, lb, pr);
 
1157
          
 
1158
          if (hb != 0xff)
 
1159
                queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HBANK, hb));
 
1160
          if (lb != 0xff)
 
1161
                queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LBANK, lb));
 
1162
          queueEvent(MidiPlayEvent(t+2, port, chn, ME_PROGRAM, pr, 0));
 
1163
    //      }
 
1164
  }
 
1165
  else
 
1166
  if(event.type() == ME_PITCHBEND) 
 
1167
  {
 
1168
      int v = a + 8192;
 
1169
      // p3.3.44
 
1170
      //printf("MidiJackDevice::processEvent ME_PITCHBEND v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
 
1171
      
 
1172
      queueEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f));
 
1173
  }
 
1174
  else
 
1175
  if(event.type() == ME_CONTROLLER) 
 
1176
  {
 
1177
    //int a      = event.dataA();
 
1178
    //int b      = event.dataB();
 
1179
    // Perhaps we can find use for this value later, together with the Jack midi MusE port(s).
 
1180
    // No big deal if not. Not used for now.
 
1181
    //int port   = event.port();
 
1182
 
 
1183
    int nvh = 0xff;
 
1184
    int nvl = 0xff;
 
1185
    if(_port != -1)
 
1186
    {
 
1187
      int nv = midiPorts[_port].nullSendValue();
 
1188
      if(nv != -1)
 
1189
      {
 
1190
        nvh = (nv >> 8) & 0xff;
 
1191
        nvl = nv & 0xff;
 
1192
      }
 
1193
    }
 
1194
      
 
1195
    if(a == CTRL_PITCH) 
 
1196
    {
 
1197
      int v = b + 8192;
 
1198
      // p3.3.44
 
1199
      //printf("MidiJackDevice::processEvent CTRL_PITCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
 
1200
      
 
1201
      queueEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f));
 
1202
    }
 
1203
    else if (a == CTRL_PROGRAM) 
 
1204
    {
 
1205
      // don't output program changes for GM drum channel
 
1206
      //if (!(song->mtype() == MT_GM && chn == 9)) {
 
1207
            int hb = (b >> 16) & 0xff;
 
1208
            int lb = (b >> 8) & 0xff;
 
1209
            int pr = b & 0x7f;
 
1210
          
 
1211
            // p3.3.44
 
1212
            //printf("MidiJackDevice::processEvent CTRL_PROGRAM time:%d type:%d ch:%d A:%d B:%d hb:%d lb:%d pr:%d\n", 
 
1213
            //       event.time(), event.type(), event.channel(), event.dataA(), event.dataB(), hb, lb, pr);
 
1214
          
 
1215
            if (hb != 0xff)
 
1216
                  queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HBANK, hb));
 
1217
            if (lb != 0xff)
 
1218
                  queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LBANK, lb));
 
1219
            queueEvent(MidiPlayEvent(t+2, port, chn, ME_PROGRAM, pr, 0));
 
1220
      //      }
 
1221
    }
 
1222
    /*
 
1223
    else if (a == CTRL_MASTER_VOLUME) 
 
1224
    {
 
1225
      unsigned char sysex[] = {
 
1226
            0x7f, 0x7f, 0x04, 0x01, 0x00, 0x00
 
1227
            };
 
1228
      sysex[1] = deviceId();
 
1229
      sysex[4] = b & 0x7f;
 
1230
      sysex[5] = (b >> 7) & 0x7f;
 
1231
      queueEvent(MidiPlayEvent(t, port, ME_SYSEX, sysex, 6));
 
1232
    }
 
1233
    */
 
1234
    else if (a < CTRL_14_OFFSET) 
 
1235
    {              // 7 Bit Controller
 
1236
      queueEvent(event);
 
1237
      //queueEvent(museport, MidiPlayEvent(t, port, chn, event));
 
1238
    }
 
1239
    else if (a < CTRL_RPN_OFFSET) 
 
1240
    {     // 14 bit high resolution controller
 
1241
      int ctrlH = (a >> 8) & 0x7f;
 
1242
      int ctrlL = a & 0x7f;
 
1243
      int dataH = (b >> 7) & 0x7f;
 
1244
      int dataL = b & 0x7f;
 
1245
      queueEvent(MidiPlayEvent(t,   port, chn, ME_CONTROLLER, ctrlH, dataH));
 
1246
      queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, ctrlL, dataL));
 
1247
    }
 
1248
    else if (a < CTRL_NRPN_OFFSET) 
 
1249
    {     // RPN 7-Bit Controller
 
1250
      int ctrlH = (a >> 8) & 0x7f;
 
1251
      int ctrlL = a & 0x7f;
 
1252
      queueEvent(MidiPlayEvent(t,   port, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH));
 
1253
      queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL));
 
1254
      queueEvent(MidiPlayEvent(t+2, port, chn, ME_CONTROLLER, CTRL_HDATA, b));
 
1255
      
 
1256
      t += 3;  
 
1257
      // Select null parameters so that subsequent data controller events do not upset the last *RPN controller.
 
1258
      //sendNullRPNParams(chn, false);
 
1259
      if(nvh != 0xff)
 
1260
      {
 
1261
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HRPN, nvh & 0x7f));
 
1262
        t += 1;  
 
1263
      }
 
1264
      if(nvl != 0xff)
 
1265
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_LRPN, nvl & 0x7f));
 
1266
    }
 
1267
    //else if (a < CTRL_RPN14_OFFSET) 
 
1268
    else if (a < CTRL_INTERNAL_OFFSET) 
 
1269
    {     // NRPN 7-Bit Controller
 
1270
      int ctrlH = (a >> 8) & 0x7f;
 
1271
      int ctrlL = a & 0x7f;
 
1272
      queueEvent(MidiPlayEvent(t,   port, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
 
1273
      queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
 
1274
      queueEvent(MidiPlayEvent(t+2, port, chn, ME_CONTROLLER, CTRL_HDATA, b));
 
1275
                  
 
1276
      t += 3;  
 
1277
      //sendNullRPNParams(chn, true);
 
1278
      if(nvh != 0xff)
 
1279
      {
 
1280
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HNRPN, nvh & 0x7f));
 
1281
        t += 1;  
 
1282
      }
 
1283
      if(nvl != 0xff)
 
1284
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_LNRPN, nvl & 0x7f));
 
1285
    }
 
1286
    else if (a < CTRL_NRPN14_OFFSET) 
 
1287
    {     // RPN14 Controller
 
1288
      int ctrlH = (a >> 8) & 0x7f;
 
1289
      int ctrlL = a & 0x7f;
 
1290
      int dataH = (b >> 7) & 0x7f;
 
1291
      int dataL = b & 0x7f;
 
1292
      queueEvent(MidiPlayEvent(t,   port, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH));
 
1293
      queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL));
 
1294
      queueEvent(MidiPlayEvent(t+2, port, chn, ME_CONTROLLER, CTRL_HDATA, dataH));
 
1295
      queueEvent(MidiPlayEvent(t+3, port, chn, ME_CONTROLLER, CTRL_LDATA, dataL));
 
1296
      
 
1297
      t += 4;  
 
1298
      //sendNullRPNParams(chn, false);
 
1299
      if(nvh != 0xff)
 
1300
      {
 
1301
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HRPN, nvh & 0x7f));
 
1302
        t += 1;  
 
1303
      }
 
1304
      if(nvl != 0xff)
 
1305
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_LRPN, nvl & 0x7f));
 
1306
    }
 
1307
    else if (a < CTRL_NONE_OFFSET) 
 
1308
    {     // NRPN14 Controller
 
1309
      int ctrlH = (a >> 8) & 0x7f;
 
1310
      int ctrlL = a & 0x7f;
 
1311
      int dataH = (b >> 7) & 0x7f;
 
1312
      int dataL = b & 0x7f;
 
1313
      queueEvent(MidiPlayEvent(t,   port, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
 
1314
      queueEvent(MidiPlayEvent(t+1, port, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
 
1315
      queueEvent(MidiPlayEvent(t+2, port, chn, ME_CONTROLLER, CTRL_HDATA, dataH));
 
1316
      queueEvent(MidiPlayEvent(t+3, port, chn, ME_CONTROLLER, CTRL_LDATA, dataL));
 
1317
    
 
1318
      t += 4;  
 
1319
      //sendNullRPNParams(chn, true);
 
1320
      if(nvh != 0xff)
 
1321
      {
 
1322
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_HNRPN, nvh & 0x7f));
 
1323
        t += 1;  
 
1324
      }
 
1325
      if(nvl != 0xff)
 
1326
        queueEvent(MidiPlayEvent(t, port, chn, ME_CONTROLLER, CTRL_LNRPN, nvl & 0x7f));
 
1327
    }
 
1328
    else 
 
1329
    {
 
1330
      printf("MidiJackDevice::processEvent: unknown controller type 0x%x\n", a);
 
1331
    }
 
1332
  }
 
1333
  else 
 
1334
  {
 
1335
    queueEvent(event);
 
1336
    //queueEvent(MidiPlayEvent(t, port, chn, event));
 
1337
  }
 
1338
}
 
1339
    
 
1340
//---------------------------------------------------------
 
1341
//    processMidi called from audio process only.
 
1342
//---------------------------------------------------------
 
1343
 
 
1344
void MidiJackDevice::processMidi()
 
1345
{
 
1346
  if(!_client_jackport)
 
1347
    return;
 
1348
  void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
 
1349
  jack_midi_clear_buffer(port_buf);
 
1350
  
 
1351
  while(!eventFifo.isEmpty())
 
1352
  {
 
1353
    MidiPlayEvent e(eventFifo.get());
 
1354
    int evTime = e.time(); 
 
1355
    // Is event marked to be played immediately?
 
1356
    if(evTime == 0) 
 
1357
    {
 
1358
      // Nothing to do but stamp the event to be queued for frame 0+.
 
1359
      //e.setTime(frameOffset + pos);
 
1360
      e.setTime(audio->getFrameOffset() + audio->pos().frame());
 
1361
    }
 
1362
    
 
1363
    #ifdef JACK_MIDI_DEBUG
 
1364
    printf("MidiJackDevice::processMidi eventFifo time:%d type:%d ch:%d A:%d B:%d\n", e.time(), e.type(), e.channel(), e.dataA(), e.dataB());
 
1365
    #endif  
 
1366
    
 
1367
    //el->insert(eventFifo.get());
 
1368
    //el->insert(e);
 
1369
    processEvent(e);
 
1370
  }
 
1371
  
 
1372
  MPEventList* el = playEvents();
 
1373
  if(el->empty())
 
1374
    return;
 
1375
  
 
1376
  iMPEvent i = nextPlayEvent();
 
1377
  for(; i != el->end(); ++i) 
 
1378
  {
 
1379
    // p3.3.39 Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values.
 
1380
    // Same code as in MidiPort::sendEvent()
 
1381
    if(_port != -1)
 
1382
    {
 
1383
      MidiPort* mp = &midiPorts[_port];
 
1384
      if(i->type() == ME_CONTROLLER) 
 
1385
      {
 
1386
        int da = i->dataA();
 
1387
        int db = i->dataB();
 
1388
        db = mp->limitValToInstrCtlRange(da, db);
 
1389
        if(!mp->setHwCtrlState(i->channel(), da, db))
 
1390
          continue;
 
1391
        //mp->setHwCtrlState(i->channel(), da, db);
 
1392
      }
 
1393
      else
 
1394
      if(i->type() == ME_PITCHBEND) 
 
1395
      {
 
1396
        // p3.3.44
 
1397
        //printf("MidiJackDevice::processMidi playEvents ME_PITCHBEND time:%d type:%d ch:%d A:%d B:%d\n", (*i).time(), (*i).type(), (*i).channel(), (*i).dataA(), (*i).dataB());
 
1398
        
 
1399
        int da = mp->limitValToInstrCtlRange(CTRL_PITCH, i->dataA());
 
1400
        if(!mp->setHwCtrlState(i->channel(), CTRL_PITCH, da))
 
1401
          continue;
 
1402
        //mp->setHwCtrlState(i->channel(), CTRL_PITCH, da);
 
1403
        
 
1404
        //(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f));
 
1405
      }
 
1406
      else
 
1407
      if(i->type() == ME_PROGRAM) 
 
1408
      {
 
1409
        if(!mp->setHwCtrlState(i->channel(), CTRL_PROGRAM, i->dataA()))
 
1410
          continue;
 
1411
        //mp->setHwCtrlState(i->channel(), CTRL_PROGRAM, i->dataA());
 
1412
      }
 
1413
    }
 
1414
  
 
1415
    processEvent(*i);
 
1416
  }
 
1417
  
 
1418
  setNextPlayEvent(i);
 
1419
}
 
1420
 
 
1421
//---------------------------------------------------------
 
1422
//   initMidiJack
 
1423
//    return true on error
 
1424
//---------------------------------------------------------
 
1425
 
 
1426
bool initMidiJack()
 
1427
{
 
1428
  /*
 
1429
  int adr = 0;
 
1430
 
 
1431
  memset(jack_midi_out_data, 0, JACK_MIDI_CHANNELS * sizeof(muse_jack_midi_buffer));
 
1432
  memset(jack_midi_in_data, 0, JACK_MIDI_CHANNELS * sizeof(muse_jack_midi_buffer));
 
1433
 
 
1434
  MidiJackDevice* dev = new MidiJackDevice(adr, QString("jack-midi"));
 
1435
  dev->setrwFlags(3); // set read and write flags 
 
1436
 
 
1437
  if(pipe(jackmidi_pi) < 0){
 
1438
    fprintf(stderr, "cant create midi-jack input pipe\n");
 
1439
  }
 
1440
  if(pipe(jackmidi_po) < 0){
 
1441
    fprintf(stderr, "cant create midi-jack output pipe\n");
 
1442
  }
 
1443
  
 
1444
  midiDevices.add(dev);
 
1445
  
 
1446
  gmdev = dev; // proclaim the global jack-midi instance 
 
1447
 
 
1448
  //jackScanMidiPorts();
 
1449
  */
 
1450
  
 
1451
  return false;
 
1452
}
 
1453
 
 
1454
/*
 
1455
struct JackPort {
 
1456
      int adr;
 
1457
      //char* name;
 
1458
      QString name;
 
1459
      int flags;
 
1460
      //JackPort(int a, const char* s, int f) {
 
1461
      JackPort(int a, const QString& s, int f) {
 
1462
            adr = a;
 
1463
            //name = strdup(s);
 
1464
            name = QString(s);
 
1465
            flags = f;
 
1466
            }
 
1467
      };
 
1468
 
 
1469
 
 
1470
static std::list<JackPort> portList;
 
1471
 
 
1472
//---------------------------------------------------------
 
1473
//   jackScanMidiPorts
 
1474
//---------------------------------------------------------
 
1475
 
 
1476
void jackScanMidiPorts()
 
1477
{
 
1478
  int adr;
 
1479
  const char* name;
 
1480
 
 
1481
  portList.clear();
 
1482
  adr  = 0;
 
1483
  name = strdup("namex");
 
1484
  portList.push_back(JackPort(adr, name, 0));
 
1485
  //
 
1486
  //  check for devices to add
 
1487
  //
 
1488
  for (std::list<JackPort>::iterator k = portList.begin(); k != portList.end(); ++k) {
 
1489
    iMidiDevice i = midiDevices.begin();
 
1490
    for (;i != midiDevices.end(); ++i) {
 
1491
      //MidiJackDevice* d = dynamic_cast<MidiJackDevice*>(*i);
 
1492
      break;
 
1493
      //if (d == 0) continue;
 
1494
      //if ((k->adr.client == d->adr.client) && (k->adr.port == d->adr.port)) {
 
1495
      //  break;
 
1496
      //}
 
1497
    }
 
1498
    if (i == midiDevices.end()) {
 
1499
      // add device
 
1500
      MidiJackDevice* dev = new MidiJackDevice(k->adr, QString(k->name));
 
1501
      dev->setrwFlags(k->flags);
 
1502
      midiDevices.add(dev);
 
1503
    }
 
1504
  }
 
1505
}
 
1506
*/
 
1507
 
 
1508
/*
 
1509
//---------------------------------------------------------
 
1510
//   processInput
 
1511
//---------------------------------------------------------
 
1512
static void handle_jack_midi_in(int channel)
 
1513
{
 
1514
  MidiRecordEvent event;
 
1515
  int t,n,v;
 
1516
  t = jack_midi_in_data[channel].buffer[0];
 
1517
  n = jack_midi_in_data[channel].buffer[1];
 
1518
  v = jack_midi_in_data[channel].buffer[2];
 
1519
 
 
1520
  event.setType(0);      // mark as unused
 
1521
  event.setPort(gmdev->midiPort());
 
1522
  event.setB(0);
 
1523
 
 
1524
  if(t == 0x90){ // note on 
 
1525
    fprintf(stderr, "jackProcessMidiInput note-on\n");
 
1526
    event.setChannel(channel);
 
1527
    event.setType(ME_NOTEON);
 
1528
    event.setA(n);
 
1529
    event.setB(v);
 
1530
  }else if (t == 0x80){ // note off 
 
1531
    fprintf(stderr, "jackProcessMidiInput note-off\n");
 
1532
    event.setChannel(channel);
 
1533
    event.setType(ME_NOTEOFF);
 
1534
    event.setA(n);
 
1535
    event.setB(v);
 
1536
  }else{
 
1537
    fprintf(stderr, "WARNING: unknown midi-in on channel %d: %x,%x,%x\n",
 
1538
            channel, t, n, v);
 
1539
    return;
 
1540
  }
 
1541
  if(event.type()){
 
1542
    gmdev->recordEvent(event);
 
1543
    midiPorts[gmdev->midiPort()].syncInfo().trigActDetect(event.channel());
 
1544
  }
 
1545
}
 
1546
 
 
1547
void MidiJackDevice::processInput()
 
1548
{
 
1549
  char buf;
 
1550
  int i,s;
 
1551
  read(gmdev->selectRfd(), &buf, 1);
 
1552
 
 
1553
  s = 1;
 
1554
  for(i = 0; i < JACK_MIDI_CHANNELS; i++){
 
1555
    if(jack_midi_in_data[i].buffer[3]){
 
1556
      s = 0;
 
1557
      handle_jack_midi_in(i);
 
1558
      jack_midi_in_data[i].buffer[3] = 0;
 
1559
    }
 
1560
  }
 
1561
}
 
1562
 
 
1563
*/
 
 
b'\\ No newline at end of file'