ed80adec0757db2acd900ae71b792cafe17948bd
[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;
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[k+14];
515                         printf("findex=%x\n", findex);
516                         j--;
517                         uint32_t start = 0;
518                         switch (startbytes) {
519                         case 4:
520                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
521                         case 3:
522                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
523                         case 2:
524                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
525                         case 1:
526                                 start |= (uint32_t)(ptfunxored[j+5]);
527                         default:
528                                 break;
529                         }
530                         j+=startbytes;
531                         uint32_t length = 0;
532                         switch (lengthbytes) {
533                         case 4:
534                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
535                         case 3:
536                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
537                         case 2:
538                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
539                         case 1:
540                                 length |= (uint32_t)(ptfunxored[j+5]);
541                         default:
542                                 break;
543                         }
544                         j+=lengthbytes;
545                         uint32_t sampleoffset = 0;
546                         switch (offsetbytes) {
547                         case 4:
548                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
549                         case 3:
550                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
551                         case 2:
552                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
553                         case 1:
554                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
555                         default:
556                                 break;
557                         }
558                         j+=offsetbytes;
559
560                         //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
561
562                         std::string filename = string(name) + extension;
563                         wav_t f = { 
564                                 filename,
565                                 findex,
566                                 (int64_t)(start*ratefactor),
567                                 (int64_t)(length*ratefactor),
568                         };
569
570                         vector<wav_t>::iterator begin = audiofiles.begin();
571                         vector<wav_t>::iterator finish = audiofiles.end();
572                         vector<wav_t>::iterator found;
573                         // Add file to lists
574                         if ((found = std::find(begin, finish, f)) != finish) {
575                                 region_t r = {
576                                         name,
577                                         rindex,
578                                         (int64_t)(start*ratefactor),
579                                         (int64_t)(sampleoffset*ratefactor),
580                                         (int64_t)(length*ratefactor),
581                                         *found,
582                                 };
583                                 regions.push_back(r);
584                                 vector<track_t>::iterator ti;
585                                 vector<track_t>::iterator bt = tracks.begin();
586                                 vector<track_t>::iterator et = tracks.end();
587                                 track_t tr = { name, 0, 0, r };
588                                 if ((ti = std::find(bt, et, tr)) != et) {
589                                         tracknumber = (*ti).index;
590                                 } else {
591                                         tracknumber = tracks.size() + 1;
592                                 }
593                                 track_t t = {
594                                         name,
595                                         (uint16_t)tracknumber,
596                                         uint8_t(0),
597                                         r
598                                 };
599                                 tracks.push_back(t);
600                         } else {
601                                 region_t r = {
602                                         name,
603                                         rindex,
604                                         (int64_t)(start*ratefactor),
605                                         (int64_t)(sampleoffset*ratefactor),
606                                         (int64_t)(length*ratefactor),
607                                         f,
608                                 };
609                                 regions.push_back(r);
610                                 vector<track_t>::iterator ti;
611                                 vector<track_t>::iterator bt = tracks.begin();
612                                 vector<track_t>::iterator et = tracks.end();
613                                 track_t tr = { name, 0, 0, r };
614                                 if ((ti = std::find(bt, et, tr)) != et) {
615                                         tracknumber = (*ti).index;
616                                 } else {
617                                         tracknumber = tracks.size() + 1;
618                                 }
619                                 track_t t = {
620                                         name,
621                                         (uint16_t)tracknumber,
622                                         uint8_t(0),
623                                         r
624                                 };
625                                 tracks.push_back(t);
626                         }
627                         rindex++;
628                         k++;
629                 }
630                 k++;
631         }
632 }
633
634 void
635 PTFFormat::parseaudio5(void) {
636         int i,k,l;
637         int lengthofname, wavnumber;
638
639         // Find end of wav file list
640         k = 0;
641         while (k < len) {
642                 if (            (ptfunxored[k  ] == 0x5f) &&
643                                 (ptfunxored[k+1] == 0x50) &&
644                                 (ptfunxored[k+2] == 0x35)) {
645                         break;
646                 }
647                 k++;
648         }
649         k++;
650         while (k < len) {
651                 if (            (ptfunxored[k  ] == 0x5f) &&
652                                 (ptfunxored[k+1] == 0x50) &&
653                                 (ptfunxored[k+2] == 0x35)) {
654                         break;
655                 }
656                 k++;
657         }
658
659         // Find actual wav names
660         uint16_t numberofwavs = ptfunxored[k-23];
661         char wavname[256];
662         for (i = k; i < len; i++) {
663                 if (            (ptfunxored[i  ] == 'F') &&
664                                 (ptfunxored[i+1] == 'i') &&
665                                 (ptfunxored[i+2] == 'l') &&
666                                 (ptfunxored[i+3] == 'e') &&
667                                 (ptfunxored[i+4] == 's')) {
668                         break;
669                 }
670         }
671         
672         wavnumber = 0;
673         i+=16;
674         while (i < len && numberofwavs > 0) {
675                 i++;
676                 if (            (ptfunxored[i  ] == 0x5a) &&
677                                 (ptfunxored[i+1] == 0x00) &&
678                                 (ptfunxored[i+2] == 0x05)) {
679                         break;
680                 }
681                 lengthofname = ptfunxored[i];
682                 i++;
683                 l = 0;
684                 while (l < lengthofname) {
685                         wavname[l] = ptfunxored[i+l];
686                         l++;
687                 }
688                 i+=lengthofname + 4;
689                 wavname[l] = 0;
690                 if (foundin(wavname, ".wav")) {
691                         extension = string(".wav");
692                 } else if (foundin(wavname, ".aif")) {
693                         extension = string(".aif");
694                 } else {
695                         extension = string("");
696                 }
697
698                 std::string wave = string(wavname);
699                 wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
700
701                 if (foundin(wave, string(".grp"))) {
702                         continue;
703                 }
704
705                 actualwavs.push_back(f);
706                 audiofiles.push_back(f);
707                 //printf("done\n");
708                 numberofwavs--;
709                 i += 7;
710         }
711 }
712
713 void
714 PTFFormat::parseaudio(void) {
715         int i,j,k,l;
716
717         // Find end of wav file list
718         k = 0;
719         while (k < len) {
720                 if (            (ptfunxored[k  ] == 0xff) &&
721                                 (ptfunxored[k+1] == 0xff) &&
722                                 (ptfunxored[k+2] == 0xff) &&
723                                 (ptfunxored[k+3] == 0xff)) {
724                         break;
725                 }
726                 k++;
727         }
728
729         // Find actual wav names
730         bool first = true;
731         uint16_t numberofwavs;
732         char wavname[256];
733         for (i = k; i > 4; i--) {
734                 if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'A')) &&
735                                 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I')) &&
736                                 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F')) &&
737                                 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F'))) {
738                         j = i-4;
739                         l = 0;
740                         while (ptfunxored[j] != '\0') {
741                                 wavname[l] = ptfunxored[j];
742                                 l++;
743                                 j--;
744                         }
745                         wavname[l] = 0;
746                         if (ptfunxored[i] == 'W') {
747                                 extension = string(".wav");
748                         } else {
749                                 extension = string(".aif");
750                         }
751                         //uint8_t playlist = ptfunxored[j-8];
752
753                         if (first) {
754                                 first = false;
755                                 for (j = k; j > 4; j--) {
756                                         if (    (ptfunxored[j  ] == 0x01) &&
757                                                 (ptfunxored[j-1] == 0x5a)) {
758
759                                                 numberofwavs = 0;
760                                                 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
761                                                 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
762                                                 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
763                                                 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
764                                                 //printf("%d wavs\n", numberofwavs);
765                                                 break;
766                                         }
767                                 k--;
768                                 }
769                         }
770
771                         std::string wave = string(wavname);
772                         std::reverse(wave.begin(), wave.end());
773                         wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
774
775                         if (foundin(wave, string(".grp"))) {
776                                 continue;
777                         }
778
779                         actualwavs.push_back(f);
780
781                         numberofwavs--;
782                         if (numberofwavs <= 0)
783                                 break;
784                 }
785         }
786 }
787
788 void
789 PTFFormat::parserest89(void) {
790         int i,j,k,l;
791         // Find Regions
792         uint8_t startbytes = 0;
793         uint8_t lengthbytes = 0;
794         uint8_t offsetbytes = 0;
795         uint8_t somethingbytes = 0;
796         uint8_t skipbytes = 0;
797
798         k = 0;
799         while (k < len) {
800                 if (            (ptfunxored[k  ] == 'S') &&
801                                 (ptfunxored[k+1] == 'n') &&
802                                 (ptfunxored[k+2] == 'a') &&
803                                 (ptfunxored[k+3] == 'p')) {
804                         break;
805                 }
806                 k++;
807         }
808         uint16_t rindex = 0;
809         uint32_t findex = 0;
810         for (i = k; i < len-70; i++) {
811                 if (            (ptfunxored[i  ] == 0x5a) &&
812                                 (ptfunxored[i+1] == 0x0a)) {
813                                 break;
814                 }
815                 if (            (ptfunxored[i  ] == 0x5a) &&
816                                 (ptfunxored[i+1] == 0x0c)) {
817
818                         uint8_t lengthofname = ptfunxored[i+9];
819
820                         char name[256] = {0};
821                         for (j = 0; j < lengthofname; j++) {
822                                 name[j] = ptfunxored[i+13+j];
823                         }
824                         name[j] = '\0';
825                         j += i+13;
826                         //uint8_t disabled = ptfunxored[j];
827
828                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
829                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
830                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
831                         somethingbytes = (ptfunxored[j+3] & 0xf);
832                         skipbytes = ptfunxored[j+4];
833                         findex = ptfunxored[j+5
834                                         +startbytes
835                                         +lengthbytes
836                                         +offsetbytes
837                                         +somethingbytes
838                                         +skipbytes
839                                         +40];
840                         /*rindex = ptfunxored[j+5
841                                         +startbytes
842                                         +lengthbytes
843                                         +offsetbytes
844                                         +somethingbytes
845                                         +skipbytes
846                                         +24];
847                         */
848                         uint32_t sampleoffset = 0;
849                         switch (offsetbytes) {
850                         case 4:
851                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
852                         case 3:
853                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
854                         case 2:
855                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
856                         case 1:
857                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
858                         default:
859                                 break;
860                         }
861                         j+=offsetbytes;
862                         uint32_t length = 0;
863                         switch (lengthbytes) {
864                         case 4:
865                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
866                         case 3:
867                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
868                         case 2:
869                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
870                         case 1:
871                                 length |= (uint32_t)(ptfunxored[j+5]);
872                         default:
873                                 break;
874                         }
875                         j+=lengthbytes;
876                         uint32_t start = 0;
877                         switch (startbytes) {
878                         case 4:
879                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
880                         case 3:
881                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
882                         case 2:
883                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
884                         case 1:
885                                 start |= (uint32_t)(ptfunxored[j+5]);
886                         default:
887                                 break;
888                         }
889                         j+=startbytes;
890                         /*
891                         uint32_t something = 0;
892                         switch (somethingbytes) {
893                         case 4:
894                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
895                         case 3:
896                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
897                         case 2:
898                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
899                         case 1:
900                                 something |= (uint32_t)(ptfunxored[j+5]);
901                         default:
902                                 break;
903                         }
904                         j+=somethingbytes;
905                         */
906                         std::string filename = string(name) + extension;
907                         wav_t f = { 
908                                 filename,
909                                 0,
910                                 (int64_t)(start*ratefactor),
911                                 (int64_t)(length*ratefactor),
912                         };
913
914                         f.index = findex;
915                         //printf("something=%d\n", something);
916
917                         vector<wav_t>::iterator begin = actualwavs.begin();
918                         vector<wav_t>::iterator finish = actualwavs.end();
919                         vector<wav_t>::iterator found;
920                         // Add file to list only if it is an actual wav
921                         if ((found = std::find(begin, finish, f)) != finish) {
922                                 audiofiles.push_back(f);
923                                 // Also add plain wav as region
924                                 region_t r = {
925                                         name,
926                                         rindex,
927                                         (int64_t)(start*ratefactor),
928                                         (int64_t)(sampleoffset*ratefactor),
929                                         (int64_t)(length*ratefactor),
930                                         f
931                                 };
932                                 regions.push_back(r);
933                         // Region only
934                         } else {
935                                 if (foundin(filename, string(".grp"))) {
936                                         continue;
937                                 }
938                                 region_t r = {
939                                         name,
940                                         rindex,
941                                         (int64_t)(start*ratefactor),
942                                         (int64_t)(sampleoffset*ratefactor),
943                                         (int64_t)(length*ratefactor),
944                                         f
945                                 };
946                                 regions.push_back(r);
947                         }
948                         rindex++;
949                 }
950         }
951
952         while (k < len) {
953                 if (            (ptfunxored[k  ] == 0x5a) &&
954                                 (ptfunxored[k+1] == 0x03)) {
955                                 break;
956                 }
957                 k++;
958         }
959         while (k < len) {
960                 if (            (ptfunxored[k  ] == 0x5a) &&
961                                 (ptfunxored[k+1] == 0x02)) {
962                                 break;
963                 }
964                 k++;
965         }
966         k++;
967
968         //  Tracks
969         uint32_t offset;
970         uint32_t tracknumber = 0;
971         uint32_t regionspertrack = 0;
972         for (;k < len; k++) {
973                 if (    (ptfunxored[k  ] == 0x5a) &&
974                         (ptfunxored[k+1] == 0x04)) {
975                         break;
976                 }
977                 if (    (ptfunxored[k  ] == 0x5a) &&
978                         (ptfunxored[k+1] == 0x02)) {
979
980                         uint8_t lengthofname = 0;
981                         lengthofname = ptfunxored[k+9];
982                         if (lengthofname == 0x5a) {
983                                 continue;
984                         }
985                         track_t tr;
986
987                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
988
989                         //printf("regions/track=%d\n", regionspertrack);
990                         char name[256] = {0};
991                         for (j = 0; j < lengthofname; j++) {
992                                 name[j] = ptfunxored[j+k+13];
993                         }
994                         name[j] = '\0';
995                         tr.name = string(name);
996                         tr.index = tracknumber++;
997
998                         for (j = k; regionspertrack > 0 && j < len; j++) {
999                                 for (l = j; l < len; l++) {
1000                                         if (    (ptfunxored[l  ] == 0x5a) &&
1001                                                 (ptfunxored[l+1] == 0x07)) {
1002                                                 j = l;
1003                                                 break;
1004                                         }
1005                                 }
1006
1007
1008                                 if (regionspertrack == 0) {
1009                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1010                                         break;
1011                                 } else {
1012
1013                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1014                                         vector<region_t>::iterator begin = regions.begin();
1015                                         vector<region_t>::iterator finish = regions.end();
1016                                         vector<region_t>::iterator found;
1017                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1018                                                 tr.reg = (*found);
1019                                         }
1020                                         i = l+16;
1021                                         offset = 0;
1022                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1023                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1024                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1025                                         offset |= (uint32_t)(ptfunxored[i]);
1026                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1027                                         if (tr.reg.length > 0) {
1028                                                 tracks.push_back(tr);
1029                                         }
1030                                         regionspertrack--;
1031                                 }
1032                         }
1033                 }
1034         }
1035 }
1036
1037 void
1038 PTFFormat::parserest10(void) {
1039         int i,j,k,l;
1040         // Find Regions
1041         uint8_t startbytes = 0;
1042         uint8_t lengthbytes = 0;
1043         uint8_t offsetbytes = 0;
1044         uint8_t somethingbytes = 0;
1045         uint8_t skipbytes = 0;
1046
1047         k = 0;
1048         while (k < len) {
1049                 if (            (ptfunxored[k  ] == 'S') &&
1050                                 (ptfunxored[k+1] == 'n') &&
1051                                 (ptfunxored[k+2] == 'a') &&
1052                                 (ptfunxored[k+3] == 'p')) {
1053                         break;
1054                 }
1055                 k++;
1056         }
1057         for (i = k; i < len-70; i++) {
1058                 if (            (ptfunxored[i  ] == 0x5a) &&
1059                                 (ptfunxored[i+1] == 0x02)) {
1060                                 k = i;
1061                                 break;
1062                 }
1063         }
1064         k++;
1065         for (i = k; i < len-70; i++) {
1066                 if (            (ptfunxored[i  ] == 0x5a) &&
1067                                 (ptfunxored[i+1] == 0x02)) {
1068                                 k = i;
1069                                 break;
1070                 }
1071         }
1072         k++;
1073         uint16_t rindex = 0;
1074         uint32_t findex = 0;
1075         for (i = k; i < len-70; i++) {
1076                 if (            (ptfunxored[i  ] == 0x5a) &&
1077                                 (ptfunxored[i+1] == 0x08)) {
1078                                 break;
1079                 }
1080                 if (            (ptfunxored[i  ] == 0x5a) &&
1081                                 (ptfunxored[i+1] == 0x01)) {
1082
1083                         uint8_t lengthofname = ptfunxored[i+9];
1084                         if (ptfunxored[i+13] == 0x5a) {
1085                                 continue;
1086                         }
1087                         char name[256] = {0};
1088                         for (j = 0; j < lengthofname; j++) {
1089                                 name[j] = ptfunxored[i+13+j];
1090                         }
1091                         name[j] = '\0';
1092                         j += i+13;
1093                         //uint8_t disabled = ptfunxored[j];
1094                         //printf("%s\n", name);
1095
1096                         offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1097                         lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1098                         startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1099                         somethingbytes = (ptfunxored[j+3] & 0xf);
1100                         skipbytes = ptfunxored[j+4];
1101                         findex = ptfunxored[j+5
1102                                         +startbytes
1103                                         +lengthbytes
1104                                         +offsetbytes
1105                                         +somethingbytes
1106                                         +skipbytes
1107                                         +37];
1108                         /*rindex = ptfunxored[j+5
1109                                         +startbytes
1110                                         +lengthbytes
1111                                         +offsetbytes
1112                                         +somethingbytes
1113                                         +skipbytes
1114                                         +24];
1115                         */
1116                         uint32_t sampleoffset = 0;
1117                         switch (offsetbytes) {
1118                         case 4:
1119                                 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1120                         case 3:
1121                                 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1122                         case 2:
1123                                 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1124                         case 1:
1125                                 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1126                         default:
1127                                 break;
1128                         }
1129                         j+=offsetbytes;
1130                         uint32_t length = 0;
1131                         switch (lengthbytes) {
1132                         case 4:
1133                                 length |= (uint32_t)(ptfunxored[j+8] << 24);
1134                         case 3:
1135                                 length |= (uint32_t)(ptfunxored[j+7] << 16);
1136                         case 2:
1137                                 length |= (uint32_t)(ptfunxored[j+6] << 8);
1138                         case 1:
1139                                 length |= (uint32_t)(ptfunxored[j+5]);
1140                         default:
1141                                 break;
1142                         }
1143                         j+=lengthbytes;
1144                         uint32_t start = 0;
1145                         switch (startbytes) {
1146                         case 4:
1147                                 start |= (uint32_t)(ptfunxored[j+8] << 24);
1148                         case 3:
1149                                 start |= (uint32_t)(ptfunxored[j+7] << 16);
1150                         case 2:
1151                                 start |= (uint32_t)(ptfunxored[j+6] << 8);
1152                         case 1:
1153                                 start |= (uint32_t)(ptfunxored[j+5]);
1154                         default:
1155                                 break;
1156                         }
1157                         j+=startbytes;
1158                         /*
1159                         uint32_t something = 0;
1160                         switch (somethingbytes) {
1161                         case 4:
1162                                 something |= (uint32_t)(ptfunxored[j+8] << 24);
1163                         case 3:
1164                                 something |= (uint32_t)(ptfunxored[j+7] << 16);
1165                         case 2:
1166                                 something |= (uint32_t)(ptfunxored[j+6] << 8);
1167                         case 1:
1168                                 something |= (uint32_t)(ptfunxored[j+5]);
1169                         default:
1170                                 break;
1171                         }
1172                         j+=somethingbytes;
1173                         */
1174                         std::string filename = string(name) + extension;
1175                         wav_t f = { 
1176                                 filename,
1177                                 0,
1178                                 (int64_t)(start*ratefactor),
1179                                 (int64_t)(length*ratefactor),
1180                         };
1181
1182                         if (strlen(name) == 0) {
1183                                 continue;
1184                         }
1185                         if (length == 0) {
1186                                 continue;
1187                         }
1188                         f.index = findex;
1189                         //printf("something=%d\n", something);
1190
1191                         vector<wav_t>::iterator begin = actualwavs.begin();
1192                         vector<wav_t>::iterator finish = actualwavs.end();
1193                         vector<wav_t>::iterator found;
1194                         // Add file to list only if it is an actual wav
1195                         if ((found = std::find(begin, finish, f)) != finish) {
1196                                 audiofiles.push_back(f);
1197                                 // Also add plain wav as region
1198                                 region_t r = {
1199                                         name,
1200                                         rindex,
1201                                         (int64_t)(start*ratefactor),
1202                                         (int64_t)(sampleoffset*ratefactor),
1203                                         (int64_t)(length*ratefactor),
1204                                         f
1205                                 };
1206                                 regions.push_back(r);
1207                         // Region only
1208                         } else {
1209                                 if (foundin(filename, string(".grp"))) {
1210                                         continue;
1211                                 }
1212                                 region_t r = {
1213                                         name,
1214                                         rindex,
1215                                         (int64_t)(start*ratefactor),
1216                                         (int64_t)(sampleoffset*ratefactor),
1217                                         (int64_t)(length*ratefactor),
1218                                         f
1219                                 };
1220                                 regions.push_back(r);
1221                         }
1222                         rindex++;
1223                         //printf("%s\n", name);
1224                 }
1225         }
1226         //  Tracks
1227         uint32_t offset;
1228         uint32_t tracknumber = 0;
1229         uint32_t regionspertrack = 0;
1230         for (;k < len; k++) {
1231                 if (    (ptfunxored[k  ] == 0x5a) &&
1232                         (ptfunxored[k+1] == 0x08)) {
1233                         break;
1234                 }
1235         }
1236         k++;
1237         for (;k < len; k++) {
1238                 if (    (ptfunxored[k  ] == 0x5a) &&
1239                         (ptfunxored[k+1] == 0x04)) {
1240                         break;
1241                 }
1242                 if (    (ptfunxored[k  ] == 0x5a) &&
1243                         (ptfunxored[k+1] == 0x02)) {
1244
1245                         uint8_t lengthofname = 0;
1246                         lengthofname = ptfunxored[k+9];
1247                         if (lengthofname == 0x5a) {
1248                                 continue;
1249                         }
1250                         track_t tr;
1251
1252                         regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1253
1254                         //printf("regions/track=%d\n", regionspertrack);
1255                         char name[256] = {0};
1256                         for (j = 0; j < lengthofname; j++) {
1257                                 name[j] = ptfunxored[j+k+13];
1258                         }
1259                         name[j] = '\0';
1260                         tr.name = string(name);
1261                         tr.index = tracknumber++;
1262
1263                         for (j = k; regionspertrack > 0 && j < len; j++) {
1264                                 for (l = j; l < len; l++) {
1265                                         if (    (ptfunxored[l  ] == 0x5a) &&
1266                                                 (ptfunxored[l+1] == 0x08)) {
1267                                                 j = l+1;
1268                                                 break;
1269                                         }
1270                                 }
1271
1272
1273                                 if (regionspertrack == 0) {
1274                                 //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1275                                         break;
1276                                 } else {
1277
1278                                         tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1279                                         vector<region_t>::iterator begin = regions.begin();
1280                                         vector<region_t>::iterator finish = regions.end();
1281                                         vector<region_t>::iterator found;
1282                                         if ((found = std::find(begin, finish, tr.reg)) != finish) {
1283                                                 tr.reg = (*found);
1284                                         }
1285                                         i = l+16;
1286                                         offset = 0;
1287                                         offset |= (uint32_t)(ptfunxored[i+3] << 24);
1288                                         offset |= (uint32_t)(ptfunxored[i+2] << 16);
1289                                         offset |= (uint32_t)(ptfunxored[i+1] << 8);
1290                                         offset |= (uint32_t)(ptfunxored[i]);
1291                                         tr.reg.startpos = (int64_t)(offset*ratefactor);
1292                                         if (tr.reg.length > 0) {
1293                                                 tracks.push_back(tr);
1294                                         }
1295                                         regionspertrack--;
1296                                 }
1297                         }
1298                 }
1299         }
1300 }