~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to muse/sync.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:
18
18
#include "audiodev.h"
19
19
#include "gconfig.h"
20
20
#include "xml.h"
 
21
#include "midi.h"
21
22
 
22
23
//int rxSyncPort = -1;         // receive from all ports
23
24
//int txSyncPort = 1;
24
25
//int rxDeviceId = 0x7f;       // any device
25
26
//int txDeviceId = 0x7f;       // any device
26
27
//MidiSyncPort midiSyncPorts[MIDI_PORTS];
27
 
int curMidiSyncInPort = -1;
28
 
 
29
 
bool debugSync = false;
 
28
int volatile curMidiSyncInPort = -1;
 
29
 
 
30
bool debugSync = true;
 
31
 
30
32
int mtcType     = 1;
31
33
MTC mtcOffset;
32
34
BValue extSyncFlag(0, "extSync");       // false - MASTER, true - SLAVE
36
38
//bool acceptMTC  = false;
37
39
//bool acceptMC   = true;
38
40
//bool acceptMMC  = true;
39
 
bool useJackTransport = true;
 
41
BValue useJackTransport(0,"useJackTransport");
 
42
bool volatile jackTransportMaster = true;
40
43
 
41
44
static MTC mtcCurTime;
42
45
static int mtcState;    // 0-7 next expected quarter message
44
47
static int mtcLost;
45
48
static bool mtcSync;    // receive complete mtc frame?
46
49
 
 
50
// p3.3.28
 
51
static bool playPendingFirstClock = false;
 
52
unsigned int syncSendFirstClockDelay = 1; // In milliseconds.
 
53
//static int lastStoppedBeat = 0;
 
54
static unsigned int curExtMidiSyncTick = 0;
 
55
unsigned int volatile lastExtMidiSyncTick = 0;
 
56
double volatile curExtMidiSyncTime = 0.0;
 
57
double volatile lastExtMidiSyncTime = 0.0;
 
58
 
47
59
// Not used yet.
48
60
// static bool mcStart = false;
49
61
// static int mcStartTick;
50
62
 
 
63
// p3.3.25
 
64
// From the "Introduction to the Volatile Keyword" at Embedded dot com
 
65
/* A variable should be declared volatile whenever its value could change unexpectedly. 
 
66
 ... <such as> global variables within a multi-threaded application    
 
67
 ... So all shared global variables should be declared volatile */
 
68
unsigned int volatile midiExtSyncTicks = 0;
 
69
 
51
70
//---------------------------------------------------------
52
71
//  MidiSyncInfo
53
72
//---------------------------------------------------------
58
77
  _idOut         = 127;
59
78
  _idIn          = 127;
60
79
  _sendMC        = false;
 
80
  _sendMRT       = false;
61
81
  _sendMMC       = false;
62
82
  _sendMTC       = false;
63
83
  _recMC         = false;
 
84
  _recMRT        = false;
64
85
  _recMMC        = false;
65
86
  _recMTC        = false;
66
87
  
67
88
  _lastClkTime   = 0.0;
68
89
  _lastTickTime  = 0.0;
 
90
  _lastMRTTime   = 0.0;
 
91
  _lastMMCTime   = 0.0;
 
92
  _lastMTCTime   = 0.0;
69
93
  _clockTrig     = false;
70
94
  _tickTrig      = false;
 
95
  _MRTTrig       = false;
 
96
  _MMCTrig       = false;
 
97
  _MTCTrig       = false;
71
98
  _clockDetect   = false;
72
99
  _tickDetect    = false;
 
100
  _MRTDetect     = false;
 
101
  _MMCDetect     = false;
 
102
  _MTCDetect     = false;
 
103
  _recMTCtype    = 0;
 
104
  _recRewOnStart  = true;
 
105
  //_sendContNotStart = false;
73
106
  _actDetectBits = 0;
74
107
  for(int i = 0; i < MIDI_CHANNELS; ++i)
