20 #include <QDataStream> 23 #include <QTextStream> 25 #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 && !atEnd(); ++i ) {
562 if (d->m_codec == NULL)
565 s = d->m_codec->toUnicode(data);
574 QString QWrk::readVarString()
583 }
while (b != 0 && !atEnd());
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, i = 0;
734 int value = 0, type = 0, channel = 0, len = 0;
737 for ( i = 0; (i < events) && !atEnd(); ++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);
806 if ((i < events) && atEnd()) {
812 void QWrk::processStreamChunk()
815 int dur = 0, value = 0, type = 0, channel = 0, i = 0;
816 quint8 status = 0, data1 = 0, data2 = 0;
817 quint16 track = read16bit();
818 int events = read16bit();
819 for ( i = 0; (i < events) && !atEnd(); ++i ) {
825 type = status & 0xf0;
826 channel = status & 0x0f;
829 Q_EMIT
signalWRKNote(track, time, channel, data1, data2, dur);
844 value = (data2 << 7) + data1 - 8192;
852 if ((i < events) && atEnd()) {
858 void QWrk::processMeterChunk()
860 int count = read16bit();
861 for (
int i = 0; i < count; ++i) {
863 int measure = read16bit();
864 int num = readByte();
865 int den = pow(2.0, readByte());
871 void QWrk::processMeterKeyChunk()
873 int count = read16bit();
874 for (
int i = 0; i < count; ++i) {
875 int measure = read16bit();
876 int num = readByte();
877 int den = pow(2.0, readByte());
878 qint8 alt = readByte();
884 double QWrk::getRealTime(
long ticks)
const 886 double division = 1.0 * d->m_division;
891 if (!d->m_tempos.isEmpty()) {
892 foreach(
const RecTempo& rec, d->m_tempos) {
893 if (rec.time >= ticks)
898 return last.seconds + (((ticks - last.time) / division) * (60.0 / last.tempo));
901 void QWrk::processTempoChunk(
int factor)
903 double division = 1.0 * d->m_division;
904 int count = read16bit();
906 for (
int i = 0; i < count; ++i) {
908 long time = read32bit();
910 long tempo = read16bit() * factor;
914 next.tempo = tempo / 100.0;
917 last.tempo = next.tempo;
919 if (! d->m_tempos.isEmpty()) {
920 foreach(
const RecTempo& rec, d->m_tempos) {
921 if (rec.time >= time)
925 next.seconds = last.seconds +
926 (((time - last.time) / division) * (60.0 / last.tempo));
928 d->m_tempos.append(next);
934 void QWrk::processSysexChunk()
939 int bank = readByte();
940 int length = read16bit();
941 bool autosend = (readByte() != 0);
942 int namelen = readByte();
943 name = readString(namelen);
944 for(j=0; j<length; ++j) {
945 int byte = readByte();
951 void QWrk::processSysex2Chunk()
956 int bank = read16bit();
957 int length = read32bit();
958 quint8 b = readByte();
959 int port = ( b & 0xf0 ) >> 4;
960 bool autosend = ( (b & 0x0f) != 0);
961 int namelen = readByte();
962 name = readString(namelen);
963 for(j=0; j<length; ++j) {
964 int byte = readByte();
970 void QWrk::processNewSysexChunk()
975 int bank = read16bit();
976 int length = read32bit();
977 int port = read16bit();
978 bool autosend = (readByte() != 0);
979 int namelen = readByte();
980 name = readString(namelen);
981 for(j=0; j<length; ++j) {
982 int byte = readByte();
988 void QWrk::processThruChunk()
991 qint8 port = readByte();
992 qint8 channel = readByte();
993 qint8 keyPlus = readByte();
994 qint8 velPlus = readByte();
995 qint8 localPort = readByte();
996 qint8 mode = readByte();
997 Q_EMIT
signalWRKThru(mode, port, channel, keyPlus, velPlus, localPort);
1000 void QWrk::processTrackOffset()
1002 quint16 track = read16bit();
1003 qint16 offset = read16bit();
1007 void QWrk::processTrackReps()
1009 quint16 track = read16bit();
1010 quint16 reps = read16bit();
1014 void QWrk::processTrackPatch()
1016 quint16 track = read16bit();
1017 qint8 patch = readByte();
1021 void QWrk::processTimeFormat()
1023 quint16 fmt = read16bit();
1024 quint16 ofs = read16bit();
1028 void QWrk::processComments()
1030 int len = read16bit();
1031 QString text = readString(len);
1035 void QWrk::processVariableRecord(
int max)
1037 int datalen = max - 32;
1039 QString name = readVarString();
1040 readGap(31 - name.length());
1041 for (
int i = 0; i < datalen; ++i )
1046 void QWrk::processUnknown(
int id)
1051 void QWrk::processNewTrack()
1061 bool selected =
false;
1064 quint16 track = read16bit();
1065 quint8 len = readByte();
1066 QString name = readString(len);
1068 patch = read16bit();
1075 channel = readByte();
1076 muted = (readByte() != 0);
1077 Q_EMIT
signalWRKNewTrack(name, track, channel, key, vel, port, selected, muted, loop);
1088 void QWrk::processSoftVer()
1090 int len = readByte();
1091 QString vers = readString(len);
1095 void QWrk::processTrackName()
1097 int track = read16bit();
1098 int len = readByte();
1099 QString name = readString(len);
1103 void QWrk::processStringTable()
1106 int rows = read16bit();
1107 for (
int i = 0; i < rows; ++i) {
1108 int len = readByte();
1109 QString name = readString(len);
1110 int idx = readByte();
1111 table.insert(idx, name);
1116 void QWrk::processLyricsStream()
1118 quint16 track = read16bit();
1119 int events = read32bit();
1120 processNoteArray(track, events);
1123 void QWrk::processTrackVol()
1125 quint16 track = read16bit();
1126 int vol = read16bit();
1130 void QWrk::processNewTrackOffset()
1132 quint16 track = read16bit();
1133 int offset = read32bit();
1137 void QWrk::processTrackBank()
1139 quint16 track = read16bit();
1140 int bank = read16bit();
1144 void QWrk::processSegmentChunk()
1147 int track = read16bit();
1148 int offset = read32bit();
1150 int len = readByte();
1151 name = readString(len);
1154 int events = read32bit();
1155 processNoteArray(track, events);
1158 void QWrk::processNewStream()
1161 int track = read16bit();
1162 int len = readByte();
1163 name = readString(len);
1165 int events = read32bit();
1166 processNoteArray(track, events);
1169 void QWrk::processEndChunk()
1174 int QWrk::readChunk()
1176 long start_pos, final_pos;
1177 int ck_len, ck = readByte();
1178 if (ck != END_CHUNK) {
1179 ck_len = read32bit();
1181 final_pos = start_pos + ck_len;
1182 readRawData(ck_len);
1186 processTrackChunk();
1192 processTimebaseChunk();
1195 processStreamChunk();
1198 processMeterChunk();
1201 processTempoChunk(100);
1204 processTempoChunk();
1207 processSysexChunk();
1213 processTrackOffset();
1219 processTrackPatch();
1222 processTimeFormat();
1228 processVariableRecord(ck_len);
1240 processStringTable();
1243 processLyricsStream();
1249 processNewTrackOffset();
1255 processMeterKeyChunk();
1258 processSysex2Chunk();
1261 processNewSysexChunk();
1264 processSegmentChunk();
1277 void QWrk::wrkRead()
1281 QByteArray hdr(
HEADER.length(),
' ');
1282 d->m_tempos.clear();
1283 d->m_IOStream->device()->read(hdr.data(),
HEADER.length());
1284 if (hdr == HEADER) {
1290 ck_id = readChunk();
1291 }
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.