Prefer std::vector<> over C-style malloc/free**
[ardour.git] / libs / ptformat / ptformat.cc
1 /*
2  * libptformat - a library to read ProTools sessions
3  *
4  * Copyright (C) 2015-2019  Damien Zammit
5  * Copyright (C) 2015-2019  Robin Gareus
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string>
26 #include <string.h>
27 #include <assert.h>
28
29 #ifdef HAVE_GLIB
30 # include <glib/gstdio.h>
31 # define ptf_open       g_fopen
32 #else
33 # define ptf_open       fopen
34 #endif
35
36 #include "ptformat/ptformat.h"
37
38 #define BITCODE                 "0010111100101011"
39 #define ZMARK                   '\x5a'
40 #define ZERO_TICKS              0xe8d4a51000ULL
41 #define MAX_CONTENT_TYPE        0x3000
42 #define MAX_CHANNELS_PER_TRACK  8
43
44 #if 0
45 #define DEBUG
46 #endif
47
48 #ifdef DEBUG
49 #define verbose_printf(...) printf("XXX PTFORMAT XXX: " __VA_ARGS__)
50 #else
51 #define verbose_printf(...)
52 #endif
53
54 using namespace std;
55
56 static void
57 hexdump(uint8_t *data, int length, int level)
58 {
59         int i,j,k,end,step=16;
60
61         for (i = 0; i < length; i += step) {
62                 end = i + step;
63                 if (end > length) end = length;
64                 for (k = 0; k < level; k++)
65                         printf("    ");
66                 for (j = i; j < end; j++) {
67                         printf("%02X ", data[j]);
68                 }
69                 for (j = i; j < end; j++) {
70                         if (data[j] < 128 && data[j] > 32)
71                                 printf("%c", data[j]);
72                         else
73                                 printf(".");
74                 }
75                 printf("\n");
76         }
77 }
78
79 PTFFormat::PTFFormat()
80         : _ptfunxored(0)
81         , _len(0)
82         , _sessionrate(0)
83         , _version(0)
84         , _product(NULL)
85         , _targetrate (0)
86         , _ratefactor (1.0)
87         , is_bigendian(false)
88 {
89 }
90
91 PTFFormat::~PTFFormat() {
92         cleanup();
93 }
94
95 const std::string
96 PTFFormat::get_content_description(uint16_t ctype) {
97         switch(ctype) {
98         case 0x0030:
99                 return std::string("INFO product and version");
100         case 0x1001:
101                 return std::string("WAV samplerate, size");
102         case 0x1003:
103                 return std::string("WAV metadata");
104         case 0x1004:
105                 return std::string("WAV list full");
106         case 0x1007:
107                 return std::string("region name, number");
108         case 0x1008:
109                 return std::string("AUDIO region name, number (v5)");
110         case 0x100b:
111                 return std::string("AUDIO region list (v5)");
112         case 0x100f:
113                 return std::string("AUDIO region->track entry");
114         case 0x1011:
115                 return std::string("AUDIO region->track map entries");
116         case 0x1012:
117                 return std::string("AUDIO region->track full map");
118         case 0x1014:
119                 return std::string("AUDIO track name, number");
120         case 0x1015:
121                 return std::string("AUDIO tracks");
122         case 0x1017:
123                 return std::string("PLUGIN entry");
124         case 0x1018:
125                 return std::string("PLUGIN full list");
126         case 0x1021:
127                 return std::string("I/O channel entry");
128         case 0x1022:
129                 return std::string("I/O channel list");
130         case 0x1028:
131                 return std::string("INFO sample rate");
132         case 0x103a:
133                 return std::string("WAV names");
134         case 0x104f:
135                 return std::string("AUDIO region->track subentry (v8)");
136         case 0x1050:
137                 return std::string("AUDIO region->track entry (v8)");
138         case 0x1052:
139                 return std::string("AUDIO region->track map entries (v8)");
140         case 0x1054:
141                 return std::string("AUDIO region->track full map (v8)");
142         case 0x1056:
143                 return std::string("MIDI region->track entry");
144         case 0x1057:
145                 return std::string("MIDI region->track map entries");
146         case 0x1058:
147                 return std::string("MIDI region->track full map");
148         case 0x2000:
149                 return std::string("MIDI events block");
150         case 0x2001:
151                 return std::string("MIDI region name, number (v5)");
152         case 0x2002:
153                 return std::string("MIDI regions map (v5)");
154         case 0x2067:
155                 return std::string("INFO path of session");
156         case 0x2511:
157                 return std::string("Snaps block");
158         case 0x2519:
159                 return std::string("MIDI track full list");
160         case 0x251a:
161                 return std::string("MIDI track name, number");
162         case 0x2523:
163                 return std::string("COMPOUND region element");
164         case 0x2602:
165                 return std::string("I/O route");
166         case 0x2603:
167                 return std::string("I/O routing table");
168         case 0x2628:
169                 return std::string("COMPOUND region group");
170         case 0x2629:
171                 return std::string("AUDIO region name, number (v10)");
172         case 0x262a:
173                 return std::string("AUDIO region list (v10)");
174         case 0x262c:
175                 return std::string("COMPOUND region full map");
176         case 0x2633:
177                 return std::string("MIDI regions name, number (v10)");
178         case 0x2634:
179                 return std::string("MIDI regions map (v10)");
180         case 0x271a:
181                 return std::string("MARKER list");
182         default:
183                 return std::string("UNKNOWN content type");
184         }
185 }
186
187 static uint16_t
188 u_endian_read2(unsigned char *buf, bool bigendian)
189 {
190         if (bigendian) {
191                 return ((uint16_t)(buf[0]) << 8) | (uint16_t)(buf[1]);
192         } else {
193                 return ((uint16_t)(buf[1]) << 8) | (uint16_t)(buf[0]);
194         }
195 }
196
197 static uint32_t
198 u_endian_read3(unsigned char *buf, bool bigendian)
199 {
200         if (bigendian) {
201                 return ((uint32_t)(buf[0]) << 16) |
202                         ((uint32_t)(buf[1]) << 8) |
203                         (uint32_t)(buf[2]);
204         } else {
205                 return ((uint32_t)(buf[2]) << 16) |
206                         ((uint32_t)(buf[1]) << 8) |
207                         (uint32_t)(buf[0]);
208         }
209 }
210
211 static uint32_t
212 u_endian_read4(unsigned char *buf, bool bigendian)
213 {
214         if (bigendian) {
215                 return ((uint32_t)(buf[0]) << 24) |
216                         ((uint32_t)(buf[1]) << 16) |
217                         ((uint32_t)(buf[2]) << 8) |
218                         (uint32_t)(buf[3]);
219         } else {
220                 return ((uint32_t)(buf[3]) << 24) |
221                         ((uint32_t)(buf[2]) << 16) |
222                         ((uint32_t)(buf[1]) << 8) |
223                         (uint32_t)(buf[0]);
224         }
225 }
226
227 static uint64_t
228 u_endian_read5(unsigned char *buf, bool bigendian)
229 {
230         if (bigendian) {
231                 return ((uint64_t)(buf[0]) << 32) |
232                         ((uint64_t)(buf[1]) << 24) |
233                         ((uint64_t)(buf[2]) << 16) |
234                         ((uint64_t)(buf[3]) << 8) |
235                         (uint64_t)(buf[4]);
236         } else {
237                 return ((uint64_t)(buf[4]) << 32) |
238                         ((uint64_t)(buf[3]) << 24) |
239                         ((uint64_t)(buf[2]) << 16) |
240                         ((uint64_t)(buf[1]) << 8) |
241                         (uint64_t)(buf[0]);
242         }
243 }
244
245 static uint64_t
246 u_endian_read8(unsigned char *buf, bool bigendian)
247 {
248         if (bigendian) {
249                 return ((uint64_t)(buf[0]) << 56) |
250                         ((uint64_t)(buf[1]) << 48) |
251                         ((uint64_t)(buf[2]) << 40) |
252                         ((uint64_t)(buf[3]) << 32) |
253                         ((uint64_t)(buf[4]) << 24) |
254                         ((uint64_t)(buf[5]) << 16) |
255                         ((uint64_t)(buf[6]) << 8) |
256                         (uint64_t)(buf[7]);
257         } else {
258                 return ((uint64_t)(buf[7]) << 56) |
259                         ((uint64_t)(buf[6]) << 48) |
260                         ((uint64_t)(buf[5]) << 40) |
261                         ((uint64_t)(buf[4]) << 32) |
262                         ((uint64_t)(buf[3]) << 24) |
263                         ((uint64_t)(buf[2]) << 16) |
264                         ((uint64_t)(buf[1]) << 8) |
265                         (uint64_t)(buf[0]);
266         }
267 }
268
269 void
270 PTFFormat::cleanup(void) {
271         _len = 0;
272         _sessionrate = 0;
273         _version = 0;
274         free(_ptfunxored);
275         _ptfunxored = NULL;
276         free (_product);
277         _product = NULL;
278         _audiofiles.clear();
279         _regions.clear();
280         _midiregions.clear();
281         _tracks.clear();
282         _miditracks.clear();
283         free_all_blocks();
284 }
285
286 int64_t
287 PTFFormat::foundat(unsigned char *haystack, uint64_t n, const char *needle) {
288         int64_t found = 0;
289         uint64_t i, j, needle_n;
290         needle_n = strlen(needle);
291
292         for (i = 0; i < n; i++) {
293                 found = i;
294                 for (j = 0; j < needle_n; j++) {
295                         if (haystack[i+j] != needle[j]) {
296                                 found = -1;
297                                 break;
298                         }
299                 }
300                 if (found > 0)
301                         return found;
302         }
303         return -1;
304 }
305
306 bool
307 PTFFormat::jumpto(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen) {
308         uint64_t i;
309         uint64_t k = *currpos;
310         while (k + needlelen < maxoffset) {
311                 bool foundall = true;
312                 for (i = 0; i < needlelen; i++) {
313                         if (buf[k+i] != needle[i]) {
314                                 foundall = false;
315                                 break;
316                         }
317                 }
318                 if (foundall) {
319                         *currpos = k;
320                         return true;
321                 }
322                 k++;
323         }
324         return false;
325 }
326
327 bool
328 PTFFormat::jumpback(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen) {
329         uint64_t i;
330         uint64_t k = *currpos;
331         while (k > 0 && k + needlelen < maxoffset) {
332                 bool foundall = true;
333                 for (i = 0; i < needlelen; i++) {
334                         if (buf[k+i] != needle[i]) {
335                                 foundall = false;
336                                 break;
337                         }
338                 }
339                 if (foundall) {
340                         *currpos = k;
341                         return true;
342                 }
343                 k--;
344         }
345         return false;
346 }
347
348 bool
349 PTFFormat::foundin(std::string const& haystack, std::string const& needle) {
350         size_t found = haystack.find(needle);
351         if (found != std::string::npos) {
352                 return true;
353         } else {
354                 return false;
355         }
356 }
357
358 /* Return values:       0            success
359                         -1           error decrypting pt session
360 */
361 int
362 PTFFormat::unxor(std::string const& path) {
363         FILE *fp;
364         unsigned char xxor[256];
365         unsigned char ct;
366         uint64_t i;
367         uint8_t xor_type;
368         uint8_t xor_value;
369         uint8_t xor_delta;
370         uint16_t xor_len;
371
372         if (! (fp = ptf_open(path.c_str(), "rb"))) {
373                 return -1;
374         }
375
376         fseek(fp, 0, SEEK_END);
377         _len = ftell(fp);
378         if (_len < 0x14) {
379                 fclose(fp);
380                 return -1;
381         }
382
383         if (! (_ptfunxored = (unsigned char*) malloc(_len * sizeof(unsigned char)))) {
384                 /* Silently fail -- out of memory*/
385                 fclose(fp);
386                 _ptfunxored = 0;
387                 return -1;
388         }
389
390         /* The first 20 bytes are always unencrypted */
391         fseek(fp, 0x00, SEEK_SET);
392         i = fread(_ptfunxored, 1, 0x14, fp);
393         if (i < 0x14) {
394                 fclose(fp);
395                 return -1;
396         }
397
398         xor_type = _ptfunxored[0x12];
399         xor_value = _ptfunxored[0x13];
400         xor_len = 256;
401
402         // xor_type 0x01 = ProTools 5, 6, 7, 8 and 9
403         // xor_type 0x05 = ProTools 10, 11, 12
404         switch(xor_type) {
405         case 0x01:
406                 xor_delta = gen_xor_delta(xor_value, 53, false);
407                 break;
408         case 0x05:
409                 xor_delta = gen_xor_delta(xor_value, 11, true);
410                 break;
411         default:
412                 fclose(fp);
413                 return -1;
414         }
415
416         /* Generate the xor_key */
417         for (i=0; i < xor_len; i++)
418                 xxor[i] = (i * xor_delta) & 0xff;
419
420         /* hexdump(xxor, xor_len); */
421
422         /* Read file and decrypt rest of file */
423         i = 0x14;
424         fseek(fp, i, SEEK_SET);
425         while (fread(&ct, 1, 1, fp) != 0) {
426                 uint8_t xor_index = (xor_type == 0x01) ? i & 0xff : (i >> 12) & 0xff;
427                 _ptfunxored[i++] = ct ^ xxor[xor_index];
428         }
429         fclose(fp);
430         return 0;
431 }
432
433 /* Return values:       0            success
434                         -1           error decrypting pt session
435                         -2           error detecting pt session
436                         -3           incompatible pt version
437                         -4           error parsing pt session
438 */
439 int
440 PTFFormat::load(std::string const& ptf, int64_t targetsr) {
441         cleanup();
442         _path = ptf;
443
444         if (unxor(_path))
445                 return -1;
446
447         if (parse_version())
448                 return -2;
449
450         if (_version < 5 || _version > 12)
451                 return -3;
452
453         _targetrate = targetsr;
454
455         int err = 0;
456         if ((err = parse())) {
457                 printf ("PARSE FAILED %d\n", err);
458                 return -4;
459         }
460
461         return 0;
462 }
463
464 bool
465 PTFFormat::parse_version() {
466         uint32_t seg_len,str_len;
467         uint8_t *data = _ptfunxored + 0x14;
468         uintptr_t data_end = ((uintptr_t)_ptfunxored) + 0x100;
469         uint8_t seg_type;
470         bool success = false;
471
472         if (_ptfunxored[0] != '\x03' && foundat(_ptfunxored, 0x100, BITCODE) != 1) {
473                 return false;
474         }
475
476         while( ((uintptr_t)data < data_end) && (success == false) ) {
477
478                 if (data[0] != 0x5a) {
479                         success = false;
480                         break;
481                 }
482
483                 seg_type = data[1];
484                 /* Skip segment header */
485                 data += 3;
486                 if (data[0] == 0 && data[1] == 0) {
487                         /* BE */
488                         is_bigendian = true;
489                 } else {
490                         /* LE */
491                         is_bigendian = false;
492                 }
493                 seg_len = u_endian_read4(&data[0], is_bigendian);
494
495                 /* Skip seg_len */
496                 data += 4;
497                 if (!(seg_type == 0x04 || seg_type == 0x03) || data[0] != 0x03) {
498                         /* Go to next segment */
499                         data += seg_len;
500                         continue;
501                 }
502                 /* Skip 0x03 0x00 0x00 */
503                 data += 3;
504                 seg_len -= 3;
505                 str_len = (*(uint8_t *)data);
506                 if (! (_product = (uint8_t *)malloc((str_len+1) * sizeof(uint8_t)))) {
507                         success = false;
508                         break;
509                 }
510
511                 /* Skip str_len */
512                 data += 4;
513                 seg_len -= 4;
514
515                 memcpy(_product, data, str_len);
516                 _product[str_len] = 0;
517                 data += str_len;
518                 seg_len -= str_len;
519
520                 /* Skip 0x03 0x00 0x00 0x00 */
521                 data += 4;
522                 seg_len -= 4;
523
524                 _version = data[0];
525                 if (_version == 0) {
526                         _version = data[3];
527                 }
528                 data += seg_len;
529                 success = true;
530         }
531
532         /* If the above does not work, try other heuristics */
533         if ((uintptr_t)data >= data_end - seg_len) {
534                 _version = _ptfunxored[0x40];
535                 if (_version == 0) {
536                         _version = _ptfunxored[0x3d];
537                 }
538                 if (_version == 0) {
539                         _version = _ptfunxored[0x3a] + 2;
540                 }
541                 if (_version != 0) {
542                         success = true;
543                 }
544         }
545         return (!success);
546 }
547
548 uint8_t
549 PTFFormat::gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative) {
550         uint16_t i;
551         for (i = 0; i < 256; i++) {
552                 if (((i * mul) & 0xff) == xor_value) {
553                                 return (negative) ? i * (-1) : i;
554                 }
555         }
556         // Should not occur
557         return 0;
558 }
559
560 void
561 PTFFormat::setrates(void) {
562         _ratefactor = 1.f;
563         if (_sessionrate != 0) {
564                 _ratefactor = (float)_targetrate / _sessionrate;
565         }
566 }
567
568 bool
569 PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, struct block_t *parent, int level) {
570         struct block_t b;
571         int childjump = 0;
572         uint32_t i;
573         uint32_t max = _len;
574
575         if (_ptfunxored[pos] != ZMARK)
576                 return false;
577
578         if (parent)
579                 max = parent->block_size + parent->offset;
580
581         b.zmark = ZMARK;
582         b.block_type = u_endian_read2(&_ptfunxored[pos+1], is_bigendian);
583         b.block_size = u_endian_read4(&_ptfunxored[pos+3], is_bigendian);
584         b.content_type = u_endian_read2(&_ptfunxored[pos+7], is_bigendian);
585         b.offset = pos + 7;
586
587         if (b.block_size + b.offset > max)
588                 return false;
589         if (b.block_type & 0xff00)
590                 return false;
591
592         block->zmark = b.zmark;
593         block->block_type = b.block_type;
594         block->block_size = b.block_size;
595         block->content_type = b.content_type;
596         block->offset = b.offset;
597         block->child.clear();
598
599         for (i = 1; (i < block->block_size) && (pos + i + childjump < max); i += childjump ? childjump : 1) {
600                 int p = pos + i;
601                 struct block_t bchild;
602                 childjump = 0;
603                 if (parse_block_at(p, &bchild, block, level+1)) {
604                         block->child.push_back(bchild);
605                         childjump = bchild.block_size + 7;
606                 }
607         }
608         return true;
609 }
610
611 void
612 PTFFormat::dump_block(struct block_t& b, int level)
613 {
614         int i;
615
616         for (i = 0; i < level; i++) {
617                 printf("    ");
618         }
619         printf("%s(0x%04x)\n", get_content_description(b.content_type).c_str(), b.content_type);
620         hexdump(&_ptfunxored[b.offset], b.block_size, level);
621
622         for (vector<PTFFormat::block_t>::iterator c = b.child.begin();
623                         c != b.child.end(); ++c) {
624                 dump_block(*c, level + 1);
625         }
626 }
627
628 void
629 PTFFormat::free_block(struct block_t& b)
630 {
631         for (vector<PTFFormat::block_t>::iterator c = b.child.begin();
632                         c != b.child.end(); ++c) {
633                 free_block(*c);
634         }
635
636         b.child.clear();
637 }
638
639 void
640 PTFFormat::free_all_blocks(void)
641 {
642         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
643                         b != blocks.end(); ++b) {
644                 free_block(*b);
645         }
646
647         blocks.clear();
648 }
649
650 void
651 PTFFormat::dump(void) {
652         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
653                         b != blocks.end(); ++b) {
654                 dump_block(*b, 0);
655         }
656 }
657
658 void
659 PTFFormat::parseblocks(void) {
660         uint32_t i = 20;
661
662         while (i < _len) {
663                 struct block_t b;
664                 if (parse_block_at(i, &b, NULL, 0)) {
665                         blocks.push_back(b);
666                 }
667                 i += b.block_size ? b.block_size + 7 : 1;
668         }
669 }
670
671 int
672 PTFFormat::parse(void) {
673         parseblocks();
674 #ifdef DEBUG
675         dump();
676 #endif
677         if (!parseheader())
678                 return -1;
679         setrates();
680         if (_sessionrate < 44100 || _sessionrate > 192000)
681                 return -2;
682         if (!parseaudio())
683                 return -3;
684         if (!parserest())
685                 return -4;
686         if (!parsemidi())
687                 return -5;
688         return 0;
689 }
690
691 bool
692 PTFFormat::parseheader(void) {
693         bool found = false;
694
695         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
696                         b != blocks.end(); ++b) {
697                 if (b->content_type == 0x1028) {
698                         _sessionrate = u_endian_read4(&_ptfunxored[b->offset+4], is_bigendian);
699                         found = true;
700                 }
701         }
702         return found;
703 }
704
705 std::string
706 PTFFormat::parsestring (uint32_t pos) {
707         uint32_t length = u_endian_read4(&_ptfunxored[pos], is_bigendian);
708         pos += 4;
709         return std::string((const char *)&_ptfunxored[pos], length);
710 }
711
712 bool
713 PTFFormat::parseaudio(void) {
714         bool found = false;
715         uint32_t nwavs, i, n;
716         uint32_t pos = 0;
717         std::string wavtype;
718         std::string wavname;
719
720         // Parse wav names
721         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
722                         b != blocks.end(); ++b) {
723                 if (b->content_type == 0x1004) {
724
725                         nwavs = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
726
727                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
728                                         c != b->child.end(); ++c) {
729                                 if (c->content_type == 0x103a) {
730                                         found = true;
731                                         //nstrings = u_endian_read4(&_ptfunxored[c->offset+1], is_bigendian);
732                                         pos = c->offset + 11;
733                                         // Found wav list
734                                         for (i = n = 0; (pos < c->offset + c->block_size) && (n < nwavs); i++) {
735                                                 wavname = parsestring(pos);
736                                                 pos += wavname.size() + 4;
737                                                 wavtype = std::string((const char*)&_ptfunxored[pos], 4);
738                                                 pos += 9;
739                                                 if (foundin(wavname, std::string(".grp")))
740                                                         continue;
741
742                                                 if (foundin(wavname, std::string("Audio Files"))) {
743                                                         continue;
744                                                 }
745                                                 if (foundin(wavname, std::string("Fade Files"))) {
746                                                         continue;
747                                                 }
748                                                 if (_version < 10) {
749                                                         if (!(foundin(wavtype, std::string("WAVE")) ||
750                                                                         foundin(wavtype, std::string("EVAW")) ||
751                                                                         foundin(wavtype, std::string("AIFF")) ||
752                                                                         foundin(wavtype, std::string("FFIA"))) ) {
753                                                                 continue;
754                                                         }
755                                                 } else {
756                                                         if (wavtype.size() != 0) {
757                                                                 if (!(foundin(wavtype, std::string("WAVE")) ||
758                                                                                 foundin(wavtype, std::string("EVAW")) ||
759                                                                                 foundin(wavtype, std::string("AIFF")) ||
760                                                                                 foundin(wavtype, std::string("FFIA"))) ) {
761                                                                         continue;
762                                                                 }
763                                                         } else if (!(foundin(wavname, std::string(".wav")) || 
764                                                                         foundin(wavname, std::string(".aif"))) ) {
765                                                                 continue;
766                                                         }
767                                                 }
768                                                 wav_t f (n);
769                                                 f.filename = wavname;
770                                                 n++;
771                                                 _audiofiles.push_back(f);
772                                         }
773                                 }
774                         }
775                 }
776         }
777
778         // Add wav length information
779         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
780                         b != blocks.end(); ++b) {
781                 if (b->content_type == 0x1004) {
782
783                         vector<PTFFormat::wav_t>::iterator wav = _audiofiles.begin();
784
785                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
786                                         c != b->child.end(); ++c) {
787                                 if (c->content_type == 0x1003) {
788                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
789                                                         d != c->child.end(); ++d) {
790                                                 if (d->content_type == 0x1001) {
791                                                         (*wav).length = u_endian_read8(&_ptfunxored[d->offset+8], is_bigendian);
792                                                         wav++;
793                                                 }
794                                         }
795                                 }
796                         }
797                 }
798         }
799
800         return found;
801 }
802
803
804 void
805 PTFFormat::parse_three_point(uint32_t j, uint64_t& start, uint64_t& offset, uint64_t& length) {
806         uint8_t offsetbytes, lengthbytes, startbytes;
807
808         if (is_bigendian) {
809                 offsetbytes = (_ptfunxored[j+4] & 0xf0) >> 4;
810                 lengthbytes = (_ptfunxored[j+3] & 0xf0) >> 4;
811                 startbytes = (_ptfunxored[j+2] & 0xf0) >> 4;
812                 //somethingbytes = (_ptfunxored[j+2] & 0xf);
813                 //skipbytes = _ptfunxored[j+1];
814         } else {
815                 offsetbytes = (_ptfunxored[j+1] & 0xf0) >> 4; //3
816                 lengthbytes = (_ptfunxored[j+2] & 0xf0) >> 4;
817                 startbytes = (_ptfunxored[j+3] & 0xf0) >> 4; //1
818                 //somethingbytes = (_ptfunxored[j+3] & 0xf);
819                 //skipbytes = _ptfunxored[j+4];
820         }
821
822         switch (offsetbytes) {
823         case 5:
824                 offset = u_endian_read5(&_ptfunxored[j+5], false);
825                 break;
826         case 4:
827                 offset = (uint64_t)u_endian_read4(&_ptfunxored[j+5], false);
828                 break;
829         case 3:
830                 offset = (uint64_t)u_endian_read3(&_ptfunxored[j+5], false);
831                 break;
832         case 2:
833                 offset = (uint64_t)u_endian_read2(&_ptfunxored[j+5], false);
834                 break;
835         case 1:
836                 offset = (uint64_t)(_ptfunxored[j+5]);
837                 break;
838         default:
839                 offset = 0;
840                 break;
841         }
842         j+=offsetbytes;
843         switch (lengthbytes) {
844         case 5:
845                 length = u_endian_read5(&_ptfunxored[j+5], false);
846                 break;
847         case 4:
848                 length = (uint64_t)u_endian_read4(&_ptfunxored[j+5], false);
849                 break;
850         case 3:
851                 length = (uint64_t)u_endian_read3(&_ptfunxored[j+5], false);
852                 break;
853         case 2:
854                 length = (uint64_t)u_endian_read2(&_ptfunxored[j+5], false);
855                 break;
856         case 1:
857                 length = (uint64_t)(_ptfunxored[j+5]);
858                 break;
859         default:
860                 length = 0;
861                 break;
862         }
863         j+=lengthbytes;
864         switch (startbytes) {
865         case 5:
866                 start = u_endian_read5(&_ptfunxored[j+5], false);
867                 break;
868         case 4:
869                 start = (uint64_t)u_endian_read4(&_ptfunxored[j+5], false);
870                 break;
871         case 3:
872                 start = (uint64_t)u_endian_read3(&_ptfunxored[j+5], false);
873                 break;
874         case 2:
875                 start = (uint64_t)u_endian_read2(&_ptfunxored[j+5], false);
876                 break;
877         case 1:
878                 start = (uint64_t)(_ptfunxored[j+5]);
879                 break;
880         default:
881                 start = 0;
882                 break;
883         }
884 }
885
886 void
887 PTFFormat::parse_region_info(uint32_t j, block_t& blk, region_t& r) {
888         uint64_t findex, start, sampleoffset, length;
889
890         parse_three_point(j, start, sampleoffset, length);
891
892         findex = u_endian_read4(&_ptfunxored[blk.offset + blk.block_size], is_bigendian);
893         wav_t f (findex);
894         f.posabsolute = start * _ratefactor;
895         f.length = length * _ratefactor;
896
897         wav_t found;
898         if (find_wav(findex, found)) {
899                 f.filename = found.filename;
900         }
901
902         std::vector<midi_ev_t> m;
903         r.startpos = (int64_t)(start*_ratefactor);
904         r.sampleoffset = (int64_t)(sampleoffset*_ratefactor);
905         r.length = (int64_t)(length*_ratefactor);
906         r.wave = f;
907         r.midi = m;
908 }
909
910 bool
911 PTFFormat::parserest(void) {
912         uint32_t i, j, count;
913         uint64_t start;
914         uint16_t rindex, rawindex, tindex, mindex;
915         uint32_t nch;
916         uint16_t ch_map[MAX_CHANNELS_PER_TRACK];
917         bool found = false;
918         bool region_is_fade = false;
919         std::string regionname, trackname, midiregionname;
920         rindex = 0;
921
922         // Parse sources->regions
923         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
924                         b != blocks.end(); ++b) {
925                 if (b->content_type == 0x100b || b->content_type == 0x262a) {
926                         //nregions = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
927                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
928                                         c != b->child.end(); ++c) {
929                                 if (c->content_type == 0x1008 || c->content_type == 0x2629) {
930                                         vector<PTFFormat::block_t>::iterator d = c->child.begin();
931                                         region_t r;
932
933                                         found = true;
934                                         j = c->offset + 11;
935                                         regionname = parsestring(j);
936                                         j += regionname.size() + 4;
937
938                                         r.name = regionname;
939                                         r.index = rindex;
940                                         parse_region_info(j, *d, r);
941
942                                         _regions.push_back(r);
943                                         rindex++;
944                                 }
945                         }
946                         found = true;
947                 }
948         }
949
950         // Parse tracks
951         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
952                         b != blocks.end(); ++b) {
953                 if (b->content_type == 0x1015) {
954                         //ntracks = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
955                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
956                                         c != b->child.end(); ++c) {
957                                 if (c->content_type == 0x1014) {
958                                         j = c->offset + 2;
959                                         trackname = parsestring(j);
960                                         j += trackname.size() + 5;
961                                         nch = u_endian_read4(&_ptfunxored[j], is_bigendian);
962                                         j += 4;
963                                         for (i = 0; i < nch; i++) {
964                                                 ch_map[i] = u_endian_read2(&_ptfunxored[j], is_bigendian);
965
966                                                 track_t ti;
967                                                 if (!find_track(ch_map[i], ti)) {
968                                                         // Add a dummy region for now
969                                                         region_t r (65535);
970                                                         track_t t (ch_map[i]);
971                                                         t.name = trackname;
972                                                         t.reg = r;
973                                                         _tracks.push_back(t);
974                                                 }
975                                                 //verbose_printf("%s : %d(%d)\n", reg, nch, ch_map[0]);
976                                                 j += 2;
977                                         }
978                                 }
979                         }
980                 }
981         }
982
983         // Reparse from scratch to exclude audio tracks from all tracks to get midi tracks
984         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
985                         b != blocks.end(); ++b) {
986                 if (b->content_type == 0x2519) {
987                         tindex = 0;
988                         mindex = 0;
989                         //ntracks = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
990                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
991                                         c != b->child.end(); ++c) {
992                                 if (c->content_type == 0x251a) {
993                                         j = c->offset + 4;
994                                         trackname = parsestring(j);
995                                         j += trackname.size() + 4 + 18;
996                                         //tindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
997
998                                         // Add a dummy region for now
999                                         region_t r (65535);
1000                                         track_t t (mindex);
1001                                         t.name = trackname;
1002                                         t.reg = r;
1003
1004                                         track_t ti;
1005                                         // If the current track is not an audio track, insert as midi track
1006                                         if (!(find_track(tindex, ti) && foundin(trackname, ti.name))) {
1007                                                 _miditracks.push_back(t);
1008                                                 mindex++;
1009                                         }
1010                                         tindex++;
1011                                 }
1012                         }
1013                 }
1014         }
1015
1016         // Parse regions->tracks
1017         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
1018                         b != blocks.end(); ++b) {
1019                 tindex = 0;
1020                 if (b->content_type == 0x1012) {
1021                         //nregions = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
1022                         count = 0;
1023                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
1024                                         c != b->child.end(); ++c) {
1025                                 if (c->content_type == 0x1011) {
1026                                         regionname = parsestring(c->offset + 2);
1027                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
1028                                                         d != c->child.end(); ++d) {
1029                                                 if (d->content_type == 0x100f) {
1030                                                         for (vector<PTFFormat::block_t>::iterator e = d->child.begin();
1031                                                                         e != d->child.end(); ++e) {
1032                                                                 if (e->content_type == 0x100e) {
1033                                                                         // Region->track
1034                                                                         track_t ti;
1035                                                                         j = e->offset + 4;
1036                                                                         rawindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
1037                                                                         if (!find_track(count, ti))
1038                                                                                 continue;
1039                                                                         if (!find_region(rawindex, ti.reg))
1040                                                                                 continue;
1041                                                                         if (ti.reg.index != 65535) {
1042                                                                                 _tracks.push_back(ti);
1043                                                                         }
1044                                                                 }
1045                                                         }
1046                                                 }
1047                                         }
1048                                         found = true;
1049                                         count++;
1050                                 }
1051                         }
1052                 } else if (b->content_type == 0x1054) {
1053                         //nregions = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
1054                         count = 0;
1055                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
1056                                         c != b->child.end(); ++c) {
1057                                 if (c->content_type == 0x1052) {
1058                                         trackname = parsestring(c->offset + 2);
1059                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
1060                                                         d != c->child.end(); ++d) {
1061                                                 if (d->content_type == 0x1050) {
1062                                                         region_is_fade = (_ptfunxored[d->offset + 46] == 0x01);
1063                                                         if (region_is_fade) {
1064                                                                 verbose_printf("dropped fade region\n");
1065                                                                 continue;
1066                                                         }
1067                                                         for (vector<PTFFormat::block_t>::iterator e = d->child.begin();
1068                                                                         e != d->child.end(); ++e) {
1069                                                                 if (e->content_type == 0x104f) {
1070                                                                         // Region->track
1071                                                                         j = e->offset + 4;
1072                                                                         rawindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
1073                                                                         j += 4 + 1;
1074                                                                         start = u_endian_read4(&_ptfunxored[j], is_bigendian);
1075                                                                         tindex = count;
1076                                                                         track_t ti;
1077                                                                         if (!find_track(tindex, ti)) {
1078                                                                                 verbose_printf("dropped track %d\n", tindex);
1079                                                                                 continue;
1080                                                                         }
1081                                                                         if (!find_region(rawindex, ti.reg)) {
1082                                                                                 verbose_printf("dropped region %d\n", rawindex);
1083                                                                                 continue;
1084                                                                         }
1085                                                                         ti.reg.startpos = start * _ratefactor;
1086                                                                         if (ti.reg.index != 65535) {
1087                                                                                 _tracks.push_back(ti);
1088                                                                         }
1089                                                                 }
1090                                                         }
1091                                                 }
1092                                         }
1093                                         found = true;
1094                                         count++;
1095                                 }
1096                         }
1097                 }
1098         }
1099         for (std::vector<track_t>::iterator tr = _tracks.begin();
1100                         tr != _tracks.end(); /* noop */) {
1101                 if ((*tr).reg.index == 65535) {
1102                         tr = _tracks.erase(tr);
1103                 } else {
1104                         tr++;
1105                 }
1106         }
1107         return found;
1108 }
1109
1110 struct mchunk {
1111         mchunk (uint64_t zt, uint64_t ml, std::vector<PTFFormat::midi_ev_t> const& c)
1112         : zero (zt)
1113         , maxlen (ml)
1114         , chunk (c)
1115         {}
1116         uint64_t zero;
1117         uint64_t maxlen;
1118         std::vector<PTFFormat::midi_ev_t> chunk;
1119 };
1120
1121 bool
1122 PTFFormat::parsemidi(void) {
1123         uint32_t i, j, k, n, rindex, tindex, mindex, count, rawindex;
1124         uint64_t n_midi_events, zero_ticks, start, offset, length, start2, stop2;
1125         uint64_t midi_pos, midi_len, max_pos, region_pos;
1126         uint8_t midi_velocity, midi_note;
1127         uint16_t regionnumber = 0;
1128         std::string midiregionname;
1129
1130         std::vector<mchunk> midichunks;
1131         midi_ev_t m;
1132
1133         std::string regionname, trackname;
1134         rindex = 0;
1135
1136         // Parse MIDI events
1137         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
1138                         b != blocks.end(); ++b) {
1139                 if (b->content_type == 0x2000) {
1140
1141                         k = b->offset;
1142
1143                         // Parse all midi chunks, not 1:1 mapping to regions yet
1144                         while (k + 35 < b->block_size + b->offset) {
1145                                 max_pos = 0;
1146                                 std::vector<midi_ev_t> midi;
1147
1148                                 if (!jumpto(&k, _ptfunxored, _len, (const unsigned char *)"MdNLB", 5)) {
1149                                         break;
1150                                 }
1151                                 k += 11;
1152                                 n_midi_events = u_endian_read4(&_ptfunxored[k], is_bigendian);
1153
1154                                 k += 4;
1155                                 zero_ticks = u_endian_read5(&_ptfunxored[k], is_bigendian);
1156                                 for (i = 0; i < n_midi_events && k < _len; i++, k += 35) {
1157                                         midi_pos = u_endian_read5(&_ptfunxored[k], is_bigendian);
1158                                         midi_pos -= zero_ticks;
1159                                         midi_note = _ptfunxored[k+8];
1160                                         midi_len = u_endian_read5(&_ptfunxored[k+9], is_bigendian);
1161                                         midi_velocity = _ptfunxored[k+17];
1162
1163                                         if (midi_pos + midi_len > max_pos) {
1164                                                 max_pos = midi_pos + midi_len;
1165                                         }
1166
1167                                         m.pos = midi_pos;
1168                                         m.length = midi_len;
1169                                         m.note = midi_note;
1170                                         m.velocity = midi_velocity;
1171                                         midi.push_back(m);
1172                                 }
1173                                 midichunks.push_back(mchunk (zero_ticks, max_pos, midi));
1174                         }
1175
1176                 // Put chunks onto regions
1177                 } else if ((b->content_type == 0x2002) || (b->content_type == 0x2634)) {
1178                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
1179                                         c != b->child.end(); ++c) {
1180                                 if ((c->content_type == 0x2001) || (c->content_type == 0x2633)) {
1181                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
1182                                                         d != c->child.end(); ++d) {
1183                                                 if ((d->content_type == 0x1007) || (d->content_type == 0x2628)) {
1184                                                         j = d->offset + 2;
1185                                                         midiregionname = parsestring(j);
1186                                                         j += 4 + midiregionname.size();
1187                                                         parse_three_point(j, region_pos, zero_ticks, midi_len);
1188                                                         j = d->offset + d->block_size;
1189                                                         rindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
1190                                                         struct mchunk mc = *(midichunks.begin()+rindex);
1191
1192                                                         region_t r (regionnumber++);
1193                                                         r.name = midiregionname;
1194                                                         r.startpos = (int64_t)0xe8d4a51000ULL;
1195                                                         r.sampleoffset = 0;
1196                                                         r.length = mc.maxlen;
1197                                                         r.midi = mc.chunk;
1198
1199                                                         _midiregions.push_back(r);
1200                                                         //verbose_printf("MIDI %s : r(%d) (%llu, %llu, %llu)\n", str, rindex, zero_ticks, region_pos, midi_len);
1201                                                         //dump_block(*d, 1);
1202                                                 }
1203                                         }
1204                                 }
1205                         }
1206                 } 
1207         }
1208         
1209         // COMPOUND MIDI regions
1210         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
1211                         b != blocks.end(); ++b) {
1212                 if (b->content_type == 0x262c) {
1213                         mindex = 0;
1214                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
1215                                         c != b->child.end(); ++c) {
1216                                 if (c->content_type == 0x262b) {
1217                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
1218                                                         d != c->child.end(); ++d) {
1219                                                 if (d->content_type == 0x2628) {
1220                                                         count = 0;
1221                                                         j = d->offset + 2;
1222                                                         regionname = parsestring(j);
1223                                                         j += 4 + regionname.size();
1224                                                         parse_three_point(j, start, offset, length);
1225                                                         j = d->offset + d->block_size + 2;
1226                                                         n = u_endian_read2(&_ptfunxored[j], is_bigendian);
1227
1228                                                         for (vector<PTFFormat::block_t>::iterator e = d->child.begin();
1229                                                                         e != d->child.end(); ++e) {
1230                                                                 if (e->content_type == 0x2523) {
1231                                                                         // FIXME Compound MIDI region
1232                                                                         j = e->offset + 39;
1233                                                                         rawindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
1234                                                                         j += 12; 
1235                                                                         start2 = u_endian_read5(&_ptfunxored[j], is_bigendian);
1236                                                                         int64_t signedval = (int64_t)start2;
1237                                                                         signedval -= ZERO_TICKS;
1238                                                                         if (signedval < 0) {
1239                                                                                 signedval = -signedval;
1240                                                                         }
1241                                                                         start2 = signedval;
1242                                                                         j += 8;
1243                                                                         stop2 = u_endian_read5(&_ptfunxored[j], is_bigendian);
1244                                                                         signedval = (int64_t)stop2;
1245                                                                         signedval -= ZERO_TICKS;
1246                                                                         if (signedval < 0) {
1247                                                                                 signedval = -signedval;
1248                                                                         }
1249                                                                         stop2 = signedval;
1250                                                                         j += 16;
1251                                                                         //nn = u_endian_read4(&_ptfunxored[j], is_bigendian);
1252                                                                         //verbose_printf("COMPOUND %s : c(%d) r(%d) ?(%d) ?(%d) (%llu %llu)(%llu %llu %llu)\n", str, mindex, rawindex, n, nn, start2, stop2, start, offset, length);
1253                                                                         count++;
1254                                                                 }
1255                                                         }
1256                                                         if (!count) {
1257                                                                 // Plain MIDI region
1258                                                                 struct mchunk mc = *(midichunks.begin()+n);
1259
1260                                                                 region_t r (n);
1261                                                                 r.name = midiregionname;
1262                                                                 r.startpos = (int64_t)0xe8d4a51000ULL;
1263                                                                 r.length = mc.maxlen;
1264                                                                 r.midi = mc.chunk;
1265                                                                 _midiregions.push_back(r);
1266                                                                 verbose_printf("%s : MIDI region mr(%d) ?(%d) (%lu %lu %lu)\n", regionname.c_str(), mindex, n, start, offset, length);
1267                                                                 mindex++;
1268                                                         }
1269                                                 }
1270                                         }
1271                                 }
1272                         }
1273                 } 
1274         }
1275         
1276         // Put midi regions onto midi tracks
1277         for (vector<PTFFormat::block_t>::iterator b = blocks.begin();
1278                         b != blocks.end(); ++b) {
1279                 if (b->content_type == 0x1058) {
1280                         //nregions = u_endian_read4(&_ptfunxored[b->offset+2], is_bigendian);
1281                         count = 0;
1282                         for (vector<PTFFormat::block_t>::iterator c = b->child.begin();
1283                                         c != b->child.end(); ++c) {
1284                                 if (c->content_type == 0x1057) {
1285                                         regionname = parsestring(c->offset + 2);
1286                                         for (vector<PTFFormat::block_t>::iterator d = c->child.begin();
1287                                                         d != c->child.end(); ++d) {
1288                                                 if (d->content_type == 0x1056) {
1289                                                         for (vector<PTFFormat::block_t>::iterator e = d->child.begin();
1290                                                                         e != d->child.end(); ++e) {
1291                                                                 if (e->content_type == 0x104f) {
1292                                                                         // MIDI region->MIDI track
1293                                                                         track_t ti;
1294                                                                         j = e->offset + 4;
1295                                                                         rawindex = u_endian_read4(&_ptfunxored[j], is_bigendian);
1296                                                                         j += 4 + 1;
1297                                                                         start = u_endian_read5(&_ptfunxored[j], is_bigendian);
1298                                                                         tindex = count;
1299                                                                         if (!find_miditrack(tindex, ti)) {
1300                                                                                 verbose_printf("dropped midi t(%d) r(%d)\n", tindex, rawindex);
1301                                                                                 continue;
1302                                                                         }
1303                                                                         if (!find_midiregion(rawindex, ti.reg)) {
1304                                                                                 verbose_printf("dropped midiregion\n");
1305                                                                                 continue;
1306                                                                         }
1307                                                                         //verbose_printf("MIDI : %s : t(%d) r(%d) %llu(%llu)\n", ti.name.c_str(), tindex, rawindex, start, ti.reg.startpos);
1308                                                                         int64_t signedstart = (int64_t)(start - ZERO_TICKS);
1309                                                                         if (signedstart < 0)
1310                                                                                 signedstart = -signedstart;
1311                                                                         ti.reg.startpos = (uint64_t)(signedstart * _ratefactor);
1312                                                                         if (ti.reg.index != 65535) {
1313                                                                                 _miditracks.push_back(ti);
1314                                                                         }
1315                                                                 }
1316                                                         }
1317                                                 }
1318                                         }
1319                                         count++;
1320                                 }
1321                         }
1322                 }
1323         }
1324         for (std::vector<track_t>::iterator tr = _miditracks.begin();
1325                         tr != _miditracks.end(); /* noop */) {
1326                 if ((*tr).reg.index == 65535) {
1327                         tr = _miditracks.erase(tr);
1328                 } else {
1329                         tr++;
1330                 }
1331         }
1332         return true;
1333 }