00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qsmf.h"
00023 #include <limits>
00024 #include <QList>
00025 #include <QFile>
00026 #include <QDataStream>
00027 #include <QTextCodec>
00028
00034 namespace drumstick {
00035
00048 class QSmf::QSmfPrivate {
00049 public:
00050 QSmfPrivate():
00051 m_Interactive(false),
00052 m_CurrTime(0),
00053 m_RealTime(0),
00054 m_DblRealTime(0),
00055 m_DblOldRealtime(0),
00056 m_Division(96),
00057 m_CurrTempo(500000),
00058 m_OldCurrTempo(500000),
00059 m_OldRealTime(0),
00060 m_OldCurrTime(0),
00061 m_RevisedTime(0),
00062 m_TempoChangeTime(0),
00063 m_ToBeRead(0),
00064 m_NumBytesWritten(0),
00065 m_Tracks(0),
00066 m_fileFormat(0),
00067 m_LastStatus(0),
00068 m_codec(0),
00069 m_IOStream(0)
00070 { }
00071
00072 bool m_Interactive;
00073 quint64 m_CurrTime;
00074 quint64 m_RealTime;
00075 double m_DblRealTime;
00076 double m_DblOldRealtime;
00077 int m_Division;
00078 quint64 m_CurrTempo;
00079 quint64 m_OldCurrTempo;
00080 quint64 m_OldRealTime;
00081 quint64 m_OldCurrTime;
00082 quint64 m_RevisedTime;
00083 quint64 m_TempoChangeTime;
00084 quint64 m_ToBeRead;
00085 quint64 m_NumBytesWritten;
00086 int m_Tracks;
00087 int m_fileFormat;
00088 int m_LastStatus;
00089 QTextCodec *m_codec;
00090 QDataStream *m_IOStream;
00091 QByteArray m_MsgBuff;
00092 QList<QSmfRecTempo> m_TempoList;
00093 };
00094
00099 QSmf::QSmf(QObject * parent) :
00100 QObject(parent),
00101 d(new QSmfPrivate)
00102 { }
00103
00107 QSmf::~QSmf()
00108 {
00109 d->m_TempoList.clear();
00110 delete d;
00111 }
00112
00117 bool QSmf::endOfSmf()
00118 {
00119 return d->m_IOStream->atEnd();
00120 }
00121
00126 quint8 QSmf::getByte()
00127 {
00128 quint8 b = 0;
00129 if (!d->m_IOStream->atEnd())
00130 {
00131 *d->m_IOStream >> b;
00132 d->m_ToBeRead--;
00133 }
00134 return b;
00135 }
00136
00141 void QSmf::putByte(quint8 value)
00142 {
00143 *d->m_IOStream << value;
00144 d->m_NumBytesWritten++;
00145 }
00146
00152 void QSmf::addTempo(quint64 tempo, quint64 time)
00153 {
00154 QSmfRecTempo tempoRec;
00155 tempoRec.tempo = tempo;
00156 tempoRec.time = time;
00157 d->m_TempoList.append(tempoRec);
00158 }
00159
00163 void QSmf::readHeader()
00164 {
00165 d->m_CurrTime = 0;
00166 d->m_RealTime = 0;
00167 d->m_Division = 96;
00168 d->m_CurrTempo = 500000;
00169 d->m_OldCurrTempo = 500000;
00170 addTempo(d->m_CurrTempo, 0);
00171 if (d->m_Interactive)
00172 {
00173 d->m_fileFormat= 0;
00174 d->m_Tracks = 1;
00175 d->m_Division = 96;
00176 }
00177 else
00178 {
00179 readExpected("MThd");
00180 d->m_ToBeRead = read32bit();
00181 d->m_fileFormat = read16bit();
00182 d->m_Tracks = read16bit();
00183 d->m_Division = read16bit();
00184 }
00185 emit signalSMFHeader(d->m_fileFormat, d->m_Tracks, d->m_Division);
00186
00187
00188 while ((d->m_ToBeRead > 0) && !endOfSmf())
00189 {
00190 getByte();
00191 }
00192 }
00193
00197 void QSmf::readTrack()
00198 {
00199
00200
00201
00202 static const quint8 chantype[16] =
00203 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 };
00204
00205 quint64 lookfor;
00206 quint8 c, c1, type;
00207 bool sysexcontinue;
00208 bool running;
00209 quint8 status;
00210 int needed;
00211 double delta_secs;
00212 quint64 delta_ticks, save_time, save_tempo;
00213
00214 sysexcontinue = false;
00215 status = 0;
00216 if (d->m_Interactive)
00217 {
00218 d->m_ToBeRead = std::numeric_limits<unsigned long long>::max();
00219 }
00220 else
00221 {
00222 readExpected("MTrk");
00223 d->m_ToBeRead = read32bit();
00224 }
00225 d->m_CurrTime = 0;
00226 d->m_RealTime = 0;
00227 d->m_DblRealTime = 0;
00228 d->m_DblOldRealtime = 0;
00229 d->m_OldCurrTime = 0;
00230 d->m_OldRealTime = 0;
00231 d->m_CurrTempo = findTempo();
00232
00233 emit signalSMFTrackStart();
00234
00235 while (!endOfSmf() && (d->m_Interactive || d->m_ToBeRead > 0))
00236 {
00237 if (d->m_Interactive)
00238 {
00239 d->m_CurrTime++;
00240 }
00241 else
00242 {
00243 delta_ticks = readVarLen();
00244 d->m_RevisedTime = d->m_CurrTime;
00245 d->m_CurrTime += delta_ticks;
00246 while (d->m_RevisedTime < d->m_CurrTime)
00247 {
00248 save_time = d->m_RevisedTime;
00249 save_tempo = d->m_CurrTempo;
00250 d->m_CurrTempo = findTempo();
00251 if (d->m_CurrTempo != d->m_OldCurrTempo)
00252 {
00253 d->m_OldCurrTempo = d->m_CurrTempo;
00254 d->m_OldRealTime = d->m_RealTime;
00255 if (d->m_RevisedTime != d->m_TempoChangeTime)
00256 {
00257 d->m_DblOldRealtime = d->m_DblRealTime;
00258 d->m_OldCurrTime = save_time;
00259 }
00260 delta_secs = ticksToSecs(d->m_RevisedTime - d->m_OldCurrTime,
00261 d->m_Division, save_tempo);
00262 d->m_DblRealTime = d->m_DblOldRealtime + delta_secs * 1600.0;
00263 d->m_RealTime = static_cast<quint64>(0.5 + d->m_DblRealTime);
00264 if (d->m_RevisedTime == d->m_TempoChangeTime)
00265 {
00266 d->m_OldCurrTime = d->m_RevisedTime;
00267 d->m_DblOldRealtime = d->m_DblRealTime;
00268 }
00269 }
00270 else
00271 {
00272 delta_secs = ticksToSecs(d->m_RevisedTime - d->m_OldCurrTime,
00273 d->m_Division, d->m_CurrTempo);
00274 d->m_DblRealTime = d->m_DblOldRealtime + delta_secs * 1600.0;
00275 d->m_RealTime = static_cast<quint64>(0.5 + d->m_DblRealTime);
00276 }
00277 }
00278 }
00279
00280 c = getByte();
00281 if (sysexcontinue && (c != end_of_sysex))
00282 {
00283 SMFError("didn't find expected continuation of a SysEx");
00284 }
00285 if (c < 0xf8)
00286 {
00287 if ((c & 0x80) == 0)
00288 {
00289 if (status == 0)
00290 {
00291 SMFError("unexpected running status");
00292 }
00293 running = true;
00294 }
00295 else
00296 {
00297 status = c;
00298 running = false;
00299 }
00300 needed = chantype[status >> 4 & 0x0f];
00301 if (needed != 0)
00302 {
00303 if (running)
00304 {
00305 c1 = c;
00306 }
00307 else
00308 {
00309 c1 = getByte();
00310 }
00311 if (needed > 1)
00312 {
00313 channelMessage(status, c1, getByte());
00314 }
00315 else
00316 {
00317 channelMessage(status, c1, 0);
00318 }
00319 continue;
00320 }
00321 }
00322
00323 switch (c)
00324 {
00325 case meta_event:
00326 type = getByte();
00327 lookfor = readVarLen();
00328 lookfor = d->m_ToBeRead - lookfor;
00329 msgInit();
00330 while (d->m_ToBeRead > lookfor)
00331 {
00332 msgAdd(getByte());
00333 }
00334 metaEvent(type);
00335 break;
00336 case system_exclusive:
00337 lookfor = readVarLen();
00338 lookfor = d->m_ToBeRead - lookfor;
00339 msgInit();
00340 msgAdd(system_exclusive);
00341 while (d->m_ToBeRead > lookfor)
00342 {
00343 c = getByte();
00344 msgAdd(c);
00345 }
00346 if (c == end_of_sysex)
00347 {
00348 sysEx();
00349 }
00350 else
00351 {
00352 sysexcontinue = true;
00353 }
00354 break;
00355 case end_of_sysex:
00356 lookfor = readVarLen();
00357 lookfor = d->m_ToBeRead - lookfor;
00358 if (!sysexcontinue)
00359 {
00360 msgInit();
00361 }
00362 while (d->m_ToBeRead > lookfor)
00363 {
00364 c = getByte();
00365 msgAdd(c);
00366 }
00367 if (sysexcontinue)
00368 {
00369 if (c == end_of_sysex)
00370 {
00371 sysEx();
00372 sysexcontinue = false;
00373 }
00374 }
00375 break;
00376 default:
00377 badByte(c, d->m_IOStream->device()->pos() - 1);
00378 break;
00379 }
00380 }
00381 emit signalSMFTrackEnd();
00382 }
00383
00387 void QSmf::SMFRead()
00388 {
00389 int i;
00390 readHeader();
00391 for ( i = d->m_Tracks; (i > 0) && !endOfSmf(); i--)
00392 {
00393 readTrack();
00394 }
00395 }
00396
00404 void QSmf::SMFWrite()
00405 {
00406 int i;
00407 d->m_LastStatus = 0;
00408 writeHeaderChunk(d->m_fileFormat, d->m_Tracks, d->m_Division);
00409 d->m_LastStatus = 0;
00410 if (d->m_fileFormat == 1)
00411 {
00412 emit signalSMFWriteTempoTrack();
00413 }
00414 for (i = 0; i < d->m_Tracks; ++i)
00415 {
00416 writeTrackChunk(i);
00417 }
00418 }
00419
00424 void QSmf::readFromStream(QDataStream *stream)
00425 {
00426 d->m_IOStream = stream;
00427 SMFRead();
00428 }
00429
00434 void QSmf::readFromFile(const QString& fileName)
00435 {
00436 QFile file(fileName);
00437 file.open(QIODevice::ReadOnly);
00438 QDataStream ds(&file);
00439 readFromStream(&ds);
00440 file.close();
00441 }
00442
00447 void QSmf::writeToStream(QDataStream *stream)
00448 {
00449 d->m_IOStream = stream;
00450 SMFWrite();
00451 }
00452
00457 void QSmf::writeToFile(const QString& fileName)
00458 {
00459 QFile file(fileName);
00460 file.open(QIODevice::WriteOnly);
00461 QDataStream ds(&file);
00462 writeToStream(&ds);
00463 file.close();
00464 }
00465
00472 void QSmf::writeHeaderChunk(int format, int ntracks, int division)
00473 {
00474 write32bit(MThd);
00475 write32bit(6);
00476 write16bit(format);
00477 write16bit(ntracks);
00478 write16bit(division);
00479 }
00480
00485 void QSmf::writeTrackChunk(int track)
00486 {
00487 quint32 trkhdr;
00488 quint32 trklength;
00489 qint64 offset;
00490 qint64 place_marker;
00491
00492 d->m_LastStatus = 0;
00493 trkhdr = MTrk;
00494 trklength = 0;
00495 offset = d->m_IOStream->device()->pos();
00496 write32bit(trkhdr);
00497 write32bit(trklength);
00498 d->m_NumBytesWritten = 0;
00499
00500 emit signalSMFWriteTrack(track);
00501
00502 place_marker = d->m_IOStream->device()->pos();
00503 d->m_IOStream->device()->seek(offset);
00504 trklength = d->m_NumBytesWritten;
00505 write32bit(trkhdr);
00506 write32bit(trklength);
00507 d->m_IOStream->device()->seek(place_marker);
00508 }
00509
00516 void QSmf::writeMetaEvent(long deltaTime, int type, const QByteArray& data)
00517 {
00518 writeVarLen(deltaTime);
00519 d->m_LastStatus = meta_event;
00520 putByte(d->m_LastStatus);
00521 putByte(type);
00522 writeVarLen(data.size());
00523 foreach(char byte, data)
00524 putByte(byte);
00525 }
00526
00533 void QSmf::writeMetaEvent(long deltaTime, int type, const QString& data)
00534 {
00535 writeVarLen(deltaTime);
00536 putByte(d->m_LastStatus = meta_event);
00537 putByte(type);
00538 QByteArray lcldata;
00539 if (d->m_codec == NULL)
00540 lcldata = data.toLatin1();
00541 else
00542 lcldata = d->m_codec->fromUnicode(data);
00543 writeVarLen(lcldata.length());
00544 foreach(char byte, lcldata)
00545 putByte(byte);
00546 }
00547
00555 void QSmf::writeMetaEvent(long deltaTime, int type, int data)
00556 {
00557 writeVarLen(deltaTime);
00558 putByte(d->m_LastStatus = meta_event);
00559 putByte(type);
00560 putByte(1);
00561 putByte(data);
00562 }
00563
00569 void QSmf::writeMetaEvent(long deltaTime, int type)
00570 {
00571 writeVarLen(deltaTime);
00572 putByte(d->m_LastStatus = meta_event);
00573 putByte(type);
00574 putByte(0);
00575 }
00576
00584 void QSmf::writeMidiEvent(long deltaTime, int type, int chan,
00585 const QByteArray& data)
00586 {
00587 int i, j, size;
00588 quint8 c;
00589 writeVarLen(deltaTime);
00590 if ((type == system_exclusive) || (type == end_of_sysex))
00591 {
00592 c = type;
00593 d->m_LastStatus = 0;
00594 }
00595 else
00596 {
00597 if (chan > 15)
00598 {
00599 SMFError("error: MIDI channel greater than 16");
00600 }
00601 c = type | chan;
00602 }
00603 if (d->m_LastStatus != c)
00604 {
00605 d->m_LastStatus = c;
00606 putByte(c);
00607 }
00608 if (type == system_exclusive || type == end_of_sysex)
00609 {
00610 size = data.size();
00611 if (data[0] == type)
00612 --size;
00613 writeVarLen(size);
00614 }
00615 j = (data[0] == type ? 1 : 0);
00616 for (i = j; i < data.size(); ++i)
00617 {
00618 putByte(data[i]);
00619 }
00620 }
00621
00629 void QSmf::writeMidiEvent(long deltaTime, int type, int chan, int b1)
00630 {
00631 quint8 c;
00632 writeVarLen(deltaTime);
00633 if ((type == system_exclusive) || (type == end_of_sysex))
00634 {
00635 SMFError("error: Wrong method for a system exclusive event");
00636 }
00637 if (chan > 15)
00638 {
00639 SMFError("error: MIDI channel greater than 16");
00640 }
00641 c = type | chan;
00642 if (d->m_LastStatus != c)
00643 {
00644 d->m_LastStatus = c;
00645 putByte(c);
00646 }
00647 putByte(b1);
00648 }
00649
00658 void QSmf::writeMidiEvent(long deltaTime, int type, int chan, int b1, int b2)
00659 {
00660 quint8 c;
00661 writeVarLen(deltaTime);
00662 if ((type == system_exclusive) || (type == end_of_sysex))
00663 {
00664 SMFError("error: Wrong method for a system exclusive event");
00665 }
00666 if (chan > 15)
00667 {
00668 SMFError("error: MIDI channel greater than 16");
00669 }
00670 c = type | chan;
00671 if (d->m_LastStatus != c)
00672 {
00673 d->m_LastStatus = c;
00674 putByte(c);
00675 }
00676 putByte(b1);
00677 putByte(b2);
00678 }
00679
00687 void QSmf::writeMidiEvent(long deltaTime, int type, long len, char* data)
00688 {
00689 unsigned int i, j, size;
00690 quint8 c;
00691 writeVarLen(deltaTime);
00692 if ((type != system_exclusive) && (type != end_of_sysex))
00693 {
00694 SMFError("error: type should be system exclusive");
00695 }
00696 d->m_LastStatus = 0;
00697 c = type;
00698 putByte(c);
00699 size = len;
00700 c = (unsigned)data[0];
00701 if (c == type)
00702 --size;
00703 writeVarLen(size);
00704 j = (c == type ? 1 : 0);
00705 for (i = j; i < (unsigned)len; ++i)
00706 {
00707 putByte(data[i]);
00708 }
00709 }
00710
00716 void QSmf::writeSequenceNumber(long deltaTime, int seqnum)
00717 {
00718 writeVarLen(deltaTime);
00719 d->m_LastStatus = meta_event;
00720 putByte(d->m_LastStatus);
00721 putByte(sequence_number);
00722 putByte(2);
00723 putByte((seqnum >> 8) & 0xff);
00724 putByte(seqnum & 0xff);
00725 }
00726
00732 void QSmf::writeTempo(long deltaTime, long tempo)
00733 {
00734 writeVarLen(deltaTime);
00735 putByte(d->m_LastStatus = meta_event);
00736 putByte(set_tempo);
00737 putByte(3);
00738 putByte((tempo >> 16) & 0xff);
00739 putByte((tempo >> 8) & 0xff);
00740 putByte(tempo & 0xff);
00741 }
00742
00748 void QSmf::writeBpmTempo(long deltaTime, int tempo)
00749 {
00750 long us_tempo = 60000000l / tempo;
00751 writeTempo(deltaTime, us_tempo);
00752 }
00753
00762 void QSmf::writeTimeSignature(long deltaTime, int num, int den, int cc, int bb)
00763 {
00764 writeVarLen(deltaTime);
00765 putByte(d->m_LastStatus = meta_event);
00766 putByte(time_signature);
00767 putByte(4);
00768 putByte(num & 0xff);
00769 putByte(den & 0xff);
00770 putByte(cc & 0xff);
00771 putByte(bb & 0xff);
00772 }
00773
00780 void QSmf::writeKeySignature(long deltaTime, int tone, int mode)
00781 {
00782 writeVarLen(deltaTime);
00783 putByte(d->m_LastStatus = meta_event);
00784 putByte(key_signature);
00785 putByte(2);
00786 putByte((char)tone);
00787 putByte(mode & 0x01);
00788 }
00789
00794 void QSmf::writeVarLen(quint64 value)
00795 {
00796 quint64 buffer;
00797
00798 buffer = value & 0x7f;
00799 while ((value >>= 7) > 0)
00800 {
00801 buffer <<= 8;
00802 buffer |= 0x80;
00803 buffer += (value & 0x7f);
00804 }
00805 while (true)
00806 {
00807 putByte(buffer & 0xff);
00808 if (buffer & 0x80)
00809 buffer >>= 8;
00810 else
00811 break;
00812 }
00813 }
00814
00815
00816
00817 void QSmf::write32bit(quint32 data)
00818 {
00819 putByte((data >> 24) & 0xff);
00820 putByte((data >> 16) & 0xff);
00821 putByte((data >> 8) & 0xff);
00822 putByte(data & 0xff);
00823 }
00824
00825 void QSmf::write16bit(quint16 data)
00826 {
00827 putByte((data >> 8) & 0xff);
00828 putByte(data & 0xff);
00829 }
00830
00831 quint16 QSmf::to16bit(quint8 c1, quint8 c2)
00832 {
00833 quint16 value;
00834 value = (c1 << 8);
00835 value += c2;
00836 return value;
00837 }
00838
00839 quint32 QSmf::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
00840 {
00841 quint32 value;
00842 value = (c1 << 24);
00843 value += (c2 << 16);
00844 value += (c3 << 8);
00845 value += c4;
00846 return value;
00847 }
00848
00849 quint16 QSmf::read16bit()
00850 {
00851 quint8 c1, c2;
00852 c1 = getByte();
00853 c2 = getByte();
00854 return to16bit(c1, c2);
00855 }
00856
00857 quint32 QSmf::read32bit()
00858 {
00859 quint8 c1, c2, c3, c4;
00860 c1 = getByte();
00861 c2 = getByte();
00862 c3 = getByte();
00863 c4 = getByte();
00864 return to32bit(c1, c2, c3, c4);
00865 }
00866
00867 long QSmf::readVarLen()
00868 {
00869 long value;
00870 quint8 c;
00871
00872 c = getByte();
00873 value = c;
00874 if ((c & 0x80) != 0)
00875 {
00876 value &= 0x7f;
00877 do
00878 {
00879 c = getByte();
00880 value = (value << 7) + (c & 0x7f);
00881 } while ((c & 0x80) != 0);
00882 }
00883 return value;
00884 }
00885
00886 void QSmf::readExpected(const QString& s)
00887 {
00888 int j;
00889 quint8 b;
00890 for (j = 0; j < s.length(); ++j)
00891 {
00892 b = getByte();
00893 if (QChar(b) != s[j])
00894 {
00895 SMFError(QString("Invalid (%1) SMF format at %2").arg(b, 0, 16).arg(d->m_IOStream->device()->pos()));
00896 break;
00897 }
00898 }
00899 }
00900
00901 quint64 QSmf::findTempo()
00902 {
00903 quint64 result, old_tempo, new_tempo;
00904 QSmfRecTempo rec = d->m_TempoList.last();
00905 old_tempo = d->m_CurrTempo;
00906 new_tempo = d->m_CurrTempo;
00907 QList<QSmfRecTempo>::Iterator it;
00908 for( it = d->m_TempoList.begin(); it != d->m_TempoList.end(); ++it )
00909 {
00910 rec = (*it);
00911 if (rec.time <= d->m_CurrTime)
00912 {
00913 old_tempo = rec.tempo;
00914 }
00915 new_tempo = rec.tempo;
00916 if (rec.time > d->m_RevisedTime)
00917 {
00918 break;
00919 }
00920 }
00921 if ((rec.time <= d->m_RevisedTime) || (rec.time > d->m_CurrTime))
00922 {
00923 d->m_RevisedTime = d->m_CurrTime;
00924 result = old_tempo;
00925 }
00926 else
00927 {
00928 d->m_RevisedTime = rec.time;
00929 d->m_TempoChangeTime = d->m_RevisedTime;
00930 result = new_tempo;
00931 }
00932 return result;
00933 }
00934
00935
00936
00937
00938 double QSmf::ticksToSecs(quint64 ticks, quint16 division, quint64 tempo)
00939 {
00940 double result;
00941 double smpte_format;
00942 double smpte_resolution;
00943
00944 if (division > 0)
00945 {
00946 result = static_cast<double>(ticks * tempo)/(division * 1000000.0);
00947 }
00948 else
00949 {
00950 smpte_format = upperByte(division);
00951 smpte_resolution = lowerByte(division);
00952 result = static_cast<double>(ticks)/(smpte_format * smpte_resolution
00953 * 1000000.0);
00954 }
00955 return result;
00956 }
00957
00958 void QSmf::SMFError(const QString& s)
00959 {
00960 emit signalSMFError(s);
00961 }
00962
00963 void QSmf::channelMessage(quint8 status, quint8 c1, quint8 c2)
00964 {
00965 quint8 chan;
00966 int k;
00967 chan = status & midi_channel_mask;
00968 if (c1 > 127)
00969 {
00970 SMFError(QString("ChannelMessage with bad c1 = %1").arg(c1));
00971
00972 }
00973 if (c2 > 127)
00974 {
00975 SMFError(QString("ChannelMessage with bad c2 = %1").arg(c2));
00976
00977 }
00978 switch (status & midi_command_mask)
00979 {
00980 case note_off:
00981 emit signalSMFNoteOff(chan, c1, c2);
00982 break;
00983 case note_on:
00984 emit signalSMFNoteOn(chan, c1, c2);
00985 break;
00986 case poly_aftertouch:
00987 emit signalSMFKeyPress(chan, c1, c2);
00988 break;
00989 case control_change:
00990 emit signalSMFCtlChange(chan, c1, c2);
00991 break;
00992 case program_chng:
00993 emit signalSMFProgram(chan, c1);
00994 break;
00995 case channel_aftertouch:
00996 emit signalSMFChanPress(chan, c1);
00997 break;
00998 case pitch_wheel:
00999 k = c1 + (c2 << 7) - 8192;
01000 emit signalSMFPitchBend(chan, k);
01001 break;
01002 default:
01003 SMFError(QString("Invalid MIDI status %1. Unhandled event").arg(status));
01004 break;
01005 }
01006 }
01007
01008 void QSmf::metaEvent(quint8 b)
01009 {
01010 QSmfRecTempo rec;
01011 QByteArray m(d->m_MsgBuff);
01012
01013 switch (b)
01014 {
01015 case sequence_number:
01016 emit signalSMFSequenceNum(to16bit(m[0], m[1]));
01017 break;
01018 case text_event:
01019 case copyright_notice:
01020 case sequence_name:
01021 case instrument_name:
01022 case lyric:
01023 case marker:
01024 case cue_point: {
01025 QString s;
01026 if (d->m_codec == NULL)
01027 s = QString(m);
01028 else
01029 s = d->m_codec->toUnicode(m);
01030 emit signalSMFText(b, s);
01031 }
01032 break;
01033 case forced_channel:
01034 emit signalSMFforcedChannel(m[0]);
01035 break;
01036 case forced_port:
01037 emit signalSMFforcedPort(m[0]);
01038 break;
01039 case end_of_track:
01040 emit signalSMFendOfTrack();
01041 break;
01042 case set_tempo:
01043 d->m_CurrTempo = to32bit(0, m[0], m[1], m[2]);
01044 emit signalSMFTempo(d->m_CurrTempo);
01045 rec = d->m_TempoList.last();
01046 if (rec.tempo == d->m_CurrTempo)
01047 {
01048 return;
01049 }
01050 if (rec.time > d->m_CurrTime)
01051 {
01052 return;
01053 }
01054 addTempo(d->m_CurrTempo, d->m_CurrTime);
01055 break;
01056 case smpte_offset:
01057 emit signalSMFSmpte(m[0], m[1], m[2], m[3], m[4]);
01058 break;
01059 case time_signature:
01060 emit signalSMFTimeSig(m[0], m[1], m[2], m[3]);
01061 break;
01062 case key_signature:
01063 emit signalSMFKeySig(m[0], m[1]);
01064 break;
01065 case sequencer_specific:
01066 emit signalSMFSeqSpecific(m);
01067 break;
01068 default:
01069 emit signalSMFMetaUnregistered(b, m);
01070 break;
01071 }
01072 emit signalSMFMetaMisc(b, m);
01073 }
01074
01075 void QSmf::sysEx()
01076 {
01077 QByteArray varr(d->m_MsgBuff);
01078 emit signalSMFSysex(varr);
01079 }
01080
01081 void QSmf::badByte(quint8 b, int p)
01082 {
01083 SMFError(QString("Unexpected byte (%1) at %2").arg(b, 2, 16).arg(p));
01084 }
01085
01086 quint8 QSmf::lowerByte(quint16 x)
01087 {
01088 return (x & 0xff);
01089 }
01090
01091 quint8 QSmf::upperByte(quint16 x)
01092 {
01093 return ((x >> 8) & 0xff);
01094 }
01095
01096 void QSmf::msgInit()
01097 {
01098 d->m_MsgBuff.truncate(0);
01099 }
01100
01101 void QSmf::msgAdd(quint8 b)
01102 {
01103 int s = d->m_MsgBuff.size();
01104 d->m_MsgBuff.resize(s + 1);
01105 d->m_MsgBuff[s] = b;
01106 }
01107
01108
01109
01114 long QSmf::getCurrentTime()
01115 {
01116 return d->m_CurrTime;
01117 }
01118
01123 long QSmf::getCurrentTempo()
01124 {
01125 return d->m_CurrTempo;
01126 }
01127
01132 long QSmf::getRealTime()
01133 {
01134 return d->m_RealTime;
01135 }
01136
01141 int QSmf::getDivision()
01142 {
01143 return d->m_Division;
01144 }
01145
01150 void QSmf::setDivision(int division)
01151 {
01152 d->m_Division = division;
01153 }
01154
01159 int QSmf::getTracks()
01160 {
01161 return d->m_Tracks;
01162 }
01163
01168 void QSmf::setTracks(int tracks)
01169 {
01170 d->m_Tracks = tracks;
01171 }
01172
01177 int QSmf::getFileFormat()
01178 {
01179 return d->m_fileFormat;
01180 }
01181
01186 void QSmf::setFileFormat(int fileFormat)
01187 {
01188 d->m_fileFormat = fileFormat;
01189 }
01190
01195 long QSmf::getFilePos()
01196 {
01197 return (long) d->m_IOStream->device()->pos();
01198 }
01199
01205 QTextCodec* QSmf::getTextCodec()
01206 {
01207 return d->m_codec;
01208 }
01209
01217 void QSmf::setTextCodec(QTextCodec *codec)
01218 {
01219 d->m_codec = codec;
01220 }
01221
01222 }