2 Copyright (C) 2015 Damien Zammit
3 Copyright (C) 2015 Robin Gareus
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.
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.
23 #include <glib/gstdio.h>
25 #include "ptfformat.h"
30 hexdump(uint8_t *data, int len)
34 for (i = 0; i < len; i += step) {
35 printf("0x%02X: ", i);
37 if (end > len) end = len;
38 for (j = i; j < end; j++) {
39 printf("0x%02X ", data[j]);
41 for (j = i; j < end; j++) {
42 if (data[j] < 128 && data[j] > 32)
43 printf("%c", data[j]);
51 PTFFormat::PTFFormat() : version(0), product(NULL) {
54 PTFFormat::~PTFFormat() {
61 PTFFormat::foundin(std::string haystack, std::string needle) {
62 size_t found = haystack.find(needle);
63 if (found != std::string::npos) {
70 /* Return values: 0 success
71 0x01 to 0xff value of missing lut
72 -1 could not open file as ptf
75 PTFFormat::load(std::string path, int64_t targetsr) {
77 unsigned char xxor[256];
86 if (! (fp = g_fopen(path.c_str(), "rb"))) {
90 fseek(fp, 0, SEEK_END);
97 if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
98 /* Silently fail -- out of memory*/
104 /* The first 20 bytes are always unencrypted */
105 fseek(fp, 0x00, SEEK_SET);
106 i = fread(ptfunxored, 1, 0x14, fp);
112 xor_type = ptfunxored[0x12];
113 xor_value = ptfunxored[0x13];
115 // xor_type 0x01 = ProTools 5, 6, 7, 8 and 9
116 // xor_type 0x05 = ProTools 10, 11, 12
119 xor_delta = gen_xor_delta(xor_value, 53, false);
123 xor_delta = gen_xor_delta(xor_value, 11, true);
131 /* Generate the xor_key */
132 for (i=0; i < xor_len; i++)
133 xxor[i] = (i * xor_delta) & 0xff;
135 /* hexdump(xxor, xor_len); */
137 /* Read file and decrypt rest of file */
139 fseek(fp, i, SEEK_SET);
140 while (fread(&ct, 1, 1, fp) != 0) {
141 uint8_t xor_index = (xor_type == 0x01) ? i & 0xff : (i >> 12) & 0x7f;
142 ptfunxored[i++] = ct ^ xxor[xor_index];
146 if (!parse_version())
149 if (version < 5 || version > 12)
152 targetrate = targetsr;
161 PTFFormat::parse_version() {
162 uint32_t seg_len,str_len;
163 uint8_t *data = ptfunxored + 0x14;
164 uintptr_t data_end = ((uintptr_t)ptfunxored) + 0x100;
166 bool success = false;
168 while( ((uintptr_t)data < data_end) && (success == false) ) {
170 if (data[0] != 0x5a) {
176 /* Skip segment header */
178 if (data[0] == 0 && data[1] == 0) {
180 seg_len = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
183 seg_len = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0];
187 if (!(seg_type == 0x04 || seg_type == 0x03) || data[0] != 0x03) {
188 /* Go to next segment */
192 /* Skip 0x03 0x00 0x00 */
195 str_len = (*(uint8_t *)data);
196 if (! (product = (uint8_t *)malloc((str_len+1) * sizeof(uint8_t)))) {
205 memcpy(product, data, str_len);
206 product[str_len] = 0;
210 /* Skip 0x03 0x00 0x00 0x00 */
222 /* If the above does not work, assume old version 5,6,7 */
223 if ((uintptr_t)data >= data_end - seg_len) {
224 version = ptfunxored[0x40];
231 PTFFormat::gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative) {
233 for (i = 0; i < 256; i++) {
234 if (((i * mul) & 0xff) == xor_value) {
235 return (negative) ? i * (-1) : i;
243 PTFFormat::parse(void) {
247 if (sessionrate < 44100 || sessionrate > 192000)
252 } else if (version == 7) {
255 if (sessionrate < 44100 || sessionrate > 192000)
260 } else if (version == 8) {
263 if (sessionrate < 44100 || sessionrate > 192000)
268 } else if (version == 9) {
271 if (sessionrate < 44100 || sessionrate > 192000)
276 } else if (version == 10 || version == 11 || version == 12) {
279 if (sessionrate < 44100 || sessionrate > 192000)
292 PTFFormat::setrates(void) {
294 if (sessionrate != 0) {
295 ratefactor = (float)targetrate / sessionrate;
300 PTFFormat::parse5header(void) {
303 // Find session sample rate
306 if ( (ptfunxored[k ] == 0x5a) &&
307 (ptfunxored[k+1] == 0x00) &&
308 (ptfunxored[k+2] == 0x02)) {
315 sessionrate |= ptfunxored[k+12] << 16;
316 sessionrate |= ptfunxored[k+13] << 8;
317 sessionrate |= ptfunxored[k+14];
321 PTFFormat::parse7header(void) {
324 // Find session sample rate
327 if ( (ptfunxored[k ] == 0x5a) &&
328 (ptfunxored[k+1] == 0x00) &&
329 (ptfunxored[k+2] == 0x05)) {
336 sessionrate |= ptfunxored[k+12] << 16;
337 sessionrate |= ptfunxored[k+13] << 8;
338 sessionrate |= ptfunxored[k+14];
342 PTFFormat::parse8header(void) {
345 // Find session sample rate
348 if ( (ptfunxored[k ] == 0x5a) &&
349 (ptfunxored[k+1] == 0x05)) {
356 sessionrate |= ptfunxored[k+11];
357 sessionrate |= ptfunxored[k+12] << 8;
358 sessionrate |= ptfunxored[k+13] << 16;
362 PTFFormat::parse9header(void) {
365 // Find session sample rate
368 if ( (ptfunxored[k ] == 0x5a) &&
369 (ptfunxored[k+1] == 0x06)) {
376 sessionrate |= ptfunxored[k+11];
377 sessionrate |= ptfunxored[k+12] << 8;
378 sessionrate |= ptfunxored[k+13] << 16;
382 PTFFormat::parse10header(void) {
385 // Find session sample rate
388 if ( (ptfunxored[k ] == 0x5a) &&
389 (ptfunxored[k+1] == 0x09)) {
396 sessionrate |= ptfunxored[k+11];
397 sessionrate |= ptfunxored[k+12] << 8;
398 sessionrate |= ptfunxored[k+13] << 16;
402 PTFFormat::parserest5(void) {
404 uint64_t regionspertrack, lengthofname;
405 uint64_t startbytes, lengthbytes, offsetbytes;
406 uint16_t tracknumber = 0;
411 for (i = 0; i < 5; i++) {
413 if ( (ptfunxored[k ] == 0x5a) &&
414 (ptfunxored[k+1] == 0x00) &&
415 (ptfunxored[k+2] == 0x03)) {
424 for (i = 0; i < 2; i++) {
426 if ( (ptfunxored[k ] == 0x5a) &&
427 (ptfunxored[k+1] == 0x00) &&
428 (ptfunxored[k+2] == 0x01)) {
440 if ( (ptfunxored[k ] == 0xff) &&
441 (ptfunxored[k+1] == 0xff)) {
445 if ( (ptfunxored[k ] == 0x5a) &&
446 (ptfunxored[k+1] == 0x00) &&
447 (ptfunxored[k+2] == 0x01)) {
453 lengthofname = ptfunxored[k+12];
454 if (ptfunxored[k+13] == 0x5a) {
458 char name[256] = {0};
459 for (j = 0; j < lengthofname; j++) {
460 name[j] = ptfunxored[k+13+j];
463 regionspertrack = ptfunxored[k+13+j+3];
464 for (i = 0; i < regionspertrack; i++) {
466 if ( (ptfunxored[k ] == 0x5a) &&
467 (ptfunxored[k+1] == 0x00) &&
468 (ptfunxored[k+2] == 0x03)) {
474 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
475 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
476 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
477 //somethingbytes = (ptfunxored[j+1] & 0xf);
478 findex = ptfunxored[k+14];
481 switch (startbytes) {
483 start |= (uint32_t)(ptfunxored[j+8] << 24);
485 start |= (uint32_t)(ptfunxored[j+7] << 16);
487 start |= (uint32_t)(ptfunxored[j+6] << 8);
489 start |= (uint32_t)(ptfunxored[j+5]);
495 switch (lengthbytes) {
497 length |= (uint32_t)(ptfunxored[j+8] << 24);
499 length |= (uint32_t)(ptfunxored[j+7] << 16);
501 length |= (uint32_t)(ptfunxored[j+6] << 8);
503 length |= (uint32_t)(ptfunxored[j+5]);
508 uint32_t sampleoffset = 0;
509 switch (offsetbytes) {
511 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
513 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
515 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
517 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
523 //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
525 std::string filename = string(name) + extension;
529 (int64_t)(start*ratefactor),
530 (int64_t)(length*ratefactor),
533 vector<wav_t>::iterator begin = audiofiles.begin();
534 vector<wav_t>::iterator finish = audiofiles.end();
535 vector<wav_t>::iterator found;
537 if ((found = std::find(begin, finish, f)) != finish) {
538 std::vector<midi_ev_t> m;
542 (int64_t)(start*ratefactor),
543 (int64_t)(sampleoffset*ratefactor),
544 (int64_t)(length*ratefactor),
548 regions.push_back(r);
549 vector<track_t>::iterator ti;
550 vector<track_t>::iterator bt = tracks.begin();
551 vector<track_t>::iterator et = tracks.end();
552 track_t tr = { name, 0, 0, r };
553 if ((ti = std::find(bt, et, tr)) != et) {
554 tracknumber = (*ti).index;
556 tracknumber = tracks.size() + 1;
560 (uint16_t)tracknumber,
566 std::vector<midi_ev_t> m;
570 (int64_t)(start*ratefactor),
571 (int64_t)(sampleoffset*ratefactor),
572 (int64_t)(length*ratefactor),
576 regions.push_back(r);
577 vector<track_t>::iterator ti;
578 vector<track_t>::iterator bt = tracks.begin();
579 vector<track_t>::iterator et = tracks.end();
580 track_t tr = { name, 0, 0, r };
581 if ((ti = std::find(bt, et, tr)) != et) {
582 tracknumber = (*ti).index;
584 tracknumber = tracks.size() + 1;
588 (uint16_t)tracknumber,
602 PTFFormat::resort(std::vector<wav_t>& ws) {
604 std::sort(ws.begin(), ws.end());
605 for (std::vector<wav_t>::iterator i = ws.begin(); i != ws.end(); ++i) {
612 PTFFormat::parseaudio5(void) {
614 uint64_t lengthofname, wavnumber;
616 // Find end of wav file list
619 if ( (ptfunxored[k ] == 0x5f) &&
620 (ptfunxored[k+1] == 0x50) &&
621 (ptfunxored[k+2] == 0x35)) {
628 if ( (ptfunxored[k ] == 0x5f) &&
629 (ptfunxored[k+1] == 0x50) &&
630 (ptfunxored[k+2] == 0x35)) {
636 // Find actual wav names
637 uint16_t numberofwavs = ptfunxored[k-23];
639 for (i = k; i < len; i++) {
640 if ( (ptfunxored[i ] == 'F') &&
641 (ptfunxored[i+1] == 'i') &&
642 (ptfunxored[i+2] == 'l') &&
643 (ptfunxored[i+3] == 'e') &&
644 (ptfunxored[i+4] == 's')) {
652 while (i < len && numberofwavs > 0) {
654 if ( (ptfunxored[i ] == 0x5a) &&
655 (ptfunxored[i+1] == 0x00) &&
656 (ptfunxored[i+2] == 0x05)) {
659 lengthofname = ptfunxored[i];
662 while (l < lengthofname) {
663 wavname[l] = ptfunxored[i+l];
667 ext[0] = ptfunxored[i++];
668 ext[1] = ptfunxored[i++];
669 ext[2] = ptfunxored[i++];
670 ext[3] = ptfunxored[i++];
674 if (foundin(wavname, ".L") || foundin(wavname, ".R")) {
675 extension = string("");
676 } else if (foundin(wavname, ".wav") || foundin(ext, "WAVE")) {
677 extension = string(".wav");
678 } else if (foundin(wavname, ".aif") || foundin(ext, "AIFF")) {
679 extension = string(".aif");
681 extension = string("");
684 std::string wave = string(wavname);
685 wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
687 if (foundin(wave, string(".grp"))) {
691 actualwavs.push_back(f);
692 audiofiles.push_back(f);
702 PTFFormat::parsemidi(void) {
703 uint64_t i, k, n_midi_events, zero_ticks;
704 uint64_t midi_pos, midi_len, max_pos;
705 uint8_t midi_velocity, midi_note;
709 int max_regions = regions.size();
710 char midiname[26] = { 0 };
715 // Parse all midi tracks, treat each group of midi bytes as a track
716 while (k + 35 < len) {
718 std::vector<midi_ev_t> midi;
721 if ( (ptfunxored[k ] == 'M') &&
722 (ptfunxored[k+1] == 'd') &&
723 (ptfunxored[k+2] == 'N') &&
724 (ptfunxored[k+3] == 'L') &&
725 (ptfunxored[k+4] == 'B')) {
737 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
738 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
741 zero_ticks = (uint64_t)ptfunxored[k] |
742 (uint64_t)ptfunxored[k+1] << 8 |
743 (uint64_t)ptfunxored[k+2] << 16 |
744 (uint64_t)ptfunxored[k+3] << 24 |
745 (uint64_t)ptfunxored[k+4] << 32;
746 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
747 midi_pos = (uint64_t)ptfunxored[k] |
748 (uint64_t)ptfunxored[k+1] << 8 |
749 (uint64_t)ptfunxored[k+2] << 16 |
750 (uint64_t)ptfunxored[k+3] << 24 |
751 (uint64_t)ptfunxored[k+4] << 32;
752 midi_pos -= zero_ticks;
753 midi_note = ptfunxored[k+8];
754 midi_len = (uint64_t)ptfunxored[k+9] |
755 (uint64_t)ptfunxored[k+10] << 8 |
756 (uint64_t)ptfunxored[k+11] << 16 |
757 (uint64_t)ptfunxored[k+12] << 24 |
758 (uint64_t)ptfunxored[k+13] << 32;
759 midi_velocity = ptfunxored[k+17];
761 if (midi_pos + midi_len > max_pos) {
762 max_pos = midi_pos + midi_len;
768 m.velocity = midi_velocity;
771 //fprintf(stderr, "MIDI: Note=%d Vel=%d Start=%d(samples) Len=%d(samples)\n", midi_note, midi_velocity, midi_pos, midi_len);
774 rsize = (uint16_t)regions.size();
775 snprintf(midiname, 20, "MIDI-%d", rsize - max_regions + 1);
776 wav_t w = { std::string(""), 0, 0, 0 };
782 (int64_t)(max_pos*sessionrate*60/(960000*120)),
786 regions.push_back(r);
791 PTFFormat::parseaudio(void) {
794 // Find end of wav file list
797 if ( (ptfunxored[k ] == 0xff) &&
798 (ptfunxored[k+1] == 0xff) &&
799 (ptfunxored[k+2] == 0xff) &&
800 (ptfunxored[k+3] == 0xff)) {
806 // Find actual wav names
808 uint16_t numberofwavs;
810 for (i = k; i > 4; i--) {
811 if ( ((ptfunxored[i ] == 'W') || (ptfunxored[i ] == 'A')) &&
812 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I')) &&
813 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F')) &&
814 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F'))) {
817 while (ptfunxored[j] != '\0') {
818 wavname[l] = ptfunxored[j];
823 if (ptfunxored[i] == 'W') {
824 extension = string(".wav");
826 extension = string(".aif");
828 //uint8_t playlist = ptfunxored[j-8];
832 for (j = k; j > 4; j--) {
833 if ( (ptfunxored[j ] == 0x01) &&
834 (ptfunxored[j-1] == 0x5a)) {
837 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
838 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
839 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
840 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
841 //printf("%d wavs\n", numberofwavs);
848 std::string wave = string(wavname);
849 std::reverse(wave.begin(), wave.end());
850 wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
852 if (foundin(wave, string(".grp"))) {
856 actualwavs.push_back(f);
859 if (numberofwavs <= 0)
866 PTFFormat::parserest89(void) {
869 uint8_t startbytes = 0;
870 uint8_t lengthbytes = 0;
871 uint8_t offsetbytes = 0;
872 uint8_t somethingbytes = 0;
873 uint8_t skipbytes = 0;
877 if ( (ptfunxored[k ] == 'S') &&
878 (ptfunxored[k+1] == 'n') &&
879 (ptfunxored[k+2] == 'a') &&
880 (ptfunxored[k+3] == 'p')) {
887 for (i = k; i < len-70; i++) {
888 if ( (ptfunxored[i ] == 0x5a) &&
889 (ptfunxored[i+1] == 0x0a)) {
892 if ( (ptfunxored[i ] == 0x5a) &&
893 (ptfunxored[i+1] == 0x0c)) {
895 uint8_t lengthofname = ptfunxored[i+9];
897 char name[256] = {0};
898 for (j = 0; j < lengthofname; j++) {
899 name[j] = ptfunxored[i+13+j];
903 //uint8_t disabled = ptfunxored[j];
905 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
906 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
907 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
908 somethingbytes = (ptfunxored[j+3] & 0xf);
909 skipbytes = ptfunxored[j+4];
910 findex = ptfunxored[j+5
917 /*rindex = ptfunxored[j+5
925 uint32_t sampleoffset = 0;
926 switch (offsetbytes) {
928 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
930 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
932 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
934 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
940 switch (lengthbytes) {
942 length |= (uint32_t)(ptfunxored[j+8] << 24);
944 length |= (uint32_t)(ptfunxored[j+7] << 16);
946 length |= (uint32_t)(ptfunxored[j+6] << 8);
948 length |= (uint32_t)(ptfunxored[j+5]);
954 switch (startbytes) {
956 start |= (uint32_t)(ptfunxored[j+8] << 24);
958 start |= (uint32_t)(ptfunxored[j+7] << 16);
960 start |= (uint32_t)(ptfunxored[j+6] << 8);
962 start |= (uint32_t)(ptfunxored[j+5]);
968 uint32_t something = 0;
969 switch (somethingbytes) {
971 something |= (uint32_t)(ptfunxored[j+8] << 24);
973 something |= (uint32_t)(ptfunxored[j+7] << 16);
975 something |= (uint32_t)(ptfunxored[j+6] << 8);
977 something |= (uint32_t)(ptfunxored[j+5]);
983 std::string filename = string(name) + extension;
987 (int64_t)(start*ratefactor),
988 (int64_t)(length*ratefactor),
992 //printf("something=%d\n", something);
994 vector<wav_t>::iterator begin = actualwavs.begin();
995 vector<wav_t>::iterator finish = actualwavs.end();
996 vector<wav_t>::iterator found;
997 // Add file to list only if it is an actual wav
998 if ((found = std::find(begin, finish, f)) != finish) {
999 audiofiles.push_back(f);
1000 // Also add plain wav as region
1001 std::vector<midi_ev_t> m;
1005 (int64_t)(start*ratefactor),
1006 (int64_t)(sampleoffset*ratefactor),
1007 (int64_t)(length*ratefactor),
1011 regions.push_back(r);
1014 if (foundin(filename, string(".grp"))) {
1017 std::vector<midi_ev_t> m;
1021 (int64_t)(start*ratefactor),
1022 (int64_t)(sampleoffset*ratefactor),
1023 (int64_t)(length*ratefactor),
1027 regions.push_back(r);
1034 if ( (ptfunxored[k ] == 0x5a) &&
1035 (ptfunxored[k+1] == 0x03)) {
1041 if ( (ptfunxored[k ] == 0x5a) &&
1042 (ptfunxored[k+1] == 0x02)) {
1051 uint32_t tracknumber = 0;
1052 uint32_t regionspertrack = 0;
1053 for (;k < len; k++) {
1054 if ( (ptfunxored[k ] == 0x5a) &&
1055 (ptfunxored[k+1] == 0x04)) {
1058 if ( (ptfunxored[k ] == 0x5a) &&
1059 (ptfunxored[k+1] == 0x02)) {
1061 uint8_t lengthofname = 0;
1062 lengthofname = ptfunxored[k+9];
1063 if (lengthofname == 0x5a) {
1068 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1070 //printf("regions/track=%d\n", regionspertrack);
1071 char name[256] = {0};
1072 for (j = 0; j < lengthofname; j++) {
1073 name[j] = ptfunxored[j+k+13];
1076 tr.name = string(name);
1077 tr.index = tracknumber++;
1079 for (j = k; regionspertrack > 0 && j < len; j++) {
1080 for (l = j; l < len; l++) {
1081 if ( (ptfunxored[l ] == 0x5a) &&
1082 (ptfunxored[l+1] == 0x07)) {
1089 if (regionspertrack == 0) {
1090 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1094 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1095 vector<region_t>::iterator begin = regions.begin();
1096 vector<region_t>::iterator finish = regions.end();
1097 vector<region_t>::iterator found;
1098 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1103 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1104 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1105 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1106 offset |= (uint32_t)(ptfunxored[i]);
1107 tr.reg.startpos = (int64_t)(offset*ratefactor);
1108 if (tr.reg.length > 0) {
1109 tracks.push_back(tr);
1119 PTFFormat::parserest10(void) {
1122 uint8_t startbytes = 0;
1123 uint8_t lengthbytes = 0;
1124 uint8_t offsetbytes = 0;
1125 uint8_t somethingbytes = 0;
1126 uint8_t skipbytes = 0;
1130 if ( (ptfunxored[k ] == 'S') &&
1131 (ptfunxored[k+1] == 'n') &&
1132 (ptfunxored[k+2] == 'a') &&
1133 (ptfunxored[k+3] == 'p')) {
1138 for (i = k; i < len-70; i++) {
1139 if ( (ptfunxored[i ] == 0x5a) &&
1140 (ptfunxored[i+1] == 0x02)) {
1146 for (i = k; i < len-70; i++) {
1147 if ( (ptfunxored[i ] == 0x5a) &&
1148 (ptfunxored[i+1] == 0x02)) {
1154 uint16_t rindex = 0;
1155 uint32_t findex = 0;
1156 for (i = k; i < len-70; i++) {
1157 if ( (ptfunxored[i ] == 0x5a) &&
1158 (ptfunxored[i+1] == 0x08)) {
1161 if ( (ptfunxored[i ] == 0x5a) &&
1162 (ptfunxored[i+1] == 0x01)) {
1164 uint8_t lengthofname = ptfunxored[i+9];
1165 if (ptfunxored[i+13] == 0x5a) {
1168 char name[256] = {0};
1169 for (j = 0; j < lengthofname; j++) {
1170 name[j] = ptfunxored[i+13+j];
1174 //uint8_t disabled = ptfunxored[j];
1175 //printf("%s\n", name);
1177 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1178 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1179 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1180 somethingbytes = (ptfunxored[j+3] & 0xf);
1181 skipbytes = ptfunxored[j+4];
1182 findex = ptfunxored[j+5
1189 /*rindex = ptfunxored[j+5
1197 uint32_t sampleoffset = 0;
1198 switch (offsetbytes) {
1200 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1202 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1204 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1206 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1211 uint32_t length = 0;
1212 switch (lengthbytes) {
1214 length |= (uint32_t)(ptfunxored[j+8] << 24);
1216 length |= (uint32_t)(ptfunxored[j+7] << 16);
1218 length |= (uint32_t)(ptfunxored[j+6] << 8);
1220 length |= (uint32_t)(ptfunxored[j+5]);
1226 switch (startbytes) {
1228 start |= (uint32_t)(ptfunxored[j+8] << 24);
1230 start |= (uint32_t)(ptfunxored[j+7] << 16);
1232 start |= (uint32_t)(ptfunxored[j+6] << 8);
1234 start |= (uint32_t)(ptfunxored[j+5]);
1240 uint32_t something = 0;
1241 switch (somethingbytes) {
1243 something |= (uint32_t)(ptfunxored[j+8] << 24);
1245 something |= (uint32_t)(ptfunxored[j+7] << 16);
1247 something |= (uint32_t)(ptfunxored[j+6] << 8);
1249 something |= (uint32_t)(ptfunxored[j+5]);
1255 std::string filename = string(name) + extension;
1259 (int64_t)(start*ratefactor),
1260 (int64_t)(length*ratefactor),
1263 if (strlen(name) == 0) {
1270 //printf("something=%d\n", something);
1272 vector<wav_t>::iterator begin = actualwavs.begin();
1273 vector<wav_t>::iterator finish = actualwavs.end();
1274 vector<wav_t>::iterator found;
1275 // Add file to list only if it is an actual wav
1276 if ((found = std::find(begin, finish, f)) != finish) {
1277 audiofiles.push_back(f);
1278 // Also add plain wav as region
1279 std::vector<midi_ev_t> m;
1283 (int64_t)(start*ratefactor),
1284 (int64_t)(sampleoffset*ratefactor),
1285 (int64_t)(length*ratefactor),
1289 regions.push_back(r);
1292 if (foundin(filename, string(".grp"))) {
1295 std::vector<midi_ev_t> m;
1299 (int64_t)(start*ratefactor),
1300 (int64_t)(sampleoffset*ratefactor),
1301 (int64_t)(length*ratefactor),
1305 regions.push_back(r);
1308 //printf("%s\n", name);
1313 uint32_t tracknumber = 0;
1314 uint32_t regionspertrack = 0;
1315 for (;k < len; k++) {
1316 if ( (ptfunxored[k ] == 0x5a) &&
1317 (ptfunxored[k+1] == 0x08)) {
1322 for (;k < len; k++) {
1323 if ( (ptfunxored[k ] == 0x5a) &&
1324 (ptfunxored[k+1] == 0x04)) {
1327 if ( (ptfunxored[k ] == 0x5a) &&
1328 (ptfunxored[k+1] == 0x02)) {
1330 uint8_t lengthofname = 0;
1331 lengthofname = ptfunxored[k+9];
1332 if (lengthofname == 0x5a) {
1337 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1339 //printf("regions/track=%d\n", regionspertrack);
1340 char name[256] = {0};
1341 for (j = 0; j < lengthofname; j++) {
1342 name[j] = ptfunxored[j+k+13];
1345 tr.name = string(name);
1346 tr.index = tracknumber++;
1348 for (j = k; regionspertrack > 0 && j < len; j++) {
1349 for (l = j; l < len; l++) {
1350 if ( (ptfunxored[l ] == 0x5a) &&
1351 (ptfunxored[l+1] == 0x08)) {
1358 if (regionspertrack == 0) {
1359 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1363 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1364 vector<region_t>::iterator begin = regions.begin();
1365 vector<region_t>::iterator finish = regions.end();
1366 vector<region_t>::iterator found;
1367 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1372 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1373 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1374 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1375 offset |= (uint32_t)(ptfunxored[i]);
1376 tr.reg.startpos = (int64_t)(offset*ratefactor);
1377 if (tr.reg.length > 0) {
1378 tracks.push_back(tr);