22 #include <QDataStream> 25 #include <QTextStream> 27 #include <QStringList> 48 class QWrk::QWrkPrivate {
63 m_StopTime(4294967295U),
76 m_PunchEnabled(false),
106 quint8 m_CurTempoOfs;
111 quint32 m_PunchInTime;
112 quint32 m_PunchOutTime;
113 quint32 m_EndAllTime;
117 QDataStream *m_IOStream;
118 QByteArray m_lastChunkData;
119 QList<RecTempo> m_tempos;
165 return d->m_lastChunkData;
171 void QWrk::readRawData(
int size)
173 d->m_lastChunkData = d->m_IOStream->device()->read(size);
227 return d->m_AutoSave;
236 return d->m_PlayDelay;
245 return d->m_ZeroCtrls;
263 return d->m_SendCont;
272 return d->m_PatchSearch;
281 return d->m_AutoStop;
290 return d->m_StopTime;
299 return d->m_AutoRewind;
308 return d->m_RewindTime;
317 return d->m_MetroPlay;
326 return d->m_MetroRecord;
335 return d->m_MetroAccent;
362 return d->m_AutoRestart;
371 return d->m_CurTempoOfs;
390 return d->m_TempoOfs1;
409 return d->m_TempoOfs2;
428 return d->m_TempoOfs3;
437 return d->m_PunchEnabled;
446 return d->m_PunchInTime;
455 return d->m_PunchOutTime;
464 return d->m_EndAllTime;
471 quint8 QWrk::readByte()
474 if (!d->m_IOStream->atEnd())
485 quint16 QWrk::to16bit(quint8 c1, quint8 c2)
487 quint16 value = (c1 << 8);
500 quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
502 quint32 value = (c1 << 24);
513 quint16 QWrk::read16bit()
518 return to16bit(c2, c1);
525 quint32 QWrk::read24bit()
531 return to32bit(0, c3, c2, c1);
538 quint32 QWrk::read32bit()
540 quint8 c1, c2, c3, c4;
545 return to32bit(c4, c3, c2, c1);
552 QString QWrk::readString(
int len)
558 for (
int i = 0; i < len && c != 0; ++i ) {
563 if (d->m_codec == NULL)
566 s = d->m_codec->toUnicode(data);
575 QString QWrk::readVarString()
585 if (d->m_codec == NULL)
588 s = d->m_codec->toUnicode(data);
598 return d->m_IOStream->device()->pos();
605 void QWrk::seek(qint64 pos)
607 d->m_IOStream->device()->seek(pos);
616 return d->m_IOStream->atEnd();
623 void QWrk::readGap(
int size)
635 d->m_IOStream = stream;
645 QFile file(fileName);
646 file.open(QIODevice::ReadOnly);
647 QDataStream ds(&file);
652 void QWrk::processTrackChunk()
665 trackno = read16bit();
666 for(
int i=0; i<2; ++i) {
667 namelen = readByte();
668 name[i] = readString(namelen);
670 channel = (qint8) readByte();
672 velocity = readByte();
674 quint8 flags = readByte();
675 selected = ((flags & 1) != 0);
676 muted = ((flags & 2) != 0);
677 loop = ((flags & 4) != 0);
679 trackno, channel, pitch,
680 velocity, port, selected,
684 void QWrk::processVarsChunk()
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();
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();
707 d->m_ThruOn = (readByte() != 0);
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();
715 d->m_PunchEnabled = (readByte() != 0);
716 d->m_PunchInTime = read32bit();
717 d->m_PunchOutTime = read32bit();
718 d->m_EndAllTime = read32bit();
723 void QWrk::processTimebaseChunk()
725 quint16 timebase = read16bit();
726 d->m_division = timebase;
730 void QWrk::processNoteArray(
int track,
int events)
733 quint8 status = 0, data1 = 0, data2 = 0;
735 int value = 0, type = 0, channel = 0, len = 0;
738 for (
int i = 0; i < events; ++i ) {
742 if (status >= 0x90) {
743 type = status & 0xf0;
744 channel = status & 0x0f;
746 if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0)
752 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
767 value = (data2 << 7) + data1 - 8192;
774 }
else if (status == 5) {
775 int code = read16bit();
777 text = readString(len);
779 }
else if (status == 6) {
780 int code = read16bit();
784 }
else if (status == 7) {
786 text = readString(len);
788 for(
int j=0; j<13; ++j) {
789 int byte = readByte();
793 }
else if (status == 8) {
796 for(
int j=0; j<len; ++j) {
797 int byte = readByte();
803 text = readString(len);
810 void QWrk::processStreamChunk()
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 ) {
823 type = status & 0xf0;
824 channel = status & 0x0f;
827 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
842 value = (data2 << 7) + data1 - 8192;
853 void QWrk::processMeterChunk()
855 int count = read16bit();
856 for (
int i = 0; i < count; ++i) {
858 int measure = read16bit();
859 int num = readByte();
860 int den = pow(2, readByte());
866 void QWrk::processMeterKeyChunk()
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();
879 double QWrk::getRealTime(
long ticks)
const 881 double division = 1.0 * d->m_division;
886 if (!d->m_tempos.isEmpty()) {
887 foreach(
const RecTempo& rec, d->m_tempos) {
888 if (rec.time >= ticks)
893 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
896 void QWrk::processTempoChunk(
int factor)
898 double division = 1.0 * d->m_division;
899 int count = read16bit();
901 for (
int i = 0; i < count; ++i) {
903 long time = read32bit();
905 long tempo = read16bit() * factor;
909 next.tempo = tempo / 100.0;
912 last.tempo = next.tempo;
914 if (! d->m_tempos.isEmpty()) {
915 foreach(
const RecTempo& rec, d->m_tempos) {
916 if (rec.time >= time)
920 next.seconds = last.seconds +
921 (((time - last.time) / division) * (60.0 / last.tempo));
923 d->m_tempos.append(next);
929 void QWrk::processSysexChunk()
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();
946 void QWrk::processSysex2Chunk()
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();
965 void QWrk::processNewSysexChunk()
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();
983 void QWrk::processThruChunk()
986 qint8 port = readByte();
987 qint8 channel = readByte();
988 qint8 keyPlus = readByte();
989 qint8 velPlus = readByte();
990 qint8 localPort = readByte();
991 qint8 mode = readByte();
992 Q_EMIT
signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
995 void QWrk::processTrackOffset()
997 quint16 track = read16bit();
998 qint16 offset = read16bit();
1002 void QWrk::processTrackReps()
1004 quint16 track = read16bit();
1005 quint16 reps = read16bit();
1009 void QWrk::processTrackPatch()
1011 quint16 track = read16bit();
1012 qint8 patch = readByte();
1016 void QWrk::processTimeFormat()
1018 quint16 fmt = read16bit();
1019 quint16 ofs = read16bit();
1023 void QWrk::processComments()
1025 int len = read16bit();
1026 QString text = readString(len);
1030 void QWrk::processVariableRecord(
int max)
1032 int datalen = max - 32;
1034 QString name = readVarString();
1035 readGap(31 - name.length());
1036 for (
int i = 0; i < datalen; ++i )
1041 void QWrk::processUnknown(
int id)
1046 void QWrk::processNewTrack()
1056 bool selected =
false;
1059 quint16 track = read16bit();
1060 quint8 len = readByte();
1061 QString name = readString(len);
1063 patch = read16bit();
1070 channel = readByte();
1071 muted = (readByte() != 0);
1072 Q_EMIT
signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1083 void QWrk::processSoftVer()
1085 int len = readByte();
1086 QString vers = readString(len);
1090 void QWrk::processTrackName()
1092 int track = read16bit();
1093 int len = readByte();
1094 QString name = readString(len);
1098 void QWrk::processStringTable()
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);
1111 void QWrk::processLyricsStream()
1113 quint16 track = read16bit();
1114 int events = read32bit();
1115 processNoteArray(track, events);
1118 void QWrk::processTrackVol()
1120 quint16 track = read16bit();
1121 int vol = read16bit();
1125 void QWrk::processNewTrackOffset()
1127 quint16 track = read16bit();
1128 int offset = read32bit();
1132 void QWrk::processTrackBank()
1134 quint16 track = read16bit();
1135 int bank = read16bit();
1139 void QWrk::processSegmentChunk()
1142 int track = read16bit();
1143 int offset = read32bit();
1145 int len = readByte();
1146 name = readString(len);
1149 int events = read32bit();
1150 processNoteArray(track, events);
1153 void QWrk::processNewStream()
1156 int track = read16bit();
1157 int len = readByte();
1158 name = readString(len);
1160 int events = read32bit();
1161 processNoteArray(track, events);
1164 void QWrk::processEndChunk()
1169 int QWrk::readChunk()
1171 long start_pos, final_pos;
1172 int ck_len, ck = readByte();
1173 if (ck != END_CHUNK) {
1174 ck_len = read32bit();
1176 final_pos = start_pos + ck_len;
1177 readRawData(ck_len);
1181 processTrackChunk();
1187 processTimebaseChunk();
1190 processStreamChunk();
1193 processMeterChunk();
1196 processTempoChunk(100);
1199 processTempoChunk();
1202 processSysexChunk();
1208 processTrackOffset();
1214 processTrackPatch();
1217 processTimeFormat();
1223 processVariableRecord(ck_len);
1235 processStringTable();
1238 processLyricsStream();
1244 processNewTrackOffset();
1250 processMeterKeyChunk();
1253 processSysex2Chunk();
1256 processNewSysexChunk();
1259 processSegmentChunk();
1272 void QWrk::wrkRead()
1276 QByteArray hdr(
HEADER.length(),
' ');
1277 d->m_tempos.clear();
1278 d->m_IOStream->device()->read(hdr.data(),
HEADER.length());
1279 if (hdr == HEADER) {
1285 ck_id = readChunk();
1286 }
while (ck_id != END_CHUNK);
const QByteArray HEADER("CAKEWALK")
Cakewalk WRK File header id.
bool getSendCont() const
Send MIDI Continue?
int getPunchOutTime() const
Punch-out time.
Extended thru parameters.
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.
void signalWRKSegment(int track, long time, const QString &name)
Emitted after reading a segment prefix chunk.
int getPunchInTime() const
Punch-in time.
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.
void setTextCodec(QTextCodec *codec)
Sets the text codec for text meta-events.
int getPlayDelay() const
Play Delay.
int getClock() const
Clock Source (0=Int, 1=MIDI, 2=FSK, 3=SMPTE)
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.
bool getAutoStop() const
Auto-stop?
void signalWRKTrackName(int track, const QString &name)
Emitted after reading a track name chunk.
The QObject class is the base class of all Qt objects.
int getCountIn() const
Measures of count-in (0=no count-in)
QByteArray getLastChunkRawData() const
Gets the last chunk raw data (undecoded)
bool getAutoRestart() const
Auto-restart?
int getThru() const
Thru marker time.
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.
void signalWRKComments(const QString &data)
Emitted after reading a comments chunk.
void signalWRKGlobalVars()
Emitted after reading the global variables chunk.
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)
unsigned int getStopTime() const
Auto-stop time.
bool getMetroAccent() const
Metronome accents primary beats?
bool getSendSPP() const
Send Song Position Pointer?
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?
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.
bool getMetroPlay() const
Metronome on during playback?
bool getThruOn() const
MIDI Thru enabled? (only used if no THRU rec)
int getTempoOfs3() const
Fixed-point ratio value of tempo offset 3.
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.
void signalWRKEnd()
Emitted after reading the last chunk of a WRK file.
bool getMetroRecord() const
Metronome on during recording?
int getRewindTime() const
Auto-rewind time.
QTextCodec * getTextCodec()
Gets the text codec used for text meta-events I/O.
Events stream with lyrics.
void signalWRKTimeBase(int timebase)
Emitted after reading the timebase chunk.
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.
bool getPatchSearch() const
Patch/controller search-back?
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.
Table of text event types.
bool getPunchEnabled() const
Auto-Punch enabled?
void signalWRKSysexEvent(int track, long time, int bank)
Emitted after reading a System Exclusive event.
void readFromStream(QDataStream *stream)
Reads a stream.
int getKeySig() const
Key signature (0=C, 1=C#, ...
int getCurTempoOfs() const
Which of the 3 tempo offsets is used: 0..2.
bool getAutoRewind() const
Auto-rewind?
void signalWRKSoftVer(const QString &version)
Emitted after reading a software version chunk.
QWrk(QObject *parent=0)
Constructor.
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.
void signalWRKTrackBank(int track, int bank)
Emitted after reading a track bank chunk.
Timebase. If present is the first chunk in the file.
int getTempoOfs2() const
Fixed-point ratio value of tempo offset 2.
int getNow() const
Now marker time.
int getTempoOfs1() const
Fixed-point ratio value of tempo offset 1.