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