97a18c1fd5eb6f2ded69c0c9e033cd6ac60a2025
[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 "ptfformat.h"
18
19 #include <stdio.h>
20 #include <string>
21 #include <string.h>
22 #include <assert.h>
23
24 using namespace std;
25
26 static const uint32_t baselut[16] = {
27         0xaaaaaaaa, 0xaa955555, 0xa9554aaa, 0xa552a955,
28         0xb56ad5aa, 0x95a95a95, 0x94a5294a, 0x9696b4b5,
29         0xd2d25a5a, 0xd24b6d25, 0xdb6db6da, 0xd9249b6d,
30         0xc9b64d92, 0xcd93264d, 0xccd99b32, 0xcccccccd
31 };
32
33 static const uint32_t xorlut[16] = {
34         0x00000000, 0x00000b00, 0x000100b0, 0x00b0b010,
35         0x010b0b01, 0x0b10b10b, 0x01bb101b, 0x0111bbbb,
36         0x1111bbbb, 0x1bbb10bb, 0x1bb0bb0b, 0xbb0b0bab,
37         0xbab0b0ba, 0xb0abaaba, 0xba0aabaa, 0xbaaaaaaa
38 };
39
40 static uint32_t swapbytes32 (const uint32_t v) {
41         uint32_t rv = 0;
42         rv |= ((v >>  0) & 0xf) << 28;
43         rv |= ((v >>  4) & 0xf) << 24;
44         rv |= ((v >>  8) & 0xf) << 20;
45         rv |= ((v >> 12) & 0xf) << 16;
46         rv |= ((v >> 16) & 0xf) << 12;
47         rv |= ((v >> 20) & 0xf) <<  8;
48         rv |= ((v >> 24) & 0xf) <<  4;
49         rv |= ((v >> 28) & 0xf) <<  0;
50         return rv;
51 }
52
53 static uint64_t gen_secret (int i) {
54         assert (i > 0 && i < 256);
55         int iwrap = i & 0x7f; // wrap at 0x80;
56         uint32_t xor_lo = 0;  // 0x40 flag
57         int idx;              // mirror at 0x40;
58
59         if (iwrap & 0x40) {
60                 xor_lo = 0x1;
61                 idx    = 0x80 - iwrap;
62         } else {
63                 idx    = iwrap;
64         }
65
66         int i16 = (idx >> 1) & 0xf;
67         if (idx & 0x20) {
68                 i16 = 15 - i16;
69         }
70
71         uint32_t lo = baselut [i16];
72         uint32_t xk = xorlut  [i16];
73
74         if (idx & 0x20) {
75                 lo ^= 0xaaaaaaab;
76                 xk ^= 0x10000000; 
77         }
78         uint32_t hi = swapbytes32 (lo) ^ xk;
79         return  ((uint64_t)hi << 32) | (lo ^ xor_lo);
80 }
81
82 PTFFormat::PTFFormat() {
83 }
84
85 PTFFormat::~PTFFormat() {
86         if (ptfunxored) {
87                 free(ptfunxored);
88         }
89 }
90
91 bool
92 PTFFormat::foundin(std::string haystack, std::string needle) {
93         size_t found = haystack.find(needle);
94         if (found != std::string::npos) {
95                 return true;
96         } else {
97                 return false;
98         }
99 }
100
101 /* Return values:       0            success
102                         0x01 to 0xff value of missing lut
103                         -1           could not open file as ptf
104 */
105 int
106 PTFFormat::load(std::string path, int64_t targetsr) {
107         FILE *fp;
108         unsigned char xxor[256];
109         unsigned char ct;
110         unsigned char px;
111         uint64_t key;
112         uint16_t i;
113         int j;
114         int inv;
115         unsigned char message;
116
117         if (! (fp = fopen(path.c_str(), "rb"))) {
118                 return -1;
119         }
120
121         fseek(fp, 0, SEEK_END);
122         len = ftell(fp);
123         if (len < 0x40) {
124                 fclose(fp);
125                 return -1;
126         }
127         fseek(fp, 0x40, SEEK_SET);
128         fread(&c0, 1, 1, fp);
129         fread(&c1, 1, 1, fp);
130
131         // For version <= 7 support:
132         version = c0 & 0x0f;
133         c0 = c0 & 0xc0;
134
135         if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
136                 /* Silently fail -- out of memory*/
137                 fclose(fp);
138                 ptfunxored = 0;
139                 return -1;
140         }
141
142         fseek(fp, 0x0, SEEK_SET);
143
144         switch (c0) {
145         case 0x00:
146                 // Success! easy one
147                 xxor[0] = c0;
148                 xxor[1] = c1;
149                 //fprintf(stderr, "%02x %02x", c0, c1);
150
151                 for (i = 2; i < 64; i++) {
152                         xxor[i] = (xxor[i-1] + c1 - c0) & 0xff;
153                         //fprintf(stderr, "%02x ", xxor[i]);
154                 }
155                 px = xxor[0];
156                 fread(&ct, 1, 1, fp);
157                 message = px ^ ct;
158                 ptfunxored[0] = message;
159                 px  = xxor[1];
160                 fread(&ct, 1, 1, fp);
161                 message = px ^ ct;
162                 ptfunxored[1] = message;
163                 i = 2;
164                 j = 2;
165                 while (fread(&ct, 1, 1, fp) != 0) {
166                         if (i%64 == 0) {
167                                 i = 0;
168                         }
169                         message = xxor[i] ^ ct;
170                         ptfunxored[j] = message;
171                         i++;
172                         j++;
173                 }
174                 break;
175         case 0x80:
176                 //Success! easy two
177                 xxor[0] = c0;
178                 xxor[1] = c1;
179                 for (i = 2; i < 256; i++) {
180                         if (i%64 == 0) {
181                                 xxor[i] = c0;
182                         } else {
183                                 xxor[i] = ((xxor[i-1] + c1 - c0) & 0xff);
184                         }
185                 }
186                 for (i = 0; i < 64; i++) {
187                         xxor[i] ^= 0x80;
188                 }
189                 for (i = 128; i < 192; i++) {
190                         xxor[i] ^= 0x80;
191                 }
192                 px = xxor[0];
193                 fread(&ct, 1, 1, fp);
194                 message = px ^ ct;
195                 ptfunxored[0] = message;
196                 px  = xxor[1];
197                 fread(&ct, 1, 1, fp);
198                 message = px ^ ct;
199                 ptfunxored[1] = message;
200                 i = 2;
201                 j = 2;
202                 while (fread(&ct, 1, 1, fp) != 0) {
203                         if (i%256 == 0) {
204                                 i = 0;
205                         }
206                         message = xxor[i] ^ ct;
207                         ptfunxored[j] = message;
208                         i++;
209                         j++;
210                 }
211                 break;
212         case 0x40:
213         case 0xc0:
214                 xxor[0] = c0;
215                 xxor[1] = c1;
216                 for (i = 2; i < 256; i++) {
217                         if (i%64 == 0) {
218                                 xxor[i] = c0;
219                         } else {
220                                 xxor[i] = ((xxor[i-1] + c1 - c0) & 0xff);
221                         }
222                 }
223
224                 key = gen_secret(c1);
225                 for (i = 0; i < 64; i++) {
226                         xxor[i] ^= (((key >> i) & 1) * 2 * 0x40) + 0x40;
227                 }
228                 for (i = 128; i < 192; i++) {
229                         inv = (((key >> (i-128)) & 1) == 1) ? 1 : 3;
230                         xxor[i] ^= (inv * 0x40);
231                 }
232
233                 for (i = 192; i < 256; i++) {
234                         xxor[i] ^= 0x80;
235                 }
236                 px = xxor[0];
237                 fread(&ct, 1, 1, fp);
238                 message = px ^ ct;
239                 ptfunxored[0] = message;
240                 px  = xxor[1];
241                 fread(&ct, 1, 1, fp);
242                 message = px ^ ct;
243                 ptfunxored[1] = message;
244                 i = 2;
245                 j = 2;
246                 while (fread(&ct, 1, 1, fp) != 0) {
247                         if (i%256 == 0) {
248                                 i = 0;
249                         }
250                         message = xxor[i] ^ ct;
251                         ptfunxored[j] = message;
252                         i++;
253                         j++;
254                 }
255                 break;
256                 break;
257         default:
258                 //Should not happen, failed c[0] c[1]
259                 return -1;
260                 break;
261         }
262         fclose(fp);
263         targetrate = targetsr;
264         parse();
265         return 0;
266 }
267
268 void
269 PTFFormat::unxor10(void)
270 {
271         key10a = ptfunxored[0x9f];
272         key10b = ptfunxored[0x9e] - ptfunxored[0x9b];
273         int j, k, currkey;
274
275         k = 0x1000;
276         for (j = k; j < k + 0x1000 && j < len; j++) {
277                 ptfunxored[j] ^= key10a;
278         }
279         k = 0x2000;
280         for (j = k; j < k + 0x1000 && j < len; j++) {
281                 ptfunxored[j] ^= key10b;
282         }
283         currkey = key10b;
284         while (k < len) {
285                 k += 0x1000;
286                 currkey = (key10a + currkey) & 0xff;
287                 for (j = k; j < k + 0x1000 && j < len; j++) {
288                         ptfunxored[j] ^= currkey;
289                 }
290         }
291 }
292
293 void
294 PTFFormat::parse(void) {
295         version = (version == 0) ? ptfunxored[61] : version;
296
297         if (version == 5) {
298                 parse5header();
299                 setrates();
300                 parseaudio5();
301                 parserest5();
302         } else if (version == 7) {
303                 parse7header();
304                 setrates();
305                 parseaudio();
306                 parserest89();
307         } else if (version == 8) {
308                 parse8header();
309                 setrates();
310                 parseaudio();
311                 parserest89();
312         } else if (version == 9) {
313                 parse9header();
314                 setrates();
315                 parseaudio();
316                 parserest89();
317         } else if (version == 10) {
318                 unxor10();
319                 parse10header();
320                 setrates();
321                 parseaudio();
322                 parserest10();
323         } else {
324                 // Should not occur
325         }
326 }
327
328 void
329 PTFFormat::setrates(void) {
330         ratefactor = 1.f;
331         if (sessionrate != 0) {
332                 ratefactor = (float)targetrate / sessionrate;
333         }
334 }
335
336 void
337 PTFFormat::parse5header(void) {
338         int k;
339
340         // Find session sample rate
341         k = 0x100;
342         while (k < len) {
343                 if (            (ptfunxored[k  ] == 0x5a) &&
344                                 (ptfunxored[k+1] == 0x00) &&
345                                 (ptfunxored[k+2] == 0x02)) {
346                         break;
347                 }
348                 k++;
349         }
350
351         sessionrate = 0;
352         sessionrate |= ptfunxored[k+12] << 16;
353         sessionrate |= ptfunxored[k+13] << 8;
354         sessionrate |= ptfunxored[k+14];
355 }
356
357 void
358 PTFFormat::parse7header(void) {
359         int k;
360
361         // Find session sample rate
362         k = 0x100;
363         while (k < len) {
364                 if (            (ptfunxored[k  ] == 0x5a) &&
365                                 (ptfunxored[k+1] == 0x00) &&
366                                 (ptfunxored[k+2] == 0x05)) {
367                         break;
368                 }
369                 k++;
370         }
371
372         sessionrate = 0;
373         sessionrate |= ptfunxored[k+12] << 16;
374         sessionrate |= ptfunxored[k+13] << 8;
375         sessionrate |= ptfunxored[k+14];
376 }
377
378 void
379 PTFFormat::parse8header(void) {
380         int k;
381
382         // Find session sample rate
383         k = 0;
384         while (k < len) {
385                 if (            (ptfunxored[k  ] == 0x5a) &&
386                                 (ptfunxored[k+1] == 0x05)) {
387                         break;
388                 }
389                 k++;
390         }
391
392         sessionrate = 0;
393         sessionrate |= ptfunxored[k+11];
394         sessionrate |= ptfunxored[k+12] << 8;
395         sessionrate |= ptfunxored[k+13] << 16;
396 }
397
398 void
399 PTFFormat::parse9header(void) {
400         int k;
401
402         // Find session sample rate
403         k = 0x100;
404         while (k < len) {
405                 if (            (ptfunxored[k  ] == 0x5a) &&
406                                 (ptfunxored[k+1] == 0x06)) {
407                         break;
408                 }
409                 k++;
410         }
411
412         sessionrate = 0;
413         sessionrate |= ptfunxored[k+11];
414         sessionrate |= ptfunxored[k+12] << 8;
415         sessionrate |= ptfunxored[k+13] << 16;
416 }
417
418 void
419 PTFFormat::parse10header(void) {
420         int k;
421
422         // Find session sample rate
423         k = 0;
424         while (k < len) {
425                 if (            (ptfunxored[k  ] == 0x5a) &&
426                                 (ptfunxored[k+1] == 0x09)) {
427                         break;
428                 }
429                 k++;
430         }
431
432         sessionrate = 0;
433         sessionrate |= ptfunxored[k+11];
434         sessionrate |= ptfunxored[k+12] << 8;
435         sessionrate |= ptfunxored[k+13] << 16;
436 }
437
438 void
439 PTFFormat::parserest5(void) {
440         int i, j, k;
441         int regionspertrack, lengthofname;
442         int startbytes, lengthbytes, offsetbytes, somethingbytes;
443         uint16_t tracknumber = 0;
444         uint16_t findex;
445         uint16_t rindex;
446
447         k = 0;
448         for (i = 0; i < 5; i++) {
449                 while (k < len) {
450                         if (            (ptfunxored[k  ] == 0x5a) &&
451                                         (ptfunxored[k+1] == 0x00) &&
452                                         (ptfunxored[k+2] == 0x03)) {
453                                 break;
454                         }
455                         k++;
456                 }
457                 k++;
458         }
459         k--;
460
461         for (i = 0; i < 2; i++) {
462                 while (k > 0) {
463                         if (            (ptfunxored[k  ] == 0x5a) &&
464                                         (ptfunxored[k+1] == 0x00) &&
465                                         (ptfunxored[k+2] == 0x01)) {
466                                 break;
467                         }
468                         k--;
469                 }
470                 k--;
471         }
472         k++;
473
474         rindex = 0;
475         while (k < len) {
476                 if (            (ptfunxored[k  ] == 0xff) &&
477                                 (ptfunxored[k+1] == 0xff)) {
478                         break;
479                 }
480                 while (k < len) {
481                         if (            (ptfunxored[k  ] == 0x5a) &&
482                                         (ptfunxored[k+1] == 0x00) &&
483                                         (ptfunxored[k+2] == 0x01)) {
484                                 break;
485                         }
486                         k++;
487                 }
488
489                 lengthofname = ptfunxored[k+12];
490                 if (ptfunxored[k+13] == 0x5a) {
491                         k++;
492                         break;
493                 }
494                 char name[256] = {0};
495                 for (j = 0; j < lengthofname; j++) {
496                         name[j] = ptfunxored[k+13+j];
497                 }
498                 name[j] = '\0';
499                 regionspertrack = ptfunxored[k+13+j+3];
500                 for (i = 0; i < regionspertrack; i++) {
501                         while (k < len) {
502                                 if (            (ptfunxored[k  ] == 0x5a) &&
503                                                 (ptfunxored[k+1] == 0x00) &&
504                                                 (ptfunxored[k+2] == 0x03)) {
505                                         break;
506                                 }
507                                 k++;
508                         }
509                         j = k+16;
510                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
511                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
512                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
513                         somethingbytes = (ptfunxored[j+1] & 0xf);
514                         findex = ptfunxored[j+4
515                                         +startbytes
516                                         +lengthbytes
517                                         +offsetbytes
518                                         +somethingbytes
519                                         ];
520                         j--;
521                         uint32_t start = 0;
522                         switch (startbytes) {
523                         case 4:
524                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
525                         case 3:
526                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
527                         case 2:
528                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
529                         case 1:
530                                 start |= (uint32_t)(ptfunxored[j+5]);
531                         default:
532                                 break;
533                         }
534                         j+=startbytes;
535                         uint32_t length = 0;
536                         switch (lengthbytes) {
537                         case 4:
538                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
539                         case 3:
540                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
541                         case 2:
542                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
543                         case 1:
544                                 length |= (uint32_t)(ptfunxored[j+5]);
545                         default:
546                                 break;
547                         }
548                         j+=lengthbytes;
549                         uint32_t sampleoffset = 0;
550                         switch (offsetbytes) {
551                         case 4:
552                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
553                         case 3:
554                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
555                         case 2:
556                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
557                         case 1:
558                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
559                         default:
560                                 break;
561                         }
562                         j+=offsetbytes;
563
564                         //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
565
566                         std::string filename = string(name) + extension;
567                         wav_t f = { 
568                                 filename,
569                                 findex,
570                                 (int64_t)(start*ratefactor),
571                                 (int64_t)(length*ratefactor),
572                         };
573
574                         vector<wav_t>::iterator begin = audiofiles.begin();
575                         vector<wav_t>::iterator finish = audiofiles.end();
576                         vector<wav_t>::iterator found;
577                         // Add file to lists
578                         if ((found = std::find(begin, finish, f)) != finish) {
579                                 region_t r = {
580                                         name,
581                                         rindex,
582                                         (int64_t)(start*ratefactor),
583                                         (int64_t)(sampleoffset*ratefactor),
584                                         (int64_t)(length*ratefactor),
585                                         *found,
586                                 };
587                                 regions.push_back(r);
588                                 vector<track_t>::iterator ti;
589                                 vector<track_t>::iterator bt = tracks.begin();
590                                 vector<track_t>::iterator et = tracks.end();
591                                 track_t tr = { name, 0, 0, r };
592                                 if ((ti = std::find(bt, et, tr)) != et) {
593                                         tracknumber = (*ti).index;
594                                 } else {
595                                         tracknumber = tracks.size() + 1;
596                                 }
597                                 track_t t = {
598                                         name,
599                                         (uint16_t)tracknumber,
600                                         uint8_t(0),
601                                         r
602                                 };
603                                 tracks.push_back(t);
604                         } else {
605                                 audiofiles.push_back(f);
606                                 region_t r = {
607                                         name,
608                                         rindex,
609                                         (int64_t)(start*ratefactor),
610                                         (int64_t)(sampleoffset*ratefactor),
611                                         (int64_t)(length*ratefactor),
612                                         f,
613                                 };
614                                 regions.push_back(r);
615                                 vector<track_t>::iterator ti;
616                                 vector<track_t>::iterator bt = tracks.begin();
617                                 vector<track_t>::iterator et = tracks.end();
618                                 track_t tr = { name, 0, 0, r };
619                                 if ((ti = std::find(bt, et, tr)) != et) {
620                                         tracknumber = (*ti).index;
621                                 } else {
622                                         tracknumber = tracks.size() + 1;
623                                 }
624                                 track_t t = {
625                                         name,
626                                         (uint16_t)tracknumber,
627                                         uint8_t(0),
628                                         r
629                                 };
630                                 tracks.push_back(t);
631                         }
632                         rindex++;
633                         k++;
634                 }
635                 k++;
636         }
637 }
638
639 void
640 PTFFormat::parseaudio5(void) {
641         int i,j,k,l;
642
643         // Find end of wav file list
644         k = 0;
645         while (k < len) {
646                 if (            (ptfunxored[k  ] == 0x5a) &&
647                                 (ptfunxored[k+1] == 0x00) &&
648                                 (ptfunxored[k+2] == 0x05)) {
649                         break;
650                 }
651                 k++;
652         }
653
654         // Find actual wav names
655         bool first = true;
656         uint16_t numberofwavs;
657         char wavname[256];
658         for (i = k; i > 4; i--) {
659                 if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'F')) &&
660                                 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'F')) &&
661                                 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'I')) &&
662                                 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'A'))) {
663                         j = i-4;
664                         l = 0;
665                         while (ptfunxored[j] != '\0') {
666                                 wavname[l] = ptfunxored[j];
667                                 l++;
668                                 j--;
669                         }
670                         wavname[l] = 0;
671                         if (ptfunxored[i] == 'W') {
672                                 extension = string(".wav");
673                         } else {
674                                 extension = string(".aif");
675                         }
676                         //uint8_t playlist = ptfunxored[j-8];
677
678                         if (first) {
679                                 first = false;
680                                 for (j = k; j > 4; j--) {
681                                         if (    (ptfunxored[j  ] == 0x01) &&
682                                                 (ptfunxored[j-1] == 0x00) &&
683                                                 (ptfunxored[j-2] == 0x5a)) {
684
685                                                 numberofwavs = 0;
686                                                 numberofwavs |= (uint32_t)(ptfunxored[j-6] << 24);
687                                                 numberofwavs |= (uint32_t)(ptfunxored[j-5] << 16);
688                                                 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
689                                                 numberofwavs |= (uint32_t)(ptfunxored[j-3]);
690                                                 //printf("%d wavs\n", numberofwavs);
691                                                 break;
692                                         }
693                                 k--;
694                                 }
695                         }
696
697                         std::string wave = string(wavname);
698                         std::reverse(wave.begin(), wave.end());
699                         wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
700
701                         if (foundin(wave, string(".grp"))) {
702                                 continue;
703                         }
704
705                         actualwavs.push_back(f);
706                         //printf("done\n");
707                         numberofwavs--;
708                         if (numberofwavs <= 0)
709                                 break;
710                 }
711         }
712 }
713
714 void
715 PTFFormat::parseaudio(void) {
716         int i,j,k,l;
717
718         // Find end of wav file list
719         k = 0;
720         while (k < len) {
721                 if (            (ptfunxored[k  ] == 0xff) &&
722                                 (ptfunxored[k+1] == 0xff) &&
723                                 (ptfunxored[k+2] == 0xff) &&
724                                 (ptfunxored[k+3] == 0xff)) {
725                         break;
726                 }
727                 k++;
728         }
729
730         // Find actual wav names
731         bool first = true;
732         uint16_t numberofwavs;
733         char wavname[256];
734         for (i = k; i > 4; i--) {
735                 if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'A')) &&
736                                 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I')) &&
737                                 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F')) &&
738                                 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F'))) {
739                         j = i-4;
740                         l = 0;
741                         while (ptfunxored[j] != '\0') {
742                                 wavname[l] = ptfunxored[j];
743                                 l++;
744                                 j--;
745                         }
746                         wavname[l] = 0;
747                         if (ptfunxored[i] == 'W') {
748                                 extension = string(".wav");
749                         } else {
750                                 extension = string(".aif");
751                         }
752                         //uint8_t playlist = ptfunxored[j-8];
753
754                         if (first) {
755                                 first = false;
756                                 for (j = k; j > 4; j--) {
757                                         if (    (ptfunxored[j  ] == 0x01) &&
758                                                 (ptfunxored[j-1] == 0x5a)) {
759
760                                                 numberofwavs = 0;
761                                                 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
762                                                 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
763                                                 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
764                                                 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
765                                                 //printf("%d wavs\n", numberofwavs);
766                                                 break;
767                                         }
768                                 k--;
769                                 }
770                         }
771
772                         std::string wave = string(wavname);
773                         std::reverse(wave.begin(), wave.end());
774                         wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
775
776                         if (foundin(wave, string(".grp"))) {
777                                 continue;
778                         }
779
780                         actualwavs.push_back(f);
781
782                         numberofwavs--;
783                         if (numberofwavs <= 0)
784                                 break;
785                 }
786         }
787 }
788
789 void
790 PTFFormat::parserest89(void) {
791         int i,j,k,l;
792         // Find Regions
793         uint8_t startbytes = 0;
794         uint8_t lengthbytes = 0;
795         uint8_t offsetbytes = 0;
796         uint8_t somethingbytes = 0;
797         uint8_t skipbytes = 0;
798
799         k = 0;
800         while (k < len) {
801                 if (            (ptfunxored[k  ] == 'S') &&
802                                 (ptfunxored[k+1] == 'n') &&
803                                 (ptfunxored[k+2] == 'a') &&
804                                 (ptfunxored[k+3] == 'p')) {
805                         break;
806                 }
807                 k++;
808         }
809         uint16_t rindex = 0;
810         uint32_t findex = 0;
811         for (i = k; i < len-70; i++) {
812                 if (            (ptfunxored[i  ] == 0x5a) &&
813                                 (ptfunxored[i+1] == 0x0a)) {
814                                 break;
815                 }
816                 if (            (ptfunxored[i  ] == 0x5a) &&
817                                 (ptfunxored[i+1] == 0x0c)) {
818
819                         uint8_t lengthofname = ptfunxored[i+9];
820
821                         char name[256] = {0};
822                         for (j = 0; j < lengthofname; j++) {
823                                 name[j] = ptfunxored[i+13+j];
824                         }
825                         name[j] = '\0';
826                         j += i+13;
827                         //uint8_t disabled = ptfunxored[j];
828
829                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
830                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
831                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
832                         somethingbytes = (ptfunxored[j+3] & 0xf);
833                         skipbytes = ptfunxored[j+4];
834                         findex = ptfunxored[j+5
835                                         +startbytes
836                                         +lengthbytes
837                                         +offsetbytes
838                                         +somethingbytes
839                                         +skipbytes
840                                         +40];
841                         /*rindex = ptfunxored[j+5
842                                         +startbytes
843                                         +lengthbytes
844                                         +offsetbytes
845                                         +somethingbytes
846                                         +skipbytes
847                                         +24];
848                         */
849                         uint32_t sampleoffset = 0;
850                         switch (offsetbytes) {
851                         case 4:
852                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
853                         case 3:
854                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
855                         case 2:
856                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
857                         case 1:
858                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
859                         default:
860                                 break;
861                         }
862                         j+=offsetbytes;
863                         uint32_t length = 0;
864                         switch (lengthbytes) {
865                         case 4:
866                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
867                         case 3:
868                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
869                         case 2:
870                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
871                         case 1:
872                                 length |= (uint32_t)(ptfunxored[j+5]);
873                         default:
874                                 break;
875                         }
876                         j+=lengthbytes;
877                         uint32_t start = 0;
878                         switch (startbytes) {
879                         case 4:
880                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
881                         case 3:
882                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
883                         case 2:
884                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
885                         case 1:
886                                 start |= (uint32_t)(ptfunxored[j+5]);
887                         default:
888                                 break;
889                         }
890                         j+=startbytes;
891                         /*
892                         uint32_t something = 0;
893                         switch (somethingbytes) {
894                         case 4:
895                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
896                         case 3:
897                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
898                         case 2:
899                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
900                         case 1:
901                                 something |= (uint32_t)(ptfunxored[j+5]);
902                         default:
903                                 break;
904                         }
905                         j+=somethingbytes;
906                         */
907                         std::string filename = string(name) + extension;
908                         wav_t f = { 
909                                 filename,
910                                 0,
911                                 (int64_t)(start*ratefactor),
912                                 (int64_t)(length*ratefactor),
913                         };
914
915                         f.index = findex;
916                         //printf("something=%d\n", something);
917
918                         vector<wav_t>::iterator begin = actualwavs.begin();
919                         vector<wav_t>::iterator finish = actualwavs.end();
920                         vector<wav_t>::iterator found;
921                         // Add file to list only if it is an actual wav
922                         if ((found = std::find(begin, finish, f)) != finish) {
923                                 audiofiles.push_back(f);
924                                 // Also add plain wav as region
925                                 region_t r = {
926                                         name,
927                                         rindex,
928                                         (int64_t)(start*ratefactor),
929                                         (int64_t)(sampleoffset*ratefactor),
930                                         (int64_t)(length*ratefactor),
931                                         f
932                                 };
933                                 regions.push_back(r);
934                         // Region only
935                         } else {
936                                 if (foundin(filename, string(".grp"))) {
937                                         continue;
938                                 }
939                                 region_t r = {
940                                         name,
941                                         rindex,
942                                         (int64_t)(start*ratefactor),
943                                         (int64_t)(sampleoffset*ratefactor),
944                                         (int64_t)(length*ratefactor),
945                                         f
946                                 };
947                                 regions.push_back(r);
948                         }
949                         rindex++;
950                 }
951         }
952
953         while (k < len) {
954                 if (            (ptfunxored[k  ] == 0x5a) &&
955                                 (ptfunxored[k+1] == 0x03)) {
956                                 break;
957                 }
958                 k++;
959         }
960         while (k < len) {
961                 if (            (ptfunxored[k  ] == 0x5a) &&
962                                 (ptfunxored[k+1] == 0x02)) {
963                                 break;
964                 }
965                 k++;
966         }
967         k++;
968
969         //  Tracks
970         uint32_t offset;
971         uint32_t tracknumber = 0;
972         uint32_t regionspertrack = 0;
973         for (;k < len; k++) {
974                 if (    (ptfunxored[k  ] == 0x5a) &&
975                         (ptfunxored[k+1] == 0x04)) {
976                         break;
977                 }
978                 if (    (ptfunxored[k  ] == 0x5a) &&
979                         (ptfunxored[k+1] == 0x02)) {
980
981                         uint8_t lengthofname = 0;
982                         lengthofname = ptfunxored[k+9];
983                         if (lengthofname == 0x5a) {
984                                 continue;
985                         }
986                         track_t tr;
987
988                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
989
990                         //printf("regions/track=%d\n", regionspertrack);
991                         char name[256] = {0};
992                         for (j = 0; j < lengthofname; j++) {
993                                 name[j] = ptfunxored[j+k+13];
994                         }
995                         name[j] = '\0';
996                         tr.name = string(name);
997                         tr.index = tracknumber++;
998
999                         for (j = k; regionspertrack > 0 && j < len; j++) {
1000                                 for (l = j; l < len; l++) {
1001                                         if (    (ptfunxored[l  ] == 0x5a) &&
1002                                                 (ptfunxored[l+1] == 0x07)) {
1003                                                 j = l;
1004                                                 break;
1005                                         }
1006                                 }
1007
1008
1009                                 if (regionspertrack == 0) {
1010                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1011                                         break;
1012                                 } else {
1013
1014                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1015                                         vector<region_t>::iterator begin = regions.begin();
1016                                         vector<region_t>::iterator finish = regions.end();
1017                                         vector<region_t>::iterator found;
1018                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1019                                                 tr.reg = (*found);
1020                                         }
1021                                         i = l+16;
1022                                         offset = 0;
1023                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1024                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1025                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1026                                         offset |= (uint32_t)(ptfunxored[i]);
1027                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1028                                         if (tr.reg.length > 0) {
1029                                                 tracks.push_back(tr);
1030                                         }
1031                                         regionspertrack--;
1032                                 }
1033                         }
1034                 }
1035         }
1036 }
1037
1038 void
1039 PTFFormat::parserest10(void) {
1040         int i,j,k,l;
1041         // Find Regions
1042         uint8_t startbytes = 0;
1043         uint8_t lengthbytes = 0;
1044         uint8_t offsetbytes = 0;
1045         uint8_t somethingbytes = 0;
1046         uint8_t skipbytes = 0;
1047
1048         k = 0;
1049         while (k < len) {
1050                 if (            (ptfunxored[k  ] == 'S') &&
1051                                 (ptfunxored[k+1] == 'n') &&
1052                                 (ptfunxored[k+2] == 'a') &&
1053                                 (ptfunxored[k+3] == 'p')) {
1054                         break;
1055                 }
1056                 k++;
1057         }
1058         for (i = k; i < len-70; i++) {
1059                 if (            (ptfunxored[i  ] == 0x5a) &&
1060                                 (ptfunxored[i+1] == 0x02)) {
1061                                 k = i;
1062                                 break;
1063                 }
1064         }
1065         k++;
1066         for (i = k; i < len-70; i++) {
1067                 if (            (ptfunxored[i  ] == 0x5a) &&
1068                                 (ptfunxored[i+1] == 0x02)) {
1069                                 k = i;
1070                                 break;
1071                 }
1072         }
1073         k++;
1074         uint16_t rindex = 0;
1075         uint32_t findex = 0;
1076         for (i = k; i < len-70; i++) {
1077                 if (            (ptfunxored[i  ] == 0x5a) &&
1078                                 (ptfunxored[i+1] == 0x08)) {
1079                                 break;
1080                 }
1081                 if (            (ptfunxored[i  ] == 0x5a) &&
1082                                 (ptfunxored[i+1] == 0x01)) {
1083
1084                         uint8_t lengthofname = ptfunxored[i+9];
1085                         if (ptfunxored[i+13] == 0x5a) {
1086                                 continue;
1087                         }
1088                         char name[256] = {0};
1089                         for (j = 0; j < lengthofname; j++) {
1090                                 name[j] = ptfunxored[i+13+j];
1091                         }
1092                         name[j] = '\0';
1093                         j += i+13;
1094                         //uint8_t disabled = ptfunxored[j];
1095                         //printf("%s\n", name);
1096
1097                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1098                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1099                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1100                         somethingbytes = (ptfunxored[j+3] & 0xf);
1101                         skipbytes = ptfunxored[j+4];
1102                         findex = ptfunxored[j+5
1103                                         +startbytes
1104                                         +lengthbytes
1105                                         +offsetbytes
1106                                         +somethingbytes
1107                                         +skipbytes
1108                                         +37];
1109                         /*rindex = ptfunxored[j+5
1110                                         +startbytes
1111                                         +lengthbytes
1112                                         +offsetbytes
1113                                         +somethingbytes
1114                                         +skipbytes
1115                                         +24];
1116                         */
1117                         uint32_t sampleoffset = 0;
1118                         switch (offsetbytes) {
1119                         case 4:
1120                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1121                         case 3:
1122                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1123                         case 2:
1124                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1125                         case 1:
1126                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1127                         default:
1128                                 break;
1129                         }
1130                         j+=offsetbytes;
1131                         uint32_t length = 0;
1132                         switch (lengthbytes) {
1133                         case 4:
1134                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1135                         case 3:
1136                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1137                         case 2:
1138                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1139                         case 1:
1140                                 length |= (uint32_t)(ptfunxored[j+5]);
1141                         default:
1142                                 break;
1143                         }
1144                         j+=lengthbytes;
1145                         uint32_t start = 0;
1146                         switch (startbytes) {
1147                         case 4:
1148                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1149                         case 3:
1150                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1151                         case 2:
1152                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1153                         case 1:
1154                                 start |= (uint32_t)(ptfunxored[j+5]);
1155                         default:
1156                                 break;
1157                         }
1158                         j+=startbytes;
1159                         /*
1160                         uint32_t something = 0;
1161                         switch (somethingbytes) {
1162                         case 4:
1163                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1164                         case 3:
1165                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1166                         case 2:
1167                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1168                         case 1:
1169                                 something |= (uint32_t)(ptfunxored[j+5]);
1170                         default:
1171                                 break;
1172                         }
1173                         j+=somethingbytes;
1174                         */
1175                         std::string filename = string(name) + extension;
1176                         wav_t f = { 
1177                                 filename,
1178                                 0,
1179                                 (int64_t)(start*ratefactor),
1180                                 (int64_t)(length*ratefactor),
1181                         };
1182
1183                         if (strlen(name) == 0) {
1184                                 continue;
1185                         }
1186                         if (length == 0) {
1187                                 continue;
1188                         }
1189                         f.index = findex;
1190                         //printf("something=%d\n", something);
1191
1192                         vector<wav_t>::iterator begin = actualwavs.begin();
1193                         vector<wav_t>::iterator finish = actualwavs.end();
1194                         vector<wav_t>::iterator found;
1195                         // Add file to list only if it is an actual wav
1196                         if ((found = std::find(begin, finish, f)) != finish) {
1197                                 audiofiles.push_back(f);
1198                                 // Also add plain wav as region
1199                                 region_t r = {
1200                                         name,
1201                                         rindex,
1202                                         (int64_t)(start*ratefactor),
1203                                         (int64_t)(sampleoffset*ratefactor),
1204                                         (int64_t)(length*ratefactor),
1205                                         f
1206                                 };
1207                                 regions.push_back(r);
1208                         // Region only
1209                         } else {
1210                                 if (foundin(filename, string(".grp"))) {
1211                                         continue;
1212                                 }
1213                                 region_t r = {
1214                                         name,
1215                                         rindex,
1216                                         (int64_t)(start*ratefactor),
1217                                         (int64_t)(sampleoffset*ratefactor),
1218                                         (int64_t)(length*ratefactor),
1219                                         f
1220                                 };
1221                                 regions.push_back(r);
1222                         }
1223                         rindex++;
1224                         //printf("%s\n", name);
1225                 }
1226         }
1227         //  Tracks
1228         uint32_t offset;
1229         uint32_t tracknumber = 0;
1230         uint32_t regionspertrack = 0;
1231         for (;k < len; k++) {
1232                 if (    (ptfunxored[k  ] == 0x5a) &&
1233                         (ptfunxored[k+1] == 0x08)) {
1234                         break;
1235                 }
1236         }
1237         k++;
1238         for (;k < len; k++) {
1239                 if (    (ptfunxored[k  ] == 0x5a) &&
1240                         (ptfunxored[k+1] == 0x04)) {
1241                         break;
1242                 }
1243                 if (    (ptfunxored[k  ] == 0x5a) &&
1244                         (ptfunxored[k+1] == 0x02)) {
1245
1246                         uint8_t lengthofname = 0;
1247                         lengthofname = ptfunxored[k+9];
1248                         if (lengthofname == 0x5a) {
1249                                 continue;
1250                         }
1251                         track_t tr;
1252
1253                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1254
1255                         //printf("regions/track=%d\n", regionspertrack);
1256                         char name[256] = {0};
1257                         for (j = 0; j < lengthofname; j++) {
1258                                 name[j] = ptfunxored[j+k+13];
1259                         }
1260                         name[j] = '\0';
1261                         tr.name = string(name);
1262                         tr.index = tracknumber++;
1263
1264                         for (j = k; regionspertrack > 0 && j < len; j++) {
1265                                 for (l = j; l < len; l++) {
1266                                         if (    (ptfunxored[l  ] == 0x5a) &&
1267                                                 (ptfunxored[l+1] == 0x08)) {
1268                                                 j = l+1;
1269                                                 break;
1270                                         }
1271                                 }
1272
1273
1274                                 if (regionspertrack == 0) {
1275                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1276                                         break;
1277                                 } else {
1278
1279                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1280                                         vector<region_t>::iterator begin = regions.begin();
1281                                         vector<region_t>::iterator finish = regions.end();
1282                                         vector<region_t>::iterator found;
1283                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1284                                                 tr.reg = (*found);
1285                                         }
1286                                         i = l+16;
1287                                         offset = 0;
1288                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1289                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1290                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1291                                         offset |= (uint32_t)(ptfunxored[i]);
1292                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1293                                         if (tr.reg.length > 0) {
1294                                                 tracks.push_back(tr);
1295                                         }
1296                                         regionspertrack--;
1297                                 }
1298                         }
1299                 }
1300         }
1301 }