drumstick
0.5.0
|
00001 /* 00002 WRK File component 00003 Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl@users.sf.net> 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License along 00016 with this program; if not, write to the Free Software Foundation, Inc., 00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "qwrk.h" 00021 #include <cmath> 00022 #include <QDataStream> 00023 #include <QFile> 00024 #include <QIODevice> 00025 #include <QTextStream> 00026 #include <QTextCodec> 00027 #include <QStringList> 00028 00034 namespace drumstick { 00035 00048 class QWrk::QWrkPrivate { 00049 public: 00050 QWrkPrivate(): 00051 m_Now(0), 00052 m_From(0), 00053 m_Thru(11930), 00054 m_KeySig(0), 00055 m_Clock(0), 00056 m_AutoSave(0), 00057 m_PlayDelay(0), 00058 m_ZeroCtrls(false), 00059 m_SendSPP(true), 00060 m_SendCont(true), 00061 m_PatchSearch(false), 00062 m_AutoStop(false), 00063 m_StopTime(4294967295U), 00064 m_AutoRewind(false), 00065 m_RewindTime(0), 00066 m_MetroPlay(false), 00067 m_MetroRecord(true), 00068 m_MetroAccent(false), 00069 m_CountIn(1), 00070 m_ThruOn(true), 00071 m_AutoRestart(false), 00072 m_CurTempoOfs(1), 00073 m_TempoOfs1(32), 00074 m_TempoOfs2(64), 00075 m_TempoOfs3(128), 00076 m_PunchEnabled(false), 00077 m_PunchInTime(0), 00078 m_PunchOutTime(0), 00079 m_EndAllTime(0), 00080 m_division(120), 00081 m_codec(0), 00082 m_IOStream(0) 00083 { } 00084 00085 quint32 m_Now; 00086 quint32 m_From; 00087 quint32 m_Thru; 00088 quint8 m_KeySig; 00089 quint8 m_Clock; 00090 quint8 m_AutoSave; 00091 quint8 m_PlayDelay; 00092 bool m_ZeroCtrls; 00093 bool m_SendSPP; 00094 bool m_SendCont; 00095 bool m_PatchSearch; 00096 bool m_AutoStop; 00097 quint32 m_StopTime; 00098 bool m_AutoRewind; 00099 quint32 m_RewindTime; 00100 bool m_MetroPlay; 00101 bool m_MetroRecord; 00102 bool m_MetroAccent; 00103 quint8 m_CountIn; 00104 bool m_ThruOn; 00105 bool m_AutoRestart; 00106 quint8 m_CurTempoOfs; 00107 quint8 m_TempoOfs1; 00108 quint8 m_TempoOfs2; 00109 quint8 m_TempoOfs3; 00110 bool m_PunchEnabled; 00111 quint32 m_PunchInTime; 00112 quint32 m_PunchOutTime; 00113 quint32 m_EndAllTime; 00114 00115 int m_division; 00116 QTextCodec *m_codec; 00117 QDataStream *m_IOStream; 00118 QByteArray m_lastChunkData; 00119 QList<RecTempo> m_tempos; 00120 }; 00121 00125 QWrk::QWrk(QObject * parent) : 00126 QObject(parent), 00127 d(new QWrkPrivate) 00128 { } 00129 00133 QWrk::~QWrk() 00134 { 00135 delete d; 00136 } 00137 00142 QTextCodec* QWrk::getTextCodec() 00143 { 00144 return d->m_codec; 00145 } 00146 00153 void QWrk::setTextCodec(QTextCodec *codec) 00154 { 00155 d->m_codec = codec; 00156 } 00157 00163 QByteArray QWrk::getLastChunkRawData() const 00164 { 00165 return d->m_lastChunkData; 00166 } 00167 00171 void QWrk::readRawData(int size) 00172 { 00173 d->m_lastChunkData = d->m_IOStream->device()->read(size); 00174 } 00175 00180 int QWrk::getNow() const 00181 { 00182 return d->m_Now; 00183 } 00184 00189 int QWrk::getFrom() const 00190 { 00191 return d->m_From; 00192 } 00193 00198 int QWrk::getThru() const 00199 { 00200 return d->m_Thru; 00201 } 00202 00207 int QWrk::getKeySig() const 00208 { 00209 return d->m_KeySig; 00210 } 00211 00216 int QWrk::getClock() const 00217 { 00218 return d->m_Clock; 00219 } 00220 00225 int QWrk::getAutoSave() const 00226 { 00227 return d->m_AutoSave; 00228 } 00229 00234 int QWrk::getPlayDelay() const 00235 { 00236 return d->m_PlayDelay; 00237 } 00238 00243 bool QWrk::getZeroCtrls() const 00244 { 00245 return d->m_ZeroCtrls; 00246 } 00247 00252 bool QWrk::getSendSPP() const 00253 { 00254 return d->m_SendSPP; 00255 } 00256 00261 bool QWrk::getSendCont() const 00262 { 00263 return d->m_SendCont; 00264 } 00265 00270 bool QWrk::getPatchSearch() const 00271 { 00272 return d->m_PatchSearch; 00273 } 00274 00279 bool QWrk::getAutoStop() const 00280 { 00281 return d->m_AutoStop; 00282 } 00283 00288 unsigned int QWrk::getStopTime() const 00289 { 00290 return d->m_StopTime; 00291 } 00292 00297 bool QWrk::getAutoRewind() const 00298 { 00299 return d->m_AutoRewind; 00300 } 00301 00306 int QWrk::getRewindTime() const 00307 { 00308 return d->m_RewindTime; 00309 } 00310 00315 bool QWrk::getMetroPlay() const 00316 { 00317 return d->m_MetroPlay; 00318 } 00319 00324 bool QWrk::getMetroRecord() const 00325 { 00326 return d->m_MetroRecord; 00327 } 00328 00333 bool QWrk::getMetroAccent() const 00334 { 00335 return d->m_MetroAccent; 00336 } 00337 00342 int QWrk::getCountIn() const 00343 { 00344 return d->m_CountIn; 00345 } 00346 00351 bool QWrk::getThruOn() const 00352 { 00353 return d->m_ThruOn; 00354 } 00355 00360 bool QWrk::getAutoRestart() const 00361 { 00362 return d->m_AutoRestart; 00363 } 00364 00369 int QWrk::getCurTempoOfs() const 00370 { 00371 return d->m_CurTempoOfs; 00372 } 00373 00388 int QWrk::getTempoOfs1() const 00389 { 00390 return d->m_TempoOfs1; 00391 } 00392 00407 int QWrk::getTempoOfs2() const 00408 { 00409 return d->m_TempoOfs2; 00410 } 00411 00426 int QWrk::getTempoOfs3() const 00427 { 00428 return d->m_TempoOfs3; 00429 } 00430 00435 bool QWrk::getPunchEnabled() const 00436 { 00437 return d->m_PunchEnabled; 00438 } 00439 00444 int QWrk::getPunchInTime() const 00445 { 00446 return d->m_PunchInTime; 00447 } 00448 00453 int QWrk::getPunchOutTime() const 00454 { 00455 return d->m_PunchOutTime; 00456 } 00457 00462 int QWrk::getEndAllTime() const 00463 { 00464 return d->m_EndAllTime; 00465 } 00466 00471 quint8 QWrk::readByte() 00472 { 00473 quint8 b = 0xff; 00474 if (!d->m_IOStream->atEnd()) 00475 *d->m_IOStream >> b; 00476 return b; 00477 } 00478 00485 quint16 QWrk::to16bit(quint8 c1, quint8 c2) 00486 { 00487 quint16 value = (c1 << 8); 00488 value += c2; 00489 return value; 00490 } 00491 00500 quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4) 00501 { 00502 quint32 value = (c1 << 24); 00503 value += (c2 << 16); 00504 value += (c3 << 8); 00505 value += c4; 00506 return value; 00507 } 00508 00513 quint16 QWrk::read16bit() 00514 { 00515 quint8 c1, c2; 00516 c1 = readByte(); 00517 c2 = readByte(); 00518 return to16bit(c2, c1); 00519 } 00520 00525 quint32 QWrk::read24bit() 00526 { 00527 quint8 c1, c2, c3; 00528 c1 = readByte(); 00529 c2 = readByte(); 00530 c3 = readByte(); 00531 return to32bit(0, c3, c2, c1); 00532 } 00533 00538 quint32 QWrk::read32bit() 00539 { 00540 quint8 c1, c2, c3, c4; 00541 c1 = readByte(); 00542 c2 = readByte(); 00543 c3 = readByte(); 00544 c4 = readByte(); 00545 return to32bit(c4, c3, c2, c1); 00546 } 00547 00552 QString QWrk::readString(int len) 00553 { 00554 QString s; 00555 if ( len > 0 ) { 00556 quint8 c = 0xff; 00557 QByteArray data; 00558 for ( int i = 0; i < len && c != 0; ++i ) { 00559 c = readByte(); 00560 if ( c != 0) 00561 data += c; 00562 } 00563 if (d->m_codec == NULL) 00564 s = QString(data); 00565 else 00566 s = d->m_codec->toUnicode(data); 00567 } 00568 return s; 00569 } 00570 00575 QString QWrk::readVarString() 00576 { 00577 QString s; 00578 QByteArray data; 00579 quint8 b; 00580 do { 00581 b = readByte(); 00582 if (b != 0) 00583 data += b; 00584 } while (b != 0); 00585 if (d->m_codec == NULL) 00586 s = QString(data); 00587 else 00588 s = d->m_codec->toUnicode(data); 00589 return s; 00590 } 00591 00596 long QWrk::getFilePos() 00597 { 00598 return d->m_IOStream->device()->pos(); 00599 } 00600 00605 void QWrk::seek(qint64 pos) 00606 { 00607 d->m_IOStream->device()->seek(pos); 00608 } 00609 00614 bool QWrk::atEnd() 00615 { 00616 return d->m_IOStream->atEnd(); 00617 } 00618 00623 void QWrk::readGap(int size) 00624 { 00625 if ( size > 0) 00626 seek( getFilePos() + size ); 00627 } 00628 00633 void QWrk::readFromStream(QDataStream *stream) 00634 { 00635 d->m_IOStream = stream; 00636 wrkRead(); 00637 } 00638 00643 void QWrk::readFromFile(const QString& fileName) 00644 { 00645 QFile file(fileName); 00646 file.open(QIODevice::ReadOnly); 00647 QDataStream ds(&file); 00648 readFromStream(&ds); 00649 file.close(); 00650 } 00651 00652 void QWrk::processTrackChunk() 00653 { 00654 int namelen; 00655 QString name[2]; 00656 int trackno; 00657 int channel; 00658 int pitch; 00659 int velocity; 00660 int port; 00661 bool selected; 00662 bool muted; 00663 bool loop; 00664 00665 trackno = read16bit(); 00666 for(int i=0; i<2; ++i) { 00667 namelen = readByte(); 00668 name[i] = readString(namelen); 00669 } 00670 channel = (qint8) readByte(); 00671 pitch = readByte(); 00672 velocity = readByte(); 00673 port = readByte(); 00674 quint8 flags = readByte(); 00675 selected = ((flags & 1) != 0); 00676 muted = ((flags & 2) != 0); 00677 loop = ((flags & 4) != 0); 00678 Q_EMIT signalWRKTrack( name[0], name[1], 00679 trackno, channel, pitch, 00680 velocity, port, selected, 00681 muted, loop ); 00682 } 00683 00684 void QWrk::processVarsChunk() 00685 { 00686 d->m_Now = read32bit(); 00687 d->m_From = read32bit(); 00688 d->m_Thru = read32bit(); 00689 d->m_KeySig = readByte(); 00690 d->m_Clock = readByte(); 00691 d->m_AutoSave = readByte(); 00692 d->m_PlayDelay = readByte(); 00693 readGap(1); 00694 d->m_ZeroCtrls = (readByte() != 0); 00695 d->m_SendSPP = (readByte() != 0); 00696 d->m_SendCont = (readByte() != 0); 00697 d->m_PatchSearch = (readByte() != 0); 00698 d->m_AutoStop = (readByte() != 0); 00699 d->m_StopTime = read32bit(); 00700 d->m_AutoRewind = (readByte() != 0); 00701 d->m_RewindTime = read32bit(); 00702 d->m_MetroPlay = (readByte() != 0); 00703 d->m_MetroRecord = (readByte() != 0); 00704 d->m_MetroAccent = (readByte() != 0); 00705 d->m_CountIn = readByte(); 00706 readGap(2); 00707 d->m_ThruOn = (readByte() != 0); 00708 readGap(19); 00709 d->m_AutoRestart = (readByte() != 0); 00710 d->m_CurTempoOfs = readByte(); 00711 d->m_TempoOfs1 = readByte(); 00712 d->m_TempoOfs2 = readByte(); 00713 d->m_TempoOfs3 = readByte(); 00714 readGap(2); 00715 d->m_PunchEnabled = (readByte() != 0); 00716 d->m_PunchInTime = read32bit(); 00717 d->m_PunchOutTime = read32bit(); 00718 d->m_EndAllTime = read32bit(); 00719 00720 Q_EMIT signalWRKGlobalVars(); 00721 } 00722 00723 void QWrk::processTimebaseChunk() 00724 { 00725 quint16 timebase = read16bit(); 00726 d->m_division = timebase; 00727 Q_EMIT signalWRKTimeBase(timebase); 00728 } 00729 00730 void QWrk::processNoteArray(int track, int events) 00731 { 00732 quint32 time = 0; 00733 quint8 status = 0, data1 = 0, data2 = 0; 00734 quint16 dur = 0; 00735 int value = 0, type = 0, channel = 0, len = 0; 00736 QString text; 00737 QByteArray data; 00738 for ( int i = 0; i < events; ++i ) { 00739 time = read24bit(); 00740 status = readByte(); 00741 dur = 0; 00742 if (status >= 0x90) { 00743 type = status & 0xf0; 00744 channel = status & 0x0f; 00745 data1 = readByte(); 00746 if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0) 00747 data2 = readByte(); 00748 if (type == 0x90) 00749 dur = read16bit(); 00750 switch (type) { 00751 case 0x90: 00752 Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur); 00753 break; 00754 case 0xA0: 00755 Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2); 00756 break; 00757 case 0xB0: 00758 Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2); 00759 break; 00760 case 0xC0: 00761 Q_EMIT signalWRKProgram(track, time, channel, data1); 00762 break; 00763 case 0xD0: 00764 Q_EMIT signalWRKChanPress(track, time, channel, data1); 00765 break; 00766 case 0xE0: 00767 value = (data2 << 7) + data1 - 8192; 00768 Q_EMIT signalWRKPitchBend(track, time, channel, value); 00769 break; 00770 case 0xF0: 00771 Q_EMIT signalWRKSysexEvent(track, time, data1); 00772 break; 00773 } 00774 } else if (status == 5) { 00775 int code = read16bit(); 00776 len = read32bit(); 00777 text = readString(len); 00778 Q_EMIT signalWRKExpression(track, time, code, text); 00779 } else if (status == 6) { 00780 int code = read16bit(); 00781 dur = read16bit(); 00782 readGap(4); 00783 Q_EMIT signalWRKHairpin(track, time, code, dur); 00784 } else if (status == 7) { 00785 len = read32bit(); 00786 text = readString(len); 00787 data.clear(); 00788 for(int j=0; j<13; ++j) { 00789 int byte = readByte(); 00790 data += byte; 00791 } 00792 Q_EMIT signalWRKChord(track, time, text, data); 00793 } else if (status == 8) { 00794 len = read16bit(); 00795 data.clear(); 00796 for(int j=0; j<len; ++j) { 00797 int byte = readByte(); 00798 data += byte; 00799 } 00800 Q_EMIT signalWRKSysex(0, QString(), false, 0, data); 00801 } else { 00802 len = read32bit(); 00803 text = readString(len); 00804 Q_EMIT signalWRKText(track, time, status, text); 00805 } 00806 } 00807 Q_EMIT signalWRKStreamEnd(time + dur); 00808 } 00809 00810 void QWrk::processStreamChunk() 00811 { 00812 long time = 0; 00813 int dur = 0, value = 0, type = 0, channel = 0; 00814 quint8 status = 0, data1 = 0, data2 = 0; 00815 quint16 track = read16bit(); 00816 int events = read16bit(); 00817 for ( int i = 0; i < events; ++i ) { 00818 time = read24bit(); 00819 status = readByte(); 00820 data1 = readByte(); 00821 data2 = readByte(); 00822 dur = read16bit(); 00823 type = status & 0xf0; 00824 channel = status & 0x0f; 00825 switch (type) { 00826 case 0x90: 00827 Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur); 00828 break; 00829 case 0xA0: 00830 Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2); 00831 break; 00832 case 0xB0: 00833 Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2); 00834 break; 00835 case 0xC0: 00836 Q_EMIT signalWRKProgram(track, time, channel, data1); 00837 break; 00838 case 0xD0: 00839 Q_EMIT signalWRKChanPress(track, time, channel, data1); 00840 break; 00841 case 0xE0: 00842 value = (data2 << 7) + data1 - 8192; 00843 Q_EMIT signalWRKPitchBend(track, time, channel, value); 00844 break; 00845 case 0xF0: 00846 Q_EMIT signalWRKSysexEvent(track, time, data1); 00847 break; 00848 } 00849 } 00850 Q_EMIT signalWRKStreamEnd(time + dur); 00851 } 00852 00853 void QWrk::processMeterChunk() 00854 { 00855 int count = read16bit(); 00856 for (int i = 0; i < count; ++i) { 00857 readGap(4); 00858 int measure = read16bit(); 00859 int num = readByte(); 00860 int den = pow(2, readByte()); 00861 readGap(4); 00862 Q_EMIT signalWRKTimeSig(measure, num, den); 00863 } 00864 } 00865 00866 void QWrk::processMeterKeyChunk() 00867 { 00868 int count = read16bit(); 00869 for (int i = 0; i < count; ++i) { 00870 int measure = read16bit(); 00871 int num = readByte(); 00872 int den = pow(2, readByte()); 00873 qint8 alt = readByte(); 00874 Q_EMIT signalWRKTimeSig(measure, num, den); 00875 Q_EMIT signalWRKKeySig(measure, alt); 00876 } 00877 } 00878 00879 double QWrk::getRealTime(long ticks) const 00880 { 00881 double division = 1.0 * d->m_division; 00882 RecTempo last; 00883 last.time = 0; 00884 last.tempo = 100.0; 00885 last.seconds = 0.0; 00886 if (!d->m_tempos.isEmpty()) { 00887 foreach(const RecTempo& rec, d->m_tempos) { 00888 if (rec.time >= ticks) 00889 break; 00890 last = rec; 00891 } 00892 } 00893 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo)); 00894 } 00895 00896 void QWrk::processTempoChunk(int factor) 00897 { 00898 double division = 1.0 * d->m_division; 00899 int count = read16bit(); 00900 RecTempo last, next; 00901 for (int i = 0; i < count; ++i) { 00902 00903 long time = read32bit(); 00904 readGap(4); 00905 long tempo = read16bit() * factor; 00906 readGap(8); 00907 00908 next.time = time; 00909 next.tempo = tempo / 100.0; 00910 next.seconds = 0.0; 00911 last.time = 0; 00912 last.tempo = next.tempo; 00913 last.seconds = 0.0; 00914 if (! d->m_tempos.isEmpty()) { 00915 foreach(const RecTempo& rec, d->m_tempos) { 00916 if (rec.time >= time) 00917 break; 00918 last = rec; 00919 } 00920 next.seconds = last.seconds + 00921 (((time - last.time) / division) * (60.0 / last.tempo)); 00922 } 00923 d->m_tempos.append(next); 00924 00925 Q_EMIT signalWRKTempo(time, tempo); 00926 } 00927 } 00928 00929 void QWrk::processSysexChunk() 00930 { 00931 int j; 00932 QString name; 00933 QByteArray data; 00934 int bank = readByte(); 00935 int length = read16bit(); 00936 bool autosend = (readByte() != 0); 00937 int namelen = readByte(); 00938 name = readString(namelen); 00939 for(j=0; j<length; ++j) { 00940 int byte = readByte(); 00941 data += byte; 00942 } 00943 Q_EMIT signalWRKSysex(bank, name, autosend, 0, data); 00944 } 00945 00946 void QWrk::processSysex2Chunk() 00947 { 00948 int j; 00949 QString name; 00950 QByteArray data; 00951 int bank = read16bit(); 00952 int length = read32bit(); 00953 quint8 b = readByte(); 00954 int port = ( b & 0xf0 ) >> 4; 00955 bool autosend = ( (b & 0x0f) != 0); 00956 int namelen = readByte(); 00957 name = readString(namelen); 00958 for(j=0; j<length; ++j) { 00959 int byte = readByte(); 00960 data += byte; 00961 } 00962 Q_EMIT signalWRKSysex(bank, name, autosend, port, data); 00963 } 00964 00965 void QWrk::processNewSysexChunk() 00966 { 00967 int j; 00968 QString name; 00969 QByteArray data; 00970 int bank = read16bit(); 00971 int length = read32bit(); 00972 int port = read16bit(); 00973 bool autosend = (readByte() != 0); 00974 int namelen = readByte(); 00975 name = readString(namelen); 00976 for(j=0; j<length; ++j) { 00977 int byte = readByte(); 00978 data += byte; 00979 } 00980 Q_EMIT signalWRKSysex(bank, name, autosend, port, data); 00981 } 00982 00983 void QWrk::processThruChunk() 00984 { 00985 readGap(2); 00986 qint8 port = readByte(); // 0->127 00987 qint8 channel = readByte(); // -1, 0->15 00988 qint8 keyPlus = readByte(); // 0->127 00989 qint8 velPlus = readByte(); // 0->127 00990 qint8 localPort = readByte(); 00991 qint8 mode = readByte(); 00992 Q_EMIT signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort); 00993 } 00994 00995 void QWrk::processTrackOffset() 00996 { 00997 quint16 track = read16bit(); 00998 qint16 offset = read16bit(); 00999 Q_EMIT signalWRKTrackOffset(track, offset); 01000 } 01001 01002 void QWrk::processTrackReps() 01003 { 01004 quint16 track = read16bit(); 01005 quint16 reps = read16bit(); 01006 Q_EMIT signalWRKTrackReps(track, reps); 01007 } 01008 01009 void QWrk::processTrackPatch() 01010 { 01011 quint16 track = read16bit(); 01012 qint8 patch = readByte(); 01013 Q_EMIT signalWRKTrackPatch(track, patch); 01014 } 01015 01016 void QWrk::processTimeFormat() 01017 { 01018 quint16 fmt = read16bit(); 01019 quint16 ofs = read16bit(); 01020 Q_EMIT signalWRKTimeFormat(fmt, ofs); 01021 } 01022 01023 void QWrk::processComments() 01024 { 01025 int len = read16bit(); 01026 QString text = readString(len); 01027 Q_EMIT signalWRKComments(text); 01028 } 01029 01030 void QWrk::processVariableRecord(int max) 01031 { 01032 int datalen = max - 32; 01033 QByteArray data; 01034 QString name = readVarString(); 01035 readGap(31 - name.length()); 01036 for ( int i = 0; i < datalen; ++i ) 01037 data += readByte(); 01038 Q_EMIT signalWRKVariableRecord(name, data); 01039 } 01040 01041 void QWrk::processUnknown(int id) 01042 { 01043 Q_EMIT signalWRKUnknownChunk(id, d->m_lastChunkData); 01044 } 01045 01046 void QWrk::processNewTrack() 01047 { 01048 qint16 bank = -1; 01049 qint16 patch = -1; 01050 qint16 vol = -1; 01051 qint16 pan = -1; 01052 qint8 key = -1; 01053 qint8 vel = 0; 01054 quint8 port = 0; 01055 qint8 channel = 0; 01056 bool selected = false; 01057 bool muted = false; 01058 bool loop = false; 01059 quint16 track = read16bit(); 01060 quint8 len = readByte(); 01061 QString name = readString(len); 01062 bank = read16bit(); 01063 patch = read16bit(); 01064 vol = read16bit(); 01065 pan = read16bit(); 01066 key = readByte(); 01067 vel = readByte(); 01068 readGap(7); 01069 port = readByte(); 01070 channel = readByte(); 01071 muted = (readByte() != 0); 01072 Q_EMIT signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop); 01073 if (bank > -1) 01074 Q_EMIT signalWRKTrackBank(track, bank); 01075 if (patch > -1) { 01076 if (channel > -1) 01077 Q_EMIT signalWRKProgram(track, 0, channel, patch); 01078 else 01079 Q_EMIT signalWRKTrackPatch(track, patch); 01080 } 01081 } 01082 01083 void QWrk::processSoftVer() 01084 { 01085 int len = readByte(); 01086 QString vers = readString(len); 01087 Q_EMIT signalWRKSoftVer(vers); 01088 } 01089 01090 void QWrk::processTrackName() 01091 { 01092 int track = read16bit(); 01093 int len = readByte(); 01094 QString name = readString(len); 01095 Q_EMIT signalWRKTrackName(track, name); 01096 } 01097 01098 void QWrk::processStringTable() 01099 { 01100 QStringList table; 01101 int rows = read16bit(); 01102 for (int i = 0; i < rows; ++i) { 01103 int len = readByte(); 01104 QString name = readString(len); 01105 int idx = readByte(); 01106 table.insert(idx, name); 01107 } 01108 Q_EMIT signalWRKStringTable(table); 01109 } 01110 01111 void QWrk::processLyricsStream() 01112 { 01113 quint16 track = read16bit(); 01114 int events = read32bit(); 01115 processNoteArray(track, events); 01116 } 01117 01118 void QWrk::processTrackVol() 01119 { 01120 quint16 track = read16bit(); 01121 int vol = read16bit(); 01122 Q_EMIT signalWRKTrackVol(track, vol); 01123 } 01124 01125 void QWrk::processNewTrackOffset() 01126 { 01127 quint16 track = read16bit(); 01128 int offset = read32bit(); 01129 Q_EMIT signalWRKTrackOffset(track, offset); 01130 } 01131 01132 void QWrk::processTrackBank() 01133 { 01134 quint16 track = read16bit(); 01135 int bank = read16bit(); 01136 Q_EMIT signalWRKTrackBank(track, bank); 01137 } 01138 01139 void QWrk::processSegmentChunk() 01140 { 01141 QString name; 01142 int track = read16bit(); 01143 int offset = read32bit(); 01144 readGap(8); 01145 int len = readByte(); 01146 name = readString(len); 01147 readGap(20); 01148 Q_EMIT signalWRKSegment(track, offset, name); 01149 int events = read32bit(); 01150 processNoteArray(track, events); 01151 } 01152 01153 void QWrk::processNewStream() 01154 { 01155 QString name; 01156 int track = read16bit(); 01157 int len = readByte(); 01158 name = readString(len); 01159 Q_EMIT signalWRKSegment(track, 0, name); 01160 int events = read32bit(); 01161 processNoteArray(track, events); 01162 } 01163 01164 void QWrk::processEndChunk() 01165 { 01166 emit signalWRKEnd(); 01167 } 01168 01169 int QWrk::readChunk() 01170 { 01171 long start_pos, final_pos; 01172 int ck_len, ck = readByte(); 01173 if (ck != END_CHUNK) { 01174 ck_len = read32bit(); 01175 start_pos = getFilePos(); 01176 final_pos = start_pos + ck_len; 01177 readRawData(ck_len); 01178 seek(start_pos); 01179 switch (ck) { 01180 case TRACK_CHUNK: 01181 processTrackChunk(); 01182 break; 01183 case VARS_CHUNK: 01184 processVarsChunk(); 01185 break; 01186 case TIMEBASE_CHUNK: 01187 processTimebaseChunk(); 01188 break; 01189 case STREAM_CHUNK: 01190 processStreamChunk(); 01191 break; 01192 case METER_CHUNK: 01193 processMeterChunk(); 01194 break; 01195 case TEMPO_CHUNK: 01196 processTempoChunk(100); 01197 break; 01198 case NTEMPO_CHUNK: 01199 processTempoChunk(); 01200 break; 01201 case SYSEX_CHUNK: 01202 processSysexChunk(); 01203 break; 01204 case THRU_CHUNK: 01205 processThruChunk(); 01206 break; 01207 case TRKOFFS_CHUNK: 01208 processTrackOffset(); 01209 break; 01210 case TRKREPS_CHUNK: 01211 processTrackReps(); 01212 break; 01213 case TRKPATCH_CHUNK: 01214 processTrackPatch(); 01215 break; 01216 case TIMEFMT_CHUNK: 01217 processTimeFormat(); 01218 break; 01219 case COMMENTS_CHUNK: 01220 processComments(); 01221 break; 01222 case VARIABLE_CHUNK: 01223 processVariableRecord(ck_len); 01224 break; 01225 case NTRACK_CHUNK: 01226 processNewTrack(); 01227 break; 01228 case SOFTVER_CHUNK: 01229 processSoftVer(); 01230 break; 01231 case TRKNAME_CHUNK: 01232 processTrackName(); 01233 break; 01234 case STRTAB_CHUNK: 01235 processStringTable(); 01236 break; 01237 case LYRICS_CHUNK: 01238 processLyricsStream(); 01239 break; 01240 case TRKVOL_CHUNK: 01241 processTrackVol(); 01242 break; 01243 case NTRKOFS_CHUNK: 01244 processNewTrackOffset(); 01245 break; 01246 case TRKBANK_CHUNK: 01247 processTrackBank(); 01248 break; 01249 case METERKEY_CHUNK: 01250 processMeterKeyChunk(); 01251 break; 01252 case SYSEX2_CHUNK: 01253 processSysex2Chunk(); 01254 break; 01255 case NSYSEX_CHUNK: 01256 processNewSysexChunk(); 01257 break; 01258 case SGMNT_CHUNK: 01259 processSegmentChunk(); 01260 break; 01261 case NSTREAM_CHUNK: 01262 processNewStream(); 01263 break; 01264 default: 01265 processUnknown(ck); 01266 } 01267 seek(final_pos); 01268 } 01269 return ck; 01270 } 01271 01272 void QWrk::wrkRead() 01273 { 01274 int vma, vme; 01275 int ck_id; 01276 QByteArray hdr(HEADER.length(), ' '); 01277 d->m_tempos.clear(); 01278 d->m_IOStream->device()->read(hdr.data(), HEADER.length()); 01279 if (hdr == HEADER) { 01280 readGap(1); 01281 vme = readByte(); 01282 vma = readByte(); 01283 Q_EMIT signalWRKHeader(vma, vme); 01284 do { 01285 ck_id = readChunk(); 01286 } while (ck_id != END_CHUNK); 01287 if (!atEnd()) 01288 Q_EMIT signalWRKError("Corrupted file"); 01289 else 01290 processEndChunk(); 01291 } else 01292 Q_EMIT signalWRKError("Invalid file format"); 01293 } 01294 01295 } // namespace drumstick