1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Rosegarden
5 A sequencer and musical notation editor.
6 Copyright 2000-2021 the Rosegarden development team.
7 See the AUTHORS file for more details.
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 as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #define RG_MODULE_STRING "[MidiFile]"
17 // Turn off all debugging here.
18 #define RG_NO_DEBUG_PRINT
19
20 #include "MidiFile.h"
21
22 #include "Midi.h"
23 #include "MidiEvent.h"
24 #include "base/Segment.h"
25 //#include "base/NotationTypes.h"
26 #include "base/BaseProperties.h"
27 #include "base/Track.h"
28 #include "base/Instrument.h"
29 #include "base/Studio.h"
30 #include "base/MidiTypes.h"
31 #include "base/Profiler.h"
32 #include "document/RosegardenDocument.h"
33 #include "gui/application/RosegardenMainWindow.h"
34 #include "gui/seqmanager/SequenceManager.h"
35 #include "misc/Debug.h"
36 #include "misc/Strings.h"
37 #include "sound/MappedBufMetaIterator.h"
38 #include "sound/MidiInserter.h"
39 #include "sound/SortingInserter.h"
40
41 #include <QProgressDialog>
42
43 #include <fstream>
44 #include <string>
45 #include <sstream>
46
47 static const char MIDI_FILE_HEADER[] = "MThd";
48 static const char MIDI_TRACK_HEADER[] = "MTrk";
49
50 namespace Rosegarden
51 {
52
53
MidiFile()54 MidiFile::MidiFile() :
55 m_format(MIDI_FILE_NOT_LOADED),
56 m_numberOfTracks(0),
57 m_timingFormat(MIDI_TIMING_PPQ_TIMEBASE),
58 m_timingDivision(0),
59 m_fps(0),
60 m_subframes(0),
61 m_fileSize(0),
62 m_trackByteCount(0),
63 m_decrementCount(false),
64 m_bytesRead(0)
65 {
66 }
67
~MidiFile()68 MidiFile::~MidiFile()
69 {
70 // Delete all the event objects.
71 clearMidiComposition();
72 }
73
74 long
midiBytesToLong(const std::string & bytes)75 MidiFile::midiBytesToLong(const std::string &bytes)
76 {
77 if (bytes.length() != 4) {
78 RG_WARNING << "midiBytesToLong(): WARNING: Wrong length for long data (" << bytes.length() << ", should be 4)";
79
80 // TRANSLATOR: "long" is a C++ data type
81 throw Exception(qstrtostr(tr("Wrong length for long data in MIDI stream")));
82 }
83
84 long longRet = static_cast<long>(static_cast<MidiByte>(bytes[0])) << 24 |
85 static_cast<long>(static_cast<MidiByte>(bytes[1])) << 16 |
86 static_cast<long>(static_cast<MidiByte>(bytes[2])) << 8 |
87 static_cast<long>(static_cast<MidiByte>(bytes[3]));
88
89 RG_DEBUG << "midiBytesToLong(" << static_cast<long>(static_cast<MidiByte>(bytes[0])) << "," << static_cast<long>(static_cast<MidiByte>(bytes[1])) << "," << static_cast<long>(static_cast<MidiByte>(bytes[2])) << "," << static_cast<long>(static_cast<MidiByte>(bytes[3])) << ") -> " << longRet;
90
91 return longRet;
92 }
93
94 int
midiBytesToInt(const std::string & bytes)95 MidiFile::midiBytesToInt(const std::string &bytes)
96 {
97 if (bytes.length() != 2) {
98 RG_WARNING << "midiBytesToInt(): WARNING: Wrong length for int data (" << bytes.length() << ", should be 2)";
99
100 // TRANSLATOR: "int" is a C++ data type
101 throw Exception(qstrtostr(tr("Wrong length for int data in MIDI stream")));
102 }
103
104 return static_cast<int>(static_cast<MidiByte>(bytes[0])) << 8 |
105 static_cast<int>(static_cast<MidiByte>(bytes[1]));
106 }
107
108 MidiByte
read(std::ifstream * midiFile)109 MidiFile::read(std::ifstream *midiFile)
110 {
111 return static_cast<MidiByte>(read(midiFile, 1)[0]);
112 }
113
114 std::string
read(std::ifstream * midiFile,unsigned long numberOfBytes)115 MidiFile::read(std::ifstream *midiFile, unsigned long numberOfBytes)
116 {
117 if (midiFile->eof()) {
118 RG_WARNING << "read(): MIDI file EOF - got 0 bytes out of " << numberOfBytes;
119
120 throw Exception(qstrtostr(tr("End of MIDI file encountered while reading")));
121 }
122
123 // For each track section we can read only m_trackByteCount bytes.
124 if (m_decrementCount &&
125 numberOfBytes > static_cast<unsigned long>(m_trackByteCount)) {
126
127 RG_WARNING << "read(): Attempt to get more bytes than allowed on Track (" << numberOfBytes << " > " << m_trackByteCount << ")";
128
129 throw Exception(qstrtostr(tr("Attempt to get more bytes than expected on Track")));
130 }
131
132 char fileMidiByte;
133 std::string stringRet;
134
135 // ??? Reading one byte at a time is terribly slow. However, this
136 // routine is usually called with numberOfBytes == 1.
137 while (stringRet.length() < numberOfBytes &&
138 midiFile->read(&fileMidiByte, 1)) {
139 stringRet += fileMidiByte;
140
141 // Kick the event loop to make sure the UI doesn't become
142 // unresponsive during a long load.
143 qApp->processEvents();
144 }
145
146 // Unexpected EOF
147 if (stringRet.length() < numberOfBytes) {
148 RG_WARNING << "read(): Attempt to read past file end - got " << stringRet.length() << " bytes out of " << numberOfBytes;
149
150 throw Exception(qstrtostr(tr("Attempt to read past MIDI file end")));
151 }
152
153 if (m_decrementCount)
154 m_trackByteCount -= numberOfBytes;
155
156 m_bytesRead += numberOfBytes;
157
158 // Every 2000 bytes...
159 if (m_bytesRead >= 2000) {
160 m_bytesRead = 0;
161
162 // Update the progress dialog if one is connected.
163 if (m_progressDialog) {
164 if (m_progressDialog->wasCanceled())
165 throw Exception(qstrtostr(tr("Cancelled by user")));
166
167 // This is the first 20% of the "reading" process.
168 int progressValue = static_cast<int>(
169 static_cast<double>(midiFile->tellg()) /
170 static_cast<double>(m_fileSize) * 20.0);
171
172 m_progressDialog->setValue(progressValue);
173 }
174 }
175
176 return stringRet;
177 }
178
179 long
readNumber(std::ifstream * midiFile,int firstByte)180 MidiFile::readNumber(std::ifstream *midiFile, int firstByte)
181 {
182 if (midiFile->eof())
183 return 0;
184
185 MidiByte midiByte;
186
187 // If we already have the first byte, use it
188 if (firstByte >= 0) {
189 midiByte = static_cast<MidiByte>(firstByte);
190 } else { // read it
191 midiByte = read(midiFile);
192 }
193
194 long longRet = midiByte;
195
196 // See MIDI spec section 4, pages 2 and 11.
197
198 if (midiByte & 0x80) {
199 longRet &= 0x7F;
200 do {
201 midiByte = read(midiFile);
202 longRet = (longRet << 7) + (midiByte & 0x7F);
203 } while (!midiFile->eof() && (midiByte & 0x80));
204 }
205
206 return longRet;
207 }
208
209 void
findNextTrack(std::ifstream * midiFile)210 MidiFile::findNextTrack(std::ifstream *midiFile)
211 {
212 // Conforms to recommendation in the MIDI spec, section 4, page 3:
213 // "Your programs should /expect/ alien chunks and treat them as if
214 // they weren't there." (Emphasis theirs.)
215
216 // Assume not found.
217 m_decrementCount = false;
218 m_trackByteCount = -1;
219
220 // For each chunk
221 while (!midiFile->eof()) {
222 // Read the chunk type and size.
223 std::string chunkType = read(midiFile, 4);
224 long chunkSize = midiBytesToLong(read(midiFile, 4));
225
226 // If we've found a track chunk
227 if (chunkType.compare(0, 4, MIDI_TRACK_HEADER) == 0) {
228 m_trackByteCount = chunkSize;
229 m_decrementCount = true;
230 return;
231 }
232
233 RG_DEBUG << "findNextTrack(): skipping alien chunk. Type:" << chunkType;
234
235 // Alien chunk encountered, initiate evasive maneuvers (skip it).
236 midiFile->seekg(chunkSize, std::ios::cur);
237 }
238
239 // Track not found.
240 RG_WARNING << "findNextTrack(): Couldn't find Track";
241 throw Exception(qstrtostr(tr("File corrupted or in non-standard format")));
242 }
243
244 bool
read(const QString & filename)245 MidiFile::read(const QString &filename)
246 {
247 RG_DEBUG << "read(): filename = " << filename;
248
249 clearMidiComposition();
250
251 // Open the file
252 std::ifstream *midiFile =
253 new std::ifstream(filename.toLocal8Bit(),
254 std::ios::in | std::ios::binary);
255
256 if (!(*midiFile)) {
257 m_error = "File not found or not readable.";
258 m_format = MIDI_FILE_NOT_LOADED;
259 return false;
260 }
261
262 // Compute the file size so we can report progress.
263 midiFile->seekg(0, std::ios::end);
264 m_fileSize = midiFile->tellg();
265 midiFile->seekg(0, std::ios::beg);
266
267 // The parsing process throws string exceptions back up here if we
268 // run into trouble which we can then pass back out to whomever
269 // called us using m_error and a nice bool.
270 try {
271 // Parse the MIDI header first.
272 parseHeader(midiFile);
273
274 // For each track chunk in the MIDI file.
275 for (unsigned track = 0; track < m_numberOfTracks; ++track) {
276
277 RG_DEBUG << "read(): Parsing MIDI file track " << track;
278
279 // Skip any alien chunks.
280 findNextTrack(midiFile);
281
282 RG_DEBUG << "read(): Track has " << m_trackByteCount << " bytes";
283
284 // Read the track into m_midiComposition.
285 parseTrack(midiFile);
286 }
287
288 } catch (const Exception &e) {
289 RG_WARNING << "read() - caught exception - " << e.getMessage();
290
291 m_error = e.getMessage();
292 m_format = MIDI_FILE_NOT_LOADED;
293 return false;
294 }
295
296 midiFile->close();
297
298 return true;
299 }
300
301 void
parseHeader(std::ifstream * midiFile)302 MidiFile::parseHeader(std::ifstream *midiFile)
303 {
304 // The basic MIDI header is 14 bytes.
305 std::string midiHeader = read(midiFile, 14);
306
307 if (midiHeader.size() < 14) {
308 RG_WARNING << "parseHeader() - file header undersized";
309 throw Exception(qstrtostr(tr("Not a MIDI file")));
310 }
311
312 if (midiHeader.compare(0, 4, MIDI_FILE_HEADER) != 0) {
313 RG_WARNING << "parseHeader() - file header not found or malformed";
314 throw Exception(qstrtostr(tr("Not a MIDI file")));
315 }
316
317 long chunkSize = midiBytesToLong(midiHeader.substr(4, 4));
318 m_format = static_cast<FileFormatType>(
319 midiBytesToInt(midiHeader.substr(8, 2)));
320 m_numberOfTracks = midiBytesToInt(midiHeader.substr(10, 2));
321 m_timingDivision = midiBytesToInt(midiHeader.substr(12, 2));
322 m_timingFormat = MIDI_TIMING_PPQ_TIMEBASE;
323
324 if (m_format == MIDI_SEQUENTIAL_TRACK_FILE) {
325 RG_WARNING << "parseHeader() - can't load sequential track (Format 2) MIDI file";
326 throw Exception(qstrtostr(tr("Unexpected MIDI file format")));
327 }
328
329 if (m_timingDivision > 32767) {
330 RG_DEBUG << "parseHeader() - file uses SMPTE timing";
331
332 m_timingFormat = MIDI_TIMING_SMPTE;
333 m_fps = 256 - (m_timingDivision >> 8);
334 m_subframes = (m_timingDivision & 0xff);
335 }
336
337 if (chunkSize > 6) {
338 // Skip any remaining bytes in the header chunk.
339 // MIDI spec section 4, page 5: "[...] more parameters may be
340 // added to the MThd chunk in the future: it is important to
341 // read and honor the length, even if it is longer than 6."
342 midiFile->seekg(chunkSize - 6, std::ios::cur);
343 }
344 }
345
346 static const std::string defaultTrackName = "Imported MIDI";
347
348 void
parseTrack(std::ifstream * midiFile)349 MidiFile::parseTrack(std::ifstream *midiFile)
350 {
351 // The term "Track" is overloaded in this routine. The first
352 // meaning is a track in the MIDI file. That is what this routine
353 // processes. A single track from a MIDI file. The second meaning
354 // is a track in m_midiComposition. This is the most common usage.
355 // To improve clarity, "MIDI file track" will be used to refer to
356 // the first sense of the term. Occasionally, "m_midiComposition
357 // track" will be used to refer to the second sense.
358
359 // Absolute time of the last event on any track.
360 unsigned long eventTime = 0;
361
362 // lastTrackNum is the track for all events provided they're
363 // all on the same channel. If we find events on more than one
364 // channel, we increment lastTrackNum and record the mapping from
365 // channel to trackNum in channelToTrack.
366 TrackId lastTrackNum = m_midiComposition.size();
367
368 // MIDI channel to m_midiComposition track.
369 // Note: This would be a vector<TrackId> but TrackId is unsigned
370 // and we need -1 to indicate "not yet used"
371 std::vector<int> channelToTrack(16, -1);
372
373 // This is used to store the last absolute time found on each track,
374 // allowing us to modify delta-times correctly when separating events
375 // out from one to multiple tracks
376 std::map<int /*track*/, unsigned long /*lastTime*/> lastEventTime;
377 lastEventTime[lastTrackNum] = 0;
378
379 // Meta-events don't have a channel, so we place them in a fixed
380 // track number instead
381 TrackId metaTrack = lastTrackNum;
382
383 std::string trackName = defaultTrackName;
384 std::string instrumentName;
385
386 // Remember the last non-meta status byte (-1 if we haven't seen one)
387 int runningStatus = -1;
388
389 bool firstTrack = true;
390
391 RG_DEBUG << "parseTrack(): last track number is " << lastTrackNum;
392
393 // While there is still data to read in the MIDI file track.
394 // Why "m_trackByteCount > 1" instead of "m_trackByteCount > 0"? Since
395 // no event and its associated delta time can fit in just one
396 // byte, a single remaining byte in the MIDI file track has to be padding.
397 // This is obscure and non-standard, but such files do exist; ordinarily
398 // there should be no bytes in the MIDI file track after the last event.
399 while (!midiFile->eof() && m_trackByteCount > 1) {
400
401 unsigned long deltaTime = readNumber(midiFile);
402
403 RG_DEBUG << "parseTrack(): read delta time " << deltaTime;
404
405 // Compute the absolute time for the event.
406 eventTime += deltaTime;
407
408 // Get a single byte
409 MidiByte midiByte = read(midiFile);
410
411 MidiByte statusByte = 0;
412 MidiByte data1 = 0;
413
414 // If this is a status byte, use it.
415 if (midiByte & MIDI_STATUS_BYTE_MASK) {
416 RG_DEBUG << "parseTrack(): have new status byte" << QString("0x%1").arg(midiByte, 0, 16);
417
418 statusByte = midiByte;
419 data1 = read(midiFile);
420 } else { // Use running status.
421 // If we haven't seen a status byte yet, fail.
422 if (runningStatus < 0)
423 throw Exception(qstrtostr(tr("Running status used for first event in track")));
424
425 statusByte = static_cast<MidiByte>(runningStatus);
426 data1 = midiByte;
427
428 RG_DEBUG << "parseTrack(): using running status (byte " << QString("0x%1").arg(midiByte, 0, 16) << " found)";
429 }
430
431 if (statusByte == MIDI_FILE_META_EVENT) {
432
433 MidiByte metaEventCode = data1;
434 unsigned messageLength = readNumber(midiFile);
435
436 RG_DEBUG << "parseTrack(): Meta event of type " << QString("0x%1").arg(metaEventCode, 0, 16) << " and " << messageLength << " bytes found";
437
438 std::string metaMessage = read(midiFile, messageLength);
439
440 // Compute the difference between this event and the previous
441 // event on this track.
442 deltaTime = eventTime - lastEventTime[metaTrack];
443 // Store the absolute time of the last event on this track.
444 lastEventTime[metaTrack] = eventTime;
445
446 // create and store our event
447 MidiEvent *e = new MidiEvent(deltaTime,
448 MIDI_FILE_META_EVENT,
449 metaEventCode,
450 metaMessage);
451 m_midiComposition[metaTrack].push_back(e);
452
453 if (metaEventCode == MIDI_TRACK_NAME)
454 trackName = metaMessage;
455 else if (metaEventCode == MIDI_INSTRUMENT_NAME)
456 instrumentName = metaMessage;
457
458 // Get the next event.
459 continue;
460 }
461
462 runningStatus = statusByte;
463
464 int channel = (statusByte & MIDI_CHANNEL_NUM_MASK);
465
466 // If this channel hasn't been seen yet in this MIDI file track
467 if (channelToTrack[channel] == -1) {
468 // If this is the first m_midiComposition track we've
469 // used
470 if (firstTrack) {
471 // We've already allocated an m_midiComposition track for
472 // the first channel we encounter. Use it.
473 firstTrack = false;
474 } else { // We need a new track.
475 // Allocate a new track for this channel.
476 ++lastTrackNum;
477 lastEventTime[lastTrackNum] = 0;
478 }
479
480 RG_DEBUG << "parseTrack(): new channel map entry: channel " << channel << " -> track " << lastTrackNum;
481
482 channelToTrack[channel] = lastTrackNum;
483 m_trackChannelMap[lastTrackNum] = channel;
484 }
485
486 TrackId trackNum = channelToTrack[channel];
487
488 #ifdef DEBUG
489 {
490 static int prevTrackNum = -1;
491 static int prevChannel = -1;
492
493 // If we're on a different track or channel
494 if (prevTrackNum != static_cast<int>(trackNum) ||
495 prevChannel != channel) {
496
497 // Report it for debugging.
498 RG_DEBUG << "parseTrack(): track number for channel " << channel << " is " << trackNum;
499
500 prevTrackNum = trackNum;
501 prevChannel = channel;
502 }
503 }
504 #endif
505
506 // Compute the difference between this event and the previous
507 // event on this track.
508 deltaTime = eventTime - lastEventTime[trackNum];
509 // Store the absolute time of the last event on this track.
510 lastEventTime[trackNum] = eventTime;
511
512 switch (statusByte & MIDI_MESSAGE_TYPE_MASK) {
513 case MIDI_NOTE_ON: // These events have two data bytes.
514 case MIDI_NOTE_OFF:
515 case MIDI_POLY_AFTERTOUCH:
516 case MIDI_CTRL_CHANGE:
517 case MIDI_PITCH_BEND:
518 {
519 MidiByte data2 = read(midiFile);
520
521 // create and store our event
522 MidiEvent *midiEvent =
523 new MidiEvent(deltaTime, statusByte, data1, data2);
524 m_midiComposition[trackNum].push_back(midiEvent);
525
526 if (statusByte != MIDI_PITCH_BEND) {
527 RG_DEBUG << "parseTrack(): MIDI event for channel " << channel + 1 << " (track " << trackNum << ')';
528 RG_DEBUG << *midiEvent;
529 }
530 }
531 break;
532
533 case MIDI_PROG_CHANGE: // These events have a single data byte.
534 case MIDI_CHNL_AFTERTOUCH:
535 {
536 RG_DEBUG << "parseTrack(): Program change (Cn) or channel aftertouch (Dn): time " << deltaTime << ", code " << QString("0x%1").arg(statusByte, 0, 16) << ", data " << (int) data1 << " going to track " << trackNum;
537
538 // create and store our event
539 MidiEvent *midiEvent =
540 new MidiEvent(deltaTime, statusByte, data1);
541 m_midiComposition[trackNum].push_back(midiEvent);
542 }
543 break;
544
545 case MIDI_SYSTEM_EXCLUSIVE:
546 {
547 unsigned messageLength = readNumber(midiFile, data1);
548
549 RG_DEBUG << "parseTrack(): SysEx of " << messageLength << " bytes found";
550
551 std::string sysex = read(midiFile, messageLength);
552
553 if (MidiByte(sysex[sysex.length() - 1]) !=
554 MIDI_END_OF_EXCLUSIVE) {
555 RG_WARNING << "parseTrack() - malformed or unsupported SysEx type";
556 continue;
557 }
558
559 // Chop off the EOX.
560 sysex = sysex.substr(0, sysex.length() - 1);
561
562 // create and store our event
563 MidiEvent *midiEvent =
564 new MidiEvent(deltaTime,
565 MIDI_SYSTEM_EXCLUSIVE,
566 sysex);
567 m_midiComposition[trackNum].push_back(midiEvent);
568 }
569 break;
570
571 case MIDI_END_OF_EXCLUSIVE:
572 RG_WARNING << "parseTrack() - Found a stray MIDI_END_OF_EXCLUSIVE";
573 break;
574
575 default:
576 RG_WARNING << "parseTrack() - Unsupported MIDI Status Byte: " << QString("0x%1").arg(statusByte, 0, 16);
577 break;
578 }
579 }
580
581 // If the MIDI file track has a padding byte, read and discard it
582 // to make sure that the stream is positioned at the beginning of
583 // the following MIDI file track (if there is one.)
584 if (m_trackByteCount == 1)
585 midiFile->ignore();
586
587 if (instrumentName != "")
588 trackName += " (" + instrumentName + ")";
589
590 // Fill out the Track Names
591 for (TrackId i = metaTrack; i <= lastTrackNum; ++i)
592 m_trackNames.push_back(trackName);
593 }
594
595 bool
convertToRosegarden(const QString & filename,RosegardenDocument * doc)596 MidiFile::convertToRosegarden(const QString &filename, RosegardenDocument *doc)
597 {
598 Profiler profiler("MidiFile::convertToRosegarden");
599
600 // Read the MIDI file into m_midiComposition.
601 if (!read(filename))
602 return false;
603
604 if (m_midiComposition.size() != m_trackNames.size()) {
605 RG_WARNING << "convertToRosegarden(): m_midiComposition and m_trackNames size mismatch";
606 return false;
607 }
608
609 Composition &composition = doc->getComposition();
610 Studio &studio = doc->getStudio();
611
612 composition.clear();
613
614 // Clear down the assigned Instruments we already have
615 studio.unassignAllInstruments();
616
617 RG_DEBUG << "convertToRosegarden(): MIDI COMP SIZE = " << m_midiComposition.size();
618
619 if (m_timingFormat == MIDI_TIMING_SMPTE) {
620
621 // If we have SMPTE timecode (i.e. seconds and frames, roughly
622 // equivalent to RealTime timestamps) then we need to add any
623 // tempo change events _first_ before we can do any conversion
624 // from SMPTE to musical time, because this conversion depends
625 // on tempo. Also we need to add tempo changes in time order,
626 // not track order, because their own timestamps depend on all
627 // prior tempo changes.
628
629 // In principle there's no harm in doing this for non-SMPTE
630 // files as well, but there's no gain and it's probably not a
631 // good idea to mess with file loading just for the sake of
632 // slightly simpler code. So, SMPTE only.
633
634 typedef std::map<int /*time*/, tempoT> TempoMap;
635 TempoMap tempi;
636
637 // For each track
638 for (TrackId i = 0; i < m_midiComposition.size(); ++i) {
639 // For each event
640 for (MidiTrack::const_iterator midiEvent = m_midiComposition[i].begin();
641 midiEvent != m_midiComposition[i].end();
642 ++midiEvent) {
643 if ((*midiEvent)->isMeta()) {
644 // If we have a set tempo meta-event
645 if ((*midiEvent)->getMetaEventCode() == MIDI_SET_TEMPO) {
646 MidiByte m0 = (*midiEvent)->getMetaMessage()[0];
647 MidiByte m1 = (*midiEvent)->getMetaMessage()[1];
648 MidiByte m2 = (*midiEvent)->getMetaMessage()[2];
649 long tempo = (((m0 << 8) + m1) << 8) + m2;
650 if (tempo != 0) {
651 double qpm = 60000000.0 / double(tempo);
652 tempoT rgt(Composition::getTempoForQpm(qpm));
653 // Store the tempo in the tempo map.
654 // ??? Strange. The event's time is a delta
655 // time at this point. Seems wrong.
656 tempi[(*midiEvent)->getTime()] = rgt;
657 }
658 }
659 }
660 }
661 }
662
663 // For each set tempo meta-event
664 for (TempoMap::const_iterator i = tempi.begin();
665 i != tempi.end();
666 ++i) {
667 timeT t = composition.getElapsedTimeForRealTime(
668 RealTime::frame2RealTime(i->first, m_fps * m_subframes));
669 composition.addTempoAtTime(t, i->second);
670 }
671 }
672
673 const int rosegardenPPQ = Note(Note::Crotchet).getDuration();
674 const int midiFilePPQ = m_timingDivision ? m_timingDivision : 96;
675 // Conversion factor.
676 const double midiToRgTime =
677 static_cast<double>(rosegardenPPQ) /
678 static_cast<double>(midiFilePPQ);
679
680 // Used to expand the composition if needed.
681 timeT maxTime = 0;
682
683 Segment *conductorSegment = nullptr;
684
685 // Time Signature
686 int numerator = 4;
687 int denominator = 4;
688
689 // Destination TrackId in the Composition.
690 TrackId rosegardenTrackId = 0;
691
692 // For each track
693 // ??? BIG loop.
694 for (TrackId trackId = 0;
695 trackId < m_midiComposition.size();
696 ++trackId) {
697
698 if (m_progressDialog) {
699 if (m_progressDialog->wasCanceled()) {
700 m_error = qstrtostr(tr("Cancelled by user"));
701 return false;
702 }
703
704 // 20% total in file import itself (see read()) and then 80%
705 // split over the tracks.
706 int progressValue = 20 + static_cast<int>(
707 80.0 * trackId / m_midiComposition.size());
708
709 //RG_DEBUG << "convertToRosegarden() progressValue: " << progressValue;
710
711 m_progressDialog->setValue(progressValue);
712 }
713
714 // Kick the event loop.
715 qApp->processEvents();
716
717 timeT absTime = 0;
718
719 // Convert the event times from delta to absolute for
720 // consolidateNoteEvents().
721 for (MidiTrack::iterator eventIter = m_midiComposition[trackId].begin();
722 eventIter != m_midiComposition[trackId].end();
723 ++eventIter) {
724 absTime += (*eventIter)->getTime();
725 (*eventIter)->setTime(absTime);
726 }
727
728 // Consolidate NOTE ON and NOTE OFF events into NOTE ON events with
729 // a duration.
730 consolidateNoteEvents(trackId);
731
732 InstrumentId instrumentId = MidiInstrumentBase;
733
734 // If this track has a channel, use that channel's instrument.
735 if (m_trackChannelMap.find(trackId) != m_trackChannelMap.end()) {
736 instrumentId = MidiInstrumentBase + m_trackChannelMap[trackId];
737 }
738
739 Track *track = new Track(rosegardenTrackId, // id
740 instrumentId, // instrument
741 rosegardenTrackId, // position
742 m_trackNames[trackId], // label
743 false); // muted
744
745 Segment *segment = new Segment;
746 segment->setLabel(m_trackNames[trackId]);
747 segment->setTrack(rosegardenTrackId);
748 segment->setStartTime(0);
749
750 RG_DEBUG << "convertToRosegarden(): New Rosegarden track: id = " << rosegardenTrackId << ", instrument = " << instrumentId;
751
752 // Used for filling the space between events with rests. Also used
753 // for padding the end of the track with rests.
754 timeT endOfLastNote = 0;
755
756 // Statistics.
757 int noteCount = 0;
758 int keySigCount = 0;
759
760 // For each event on the current track
761 // ??? BIG loop.
762 for (MidiTrack::const_iterator midiEventIter =
763 m_midiComposition[trackId].begin();
764 midiEventIter != m_midiComposition[trackId].end();
765 ++midiEventIter) {
766 const MidiEvent &midiEvent = **midiEventIter;
767
768 // Kick the event loop.
769 qApp->processEvents();
770
771 const timeT midiAbsoluteTime = midiEvent.getTime();
772 const timeT midiDuration = midiEvent.getDuration();
773 timeT rosegardenTime = 0;
774 timeT rosegardenDuration = 0;
775
776 if (m_timingFormat == MIDI_TIMING_PPQ_TIMEBASE) {
777 rosegardenTime =
778 static_cast<timeT>(midiAbsoluteTime * midiToRgTime);
779 rosegardenDuration =
780 static_cast<timeT>(midiDuration * midiToRgTime);
781 } else {
782
783 // SMPTE timestamps are a count of the number of
784 // subframes, where the number of subframes per frame
785 // and frames per second have been defined in the file
786 // header (stored as m_subframes, m_fps). We need to
787 // go through a realtime -> musical time conversion
788 // for these, having added our tempo changes earlier
789
790 rosegardenTime = composition.getElapsedTimeForRealTime(
791 RealTime::frame2RealTime(midiAbsoluteTime,
792 m_fps * m_subframes));
793
794 rosegardenDuration = composition.getElapsedTimeForRealTime(
795 RealTime::frame2RealTime(midiAbsoluteTime + midiDuration,
796 m_fps * m_subframes))
797 - rosegardenTime;
798 }
799
800 RG_DEBUG << "convertToRosegarden(): MIDI file import: event time " << rosegardenTime
801 << ", duration " << rosegardenDuration
802 << ", event type " << QString("0x%1").arg(midiEvent.getMessageType(), 0, 16)
803 << ", previous max time " << maxTime
804 << ", potential max time " << (rosegardenTime + rosegardenDuration)
805 << ", ev raw time " << midiAbsoluteTime
806 << ", ev raw duration " << midiDuration
807 << ", crotchet " << Note(Note::Crotchet).getDuration()
808 << ", midiToRgTime " << midiToRgTime
809 << ", sfps " << m_fps * m_subframes;
810
811 if (rosegardenTime + rosegardenDuration > maxTime)
812 maxTime = rosegardenTime + rosegardenDuration;
813
814 // If we don't have any events yet
815 if (segment->empty()) {
816 // Save the beginning of the bar so we can pad to the
817 // left with rests.
818 // ??? But if we have a loop with a precise start and end,
819 // this ruins the start. This would preserve it:
820 // endOfLastNote = rosegardenTime;
821 // If the user wants the beginning on a bar, they can
822 // easily do that. We shouldn't be modifying things.
823 endOfLastNote = composition.getBarStartForTime(rosegardenTime);
824 }
825
826 // The incoming midiEvent is transformed into this rosegardenEvent.
827 Event *rosegardenEvent = nullptr;
828
829 if (midiEvent.isMeta()) {
830
831 switch (midiEvent.getMetaEventCode()) {
832
833 case MIDI_TEXT_EVENT: {
834 std::string text = midiEvent.getMetaMessage();
835 rosegardenEvent =
836 Text(text).getAsEvent(rosegardenTime);
837 break;
838 }
839
840 case MIDI_LYRIC: {
841 std::string text = midiEvent.getMetaMessage();
842 rosegardenEvent =
843 Text(text, Text::Lyric).getAsEvent(rosegardenTime);
844 break;
845 }
846
847 case MIDI_TEXT_MARKER: {
848 std::string text = midiEvent.getMetaMessage();
849 composition.addMarker(
850 new Marker(rosegardenTime, text, ""));
851 break;
852 }
853
854 case MIDI_COPYRIGHT_NOTICE:
855 composition.setCopyrightNote(midiEvent.getMetaMessage());
856 break;
857
858 case MIDI_TRACK_NAME:
859 // We already handled this in parseTrack().
860 break;
861
862 case MIDI_INSTRUMENT_NAME:
863 // We already handled this in parseTrack().
864 break;
865
866 case MIDI_END_OF_TRACK: {
867 timeT trackEndTime = rosegardenTime;
868
869 // If the track's empty (or worse)
870 if (trackEndTime - segment->getStartTime() <= 0) {
871 RG_WARNING << "convertToRosegarden(): Zero-length track encountered";
872
873 // Make it a full bar.
874 trackEndTime = segment->getStartTime() +
875 Note(Note::Semibreve).getDuration() *
876 numerator / denominator;
877 }
878
879 // If there's space between the last note and the track
880 // end, fill it out with rests.
881 if (endOfLastNote < trackEndTime) {
882 // If there's nothing in the segment yet, then we
883 // shouldn't fill with rests because we don't want
884 // to cause the otherwise empty segment to be created.
885 if (!segment->empty())
886 segment->fillWithRests(trackEndTime);
887 }
888
889 break;
890 }
891
892 case MIDI_SET_TEMPO:
893 // We've already handled the SMPTE case above.
894 if (m_timingFormat == MIDI_TIMING_PPQ_TIMEBASE) {
895 MidiByte m0 = midiEvent.getMetaMessage()[0];
896 MidiByte m1 = midiEvent.getMetaMessage()[1];
897 MidiByte m2 = midiEvent.getMetaMessage()[2];
898
899 // usecs per quarter-note
900 long midiTempo = (((m0 << 8) + m1) << 8) + m2;
901
902 if (midiTempo != 0) {
903 // Convert to quarter-notes per minute.
904 double qpm = 60000000.0 / midiTempo;
905 tempoT rosegardenTempo(
906 Composition::getTempoForQpm(qpm));
907 //RG_DEBUG << "convertToRosegarden(): converted MIDI tempo " << midiTempo << " to Rosegarden tempo " << rosegardenTempo;
908 composition.addTempoAtTime(
909 rosegardenTime, rosegardenTempo);
910 }
911 }
912 break;
913
914 case MIDI_TIME_SIGNATURE: {
915 std::string metaMessage = midiEvent.getMetaMessage();
916
917 numerator = static_cast<int>(metaMessage[0]);
918 denominator = 1 << static_cast<int>(metaMessage[1]);
919
920 // A MIDI time signature has additional information that
921 // we ignore. From the spec, section 4 page 10:
922 // metaMessage[2] "expresses the number of *MIDI clocks*
923 // in a metronome tick."
924 // metaMessage[3] "expresses the number of notated
925 // 32nd-notes in what MIDI thinks of as a quarter-note
926 // (24 MIDI clocks)."
927
928 // Fall back on 4/4
929 if (numerator == 0)
930 numerator = 4;
931 if (denominator == 0)
932 denominator = 4;
933
934 composition.addTimeSignature(
935 rosegardenTime,
936 TimeSignature(numerator, denominator));
937
938 break;
939 }
940
941 case MIDI_KEY_SIGNATURE: {
942 std::string metaMessage = midiEvent.getMetaMessage();
943
944 // Whether char is signed or unsigned is platform
945 // dependent. Casting to signed char guarantees the
946 // correct results on all platforms.
947
948 int accidentals =
949 abs(static_cast<signed char>(metaMessage[0]));
950 bool isSharp =
951 (static_cast<signed char>(metaMessage[0]) >= 0);
952
953 bool isMinor = (metaMessage[1] != 0);
954
955 try {
956 rosegardenEvent =
957 Rosegarden::Key(accidentals, isSharp, isMinor).
958 getAsEvent(rosegardenTime);
959 }
960 catch (...) {
961 RG_WARNING << "convertToRosegarden() - badly formed key signature";
962 break;
963 }
964
965 ++keySigCount;
966
967 break;
968 }
969
970 case MIDI_SEQUENCE_NUMBER:
971 case MIDI_CHANNEL_PREFIX_OR_PORT:
972 case MIDI_CUE_POINT:
973 case MIDI_CHANNEL_PREFIX:
974 case MIDI_SEQUENCER_SPECIFIC:
975 case MIDI_SMPTE_OFFSET:
976 default:
977 RG_WARNING << "convertToRosegarden() - unsupported META event code " << QString("0x%1").arg(midiEvent.getMetaEventCode(), 0, 16);
978 break;
979 }
980
981 } else { // Not a meta-event.
982 switch (midiEvent.getMessageType()) {
983 case MIDI_NOTE_ON:
984
985 // Note-off? Ignore. Note-ons and note-offs have been
986 // consolidated. Stray note-offs can be ignored.
987 if (midiEvent.getVelocity() == 0)
988 break;
989
990 endOfLastNote = rosegardenTime + rosegardenDuration;
991
992 RG_DEBUG << "convertToRosegarden(): note at " << rosegardenTime << ", duration " << rosegardenDuration << ", midi time " << midiAbsoluteTime << " and duration " << midiDuration;
993
994 rosegardenEvent = new Event(Note::EventType,
995 rosegardenTime,
996 rosegardenDuration);
997 rosegardenEvent->set<Int>(BaseProperties::PITCH,
998 midiEvent.getPitch());
999 rosegardenEvent->set<Int>(BaseProperties::VELOCITY,
1000 midiEvent.getVelocity());
1001
1002 ++noteCount;
1003
1004 break;
1005
1006 case MIDI_NOTE_OFF:
1007 // Note-off? Ignore. Note-ons and note-offs have been
1008 // consolidated. Stray note-offs can be ignored.
1009 break;
1010
1011 case MIDI_PROG_CHANGE:
1012 rosegardenEvent = ProgramChange::makeEvent(
1013 rosegardenTime,
1014 midiEvent.getData1()); // program
1015 break;
1016
1017 case MIDI_CTRL_CHANGE:
1018 rosegardenEvent = Controller::makeEvent(
1019 rosegardenTime,
1020 midiEvent.getData1(), // number
1021 midiEvent.getData2()); // value
1022 break;
1023
1024 case MIDI_PITCH_BEND:
1025 rosegardenEvent = PitchBend::makeEvent(
1026 rosegardenTime,
1027 midiEvent.getData2(), // msb
1028 midiEvent.getData1()); // lsb
1029 break;
1030
1031 case MIDI_SYSTEM_EXCLUSIVE:
1032 rosegardenEvent = SystemExclusive::makeEvent(
1033 rosegardenTime,
1034 midiEvent.getMetaMessage()); // rawData
1035 break;
1036
1037 case MIDI_POLY_AFTERTOUCH:
1038 rosegardenEvent = KeyPressure::makeEvent(
1039 rosegardenTime,
1040 midiEvent.getData1(), // pitch
1041 midiEvent.getData2()); // pressure
1042 break;
1043
1044 case MIDI_CHNL_AFTERTOUCH:
1045 rosegardenEvent = ChannelPressure::makeEvent(
1046 rosegardenTime,
1047 midiEvent.getData1()); // pressure
1048 break;
1049
1050 default:
1051 RG_WARNING << "convertToRosegarden() - Unsupported event code = " << QString("0x%1").arg(midiEvent.getMessageType(), 0, 16);
1052 break;
1053 } // switch message type (non-meta-event)
1054 } // if meta-event
1055
1056 if (rosegardenEvent) {
1057 // If there's a gap between the last note and this event
1058 if (endOfLastNote < rosegardenTime) {
1059 // Fill it with rests.
1060 segment->fillWithRests(endOfLastNote, rosegardenTime);
1061 }
1062 segment->insert(rosegardenEvent);
1063 }
1064 } // for each event
1065
1066 // Empty segment? Toss it.
1067 if (segment->empty()) {
1068 delete segment;
1069 segment = nullptr;
1070 delete track;
1071 track = nullptr;
1072
1073 // Try the next track
1074 continue;
1075 }
1076
1077 // Need to count rests separately.
1078 int restCount = 0;
1079
1080 // For each event in the segment
1081 for (Segment::const_iterator i = segment->begin();
1082 i != segment->end();
1083 ++i) {
1084 const Event &event = **i;
1085
1086 if (event.isa(Note::EventRestType))
1087 ++restCount;
1088 }
1089
1090 int nonRestCount = segment->size() - restCount;
1091
1092 RG_DEBUG << "convertToRosegarden(): Track analysis...";
1093 RG_DEBUG << " Total events:" << segment->size();
1094 RG_DEBUG << " Notes:" << noteCount;
1095 RG_DEBUG << " Rests:" << restCount;
1096 RG_DEBUG << " Non-rests:" << nonRestCount;
1097 RG_DEBUG << " Key signatures:" << keySigCount;
1098
1099 // Key sigs and no notes means a conductor segment.
1100 // Note: A conductor track also contains time signatures and
1101 // tempo events, however we've already added those to the
1102 // composition above. They are not added to the segment.
1103 if (noteCount == 0 && keySigCount > 0) {
1104 conductorSegment = segment;
1105
1106 // If this conductor segment has nothing but rests and key sigs,
1107 // there's no need to add it to the composition.
1108 // ??? This probably never happens. Conductor tracks almost
1109 // always have a few text events in them.
1110 if (nonRestCount == keySigCount) {
1111 // ??? Memory leak. conductorSegment will not be deleted.
1112 continue;
1113 }
1114 }
1115
1116 // If this track has no key sigs and we have a conductor segment
1117 if (keySigCount == 0 && conductorSegment) {
1118 // copy across any key sigs from the conductor segment
1119
1120 timeT segmentStartTime = segment->getStartTime();
1121 timeT earliestEventEndTime = segmentStartTime;
1122
1123 // For each event in the segment
1124 for (Segment::iterator i = conductorSegment->begin();
1125 i != conductorSegment->end();
1126 ++i) {
1127 const Event &event = **i;
1128
1129 // If this isn't a key sig, try the next event.
1130 if (!event.isa(Rosegarden::Key::EventType))
1131 continue;
1132
1133 // ??? Should we really expand the segment? Seems like
1134 // it would make more sense to only add the key sigs
1135 // that fall within the segment's time. If there isn't
1136 // one at the very start of the segment, then insert
1137 // the previous.
1138
1139 // Adjust the earliest event time if needed.
1140 if (event.getAbsoluteTime() + event.getDuration() <
1141 earliestEventEndTime) {
1142 earliestEventEndTime =
1143 event.getAbsoluteTime() + event.getDuration();
1144 }
1145
1146 segment->insert(new Event(event));
1147 }
1148
1149 // Add rests to the beginning.
1150 // ??? No need. It happens anyway. Must be someone else doing
1151 // this.
1152 if (earliestEventEndTime < segmentStartTime)
1153 segment->fillWithRests(earliestEventEndTime,
1154 segmentStartTime);
1155 }
1156
1157 // Configure the Instrument based on events at time 0.
1158 configureInstrument(track, segment,
1159 studio.getInstrumentById(instrumentId));
1160
1161 #ifdef DEBUG
1162 RG_DEBUG << "convertToRosegarden(): MIDI import: adding segment with start time " << segment->getStartTime() << " and end time " << segment->getEndTime();
1163 // For this secret event dump to be triggered, a track that ends
1164 // on beat 4 (2880 = 3 * 960) is required. To generate such
1165 // a track in rg, set the time signature to 3/4 and reduce the
1166 // composition to one bar in length. Make a single bar segment and
1167 // add events to it. Export as MIDI.
1168 if (segment->getEndTime() == 2880) {
1169 RG_DEBUG << " events:";
1170 for (Segment::iterator i = segment->begin();
1171 i != segment->end(); ++i) {
1172 RG_DEBUG << **i;
1173 }
1174 }
1175 #endif
1176
1177 // This does not send a "track added" notification.
1178 composition.addTrack(track);
1179
1180 // Notify Composition observers of the new track.
1181 std::vector<TrackId> trackIds;
1182 trackIds.push_back(track->getId());
1183 composition.notifyTracksAdded(trackIds);
1184
1185 // This also sends a "segment added" notification.
1186 composition.addSegment(segment);
1187
1188 // Next Track in the Composition.
1189 ++rosegardenTrackId;
1190
1191 } // for each track
1192
1193 // Adjust the composition to hold the segments.
1194 composition.setEndMarker(composition.getBarEndForTime(maxTime));
1195
1196 return true;
1197 }
1198
configureInstrument(Track * track,Segment * segment,Instrument * instrument)1199 void MidiFile::configureInstrument(
1200 Track *track, Segment *segment, Instrument *instrument)
1201 {
1202 if (!instrument)
1203 return;
1204
1205 instrument->setPercussion(
1206 instrument->getNaturalChannel() ==
1207 MIDI_PERCUSSION_CHANNEL);
1208
1209 track->setInstrument(instrument->getId());
1210
1211 Segment::iterator msbIter = segment->end();
1212 Segment::iterator lsbIter = segment->end();
1213
1214 // For each event in the segment
1215 for (Segment::iterator i = segment->begin();
1216 i != segment->end();
1217 /* increment before use */) {
1218 // Increment before use. This allows us to delete events
1219 // from the Segment.
1220 Segment::iterator j = i++;
1221
1222 const Event &event = **j;
1223
1224 // We only care about events at time 0.
1225 if (event.getAbsoluteTime() > 0)
1226 break;
1227
1228 // If this is a Bank Select MSB, save it.
1229 if (event.isa(Controller::EventType) &&
1230 event.get<Int>(Controller::NUMBER) ==
1231 MIDI_CONTROLLER_BANK_MSB) {
1232 msbIter = j;
1233 continue;
1234 }
1235
1236 // If this is a Bank Select LSB, save it.
1237 if (event.isa(Controller::EventType) &&
1238 event.get<Int>(Controller::NUMBER) ==
1239 MIDI_CONTROLLER_BANK_LSB) {
1240 lsbIter = j;
1241 continue;
1242 }
1243
1244 // If this is a Program Change
1245 if (event.isa(ProgramChange::EventType)) {
1246 // Configure the instrument.
1247 int program = event.get<Int>(ProgramChange::PROGRAM);
1248 instrument->setProgramChange(program);
1249 instrument->setSendProgramChange(true);
1250
1251 // Remove the program change from the Segment.
1252 segment->erase(j);
1253
1254 continue;
1255 }
1256
1257 // If this is a control change
1258 if (event.isa(Controller::EventType)) {
1259 int controller = event.get<Int>(Controller::NUMBER);
1260
1261 // Only process the four that usually appear in the
1262 // Instrument Parameters box.
1263 if (controller == MIDI_CONTROLLER_VOLUME ||
1264 controller == MIDI_CONTROLLER_PAN ||
1265 controller == MIDI_CONTROLLER_REVERB ||
1266 controller == MIDI_CONTROLLER_CHORUS) {
1267
1268 // Configure the Instrument.
1269 instrument->setControllerValue(
1270 controller,
1271 event.get<Int>(Controller::VALUE));
1272
1273 // Remove the event from the Segment.
1274 segment->erase(j);
1275
1276 continue;
1277 }
1278 }
1279 }
1280
1281 // If we have both msb and lsb for bank select
1282 if (msbIter != segment->end() && lsbIter != segment->end()) {
1283 // Configure the Instrument
1284 instrument->setMSB((*msbIter)->get<Int>(Controller::VALUE));
1285 instrument->setLSB((*lsbIter)->get<Int>(Controller::VALUE));
1286 instrument->setSendBankSelect(true);
1287
1288 // Remove the events.
1289 segment->erase(msbIter);
1290 segment->erase(lsbIter);
1291 }
1292
1293 // Use the program name for a label if nothing else
1294 // was found.
1295 std::string programName = instrument->getProgramName();
1296 if (programName != "") {
1297 if (track->getLabel() == defaultTrackName)
1298 track->setLabel(instrument->getProgramName());
1299 if (segment->getLabel() == defaultTrackName)
1300 segment->setLabel(instrument->getProgramName());
1301 }
1302 }
1303
1304 bool
convertToMidi(RosegardenDocument * doc,const QString & filename)1305 MidiFile::convertToMidi(RosegardenDocument *doc, const QString &filename)
1306 {
1307 Composition &composition = doc->getComposition();
1308
1309 RosegardenMainWindow *mainWindow = RosegardenMainWindow::self();
1310 bool haveUI = (mainWindow != nullptr);
1311
1312 SequenceManager *sequenceManager = nullptr;
1313
1314 if (haveUI) {
1315 // Use the UI's sequence manager.
1316 sequenceManager = RosegardenMainWindow::self()->getSequenceManager();
1317 } else { // No UI. Command line conversion.
1318 // Create our own temporary SequenceManager.
1319 sequenceManager = new SequenceManager();
1320 sequenceManager->setDocument(doc);
1321 // Create a new CompositionMapper.
1322 sequenceManager->resetCompositionMapper();
1323 }
1324
1325 MappedBufMetaIterator *metaIterator =
1326 sequenceManager->makeTempMetaiterator();
1327
1328 RealTime start = composition.getElapsedRealTime(composition.getStartMarker());
1329 RealTime end = composition.getElapsedRealTime(composition.getEndMarker());
1330
1331 // For ramping, we need to get MappedEvents in order, but
1332 // fetchEvents's order is only approximately
1333 // right, so we sort events first.
1334 SortingInserter sorter;
1335
1336 // Fetch the channel setup for all MIDI tracks in Fixed channel mode.
1337 metaIterator->fetchFixedChannelSetup(sorter);
1338
1339 metaIterator->jumpToTime(start);
1340 // Copy the events from metaIterator to sorter.
1341 // Give the end a little margin to make it insert noteoffs at the
1342 // end. If they tied with the end they'd get lost.
1343 metaIterator->fetchEvents(sorter, start, end + RealTime(0,1000));
1344
1345 delete metaIterator;
1346
1347 MidiInserter inserter(composition, 480, end);
1348 // Copy the events from sorter to inserter.
1349 sorter.insertSorted(inserter);
1350 // Finally, copy the events from inserter to m_midiComposition.
1351 inserter.assignToMidiFile(*this);
1352
1353 // Write m_midiComposition to the file.
1354 bool success = write(filename);
1355
1356 // Clean up if needed.
1357 if (!haveUI)
1358 delete sequenceManager;
1359
1360 return success;
1361 }
1362
1363 void
writeInt(std::ofstream * midiFile,int number)1364 MidiFile::writeInt(std::ofstream *midiFile, int number)
1365 {
1366 *midiFile << static_cast<MidiByte>((number & 0xFF00) >> 8);
1367 *midiFile << static_cast<MidiByte>(number & 0x00FF);
1368 }
1369
1370 void
writeLong(std::ofstream * midiFile,unsigned long number)1371 MidiFile::writeLong(std::ofstream *midiFile, unsigned long number)
1372 {
1373 *midiFile << static_cast<MidiByte>((number & 0xFF000000) >> 24);
1374 *midiFile << static_cast<MidiByte>((number & 0x00FF0000) >> 16);
1375 *midiFile << static_cast<MidiByte>((number & 0x0000FF00) >> 8);
1376 *midiFile << static_cast<MidiByte>(number & 0x000000FF);
1377 }
1378
1379 std::string
longToVarBuffer(unsigned long value)1380 MidiFile::longToVarBuffer(unsigned long value)
1381 {
1382 // See WriteVarLen() in the MIDI Spec section 4, page 11.
1383
1384 // Convert value into a "variable-length quantity" in buffer.
1385
1386 // Start with the lowest 7 bits of the number
1387 long buffer = value & 0x7f;
1388
1389 while ((value >>= 7 ) > 0) {
1390 buffer <<= 8;
1391 buffer |= 0x80;
1392 buffer += (value & 0x7f);
1393 }
1394
1395 // Copy buffer to returnString and return it.
1396
1397 std::string returnString;
1398
1399 while (true) {
1400 returnString += (MidiByte)(buffer & 0xff);
1401 if (buffer & 0x80)
1402 buffer >>= 8;
1403 else
1404 break;
1405 }
1406
1407 return returnString;
1408 }
1409
1410 void
writeHeader(std::ofstream * midiFile)1411 MidiFile::writeHeader(std::ofstream *midiFile)
1412 {
1413 // Our identifying Header string
1414 *midiFile << MIDI_FILE_HEADER;
1415
1416 // Write number of Bytes to follow
1417 *midiFile << static_cast<MidiByte>(0x00);
1418 *midiFile << static_cast<MidiByte>(0x00);
1419 *midiFile << static_cast<MidiByte>(0x00);
1420 *midiFile << static_cast<MidiByte>(0x06);
1421
1422 writeInt(midiFile, static_cast<int>(m_format));
1423 writeInt(midiFile, m_numberOfTracks);
1424 writeInt(midiFile, m_timingDivision);
1425 }
1426
1427 void
writeTrack(std::ofstream * midiFile,TrackId trackNumber)1428 MidiFile::writeTrack(std::ofstream *midiFile, TrackId trackNumber)
1429 {
1430 // For running status.
1431 MidiByte previousEventCode = 0;
1432
1433 // First we write into trackBuffer, then we write trackBuffer
1434 // out to the file with its accompanying length.
1435
1436 std::string trackBuffer;
1437
1438 // Used to accumulate time deltas for skipped events.
1439 timeT skippedTime = 0;
1440
1441 // For each event in the Track
1442 for (MidiTrack::iterator i = m_midiComposition[trackNumber].begin();
1443 i != m_midiComposition[trackNumber].end();
1444 ++i) {
1445 const MidiEvent &midiEvent = **i;
1446
1447 // Do not write controller reset events to the buffer/file.
1448 // HACK for #1404. I gave up trying to find where the events
1449 // were originating, and decided to try just stripping them. If
1450 // you can't do it right, do it badly, and somebody will
1451 // eventually freak out, then fix it the right way.
1452 // ??? This is created in ChannelManager::insertControllers().
1453 // ??? Since we now have the "Allow Reset All Controllers" config
1454 // option, we can probably get rid of this and tell people to
1455 // use the config option. If someone complains that 121's
1456 // aren't appearing in MIDI files, that's probably the route
1457 // we'll have to go.
1458 if (midiEvent.getData1() == MIDI_CONTROLLER_RESET) {
1459 RG_WARNING << "writeTrack(): Found controller 121. Skipping. This is a HACK to address BUG #1404.";
1460
1461 // Keep track of the timestamps from skipped events so we can
1462 // add them to the next event that makes it through.
1463 skippedTime += midiEvent.getTime();
1464
1465 continue;
1466 }
1467
1468 // Add the time to the buffer in MIDI format
1469 trackBuffer += longToVarBuffer(midiEvent.getTime() + skippedTime);
1470
1471 skippedTime = 0;
1472
1473 RG_DEBUG << "MIDI event for channel "
1474 << static_cast<int>(midiEvent.getChannelNumber())
1475 << " (track " << trackNumber << ") "
1476 << " time" << midiEvent.getTime();
1477 RG_DEBUG << midiEvent;
1478
1479 if (midiEvent.isMeta()) {
1480 trackBuffer += MIDI_FILE_META_EVENT;
1481 trackBuffer += midiEvent.getMetaEventCode();
1482
1483 trackBuffer += longToVarBuffer(midiEvent.
1484 getMetaMessage().length());
1485 trackBuffer += midiEvent.getMetaMessage();
1486
1487 // Meta events cannot use running status.
1488 previousEventCode = 0;
1489
1490 } else { // non-meta event
1491 // If the event code has changed, or this is a SYSEX event, we
1492 // can't use running status.
1493 // Running status is "[f]or Voice and Mode messages only."
1494 // Sysex is a system message. See the MIDI spec, Section 2,
1495 // page 5.
1496 if ((midiEvent.getEventCode() != previousEventCode) ||
1497 (midiEvent.getEventCode() == MIDI_SYSTEM_EXCLUSIVE)) {
1498
1499 // Send the normal event code (with encoded channel information)
1500 trackBuffer += midiEvent.getEventCode();
1501
1502 previousEventCode = midiEvent.getEventCode();
1503 }
1504
1505 switch (midiEvent.getMessageType()) {
1506 case MIDI_NOTE_ON: // These have two data bytes.
1507 case MIDI_NOTE_OFF:
1508 case MIDI_PITCH_BEND:
1509 case MIDI_CTRL_CHANGE:
1510 case MIDI_POLY_AFTERTOUCH:
1511 trackBuffer += midiEvent.getData1();
1512 trackBuffer += midiEvent.getData2();
1513 break;
1514
1515 case MIDI_PROG_CHANGE: // These have one data byte.
1516 case MIDI_CHNL_AFTERTOUCH:
1517 trackBuffer += midiEvent.getData1();
1518 break;
1519
1520 case MIDI_SYSTEM_EXCLUSIVE:
1521 trackBuffer +=
1522 longToVarBuffer(midiEvent.getMetaMessage().length());
1523 trackBuffer += midiEvent.getMetaMessage();
1524 break;
1525
1526 default:
1527 RG_WARNING << "writeTrack() - cannot write unsupported MIDI event: " << QString("0x%1").arg(midiEvent.getMessageType(), 0, 16);
1528 break;
1529 }
1530 }
1531
1532 // Kick the event loop to keep the UI responsive.
1533 qApp->processEvents();
1534 }
1535
1536 // Now we write the track to the file.
1537
1538 *midiFile << MIDI_TRACK_HEADER;
1539 writeLong(midiFile, trackBuffer.length());
1540 *midiFile << trackBuffer;
1541 }
1542
1543 bool
write(const QString & filename)1544 MidiFile::write(const QString &filename)
1545 {
1546 std::ofstream midiFile(filename.toLocal8Bit(),
1547 std::ios::out | std::ios::binary);
1548
1549 if (!midiFile.good()) {
1550 RG_WARNING << "write() - can't write file";
1551 m_format = MIDI_FILE_NOT_LOADED;
1552 return false;
1553 }
1554
1555 writeHeader(&midiFile);
1556
1557 // For each track, write it out.
1558 for (TrackId i = 0; i < m_numberOfTracks; ++i) {
1559 writeTrack(&midiFile, i);
1560
1561 if (m_progressDialog && m_progressDialog->wasCanceled())
1562 return false;
1563
1564 if (m_progressDialog)
1565 m_progressDialog->setValue(i * 100 / m_numberOfTracks);
1566 }
1567
1568 midiFile.close();
1569
1570 return true;
1571 }
1572
1573 void
consolidateNoteEvents(TrackId trackId)1574 MidiFile::consolidateNoteEvents(TrackId trackId)
1575 {
1576 MidiTrack &track = m_midiComposition[trackId];
1577
1578 // For each MIDI event on the track.
1579 for (MidiTrack::iterator firstEventIter = track.begin();
1580 firstEventIter != track.end();
1581 ++firstEventIter) {
1582 MidiEvent &firstEvent = **firstEventIter;
1583
1584 // Not a note-on? Try the next event.
1585 if (firstEvent.getMessageType() != MIDI_NOTE_ON)
1586 continue;
1587
1588 // Note-on with velocity 0 is a note-off. Try the next event.
1589 if (firstEvent.getVelocity() == 0)
1590 continue;
1591
1592 // At this point, firstEvent is a note-on event.
1593 // Search for the matching note-off event.
1594
1595 bool noteOffFound = false;
1596
1597 MidiTrack::iterator secondEventIter;
1598
1599 // For each following MIDI event
1600 for (secondEventIter = firstEventIter + 1;
1601 secondEventIter != track.end();
1602 ++secondEventIter) {
1603 const MidiEvent &secondEvent = **secondEventIter;
1604
1605 bool noteOff = (secondEvent.getMessageType() == MIDI_NOTE_OFF ||
1606 (secondEvent.getMessageType() == MIDI_NOTE_ON &&
1607 secondEvent.getVelocity() == 0x00));
1608
1609 // Not a note-off? Try the next event.
1610 if (!noteOff)
1611 continue;
1612
1613 // Wrong pitch? Try the next event.
1614 if (secondEvent.getPitch() != firstEvent.getPitch())
1615 continue;
1616
1617 // Wrong channel? Try the next event.
1618 // Note: Since all the events in a track are for a single channel,
1619 // this will never be true.
1620 if (secondEvent.getChannelNumber() != firstEvent.getChannelNumber())
1621 continue;
1622
1623 timeT noteDuration = secondEvent.getTime() - firstEvent.getTime();
1624
1625 // Some MIDI files floating around in the real world
1626 // apparently have note-on followed immediately by note-off
1627 // on percussion tracks. Instead of setting the duration to
1628 // 0 in this case, which has no meaning, set it to 1.
1629 if (noteDuration == 0) {
1630 RG_WARNING << "consolidateNoteEvents() - detected MIDI note duration of 0. Using duration of 1. Touch wood.";
1631 noteDuration = 1;
1632 }
1633
1634 firstEvent.setDuration(noteDuration);
1635
1636 // Remove the note-off.
1637 delete *secondEventIter;
1638 track.erase(secondEventIter);
1639
1640 noteOffFound = true;
1641 break;
1642 }
1643
1644 if (!noteOffFound) {
1645 // avoid crash due to secondEventIter == track.end()
1646 --secondEventIter;
1647 // Set Event duration to length of Segment.
1648 firstEvent.setDuration(
1649 (*secondEventIter)->getTime() - firstEvent.getTime());
1650 }
1651 }
1652 }
1653
1654 void
clearMidiComposition()1655 MidiFile::clearMidiComposition()
1656 {
1657 // For each track
1658 for (MidiComposition::iterator trackIter = m_midiComposition.begin();
1659 trackIter != m_midiComposition.end();
1660 ++trackIter) {
1661
1662 MidiTrack &midiTrack = trackIter->second;
1663
1664 // For each event on the track.
1665 for (MidiTrack::iterator eventIter = midiTrack.begin();
1666 eventIter != midiTrack.end();
1667 ++eventIter) {
1668
1669 delete *eventIter;
1670 }
1671
1672 midiTrack.clear();
1673 }
1674
1675 m_midiComposition.clear();
1676 m_trackChannelMap.clear();
1677 m_trackNames.clear();
1678 }
1679
1680
1681 }
1682
1683