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