ptformat: Update to 877fa28 - more endian resilient && pt5 fixes
[ardour.git] / libs / ptformat / ptfformat.cc
1 /*
2  * libptformat - a library to read ProTools sessions
3  *
4  * Copyright (C) 2015  Damien Zammit
5  * Copyright (C) 2015  Robin Gareus
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string>
26 #include <string.h>
27 #include <assert.h>
28
29 #include <glib/gstdio.h>
30
31 #include "ptformat/ptfformat.h"
32
33 #if 0
34 #define verbose_printf(...) printf(__VA_ARGS__)
35 #else
36 #define verbose_printf(...)
37 #endif
38
39 using namespace std;
40
41 static bool wavidx_compare(PTFFormat::wav_t& w1, PTFFormat::wav_t& w2) {
42         return w1.index < w2.index;
43 }
44
45 static bool wavname_compare(PTFFormat::wav_t& w1, PTFFormat::wav_t& w2) {
46         return (strcasecmp(w1.filename.c_str(), w2.filename.c_str()) < 0);
47 }
48
49 static bool regidx_compare(PTFFormat::region_t& r1, PTFFormat::region_t& r2) {
50         return r1.index < r2.index;
51 }
52
53 static bool regname_compare(PTFFormat::region_t& r1, PTFFormat::region_t& r2) {
54         return (strcasecmp(r1.name.c_str(), r2.name.c_str()) < 0);
55 }
56
57 static void
58 hexdump(uint8_t *data, int len)
59 {
60         int i,j,end,step=16;
61
62         for (i = 0; i < len; i += step) {
63                 printf("0x%02X: ", i);
64                 end = i + step;
65                 if (end > len) end = len;
66                 for (j = i; j < end; j++) {
67                         printf("0x%02X ", data[j]);
68                 }
69                 for (j = i; j < end; j++) {
70                         if (data[j] < 128 && data[j] > 32)
71                                 printf("%c", data[j]);
72                         else
73                                 printf(".");
74                 }
75                 printf("\n");
76         }
77 }
78
79 PTFFormat::PTFFormat() : version(0), product(NULL), ptfunxored(NULL) {
80 }
81
82 PTFFormat::~PTFFormat() {
83         cleanup();
84 }
85
86 uint16_t
87 PTFFormat::u_endian_read2(unsigned char *buf, bool bigendian)
88 {
89         if (bigendian) {
90                 return ((uint16_t)(buf[0]) << 8) | (uint16_t)(buf[1]);
91         } else {
92                 return ((uint16_t)(buf[1]) << 8) | (uint16_t)(buf[0]);
93         }
94 }
95
96 uint32_t
97 PTFFormat::u_endian_read3(unsigned char *buf, bool bigendian)
98 {
99         if (bigendian) {
100                 return ((uint32_t)(buf[0]) << 16) |
101                         ((uint32_t)(buf[1]) << 8) |
102                         (uint32_t)(buf[2]);
103         } else {
104                 return ((uint32_t)(buf[2]) << 16) |
105                         ((uint32_t)(buf[1]) << 8) |
106                         (uint32_t)(buf[0]);
107         }
108 }
109
110 uint32_t
111 PTFFormat::u_endian_read4(unsigned char *buf, bool bigendian)
112 {
113         if (bigendian) {
114                 return ((uint32_t)(buf[0]) << 24) |
115                         ((uint32_t)(buf[1]) << 16) |
116                         ((uint32_t)(buf[2]) << 8) |
117                         (uint32_t)(buf[3]);
118         } else {
119                 return ((uint32_t)(buf[3]) << 24) |
120                         ((uint32_t)(buf[2]) << 16) |
121                         ((uint32_t)(buf[1]) << 8) |
122                         (uint32_t)(buf[0]);
123         }
124 }
125
126 uint64_t
127 PTFFormat::u_endian_read5(unsigned char *buf, bool bigendian)
128 {
129         if (bigendian) {
130                 return ((uint64_t)(buf[0]) << 32) |
131                         ((uint64_t)(buf[1]) << 24) |
132                         ((uint64_t)(buf[2]) << 16) |
133                         ((uint64_t)(buf[3]) << 8) |
134                         (uint64_t)(buf[4]);
135         } else {
136                 return ((uint64_t)(buf[4]) << 32) |
137                         ((uint64_t)(buf[3]) << 24) |
138                         ((uint64_t)(buf[2]) << 16) |
139                         ((uint64_t)(buf[1]) << 8) |
140                         (uint64_t)(buf[0]);
141         }
142 }
143
144 void
145 PTFFormat::cleanup(void) {
146         if (ptfunxored) {
147                 free(ptfunxored);
148                 ptfunxored = NULL;
149         }
150         audiofiles.clear();
151         regions.clear();
152         midiregions.clear();
153         compounds.clear();
154         tracks.clear();
155         miditracks.clear();
156         version = 0;
157         product = NULL;
158 }
159
160 int64_t
161 PTFFormat::foundat(unsigned char *haystack, uint64_t n, const char *needle) {
162         int64_t found = 0;
163         uint64_t i, j, needle_n;
164         needle_n = strlen(needle);
165
166         for (i = 0; i < n; i++) {
167                 found = i;
168                 for (j = 0; j < needle_n; j++) {
169                         if (haystack[i+j] != needle[j]) {
170                                 found = -1;
171                                 break;
172                         }
173                 }
174                 if (found > 0)
175                         return found;
176         }
177         return -1;
178 }
179
180 bool
181 PTFFormat::jumpto(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen) {
182         uint64_t i;
183         uint64_t k = *currpos;
184         while (k + needlelen < maxoffset) {
185                 bool foundall = true;
186                 for (i = 0; i < needlelen; i++) {
187                         if (buf[k+i] != needle[i]) {
188                                 foundall = false;
189                                 break;
190                         }
191                 }
192                 if (foundall) {
193                         *currpos = k;
194                         return true;
195                 }
196                 k++;
197         }
198         return false;
199 }
200
201 bool
202 PTFFormat::jumpback(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen) {
203         uint64_t i;
204         uint64_t k = *currpos;
205         while (k > 0 && k + needlelen < maxoffset) {
206                 bool foundall = true;
207                 for (i = 0; i < needlelen; i++) {
208                         if (buf[k+i] != needle[i]) {
209                                 foundall = false;
210                                 break;
211                         }
212                 }
213                 if (foundall) {
214                         *currpos = k;
215                         return true;
216                 }
217                 k--;
218         }
219         return false;
220 }
221
222 bool
223 PTFFormat::foundin(std::string haystack, std::string needle) {
224         size_t found = haystack.find(needle);
225         if (found != std::string::npos) {
226                 return true;
227         } else {
228                 return false;
229         }
230 }
231
232 /* Return values:       0            success
233                         -1           could not decrypt pt session
234 */
235 int
236 PTFFormat::unxor(std::string path) {
237         FILE *fp;
238         unsigned char xxor[256];
239         unsigned char ct;
240         uint64_t i;
241         uint8_t xor_type;
242         uint8_t xor_value;
243         uint8_t xor_delta;
244         uint16_t xor_len;
245
246         if (! (fp = g_fopen(path.c_str(), "rb"))) {
247                 return -1;
248         }
249
250         fseek(fp, 0, SEEK_END);
251         len = ftell(fp);
252         if (len < 0x14) {
253                 fclose(fp);
254                 return -1;
255         }
256
257         if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
258                 /* Silently fail -- out of memory*/
259                 fclose(fp);
260                 ptfunxored = 0;
261                 return -1;
262         }
263
264         /* The first 20 bytes are always unencrypted */
265         fseek(fp, 0x00, SEEK_SET);
266         i = fread(ptfunxored, 1, 0x14, fp);
267         if (i < 0x14) {
268                 fclose(fp);
269                 return -1;
270         }
271
272         xor_type = ptfunxored[0x12];
273         xor_value = ptfunxored[0x13];
274         xor_len = 256;
275
276         // xor_type 0x01 = ProTools 5, 6, 7, 8 and 9
277         // xor_type 0x05 = ProTools 10, 11, 12
278         switch(xor_type) {
279         case 0x01:
280                 xor_delta = gen_xor_delta(xor_value, 53, false);
281                 break;
282         case 0x05:
283                 xor_delta = gen_xor_delta(xor_value, 11, true);
284                 break;
285         default:
286                 fclose(fp);
287                 return -1;
288         }
289
290         /* Generate the xor_key */
291         for (i=0; i < xor_len; i++)
292                 xxor[i] = (i * xor_delta) & 0xff;
293
294         /* hexdump(xxor, xor_len); */
295
296         /* Read file and decrypt rest of file */
297         i = 0x14;
298         fseek(fp, i, SEEK_SET);
299         while (fread(&ct, 1, 1, fp) != 0) {
300                 uint8_t xor_index = (xor_type == 0x01) ? i & 0xff : (i >> 12) & 0xff;
301                 ptfunxored[i++] = ct ^ xxor[xor_index];
302         }
303         fclose(fp);
304         return 0;
305 }
306
307 /* Return values:       0            success
308                         -1           could not parse pt session
309 */
310 int
311 PTFFormat::load(std::string ptf, int64_t targetsr) {
312         cleanup();
313         path = ptf;
314
315         if (unxor(path))
316                 return -1;
317
318         if (parse_version())
319                 return -1;
320
321         if (version < 5 || version > 12)
322                 return -1;
323
324         targetrate = targetsr;
325
326         if (parse())
327                 return -1;
328
329         return 0;
330 }
331
332 bool
333 PTFFormat::parse_version() {
334         uint32_t seg_len,str_len;
335         uint8_t *data = ptfunxored + 0x14;
336         uintptr_t data_end = ((uintptr_t)ptfunxored) + 0x100;
337         uint8_t seg_type;
338         bool success = false;
339
340         while( ((uintptr_t)data < data_end) && (success == false) ) {
341
342                 if (data[0] != 0x5a) {
343                         success = false;
344                         break;
345                 }
346
347                 seg_type = data[1];
348                 /* Skip segment header */
349                 data += 3;
350                 if (data[0] == 0 && data[1] == 0) {
351                         /* BE */
352                         is_bigendian = true;
353                 } else {
354                         /* LE */
355                         is_bigendian = false;
356                 }
357                 seg_len = u_endian_read4(&data[0], is_bigendian);
358
359                 /* Skip seg_len */
360                 data += 4;
361                 if (!(seg_type == 0x04 || seg_type == 0x03) || data[0] != 0x03) {
362                         /* Go to next segment */
363                         data += seg_len;
364                         continue;
365                 }
366                 /* Skip 0x03 0x00 0x00 */
367                 data += 3;
368                 seg_len -= 3;
369                 str_len = (*(uint8_t *)data);
370                 if (! (product = (uint8_t *)malloc((str_len+1) * sizeof(uint8_t)))) {
371                         success = false;
372                         break;
373                 }
374
375                 /* Skip str_len */
376                 data += 4;
377                 seg_len -= 4;
378
379                 memcpy(product, data, str_len);
380                 product[str_len] = 0;
381                 data += str_len;
382                 seg_len -= str_len;
383
384                 /* Skip 0x03 0x00 0x00 0x00 */
385                 data += 4;
386                 seg_len -= 4;
387
388                 version = data[0];
389                 if (version == 0) {
390                         version = data[3];
391                 }
392                 data += seg_len;
393                 success = true;
394         }
395
396         /* If the above does not work, try other heuristics */
397         if ((uintptr_t)data >= data_end - seg_len) {
398                 version = ptfunxored[0x40];
399                 if (version == 0) {
400                         version = ptfunxored[0x3d];
401                 }
402                 if (version == 0) {
403                         version = ptfunxored[0x3a] + 2;
404                 }
405                 if (version != 0) {
406                         success = true;
407                 }
408         }
409         return (!success);
410 }
411
412 uint8_t
413 PTFFormat::gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative) {
414         uint16_t i;
415         for (i = 0; i < 256; i++) {
416                 if (((i * mul) & 0xff) == xor_value) {
417                                 return (negative) ? i * (-1) : i;
418                 }
419         }
420         // Should not occur
421         return 0;
422 }
423
424 int
425 PTFFormat::parse(void) {
426         if (version == 5) {
427                 parse5header();
428                 setrates();
429                 if (sessionrate < 44100 || sessionrate > 192000)
430                   return -1;
431                 parseaudio5();
432                 parserest5();
433                 parsemidi();
434         } else if (version == 7) {
435                 parse7header();
436                 setrates();
437                 if (sessionrate < 44100 || sessionrate > 192000)
438                   return -1;
439                 parseaudio();
440                 parserest89();
441                 parsemidi();
442         } else if (version == 8) {
443                 parse8header();
444                 setrates();
445                 if (sessionrate < 44100 || sessionrate > 192000)
446                   return -1;
447                 parseaudio();
448                 parserest89();
449                 parsemidi();
450         } else if (version == 9) {
451                 parse9header();
452                 setrates();
453                 if (sessionrate < 44100 || sessionrate > 192000)
454                   return -1;
455                 parseaudio();
456                 parserest89();
457                 parsemidi();
458         } else if (version == 10 || version == 11 || version == 12) {
459                 parse10header();
460                 setrates();
461                 if (sessionrate < 44100 || sessionrate > 192000)
462                   return -1;
463                 parseaudio();
464                 parserest12();
465                 parsemidi12();
466         } else {
467                 // Should not occur
468                 return -1;
469         }
470         return 0;
471 }
472
473 void
474 PTFFormat::setrates(void) {
475         ratefactor = 1.f;
476         if (sessionrate != 0) {
477                 ratefactor = (float)targetrate / sessionrate;
478         }
479 }
480
481 void
482 PTFFormat::parse5header(void) {
483         uint32_t k;
484
485         // Find session sample rate
486         k = 0x100;
487
488         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x00\x02", 3)) {
489                 jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2);
490                 k--;
491         }
492
493         sessionrate = u_endian_read3(&ptfunxored[k+12], is_bigendian);
494 }
495
496 void
497 PTFFormat::parse7header(void) {
498         uint32_t k;
499
500         // Find session sample rate
501         k = 0x100;
502
503         jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x00\x05", 3);
504
505         sessionrate = u_endian_read3(&ptfunxored[k+12], is_bigendian);
506 }
507
508 void
509 PTFFormat::parse8header(void) {
510         uint32_t k;
511
512         // Find session sample rate
513         k = 0;
514
515         jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x05", 2);
516
517         sessionrate = u_endian_read3(&ptfunxored[k+11], is_bigendian);
518 }
519
520 void
521 PTFFormat::parse9header(void) {
522         uint32_t k;
523
524         // Find session sample rate
525         k = 0x100;
526
527         jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x06", 2);
528
529         sessionrate = u_endian_read3(&ptfunxored[k+11], is_bigendian);
530 }
531
532 void
533 PTFFormat::parse10header(void) {
534         uint32_t k;
535
536         // Find session sample rate
537         k = 0x100;
538
539         jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x09", 2);
540
541         sessionrate = u_endian_read3(&ptfunxored[k+11], is_bigendian);
542 }
543
544 void
545 PTFFormat::parserest5(void) {
546         uint32_t i, j, k;
547         uint64_t regionspertrack, lengthofname, numberofregions;
548         uint64_t startbytes, lengthbytes, offsetbytes, somethingbytes, skipbytes;
549         uint16_t tracknumber = 0;
550         uint16_t findex;
551         uint16_t rindex;
552         unsigned char tag1[3];
553         unsigned char tag2[3];
554         unsigned char tag3[3];
555
556         if (is_bigendian) {
557                 tag1[0] = tag2[0] = tag3[0] = '\x5a';
558                 tag1[1] = tag2[1] = tag3[1] = '\x00';
559                 tag1[2] = '\x01';
560                 tag2[2] = '\x02';
561                 tag3[2] = '\x03';
562         } else {
563                 tag1[0] = tag2[0] = tag3[0] = '\x5a';
564                 tag1[1] = '\x01';
565                 tag2[1] = '\x02';
566                 tag3[1] = '\x03';
567                 tag1[2] = tag2[2] = tag3[2] = '\x00';
568         }
569
570         // Find Source->Region info
571         k = upto;
572         for (i = 0; i < 2; i++) {
573                 jumpto(&k, ptfunxored, len, tag3, 3);
574                 k++;
575         }
576         jumpto(&k, ptfunxored, len, tag2, 3);
577
578         numberofregions = u_endian_read4(&ptfunxored[k-13], is_bigendian);
579
580         i = k;
581         while (numberofregions > 0 && i < len) {
582                 jumpto(&i, ptfunxored, len, tag2, 3);
583
584                 uint32_t lengthofname = u_endian_read4(&ptfunxored[i+9], is_bigendian);
585
586                 char name[256] = {0};
587                 for (j = 0; j < lengthofname; j++) {
588                         name[j] = ptfunxored[i+13+j];
589                 }
590                 name[j] = '\0';
591                 j += i+13;
592                 //uint8_t disabled = ptfunxored[j];
593
594                 if (is_bigendian) {
595                         offsetbytes = (ptfunxored[j+4] & 0xf0) >> 4;
596                         lengthbytes = (ptfunxored[j+3] & 0xf0) >> 4;
597                         startbytes = (ptfunxored[j+2] & 0xf0) >> 4;
598                         somethingbytes = (ptfunxored[j+2] & 0xf);
599                         skipbytes = ptfunxored[j+1];
600                 } else {
601                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4; //3
602                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
603                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4; //1
604                         somethingbytes = (ptfunxored[j+3] & 0xf);
605                         skipbytes = ptfunxored[j+4];
606                 }
607                 findex = u_endian_read4(&ptfunxored[j+5
608                                 +startbytes
609                                 +lengthbytes
610                                 +offsetbytes
611                                 +somethingbytes
612                                 +skipbytes], is_bigendian);
613
614                 uint32_t sampleoffset = 0;
615                 switch (offsetbytes) {
616                 case 4:
617                         sampleoffset = u_endian_read4(&ptfunxored[j+5], false);
618                         break;
619                 case 3:
620                         sampleoffset = u_endian_read3(&ptfunxored[j+5], false);
621                         break;
622                 case 2:
623                         sampleoffset = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
624                         break;
625                 case 1:
626                         sampleoffset = (uint32_t)(ptfunxored[j+5]);
627                         break;
628                 default:
629                         break;
630                 }
631                 j+=offsetbytes;
632                 uint32_t length = 0;
633                 switch (lengthbytes) {
634                 case 4:
635                         length = u_endian_read4(&ptfunxored[j+5], false);
636                         break;
637                 case 3:
638                         length = u_endian_read3(&ptfunxored[j+5], false);
639                         break;
640                 case 2:
641                         length = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
642                         break;
643                 case 1:
644                         length = (uint32_t)(ptfunxored[j+5]);
645                         break;
646                 default:
647                         break;
648                 }
649                 j+=lengthbytes;
650                 uint32_t start = 0;
651                 switch (startbytes) {
652                 case 4:
653                         start = u_endian_read4(&ptfunxored[j+5], false);
654                         break;
655                 case 3:
656                         start = u_endian_read3(&ptfunxored[j+5], false);
657                         break;
658                 case 2:
659                         start = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
660                         break;
661                 case 1:
662                         start = (uint32_t)(ptfunxored[j+5]);
663                         break;
664                 default:
665                         break;
666                 }
667                 j+=startbytes;
668
669                 std::string filename = string(name);
670                 wav_t f = {
671                         "",
672                         (uint16_t)findex,
673                         (int64_t)(start*ratefactor),
674                         (int64_t)(length*ratefactor),
675                 };
676
677                 vector<wav_t>::iterator begin = actualwavs.begin();
678                 vector<wav_t>::iterator finish = actualwavs.end();
679                 vector<wav_t>::iterator found;
680                 if ((found = std::find(begin, finish, f)) != finish) {
681                         f.filename = (*found).filename;
682                 }
683                 std::vector<midi_ev_t> m;
684                 region_t r = {
685                         name,
686                         rindex,
687                         (int64_t)(start*ratefactor),
688                         (int64_t)(sampleoffset*ratefactor),
689                         (int64_t)(length*ratefactor),
690                         f,
691                         m
692                 };
693                 regions.push_back(r);
694                 rindex++;
695                 i = j + 1;
696                 numberofregions--;
697         }
698
699         // Find Region->Track info
700         /*
701         k = 0;
702         for (i = 0; i < 4; i++) {
703                 jumpto(&k, ptfunxored, len, tag3, 3);
704                 k++;
705         }
706         */
707         k = j = i;
708         while (j < len) {
709                 if (jumpto(&j, ptfunxored, j+13+3, tag1, 3)) {
710                         j++;
711                         if (jumpto(&j, ptfunxored, j+13+3, tag1, 3)) {
712                                 j++;
713                                 if (jumpto(&j, ptfunxored, j+13+3, tag1, 3)) {
714                                         if ((j == k+26) && (ptfunxored[j-13] == '\x5a') && (ptfunxored[j-26] == '\x5a')) {
715                                                 k = j;
716                                                 break;
717                                         }
718                                 }
719                         }
720                 }
721                 k++;
722                 j = k;
723         }
724
725         if (ptfunxored[k+13] == '\x5a') {
726                 k++;
727         }
728
729         // Start parsing track info
730         rindex = 0;
731         while (k < len) {
732                 if (            (ptfunxored[k  ] == 0xff) &&
733                                 (ptfunxored[k+1] == 0xff)) {
734                         break;
735                 }
736                 jumpto(&k, ptfunxored, len, tag1, 3);
737
738                 lengthofname = u_endian_read4(&ptfunxored[k+9], is_bigendian);
739                 if (ptfunxored[k+13] == 0x5a) {
740                         k++;
741                         break;
742                 }
743                 char name[256] = {0};
744                 for (j = 0; j < lengthofname; j++) {
745                         name[j] = ptfunxored[k+13+j];
746                 }
747                 name[j] = '\0';
748                 regionspertrack = u_endian_read4(&ptfunxored[k+13+j], is_bigendian);
749                 for (i = 0; i < regionspertrack; i++) {
750                         jumpto(&k, ptfunxored, len, tag3, 3);
751                         j = k + 15;
752                         if (is_bigendian) {
753                                 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
754                                 //somethingbytes = (ptfunxored[j+2] & 0xf);
755                                 lengthbytes = (ptfunxored[j+3] & 0xf0) >> 4;
756                                 startbytes = (ptfunxored[j+4] & 0xf0) >> 4;
757                         } else {
758                                 offsetbytes = (ptfunxored[j+4] & 0xf0) >> 4;
759                                 //somethingbytes = (ptfunxored[j+3] & 0xf);
760                                 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
761                                 startbytes = (ptfunxored[j+1] & 0xf0) >> 4;
762                         }
763                         rindex = u_endian_read4(&ptfunxored[k+11], is_bigendian);
764                         uint32_t start = 0;
765                         switch (startbytes) {
766                         case 4:
767                                 start = u_endian_read4(&ptfunxored[j+5], false); 
768                                 break;
769                         case 3:
770                                 start = u_endian_read3(&ptfunxored[j+5], false); 
771                                 break;
772                         case 2:
773                                 start = (uint32_t)u_endian_read2(&ptfunxored[j+5], false); 
774                                 break;
775                         case 1:
776                                 start = (uint32_t)(ptfunxored[j+5]);
777                                 break;
778                         default:
779                                 break;
780                         }
781                         j+=startbytes;
782                         uint32_t length = 0;
783                         switch (lengthbytes) {
784                         case 4:
785                                 length = u_endian_read4(&ptfunxored[j+5], false);
786                                 break;
787                         case 3:
788                                 length = u_endian_read3(&ptfunxored[j+5], false);
789                                 break;
790                         case 2:
791                                 length = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
792                                 break;
793                         case 1:
794                                 length = (uint32_t)(ptfunxored[j+5]);
795                                 break;
796                         default:
797                                 break;
798                         }
799                         j+=lengthbytes;
800                         uint32_t sampleoffset = 0;
801                         switch (offsetbytes) {
802                         case 4:
803                                 sampleoffset = u_endian_read4(&ptfunxored[j+5], false); 
804                                 break;
805                         case 3:
806                                 sampleoffset = u_endian_read3(&ptfunxored[j+5], false); 
807                                 break;
808                         case 2:
809                                 sampleoffset = (uint32_t)u_endian_read2(&ptfunxored[j+5], false); 
810                                 break;
811                         case 1:
812                                 sampleoffset = (uint32_t)(ptfunxored[j+5]);
813                                 break;
814                         default:
815                                 break;
816                         }
817                         j+=offsetbytes;
818
819                         track_t tr;
820                         tr.name = name;
821
822                         region_t r;
823                         r.index = rindex;
824
825                         vector<region_t>::iterator begin = regions.begin();
826                         vector<region_t>::iterator finish = regions.end();
827                         vector<region_t>::iterator found;
828                         if ((found = std::find(begin, finish, r)) != finish) {
829                                 tr.reg = (*found);
830                         }
831
832                         tr.reg.startpos = (int64_t)(start*ratefactor);
833                         tr.reg.sampleoffset = (int64_t)(sampleoffset*ratefactor);
834                         tr.reg.length = (int64_t)(length*ratefactor);
835                         vector<track_t>::iterator ti;
836                         vector<track_t>::iterator bt = tracks.begin();
837                         vector<track_t>::iterator et = tracks.end();
838                         if ((ti = std::find(bt, et, tr)) != et) {
839                                 tracknumber = (*ti).index;
840                         } else {
841                                 ++tracknumber;
842                         }
843                         track_t t = {
844                                 name,
845                                 (uint16_t)tracknumber,
846                                 uint8_t(0),
847                                 tr.reg
848                         };
849                         //if (tr.reg.length > 0) {
850                                 tracks.push_back(t);
851                         //}
852                         k++;
853                 }
854                 k++;
855         }
856 }
857
858 void
859 PTFFormat::resort(std::vector<wav_t>& ws) {
860         int j = 0;
861         std::sort(ws.begin(), ws.end());
862         for (std::vector<wav_t>::iterator i = ws.begin(); i != ws.end(); ++i) {
863                 (*i).index = j;
864                 j++;
865         }
866 }
867
868 void
869 PTFFormat::resort(std::vector<region_t>& rs) {
870         int j = 0;
871         //std::sort(rs.begin(), rs.end());
872         for (std::vector<region_t>::iterator i = rs.begin(); i != rs.end(); ++i) {
873                 (*i).index = j;
874                 j++;
875         }
876 }
877
878 void
879 PTFFormat::filter(std::vector<region_t>& rs) {
880         for (std::vector<region_t>::iterator i = rs.begin(); i != rs.end(); ++i) {
881                 if (i->length == 0)
882                         rs.erase(i);
883         }
884 }
885
886 void
887 PTFFormat::parseaudio5(void) {
888         uint32_t i,k,l;
889         uint64_t lengthofname, wavnumber;
890         uint32_t numberofwavs;
891         unsigned char tag6_LE[3], tag5_BE[3];
892         unsigned char tag2_LE[3], tag2_BE[3];
893
894         // Find start of wav file list
895         k = 0;
896         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff", 4))
897                 return;
898         numberofwavs = u_endian_read4(&ptfunxored[k-18], is_bigendian);
899
900         // Find actual wav names
901         char wavname[256];
902         i = k;
903         jumpto(&i, ptfunxored, len, (const unsigned char *)"Files", 5);
904
905         wavnumber = 0;
906         i+=16;
907         char ext[5];
908         while (i < len && numberofwavs > 0) {
909                 i++;
910                 if (            ((ptfunxored[i  ] == 0x5a) &&
911                                 (ptfunxored[i+1] == 0x00) &&
912                                 (ptfunxored[i+2] == 0x05)) ||
913                                 ((ptfunxored[i  ] == 0x5a) &&
914                                 (ptfunxored[i+1] == 0x06))) {
915                         break;
916                 }
917                 lengthofname = u_endian_read4(&ptfunxored[i-3], is_bigendian);
918                 i++;
919                 l = 0;
920                 while (l < lengthofname) {
921                         wavname[l] = ptfunxored[i+l];
922                         l++;
923                 }
924                 i+=lengthofname;
925                 ext[0] = ptfunxored[i++];
926                 ext[1] = ptfunxored[i++];
927                 ext[2] = ptfunxored[i++];
928                 ext[3] = ptfunxored[i++];
929                 ext[4] = '\0';
930
931                 wavname[l] = 0;
932                 if (foundin(wavname, ".L") || foundin(wavname, ".R")) {
933                         extension = string("");
934                 } else if (foundin(wavname, ".wav") || foundin(ext, "WAVE")) {
935                         extension = string(".wav");
936                 } else if (foundin(wavname, ".aif") || foundin(ext, "AIFF")) {
937                         extension = string(".aif");
938                 } else {
939                         extension = string("");
940                 }
941
942                 std::string wave = string(wavname);
943
944                 if (foundin(wave, string(".grp"))) {
945                         continue;
946                 }
947                 if (foundin(wave, string("Fade Files"))) {
948                         i += 7;
949                         continue;
950                 }
951
952                 wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
953
954                 actualwavs.push_back(f);
955                 audiofiles.push_back(f);
956                 //printf("done\n");
957                 numberofwavs--;
958                 i += 7;
959         }
960
961         i -= 7;
962
963         tag5_BE[0] = tag6_LE[0] = tag2_BE[0] = tag2_LE[0] = '\x5a';
964         tag5_BE[1] = '\x00';
965         tag6_LE[1] = '\x06';
966         tag2_BE[1] = '\x00';
967         tag2_LE[1] = '\x02';
968         tag5_BE[2] = '\x05';
969         tag6_LE[2] = '\x00';
970         tag2_BE[2] = '\x02';
971         tag2_LE[2] = '\x00';
972
973         // Loop through all the sources
974         for (vector<wav_t>::iterator w = audiofiles.begin(); w != audiofiles.end(); ++w) {
975                 // Jump to start of source metadata for this source
976                 if (is_bigendian) {
977                         if (!jumpto(&i, ptfunxored, len, tag5_BE, 3))
978                                 return;
979                         if (!jumpto(&i, ptfunxored, len, tag2_BE, 3))
980                                 return;
981                         w->length = u_endian_read4(&ptfunxored[i+19], true);
982                 } else {
983                         if (!jumpto(&i, ptfunxored, len, tag6_LE, 3))
984                                 return;
985                         if (!jumpto(&i, ptfunxored, len, tag2_LE, 3))
986                                 return;
987                         w->length = u_endian_read4(&ptfunxored[i+15], false);
988                 }
989         }
990         upto = i;
991 }
992
993 struct mchunk {
994         mchunk (uint64_t zt, uint64_t ml, std::vector<PTFFormat::midi_ev_t> const& c)
995         : zero (zt)
996         , maxlen (ml)
997         , chunk (c)
998         {}
999         uint64_t zero;
1000         uint64_t maxlen;
1001         std::vector<PTFFormat::midi_ev_t> chunk;
1002 };
1003
1004 void
1005 PTFFormat::parsemidi(void) {
1006         uint32_t i, k;
1007         uint64_t tr, n_midi_events, zero_ticks;
1008         uint64_t midi_pos, midi_len, max_pos, region_pos;
1009         uint8_t midi_velocity, midi_note;
1010         uint16_t ridx;
1011         uint16_t nmiditracks, regionnumber = 0;
1012         uint32_t nregions, mr;
1013
1014         std::vector<mchunk> midichunks;
1015         midi_ev_t m;
1016
1017         // Find MdNLB
1018         k = 0;
1019
1020         // Parse all midi chunks, not 1:1 mapping to regions yet
1021         while (k + 35 < len) {
1022                 max_pos = 0;
1023                 std::vector<midi_ev_t> midi;
1024
1025                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"MdNLB", 5)) {
1026                         break;
1027                 }
1028                 k += 11;
1029                 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
1030                                 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
1031
1032                 k += 4;
1033                 zero_ticks = u_endian_read5(&ptfunxored[k], is_bigendian);
1034                 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
1035                         midi_pos = u_endian_read5(&ptfunxored[k], is_bigendian);
1036                         midi_pos -= zero_ticks;
1037                         midi_note = ptfunxored[k+8];
1038                         midi_len = u_endian_read5(&ptfunxored[k+9], is_bigendian);
1039                         midi_velocity = ptfunxored[k+17];
1040
1041                         if (midi_pos + midi_len > max_pos) {
1042                                 max_pos = midi_pos + midi_len;
1043                         }
1044
1045                         m.pos = midi_pos;
1046                         m.length = midi_len;
1047                         m.note = midi_note;
1048                         m.velocity = midi_velocity;
1049 #if 1
1050 // stop gap measure to prevent crashes in ardour,
1051 // remove when decryption is fully solved for .ptx
1052                         if ((m.velocity & 0x80) || (m.note & 0x80) ||
1053                                         (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
1054                                 continue;
1055                         }
1056 #endif
1057                         midi.push_back(m);
1058                 }
1059                 midichunks.push_back(mchunk (zero_ticks, max_pos, midi));
1060         }
1061
1062         // Map midi chunks to regions
1063         while (k < len) {
1064                 char midiregionname[256];
1065                 uint8_t namelen;
1066
1067                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"MdTEL", 5)) {
1068                         break;
1069                 }
1070
1071                 k += 41;
1072
1073                 nregions = u_endian_read2(&ptfunxored[k], is_bigendian);
1074
1075                 for (mr = 0; mr < nregions; mr++) {
1076                         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x0c", 2)) {
1077                                 break;
1078                         }
1079
1080                         k += 9;
1081
1082                         namelen = ptfunxored[k];
1083                         for (i = 0; i < namelen; i++) {
1084                                 midiregionname[i] = ptfunxored[k+4+i];
1085                         }
1086                         midiregionname[namelen] = '\0';
1087                         k += 4 + namelen;
1088
1089                         k += 5;
1090                         /*
1091                         region_pos = (uint64_t)ptfunxored[k] |
1092                                         (uint64_t)ptfunxored[k+1] << 8 |
1093                                         (uint64_t)ptfunxored[k+2] << 16 |
1094                                         (uint64_t)ptfunxored[k+3] << 24 |
1095                                         (uint64_t)ptfunxored[k+4] << 32;
1096                         */
1097                         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xfe\xff\xff\xff", 4)) {
1098                                 break;
1099                         }
1100
1101                         k += 40;
1102
1103                         ridx = ptfunxored[k];
1104                         ridx |= ptfunxored[k+1] << 8;
1105
1106                         struct mchunk mc = *(midichunks.begin()+ridx);
1107
1108                         wav_t w = { std::string(""), 0, 0, 0 };
1109                         region_t r = {
1110                                 midiregionname,
1111                                 regionnumber++,
1112                                 //(int64_t)mc.zero,
1113                                 (int64_t)0xe8d4a51000ULL,
1114                                 (int64_t)(0),
1115                                 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
1116                                 (int64_t)mc.maxlen,
1117                                 w,
1118                                 mc.chunk,
1119                         };
1120                         midiregions.push_back(r);
1121                 }
1122         }
1123
1124         // Put midi regions on midi tracks
1125         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2)) {
1126                 return;
1127         }
1128
1129         nmiditracks = u_endian_read2(&ptfunxored[k-4], is_bigendian);
1130
1131         for (tr = 0; tr < nmiditracks; tr++) {
1132                 char miditrackname[256];
1133                 uint8_t namelen;
1134                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2)) {
1135                         return;
1136                 }
1137
1138                 namelen = ptfunxored[k+9];
1139                 for (i = 0; i < namelen; i++) {
1140                         miditrackname[i] = ptfunxored[k+13+i];
1141                 }
1142                 miditrackname[namelen] = '\0';
1143                 k += 13 + namelen;
1144                 nregions = u_endian_read2(&ptfunxored[k], is_bigendian);
1145
1146                 for (i = 0; (i < nregions) && (k < len); i++) {
1147                         k += 24;
1148
1149                         ridx = u_endian_read2(&ptfunxored[k], is_bigendian);
1150
1151                         k += 5;
1152
1153                         region_pos = u_endian_read5(&ptfunxored[k], is_bigendian);
1154
1155                         k += 20;
1156
1157                         track_t mtr;
1158                         mtr.name = string(miditrackname);
1159                         mtr.index = tr;
1160                         mtr.playlist = 0;
1161                         // Find the midi region with index 'ridx'
1162                         std::vector<region_t>::iterator begin = midiregions.begin();
1163                         std::vector<region_t>::iterator finish = midiregions.end();
1164                         std::vector<region_t>::iterator mregion;
1165                         wav_t w = { std::string(""), 0, 0, 0 };
1166                         std::vector<midi_ev_t> m;
1167                         region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
1168                         if ((mregion = std::find(begin, finish, r)) != finish) {
1169                                 mtr.reg = *mregion;
1170                                 mtr.reg.startpos = labs(region_pos - mtr.reg.startpos);
1171                                 miditracks.push_back(mtr);
1172                         }
1173                 }
1174         }
1175 }
1176
1177 void
1178 PTFFormat::parsemidi12(void) {
1179         uint32_t i, k;
1180         uint64_t tr, n_midi_events, zero_ticks;
1181         uint64_t midi_pos, midi_len, max_pos, region_pos;
1182         uint8_t midi_velocity, midi_note;
1183         uint16_t ridx;
1184         uint16_t nmiditracks, regionnumber = 0;
1185         uint32_t nregions, mr;
1186
1187         std::vector<mchunk> midichunks;
1188         midi_ev_t m;
1189
1190         k = 0;
1191
1192         // Parse all midi chunks, not 1:1 mapping to regions yet
1193         while (k + 35 < len) {
1194                 max_pos = 0;
1195                 std::vector<midi_ev_t> midi;
1196
1197                 // Find MdNLB
1198                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"MdNLB", 5)) {
1199                         break;
1200                 }
1201
1202                 k += 11;
1203                 n_midi_events = u_endian_read4(&ptfunxored[k], is_bigendian);
1204
1205                 k += 4;
1206                 zero_ticks = u_endian_read5(&ptfunxored[k], is_bigendian);
1207                 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
1208                         midi_pos = u_endian_read5(&ptfunxored[k], is_bigendian);
1209                         midi_pos -= zero_ticks;
1210                         midi_note = ptfunxored[k+8];
1211                         midi_len = u_endian_read5(&ptfunxored[k+9], is_bigendian);
1212                         midi_velocity = ptfunxored[k+17];
1213
1214                         if (midi_pos + midi_len > max_pos) {
1215                                 max_pos = midi_pos + midi_len;
1216                         }
1217
1218                         m.pos = midi_pos;
1219                         m.length = midi_len;
1220                         m.note = midi_note;
1221                         m.velocity = midi_velocity;
1222 #if 1
1223 // stop gap measure to prevent crashes in ardour,
1224 // remove when decryption is fully solved for .ptx
1225                         if ((m.velocity & 0x80) || (m.note & 0x80) ||
1226                                         (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
1227                                 continue;
1228                         }
1229 #endif
1230                         midi.push_back(m);
1231                 }
1232                 midichunks.push_back(mchunk (zero_ticks, max_pos, midi));
1233         }
1234
1235         // Map midi chunks to regions
1236         while (k < len) {
1237                 char midiregionname[256];
1238                 uint8_t namelen;
1239
1240                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"MdTEL", 5)) {
1241                         break;
1242                 }
1243
1244                 k += 41;
1245
1246                 nregions = u_endian_read2(&ptfunxored[k], is_bigendian);
1247
1248                 for (mr = 0; mr < nregions; mr++) {
1249                         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x01", 2)) {
1250                                 break;
1251                         }
1252                         k += 18;
1253
1254                         namelen = ptfunxored[k];
1255                         for (i = 0; i < namelen; i++) {
1256                                 midiregionname[i] = ptfunxored[k+4+i];
1257                         }
1258                         midiregionname[namelen] = '\0';
1259                         k += 4 + namelen;
1260
1261                         k += 5;
1262                         /*
1263                         region_pos = (uint64_t)ptfunxored[k] |
1264                                         (uint64_t)ptfunxored[k+1] << 8 |
1265                                         (uint64_t)ptfunxored[k+2] << 16 |
1266                                         (uint64_t)ptfunxored[k+3] << 24 |
1267                                         (uint64_t)ptfunxored[k+4] << 32;
1268                         */
1269                         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xfe\xff\x00\x00", 4)) {
1270                                 break;
1271                         }
1272
1273                         k += 37;
1274
1275                         ridx = u_endian_read2(&ptfunxored[k], is_bigendian);
1276
1277                         k += 3;
1278                         struct mchunk mc = *(midichunks.begin()+ridx);
1279
1280                         wav_t w = { std::string(""), 0, 0, 0 };
1281                         region_t r = {
1282                                 midiregionname,
1283                                 regionnumber++,
1284                                 //(int64_t)mc.zero,
1285                                 (int64_t)0xe8d4a51000ULL,
1286                                 (int64_t)(0),
1287                                 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
1288                                 (int64_t)mc.maxlen,
1289                                 w,
1290                                 mc.chunk,
1291                         };
1292                         midiregions.push_back(r);
1293                 }
1294         }
1295
1296         // Put midi regions on midi tracks
1297         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2)) {
1298                 return;
1299         }
1300
1301         nmiditracks = u_endian_read2(&ptfunxored[k-4], is_bigendian);
1302
1303         for (tr = 0; tr < nmiditracks; tr++) {
1304                 char miditrackname[256];
1305                 uint8_t namelen;
1306                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2)) {
1307                         return;
1308                 }
1309
1310                 namelen = ptfunxored[k+9];
1311                 for (i = 0; i < namelen; i++) {
1312                         miditrackname[i] = ptfunxored[k+13+i];
1313                 }
1314                 miditrackname[namelen] = '\0';
1315                 k += 13 + namelen;
1316                 nregions = u_endian_read2(&ptfunxored[k], is_bigendian);
1317
1318                 k += 13;
1319
1320                 for (i = 0; (i < nregions) && (k < len); i++) {
1321                         while (k < len) {
1322                                 if (            (ptfunxored[k] == 0x5a) &&
1323                                                 (ptfunxored[k+1] & 0x08)) {
1324                                         break;
1325                                 }
1326                                 k++;
1327                         }
1328                         k += 11;
1329
1330                         ridx = u_endian_read2(&ptfunxored[k], is_bigendian);
1331
1332                         k += 5;
1333
1334                         region_pos = u_endian_read5(&ptfunxored[k], is_bigendian);
1335
1336                         track_t mtr;
1337                         mtr.name = string(miditrackname);
1338                         mtr.index = tr;
1339                         mtr.playlist = 0;
1340                         // Find the midi region with index 'ridx'
1341                         std::vector<region_t>::iterator begin = midiregions.begin();
1342                         std::vector<region_t>::iterator finish = midiregions.end();
1343                         std::vector<region_t>::iterator mregion;
1344                         wav_t w = { std::string(""), 0, 0, 0 };
1345                         std::vector<midi_ev_t> m;
1346                         region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
1347                         if ((mregion = std::find(begin, finish, r)) != finish) {
1348                                 mtr.reg = *mregion;
1349                                 mtr.reg.startpos = labs(region_pos - mtr.reg.startpos);
1350                                 miditracks.push_back(mtr);
1351                         }
1352                         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff\xff\xff\xff\xff", 8)) {
1353                                 return;
1354                         }
1355                 }
1356         }
1357 }
1358
1359 void
1360 PTFFormat::parseaudio(void) {
1361         uint32_t i,j,k,l;
1362         std::string wave;
1363
1364         k = 0;
1365         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"Audio Files", 11))
1366                 return;
1367
1368         // Find end of wav file list
1369         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff", 4))
1370                 return;
1371
1372         // Find number of wave files
1373         uint16_t numberofwavs;
1374         j = k;
1375         if (!jumpback(&j, ptfunxored, len, (const unsigned char *)"\x5a\x01", 2))
1376                 return;
1377
1378         numberofwavs = u_endian_read4(&ptfunxored[j-4], is_bigendian);
1379         //printf("%d wavs\n", numberofwavs);
1380
1381         // Find actual wav names
1382         char wavname[256];
1383         j = k - 2;
1384         for (i = 0; i < numberofwavs; i++) {
1385                 while (j > 0) {
1386                         if (    ((ptfunxored[j  ] == 'W') || (ptfunxored[j  ] == 'A') || ptfunxored[j  ] == '\0') &&
1387                                 ((ptfunxored[j-1] == 'A') || (ptfunxored[j-1] == 'I') || ptfunxored[j-1] == '\0') &&
1388                                 ((ptfunxored[j-2] == 'V') || (ptfunxored[j-2] == 'F') || ptfunxored[j-2] == '\0')) {
1389                                 break;
1390                         }
1391                         j--;
1392                 }
1393                 j -= 4;
1394                 l = 0;
1395                 while (ptfunxored[j] != '\0') {
1396                         wavname[l] = ptfunxored[j];
1397                         l++;
1398                         j--;
1399                 }
1400                 wavname[l] = '\0';
1401
1402                 // Must be at least "vaw.z\0"
1403                 if (l < 6) {
1404                         i--;
1405                         continue;
1406                 }
1407
1408                 // and skip "zWAVE" or "zAIFF"
1409                 if (    (       (wavname[1] == 'W') &&
1410                                 (wavname[2] == 'A') &&
1411                                 (wavname[3] == 'V') &&
1412                                 (wavname[4] == 'E')) ||
1413                         (       (wavname[1] == 'A') &&
1414                                 (wavname[2] == 'I') &&
1415                                 (wavname[3] == 'F') &&
1416                                 (wavname[4] == 'F'))) {
1417                         wave = string(&wavname[5]);
1418                 } else {
1419                         wave = string(wavname);
1420                 }
1421                 //uint8_t playlist = ptfunxored[j-8];
1422
1423                 std::reverse(wave.begin(), wave.end());
1424                 wav_t f = { wave, (uint16_t)(numberofwavs - i - 1), 0, 0 };
1425
1426                 if (foundin(wave, string("Audio Files")) ||
1427                                 foundin(wave, string("Fade Files"))) {
1428                         i--;
1429                         continue;
1430                 }
1431
1432                 actualwavs.push_back(f);
1433                 audiofiles.push_back(f);
1434
1435                 //printf(" %d:%s \n", numberofwavs - i - 1, wave.c_str());
1436         }
1437         std::reverse(audiofiles.begin(), audiofiles.end());
1438         std::reverse(actualwavs.begin(), actualwavs.end());
1439         //resort(audiofiles);
1440         //resort(actualwavs);
1441
1442         // Jump to end of wav file list
1443         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff", 4))
1444                 return;
1445
1446         // Loop through all the sources
1447         for (vector<wav_t>::iterator w = audiofiles.begin(); w != audiofiles.end(); ++w) {
1448                 // Jump to start of source metadata for this source
1449                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x07", 2))
1450                         return;
1451                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2))
1452                         return;
1453                 k++;
1454                 if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2))
1455                         return;
1456
1457                 w->length = u_endian_read4(&ptfunxored[k-25], false);
1458         }
1459 }
1460
1461 void
1462 PTFFormat::parserest89(void) {
1463         uint32_t i,j,k;
1464         uint8_t startbytes = 0;
1465         uint8_t lengthbytes = 0;
1466         uint8_t offsetbytes = 0;
1467         uint8_t somethingbytes = 0;
1468         uint8_t skipbytes = 0;
1469
1470         // Find Regions
1471         k = 0;
1472         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"Snap", 4)) {
1473                 return;
1474         }
1475
1476         uint16_t rindex = 0;
1477         uint32_t findex = 0;
1478         for (i = k; i < len-70; i++) {
1479                 if (            (ptfunxored[i  ] == 0x5a) &&
1480                                 (ptfunxored[i+1] == 0x0a)) {
1481                                 break;
1482                 }
1483                 if (            (ptfunxored[i  ] == 0x5a) &&
1484                                 (ptfunxored[i+1] == 0x0c)) {
1485
1486                         uint8_t lengthofname = ptfunxored[i+9];
1487
1488                         char name[256] = {0};
1489                         for (j = 0; j < lengthofname; j++) {
1490                                 name[j] = ptfunxored[i+13+j];
1491                         }
1492                         name[j] = '\0';
1493                         j += i+13;
1494                         //uint8_t disabled = ptfunxored[j];
1495
1496                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1497                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1498                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1499                         somethingbytes = (ptfunxored[j+3] & 0xf);
1500                         skipbytes = ptfunxored[j+4];
1501                         findex = ptfunxored[j+5
1502                                         +startbytes
1503                                         +lengthbytes
1504                                         +offsetbytes
1505                                         +somethingbytes
1506                                         +skipbytes
1507                                         +40];
1508                         /*rindex = ptfunxored[j+5
1509                                         +startbytes
1510                                         +lengthbytes
1511                                         +offsetbytes
1512                                         +somethingbytes
1513                                         +skipbytes
1514                                         +24];
1515                         */
1516                         uint32_t sampleoffset = 0;
1517                         switch (offsetbytes) {
1518                         case 4:
1519                                 sampleoffset = u_endian_read4(&ptfunxored[j+5], false);
1520                                 break;
1521                         case 3:
1522                                 sampleoffset = u_endian_read3(&ptfunxored[j+5], false);
1523                                 break;
1524                         case 2:
1525                                 sampleoffset = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
1526                                 break;
1527                         case 1:
1528                                 sampleoffset = (uint32_t)(ptfunxored[j+5]);
1529                                 break;
1530                         default:
1531                                 break;
1532                         }
1533                         j+=offsetbytes;
1534                         uint32_t length = 0;
1535                         switch (lengthbytes) {
1536                         case 4:
1537                                 length = u_endian_read4(&ptfunxored[j+5], false);
1538                                 break;
1539                         case 3:
1540                                 length = u_endian_read3(&ptfunxored[j+5], false);
1541                                 break;
1542                         case 2:
1543                                 length = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
1544                                 break;
1545                         case 1:
1546                                 length = (uint32_t)(ptfunxored[j+5]);
1547                                 break;
1548                         default:
1549                                 break;
1550                         }
1551                         j+=lengthbytes;
1552                         uint32_t start = 0;
1553                         switch (startbytes) {
1554                         case 4:
1555                                 start = u_endian_read4(&ptfunxored[j+5], false);
1556                                 break;
1557                         case 3:
1558                                 start = u_endian_read3(&ptfunxored[j+5], false);
1559                                 break;
1560                         case 2:
1561                                 start = (uint32_t)u_endian_read2(&ptfunxored[j+5], false);
1562                                 break;
1563                         case 1:
1564                                 start = (uint32_t)(ptfunxored[j+5]);
1565                                 break;
1566                         default:
1567                                 break;
1568                         }
1569                         j+=startbytes;
1570                         /*
1571                         uint32_t something = 0;
1572                         switch (somethingbytes) {
1573                         case 4:
1574                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1575                         case 3:
1576                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1577                         case 2:
1578                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1579                         case 1:
1580                                 something |= (uint32_t)(ptfunxored[j+5]);
1581                         default:
1582                                 break;
1583                         }
1584                         j+=somethingbytes;
1585                         */
1586                         std::string filename = string(name);
1587                         wav_t f = {
1588                                 filename,
1589                                 (uint16_t)findex,
1590                                 (int64_t)(start*ratefactor),
1591                                 (int64_t)(length*ratefactor),
1592                         };
1593
1594                         //printf("something=%d\n", something);
1595
1596                         vector<wav_t>::iterator begin = actualwavs.begin();
1597                         vector<wav_t>::iterator finish = actualwavs.end();
1598                         vector<wav_t>::iterator found;
1599                         // Add file to list only if it is an actual wav
1600                         if ((found = std::find(begin, finish, f)) != finish) {
1601                                 f.filename = (*found).filename;
1602                                 // Also add plain wav as region
1603                                 std::vector<midi_ev_t> m;
1604                                 region_t r = {
1605                                         name,
1606                                         rindex,
1607                                         (int64_t)(start*ratefactor),
1608                                         (int64_t)(sampleoffset*ratefactor),
1609                                         (int64_t)(length*ratefactor),
1610                                         f,
1611                                         m
1612                                 };
1613                                 regions.push_back(r);
1614                         // Region only
1615                         } else {
1616                                 if (foundin(filename, string(".grp"))) {
1617                                         continue;
1618                                 }
1619                                 std::vector<midi_ev_t> m;
1620                                 region_t r = {
1621                                         name,
1622                                         rindex,
1623                                         (int64_t)(start*ratefactor),
1624                                         (int64_t)(sampleoffset*ratefactor),
1625                                         (int64_t)(length*ratefactor),
1626                                         f,
1627                                         m
1628                                 };
1629                                 regions.push_back(r);
1630                         }
1631                         rindex++;
1632                 }
1633         }
1634
1635         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2)) {
1636                 return;
1637         }
1638         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2)) {
1639                 return;
1640         }
1641         k++;
1642
1643         //  Tracks
1644         uint32_t offset;
1645         uint32_t tracknumber = 0;
1646         uint32_t regionspertrack = 0;
1647         for (;k < len; k++) {
1648                 if (    (ptfunxored[k  ] == 0x5a) &&
1649                         (ptfunxored[k+1] == 0x04)) {
1650                         break;
1651                 }
1652                 if (    (ptfunxored[k  ] == 0x5a) &&
1653                         (ptfunxored[k+1] == 0x02)) {
1654
1655                         uint8_t lengthofname = 0;
1656                         lengthofname = ptfunxored[k+9];
1657                         if (lengthofname == 0x5a) {
1658                                 continue;
1659                         }
1660                         track_t tr;
1661
1662                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1663
1664                         //printf("regions/track=%d\n", regionspertrack);
1665                         char name[256] = {0};
1666                         for (j = 0; j < lengthofname; j++) {
1667                                 name[j] = ptfunxored[j+k+13];
1668                         }
1669                         name[j] = '\0';
1670                         tr.name = string(name);
1671                         tr.index = tracknumber++;
1672
1673                         for (j = k; regionspertrack > 0 && j < len; j++) {
1674                                 jumpto(&j, ptfunxored, len, (const unsigned char *)"\x5a\x07", 2);
1675                                 tr.reg.index = (uint16_t)(ptfunxored[j+11] & 0xff)
1676                                         | (uint16_t)((ptfunxored[j+12] << 8) & 0xff00);
1677                                 vector<region_t>::iterator begin = regions.begin();
1678                                 vector<region_t>::iterator finish = regions.end();
1679                                 vector<region_t>::iterator found;
1680                                 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1681                                         tr.reg = (*found);
1682                                 }
1683                                 i = j+16;
1684                                 offset = u_endian_read4(&ptfunxored[i], is_bigendian);
1685                                 tr.reg.startpos = (int64_t)(offset*ratefactor);
1686                                 if (tr.reg.length > 0) {
1687                                         tracks.push_back(tr);
1688                                 }
1689                                 regionspertrack--;
1690                         }
1691                 }
1692         }
1693 }
1694
1695 void
1696 PTFFormat::parserest12(void) {
1697         uint32_t i,j,k,l,m,n;
1698         uint8_t startbytes = 0;
1699         uint8_t lengthbytes = 0;
1700         uint8_t offsetbytes = 0;
1701         uint8_t somethingbytes = 0;
1702         uint8_t skipbytes = 0;
1703         uint32_t maxregions = 0;
1704         uint32_t findex = 0;
1705         uint32_t findex2 = 0;
1706         uint32_t findex3 = 0;
1707         uint16_t rindex = 0;
1708         vector<region_t> groups;
1709         uint16_t groupcount, compoundcount, groupmax;
1710         uint16_t gindex, gindex2;
1711
1712         m = 0;
1713         n = 0;
1714         vector<compound_t> groupmap;
1715         // Find region group total
1716         k = 0;
1717         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"Custom 1\0\0\x5a", 11))
1718                 goto nocustom;
1719
1720         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff", 4))
1721                 return;
1722
1723         if (!jumpback(&k, ptfunxored, len, (const unsigned char *)"\x5a", 1))
1724                 return;
1725
1726         jumpto(&k, ptfunxored, k+0x2000, (const unsigned char *)"\x5a\x03", 2);
1727         k++;
1728
1729         groupcount = 0;
1730         for (i = k; i < len; i++) {
1731                 if (!jumpto(&i, ptfunxored, len, (const unsigned char *)"\x5a\x03", 2))
1732                         break;
1733                 groupcount++;
1734         }
1735         verbose_printf("groupcount=%d\n", groupcount);
1736
1737         // Find start of group names -> group indexes
1738         k = 0;
1739         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"Custom 1\0\0\x5a", 11))
1740                 return;
1741
1742         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff", 4))
1743                 return;
1744
1745         if (!jumpback(&k, ptfunxored, len, (const unsigned char *)"\x5a", 1))
1746                 return;
1747         k++;
1748
1749         // Skip total number of groups
1750         for (i = 0; i < groupcount; i++) {
1751                 while (k < len) {
1752                         if (            (ptfunxored[k  ] == 0x5a) &&
1753                                         ((ptfunxored[k+1] == 0x03) || (ptfunxored[k+1] == 0x0a))) {
1754                                 break;
1755                         }
1756                         k++;
1757                 }
1758                 k++;
1759         }
1760
1761         while (k < len) {
1762                 if (            (ptfunxored[k  ] == 0x5a) &&
1763                                 (ptfunxored[k+1] & 0x02)) {
1764                         break;
1765                 }
1766                 k++;
1767         }
1768         k++;
1769
1770         while (k < len) {
1771                 if (            (ptfunxored[k  ] == 0x5a) &&
1772                                 (ptfunxored[k+1] & 0x02)) {
1773                         break;
1774                 }
1775                 k++;
1776         }
1777         k++;
1778
1779         verbose_printf("start of groups k=0x%x\n", k);
1780         // Loop over all groups and associate the compound index/name
1781         for (i = 0; i < groupcount; i++) {
1782                 while (k < len) {
1783                         if (            (ptfunxored[k  ] == 0x5a) &&
1784                                         (ptfunxored[k+1] & 0x02)) {
1785                                 break;
1786                         }
1787                         k++;
1788                 }
1789                 if (k > len)
1790                         break;
1791                 gindex = u_endian_read2(&ptfunxored[k+9], is_bigendian);
1792                 gindex2 = u_endian_read2(&ptfunxored[k+3], is_bigendian);
1793
1794                 uint8_t lengthofname = ptfunxored[k+13];
1795                 char name[256] = {0};
1796                 for (l = 0; l < lengthofname; l++) {
1797                         name[l] = ptfunxored[k+17+l];
1798                 }
1799                 name[l] = '\0';
1800
1801                 if (strlen(name) == 0) {
1802                         i--;
1803                         k++;
1804                         continue;
1805                 }
1806                 compound_t c = {
1807                         (uint16_t)i,    // curr_index
1808                         gindex,         // unknown1
1809                         0,              // level
1810                         0,              // ontopof_index
1811                         gindex2,        // next_index
1812                         string(name)
1813                 };
1814                 groupmap.push_back(c);
1815                 k++;
1816         }
1817
1818         // Sort lookup table by group index
1819         //std::sort(glookup.begin(), glookup.end(), regidx_compare);
1820
1821         // print compounds as flattened tree
1822         j = 0;
1823         for (std::vector<compound_t>::iterator i = groupmap.begin(); i != groupmap.end(); ++i) {
1824                 verbose_printf("g(%u) uk(%u) ni(%u) %s\n", i->curr_index, i->unknown1, i->next_index, i->name.c_str());
1825                 j++;
1826         }
1827
1828 nocustom:
1829         // Find region groups
1830         k = 0;
1831         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"Snap", 4))
1832                 return;
1833
1834         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\x5a\x06", 2))
1835                 return;
1836         k++;
1837
1838         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
1839                 return;
1840         k++;
1841
1842         if (!jumpto(&k, ptfunxored, len, (const unsigned char *)"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
1843                 return;
1844         k++;
1845
1846         // Hack to find actual start of region group information
1847         while (k < len) {
1848                 if ((ptfunxored[k+13] == 0x5a) && (ptfunxored[k+14] & 0xf)) {
1849                         k += 13;
1850                         continue;
1851                 } else {
1852                         if ((ptfunxored[k+9] == 0x5a) && (ptfunxored[k+10] & 0xf)) {
1853                                 k += 9;
1854                                 continue;
1855                         }
1856                 }
1857                 if ((ptfunxored[k] == 0x5a) && (ptfunxored[k+1] & 0xf))
1858                         break;
1859                 k++;
1860         }
1861         verbose_printf("hack region groups k=0x%x\n", k);
1862
1863         compoundcount = 0;
1864         j = k;
1865         groupmax = groupcount == 0 ? 0 : u_endian_read2(&ptfunxored[j+3], is_bigendian);
1866         groupcount = 0;
1867         for (i = k; (groupcount < groupmax) && (i < len-70); i++) {
1868                 if (            (ptfunxored[i  ] == 0x5a) &&
1869                                 (ptfunxored[i+1] == 0x03)) {
1870                                 break;
1871                 }
1872                 if (            (ptfunxored[i  ] == 0x5a) &&
1873                                 ((ptfunxored[i+1] == 0x01) || (ptfunxored[i+1] == 0x02))) {
1874
1875                         //findex = ptfunxored[i-48] | ptfunxored[i-47] << 8;
1876                         //rindex = ptfunxored[i+3] | ptfunxored[i+4] << 8;
1877
1878                         uint8_t lengthofname = ptfunxored[i+9];
1879                         if (ptfunxored[i+13] == 0x5a) {
1880                                 continue;
1881                         }
1882                         char name[256] = {0};
1883                         for (j = 0; j < lengthofname; j++) {
1884                                 name[j] = ptfunxored[i+13+j];
1885                         }
1886                         name[j] = '\0';
1887                         j += i+13;
1888
1889                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1890                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1891                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1892                         somethingbytes = (ptfunxored[j+3] & 0xf);
1893                         skipbytes = ptfunxored[j+4];
1894                         uint16_t regionsingroup = ptfunxored[j+5
1895                                         +startbytes
1896                                         +lengthbytes
1897                                         +offsetbytes
1898                                         +somethingbytes
1899                                         +skipbytes
1900                                         +12]
1901                                 | ptfunxored[j+5
1902                                         +startbytes
1903                                         +lengthbytes
1904                                         +offsetbytes
1905                                         +somethingbytes
1906                                         +skipbytes
1907                                         +13] << 8;
1908
1909                         findex = ptfunxored[j+5
1910                                         +startbytes
1911                                         +lengthbytes
1912                                         +offsetbytes
1913                                         +somethingbytes
1914                                         +skipbytes
1915                                         +37]
1916                                 | ptfunxored[j+5
1917                                         +startbytes
1918                                         +lengthbytes
1919                                         +offsetbytes
1920                                         +somethingbytes
1921                                         +skipbytes
1922                                         +38] << 8;
1923
1924                         uint64_t sampleoffset = 0;
1925                         switch (offsetbytes) {
1926                         case 5:
1927                                 sampleoffset = u_endian_read5(&ptfunxored[j+5], false);
1928                                 break;
1929                         case 4:
1930                                 sampleoffset = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
1931                                 break;
1932                         case 3:
1933                                 sampleoffset = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
1934                                 break;
1935                         case 2:
1936                                 sampleoffset = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
1937                                 break;
1938                         case 1:
1939                                 sampleoffset = (uint64_t)(ptfunxored[j+5]);
1940                                 break;
1941                         default:
1942                                 break;
1943                         }
1944                         j+=offsetbytes;
1945                         uint64_t length = 0;
1946                         switch (lengthbytes) {
1947                         case 5:
1948                                 length = u_endian_read5(&ptfunxored[j+5], false);
1949                                 break;
1950                         case 4:
1951                                 length = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
1952                                 break;
1953                         case 3:
1954                                 length = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
1955                                 break;
1956                         case 2:
1957                                 length = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
1958                                 break;
1959                         case 1:
1960                                 length = (uint64_t)(ptfunxored[j+5]);
1961                                 break;
1962                         default:
1963                                 break;
1964                         }
1965                         j+=lengthbytes;
1966                         uint64_t start = 0;
1967                         switch (startbytes) {
1968                         case 5:
1969                                 start = u_endian_read5(&ptfunxored[j+5], false);
1970                                 break;
1971                         case 4:
1972                                 start = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
1973                                 break;
1974                         case 3:
1975                                 start = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
1976                                 break;
1977                         case 2:
1978                                 start = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
1979                                 break;
1980                         case 1:
1981                                 start = (uint64_t)(ptfunxored[j+5]);
1982                                 break;
1983                         default:
1984                                 break;
1985                         }
1986                         j+=startbytes;
1987
1988                         if (offsetbytes == 5)
1989                                 sampleoffset -= 1000000000000ULL;
1990                         if (startbytes == 5)
1991                                 start -= 1000000000000ULL;
1992
1993                         std::string filename = string(name);
1994                         wav_t f = {
1995                                 filename,
1996                                 (uint16_t)findex,
1997                                 (int64_t)(start*ratefactor),
1998                                 (int64_t)(length*ratefactor),
1999                         };
2000
2001                         if (strlen(name) == 0) {
2002                                 continue;
2003                         }
2004                         if (length == 0) {
2005                                 continue;
2006                         }
2007                         //if (foundin(filename, string(".grp")) && !regionsingroup && !findex) {
2008                         //      // Empty region group
2009                         //      verbose_printf("        EMPTY: %s\n", name);
2010                         //      continue;
2011                         if (regionsingroup) {
2012                                 // Active region grouping
2013                                 // Iterate parsing all the regions in the group
2014                                 verbose_printf("\nGROUP\t%d %s\n", groupcount, name);
2015                                 m = j;
2016                                 n = j+16;
2017
2018                                 for (l = 0; l < regionsingroup; l++) {
2019                                         if (!jumpto(&n, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2)) {
2020                                                 return;
2021                                         }
2022                                         n++;
2023                                 }
2024                                 n--;
2025                                 //printf("n=0x%x\n", n+112);
2026                                 //findex = ptfunxored[n+112] | (ptfunxored[n+113] << 8);
2027                                 findex = u_endian_read2(&ptfunxored[i-11], is_bigendian);
2028                                 findex2 = u_endian_read2(&ptfunxored[n+108], is_bigendian);
2029                                 //findex2= rindex; //XXX
2030                                 // Find wav with correct findex
2031                                 vector<wav_t>::iterator wave = actualwavs.end();
2032                                 for (vector<wav_t>::iterator aw = actualwavs.begin();
2033                                                 aw != actualwavs.end(); ++aw) {
2034                                         if (aw->index == findex) {
2035                                                 wave = aw;
2036                                         }
2037                                 }
2038                                 if (wave == actualwavs.end())
2039                                         return;
2040
2041                                 if (!jumpto(&n, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2))
2042                                         return;
2043                                 n += 37;
2044                                 //rindex = ptfunxored[n] | (ptfunxored[n+1] << 8);
2045                                 for (l = 0; l < regionsingroup; l++) {
2046                                         if (!jumpto(&m, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2))
2047                                                 return;
2048
2049                                         m += 37;
2050                                         rindex = u_endian_read2(&ptfunxored[m], is_bigendian);
2051
2052                                         m += 12;
2053                                         sampleoffset = 0;
2054                                         switch (offsetbytes) {
2055                                         case 5:
2056                                                 sampleoffset = u_endian_read5(&ptfunxored[m], false);
2057                                                 break;
2058                                         case 4:
2059                                                 sampleoffset = (uint64_t)u_endian_read4(&ptfunxored[m], false);
2060                                                 break;
2061                                         case 3:
2062                                                 sampleoffset = (uint64_t)u_endian_read3(&ptfunxored[m], false);
2063                                                 break;
2064                                         case 2:
2065                                                 sampleoffset = (uint64_t)u_endian_read2(&ptfunxored[m], false);
2066                                                 break;
2067                                         case 1:
2068                                                 sampleoffset = (uint64_t)(ptfunxored[m]);
2069                                                 break;
2070                                         default:
2071                                                 break;
2072                                         }
2073                                         m+=offsetbytes+3;
2074                                         start = 0;
2075                                         switch (offsetbytes) {
2076                                         case 5:
2077                                                 start = u_endian_read5(&ptfunxored[m], false);
2078                                                 break;
2079                                         case 4:
2080                                                 start = (uint64_t)u_endian_read4(&ptfunxored[m], false);
2081                                                 break;
2082                                         case 3:
2083                                                 start = (uint64_t)u_endian_read3(&ptfunxored[m], false);
2084                                                 break;
2085                                         case 2:
2086                                                 start = (uint64_t)u_endian_read2(&ptfunxored[m], false);
2087                                                 break;
2088                                         case 1:
2089                                                 start = (uint64_t)(ptfunxored[m]);
2090                                                 break;
2091                                         default:
2092                                                 break;
2093                                         }
2094                                         m+=offsetbytes+3;
2095                                         length = 0;
2096                                         switch (lengthbytes) {
2097                                         case 5:
2098                                                 length = u_endian_read5(&ptfunxored[m], false);
2099                                                 break;
2100                                         case 4:
2101                                                 length = (uint64_t)u_endian_read4(&ptfunxored[m], false);
2102                                                 break;
2103                                         case 3:
2104                                                 length = (uint64_t)u_endian_read3(&ptfunxored[m], false);
2105                                                 break;
2106                                         case 2:
2107                                                 length = (uint64_t)u_endian_read2(&ptfunxored[m], false);
2108                                                 break;
2109                                         case 1:
2110                                                 length = (uint64_t)(ptfunxored[m]);
2111                                                 break;
2112                                         default:
2113                                                 break;
2114                                         }
2115                                         m+=8;
2116                                         findex3 = ptfunxored[m] | (ptfunxored[m+1] << 8);
2117                                         sampleoffset -= 1000000000000ULL;
2118                                         start -= 1000000000000ULL;
2119
2120                                         /*
2121                                         // Find wav with correct findex
2122                                         vector<wav_t>::iterator wave = actualwavs.end();
2123                                         for (vector<wav_t>::iterator aw = actualwavs.begin();
2124                                                         aw != actualwavs.end(); ++aw) {
2125                                                 if (aw->index == (glookup.begin()+findex2)->startpos) {
2126                                                         wave = aw;
2127                                                 }
2128                                         }
2129                                         if (wave == actualwavs.end())
2130                                                 return;
2131                                         // findex is the true source
2132                                         std::vector<midi_ev_t> md;
2133                                         region_t r = {
2134                                                 name,
2135                                                 (uint16_t)rindex,
2136                                                 (int64_t)findex, //(start*ratefactor),
2137                                                 (int64_t)findex2, //(sampleoffset*ratefactor),
2138                                                 (int64_t)findex3, //(length*ratefactor),
2139                                                 *wave,
2140                                                 md
2141                                         };
2142                                         groups.push_back(r);
2143                                         */
2144                                         vector<compound_t>::iterator g = groupmap.begin()+findex2;
2145                                         if (g >= groupmap.end())
2146                                                 continue;
2147                                         compound_t c;
2148                                         c.name = string(g->name);
2149                                         c.curr_index = compoundcount;
2150                                         c.level = findex;
2151                                         c.ontopof_index = findex3;
2152                                         c.next_index = g->next_index;
2153                                         c.unknown1 = g->unknown1;
2154                                         compounds.push_back(c);
2155                                         verbose_printf("COMPOUND\tc(%d) %s (%d %d) -> c(%u) %s\n", c.curr_index, c.name.c_str(), c.level, c.ontopof_index, c.next_index, name);
2156                                         compoundcount++;
2157                                 }
2158                                 groupcount++;
2159                         }
2160                 }
2161         }
2162         j = 0;
2163
2164         // Start pure regions
2165         k = m != 0 ? m : k - 1;
2166         if (!jumpto(&k, ptfunxored, k+64, (const unsigned char *)"\x5a\x05", 2))
2167                 jumpto(&k, ptfunxored, k+0x400, (const unsigned char *)"\x5a\x02", 2);
2168
2169         verbose_printf("pure regions k=0x%x\n", k);
2170
2171         maxregions = u_endian_read4(&ptfunxored[k-4], is_bigendian);
2172
2173         verbose_printf("maxregions=%u\n", maxregions);
2174         rindex = 0;
2175         for (i = k; rindex < maxregions && i < len; i++) {
2176                 if (            (ptfunxored[i  ] == 0xff) &&
2177                                 (ptfunxored[i+1] == 0x5a) &&
2178                                 (ptfunxored[i+2] == 0x01)) {
2179                         break;
2180                 }
2181                 //if (          (ptfunxored[i  ] == 0x5a) &&
2182                 //              (ptfunxored[i+1] == 0x03)) {
2183                 //      break;
2184                 //}
2185                 if (            (ptfunxored[i  ] == 0x5a) &&
2186                                 ((ptfunxored[i+1] == 0x01) || (ptfunxored[i+1] == 0x02))) {
2187
2188                         //findex = ptfunxored[i-48] | ptfunxored[i-47] << 8;
2189                         //rindex = ptfunxored[i+3] | ptfunxored[i+4] << 8;
2190
2191                         uint8_t lengthofname = ptfunxored[i+9];
2192                         if (ptfunxored[i+13] == 0x5a) {
2193                                 continue;
2194                         }
2195                         char name[256] = {0};
2196                         for (j = 0; j < lengthofname; j++) {
2197                                 name[j] = ptfunxored[i+13+j];
2198                         }
2199                         name[j] = '\0';
2200                         j += i+13;
2201
2202                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
2203                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
2204                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
2205                         somethingbytes = (ptfunxored[j+3] & 0xf);
2206                         skipbytes = ptfunxored[j+4];
2207                         findex = ptfunxored[j+5
2208                                         +startbytes
2209                                         +lengthbytes
2210                                         +offsetbytes
2211                                         +somethingbytes
2212                                         +skipbytes
2213                                         +37]
2214                                 | ptfunxored[j+5
2215                                         +startbytes
2216                                         +lengthbytes
2217                                         +offsetbytes
2218                                         +somethingbytes
2219                                         +skipbytes
2220                                         +38] << 8;
2221
2222                         uint64_t sampleoffset = 0;
2223                         switch (offsetbytes) {
2224                         case 5:
2225                                 sampleoffset = u_endian_read5(&ptfunxored[j+5], false);
2226                                 break;
2227                         case 4:
2228                                 sampleoffset = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
2229                                 break;
2230                         case 3:
2231                                 sampleoffset = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
2232                                 break;
2233                         case 2:
2234                                 sampleoffset = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
2235                                 break;
2236                         case 1:
2237                                 sampleoffset = (uint64_t)(ptfunxored[j+5]);
2238                                 break;
2239                         default:
2240                                 break;
2241                         }
2242                         j+=offsetbytes;
2243                         uint64_t length = 0;
2244                         switch (lengthbytes) {
2245                         case 5:
2246                                 length = u_endian_read5(&ptfunxored[j+5], false);
2247                                 break;
2248                         case 4:
2249                                 length = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
2250                                 break;
2251                         case 3:
2252                                 length = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
2253                                 break;
2254                         case 2:
2255                                 length = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
2256                                 break;
2257                         case 1:
2258                                 length = (uint64_t)(ptfunxored[j+5]);
2259                                 break;
2260                         default:
2261                                 break;
2262                         }
2263                         j+=lengthbytes;
2264                         uint64_t start = 0;
2265                         switch (startbytes) {
2266                         case 5:
2267                                 start = u_endian_read5(&ptfunxored[j+5], false);
2268                                 break;
2269                         case 4:
2270                                 start = (uint64_t)u_endian_read4(&ptfunxored[j+5], false);
2271                                 break;
2272                         case 3:
2273                                 start = (uint64_t)u_endian_read3(&ptfunxored[j+5], false);
2274                                 break;
2275                         case 2:
2276                                 start = (uint64_t)u_endian_read2(&ptfunxored[j+5], false);
2277                                 break;
2278                         case 1:
2279                                 start = (uint64_t)(ptfunxored[j+5]);
2280                                 break;
2281                         default:
2282                                 break;
2283                         }
2284                         j+=startbytes;
2285
2286                         if (offsetbytes == 5)
2287                                 sampleoffset -= 1000000000000ULL;
2288                         if (startbytes == 5)
2289                                 start -= 1000000000000ULL;
2290
2291                         std::string filename = string(name);
2292                         wav_t f = {
2293                                 filename,
2294                                 (uint16_t)findex,
2295                                 (int64_t)(start*ratefactor),
2296                                 (int64_t)(length*ratefactor),
2297                         };
2298
2299                         if (strlen(name) == 0) {
2300                                 continue;
2301                         }
2302                         if (length == 0) {
2303                                 continue;
2304                         }
2305                         // Regular region mapping to a source
2306                         uint32_t n = j;
2307                         if (!jumpto(&n, ptfunxored, len, (const unsigned char *)"\x5a\x01", 2))
2308                                 return;
2309                         //printf("XXX=%d\n", ptfunxored[n+12] | ptfunxored[n+13]<<8);
2310
2311                         // Find wav with correct findex
2312                         vector<wav_t>::iterator wave = actualwavs.end();
2313                         for (vector<wav_t>::iterator aw = actualwavs.begin();
2314                                         aw != actualwavs.end(); ++aw) {
2315                                 if (aw->index == findex) {
2316                                         wave = aw;
2317                                 }
2318                         }
2319                         if (wave == actualwavs.end()) {
2320                                 verbose_printf("missing source with findex\n");
2321                                 continue;
2322                         }
2323                         //verbose_printf("\n+r(%d) w(%d) REGION: %s st(%lx)x%u of(%lx)x%u ln(%lx)x%u\n", rindex, findex, name, start, startbytes, sampleoffset, offsetbytes, length, lengthbytes);
2324                         verbose_printf("REGION\tg(NA)\tr(%d)\tw(%d) %s(%s)\n", rindex, findex, name, wave->filename.c_str());
2325                         std::vector<midi_ev_t> md;
2326                         region_t r = {
2327                                 name,
2328                                 rindex,
2329                                 (int64_t)(start*ratefactor),
2330                                 (int64_t)(sampleoffset*ratefactor),
2331                                 (int64_t)(length*ratefactor),
2332                                 *wave,
2333                                 md
2334                         };
2335                         regions.push_back(r);
2336                         rindex++;
2337                 }
2338         }
2339
2340         // print compounds
2341         vector<uint16_t> rootnodes;
2342         bool found = false;
2343
2344         j = 0;
2345         for (vector<compound_t>::iterator cmp = compounds.begin();
2346                         cmp != compounds.end(); ++cmp) {
2347                 found = false;
2348                 for (vector<compound_t>::iterator tmp = compounds.begin();
2349                                 tmp != compounds.end(); ++tmp) {
2350                         if (tmp == cmp)
2351                                 continue;
2352                         if (tmp->ontopof_index == cmp->curr_index)
2353                                 found = true;
2354                 }
2355                 // Collect a vector of all the root nodes (no others point to)
2356                 if (!found)
2357                         rootnodes.push_back(cmp->curr_index);
2358         }
2359
2360         for (vector<uint16_t>::iterator rt = rootnodes.begin();
2361                         rt != rootnodes.end(); ++rt) {
2362                 vector<compound_t>::iterator cmp = compounds.begin()+(*rt);
2363                 // Now we are at a root node, follow to leaf
2364                 if (cmp >= compounds.end())
2365                         continue;
2366
2367                 verbose_printf("----\n");
2368
2369                 for (; cmp < compounds.end() && cmp->curr_index != cmp->next_index;
2370                                 cmp = compounds.begin()+cmp->next_index) {
2371
2372                         // Find region
2373                         vector<region_t>::iterator r = regions.end();
2374                         for (vector<region_t>::iterator rs = regions.begin();
2375                                         rs != regions.end(); rs++) {
2376                                 if (rs->index == cmp->unknown1 + cmp->level) {
2377                                         r = rs;
2378                                 }
2379                         }
2380                         if (r == regions.end())
2381                                 continue;
2382                         verbose_printf("\t->cidx(%u) pl(%u)+ridx(%u) cflags(0x%x) ?(%u) grp(%s) reg(%s)\n", cmp->curr_index, cmp->level, cmp->unknown1, cmp->ontopof_index, cmp->next_index, cmp->name.c_str(), r->name.c_str());
2383                 }
2384                 // Find region
2385                 vector<region_t>::iterator r = regions.end();
2386                 for (vector<region_t>::iterator rs = regions.begin();
2387                                 rs != regions.end(); rs++) {
2388                         if (rs->index == cmp->unknown1 + cmp->level) {
2389                                 r = rs;
2390                         }
2391                 }
2392                 if (r == regions.end())
2393                         continue;
2394                 verbose_printf("\tLEAF->cidx(%u) pl(%u)+ridx(%u) cflags(0x%x) ?(%u) grp(%s) reg(%s)\n", cmp->curr_index, cmp->level, cmp->unknown1, cmp->ontopof_index, cmp->next_index, cmp->name.c_str(), r->name.c_str());
2395         }
2396
2397         // Start grouped regions
2398
2399         // Print region groups mapped to sources
2400         for (vector<region_t>::iterator a = groups.begin(); a != groups.end(); ++a) {
2401                 // Find wav with findex
2402                 vector<wav_t>::iterator wav = audiofiles.end();
2403                 for (vector<wav_t>::iterator ws = audiofiles.begin();
2404                                 ws != audiofiles.end(); ws++) {
2405                         if (ws->index == a->startpos) {
2406                                 wav = ws;
2407                         }
2408                 }
2409                 if (wav == audiofiles.end())
2410                         continue;
2411
2412                 // Find wav with findex2
2413                 vector<wav_t>::iterator wav2 = audiofiles.end();
2414                 for (vector<wav_t>::iterator ws = audiofiles.begin();
2415                                 ws != audiofiles.end(); ws++) {
2416                         if (ws->index == a->sampleoffset) {
2417                                 wav2 = ws;
2418                         }
2419                 }
2420                 if (wav2 == audiofiles.end())
2421                         continue;
2422
2423                 verbose_printf("Group: %s -> %s OR %s\n", a->name.c_str(), wav->filename.c_str(), wav2->filename.c_str());
2424         }
2425
2426         //filter(regions);
2427         //resort(regions);
2428
2429         //  Tracks
2430         uint32_t offset;
2431         uint32_t tracknumber = 0;
2432         uint32_t regionspertrack = 0;
2433
2434         // Total tracks
2435         j = k;
2436         if (!jumpto(&j, ptfunxored, len, (const unsigned char *)"\x5a\x03\x00", 3))
2437                 return;
2438         //maxtracks = u_endian_read4(&ptfunxored[j-4]);
2439
2440         // Jump to start of region -> track mappings
2441         if (jumpto(&k, ptfunxored, k + regions.size() * 0x400, (const unsigned char *)"\x5a\x08", 2)) {
2442                 if (!jumpback(&k, ptfunxored, len, (const unsigned char *)"\x5a\x02", 2))
2443                         return;
2444         } else if (jumpto(&k, ptfunxored, k + regions.size() * 0x400, (const unsigned char *)"\x5a\x0a", 2)) {
2445                 if (!jumpback(&k, ptfunxored, len, (const unsigned char *)"\x5a\x01", 2))
2446                         return;
2447         } else {
2448                 return;
2449         }
2450         verbose_printf("tracks k=0x%x\n", k);
2451
2452         for (;k < len; k++) {
2453                 if (    (ptfunxored[k  ] == 0x5a) &&
2454                         (ptfunxored[k+1] & 0x04)) {
2455                         break;
2456                 }
2457                 if (    (ptfunxored[k  ] == 0x5a) &&
2458                         (ptfunxored[k+1] & 0x02)) {
2459
2460                         uint8_t lengthofname = 0;
2461                         lengthofname = ptfunxored[k+9];
2462                         if (lengthofname == 0x5a) {
2463                                 continue;
2464                         }
2465                         track_t tr;
2466
2467                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
2468
2469                         //printf("regions/track=%d\n", regionspertrack);
2470                         char name[256] = {0};
2471                         for (j = 0; j < lengthofname; j++) {
2472                                 name[j] = ptfunxored[j+k+13];
2473                         }
2474                         name[j] = '\0';
2475                         tr.name = string(name);
2476                         tr.index = tracknumber++;
2477
2478                         for (j = k+18+lengthofname; regionspertrack > 0 && j < len; j++) {
2479                                 jumpto(&j, ptfunxored, len, (const unsigned char *)"\x5a", 1);
2480                                 bool isgroup = ptfunxored[j+27] > 0;
2481                                 if (isgroup) {
2482                                         tr.reg.name = string("");
2483                                         tr.reg.length = 0;
2484                                         //tr.reg.index = 0xffff;
2485                                         verbose_printf("TRACK: t(%d) g(%d) G(%s) -> T(%s)\n",
2486                                                 tracknumber, tr.reg.index, tr.reg.name.c_str(), tr.name.c_str());
2487                                 } else {
2488                                         tr.reg.index = ((uint16_t)(ptfunxored[j+11]) & 0xff)
2489                                                 | (((uint16_t)(ptfunxored[j+12]) << 8) & 0xff00);
2490                                         vector<region_t>::iterator begin = regions.begin();
2491                                         vector<region_t>::iterator finish = regions.end();
2492                                         vector<region_t>::iterator found;
2493                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
2494                                                 tr.reg = *found;
2495                                         }
2496                                         verbose_printf("TRACK: t(%d) r(%d) R(%s) -> T(%s)\n",
2497                                                 tracknumber, tr.reg.index, tr.reg.name.c_str(), tr.name.c_str());
2498                                 }
2499                                 i = j+16;
2500                                 offset = u_endian_read4(&ptfunxored[i], is_bigendian);
2501                                 tr.reg.startpos = (int64_t)(offset*ratefactor);
2502                                 if (tr.reg.length > 0) {
2503                                         tracks.push_back(tr);
2504                                 }
2505                                 regionspertrack--;
2506
2507                                 jumpto(&j, ptfunxored, len, (const unsigned char *)"\xff\xff\xff\xff\xff\xff\xff\xff", 8);
2508                                 j += 12;
2509                         }
2510                 }
2511         }
2512 }