drumstick  1.1.2
qwrk.cpp
Go to the documentation of this file.
1 /*
2  WRK File component
3  Copyright (C) 2010-2018, 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 "qwrk.h"
20 #include <cmath>
21 #include <QDataStream>
22 #include <QFile>
23 #include <QIODevice>
24 #include <QTextStream>
25 #include <QTextCodec>
26 #include <QStringList>
27 
33 namespace drumstick {
34 
47 class QWrk::QWrkPrivate {
48 public:
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 
124 QWrk::QWrk(QObject * parent) :
125  QObject(parent),
126  d(new QWrkPrivate)
127 { }
128 
133 {
134  delete d;
135 }
136 
141 QTextCodec* QWrk::getTextCodec()
142 {
143  return d->m_codec;
144 }
145 
152 void QWrk::setTextCodec(QTextCodec *codec)
153 {
154  d->m_codec = codec;
155 }
156 
162 QByteArray QWrk::getLastChunkRawData() const
163 {
164  return d->m_lastChunkData;
165 }
166 
170 void QWrk::readRawData(int size)
171 {
172  d->m_lastChunkData = d->m_IOStream->device()->read(size);
173 }
174 
179 int QWrk::getNow() const
180 {
181  return d->m_Now;
182 }
183 
188 int QWrk::getFrom() const
189 {
190  return d->m_From;
191 }
192 
197 int QWrk::getThru() const
198 {
199  return d->m_Thru;
200 }
201 
206 int QWrk::getKeySig() const
207 {
208  return d->m_KeySig;
209 }
210 
215 int QWrk::getClock() const
216 {
217  return d->m_Clock;
218 }
219 
224 int QWrk::getAutoSave() const
225 {
226  return d->m_AutoSave;
227 }
228 
234 {
235  return d->m_PlayDelay;
236 }
237 
242 bool QWrk::getZeroCtrls() const
243 {
244  return d->m_ZeroCtrls;
245 }
246 
251 bool QWrk::getSendSPP() const
252 {
253  return d->m_SendSPP;
254 }
255 
260 bool QWrk::getSendCont() const
261 {
262  return d->m_SendCont;
263 }
264 
270 {
271  return d->m_PatchSearch;
272 }
273 
278 bool QWrk::getAutoStop() const
279 {
280  return d->m_AutoStop;
281 }
282 
287 unsigned 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 
314 bool QWrk::getMetroPlay() const
315 {
316  return d->m_MetroPlay;
317 }
318 
324 {
325  return d->m_MetroRecord;
326 }
327 
333 {
334  return d->m_MetroAccent;
335 }
336 
341 int QWrk::getCountIn() const
342 {
343  return d->m_CountIn;
344 }
345 
350 bool 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 
470 quint8 QWrk::readByte()
471 {
472  quint8 b = 0xff;
473  if (!d->m_IOStream->atEnd())
474  *d->m_IOStream >> b;
475  return b;
476 }
477 
484 quint16 QWrk::to16bit(quint8 c1, quint8 c2)
485 {
486  quint16 value = (c1 << 8);
487  value += c2;
488  return value;
489 }
490 
499 quint32 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 
512 quint16 QWrk::read16bit()
513 {
514  quint8 c1, c2;
515  c1 = readByte();
516  c2 = readByte();
517  return to16bit(c2, c1);
518 }
519 
524 quint32 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 
537 quint32 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 
551 QString 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; ++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 
574 QString 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);
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 
604 void QWrk::seek(qint64 pos)
605 {
606  d->m_IOStream->device()->seek(pos);
607 }
608 
613 bool QWrk::atEnd()
614 {
615  return d->m_IOStream->atEnd();
616 }
617 
622 void QWrk::readGap(int size)
623 {
624  if ( size > 0)
625  seek( getFilePos() + size );
626 }
627 
632 void QWrk::readFromStream(QDataStream *stream)
633 {
634  d->m_IOStream = stream;
635  wrkRead();
636 }
637 
642 void 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 
651 void 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 
683 void 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 
722 void QWrk::processTimebaseChunk()
723 {
724  quint16 timebase = read16bit();
725  d->m_division = timebase;
726  Q_EMIT signalWRKTimeBase(timebase);
727 }
728 
729 void QWrk::processNoteArray(int track, int events)
730 {
731  quint32 time = 0;
732  quint8 status = 0, data1 = 0, data2 = 0;
733  quint16 dur = 0;
734  int value = 0, type = 0, channel = 0, len = 0;
735  QString text;
736  QByteArray data;
737  for ( int i = 0; i < events; ++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  Q_EMIT signalWRKStreamEnd(time + dur);
807 }
808 
809 void QWrk::processStreamChunk()
810 {
811  long time = 0;
812  int dur = 0, value = 0, type = 0, channel = 0;
813  quint8 status = 0, data1 = 0, data2 = 0;
814  quint16 track = read16bit();
815  int events = read16bit();
816  for ( int i = 0; i < events; ++i ) {
817  time = read24bit();
818  status = readByte();
819  data1 = readByte();
820  data2 = readByte();
821  dur = read16bit();
822  type = status & 0xf0;
823  channel = status & 0x0f;
824  switch (type) {
825  case 0x90:
826  Q_EMIT signalWRKNote(track, time, channel, data1, data2, dur);
827  break;
828  case 0xA0:
829  Q_EMIT signalWRKKeyPress(track, time, channel, data1, data2);
830  break;
831  case 0xB0:
832  Q_EMIT signalWRKCtlChange(track, time, channel, data1, data2);
833  break;
834  case 0xC0:
835  Q_EMIT signalWRKProgram(track, time, channel, data1);
836  break;
837  case 0xD0:
838  Q_EMIT signalWRKChanPress(track, time, channel, data1);
839  break;
840  case 0xE0:
841  value = (data2 << 7) + data1 - 8192;
842  Q_EMIT signalWRKPitchBend(track, time, channel, value);
843  break;
844  case 0xF0:
845  Q_EMIT signalWRKSysexEvent(track, time, data1);
846  break;
847  }
848  }
849  Q_EMIT signalWRKStreamEnd(time + dur);
850 }
851 
852 void QWrk::processMeterChunk()
853 {
854  int count = read16bit();
855  for (int i = 0; i < count; ++i) {
856  readGap(4);
857  int measure = read16bit();
858  int num = readByte();
859  int den = pow(2.0, readByte());
860  readGap(4);
861  Q_EMIT signalWRKTimeSig(measure, num, den);
862  }
863 }
864 
865 void QWrk::processMeterKeyChunk()
866 {
867  int count = read16bit();
868  for (int i = 0; i < count; ++i) {
869  int measure = read16bit();
870  int num = readByte();
871  int den = pow(2.0, readByte());
872  qint8 alt = readByte();
873  Q_EMIT signalWRKTimeSig(measure, num, den);
874  Q_EMIT signalWRKKeySig(measure, alt);
875  }
876 }
877 
878 double QWrk::getRealTime(long ticks) const
879 {
880  double division = 1.0 * d->m_division;
881  RecTempo last;
882  last.time = 0;
883  last.tempo = 100.0;
884  last.seconds = 0.0;
885  if (!d->m_tempos.isEmpty()) {
886  foreach(const RecTempo& rec, d->m_tempos) {
887  if (rec.time >= ticks)
888  break;
889  last = rec;
890  }
891  }
892  return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
893 }
894 
895 void QWrk::processTempoChunk(int factor)
896 {
897  double division = 1.0 * d->m_division;
898  int count = read16bit();
899  RecTempo last, next;
900  for (int i = 0; i < count; ++i) {
901 
902  long time = read32bit();
903  readGap(4);
904  long tempo = read16bit() * factor;
905  readGap(8);
906 
907  next.time = time;
908  next.tempo = tempo / 100.0;
909  next.seconds = 0.0;
910  last.time = 0;
911  last.tempo = next.tempo;
912  last.seconds = 0.0;
913  if (! d->m_tempos.isEmpty()) {
914  foreach(const RecTempo& rec, d->m_tempos) {
915  if (rec.time >= time)
916  break;
917  last = rec;
918  }
919  next.seconds = last.seconds +
920  (((time - last.time) / division) * (60.0 / last.tempo));
921  }
922  d->m_tempos.append(next);
923 
924  Q_EMIT signalWRKTempo(time, tempo);
925  }
926 }
927 
928 void QWrk::processSysexChunk()
929 {
930  int j;
931  QString name;
932  QByteArray data;
933  int bank = readByte();
934  int length = read16bit();
935  bool autosend = (readByte() != 0);
936  int namelen = readByte();
937  name = readString(namelen);
938  for(j=0; j<length; ++j) {
939  int byte = readByte();
940  data += byte;
941  }
942  Q_EMIT signalWRKSysex(bank, name, autosend, 0, data);
943 }
944 
945 void QWrk::processSysex2Chunk()
946 {
947  int j;
948  QString name;
949  QByteArray data;
950  int bank = read16bit();
951  int length = read32bit();
952  quint8 b = readByte();
953  int port = ( b & 0xf0 ) >> 4;
954  bool autosend = ( (b & 0x0f) != 0);
955  int namelen = readByte();
956  name = readString(namelen);
957  for(j=0; j<length; ++j) {
958  int byte = readByte();
959  data += byte;
960  }
961  Q_EMIT signalWRKSysex(bank, name, autosend, port, data);
962 }
963 
964 void QWrk::processNewSysexChunk()
965 {
966  int j;
967  QString name;
968  QByteArray data;
969  int bank = read16bit();
970  int length = read32bit();
971  int port = read16bit();
972  bool autosend = (readByte() != 0);
973  int namelen = readByte();
974  name = readString(namelen);
975  for(j=0; j<length; ++j) {
976  int byte = readByte();
977  data += byte;
978  }
979  Q_EMIT signalWRKSysex(bank, name, autosend, port, data);
980 }
981 
982 void QWrk::processThruChunk()
983 {
984  readGap(2);
985  qint8 port = readByte(); // 0->127
986  qint8 channel = readByte(); // -1, 0->15
987  qint8 keyPlus = readByte(); // 0->127
988  qint8 velPlus = readByte(); // 0->127
989  qint8 localPort = readByte();
990  qint8 mode = readByte();
991  Q_EMIT signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
992 }
993 
994 void QWrk::processTrackOffset()
995 {
996  quint16 track = read16bit();
997  qint16 offset = read16bit();
998  Q_EMIT signalWRKTrackOffset(track, offset);
999 }
1000 
1001 void QWrk::processTrackReps()
1002 {
1003  quint16 track = read16bit();
1004  quint16 reps = read16bit();
1005  Q_EMIT signalWRKTrackReps(track, reps);
1006 }
1007 
1008 void QWrk::processTrackPatch()
1009 {
1010  quint16 track = read16bit();
1011  qint8 patch = readByte();
1012  Q_EMIT signalWRKTrackPatch(track, patch);
1013 }
1014 
1015 void QWrk::processTimeFormat()
1016 {
1017  quint16 fmt = read16bit();
1018  quint16 ofs = read16bit();
1019  Q_EMIT signalWRKTimeFormat(fmt, ofs);
1020 }
1021 
1022 void QWrk::processComments()
1023 {
1024  int len = read16bit();
1025  QString text = readString(len);
1026  Q_EMIT signalWRKComments(text);
1027 }
1028 
1029 void QWrk::processVariableRecord(int max)
1030 {
1031  int datalen = max - 32;
1032  QByteArray data;
1033  QString name = readVarString();
1034  readGap(31 - name.length());
1035  for ( int i = 0; i < datalen; ++i )
1036  data += readByte();
1037  Q_EMIT signalWRKVariableRecord(name, data);
1038 }
1039 
1040 void QWrk::processUnknown(int id)
1041 {
1042  Q_EMIT signalWRKUnknownChunk(id, d->m_lastChunkData);
1043 }
1044 
1045 void QWrk::processNewTrack()
1046 {
1047  qint16 bank = -1;
1048  qint16 patch = -1;
1049  //qint16 vol = -1;
1050  //qint16 pan = -1;
1051  qint8 key = -1;
1052  qint8 vel = 0;
1053  quint8 port = 0;
1054  qint8 channel = 0;
1055  bool selected = false;
1056  bool muted = false;
1057  bool loop = false;
1058  quint16 track = read16bit();
1059  quint8 len = readByte();
1060  QString name = readString(len);
1061  bank = read16bit();
1062  patch = read16bit();
1063  /*vol =*/ read16bit();
1064  /*pan =*/ read16bit();
1065  key = readByte();
1066  vel = readByte();
1067  readGap(7);
1068  port = readByte();
1069  channel = readByte();
1070  muted = (readByte() != 0);
1071  Q_EMIT signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1072  if (bank > -1)
1073  Q_EMIT signalWRKTrackBank(track, bank);
1074  if (patch > -1) {
1075  if (channel > -1)
1076  Q_EMIT signalWRKProgram(track, 0, channel, patch);
1077  else
1078  Q_EMIT signalWRKTrackPatch(track, patch);
1079  }
1080 }
1081 
1082 void QWrk::processSoftVer()
1083 {
1084  int len = readByte();
1085  QString vers = readString(len);
1086  Q_EMIT signalWRKSoftVer(vers);
1087 }
1088 
1089 void QWrk::processTrackName()
1090 {
1091  int track = read16bit();
1092  int len = readByte();
1093  QString name = readString(len);
1094  Q_EMIT signalWRKTrackName(track, name);
1095 }
1096 
1097 void QWrk::processStringTable()
1098 {
1099  QStringList table;
1100  int rows = read16bit();
1101  for (int i = 0; i < rows; ++i) {
1102  int len = readByte();
1103  QString name = readString(len);
1104  int idx = readByte();
1105  table.insert(idx, name);
1106  }
1107  Q_EMIT signalWRKStringTable(table);
1108 }
1109 
1110 void QWrk::processLyricsStream()
1111 {
1112  quint16 track = read16bit();
1113  int events = read32bit();
1114  processNoteArray(track, events);
1115 }
1116 
1117 void QWrk::processTrackVol()
1118 {
1119  quint16 track = read16bit();
1120  int vol = read16bit();
1121  Q_EMIT signalWRKTrackVol(track, vol);
1122 }
1123 
1124 void QWrk::processNewTrackOffset()
1125 {
1126  quint16 track = read16bit();
1127  int offset = read32bit();
1128  Q_EMIT signalWRKTrackOffset(track, offset);
1129 }
1130 
1131 void QWrk::processTrackBank()
1132 {
1133  quint16 track = read16bit();
1134  int bank = read16bit();
1135  Q_EMIT signalWRKTrackBank(track, bank);
1136 }
1137 
1138 void QWrk::processSegmentChunk()
1139 {
1140  QString name;
1141  int track = read16bit();
1142  int offset = read32bit();
1143  readGap(8);
1144  int len = readByte();
1145  name = readString(len);
1146  readGap(20);
1147  Q_EMIT signalWRKSegment(track, offset, name);
1148  int events = read32bit();
1149  processNoteArray(track, events);
1150 }
1151 
1152 void QWrk::processNewStream()
1153 {
1154  QString name;
1155  int track = read16bit();
1156  int len = readByte();
1157  name = readString(len);
1158  Q_EMIT signalWRKSegment(track, 0, name);
1159  int events = read32bit();
1160  processNoteArray(track, events);
1161 }
1162 
1163 void QWrk::processEndChunk()
1164 {
1165  emit signalWRKEnd();
1166 }
1167 
1168 int QWrk::readChunk()
1169 {
1170  long start_pos, final_pos;
1171  int ck_len, ck = readByte();
1172  if (ck != END_CHUNK) {
1173  ck_len = read32bit();
1174  start_pos = getFilePos();
1175  final_pos = start_pos + ck_len;
1176  readRawData(ck_len);
1177  seek(start_pos);
1178  switch (ck) {
1179  case TRACK_CHUNK:
1180  processTrackChunk();
1181  break;
1182  case VARS_CHUNK:
1183  processVarsChunk();
1184  break;
1185  case TIMEBASE_CHUNK:
1186  processTimebaseChunk();
1187  break;
1188  case STREAM_CHUNK:
1189  processStreamChunk();
1190  break;
1191  case METER_CHUNK:
1192  processMeterChunk();
1193  break;
1194  case TEMPO_CHUNK:
1195  processTempoChunk(100);
1196  break;
1197  case NTEMPO_CHUNK:
1198  processTempoChunk();
1199  break;
1200  case SYSEX_CHUNK:
1201  processSysexChunk();
1202  break;
1203  case THRU_CHUNK:
1204  processThruChunk();
1205  break;
1206  case TRKOFFS_CHUNK:
1207  processTrackOffset();
1208  break;
1209  case TRKREPS_CHUNK:
1210  processTrackReps();
1211  break;
1212  case TRKPATCH_CHUNK:
1213  processTrackPatch();
1214  break;
1215  case TIMEFMT_CHUNK:
1216  processTimeFormat();
1217  break;
1218  case COMMENTS_CHUNK:
1219  processComments();
1220  break;
1221  case VARIABLE_CHUNK:
1222  processVariableRecord(ck_len);
1223  break;
1224  case NTRACK_CHUNK:
1225  processNewTrack();
1226  break;
1227  case SOFTVER_CHUNK:
1228  processSoftVer();
1229  break;
1230  case TRKNAME_CHUNK:
1231  processTrackName();
1232  break;
1233  case STRTAB_CHUNK:
1234  processStringTable();
1235  break;
1236  case LYRICS_CHUNK:
1237  processLyricsStream();
1238  break;
1239  case TRKVOL_CHUNK:
1240  processTrackVol();
1241  break;
1242  case NTRKOFS_CHUNK:
1243  processNewTrackOffset();
1244  break;
1245  case TRKBANK_CHUNK:
1246  processTrackBank();
1247  break;
1248  case METERKEY_CHUNK:
1249  processMeterKeyChunk();
1250  break;
1251  case SYSEX2_CHUNK:
1252  processSysex2Chunk();
1253  break;
1254  case NSYSEX_CHUNK:
1255  processNewSysexChunk();
1256  break;
1257  case SGMNT_CHUNK:
1258  processSegmentChunk();
1259  break;
1260  case NSTREAM_CHUNK:
1261  processNewStream();
1262  break;
1263  default:
1264  processUnknown(ck);
1265  }
1266  seek(final_pos);
1267  }
1268  return ck;
1269 }
1270 
1271 void QWrk::wrkRead()
1272 {
1273  int vma, vme;
1274  int ck_id;
1275  QByteArray hdr(HEADER.length(), ' ');
1276  d->m_tempos.clear();
1277  d->m_IOStream->device()->read(hdr.data(), HEADER.length());
1278  if (hdr == HEADER) {
1279  readGap(1);
1280  vme = readByte();
1281  vma = readByte();
1282  Q_EMIT signalWRKHeader(vma, vme);
1283  do {
1284  ck_id = readChunk();
1285  } while (ck_id != END_CHUNK);
1286  if (!atEnd())
1287  Q_EMIT signalWRKError("Corrupted file");
1288  else
1289  processEndChunk();
1290  } else
1291  Q_EMIT signalWRKError("Invalid file format");
1292 }
1293 
1294 } // namespace drumstick
New Tempo map.
Definition: qwrk.h:53
const QByteArray HEADER("CAKEWALK")
Cakewalk WRK File header id.
Track volume.
Definition: qwrk.h:56
bool getSendCont() const
Send MIDI Continue?
Definition: qwrk.cpp:260
int getPunchOutTime() const
Punch-out time.
Definition: qwrk.cpp:452
Extended thru parameters.
Definition: qwrk.h:54
void signalWRKTrackOffset(int track, int offset)
Emitted after reading a track offset chunk.
Definition: moc_qwrk.cpp:734
void signalWRKError(const QString &errorStr)
Emitted for a WRK file read error.
Definition: moc_qwrk.cpp:589
void signalWRKStringTable(const QStringList &strs)
Emitted after reading a string event types chunk.
Definition: moc_qwrk.cpp:811
void signalWRKText(int track, long time, int type, const QString &data)
Emitted after reading a text message.
Definition: moc_qwrk.cpp:679
Track patch.
Definition: qwrk.h:52
int getEndAllTime() const
Time of latest event (incl.
Definition: qwrk.cpp:461
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
Definition: moc_qwrk.cpp:818
int getPunchInTime() const
Punch-in time.
Definition: qwrk.cpp:443
void signalWRKStreamEnd(long time)
Emitted after reading the last event of a event stream.
Definition: moc_qwrk.cpp:616
void signalWRKNote(int track, long time, int chan, int pitch, int vol, int dur)
Emitted after reading a Note message.
Definition: moc_qwrk.cpp:623
void readFromFile(const QString &fileName)
Reads a stream from a disk file.
Definition: qwrk.cpp:642
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
Definition: qwrk.cpp:152
int getPlayDelay() const
Play Delay.
Definition: qwrk.cpp:233
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
Definition: qwrk.cpp:215
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
Definition: moc_qwrk.cpp:839
void signalWRKHeader(int verh, int verl)
Emitted after reading a WRK header.
Definition: moc_qwrk.cpp:603
void signalWRKTrackVol(int track, int vol)
Emitted after reading a track volume chunk.
Definition: moc_qwrk.cpp:783
int getFrom() const
From marker time.
Definition: qwrk.cpp:188
bool getAutoStop() const
Auto-stop?
Definition: qwrk.cpp:278
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
Definition: moc_qwrk.cpp:804
System exclusive bank.
Definition: qwrk.h:57
The QObject class is the base class of all Qt objects.
int getCountIn() const
Measures of count-in (0=no count-in)
Definition: qwrk.cpp:341
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
Definition: qwrk.cpp:162
bool getAutoRestart() const
Auto-restart?
Definition: qwrk.cpp:359
Events stream.
Definition: qwrk.h:41
Global variables.
Definition: qwrk.h:42
int getThru() const
Thru marker time.
Definition: qwrk.cpp:197
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
Definition: moc_qwrk.cpp:748
Tempo map.
Definition: qwrk.h:43
void signalWRKKeyPress(int track, long time, int chan, int pitch, int press)
Emitted after reading a Polyphonic Aftertouch message.
Definition: moc_qwrk.cpp:630
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
Definition: moc_qwrk.cpp:769
Track name.
Definition: qwrk.h:60
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
Definition: moc_qwrk.cpp:721
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
Definition: moc_qwrk.cpp:825
void signalWRKTimeFormat(int frames, int offset)
Emitted after reading a SMPTE time format chunk.
Definition: moc_qwrk.cpp:762
void signalWRKSysex(int bank, const QString &name, bool autosend, int port, const QByteArray &data)
Emitted after reading a System Exclusive Bank.
Definition: moc_qwrk.cpp:672
Cakewalk WRK Files Input.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes)
Definition: qwrk.cpp:224
unsigned int getStopTime() const
Auto-stop time.
Definition: qwrk.cpp:287
bool getMetroAccent() const
Metronome accents primary beats?
Definition: qwrk.cpp:332
bool getSendSPP() const
Send Song Position Pointer?
Definition: qwrk.cpp:251
void signalWRKKeySig(int bar, int alt)
Emitted after reading a WRK Key Signature.
Definition: moc_qwrk.cpp:693
void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort)
Emitted after reading an Extended Thru parameters chunk.
Definition: moc_qwrk.cpp:727
bool getZeroCtrls() const
Zero continuous controllers?
Definition: qwrk.cpp:242
void signalWRKCtlChange(int track, long time, int chan, int ctl, int value)
Emitted after reading a Control Change message.
Definition: moc_qwrk.cpp:637
void signalWRKChanPress(int track, long time, int chan, int press)
Emitted after reading a Channel Aftertouch message.
Definition: moc_qwrk.cpp:658
long getFilePos()
Current position in the data stream.
Definition: qwrk.cpp:595
bool getMetroPlay() const
Metronome on during playback?
Definition: qwrk.cpp:314
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
Definition: qwrk.cpp:350
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
Definition: qwrk.cpp:425
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
Definition: moc_qwrk.cpp:832
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
Definition: moc_qwrk.cpp:776
SMPTE time format.
Definition: qwrk.h:50
Track offset.
Definition: qwrk.h:48
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
Definition: moc_qwrk.cpp:610
System exclusive bank.
Definition: qwrk.h:65
Track prefix.
Definition: qwrk.h:64
Variable record chunk.
Definition: qwrk.h:61
bool getMetroRecord() const
Metronome on during recording?
Definition: qwrk.cpp:323
int getRewindTime() const
Auto-rewind time.
Definition: qwrk.cpp:305
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
Definition: qwrk.cpp:141
System exclusive bank.
Definition: qwrk.h:45
Events stream with lyrics.
Definition: qwrk.h:55
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
Definition: moc_qwrk.cpp:714
Meter/Key map.
Definition: qwrk.h:59
Track repetitions.
Definition: qwrk.h:51
void signalWRKUnknownChunk(int type, const QByteArray &data)
Emitted after reading an unknown chunk.
Definition: moc_qwrk.cpp:596
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.
Definition: moc_qwrk.cpp:790
virtual ~QWrk()
Destructor.
Definition: qwrk.cpp:132
bool getPatchSearch() const
Patch/controller search-back?
Definition: qwrk.cpp:269
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
Definition: moc_qwrk.cpp:741
Track bank.
Definition: qwrk.h:63
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.
Definition: moc_qwrk.cpp:707
void signalWRKTempo(long time, int tempo)
Emitted after reading a Tempo Change message.
Definition: moc_qwrk.cpp:700
Table of text event types.
Definition: qwrk.h:58
bool getPunchEnabled() const
Auto-Punch enabled?
Definition: qwrk.cpp:434
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
Definition: moc_qwrk.cpp:665
void readFromStream(QDataStream *stream)
Reads a stream.
Definition: qwrk.cpp:632
int getKeySig() const
Key signature (0=C, 1=C#, ...
Definition: qwrk.cpp:206
Meter map.
Definition: qwrk.h:44
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
Definition: qwrk.cpp:368
bool getAutoRewind() const
Auto-rewind?
Definition: qwrk.cpp:296
Segment prefix.
Definition: qwrk.h:67
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
Definition: moc_qwrk.cpp:797
QWrk(QObject *parent=0)
Constructor.
Definition: qwrk.cpp:124
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
Definition: moc_qwrk.cpp:644
void signalWRKTimeSig(int bar, int num, int den)
Emitted after reading a WRK Time signature.
Definition: moc_qwrk.cpp:686
void signalWRKProgram(int track, long time, int chan, int patch)
Emitted after reading a Program change message.
Definition: moc_qwrk.cpp:651
Software version which saved the file.
Definition: qwrk.h:68
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
Definition: moc_qwrk.cpp:755
Timebase. If present is the first chunk in the file.
Definition: qwrk.h:49
Events stream.
Definition: qwrk.h:66
Track prefix.
Definition: qwrk.h:40
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
Definition: qwrk.cpp:406
int getNow() const
Now marker time.
Definition: qwrk.cpp:179
Track offset.
Definition: qwrk.h:62
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
Definition: qwrk.cpp:387