75
108
  {
91
124
  
92
125
  _lastClkTime   = sp._lastClkTime;
93
126
  _lastTickTime  = sp._lastTickTime;
 
127
  _lastMRTTime   = sp._lastMRTTime;
 
128
  _lastMMCTime   = sp._lastMMCTime;
 
129
  _lastMTCTime   = sp._lastMTCTime;
94
130
  _clockTrig     = sp._clockTrig;
95
131
  _tickTrig      = sp._tickTrig;
 
132
  _MRTTrig       = sp._MRTTrig;
 
133
  _MMCTrig       = sp._MMCTrig;
 
134
  _MTCTrig       = sp._MTCTrig;
96
135
  _clockDetect   = sp._clockDetect;
97
136
  _tickDetect    = sp._tickDetect;
98
 
  _actDetectBits = sp._actDetectBits;
 
137
  _MRTDetect     = sp._MRTDetect;
 
138
  _MMCDetect     = sp._MMCDetect;
 
139
  _MTCDetect     = sp._MTCDetect;
 
140
  _recMTCtype    = sp._recMTCtype;
99
141
  for(int i = 0; i < MIDI_CHANNELS; ++i)
100
142
  {
101
143
    _lastActTime[i] = sp._lastActTime[i];
116
158
  _idOut         = sp._idOut;
117
159
  _idIn          = sp._idIn;
118
160
  _sendMC        = sp._sendMC;
 
161
  _sendMRT       = sp._sendMRT;
119
162
  _sendMMC       = sp._sendMMC;
120
163
  _sendMTC       = sp._sendMTC;
121
164
  setMCIn(sp._recMC);
 
165
  _recMRT        = sp._recMRT;
122
166
  _recMMC        = sp._recMMC;
123
167
  _recMTC        = sp._recMTC;
 
168
  _recRewOnStart = sp._recRewOnStart;
 
169
  //_sendContNotStart = sp._sendContNotStart;
124
170
  return *this;
125
171
}
126
172
 
144
190
  if(_clockDetect && (t - _lastClkTime >= 1.0)) // Set detect indicator timeout to about 1 second.
145
191
  {
146
192
    _clockDetect = false;
 
193
    // Give up the current midi sync in port number if we took it...
147
194
    if(curMidiSyncInPort == _port)
148
195
      curMidiSyncInPort = -1;
149
196
  }
157
204
  if(_tickDetect && (t - _lastTickTime) >= 1.0) // Set detect indicator timeout to about 1 second.
158
205
    _tickDetect = false;
159
206
    
 
207
  if(_MRTTrig)
 
208
  {
 
209
    _MRTTrig = false;
 
210
    _lastMRTTime = t;  
 
211
  }
 
212
  else
 
213
  if(_MRTDetect && (t - _lastMRTTime) >= 1.0) // Set detect indicator timeout to about 1 second.
 
214
  {
 
215
    _MRTDetect = false;
 
216
    // Give up the current midi sync in port number if we took it...
 
217
    //if(curMidiSyncInPort == _port)
 
218
    //  curMidiSyncInPort = -1;
 
219
  }
 
220
    
 
221
  if(_MMCTrig)
 
222
  {
 
223
    _MMCTrig = false;
 
224
    _lastMMCTime = t;  
 
225
  }
 
226
  else
 
227
  if(_MMCDetect && (t - _lastMMCTime) >= 1.0) // Set detect indicator timeout to about 1 second.
 
228
  {
 
229
    _MMCDetect = false;
 
230
    // Give up the current midi sync in port number if we took it...
 
231
    //if(curMidiSyncInPort == _port)
 
232
    //  curMidiSyncInPort = -1;
 
233
  }
 
234
    
 
235
  if(_MTCTrig)
 
236
  {
 
237
    _MTCTrig = false;
 
238
    _lastMTCTime = t;  
 
239
  }
 
240
  else
 
241
  if(_MTCDetect && (t - _lastMTCTime) >= 1.0) // Set detect indicator timeout to about 1 second.
 
242
  {
 
243
    _MTCDetect = false;
 
244
    // Give up the current midi sync in port number if we took it...
 
245
    if(curMidiSyncInPort == _port)
 
246
      curMidiSyncInPort = -1;
 
247
  }
 
248
    
160
249
  for(int i = 0; i < MIDI_CHANNELS; i++)
161
250
  {
162
251
    if(_actTrig[i])
186
275
}
187
276
 
188
277
//---------------------------------------------------------
 
278
//  setMRTIn
 
279
//---------------------------------------------------------
 
280
 
 
281
void MidiSyncInfo::setMRTIn(const bool v) 
 
282
 
283
  _recMRT = v; 
 
284
  // If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
 
285
  //if(!_recMRT && _port != -1 && curMidiSyncInPort == _port)
 
286
  //  curMidiSyncInPort = -1;
 
287
}
 
288
 
 
289
//---------------------------------------------------------
 
290
//  setMMCIn
 
291
//---------------------------------------------------------
 
292
 
 
293
void MidiSyncInfo::setMMCIn(const bool v) 
 
294
 
295
  _recMMC = v; 
 
296
  // If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
 
297
  //if(!_recMMC && _port != -1 && curMidiSyncInPort == _port)
 
298
  //  curMidiSyncInPort = -1;
 
299
}
 
300
 
 
301
//---------------------------------------------------------
 
302
//  setMTCIn
 
303
//---------------------------------------------------------
 
304
 
 
305
void MidiSyncInfo::setMTCIn(const bool v) 
 
306
 
307
  _recMTC = v; 
 
308
  // If sync receive was turned off, clear the current midi sync in port number so another port can grab it.
 
309
  if(!_recMTC && _port != -1 && curMidiSyncInPort == _port)
 
310
    curMidiSyncInPort = -1;
 
311
}
 
312
 
 
313
//---------------------------------------------------------
189
314
//  trigMCSyncDetect
190
315
//---------------------------------------------------------
191
316
 
209
334
}
210
335
    
211
336
//---------------------------------------------------------
 
337
//  trigMRTDetect
 
338
//---------------------------------------------------------
 
339
 
 
340
void MidiSyncInfo::trigMRTDetect()   
 
341
 
342
  _MRTDetect = true;
 
343
  _MRTTrig = true;
 
344
  // Set the current midi sync in port number if it's not taken...
 
345
  //if(_recMRT && curMidiSyncInPort == -1)
 
346
  //  curMidiSyncInPort = _port;
 
347
}
 
348
    
 
349
//---------------------------------------------------------
 
350
//  trigMMCDetect
 
351
//---------------------------------------------------------
 
352
 
 
353
void MidiSyncInfo::trigMMCDetect()   
 
354
 
355
  _MMCDetect = true;
 
356
  _MMCTrig = true;
 
357
  // Set the current midi sync in port number if it's not taken...
 
358
  //if(_recMMC && curMidiSyncInPort == -1)
 
359
  //  curMidiSyncInPort = _port;
 
360
}
 
361
    
 
362
//---------------------------------------------------------
 
363
//  trigMTCDetect
 
364
//---------------------------------------------------------
 
365
 
 
366
void MidiSyncInfo::trigMTCDetect()   
 
367
 
368
  _MTCDetect = true;
 
369
  _MTCTrig = true;
 
370
  // Set the current midi sync in port number if it's not taken...
 
371
  if(_recMTC && curMidiSyncInPort == -1)
 
372
    curMidiSyncInPort = _port;
 
373
}
 
374
    
 
375
//---------------------------------------------------------
212
376
//  actDetect
213
377
//---------------------------------------------------------
214
378
 
254
418
                              _idIn = xml.parseInt();
255
419
                        else if (tag == "sendMC")
256
420
                              _sendMC = xml.parseInt();
 
421
                        else if (tag == "sendMRT")
 
422
                              _sendMRT = xml.parseInt();
257
423
                        else if (tag == "sendMMC")
258
424
                              _sendMMC = xml.parseInt();
259
425
                        else if (tag == "sendMTC")
260
426
                              _sendMTC = xml.parseInt();
 
427
                        //else if (tag == "sendContNotStart")
 
428
                        //      _sendContNotStart = xml.parseInt();
261
429
                        else if (tag == "recMC")
262
430
                              _recMC = xml.parseInt();
 
431
                        else if (tag == "recMRT")
 
432
                              _recMRT = xml.parseInt();
