1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: midi.cpp,v 1.43.2.22 2009/11/09 20:28:28 terminator356 Exp $
5 //
6 //  (C) Copyright 1999/2004 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2011-2016 Tim E. Real (terminator356 on users dot sourceforge dot net)
8 //
9 //  This program is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU General Public License
11 //  as published by the Free Software Foundation; version 2 of
12 //  the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //=========================================================
24 
25 #include "muse_math.h"
26 #include <errno.h>
27 
28 #include "song.h"
29 #include "midi.h"
30 #include "drummap.h"
31 #include "event.h"
32 #include "globals.h"
33 #include "midictrl.h"
34 #include "marker/marker.h"
35 #include "midiport.h"
36 #include "minstrument.h"
37 #include "midictrl.h"
38 #include "sync.h"
39 #include "audio.h"
40 #include "audiodev.h"
41 #include "mididev.h"
42 #include "driver/alsamidi.h"
43 #include "driver/jackmidi.h"
44 #include "wave.h"
45 #include "synth.h"
46 #include "sync.h"
47 #include "midiseq.h"
48 #include "gconfig.h"
49 #include "ticksynth.h"
50 #include "mpevent.h"
51 #include "metronome_class.h"
52 #include "tempo.h"
53 #include "sig.h"
54 #include "keyevent.h"
55 #include "track.h"
56 
57 // REMOVE Tim. Persistent routes. Added. Make this permanent later if it works OK and makes good sense.
58 #define _USE_MIDI_ROUTE_PER_CHANNEL_
59 
60 // Undefine if and when multiple output routes are added to midi tracks.
61 #define _USE_MIDI_TRACK_SINGLE_OUT_PORT_CHAN_
62 
63 // For debugging output: Uncomment the fprintf section.
64 #define DEBUG_MIDI(dev, format, args...) // fprintf(dev, format, ##args);
65 // For debugging metronome and precount output: Uncomment the fprintf section.
66 #define DEBUG_MIDI_METRONOME(dev, format, args...) // fprintf(dev, format, ##args);
67 // For debugging midi timing: Uncomment the fprintf section.
68 #define DEBUG_MIDI_TIMING(dev, format, args...) // fprintf(dev, format, ##args);
69 // For debugging midi event time differences.
70 //#define DEBUG_MIDI_TIMING_DIFFS ;
71 
72 namespace MusECore {
73 
74 #ifdef DEBUG_MIDI_TIMING_DIFFS
75 // For testing.
76 unsigned _lastEvTime = 0;
77 #endif
78 
79 
80 extern void dump(const unsigned char* p, int n);
81 
82 // Division can be zero meaning the event times are to be taken verbosely
83 //  (as ticks already), no conversion is to be applied.
84 #define CALC_TICK(the_tick) (div > 0 ? lrintf((float(the_tick) * float(MusEGlobal::config.division) + float(div/2)) / float(div)) : the_tick);
85 
86 /*---------------------------------------------------------
87  *    midi_meta_name
88  *---------------------------------------------------------*/
89 
midiMetaName(int meta)90 QString midiMetaName(int meta)
91       {
92       const char* s = "";
93       switch (meta) {
94             case 0:     s = "Text 0: Sequence Number"; break;
95             case 1:     s = "Text 1: Track comment"; break;
96             case 2:     s = "Text 2: Copyright"; break;
97             case 3:     s = "Text 3: Sequence/Track Name"; break;
98             case 4:     s = "Text 4: Instrument Name"; break;
99             case 5:     s = "Text 5: Lyric"; break;
100             case 6:     s = "Text 6: Marker"; break;
101             case 7:     s = "Text 7: Cue Point"; break;
102             case 8:     s = "Text 8"; break;
103             case 9:     s = "Text 9: Device Name"; break;
104             case 0x0a:  s = "Text A"; break;
105             case 0x0b:  s = "Text B"; break;
106             case 0x0c:  s = "Text C"; break;
107             case 0x0d:  s = "Text D"; break;
108             case 0x0e:  s = "Text E"; break;
109             case 0x0f:  s = "Text F"; break;
110             case 0x20:  s = "Channel Prefix"; break;
111             case 0x21:  s = "Port Change"; break;
112             case 0x2f:  s = "End of Track"; break;
113             case 0x51:  s = "Set Tempo"; break;
114             case 0x54:  s = "SMPTE Offset"; break;
115             case 0x58:  s = "Time Signature"; break;
116             case 0x59:  s = "Key Signature"; break;
117             case 0x74:  s = "Sequencer-Specific1"; break;
118             case 0x7f:  s = "Sequencer-Specific2"; break;
119             default:
120                   break;
121             }
122       return QString(s);
123       }
124 
125 //---------------------------------------------------------
126 //   QString nameSysex
127 //---------------------------------------------------------
128 
nameSysex(unsigned int len,const unsigned char * buf,MidiInstrument * instr)129 QString nameSysex(unsigned int len, const unsigned char* buf, MidiInstrument* instr)
130       {
131       QString s;
132       if(len == 0)
133         return s;
134 
135       switch(buf[0]) {
136             case 0x00:
137                   if(len < 3)
138                     return s;
139                   if (buf[1] == 0 && buf[2] == 0x41)
140                         s = "Microsoft";
141                   break;
142             case 0x01:  s = "Sequential Circuits"; break;
143             case 0x02:  s = "Big Briar"; break;
144             case 0x03:  s = "Octave / Plateau"; break;
145             case 0x04:  s = "Moog"; break;
146             case 0x05:  s = "Passport Designs"; break;
147             case 0x06:  s = "Lexicon"; break;
148             case 0x07:  s = "Kurzweil"; break;
149             case 0x08:  s = "Fender"; break;
150             case 0x09:  s = "Gulbransen"; break;
151             case 0x0a:  s = "Delta Labas"; break;
152             case 0x0b:  s = "Sound Comp."; break;
153             case 0x0c:  s = "General Electro"; break;
154             case 0x0d:  s = "Techmar"; break;
155             case 0x0e:  s = "Matthews Research"; break;
156             case 0x10:  s = "Oberheim"; break;
157             case 0x11:  s = "PAIA"; break;
158             case 0x12:  s = "Simmons"; break;
159             case 0x13:  s = "DigiDesign"; break;
160             case 0x14:  s = "Fairlight"; break;
161             case 0x15:  s = "JL Cooper"; break;
162             case 0x16:  s = "Lowery"; break;
163             case 0x17:  s = "Lin"; break;
164             case 0x18:  s = "Emu"; break;
165             case 0x1b:  s = "Peavy"; break;
166             case 0x20:  s = "Bon Tempi"; break;
167             case 0x21:  s = "S.I.E.L"; break;
168             case 0x23:  s = "SyntheAxe"; break;
169             case 0x24:  s = "Hohner"; break;
170             case 0x25:  s = "Crumar"; break;
171             case 0x26:  s = "Solton"; break;
172             case 0x27:  s = "Jellinghaus Ms"; break;
173             case 0x28:  s = "CTS"; break;
174             case 0x29:  s = "PPG"; break;
175             case 0x2f:  s = "Elka"; break;
176             case 0x36:  s = "Cheetah"; break;
177             case 0x3e:  s = "Waldorf"; break;
178             case 0x40:  s = "Kawai"; break;
179             case 0x41:  s = "Roland"; break;
180             case 0x42:  s = "Korg"; break;
181             case 0x43:  s = "Yamaha"; break;
182             case 0x44:  s = "Casio"; break;
183             case 0x45:  s = "Akai"; break;
184             case MUSE_SYNTH_SYSEX_MFG_ID:  s = "MusE Soft Synth"; break;
185             case 0x7d:  s = "Educational Use"; break;
186             case 0x7e:  s = "Universal: Non Real Time"; break;
187             case 0x7f:  s = "Universal: Real Time"; break;
188             default:    s = "??"; break;
189             }
190 
191       if(instr)
192       {
193         // Check for user-defined sysex in instrument...
194         foreach(const MusECore::SysEx* sx, instr->sysex())
195         {
196           if((int)len == sx->dataLen && memcmp(buf, sx->data, len) == 0)
197             return s + QString(": ") + sx->name;
198         }
199       }
200 
201       //
202       // following messages should not show up in event list
203       // they are filtered while importing midi files
204       //
205       if ((len == gmOnMsgLen) && memcmp(buf, gmOnMsg, gmOnMsgLen) == 0)
206             s += ": GM-ON";
207       else if ((len == gm2OnMsgLen) && memcmp(buf, gm2OnMsg, gm2OnMsgLen) == 0)
208             s += ": GM2-ON";
209       else if ((len == gmOffMsgLen) && memcmp(buf, gmOffMsg, gmOffMsgLen) == 0)
210             s += ": GM-OFF";
211       else if ((len == gsOnMsgLen) && memcmp(buf, gsOnMsg, gsOnMsgLen) == 0)
212             s += ": GS-ON";
213       else if ((len == xgOnMsgLen) && memcmp(buf, xgOnMsg, xgOnMsgLen) == 0)
214             s += ": XG-ON";
215       return s;
216       }
217 
218 //---------------------------------------------------------
219 //   QString sysexComment
220 //---------------------------------------------------------
221 
sysexComment(unsigned int len,const unsigned char * buf,MidiInstrument * instr)222 QString sysexComment(unsigned int len, const unsigned char* buf, MidiInstrument* instr)
223       {
224       QString s;
225       if(len == 0)
226         return s;
227 
228       if(instr)
229       {
230         // Check for user-defined sysex in instrument...
231         foreach(const MusECore::SysEx* sx, instr->sysex())
232         {
233           if((int)len == sx->dataLen && memcmp(buf, sx->data, len) == 0)
234             return sx->comment;
235         }
236       }
237 
238       // These are the common ones we know about so far...
239       if ((len == gmOnMsgLen) && memcmp(buf, gmOnMsg, gmOnMsgLen) == 0)
240             s = QObject::tr("Switch on General Midi Level 1 mode");
241       else if ((len == gm2OnMsgLen) && memcmp(buf, gm2OnMsg, gm2OnMsgLen) == 0)
242             s = QObject::tr("Switch on General Midi Level 2 mode");
243       else if ((len == gmOffMsgLen) && memcmp(buf, gmOffMsg, gmOffMsgLen) == 0)
244             s = QObject::tr("Switch off General Midi Level 1 or 2");
245       else if ((len == gsOnMsgLen) && memcmp(buf, gsOnMsg, gsOnMsgLen) == 0)
246             s = QObject::tr("Switch on Roland GS mode");
247       else if ((len == xgOnMsgLen) && memcmp(buf, xgOnMsg, xgOnMsgLen) == 0)
248             s = QObject::tr("Switch on Yamaha XG mode");
249       return s;
250       }
251 
252 //---------------------------------------------------------
253 //   buildMidiEventList
254 //    TODO:
255 //      parse data increment/decrement controller
256 //      NRPN/RPN  fine/course data 7/14 Bit
257 //          must we set datah/datal to zero after change
258 //          of NRPN/RPN register?
259 //      generally: how to handle incomplete messages
260 //---------------------------------------------------------
261 
buildMidiEventList(EventList * del,const MPEventList & el,MidiTrack * track,int div,bool addSysexMeta,bool doLoops)262 void buildMidiEventList(EventList* del, const MPEventList& el, MidiTrack* track,
263    int div, bool addSysexMeta, bool doLoops)
264       {
265       int hbank    = 0xff;
266       int lbank    = 0xff;
267       int rpnh     = -1;
268       int rpnl     = -1;
269       int datah    = 0;
270       int datal    = 0;
271       int dataType = 0;   // 0 : disabled, 0x20000 : rpn, 0x30000 : nrpn
272 
273       EventList mel;
274 
275       MidiInstrument::NoteOffMode nom = MidiInstrument::NoteOffAll;
276       MidiPort* mp = 0;
277       MidiInstrument* minstr = 0;
278       const int port = track->outPort();
279       if(port >= 0 && port < MusECore::MIDI_PORTS)
280       {
281         mp = &MusEGlobal::midiPorts[port];
282         minstr = mp->instrument();
283         if(minstr)
284           nom = minstr->noteOffMode();
285       }
286 
287       for (iMPEvent i = el.begin(); i != el.end(); ++i) {
288             MidiPlayEvent ev = *i;
289             if (!addSysexMeta && (ev.type() == ME_SYSEX || ev.type() == ME_META))
290                   continue;
291             if (!(ev.type() == ME_SYSEX || ev.type() == ME_META
292                || ((ev.channel() == track->outChannel()) && (ev.port() == track->outPort()))))
293                   continue;
294             unsigned tick = ev.time();
295 
296             DEBUG_MIDI(stderr, "buildMidiEventList tick:%d dataA:%d dataB:%d\n",
297                             ev.time(), ev.dataA(), ev.dataB());
298 
299             if(doLoops)
300             {
301               if(tick >= MusEGlobal::song->lPos().tick() && tick < MusEGlobal::song->rPos().tick())
302               {
303                 int loopn = ev.loopNum();
304                 int loopc = MusEGlobal::audio->loopCount();
305                 int cmode = MusEGlobal::song->cycleMode(); // CYCLE_NORMAL, CYCLE_MIX, CYCLE_REPLACE
306                 // If we want REPLACE and the event was recorded in a previous loop,
307                 //  just ignore it. This will effectively ignore ALL previous loop events inside
308                 //  the left and right markers, regardless of where recording was started or stopped.
309                 // We want to keep any loop 0 note-offs from notes which crossed over the left marker.
310                 // To avoid more searching here, just keep ALL note-offs from loop 0, and let code below
311                 //  sort out and keep which ones had note-ons.
312                 if(!(ev.isNoteOff() && loopn == 0))
313                 {
314                   if(cmode == Song::CYCLE_REPLACE && loopn < loopc)
315                     continue;
316 
317                   // If we want NORMAL, same as REPLACE except keep all events from the previous loop
318                   //  from rec stop position to right marker (and beyond).
319                   if(cmode == Song::CYCLE_NORMAL)
320                   {
321                     // Not sure of accuracy here. Adjust? Adjusted when used elsewhere?
322                     unsigned endRec = MusEGlobal::audio->getEndRecordPos().tick();
323                     if((tick < endRec && loopn < loopc) || (tick >= endRec && loopn < (loopc - 1)))
324                       continue;
325                   }
326                 }
327               }
328             }
329 
330             Event e;
331             switch(ev.type()) {
332                   case ME_NOTEON:
333                         e.setType(Note);
334 
335                         if (track->isDrumTrack()) {
336                               int instr = track->map_drum_in(ev.dataA());
337                               e.setPitch(instr);
338                               }
339                         else
340                               e.setPitch(ev.dataA());
341 
342                         e.setVelo(ev.dataB());
343                         e.setLenTick(0);
344                         break;
345                   case ME_NOTEOFF:
346                         e.setType(Note);
347                         if (track->isDrumTrack()) {
348                               int instr = track->map_drum_in(ev.dataA());
349                               e.setPitch(instr);
350                               }
351                         else
352                               e.setPitch(ev.dataA());
353 
354                         e.setVelo(0);
355                         e.setVeloOff(ev.dataB());
356                         e.setLenTick(0);
357                         break;
358                   case ME_POLYAFTER:
359                         e.setType(Controller);
360                         e.setA((CTRL_POLYAFTER & ~0xff) | (ev.dataA() & 0x7f));
361                         e.setB(ev.dataB());
362                         break;
363 
364                   case ME_CONTROLLER:
365                         {
366                         int val = ev.dataB();
367                         switch(ev.dataA()) {
368                               case CTRL_HBANK:
369                                     hbank = val;
370                                     break;
371 
372                               case CTRL_LBANK:
373                                     lbank = val;
374                                     break;
375 
376                               case CTRL_HDATA:
377                                     datah = val;
378                                     // check if a CTRL_LDATA follows
379                                     // e.g. wie have a 14 bit controller:
380                                     {
381                                     iMPEvent ii = i;
382                                     ++ii;
383                                     bool found = false;
384                                     for (; ii != el.end(); ++ii) {
385                                           MidiPlayEvent ev = *ii;
386                                           if (ev.type() == ME_CONTROLLER) {
387                                                 if (ev.dataA() == CTRL_LDATA) {
388                                                       // handle later
389                                                       found = true;
390                                                       }
391                                                 break;
392                                                 }
393                                           }
394                                     if (!found) {
395                                           if (rpnh == -1 || rpnl == -1) {
396                                                 fprintf(stderr, "parameter number not defined, data 0x%x\n", datah);
397                                                 }
398                                           else {
399                                                 int ctrl = dataType | (rpnh << 8) | rpnl;
400                                                 e.setType(Controller);
401                                                 e.setA(ctrl);
402                                                 e.setB(datah);
403                                                 }
404                                           }
405                                     }
406                                     break;
407 
408                               case CTRL_LDATA:
409                                     datal = val;
410 
411                                     if (rpnh == -1 || rpnl == -1) {
412                                           fprintf(stderr, "parameter number not defined, data 0x%x 0x%x, tick %d, channel %d\n",
413                                              datah, datal, tick, track->outChannel());
414                                           break;
415                                           }
416                                     // assume that the sequence is always
417                                     //    CTRL_HDATA - CTRL_LDATA
418                                     // eg. that LDATA is always send last
419 
420                                     e.setType(Controller);
421                                     // 14 Bit RPN/NRPN
422                                     e.setA((dataType+0x30000) | (rpnh << 8) | rpnl);
423                                     e.setB((datah << 7) | datal);
424                                     break;
425 
426                               case CTRL_HNRPN:
427                                     rpnh = val;
428                                     dataType = 0x30000;
429                                     break;
430 
431                               case CTRL_LNRPN:
432                                     rpnl = val;
433                                     dataType = 0x30000;
434                                     break;
435 
436                               case CTRL_HRPN:
437                                     rpnh     = val;
438                                     dataType = 0x20000;
439                                     break;
440 
441                               case CTRL_LRPN:
442                                     rpnl     = val;
443                                     dataType = 0x20000;
444                                     break;
445 
446                               default:
447                                     e.setType(Controller);
448                                     int ctl = ev.dataA();
449                                     e.setA(ctl);
450 
451                                     if(track->isDrumTrack())
452                                     {
453                                       // Is it a drum controller event, according to the track port's instrument?
454                                       MidiController *mc = MusEGlobal::midiPorts[track->outPort()].drumController(ctl);
455                                       if(mc)
456                                         // Store an index into the drum map.
457                                         e.setA((ctl & ~0xff) | track->map_drum_in(ctl & 0x7f));
458                                     }
459 
460                                     e.setB(val);
461                                     break;
462                               }
463                         }
464                         break;
465 
466                   case ME_PROGRAM:
467                         e.setType(Controller);
468                         e.setA(CTRL_PROGRAM);
469                         e.setB((hbank << 16) | (lbank << 8) | ev.dataA());
470                         break;
471 
472                   case ME_AFTERTOUCH:
473                         e.setType(Controller);
474                         e.setA(CTRL_AFTERTOUCH);
475                         e.setB(ev.dataA());
476                         break;
477 
478                   case ME_PITCHBEND:
479                         e.setType(Controller);
480                         e.setA(CTRL_PITCH);
481                         e.setB(ev.dataA());
482                         break;
483 
484                   case ME_SYSEX:
485                         e.setType(Sysex);
486                         e.setData(ev.constData(), ev.len());
487                         break;
488 
489                   case ME_META:
490                         {
491                         const unsigned char* data = ev.constData();
492                         switch (ev.dataA()) {
493                               case ME_META_TEXT_1_COMMENT:
494                                     if (track->comment().isEmpty())
495                                           track->setComment(QString((const char*)data));
496                                     else
497                                           track->setComment(track->comment() + "\n" + QString((const char*)data));
498                                     break;
499                               case ME_META_TEXT_3_TRACK_NAME: // Sequence-/TrackName
500                                     track->setName(QString((char*)data));
501                                     break;
502                               case ME_META_TEXT_6_MARKER:
503                                     {
504                                     unsigned ltick  = CALC_TICK(tick);
505                                     MusEGlobal::song->addMarker(QString((const char*)(data)), ltick, false);
506                                     }
507                                     break;
508                               // Copyright is supposed to occur only at the beginning of the first track, but we don't
509                               //  specifically catch it yet during import, so let's just allow it 'wherever' for now.
510                               case ME_META_TEXT_2_COPYRIGHT:
511                               // Lyrics are allowed anywhere.
512                               case ME_META_TEXT_5_LYRIC:
513                               // Cue points are supposed to occur only in the first track, but we don't support them
514                               //  yet (need a list just like markers), so just allow them 'wherever' for now.
515                               case ME_META_TEXT_7_CUE_POINT:
516                               // Program name is allowed anywhere.
517                               case ME_META_TEXT_8_PROGRAM_NAME:
518                               // No documentation could be found for these, so just allow them 'wherever' for now.
519                               case ME_META_TEXT_A:
520                               case ME_META_TEXT_B:
521                               case ME_META_TEXT_C:
522                               case ME_META_TEXT_D:
523                               case ME_META_TEXT_E:
524                                     {
525                                     e.setType(Meta);
526                                     e.setA(ev.dataA());
527                                     e.setData(ev.constData(), ev.len());
528                                     }
529                                     break;
530                               // Instrument and device name metas are already handled by the midi importing code.
531                               case ME_META_TEXT_4_INSTRUMENT_NAME:
532                               case ME_META_TEXT_9_DEVICE_NAME:
533                                     break;
534 
535                               case ME_META_TEXT_F_TRACK_COMMENT:
536                                     track->setComment(QString((char*)data));
537                                     break;
538                               case ME_META_SET_TEMPO:
539                                     {
540                                     unsigned tempo = data[2] + (data[1] << 8) + (data[0] <<16);
541                                     unsigned ltick  = CALC_TICK(tick);
542                                     // FIXME: After ca 10 mins 32 bits will not be enough... This expression has to be changed/factorized or so in some "sane" way...
543                                     MusEGlobal::tempomap.addTempo(ltick, tempo);
544                                     }
545                                     break;
546                               case ME_META_TIME_SIGNATURE:
547                                     {
548                                     int timesig_z = data[0];
549                                     int n = data[1];
550                                     int timesig_n = 1;
551                                     for (int i = 0; i < n; i++)
552                                           timesig_n *= 2;
553                                     int ltick  = CALC_TICK(tick);
554                                     MusEGlobal::sigmap.add(ltick, MusECore::TimeSignature(timesig_z, timesig_n));
555                                     }
556                                     break;
557                               case ME_META_KEY_SIGNATURE:
558                                     {
559                                     char kc = data[0];
560                                     bool minor = data[1];
561                                     key_enum key = KEY_SHARP_BEGIN;
562                                     switch(kc)
563                                     {
564                                       case -5:
565                                         key = KEY_DES;
566                                       break;
567                                       case -4:
568                                         key = KEY_AS;
569                                       break;
570                                       case -3:
571                                         key = KEY_ES;
572                                       break;
573                                       case -2:
574                                         key = KEY_BES;
575                                       break;
576                                       case -1:
577                                         key = KEY_F;
578                                       break;
579                                       case 0:
580                                         key = KEY_C;
581                                       break;
582                                       case 1:
583                                         key = KEY_G;
584                                       break;
585                                       case 2:
586                                         key = KEY_D;
587                                       break;
588                                       case 3:
589                                         key = KEY_A;
590                                       break;
591                                       case 4:
592                                         key = KEY_E;
593                                       break;
594                                       case 5:
595                                         key = KEY_B;
596                                       break;
597                                       default:
598                                       break;
599                                     }
600                                     if(key != KEY_SHARP_BEGIN)
601                                     {
602                                       unsigned ltick  = CALC_TICK(tick);
603                                       MusEGlobal::keymap.addKey(ltick, key, minor);
604                                     }
605                                     }
606                                     break;
607                               default:
608                                     fprintf(stderr, "buildMidiEventList: unknown Meta 0x%x %d unabsorbed, adding instead to track:%s\n",
609                                             ev.dataA(), ev.dataA(), track->name().toLatin1().constData());
610                                     e.setType(Meta);
611                                     e.setA(ev.dataA());
612                                     e.setData(ev.constData(), ev.len());
613                                     break;
614                               }
615                         }
616                         break;
617                   }   // switch(ev.type()
618             if (!e.empty()) {
619                   e.setTick(tick);
620 
621                   //-------------------------------------------
622                   //    Check for and prevent duplicate events
623                   //-------------------------------------------
624 
625                   const int midi_evtype = ev.type();
626                   const bool midi_noteoff = (midi_evtype == ME_NOTEOFF) || (midi_evtype == ME_NOTEON && ev.dataB() == 0);
627                   const bool midi_noteon = midi_evtype == ME_NOTEON && ev.dataB() != 0;
628                   const bool midi_controller = midi_evtype == ME_CONTROLLER;
629                   bool noteon_found = false;
630                   bool noteoff_found = false;
631                   bool ctrlval_found = false;
632                   //bool other_ctrlval_found = false;
633                   if(i != el.begin())
634                   {
635                     iMPEvent k = i;
636                     while(k != el.begin())
637                     {
638                       --k;
639                       MidiPlayEvent k_ev = *k;
640                       if(k_ev.channel() != ev.channel() || k_ev.port() != ev.port())
641                         continue;
642                       const int check_midi_evtype = k_ev.type();
643                       const bool check_midi_noteoff = (check_midi_evtype == ME_NOTEOFF) || (check_midi_evtype == ME_NOTEON && k_ev.dataB() == 0);
644                       const bool check_midi_noteon = check_midi_evtype == ME_NOTEON && k_ev.dataB() != 0;
645                       const bool check_midi_controller = check_midi_evtype == ME_CONTROLLER;
646                       if(midi_noteon || midi_noteoff)
647                       {
648                         if(ev.dataA() == k_ev.dataA())  // Note
649                         {
650                           if(check_midi_noteon)
651                           {
652                             // Check the instrument's note-off mode: If it does not support note-offs,
653                             //  don't bother doing duplicate note-on checks.
654                             // This allows drum input triggers (no note offs at all), although it is awkward to
655                             //  first have to choose an output instrument with no note-off mode.
656                             if(!midi_noteon || (nom != MidiInstrument::NoteOffNone))
657                               noteon_found = true;
658                             break;
659                           }
660                           if(check_midi_noteoff)
661                           {
662                             noteoff_found = true;
663                             break;
664                           }
665                         }
666                       }
667                       else if(midi_controller)
668                       {
669                         if(ev.dataA() == k_ev.dataA())     // Controller number
670                         {
671                           if(check_midi_controller)
672                           {
673                             // All we can really do is prevent multiple events at the same time.
674                             // We must allow multiple events at different times having the same value,
675                             //  since the sender may have wanted it that way (a 'flat' graph).
676                             if(ev.time() == k_ev.time())     // Event time
677                               ctrlval_found = true;
678                             // Optimization: Do not allow multiple events at different times having the same value.
679                             // Nice, but can't really discard these, sender may have wanted it that way (a 'flat' graph).
680                           #if 0
681                             if(ev.dataB() == k_ev.dataB()) // Controller value
682                               ctrlval_found = true;
683                             else
684                               other_ctrlval_found = true;
685                           #endif
686                             break;
687                           }
688                         }
689                       }
690                       else
691                       {
692                         // TODO: Other types!
693                       }
694                     }
695                   }
696                   // Accept the event only if no duplicate was found. // TODO: Other types!
697                   if((midi_noteon && !noteon_found) ||
698                     (midi_noteoff && !noteoff_found) ||
699                     //(midi_controller && (other_ctrlval_found || !ctrlval_found)))
700                     (midi_controller && !ctrlval_found) ||
701                     // Accept any other type of event.
702                     (!midi_noteon && !midi_noteoff && !midi_controller) )
703                     mel.add(e);
704                   }
705             }  // i != el.end()
706 
707 
708       //---------------------------------------------------
709       //    read NoteOn events and remove corresponding NoteOffs
710       //---------------------------------------------------
711 
712         for (iEvent i = mel.begin(); i != mel.end(); ++i) {
713               Event ev  = i->second;
714               if (ev.isNote()) {
715                     if (!ev.isNoteOff()) {
716 
717                     // If the event length is not zero, it means the event and its
718                     //  note on/off have already been taken care of. So ignore it.
719                     if(ev.lenTick() != 0)
720                       continue;
721 
722                     iEvent k;
723                     for (k = mel.lower_bound(ev.tick()); k != mel.end(); ++k) {
724                           Event event = k->second;
725                           if (ev.isNoteOff(event)) {
726                                 int t = k->first - i->first;
727                                 if (t <= 0) {
728                                       if (MusEGlobal::debugMsg) {
729                                             fprintf(stderr, "Note len is (%d-%d)=%d, set to 1\n",
730                                               k->first, i->first, k->first - i->first);
731                                             ev.dump();
732                                             event.dump();
733                                             }
734                                       t = 1;
735                                       }
736                                 ev.setLenTick(t);
737                                 ev.setVeloOff(event.veloOff());
738                                 break;
739                                 }
740                           }
741                     if (k == mel.end()) {
742                           fprintf(stderr, "-no note-off! %d pitch %d velo %d\n",
743                             ev.tick(), ev.pitch(), ev.velo());
744                           //
745                           // switch off at end of measure
746                           //
747                           int endTick = MusEGlobal::song->roundUpBar(ev.tick()+1);
748                           ev.setLenTick(endTick-ev.tick());
749                           }
750                     else {
751                           if (k==i) {
752                             //this will never happen, because i->second has to be a NOTE ON,
753                             //while k has to be a NOTE OFF. but in case something changes:
754                             fprintf(stderr, "ERROR: THIS SHOULD NEVER HAPPEN: k==i in midi.cpp:buildMidiEventList()\n");
755                           }
756                           else {
757                             mel.erase(k);
758                           }
759                             i = mel.begin();
760                           continue;
761                           }
762                     }
763                                     }
764               }
765 
766       for (iEvent i = mel.begin(); i != mel.end(); ++i) {
767             Event ev  = i->second;
768             if (ev.isNoteOff()) {
769                   fprintf(stderr, "+extra note-off! %d pitch %d velo %d\n",
770                            i->first, ev.pitch(), ev.velo());
771                   continue;
772                   }
773             int tick  = CALC_TICK(ev.tick());
774             if (ev.isNote()) {
775                   int lenTick = CALC_TICK(ev.lenTick());
776                   ev.setLenTick(lenTick);
777                   }
778             ev.setTick(tick);
779             del->add(ev);
780             }
781       }
782 
783 } // namespace MusECore
784 
785 namespace MusECore {
786 
787 //---------------------------------------------------------
788 //   midiPortsChanged
789 //---------------------------------------------------------
790 
midiPortsChanged()791 void Audio::midiPortsChanged()
792       {
793       write(sigFd, "P", 1);
794       }
795 
796 //---------------------------------------------------------
797 //   sendLocalOff
798 //   Can be called by any thread.
799 //---------------------------------------------------------
800 
sendLocalOff()801 void Audio::sendLocalOff()
802       {
803       MidiPlayEvent ev;
804       ev.setTime(0);  // Immediate processing. TODO Use curFrame?
805       ev.setType(MusECore::ME_CONTROLLER);
806       ev.setA(MusECore::CTRL_LOCAL_OFF);
807       ev.setB(0);
808       for (int k = 0; k < MusECore::MIDI_PORTS; ++k) {
809             for (int i = 0; i < MusECore::MUSE_MIDI_CHANNELS; ++i)
810             {
811                   ev.setPort(k);
812                   ev.setChannel(i);
813                   // This is a 'trigger' event. Send to the device, but do not send to the
814                   //  midi port controllers because it leaves them in this state.
815                   if(MusEGlobal::midiPorts[k].device())
816                     MusEGlobal::midiPorts[k].device()->putEvent(ev, MidiDevice::NotLate);
817             }
818             }
819       }
820 
821 //---------------------------------------------------------
822 //   panic
823 //   Can be called by any thread.
824 //---------------------------------------------------------
825 
panic()826 void Audio::panic()
827       {
828       MidiPlayEvent ev;
829       ev.setTime(0);  // Immediate processing. TODO Use curFrame?
830       ev.setType(MusECore::ME_CONTROLLER);
831       ev.setB(0);
832 
833       // TODO Reset those controllers back to unknown!
834       for (int i = 0; i < MusECore::MIDI_PORTS; ++i) {
835             MusECore::MidiPort* port = &MusEGlobal::midiPorts[i];
836             for (int chan = 0; chan < MusECore::MUSE_MIDI_CHANNELS; ++chan) {
837                   if (MusEGlobal::debugMsg)
838                     fprintf(stderr, "send all sound of to midi port %d channel %d\n", i, chan);
839 
840                   ev.setPort(i);
841                   ev.setChannel(chan);
842 
843                   ev.setA(MusECore::CTRL_ALL_SOUNDS_OFF);
844                   // This is a 'trigger' event. Send to the device, but do not send to the
845                   //  midi port controllers because it leaves them in this state.
846                   //port->putHwCtrlEvent(ev);
847                   if(port->device())
848                     port->device()->putEvent(ev, MidiDevice::NotLate);
849 
850                   ev.setA(MusECore::CTRL_RESET_ALL_CTRL);
851                   // This is a 'trigger' event. Send to the device, but do not send to the
852                   //  midi port controllers because it leaves them in this state.
853                   //port->putHwCtrlEvent(ev);
854                   if(port->device())
855                     port->device()->putEvent(ev, MidiDevice::NotLate);
856                   }
857             }
858       }
859 
860 //---------------------------------------------------------
861 //   initDevices
862 //    - called when instrument init sequences plus controller
863 //       defaults should be checked and/or sent
864 //    - called from arranger pulldown menu
865 //---------------------------------------------------------
866 
initDevices(bool force)867 void Audio::initDevices(bool force)
868       {
869       for (int i = 0; i < MusECore::MIDI_PORTS; ++i) {
870             MusEGlobal::midiPorts[i].sendPendingInitializations(force);
871             }
872       }
873 
874 //---------------------------------------------------------
875 //   seekMidi
876 //   Called from audio thread only.
877 //---------------------------------------------------------
878 
seekMidi()879 void Audio::seekMidi()
880 {
881   MusECore::MetronomeSettings* metro_settings =
882     MusEGlobal::metroUseSongSettings ? &MusEGlobal::metroSongSettings : &MusEGlobal::metroGlobalSettings;
883 
884   unsigned int pos = MusEGlobal::audio->tickPos();
885   const bool playing = isPlaying();
886 
887   // Bit-wise channels that are used.
888   int used_ports[MusECore::MIDI_PORTS];
889   // Initialize the array.
890   for(int i = 0; i < MusECore::MIDI_PORTS; ++i)
891     used_ports[i] = 0;
892 
893   // Find all used channels on all used ports.
894 //   bool drum_found = false;
895   if(MusEGlobal::song->click() &&
896      metro_settings->clickPort < MusECore::MIDI_PORTS &&
897      metro_settings->clickChan < MusECore::MUSE_MIDI_CHANNELS)
898     used_ports[metro_settings->clickPort] |= (1 << metro_settings->clickChan);
899   MidiTrackList* tl = MusEGlobal::song->midis();
900   for(ciMidiTrack imt = tl->begin(); imt != tl->end(); ++imt)
901   {
902     MidiTrack* mt = *imt;
903 
904     //------------------------------------------------------------
905     //    While we are at it, flush out any track-related playback stuck notes
906     //     (NOT 'live' notes) which were not put directly to the device
907     //------------------------------------------------------------
908     MPEventList& mel = mt->stuckNotes;
909     for(iMPEvent i = mel.begin(), i_next = i; i != mel.end(); i = i_next)
910     {
911       ++i_next;
912 
913       MidiPlayEvent ev(*i);
914       const int ev_port = ev.port();
915       if(ev_port >= 0 && ev_port < MusECore::MIDI_PORTS)
916       {
917         MidiPort* mp = &MusEGlobal::midiPorts[ev_port];
918         ev.setTime(0);  // Immediate processing. TODO Use curFrame?
919         if(mp->device())
920           mp->device()->putEvent(ev, MidiDevice::NotLate);
921       }
922       mel.erase(i);
923     }
924 
925 
926 #ifdef _USE_MIDI_TRACK_SINGLE_OUT_PORT_CHAN_
927 
928     if(mt->isDrumTrack())
929     {
930       for(int i = 0; i < DRUM_MAPSIZE; ++i)
931       {
932         // Default to track port if -1 and track channel if -1.
933         int mport = mt->drummap()[i].port;
934         if(mport == -1)
935           mport = mt->outPort();
936         int mchan = mt->drummap()[i].channel;
937         if(mchan == -1)
938           mchan = mt->outChannel();
939         if(mport >= 0 && mport < MusECore::MIDI_PORTS && mchan >= 0 && mchan < MusECore::MUSE_MIDI_CHANNELS)
940           used_ports[mport] |= (1 << mchan);
941       }
942     }
943     else
944     {
945         const int mport = mt->outPort();
946         const int mchan = mt->outChannel();
947         if(mport >= 0 && mport < MusECore::MIDI_PORTS && mchan >= 0 && mchan < MusECore::MUSE_MIDI_CHANNELS)
948           used_ports[mport] |= (1 << mchan);
949     }
950 
951 #else
952     MusECore::RouteList* rl = mt->outRoutes();
953     for(MusECore::ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
954     {
955       switch(ir->type)
956       {
957         case MusECore::Route::MIDI_PORT_ROUTE:
958         {
959           if(mt->isDrumTrack())
960           {
961             for(int i = 0; i < DRUM_MAPSIZE; ++i)
962             {
963               // Default to track port if -1 and track channel if -1.
964               int mport = mt->drummap()[i].port;
965               if(mport == -1)
966                 mport = mt->outPort();
967               int mchan = mt->drummap()[i].channel;
968               if(mchan == -1)
969                 mchan = mt->outChannel();
970               if(mport >= 0 && mport < MIDI_PORTS && mchan >= 0 && mchan < MusECore::MUSE_MIDI_CHANNELS)
971                 used_ports[mport] |= (1 << mchan);
972             }
973           }
974           else
975           {
976               const int mport = ir->midiPort;
977               const int mchan = ir->channel;
978               if(mport >= 0 && mport < MIDI_PORTS && mchan >= 0 && mchan < MusECore::MUSE_MIDI_CHANNELS)
979                 used_ports[mport] |= (1 << mchan);
980           }
981         }
982         break;
983 
984         case MusECore::Route::TRACK_ROUTE:
985         case MusECore::Route::JACK_ROUTE:
986         case MusECore::Route::MIDI_DEVICE_ROUTE:
987         break;
988       }
989     }
990 #endif
991   }
992 
993   for(int i = 0; i < MusECore::MIDI_PORTS; ++i)
994   {
995     if(used_ports[i] == 0)
996       continue;
997 
998     MidiPort* mp = &MusEGlobal::midiPorts[i];
999     MidiDevice* md = mp->device();
1000 
1001     //---------------------------------------------------
1002     //    Send STOP
1003     //---------------------------------------------------
1004 
1005     // Don't send if external sync is on. The master, and our sync routing system will take care of that.
1006     if(!MusEGlobal::extSyncFlag)
1007     {
1008       if(mp->syncInfo().MRTOut())
1009       {
1010         // Shall we check for device write open flag to see if it's ok to send?...
1011         //if(!(rwFlags() & 0x1) || !(openFlags() & 1))
1012         //if(!(openFlags() & 1))
1013         //  continue;
1014         mp->sendStop();
1015       }
1016     }
1017 
1018     //---------------------------------------------------
1019     //    If playing, clear all notes and flush out any
1020     //     stuck notes which were put directly to the device
1021     //---------------------------------------------------
1022 
1023     if(md && playing)
1024       md->handleSeek();
1025 
1026     //---------------------------------------------------
1027     //    reset sustain
1028     //---------------------------------------------------
1029 
1030     if(md)
1031     {
1032       for(int ch = 0; ch < MusECore::MUSE_MIDI_CHANNELS; ++ch)
1033       {
1034         if(mp->hwCtrlState(ch, CTRL_SUSTAIN) == 127)
1035         {
1036           const MidiPlayEvent ev(0, i, ch, ME_CONTROLLER, CTRL_SUSTAIN, 0);
1037           md->putEvent(ev, MidiDevice::NotLate);
1038         }
1039       }
1040     }
1041 
1042     MidiInstrument* instr = mp->instrument();
1043     MidiCtrlValListList* cll = mp->controller();
1044 
1045     for(iMidiCtrlValList ivl = cll->begin(); ivl != cll->end(); ++ivl)
1046     {
1047       MidiCtrlValList* vl = ivl->second;
1048       int chan = ivl->first >> 24;
1049       if(!(used_ports[i] & (1 << chan)))  // Channel not used in song?
1050         continue;
1051       int ctlnum = vl->num();
1052 
1053       // Find the first non-muted value at the given tick...
1054       bool values_found = false;
1055       bool found_value = false;
1056 
1057       iMidiCtrlVal imcv = vl->lower_bound(pos);
1058       if(imcv != vl->end() && imcv->first == pos)
1059       {
1060         for( ; imcv != vl->end() && imcv->first == pos; ++imcv)
1061         {
1062           const Part* p = imcv->second.part;
1063           if(!p)
1064             continue;
1065           // Ignore values that are outside of the part.
1066           if(pos < p->tick() || pos >= (p->tick() + p->lenTick()))
1067             continue;
1068           values_found = true;
1069           // Ignore if part or track is muted or off.
1070           if(p->mute())
1071             continue;
1072           const Track* track = p->track();
1073           if(track && (track->isMute() || track->off()))
1074             continue;
1075           found_value = true;
1076           break;
1077         }
1078       }
1079       else
1080       {
1081         while(imcv != vl->begin())
1082         {
1083           --imcv;
1084           const Part* p = imcv->second.part;
1085           if(!p)
1086             continue;
1087           // Ignore values that are outside of the part.
1088           unsigned t = imcv->first;
1089           if(t < p->tick() || t >= (p->tick() + p->lenTick()))
1090             continue;
1091           values_found = true;
1092           // Ignore if part or track is muted or off.
1093           if(p->mute())
1094             continue;
1095           const Track* track = p->track();
1096           if(track && (track->isMute() || track->off()))
1097             continue;
1098           found_value = true;
1099           break;
1100         }
1101       }
1102 
1103       if(found_value)
1104       {
1105         int fin_port = i;
1106         MidiPort* fin_mp = mp;
1107         int fin_chan = chan;
1108         int fin_ctlnum = ctlnum;
1109         // Is it a drum controller event, according to the track port's instrument?
1110         if(mp->drumController(ctlnum))
1111         {
1112           if(const Part* p = imcv->second.part)
1113           {
1114             if(Track* t = p->track())
1115             {
1116               if(t->type() == MusECore::Track::DRUM)
1117               {
1118                 MidiTrack* mt = static_cast<MidiTrack*>(t);
1119                 int v_idx = ctlnum & 0x7f;
1120                 fin_ctlnum = (ctlnum & ~0xff) | mt->drummap()[v_idx].anote;
1121                 int map_port = mt->drummap()[v_idx].port;
1122                 if(map_port != -1)
1123                 {
1124                   fin_port = map_port;
1125                   fin_mp = &MusEGlobal::midiPorts[fin_port];
1126                 }
1127                 int map_chan = mt->drummap()[v_idx].channel;
1128                 if(map_chan != -1)
1129                   fin_chan = map_chan;
1130               }
1131             }
1132           }
1133         }
1134 
1135         const MidiPlayEvent ev(0, fin_port, fin_chan, ME_CONTROLLER, fin_ctlnum, imcv->second.val);
1136         // This is the audio thread. Just set directly.
1137         fin_mp->setHwCtrlState(ev);
1138         // Don't bother sending any sustain values to the device, because we already
1139         //  just sent out zero sustain values, above. Just set the hw state.
1140         // When play resumes, the correct values are sent again if necessary in Audio::startRolling().
1141         if(fin_ctlnum != CTRL_SUSTAIN && fin_mp->device())
1142           fin_mp->device()->putEvent(ev, MidiDevice::NotLate);
1143       }
1144 
1145       // Either no value was found, or they were outside parts, or pos is in the unknown area before the first value.
1146       // Send instrument default initial values.  NOT for syntis. Use midiState and/or initParams for that.
1147       //if((imcv == vl->end() || !done) && !MusEGlobal::song->record() && instr && !isSynti())
1148       // Hmm, without refinement we can only do this at position 0, due to possible 'skipped' values outside parts, above.
1149       if(instr && md && !md->isSynti() && !values_found &&
1150          MusEGlobal::config.midiSendCtlDefaults && !MusEGlobal::song->record() && pos == 0)
1151       {
1152           // NOTE: If this is a PROGRAM controller, this code is not as crazy as it looks.
1153           //       (How can we ask for, and then set, an initial program when we are first asking
1154           //        for the current program? Seems like a 'circular' conflict.)
1155           //       Midnam does not contain a program controller, so the setHwCtrlState() below
1156           //        has no effect on the current controller list since in midnam there's no
1157           //        program controller which would make it patch-dependent. There is only our
1158           //        instrument's global PROGRAM controller (does not care about channel or current patch).
1159           const int patch = mp->hwCtrlState(chan, CTRL_PROGRAM);
1160           const MidiController* mc = instr->findController(vl->num(), chan, patch);
1161           if(mc->initVal() != CTRL_VAL_UNKNOWN)
1162           {
1163             //fprintf(stderr, "Audio::seekMidi: !values_found: calling sendEvent: ctlnum:%d val:%d\n", ctlnum, mc->initVal() + mc->bias());
1164             // Use sendEvent to get the optimizations and limiting. No force sending. Note the addition of bias.
1165             const MidiPlayEvent ev(0, i, chan, ME_CONTROLLER, ctlnum, mc->initVal() + mc->bias());
1166             // This is the audio thread. Just set directly.
1167             mp->setHwCtrlState(ev);
1168             md->putEvent(ev, MidiDevice::NotLate);
1169           }
1170       }
1171 
1172       //---------------------------------------------------
1173       //    Send STOP and "set song position pointer"
1174       //---------------------------------------------------
1175 
1176       // Don't send if external sync is on. The master, and our sync routing system will take care of that.
1177       if(!MusEGlobal::extSyncFlag)
1178       {
1179         if(mp->syncInfo().MRTOut())
1180         {
1181           int beat = (pos * 4) / MusEGlobal::config.division;
1182           mp->sendSongpos(beat);
1183         }
1184       }
1185     }
1186   }
1187 }
1188 
1189 //---------------------------------------------------------
1190 //   extClockHistoryTick2Frame
1191 //    Convert tick to frame using the external clock history list.
1192 //    The function takes a tick relative to zero (ie. relative to the first event in a processing batch).
1193 //    The returned clock frames occurred during the previous audio cycle(s), so you may want to shift
1194 //     the frames forward by one audio segment size for scheduling purposes.
1195 //    CAUTION: There must be at least one valid clock in the history,
1196 //              otherwise it returns zero. Don't feed this a tick
1197 //              greater than or equal to the next tick, it will simply return
1198 //              the very last frame, which is not very useful since
1199 //              that will just bunch the events together at the last frame.
1200 //---------------------------------------------------------
1201 
extClockHistoryTick2Frame(unsigned int tick) const1202 unsigned int Audio::extClockHistoryTick2Frame(unsigned int tick) const
1203 {
1204   if(_extClockHistorySize == 0)
1205   {
1206     fprintf(stderr, "Error: Audio::extClockTickToFrame(): empty list\n");
1207     return 0;
1208   }
1209 
1210   const int div = MusEGlobal::config.division / 24;
1211   if(div == 0)
1212     return 0; // Prevent divide by zero.
1213 
1214   int index = tick / div;
1215   if(index >= _extClockHistorySize)
1216   {
1217     fprintf(stderr, "Error: Audio::extClockTickToFrame(): index:%d >= size:%d\n", index, _extClockHistorySize);
1218     index = _extClockHistorySize - 1;
1219   }
1220 
1221 // Divide the clock period by the division and interpolate for even better resolution.
1222 // FIXME: Darn, too bad we can't use this. It would work, but the previous cycle
1223 //         has no knowledge of what to put at the end, and the current cycle
1224 //         would end up lumping together events at the start which should have
1225 //         been played at end of previous cycle.
1226 //   const unsigned int subtick = tick % div;
1227 //   const unsigned int frame = _extClockLastFrame + double(_extClockHistory[index] - _extClockLastFrame) * (double(subtick) / double(div));
1228   const unsigned int frame = _extClockHistory[index].frame();
1229 
1230   return frame;
1231 }
1232 
1233 //---------------------------------------------------------
1234 //   extClockHistoryTick2Frame
1235 //    Convert frame to tick using the external clock history list.
1236 //    The function takes an absolute linearly increasing frame and returns a tick relative to zero
1237 //     (ie. relative to the first event in a processing batch).
1238 //    CAUTION: There must be at least one valid clock in the history,
1239 //              otherwise it returns zero. Don't feed this a frame
1240 //              greater than or equal to the next frame, it will simply return
1241 //              the very last tick, which is not very useful since
1242 //              that will just bunch the events together at the last tick.
1243 //---------------------------------------------------------
1244 
extClockHistoryFrame2Tick(unsigned int frame) const1245 unsigned int Audio::extClockHistoryFrame2Tick(unsigned int frame) const
1246 {
1247   if(_extClockHistorySize == 0)
1248   {
1249     fprintf(stderr, "Error: Audio::extClockHistoryFrame2Tick(): empty list\n");
1250     return curTickPos;
1251   }
1252 
1253   const unsigned int div = MusEGlobal::config.division / 24;
1254 
1255   bool found = false;
1256   unsigned int val = 0;
1257 
1258   for(int i = _extClockHistorySize - 1; i >= 0; --i)
1259   {
1260     DEBUG_MIDI(stderr, "Audio::extClockHistoryFrame2Tick(): frame:%u i:%d _extClockHistory[i]._frame:%u\n",
1261             frame, i, _extClockHistory[i].frame());
1262 
1263     if(_extClockHistory[i].frame() <= frame)
1264     {
1265       if(!found)
1266       {
1267         found = true;
1268         int clocks = 0;
1269         unsigned int offset = curTickPos;
1270 
1271         for(int k = i; k >= 0; --k)
1272         {
1273           if(_extClockHistory[k].isFirstClock())
1274           {
1275             if(_extClockHistory[k].externState() == ExtMidiClock::ExternStarted)
1276               offset = 0;
1277           }
1278 
1279           if(!_extClockHistory[k].isPlaying())
1280             break;
1281 
1282           if(k < i)  // Ignore first clock.
1283             ++clocks;
1284         }
1285 
1286         val = offset + clocks * div;
1287       }
1288     }
1289   }
1290   if(found)
1291     return val;
1292 
1293   fprintf(stderr, "Error: Audio::extClockHistoryFrame2Tick(): frame:%u out of range. Returning zero. _extClockHistorySize:%u\n",
1294           frame, _extClockHistorySize);
1295 
1296   // We don't know the state of the last clock, we can only assume it was playing.
1297   if(curTickPos >= div)
1298     return curTickPos - div;
1299 
1300   return curTickPos;
1301 }
1302 
1303 //---------------------------------------------------------
1304 //   collectEvents
1305 //    collect events for next audio segment
1306 //---------------------------------------------------------
1307 
collectEvents(MusECore::MidiTrack * track,unsigned int cts,unsigned int nts,unsigned int frames,unsigned int latency_offset)1308 void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts,
1309                           unsigned int nts, unsigned int frames, unsigned int latency_offset)
1310       {
1311       DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: cts:%u nts:%u\n", cts, nts);
1312       const bool extsync = MusEGlobal::extSyncFlag;
1313       const int delay = track->delay;
1314       // If external sync is not on, we can take advantage of frame accuracy but
1315       //  first we must allow the next tick position to be included in the search
1316       //  even if it is equal to the current tick position.
1317       if((extsync && cts >= nts) ||
1318          (!extsync && cts > nts))
1319         return;
1320 
1321       int port    = track->outPort();
1322       int channel = track->outChannel();
1323       int defaultPort = port;
1324       MidiPort* mp = &MusEGlobal::midiPorts[port];
1325       MidiDevice* md = mp->device();
1326 
1327       const unsigned int pos_fr = _pos.frame() + latency_offset;
1328       const unsigned int next_pos_fr = pos_fr + frames;
1329 
1330       // at least one punch is set at this point
1331       const bool replaceMode = recording && track->recordFlag() && MusEGlobal::song->recMode() == MusEGlobal::song->REC_REPLACE;
1332       const bool punchboth = MusEGlobal::song->punchin() && MusEGlobal::song->punchout();
1333       const bool punchin = MusEGlobal::song->punchin() && !MusEGlobal::song->punchout();
1334       const bool punchout = MusEGlobal::song->punchout() && !MusEGlobal::song->punchin();
1335       const unsigned int rangeStart = MusEGlobal::song->lPos().tick();
1336       const unsigned int rangeEnd = MusEGlobal::song->rPos().tick();
1337 
1338 
1339       DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: pos_fr:%u next_pos_fr:%u\n", pos_fr, next_pos_fr);
1340 
1341       PartList* pl = track->parts();
1342       for (iPart p = pl->begin(); p != pl->end(); ++p) {
1343             MusECore::MidiPart* part = (MusECore::MidiPart*)(p->second);
1344             // don't play muted parts
1345             if (part->mute())
1346                   continue;
1347             const EventList& events = part->events();
1348             unsigned partTick = part->tick();
1349             unsigned partLen  = part->lenTick();
1350             unsigned offset = delay + partTick;
1351             if (offset > nts)
1352                   continue;
1353             unsigned stick = (offset > cts) ? 0 : cts - offset;
1354             unsigned etick = nts - offset;
1355             // Do not play events which are past the end of this part.
1356             if(etick > partLen)
1357               continue;
1358 
1359             // The start and end tick are a rough range to make the loop faster instead of having
1360             //  to iterate the whole list each time, comparing frames.
1361             // Use upper_bound because we need to include the 'next' last item because it may have a
1362             //  fractional tick component that we would otherwise miss with lower_bound. The loop will
1363             //  decide whether to process iterated items or not by precisely comparing frames.
1364             // We rely on the tempo value being 'stable' during the process period - that is
1365             //  no user changes in-between cycles. We don't have that capability currently anyway -
1366             //  to break the process up into chunks (like our controllers) depending on tempo frames,
1367             //  our tempo map is not frame-accurate, only tick-accurate.
1368             ciEvent ie   = events.lower_bound(stick);
1369             ciEvent iend = events.upper_bound(etick);
1370 
1371             DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: part events stick:%u etick:%u\n", stick, etick);
1372 
1373             for (; ie != iend; ++ie) {
1374                   Event ev = ie->second;
1375                   port = defaultPort; //Reset each loop
1376                   //
1377                   //  don't play any meta events
1378                   //
1379                   if (ev.type() == Meta)
1380                         continue;
1381                   if (track->isDrumTrack()) {
1382                         int instr = ev.pitch();
1383                         // ignore muted drums
1384                         if (ev.isNote() && track->drummap()[instr].mute)
1385                               continue;
1386                         }
1387 
1388                   if (replaceMode) {
1389                       unsigned eventStart = ev.tick() + partTick;
1390                       if (punchboth && (eventStart >= rangeStart && eventStart < rangeEnd))
1391                           continue;
1392                       else if (punchin && eventStart >= rangeStart)
1393                           continue;
1394                       else if (punchout && eventStart < rangeEnd)
1395                           continue;
1396                   }
1397 
1398                   unsigned tick  = ev.tick() + offset;
1399 
1400                   DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: event tick:%u\n", tick);
1401 
1402                   //-----------------------------------------------------------------
1403                   // Determining the playback scheduling frame from the event's tick:
1404                   //-----------------------------------------------------------------
1405                   unsigned frame;
1406                   if(extsync)
1407                     // If external sync is on, look up the scheduling frame from the tick,
1408                     //  in the external clock history list (which is cleared, re-composed, and processed each cycle).
1409                     // The function takes a tick relative to zero (ie. relative to the first event in this batch).
1410                     // The returned clock frame occurred during the previous audio cycle(s), so shift the frame
1411                     //  forward by one audio segment size.
1412                     frame = extClockHistoryTick2Frame(tick - stick) + MusEGlobal::segmentSize;
1413                   else
1414                   {
1415                     // If external sync is off, look up the scheduling frame from our tempo list
1416                     //  ie. normal playback.
1417                     const unsigned int fr = MusEGlobal::tempomap.tick2frame(tick);
1418 
1419                     DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: event: frame:%u\n", fr);
1420 
1421                     // Take advantage of frame-accurate comparison ability here.
1422                     // At some point, the event's frame time and the 'swept' current range of pos frame will intersect,
1423                     //  so all events should be accounted for.
1424                     if(fr < pos_fr || fr >= next_pos_fr)
1425                     {
1426                       DEBUG_MIDI_TIMING(stderr, "Audio::collectEvents: Ignoring event\n");
1427                       continue;
1428                     }
1429 
1430                     frame = fr - pos_fr;
1431                     frame += syncFrame;
1432                   }
1433 
1434                   DEBUG_MIDI(stderr, "Audio::collectEvents: event: tick:%u final frame:%u\n", tick, frame);
1435 
1436                   switch (ev.type()) {
1437                         case Note:
1438                               {
1439                               int len   = ev.lenTick();
1440                               int pitch = ev.pitch();
1441                               int velo  = ev.velo();
1442                               int veloOff = ev.veloOff();
1443                               if (track->isDrumTrack())  {
1444                                     // Map drum-notes to the drum-map values
1445                                    int instr = ev.pitch();
1446                                    pitch     = track->drummap()[instr].anote;
1447                                    // Default to track port if -1 and track channel if -1.
1448                                    port      = track->drummap()[instr].port; //This changes to non-default port
1449                                    if(port == -1)
1450                                      port = track->outPort();
1451                                    channel   = track->drummap()[instr].channel;
1452                                    if(channel == -1)
1453                                      channel = track->outChannel();
1454                                    velo      = int(double(velo) * (double(track->drummap()[instr].vol) / 100.0)) ;
1455                                    veloOff   = int(double(veloOff) * (double(track->drummap()[instr].vol) / 100.0)) ;
1456                                    }
1457                               else if (track->type() == Track::MIDI) {
1458                                     // transpose non drum notes
1459                                     pitch += (track->transposition + MusEGlobal::song->globalPitchShift());
1460                                     }
1461 
1462                               if (pitch > 127)
1463                                     pitch = 127;
1464                               if (pitch < 0)
1465                                     pitch = 0;
1466 
1467                               // Apply track velocity and compression to both note-on and note-off velocity...
1468                               velo += track->velocity;
1469                               velo = (velo * track->compression) / 100;
1470                               if (velo > 127)
1471                                     velo = 127;
1472                               if (velo < 1)           // no off event
1473                                     // Zero means zero. Should mean no note at all?
1474                                     //velo = 1;
1475                                     continue;
1476                               veloOff += track->velocity;
1477                               veloOff = (veloOff * track->compression) / 100;
1478                               if (veloOff > 127)
1479                                     veloOff = 127;
1480                               if (veloOff < 1)
1481                                     veloOff = 0;
1482 
1483                               len = (len *  track->len) / 100;
1484                               if (len <= 0)     // don't allow zero length
1485                                     len = 1;
1486 
1487                               if (port == defaultPort) {
1488                                     if (md) {
1489                                           md->putEvent(
1490                                             MusECore::MidiPlayEvent(frame, port, channel, MusECore::ME_NOTEON, pitch, velo),
1491                                               MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
1492                                         track->addStuckNote(MusECore::MidiPlayEvent(tick + len, port, channel,
1493                                           MusECore::ME_NOTEOFF, pitch, veloOff));
1494                                       }
1495                                     }
1496                               else { //Handle events to different port than standard.
1497                                     MidiDevice* mdAlt = MusEGlobal::midiPorts[port].device();
1498                                     if (mdAlt) {
1499                                           mdAlt->putEvent(
1500                                             MusECore::MidiPlayEvent(frame, port, channel, MusECore::ME_NOTEON, pitch, velo),
1501                                               MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
1502                                         track->addStuckNote(MusECore::MidiPlayEvent(tick + len, port, channel,
1503                                           MusECore::ME_NOTEOFF, pitch, veloOff));
1504                                       }
1505                                     }
1506 
1507                               if(velo > track->activity())
1508                                 track->setActivity(velo);
1509                               }
1510                               break;
1511 
1512                         case Controller:
1513                               {
1514                                 if (track->isDrumTrack())
1515                                 {
1516                                   int ctl   = ev.dataA();
1517                                   // Is it a drum controller event, according to the track port's instrument?
1518                                   MusECore::MidiController *mc = MusEGlobal::midiPorts[defaultPort].drumController(ctl);
1519                                   if(mc)
1520                                   {
1521                                     int instr = ctl & 0x7f;
1522                                     ctl &=  ~0xff;
1523                                     int pitch = track->drummap()[instr].anote & 0x7f;
1524                                     // Default to track port if -1 and track channel if -1.
1525                                     port      = track->drummap()[instr].port; //This changes to non-default port
1526                                     if(port == -1)
1527                                       port = track->outPort();
1528                                     channel   = track->drummap()[instr].channel;
1529                                     if(channel == -1)
1530                                       channel = track->outChannel();
1531 
1532                                     MusECore::MidiPlayEvent mpeAlt(frame, port, channel,
1533                                                                    MusECore::ME_CONTROLLER,
1534                                                                    ctl | pitch,
1535                                                                    ev.dataB());
1536 
1537                                     MidiPort* mpAlt = &MusEGlobal::midiPorts[port];
1538                                     // TODO Maybe grab the flag from the 'Optimize Controllers' Global Setting,
1539                                     //       which so far was meant for (N)RPN stuff. For now, just force it.
1540                                     // This is the audio thread. Just set directly.
1541                                     mpAlt->setHwCtrlState(mpeAlt);
1542                                     if(MidiDevice* mdAlt = mpAlt->device())
1543                                       mdAlt->putEvent(mpeAlt, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
1544 
1545                                     break;  // Break out.
1546                                   }
1547                                 }
1548 
1549                                 MusECore::MidiPlayEvent mpe = ev.asMidiPlayEvent(frame, port, channel);
1550                                 // TODO Maybe grab the flag from the 'Optimize Controllers' Global Setting,
1551                                 //       which so far was meant for (N)RPN stuff. For now, just force it.
1552                                 // This is the audio thread. Just set directly.
1553                                 mp->setHwCtrlState(mpe);
1554                                 if(md)
1555                                   md->putEvent(mpe, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
1556                               }
1557                               break;
1558 
1559                         default:
1560 
1561                               if(md)
1562                               {
1563                                  md->putEvent(ev.asMidiPlayEvent(frame, port, channel),
1564                                                   MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
1565                               }
1566                               break;
1567                         }
1568                   }
1569             }
1570       }
1571 
1572 //---------------------------------------------------------
1573 //   processMidi
1574 //    - collects midi events for current audio segment and
1575 //       sends them to midi thread
1576 //    - current audio segment position is (curTickPos, nextTickPos)
1577 //    - called from midiseq thread,
1578 //      executed in audio thread
1579 //---------------------------------------------------------
1580 
processMidi(unsigned int frames)1581 void Audio::processMidi(unsigned int frames)
1582       {
1583       const bool extsync = MusEGlobal::extSyncFlag;
1584       const bool playing = isPlaying();
1585 
1586       for (iMidiDevice id = MusEGlobal::midiDevices.begin(); id != MusEGlobal::midiDevices.end(); ++id)
1587       {
1588         MidiDevice* md = *id;
1589         int port = md->midiPort(); // Port should be same as event.port() from this device. Same idea event.channel().
1590 
1591         // Process events sent by synthesizers (which in turn may have been passed by their GUI -> synth FIFOs).
1592         // Receive events sent from a synth's gui thread (which might be different than our gui thread) to the audio thread.
1593         if(md->isSynti())
1594         {
1595           SynthI* s = (SynthI*)md;
1596           while (s->eventsPending())
1597           {
1598             MidiRecordEvent ev = s->receiveEvent();
1599             // FIXME: This is for recording the events sent by GUI.
1600             //        It never gets a chance to be processed since reading of
1601             //         record FIFOs is done only by connected input ROUTES, below.
1602             //        To be useful, the synth itself must be allowed to be chosen
1603             //         as an input route, which is simple enough, but we currently don't
1604             //         list synths as inputs for fear of too many INCOMPATIBLE messages
1605             //         from DIFFERING synths. However, we could allow ONLY THIS synth
1606             //         to be listed and therefore be automatically connected too, if desired.
1607             //md->recordEvent(ev);
1608             //
1609             // For now, instead of recording, here is the minimum that we must do:
1610 
1611             // Intercept any special MusE system sysex messages. (This IS the system right here.)
1612             bool intercepted = false;
1613             const int type = ev.type();
1614             switch(type)
1615             {
1616               case ME_SYSEX:
1617               {
1618                 const unsigned char* p = ev.constData();
1619                 int n = ev.len();
1620                 if(n >= 3)
1621                 {
1622                   if(p[0] == MUSE_SYNTH_SYSEX_MFG_ID)
1623                   {
1624                     if(p[1] == MUSE_SYSEX_SYSTEM_ID && p[2] == MUSE_SYSEX_SYSTEM_UPDATE_DRUM_MAPS_ID)
1625                     {
1626                       intercepted = true;
1627                       if(port >= 0 && port < MusECore::MIDI_PORTS)
1628                         MusEGlobal::midiPorts[port].updateDrumMaps();
1629                     }
1630                   }
1631                 }
1632               }
1633               break;
1634 
1635               default:
1636               break;
1637             }
1638 
1639             // Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values.
1640             // Same code as in MidiPort::sendEvent()
1641             if(!intercepted && port != -1)
1642               // This is the audio thread. Just set directly.
1643               MusEGlobal::midiPorts[port].setHwCtrlState(MidiPlayEvent(ev));
1644           }
1645         }
1646 
1647         // Take snapshots of the current sizes of the recording fifos,
1648         //  because they may change while here in process, asynchronously.
1649         md->beforeProcess();
1650 
1651         //
1652         // --------- Handle midi events for audio tracks -----------
1653         //
1654 
1655         if(port < 0)
1656           continue;
1657 
1658         for(int chan = 0; chan < MusECore::MUSE_MIDI_CHANNELS; ++chan)
1659         {
1660           MusECore::MidiRecFifo& rf = md->recordEvents(chan);
1661           int count = md->tmpRecordCount(chan);
1662           for(int i = 0; i < count; ++i)
1663           {
1664             const MusECore::MidiRecordEvent& event(rf.peek(i));
1665 
1666             int etype = event.type();
1667             if(etype == MusECore::ME_CONTROLLER || etype == MusECore::ME_PITCHBEND || etype == MusECore::ME_PROGRAM)
1668             {
1669               int ctl, val;
1670               if(etype == MusECore::ME_CONTROLLER)
1671               {
1672                 ctl = event.dataA();
1673                 val = event.dataB();
1674               }
1675               else if(etype == MusECore::ME_PITCHBEND)
1676               {
1677                 ctl = MusECore::CTRL_PITCH;
1678                 val = event.dataA();
1679               }
1680               else //if(etype == MusECore::ME_PROGRAM)
1681               {
1682                 ctl = MusECore::CTRL_PROGRAM;
1683                 val = event.dataA();
1684               }
1685 
1686               // Midi learn!
1687               MusEGlobal::midiLearnPort = port;
1688               MusEGlobal::midiLearnChan = chan;
1689               MusEGlobal::midiLearnCtrl = ctl;
1690 
1691               // Send to audio tracks...
1692               for (MusECore::iTrack t = MusEGlobal::song->tracks()->begin(); t != MusEGlobal::song->tracks()->end(); ++t)
1693               {
1694                 if((*t)->isMidiTrack())
1695                   continue;
1696                 MusECore::AudioTrack* track = static_cast<MusECore::AudioTrack*>(*t);
1697                 MidiAudioCtrlMap* macm = track->controller()->midiControls();
1698                 int h = macm->index_hash(port, chan, ctl);
1699                 std::pair<ciMidiAudioCtrlMap, ciMidiAudioCtrlMap> range = macm->equal_range(h);
1700                 for(ciMidiAudioCtrlMap imacm = range.first; imacm != range.second; ++imacm)
1701                 {
1702                   const MidiAudioCtrlStruct* macs = &imacm->second;
1703                   int actrl = macs->audioCtrlId();
1704 
1705                   iCtrlList icl = track->controller()->find(actrl);
1706                   if(icl == track->controller()->end())
1707                     continue;
1708                   CtrlList* cl = icl->second;
1709                   double dval = midi2AudioCtrlValue(cl, macs, ctl, val);
1710 
1711                   // Time here needs to be frames always.
1712                   unsigned int ev_t = event.time();
1713                   unsigned int t = ev_t;
1714 
1715                   unsigned int pframe = _pos.frame();
1716                   if(pframe > t)  // Technically that's an error, shouldn't happen
1717                     t = 0;
1718                   else
1719                     // Subtract the current audio position frame
1720                     t -= pframe;
1721 
1722                   // Add the current running sync frame to make the control processing happy
1723                   t += syncFrame;
1724                   track->addScheduledControlEvent(actrl, dval, t);
1725 
1726                   // Rec automation...
1727 
1728                   // For the record time, if stopped we don't want the circular running position,
1729                   //  just the static one.
1730                   unsigned int rec_t = playing ? ev_t : pframe;
1731 
1732                   if(!MusEGlobal::automation)
1733                     continue;
1734                   AutomationType at = track->automationType();
1735                   // Unlike our built-in gui controls, there is not much choice here but to
1736                   //  just do this:
1737                   if ( (at == AUTO_WRITE) ||
1738                        (at == AUTO_READ && !playing) ||
1739                        (at == AUTO_TOUCH) )
1740                     track->enableController(actrl, false);
1741                   if(playing)
1742                   {
1743                     if(at == AUTO_WRITE || at == AUTO_TOUCH)
1744                       track->recEvents()->push_back(CtrlRecVal(rec_t, actrl, dval));
1745                   }
1746                   else
1747                   {
1748                     if(at == AUTO_WRITE)
1749                       track->recEvents()->push_back(CtrlRecVal(rec_t, actrl, dval));
1750                     else if(at == AUTO_TOUCH)
1751                       // In touch mode and not playing. Send directly to controller list.
1752                       // Add will replace if found.
1753                       cl->add(rec_t, dval);
1754                   }
1755                 }
1756               }
1757             }
1758           }
1759         }
1760       }
1761 
1762       MidiTrackList* mtl = MusEGlobal::song->midis();
1763       for (iMidiTrack t = mtl->begin(); t != mtl->end(); ++t)
1764       {
1765             MidiTrack* track = *t;
1766             const int t_port = track->outPort();
1767             const int t_channel = track->outChannel();
1768             MidiPort* mp = nullptr;
1769             if(t_port >= 0 && t_port < MusECore::MIDI_PORTS)
1770               mp = &MusEGlobal::midiPorts[t_port];
1771             MidiDevice* md = nullptr;
1772             if(mp)
1773               md = mp->device();
1774 
1775             // only add track events if the track is unmuted and turned on
1776             if(!track->isMute() && !track->off())
1777             {
1778                 // don't render existing events in replace mode (except when punch is active - to be filtered later)
1779                 if (!(recording && track->recordFlag() && MusEGlobal::song->recMode() == MusEGlobal::song->REC_REPLACE
1780                       && !MusEGlobal::song->punchin() && !MusEGlobal::song->punchout()))
1781                 {
1782                     if(playing)
1783                     {
1784                         unsigned int lat_offset = 0;
1785                         unsigned int cur_tick = curTickPos;
1786                         unsigned int next_tick = nextTickPos;
1787 
1788                         //--------------------------------------------------------------------
1789                         // Account for the midi track's latency correction and/or compensation.
1790                         //--------------------------------------------------------------------
1791                         // TODO How to handle when external sync is on. For now, don't try to correct.
1792                         if(MusEGlobal::config.enableLatencyCorrection && !extsync)
1793                         {
1794                             const TrackLatencyInfo& li = track->getLatencyInfo(false);
1795                             // This value is negative for correction.
1796                             const float mlat = li._sourceCorrectionValue;
1797                             if((int)mlat < 0)
1798                             {
1799                                 // Convert to a positive offset.
1800                                 const unsigned int l = (unsigned int)(-mlat);
1801                                 if(l > lat_offset)
1802                                     lat_offset = l;
1803                             }
1804                             if(lat_offset != 0)
1805                             {
1806                                 Pos ppp(_pos.frame() + lat_offset, false);
1807                                 cur_tick = ppp.tick();
1808                                 ppp += frames;
1809                                 next_tick = ppp.tick();
1810                             }
1811                         }
1812 
1813                         collectEvents(track, cur_tick, next_tick, frames, lat_offset);
1814                     }
1815                 }
1816             }
1817 
1818             //
1819             //----------midi recording
1820             //
1821             const bool track_rec_flag = track->recordFlag();
1822 // REMOVE Tim. monitor. Changed.
1823 //            const bool track_rec_monitor = track->recMonitor(); // Separate monitor and record functions.
1824             const bool track_rec_monitor = track->isRecMonitored(); // Separate monitor and record functions.
1825 
1826             if(track_rec_monitor || track_rec_flag)
1827             {
1828                   MPEventList& rl = track->mpevents;
1829                   RouteList* irl = track->inRoutes();
1830                   for(ciRoute r = irl->begin(); r != irl->end(); ++r)
1831                   {
1832                         if(!r->isValid() || (r->type != Route::MIDI_PORT_ROUTE))
1833                           continue;
1834                         int devport = r->midiPort;
1835                         if (devport == -1)
1836                           continue;
1837                         MidiDevice* dev = MusEGlobal::midiPorts[devport].device();
1838                         if(!dev)
1839                           continue;
1840 
1841 #ifdef _USE_MIDI_ROUTE_PER_CHANNEL_
1842 
1843                         const int r_chan = r->channel;
1844 #else
1845                         const int channelMask = r->channel;
1846                         if(channelMask == -1 || channelMask == 0)
1847                           continue;
1848 #endif // _USE_MIDI_ROUTE_PER_CHANNEL_
1849 
1850                         for(int channel = 0; channel < MusECore::MUSE_MIDI_CHANNELS; ++channel)
1851                         {
1852 
1853 #ifdef _USE_MIDI_ROUTE_PER_CHANNEL_
1854                           if(r_chan != -1 && channel != r_chan)
1855                             continue;
1856 #else // _USE_MIDI_ROUTE_PER_CHANNEL_
1857                           if(!(channelMask & (1 << channel)))
1858                             continue;
1859 #endif // _USE_MIDI_ROUTE_PER_CHANNEL_
1860 
1861                           if(!dev->sysexFIFOProcessed())
1862                           {
1863                             // Set to the sysex fifo at first.
1864                             MidiRecFifo& rf = dev->recordEvents(MusECore::MUSE_MIDI_CHANNELS);
1865                             // Get the frozen snapshot of the size.
1866                             int count = dev->tmpRecordCount(MusECore::MUSE_MIDI_CHANNELS);
1867 
1868                             for(int i = 0; i < count; ++i)
1869                             {
1870                               MidiRecordEvent event(rf.peek(i));
1871                               event.setPort(t_port);
1872                               event.setChannel(t_channel);
1873                               // don't echo controller changes back to software
1874                               // synthesizer:
1875                               if(md && track_rec_monitor)
1876                               {
1877                                 // Do not echo synth events back to the same synth instance under any circumstances,
1878                                 //  not even if monitor (echo) is on.
1879                                 if(!dev->isSynti() || dev != md)
1880                                 {
1881                                   // All recorded events arrived in the previous period. Shift into this period for playback.
1882                                   unsigned int et = event.time();
1883                                   // The events arrived in the previous period. Shift into this period for playback.
1884                                   // The events are already biased with the last frame time.
1885                                   unsigned int t = et + MusEGlobal::segmentSize;
1886                                   // Protection from slight errors in estimated frame time.
1887                                   if(t >= (syncFrame + MusEGlobal::segmentSize))
1888                                   {
1889                                     DEBUG_MIDI(stderr, "Error: Audio::processMidi(): sysex: t:%u >= syncFrame:%u + segmentSize:%u (==%u)\n",
1890                                             t, syncFrame, MusEGlobal::segmentSize, syncFrame + MusEGlobal::segmentSize);
1891 
1892                                     t = syncFrame + (MusEGlobal::segmentSize - 1);
1893                                   }
1894                                   event.setTime(t);
1895                                   md->putEvent(event, MidiDevice::NotLate);
1896                                   event.setTime(et);  // Restore for recording.
1897                                 }
1898                               }
1899 
1900                               unsigned int et = event.time();
1901                               // Make sure the event is recorded in units of ticks.
1902                               if(extsync)
1903                               {
1904                                 const unsigned int xt = extClockHistoryFrame2Tick(event.time());
1905                                 DEBUG_MIDI(stderr, "processMidi: event time:%d dataA:%d dataB:%d curTickPos:%u set time:%u\n",
1906                                                 event.time(), event.dataA(), event.dataB(), curTickPos, xt);
1907 
1908                                 event.setTime(xt);
1909                               }
1910                               else
1911                               {
1912                                 // All recorded events arrived in the previous period. Shift into this period for record.
1913                                 unsigned int t = et + MusEGlobal::segmentSize;
1914                                 // Protection from slight errors in estimated frame time.
1915                                 if(t >= (syncFrame + MusEGlobal::segmentSize))
1916                                 {
1917                                   DEBUG_MIDI(stderr, "Error: Audio::processMidi(): record sysex: t:%u >= syncFrame:%u + segmentSize:%u (==%u)\n",
1918                                           t, syncFrame, MusEGlobal::segmentSize, syncFrame + MusEGlobal::segmentSize);
1919 
1920                                   t = syncFrame + (MusEGlobal::segmentSize - 1);
1921                                 }
1922                                 // Be sure to allow for some (very) late events, such as
1923                                 //  the first chunk's time in a multi-chunk sysex.
1924                                 const unsigned int a_fr = pos().frame() + t;
1925                                 const unsigned int fin_fr = syncFrame > a_fr ? 0 : a_fr - syncFrame;
1926                                 event.setTime(MusEGlobal::tempomap.frame2tick(fin_fr));
1927                               }
1928 
1929                               // Is the transport recording, or, is it about to be from external sync?
1930                               if((recording ||
1931                                  (MusEGlobal::song->record() && extsync && MusEGlobal::midiSyncContainer.isPlaying()))
1932                                  && track_rec_flag)
1933                                 rl.add(event);
1934 
1935                               event.setTime(et);  // Restore.
1936                             }
1937                             dev->setSysexFIFOProcessed(true);
1938                           }
1939 
1940                           MidiRecFifo& rf = dev->recordEvents(channel);
1941                           int count = dev->tmpRecordCount(channel);
1942                           for(int i = 0; i < count; ++i)
1943                           {
1944                                 MidiRecordEvent event(rf.peek(i));
1945                                 int defaultPort = devport;
1946                                 int drumRecPitch=0; //prevent compiler warning: variable used without initialization
1947                                 MidiController *mc = nullptr;
1948                                 int ctl = 0;
1949                                 int prePitch = 0, preVelo = 0;
1950 
1951                                 event.setPort(t_port);
1952                                 event.setChannel(t_channel);
1953 
1954                                 if (event.isNote() || event.isNoteOff())
1955                                 {
1956                                       //
1957                                       // apply track values
1958                                       //
1959 
1960                                       //Apply drum inkey:
1961                                       if (track->isDrumTrack())
1962                                       {
1963                                         int pitch = event.dataA();
1964                                         int dmindex = track->map_drum_in(pitch);
1965                                         //Map note that is played according to MusEGlobal::drumInmap
1966                                         drumRecPitch = track->drummap()[dmindex].enote;
1967                                         // Default to track port if -1 and track channel if -1.
1968                                         devport = track->drummap()[dmindex].port;
1969                                         if(devport == -1)
1970                                           devport = track->outPort();
1971                                         event.setPort(devport);
1972                                         int mapchan = track->drummap()[dmindex].channel;
1973                                         if(mapchan != -1)
1974                                           event.setChannel(mapchan);
1975                                         event.setA(track->drummap()[dmindex].anote);
1976 
1977                                         if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_HIDDEN &&
1978                                             track->drummap()[dmindex].hide )
1979                                           continue; // skip that event, proceed with the next
1980 
1981                                         if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_MUTED &&
1982                                             track->drummap()[dmindex].mute )
1983                                           continue; // skip that event, proceed with the next
1984                                       }
1985                                       else
1986                                       { //Track transpose if non-drum
1987                                             prePitch = event.dataA();
1988                                             int pitch = prePitch + track->transposition;
1989                                             if (pitch > 127)
1990                                                   pitch = 127;
1991                                             if (pitch < 0)
1992                                                   pitch = 0;
1993                                             event.setA(pitch);
1994                                       }
1995 
1996                                       // Apply track velocity and compression to note-on AND note-off events.
1997                                       preVelo = event.dataB();
1998                                       int velo = preVelo + track->velocity;
1999                                       velo = (velo * track->compression) / 100;
2000                                       if (velo > 127)
2001                                             velo = 127;
2002                                       if (velo < 1)
2003                                             // Zero means zero. Should mean no note at all?
2004                                             //velo = 1;
2005                                             velo = 0; // Use zero as a marker to tell the playback (below) not to sound the note.
2006 
2007                                       event.setB(velo);
2008                                 }
2009                                 else if(event.type() == MusECore::ME_CONTROLLER)
2010                                 {
2011                                   if (track->isDrumTrack()) //FINDMICHJETZT TEST
2012                                   {
2013                                     ctl = event.dataA();
2014                                     // Regardless of what port the event came from, is it a drum controller event
2015                                     //  according to the track port's instrument?
2016                                     if(mp)
2017                                       mc = mp->drumController(ctl);
2018                                     if(mc)
2019                                     {
2020                                       int pitch = ctl & 0x7f; // pitch is now the incoming pitch
2021                                       ctl &= ~0xff;
2022                                       int dmindex = track->map_drum_in(pitch) & 0x7f;
2023                                       //Map note that is played according to drumInmap
2024                                       drumRecPitch = track->drummap()[dmindex].enote;
2025                                       // Default to track port if -1 and track channel if -1.
2026                                       devport = track->drummap()[dmindex].port;
2027                                       if(devport == -1)
2028                                         devport = track->outPort();
2029                                       event.setPort(devport);
2030                                       int mapchan = track->drummap()[dmindex].channel;
2031                                       if(mapchan != -1)
2032                                         event.setChannel(mapchan);
2033                                       event.setA(ctl | track->drummap()[dmindex].anote);
2034 
2035                                       if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_HIDDEN &&
2036                                           track->drummap()[dmindex].hide )
2037                                         continue; // skip that event, proceed with the next
2038 
2039                                       if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_MUTED &&
2040                                           track->drummap()[dmindex].mute )
2041                                         continue; // skip that event, proceed with the next
2042                                     }
2043                                   }
2044                                 }
2045 
2046                                 // MusE uses a fixed clocks per quarternote of 24.
2047                                 // At standard 384 ticks per quarternote for example,
2048                                 // 384/24=16 for a division of 16 sub-frames (16 MusE 'ticks').
2049                                 // If ext sync, events are now time-stamped with last tick in MidiDevice::recordEvent(). p3.3.35
2050                                 // TODO: Tested, but record resolution not so good. Switch to wall clock based separate list in MidiDevice.
2051 
2052                                 // don't echo controller changes back to software
2053                                 // synthesizer:
2054 
2055                                 // Zero means zero. Should mean no note at all?
2056                                 // If the event is marked as a note with zero velocity (above), do not sound the note.
2057                                 if(!event.isNote() || event.dataB() != 0)
2058                                 {
2059 
2060                                   // All recorded events arrived in previous period. Shift into this period for playback.
2061                                   //  frameoffset needed to make process happy.
2062                                   unsigned int et = event.time();
2063                                   // The events arrived in the previous period. Shift into this period for playback.
2064                                   // The events are already biased with the last frame time.
2065                                   unsigned int t = et + MusEGlobal::segmentSize;
2066                                   // Protection from slight errors in estimated frame time.
2067                                   if(t >= (syncFrame + MusEGlobal::segmentSize))
2068                                   {
2069                                     DEBUG_MIDI(stderr, "Error: Audio::processMidi(): event: t:%u >= syncFrame:%u + segmentSize:%u (==%u)\n",
2070                                             t, syncFrame, MusEGlobal::segmentSize, syncFrame + MusEGlobal::segmentSize);
2071 
2072                                     t = syncFrame + (MusEGlobal::segmentSize - 1);
2073                                   }
2074                                   event.setTime(t);
2075                                   // Check if we're outputting to another port than default:
2076                                   if (devport == defaultPort) {
2077                                         event.setPort(t_port);
2078                                         // REMOVE Tim. monitor. Changed.
2079                                         //if(md && track_rec_monitor && !track->off() && !track->isMute())
2080                                         if(md && track_rec_monitor)
2081                                         {
2082                                           // Do not echo synth events back to the same synth instance under any circumstances,
2083                                           //  not even if monitor (echo) is on.
2084                                           if(!dev->isSynti() || dev != md)
2085                                           {
2086                                             MidiInstrument* minstr = MusEGlobal::midiPorts[t_port].instrument();
2087                                             const MidiInstrument::NoteOffMode nom = minstr->noteOffMode();
2088                                             // If the instrument has no note-off mode, do not use the stuck notes mechanism, send as is.
2089                                             // This allows drum input triggers (no note offs at all), although it is awkward to
2090                                             //  first have to choose an output instrument with no note-off mode.
2091                                             if(nom == MidiInstrument::NoteOffNone)
2092                                             {
2093                                               if(event.isNoteOff())
2094                                                 // Try to remove any corresponding stuck live note.
2095                                                 track->removeStuckLiveNote(t_port, event.channel(), event.dataA());
2096 //                                               md->addScheduledEvent(event);
2097                                               md->putEvent(event, MidiDevice::NotLate);
2098                                             }
2099                                             else if(event.isNoteOff())
2100                                             {
2101                                               // Try to remove any corresponding stuck live note.
2102                                               // Only if a stuck live note existed do we schedule the note off to play.
2103                                               if(track->removeStuckLiveNote(t_port, event.channel(), event.dataA()))
2104 //                                                 md->addScheduledEvent(event);
2105                                                 md->putEvent(event, MidiDevice::NotLate);
2106                                             }
2107                                             else if(event.isNote())
2108                                             {
2109                                               // Check if a stuck live note exists on any track.
2110                                               ciMidiTrack it_other = mtl->begin();
2111                                               for( ; it_other != mtl->end(); ++it_other)
2112                                               {
2113                                                 if((*it_other)->stuckLiveNoteExists(t_port, event.channel(), event.dataA()))
2114                                                   break;
2115                                               }
2116                                               // Only if NO stuck live note existed do we schedule the note on to play.
2117                                               if(it_other == mtl->end())
2118                                               {
2119                                                 if(track->addStuckLiveNote(t_port, event.channel(), event.dataA()))
2120 //                                                   md->addScheduledEvent(event);
2121                                                   md->putEvent(event, MidiDevice::NotLate);
2122                                               }
2123                                             }
2124                                             else
2125                                             {
2126                                               // TODO Maybe grab the flag from the 'Optimize Controllers' Global Setting,
2127                                               //       which so far was meant for (N)RPN stuff. For now, just force it.
2128                                               // This is the audio thread. Just set directly.
2129                                               MusEGlobal::midiPorts[t_port].setHwCtrlState(event);
2130                                               md->putEvent(event, MidiDevice::NotLate);
2131                                             }
2132                                           }
2133                                         }
2134                                       }
2135                                   else {
2136                                         MidiDevice* mdAlt = MusEGlobal::midiPorts[devport].device();
2137                                         // REMOVE Tim. monitor. Changed.
2138                                         //if(mdAlt && track_rec_monitor && !track->off() && !track->isMute())
2139                                         if(mdAlt && track_rec_monitor)
2140                                         {
2141                                           // Do not echo synth events back to the same synth instance under any circumstances,
2142                                           //  not even if monitor (echo) is on.
2143                                           if(!dev->isSynti() || dev != mdAlt)
2144                                           {
2145                                             MidiInstrument* minstr = MusEGlobal::midiPorts[devport].instrument();
2146                                             MidiInstrument::NoteOffMode nom = minstr->noteOffMode();
2147                                             // If the instrument has no note-off mode, do not use the
2148                                             //  stuck notes mechanism, just send as is.
2149                                             // If the instrument has no note-off mode, do not use the stuck notes mechanism, send as is.
2150                                             // This allows drum input triggers (no note offs at all), although it is awkward to
2151                                             //  first have to choose an output instrument with no note-off mode.
2152                                             if(nom == MidiInstrument::NoteOffNone)
2153                                             {
2154                                               if(event.isNoteOff())
2155                                                 // Try to remove any corresponding stuck live note.
2156                                                 track->removeStuckLiveNote(event.port(), event.channel(), event.dataA());
2157 //                                               mdAlt->addScheduledEvent(event);
2158                                               mdAlt->putEvent(event, MidiDevice::NotLate);
2159                                             }
2160                                             else if(event.isNoteOff())
2161                                             {
2162                                               // Try to remove any corresponding stuck live note.
2163                                               // Only if a stuck live note existed do we schedule the note off to play.
2164                                               if(track->removeStuckLiveNote(event.port(), event.channel(), event.dataA()))
2165 //                                                 mdAlt->addScheduledEvent(event);
2166                                                 mdAlt->putEvent(event, MidiDevice::NotLate);
2167                                             }
2168                                             else if(event.isNote())
2169                                             {
2170                                               // Check if a stuck live note exists on any track.
2171                                               ciMidiTrack it_other = mtl->begin();
2172                                               for( ; it_other != mtl->end(); ++it_other)
2173                                               {
2174                                                 if((*it_other)->stuckLiveNoteExists(event.port(), event.channel(), event.dataA()))
2175                                                   break;
2176                                               }
2177                                               // Only if NO stuck live note existed do we schedule the note on to play.
2178                                               if(it_other == mtl->end())
2179                                               {
2180                                                 if(track->addStuckLiveNote(event.port(), event.channel(), event.dataA()))
2181                                                   mdAlt->putEvent(event, MidiDevice::NotLate);
2182                                               }
2183                                             }
2184                                             else
2185                                             {
2186                                               // TODO Maybe grab the flag from the 'Optimize Controllers' Global Setting,
2187                                               //       which so far was meant for (N)RPN stuff. For now, just force it.
2188                                               // This is the audio thread. Just set directly.
2189                                               MusEGlobal::midiPorts[devport].setHwCtrlState(event);
2190                                               mdAlt->putEvent(event, MidiDevice::NotLate);
2191                                             }
2192                                           }
2193                                         }
2194                                       }
2195                                   event.setTime(et);  // Restore for recording.
2196 
2197                                 // Shall we activate meters even while rec echo is off? Sure, why not...
2198                                 if(event.isNote() && event.dataB() > track->activity())
2199                                   track->setActivity(event.dataB());
2200                               }
2201 
2202                               // Is the transport recording, or, is it about to be from external sync?
2203                               if((recording ||
2204                                  (MusEGlobal::song->record() && extsync && MusEGlobal::midiSyncContainer.isPlaying()))
2205                                  && track_rec_flag)
2206                               {
2207                                     unsigned int et = event.time();
2208                                     // Make sure the event is recorded in units of ticks.
2209                                     if(extsync)
2210                                     {
2211                                       const unsigned int xt = extClockHistoryFrame2Tick(event.time());
2212                                       DEBUG_MIDI(stderr, "processMidi: event time:%d dataA:%d dataB:%d curTickPos:%u set time:%u\n",
2213                                                       event.time(), event.dataA(), event.dataB(), curTickPos, xt);
2214 
2215                                       event.setTime(xt);
2216                                     }
2217                                     else
2218                                     {
2219                                       // REMOVE Tim. latency. Removed. Oops, with ALSA this adds undesired shift forward!
2220 //                                       // All recorded events arrived in the previous period. Shift into this period for record.
2221                                       // REMOVE Tim. latency. Changed. Oops, with ALSA this adds undesired shift forward!
2222                                       // And with Jack midi we currently already shift forward, in the input routine!
2223                                       // But I'm debating where to add the correction factor - I really need to add it here
2224                                       //  (exactly like the WaveTrack recording correction) but a very simple fix would be
2225                                       //  in the Jack midi input routine to replace the current fixed segSize correction
2226                                       //  factor with the MidiDevice::_latencyInfo._outputLatency,
2227                                       //  but that is wrong although it would work.
2228                                       // To add the correction here may be more complicated than the WaveTrack,
2229                                       //  some things in the ALSA and Jack midi input routines depend on the event time
2230                                       //  (like midi clock, other rt events).
2231                                       //
2232                                       //
2233 //                                       unsigned int t = et + MusEGlobal::segmentSize;
2234 //                                       // Protection from slight errors in estimated frame time.
2235 //                                       if(t >= (syncFrame + MusEGlobal::segmentSize))
2236 //                                       {
2237 //                                         DEBUG_MIDI(stderr, "Error: Audio::processMidi(): record event: t:%u >= syncFrame:%u + segmentSize:%u (==%u)\n",
2238 //                                                 t, syncFrame, MusEGlobal::segmentSize, syncFrame + MusEGlobal::segmentSize);
2239 //
2240 //                                         t = syncFrame + (MusEGlobal::segmentSize - 1);
2241 //                                       }
2242                                       unsigned int t = et;
2243                                       // Protection from slight errors in estimated frame time.
2244                                       if(t >= syncFrame)
2245                                       {
2246                                         DEBUG_MIDI(stderr, "Error: Audio::processMidi(): record event: t:%u >= syncFrame:%u\n",
2247                                                 t, syncFrame);
2248 
2249                                         t = syncFrame - 1;
2250                                       }
2251 
2252                                       // Be sure to allow for some (very) late events, such as
2253                                       //  the first chunk's time in a multi-chunk sysex.
2254                                       const unsigned int a_fr = pos().frame() + t;
2255                                       const unsigned int fin_fr = syncFrame > a_fr ? 0 : a_fr - syncFrame;
2256                                       event.setTime(MusEGlobal::tempomap.frame2tick(fin_fr));
2257                                     }
2258 
2259                                     // In these next steps, it is essential to set the recorded event's port
2260                                     //  to the track port so buildMidiEventList will accept it. Even though
2261                                     //  the port may have no device "<none>".
2262                                     //
2263                                     if (track->isDrumTrack())
2264                                     {
2265                                       // Is it a drum controller event?
2266                                       if(mc)
2267                                       {
2268                                           MusECore::MidiPlayEvent drumRecEvent = event;
2269                                           drumRecEvent.setA(ctl | drumRecPitch);
2270                                           // In this case, preVelo is simply the controller value.
2271                                           drumRecEvent.setB(preVelo);
2272                                           drumRecEvent.setPort(t_port); //rec-event to current port
2273                                           drumRecEvent.setChannel(t_channel); //rec-event to current channel
2274                                           track->mpevents.add(drumRecEvent);
2275                                       }
2276                                       else
2277                                       {
2278                                           MusECore::MidiPlayEvent drumRecEvent = event;
2279                                           drumRecEvent.setA(drumRecPitch);
2280                                           drumRecEvent.setB(preVelo);
2281                                           // Changed to 'port'. Events were not being recorded for a drum map entry pointing to a
2282                                           //  different port. That must have been wrong - buildMidiEventList would ignore that. Tim.
2283                                           drumRecEvent.setPort(t_port);  //rec-event to current port
2284                                           drumRecEvent.setChannel(t_channel); //rec-event to current channel
2285                                           track->mpevents.add(drumRecEvent);
2286                                       }
2287                                     }
2288                                     else
2289                                     {
2290                                           // Restore record-pitch to non-transposed value since we don't want the note transposed twice next
2291                                           MusECore::MidiPlayEvent recEvent = event;
2292                                           if (prePitch)
2293                                                 recEvent.setA(prePitch);
2294                                           if (preVelo)
2295                                                 recEvent.setB(preVelo);
2296                                           recEvent.setPort(t_port);
2297                                           recEvent.setChannel(t_channel);
2298 
2299                                           track->mpevents.add(recEvent);
2300                                     }
2301                                     // Restore. Not required.
2302                                     //event.setTime(et);
2303                               }
2304                         }
2305                   }
2306             }
2307         }
2308 
2309         // Must be playing for valid nextTickPos, right? But wasn't checked in Audio::processMidi().
2310         // MusEGlobal::audio->isPlaying() might not be true during seek right now.
2311         //if(MusEGlobal::audio->isPlaying())
2312         //if(playing)
2313         //{
2314           ciMPEvent k;
2315           MidiDevice* mdev;
2316           int mport;
2317           // What is the current transport frame?
2318           const unsigned int pos_fr = _pos.frame();
2319           // What is the (theoretical) next transport frame?
2320           const unsigned int next_pos_fr = pos_fr + frames;
2321 
2322           // If muted or off we want to send all playback note-offs immediately.
2323           if(track->isMute() || track->off())
2324           {
2325             //---------------------------------------------------
2326             //    Send all track-related playback note-offs (NOT 'live' note-offs)
2327             //     which were not put directly to the device
2328             //---------------------------------------------------
2329             MPEventList& mel = track->stuckNotes;
2330             if(!mel.empty())
2331             {
2332               for(k = mel.begin(); k != mel.end(); ++k)
2333               {
2334                 MidiPlayEvent ev(*k);
2335                 mport = ev.port();
2336                 if(mport < 0)
2337                   continue;
2338                 mdev = MusEGlobal::midiPorts[mport].device();
2339                 if(!mdev)
2340                   continue;
2341                 ev.setTime(0);   // Mark for immediate delivery.
2342                 //ev.setTime(MusEGlobal::audio->midiQueueTimeStamp(k->time()));
2343                 mdev->putEvent(ev, MidiDevice::NotLate);
2344               }
2345               mel.clear();
2346             }
2347           }
2348           else
2349           // If not muted and not off, we want to schedule all playback note-offs normally.
2350           {
2351             //---------------------------------------------------
2352             //    Schedule all track-related playback note-offs (NOT 'live' note-offs)
2353             //     which were not put directly to the device
2354             //    To save time this was put here instead of MidiDevice::processStuckNotes()
2355             //---------------------------------------------------
2356             MPEventList& mel = track->stuckNotes;
2357             if(!mel.empty())
2358             {
2359               for(k = mel.begin(); k != mel.end(); ++k)
2360               {
2361                 MidiPlayEvent ev(*k);
2362                 unsigned int off_tick = ev.time();
2363                 // If external sync is not on, we can take advantage of frame accuracy but
2364                 //  first we must allow the next tick position to be included in the search
2365                 //  even if it is equal to the current tick position.
2366                 if(extsync ? (off_tick >= nextTickPos) : (off_tick > nextTickPos))
2367                       break;
2368                 mport = ev.port();
2369                 if(mport < 0)
2370                   continue;
2371                 mdev = MusEGlobal::midiPorts[mport].device();
2372                 if(!mdev)
2373                   continue;
2374 
2375                 unsigned int off_frame = 0;
2376                 if(extsync)
2377                 {
2378                   if(off_tick < curTickPos)
2379                     off_tick = curTickPos;
2380                   off_frame = extClockHistoryTick2Frame(off_tick - curTickPos) + MusEGlobal::segmentSize;
2381                 }
2382                 else
2383                 {
2384                   // What is the exact transport frame that the event should be played at?
2385                   const unsigned int fr = MusEGlobal::tempomap.tick2frame(off_tick);
2386                   // Is the event frame outside of the current transport frame range?
2387                   if(fr >= next_pos_fr)
2388                     break;
2389                   off_frame = (fr < pos_fr) ? 0 : fr - pos_fr;
2390                   off_frame += syncFrame;
2391                 }
2392                 ev.setTime(off_frame);
2393 
2394                 // TODO: DECIDE: Hm, we don't want the device to miss any note offs.
2395                 //               So I guess schedule this as a user event rather than a playback event.
2396                 mdev->putEvent(ev, MidiDevice::NotLate);
2397               }
2398               mel.erase(mel.begin(), k);
2399             }
2400           }
2401 
2402           // If no monitor or off, or not rec-armed (or muted), we want to cancel all 'live' (rec) stuck notes immediately.
2403           // REMOVE Tim. monitor. Changed.
2404           //if(!track_rec_monitor || track->off() || track->isMute())
2405           if(!track_rec_monitor)
2406           {
2407             //------------------------------------------------------------
2408             //    Send all track-related 'live' (rec) note-offs
2409             //     which were not put directly to the device
2410             //------------------------------------------------------------
2411             MPEventList& mel = track->stuckLiveNotes;
2412             if(!mel.empty())
2413             {
2414               for(k = mel.begin(); k != mel.end(); ++k)
2415               {
2416                 MidiPlayEvent ev(*k);
2417                 mport = ev.port();
2418                 if(mport < 0)
2419                   continue;
2420                 mdev = MusEGlobal::midiPorts[mport].device();
2421                 if(!mdev)
2422                   continue;
2423                 ev.setTime(0);   // Mark for immediate delivery.
2424                 //ev.setTime(MusEGlobal::audio->midiQueueTimeStamp(k->time()));
2425                 mdev->putEvent(ev, MidiDevice::NotLate);
2426               }
2427               mel.clear();
2428             }
2429           }
2430         //}
2431       }
2432 
2433       //---------------------------------------------------
2434       //    insert metronome clicks
2435       //---------------------------------------------------
2436 
2437       // If in PRECOUNT state, process the precount events.
2438       processPrecount(frames);
2439 
2440       // Since the latency for audio and midi may be different,
2441       //  process the audio and midi metronomes separately.
2442       processAudioMetronome(frames);
2443       processMidiMetronome(frames);
2444 
2445       // REMOVE Tim. clock. Added.
2446 //       //---------------------------------------------------
2447 //       //    send midi clock output events
2448 //       //---------------------------------------------------
2449 //
2450 //       _clockOutputQueueSize = 0;
2451 //       if(!extsync)
2452 //       {
2453 //         const unsigned curr_audio_frame = syncFrame;
2454 //         const unsigned next_audio_frame = curr_audio_frame + frames;
2455 // //         const uint64_t numer = (uint64_t)MusEGlobal::config.division * (uint64_t)MusEGlobal::tempomap.globalTempo() * 10000UL;
2456 //         const uint64_t denom = (uint64_t)MusEGlobal::config.division * (uint64_t)MusEGlobal::tempomap.globalTempo() * 10000UL;
2457 //         const unsigned int div = MusEGlobal::config.division/24;
2458 //
2459 // //         // Do not round up here since (audio) frame resolution is higher than tick resolution.
2460 // //         const unsigned int clock_tick = muse_multiply_64_div_64_to_64(numer, curr_audio_frame,
2461 // //           (uint64_t)MusEGlobal::sampleRate * (uint64_t)MusEGlobal::tempomap.tempo(curTickPos));
2462 //
2463 // //         unsigned int clock_tick_end;
2464 //         // Is the transport moving?
2465 //         if(playing)
2466 //         {
2467 // //           unsigned int delta_tick;
2468 // //           // Did tick position wrap around?
2469 // //           if(curTickPos > nextTickPos)
2470 // //             delta_tick = curTickPos - nextTickPos;
2471 // //           else
2472 // //             delta_tick = nextTickPos - curTickPos;
2473 // //           clock_tick_end = clock_tick + delta_tick;
2474 //         }
2475 //         else
2476 //         {
2477 // //           // Do not round up here since (audio) frame resolution is higher than tick resolution.
2478 // //           clock_tick_end = muse_multiply_64_div_64_to_64(numer, next_audio_frame,
2479 // //             (uint64_t)MusEGlobal::sampleRate * (uint64_t)MusEGlobal::tempomap.tempo(curTickPos));
2480 //
2481 //           uint64_t div_remainder;
2482 //           const uint64_t div_frames = muse_multiply_64_div_64_to_64(
2483 //             (uint64_t)MusEGlobal::sampleRate * (uint64_t)MusEGlobal::tempomap.tempo(curTickPos), div,
2484 //             denom, LargeIntRoundNone, &div_remainder);
2485 //
2486 //           // Counter too far in future? Reset.
2487 //           if(_clockOutputCounter >= curr_audio_frame && _clockOutputCounter - curr_audio_frame >= div_frames)
2488 //           {
2489 //             _clockOutputCounter = curr_audio_frame;
2490 //             _clockOutputCounterRemainder = 0;
2491 //           }
2492 //           // Counter too far in past? Reset.
2493 //           else if(_clockOutputCounter < curr_audio_frame)
2494 //           {
2495 //             _clockOutputCounter = curr_audio_frame;
2496 //             _clockOutputCounterRemainder = 0;
2497 //           }
2498 //
2499 //           //const uint64_t curr_clock_out_count = _clockOutputCounter + div_frames + (_clockOutputCounterRemainder + div_remainder) / denom;
2500 //           //uint64_t next_clock_out_frame = _clockOutputCounter + div_frames + (_clockOutputCounterRemainder + div_remainder) / denom;
2501 //           uint64_t raccum;
2502 //           //while(next_clock_out_frame <= next_audio_frame)
2503 //           while(_clockOutputCounter < next_audio_frame)
2504 //           {
2505 //             if(_clockOutputQueueSize >= _clockOutputQueueCapacity)
2506 //               break;
2507 //
2508 //             //_clockOutputQueue[_clockOutputQueueSize] = _clockOutputCounter - curr_audio_frame;
2509 //             _clockOutputQueue[_clockOutputQueueSize] = _clockOutputCounter;
2510 //             ++_clockOutputQueueSize;
2511 //             raccum = _clockOutputCounterRemainder + div_remainder;
2512 //             _clockOutputCounter += div_frames + (raccum / denom);
2513 //             _clockOutputCounterRemainder = raccum % denom;
2514 //           }
2515 //           //const uint64_t next_clock_out_count = _clockOutputCounter + div_frames + (_clockOutputCounterRemainder + div_remainder) / denom;
2516 //
2517 //           //if(next_audio_frame >= next_clock_out_count)
2518 //           //{
2519 //
2520 //           //}
2521 //         }
2522 //
2523 // //         // Did clock_tick wrap around?
2524 // //         if(_clockOutputCounter > clock_tick)
2525 // //           _clockOutputCounter = clock_tick;
2526 // //
2527 // //         //const unsigned int div = MusEGlobal::config.division/24;
2528 // //         if(clock_tick_end >= _clockOutputCounter + div)
2529 // //         {
2530 // //           // This will always be at least 1.
2531 // //           const unsigned int num_clocks = (clock_tick_end - _clockOutputCounter) / div;
2532 // //           const unsigned int clk_frame_step = frames / num_clocks;
2533 // //           const unsigned int clk_frame_step_rem = frames % num_clocks;
2534 // //           unsigned int clk_frame_off;
2535 // //           for(unsigned int c = 0; c < num_clocks; ++c)
2536 // //           {
2537 // //             if(c >= _clockOutputQueueCapacity)
2538 // //               break;
2539 // //             clk_frame_off = c * clk_frame_step + (c * clk_frame_step_rem) / num_clocks;
2540 // //           }
2541 // //
2542 // //           _clockOutputCounter = clock_tick_end;
2543 // //         }
2544 // //
2545 // //
2546 // //         unsigned cc, f;
2547 // //         while(1)
2548 // //         {
2549 // //           cc = _clockOutputCounter + div;
2550 // //           f = Pos(cc, true).frame();
2551 // //           //if(f
2552 // //         }
2553 //       }
2554 
2555       //
2556       // Play all midi events up to curFrame.
2557       //
2558       for(iMidiDevice id = MusEGlobal::midiDevices.begin(); id != MusEGlobal::midiDevices.end(); ++id)
2559       {
2560         MidiDevice* pl_md = *id;
2561 //         const int pl_port = pl_md->midiPort();
2562 
2563         // We are done with the 'frozen' recording fifos, remove the events.
2564         pl_md->afterProcess();
2565 
2566         pl_md->processStuckNotes();
2567 
2568         // REMOVE Tim. clock. Added.
2569         // While we are at it, to avoid the overhead of yet another device loop,
2570         //  handle midi clock output here, for all device types.
2571 //         if(!extsync && pl_port >= 0 && pl_port < MIDI_PORTS)
2572 //         {
2573 //           MidiPort* clk_mp = &MusEGlobal::midiPorts[pl_port];
2574 //           // Clock out turned on?
2575 //           if(clk_mp->syncInfo().MCOut())
2576 //           {
2577 //             for(unsigned int i = 0; i < _clockOutputQueueSize; ++i)
2578 //             {
2579 //               const MidiPlayEvent clk_ev(_clockOutputQueue[i], pl_port, 0, MusECore::ME_CLOCK, 0, 0);
2580 //               pl_md->putEvent(clk_ev, MidiDevice::NotLate /*,MidiDevice::PlaybackBuffer*/);
2581 //             }
2582 //           }
2583 //         }
2584 
2585         // ALSA devices handled by another thread.
2586         const MidiDevice::MidiDeviceType typ = pl_md->deviceType();
2587         switch(typ)
2588         {
2589           case MidiDevice::ALSA_MIDI:
2590           break;
2591 
2592           case MidiDevice::JACK_MIDI:
2593           case MidiDevice::SYNTH_MIDI:
2594             // The frame is not used by these devices but we pass it along anyway.
2595             // Only ALSA devices need the frame.
2596             pl_md->processMidi(syncFrame);
2597           break;
2598         }
2599       }
2600 
2601       // Receive hardware state events sent from various threads to this audio thread.
2602       // Update hardware state so gui controls are updated.
2603       MusEGlobal::song->processIpcOutEventBuffers();
2604       }
2605 
2606 
2607 //---------------------------------------------------------
2608 //   processPrecount
2609 //---------------------------------------------------------
2610 
processPrecount(unsigned int frames)2611 void Audio::processPrecount(unsigned int frames)
2612 {
2613   //DEBUG_MIDI_METRONOME(stderr, "Audio::processPrecount: state:%d\n", state);
2614   if(state != PRECOUNT)
2615     return;
2616 
2617   MusECore::MetronomeSettings* metro_settings =
2618     MusEGlobal::metroUseSongSettings ? &MusEGlobal::metroSongSettings : &MusEGlobal::metroGlobalSettings;
2619 
2620   const unsigned int nextPrecountFramePos = _precountFramePos + frames;
2621 
2622   DEBUG_MIDI_METRONOME(stderr, "Audio::processPrecount: precount: syncFrame:%u _pos.frame():%u"
2623     "_precountFramePos:%u precountMidiClickFrame:%u nextPrecountFramePos:%u clickno:%d\n",
2624     syncFrame, _pos.frame(), _precountFramePos, precountMidiClickFrame, nextPrecountFramePos, clickno);
2625 
2626   MidiDevice* md = nullptr;
2627   if(metro_settings->midiClickFlag)
2628     md = MusEGlobal::midiPorts[metro_settings->clickPort].device();
2629 
2630   AudioTickSound audioTickSound = MusECore::beatSound;
2631 
2632   while(true)
2633   {
2634     const unsigned precount_click_frame = precountMidiClickFrame + (precountMidiClickFrameRemainder ? 1 :0);
2635     if(precount_click_frame >= nextPrecountFramePos)
2636       break;
2637     // Don't actually sound anything if we're just running out the time.
2638     // There will be times when _precountFramePos >= precountTotalFrames
2639     //  and we must let it run out.
2640     if(_precountFramePos < precountTotalFrames)
2641     {
2642       if(MusEGlobal::song->click())
2643       {
2644         if ((clickno % clicksMeasure) == 0)
2645           audioTickSound = MusECore::measureSound;
2646         else
2647           audioTickSound = MusECore::beatSound;
2648 
2649         // We need to shift ahead in time because Jack waits one more cycle,
2650         //   unlike our own built-in transport which starts immediately.
2651         const unsigned int evtime = syncFrame + MusEGlobal::audioDevice->transportSyncToPlayDelay() +
2652           ((precount_click_frame < _precountFramePos) ? 0 : precount_click_frame - _precountFramePos);
2653 
2654         MusECore::MidiPlayEvent ev(evtime, metro_settings->clickPort, metro_settings->clickChan,
2655           MusECore::ME_NOTEON, metro_settings->beatClickNote, metro_settings->beatClickVelo);
2656 
2657         if (audioTickSound == MusECore::measureSound) {
2658           ev.setA(metro_settings->measureClickNote);
2659           ev.setB(metro_settings->measureClickVelo);
2660         }
2661         if (md) {
2662           MusECore::MidiPlayEvent evmidi = ev;
2663 
2664 #ifdef DEBUG_MIDI_TIMING_DIFFS
2665           fprintf(stderr, "EVENT TIME DIFF:%u\n", ev.time() - _lastEvTime);
2666                     _lastEvTime = ev.time();
2667 #endif
2668 
2669           md->putEvent(evmidi, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
2670           // Internal midi paths are now all note off aware. Driver handles note offs. Convert.
2671           // Ticksynth has been modified too.
2672           evmidi.setType(MusECore::ME_NOTEOFF);
2673           evmidi.setB(0);
2674           evmidi.setTime(ev.time() + MusEGlobal::tempomap.ticks2frames(10, curTickPos));
2675 
2676           // The precount CANNOT use the stuck notes mechanism because the stuck notes
2677           //  mechanism wants ticks not frames, and it later compares those ticks
2678           //  with nextTickPos and converts them into frames using midiQueueTimeStamp(),
2679           //  which is not a valid mechanism during precount!
2680           // Therefore we have no choice but to directly schedule a note-off.
2681           // Since it is important that they not be missed, schedule these as userBuffer events.
2682           // Should be OK, it's unlikely that the note-off would be missed unless the user could
2683           //  somehow seek during precount or something. (The userBuffer tries not to miss anything.)
2684           // The idea behind the stuck notes mechanism was that it converts to frames
2685           //  only at scheduling time so that if the user might change the tempo while
2686           //  playing a song, the note-off times will be properly adjusted.
2687           // But this precount mechanism CANNOT honour any tempo changes anyway because
2688           //  we must know the total required precount frames BEFOREHAND so that it can be aligned
2689           //  with the metronome clicks properly. Thus negating any possible tempo change support.
2690           //md->addStuckNote(evmidi);
2691           md->putEvent(evmidi, MidiDevice::NotLate, MidiDevice::UserBuffer);
2692         }
2693         if (metro_settings->audioClickFlag) {
2694           ev.setA(audioTickSound);
2695           DEBUG_MIDI_METRONOME(stderr, "Audio::processMidi: precount: metronome->putEvent\n");
2696           metronome->putEvent(ev, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
2697           // Built-in metronome synth does not use stuck notes...
2698         }
2699       }
2700     }
2701 
2702     precountMidiClickFrame += framesBeat;
2703 
2704     precountMidiClickFrameRemainder += framesBeatRemainder;
2705     if(precountMidiClickFrameRemainder >= framesBeatDivisor)
2706     {
2707       precountMidiClickFrame++;
2708       precountMidiClickFrameRemainder -= framesBeatDivisor;
2709     }
2710 
2711     ++clickno;
2712   }
2713 
2714   _precountFramePos += frames;
2715 }
2716 
2717 //---------------------------------------------------------
2718 //   processAudioMetronome
2719 //---------------------------------------------------------
2720 
processMidiMetronome(unsigned int frames)2721 void Audio::processMidiMetronome(unsigned int frames)
2722 {
2723       const MusECore::MetronomeSettings* metro_settings =
2724       MusEGlobal::metroUseSongSettings ? &MusEGlobal::metroSongSettings : &MusEGlobal::metroGlobalSettings;
2725 
2726       const bool extsync = MusEGlobal::extSyncFlag;
2727       const bool playing = isPlaying();
2728 
2729       // Should the metronome be muted after precount?
2730       const bool precount_mute_metronome = metro_settings->precountEnableFlag
2731         && MusEGlobal::song->click()
2732         && !extsync
2733         && ((!MusEGlobal::song->record() && metro_settings->precountOnPlay) || MusEGlobal::song->record())
2734         && metro_settings->precountMuteMetronome;
2735 
2736       MidiDevice* md = 0;
2737       if (metro_settings->midiClickFlag && !precount_mute_metronome)
2738             md = MusEGlobal::midiPorts[metro_settings->clickPort].device();
2739 
2740       if (playing)
2741       {
2742             int bar, beat, z, n;
2743             unsigned tick;
2744             AudioTickSound audioTickSound = MusECore::beatSound;
2745             const MusECore::MetroAccents* accents;
2746             int accents_sz;
2747 
2748             unsigned int lat_offset_midi = 0;
2749             unsigned int cur_tick_midi = curTickPos;
2750             unsigned int next_tick_midi = nextTickPos;
2751 
2752             //--------------------------------------------------------------------
2753             // Account for the metronome's latency correction and/or compensation.
2754             //--------------------------------------------------------------------
2755             // TODO How to handle when external sync is on. For now, don't try to correct.
2756             if(MusEGlobal::config.enableLatencyCorrection && !extsync)
2757             {
2758               if(metro_settings->midiClickFlag)
2759               {
2760                 const TrackLatencyInfo& li = metronome->getLatencyInfoMidi(false /*playback*/, false);
2761                 // This value is negative for correction.
2762                 const float mlat = li._sourceCorrectionValue;
2763                 if((int)mlat < 0)
2764                 {
2765                   // Convert to a positive offset.
2766                   const unsigned int l = (unsigned int)(-mlat);
2767                   if(l > lat_offset_midi)
2768                     lat_offset_midi = l;
2769                 }
2770                 if(lat_offset_midi != 0)
2771                 {
2772                   Pos ppp(_pos.frame() + lat_offset_midi, false);
2773                   cur_tick_midi = ppp.tick();
2774                   ppp += frames;
2775                   next_tick_midi = ppp.tick();
2776                 }
2777               }
2778             }
2779 
2780             // What is the current transport frame, adjusted?
2781             const unsigned int pos_fr_midi = _pos.frame() + lat_offset_midi;
2782             // What is the (theoretical) next transport frame?
2783             const unsigned int next_pos_fr_midi = pos_fr_midi + frames;
2784 
2785             // If external sync is not on, we can take advantage of frame accuracy but
2786             //  first we must allow the next tick position to be included in the search
2787             //  even if it is equal to the current tick position.
2788             while (extsync ? (midiClick < next_tick_midi) : (midiClick <= next_tick_midi))
2789             {
2790               bool do_play = true;
2791               unsigned int evtime = 0;
2792               if(extsync)
2793               {
2794                 if(midiClick < cur_tick_midi)
2795                   midiClick = cur_tick_midi;
2796                 evtime = extClockHistoryTick2Frame(midiClick - cur_tick_midi) + MusEGlobal::segmentSize;
2797               }
2798               else
2799               {
2800                 // What is the exact transport frame that the midiClick should be played at?
2801                 const unsigned int fr = MusEGlobal::tempomap.tick2frame(midiClick);
2802                 // Is the midiClick frame outside of the current transport frame range?
2803                 if(fr < pos_fr_midi || fr >= next_pos_fr_midi)
2804                 {
2805                   // Break out of the loop if midiClick equals nextTickPos.
2806                   if(midiClick == next_tick_midi)
2807                     break;
2808                   // Continue on, but do not play any notes.
2809                   do_play = false;
2810                 }
2811                 evtime = fr - pos_fr_midi;
2812                 evtime += syncFrame;
2813               }
2814 
2815               DEBUG_MIDI_METRONOME(stderr,
2816                 "Audio::processMidiMetronome: playing: syncFrame:%u _pos.frame():%u midiClick:%u next_tick_midi:%u clickno:%d\n",
2817                 syncFrame, _pos.frame(), midiClick, next_tick_midi, clickno);
2818 
2819               MusEGlobal::sigmap.tickValues(midiClick, &bar, &beat, &tick);
2820               MusEGlobal::sigmap.timesig(midiClick, z, n);
2821               // How many ticks per beat?
2822               const int ticks_beat = MusEGlobal::sigmap.ticks_beat(n);
2823 
2824               if (do_play && MusEGlobal::song->click()
2825                   && (metro_settings->midiClickFlag)
2826                   && !precount_mute_metronome) {
2827 
2828                   if (tick == 0 && beat == 0) {
2829                       audioTickSound = MusECore::measureSound;
2830                       if (MusEGlobal::debugMsg)
2831                           fprintf(stderr, "meas: midiClick %d nextPos %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
2832                                   midiClick, next_tick_midi, bar, beat, tick, z, n, ticks_beat);
2833                   }
2834                   else if (tick == unsigned(ticks_beat - (ticks_beat/(n*2)))) {
2835                       audioTickSound = MusECore::accent2Sound;
2836                       if (MusEGlobal::debugMsg)
2837                           fprintf(stderr, "acc2: midiClick %d nextPos %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
2838                                   midiClick, next_tick_midi, bar, beat, tick, z, n, ticks_beat);
2839                   }
2840                   else if (tick == unsigned(ticks_beat - (ticks_beat/n))) {
2841                       audioTickSound = MusECore::accent1Sound;
2842                       if (MusEGlobal::debugMsg)
2843                           fprintf(stderr, "acc1: midiClick %d nextPos %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
2844                                   midiClick, next_tick_midi, bar, beat, tick, z, n, ticks_beat);
2845                   } else {
2846                       if (MusEGlobal::debugMsg)
2847                           fprintf(stderr, "beat: midiClick %d nextPos %d bar %d beat %d tick %d z %d n %d div %d\n",
2848                                   midiClick, next_tick_midi, bar, beat, tick, z, n, ticks_beat);
2849                   }
2850 
2851                   MusECore::MidiPlayEvent ev(evtime, metro_settings->clickPort, metro_settings->clickChan,
2852                     MusECore::ME_NOTEON, metro_settings->beatClickNote, metro_settings->beatClickVelo);
2853                   if (audioTickSound == MusECore::measureSound) {
2854                     ev.setA(metro_settings->measureClickNote);
2855                     ev.setB(metro_settings->measureClickVelo);
2856                   }
2857                   if (audioTickSound == MusECore::accent1Sound) {
2858                     ev.setA(metro_settings->accentClick1);
2859                     ev.setB(metro_settings->accentClick1Velo);
2860                   }
2861                   if (audioTickSound == MusECore::accent2Sound) {
2862                     ev.setA(metro_settings->accentClick2);
2863                     ev.setB(metro_settings->accentClick2Velo);
2864                   }
2865 
2866                   // Should the metronome be played after precount?
2867                   if(!precount_mute_metronome)
2868                   {
2869                     // Don't bother sending to midi out if velocity is zero.
2870                     if (metro_settings->midiClickFlag && md && ev.dataB() > 0) {
2871                       MusECore::MidiPlayEvent evmidi = ev;
2872 
2873   #ifdef DEBUG_MIDI_TIMING_DIFFS
2874                       fprintf(stderr, "EVENT TIME DIFF:%u\n", evmidi.time() - _lastEvTime);
2875                       _lastEvTime = evmidi.time();
2876   #endif
2877 
2878                       md->putEvent(evmidi, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
2879                       // Internal midi paths are now all note off aware. Driver handles note offs. Convert.
2880                       // Ticksynth has been modified too.
2881                       evmidi.setType(MusECore::ME_NOTEOFF);
2882                       evmidi.setB(0);
2883                       evmidi.setTime(midiClick+10);
2884                       md->addStuckNote(evmidi);
2885                     }
2886                   }
2887               }
2888 
2889               const int beat_mod = (beat + 1) % z;
2890 
2891               MetroAccent::AccentTypes_t acc_types = MetroAccent::NoAccent;
2892               if(metro_settings->metroAccentsMap)
2893               {
2894                 MusECore::MetroAccentsMap::const_iterator imap = metro_settings->metroAccentsMap->find(z);
2895                 if(imap != metro_settings->metroAccentsMap->cend())
2896                 {
2897                   const MusECore::MetroAccentsStruct& mas = imap->second;
2898                   accents = &mas._accents;
2899                   accents_sz = accents->size();
2900                   if(beat_mod < accents_sz)
2901                     acc_types = accents->at(beat_mod)._accentType;
2902                 }
2903               }
2904 
2905               // State machine to select next midiClick position.
2906               if (metro_settings->clickSamples == MetronomeSettings::newSamples) {
2907                   if (tick == 0) {//  ON key
2908                     if(acc_types & MetroAccent::Accent1)
2909                     {
2910                       // Cue an accent 1. (This part 'triggers' an accent sequence to begin
2911                       //  which automatically cues accent 2 if required then a normal beat, as shown below.)
2912                       midiClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - ((ticks_beat/n)));
2913                     }
2914                     else if(acc_types & MetroAccent::Accent2)
2915                     {
2916                       // Cue accent 2.
2917                       midiClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - (ticks_beat/(n*2)));
2918                     }
2919                     else
2920                     {
2921                       // Cue a normal beat.
2922                       midiClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
2923                     }
2924                   }
2925                   else if (tick >= unsigned(ticks_beat - (ticks_beat/(n*2)))) { // second accent tick
2926                       // Finished accent 2. Cue a normal beat.
2927                       midiClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
2928                   }
2929                   else if (tick < unsigned(ticks_beat - ((ticks_beat/(n*2))))) { // first accent tick
2930                       if(acc_types & MetroAccent::Accent2)
2931                         // Finished accent 1. Cue accent 2.
2932                         midiClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - (ticks_beat/(n*2)));
2933                       else
2934                         // Finished accent 1. Cue a normal beat.
2935                         midiClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
2936                   }
2937               }
2938               else
2939               {
2940                 midiClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
2941               }
2942             }
2943       }
2944 }
2945 
2946 //---------------------------------------------------------
2947 //   processAudioMetronome
2948 //---------------------------------------------------------
2949 
processAudioMetronome(unsigned int frames)2950 void Audio::processAudioMetronome(unsigned int frames)
2951 {
2952       const MusECore::MetronomeSettings* metro_settings =
2953       MusEGlobal::metroUseSongSettings ? &MusEGlobal::metroSongSettings : &MusEGlobal::metroGlobalSettings;
2954 
2955       const bool extsync = MusEGlobal::extSyncFlag;
2956       const bool playing = isPlaying();
2957 
2958       // Should the metronome be muted after precount?
2959       const bool precount_mute_metronome = metro_settings->precountEnableFlag
2960         && MusEGlobal::song->click()
2961         && !extsync
2962         && ((!MusEGlobal::song->record() && metro_settings->precountOnPlay) || MusEGlobal::song->record())
2963         && metro_settings->precountMuteMetronome;
2964 
2965       if (playing)
2966       {
2967             int bar, beat, z, n;
2968             unsigned tick;
2969             AudioTickSound audioTickSound = MusECore::beatSound;
2970             const MusECore::MetroAccents* accents;
2971             int accents_sz;
2972 
2973             unsigned int lat_offset = 0;
2974             unsigned int cur_tick = curTickPos;
2975             unsigned int next_tick = nextTickPos;
2976 
2977             //--------------------------------------------------------------------
2978             // Account for the metronome's latency correction and/or compensation.
2979             //--------------------------------------------------------------------
2980             // TODO How to handle when external sync is on. For now, don't try to correct.
2981             if(MusEGlobal::config.enableLatencyCorrection && !extsync)
2982             {
2983               if(metro_settings->audioClickFlag)
2984               {
2985                 const TrackLatencyInfo& li = metronome->getLatencyInfo(false);
2986                 // This value is negative for correction.
2987                 const float mlat = li._sourceCorrectionValue;
2988                 if((int)mlat < 0)
2989                 {
2990                   // Convert to a positive offset.
2991                   const unsigned int l = (unsigned int)(-mlat);
2992                   if(l > lat_offset)
2993                     lat_offset = l;
2994                 }
2995                 if(lat_offset != 0)
2996                 {
2997                   Pos ppp(_pos.frame() + lat_offset, false);
2998                   cur_tick = ppp.tick();
2999                   ppp += frames;
3000                   next_tick = ppp.tick();
3001                 }
3002               }
3003             }
3004 
3005             // What is the current transport frame, adjusted?
3006             const unsigned int pos_fr = _pos.frame() + lat_offset;
3007             // What is the (theoretical) next transport frame?
3008             const unsigned int next_pos_fr = pos_fr + frames;
3009 
3010             // If external sync is not on, we can take advantage of frame accuracy but
3011             //  first we must allow the next tick position to be included in the search
3012             //  even if it is equal to the current tick position.
3013             while (extsync ? (audioClick < next_tick) : (audioClick <= next_tick))
3014             {
3015               bool do_play = true;
3016               unsigned int evtime = 0;
3017               if(extsync)
3018               {
3019                 if(audioClick < cur_tick)
3020                   audioClick = cur_tick;
3021                 evtime = extClockHistoryTick2Frame(audioClick - cur_tick) + MusEGlobal::segmentSize;
3022               }
3023               else
3024               {
3025                 // What is the exact transport frame that the click should be played at?
3026                 const unsigned int fr = MusEGlobal::tempomap.tick2frame(audioClick);
3027                 // Is the click frame outside of the current transport frame range?
3028                 if(fr < pos_fr || fr >= next_pos_fr)
3029                 {
3030                   // Break out of the loop if midiClick equals nextTickPos.
3031                   if(audioClick == next_tick)
3032                     break;
3033                   // Continue on, but do not play any notes.
3034                   do_play = false;
3035                 }
3036                 evtime = fr - pos_fr;
3037                 evtime += syncFrame;
3038               }
3039 
3040               DEBUG_MIDI_METRONOME(stderr,
3041                 "Audio::processAudioMetronome: playing: syncFrame:%u _pos.frame():%u audioClick:%u next_tick:%u clickno:%d\n",
3042                 syncFrame, _pos.frame(), audioClick, next_tick, clickno);
3043 
3044               MusEGlobal::sigmap.tickValues(audioClick, &bar, &beat, &tick);
3045               MusEGlobal::sigmap.timesig(audioClick, z, n);
3046               // How many ticks per beat?
3047               const int ticks_beat = MusEGlobal::sigmap.ticks_beat(n);
3048 
3049               if (do_play && MusEGlobal::song->click()
3050                   && (metro_settings->audioClickFlag)
3051                   && !precount_mute_metronome) {
3052 
3053                   if (tick == 0 && beat == 0) {
3054                       audioTickSound = MusECore::measureSound;
3055                       if (MusEGlobal::debugMsg)
3056                           fprintf(stderr, "meas: audioClick %d next_tick %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
3057                                   audioClick, next_tick, bar, beat, tick, z, n, ticks_beat);
3058                   }
3059                   else if (tick == unsigned(ticks_beat - (ticks_beat/(n*2)))) {
3060                       audioTickSound = MusECore::accent2Sound;
3061                       if (MusEGlobal::debugMsg)
3062                           fprintf(stderr, "acc2: audioClick %d next_tick %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
3063                                   audioClick, next_tick, bar, beat, tick, z, n, ticks_beat);
3064                   }
3065                   else if (tick == unsigned(ticks_beat - (ticks_beat/n))) {
3066                       audioTickSound = MusECore::accent1Sound;
3067                       if (MusEGlobal::debugMsg)
3068                           fprintf(stderr, "acc1: audioClick %d next_tick %d bar %d beat %d tick %d z %d n %d ticks_beat %d\n",
3069                                   audioClick, next_tick, bar, beat, tick, z, n, ticks_beat);
3070                   } else {
3071                       if (MusEGlobal::debugMsg)
3072                           fprintf(stderr, "beat: audioClick %d next_tick %d bar %d beat %d tick %d z %d n %d div %d\n",
3073                                   audioClick, next_tick, bar, beat, tick, z, n, ticks_beat);
3074                   }
3075 
3076                   // Should the metronome be played after precount?
3077                   if(!precount_mute_metronome)
3078                   {
3079                     if (metro_settings->audioClickFlag) {
3080                       MusECore::MidiPlayEvent ev(evtime, 0, 0,
3081                         MusECore::ME_NOTEON, audioTickSound, 0);
3082                       DEBUG_MIDI_METRONOME(stderr, "Audio::processAudioMetronome: playing: metronome->putEvent\n");
3083                       metronome->putEvent(ev, MidiDevice::NotLate, MidiDevice::PlaybackBuffer);
3084                       // Built-in metronome synth does not use stuck notes...
3085                     }
3086                   }
3087               }
3088 
3089               const int beat_mod = (beat + 1) % z;
3090 
3091               MetroAccent::AccentTypes_t acc_types = MetroAccent::NoAccent;
3092               if(metro_settings->metroAccentsMap)
3093               {
3094                 MusECore::MetroAccentsMap::const_iterator imap = metro_settings->metroAccentsMap->find(z);
3095                 if(imap != metro_settings->metroAccentsMap->cend())
3096                 {
3097                   const MusECore::MetroAccentsStruct& mas = imap->second;
3098                   accents = &mas._accents;
3099                   accents_sz = accents->size();
3100                   if(beat_mod < accents_sz)
3101                     acc_types = accents->at(beat_mod)._accentType;
3102                 }
3103               }
3104 
3105               // State machine to select next midiClick position.
3106               if (metro_settings->clickSamples == MetronomeSettings::newSamples) {
3107                   if (tick == 0) {//  ON key
3108                     if(acc_types & MetroAccent::Accent1)
3109                     {
3110                       // Cue an accent 1. (This part 'triggers' an accent sequence to begin
3111                       //  which automatically cues accent 2 if required then a normal beat, as shown below.)
3112                       audioClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - ((ticks_beat/n)));
3113                     }
3114                     else if(acc_types & MetroAccent::Accent2)
3115                     {
3116                       // Cue accent 2.
3117                       audioClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - (ticks_beat/(n*2)));
3118                     }
3119                     else
3120                     {
3121                       // Cue a normal beat.
3122                       audioClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
3123                     }
3124                   }
3125                   else if (tick >= unsigned(ticks_beat - (ticks_beat/(n*2)))) { // second accent tick
3126                       // Finished accent 2. Cue a normal beat.
3127                       audioClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
3128                   }
3129                   else if (tick < unsigned(ticks_beat - ((ticks_beat/(n*2))))) { // first accent tick
3130                       if(acc_types & MetroAccent::Accent2)
3131                         // Finished accent 1. Cue accent 2.
3132                         audioClick = MusEGlobal::sigmap.bar2tick(bar, beat, ticks_beat - (ticks_beat/(n*2)));
3133                       else
3134                         // Finished accent 1. Cue a normal beat.
3135                         audioClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
3136                   }
3137               }
3138               else
3139               {
3140                 audioClick = MusEGlobal::sigmap.bar2tick(bar, beat+1, 0);
3141               }
3142             }
3143       }
3144 }
3145 
3146 
3147 } // namespace MusECore
3148