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;
770 // stop gap measure to prevent crashes in ardour,
771 // remove when decryption is fully solved for .ptx
772 if ((m.velocity & 0x80) || (m.note & 0x80) ||
773 (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
779 //fprintf(stderr, "MIDI: Note=%d Vel=%d Start=%d(samples) Len=%d(samples)\n", midi_note, midi_velocity, midi_pos, midi_len);
782 rsize = (uint16_t)regions.size();
783 snprintf(midiname, 20, "MIDI-%d", rsize - max_regions + 1);
784 wav_t w = { std::string(""), 0, 0, 0 };
790 (int64_t)(max_pos*sessionrate*60/(960000*120)),
794 regions.push_back(r);
799 PTFFormat::parseaudio(void) {
802 // Find end of wav file list
805 if ( (ptfunxored[k ] == 0xff) &&
806 (ptfunxored[k+1] == 0xff) &&
807 (ptfunxored[k+2] == 0xff) &&
808 (ptfunxored[k+3] == 0xff)) {
814 // Find actual wav names
816 uint16_t numberofwavs;
818 for (i = k; i > 4; i--) {
819 if ( ((ptfunxored[i ] == 'W') || (ptfunxored[i ] == 'A')) &&
820 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I')) &&
821 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F')) &&
822 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F'))) {
825 while (ptfunxored[j] != '\0') {
826 wavname[l] = ptfunxored[j];
831 if (ptfunxored[i] == 'W') {
832 extension = string(".wav");
834 extension = string(".aif");
836 //uint8_t playlist = ptfunxored[j-8];
840 for (j = k; j > 4; j--) {
841 if ( (ptfunxored[j ] == 0x01) &&
842 (ptfunxored[j-1] == 0x5a)) {
845 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
846 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
847 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
848 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
849 //printf("%d wavs\n", numberofwavs);
856 std::string wave = string(wavname);
857 std::reverse(wave.begin(), wave.end());
858 wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
860 if (foundin(wave, string(".grp"))) {
864 actualwavs.push_back(f);
867 if (numberofwavs <= 0)
874 PTFFormat::parserest89(void) {
877 uint8_t startbytes = 0;
878 uint8_t lengthbytes = 0;
879 uint8_t offsetbytes = 0;
880 uint8_t somethingbytes = 0;
881 uint8_t skipbytes = 0;
885 if ( (ptfunxored[k ] == 'S') &&
886 (ptfunxored[k+1] == 'n') &&
887 (ptfunxored[k+2] == 'a') &&
888 (ptfunxored[k+3] == 'p')) {
895 for (i = k; i < len-70; i++) {
896 if ( (ptfunxored[i ] == 0x5a) &&
897 (ptfunxored[i+1] == 0x0a)) {
900 if ( (ptfunxored[i ] == 0x5a) &&
901 (ptfunxored[i+1] == 0x0c)) {
903 uint8_t lengthofname = ptfunxored[i+9];
905 char name[256] = {0};
906 for (j = 0; j < lengthofname; j++) {
907 name[j] = ptfunxored[i+13+j];
911 //uint8_t disabled = ptfunxored[j];
913 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
914 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
915 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
916 somethingbytes = (ptfunxored[j+3] & 0xf);
917 skipbytes = ptfunxored[j+4];
918 findex = ptfunxored[j+5
925 /*rindex = ptfunxored[j+5
933 uint32_t sampleoffset = 0;
934 switch (offsetbytes) {
936 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
938 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
940 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
942 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
948 switch (lengthbytes) {
950 length |= (uint32_t)(ptfunxored[j+8] << 24);
952 length |= (uint32_t)(ptfunxored[j+7] << 16);
954 length |= (uint32_t)(ptfunxored[j+6] << 8);
956 length |= (uint32_t)(ptfunxored[j+5]);
962 switch (startbytes) {
964 start |= (uint32_t)(ptfunxored[j+8] << 24);
966 start |= (uint32_t)(ptfunxored[j+7] << 16);
968 start |= (uint32_t)(ptfunxored[j+6] << 8);
970 start |= (uint32_t)(ptfunxored[j+5]);
976 uint32_t something = 0;
977 switch (somethingbytes) {
979 something |= (uint32_t)(ptfunxored[j+8] << 24);
981 something |= (uint32_t)(ptfunxored[j+7] << 16);
983 something |= (uint32_t)(ptfunxored[j+6] << 8);
985 something |= (uint32_t)(ptfunxored[j+5]);
991 std::string filename = string(name) + extension;
995 (int64_t)(start*ratefactor),
996 (int64_t)(length*ratefactor),
1000 //printf("something=%d\n", something);
1002 vector<wav_t>::iterator begin = actualwavs.begin();
1003 vector<wav_t>::iterator finish = actualwavs.end();
1004 vector<wav_t>::iterator found;
1005 // Add file to list only if it is an actual wav
1006 if ((found = std::find(begin, finish, f)) != finish) {
1007 audiofiles.push_back(f);
1008 // Also add plain wav as region
1009 std::vector<midi_ev_t> m;
1013 (int64_t)(start*ratefactor),
1014 (int64_t)(sampleoffset*ratefactor),
1015 (int64_t)(length*ratefactor),
1019 regions.push_back(r);
1022 if (foundin(filename, string(".grp"))) {
1025 std::vector<midi_ev_t> m;
1029 (int64_t)(start*ratefactor),
1030 (int64_t)(sampleoffset*ratefactor),
1031 (int64_t)(length*ratefactor),
1035 regions.push_back(r);
1042 if ( (ptfunxored[k ] == 0x5a) &&
1043 (ptfunxored[k+1] == 0x03)) {
1049 if ( (ptfunxored[k ] == 0x5a) &&
1050 (ptfunxored[k+1] == 0x02)) {
1059 uint32_t tracknumber = 0;
1060 uint32_t regionspertrack = 0;
1061 for (;k < len; k++) {
1062 if ( (ptfunxored[k ] == 0x5a) &&
1063 (ptfunxored[k+1] == 0x04)) {
1066 if ( (ptfunxored[k ] == 0x5a) &&
1067 (ptfunxored[k+1] == 0x02)) {
1069 uint8_t lengthofname = 0;
1070 lengthofname = ptfunxored[k+9];
1071 if (lengthofname == 0x5a) {
1076 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1078 //printf("regions/track=%d\n", regionspertrack);
1079 char name[256] = {0};
1080 for (j = 0; j < lengthofname; j++) {
1081 name[j] = ptfunxored[j+k+13];
1084 tr.name = string(name);
1085 tr.index = tracknumber++;
1087 for (j = k; regionspertrack > 0 && j < len; j++) {
1088 for (l = j; l < len; l++) {
1089 if ( (ptfunxored[l ] == 0x5a) &&
1090 (ptfunxored[l+1] == 0x07)) {
1097 if (regionspertrack == 0) {
1098 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1102 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1103 vector<region_t>::iterator begin = regions.begin();
1104 vector<region_t>::iterator finish = regions.end();
1105 vector<region_t>::iterator found;
1106 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1111 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1112 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1113 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1114 offset |= (uint32_t)(ptfunxored[i]);
1115 tr.reg.startpos = (int64_t)(offset*ratefactor);
1116 if (tr.reg.length > 0) {
1117 tracks.push_back(tr);
1127 PTFFormat::parserest10(void) {
1130 uint8_t startbytes = 0;
1131 uint8_t lengthbytes = 0;
1132 uint8_t offsetbytes = 0;
1133 uint8_t somethingbytes = 0;
1134 uint8_t skipbytes = 0;
1138 if ( (ptfunxored[k ] == 'S') &&
1139 (ptfunxored[k+1] == 'n') &&
1140 (ptfunxored[k+2] == 'a') &&
1141 (ptfunxored[k+3] == 'p')) {
1146 for (i = k; i < len-70; i++) {
1147 if ( (ptfunxored[i ] == 0x5a) &&
1148 (ptfunxored[i+1] == 0x02)) {
1154 for (i = k; i < len-70; i++) {
1155 if ( (ptfunxored[i ] == 0x5a) &&
1156 (ptfunxored[i+1] == 0x02)) {
1162 uint16_t rindex = 0;
1163 uint32_t findex = 0;
1164 for (i = k; i < len-70; i++) {
1165 if ( (ptfunxored[i ] == 0x5a) &&
1166 (ptfunxored[i+1] == 0x08)) {
1169 if ( (ptfunxored[i ] == 0x5a) &&
1170 (ptfunxored[i+1] == 0x01)) {
1172 uint8_t lengthofname = ptfunxored[i+9];
1173 if (ptfunxored[i+13] == 0x5a) {
1176 char name[256] = {0};
1177 for (j = 0; j < lengthofname; j++) {
1178 name[j] = ptfunxored[i+13+j];
1182 //uint8_t disabled = ptfunxored[j];
1183 //printf("%s\n", name);
1185 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1186 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1187 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1188 somethingbytes = (ptfunxored[j+3] & 0xf);
1189 skipbytes = ptfunxored[j+4];
1190 findex = ptfunxored[j+5
1197 /*rindex = ptfunxored[j+5
1205 uint32_t sampleoffset = 0;
1206 switch (offsetbytes) {
1208 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1210 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1212 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1214 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1219 uint32_t length = 0;
1220 switch (lengthbytes) {
1222 length |= (uint32_t)(ptfunxored[j+8] << 24);
1224 length |= (uint32_t)(ptfunxored[j+7] << 16);
1226 length |= (uint32_t)(ptfunxored[j+6] << 8);
1228 length |= (uint32_t)(ptfunxored[j+5]);
1234 switch (startbytes) {
1236 start |= (uint32_t)(ptfunxored[j+8] << 24);
1238 start |= (uint32_t)(ptfunxored[j+7] << 16);
1240 start |= (uint32_t)(ptfunxored[j+6] << 8);
1242 start |= (uint32_t)(ptfunxored[j+5]);
1248 uint32_t something = 0;
1249 switch (somethingbytes) {
1251 something |= (uint32_t)(ptfunxored[j+8] << 24);
1253 something |= (uint32_t)(ptfunxored[j+7] << 16);
1255 something |= (uint32_t)(ptfunxored[j+6] << 8);
1257 something |= (uint32_t)(ptfunxored[j+5]);
1263 std::string filename = string(name) + extension;
1267 (int64_t)(start*ratefactor),
1268 (int64_t)(length*ratefactor),
1271 if (strlen(name) == 0) {
1278 //printf("something=%d\n", something);
1280 vector<wav_t>::iterator begin = actualwavs.begin();
1281 vector<wav_t>::iterator finish = actualwavs.end();
1282 vector<wav_t>::iterator found;
1283 // Add file to list only if it is an actual wav
1284 if ((found = std::find(begin, finish, f)) != finish) {
1285 audiofiles.push_back(f);
1286 // Also add plain wav as region
1287 std::vector<midi_ev_t> m;
1291 (int64_t)(start*ratefactor),
1292 (int64_t)(sampleoffset*ratefactor),
1293 (int64_t)(length*ratefactor),
1297 regions.push_back(r);
1300 if (foundin(filename, string(".grp"))) {
1303 std::vector<midi_ev_t> m;
1307 (int64_t)(start*ratefactor),
1308 (int64_t)(sampleoffset*ratefactor),
1309 (int64_t)(length*ratefactor),
1313 regions.push_back(r);
1316 //printf("%s\n", name);
1321 uint32_t tracknumber = 0;
1322 uint32_t regionspertrack = 0;
1323 for (;k < len; k++) {
1324 if ( (ptfunxored[k ] == 0x5a) &&
1325 (ptfunxored[k+1] == 0x08)) {
1330 for (;k < len; k++) {
1331 if ( (ptfunxored[k ] == 0x5a) &&
1332 (ptfunxored[k+1] == 0x04)) {
1335 if ( (ptfunxored[k ] == 0x5a) &&
1336 (ptfunxored[k+1] == 0x02)) {
1338 uint8_t lengthofname = 0;
1339 lengthofname = ptfunxored[k+9];
1340 if (lengthofname == 0x5a) {
1345 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1347 //printf("regions/track=%d\n", regionspertrack);
1348 char name[256] = {0};
1349 for (j = 0; j < lengthofname; j++) {
1350 name[j] = ptfunxored[j+k+13];
1353 tr.name = string(name);
1354 tr.index = tracknumber++;
1356 for (j = k; regionspertrack > 0 && j < len; j++) {
1357 for (l = j; l < len; l++) {
1358 if ( (ptfunxored[l ] == 0x5a) &&
1359 (ptfunxored[l+1] == 0x08)) {
1366 if (regionspertrack == 0) {
1367 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1371 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1372 vector<region_t>::iterator begin = regions.begin();
1373 vector<region_t>::iterator finish = regions.end();
1374 vector<region_t>::iterator found;
1375 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1380 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1381 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1382 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1383 offset |= (uint32_t)(ptfunxored[i]);
1384 tr.reg.startpos = (int64_t)(offset*ratefactor);
1385 if (tr.reg.length > 0) {
1386 tracks.push_back(tr);