263
433
                        else if (tag == "recMMC")
264
434
                              _recMMC = xml.parseInt();
265
435
                        else if (tag == "recMTC")
266
436
                              _recMTC = xml.parseInt();
 
437
                        else if (tag == "recRewStart")
 
438
                              _recRewOnStart = xml.parseInt();
267
439
                        else
268
440
                              xml.unknown("midiSyncInfo");
269
441
                        break;
287
459
  //  return;
288
460
  
289
461
  // All defaults? Nothing to write.
290
 
  if(_idOut == 127 && _idIn == 127 && !_sendMC && !_sendMMC && !_sendMTC && !_recMC && !_recMMC && !_recMTC)
 
462
  if(_idOut == 127 && _idIn == 127 && !_sendMC && !_sendMRT && !_sendMMC && !_sendMTC && 
 
463
     /* !_sendContNotStart && */ !_recMC && !_recMRT && !_recMMC && !_recMTC && _recRewOnStart)
291
464
    return;
292
465
  
293
466
  xml.tag(level++, "midiSyncInfo");
304
477
  
305
478
  if(_sendMC)
306
479
    xml.intTag(level, "sendMC", true);
307
 
  if(_sendMMC)
 
480
  if(_sendMRT)
 
481
    xml.intTag(level, "sendMRT", true);
 
482
  if(_sendMRT)
308
483
    xml.intTag(level, "sendMMC", true);
309
484
  if(_sendMTC)
310
485
    xml.intTag(level, "sendMTC", true);
 
486
  //if(_sendContNotStart)
 
487
  //  xml.intTag(level, "sendContNotStart", true);
311
488
  
312
489
  if(_recMC)
313
490
    xml.intTag(level, "recMC", true);
 
491
  if(_recMRT)
 
492
    xml.intTag(level, "recMRT", true);
314
493
  if(_recMMC)
315
494
    xml.intTag(level, "recMMC", true);
316
495
  if(_recMTC)
317
496
    xml.intTag(level, "recMTC", true);
 
497
  if(!_recRewOnStart)
 
498
    xml.intTag(level, "recRewStart", false);
318
499
  
319
500
  xml.etag(level, "midiSyncInfo");
320
501
}
324
505
//    Midi Machine Control Input received
325
506
//---------------------------------------------------------
326
507
 
327
 
void MidiSeq::mmcInput(const unsigned char* p, int n)
 
508
//void MidiSeq::mmcInput(const unsigned char* p, int n)
 
