ptformat: Update to upstream master 4e653041
[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 void
721 PTFFormat::parsemidi(void) {
722         uint64_t tr, i, k, lastk, n_midi_events, zero_ticks;
723         uint64_t midi_pos, midi_len, max_pos, region_pos;
724         uint8_t midi_velocity, midi_note;
725         uint16_t ridx;
726         uint16_t nmiditracks, regionnumber = 0;
727         uint32_t nregions, mr;
728         struct mchunk_t {
729                 uint64_t zero;
730                 uint64_t maxlen;
731                 std::vector<midi_ev_t> chunk;
732         };
733         std::vector<struct mchunk_t> midichunks;
734         midi_ev_t m;
735         bool found = false;
736
737         // Find MdNLB
738         k = 0;
739         lastk = 0;
740
741         // Parse all midi chunks, not 1:1 mapping to regions yet
742         while (k + 35 < len) {
743                 found = false;
744                 max_pos = 0;
745                 std::vector<midi_ev_t> midi;
746
747                 while (k < len && !found) {
748                         if (            (ptfunxored[k  ] == 'M') &&
749                                         (ptfunxored[k+1] == 'd') &&
750                                         (ptfunxored[k+2] == 'N') &&
751                                         (ptfunxored[k+3] == 'L') &&
752                                         (ptfunxored[k+4] == 'B')) {
753                                 found = true;
754                                 lastk = k;
755                                 break;
756                         }
757                         k++;
758                 }
759
760                 if (!found) {
761                         k = lastk;
762                         break;
763                 }
764
765                 k += 11;
766                 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
767                                 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
768
769                 k += 4;
770                 zero_ticks = (uint64_t)ptfunxored[k] |
771                         (uint64_t)ptfunxored[k+1] << 8 |
772                         (uint64_t)ptfunxored[k+2] << 16 |
773                         (uint64_t)ptfunxored[k+3] << 24 |
774                         (uint64_t)ptfunxored[k+4] << 32;
775                 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
776                         midi_pos = (uint64_t)ptfunxored[k] |
777                                 (uint64_t)ptfunxored[k+1] << 8 |
778                                 (uint64_t)ptfunxored[k+2] << 16 |
779                                 (uint64_t)ptfunxored[k+3] << 24 |
780                                 (uint64_t)ptfunxored[k+4] << 32;
781                         midi_pos -= zero_ticks;
782                         midi_note = ptfunxored[k+8];
783                         midi_len = (uint64_t)ptfunxored[k+9] |
784                                 (uint64_t)ptfunxored[k+10] << 8 |
785                                 (uint64_t)ptfunxored[k+11] << 16 |
786                                 (uint64_t)ptfunxored[k+12] << 24 |
787                                 (uint64_t)ptfunxored[k+13] << 32;
788                         midi_velocity = ptfunxored[k+17];
789
790                         if (midi_pos + midi_len > max_pos) {
791                                 max_pos = midi_pos + midi_len;
792                         }
793
794                         m.pos = midi_pos;
795                         m.length = midi_len;
796                         m.note = midi_note;
797                         m.velocity = midi_velocity;
798 #if 1
799 // stop gap measure to prevent crashes in ardour,
800 // remove when decryption is fully solved for .ptx
801                         if ((m.velocity & 0x80) || (m.note & 0x80) ||
802                                         (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
803                                 continue;
804                         }
805 #endif
806                         midi.push_back(m);
807                 }
808                 midichunks.push_back({zero_ticks, max_pos, midi});
809         }
810
811         lastk = k;
812
813         // Map midi chunks to regions
814         while (k < len) {
815                 char midiregionname[256];
816                 uint8_t namelen;
817
818                 found = false;
819                 while (k < len && !found) {
820                         if (            (ptfunxored[k  ] == 'M') &&
821                                         (ptfunxored[k+1] == 'd') &&
822                                         (ptfunxored[k+2] == 'T') &&
823                                         (ptfunxored[k+3] == 'E') &&
824                                         (ptfunxored[k+4] == 'L')) {
825                                 found = true;
826                                 lastk = k;
827                                 break;
828                         }
829                         k++;
830                 }
831
832                 if (!found) {
833                         k = lastk;
834                         break;
835                 }
836
837                 k += 41;
838
839                 nregions = 0;
840                 nregions |= ptfunxored[k];
841                 nregions |= ptfunxored[k+1] << 8;
842
843                 for (mr = 0; mr < nregions; mr++) {
844                         found = false;
845                         while (k < len && !found) {
846                                 if (            (ptfunxored[k  ] == 0x5a) &&
847                                                 (ptfunxored[k+1] == 0x0c)) {
848                                         found = true;
849                                         lastk = k;
850                                         break;
851                                 }
852                                 k++;
853                         }
854
855                         if (!found) {
856                                 k = lastk;
857                                 break;
858                         }
859
860                         k += 9;
861
862                         namelen = ptfunxored[k];
863                         for (i = 0; i < namelen; i++) {
864                                 midiregionname[i] = ptfunxored[k+4+i];
865                         }
866                         midiregionname[namelen] = '\0';
867                         k += 4 + namelen;
868
869                         k += 5;
870                         /*
871                         region_pos = (uint64_t)ptfunxored[k] |
872                                         (uint64_t)ptfunxored[k+1] << 8 |
873                                         (uint64_t)ptfunxored[k+2] << 16 |
874                                         (uint64_t)ptfunxored[k+3] << 24 |
875                                         (uint64_t)ptfunxored[k+4] << 32;
876                         */
877                         found = false;
878                         while (k < len && !found) {
879                                 if (            (ptfunxored[k  ] == 0xfe) &&
880                                                 (ptfunxored[k+1] == 0xff) &&
881                                                 (ptfunxored[k+2] == 0xff) &&
882                                                 (ptfunxored[k+3] == 0xff)) {
883                                         found = true;
884                                         lastk = k;
885                                         break;
886                                 }
887                                 k++;
888                         }
889
890                         if (!found) {
891                                 k = lastk;
892                                 break;
893                         }
894
895                         k += 40;
896
897                         ridx = ptfunxored[k];
898                         ridx |= ptfunxored[k+1] << 8;
899
900                         struct mchunk_t mchunk = *(midichunks.begin()+ridx);
901
902                         wav_t w = { std::string(""), 0, 0, 0 };
903                         region_t r = {
904                                 midiregionname,
905                                 regionnumber++,
906                                 //(int64_t)mchunk.zero,
907                                 (int64_t)0xe8d4a51000ull,
908                                 (int64_t)(0),
909                                 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
910                                 (int64_t)mchunk.maxlen,
911                                 w,
912                                 mchunk.chunk,
913                         };
914                         midiregions.push_back(r);
915                 }
916         }
917
918         found = false;
919         // Put midi regions on midi tracks
920         while (k < len && !found) {
921                 if (            (ptfunxored[k  ] == 0x5a) &&
922                                 (ptfunxored[k+1] == 0x03)) {
923                         found = true;
924                         break;
925                 }
926                 k++;
927         }
928
929         if (!found)
930                 return;
931
932         k -= 4;
933
934         nmiditracks = 0;
935         nmiditracks |= ptfunxored[k];
936         nmiditracks |= ptfunxored[k+1] << 8;
937
938         k += 4;
939
940         for (tr = 0; tr < nmiditracks; tr++) {
941                 char miditrackname[256];
942                 uint8_t namelen;
943                 found = false;
944                 while (k < len && !found) {
945                         if (            (ptfunxored[k  ] == 0x5a) &&
946                                         (ptfunxored[k+1] == 0x03)) {
947                                 found = true;
948                                 break;
949                         }
950                         k++;
951                 }
952
953                 if (!found)
954                         return;
955
956                 namelen = ptfunxored[k+9];
957                 for (i = 0; i < namelen; i++) {
958                         miditrackname[i] = ptfunxored[k+13+i];
959                 }
960                 miditrackname[namelen] = '\0';
961                 k += 13 + namelen;
962                 nregions = 0;
963                 nregions |= ptfunxored[k];
964                 nregions |= ptfunxored[k+1] << 8;
965
966                 for (i = 0; (i < nregions) && (k < len); i++) {
967                         k += 24;
968
969                         ridx = 0;
970                         ridx |= ptfunxored[k];
971                         ridx |= ptfunxored[k+1] << 8;
972
973                         k += 5;
974
975                         region_pos = (uint64_t)ptfunxored[k] |
976                                         (uint64_t)ptfunxored[k+1] << 8 |
977                                         (uint64_t)ptfunxored[k+2] << 16 |
978                                         (uint64_t)ptfunxored[k+3] << 24 |
979                                         (uint64_t)ptfunxored[k+4] << 32;
980
981                         k += 20;
982
983                         track_t mtr;
984                         mtr.name = string(miditrackname);
985                         mtr.index = tr;
986                         mtr.playlist = 0;
987                         // Find the midi region with index 'ridx'
988                         std::vector<region_t>::iterator begin = midiregions.begin();
989                         std::vector<region_t>::iterator finish = midiregions.end();
990                         std::vector<region_t>::iterator mregion;
991                         wav_t w = { std::string(""), 0, 0, 0 };
992                         std::vector<midi_ev_t> m;
993                         region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
994                         if ((mregion = std::find(begin, finish, r)) != finish) {
995                                 mtr.reg = *mregion;
996                                 mtr.reg.startpos = std::labs(region_pos - mtr.reg.startpos);
997                                 miditracks.push_back(mtr);
998                         }
999                 }
1000         }
1001 }
1002
1003 void
1004 PTFFormat::parseaudio(void) {
1005         uint64_t i,j,k,l;
1006         int64_t index = foundat(ptfunxored, len, "Audio Files");
1007
1008         if (index < 0)
1009                 return;
1010
1011         // Find end of wav file list
1012         k = (uint64_t)index;
1013         while (k < len) {
1014                 if (            (ptfunxored[k  ] == 0xff) &&
1015                                 (ptfunxored[k+1] == 0xff) &&
1016                                 (ptfunxored[k+2] == 0xff) &&
1017                                 (ptfunxored[k+3] == 0xff)) {
1018                         break;
1019                 }
1020                 k++;
1021         }
1022
1023         // Find actual wav names
1024         bool first = true;
1025         uint16_t numberofwavs;
1026         char wavname[256];
1027         for (i = k-2; i > 4; i--) {
1028                 if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'A') || ptfunxored[i  ] == '\0') &&
1029                                 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I') || ptfunxored[i-1] == '\0') &&
1030                                 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F') || ptfunxored[i-2] == '\0') &&
1031                                 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F') || ptfunxored[i-3] == '\0')) {
1032                         j = i-4;
1033                         l = 0;
1034                         while (ptfunxored[j] != '\0') {
1035                                 wavname[l] = ptfunxored[j];
1036                                 l++;
1037                                 j--;
1038                         }
1039                         wavname[l] = 0;
1040                         if (ptfunxored[i] == 'A') {
1041                                 extension = string(".aif");
1042                         } else {
1043                                 extension = string(".wav");
1044                         }
1045                         //uint8_t playlist = ptfunxored[j-8];
1046
1047                         if (first) {
1048                                 first = false;
1049                                 for (j = k; j > 4; j--) {
1050                                         if (    (ptfunxored[j  ] == 0x01) &&
1051                                                 (ptfunxored[j-1] == 0x5a)) {
1052
1053                                                 numberofwavs = 0;
1054                                                 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
1055                                                 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
1056                                                 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
1057                                                 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
1058                                                 //printf("%d wavs\n", numberofwavs);
1059                                                 break;
1060                                         }
1061                                 k--;
1062                                 }
1063                         }
1064
1065                         std::string wave = string(wavname);
1066                         std::reverse(wave.begin(), wave.end());
1067                         wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
1068
1069                         if (foundin(wave, string(".grp"))) {
1070                                 continue;
1071                         }
1072
1073                         actualwavs.push_back(f);
1074
1075                         numberofwavs--;
1076                         if (numberofwavs <= 0)
1077                                 break;
1078                 }
1079         }
1080 }
1081
1082 void
1083 PTFFormat::parserest89(void) {
1084         uint64_t i,j,k,l;
1085         // Find Regions
1086         uint8_t startbytes = 0;
1087         uint8_t lengthbytes = 0;
1088         uint8_t offsetbytes = 0;
1089         uint8_t somethingbytes = 0;
1090         uint8_t skipbytes = 0;
1091
1092         k = 0;
1093         while (k < len) {
1094                 if (            (ptfunxored[k  ] == 'S') &&
1095                                 (ptfunxored[k+1] == 'n') &&
1096                                 (ptfunxored[k+2] == 'a') &&
1097                                 (ptfunxored[k+3] == 'p')) {
1098                         break;
1099                 }
1100                 k++;
1101         }
1102         uint16_t rindex = 0;
1103         uint32_t findex = 0;
1104         for (i = k; i < len-70; i++) {
1105                 if (            (ptfunxored[i  ] == 0x5a) &&
1106                                 (ptfunxored[i+1] == 0x0a)) {
1107                                 break;
1108                 }
1109                 if (            (ptfunxored[i  ] == 0x5a) &&
1110                                 (ptfunxored[i+1] == 0x0c)) {
1111
1112                         uint8_t lengthofname = ptfunxored[i+9];
1113
1114                         char name[256] = {0};
1115                         for (j = 0; j < lengthofname; j++) {
1116                                 name[j] = ptfunxored[i+13+j];
1117                         }
1118                         name[j] = '\0';
1119                         j += i+13;
1120                         //uint8_t disabled = ptfunxored[j];
1121
1122                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1123                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1124                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1125                         somethingbytes = (ptfunxored[j+3] & 0xf);
1126                         skipbytes = ptfunxored[j+4];
1127                         findex = ptfunxored[j+5
1128                                         +startbytes
1129                                         +lengthbytes
1130                                         +offsetbytes
1131                                         +somethingbytes
1132                                         +skipbytes
1133                                         +40];
1134                         /*rindex = ptfunxored[j+5
1135                                         +startbytes
1136                                         +lengthbytes
1137                                         +offsetbytes
1138                                         +somethingbytes
1139                                         +skipbytes
1140                                         +24];
1141                         */
1142                         uint32_t sampleoffset = 0;
1143                         switch (offsetbytes) {
1144                         case 4:
1145                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1146                         case 3:
1147                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1148                         case 2:
1149                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1150                         case 1:
1151                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1152                         default:
1153                                 break;
1154                         }
1155                         j+=offsetbytes;
1156                         uint32_t length = 0;
1157                         switch (lengthbytes) {
1158                         case 4:
1159                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1160                         case 3:
1161                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1162                         case 2:
1163                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1164                         case 1:
1165                                 length |= (uint32_t)(ptfunxored[j+5]);
1166                         default:
1167                                 break;
1168                         }
1169                         j+=lengthbytes;
1170                         uint32_t start = 0;
1171                         switch (startbytes) {
1172                         case 4:
1173                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1174                         case 3:
1175                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1176                         case 2:
1177                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1178                         case 1:
1179                                 start |= (uint32_t)(ptfunxored[j+5]);
1180                         default:
1181                                 break;
1182                         }
1183                         j+=startbytes;
1184                         /*
1185                         uint32_t something = 0;
1186                         switch (somethingbytes) {
1187                         case 4:
1188                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1189                         case 3:
1190                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1191                         case 2:
1192                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1193                         case 1:
1194                                 something |= (uint32_t)(ptfunxored[j+5]);
1195                         default:
1196                                 break;
1197                         }
1198                         j+=somethingbytes;
1199                         */
1200                         std::string filename = string(name) + extension;
1201                         wav_t f = {
1202                                 filename,
1203                                 0,
1204                                 (int64_t)(start*ratefactor),
1205                                 (int64_t)(length*ratefactor),
1206                         };
1207
1208                         f.index = findex;
1209                         //printf("something=%d\n", something);
1210
1211                         vector<wav_t>::iterator begin = actualwavs.begin();
1212                         vector<wav_t>::iterator finish = actualwavs.end();
1213                         vector<wav_t>::iterator found;
1214                         // Add file to list only if it is an actual wav
1215                         if ((found = std::find(begin, finish, f)) != finish) {
1216                                 audiofiles.push_back(f);
1217                                 // Also add plain wav as region
1218                                 std::vector<midi_ev_t> m;
1219                                 region_t r = {
1220                                         name,
1221                                         rindex,
1222                                         (int64_t)(start*ratefactor),
1223                                         (int64_t)(sampleoffset*ratefactor),
1224                                         (int64_t)(length*ratefactor),
1225                                         f,
1226                                         m
1227                                 };
1228                                 regions.push_back(r);
1229                         // Region only
1230                         } else {
1231                                 if (foundin(filename, string(".grp"))) {
1232                                         continue;
1233                                 }
1234                                 std::vector<midi_ev_t> m;
1235                                 region_t r = {
1236                                         name,
1237                                         rindex,
1238                                         (int64_t)(start*ratefactor),
1239                                         (int64_t)(sampleoffset*ratefactor),
1240                                         (int64_t)(length*ratefactor),
1241                                         f,
1242                                         m
1243                                 };
1244                                 regions.push_back(r);
1245                         }
1246                         rindex++;
1247                 }
1248         }
1249
1250         while (k < len) {
1251                 if (            (ptfunxored[k  ] == 0x5a) &&
1252                                 (ptfunxored[k+1] == 0x03)) {
1253                                 break;
1254                 }
1255                 k++;
1256         }
1257         while (k < len) {
1258                 if (            (ptfunxored[k  ] == 0x5a) &&
1259                                 (ptfunxored[k+1] == 0x02)) {
1260                                 break;
1261                 }
1262                 k++;
1263         }
1264         k++;
1265
1266         //  Tracks
1267         uint32_t offset;
1268         uint32_t tracknumber = 0;
1269         uint32_t regionspertrack = 0;
1270         for (;k < len; k++) {
1271                 if (    (ptfunxored[k  ] == 0x5a) &&
1272                         (ptfunxored[k+1] == 0x04)) {
1273                         break;
1274                 }
1275                 if (    (ptfunxored[k  ] == 0x5a) &&
1276                         (ptfunxored[k+1] == 0x02)) {
1277
1278                         uint8_t lengthofname = 0;
1279                         lengthofname = ptfunxored[k+9];
1280                         if (lengthofname == 0x5a) {
1281                                 continue;
1282                         }
1283                         track_t tr;
1284
1285                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1286
1287                         //printf("regions/track=%d\n", regionspertrack);
1288                         char name[256] = {0};
1289                         for (j = 0; j < lengthofname; j++) {
1290                                 name[j] = ptfunxored[j+k+13];
1291                         }
1292                         name[j] = '\0';
1293                         tr.name = string(name);
1294                         tr.index = tracknumber++;
1295
1296                         for (j = k; regionspertrack > 0 && j < len; j++) {
1297                                 for (l = j; l < len; l++) {
1298                                         if (    (ptfunxored[l  ] == 0x5a) &&
1299                                                 (ptfunxored[l+1] == 0x07)) {
1300                                                 j = l;
1301                                                 break;
1302                                         }
1303                                 }
1304
1305
1306                                 if (regionspertrack == 0) {
1307                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1308                                         break;
1309                                 } else {
1310
1311                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1312                                         vector<region_t>::iterator begin = regions.begin();
1313                                         vector<region_t>::iterator finish = regions.end();
1314                                         vector<region_t>::iterator found;
1315                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1316                                                 tr.reg = (*found);
1317                                         }
1318                                         i = l+16;
1319                                         offset = 0;
1320                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1321                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1322                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1323                                         offset |= (uint32_t)(ptfunxored[i]);
1324                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1325                                         if (tr.reg.length > 0) {
1326                                                 tracks.push_back(tr);
1327                                         }
1328                                         regionspertrack--;
1329                                 }
1330                         }
1331                 }
1332         }
1333 }
1334
1335 void
1336 PTFFormat::parserest10(void) {
1337         uint64_t i,j,k,l;
1338         // Find Regions
1339         uint8_t startbytes = 0;
1340         uint8_t lengthbytes = 0;
1341         uint8_t offsetbytes = 0;
1342         uint8_t somethingbytes = 0;
1343         uint8_t skipbytes = 0;
1344
1345         k = 0;
1346         while (k < len) {
1347                 if (            (ptfunxored[k  ] == 'S') &&
1348                                 (ptfunxored[k+1] == 'n') &&
1349                                 (ptfunxored[k+2] == 'a') &&
1350                                 (ptfunxored[k+3] == 'p')) {
1351                         break;
1352                 }
1353                 k++;
1354         }
1355         for (i = k; i < len-70; i++) {
1356                 if (            (ptfunxored[i  ] == 0x5a) &&
1357                                 (ptfunxored[i+1] == 0x02)) {
1358                                 k = i;
1359                                 break;
1360                 }
1361         }
1362         k++;
1363         for (i = k; i < len-70; i++) {
1364                 if (            (ptfunxored[i  ] == 0x5a) &&
1365                                 (ptfunxored[i+1] == 0x02)) {
1366                                 k = i;
1367                                 break;
1368                 }
1369         }
1370         k++;
1371         uint16_t rindex = 0;
1372         uint32_t findex = 0;
1373         for (i = k; i < len-70; i++) {
1374                 if (            (ptfunxored[i  ] == 0x5a) &&
1375                                 (ptfunxored[i+1] == 0x08)) {
1376                                 break;
1377                 }
1378                 if (            (ptfunxored[i  ] == 0x5a) &&
1379                                 (ptfunxored[i+1] == 0x01)) {
1380
1381                         uint8_t lengthofname = ptfunxored[i+9];
1382                         if (ptfunxored[i+13] == 0x5a) {
1383                                 continue;
1384                         }
1385                         char name[256] = {0};
1386                         for (j = 0; j < lengthofname; j++) {
1387                                 name[j] = ptfunxored[i+13+j];
1388                         }
1389                         name[j] = '\0';
1390                         j += i+13;
1391                         //uint8_t disabled = ptfunxored[j];
1392                         //printf("%s\n", name);
1393
1394                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1395                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1396                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1397                         somethingbytes = (ptfunxored[j+3] & 0xf);
1398                         skipbytes = ptfunxored[j+4];
1399                         findex = ptfunxored[j+5
1400                                         +startbytes
1401                                         +lengthbytes
1402                                         +offsetbytes
1403                                         +somethingbytes
1404                                         +skipbytes
1405                                         +37];
1406                         /*rindex = ptfunxored[j+5
1407                                         +startbytes
1408                                         +lengthbytes
1409                                         +offsetbytes
1410                                         +somethingbytes
1411                                         +skipbytes
1412                                         +24];
1413                         */
1414                         uint32_t sampleoffset = 0;
1415                         switch (offsetbytes) {
1416                         case 4:
1417                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1418                         case 3:
1419                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1420                         case 2:
1421                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1422                         case 1:
1423                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1424                         default:
1425                                 break;
1426                         }
1427                         j+=offsetbytes;
1428                         uint32_t length = 0;
1429                         switch (lengthbytes) {
1430                         case 4:
1431                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1432                         case 3:
1433                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1434                         case 2:
1435                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1436                         case 1:
1437                                 length |= (uint32_t)(ptfunxored[j+5]);
1438                         default:
1439                                 break;
1440                         }
1441                         j+=lengthbytes;
1442                         uint32_t start = 0;
1443                         switch (startbytes) {
1444                         case 4:
1445                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1446                         case 3:
1447                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1448                         case 2:
1449                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1450                         case 1:
1451                                 start |= (uint32_t)(ptfunxored[j+5]);
1452                         default:
1453                                 break;
1454                         }
1455                         j+=startbytes;
1456                         /*
1457                         uint32_t something = 0;
1458                         switch (somethingbytes) {
1459                         case 4:
1460                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1461                         case 3:
1462                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1463                         case 2:
1464                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1465                         case 1:
1466                                 something |= (uint32_t)(ptfunxored[j+5]);
1467                         default:
1468                                 break;
1469                         }
1470                         j+=somethingbytes;
1471                         */
1472                         std::string filename = string(name) + extension;
1473                         wav_t f = {
1474                                 filename,
1475                                 0,
1476                                 (int64_t)(start*ratefactor),
1477                                 (int64_t)(length*ratefactor),
1478                         };
1479
1480                         if (strlen(name) == 0) {
1481                                 continue;
1482                         }
1483                         if (length == 0) {
1484                                 continue;
1485                         }
1486                         f.index = findex;
1487                         //printf("something=%d\n", something);
1488
1489                         vector<wav_t>::iterator begin = actualwavs.begin();
1490                         vector<wav_t>::iterator finish = actualwavs.end();
1491                         vector<wav_t>::iterator found;
1492                         // Add file to list only if it is an actual wav
1493                         if ((found = std::find(begin, finish, f)) != finish) {
1494                                 audiofiles.push_back(f);
1495                                 // Also add plain wav as region
1496                                 std::vector<midi_ev_t> m;
1497                                 region_t r = {
1498                                         name,
1499                                         rindex,
1500                                         (int64_t)(start*ratefactor),
1501                                         (int64_t)(sampleoffset*ratefactor),
1502                                         (int64_t)(length*ratefactor),
1503                                         f,
1504                                         m
1505                                 };
1506                                 regions.push_back(r);
1507                         // Region only
1508                         } else {
1509                                 if (foundin(filename, string(".grp"))) {
1510                                         continue;
1511                                 }
1512                                 std::vector<midi_ev_t> m;
1513                                 region_t r = {
1514                                         name,
1515                                         rindex,
1516                                         (int64_t)(start*ratefactor),
1517                                         (int64_t)(sampleoffset*ratefactor),
1518                                         (int64_t)(length*ratefactor),
1519                                         f,
1520                                         m
1521                                 };
1522                                 regions.push_back(r);
1523                         }
1524                         rindex++;
1525                         //printf("%s\n", name);
1526                 }
1527         }
1528         //  Tracks
1529         uint32_t offset;
1530         uint32_t tracknumber = 0;
1531         uint32_t regionspertrack = 0;
1532         for (;k < len; k++) {
1533                 if (    (ptfunxored[k  ] == 0x5a) &&
1534                         (ptfunxored[k+1] == 0x08)) {
1535                         break;
1536                 }
1537         }
1538         k++;
1539         for (;k < len; k++) {
1540                 if (    (ptfunxored[k  ] == 0x5a) &&
1541                         (ptfunxored[k+1] == 0x04)) {
1542                         break;
1543                 }
1544                 if (    (ptfunxored[k  ] == 0x5a) &&
1545                         (ptfunxored[k+1] == 0x02)) {
1546
1547                         uint8_t lengthofname = 0;
1548                         lengthofname = ptfunxored[k+9];
1549                         if (lengthofname == 0x5a) {
1550                                 continue;
1551                         }
1552                         track_t tr;
1553
1554                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1555
1556                         //printf("regions/track=%d\n", regionspertrack);
1557                         char name[256] = {0};
1558                         for (j = 0; j < lengthofname; j++) {
1559                                 name[j] = ptfunxored[j+k+13];
1560                         }
1561                         name[j] = '\0';
1562                         tr.name = string(name);
1563                         tr.index = tracknumber++;
1564
1565                         for (j = k; regionspertrack > 0 && j < len; j++) {
1566                                 for (l = j; l < len; l++) {
1567                                         if (    (ptfunxored[l  ] == 0x5a) &&
1568                                                 (ptfunxored[l+1] == 0x08)) {
1569                                                 j = l+1;
1570                                                 break;
1571                                         }
1572                                 }
1573
1574
1575                                 if (regionspertrack == 0) {
1576                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1577                                         break;
1578                                 } else {
1579
1580                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1581                                         vector<region_t>::iterator begin = regions.begin();
1582                                         vector<region_t>::iterator finish = regions.end();
1583                                         vector<region_t>::iterator found;
1584                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1585                                                 tr.reg = (*found);
1586                                         }
1587                                         i = l+16;
1588                                         offset = 0;
1589                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1590                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1591                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1592                                         offset |= (uint32_t)(ptfunxored[i]);
1593                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1594                                         if (tr.reg.length > 0) {
1595                                                 tracks.push_back(tr);
1596                                         }
1597                                         regionspertrack--;
1598                                 }
1599                         }
1600                 }
1601         }
1602 }