21 #include <QDataStream> 24 #include <QTextStream> 26 #include <QStringList> 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;
164 return d->m_lastChunkData;
170 void QWrk::readRawData(
int size)
172 d->m_lastChunkData = d->m_IOStream->device()->read(size);
226 return d->m_AutoSave;
235 return d->m_PlayDelay;
244 return d->m_ZeroCtrls;
262 return d->m_SendCont;
271 return d->m_PatchSearch;
280 return d->m_AutoStop;
289 return d->m_StopTime;
298 return d->m_AutoRewind;
307 return d->m_RewindTime;
316 return d->m_MetroPlay;
325 return d->m_MetroRecord;
334 return d->m_MetroAccent;
361 return d->m_AutoRestart;
370 return d->m_CurTempoOfs;
389 return d->m_TempoOfs1;
408 return d->m_TempoOfs2;
427 return d->m_TempoOfs3;
436 return d->m_PunchEnabled;
445 return d->m_PunchInTime;
454 return d->m_PunchOutTime;
463 return d->m_EndAllTime;
470 quint8 QWrk::readByte()
473 if (!d->m_IOStream->atEnd())
484 quint16 QWrk::to16bit(quint8 c1, quint8 c2)
486 quint16 value = (c1 << 8);
499 quint32 QWrk::to32bit(quint8 c1, quint8 c2, quint8 c3, quint8 c4)
501 quint32 value = (c1 << 24);
512 quint16 QWrk::read16bit()
517 return to16bit(c2, c1);
524 quint32 QWrk::read24bit()
530 return to32bit(0, c3, c2, c1);
537 quint32 QWrk::read32bit()
539 quint8 c1, c2, c3, c4;
544 return to32bit(c4, c3, c2, c1);
551 QString QWrk::readString(
int len)
557 for (
int i = 0; i < len && c != 0; ++i ) {
562 if (d->m_codec == NULL)
565 s = d->m_codec->toUnicode(data);
574 QString QWrk::readVarString()
584 if (d->m_codec == NULL)
587 s = d->m_codec->toUnicode(data);
597 return d->m_IOStream->device()->pos();
604 void QWrk::seek(qint64 pos)
606 d->m_IOStream->device()->seek(pos);
615 return d->m_IOStream->atEnd();
622 void QWrk::readGap(
int size)
634 d->m_IOStream = stream;
644 QFile file(fileName);
645 file.open(QIODevice::ReadOnly);
646 QDataStream ds(&file);
651 void QWrk::processTrackChunk()
664 trackno = read16bit();
665 for(
int i=0; i<2; ++i) {
666 namelen = readByte();
667 name[i] = readString(namelen);
669 channel = (qint8) readByte();
671 velocity = readByte();
673 quint8 flags = readByte();
674 selected = ((flags & 1) != 0);
675 muted = ((flags & 2) != 0);
676 loop = ((flags & 4) != 0);
678 trackno, channel, pitch,
679 velocity, port, selected,
683 void QWrk::processVarsChunk()
685 d->m_Now = read32bit();
686 d->m_From = read32bit();
687 d->m_Thru = read32bit();
688 d->m_KeySig = readByte();
689 d->m_Clock = readByte();
690 d->m_AutoSave = readByte();
691 d->m_PlayDelay = readByte();
693 d->m_ZeroCtrls = (readByte() != 0);
694 d->m_SendSPP = (readByte() != 0);
695 d->m_SendCont = (readByte() != 0);
696 d->m_PatchSearch = (readByte() != 0);
697 d->m_AutoStop = (readByte() != 0);
698 d->m_StopTime = read32bit();
699 d->m_AutoRewind = (readByte() != 0);
700 d->m_RewindTime = read32bit();
701 d->m_MetroPlay = (readByte() != 0);
702 d->m_MetroRecord = (readByte() != 0);
703 d->m_MetroAccent = (readByte() != 0);
704 d->m_CountIn = readByte();
706 d->m_ThruOn = (readByte() != 0);
708 d->m_AutoRestart = (readByte() != 0);
709 d->m_CurTempoOfs = readByte();
710 d->m_TempoOfs1 = readByte();
711 d->m_TempoOfs2 = readByte();
712 d->m_TempoOfs3 = readByte();
714 d->m_PunchEnabled = (readByte() != 0);
715 d->m_PunchInTime = read32bit();
716 d->m_PunchOutTime = read32bit();
717 d->m_EndAllTime = read32bit();
722 void QWrk::processTimebaseChunk()
724 quint16 timebase = read16bit();
725 d->m_division = timebase;
729 void QWrk::processNoteArray(
int track,
int events)
732 quint8 status = 0, data1 = 0, data2 = 0;
734 int value = 0, type = 0, channel = 0, len = 0;
737 for (
int i = 0; i < events; ++i ) {
741 if (status >= 0x90) {
742 type = status & 0xf0;
743 channel = status & 0x0f;
745 if (type == 0x90 || type == 0xA0 || type == 0xB0 || type == 0xE0)
751 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
766 value = (data2 << 7) + data1 - 8192;
773 }
else if (status == 5) {
774 int code = read16bit();
776 text = readString(len);
778 }
else if (status == 6) {
779 int code = read16bit();
783 }
else if (status == 7) {
785 text = readString(len);
787 for(
int j=0; j<13; ++j) {
788 int byte = readByte();
792 }
else if (status == 8) {
795 for(
int j=0; j<len; ++j) {
796 int byte = readByte();
802 text = readString(len);
809 void QWrk::processStreamChunk()
812 int dur = 0, value = 0, type = 0, channel = 0;
813 quint8 status = 0, data1 = 0, data2 = 0;
814 quint16 track = read16bit();
815 int events = read16bit();
816 for (
int i = 0; i < events; ++i ) {
822 type = status & 0xf0;
823 channel = status & 0x0f;
826 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
841 value = (data2 << 7) + data1 - 8192;
852 void QWrk::processMeterChunk()
854 int count = read16bit();
855 for (
int i = 0; i < count; ++i) {
857 int measure = read16bit();
858 int num = readByte();
859 int den = pow(2.0, readByte());
865 void QWrk::processMeterKeyChunk()
867 int count = read16bit();
868 for (
int i = 0; i < count; ++i) {
869 int measure = read16bit();
870 int num = readByte();
871 int den = pow(2.0, readByte());
872 qint8 alt = readByte();
878 double QWrk::getRealTime(
long ticks)
const 880 double division = 1.0 * d->m_division;
885 if (!d->m_tempos.isEmpty()) {
886 foreach(
const RecTempo& rec, d->m_tempos) {
887 if (rec.time >= ticks)
892 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
895 void QWrk::processTempoChunk(
int factor)
897 double division = 1.0 * d->m_division;
898 int count = read16bit();
900 for (
int i = 0; i < count; ++i) {
902 long time = read32bit();
904 long tempo = read16bit() * factor;
908 next.tempo = tempo / 100.0;
911 last.tempo = next.tempo;
913 if (! d->m_tempos.isEmpty()) {
914 foreach(
const RecTempo& rec, d->m_tempos) {
915 if (rec.time >= time)
919 next.seconds = last.seconds +
920 (((time - last.time) / division) * (60.0 / last.tempo));
922 d->m_tempos.append(next);
928 void QWrk::processSysexChunk()
933 int bank = readByte();
934 int length = read16bit();
935 bool autosend = (readByte() != 0);
936 int namelen = readByte();
937 name = readString(namelen);
938 for(j=0; j<length; ++j) {
939 int byte = readByte();
945 void QWrk::processSysex2Chunk()
950 int bank = read16bit();
951 int length = read32bit();
952 quint8 b = readByte();
953 int port = ( b & 0xf0 ) >> 4;
954 bool autosend = ( (b & 0x0f) != 0);
955 int namelen = readByte();
956 name = readString(namelen);
957 for(j=0; j<length; ++j) {
958 int byte = readByte();
964 void QWrk::processNewSysexChunk()
969 int bank = read16bit();
970 int length = read32bit();
971 int port = read16bit();
972 bool autosend = (readByte() != 0);
973 int namelen = readByte();
974 name = readString(namelen);
975 for(j=0; j<length; ++j) {
976 int byte = readByte();
982 void QWrk::processThruChunk()
985 qint8 port = readByte();
986 qint8 channel = readByte();
987 qint8 keyPlus = readByte();
988 qint8 velPlus = readByte();
989 qint8 localPort = readByte();
990 qint8 mode = readByte();
991 Q_EMIT
signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
994 void QWrk::processTrackOffset()
996 quint16 track = read16bit();
997 qint16 offset = read16bit();
1001 void QWrk::processTrackReps()
1003 quint16 track = read16bit();
1004 quint16 reps = read16bit();
1008 void QWrk::processTrackPatch()
1010 quint16 track = read16bit();
1011 qint8 patch = readByte();
1015 void QWrk::processTimeFormat()
1017 quint16 fmt = read16bit();
1018 quint16 ofs = read16bit();
1022 void QWrk::processComments()
1024 int len = read16bit();
1025 QString text = readString(len);
1029 void QWrk::processVariableRecord(
int max)
1031 int datalen = max - 32;
1033 QString name = readVarString();
1034 readGap(31 - name.length());
1035 for (
int i = 0; i < datalen; ++i )
1040 void QWrk::processUnknown(
int id)
1045 void QWrk::processNewTrack()
1055 bool selected =
false;
1058 quint16 track = read16bit();
1059 quint8 len = readByte();
1060 QString name = readString(len);
1062 patch = read16bit();
1069 channel = readByte();
1070 muted = (readByte() != 0);
1071 Q_EMIT
signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1082 void QWrk::processSoftVer()
1084 int len = readByte();
1085 QString vers = readString(len);
1089 void QWrk::processTrackName()
1091 int track = read16bit();
1092 int len = readByte();
1093 QString name = readString(len);
1097 void QWrk::processStringTable()
1100 int rows = read16bit();
1101 for (
int i = 0; i < rows; ++i) {
1102 int len = readByte();
1103 QString name = readString(len);
1104 int idx = readByte();
1105 table.insert(idx, name);
1110 void QWrk::processLyricsStream()
1112 quint16 track = read16bit();
1113 int events = read32bit();
1114 processNoteArray(track, events);
1117 void QWrk::processTrackVol()
1119 quint16 track = read16bit();
1120 int vol = read16bit();
1124 void QWrk::processNewTrackOffset()
1126 quint16 track = read16bit();
1127 int offset = read32bit();
1131 void QWrk::processTrackBank()
1133 quint16 track = read16bit();
1134 int bank = read16bit();
1138 void QWrk::processSegmentChunk()
1141 int track = read16bit();
1142 int offset = read32bit();
1144 int len = readByte();
1145 name = readString(len);
1148 int events = read32bit();
1149 processNoteArray(track, events);
1152 void QWrk::processNewStream()
1155 int track = read16bit();
1156 int len = readByte();
1157 name = readString(len);
1159 int events = read32bit();
1160 processNoteArray(track, events);
1163 void QWrk::processEndChunk()
1168 int QWrk::readChunk()
1170 long start_pos, final_pos;
1171 int ck_len, ck = readByte();
1173 ck_len = read32bit();
1175 final_pos = start_pos + ck_len;
1176 readRawData(ck_len);
1180 processTrackChunk();
1186 processTimebaseChunk();
1189 processStreamChunk();
1192 processMeterChunk();
1195 processTempoChunk(100);
1198 processTempoChunk();
1201 processSysexChunk();
1207 processTrackOffset();
1213 processTrackPatch();
1216 processTimeFormat();
1222 processVariableRecord(ck_len);
1234 processStringTable();
1237 processLyricsStream();
1243 processNewTrackOffset();
1249 processMeterKeyChunk();
1252 processSysex2Chunk();
1255 processNewSysexChunk();
1258 processSegmentChunk();
1271 void QWrk::wrkRead()
1275 QByteArray hdr(
HEADER.length(),
' ');
1276 d->m_tempos.clear();
1277 d->m_IOStream->device()->read(hdr.data(),
HEADER.length());
1284 ck_id = readChunk();
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.