509
void MidiSeq::mmcInput(int port, const unsigned char* p, int n)
328
510
      {
329
511
      if (debugSync)
330
512
            printf("mmcInput: n:%d %02x %02x %02x %02x\n",
331
513
               n, p[2], p[3], p[4], p[5]);
 
514
     
 
515
      MidiPort* mp = &midiPorts[port];
 
516
      MidiSyncInfo& msync = mp->syncInfo();
 
517
      // Trigger MMC detect in.
 
518
      msync.trigMMCDetect();
 
519
      // MMC locate SMPTE time code may contain format type bits. Grab them.
 
520
      if(p[3] == 0x44 && p[4] == 6 && p[5] == 1)
 
521
        msync.setRecMTCtype((p[6] >> 5) & 3);
 
522
      
 
523
      // MMC in not turned on? Forget it.
 
524
      if(!msync.MMCIn())
 
525
        return;
 
526
      
332
527
      //if (!(extSyncFlag.value() && acceptMMC))
333
 
      if(!extSyncFlag.value())
334
 
            return;
335
 
 
 
528
      //if(!extSyncFlag.value())
 
529
      //      return;
 
530
      
336
531
      switch(p[3]) {
337
532
            case 1:
338
533
                  if (debugSync)
339
534
                        printf("  MMC: STOP\n");
 
535
                  
 
536
                  playPendingFirstClock = false;
 
537
                  
340
538
                  //if ((state == PLAY || state == PRECOUNT))
341
539
                  if (audio->isPlaying())
342
540
                        audio->msgPlay(false);
362
560
 
363
561
            case 4:
364
562
                  printf("MMC: FF not implemented\n");
 
563
                  playPendingFirstClock = false;
365
564
                  break;
366
565
            case 5:
367
566
                  printf("MMC: REWIND not implemented\n");
 
567
                  playPendingFirstClock = false;
368
568
                  break;
369
569
            case 6:
370
570
                  printf("MMC: REC STROBE not implemented\n");
 
571
                  playPendingFirstClock = false;
371
572
                  break;
372
573
            case 7:
373
574
                  printf("MMC: REC EXIT not implemented\n");
 
575
                  playPendingFirstClock = false;
374
576
                  break;
375
577
            case 0xd:
376
578
                  printf("MMC: RESET not implemented\n");
 
579
                  playPendingFirstClock = false;
377
580
                  break;
378
581
            case 0x44:
379
582
                  if (p[5] == 0) {
381
584
                        break;
382
585
                        }
383
586
                  else if (p[5] == 1) {
 
587
                        if (!checkAudioDevice()) return;
384
588
                        MTC mtc(p[6] & 0x1f, p[7], p[8], p[9], p[10]);
385
 
                        int mmcPos = tempomap.frame2tick(lrint(mtc.time()*sampleRate));
 
589
                        int type = (p[6] >> 5) & 3;
 
590
                        //int mmcPos = tempomap.frame2tick(lrint(mtc.time()*sampleRate));
 
591
                        //int mmcPos = lrint(mtc.time()*sampleRate);
 
592
                        int mmcPos = lrint(mtc.time(type) * sampleRate);
386
593
 
387
 
                        Pos tp(mmcPos, true);
388
 
                        if (!checkAudioDevice()) return;
 
594
                        //Pos tp(mmcPos, true);
 
595
                        Pos tp(mmcPos, false);
389
596
                        //audioDevice->seekTransport(tp.frame());
390
597
                        audioDevice->seekTransport(tp);
391
598
                        alignAllTicks();
392
599
                        //seek(tp);
393
600
                        if (debugSync) {
394
 
                              printf("MMC: %f %d seek ",
395
 
                                 mtc.time(), mmcPos);
 
601
                              //printf("MMC: %f %d seek ", mtc.time(), mmcPos);
 
602
                              printf("MMC: LOCATE mtc type:%d time:%lf frame:%d mtc: ", type, mtc.time(), mmcPos);
396
603
                              mtc.print();
397
604
                              printf("\n");
398
605
                              }
410
617
//    process Quarter Frame Message
411
618
//---------------------------------------------------------
412
619
 
413
 
void MidiSeq::mtcInputQuarter(int, unsigned char c)
 
620
//void MidiSeq::mtcInputQuarter(int, unsigned char c)
 
621
void MidiSeq::mtcInputQuarter(int port, unsigned char c)
414
622
      {
415
623
      static int hour, min, sec, frame;
416
624
 
417
 
      if (!extSyncFlag.value())
418
 
            return;
419
 
 
 
625
      // p3.3.28
 
626
      //printf("MidiSeq::mtcInputQuarter c:%h\n", c);
 
627
      
420
628
      int valL = c & 0xf;
421
629
      int valH = valL << 4;
422
630
 
453
661
      frame &= 0x1f;    // 0-29
454
662
      sec   &= 0x3f;    // 0-59
455
663
      min   &= 0x3f;    // 0-59
 
664
      int tmphour = hour;
 
665
      int type = (hour >> 5) & 3;
456
666
      hour  &= 0x1f;
457
667
 
458
 
      if (mtcState == 8) {
 
668
      if(mtcState == 8) 
 
669
      {
459
670
            mtcValid = (mtcLost == 0);
460
671
            mtcState = 0;
461
672
            mtcLost  = 0;
462
 
            if (mtcValid) {
 
673
            if(mtcValid) 
 
674
            {
463
675
                  mtcCurTime.set(hour, min, sec, frame);
464
 
                  mtcSyncMsg(mtcCurTime, !mtcSync);
 
676
                  if(port != -1)
 
677
                  {
 
678
                    MidiPort* mp = &midiPorts[port];
 
679
                    MidiSyncInfo& msync = mp->syncInfo();
 
680
                    msync.setRecMTCtype(type);
 
681
                    msync.trigMTCDetect();
 
682
                    // Not for the current in port? External sync not turned on? MTC in not turned on? Forget it.
 
683
                    if(port == curMidiSyncInPort && extSyncFlag.value() && msync.MTCIn()) 
 
684
                    {
 
685
                      if(debugSync)
 
686
                        printf("MidiSeq::mtcInputQuarter hour byte:%hx\n", tmphour);
 
687
                      mtcSyncMsg(mtcCurTime, type, !mtcSync);
 
688
                    }  
 
689
                  }
465
690
                  mtcSync = true;
466
 
                  }
467
 
            }
468
 
      else if (mtcValid && (mtcLost == 0)) {
469
 
            mtcCurTime.incQuarter();
470
 
            mtcSyncMsg(mtcCurTime, false);
471
 
            }
 
691
            }
 
692
      }      
 
693
      else if (mtcValid && (mtcLost == 0)) 
 
694
      {
 
695
            //mtcCurTime.incQuarter();
 
696
            mtcCurTime.incQuarter(type);
 
697
            //mtcSyncMsg(mtcCurTime, type, false);
472
698
      }
 
699
    }
473
700
 
474
701
//---------------------------------------------------------
475
702
//   mtcInputFull
476
703
//    process Frame Message
477
704
//---------------------------------------------------------
478
705
 
479
 
void MidiSeq::mtcInputFull(const unsigned char* p, int n)
 
706
//void MidiSeq::mtcInputFull(const unsigned char* p, int n)
 
707
void MidiSeq::mtcInputFull(int port, const unsigned char* p, int n)
480
708
      {
481
709
      if (debugSync)
482
710
            printf("mtcInputFull\n");
483
 
      if (!extSyncFlag.value())
484
 
            return;
 
711
      //if (!extSyncFlag.value())
 
712
      //      return;
485
713
 
486
714
      if (p[3] != 1) {
487
715
            if (p[3] != 2) {   // silently ignore user bits
498
726
      frame &= 0x1f;    // 0-29
499
727
      sec   &= 0x3f;    // 0-59
500
728
      min   &= 0x3f;    // 0-59
501
 
//      int type = (hour >> 5) & 3;
 
729
      int type = (hour >> 5) & 3;
502
730
      hour &= 0x1f;
503
731
 
504
732
      mtcCurTime.set(hour, min, sec, frame);
505
733
      mtcState = 0;
506
734
      mtcValid = true;
507
735
      mtcLost  = 0;
508
 
      }
 
736
      
 
737
      // Added by Tim.
 
738
      if(debugSync)
 
739
        printf("mtcInputFull: time:%lf stime:%lf hour byte (all bits):%hx\n", mtcCurTime.time(), mtcCurTime.time(type), p[4]);
 
740
      if(port != -1)
 
741
      {
 
742
        MidiPort* mp = &midiPorts[port];
 
743
        MidiSyncInfo& msync = mp->syncInfo();
 
744
        msync.setRecMTCtype(type);
 
745
        msync.trigMTCDetect();
 
746
        // MTC in not turned on? Forget it.
 
747
        //if(extSyncFlag.value() && msync.MTCIn())
 
748
        if(msync.MTCIn())
 
749
        {
 
750
          //Pos tp(lrint(mtcCurTime.time() * sampleRate), false);
 
751
          Pos tp(lrint(mtcCurTime.time(type) * sampleRate), false);
 
752
          audioDevice->seekTransport(tp);
 
753
          alignAllTicks();
 
754
        }
 
755
      }    
 
756
    }
509
757
 
510
758
//---------------------------------------------------------
511
759
//   nonRealtimeSystemSysex
512
760
//---------------------------------------------------------
513
761
 
514
 
void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)
 
762
//void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)
 
763
void MidiSeq::nonRealtimeSystemSysex(int /*port*/, const unsigned char* p, int n)
515
764
      {
516
765
//      int chan = p[2];
517
766
      switch(p[3]) {
538
787
      if (midiInputTrace)
539
788
            printf("set song position port:%d %d\n", port, midiBeat);
540
789
      
541
 
      midiPorts[port].syncInfo().trigMCSyncDetect();
 
790
      //midiPorts[port].syncInfo().trigMCSyncDetect();
 
791
      midiPorts[port].syncInfo().trigMRTDetect();
542
792
      
543
793
      //if (!extSyncFlag.value())
544
794
      // External sync not on? Clock in not turned on? 
545
 
      if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MCIn())
 
795
      //if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MCIn())
 
796
      if(!extSyncFlag.value() || !midiPorts[port].syncInfo().MRTIn())
546
797
            return;
547
798
            
548
 
      Pos pos((config.division * midiBeat) / 4, true);
549
 
      
550
799
      // Re-transmit song position to other devices if clock out turned on.
551
800
      for(int p = 0; p < MIDI_PORTS; ++p)
552
 
        if(p != port && midiPorts[p].syncInfo().MCOut())
 
801
        //if(p != port && midiPorts[p].syncInfo().MCOut())
 
802
        if(p != port && midiPorts[p].syncInfo().MRTOut())
553
803
          midiPorts[p].sendSongpos(midiBeat);
554
804
                  
 
805
      curExtMidiSyncTick = (config.division * midiBeat) / 4;
 
806
      lastExtMidiSyncTick = curExtMidiSyncTick;
 
807
      
 
808
      //Pos pos((config.division * midiBeat) / 4, true);
 
809
      Pos pos(curExtMidiSyncTick, true);
 
810
      
555
811
      if (!checkAudioDevice()) return;
556
812
 
557
813
      //audioDevice->seekTransport(pos.frame());
625
881
      MidiPort* mp = &midiPorts[port];
626
882
      
627
883
      // Trigger on any tick, clock, or realtime command. 
628
 
      if(c == 0xf9)
 
884
      if(c == ME_TICK) // Tick
629
885
        mp->syncInfo().trigTickDetect();
630
886
      else
 
887
      if(c == ME_CLOCK) // Clock
631
888
        mp->syncInfo().trigMCSyncDetect();
 
889
      else  
 
890
        mp->syncInfo().trigMRTDetect(); // Other
632
891
       
633
 
      // External sync not on? Clock in not turned on? 
634
 
      if(!extSyncFlag.value() || !mp->syncInfo().MCIn())
635
 
        return;
636
 
      
 
892
      // External sync not on? Clock in not turned on? Otherwise realtime in not turned on?
 
893
      if(!extSyncFlag.value())
 
894
        return;
 
895
      if(c == ME_CLOCK)
 
896
      { 
 
897
        if(!mp->syncInfo().MCIn())
 
898
          return; 
 
899
      }
 
900
      else 
 
901
      if(!mp->syncInfo().MRTIn())      
 
902
        return;
 
903
        
 
904
        
637
905
      switch(c) {
638
 
            case 0xf8:  // midi clock (24 ticks / quarter note)
 
906
            case ME_CLOCK:  // midi clock (24 ticks / quarter note)
639
907
                  {
640
908
                  // Not for the current in port? Forget it.
641
909
                  if(port != curMidiSyncInPort)
642
910
                    break;
643
911
                  
 
912
                  // p3.3.31
 
913
                  //printf("midi clock:%f\n", curTime());
 
914
                  
644
915
                  // Re-transmit clock to other devices if clock out turned on.
645
916
                  // Must be careful not to allow more than one clock input at a time.
646
917
                  // Would re-transmit mixture of multiple clocks - confusing receivers.
650
921
                    if(p != port && midiPorts[p].syncInfo().MCOut())
651
922
                      midiPorts[p].sendClock();
652
923
                  
 
924
                  // p3.3.28
 
925
                  if(playPendingFirstClock)
 
926
                  {
 
927
                    playPendingFirstClock = false;
 
928
                    // Hopefully the transport will be ready by now, the seek upon start should mean the 
 
929
                    //  audio prefetch has already finished or at least started...
 
930
                    // Must comfirm that play does not force a complete prefetch again, but don't think so...
 
931
                    if(!audio->isPlaying())
 
932
                      audioDevice->startTransport();
 
933
                  }
 
934
                  //else
 
935
                  // This part will be run on the second and subsequent clocks, after start.
 
936
                  // Can't check audio state, might not be playing yet, we might miss some increments.
 
937
                  //if(audio->isPlaying())
 
938
                  if(playStateExt)
 
939
                  {
 
940
                    lastExtMidiSyncTime = curExtMidiSyncTime;
 
941
                    curExtMidiSyncTime = curTime();
 
942
                    int div = config.division/24;
 
943
                    midiExtSyncTicks += div;
 
944
                    lastExtMidiSyncTick = curExtMidiSyncTick;
 
945
                    curExtMidiSyncTick += div;
 
946
                  }
 
947
                  
 
948
//BEGIN : Original code:
 
949
                  /*
653
950
                  double mclock0 = curTime();
654
951
                  // Difference in time last 2 rounds:
655
952
                  double tdiff0   = mclock0 - mclock1;
675
972
                        }
676
973
 
677
974
                  // Compare w audio if playing:
678
 
                  if (playStateExt == true /* audio->isPlaying() */ /*state == PLAY*/) {
 
975
                  if (playStateExt == true ) {  //audio->isPlaying()  state == PLAY
679
976
                        //BEGIN standard setup:
680
977
                        recTick  += config.division / 24; // The one we're syncing to
681
978
                        int tempo = tempomap.tempo(0);
697
994
                                      songtick, recTick, tickdiff, song_beat, sync_beat, scale, curFrame);
698
995
                              }
699
996
 
700
 
                        if ((mclock2 !=0.0) && (tdiff1 > 0.0) /*&& fabs(tickdiff) > 0.5*/ && lastTempo != 0) {
 
997
                        //if ((mclock2 !=0.0) && (tdiff1 > 0.0) && fabs(tickdiff) > 0.5 && lastTempo != 0) {
 
998
                        if ((mclock2 !=0.0) && (tdiff1 > 0.0) && lastTempo != 0) {
701
999
                              // Interpolate:
702
1000
                              double tickdiff1 = songtick1 - recTick1;
703
1001
                              double tickdiff2 = songtick2 - recTick2;
704
 
                              double newtickdiff = (tickdiff1+tickdiff2)/250; /*tickdiff/5.0  +
 
1002
                              double newtickdiff = (tickdiff1+tickdiff2)/250; 
 
1003
                                                   //tickdiff/5.0  +
705
1004
                                                   tickdiff1/16.0 +
706
 
                                                   tickdiff2/24.0;*/  //5 mins 30 secs on 116BPM, -p 512 jackd
 
1005
                                                   tickdiff2/24.0;  //5 mins 30 secs on 116BPM, -p 512 jackd
707
1006
 
708
1007
                              if (newtickdiff != 0.0) {
709
1008
                                    int newTempo = tempomap.tempo(0);
757
1056
                        }
758
1057
                  mclock2 = mclock1;
759
1058
                  mclock1 = mclock0;
 
1059
                  */
 
1060
//END : Original Code
 
1061
                  
 
1062
//BEGIN : Using external tempo map:
 
1063
                  /*
 
1064
                  double mclock0 = curTime();
 
1065
                  // Difference in time last 2 rounds:
 
1066
                  double tdiff0   = mclock0 - mclock1;
 
1067
                  double tdiff1   = mclock1 - mclock2;
 
1068
                  double averagetimediff = 0.0;
 
1069
 
 
1070
                  if (mclock1 != 0.0) {
 
1071
                        if (storedtimediffs < 24)
 
1072
                        {
 
1073
                           timediff[storedtimediffs] = mclock0 - mclock1;
 
1074
                           storedtimediffs++;
 
1075
                        }
 
1076
                        else {
 
1077
                              for (int i=0; i<23; i++) {
 
1078
                                    timediff[i] = timediff[i+1];
 
1079
                                    }
 
1080
                              timediff[23] = mclock0 - mclock1;
 
1081
                        }
 
1082
                        // Calculate average timediff:
 
1083
                        for (int i=0; i < storedtimediffs; i++) {
 
1084
                              averagetimediff += timediff[i]/storedtimediffs;
 
1085
                              }
 
1086
                        }
 
1087
 
 
1088
                  // Compare w audio if playing:
 
1089
                  //if (playStateExt == true ) {  //audio->isPlaying()  state == PLAY
 
1090
                  if (0) {
 
1091
                        //BEGIN standard setup:
 
1092
                        recTick  += config.division / 24; // The one we're syncing to
 
1093
                        int tempo = tempomap.tempo(0);
 
1094
                        //unsigned curFrame = audio->pos().frame();
 
1095
                        //double songtick = (double(curFrame)/double(sampleRate)) *
 
1096
                        //                   double(config.division * 1000000.0) / double(tempo);
 
1097
                        double songtick = tempomap.curTickExt(mclock0);
 
1098
                        
 
1099
                        double scale = double(tdiff0/averagetimediff);
 
1100
                        double tickdiff = songtick - ((double) recTick - 24 + scale*24.0);
 
1101
 
 
1102
                        //END standard setup
 
1103
                        if (debugSync) {
 
1104
                              int m, b, t;
 
1105
                              audio->pos().mbt(&m, &b, &t);
 
1106
 
 
1107
                              int song_beat = b + m*4; // if the time-signature is different than 4/4, this will be wrong.
 
1108
                              int sync_beat = recTick/config.division;
 
1109
                              printf("pT=%.3f rT=%d diff=%.3f songB=%d syncB=%d scale=%.3f, curFrame=%d averagetimediff:%.3lf", 
 
1110
                                      songtick, recTick, tickdiff, song_beat, sync_beat, scale, audio->pos().frame(), averagetimediff);
 
1111
                              }
 
1112
 
 
1113
                        //if ((mclock2 !=0.0) && (tdiff1 > 0.0) && fabs(tickdiff) > 0.5 && lastTempo != 0) {
 
1114
                        if ((mclock2 !=0.0) && (tdiff1 > 0.0) && lastTempo != 0) {
 
1115
                              // Interpolate:
 
1116
                              double tickdiff1 = songtick1 - recTick1;
 
1117
                              double tickdiff2 = songtick2 - recTick2;
 
1118
                              double newtickdiff = (tickdiff1+tickdiff2)/250; 
 
1119
                              ////double newtickdiff = (tickdiff1+tickdiff2) / 10.0; 
 
1120
                              //double newtickdiff = tickdiff/5.0  +
 
1121
                              //                     tickdiff1/16.0 +
 
1122
                              //                     tickdiff2/24.0;  //5 mins 30 secs on 116BPM, -p 512 jackd
 
1123
 
 
1124
                              if (newtickdiff != 0.0) {
 
1125
                                    //int newTempo = tempomap.tempo(0);
 
1126
                                    int newTempo = tempo;
 
1127
                                    //newTempo += int(24.0 * newtickdiff * scale);
 
1128
                                    newTempo += int(24.0 * newtickdiff);
 
1129
                                    if (debugSync)
 
1130
                                          printf(" tdiff=%f ntd=%f lt=%d tmpo=%.3f", 
 
1131
                                                tdiff0, newtickdiff, lastTempo, (float)((1000000.0 * 60.0)/newTempo));
 
1132
                                    //syncTempo = newTempo;
 
1133
                                    //tempomap.setTempo(0,newTempo);
 
1134
                                    // Don't set the last stable tempo.
 
1135
                                    //tempomap.setTempo(0, newTempo, false);
 
1136
                                    tempomap.setExtTempo(newTempo);
 
1137
                                    }
 
1138
                              if (debugSync)
 
1139
                                    printf("\n");
 
1140
                              }
 
1141
                        else if (debugSync)
 
1142
                              printf("\n");
 
1143
 
 
1144
                        //BEGIN post calc
 
1145
                        lastTempo = tempo;
 
1146
                        recTick2 = recTick1;
 
1147
                        recTick1 = recTick;
 
1148
                        mclock2 = mclock1;
 
1149
                        mclock1 = mclock0;
 
1150
                        songtick2 = songtick1;
 
1151
                        songtick1 = songtick;
 
1152
                        //END post calc
 
1153
                        break;
 
1154
                        } // END state play
 
1155
                  //
 
1156
                  // Pre-sync (when audio is not running)
 
1157
                  // Calculate tempo depending on time per pulse
 
1158
                  //
 
1159
                  if (mclock1 == 0.0) {
 
1160
                        mp->device()->discardInput();
 
1161
                        if (debugSync)
 
1162
                           printf("Discarding input from port %d\n", port);
 
1163
                        }
 
1164
                  if ((mclock2 != 0.0) && (tdiff0 > 0.0)) {
 
1165
                        
 
1166
                        //int tempo0 = int(24000000.0 * tdiff0 + .5);
 
1167
                        //int tempo1 = int(24000000.0 * tdiff1 + .5);
 
1168
                        //int tempo = tempomap.tempo(0);
 
1169
                        //int diff0 = tempo0 - tempo;
 
1170
                        //int diff1 = tempo1 - tempo0;
 
1171
                        
 
1172
                        //if (diff0) {
 
1173
                        //      int newTempo = tempo + diff0/8 + diff1/16;
 
1174
                        //      if (debugSync)
 
1175
                        //         printf("setting new tempo %d = %f\n", newTempo, (float)((1000000.0 * 60.0)/newTempo));
 
1176
                              //tempomap.setTempo(0, newTempo);
 
1177
                              // Don't set the last stable tempo.
 
1178
                              //tempomap.setTempo(0, newTempo, false);
 
1179
                        //      tempomap.setExtTempo(newTempo);
 
1180
                        //      }
 
1181
                        
 
1182
                        //double tempo0 = 24000000.0 * tdiff0;
 
1183
                        //double tempo1 = 24000000.0 * tdiff1;
 
1184
                        //int newTempo = int((tempo0 + tempo1) / 2.0);
 
1185
                        int newTempo = int(averagetimediff * 24000000.0);
 
1186
                        if(debugSync)
 
1187
                          printf("setting new tempo %d = %f\n", newTempo, (float)((1000000.0 * 60.0)/newTempo));
 
1188
                        tempomap.setExtTempo(newTempo);
 
1189
                        }
 
1190
                        
 
1191
                  mclock2 = mclock1;
 
1192
                  mclock1 = mclock0;
 
1193
                  */
 
1194
//END : Using external tempo map
 
1195
                  
760
1196
                  }
761
1197
                  break;
762
 
            case 0xf9:  // midi tick  (every 10 msec)
 
1198
            case ME_TICK:  // midi tick  (every 10 msec)
763
1199
                  // FIXME: Unfinished? mcStartTick is uninitialized and Song::setPos doesn't set it either. Dangerous to allow this.
764
1200
                  //if (mcStart) {
765
1201
                  //      song->setPos(0, mcStartTick);
767
1203
                  //      return;
768
1204
                  //      }
769
1205
                  break;
770
 
            case 0xfa:  // start
 
1206
            case ME_START:  // start
771
1207
                  // Re-transmit start to other devices if clock out turned on.
772
1208
                  for(int p = 0; p < MIDI_PORTS; ++p)
773
 
                    if(p != port && midiPorts[p].syncInfo().MCOut())
774
 
                      midiPorts[p].sendStart();
775
 
                  
 
1209
                    //if(p != port && midiPorts[p].syncInfo().MCOut())
 
1210
                    if(p != port && midiPorts[p].syncInfo().MRTOut())
 
1211
                    {
 
1212
                      // p3.3.31
 
1213
                      // If we aren't rewinding on start, there's no point in re-sending start.
 
1214
                      // Re-send continue instead, for consistency.
 
1215
                      if(midiPorts[port].syncInfo().recRewOnStart())
 
1216
                        midiPorts[p].sendStart();
 
1217
                      else  
 
1218
                        midiPorts[p].sendContinue();
 
1219
                    }
776
1220
                  if (debugSync)
777
1221
                        printf("   start\n");
 
1222
                  
 
1223
                  // p3.3.31
 
1224
                  //printf("midi start:%f\n", curTime());
 
1225
                  
778
1226
                  if (1 /* !audio->isPlaying()*/ /*state == IDLE*/) {
779
1227
                        if (!checkAudioDevice()) return;
780
 
                        //audioDevice->seekTransport(0);
781
 
                        audioDevice->seekTransport(Pos(0, false));
782
 
                        unsigned curFrame = audio->curFrame();
783
 
                        if (debugSync)
784
 
                              printf("       curFrame=%d\n", curFrame);
 
1228
                        
 
1229
                        // p3.3.31
 
1230
                        // Rew on start option.
 
1231
                        if(midiPorts[port].syncInfo().recRewOnStart())
 
1232
                        {
 
1233
                          curExtMidiSyncTick = 0;
 
1234
                          lastExtMidiSyncTick = curExtMidiSyncTick;
 
1235
                          //audioDevice->seekTransport(0);
 
1236
                          audioDevice->seekTransport(Pos(0, false));
 
1237
                        }  
 
1238
 
 
1239
                        //unsigned curFrame = audio->curFrame();
 
1240
                        //if (debugSync)
 
1241
                        //      printf("       curFrame=%d\n", curFrame);
785
1242
                        
786
1243
                        alignAllTicks();
787
 
                        if (debugSync)
788
 
                              printf("   curFrame: %d curTick: %d tempo: %d\n", curFrame, recTick, tempomap.tempo(0));
 
1244
                        //if (debugSync)
 
1245
                        //      printf("   curFrame: %d curTick: %d tempo: %d\n", curFrame, recTick, tempomap.tempo(0));
789
1246
 
790
1247
                        storedtimediffs = 0;
791
1248
                        for (int i=0; i<24; i++)
792
1249
                              timediff[i] = 0.0;
793
 
                        audio->msgPlay(true);
 
1250
                        
 
1251
                        // p3.3.26 1/23/10
 
1252
                        // Changed because msgPlay calls audioDevice->seekTransport(song->cPos())
 
1253
                        //  and song->cPos() may not be changed to 0 yet, causing tranport not to go to 0.
 
1254
                        //audio->msgPlay(true);
 
1255
                        //audioDevice->startTransport();
 
1256
                        // p3.3.28
 
1257
                        playPendingFirstClock = true;
 
1258
                        
 
1259
                        midiExtSyncTicks = 0;
794
1260
                        playStateExt = true;
795
1261
                        }
796
1262
                  break;
797
 
            case 0xfb:  // continue
 
1263
            case ME_CONTINUE:  // continue
798
1264
                  // Re-transmit continue to other devices if clock out turned on.
799
1265
                  for(int p = 0; p < MIDI_PORTS; ++p)
800
 
                    if(p != port && midiPorts[p].syncInfo().MCOut())
 
1266
                    //if(p != port && midiPorts[p].syncInfo().MCOut())
 
1267
                    if(p != port && midiPorts[p].syncInfo().MRTOut())
801
1268
                      midiPorts[p].sendContinue();
802
1269
                  
803
1270
                  if (debugSync)
804
 
                        printf("   continue\n");
 
1271
                        printf("realtimeSystemInput continue\n");
 
1272
                  
 
1273
                  // p3.3.31
 
1274
                  //printf("continue:%f\n", curTime());
 
1275
                  
805
1276
                  if (1 /* !audio->isPlaying() */ /*state == IDLE */) {
806
1277
                        //unsigned curFrame = audio->curFrame();
807
1278
                        //recTick = tempomap.frame2tick(curFrame); // don't think this will work... (ml)
808
1279
                        //alignAllTicks();
809
 
                        audio->msgPlay(true);
 
1280
                        
 
1281
                        // p3.3.28
 
1282
                        //audio->msgPlay(true);
 
1283
                        // p3.3.31
 
1284
                        // Begin incrementing immediately upon first clock reception.
 
1285
                        playPendingFirstClock = true;
 
1286
                        
810
1287
                        playStateExt = true;
811
1288
                        }
812
1289
                  break;
813
 
            case 0xfc:  // stop
814
 
                  // Re-transmit stop to other devices if clock out turned on.
815
 
                  for(int p = 0; p < MIDI_PORTS; ++p)
816
 
                    if(p != port && midiPorts[p].syncInfo().MCOut())
817
 
                      midiPorts[p].sendStop();
 
1290
            case ME_STOP:  // stop
 
1291
                  {
 
1292
                    // p3.3.35
 
1293
                    // Stop the increment right away.
 
1294
                    midiExtSyncTicks = 0;
 
1295
                    playStateExt = false;
 
1296
                    playPendingFirstClock = false;
 
1297
                    
 
1298
                    // Re-transmit stop to other devices if clock out turned on.
 
1299
                    for(int p = 0; p < MIDI_PORTS; ++p)
 
1300
                      //if(p != port && midiPorts[p].syncInfo().MCOut())
 
1301
                      if(p != port && midiPorts[p].syncInfo().MRTOut())
 
1302
                        midiPorts[p].sendStop();
 
1303
                    
 
1304
                    //playPendingFirstClock = false;
 
1305
                    
 
1306
                    //lastStoppedBeat = (audio->tickPos() * 4) / config.division;
 
1307
                    //curExtMidiSyncTick = (config.division * lastStoppedBeat) / 4;
 
1308
                    
 
1309
                    // p3.3.31
 
1310
                    //printf("stop:%f\n", curTime());
 
1311
                    
 
1312
                    if (audio->isPlaying() /*state == PLAY*/) {
 
1313
                          audio->msgPlay(false);
 
1314
                          //playStateExt = false;
 
1315
                          }
 
1316
                    
 
1317
                    if (debugSync)
 
1318
                          printf("realtimeSystemInput stop\n");
 
1319
                    
 
1320
                    // Just in case the process still runs a cycle or two and causes the 
 
1321
                    //  audio tick position to increment, reset the incrementer and force 
 
1322
                    //  the transport position to what the hardware thinks is the current position.
 
1323
                    //midiExtSyncTicks = 0;
 
1324
                    //Pos pos((config.division * lastStoppedBeat) / 4, true);
 
1325
                    //Pos pos(curExtMidiSyncTick, true);
 
1326
                    //audioDevice->seekTransport(pos);
 
1327
                  }
818
1328
                  
819
 
                  if (debugSync)
820
 
                        printf("   stop\n");
821
 
                  if (audio->isPlaying() /*state == PLAY*/) {
822
 
                        audio->msgPlay(false);
823
 
                        playStateExt = false;
824
 
                        }
825
 
                  break;
826
 
            case 0xfd:  // unknown
827
 
            case 0xfe:  // active sensing
828
 
            case 0xff:  // system reset
829
 
                  break;
 
1329
                  break;
 
1330
            //case 0xfd:  // unknown
 
1331
            //case ME_SENSE:  // active sensing
 
1332
            //case ME_META:  // system reset (reset is 0xff same enumeration as file meta event)
 
1333
            default:
 
1334
                  break;      
830
1335
            }
831
1336
 
832
1337
      }
838
1343
//                start
839
1344
//---------------------------------------------------------
840
1345
 
841
 
void MidiSeq::mtcSyncMsg(const MTC& mtc, bool seekFlag)
 
1346
void MidiSeq::mtcSyncMsg(const MTC& mtc, int type, bool seekFlag)
842
1347
      {
843
1348
      double time = mtc.time();
 
1349
      double stime = mtc.time(type);
844
1350
      if (debugSync)
845
 
            printf("mtcSyncMsg: time %f\n", time);
 
1351
            printf("MidiSeq::mtcSyncMsg time:%lf stime:%lf seekFlag:%d\n", time, stime, seekFlag);
846
1352
 
847
1353
      if (seekFlag && audio->isRunning() /*state == START_PLAY*/) {
848
1354
//            int tick = tempomap.time2tick(time);
849
1355
            //state = PLAY;
850
1356
            //write(sigFd, "1", 1);  // say PLAY to gui
851
1357
            if (!checkAudioDevice()) return;
 
1358
            if (debugSync)
 
1359
              printf("MidiSeq::mtcSyncMsg starting transport.\n");
852
1360
            audioDevice->startTransport();
853
1361
            return;
854
1362
            }