drumstick  1.0.1
qwrk.cpp
Go to the documentation of this file.
1 /*
2  WRK File component
3  Copyright (C) 2010-2015, 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 
34 namespace drumstick {
35 
48 class QWrk::QWrkPrivate {
49 public:
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 
125 QWrk::QWrk(QObject * parent) :
126  QObject(parent),
127  d(new QWrkPrivate)
128 { }
129 
134 {
135  delete d;
136 }
137 
142 QTextCodec* QWrk::getTextCodec()
143 {
144  return d->m_codec;
145 }
146 
153 void QWrk::setTextCodec(QTextCodec *codec)
154 {
155  d->m_codec = codec;
156 }
157 
163 QByteArray QWrk::getLastChunkRawData() const
164 {
165  return d->m_lastChunkData;
166 }
167 
171 void QWrk::readRawData(int size)
172 {
173  d->m_lastChunkData = d->m_IOStream->device()->read(size);
174 }
175 
180 int QWrk::getNow() const
181 {
182  return d->m_Now;
183 }
184 
189 int QWrk::getFrom() const
190 {
191  return d->m_From;
192 }
193 
198 int QWrk::getThru() const
199 {
200  return d->m_Thru;
201 }
202 
207 int QWrk::getKeySig() const
208 {
209  return d->m_KeySig;
210 }
211 
216 int QWrk::getClock() const
217 {
218  return d->m_Clock;
219 }
220 
225 int QWrk::getAutoSave() const
226 {
227  return d->m_AutoSave;
228 }
229 
235 {
236  return d->m_PlayDelay;
237 }
238 
243 bool QWrk::getZeroCtrls() const
244 {
245  return d->m_ZeroCtrls;
246 }
247 
252 bool QWrk::getSendSPP() const
253 {
254  return d->m_SendSPP;
255 }
256 
261 bool QWrk::getSendCont() const
262 {
263  return d->m_SendCont;
264 }
265 
271 {
272  return d->m_PatchSearch;
273 }
274 
279 bool QWrk::getAutoStop() const
280 {
281  return d->m_AutoStop;
282 }
283 
288 unsigned 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 
315 bool QWrk::getMetroPlay() const
316 {
317  return d->m_MetroPlay;
318 }
319 
325 {
326  return d->m_MetroRecord;
327 }
328 
334 {
335  return d->m_MetroAccent;
336 }
337 
342 int QWrk::getCountIn() const
343 {
344  return d->m_CountIn;
345 }
346 
351 bool 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 
471 quint8 QWrk::readByte()
472 {
473  quint8 b = 0xff;
474  if (!d->m_IOStream->atEnd())
475  *d->m_IOStream >> b;
476  return b;
477 }
478 
485 quint16 QWrk::to16bit(quint8 c1, quint8 c2)
486 {
487  quint16 value = (c1 << 8);
488  value += c2;
489  return value;
490 }
491 
500 quint32 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 
513 quint16 QWrk::read16bit()
514 {
515  quint8 c1, c2;
516  c1 = readByte();
517  c2 = readByte();
518  return to16bit(c2, c1);
519 }
520 
525 quint32 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 
538 quint32 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 
552 QString 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 
575 QString 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 
605 void QWrk::seek(qint64 pos)
606 {
607  d->m_IOStream->device()->seek(pos);
608 }
609 
614 bool QWrk::atEnd()
615 {
616  return d->m_IOStream->atEnd();
617 }
618 
623 void QWrk::readGap(int size)
624 {
625  if ( size > 0)
626  seek( getFilePos() + size );
627 }
628 
633 void QWrk::readFromStream(QDataStream *stream)
634 {
635  d->m_IOStream = stream;
636  wrkRead();
637 }
638 
643 void 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 
652 void 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 
684 void 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 
723 void QWrk::processTimebaseChunk()
724 {
725  quint16 timebase = read16bit();
726  d->m_division = timebase;
727  Q_EMIT signalWRKTimeBase(timebase);
728 }
729 
730 void 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 
810 void 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 
853 void 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.0, readByte());
861  readGap(4);
862  Q_EMIT signalWRKTimeSig(measure, num, den);
863  }
864 }
865 
866 void 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.0, readByte());
873  qint8 alt = readByte();
874  Q_EMIT signalWRKTimeSig(measure, num, den);
875  Q_EMIT signalWRKKeySig(measure, alt);
876  }
877 }
878 
879 double 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 
896 void 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 
929 void 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 
946 void 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 
965 void 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 
983 void 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 
995 void QWrk::processTrackOffset()
996 {
997  quint16 track = read16bit();
998  qint16 offset = read16bit();
999  Q_EMIT signalWRKTrackOffset(track, offset);
1000 }
1001 
1002 void QWrk::processTrackReps()
1003 {
1004  quint16 track = read16bit();
1005  quint16 reps = read16bit();
1006  Q_EMIT signalWRKTrackReps(track, reps);
1007 }
1008 
1009 void QWrk::processTrackPatch()
1010 {
1011  quint16 track = read16bit();
1012  qint8 patch = readByte();
1013  Q_EMIT signalWRKTrackPatch(track, patch);
1014 }
1015 
1016 void QWrk::processTimeFormat()
1017 {
1018  quint16 fmt = read16bit();
1019  quint16 ofs = read16bit();
1020  Q_EMIT signalWRKTimeFormat(fmt, ofs);
1021 }
1022 
1023 void QWrk::processComments()
1024 {
1025  int len = read16bit();
1026  QString text = readString(len);
1027  Q_EMIT signalWRKComments(text);
1028 }
1029 
1030 void 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 
1041 void QWrk::processUnknown(int id)
1042 {
1043  Q_EMIT signalWRKUnknownChunk(id, d->m_lastChunkData);
1044 }
1045 
1046 void 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 
1083 void QWrk::processSoftVer()
1084 {
1085  int len = readByte();
1086  QString vers = readString(len);
1087  Q_EMIT signalWRKSoftVer(vers);
1088 }
1089 
1090 void QWrk::processTrackName()
1091 {
1092  int track = read16bit();
1093  int len = readByte();
1094  QString name = readString(len);
1095  Q_EMIT signalWRKTrackName(track, name);
1096 }
1097 
1098 void 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 
1111 void QWrk::processLyricsStream()
1112 {
1113  quint16 track = read16bit();
1114  int events = read32bit();
1115  processNoteArray(track, events);
1116 }
1117 
1118 void QWrk::processTrackVol()
1119 {
1120  quint16 track = read16bit();
1121  int vol = read16bit();
1122  Q_EMIT signalWRKTrackVol(track, vol);
1123 }
1124 
1125 void QWrk::processNewTrackOffset()
1126 {
1127  quint16 track = read16bit();
1128  int offset = read32bit();
1129  Q_EMIT signalWRKTrackOffset(track, offset);
1130 }
1131 
1132 void QWrk::processTrackBank()
1133 {
1134  quint16 track = read16bit();
1135  int bank = read16bit();
1136  Q_EMIT signalWRKTrackBank(track, bank);
1137 }
1138 
1139 void 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 
1153 void 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 
1164 void QWrk::processEndChunk()
1165 {
1166  emit signalWRKEnd();
1167 }
1168 
1169 int 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 
1272 void 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
bool getPunchEnabled() const
Auto-Punch enabled?
Definition: qwrk.cpp:435
Events stream.
Definition: qwrk.h:42
bool getSendCont() const
Send MIDI Continue?
Definition: qwrk.cpp:261
void signalWRKTrackOffset(int track, int offset)
Emitted after reading a track offset chunk.
void signalWRKError(const QString &errorStr)
Emitted for a WRK file read error.
void signalWRKStringTable(const QStringList &strs)
Emitted after reading a string event types chunk.
void signalWRKText(int track, long time, int type, const QString &data)
Emitted after reading a text message.
int getEndAllTime() const
Time of latest event (incl.
Definition: qwrk.cpp:462
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
System exclusive bank.
Definition: qwrk.h:66
void signalWRKStreamEnd(long time)
Emitted after reading the last event of a event stream.
void signalWRKNote(int track, long time, int chan, int pitch, int vol, int dur)
Emitted after reading a Note message.
Track repetitions.
Definition: qwrk.h:52
void readFromFile(const QString &fileName)
Reads a stream from a disk file.
Definition: qwrk.cpp:643
int getKeySig() const
Key signature (0=C, 1=C#, ...
Definition: qwrk.cpp:207
int getPunchOutTime() const
Punch-out time.
Definition: qwrk.cpp:453
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
Definition: qwrk.cpp:153
int getPlayDelay() const
Play Delay.
Definition: qwrk.cpp:234
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
Definition: qwrk.cpp:407
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
Track prefix.
Definition: qwrk.h:41
void signalWRKHeader(int verh, int verl)
Emitted after reading a WRK header.
void signalWRKTrackVol(int track, int vol)
Emitted after reading a track volume chunk.
Meter/Key map.
Definition: qwrk.h:60
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
bool getAutoStop() const
Auto-stop?
Definition: qwrk.cpp:279
bool getPatchSearch() const
Patch/controller search-back?
Definition: qwrk.cpp:270
Track prefix.
Definition: qwrk.h:65
bool getZeroCtrls() const
Zero continuous controllers?
Definition: qwrk.cpp:243
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
Definition: qwrk.cpp:216
The QObject class is the base class of all Qt objects.
Track bank.
Definition: qwrk.h:64
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
Definition: qwrk.cpp:388
int getNow() const
Now marker time.
Definition: qwrk.cpp:180
Events stream.
Definition: qwrk.h:67
bool getAutoRestart() const
Auto-restart?
Definition: qwrk.cpp:360
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
void signalWRKKeyPress(int track, long time, int chan, int pitch, int press)
Emitted after reading a Polyphonic Aftertouch message.
int getPunchInTime() const
Punch-in time.
Definition: qwrk.cpp:444
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
Definition: qwrk.cpp:163
Track offset.
Definition: qwrk.h:63
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
bool getMetroAccent() const
Metronome accents primary beats?
Definition: qwrk.cpp:333
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
SMPTE time format.
Definition: qwrk.h:51
System exclusive bank.
Definition: qwrk.h:58
System exclusive bank.
Definition: qwrk.h:46
Track patch.
Definition: qwrk.h:53
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
Timebase. If present is the first chunk in the file.
Definition: qwrk.h:50
void signalWRKTimeFormat(int frames, int offset)
Emitted after reading a SMPTE time format chunk.
Global variables.
Definition: qwrk.h:43
void signalWRKSysex(int bank, const QString &name, bool autosend, int port, const QByteArray &data)
Emitted after reading a System Exclusive Bank.
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
Definition: qwrk.cpp:351
Cakewalk WRK Files Input.
bool getMetroPlay() const
Metronome on during playback?
Definition: qwrk.cpp:315
void signalWRKKeySig(int bar, int alt)
Emitted after reading a WRK Key Signature.
void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort)
Emitted after reading an Extended Thru parameters chunk.
Events stream with lyrics.
Definition: qwrk.h:56
void signalWRKCtlChange(int track, long time, int chan, int ctl, int value)
Emitted after reading a Control Change message.
void signalWRKChanPress(int track, long time, int chan, int press)
Emitted after reading a Channel Aftertouch message.
long getFilePos()
Current position in the data stream.
Definition: qwrk.cpp:596
New Tempo map.
Definition: qwrk.h:54
Software version which saved the file.
Definition: qwrk.h:69
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
Definition: qwrk.cpp:369
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
Track offset.
Definition: qwrk.h:49
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
Track volume.
Definition: qwrk.h:57
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
unsigned int getStopTime() const
Auto-stop time.
Definition: qwrk.cpp:288
int getCountIn() const
Measures of count-in (0=no count-in)
Definition: qwrk.cpp:342
Last chunk, end of file.
Definition: qwrk.h:70
bool getSendSPP() const
Send Song Position Pointer?
Definition: qwrk.cpp:252
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
Definition: qwrk.cpp:142
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
Tempo map.
Definition: qwrk.h:44
void signalWRKUnknownChunk(int type, const QByteArray &data)
Emitted after reading an unknown 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.
virtual ~QWrk()
Destructor.
Definition: qwrk.cpp:133
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
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 signalWRKTempo(long time, int tempo)
Emitted after reading a Tempo Change message.
bool getMetroRecord() const
Metronome on during recording?
Definition: qwrk.cpp:324
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
bool getAutoRewind() const
Auto-rewind?
Definition: qwrk.cpp:297
void readFromStream(QDataStream *stream)
Reads a stream.
Definition: qwrk.cpp:633
int getFrom() const
From marker time.
Definition: qwrk.cpp:189
int getRewindTime() const
Auto-rewind time.
Definition: qwrk.cpp:306
int getThru() const
Thru marker time.
Definition: qwrk.cpp:198
Track name.
Definition: qwrk.h:61
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
Definition: qwrk.cpp:426
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
QWrk(QObject *parent=0)
Constructor.
Definition: qwrk.cpp:125
Table of text event types.
Definition: qwrk.h:59
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
Segment prefix.
Definition: qwrk.h:68
void signalWRKTimeSig(int bar, int num, int den)
Emitted after reading a WRK Time signature.
void signalWRKProgram(int track, long time, int chan, int patch)
Emitted after reading a Program change message.
Extended thru parameters.
Definition: qwrk.h:55
Meter map.
Definition: qwrk.h:45
Variable record chunk.
Definition: qwrk.h:62
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes)
Definition: qwrk.cpp:225