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 mchunk (uint64_t zt, uint64_t ml, std::vector<PTFFormat::midi_ev_t> const& c)
728 std::vector<PTFFormat::midi_ev_t> chunk;
732 PTFFormat::parsemidi(void) {
733 uint64_t tr, i, k, lastk, n_midi_events, zero_ticks;
734 uint64_t midi_pos, midi_len, max_pos, region_pos;
735 uint8_t midi_velocity, midi_note;
737 uint16_t nmiditracks, regionnumber = 0;
738 uint32_t nregions, mr;
740 std::vector<mchunk> midichunks;
748 // Parse all midi chunks, not 1:1 mapping to regions yet
749 while (k + 35 < len) {
752 std::vector<midi_ev_t> midi;
754 while (k < len && !found) {
755 if ( (ptfunxored[k ] == 'M') &&
756 (ptfunxored[k+1] == 'd') &&
757 (ptfunxored[k+2] == 'N') &&
758 (ptfunxored[k+3] == 'L') &&
759 (ptfunxored[k+4] == 'B')) {
773 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
774 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
777 zero_ticks = (uint64_t)ptfunxored[k] |
778 (uint64_t)ptfunxored[k+1] << 8 |
779 (uint64_t)ptfunxored[k+2] << 16 |
780 (uint64_t)ptfunxored[k+3] << 24 |
781 (uint64_t)ptfunxored[k+4] << 32;
782 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
783 midi_pos = (uint64_t)ptfunxored[k] |
784 (uint64_t)ptfunxored[k+1] << 8 |
785 (uint64_t)ptfunxored[k+2] << 16 |
786 (uint64_t)ptfunxored[k+3] << 24 |
787 (uint64_t)ptfunxored[k+4] << 32;
788 midi_pos -= zero_ticks;
789 midi_note = ptfunxored[k+8];
790 midi_len = (uint64_t)ptfunxored[k+9] |
791 (uint64_t)ptfunxored[k+10] << 8 |
792 (uint64_t)ptfunxored[k+11] << 16 |
793 (uint64_t)ptfunxored[k+12] << 24 |
794 (uint64_t)ptfunxored[k+13] << 32;
795 midi_velocity = ptfunxored[k+17];
797 if (midi_pos + midi_len > max_pos) {
798 max_pos = midi_pos + midi_len;
804 m.velocity = midi_velocity;
806 // stop gap measure to prevent crashes in ardour,
807 // remove when decryption is fully solved for .ptx
808 if ((m.velocity & 0x80) || (m.note & 0x80) ||
809 (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
815 midichunks.push_back(mchunk (zero_ticks, max_pos, midi));
820 // Map midi chunks to regions
822 char midiregionname[256];
826 while (k < len && !found) {
827 if ( (ptfunxored[k ] == 'M') &&
828 (ptfunxored[k+1] == 'd') &&
829 (ptfunxored[k+2] == 'T') &&
830 (ptfunxored[k+3] == 'E') &&
831 (ptfunxored[k+4] == 'L')) {
847 nregions |= ptfunxored[k];
848 nregions |= ptfunxored[k+1] << 8;
850 for (mr = 0; mr < nregions; mr++) {
852 while (k < len && !found) {
853 if ( (ptfunxored[k ] == 0x5a) &&
854 (ptfunxored[k+1] == 0x0c)) {
869 namelen = ptfunxored[k];
870 for (i = 0; i < namelen; i++) {
871 midiregionname[i] = ptfunxored[k+4+i];
873 midiregionname[namelen] = '\0';
878 region_pos = (uint64_t)ptfunxored[k] |
879 (uint64_t)ptfunxored[k+1] << 8 |
880 (uint64_t)ptfunxored[k+2] << 16 |
881 (uint64_t)ptfunxored[k+3] << 24 |
882 (uint64_t)ptfunxored[k+4] << 32;
885 while (k < len && !found) {
886 if ( (ptfunxored[k ] == 0xfe) &&
887 (ptfunxored[k+1] == 0xff) &&
888 (ptfunxored[k+2] == 0xff) &&
889 (ptfunxored[k+3] == 0xff)) {
904 ridx = ptfunxored[k];
905 ridx |= ptfunxored[k+1] << 8;
907 struct mchunk mc = *(midichunks.begin()+ridx);
909 wav_t w = { std::string(""), 0, 0, 0 };
914 (int64_t)0xe8d4a51000ull,
916 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
921 midiregions.push_back(r);
926 // Put midi regions on midi tracks
927 while (k < len && !found) {
928 if ( (ptfunxored[k ] == 0x5a) &&
929 (ptfunxored[k+1] == 0x03)) {
942 nmiditracks |= ptfunxored[k];
943 nmiditracks |= ptfunxored[k+1] << 8;
947 for (tr = 0; tr < nmiditracks; tr++) {
948 char miditrackname[256];
951 while (k < len && !found) {
952 if ( (ptfunxored[k ] == 0x5a) &&
953 (ptfunxored[k+1] == 0x03)) {
963 namelen = ptfunxored[k+9];
964 for (i = 0; i < namelen; i++) {
965 miditrackname[i] = ptfunxored[k+13+i];
967 miditrackname[namelen] = '\0';
970 nregions |= ptfunxored[k];
971 nregions |= ptfunxored[k+1] << 8;
973 for (i = 0; (i < nregions) && (k < len); i++) {
977 ridx |= ptfunxored[k];
978 ridx |= ptfunxored[k+1] << 8;
982 region_pos = (uint64_t)ptfunxored[k] |
983 (uint64_t)ptfunxored[k+1] << 8 |
984 (uint64_t)ptfunxored[k+2] << 16 |
985 (uint64_t)ptfunxored[k+3] << 24 |
986 (uint64_t)ptfunxored[k+4] << 32;
991 mtr.name = string(miditrackname);
994 // Find the midi region with index 'ridx'
995 std::vector<region_t>::iterator begin = midiregions.begin();
996 std::vector<region_t>::iterator finish = midiregions.end();
997 std::vector<region_t>::iterator mregion;
998 wav_t w = { std::string(""), 0, 0, 0 };
999 std::vector<midi_ev_t> m;
1000 region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
1001 if ((mregion = std::find(begin, finish, r)) != finish) {
1003 mtr.reg.startpos = std::labs(region_pos - mtr.reg.startpos);
1004 miditracks.push_back(mtr);
1011 PTFFormat::parseaudio(void) {
1013 int64_t index = foundat(ptfunxored, len, "Audio Files");
1018 // Find end of wav file list
1019 k = (uint64_t)index;
1021 if ( (ptfunxored[k ] == 0xff) &&
1022 (ptfunxored[k+1] == 0xff) &&
1023 (ptfunxored[k+2] == 0xff) &&
1024 (ptfunxored[k+3] == 0xff)) {
1030 // Find actual wav names
1032 uint16_t numberofwavs;
1034 for (i = k-2; i > 4; i--) {
1035 if ( ((ptfunxored[i ] == 'W') || (ptfunxored[i ] == 'A') || ptfunxored[i ] == '\0') &&
1036 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I') || ptfunxored[i-1] == '\0') &&
1037 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F') || ptfunxored[i-2] == '\0') &&
1038 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F') || ptfunxored[i-3] == '\0')) {
1041 while (ptfunxored[j] != '\0') {
1042 wavname[l] = ptfunxored[j];
1047 if (ptfunxored[i] == 'A') {
1048 extension = string(".aif");
1050 extension = string(".wav");
1052 //uint8_t playlist = ptfunxored[j-8];
1056 for (j = k; j > 4; j--) {
1057 if ( (ptfunxored[j ] == 0x01) &&
1058 (ptfunxored[j-1] == 0x5a)) {
1061 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
1062 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
1063 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
1064 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
1065 //printf("%d wavs\n", numberofwavs);
1072 std::string wave = string(wavname);
1073 std::reverse(wave.begin(), wave.end());
1074 wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
1076 if (foundin(wave, string(".grp"))) {
1080 actualwavs.push_back(f);
1083 if (numberofwavs <= 0)
1090 PTFFormat::parserest89(void) {
1093 uint8_t startbytes = 0;
1094 uint8_t lengthbytes = 0;
1095 uint8_t offsetbytes = 0;
1096 uint8_t somethingbytes = 0;
1097 uint8_t skipbytes = 0;
1101 if ( (ptfunxored[k ] == 'S') &&
1102 (ptfunxored[k+1] == 'n') &&
1103 (ptfunxored[k+2] == 'a') &&
1104 (ptfunxored[k+3] == 'p')) {
1109 uint16_t rindex = 0;
1110 uint32_t findex = 0;
1111 for (i = k; i < len-70; i++) {
1112 if ( (ptfunxored[i ] == 0x5a) &&
1113 (ptfunxored[i+1] == 0x0a)) {
1116 if ( (ptfunxored[i ] == 0x5a) &&
1117 (ptfunxored[i+1] == 0x0c)) {
1119 uint8_t lengthofname = ptfunxored[i+9];
1121 char name[256] = {0};
1122 for (j = 0; j < lengthofname; j++) {
1123 name[j] = ptfunxored[i+13+j];
1127 //uint8_t disabled = ptfunxored[j];
1129 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1130 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1131 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1132 somethingbytes = (ptfunxored[j+3] & 0xf);
1133 skipbytes = ptfunxored[j+4];
1134 findex = ptfunxored[j+5
1141 /*rindex = ptfunxored[j+5
1149 uint32_t sampleoffset = 0;
1150 switch (offsetbytes) {
1152 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1154 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1156 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1158 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1163 uint32_t length = 0;
1164 switch (lengthbytes) {
1166 length |= (uint32_t)(ptfunxored[j+8] << 24);
1168 length |= (uint32_t)(ptfunxored[j+7] << 16);
1170 length |= (uint32_t)(ptfunxored[j+6] << 8);
1172 length |= (uint32_t)(ptfunxored[j+5]);
1178 switch (startbytes) {
1180 start |= (uint32_t)(ptfunxored[j+8] << 24);
1182 start |= (uint32_t)(ptfunxored[j+7] << 16);
1184 start |= (uint32_t)(ptfunxored[j+6] << 8);
1186 start |= (uint32_t)(ptfunxored[j+5]);
1192 uint32_t something = 0;
1193 switch (somethingbytes) {
1195 something |= (uint32_t)(ptfunxored[j+8] << 24);
1197 something |= (uint32_t)(ptfunxored[j+7] << 16);
1199 something |= (uint32_t)(ptfunxored[j+6] << 8);
1201 something |= (uint32_t)(ptfunxored[j+5]);
1207 std::string filename = string(name) + extension;
1211 (int64_t)(start*ratefactor),
1212 (int64_t)(length*ratefactor),
1216 //printf("something=%d\n", something);
1218 vector<wav_t>::iterator begin = actualwavs.begin();
1219 vector<wav_t>::iterator finish = actualwavs.end();
1220 vector<wav_t>::iterator found;
1221 // Add file to list only if it is an actual wav
1222 if ((found = std::find(begin, finish, f)) != finish) {
1223 audiofiles.push_back(f);
1224 // Also add plain wav as region
1225 std::vector<midi_ev_t> m;
1229 (int64_t)(start*ratefactor),
1230 (int64_t)(sampleoffset*ratefactor),
1231 (int64_t)(length*ratefactor),
1235 regions.push_back(r);
1238 if (foundin(filename, string(".grp"))) {
1241 std::vector<midi_ev_t> m;
1245 (int64_t)(start*ratefactor),
1246 (int64_t)(sampleoffset*ratefactor),
1247 (int64_t)(length*ratefactor),
1251 regions.push_back(r);
1258 if ( (ptfunxored[k ] == 0x5a) &&
1259 (ptfunxored[k+1] == 0x03)) {
1265 if ( (ptfunxored[k ] == 0x5a) &&
1266 (ptfunxored[k+1] == 0x02)) {
1275 uint32_t tracknumber = 0;
1276 uint32_t regionspertrack = 0;
1277 for (;k < len; k++) {
1278 if ( (ptfunxored[k ] == 0x5a) &&
1279 (ptfunxored[k+1] == 0x04)) {
1282 if ( (ptfunxored[k ] == 0x5a) &&
1283 (ptfunxored[k+1] == 0x02)) {
1285 uint8_t lengthofname = 0;
1286 lengthofname = ptfunxored[k+9];
1287 if (lengthofname == 0x5a) {
1292 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1294 //printf("regions/track=%d\n", regionspertrack);
1295 char name[256] = {0};
1296 for (j = 0; j < lengthofname; j++) {
1297 name[j] = ptfunxored[j+k+13];
1300 tr.name = string(name);
1301 tr.index = tracknumber++;
1303 for (j = k; regionspertrack > 0 && j < len; j++) {
1304 for (l = j; l < len; l++) {
1305 if ( (ptfunxored[l ] == 0x5a) &&
1306 (ptfunxored[l+1] == 0x07)) {
1313 if (regionspertrack == 0) {
1314 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1318 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1319 vector<region_t>::iterator begin = regions.begin();
1320 vector<region_t>::iterator finish = regions.end();
1321 vector<region_t>::iterator found;
1322 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1327 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1328 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1329 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1330 offset |= (uint32_t)(ptfunxored[i]);
1331 tr.reg.startpos = (int64_t)(offset*ratefactor);
1332 if (tr.reg.length > 0) {
1333 tracks.push_back(tr);
1343 PTFFormat::parserest10(void) {
1346 uint8_t startbytes = 0;
1347 uint8_t lengthbytes = 0;
1348 uint8_t offsetbytes = 0;
1349 uint8_t somethingbytes = 0;
1350 uint8_t skipbytes = 0;
1354 if ( (ptfunxored[k ] == 'S') &&
1355 (ptfunxored[k+1] == 'n') &&
1356 (ptfunxored[k+2] == 'a') &&
1357 (ptfunxored[k+3] == 'p')) {
1362 for (i = k; i < len-70; i++) {
1363 if ( (ptfunxored[i ] == 0x5a) &&
1364 (ptfunxored[i+1] == 0x02)) {
1370 for (i = k; i < len-70; i++) {
1371 if ( (ptfunxored[i ] == 0x5a) &&
1372 (ptfunxored[i+1] == 0x02)) {
1378 uint16_t rindex = 0;
1379 uint32_t findex = 0;
1380 for (i = k; i < len-70; i++) {
1381 if ( (ptfunxored[i ] == 0x5a) &&
1382 (ptfunxored[i+1] == 0x08)) {
1385 if ( (ptfunxored[i ] == 0x5a) &&
1386 (ptfunxored[i+1] == 0x01)) {
1388 uint8_t lengthofname = ptfunxored[i+9];
1389 if (ptfunxored[i+13] == 0x5a) {
1392 char name[256] = {0};
1393 for (j = 0; j < lengthofname; j++) {
1394 name[j] = ptfunxored[i+13+j];
1398 //uint8_t disabled = ptfunxored[j];
1399 //printf("%s\n", name);
1401 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1402 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1403 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1404 somethingbytes = (ptfunxored[j+3] & 0xf);
1405 skipbytes = ptfunxored[j+4];
1406 findex = ptfunxored[j+5
1413 /*rindex = ptfunxored[j+5
1421 uint32_t sampleoffset = 0;
1422 switch (offsetbytes) {
1424 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1426 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1428 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1430 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1435 uint32_t length = 0;
1436 switch (lengthbytes) {
1438 length |= (uint32_t)(ptfunxored[j+8] << 24);
1440 length |= (uint32_t)(ptfunxored[j+7] << 16);
1442 length |= (uint32_t)(ptfunxored[j+6] << 8);
1444 length |= (uint32_t)(ptfunxored[j+5]);
1450 switch (startbytes) {
1452 start |= (uint32_t)(ptfunxored[j+8] << 24);
1454 start |= (uint32_t)(ptfunxored[j+7] << 16);
1456 start |= (uint32_t)(ptfunxored[j+6] << 8);
1458 start |= (uint32_t)(ptfunxored[j+5]);
1464 uint32_t something = 0;
1465 switch (somethingbytes) {
1467 something |= (uint32_t)(ptfunxored[j+8] << 24);
1469 something |= (uint32_t)(ptfunxored[j+7] << 16);
1471 something |= (uint32_t)(ptfunxored[j+6] << 8);
1473 something |= (uint32_t)(ptfunxored[j+5]);
1479 std::string filename = string(name) + extension;
1483 (int64_t)(start*ratefactor),
1484 (int64_t)(length*ratefactor),
1487 if (strlen(name) == 0) {
1494 //printf("something=%d\n", something);
1496 vector<wav_t>::iterator begin = actualwavs.begin();
1497 vector<wav_t>::iterator finish = actualwavs.end();
1498 vector<wav_t>::iterator found;
1499 // Add file to list only if it is an actual wav
1500 if ((found = std::find(begin, finish, f)) != finish) {
1501 audiofiles.push_back(f);
1502 // Also add plain wav as region
1503 std::vector<midi_ev_t> m;
1507 (int64_t)(start*ratefactor),
1508 (int64_t)(sampleoffset*ratefactor),
1509 (int64_t)(length*ratefactor),
1513 regions.push_back(r);
1516 if (foundin(filename, string(".grp"))) {
1519 std::vector<midi_ev_t> m;
1523 (int64_t)(start*ratefactor),
1524 (int64_t)(sampleoffset*ratefactor),
1525 (int64_t)(length*ratefactor),
1529 regions.push_back(r);
1532 //printf("%s\n", name);
1537 uint32_t tracknumber = 0;
1538 uint32_t regionspertrack = 0;
1539 for (;k < len; k++) {
1540 if ( (ptfunxored[k ] == 0x5a) &&
1541 (ptfunxored[k+1] == 0x08)) {
1546 for (;k < len; k++) {
1547 if ( (ptfunxored[k ] == 0x5a) &&
1548 (ptfunxored[k+1] == 0x04)) {
1551 if ( (ptfunxored[k ] == 0x5a) &&
1552 (ptfunxored[k+1] == 0x02)) {
1554 uint8_t lengthofname = 0;
1555 lengthofname = ptfunxored[k+9];
1556 if (lengthofname == 0x5a) {
1561 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1563 //printf("regions/track=%d\n", regionspertrack);
1564 char name[256] = {0};
1565 for (j = 0; j < lengthofname; j++) {
1566 name[j] = ptfunxored[j+k+13];
1569 tr.name = string(name);
1570 tr.index = tracknumber++;
1572 for (j = k; regionspertrack > 0 && j < len; j++) {
1573 for (l = j; l < len; l++) {
1574 if ( (ptfunxored[l ] == 0x5a) &&
1575 (ptfunxored[l+1] == 0x08)) {
1582 if (regionspertrack == 0) {
1583 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1587 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1588 vector<region_t>::iterator begin = regions.begin();
1589 vector<region_t>::iterator finish = regions.end();
1590 vector<region_t>::iterator found;
1591 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1596 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1597 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1598 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1599 offset |= (uint32_t)(ptfunxored[i]);
1600 tr.reg.startpos = (int64_t)(offset*ratefactor);
1601 if (tr.reg.length > 0) {
1602 tracks.push_back(tr);