drumstick  0.5.0
qwrk.cpp
Go to the documentation of this file.
1 /*
2  WRK File component
3  Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl@users.sf.net>
4 
5  This library is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 #include "qwrk.h"
21 #include <cmath>
22 #include <QDataStream>
23 #include <QFile>
24 #include <QIODevice>
25 #include <QTextStream>
26 #include <QTextCodec>
27 #include <QStringList>
28 
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, 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, 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
New Tempo map.
Definition: qwrk.h:54
const QByteArray HEADER("CAKEWALK")
Cakewalk WRK File header id.
Track volume.
Definition: qwrk.h:57
bool getSendCont() const
Send MIDI Continue?
Definition: qwrk.cpp:261
int getPunchOutTime() const
Punch-out time.
Definition: qwrk.cpp:453
Extended thru parameters.
Definition: qwrk.h:55
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.
Track patch.
Definition: qwrk.h:53
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.
int getPunchInTime() const
Punch-in time.
Definition: qwrk.cpp:444
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.
void readFromFile(const QString &fileName)
Reads a stream from a disk file.
Definition: qwrk.cpp:643
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 getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
Definition: qwrk.cpp:216
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
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.
int getFrom() const
From marker time.
Definition: qwrk.cpp:189
bool getAutoStop() const
Auto-stop?
Definition: qwrk.cpp:279
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
System exclusive bank.
Definition: qwrk.h:58
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:342
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
Definition: qwrk.cpp:163
bool getAutoRestart() const
Auto-restart?
Definition: qwrk.cpp:360
Events stream.
Definition: qwrk.h:42
Global variables.
Definition: qwrk.h:43
int getThru() const
Thru marker time.
Definition: qwrk.cpp:198
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
Tempo map.
Definition: qwrk.h:44
void signalWRKKeyPress(int track, long time, int chan, int pitch, int press)
Emitted after reading a Polyphonic Aftertouch message.
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
Track name.
Definition: qwrk.h:61
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
Last chunk, end of file.
Definition: qwrk.h:70
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
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.
Cakewalk WRK Files Input.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes)
Definition: qwrk.cpp:225
unsigned int getStopTime() const
Auto-stop time.
Definition: qwrk.cpp:288
bool getMetroAccent() const
Metronome accents primary beats?
Definition: qwrk.cpp:333
bool getSendSPP() const
Send Song Position Pointer?
Definition: qwrk.cpp:252
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.
bool getZeroCtrls() const
Zero continuous controllers?
Definition: qwrk.cpp:243
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
bool getMetroPlay() const
Metronome on during playback?
Definition: qwrk.cpp:315
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
Definition: qwrk.cpp:351
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
Definition: qwrk.cpp:426
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
SMPTE time format.
Definition: qwrk.h:51
Track offset.
Definition: qwrk.h:49
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
System exclusive bank.
Definition: qwrk.h:66
Track prefix.
Definition: qwrk.h:65
Variable record chunk.
Definition: qwrk.h:62
bool getMetroRecord() const
Metronome on during recording?
Definition: qwrk.cpp:324
int getRewindTime() const
Auto-rewind time.
Definition: qwrk.cpp:306
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
Definition: qwrk.cpp:142
System exclusive bank.
Definition: qwrk.h:46
Events stream with lyrics.
Definition: qwrk.h:56
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
Meter/Key map.
Definition: qwrk.h:60
Track repetitions.
Definition: qwrk.h:52
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
bool getPatchSearch() const
Patch/controller search-back?
Definition: qwrk.cpp:270
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
Track bank.
Definition: qwrk.h:64
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.
Table of text event types.
Definition: qwrk.h:59
bool getPunchEnabled() const
Auto-Punch enabled?
Definition: qwrk.cpp:435
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
void readFromStream(QDataStream *stream)
Reads a stream.
Definition: qwrk.cpp:633
int getKeySig() const
Key signature (0=C, 1=C#, ...
Definition: qwrk.cpp:207
Meter map.
Definition: qwrk.h:45
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
Definition: qwrk.cpp:369
bool getAutoRewind() const
Auto-rewind?
Definition: qwrk.cpp:297
Segment prefix.
Definition: qwrk.h:68
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
QWrk(QObject *parent=0)
Constructor.
Definition: qwrk.cpp:125
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
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.
Software version which saved the file.
Definition: qwrk.h:69
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
Timebase. If present is the first chunk in the file.
Definition: qwrk.h:50
Events stream.
Definition: qwrk.h:67
Track prefix.
Definition: qwrk.h:41
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
Definition: qwrk.cpp:407
int getNow() const
Now marker time.
Definition: qwrk.cpp:180
Track offset.
Definition: qwrk.h:63
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
Definition: qwrk.cpp:388