47class QWrk::QWrkPrivate {
62 m_StopTime(4294967295U),
75 m_PunchEnabled(false),
105 quint8 m_CurTempoOfs;
110 quint32 m_PunchInTime;
111 quint32 m_PunchOutTime;
112 quint32 m_EndAllTime;
116 QDataStream *m_IOStream;
117 QByteArray m_lastChunkData;
118 QList<RecTempo> m_tempos;
163 return d->m_lastChunkData;
169void QWrk::readRawData(
int size)
171 d->m_lastChunkData = d->m_IOStream->device()->read(size);
225 return d->m_AutoSave;
234 return d->m_PlayDelay;
243 return d->m_ZeroCtrls;
261 return d->m_SendCont;
270 return d->m_PatchSearch;
279 return d->m_AutoStop;
288 return d->m_StopTime;
297 return d->m_AutoRewind;
306 return d->m_RewindTime;
315 return d->m_MetroPlay;
324 return d->m_MetroRecord;
333 return d->m_MetroAccent;
360 return d->m_AutoRestart;
369 return d->m_CurTempoOfs;
388 return d->m_TempoOfs1;
407 return d->m_TempoOfs2;
426 return d->m_TempoOfs3;
435 return d->m_PunchEnabled;
444 return d->m_PunchInTime;
453 return d->m_PunchOutTime;
462 return d->m_EndAllTime;
469quint8 QWrk::readByte()
472 if (!d->m_IOStream->atEnd())
483quint16 QWrk::to16bit(quint8 c1, quint8 c2)
485 quint16 value = (c1 << 8);
498quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
500 quint32 value = (c1 << 24);
511quint16 QWrk::read16bit()
516 return to16bit(c2, c1);
523quint32 QWrk::read24bit()
529 return to32bit(0, c3, c2, c1);
536quint32 QWrk::read32bit()
538 quint8 c1, c2, c3, c4;
543 return to32bit(c4, c3, c2, c1);
550QString QWrk::readString(
int len)
556 for (
int i = 0; i < len && c != 0 && !atEnd(); ++i ) {
561 if (d->m_codec ==
nullptr)
564 s = d->m_codec->toUnicode(data);
573QString QWrk::readVarString()
582 }
while (b != 0 && !atEnd());
583 if (d->m_codec ==
nullptr)
586 s = d->m_codec->toUnicode(data);
596 return d->m_IOStream->device()->pos();
603void QWrk::seek(qint64 pos)
605 d->m_IOStream->device()->seek(pos);
614 return d->m_IOStream->atEnd();
621void QWrk::readGap(
int size)
633 d->m_IOStream = stream;
643 QFile file(fileName);
644 file.open(QIODevice::ReadOnly);
645 QDataStream ds(&file);
650void QWrk::processTrackChunk()
663 trackno = read16bit();
664 for(
int i=0; i<2; ++i) {
665 namelen = readByte();
666 name[i] = readString(namelen);
668 channel = readByte() & 0x0f;
670 velocity = readByte();
672 quint8 flags = readByte();
673 selected = ((flags & 1) != 0);
674 muted = ((flags & 2) != 0);
675 loop = ((flags & 4) != 0);
677 trackno, channel, pitch,
678 velocity, port, selected,
682void QWrk::processVarsChunk()
684 d->m_Now = read32bit();
685 d->m_From = read32bit();
686 d->m_Thru = read32bit();
687 d->m_KeySig = readByte();
688 d->m_Clock = readByte();
689 d->m_AutoSave = readByte();
690 d->m_PlayDelay = readByte();
692 d->m_ZeroCtrls = (readByte() != 0);
693 d->m_SendSPP = (readByte() != 0);
694 d->m_SendCont = (readByte() != 0);
695 d->m_PatchSearch = (readByte() != 0);
696 d->m_AutoStop = (readByte() != 0);
697 d->m_StopTime = read32bit();
698 d->m_AutoRewind = (readByte() != 0);
699 d->m_RewindTime = read32bit();
700 d->m_MetroPlay = (readByte() != 0);
701 d->m_MetroRecord = (readByte() != 0);
702 d->m_MetroAccent = (readByte() != 0);
703 d->m_CountIn = readByte();
705 d->m_ThruOn = (readByte() != 0);
707 d->m_AutoRestart = (readByte() != 0);
708 d->m_CurTempoOfs = readByte();
709 d->m_TempoOfs1 = readByte();
710 d->m_TempoOfs2 = readByte();
711 d->m_TempoOfs3 = readByte();
713 d->m_PunchEnabled = (readByte() != 0);
714 d->m_PunchInTime = read32bit();
715 d->m_PunchOutTime = read32bit();
716 d->m_EndAllTime = read32bit();
721void QWrk::processTimebaseChunk()
723 quint16 timebase = read16bit();
724 d->m_division = timebase;
728void QWrk::processNoteArray(
int track,
int events)
731 quint8 status = 0, data1 = 0, data2 = 0, i = 0;
733 int value = 0, type = 0, channel = 0, len = 0;
736 for ( i = 0; (i < events) && !atEnd(); ++i ) {
740 if (status >= 0x90) {
741 type = status & 0xf0;
742 channel = status & 0x0f;
744 if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0)
750 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
765 value = (data2 << 7) + data1 - 8192;
772 }
else if (status == 5) {
773 int code = read16bit();
775 text = readString(len);
777 }
else if (status == 6) {
778 int code = read16bit();
782 }
else if (status == 7) {
784 text = readString(len);
786 for(
int j=0; j<13; ++j) {
787 int byte = readByte();
791 }
else if (status == 8) {
794 for(
int j=0; j<len; ++j) {
795 int byte = readByte();
801 text = readString(len);
805 if ((i < events) && atEnd()) {
811void QWrk::processStreamChunk()
814 int dur = 0, value = 0, type = 0, channel = 0, i = 0;
815 quint8 status = 0, data1 = 0, data2 = 0;
816 quint16 track = read16bit();
817 int events = read16bit();
818 for ( i = 0; (i < events) && !atEnd(); ++i ) {
824 type = status & 0xf0;
825 channel = status & 0x0f;
828 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
843 value = (data2 << 7) + data1 - 8192;
851 if ((i < events) && atEnd()) {
857void QWrk::processMeterChunk()
859 int count = read16bit();
860 for (
int i = 0; i < count; ++i) {
862 int measure = read16bit();
863 int num = readByte();
864 int den = pow(2.0, readByte());
870void QWrk::processMeterKeyChunk()
872 int count = read16bit();
873 for (
int i = 0; i < count; ++i) {
874 int measure = read16bit();
875 int num = readByte();
876 int den = pow(2.0, readByte());
877 qint8 alt = readByte();
883double QWrk::getRealTime(
long ticks)
const
885 double division = 1.0 * d->m_division;
890 if (!d->m_tempos.isEmpty()) {
891 foreach(
const RecTempo& rec, d->m_tempos) {
892 if (rec.time >= ticks)
897 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
900void QWrk::processTempoChunk(
int factor)
902 double division = 1.0 * d->m_division;
903 int count = read16bit();
905 for (
int i = 0; i < count; ++i) {
907 long time = read32bit();
909 long tempo = read16bit() * factor;
913 next.tempo = tempo / 100.0;
916 last.tempo = next.tempo;
918 if (! d->m_tempos.isEmpty()) {
919 foreach(
const RecTempo& rec, d->m_tempos) {
920 if (rec.time >= time)
924 next.seconds = last.seconds +
925 (((time - last.time) / division) * (60.0 / last.tempo));
927 d->m_tempos.append(next);
933void QWrk::processSysexChunk()
938 int bank = readByte();
939 int length = read16bit();
940 bool autosend = (readByte() != 0);
941 int namelen = readByte();
942 name = readString(namelen);
943 for(j=0; j<length; ++j) {
944 int byte = readByte();
950void QWrk::processSysex2Chunk()
955 int bank = read16bit();
956 int length = read32bit();
957 quint8 b = readByte();
958 int port = ( b & 0xf0 ) >> 4;
959 bool autosend = ( (b & 0x0f) != 0);
960 int namelen = readByte();
961 name = readString(namelen);
962 for(j=0; j<length; ++j) {
963 int byte = readByte();
969void QWrk::processNewSysexChunk()
974 int bank = read16bit();
975 int length = read32bit();
976 int port = read16bit();
977 bool autosend = (readByte() != 0);
978 int namelen = readByte();
979 name = readString(namelen);
980 for(j=0; j<length; ++j) {
981 int byte = readByte();
987void QWrk::processThruChunk()
990 qint8 port = readByte();
991 qint8 channel = readByte();
992 qint8 keyPlus = readByte();
993 qint8 velPlus = readByte();
994 qint8 localPort = readByte();
995 qint8 mode = readByte();
996 Q_EMIT
signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
999void QWrk::processTrackOffset()
1001 quint16 track = read16bit();
1002 qint16 offset = read16bit();
1006void QWrk::processTrackReps()
1008 quint16 track = read16bit();
1009 quint16 reps = read16bit();
1013void QWrk::processTrackPatch()
1015 quint16 track = read16bit();
1016 qint8 patch = readByte();
1020void QWrk::processTimeFormat()
1022 quint16 fmt = read16bit();
1023 quint16 ofs = read16bit();
1027void QWrk::processComments()
1029 int len = read16bit();
1030 QString text = readString(len);
1034void QWrk::processVariableRecord(
int max)
1036 int datalen = max - 32;
1038 QString name = readVarString();
1039 readGap(31 - name.length());
1040 for (
int i = 0; i < datalen; ++i )
1045void QWrk::processUnknown(
int id)
1050void QWrk::processNewTrack()
1060 bool selected =
false;
1063 quint16 track = read16bit();
1064 quint8 len = readByte();
1065 QString name = readString(len);
1067 patch = read16bit();
1074 channel = readByte();
1075 muted = (readByte() != 0);
1076 Q_EMIT
signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1087void QWrk::processSoftVer()
1089 int len = readByte();
1090 QString vers = readString(len);
1094void QWrk::processTrackName()
1096 int track = read16bit();
1097 int len = readByte();
1098 QString name = readString(len);
1102void QWrk::processStringTable()
1105 int rows = read16bit();
1106 for (
int i = 0; i < rows; ++i) {
1107 int len = readByte();
1108 QString name = readString(len);
1109 int idx = readByte();
1110 table.insert(idx, name);
1115void QWrk::processLyricsStream()
1117 quint16 track = read16bit();
1118 int events = read32bit();
1119 processNoteArray(track, events);
1122void QWrk::processTrackVol()
1124 quint16 track = read16bit();
1125 int vol = read16bit();
1129void QWrk::processNewTrackOffset()
1131 quint16 track = read16bit();
1132 int offset = read32bit();
1136void QWrk::processTrackBank()
1138 quint16 track = read16bit();
1139 int bank = read16bit();
1143void QWrk::processSegmentChunk()
1146 int track = read16bit();
1147 int offset = read32bit();
1149 int len = readByte();
1150 name = readString(len);
1153 int events = read32bit();
1154 processNoteArray(track, events);
1157void QWrk::processNewStream()
1160 int track = read16bit();
1161 int len = readByte();
1162 name = readString(len);
1164 int events = read32bit();
1165 processNoteArray(track, events);
1168void QWrk::processEndChunk()
1173int QWrk::readChunk()
1175 long start_pos, final_pos;
1176 int ck_len, ck = readByte();
1178 ck_len = read32bit();
1180 final_pos = start_pos + ck_len;
1181 readRawData(ck_len);
1185 processTrackChunk();
1191 processTimebaseChunk();
1194 processStreamChunk();
1197 processMeterChunk();
1200 processTempoChunk(100);
1203 processTempoChunk();
1206 processSysexChunk();
1212 processTrackOffset();
1218 processTrackPatch();
1221 processTimeFormat();
1227 processVariableRecord(ck_len);
1239 processStringTable();
1242 processLyricsStream();
1248 processNewTrackOffset();
1254 processMeterKeyChunk();
1257 processSysex2Chunk();
1260 processNewSysexChunk();
1263 processSegmentChunk();
1278 QByteArray hdr(
HEADER.length(),
' ');
1279 d->m_tempos.clear();
1280 d->m_IOStream->device()->read(hdr.data(),
HEADER.length());
1289 ck_id = readChunk();
1299const QByteArray
QWrk::HEADER = QByteArrayLiteral(
"CAKEWALK");
The QObject class is the base class of all Qt objects.
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
bool getMetroRecord() const
Metronome on during recording?
bool getPunchEnabled() const
Auto-Punch enabled?
void signalWRKText(int track, long time, int type, const QString &data)
Emitted after reading a text message.
int getRewindTime() const
Auto-rewind time.
bool getZeroCtrls() const
Zero continuous controllers?
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.
QWrk(QObject *parent=nullptr)
Constructor.
void signalWRKProgram(int track, long time, int chan, int patch)
Emitted after reading a Program change message.
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
static const QByteArray HEADER
Cakewalk WRK file format header string id.
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
void signalWRKHeader(int verh, int verl)
Emitted after reading a WRK header.
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes).
long getFilePos()
Current position in the data stream.
bool getThruOn() const
MIDI Thru enabled?
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
int getNow() const
Now marker time.
int getPunchOutTime() const
Punch-out time.
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
void signalWRKTrackOffset(int track, int offset)
Emitted after reading a track offset chunk.
void signalWRKChanPress(int track, long time, int chan, int press)
Emitted after reading a Channel Aftertouch message.
void signalWRKStreamEnd(long time)
Emitted after reading the last event of a event stream.
bool getAutoStop() const
Auto-stop?
int getEndAllTime() const
Time of latest event (incl.
void signalWRKKeyPress(int track, long time, int chan, int pitch, int press)
Emitted after reading a Polyphonic Aftertouch message.
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
void signalWRKTrackVol(int track, int vol)
Emitted after reading a track volume chunk.
void signalWRKStringTable(const QStringList &strs)
Emitted after reading a string event types chunk.
int getPlayDelay() const
Play Delay.
bool getSendSPP() const
Send Song Position Pointer?
void signalWRKError(const QString &errorStr)
Emitted for a WRK file read error.
virtual ~QWrk()
Destructor.
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
void signalWRKTempo(long time, int tempo)
Emitted after reading a Tempo Change message.
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
void signalWRKTimeSig(int bar, int num, int den)
Emitted after reading a WRK Time signature.
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
int getThru() const
Thru marker time.
bool getSendCont() const
Send MIDI Continue?
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
bool getPatchSearch() const
Patch/controller search-back?
void readFromStream(QDataStream *stream)
Reads a stream.
void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort)
Emitted after reading an Extended Thru parameters chunk.
int getPunchInTime() const
Punch-in time.
void signalWRKNote(int track, long time, int chan, int pitch, int vol, int dur)
Emitted after reading a Note message.
unsigned int getStopTime() const
Auto-stop time.
void signalWRKUnknownChunk(int type, const QByteArray &data)
Emitted after reading an unknown chunk.
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded).
bool getAutoRewind() const
Auto-rewind?
bool getMetroPlay() const
Metronome on during playback?
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
int getFrom() const
From marker time.
void signalWRKTimeFormat(int frames, int offset)
Emitted after reading a SMPTE time format chunk.
void signalWRKSysex(int bank, const QString &name, bool autosend, int port, const QByteArray &data)
Emitted after reading a System Exclusive Bank.
void readFromFile(const QString &fileName)
Reads a stream from a disk file.
int getCountIn() const
Measures of count-in (0=no count-in).
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
void signalWRKCtlChange(int track, long time, int chan, int ctl, int value)
Emitted after reading a Control Change message.
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
void signalWRKNewTrack(const QString &name, int trackno, int channel, int pitch, int velocity, int port, bool selected, bool muted, bool loop)
Emitted after reading a new track prefix.
void signalWRKKeySig(int bar, int alt)
Emitted after reading a WRK Key Signature.
bool getAutoRestart() const
Auto-restart?
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE).
int getKeySig() const
Key signature (0=C, 1=C#, ... 11=B).
bool getMetroAccent() const
Metronome accents primary beats?
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
@ NTRKOFS_CHUNK
Track offset.
@ NTRACK_CHUNK
Track prefix.
@ TRKPATCH_CHUNK
Track patch.
@ STRTAB_CHUNK
Table of text event types.
@ NTEMPO_CHUNK
New Tempo map.
@ VARS_CHUNK
Global variables.
@ TRKBANK_CHUNK
Track bank.
@ COMMENTS_CHUNK
Comments.
@ SGMNT_CHUNK
Segment prefix.
@ SOFTVER_CHUNK
Software version which saved the file.
@ TRKNAME_CHUNK
Track name.
@ TIMEFMT_CHUNK
SMPTE time format.
@ END_CHUNK
Last chunk, end of file.
@ STREAM_CHUNK
Events stream.
@ TRACK_CHUNK
Track prefix.
@ TIMEBASE_CHUNK
Timebase. If present is the first chunk in the file.
@ TRKOFFS_CHUNK
Track offset.
@ NSYSEX_CHUNK
System exclusive bank.
@ THRU_CHUNK
Extended thru parameters.
@ SYSEX2_CHUNK
System exclusive bank.
@ NSTREAM_CHUNK
Events stream.
@ VARIABLE_CHUNK
Variable record chunk.
@ METERKEY_CHUNK
Meter/Key map.
@ TRKREPS_CHUNK
Track repetitions.
@ TRKVOL_CHUNK
Track volume.
@ SYSEX_CHUNK
System exclusive bank.
@ LYRICS_CHUNK
Events stream with lyrics.
Cakewalk WRK Files Input.