drumstick 0.5.0
qwrk.cpp
Go to the documentation of this file.
1/*
2 WRK File component
3 Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl@users.sf.net>
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19
20#include "qwrk.h"
21#include <cmath>
22#include <QDataStream>
23#include <QFile>
24#include <QIODevice>
25#include <QTextStream>
26#include <QTextCodec>
27#include <QStringList>
28
34namespace drumstick {
35
48class QWrk::QWrkPrivate {
49public:
50 QWrkPrivate():
51 m_Now(0),
52 m_From(0),
53 m_Thru(11930),
54 m_KeySig(0),
55 m_Clock(0),
56 m_AutoSave(0),
57 m_PlayDelay(0),
58 m_ZeroCtrls(false),
59 m_SendSPP(true),
60 m_SendCont(true),
61 m_PatchSearch(false),
62 m_AutoStop(false),
63 m_StopTime(4294967295U),
64 m_AutoRewind(false),
65 m_RewindTime(0),
66 m_MetroPlay(false),
67 m_MetroRecord(true),
68 m_MetroAccent(false),
69 m_CountIn(1),
70 m_ThruOn(true),
71 m_AutoRestart(false),
72 m_CurTempoOfs(1),
73 m_TempoOfs1(32),
74 m_TempoOfs2(64),
75 m_TempoOfs3(128),
76 m_PunchEnabled(false),
77 m_PunchInTime(0),
78 m_PunchOutTime(0),
79 m_EndAllTime(0),
80 m_division(120),
81 m_codec(0),
82 m_IOStream(0)
83 { }
84
85 quint32 m_Now;
86 quint32 m_From;
87 quint32 m_Thru;
88 quint8 m_KeySig;
89 quint8 m_Clock;
90 quint8 m_AutoSave;
91 quint8 m_PlayDelay;
92 bool m_ZeroCtrls;
93 bool m_SendSPP;
94 bool m_SendCont;
95 bool m_PatchSearch;
96 bool m_AutoStop;
97 quint32 m_StopTime;
98 bool m_AutoRewind;
99 quint32 m_RewindTime;
100 bool m_MetroPlay;
101 bool m_MetroRecord;
102 bool m_MetroAccent;
103 quint8 m_CountIn;
104 bool m_ThruOn;
105 bool m_AutoRestart;
106 quint8 m_CurTempoOfs;
107 quint8 m_TempoOfs1;
108 quint8 m_TempoOfs2;
109 quint8 m_TempoOfs3;
110 bool m_PunchEnabled;
111 quint32 m_PunchInTime;
112 quint32 m_PunchOutTime;
113 quint32 m_EndAllTime;
114
115 int m_division;
116 QTextCodec *m_codec;
117 QDataStream *m_IOStream;
118 QByteArray m_lastChunkData;
119 QList<RecTempo> m_tempos;
120};
121
126 QObject(parent),
127 d(new QWrkPrivate)
128{ }
129
134{
135 delete d;
136}
137
143{
144 return d->m_codec;
145}
146
153void QWrk::setTextCodec(QTextCodec *codec)
154{
155 d->m_codec = codec;
156}
157
164{
165 return d->m_lastChunkData;
166}
167
171void QWrk::readRawData(int size)
172{
173 d->m_lastChunkData = d->m_IOStream->device()->read(size);
174}
175
180int QWrk::getNow() const
181{
182 return d->m_Now;
183}
184
189int QWrk::getFrom() const
190{
191 return d->m_From;
192}
193
198int QWrk::getThru() const
199{
200 return d->m_Thru;
201}
202
208{
209 return d->m_KeySig;
210}
211
216int QWrk::getClock() const
217{
218 return d->m_Clock;
219}
220
226{
227 return d->m_AutoSave;
228}
229
235{
236 return d->m_PlayDelay;
237}
238
244{
245 return d->m_ZeroCtrls;
246}
247
253{
254 return d->m_SendSPP;
255}
256
262{
263 return d->m_SendCont;
264}
265
271{
272 return d->m_PatchSearch;
273}
274
280{
281 return d->m_AutoStop;
282}
283
288unsigned int QWrk::getStopTime() const
289{
290 return d->m_StopTime;
291}
292
298{
299 return d->m_AutoRewind;
300}
301
307{
308 return d->m_RewindTime;
309}
310
316{
317 return d->m_MetroPlay;
318}
319
325{
326 return d->m_MetroRecord;
327}
328
334{
335 return d->m_MetroAccent;
336}
337
343{
344 return d->m_CountIn;
345}
346
351bool QWrk::getThruOn() const
352{
353 return d->m_ThruOn;
354}
355
361{
362 return d->m_AutoRestart;
363}
364
370{
371 return d->m_CurTempoOfs;
372}
373
389{
390 return d->m_TempoOfs1;
391}
392
408{
409 return d->m_TempoOfs2;
410}
411
427{
428 return d->m_TempoOfs3;
429}
430
436{
437 return d->m_PunchEnabled;
438}
439
445{
446 return d->m_PunchInTime;
447}
448
454{
455 return d->m_PunchOutTime;
456}
457
463{
464 return d->m_EndAllTime;
465}
466
471quint8 QWrk::readByte()
472{
473 quint8 b = 0xff;
474 if (!d->m_IOStream->atEnd())
475 *d->m_IOStream >> b;
476 return b;
477}
478
485quint16 QWrk::to16bit(quint8 c1, quint8 c2)
486{
487 quint16 value = (c1 << 8);
488 value += c2;
489 return value;
490}
491
500quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
501{
502 quint32 value = (c1 << 24);
503 value += (c2 << 16);
504 value += (c3 << 8);
505 value += c4;
506 return value;
507}
508
513quint16 QWrk::read16bit()
514{
515 quint8 c1, c2;
516 c1 = readByte();
517 c2 = readByte();
518 return to16bit(c2, c1);
519}
520
525quint32 QWrk::read24bit()
526{
527 quint8 c1, c2, c3;
528 c1 = readByte();
529 c2 = readByte();
530 c3 = readByte();
531 return to32bit(0, c3, c2, c1);
532}
533
538quint32 QWrk::read32bit()
539{
540 quint8 c1, c2, c3, c4;
541 c1 = readByte();
542 c2 = readByte();
543 c3 = readByte();
544 c4 = readByte();
545 return to32bit(c4, c3, c2, c1);
546}
547
552QString QWrk::readString(int len)
553{
554 QString s;
555 if ( len > 0 ) {
556 quint8 c = 0xff;
557 QByteArray data;
558 for ( int i = 0; i < len && c != 0; ++i ) {
559 c = readByte();
560 if ( c != 0)
561 data += c;
562 }
563 if (d->m_codec == NULL)
564 s = QString(data);
565 else
566 s = d->m_codec->toUnicode(data);
567 }
568 return s;
569}
570
575QString QWrk::readVarString()
576{
577 QString s;
578 QByteArray data;
579 quint8 b;
580 do {
581 b = readByte();
582 if (b != 0)
583 data += b;
584 } while (b != 0);
585 if (d->m_codec == NULL)
586 s = QString(data);
587 else
588 s = d->m_codec->toUnicode(data);
589 return s;
590}
591
597{
598 return d->m_IOStream->device()->pos();
599}
600
605void QWrk::seek(qint64 pos)
606{
607 d->m_IOStream->device()->seek(pos);
608}
609
614bool QWrk::atEnd()
615{
616 return d->m_IOStream->atEnd();
617}
618
623void QWrk::readGap(int size)
624{
625 if ( size > 0)
626 seek( getFilePos() + size );
627}
628
633void QWrk::readFromStream(QDataStream *stream)
634{
635 d->m_IOStream = stream;
636 wrkRead();
637}
638
643void QWrk::readFromFile(const QString& fileName)
644{
645 QFile file(fileName);
646 file.open(QIODevice::ReadOnly);
647 QDataStream ds(&file);
648 readFromStream(&ds);
649 file.close();
650}
651
652void QWrk::processTrackChunk()
653{
654 int namelen;
655 QString name[2];
656 int trackno;
657 int channel;
658 int pitch;
659 int velocity;
660 int port;
661 bool selected;
662 bool muted;
663 bool loop;
664
665 trackno = read16bit();
666 for(int i=0; i<2; ++i) {
667 namelen = readByte();
668 name[i] = readString(namelen);
669 }
670 channel = (qint8) readByte();
671 pitch = readByte();
672 velocity = readByte();
673 port = readByte();
674 quint8 flags = readByte();
675 selected = ((flags & 1) != 0);
676 muted = ((flags & 2) != 0);
677 loop = ((flags & 4) != 0);
678 Q_EMIT signalWRKTrack( name[0], name[1],
679 trackno, channel, pitch,
680 velocity, port, selected,
681 muted, loop );
682}
683
684void QWrk::processVarsChunk()
685{
686 d->m_Now = read32bit();
687 d->m_From = read32bit();
688 d->m_Thru = read32bit();
689 d->m_KeySig = readByte();
690 d->m_Clock = readByte();
691 d->m_AutoSave = readByte();
692 d->m_PlayDelay = readByte();
693 readGap(1);
694 d->m_ZeroCtrls = (readByte() != 0);
695 d->m_SendSPP = (readByte() != 0);
696 d->m_SendCont = (readByte() != 0);
697 d->m_PatchSearch = (readByte() != 0);
698 d->m_AutoStop = (readByte() != 0);
699 d->m_StopTime = read32bit();
700 d->m_AutoRewind = (readByte() != 0);
701 d->m_RewindTime = read32bit();
702 d->m_MetroPlay = (readByte() != 0);
703 d->m_MetroRecord = (readByte() != 0);
704 d->m_MetroAccent = (readByte() != 0);
705 d->m_CountIn = readByte();
706 readGap(2);
707 d->m_ThruOn = (readByte() != 0);
708 readGap(19);
709 d->m_AutoRestart = (readByte() != 0);
710 d->m_CurTempoOfs = readByte();
711 d->m_TempoOfs1 = readByte();
712 d->m_TempoOfs2 = readByte();
713 d->m_TempoOfs3 = readByte();
714 readGap(2);
715 d->m_PunchEnabled = (readByte() != 0);
716 d->m_PunchInTime = read32bit();
717 d->m_PunchOutTime = read32bit();
718 d->m_EndAllTime = read32bit();
719
720 Q_EMIT signalWRKGlobalVars();
721}
722
723void QWrk::processTimebaseChunk()
724{
725 quint16 timebase = read16bit();
726 d->m_division = timebase;
727 Q_EMIT signalWRKTimeBase(timebase);
728}
729
730void QWrk::processNoteArray(int track, int events)
731{
732 quint32 time = 0;
733 quint8 status = 0, data1 = 0, data2 = 0;
734 quint16 dur = 0;
735 int value = 0, type = 0, channel = 0, len = 0;
736 QString text;
737 QByteArray data;
738 for ( int i = 0; i < events; ++i ) {
739 time = read24bit();
740 status = readByte();
741 dur = 0;
742 if (status >= 0x90) {
743 type = status & 0xf0;
744 channel = status & 0x0f;
745 data1 = readByte();
746 if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0)
747 data2 = readByte();
748 if (type == 0x90)
749 dur = read16bit();
750 switch (type) {
751 case 0x90:
752 Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur);
753 break;
754 case 0xA0:
755 Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2);
756 break;
757 case 0xB0:
758 Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2);
759 break;
760 case 0xC0:
761 Q_EMIT signalWRKProgram(track, time, channel, data1);
762 break;
763 case 0xD0:
764 Q_EMIT signalWRKChanPress(track, time, channel, data1);
765 break;
766 case 0xE0:
767 value = (data2 << 7) + data1 - 8192;
768 Q_EMIT signalWRKPitchBend(track, time, channel, value);
769 break;
770 case 0xF0:
771 Q_EMIT signalWRKSysexEvent(track, time, data1);
772 break;
773 }
774 } else if (status == 5) {
775 int code = read16bit();
776 len = read32bit();
777 text = readString(len);
778 Q_EMIT signalWRKExpression(track, time, code, text);
779 } else if (status == 6) {
780 int code = read16bit();
781 dur = read16bit();
782 readGap(4);
783 Q_EMIT signalWRKHairpin(track, time, code, dur);
784 } else if (status == 7) {
785 len = read32bit();
786 text = readString(len);
787 data.clear();
788 for(int j=0; j<13; ++j) {
789 int byte = readByte();
790 data += byte;
791 }
792 Q_EMIT signalWRKChord(track, time, text, data);
793 } else if (status == 8) {
794 len = read16bit();
795 data.clear();
796 for(int j=0; j<len; ++j) {
797 int byte = readByte();
798 data += byte;
799 }
800 Q_EMIT signalWRKSysex(0, QString(), false, 0, data);
801 } else {
802 len = read32bit();
803 text = readString(len);
804 Q_EMIT signalWRKText(track, time, status, text);
805 }
806 }
807 Q_EMIT signalWRKStreamEnd(time + dur);
808}
809
810void QWrk::processStreamChunk()
811{
812 long time = 0;
813 int dur = 0, value = 0, type = 0, channel = 0;
814 quint8 status = 0, data1 = 0, data2 = 0;
815 quint16 track = read16bit();
816 int events = read16bit();
817 for ( int i = 0; i < events; ++i ) {
818 time = read24bit();
819 status = readByte();
820 data1 = readByte();
821 data2 = readByte();
822 dur = read16bit();
823 type = status & 0xf0;
824 channel = status & 0x0f;
825 switch (type) {
826 case 0x90:
827 Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur);
828 break;
829 case 0xA0:
830 Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2);
831 break;
832 case 0xB0:
833 Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2);
834 break;
835 case 0xC0:
836 Q_EMIT signalWRKProgram(track, time, channel, data1);
837 break;
838 case 0xD0:
839 Q_EMIT signalWRKChanPress(track, time, channel, data1);
840 break;
841 case 0xE0:
842 value = (data2 << 7) + data1 - 8192;
843 Q_EMIT signalWRKPitchBend(track, time, channel, value);
844 break;
845 case 0xF0:
846 Q_EMIT signalWRKSysexEvent(track, time, data1);
847 break;
848 }
849 }
850 Q_EMIT signalWRKStreamEnd(time + dur);
851}
852
853void QWrk::processMeterChunk()
854{
855 int count = read16bit();
856 for (int i = 0; i < count; ++i) {
857 readGap(4);
858 int measure = read16bit();
859 int num = readByte();
860 int den = pow(2, readByte());
861 readGap(4);
862 Q_EMIT signalWRKTimeSig(measure, num, den);
863 }
864}
865
866void QWrk::processMeterKeyChunk()
867{
868 int count = read16bit();
869 for (int i = 0; i < count; ++i) {
870 int measure = read16bit();
871 int num = readByte();
872 int den = pow(2, readByte());
873 qint8 alt = readByte();
874 Q_EMIT signalWRKTimeSig(measure, num, den);
875 Q_EMIT signalWRKKeySig(measure, alt);
876 }
877}
878
879double QWrk::getRealTime(long ticks) const
880{
881 double division = 1.0 * d->m_division;
882 RecTempo last;
883 last.time = 0;
884 last.tempo = 100.0;
885 last.seconds = 0.0;
886 if (!d->m_tempos.isEmpty()) {
887 foreach(const RecTempo& rec, d->m_tempos) {
888 if (rec.time >= ticks)
889 break;
890 last = rec;
891 }
892 }
893 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
894}
895
896void QWrk::processTempoChunk(int factor)
897{
898 double division = 1.0 * d->m_division;
899 int count = read16bit();
900 RecTempo last, next;
901 for (int i = 0; i < count; ++i) {
902
903 long time = read32bit();
904 readGap(4);
905 long tempo = read16bit() * factor;
906 readGap(8);
907
908 next.time = time;
909 next.tempo = tempo / 100.0;
910 next.seconds = 0.0;
911 last.time = 0;
912 last.tempo = next.tempo;
913 last.seconds = 0.0;
914 if (! d->m_tempos.isEmpty()) {
915 foreach(const RecTempo& rec, d->m_tempos) {
916 if (rec.time >= time)
917 break;
918 last = rec;
919 }
920 next.seconds = last.seconds +
921 (((time - last.time) / division) * (60.0 / last.tempo));
922 }
923 d->m_tempos.append(next);
924
925 Q_EMIT signalWRKTempo(time, tempo);
926 }
927}
928
929void QWrk::processSysexChunk()
930{
931 int j;
932 QString name;
933 QByteArray data;
934 int bank = readByte();
935 int length = read16bit();
936 bool autosend = (readByte() != 0);
937 int namelen = readByte();
938 name = readString(namelen);
939 for(j=0; j<length; ++j) {
940 int byte = readByte();
941 data += byte;
942 }
943 Q_EMIT signalWRKSysex(bank, name, autosend, 0, data);
944}
945
946void QWrk::processSysex2Chunk()
947{
948 int j;
949 QString name;
950 QByteArray data;
951 int bank = read16bit();
952 int length = read32bit();
953 quint8 b = readByte();
954 int port = ( b & 0xf0 ) >> 4;
955 bool autosend = ( (b & 0x0f) != 0);
956 int namelen = readByte();
957 name = readString(namelen);
958 for(j=0; j<length; ++j) {
959 int byte = readByte();
960 data += byte;
961 }
962 Q_EMIT signalWRKSysex(bank, name, autosend, port, data);
963}
964
965void QWrk::processNewSysexChunk()
966{
967 int j;
968 QString name;
969 QByteArray data;
970 int bank = read16bit();
971 int length = read32bit();
972 int port = read16bit();
973 bool autosend = (readByte() != 0);
974 int namelen = readByte();
975 name = readString(namelen);
976 for(j=0; j<length; ++j) {
977 int byte = readByte();
978 data += byte;
979 }
980 Q_EMIT signalWRKSysex(bank, name, autosend, port, data);
981}
982
983void QWrk::processThruChunk()
984{
985 readGap(2);
986 qint8 port = readByte(); // 0->127
987 qint8 channel = readByte(); // -1, 0->15
988 qint8 keyPlus = readByte(); // 0->127
989 qint8 velPlus = readByte(); // 0->127
990 qint8 localPort = readByte();
991 qint8 mode = readByte();
992 Q_EMIT signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
993}
994
995void QWrk::processTrackOffset()
996{
997 quint16 track = read16bit();
998 qint16 offset = read16bit();
999 Q_EMIT signalWRKTrackOffset(track, offset);
1000}
1001
1002void QWrk::processTrackReps()
1003{
1004 quint16 track = read16bit();
1005 quint16 reps = read16bit();
1006 Q_EMIT signalWRKTrackReps(track, reps);
1007}
1008
1009void QWrk::processTrackPatch()
1010{
1011 quint16 track = read16bit();
1012 qint8 patch = readByte();
1013 Q_EMIT signalWRKTrackPatch(track, patch);
1014}
1015
1016void QWrk::processTimeFormat()
1017{
1018 quint16 fmt = read16bit();
1019 quint16 ofs = read16bit();
1020 Q_EMIT signalWRKTimeFormat(fmt, ofs);
1021}
1022
1023void QWrk::processComments()
1024{
1025 int len = read16bit();
1026 QString text = readString(len);
1027 Q_EMIT signalWRKComments(text);
1028}
1029
1030void QWrk::processVariableRecord(int max)
1031{
1032 int datalen = max - 32;
1033 QByteArray data;
1034 QString name = readVarString();
1035 readGap(31 - name.length());
1036 for ( int i = 0; i < datalen; ++i )
1037 data += readByte();
1038 Q_EMIT signalWRKVariableRecord(name, data);
1039}
1040
1041void QWrk::processUnknown(int id)
1042{
1043 Q_EMIT signalWRKUnknownChunk(id, d->m_lastChunkData);
1044}
1045
1046void QWrk::processNewTrack()
1047{
1048 qint16 bank = -1;
1049 qint16 patch = -1;
1050 qint16 vol = -1;
1051 qint16 pan = -1;
1052 qint8 key = -1;
1053 qint8 vel = 0;
1054 quint8 port = 0;
1055 qint8 channel = 0;
1056 bool selected = false;
1057 bool muted = false;
1058 bool loop = false;
1059 quint16 track = read16bit();
1060 quint8 len = readByte();
1061 QString name = readString(len);
1062 bank = read16bit();
1063 patch = read16bit();
1064 vol = read16bit();
1065 pan = read16bit();
1066 key = readByte();
1067 vel = readByte();
1068 readGap(7);
1069 port = readByte();
1070 channel = readByte();
1071 muted = (readByte() != 0);
1072 Q_EMIT signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1073 if (bank > -1)
1074 Q_EMIT signalWRKTrackBank(track, bank);
1075 if (patch > -1) {
1076 if (channel > -1)
1077 Q_EMIT signalWRKProgram(track, 0, channel, patch);
1078 else
1079 Q_EMIT signalWRKTrackPatch(track, patch);
1080 }
1081}
1082
1083void QWrk::processSoftVer()
1084{
1085 int len = readByte();
1086 QString vers = readString(len);
1087 Q_EMIT signalWRKSoftVer(vers);
1088}
1089
1090void QWrk::processTrackName()
1091{
1092 int track = read16bit();
1093 int len = readByte();
1094 QString name = readString(len);
1095 Q_EMIT signalWRKTrackName(track, name);
1096}
1097
1098void QWrk::processStringTable()
1099{
1100 QStringList table;
1101 int rows = read16bit();
1102 for (int i = 0; i < rows; ++i) {
1103 int len = readByte();
1104 QString name = readString(len);
1105 int idx = readByte();
1106 table.insert(idx, name);
1107 }
1108 Q_EMIT signalWRKStringTable(table);
1109}
1110
1111void QWrk::processLyricsStream()
1112{
1113 quint16 track = read16bit();
1114 int events = read32bit();
1115 processNoteArray(track, events);
1116}
1117
1118void QWrk::processTrackVol()
1119{
1120 quint16 track = read16bit();
1121 int vol = read16bit();
1122 Q_EMIT signalWRKTrackVol(track, vol);
1123}
1124
1125void QWrk::processNewTrackOffset()
1126{
1127 quint16 track = read16bit();
1128 int offset = read32bit();
1129 Q_EMIT signalWRKTrackOffset(track, offset);
1130}
1131
1132void QWrk::processTrackBank()
1133{
1134 quint16 track = read16bit();
1135 int bank = read16bit();
1136 Q_EMIT signalWRKTrackBank(track, bank);
1137}
1138
1139void QWrk::processSegmentChunk()
1140{
1141 QString name;
1142 int track = read16bit();
1143 int offset = read32bit();
1144 readGap(8);
1145 int len = readByte();
1146 name = readString(len);
1147 readGap(20);
1148 Q_EMIT signalWRKSegment(track, offset, name);
1149 int events = read32bit();
1150 processNoteArray(track, events);
1151}
1152
1153void QWrk::processNewStream()
1154{
1155 QString name;
1156 int track = read16bit();
1157 int len = readByte();
1158 name = readString(len);
1159 Q_EMIT signalWRKSegment(track, 0, name);
1160 int events = read32bit();
1161 processNoteArray(track, events);
1162}
1163
1164void QWrk::processEndChunk()
1165{
1166 emit signalWRKEnd();
1167}
1168
1169int QWrk::readChunk()
1170{
1171 long start_pos, final_pos;
1172 int ck_len, ck = readByte();
1173 if (ck != END_CHUNK) {
1174 ck_len = read32bit();
1175 start_pos = getFilePos();
1176 final_pos = start_pos + ck_len;
1177 readRawData(ck_len);
1178 seek(start_pos);
1179 switch (ck) {
1180 case TRACK_CHUNK:
1181 processTrackChunk();
1182 break;
1183 case VARS_CHUNK:
1184 processVarsChunk();
1185 break;
1186 case TIMEBASE_CHUNK:
1187 processTimebaseChunk();
1188 break;
1189 case STREAM_CHUNK:
1190 processStreamChunk();
1191 break;
1192 case METER_CHUNK:
1193 processMeterChunk();
1194 break;
1195 case TEMPO_CHUNK:
1196 processTempoChunk(100);
1197 break;
1198 case NTEMPO_CHUNK:
1199 processTempoChunk();
1200 break;
1201 case SYSEX_CHUNK:
1202 processSysexChunk();
1203 break;
1204 case THRU_CHUNK:
1205 processThruChunk();
1206 break;
1207 case TRKOFFS_CHUNK:
1208 processTrackOffset();
1209 break;
1210 case TRKREPS_CHUNK:
1211 processTrackReps();
1212 break;
1213 case TRKPATCH_CHUNK:
1214 processTrackPatch();
1215 break;
1216 case TIMEFMT_CHUNK:
1217 processTimeFormat();
1218 break;
1219 case COMMENTS_CHUNK:
1220 processComments();
1221 break;
1222 case VARIABLE_CHUNK:
1223 processVariableRecord(ck_len);
1224 break;
1225 case NTRACK_CHUNK:
1226 processNewTrack();
1227 break;
1228 case SOFTVER_CHUNK:
1229 processSoftVer();
1230 break;
1231 case TRKNAME_CHUNK:
1232 processTrackName();
1233 break;
1234 case STRTAB_CHUNK:
1235 processStringTable();
1236 break;
1237 case LYRICS_CHUNK:
1238 processLyricsStream();
1239 break;
1240 case TRKVOL_CHUNK:
1241 processTrackVol();
1242 break;
1243 case NTRKOFS_CHUNK:
1244 processNewTrackOffset();
1245 break;
1246 case TRKBANK_CHUNK:
1247 processTrackBank();
1248 break;
1249 case METERKEY_CHUNK:
1250 processMeterKeyChunk();
1251 break;
1252 case SYSEX2_CHUNK:
1253 processSysex2Chunk();
1254 break;
1255 case NSYSEX_CHUNK:
1256 processNewSysexChunk();
1257 break;
1258 case SGMNT_CHUNK:
1259 processSegmentChunk();
1260 break;
1261 case NSTREAM_CHUNK:
1262 processNewStream();
1263 break;
1264 default:
1265 processUnknown(ck);
1266 }
1267 seek(final_pos);
1268 }
1269 return ck;
1270}
1271
1272void QWrk::wrkRead()
1273{
1274 int vma, vme;
1275 int ck_id;
1276 QByteArray hdr(HEADER.length(), ' ');
1277 d->m_tempos.clear();
1278 d->m_IOStream->device()->read(hdr.data(), HEADER.length());
1279 if (hdr == HEADER) {
1280 readGap(1);
1281 vme = readByte();
1282 vma = readByte();
1283 Q_EMIT signalWRKHeader(vma, vme);
1284 do {
1285 ck_id = readChunk();
1286 } while (ck_id != END_CHUNK);
1287 if (!atEnd())
1288 Q_EMIT signalWRKError("Corrupted file");
1289 else
1290 processEndChunk();
1291 } else
1292 Q_EMIT signalWRKError("Invalid file format");
1293}
1294
1295} // namespace drumstick
The QObject class is the base class of all Qt objects.
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
bool getMetroRecord() const
Metronome on during recording?
Definition qwrk.cpp:324
bool getPunchEnabled() const
Auto-Punch enabled?
Definition qwrk.cpp:435
void signalWRKText(int track, long time, int type, const QString &data)
Emitted after reading a text message.
int getRewindTime() const
Auto-rewind time.
Definition qwrk.cpp:306
bool getZeroCtrls() const
Zero continuous controllers?
Definition qwrk.cpp:243
void signalWRKTrack(const QString &name1, const QString &name2, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop)
Emitted after reading a track prefix chunk.
void signalWRKProgram(int track, long time, int chan, int patch)
Emitted after reading a Program change message.
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
Definition qwrk.cpp:153
void signalWRKHeader(int verh, int verl)
Emitted after reading a WRK header.
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes)
Definition qwrk.cpp:225
long getFilePos()
Current position in the data stream.
Definition qwrk.cpp:596
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
Definition qwrk.cpp:351
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
int getNow() const
Now marker time.
Definition qwrk.cpp:180
int getPunchOutTime() const
Punch-out time.
Definition qwrk.cpp:453
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
void signalWRKTrackOffset(int track, int offset)
Emitted after reading a track offset chunk.
void signalWRKChanPress(int track, long time, int chan, int press)
Emitted after reading a Channel Aftertouch message.
void signalWRKStreamEnd(long time)
Emitted after reading the last event of a event stream.
bool getAutoStop() const
Auto-stop?
Definition qwrk.cpp:279
int getEndAllTime() const
Time of latest event (incl.
Definition qwrk.cpp:462
void signalWRKKeyPress(int track, long time, int chan, int pitch, int press)
Emitted after reading a Polyphonic Aftertouch message.
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
void signalWRKTrackVol(int track, int vol)
Emitted after reading a track volume chunk.
void signalWRKStringTable(const QStringList &strs)
Emitted after reading a string event types chunk.
int getPlayDelay() const
Play Delay.
Definition qwrk.cpp:234
bool getSendSPP() const
Send Song Position Pointer?
Definition qwrk.cpp:252
void signalWRKError(const QString &errorStr)
Emitted for a WRK file read error.
QWrk(QObject *parent=0)
Constructor.
Definition qwrk.cpp:125
virtual ~QWrk()
Destructor.
Definition qwrk.cpp:133
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
void signalWRKTempo(long time, int tempo)
Emitted after reading a Tempo Change message.
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
void signalWRKTimeSig(int bar, int num, int den)
Emitted after reading a WRK Time signature.
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
Definition qwrk.cpp:426
int getThru() const
Thru marker time.
Definition qwrk.cpp:198
bool getSendCont() const
Send MIDI Continue?
Definition qwrk.cpp:261
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
Definition qwrk.cpp:407
bool getPatchSearch() const
Patch/controller search-back?
Definition qwrk.cpp:270
void readFromStream(QDataStream *stream)
Reads a stream.
Definition qwrk.cpp:633
void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort)
Emitted after reading an Extended Thru parameters chunk.
int getPunchInTime() const
Punch-in time.
Definition qwrk.cpp:444
void signalWRKNote(int track, long time, int chan, int pitch, int vol, int dur)
Emitted after reading a Note message.
unsigned int getStopTime() const
Auto-stop time.
Definition qwrk.cpp:288
void signalWRKUnknownChunk(int type, const QByteArray &data)
Emitted after reading an unknown chunk.
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
Definition qwrk.cpp:163
bool getAutoRewind() const
Auto-rewind?
Definition qwrk.cpp:297
bool getMetroPlay() const
Metronome on during playback?
Definition qwrk.cpp:315
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
Definition qwrk.cpp:142
int getFrom() const
From marker time.
Definition qwrk.cpp:189
void signalWRKTimeFormat(int frames, int offset)
Emitted after reading a SMPTE time format chunk.
void signalWRKSysex(int bank, const QString &name, bool autosend, int port, const QByteArray &data)
Emitted after reading a System Exclusive Bank.
void readFromFile(const QString &fileName)
Reads a stream from a disk file.
Definition qwrk.cpp:643
int getCountIn() const
Measures of count-in (0=no count-in)
Definition qwrk.cpp:342
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
Definition qwrk.cpp:369
void signalWRKCtlChange(int track, long time, int chan, int ctl, int value)
Emitted after reading a Control Change message.
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
void signalWRKNewTrack(const QString &name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop)
Emitted after reading a new track prefix.
void signalWRKKeySig(int bar, int alt)
Emitted after reading a WRK Key Signature.
bool getAutoRestart() const
Auto-restart?
Definition qwrk.cpp:360
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
Definition qwrk.cpp:216
int getKeySig() const
Key signature (0=C, 1=C#, ... 11=B)
Definition qwrk.cpp:207
bool getMetroAccent() const
Metronome accents primary beats?
Definition qwrk.cpp:333
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
Definition qwrk.cpp:388
Cakewalk WRK Files Input.
const QByteArray HEADER("CAKEWALK")
Cakewalk WRK File header id.
@ NTRKOFS_CHUNK
Track offset.
Definition qwrk.h:63
@ NTRACK_CHUNK
Track prefix.
Definition qwrk.h:65
@ TRKPATCH_CHUNK
Track patch.
Definition qwrk.h:53
@ STRTAB_CHUNK
Table of text event types.
Definition qwrk.h:59
@ NTEMPO_CHUNK
New Tempo map.
Definition qwrk.h:54
@ VARS_CHUNK
Global variables.
Definition qwrk.h:43
@ TRKBANK_CHUNK
Track bank.
Definition qwrk.h:64
@ COMMENTS_CHUNK
Comments.
Definition qwrk.h:48
@ SGMNT_CHUNK
Segment prefix.
Definition qwrk.h:68
@ SOFTVER_CHUNK
Software version which saved the file.
Definition qwrk.h:69
@ TRKNAME_CHUNK
Track name.
Definition qwrk.h:61
@ TIMEFMT_CHUNK
SMPTE time format.
Definition qwrk.h:51
@ STREAM_CHUNK
Events stream.
Definition qwrk.h:42
@ TRACK_CHUNK
Track prefix.
Definition qwrk.h:41
@ TIMEBASE_CHUNK
Timebase. If present is the first chunk in the file.
Definition qwrk.h:50
@ TRKOFFS_CHUNK
Track offset.
Definition qwrk.h:49
@ NSYSEX_CHUNK
System exclusive bank.
Definition qwrk.h:66
@ THRU_CHUNK
Extended thru parameters.
Definition qwrk.h:55
@ SYSEX2_CHUNK
System exclusive bank.
Definition qwrk.h:58
@ NSTREAM_CHUNK
Events stream.
Definition qwrk.h:67
@ TEMPO_CHUNK
Tempo map.
Definition qwrk.h:44
@ VARIABLE_CHUNK
Variable record chunk.
Definition qwrk.h:62
@ METER_CHUNK
Meter map.
Definition qwrk.h:45
@ METERKEY_CHUNK
Meter/Key map.
Definition qwrk.h:60
@ TRKREPS_CHUNK
Track repetitions.
Definition qwrk.h:52
@ TRKVOL_CHUNK
Track volume.
Definition qwrk.h:57
@ SYSEX_CHUNK
System exclusive bank.
Definition qwrk.h:46
@ LYRICS_CHUNK
Events stream with lyrics.
Definition qwrk.h:56