Fix crash when re-assigning groups to a disjunct set.
[ardour.git] / libs / ptformat / ptfformat.cc
1 /*
2     Copyright (C) 2015  Damien Zammit
3     Copyright (C) 2015  Robin Gareus
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string>
20 #include <string.h>
21 #include <assert.h>
22
23 #include <glib/gstdio.h>
24
25 #include "ptfformat.h"
26
27 using namespace std;
28
29 static void
30 hexdump(uint8_t *data, int len)
31 {
32         int i,j,end,step=16;
33
34         for (i = 0; i < len; i += step) {
35                 printf("0x%02X: ", i);
36                 end = i + step;
37                 if (end > len) end = len;
38                 for (j = i; j < end; j++) {
39                         printf("0x%02X ", data[j]);
40                 }
41                 for (j = i; j < end; j++) {
42                         if (data[j] < 128 && data[j] > 32)
43                                 printf("%c", data[j]);
44                         else
45                                 printf(".");
46                 }
47                 printf("\n");
48         }
49 }
50
51 PTFFormat::PTFFormat() : version(0), product(NULL) {
52 }
53
54 PTFFormat::~PTFFormat() {
55         if (ptfunxored) {
56                 free(ptfunxored);
57         }
58 }
59
60 int64_t
61 PTFFormat::foundat(unsigned char *haystack, uint64_t n, const char *needle) {
62         int64_t found = 0;
63         uint64_t i, j, needle_n;
64         needle_n = strlen(needle);
65
66         for (i = 0; i < n; i++) {
67                 found = i;
68                 for (j = 0; j < needle_n; j++) {
69                         if (haystack[i+j] != needle[j]) {
70                                 found = -1;
71                                 break;
72                         }
73                 }
74                 if (found > 0)
75                         return found;
76         }
77         return -1;
78 }
79
80 bool
81 PTFFormat::foundin(std::string haystack, std::string needle) {
82         size_t found = haystack.find(needle);
83         if (found != std::string::npos) {
84                 return true;
85         } else {
86                 return false;
87         }
88 }
89
90 /* Return values:       0            success
91                         0x01 to 0xff value of missing lut
92                         -1           could not open file as ptf
93 */
94 int
95 PTFFormat::load(std::string path, int64_t targetsr) {
96         FILE *fp;
97         unsigned char xxor[256];
98         unsigned char ct;
99         uint64_t i;
100         uint8_t xor_type;
101         uint8_t xor_value;
102         uint8_t xor_delta;
103         uint16_t xor_len;
104         int err;
105
106         if (! (fp = g_fopen(path.c_str(), "rb"))) {
107                 return -1;
108         }
109
110         fseek(fp, 0, SEEK_END);
111         len = ftell(fp);
112         if (len < 0x14) {
113                 fclose(fp);
114                 return -1;
115         }
116
117         if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
118                 /* Silently fail -- out of memory*/
119                 fclose(fp);
120                 ptfunxored = 0;
121                 return -1;
122         }
123
124         /* The first 20 bytes are always unencrypted */
125         fseek(fp, 0x00, SEEK_SET);
126         i = fread(ptfunxored, 1, 0x14, fp);
127         if (i < 0x14) {
128                 fclose(fp);
129                 return -1;
130         }
131
132         xor_type = ptfunxored[0x12];
133         xor_value = ptfunxored[0x13];
134         xor_len = 256;
135
136         // xor_type 0x01 = ProTools 5, 6, 7, 8 and 9
137         // xor_type 0x05 = ProTools 10, 11, 12
138         switch(xor_type) {
139         case 0x01:
140                 xor_delta = gen_xor_delta(xor_value, 53, false);
141                 break;
142         case 0x05:
143                 xor_delta = gen_xor_delta(xor_value, 11, true);
144                 break;
145         default:
146                 fclose(fp);
147                 return -1;
148         }
149
150         /* Generate the xor_key */
151         for (i=0; i < xor_len; i++)
152                 xxor[i] = (i * xor_delta) & 0xff;
153
154         /* hexdump(xxor, xor_len); */
155
156         /* Read file and decrypt rest of file */
157         i = 0x14;
158         fseek(fp, i, SEEK_SET);
159         while (fread(&ct, 1, 1, fp) != 0) {
160                 uint8_t xor_index = (xor_type == 0x01) ? i & 0xff : (i >> 12) & 0xff;
161                 ptfunxored[i++] = ct ^ xxor[xor_index];
162         }
163         fclose(fp);
164
165         if (!parse_version())
166                 return -1;
167
168         if (version < 5 || version > 12)
169                 return -1;
170
171         targetrate = targetsr;
172         err = parse();
173         if (err)
174                 return -1;
175
176         return 0;
177 }
178
179 bool
180 PTFFormat::parse_version() {
181         uint32_t seg_len,str_len;
182         uint8_t *data = ptfunxored + 0x14;
183         uintptr_t data_end = ((uintptr_t)ptfunxored) + 0x100;
184         uint8_t seg_type; 
185         bool success = false;
186
187         while( ((uintptr_t)data < data_end) && (success == false) ) {
188
189                 if (data[0] != 0x5a) {
190                         success = false;
191                         break;
192                 }
193
194                 seg_type = data[1];
195                 /* Skip segment header */
196                 data += 3;
197                 if (data[0] == 0 && data[1] == 0) {
198                         /* LE */
199                         seg_len = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
200                 } else {
201                         /* BE */
202                         seg_len = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0];
203                 }
204                 /* Skip seg_len */
205                 data += 4;
206                 if (!(seg_type == 0x04 || seg_type == 0x03) || data[0] != 0x03) {
207                         /* Go to next segment */
208                         data += seg_len;
209                         continue;
210                 }
211                 /* Skip 0x03 0x00 0x00 */
212                 data += 3;
213                 seg_len -= 3;
214                 str_len = (*(uint8_t *)data);
215                 if (! (product = (uint8_t *)malloc((str_len+1) * sizeof(uint8_t)))) {
216                         success = false;
217                         break;
218                 }
219
220                 /* Skip str_len */
221                 data += 4;
222                 seg_len -= 4;
223
224                 memcpy(product, data, str_len);
225                 product[str_len] = 0;
226                 data += str_len;
227                 seg_len -= str_len;
228
229                 /* Skip 0x03 0x00 0x00 0x00 */
230                 data += 4;
231                 seg_len -= 4;
232
233                 version = data[0];
234                 if (version == 0) {
235                         version = data[3];
236                 }
237                 data += seg_len;
238                 success = true;
239         }
240
241         /* If the above does not work, assume old version 5,6,7 */
242         if ((uintptr_t)data >= data_end - seg_len) {
243                 version = ptfunxored[0x40];
244                 success = true;
245         }
246         return success;
247 }
248
249 uint8_t
250 PTFFormat::gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative) {
251         uint16_t i;
252         for (i = 0; i < 256; i++) {
253                 if (((i * mul) & 0xff) == xor_value) {
254                                 return (negative) ? i * (-1) : i;
255                 }
256         }
257         // Should not occur
258         return 0;
259 }
260
261 int
262 PTFFormat::parse(void) {
263         if (version == 5) {
264                 parse5header();
265                 setrates();
266                 if (sessionrate < 44100 || sessionrate > 192000)
267                   return -1;
268                 parseaudio5();
269                 parserest5();
270                 parsemidi();
271         } else if (version == 7) {
272                 parse7header();
273                 setrates();
274                 if (sessionrate < 44100 || sessionrate > 192000)
275                   return -1;
276                 parseaudio();
277                 parserest89();
278                 parsemidi();
279         } else if (version == 8) {
280                 parse8header();
281                 setrates();
282                 if (sessionrate < 44100 || sessionrate > 192000)
283                   return -1;
284                 parseaudio();
285                 parserest89();
286                 parsemidi();
287         } else if (version == 9) {
288                 parse9header();
289                 setrates();
290                 if (sessionrate < 44100 || sessionrate > 192000)
291                   return -1;
292                 parseaudio();
293                 parserest89();
294                 parsemidi();
295         } else if (version == 10 || version == 11 || version == 12) {
296                 parse10header();
297                 setrates();
298                 if (sessionrate < 44100 || sessionrate > 192000)
299                   return -1;
300                 parseaudio();
301                 parserest10();
302                 parsemidi();
303         } else {
304                 // Should not occur
305                 return -1;
306         }
307         return 0;
308 }
309
310 void
311 PTFFormat::setrates(void) {
312         ratefactor = 1.f;
313         if (sessionrate != 0) {
314                 ratefactor = (float)targetrate / sessionrate;
315         }
316 }
317
318 void
319 PTFFormat::parse5header(void) {
320         uint32_t k;
321
322         // Find session sample rate
323         k = 0x100;
324         while (k < len) {
325                 if (            (ptfunxored[k  ] == 0x5a) &&
326                                 (ptfunxored[k+1] == 0x00) &&
327                                 (ptfunxored[k+2] == 0x02)) {
328                         break;
329                 }
330                 k++;
331         }
332
333         sessionrate = 0;
334         sessionrate |= ptfunxored[k+12] << 16;
335         sessionrate |= ptfunxored[k+13] << 8;
336         sessionrate |= ptfunxored[k+14];
337 }
338
339 void
340 PTFFormat::parse7header(void) {
341         uint64_t k;
342
343         // Find session sample rate
344         k = 0x100;
345         while (k < len) {
346                 if (            (ptfunxored[k  ] == 0x5a) &&
347                                 (ptfunxored[k+1] == 0x00) &&
348                                 (ptfunxored[k+2] == 0x05)) {
349                         break;
350                 }
351                 k++;
352         }
353
354         sessionrate = 0;
355         sessionrate |= ptfunxored[k+12] << 16;
356         sessionrate |= ptfunxored[k+13] << 8;
357         sessionrate |= ptfunxored[k+14];
358 }
359
360 void
361 PTFFormat::parse8header(void) {
362         uint64_t k;
363
364         // Find session sample rate
365         k = 0;
366         while (k < len) {
367                 if (            (ptfunxored[k  ] == 0x5a) &&
368                                 (ptfunxored[k+1] == 0x05)) {
369                         break;
370                 }
371                 k++;
372         }
373
374         sessionrate = 0;
375         sessionrate |= ptfunxored[k+11];
376         sessionrate |= ptfunxored[k+12] << 8;
377         sessionrate |= ptfunxored[k+13] << 16;
378 }
379
380 void
381 PTFFormat::parse9header(void) {
382         uint64_t k;
383
384         // Find session sample rate
385         k = 0x100;
386         while (k < len) {
387                 if (            (ptfunxored[k  ] == 0x5a) &&
388                                 (ptfunxored[k+1] == 0x06)) {
389                         break;
390                 }
391                 k++;
392         }
393
394         sessionrate = 0;
395         sessionrate |= ptfunxored[k+11];
396         sessionrate |= ptfunxored[k+12] << 8;
397         sessionrate |= ptfunxored[k+13] << 16;
398 }
399
400 void
401 PTFFormat::parse10header(void) {
402         uint64_t k;
403
404         // Find session sample rate
405         k = 0x100;
406         while (k < len) {
407                 if (            (ptfunxored[k  ] == 0x5a) &&
408                                 (ptfunxored[k+1] == 0x09)) {
409                         break;
410                 }
411                 k++;
412         }
413
414         sessionrate = 0;
415         sessionrate |= ptfunxored[k+11];
416         sessionrate |= ptfunxored[k+12] << 8;
417         sessionrate |= ptfunxored[k+13] << 16;
418 }
419
420 void
421 PTFFormat::parserest5(void) {
422         uint64_t i, j, k;
423         uint64_t regionspertrack, lengthofname;
424         uint64_t startbytes, lengthbytes, offsetbytes;
425         uint16_t tracknumber = 0;
426         uint16_t findex;
427         uint16_t rindex;
428
429         k = 0;
430         for (i = 0; i < 5; i++) {
431                 while (k < len) {
432                         if (            (ptfunxored[k  ] == 0x5a) &&
433                                         (ptfunxored[k+1] == 0x00) &&
434                                         (ptfunxored[k+2] == 0x03)) {
435                                 break;
436                         }
437                         k++;
438                 }
439                 k++;
440         }
441         k--;
442
443         for (i = 0; i < 2; i++) {
444                 while (k) {
445                         if (            (ptfunxored[k  ] == 0x5a) &&
446                                         (ptfunxored[k+1] == 0x00) &&
447                                         (ptfunxored[k+2] == 0x01)) {
448                                 break;
449                         }
450                         k--;
451                 }
452                 if (k)
453                         k--;
454         }
455         k++;
456
457         rindex = 0;
458         while (k < len) {
459                 if (            (ptfunxored[k  ] == 0xff) &&
460                                 (ptfunxored[k+1] == 0xff)) {
461                         break;
462                 }
463                 while (k < len) {
464                         if (            (ptfunxored[k  ] == 0x5a) &&
465                                         (ptfunxored[k+1] == 0x00) &&
466                                         (ptfunxored[k+2] == 0x01)) {
467                                 break;
468                         }
469                         k++;
470                 }
471
472                 lengthofname = ptfunxored[k+12];
473                 if (ptfunxored[k+13] == 0x5a) {
474                         k++;
475                         break;
476                 }
477                 char name[256] = {0};
478                 for (j = 0; j < lengthofname; j++) {
479                         name[j] = ptfunxored[k+13+j];
480                 }
481                 name[j] = '\0';
482                 regionspertrack = ptfunxored[k+13+j+3];
483                 for (i = 0; i < regionspertrack; i++) {
484                         while (k < len) {
485                                 if (            (ptfunxored[k  ] == 0x5a) &&
486                                                 (ptfunxored[k+1] == 0x00) &&
487                                                 (ptfunxored[k+2] == 0x03)) {
488                                         break;
489                                 }
490                                 k++;
491                         }
492                         j = k+16;
493                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
494                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
495                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
496                         //somethingbytes = (ptfunxored[j+1] & 0xf);
497                         findex = ptfunxored[k+14];
498                         j--;
499                         uint32_t start = 0;
500                         switch (startbytes) {
501                         case 4:
502                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
503                         case 3:
504                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
505                         case 2:
506                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
507                         case 1:
508                                 start |= (uint32_t)(ptfunxored[j+5]);
509                         default:
510                                 break;
511                         }
512                         j+=startbytes;
513                         uint32_t length = 0;
514                         switch (lengthbytes) {
515                         case 4:
516                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
517                         case 3:
518                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
519                         case 2:
520                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
521                         case 1:
522                                 length |= (uint32_t)(ptfunxored[j+5]);
523                         default:
524                                 break;
525                         }
526                         j+=lengthbytes;
527                         uint32_t sampleoffset = 0;
528                         switch (offsetbytes) {
529                         case 4:
530                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
531                         case 3:
532                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
533                         case 2:
534                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
535                         case 1:
536                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
537                         default:
538                                 break;
539                         }
540                         j+=offsetbytes;
541
542                         //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
543
544                         std::string filename = string(name) + extension;
545                         wav_t f = {
546                                 filename,
547                                 findex,
548                                 (int64_t)(start*ratefactor),
549                                 (int64_t)(length*ratefactor),
550                         };
551
552                         vector<wav_t>::iterator begin = audiofiles.begin();
553                         vector<wav_t>::iterator finish = audiofiles.end();
554                         vector<wav_t>::iterator found;
555                         // Add file to lists
556                         if ((found = std::find(begin, finish, f)) != finish) {
557                                 std::vector<midi_ev_t> m;
558                                 region_t r = {
559                                         name,
560                                         rindex,
561                                         (int64_t)(start*ratefactor),
562                                         (int64_t)(sampleoffset*ratefactor),
563                                         (int64_t)(length*ratefactor),
564                                         *found,
565                                         m
566                                 };
567                                 regions.push_back(r);
568                                 vector<track_t>::iterator ti;
569                                 vector<track_t>::iterator bt = tracks.begin();
570                                 vector<track_t>::iterator et = tracks.end();
571                                 track_t tr = { name, 0, 0, r };
572                                 if ((ti = std::find(bt, et, tr)) != et) {
573                                         tracknumber = (*ti).index;
574                                 } else {
575                                         tracknumber = tracks.size() + 1;
576                                 }
577                                 track_t t = {
578                                         name,
579                                         (uint16_t)tracknumber,
580                                         uint8_t(0),
581                                         r
582                                 };
583                                 tracks.push_back(t);
584                         } else {
585                                 std::vector<midi_ev_t> m;
586                                 region_t r = {
587                                         name,
588                                         rindex,
589                                         (int64_t)(start*ratefactor),
590                                         (int64_t)(sampleoffset*ratefactor),
591                                         (int64_t)(length*ratefactor),
592                                         f,
593                                         m,
594                                 };
595                                 regions.push_back(r);
596                                 vector<track_t>::iterator ti;
597                                 vector<track_t>::iterator bt = tracks.begin();
598                                 vector<track_t>::iterator et = tracks.end();
599                                 track_t tr = { name, 0, 0, r };
600                                 if ((ti = std::find(bt, et, tr)) != et) {
601                                         tracknumber = (*ti).index;
602                                 } else {
603                                         tracknumber = tracks.size() + 1;
604                                 }
605                                 track_t t = {
606                                         name,
607                                         (uint16_t)tracknumber,
608                                         uint8_t(0),
609                                         r
610                                 };
611                                 tracks.push_back(t);
612                         }
613                         rindex++;
614                         k++;
615                 }
616                 k++;
617         }
618 }
619
620 void
621 PTFFormat::resort(std::vector<wav_t>& ws) {
622         int j = 0;
623         std::sort(ws.begin(), ws.end());
624         for (std::vector<wav_t>::iterator i = ws.begin(); i != ws.end(); ++i) {
625                 (*i).index = j;
626                 j++;
627         }
628 }
629
630 void
631 PTFFormat::parseaudio5(void) {
632         uint64_t i,k,l;
633         uint64_t lengthofname, wavnumber;
634
635         // Find end of wav file list
636         k = 0;
637         while (k < len) {
638                 if (            (ptfunxored[k  ] == 0x5f) &&
639                                 (ptfunxored[k+1] == 0x50) &&
640                                 (ptfunxored[k+2] == 0x35)) {
641                         break;
642                 }
643                 k++;
644         }
645         k++;
646         while (k < len) {
647                 if (            (ptfunxored[k  ] == 0x5f) &&
648                                 (ptfunxored[k+1] == 0x50) &&
649                                 (ptfunxored[k+2] == 0x35)) {
650                         break;
651                 }
652                 k++;
653         }
654
655         // Find actual wav names
656         uint16_t numberofwavs = ptfunxored[k-23];
657         char wavname[256];
658         for (i = k; i < len; i++) {
659                 if (            (ptfunxored[i  ] == 'F') &&
660                                 (ptfunxored[i+1] == 'i') &&
661                                 (ptfunxored[i+2] == 'l') &&
662                                 (ptfunxored[i+3] == 'e') &&
663                                 (ptfunxored[i+4] == 's')) {
664                         break;
665                 }
666         }
667
668         wavnumber = 0;
669         i+=16;
670         char ext[5];
671         while (i < len && numberofwavs > 0) {
672                 i++;
673                 if (            (ptfunxored[i  ] == 0x5a) &&
674                                 (ptfunxored[i+1] == 0x00) &&
675                                 (ptfunxored[i+2] == 0x05)) {
676                         break;
677                 }
678                 lengthofname = ptfunxored[i];
679                 i++;
680                 l = 0;
681                 while (l < lengthofname) {
682                         wavname[l] = ptfunxored[i+l];
683                         l++;
684                 }
685                 i+=lengthofname;
686                 ext[0] = ptfunxored[i++];
687                 ext[1] = ptfunxored[i++];
688                 ext[2] = ptfunxored[i++];
689                 ext[3] = ptfunxored[i++];
690                 ext[4] = '\0';
691
692                 wavname[l] = 0;
693                 if (foundin(wavname, ".L") || foundin(wavname, ".R")) {
694                         extension = string("");
695                 } else if (foundin(wavname, ".wav") || foundin(ext, "WAVE")) {
696                         extension = string(".wav");
697                 } else if (foundin(wavname, ".aif") || foundin(ext, "AIFF")) {
698                         extension = string(".aif");
699                 } else {
700                         extension = string("");
701                 }
702
703                 std::string wave = string(wavname);
704                 wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
705
706                 if (foundin(wave, string(".grp"))) {
707                         continue;
708                 }
709
710                 actualwavs.push_back(f);
711                 audiofiles.push_back(f);
712                 //printf("done\n");
713                 numberofwavs--;
714                 i += 7;
715         }
716         resort(actualwavs);
717         resort(audiofiles);
718 }
719
720 struct mchunk {
721         mchunk (uint64_t zt, uint64_t ml, std::vector<PTFFormat::midi_ev_t> const& c)
722         : zero (zt)
723         , maxlen (ml)
724         , chunk (c)
725         {}
726         uint64_t zero;
727         uint64_t maxlen;
728         std::vector<PTFFormat::midi_ev_t> chunk;
729 };
730
731 void
732 PTFFormat::parsemidi(void) {
733         uint64_t tr, i, k, lastk, n_midi_events, zero_ticks;
734         uint64_t midi_pos, midi_len, max_pos, region_pos;
735         uint8_t midi_velocity, midi_note;
736         uint16_t ridx;
737         uint16_t nmiditracks, regionnumber = 0;
738         uint32_t nregions, mr;
739
740         std::vector<mchunk> midichunks;
741         midi_ev_t m;
742         bool found = false;
743
744         // Find MdNLB
745         k = 0;
746         lastk = 0;
747
748         // Parse all midi chunks, not 1:1 mapping to regions yet
749         while (k + 35 < len) {
750                 found = false;
751                 max_pos = 0;
752                 std::vector<midi_ev_t> midi;
753
754                 while (k < len && !found) {
755                         if (            (ptfunxored[k  ] == 'M') &&
756                                         (ptfunxored[k+1] == 'd') &&
757                                         (ptfunxored[k+2] == 'N') &&
758                                         (ptfunxored[k+3] == 'L') &&
759                                         (ptfunxored[k+4] == 'B')) {
760                                 found = true;
761                                 lastk = k;
762                                 break;
763                         }
764                         k++;
765                 }
766
767                 if (!found) {
768                         k = lastk;
769                         break;
770                 }
771
772                 k += 11;
773                 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
774                                 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
775
776                 k += 4;
777                 zero_ticks = (uint64_t)ptfunxored[k] |
778                         (uint64_t)ptfunxored[k+1] << 8 |
779                         (uint64_t)ptfunxored[k+2] << 16 |
780                         (uint64_t)ptfunxored[k+3] << 24 |
781                         (uint64_t)ptfunxored[k+4] << 32;
782                 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
783                         midi_pos = (uint64_t)ptfunxored[k] |
784                                 (uint64_t)ptfunxored[k+1] << 8 |
785                                 (uint64_t)ptfunxored[k+2] << 16 |
786                                 (uint64_t)ptfunxored[k+3] << 24 |
787                                 (uint64_t)ptfunxored[k+4] << 32;
788                         midi_pos -= zero_ticks;
789                         midi_note = ptfunxored[k+8];
790                         midi_len = (uint64_t)ptfunxored[k+9] |
791                                 (uint64_t)ptfunxored[k+10] << 8 |
792                                 (uint64_t)ptfunxored[k+11] << 16 |
793                                 (uint64_t)ptfunxored[k+12] << 24 |
794                                 (uint64_t)ptfunxored[k+13] << 32;
795                         midi_velocity = ptfunxored[k+17];
796
797                         if (midi_pos + midi_len > max_pos) {
798                                 max_pos = midi_pos + midi_len;
799                         }
800
801                         m.pos = midi_pos;
802                         m.length = midi_len;
803                         m.note = midi_note;
804                         m.velocity = midi_velocity;
805 #if 1
806 // stop gap measure to prevent crashes in ardour,
807 // remove when decryption is fully solved for .ptx
808                         if ((m.velocity & 0x80) || (m.note & 0x80) ||
809                                         (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
810                                 continue;
811                         }
812 #endif
813                         midi.push_back(m);
814                 }
815                 midichunks.push_back(mchunk (zero_ticks, max_pos, midi));
816         }
817
818         lastk = k;
819
820         // Map midi chunks to regions
821         while (k < len) {
822                 char midiregionname[256];
823                 uint8_t namelen;
824
825                 found = false;
826                 while (k < len && !found) {
827                         if (            (ptfunxored[k  ] == 'M') &&
828                                         (ptfunxored[k+1] == 'd') &&
829                                         (ptfunxored[k+2] == 'T') &&
830                                         (ptfunxored[k+3] == 'E') &&
831                                         (ptfunxored[k+4] == 'L')) {
832                                 found = true;
833                                 lastk = k;
834                                 break;
835                         }
836                         k++;
837                 }
838
839                 if (!found) {
840                         k = lastk;
841                         break;
842                 }
843
844                 k += 41;
845
846                 nregions = 0;
847                 nregions |= ptfunxored[k];
848                 nregions |= ptfunxored[k+1] << 8;
849
850                 for (mr = 0; mr < nregions; mr++) {
851                         found = false;
852                         while (k < len && !found) {
853                                 if (            (ptfunxored[k  ] == 0x5a) &&
854                                                 (ptfunxored[k+1] == 0x0c)) {
855                                         found = true;
856                                         lastk = k;
857                                         break;
858                                 }
859                                 k++;
860                         }
861
862                         if (!found) {
863                                 k = lastk;
864                                 break;
865                         }
866
867                         k += 9;
868
869                         namelen = ptfunxored[k];
870                         for (i = 0; i < namelen; i++) {
871                                 midiregionname[i] = ptfunxored[k+4+i];
872                         }
873                         midiregionname[namelen] = '\0';
874                         k += 4 + namelen;
875
876                         k += 5;
877                         /*
878                         region_pos = (uint64_t)ptfunxored[k] |
879                                         (uint64_t)ptfunxored[k+1] << 8 |
880                                         (uint64_t)ptfunxored[k+2] << 16 |
881                                         (uint64_t)ptfunxored[k+3] << 24 |
882                                         (uint64_t)ptfunxored[k+4] << 32;
883                         */
884                         found = false;
885                         while (k < len && !found) {
886                                 if (            (ptfunxored[k  ] == 0xfe) &&
887                                                 (ptfunxored[k+1] == 0xff) &&
888                                                 (ptfunxored[k+2] == 0xff) &&
889                                                 (ptfunxored[k+3] == 0xff)) {
890                                         found = true;
891                                         lastk = k;
892                                         break;
893                                 }
894                                 k++;
895                         }
896
897                         if (!found) {
898                                 k = lastk;
899                                 break;
900                         }
901
902                         k += 40;
903
904                         ridx = ptfunxored[k];
905                         ridx |= ptfunxored[k+1] << 8;
906
907                         struct mchunk mc = *(midichunks.begin()+ridx);
908
909                         wav_t w = { std::string(""), 0, 0, 0 };
910                         region_t r = {
911                                 midiregionname,
912                                 regionnumber++,
913                                 //(int64_t)mc.zero,
914                                 (int64_t)0xe8d4a51000ull,
915                                 (int64_t)(0),
916                                 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
917                                 (int64_t)mc.maxlen,
918                                 w,
919                                 mc.chunk,
920                         };
921                         midiregions.push_back(r);
922                 }
923         }
924
925         found = false;
926         // Put midi regions on midi tracks
927         while (k < len && !found) {
928                 if (            (ptfunxored[k  ] == 0x5a) &&
929                                 (ptfunxored[k+1] == 0x03)) {
930                         found = true;
931                         break;
932                 }
933                 k++;
934         }
935
936         if (!found)
937                 return;
938
939         k -= 4;
940
941         nmiditracks = 0;
942         nmiditracks |= ptfunxored[k];
943         nmiditracks |= ptfunxored[k+1] << 8;
944
945         k += 4;
946
947         for (tr = 0; tr < nmiditracks; tr++) {
948                 char miditrackname[256];
949                 uint8_t namelen;
950                 found = false;
951                 while (k < len && !found) {
952                         if (            (ptfunxored[k  ] == 0x5a) &&
953                                         (ptfunxored[k+1] == 0x03)) {
954                                 found = true;
955                                 break;
956                         }
957                         k++;
958                 }
959
960                 if (!found)
961                         return;
962
963                 namelen = ptfunxored[k+9];
964                 for (i = 0; i < namelen; i++) {
965                         miditrackname[i] = ptfunxored[k+13+i];
966                 }
967                 miditrackname[namelen] = '\0';
968                 k += 13 + namelen;
969                 nregions = 0;
970                 nregions |= ptfunxored[k];
971                 nregions |= ptfunxored[k+1] << 8;
972
973                 for (i = 0; (i < nregions) && (k < len); i++) {
974                         k += 24;
975
976                         ridx = 0;
977                         ridx |= ptfunxored[k];
978                         ridx |= ptfunxored[k+1] << 8;
979
980                         k += 5;
981
982                         region_pos = (uint64_t)ptfunxored[k] |
983                                         (uint64_t)ptfunxored[k+1] << 8 |
984                                         (uint64_t)ptfunxored[k+2] << 16 |
985                                         (uint64_t)ptfunxored[k+3] << 24 |
986                                         (uint64_t)ptfunxored[k+4] << 32;
987
988                         k += 20;
989
990                         track_t mtr;
991                         mtr.name = string(miditrackname);
992                         mtr.index = tr;
993                         mtr.playlist = 0;
994                         // Find the midi region with index 'ridx'
995                         std::vector<region_t>::iterator begin = midiregions.begin();
996                         std::vector<region_t>::iterator finish = midiregions.end();
997                         std::vector<region_t>::iterator mregion;
998                         wav_t w = { std::string(""), 0, 0, 0 };
999                         std::vector<midi_ev_t> m;
1000                         region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
1001                         if ((mregion = std::find(begin, finish, r)) != finish) {
1002                                 mtr.reg = *mregion;
1003                                 mtr.reg.startpos = std::labs(region_pos - mtr.reg.startpos);
1004                                 miditracks.push_back(mtr);
1005                         }
1006                 }
1007         }
1008 }
1009
1010 void
1011 PTFFormat::parseaudio(void) {
1012         uint64_t i,j,k,l;
1013         int64_t index = foundat(ptfunxored, len, "Audio Files");
1014
1015         if (index < 0)
1016                 return;
1017
1018         // Find end of wav file list
1019         k = (uint64_t)index;
1020         while (k < len) {
1021                 if (            (ptfunxored[k  ] == 0xff) &&
1022                                 (ptfunxored[k+1] == 0xff) &&
1023                                 (ptfunxored[k+2] == 0xff) &&
1024                                 (ptfunxored[k+3] == 0xff)) {
1025                         break;
1026                 }
1027                 k++;
1028         }
1029
1030         // Find actual wav names
1031         bool first = true;
1032         uint16_t numberofwavs;
1033         char wavname[256];
1034         for (i = k-2; i > 4; i--) {
1035                 if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'A') || ptfunxored[i  ] == '\0') &&
1036                                 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I') || ptfunxored[i-1] == '\0') &&
1037                                 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F') || ptfunxored[i-2] == '\0') &&
1038                                 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F') || ptfunxored[i-3] == '\0')) {
1039                         j = i-4;
1040                         l = 0;
1041                         while (ptfunxored[j] != '\0') {
1042                                 wavname[l] = ptfunxored[j];
1043                                 l++;
1044                                 j--;
1045                         }
1046                         wavname[l] = 0;
1047                         if (ptfunxored[i] == 'A') {
1048                                 extension = string(".aif");
1049                         } else {
1050                                 extension = string(".wav");
1051                         }
1052                         //uint8_t playlist = ptfunxored[j-8];
1053
1054                         if (first) {
1055                                 first = false;
1056                                 for (j = k; j > 4; j--) {
1057                                         if (    (ptfunxored[j  ] == 0x01) &&
1058                                                 (ptfunxored[j-1] == 0x5a)) {
1059
1060                                                 numberofwavs = 0;
1061                                                 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
1062                                                 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
1063                                                 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
1064                                                 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
1065                                                 //printf("%d wavs\n", numberofwavs);
1066                                                 break;
1067                                         }
1068                                 k--;
1069                                 }
1070                         }
1071
1072                         std::string wave = string(wavname);
1073                         std::reverse(wave.begin(), wave.end());
1074                         wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
1075
1076                         if (foundin(wave, string(".grp"))) {
1077                                 continue;
1078                         }
1079
1080                         actualwavs.push_back(f);
1081
1082                         numberofwavs--;
1083                         if (numberofwavs <= 0)
1084                                 break;
1085                 }
1086         }
1087 }
1088
1089 void
1090 PTFFormat::parserest89(void) {
1091         uint64_t i,j,k,l;
1092         // Find Regions
1093         uint8_t startbytes = 0;
1094         uint8_t lengthbytes = 0;
1095         uint8_t offsetbytes = 0;
1096         uint8_t somethingbytes = 0;
1097         uint8_t skipbytes = 0;
1098
1099         k = 0;
1100         while (k < len) {
1101                 if (            (ptfunxored[k  ] == 'S') &&
1102                                 (ptfunxored[k+1] == 'n') &&
1103                                 (ptfunxored[k+2] == 'a') &&
1104                                 (ptfunxored[k+3] == 'p')) {
1105                         break;
1106                 }
1107                 k++;
1108         }
1109         uint16_t rindex = 0;
1110         uint32_t findex = 0;
1111         for (i = k; i < len-70; i++) {
1112                 if (            (ptfunxored[i  ] == 0x5a) &&
1113                                 (ptfunxored[i+1] == 0x0a)) {
1114                                 break;
1115                 }
1116                 if (            (ptfunxored[i  ] == 0x5a) &&
1117                                 (ptfunxored[i+1] == 0x0c)) {
1118
1119                         uint8_t lengthofname = ptfunxored[i+9];
1120
1121                         char name[256] = {0};
1122                         for (j = 0; j < lengthofname; j++) {
1123                                 name[j] = ptfunxored[i+13+j];
1124                         }
1125                         name[j] = '\0';
1126                         j += i+13;
1127                         //uint8_t disabled = ptfunxored[j];
1128
1129                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1130                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1131                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1132                         somethingbytes = (ptfunxored[j+3] & 0xf);
1133                         skipbytes = ptfunxored[j+4];
1134                         findex = ptfunxored[j+5
1135                                         +startbytes
1136                                         +lengthbytes
1137                                         +offsetbytes
1138                                         +somethingbytes
1139                                         +skipbytes
1140                                         +40];
1141                         /*rindex = ptfunxored[j+5
1142                                         +startbytes
1143                                         +lengthbytes
1144                                         +offsetbytes
1145                                         +somethingbytes
1146                                         +skipbytes
1147                                         +24];
1148                         */
1149                         uint32_t sampleoffset = 0;
1150                         switch (offsetbytes) {
1151                         case 4:
1152                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1153                         case 3:
1154                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1155                         case 2:
1156                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1157                         case 1:
1158                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1159                         default:
1160                                 break;
1161                         }
1162                         j+=offsetbytes;
1163                         uint32_t length = 0;
1164                         switch (lengthbytes) {
1165                         case 4:
1166                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1167                         case 3:
1168                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1169                         case 2:
1170                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1171                         case 1:
1172                                 length |= (uint32_t)(ptfunxored[j+5]);
1173                         default:
1174                                 break;
1175                         }
1176                         j+=lengthbytes;
1177                         uint32_t start = 0;
1178                         switch (startbytes) {
1179                         case 4:
1180                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1181                         case 3:
1182                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1183                         case 2:
1184                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1185                         case 1:
1186                                 start |= (uint32_t)(ptfunxored[j+5]);
1187                         default:
1188                                 break;
1189                         }
1190                         j+=startbytes;
1191                         /*
1192                         uint32_t something = 0;
1193                         switch (somethingbytes) {
1194                         case 4:
1195                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1196                         case 3:
1197                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1198                         case 2:
1199                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1200                         case 1:
1201                                 something |= (uint32_t)(ptfunxored[j+5]);
1202                         default:
1203                                 break;
1204                         }
1205                         j+=somethingbytes;
1206                         */
1207                         std::string filename = string(name) + extension;
1208                         wav_t f = {
1209                                 filename,
1210                                 0,
1211                                 (int64_t)(start*ratefactor),
1212                                 (int64_t)(length*ratefactor),
1213                         };
1214
1215                         f.index = findex;
1216                         //printf("something=%d\n", something);
1217
1218                         vector<wav_t>::iterator begin = actualwavs.begin();
1219                         vector<wav_t>::iterator finish = actualwavs.end();
1220                         vector<wav_t>::iterator found;
1221                         // Add file to list only if it is an actual wav
1222                         if ((found = std::find(begin, finish, f)) != finish) {
1223                                 audiofiles.push_back(f);
1224                                 // Also add plain wav as region
1225                                 std::vector<midi_ev_t> m;
1226                                 region_t r = {
1227                                         name,
1228                                         rindex,
1229                                         (int64_t)(start*ratefactor),
1230                                         (int64_t)(sampleoffset*ratefactor),
1231                                         (int64_t)(length*ratefactor),
1232                                         f,
1233                                         m
1234                                 };
1235                                 regions.push_back(r);
1236                         // Region only
1237                         } else {
1238                                 if (foundin(filename, string(".grp"))) {
1239                                         continue;
1240                                 }
1241                                 std::vector<midi_ev_t> m;
1242                                 region_t r = {
1243                                         name,
1244                                         rindex,
1245                                         (int64_t)(start*ratefactor),
1246                                         (int64_t)(sampleoffset*ratefactor),
1247                                         (int64_t)(length*ratefactor),
1248                                         f,
1249                                         m
1250                                 };
1251                                 regions.push_back(r);
1252                         }
1253                         rindex++;
1254                 }
1255         }
1256
1257         while (k < len) {
1258                 if (            (ptfunxored[k  ] == 0x5a) &&
1259                                 (ptfunxored[k+1] == 0x03)) {
1260                                 break;
1261                 }
1262                 k++;
1263         }
1264         while (k < len) {
1265                 if (            (ptfunxored[k  ] == 0x5a) &&
1266                                 (ptfunxored[k+1] == 0x02)) {
1267                                 break;
1268                 }
1269                 k++;
1270         }
1271         k++;
1272
1273         //  Tracks
1274         uint32_t offset;
1275         uint32_t tracknumber = 0;
1276         uint32_t regionspertrack = 0;
1277         for (;k < len; k++) {
1278                 if (    (ptfunxored[k  ] == 0x5a) &&
1279                         (ptfunxored[k+1] == 0x04)) {
1280                         break;
1281                 }
1282                 if (    (ptfunxored[k  ] == 0x5a) &&
1283                         (ptfunxored[k+1] == 0x02)) {
1284
1285                         uint8_t lengthofname = 0;
1286                         lengthofname = ptfunxored[k+9];
1287                         if (lengthofname == 0x5a) {
1288                                 continue;
1289                         }
1290                         track_t tr;
1291
1292                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1293
1294                         //printf("regions/track=%d\n", regionspertrack);
1295                         char name[256] = {0};
1296                         for (j = 0; j < lengthofname; j++) {
1297                                 name[j] = ptfunxored[j+k+13];
1298                         }
1299                         name[j] = '\0';
1300                         tr.name = string(name);
1301                         tr.index = tracknumber++;
1302
1303                         for (j = k; regionspertrack > 0 && j < len; j++) {
1304                                 for (l = j; l < len; l++) {
1305                                         if (    (ptfunxored[l  ] == 0x5a) &&
1306                                                 (ptfunxored[l+1] == 0x07)) {
1307                                                 j = l;
1308                                                 break;
1309                                         }
1310                                 }
1311
1312
1313                                 if (regionspertrack == 0) {
1314                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1315                                         break;
1316                                 } else {
1317
1318                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1319                                         vector<region_t>::iterator begin = regions.begin();
1320                                         vector<region_t>::iterator finish = regions.end();
1321                                         vector<region_t>::iterator found;
1322                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1323                                                 tr.reg = (*found);
1324                                         }
1325                                         i = l+16;
1326                                         offset = 0;
1327                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1328                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1329                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1330                                         offset |= (uint32_t)(ptfunxored[i]);
1331                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1332                                         if (tr.reg.length > 0) {
1333                                                 tracks.push_back(tr);
1334                                         }
1335                                         regionspertrack--;
1336                                 }
1337                         }
1338                 }
1339         }
1340 }
1341
1342 void
1343 PTFFormat::parserest10(void) {
1344         uint64_t i,j,k,l;
1345         // Find Regions
1346         uint8_t startbytes = 0;
1347         uint8_t lengthbytes = 0;
1348         uint8_t offsetbytes = 0;
1349         uint8_t somethingbytes = 0;
1350         uint8_t skipbytes = 0;
1351
1352         k = 0;
1353         while (k < len) {
1354                 if (            (ptfunxored[k  ] == 'S') &&
1355                                 (ptfunxored[k+1] == 'n') &&
1356                                 (ptfunxored[k+2] == 'a') &&
1357                                 (ptfunxored[k+3] == 'p')) {
1358                         break;
1359                 }
1360                 k++;
1361         }
1362         for (i = k; i < len-70; i++) {
1363                 if (            (ptfunxored[i  ] == 0x5a) &&
1364                                 (ptfunxored[i+1] == 0x02)) {
1365                                 k = i;
1366                                 break;
1367                 }
1368         }
1369         k++;
1370         for (i = k; i < len-70; i++) {
1371                 if (            (ptfunxored[i  ] == 0x5a) &&
1372                                 (ptfunxored[i+1] == 0x02)) {
1373                                 k = i;
1374                                 break;
1375                 }
1376         }
1377         k++;
1378         uint16_t rindex = 0;
1379         uint32_t findex = 0;
1380         for (i = k; i < len-70; i++) {
1381                 if (            (ptfunxored[i  ] == 0x5a) &&
1382                                 (ptfunxored[i+1] == 0x08)) {
1383                                 break;
1384                 }
1385                 if (            (ptfunxored[i  ] == 0x5a) &&
1386                                 (ptfunxored[i+1] == 0x01)) {
1387
1388                         uint8_t lengthofname = ptfunxored[i+9];
1389                         if (ptfunxored[i+13] == 0x5a) {
1390                                 continue;
1391                         }
1392                         char name[256] = {0};
1393                         for (j = 0; j < lengthofname; j++) {
1394                                 name[j] = ptfunxored[i+13+j];
1395                         }
1396                         name[j] = '\0';
1397                         j += i+13;
1398                         //uint8_t disabled = ptfunxored[j];
1399                         //printf("%s\n", name);
1400
1401                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1402                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1403                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1404                         somethingbytes = (ptfunxored[j+3] & 0xf);
1405                         skipbytes = ptfunxored[j+4];
1406                         findex = ptfunxored[j+5
1407                                         +startbytes
1408                                         +lengthbytes
1409                                         +offsetbytes
1410                                         +somethingbytes
1411                                         +skipbytes
1412                                         +37];
1413                         /*rindex = ptfunxored[j+5
1414                                         +startbytes
1415                                         +lengthbytes
1416                                         +offsetbytes
1417                                         +somethingbytes
1418                                         +skipbytes
1419                                         +24];
1420                         */
1421                         uint32_t sampleoffset = 0;
1422                         switch (offsetbytes) {
1423                         case 4:
1424                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1425                         case 3:
1426                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1427                         case 2:
1428                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1429                         case 1:
1430                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1431                         default:
1432                                 break;
1433                         }
1434                         j+=offsetbytes;
1435                         uint32_t length = 0;
1436                         switch (lengthbytes) {
1437                         case 4:
1438                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1439                         case 3:
1440                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1441                         case 2:
1442                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1443                         case 1:
1444                                 length |= (uint32_t)(ptfunxored[j+5]);
1445                         default:
1446                                 break;
1447                         }
1448                         j+=lengthbytes;
1449                         uint32_t start = 0;
1450                         switch (startbytes) {
1451                         case 4:
1452                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1453                         case 3:
1454                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1455                         case 2:
1456                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1457                         case 1:
1458                                 start |= (uint32_t)(ptfunxored[j+5]);
1459                         default:
1460                                 break;
1461                         }
1462                         j+=startbytes;
1463                         /*
1464                         uint32_t something = 0;
1465                         switch (somethingbytes) {
1466                         case 4:
1467                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1468                         case 3:
1469                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1470                         case 2:
1471                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1472                         case 1:
1473                                 something |= (uint32_t)(ptfunxored[j+5]);
1474                         default:
1475                                 break;
1476                         }
1477                         j+=somethingbytes;
1478                         */
1479                         std::string filename = string(name) + extension;
1480                         wav_t f = {
1481                                 filename,
1482                                 0,
1483                                 (int64_t)(start*ratefactor),
1484                                 (int64_t)(length*ratefactor),
1485                         };
1486
1487                         if (strlen(name) == 0) {
1488                                 continue;
1489                         }
1490                         if (length == 0) {
1491                                 continue;
1492                         }
1493                         f.index = findex;
1494                         //printf("something=%d\n", something);
1495
1496                         vector<wav_t>::iterator begin = actualwavs.begin();
1497                         vector<wav_t>::iterator finish = actualwavs.end();
1498                         vector<wav_t>::iterator found;
1499                         // Add file to list only if it is an actual wav
1500                         if ((found = std::find(begin, finish, f)) != finish) {
1501                                 audiofiles.push_back(f);
1502                                 // Also add plain wav as region
1503                                 std::vector<midi_ev_t> m;
1504                                 region_t r = {
1505                                         name,
1506                                         rindex,
1507                                         (int64_t)(start*ratefactor),
1508                                         (int64_t)(sampleoffset*ratefactor),
1509                                         (int64_t)(length*ratefactor),
1510                                         f,
1511                                         m
1512                                 };
1513                                 regions.push_back(r);
1514                         // Region only
1515                         } else {
1516                                 if (foundin(filename, string(".grp"))) {
1517                                         continue;
1518                                 }
1519                                 std::vector<midi_ev_t> m;
1520                                 region_t r = {
1521                                         name,
1522                                         rindex,
1523                                         (int64_t)(start*ratefactor),
1524                                         (int64_t)(sampleoffset*ratefactor),
1525                                         (int64_t)(length*ratefactor),
1526                                         f,
1527                                         m
1528                                 };
1529                                 regions.push_back(r);
1530                         }
1531                         rindex++;
1532                         //printf("%s\n", name);
1533                 }
1534         }
1535         //  Tracks
1536         uint32_t offset;
1537         uint32_t tracknumber = 0;
1538         uint32_t regionspertrack = 0;
1539         for (;k < len; k++) {
1540                 if (    (ptfunxored[k  ] == 0x5a) &&
1541                         (ptfunxored[k+1] == 0x08)) {
1542                         break;
1543                 }
1544         }
1545         k++;
1546         for (;k < len; k++) {
1547                 if (    (ptfunxored[k  ] == 0x5a) &&
1548                         (ptfunxored[k+1] == 0x04)) {
1549                         break;
1550                 }
1551                 if (    (ptfunxored[k  ] == 0x5a) &&
1552                         (ptfunxored[k+1] == 0x02)) {
1553
1554                         uint8_t lengthofname = 0;
1555                         lengthofname = ptfunxored[k+9];
1556                         if (lengthofname == 0x5a) {
1557                                 continue;
1558                         }
1559                         track_t tr;
1560
1561                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1562
1563                         //printf("regions/track=%d\n", regionspertrack);
1564                         char name[256] = {0};
1565                         for (j = 0; j < lengthofname; j++) {
1566                                 name[j] = ptfunxored[j+k+13];
1567                         }
1568                         name[j] = '\0';
1569                         tr.name = string(name);
1570                         tr.index = tracknumber++;
1571
1572                         for (j = k; regionspertrack > 0 && j < len; j++) {
1573                                 for (l = j; l < len; l++) {
1574                                         if (    (ptfunxored[l  ] == 0x5a) &&
1575                                                 (ptfunxored[l+1] == 0x08)) {
1576                                                 j = l+1;
1577                                                 break;
1578                                         }
1579                                 }
1580
1581
1582                                 if (regionspertrack == 0) {
1583                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1584                                         break;
1585                                 } else {
1586
1587                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1588                                         vector<region_t>::iterator begin = regions.begin();
1589                                         vector<region_t>::iterator finish = regions.end();
1590                                         vector<region_t>::iterator found;
1591                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1592                                                 tr.reg = (*found);
1593                                         }
1594                                         i = l+16;
1595                                         offset = 0;
1596                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1597                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1598                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1599                                         offset |= (uint32_t)(ptfunxored[i]);
1600                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1601                                         if (tr.reg.length > 0) {
1602                                                 tracks.push_back(tr);
1603                                         }
1604                                         regionspertrack--;
1605                                 }
1606                         }
1607                 }
1608         }
1609 }