1
#include "convertgtp.h"
4
#include <qdatastream.h>
6
ConvertGtp::ConvertGtp(TabSong *song): ConvertBase(song) {}
8
QString ConvertGtp::readDelphiString()
14
int maxl = readDelphiInteger();
17
if (maxl != l + 1) kdWarning() << "readDelphiString - first word doesn't match second byte\n";
19
c = (char *) malloc(l + 5);
22
stream->readRawBytes(c, l);
24
str = QString::fromLocal8Bit(c);
31
QString ConvertGtp::readPascalString()
39
c = (char *) malloc(l + 5);
42
stream->readRawBytes(c, l);
44
str = QString::fromLocal8Bit(c);
51
QString ConvertGtp::readWordPascalString()
56
int l = readDelphiInteger();
58
c = (char *) malloc(l + 5);
61
stream->readRawBytes(c, l);
63
str = QString::fromLocal8Bit(c);
70
int ConvertGtp::readDelphiInteger()
74
(*stream) >> x; r = x;
75
(*stream) >> x; r += x << 8;
76
(*stream) >> x; r += x << 16;
77
(*stream) >> x; r += x << 24;
81
void ConvertGtp::readChromaticGraph()
86
// GREYFIX: currently just skips over chromatic graph
87
(*stream) >> num; // icon
88
readDelphiInteger(); // shown amplitude
89
n = readDelphiInteger(); // number of points
90
for (int i = 0; i < n; i++) {
91
readDelphiInteger(); // time
92
readDelphiInteger(); // pitch
93
(*stream) >> num; // vibrato
97
void ConvertGtp::readChord()
103
// GREYFIX: currently just skips over chord diagram
105
// GREYFIX: chord diagram
106
x1 = readDelphiInteger();
108
kdWarning() << "Chord INT1=" << x1 << ", not 257\n";
109
x2 = readDelphiInteger();
111
kdWarning() << "Chord INT2=" << x2 << ", not 0\n";
112
x3 = readDelphiInteger();
113
kdDebug() << "Chord INT3: " << x3 << "\n"; // FF FF FF FF if there is diagram
114
x4 = readDelphiInteger();
116
kdWarning() << "Chord INT4=" << x4 << ", not 0\n";
119
kdWarning() << "Chord BYTE5=" << (int) num << ", not 0\n";
120
text = readPascalString();
121
kdDebug() << "Chord diagram: " << text << "\n";
123
// Skip garbage after pascal string end
124
stream->readRawBytes(garbage, 25 - text.length());
126
// Chord diagram parameters - for every string
127
for (int i = 0; i < STRING_MAX_NUMBER; i++) {
128
x1 = readDelphiInteger();
129
kdDebug() << x1 << "\n";
133
stream->readRawBytes(garbage, 36);
135
kdDebug() << "after chord, position: " << stream->device()->at() << "\n";
138
bool ConvertGtp::readSignature()
142
QString s = readPascalString(); // Format string
143
kdDebug() << "GTP format: " << s << "\n";
145
stream->readRawBytes(garbage, 6); // Mysterious bytes
150
void ConvertGtp::readSongAttributes()
159
song->title = readDelphiString(); // Song title
160
kdDebug() << "Title: " << song->title << "\n";
162
s = readDelphiString(); // Song subtitle
163
if (!s.isEmpty()) song->title += " (" + s + ")";
164
kdDebug() << "Title: " << song->title << "\n";
166
song->author = readDelphiString(); // Artist
167
kdDebug() << "Author: " << song->author << "\n";
169
s = readDelphiString(); // Album
170
if (!s.isEmpty()) song->author += " (" + s + ")";
171
kdDebug() << "Author: " << song->author << "\n";
173
s = readDelphiString(); // Author
174
if (!s.isEmpty()) song->author += " / " + s;
175
kdDebug() << "Author: " << song->author << "\n";
177
s = readDelphiString(); // Copyright
178
if (!s.isEmpty()) song->comments += "(C) " + s + "\n\n";
180
song->transcriber = readDelphiString(); // Tab
182
s = readDelphiString(); // Instructions
183
if (!s.isEmpty()) song->comments += s + "\n\n";
186
int n = readDelphiInteger();
187
for (int i = 0; i < n; i++)
188
song->comments += readDelphiString() + "\n";
190
(*stream) >> num; // GREYFIX: Shuffle rhythm feel
193
readDelphiInteger(); // GREYFIX: Lyric track number start
194
for (int i = 0; i < LYRIC_LINES_MAX_NUMBER; i++) {
195
readDelphiInteger(); // GREYFIX: Start from bar
196
readWordPascalString(); // GREYFIX: Lyric line
199
song->tempo = readDelphiInteger(); // Tempo
200
stream->readRawBytes(garbage, 5); // Mysterious bytes
203
void ConvertGtp::readTrackDefaults()
207
for (int i = 0; i < TRACK_MAX_NUMBER * 2; i++) {
208
trackPatch[i] = readDelphiInteger(); // MIDI Patch
209
(*stream) >> num; // GREYFIX: volume
210
(*stream) >> num; // GREYFIX: pan
211
(*stream) >> num; // GREYFIX: chorus
212
(*stream) >> num; // GREYFIX: reverb
213
(*stream) >> num; // GREYFIX: phase
214
(*stream) >> num; // GREYFIX: tremolo
215
(*stream) >> num; // 2 byte padding: must be 00 00
220
void ConvertGtp::readBarProperties()
222
Q_UINT8 bar_bitmask, num;
227
kdDebug() << "readBarProperties(): start\n";
228
for (int i = 0; i < numBars; i++) {
229
(*stream) >> bar_bitmask; // bar property bitmask
230
if (bar_bitmask != 0)
231
kdDebug() << "BAR #" << i << " - flags " << (int) bar_bitmask << "\n";
232
// GREYFIX: new_time_numerator
233
if (bar_bitmask & 0x01) {
236
kdDebug() << "new time1 signature: " << time1 << ":" << time2 << "\n";
238
// GREYFIX: new_time_denominator
239
if (bar_bitmask & 0x02) {
242
kdDebug() << "new time2 signature: " << time1 << ":" << time2 << "\n";
244
// GREYFIX: number_of_repeats
245
if (bar_bitmask & 0x08) {
247
kdDebug() << "repeat " << (int) num << "x\n";
249
// GREYFIX: alternative_ending_to
250
if (bar_bitmask & 0x10) {
252
kdDebug() << "alternative ending to " << (int) num << "\n";
254
// GREYFIX: new section
255
if (bar_bitmask & 0x20) {
256
QString text = readDelphiString();
257
readDelphiInteger(); // color?
258
kdDebug() << "new section: " << text << "\n";
260
if (bar_bitmask & 0x40) {
261
kdDebug() << "new key signature\n";
262
(*stream) >> num; // GREYFIX: alterations_number
263
(*stream) >> num; // GREYFIX: minor
265
if (bar_bitmask & 0x80)
266
kdWarning() << "0x80 in bar properties!\n";
268
kdDebug() << "readBarProperties(): end\n";
271
void ConvertGtp::readTrackProperties()
276
kdDebug() << "readTrackProperties(): start\n";
278
for (int i = 0; i < numTracks; i++) {
279
song->t.append(new TabTrack(TabTrack::FretTab, 0, 0, 0, 0, 6, 24));
280
TabTrack *trk = song->t.current();
282
(*stream) >> num; // GREYFIX: simulations bitmask
283
trk->name = readPascalString(); // Track name
284
kdDebug() << "Track: " << trk->name << "\n";
286
stream->readRawBytes(garbage, 40 - trk->name.length()); // Padding
288
// Tuning information
290
trk->string = readDelphiInteger();
292
// Parse [0..string-1] with real string tune data in reverse order
293
for (int j = trk->string - 1; j >= 0; j--)
294
trk->tune[j] = readDelphiInteger();
296
// Throw out the other useless garbage in [string..MAX-1] range
297
for (int j = trk->string; j < STRING_MAX_NUMBER; j++)
300
// GREYFIX: auto flag here?
302
readDelphiInteger(); // GREYFIX: MIDI port
303
trk->channel = readDelphiInteger(); // MIDI channel 1
304
readDelphiInteger(); // GREYFIX: MIDI channel 2
305
trk->frets = readDelphiInteger(); // Frets
306
readDelphiInteger(); // GREYFIX: Capo
307
readDelphiInteger(); // GREYFIX: Color
309
// Fill remembered values from defaults
310
trk->patch = trackPatch[i];
312
kdDebug() << "readTrackProperties(): end\n";
315
void ConvertGtp::readTabs()
317
Q_UINT8 beat_bitmask, stroke_bitmask1, stroke_bitmask2, strings, num;
318
Q_INT8 length, volume, pan, chorus, reverb, phase, tremolo;
321
TabTrack *trk = song->t.first();
322
for (int tr = 0; tr < numTracks; tr++) {
323
trk->b.resize(numBars);
325
trk = song->t.next();
328
for (int j = 0; j < numBars; j++) {
329
TabTrack *trk = song->t.first();
330
for (int tr = 0; tr < numTracks; tr++) {
331
int numBeats = readDelphiInteger();
332
kdDebug() << "TRACK " << tr << ", BAR " << j << " (position: " << stream->device()->at() << ")\n";
335
trk->c.resize(trk->c.size() + numBeats);
336
trk->b[j].time1 = trk->b[j].time2 = 4; // GREYFIX: fixed 4:4 time signature
339
for (int k = 0; k < numBeats; k++) {
342
(*stream) >> beat_bitmask; // beat bitmask
344
if (beat_bitmask & 0x01) // dotted column
345
trk->c[x].flags |= FLAG_DOT;
347
if (beat_bitmask & 0x40) {
348
(*stream) >> num; // GREYFIX: pause_kind
351
// Guitar Pro 4 beat lengths are as following:
352
// -2 = 1 => 480 3-l = 5 2^(3-l)*15
356
// 2 = 1/16 => 30 ... etc 1
359
(*stream) >> length; // length
360
kdDebug() << "beat_bitmask: " << (int) beat_bitmask << "; length: " << length << "\n";
362
trk->c[x].l = (1 << (3 - length)) * 15;
364
if (beat_bitmask & 0x20) {
365
readDelphiInteger(); // GREYFIX: t for tuples
368
if (beat_bitmask & 0x02) // Chord diagram
371
if (beat_bitmask & 0x04) {
372
kdDebug() << "Text: " << readDelphiString() << "\n"; // GREYFIX: text with a beat
375
// GREYFIX: stroke bitmasks
376
if (beat_bitmask & 0x08) {
377
(*stream) >> stroke_bitmask1;
378
(*stream) >> stroke_bitmask2;
379
if (stroke_bitmask1 & 0x20)
380
(*stream) >> num; // GREYFIX: string torture
381
if (stroke_bitmask2 & 0x04)
382
readChromaticGraph(); // GREYFIX: tremolo graph
383
if (stroke_bitmask1 & 0x40) {
384
(*stream) >> num; // GREYFIX: down stroke length
385
(*stream) >> num; // GREYFIX: up stroke length
387
if (stroke_bitmask2 & 0x02) {
388
(*stream) >> num; // GREYFIX: stroke pick direction
392
if (beat_bitmask & 0x10) { // mixer variations
393
(*stream) >> num; // GREYFIX: new MIDI patch
394
(*stream) >> volume; // GREYFIX: new
395
(*stream) >> pan; // GREYFIX: new
396
(*stream) >> chorus; // GREYFIX: new
397
(*stream) >> reverb; // GREYFIX: new
398
(*stream) >> phase; // GREYFIX: new
399
(*stream) >> tremolo; // GREYFIX: new
400
int tempo = readDelphiInteger(); // GREYFIX: new tempo
402
// GREYFIX: transitions
403
if (volume != -1) (*stream) >> num;
404
if (pan != -1) (*stream) >> num;
405
if (chorus != -1) (*stream) >> num;
406
if (reverb != -1) (*stream) >> num;
407
if (tremolo != -1) (*stream) >> num;
408
if (tempo != -1) (*stream) >> num;
410
(*stream) >> num; // padding
413
(*stream) >> strings; // used strings mask
415
for (int y = STRING_MAX_NUMBER - 1; y >= 0; y--) {
417
trk->c[x].a[y] = NULL_NOTE;
418
if (strings & (1 << (y + STRING_MAX_NUMBER - trk->string)))
424
for (int y = 0; y <= trk->string; y++) {
425
if (trk->c[x].a[y] == NULL_NOTE) {
428
tmp += '0' + trk->c[x].a[y];
431
kdDebug() << "[" << tmp << "]\n";
435
trk = song->t.next();
440
void ConvertGtp::readNote(TabTrack *trk, int x, int y)
442
Q_UINT8 note_bitmask, variant, num, mod_mask1, mod_mask2;
444
(*stream) >> note_bitmask; // note bitmask
445
(*stream) >> variant; // variant
447
if (note_bitmask & 0x01) { // GREYFIX: note != beat
448
(*stream) >> num; // length
449
(*stream) >> num; // t
452
if (note_bitmask & 0x02) {}; // GREYFIX: note is dotted
454
if (note_bitmask & 0x10) { // GREYFIX: dynamic
458
(*stream) >> num; // fret number
459
trk->c[x].a[y] = num;
461
if (variant == 2) { // link with previous beat
462
trk->c[x].flags |= FLAG_ARC;
463
for (uint i = 0; i < MAX_STRINGS; i++) {
464
trk->c[x].a[i] = NULL_NOTE;
469
if (variant == 3) // dead notes
470
trk->c[x].a[y] = DEAD_NOTE;
472
if (note_bitmask & 0x80) { // GREYFIX: fingering
477
if (note_bitmask & 0x08) {
478
(*stream) >> mod_mask1;
479
(*stream) >> mod_mask2;
480
if (mod_mask1 & 0x01) {
481
readChromaticGraph(); // GREYFIX: bend graph
483
if (mod_mask1 & 0x02) // hammer on / pull off
484
trk->c[x].e[y] |= EFFECT_LEGATO;
485
if (mod_mask1 & 0x08) // let ring
486
trk->c[x].e[y] |= EFFECT_LETRING;
487
if (mod_mask1 & 0x10) { // GREYFIX: graces
488
(*stream) >> num; // GREYFIX: grace fret
489
(*stream) >> num; // GREYFIX: grace dynamic
490
(*stream) >> num; // GREYFIX: grace transition
491
(*stream) >> num; // GREYFIX: grace length
493
if (mod_mask2 & 0x01) // staccato - we do palm mute
494
trk->c[x].flags |= FLAG_PM;
495
if (mod_mask2 & 0x02) // palm mute - we mute the whole column
496
trk->c[x].flags |= FLAG_PM;
497
if (mod_mask2 & 0x04) { // GREYFIX: tremolo
498
(*stream) >> num; // GREYFIX: tremolo picking length
500
if (mod_mask2 & 0x08) { // slide
501
trk->c[x].e[y] |= EFFECT_SLIDE;
502
(*stream) >> num; // GREYFIX: slide kind
504
if (mod_mask2 & 0x10) { // GREYFIX: harmonic
505
(*stream) >> num; // GREYFIX: harmonic kind
507
if (mod_mask2 & 0x20) { // GREYFIX: trill
508
(*stream) >> num; // GREYFIX: trill fret
509
(*stream) >> num; // GREYFIX: trill length
514
bool ConvertGtp::load(QString fileName)
517
if (!f.open(IO_ReadOnly))
523
if (!readSignature())
529
readSongAttributes();
532
numBars = readDelphiInteger(); // Number of bars
533
numTracks = readDelphiInteger(); // Number of tracks
535
kdDebug() << "Bars: " << numBars << "\n";
536
kdDebug() << "Tracks: " << numTracks << "\n";
538
// Mysterious padding: must be 43 04 04 00 (for 4.00 format)
539
kdDebug() << "PAD: " << readDelphiInteger() << " (must be 263235)\n";
542
readTrackProperties();
545
int ex = readDelphiInteger(); // Exit code: 00 00 00 00
547
kdWarning() << "File not ended with 00 00 00 00\n";
549
kdWarning() << "File not ended - there's more data!\n";
556
bool ConvertGtp::save(QString)