drumstick 0.5.0

qwrk.cpp

Go to the documentation of this file.
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