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::foundat(unsigned char *haystack, uint64_t n, const char *needle) {
63 uint64_t i, j, needle_n;
64 needle_n = strlen(needle);
66 for (i = 0; i < n; i++) {
68 for (j = 0; j < needle_n; j++) {
69 if (haystack[i+j] != needle[j]) {
81 PTFFormat::foundin(std::string haystack, std::string needle) {
82 size_t found = haystack.find(needle);
83 if (found != std::string::npos) {
90 /* Return values: 0 success
91 0x01 to 0xff value of missing lut
92 -1 could not open file as ptf
95 PTFFormat::load(std::string path, int64_t targetsr) {
97 unsigned char xxor[256];
106 if (! (fp = g_fopen(path.c_str(), "rb"))) {
110 fseek(fp, 0, SEEK_END);
117 if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
118 /* Silently fail -- out of memory*/
124 /* The first 20 bytes are always unencrypted */
125 fseek(fp, 0x00, SEEK_SET);
126 i = fread(ptfunxored, 1, 0x14, fp);
132 xor_type = ptfunxored[0x12];
133 xor_value = ptfunxored[0x13];
136 // xor_type 0x01 = ProTools 5, 6, 7, 8 and 9
137 // xor_type 0x05 = ProTools 10, 11, 12
140 xor_delta = gen_xor_delta(xor_value, 53, false);
143 xor_delta = gen_xor_delta(xor_value, 11, true);
150 /* Generate the xor_key */
151 for (i=0; i < xor_len; i++)
152 xxor[i] = (i * xor_delta) & 0xff;
154 /* hexdump(xxor, xor_len); */
156 /* Read file and decrypt rest of file */
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];
165 if (!parse_version())
168 if (version < 5 || version > 12)
171 targetrate = targetsr;
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;
185 bool success = false;
187 while( ((uintptr_t)data < data_end) && (success == false) ) {
189 if (data[0] != 0x5a) {
195 /* Skip segment header */
197 if (data[0] == 0 && data[1] == 0) {
199 seg_len = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
202 seg_len = data[3] << 24 | data[2] << 16 | data[1] << 8 | data[0];
206 if (!(seg_type == 0x04 || seg_type == 0x03) || data[0] != 0x03) {
207 /* Go to next segment */
211 /* Skip 0x03 0x00 0x00 */
214 str_len = (*(uint8_t *)data);
215 if (! (product = (uint8_t *)malloc((str_len+1) * sizeof(uint8_t)))) {
224 memcpy(product, data, str_len);
225 product[str_len] = 0;
229 /* Skip 0x03 0x00 0x00 0x00 */
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];
250 PTFFormat::gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative) {
252 for (i = 0; i < 256; i++) {
253 if (((i * mul) & 0xff) == xor_value) {
254 return (negative) ? i * (-1) : i;
262 PTFFormat::parse(void) {
266 if (sessionrate < 44100 || sessionrate > 192000)
271 } else if (version == 7) {
274 if (sessionrate < 44100 || sessionrate > 192000)
279 } else if (version == 8) {
282 if (sessionrate < 44100 || sessionrate > 192000)
287 } else if (version == 9) {
290 if (sessionrate < 44100 || sessionrate > 192000)
295 } else if (version == 10 || version == 11 || version == 12) {
298 if (sessionrate < 44100 || sessionrate > 192000)
311 PTFFormat::setrates(void) {
313 if (sessionrate != 0) {
314 ratefactor = (float)targetrate / sessionrate;
319 PTFFormat::parse5header(void) {
322 // Find session sample rate
325 if ( (ptfunxored[k ] == 0x5a) &&
326 (ptfunxored[k+1] == 0x00) &&
327 (ptfunxored[k+2] == 0x02)) {
334 sessionrate |= ptfunxored[k+12] << 16;
335 sessionrate |= ptfunxored[k+13] << 8;
336 sessionrate |= ptfunxored[k+14];
340 PTFFormat::parse7header(void) {
343 // Find session sample rate
346 if ( (ptfunxored[k ] == 0x5a) &&
347 (ptfunxored[k+1] == 0x00) &&
348 (ptfunxored[k+2] == 0x05)) {
355 sessionrate |= ptfunxored[k+12] << 16;
356 sessionrate |= ptfunxored[k+13] << 8;
357 sessionrate |= ptfunxored[k+14];
361 PTFFormat::parse8header(void) {
364 // Find session sample rate
367 if ( (ptfunxored[k ] == 0x5a) &&
368 (ptfunxored[k+1] == 0x05)) {
375 sessionrate |= ptfunxored[k+11];
376 sessionrate |= ptfunxored[k+12] << 8;
377 sessionrate |= ptfunxored[k+13] << 16;
381 PTFFormat::parse9header(void) {
384 // Find session sample rate
387 if ( (ptfunxored[k ] == 0x5a) &&
388 (ptfunxored[k+1] == 0x06)) {
395 sessionrate |= ptfunxored[k+11];
396 sessionrate |= ptfunxored[k+12] << 8;
397 sessionrate |= ptfunxored[k+13] << 16;
401 PTFFormat::parse10header(void) {
404 // Find session sample rate
407 if ( (ptfunxored[k ] == 0x5a) &&
408 (ptfunxored[k+1] == 0x09)) {
415 sessionrate |= ptfunxored[k+11];
416 sessionrate |= ptfunxored[k+12] << 8;
417 sessionrate |= ptfunxored[k+13] << 16;
421 PTFFormat::parserest5(void) {
423 uint64_t regionspertrack, lengthofname;
424 uint64_t startbytes, lengthbytes, offsetbytes;
425 uint16_t tracknumber = 0;
430 for (i = 0; i < 5; i++) {
432 if ( (ptfunxored[k ] == 0x5a) &&
433 (ptfunxored[k+1] == 0x00) &&
434 (ptfunxored[k+2] == 0x03)) {
443 for (i = 0; i < 2; i++) {
445 if ( (ptfunxored[k ] == 0x5a) &&
446 (ptfunxored[k+1] == 0x00) &&
447 (ptfunxored[k+2] == 0x01)) {
459 if ( (ptfunxored[k ] == 0xff) &&
460 (ptfunxored[k+1] == 0xff)) {
464 if ( (ptfunxored[k ] == 0x5a) &&
465 (ptfunxored[k+1] == 0x00) &&
466 (ptfunxored[k+2] == 0x01)) {
472 lengthofname = ptfunxored[k+12];
473 if (ptfunxored[k+13] == 0x5a) {
477 char name[256] = {0};
478 for (j = 0; j < lengthofname; j++) {
479 name[j] = ptfunxored[k+13+j];
482 regionspertrack = ptfunxored[k+13+j+3];
483 for (i = 0; i < regionspertrack; i++) {
485 if ( (ptfunxored[k ] == 0x5a) &&
486 (ptfunxored[k+1] == 0x00) &&
487 (ptfunxored[k+2] == 0x03)) {
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];
500 switch (startbytes) {
502 start |= (uint32_t)(ptfunxored[j+8] << 24);
504 start |= (uint32_t)(ptfunxored[j+7] << 16);
506 start |= (uint32_t)(ptfunxored[j+6] << 8);
508 start |= (uint32_t)(ptfunxored[j+5]);
514 switch (lengthbytes) {
516 length |= (uint32_t)(ptfunxored[j+8] << 24);
518 length |= (uint32_t)(ptfunxored[j+7] << 16);
520 length |= (uint32_t)(ptfunxored[j+6] << 8);
522 length |= (uint32_t)(ptfunxored[j+5]);
527 uint32_t sampleoffset = 0;
528 switch (offsetbytes) {
530 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
532 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
534 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
536 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
542 //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
544 std::string filename = string(name) + extension;
548 (int64_t)(start*ratefactor),
549 (int64_t)(length*ratefactor),
552 vector<wav_t>::iterator begin = audiofiles.begin();
553 vector<wav_t>::iterator finish = audiofiles.end();
554 vector<wav_t>::iterator found;
556 if ((found = std::find(begin, finish, f)) != finish) {
557 std::vector<midi_ev_t> m;
561 (int64_t)(start*ratefactor),
562 (int64_t)(sampleoffset*ratefactor),
563 (int64_t)(length*ratefactor),
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;
575 tracknumber = tracks.size() + 1;
579 (uint16_t)tracknumber,
585 std::vector<midi_ev_t> m;
589 (int64_t)(start*ratefactor),
590 (int64_t)(sampleoffset*ratefactor),
591 (int64_t)(length*ratefactor),
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;
603 tracknumber = tracks.size() + 1;
607 (uint16_t)tracknumber,
621 PTFFormat::resort(std::vector<wav_t>& ws) {
623 std::sort(ws.begin(), ws.end());
624 for (std::vector<wav_t>::iterator i = ws.begin(); i != ws.end(); ++i) {
631 PTFFormat::parseaudio5(void) {
633 uint64_t lengthofname, wavnumber;
635 // Find end of wav file list
638 if ( (ptfunxored[k ] == 0x5f) &&
639 (ptfunxored[k+1] == 0x50) &&
640 (ptfunxored[k+2] == 0x35)) {
647 if ( (ptfunxored[k ] == 0x5f) &&
648 (ptfunxored[k+1] == 0x50) &&
649 (ptfunxored[k+2] == 0x35)) {
655 // Find actual wav names
656 uint16_t numberofwavs = ptfunxored[k-23];
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')) {
671 while (i < len && numberofwavs > 0) {
673 if ( (ptfunxored[i ] == 0x5a) &&
674 (ptfunxored[i+1] == 0x00) &&
675 (ptfunxored[i+2] == 0x05)) {
678 lengthofname = ptfunxored[i];
681 while (l < lengthofname) {
682 wavname[l] = ptfunxored[i+l];
686 ext[0] = ptfunxored[i++];
687 ext[1] = ptfunxored[i++];
688 ext[2] = ptfunxored[i++];
689 ext[3] = ptfunxored[i++];
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");
700 extension = string("");
703 std::string wave = string(wavname);
704 wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
706 if (foundin(wave, string(".grp"))) {
710 actualwavs.push_back(f);
711 audiofiles.push_back(f);
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;
728 int max_regions = regions.size();
729 char midiname[26] = { 0 };
734 // Parse all midi tracks, treat each group of midi bytes as a track
735 while (k + 35 < len) {
737 std::vector<midi_ev_t> midi;
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')) {
756 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
757 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
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];
780 if (midi_pos + midi_len > max_pos) {
781 max_pos = midi_pos + midi_len;
787 m.velocity = midi_velocity;
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)) {
798 //fprintf(stderr, "MIDI: Note=%d Vel=%d Start=%d(samples) Len=%d(samples)\n", midi_note, midi_velocity, midi_pos, midi_len);
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 };
809 (int64_t)(max_pos*sessionrate*60/(960000*120)),
813 regions.push_back(r);
818 PTFFormat::parseaudio(void) {
820 int64_t index = foundat(ptfunxored, len, "Audio Files");
825 // Find end of wav file list
828 if ( (ptfunxored[k ] == 0xff) &&
829 (ptfunxored[k+1] == 0xff) &&
830 (ptfunxored[k+2] == 0xff) &&
831 (ptfunxored[k+3] == 0xff)) {
837 // Find actual wav names
839 uint16_t numberofwavs;
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')) {
848 while (ptfunxored[j] != '\0') {
849 wavname[l] = ptfunxored[j];
854 if (ptfunxored[i] == 'A') {
855 extension = string(".aif");
857 extension = string(".wav");
859 //uint8_t playlist = ptfunxored[j-8];
863 for (j = k; j > 4; j--) {
864 if ( (ptfunxored[j ] == 0x01) &&
865 (ptfunxored[j-1] == 0x5a)) {
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);
879 std::string wave = string(wavname);
880 std::reverse(wave.begin(), wave.end());
881 wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
883 if (foundin(wave, string(".grp"))) {
887 actualwavs.push_back(f);
890 if (numberofwavs <= 0)
897 PTFFormat::parserest89(void) {
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;
908 if ( (ptfunxored[k ] == 'S') &&
909 (ptfunxored[k+1] == 'n') &&
910 (ptfunxored[k+2] == 'a') &&
911 (ptfunxored[k+3] == 'p')) {
918 for (i = k; i < len-70; i++) {
919 if ( (ptfunxored[i ] == 0x5a) &&
920 (ptfunxored[i+1] == 0x0a)) {
923 if ( (ptfunxored[i ] == 0x5a) &&
924 (ptfunxored[i+1] == 0x0c)) {
926 uint8_t lengthofname = ptfunxored[i+9];
928 char name[256] = {0};
929 for (j = 0; j < lengthofname; j++) {
930 name[j] = ptfunxored[i+13+j];
934 //uint8_t disabled = ptfunxored[j];
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
948 /*rindex = ptfunxored[j+5
956 uint32_t sampleoffset = 0;
957 switch (offsetbytes) {
959 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
961 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
963 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
965 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
971 switch (lengthbytes) {
973 length |= (uint32_t)(ptfunxored[j+8] << 24);
975 length |= (uint32_t)(ptfunxored[j+7] << 16);
977 length |= (uint32_t)(ptfunxored[j+6] << 8);
979 length |= (uint32_t)(ptfunxored[j+5]);
985 switch (startbytes) {
987 start |= (uint32_t)(ptfunxored[j+8] << 24);
989 start |= (uint32_t)(ptfunxored[j+7] << 16);
991 start |= (uint32_t)(ptfunxored[j+6] << 8);
993 start |= (uint32_t)(ptfunxored[j+5]);
999 uint32_t something = 0;
1000 switch (somethingbytes) {
1002 something |= (uint32_t)(ptfunxored[j+8] << 24);
1004 something |= (uint32_t)(ptfunxored[j+7] << 16);
1006 something |= (uint32_t)(ptfunxored[j+6] << 8);
1008 something |= (uint32_t)(ptfunxored[j+5]);
1014 std::string filename = string(name) + extension;
1018 (int64_t)(start*ratefactor),
1019 (int64_t)(length*ratefactor),
1023 //printf("something=%d\n", something);
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;
1036 (int64_t)(start*ratefactor),
1037 (int64_t)(sampleoffset*ratefactor),
1038 (int64_t)(length*ratefactor),
1042 regions.push_back(r);
1045 if (foundin(filename, string(".grp"))) {
1048 std::vector<midi_ev_t> m;
1052 (int64_t)(start*ratefactor),
1053 (int64_t)(sampleoffset*ratefactor),
1054 (int64_t)(length*ratefactor),
1058 regions.push_back(r);
1065 if ( (ptfunxored[k ] == 0x5a) &&
1066 (ptfunxored[k+1] == 0x03)) {
1072 if ( (ptfunxored[k ] == 0x5a) &&
1073 (ptfunxored[k+1] == 0x02)) {
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)) {
1089 if ( (ptfunxored[k ] == 0x5a) &&
1090 (ptfunxored[k+1] == 0x02)) {
1092 uint8_t lengthofname = 0;
1093 lengthofname = ptfunxored[k+9];
1094 if (lengthofname == 0x5a) {
1099 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
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];
1107 tr.name = string(name);
1108 tr.index = tracknumber++;
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)) {
1120 if (regionspertrack == 0) {
1121 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
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) {
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);
1150 PTFFormat::parserest10(void) {
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;
1161 if ( (ptfunxored[k ] == 'S') &&
1162 (ptfunxored[k+1] == 'n') &&
1163 (ptfunxored[k+2] == 'a') &&
1164 (ptfunxored[k+3] == 'p')) {
1169 for (i = k; i < len-70; i++) {
1170 if ( (ptfunxored[i ] == 0x5a) &&
1171 (ptfunxored[i+1] == 0x02)) {
1177 for (i = k; i < len-70; i++) {
1178 if ( (ptfunxored[i ] == 0x5a) &&
1179 (ptfunxored[i+1] == 0x02)) {
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)) {
1192 if ( (ptfunxored[i ] == 0x5a) &&
1193 (ptfunxored[i+1] == 0x01)) {
1195 uint8_t lengthofname = ptfunxored[i+9];
1196 if (ptfunxored[i+13] == 0x5a) {
1199 char name[256] = {0};
1200 for (j = 0; j < lengthofname; j++) {
1201 name[j] = ptfunxored[i+13+j];
1205 //uint8_t disabled = ptfunxored[j];
1206 //printf("%s\n", name);
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
1220 /*rindex = ptfunxored[j+5
1228 uint32_t sampleoffset = 0;
1229 switch (offsetbytes) {
1231 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1233 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1235 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1237 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1242 uint32_t length = 0;
1243 switch (lengthbytes) {
1245 length |= (uint32_t)(ptfunxored[j+8] << 24);
1247 length |= (uint32_t)(ptfunxored[j+7] << 16);
1249 length |= (uint32_t)(ptfunxored[j+6] << 8);
1251 length |= (uint32_t)(ptfunxored[j+5]);
1257 switch (startbytes) {
1259 start |= (uint32_t)(ptfunxored[j+8] << 24);
1261 start |= (uint32_t)(ptfunxored[j+7] << 16);
1263 start |= (uint32_t)(ptfunxored[j+6] << 8);
1265 start |= (uint32_t)(ptfunxored[j+5]);
1271 uint32_t something = 0;
1272 switch (somethingbytes) {
1274 something |= (uint32_t)(ptfunxored[j+8] << 24);
1276 something |= (uint32_t)(ptfunxored[j+7] << 16);
1278 something |= (uint32_t)(ptfunxored[j+6] << 8);
1280 something |= (uint32_t)(ptfunxored[j+5]);
1286 std::string filename = string(name) + extension;
1290 (int64_t)(start*ratefactor),
1291 (int64_t)(length*ratefactor),
1294 if (strlen(name) == 0) {
1301 //printf("something=%d\n", something);
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;
1314 (int64_t)(start*ratefactor),
1315 (int64_t)(sampleoffset*ratefactor),
1316 (int64_t)(length*ratefactor),
1320 regions.push_back(r);
1323 if (foundin(filename, string(".grp"))) {
1326 std::vector<midi_ev_t> m;
1330 (int64_t)(start*ratefactor),
1331 (int64_t)(sampleoffset*ratefactor),
1332 (int64_t)(length*ratefactor),
1336 regions.push_back(r);
1339 //printf("%s\n", name);
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)) {
1353 for (;k < len; k++) {
1354 if ( (ptfunxored[k ] == 0x5a) &&
1355 (ptfunxored[k+1] == 0x04)) {
1358 if ( (ptfunxored[k ] == 0x5a) &&
1359 (ptfunxored[k+1] == 0x02)) {
1361 uint8_t lengthofname = 0;
1362 lengthofname = ptfunxored[k+9];
1363 if (lengthofname == 0x5a) {
1368 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
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];
1376 tr.name = string(name);
1377 tr.index = tracknumber++;
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)) {
1389 if (regionspertrack == 0) {
1390 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
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) {
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);