1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2007-2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "midifile.h"
14 #include "libmscore/xml.h"
15 #include "libmscore/part.h"
16 #include "libmscore/note.h"
17 #include "libmscore/drumset.h"
18 #include "libmscore/utils.h"
19 
20 namespace Ms {
21 
22 static const uchar gmOnMsg[] = {
23       0x7e,       // Non-Real Time header
24       0x7f,       // ID of target device (7f = all devices)
25       0x09,
26       0x01
27       };
28 static const uchar gsOnMsg[] = {
29       0x41,       // roland id
30       0x10,       // Id of target device (default = 10h for roland)
31       0x42,       // model id (42h = gs devices)
32       0x12,       // command id (12h = data set)
33       0x40,       // address & value
34       0x00,
35       0x7f,
36       0x00,
37       0x41        // checksum?
38       };
39 static const uchar xgOnMsg[] = {
40       0x43,       // yamaha id
41       0x10,       // device number (0)
42       0x4c,       // model id
43       0x00,       // address (high, mid, low)
44       0x00,
45       0x7e,
46       0x00        // data
47       };
48 
49 const int gmOnMsgLen = sizeof(gmOnMsg);
50 const int gsOnMsgLen = sizeof(gsOnMsg);
51 const int xgOnMsgLen = sizeof(xgOnMsg);
52 
53 //---------------------------------------------------------
54 //   MidiFile
55 //---------------------------------------------------------
56 
MidiFile()57 MidiFile::MidiFile()
58       {
59       fp               = 0;
60       _division        = 0;
61       _isDivisionInTps = false;
62       _format          = 1;
63       _midiType        = MidiType::UNKNOWN;
64       _noRunningStatus = false;
65 
66       status           = 0;
67       sstatus          = 0;
68       click            = 0;
69       curPos           = 0;
70       }
71 
72 //---------------------------------------------------------
73 //   write
74 //    returns true on error
75 //---------------------------------------------------------
76 
write(QIODevice * out)77 bool MidiFile::write(QIODevice* out)
78       {
79       fp = out;
80       write("MThd", 4);
81       writeLong(6);                 // header len
82       writeShort(_format);          // format
83       writeShort(_tracks.size());
84       writeShort(_division);
85       for (const auto &t: qAsConst(_tracks)) {
86             if (writeTrack(t))
87                   return true;
88             }
89       return false;
90       }
91 
92 //---------------------------------------------------------
93 //   write
94 //---------------------------------------------------------
95 
writeEvent(const MidiEvent & event)96 void MidiFile::writeEvent(const MidiEvent& event)
97       {
98       switch(event.type()) {
99             case ME_NOTEON:
100                   writeStatus(ME_NOTEON, event.channel());
101                   put(event.pitch());
102                   put(event.velo());
103                   break;
104 
105             case ME_NOTEOFF:
106                   writeStatus(ME_NOTEOFF, event.channel());
107                   put(event.pitch());
108                   put(event.velo());
109                   break;
110 
111             case ME_PITCHBEND:
112                   writeStatus(ME_PITCHBEND, event.channel());
113                   put(event.dataA());
114                   put(event.dataB());
115                   break;
116 
117             case ME_CONTROLLER:
118                   switch(event.controller()) {
119                         case CTRL_PROGRAM:
120                               writeStatus(ME_PROGRAM, event.channel());
121                               put(event.value() & 0x7f);
122                               break;
123                         case CTRL_PRESS:
124                               writeStatus(ME_AFTERTOUCH, event.channel());
125                               put(event.value() & 0x7f);
126                               break;
127                         default:
128                               writeStatus(ME_CONTROLLER, event.channel());
129                               put(event.controller());
130                               put(event.value() & 0x7f);
131                               break;
132                         }
133                   break;
134 
135             case ME_META:
136                   put(ME_META);
137                   put(event.metaType());
138                   putvl(event.len());
139                   write(event.edata(), event.len());
140                   resetRunningStatus();     // really ?!
141                   break;
142 
143             case ME_SYSEX:
144                   put(ME_SYSEX);
145                   putvl(event.len() + 1);  // including 0xf7
146                   write(event.edata(), event.len());
147                   put(ME_ENDSYSEX);
148                   resetRunningStatus();
149                   break;
150             }
151       }
152 
153 //---------------------------------------------------------
154 //   writeTrack
155 //---------------------------------------------------------
156 
writeTrack(const MidiTrack & t)157 bool MidiFile::writeTrack(const MidiTrack &t)
158       {
159       write("MTrk", 4);
160       qint64 lenpos = fp->pos();
161       writeLong(0);                 // dummy len
162 
163       status   = -1;
164       int tick = 0;
165       for (auto i : t.events()) {
166             int ntick = i.first;
167             putvl(ntick - tick);    // write tick delta
168             //
169             // if track channel != -1, then use this
170             //    channel for all events in this track
171             //
172             if (t.outChannel() != -1)
173                   writeEvent(i.second);
174             tick = ntick;
175             }
176 
177       //---------------------------------------------------
178       //    write "End Of Track" Meta
179       //    write Track Len
180       //
181 
182       putvl(1);
183       put(0xff);        // Meta
184       put(0x2f);        // EOT
185       putvl(0);         // len 0
186       qint64 endpos = fp->pos();
187       fp->seek(lenpos);
188       writeLong(endpos-lenpos-4);   // tracklen
189       fp->seek(endpos);
190       return false;
191       }
192 
193 //---------------------------------------------------------
194 //   writeStatus
195 //---------------------------------------------------------
196 
writeStatus(int nstat,int c)197 void MidiFile::writeStatus(int nstat, int c)
198       {
199       nstat |= (c & 0xf);
200       //
201       //  running status; except for Sysex- and Meta Events
202       //
203       if (_noRunningStatus || (((nstat & 0xf0) != 0xf0) && (nstat != status))) {
204             status = nstat;
205             put(nstat);
206             }
207       }
208 
209 //---------------------------------------------------------
210 //   readMidi
211 //    return false on error
212 //---------------------------------------------------------
213 
read(QIODevice * in)214 bool MidiFile::read(QIODevice* in)
215      {
216       fp = in;
217       _tracks.clear();
218       curPos    = 0;
219 
220       // === Read header_chunk = "MThd" + <header_length> + <format> + <n> + <division>
221       //
222       // "MThd" 4 bytes
223       //    the literal string MThd, or in hexadecimal notation: 0x4d546864.
224       //    These four characters at the start of the MIDI file
225       //    indicate that this is a MIDI file.
226       // <header_length> 4 bytes
227       //    length of the header chunk (always =6 bytes long - the size of the next
228       //    three fields which are considered the header chunk).
229       //    Although the header chunk currently always contains 6 bytes of data,
230       //    this should not be assumed, this value should always be read and acted upon,
231       //    to allow for possible future extension to the standard.
232       // <format> 2 bytes
233       //    0 = single track file format
234       //    1 = multiple track file format
235       //    2 = multiple song file format (i.e., a series of type 0 files)
236       // <n> 2 bytes
237       //    number of track chunks that follow the header chunk
238       // <division> 2 bytes
239       //    unit of time for delta timing. If the value is positive, then it represents
240       //    the units per beat. For example, +96 would mean 96 ticks per beat.
241       //    If the value is negative, delta times are in SMPTE compatible units.
242 
243       char tmp[4];
244 
245       read(tmp, 4);
246       int len = readLong();
247       if (memcmp(tmp, "MThd", 4) || len < 6)
248             throw(QString("bad midifile: MThd expected"));
249 
250       if (len > 6)
251             throw(QString("unsupported MIDI header data size: %1 instead of 6").arg(len));
252 
253       _format     = readShort();
254       int ntracks = readShort();
255 
256       // ================ Read MIDI division =================
257       //
258       //                        2 bytes
259       //  +-------+---+-------------------+-----------------+
260       //  |  bit  |15 | 14              8 | 7             0 |
261       //  +-------+---+-------------------------------------+
262       //  |       | 0 |       ticks per quarter note        |
263       //  | value +---+-------------------------------------+
264       //  |       | 1 |  -frames/second   |   ticks/frame   |
265       //  +-------+---+-------------------+-----------------+
266 
267       char firstByte;
268       fp->getChar(&firstByte);
269       char secondByte;
270       fp->getChar(&secondByte);
271       const char topBit = (firstByte & 0x80) >> 7;
272 
273       if (topBit == 0) {            // ticks per beat
274             _isDivisionInTps = false;
275             _division = (firstByte << 8) | (secondByte & 0xff);
276             }
277       else {                        // ticks per second = fps * ticks per frame
278             _isDivisionInTps = true;
279             const int framesPerSecond = -((signed char) firstByte);
280             const int ticksPerFrame = secondByte;
281             if (framesPerSecond == 29)
282                   _division = qRound(29.97 * ticksPerFrame);
283             else
284                   _division = framesPerSecond * ticksPerFrame;
285             }
286 
287       // =====================================================
288 
289       switch (_format) {
290             case 0:
291                   if (readTrack())
292                         return false;
293                   break;
294             case 1:
295                   for (int i = 0; i < ntracks; i++) {
296                         if (readTrack())
297                               return false;
298                         }
299                   break;
300             default:
301                   throw(QString("midi file format %1 not implemented").arg(_format));
302 
303                   // Prevent "unreachable code" warning
304                   // return false;
305             }
306       return true;
307       }
308 
309 //---------------------------------------------------------
310 //   readTrack
311 //    return true on error
312 //---------------------------------------------------------
313 
readTrack()314 bool MidiFile::readTrack()
315       {
316       char tmp[4];
317       read(tmp, 4);
318       if (memcmp(tmp, "MTrk", 4))
319             throw(QString("bad midifile: MTrk expected"));
320       int len       = readLong();       // len
321       qint64 endPos = curPos + len;
322       status        = -1;
323       sstatus       = -1;  // running status, will not be reset on meta or sysex
324       click         =  0;
325       _tracks.push_back(MidiTrack());
326 
327       int port = 0;
328       _tracks.back().setOutPort(port);
329       _tracks.back().setOutChannel(-1);
330 
331       for (;;) {
332             MidiEvent event;
333             if (!readEvent(&event))
334                   return true;
335 
336             // check for end of track:
337             if ((event.type() == ME_META) && (event.metaType() == META_EOT))
338                   break;
339             _tracks.back().insert(click, event);
340             }
341       if (curPos != endPos) {
342             qWarning("bad track len: %lld != %lld, %lld bytes too much\n", endPos, curPos, endPos - curPos);
343             if (curPos < endPos) {
344                   qWarning("  skip %lld\n", endPos-curPos);
345                   skip(endPos - curPos);
346                   }
347             }
348       return false;
349       }
350 
351 /*---------------------------------------------------------
352  *    read
353  *    return false on error
354  *---------------------------------------------------------*/
355 
read(void * p,qint64 len)356 void MidiFile::read(void* p, qint64 len)
357       {
358       curPos += len;
359       qint64 rv = fp->read((char*)p, len);
360       if (rv != len)
361             throw(QString("bad midifile: unexpected EOF"));
362       }
363 
364 //---------------------------------------------------------
365 //   write
366 //---------------------------------------------------------
367 
write(const void * p,qint64 len)368 bool MidiFile::write(const void* p, qint64 len)
369       {
370       qint64 rv = fp->write((char*)p, len);
371       if (rv == len)
372             return false;
373       qDebug("write midifile failed: %s", fp->errorString().toLatin1().data());
374       return true;
375       }
376 
377 //---------------------------------------------------------
378 //   readShort
379 //---------------------------------------------------------
380 
readShort()381 int MidiFile::readShort()
382       {
383       char c;
384       int val = 0;
385       for (int i = 0; i < 2; ++i) {
386             fp->getChar(&c);
387             val <<= 8;
388             val += (c & 0xff);
389             }
390       return val;
391       }
392 
393 //---------------------------------------------------------
394 //   writeShort
395 //---------------------------------------------------------
396 
writeShort(int i)397 void MidiFile::writeShort(int i)
398       {
399       fp->putChar(i >> 8);
400       fp->putChar(i);
401       }
402 
403 //---------------------------------------------------------
404 //   readLong
405 //   writeLong
406 //---------------------------------------------------------
407 
readLong()408 int MidiFile::readLong()
409       {
410       char c;
411       int val = 0;
412       for (int i = 0; i < 4; ++i) {
413             fp->getChar(&c);
414             val <<= 8;
415             val += (c & 0xff);
416             }
417       return val;
418       }
419 
420 //---------------------------------------------------------
421 //   writeLong
422 //---------------------------------------------------------
423 
writeLong(int i)424 void MidiFile::writeLong(int i)
425       {
426       fp->putChar(i >> 24);
427       fp->putChar(i >> 16);
428       fp->putChar(i >> 8);
429       fp->putChar(i);
430       }
431 
432 /*---------------------------------------------------------
433  *    skip
434  *    This is meant for skipping a few bytes in a
435  *    file or fifo.
436  *---------------------------------------------------------*/
437 
skip(qint64 len)438 void MidiFile::skip(qint64 len)
439       {
440       // Note: if MS is updated to use Qt 5.10, this can be implemented with QIODevice::skip(), which should be more efficient
441       //       as bytes do not need to be moved around.
442       if (len <= 0)
443             return;
444 #if (!defined (_MSCVER) && !defined (_MSC_VER))
445       char tmp[len];
446       read(tmp, len);
447 #else
448       const int tmp_size = 256;  // Size of fixed-length temporary buffer. MSVC does not support VLA.
449       char tmp[tmp_size];
450       while(len > tmp_size) {
451             read(tmp, len);
452             len -= tmp_size;
453             }
454       // Now len is <= tmp_size, last read fits in the buffer.
455       read(tmp, tmp_size);
456 #endif
457       }
458 
459 /*---------------------------------------------------------
460  *    getvl
461  *    Read variable-length number (7 bits per byte, MSB first)
462  *---------------------------------------------------------*/
463 
getvl()464 int MidiFile::getvl()
465       {
466       int l = 0;
467       for (int i = 0; i < 16; i++) {
468             uchar c;
469             read(&c, 1);
470             l += (c & 0x7f);
471             if (!(c & 0x80)) {
472                   return l;
473                   }
474             l <<= 7;
475             }
476       return -1;
477       }
478 
479 /*---------------------------------------------------------
480  *    putvl
481  *    Write variable-length number (7 bits per byte, MSB first)
482  *---------------------------------------------------------*/
483 
putvl(unsigned val)484 void MidiFile::putvl(unsigned val)
485       {
486       unsigned long buf = val & 0x7f;
487       while ((val >>= 7) > 0) {
488             buf <<= 8;
489             buf |= 0x80;
490             buf += (val & 0x7f);
491             }
492       for (;;) {
493             put(buf);
494             if (buf & 0x80)
495                   buf >>= 8;
496             else
497                   break;
498             }
499       }
500 
501 //---------------------------------------------------------
502 //   MidiTrack
503 //---------------------------------------------------------
504 
MidiTrack()505 MidiTrack::MidiTrack()
506       {
507       _outChannel = -1;
508       _outPort    = -1;
509       _drumTrack  = false;
510       }
511 
~MidiTrack()512 MidiTrack::~MidiTrack()
513       {
514       }
515 
516 //---------------------------------------------------------
517 //   insert
518 //---------------------------------------------------------
519 
insert(int tick,const MidiEvent & event)520 void MidiTrack::insert(int tick, const MidiEvent& event)
521       {
522       _events.insert({tick, event});
523       }
524 
525 //---------------------------------------------------------
526 //   readEvent
527 //    return true on success
528 //---------------------------------------------------------
529 
readEvent(MidiEvent * event)530 bool MidiFile::readEvent(MidiEvent* event)
531       {
532       uchar me, a, b;
533 
534       int nclick = getvl();
535       if (nclick == -1) {
536             qDebug("readEvent: error 1(getvl)");
537             return false;
538             }
539       click += nclick;
540       for (;;) {
541             read(&me, 1);
542             if (me >= 0xf1 && me <= 0xfe && me != 0xf7) {
543                   qDebug("Midi: Unknown Message 0x%02x", me & 0xff);
544                   }
545             else
546                   break;
547             }
548 
549       unsigned char* data;
550       int dataLen;
551 
552       if (me == 0xf0 || me == 0xf7) {
553             status  = -1;                  // no running status
554             int len = getvl();
555             if (len == -1) {
556                   qDebug("readEvent: error 3");
557                   return false;
558                   }
559             data    = new unsigned char[len+1];
560             dataLen = len;
561             read(data, len);
562             data[dataLen] = 0;    // always terminate with zero
563             if (data[len-1] != 0xf7) {
564                   qDebug("SYSEX does not end with 0xf7!");
565                   // more to come?
566                   }
567             else
568                   dataLen--;      // don't count 0xf7
569             event->setType(ME_SYSEX);
570             event->setEData(data);
571             event->setLen(dataLen);
572             return true;
573             }
574 
575       if (me == ME_META) {
576             status = -1;                  // no running status
577             uchar type;
578             read(&type, 1);
579             dataLen = getvl();                // read len
580             if (dataLen == -1) {
581                   qDebug("readEvent: error 6");
582                   return false;
583                   }
584             data = new unsigned char[dataLen + 1];
585             if (dataLen)
586                   read(data, dataLen);
587             data[dataLen] = 0;      // always terminate with zero so we get valid C++ strings
588 
589             event->setType(ME_META);
590             event->setMetaType(type);
591             event->setLen(dataLen);
592             event->setEData(data);
593             return true;
594             }
595 
596       if (me & 0x80) {                     // status byte
597             status   = me;
598             sstatus  = status;
599             read(&a, 1);
600             }
601       else {
602             if (status == -1) {
603                   qDebug("readEvent: no running status, read 0x%02x", me);
604                   qDebug("sstatus ist 0x%02x", sstatus);
605                   if (sstatus == -1) {
606                         return 0;
607                         }
608                   status = sstatus;
609                   }
610             a = me;
611             }
612       int channel = status & 0x0f;
613       b           = 0;
614       switch (status & 0xf0) {
615             case ME_NOTEOFF:
616             case ME_NOTEON:
617             case ME_POLYAFTER:
618             case ME_CONTROLLER:        // controller
619             case ME_PITCHBEND:        // pitch bend
620                   read(&b, 1);
621                   break;
622             }
623       event->setType(status & 0xf0);
624       event->setChannel(channel);
625       switch (status & 0xf0) {
626             case ME_NOTEOFF:
627                   event->setDataA(a & 0x7f);
628                   event->setDataB(b & 0x7f);
629                   break;
630             case ME_NOTEON:
631                   event->setDataA(a & 0x7f);
632                   event->setDataB(b & 0x7f);
633                   break;
634             case ME_POLYAFTER:
635                   event->setType(ME_CONTROLLER);
636                   event->setController(CTRL_POLYAFTER);
637                   event->setValue(((a & 0x7f) << 8) + (b & 0x7f));
638                   break;
639             case ME_CONTROLLER:        // controller
640                   event->setController(a & 0x7f);
641                   event->setValue(b & 0x7f);
642                   break;
643             case ME_PITCHBEND:        // pitch bend
644                   event->setDataA(a & 0x7f);
645                   event->setDataB(b & 0x7f);
646                   break;
647             case ME_PROGRAM:
648                   event->setValue(a & 0x7f);
649                   break;
650             case ME_AFTERTOUCH:
651                   event->setType(ME_CONTROLLER);
652                   event->setController(CTRL_PRESS);
653                   event->setValue(a & 0x7f);
654                   break;
655             default:          // f1 f2 f3 f4 f5 f6 f7 f8 f9
656                   qDebug("BAD STATUS 0x%02x, me 0x%02x", status, me);
657                   return false;
658             }
659 
660       if ((a & 0x80) || (b & 0x80)) {
661             qDebug("8't bit in data set(%02x %02x): tick %d read 0x%02x  status:0x%02x",
662               a & 0xff, b & 0xff, click, me, status);
663             qDebug("readEvent: error 16");
664             if (b & 0x80) {
665                   // Try to fix: interpret as channel byte
666                   status   = b;
667                   sstatus  = status;
668                   return true;
669                   }
670             return false;
671             }
672       return true;
673       }
674 
675 //---------------------------------------------------------
676 //   setOutChannel
677 //---------------------------------------------------------
678 
setOutChannel(int n)679 void MidiTrack::setOutChannel(int n)
680       {
681       _outChannel = n;
682       if (_outChannel == 9)
683             _drumTrack = true;
684       }
685 
686 //---------------------------------------------------------
687 //   mergeNoteOnOffAndFindMidiType
688 //    - find matching note on / note off events and merge
689 //      into a note event with tick duration
690 //    - find MIDI type
691 //---------------------------------------------------------
692 
mergeNoteOnOffAndFindMidiType(MidiType * mt)693 void MidiTrack::mergeNoteOnOffAndFindMidiType(MidiType *mt)
694       {
695       std::multimap<int, MidiEvent> el;
696 
697       int hbank = 0xff;
698       int lbank = 0xff;
699       int rpnh  = -1;
700       int rpnl  = -1;
701       int datah = 0;
702       int datal = 0;
703       int dataType = 0; // 0 : disabled, 0x20000 : rpn, 0x30000 : nrpn;
704 
705       for (auto i = _events.begin(); i != _events.end(); ++i) {
706             MidiEvent& ev = i->second;
707             if (ev.type() == ME_INVALID)
708                   continue;
709             if ((ev.type() != ME_NOTEON) && (ev.type() != ME_NOTEOFF)) {
710                   if (ev.type() == ME_CONTROLLER) {
711                         int val  = ev.value();
712                         int cn   = ev.controller();
713                         if (cn == CTRL_HBANK) {
714                               hbank = val;
715                               ev.setType(ME_INVALID);
716                               continue;
717                               }
718                         else if (cn == CTRL_LBANK) {
719                               lbank = val;
720                               ev.setType(ME_INVALID);
721                               continue;
722                               }
723                         else if (cn == CTRL_HDATA) {
724                               datah = val;
725 
726                               // check if a CTRL_LDATA follows
727                               // e.g. wie have a 14 bit controller:
728                               auto ii = i;
729                               ++ii;
730                               bool found = false;
731                               for (; ii != _events.end(); ++ii) {
732                                     MidiEvent& ev1 = ii->second;
733                                     if (ev1.type() == ME_CONTROLLER) {
734                                           if (ev1.controller() == CTRL_LDATA) {
735                                                 // handle later
736                                                 found = true;
737                                                 }
738                                           break;
739                                           }
740                                     }
741                               if (!found) {
742                                     if (rpnh == -1 || rpnl == -1) {
743                                           qDebug("parameter number not defined, data 0x%x", datah);
744                                           ev.setType(ME_INVALID);
745                                           continue;
746                                           }
747                                     else {
748                                           ev.setController(dataType | (rpnh << 8) | rpnl);
749                                           ev.setValue(datah);
750                                           }
751                                     }
752                               else {
753                                     ev.setType(ME_INVALID);
754                                     continue;
755                                     }
756                               }
757                         else if (cn == CTRL_LDATA) {
758                               datal = val;
759 
760                               if (rpnh == -1 || rpnl == -1) {
761                                     qDebug("parameter number not defined, data 0x%x 0x%x, tick %d, channel %d",
762                                        datah, datal, i->first, ev.channel());
763                                     continue;
764                                     }
765                               // assume that the sequence is always
766                               //    CTRL_HDATA - CTRL_LDATA
767                               // eg. that LDATA is always send last
768 
769                               // 14 Bit RPN/NRPN
770                               ev.setController((dataType+0x30000) | (rpnh << 8) | rpnl);
771                               ev.setValue((datah << 7) | datal);
772                               }
773                         else if (cn == CTRL_HRPN) {
774                               rpnh = val;
775                               dataType = 0x20000;
776                               ev.setType(ME_INVALID);
777                               continue;
778                               }
779                         else if (cn == CTRL_LRPN) {
780                               rpnl = val;
781                               dataType = 0x20000;
782                               ev.setType(ME_INVALID);
783                               continue;
784                               }
785                         else if (cn == CTRL_HNRPN) {
786                               rpnh = val;
787                               dataType = 0x30000;
788                               ev.setType(ME_INVALID);
789                               continue;
790                               }
791                         else if (cn == CTRL_LNRPN) {
792                               rpnl = val;
793                               dataType = 0x30000;
794                               ev.setType(ME_INVALID);
795                               continue;
796                               }
797                         else if (cn == CTRL_PROGRAM) {
798                               ev.setValue((hbank << 16) | (lbank << 8) | ev.value());
799                               // TODO el.insert(ev);
800                               ev.setType(ME_INVALID);
801                               continue;
802                               }
803                         }
804                   else if (ev.type() == ME_SYSEX) {
805                         int len = ev.len();
806                         const uchar* buffer = ev.edata();
807                         if ((len == gmOnMsgLen) && memcmp(buffer, gmOnMsg, gmOnMsgLen) == 0) {
808                               *mt = MidiType::GM;
809                               ev.setType(ME_INVALID);
810                               continue;
811                               }
812                         if ((len == gsOnMsgLen) && memcmp(buffer, gsOnMsg, gsOnMsgLen) == 0) {
813                               *mt = MidiType::GS;
814                               ev.setType(ME_INVALID);
815                               continue;
816                               }
817                         if ((len == xgOnMsgLen) && memcmp(buffer, xgOnMsg, xgOnMsgLen) == 0) {
818                               *mt = MidiType::XG;
819                               ev.setType(ME_INVALID);
820                               continue;
821                               }
822                         if (buffer[0] == 0x43) {    // Yamaha
823                               *mt = MidiType::XG;
824                               int type   = buffer[1] & 0xf0;
825                               if (type == 0x10) {
826 //TODO                                    if (buffer[1] != 0x10) {
827 //                                          buffer[1] = 0x10;    // fix to Device 1
828 //                                          }
829                                     if ((len == xgOnMsgLen) && memcmp(buffer, xgOnMsg, xgOnMsgLen) == 0) {
830                                           *mt = MidiType::XG;
831                                           ev.setType(ME_INVALID);
832                                           continue;
833                                           }
834                                     if (len == 7 && buffer[2] == 0x4c && buffer[3] == 0x08 && buffer[5] == 7) {
835                                           // part mode
836                                           // 0 - normal
837                                           // 1 - DRUM
838                                           // 2 - DRUM 1
839                                           // 3 - DRUM 2
840                                           // 4 - DRUM 3
841                                           // 5 - DRUM 4
842                                           if (buffer[6] != 0 && buffer[4] == ev.channel()) {
843                                                 _drumTrack = true;
844                                                 }
845                                           ev.setType(ME_INVALID);
846                                           continue;
847                                           }
848                                     }
849                               }
850                         }
851                   el.insert(std::pair<int,MidiEvent>(i->first, ev));
852                   ev.setType(ME_INVALID);
853                   continue;
854                   }
855             int tick = i->first;
856             if (ev.type() == ME_NOTEOFF || ev.velo() == 0) {
857                   qDebug("-extra note off at %d", tick);
858                   ev.setType(ME_INVALID);
859                   continue;
860                   }
861             MidiEvent note(ME_NOTE, ev.channel(), ev.dataA(), ev.dataB());
862 
863             auto k = i;
864             ++k;
865             for (; k != _events.end(); ++k) {
866                   MidiEvent& e = k->second;
867                   if (e.type() != ME_NOTEON && e.type() != ME_NOTEOFF)
868                         continue;
869                   if ((e.type() == ME_NOTEOFF || (e.type() == ME_NOTEON && e.velo() == 0))
870                      && (e.pitch() == note.pitch())) {
871                         int t = k->first - tick;
872                         if (t <= 0)
873                               t = 1;
874                         note.setLen(t);
875                         e.setType(ME_INVALID);
876                         break;
877                         }
878                   }
879             if (k == _events.end()) {
880                   qDebug("-no note-off for note at %d", tick);
881                   note.setLen(1);
882                   }
883             el.insert(std::pair<int,MidiEvent>(tick, note));
884             ev.setType(ME_INVALID);
885             }
886       _events = el;
887       }
888 
889 //---------------------------------------------------------
890 //   separateChannel
891 //    if a track contains events for different midi channels,
892 //    then split events into separate tracks
893 //---------------------------------------------------------
894 
separateChannel()895 void MidiFile::separateChannel()
896       {
897       for (int i = 0; i < _tracks.size(); ++i) {
898                         // create a list of channels used in current track
899             QList<int> channel;
900             MidiTrack &mt = _tracks[i];      // current track
901             for (const auto& ie : mt.events()) {
902                   const MidiEvent& e = ie.second;
903                   if (e.isChannelEvent() && !channel.contains(e.channel()))
904                         channel.append(e.channel());
905                   }
906             mt.setOutChannel(channel.empty() ? 0 : channel[0]);
907             int nn = channel.size();
908             if (nn <= 1)
909                   continue;
910             std::sort(channel.begin(), channel.end());
911                         // -- split --
912                         // insert additional tracks, assign to them found channels
913             for (int ii = 1; ii < nn; ++ii) {
914                   MidiTrack t;
915                   t.setOutChannel(channel[ii]);
916                   _tracks.insert(i + ii, t);
917                   }
918                         // extract all different channel events from current track to inserted tracks
919             for (auto ie = mt.events().begin(); ie != mt.events().end(); ) {
920                   const MidiEvent& e = ie->second;
921                   if (e.isChannelEvent()) {
922                         int ch  = e.channel();
923                         int idx = channel.indexOf(ch);
924                         MidiTrack &t = _tracks[i + idx];
925                         if (&t != &mt) {
926                               t.insert(ie->first, e);
927                               ie = mt.events().erase(ie);
928                               continue;
929                               }
930                         }
931                   ++ie;
932                   }
933             i += nn - 1;
934             }
935       }
936 
937 } // namespace Ms
938