19 #include <QDataStream> 22 #include <QStringList> 24 #include <QTextStream> 47 class 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;
169 void 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;
469 quint8 QWrk::readByte()
472 if (!d->m_IOStream->atEnd())
483 quint16 QWrk::to16bit(quint8 c1, quint8 c2)
485 quint16 value = (c1 << 8);
498 quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
500 quint32 value = (c1 << 24);
511 quint16 QWrk::read16bit()
516 return to16bit(c2, c1);
523 quint32 QWrk::read24bit()
529 return to32bit(0, c3, c2, c1);
536 quint32 QWrk::read32bit()
538 quint8 c1, c2, c3, c4;
543 return to32bit(c4, c3, c2, c1);
550 QString 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);
573 QString 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();
603 void QWrk::seek(qint64 pos)
605 d->m_IOStream->device()->seek(pos);
614 return d->m_IOStream->atEnd();
621 void QWrk::readGap(
int size)
633 d->m_IOStream = stream;
643 QFile file(fileName);
644 file.open(QIODevice::ReadOnly);
645 QDataStream ds(&file);
650 void 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,
682 void 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();
721 void QWrk::processTimebaseChunk()
723 quint16 timebase = read16bit();
724 d->m_division = timebase;
728 void 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()) {
811 void 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()) {
857 void 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());
870 void 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();
883 double 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));
900 void 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);
933 void 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();
950 void 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();
969 void 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();
987 void 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);
999 void QWrk::processTrackOffset()
1001 quint16 track = read16bit();
1002 qint16 offset = read16bit();
1006 void QWrk::processTrackReps()
1008 quint16 track = read16bit();
1009 quint16 reps = read16bit();
1013 void QWrk::processTrackPatch()
1015 quint16 track = read16bit();
1016 qint8 patch = readByte();
1020 void QWrk::processTimeFormat()
1022 quint16 fmt = read16bit();
1023 quint16 ofs = read16bit();
1027 void QWrk::processComments()
1029 int len = read16bit();
1030 QString text = readString(len);
1034 void 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 )
1045 void QWrk::processUnknown(
int id)
1050 void 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);
1087 void QWrk::processSoftVer()
1089 int len = readByte();
1090 QString vers = readString(len);
1094 void QWrk::processTrackName()
1096 int track = read16bit();
1097 int len = readByte();
1098 QString name = readString(len);
1102 void 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);
1115 void QWrk::processLyricsStream()
1117 quint16 track = read16bit();
1118 int events = read32bit();
1119 processNoteArray(track, events);
1122 void QWrk::processTrackVol()
1124 quint16 track = read16bit();
1125 int vol = read16bit();
1129 void QWrk::processNewTrackOffset()
1131 quint16 track = read16bit();
1132 int offset = read32bit();
1136 void QWrk::processTrackBank()
1138 quint16 track = read16bit();
1139 int bank = read16bit();
1143 void 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);
1157 void QWrk::processNewStream()
1160 int track = read16bit();
1161 int len = readByte();
1162 name = readString(len);
1164 int events = read32bit();
1165 processNoteArray(track, events);
1168 void QWrk::processEndChunk()
1173 int 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();
1276 void QWrk::wrkRead()
1278 QByteArray hdr(
HEADER.length(),
' ');
1279 d->m_tempos.clear();
1280 d->m_IOStream->device()->read(hdr.data(),
HEADER.length());
1289 ck_id = readChunk();
1299 const QByteArray
QWrk::HEADER = QByteArrayLiteral(
"CAKEWALK");
void signalWRKVariableRecord(const QString &name, const QByteArray &data)
Emitted after reading a variable chunk.
void signalWRKTrackReps(int track, int reps)
Emitted after reading a track offset chunk.
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
int getEndAllTime() const
Time of latest event (incl.
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
void signalWRKChord(int track, long time, const QString &name, const QByteArray &data)
Emitted after reading a chord diagram chunk.
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
bool getMetroAccent() const
Metronome accents primary beats?
void signalWRKSysex(int bank, const QString &name, bool autosend, int port, const QByteArray &data)
Emitted after reading a System Exclusive Bank.
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.
long getFilePos()
Current position in the data stream.
int getKeySig() const
Key signature (0=C, 1=C#, ...
void signalWRKExpression(int track, long time, int code, const QString &text)
Emitted after reading an expression indication (notation) chunk.
int getFrom() const
From marker time.
void signalWRKTimeFormat(int frames, int offset)
Emitted after reading a SMPTE time format chunk.
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.
void signalWRKThru(int mode, int port, int channel, int keyPlus, int velPlus, int localPort)
Emitted after reading an Extended Thru parameters chunk.
void signalWRKStreamEnd(long time)
Emitted after reading the last event of a event stream.
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
int getPunchOutTime() const
Punch-out time.
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 signalWRKStringTable(const QStringList &strs)
Emitted after reading a string event types chunk.
static const QByteArray HEADER
Cakewalk WRK file format header string id.
void signalWRKKeySig(int bar, int alt)
Emitted after reading a WRK Key Signature.
bool getMetroPlay() const
Metronome on during playback?
void signalWRKUnknownChunk(int type, const QByteArray &data)
Emitted after reading an unknown chunk.
The QObject class is the base class of all Qt objects.
void signalWRKTimeSig(int bar, int num, int den)
Emitted after reading a WRK Time signature.
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
int getThru() const
Thru marker time.
void signalWRKCtlChange(int track, long time, int chan, int ctl, int value)
Emitted after reading a Control Change message.
Timebase. If present is the first chunk in the file.
int getAutoSave() const
Auto save (0=disabled, 1..256=minutes)
void signalWRKTrackVol(int track, int vol)
Emitted after reading a track volume chunk.
Cakewalk WRK Files Input.
bool getZeroCtrls() const
Zero continuous controllers?
QWrk(QObject *parent=nullptr)
Constructor.
void signalWRKHeader(int verh, int verl)
Emitted after reading a WRK header.
void readFromStream(QDataStream *stream)
Reads a stream.
Events stream with lyrics.
Software version which saved the file.
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
bool getAutoRestart() const
Auto-restart?
void signalWRKPitchBend(int track, long time, int chan, int value)
Emitted after reading a Bender message.
bool getSendSPP() const
Send Song Position Pointer?
bool getAutoRewind() const
Auto-rewind?
void signalWRKChanPress(int track, long time, int chan, int press)
Emitted after reading a Channel Aftertouch message.
int getCountIn() const
Measures of count-in (0=no count-in)
void signalWRKTrackPatch(int track, int patch)
Emitted after reading a track patch chunk.
bool getSendCont() const
Send MIDI Continue?
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.
bool getPunchEnabled() const
Auto-Punch enabled?
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
bool getMetroRecord() const
Metronome on during recording?
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.
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
int getNow() const
Now marker time.
bool getAutoStop() const
Auto-stop?
void signalWRKError(const QString &errorStr)
Emitted for a WRK file read error.
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
int getRewindTime() const
Auto-rewind time.
void signalWRKText(int track, long time, int type, const QString &data)
Emitted after reading a text message.
void signalWRKTrackOffset(int track, int offset)
Emitted after reading a track offset chunk.
unsigned int getStopTime() const
Auto-stop time.
Table of text event types.
Extended thru parameters.
int getPunchInTime() const
Punch-in time.
void signalWRKHairpin(int track, long time, int code, int dur)
Emitted after reading a hairpin symbol (notation) chunk.
void signalWRKProgram(int track, long time, int chan, int patch)
Emitted after reading a Program change message.
virtual ~QWrk()
Destructor.
int getPlayDelay() const
Play Delay.
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
void signalWRKTempo(long time, int tempo)
Emitted after reading a Tempo Change message.
bool getPatchSearch() const
Patch/controller search-back?