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 tr, i, k, lastk, n_midi_events, zero_ticks;
723 uint64_t midi_pos, midi_len, max_pos, region_pos;
724 uint8_t midi_velocity, midi_note;
726 uint16_t nmiditracks, regionnumber = 0;
727 uint32_t nregions, mr;
731 std::vector<midi_ev_t> chunk;
733 std::vector<struct mchunk_t> midichunks;
741 // Parse all midi chunks, not 1:1 mapping to regions yet
742 while (k + 35 < len) {
745 std::vector<midi_ev_t> midi;
747 while (k < len && !found) {
748 if ( (ptfunxored[k ] == 'M') &&
749 (ptfunxored[k+1] == 'd') &&
750 (ptfunxored[k+2] == 'N') &&
751 (ptfunxored[k+3] == 'L') &&
752 (ptfunxored[k+4] == 'B')) {
766 n_midi_events = ptfunxored[k] | ptfunxored[k+1] << 8 |
767 ptfunxored[k+2] << 16 | ptfunxored[k+3] << 24;
770 zero_ticks = (uint64_t)ptfunxored[k] |
771 (uint64_t)ptfunxored[k+1] << 8 |
772 (uint64_t)ptfunxored[k+2] << 16 |
773 (uint64_t)ptfunxored[k+3] << 24 |
774 (uint64_t)ptfunxored[k+4] << 32;
775 for (i = 0; i < n_midi_events && k < len; i++, k += 35) {
776 midi_pos = (uint64_t)ptfunxored[k] |
777 (uint64_t)ptfunxored[k+1] << 8 |
778 (uint64_t)ptfunxored[k+2] << 16 |
779 (uint64_t)ptfunxored[k+3] << 24 |
780 (uint64_t)ptfunxored[k+4] << 32;
781 midi_pos -= zero_ticks;
782 midi_note = ptfunxored[k+8];
783 midi_len = (uint64_t)ptfunxored[k+9] |
784 (uint64_t)ptfunxored[k+10] << 8 |
785 (uint64_t)ptfunxored[k+11] << 16 |
786 (uint64_t)ptfunxored[k+12] << 24 |
787 (uint64_t)ptfunxored[k+13] << 32;
788 midi_velocity = ptfunxored[k+17];
790 if (midi_pos + midi_len > max_pos) {
791 max_pos = midi_pos + midi_len;
797 m.velocity = midi_velocity;
799 // stop gap measure to prevent crashes in ardour,
800 // remove when decryption is fully solved for .ptx
801 if ((m.velocity & 0x80) || (m.note & 0x80) ||
802 (m.pos & 0xff00000000LL) || (m.length & 0xff00000000LL)) {
808 midichunks.push_back({zero_ticks, max_pos, midi});
813 // Map midi chunks to regions
815 char midiregionname[256];
819 while (k < len && !found) {
820 if ( (ptfunxored[k ] == 'M') &&
821 (ptfunxored[k+1] == 'd') &&
822 (ptfunxored[k+2] == 'T') &&
823 (ptfunxored[k+3] == 'E') &&
824 (ptfunxored[k+4] == 'L')) {
840 nregions |= ptfunxored[k];
841 nregions |= ptfunxored[k+1] << 8;
843 for (mr = 0; mr < nregions; mr++) {
845 while (k < len && !found) {
846 if ( (ptfunxored[k ] == 0x5a) &&
847 (ptfunxored[k+1] == 0x0c)) {
862 namelen = ptfunxored[k];
863 for (i = 0; i < namelen; i++) {
864 midiregionname[i] = ptfunxored[k+4+i];
866 midiregionname[namelen] = '\0';
871 region_pos = (uint64_t)ptfunxored[k] |
872 (uint64_t)ptfunxored[k+1] << 8 |
873 (uint64_t)ptfunxored[k+2] << 16 |
874 (uint64_t)ptfunxored[k+3] << 24 |
875 (uint64_t)ptfunxored[k+4] << 32;
878 while (k < len && !found) {
879 if ( (ptfunxored[k ] == 0xfe) &&
880 (ptfunxored[k+1] == 0xff) &&
881 (ptfunxored[k+2] == 0xff) &&
882 (ptfunxored[k+3] == 0xff)) {
897 ridx = ptfunxored[k];
898 ridx |= ptfunxored[k+1] << 8;
900 struct mchunk_t mchunk = *(midichunks.begin()+ridx);
902 wav_t w = { std::string(""), 0, 0, 0 };
906 //(int64_t)mchunk.zero,
907 (int64_t)0xe8d4a51000ull,
909 //(int64_t)(max_pos*sessionrate*60/(960000*120)),
910 (int64_t)mchunk.maxlen,
914 midiregions.push_back(r);
919 // Put midi regions on midi tracks
920 while (k < len && !found) {
921 if ( (ptfunxored[k ] == 0x5a) &&
922 (ptfunxored[k+1] == 0x03)) {
935 nmiditracks |= ptfunxored[k];
936 nmiditracks |= ptfunxored[k+1] << 8;
940 for (tr = 0; tr < nmiditracks; tr++) {
941 char miditrackname[256];
944 while (k < len && !found) {
945 if ( (ptfunxored[k ] == 0x5a) &&
946 (ptfunxored[k+1] == 0x03)) {
956 namelen = ptfunxored[k+9];
957 for (i = 0; i < namelen; i++) {
958 miditrackname[i] = ptfunxored[k+13+i];
960 miditrackname[namelen] = '\0';
963 nregions |= ptfunxored[k];
964 nregions |= ptfunxored[k+1] << 8;
966 for (i = 0; (i < nregions) && (k < len); i++) {
970 ridx |= ptfunxored[k];
971 ridx |= ptfunxored[k+1] << 8;
975 region_pos = (uint64_t)ptfunxored[k] |
976 (uint64_t)ptfunxored[k+1] << 8 |
977 (uint64_t)ptfunxored[k+2] << 16 |
978 (uint64_t)ptfunxored[k+3] << 24 |
979 (uint64_t)ptfunxored[k+4] << 32;
984 mtr.name = string(miditrackname);
987 // Find the midi region with index 'ridx'
988 std::vector<region_t>::iterator begin = midiregions.begin();
989 std::vector<region_t>::iterator finish = midiregions.end();
990 std::vector<region_t>::iterator mregion;
991 wav_t w = { std::string(""), 0, 0, 0 };
992 std::vector<midi_ev_t> m;
993 region_t r = { std::string(""), ridx, 0, 0, 0, w, m};
994 if ((mregion = std::find(begin, finish, r)) != finish) {
996 mtr.reg.startpos = std::labs(region_pos - mtr.reg.startpos);
997 miditracks.push_back(mtr);
1004 PTFFormat::parseaudio(void) {
1006 int64_t index = foundat(ptfunxored, len, "Audio Files");
1011 // Find end of wav file list
1012 k = (uint64_t)index;
1014 if ( (ptfunxored[k ] == 0xff) &&
1015 (ptfunxored[k+1] == 0xff) &&
1016 (ptfunxored[k+2] == 0xff) &&
1017 (ptfunxored[k+3] == 0xff)) {
1023 // Find actual wav names
1025 uint16_t numberofwavs;
1027 for (i = k-2; i > 4; i--) {
1028 if ( ((ptfunxored[i ] == 'W') || (ptfunxored[i ] == 'A') || ptfunxored[i ] == '\0') &&
1029 ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I') || ptfunxored[i-1] == '\0') &&
1030 ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F') || ptfunxored[i-2] == '\0') &&
1031 ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F') || ptfunxored[i-3] == '\0')) {
1034 while (ptfunxored[j] != '\0') {
1035 wavname[l] = ptfunxored[j];
1040 if (ptfunxored[i] == 'A') {
1041 extension = string(".aif");
1043 extension = string(".wav");
1045 //uint8_t playlist = ptfunxored[j-8];
1049 for (j = k; j > 4; j--) {
1050 if ( (ptfunxored[j ] == 0x01) &&
1051 (ptfunxored[j-1] == 0x5a)) {
1054 numberofwavs |= (uint32_t)(ptfunxored[j-2] << 24);
1055 numberofwavs |= (uint32_t)(ptfunxored[j-3] << 16);
1056 numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
1057 numberofwavs |= (uint32_t)(ptfunxored[j-5]);
1058 //printf("%d wavs\n", numberofwavs);
1065 std::string wave = string(wavname);
1066 std::reverse(wave.begin(), wave.end());
1067 wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
1069 if (foundin(wave, string(".grp"))) {
1073 actualwavs.push_back(f);
1076 if (numberofwavs <= 0)
1083 PTFFormat::parserest89(void) {
1086 uint8_t startbytes = 0;
1087 uint8_t lengthbytes = 0;
1088 uint8_t offsetbytes = 0;
1089 uint8_t somethingbytes = 0;
1090 uint8_t skipbytes = 0;
1094 if ( (ptfunxored[k ] == 'S') &&
1095 (ptfunxored[k+1] == 'n') &&
1096 (ptfunxored[k+2] == 'a') &&
1097 (ptfunxored[k+3] == 'p')) {
1102 uint16_t rindex = 0;
1103 uint32_t findex = 0;
1104 for (i = k; i < len-70; i++) {
1105 if ( (ptfunxored[i ] == 0x5a) &&
1106 (ptfunxored[i+1] == 0x0a)) {
1109 if ( (ptfunxored[i ] == 0x5a) &&
1110 (ptfunxored[i+1] == 0x0c)) {
1112 uint8_t lengthofname = ptfunxored[i+9];
1114 char name[256] = {0};
1115 for (j = 0; j < lengthofname; j++) {
1116 name[j] = ptfunxored[i+13+j];
1120 //uint8_t disabled = ptfunxored[j];
1122 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1123 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1124 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1125 somethingbytes = (ptfunxored[j+3] & 0xf);
1126 skipbytes = ptfunxored[j+4];
1127 findex = ptfunxored[j+5
1134 /*rindex = ptfunxored[j+5
1142 uint32_t sampleoffset = 0;
1143 switch (offsetbytes) {
1145 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1147 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1149 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1151 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1156 uint32_t length = 0;
1157 switch (lengthbytes) {
1159 length |= (uint32_t)(ptfunxored[j+8] << 24);
1161 length |= (uint32_t)(ptfunxored[j+7] << 16);
1163 length |= (uint32_t)(ptfunxored[j+6] << 8);
1165 length |= (uint32_t)(ptfunxored[j+5]);
1171 switch (startbytes) {
1173 start |= (uint32_t)(ptfunxored[j+8] << 24);
1175 start |= (uint32_t)(ptfunxored[j+7] << 16);
1177 start |= (uint32_t)(ptfunxored[j+6] << 8);
1179 start |= (uint32_t)(ptfunxored[j+5]);
1185 uint32_t something = 0;
1186 switch (somethingbytes) {
1188 something |= (uint32_t)(ptfunxored[j+8] << 24);
1190 something |= (uint32_t)(ptfunxored[j+7] << 16);
1192 something |= (uint32_t)(ptfunxored[j+6] << 8);
1194 something |= (uint32_t)(ptfunxored[j+5]);
1200 std::string filename = string(name) + extension;
1204 (int64_t)(start*ratefactor),
1205 (int64_t)(length*ratefactor),
1209 //printf("something=%d\n", something);
1211 vector<wav_t>::iterator begin = actualwavs.begin();
1212 vector<wav_t>::iterator finish = actualwavs.end();
1213 vector<wav_t>::iterator found;
1214 // Add file to list only if it is an actual wav
1215 if ((found = std::find(begin, finish, f)) != finish) {
1216 audiofiles.push_back(f);
1217 // Also add plain wav as region
1218 std::vector<midi_ev_t> m;
1222 (int64_t)(start*ratefactor),
1223 (int64_t)(sampleoffset*ratefactor),
1224 (int64_t)(length*ratefactor),
1228 regions.push_back(r);
1231 if (foundin(filename, string(".grp"))) {
1234 std::vector<midi_ev_t> m;
1238 (int64_t)(start*ratefactor),
1239 (int64_t)(sampleoffset*ratefactor),
1240 (int64_t)(length*ratefactor),
1244 regions.push_back(r);
1251 if ( (ptfunxored[k ] == 0x5a) &&
1252 (ptfunxored[k+1] == 0x03)) {
1258 if ( (ptfunxored[k ] == 0x5a) &&
1259 (ptfunxored[k+1] == 0x02)) {
1268 uint32_t tracknumber = 0;
1269 uint32_t regionspertrack = 0;
1270 for (;k < len; k++) {
1271 if ( (ptfunxored[k ] == 0x5a) &&
1272 (ptfunxored[k+1] == 0x04)) {
1275 if ( (ptfunxored[k ] == 0x5a) &&
1276 (ptfunxored[k+1] == 0x02)) {
1278 uint8_t lengthofname = 0;
1279 lengthofname = ptfunxored[k+9];
1280 if (lengthofname == 0x5a) {
1285 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1287 //printf("regions/track=%d\n", regionspertrack);
1288 char name[256] = {0};
1289 for (j = 0; j < lengthofname; j++) {
1290 name[j] = ptfunxored[j+k+13];
1293 tr.name = string(name);
1294 tr.index = tracknumber++;
1296 for (j = k; regionspertrack > 0 && j < len; j++) {
1297 for (l = j; l < len; l++) {
1298 if ( (ptfunxored[l ] == 0x5a) &&
1299 (ptfunxored[l+1] == 0x07)) {
1306 if (regionspertrack == 0) {
1307 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1311 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1312 vector<region_t>::iterator begin = regions.begin();
1313 vector<region_t>::iterator finish = regions.end();
1314 vector<region_t>::iterator found;
1315 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1320 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1321 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1322 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1323 offset |= (uint32_t)(ptfunxored[i]);
1324 tr.reg.startpos = (int64_t)(offset*ratefactor);
1325 if (tr.reg.length > 0) {
1326 tracks.push_back(tr);
1336 PTFFormat::parserest10(void) {
1339 uint8_t startbytes = 0;
1340 uint8_t lengthbytes = 0;
1341 uint8_t offsetbytes = 0;
1342 uint8_t somethingbytes = 0;
1343 uint8_t skipbytes = 0;
1347 if ( (ptfunxored[k ] == 'S') &&
1348 (ptfunxored[k+1] == 'n') &&
1349 (ptfunxored[k+2] == 'a') &&
1350 (ptfunxored[k+3] == 'p')) {
1355 for (i = k; i < len-70; i++) {
1356 if ( (ptfunxored[i ] == 0x5a) &&
1357 (ptfunxored[i+1] == 0x02)) {
1363 for (i = k; i < len-70; i++) {
1364 if ( (ptfunxored[i ] == 0x5a) &&
1365 (ptfunxored[i+1] == 0x02)) {
1371 uint16_t rindex = 0;
1372 uint32_t findex = 0;
1373 for (i = k; i < len-70; i++) {
1374 if ( (ptfunxored[i ] == 0x5a) &&
1375 (ptfunxored[i+1] == 0x08)) {
1378 if ( (ptfunxored[i ] == 0x5a) &&
1379 (ptfunxored[i+1] == 0x01)) {
1381 uint8_t lengthofname = ptfunxored[i+9];
1382 if (ptfunxored[i+13] == 0x5a) {
1385 char name[256] = {0};
1386 for (j = 0; j < lengthofname; j++) {
1387 name[j] = ptfunxored[i+13+j];
1391 //uint8_t disabled = ptfunxored[j];
1392 //printf("%s\n", name);
1394 offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
1395 lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
1396 startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
1397 somethingbytes = (ptfunxored[j+3] & 0xf);
1398 skipbytes = ptfunxored[j+4];
1399 findex = ptfunxored[j+5
1406 /*rindex = ptfunxored[j+5
1414 uint32_t sampleoffset = 0;
1415 switch (offsetbytes) {
1417 sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
1419 sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
1421 sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
1423 sampleoffset |= (uint32_t)(ptfunxored[j+5]);
1428 uint32_t length = 0;
1429 switch (lengthbytes) {
1431 length |= (uint32_t)(ptfunxored[j+8] << 24);
1433 length |= (uint32_t)(ptfunxored[j+7] << 16);
1435 length |= (uint32_t)(ptfunxored[j+6] << 8);
1437 length |= (uint32_t)(ptfunxored[j+5]);
1443 switch (startbytes) {
1445 start |= (uint32_t)(ptfunxored[j+8] << 24);
1447 start |= (uint32_t)(ptfunxored[j+7] << 16);
1449 start |= (uint32_t)(ptfunxored[j+6] << 8);
1451 start |= (uint32_t)(ptfunxored[j+5]);
1457 uint32_t something = 0;
1458 switch (somethingbytes) {
1460 something |= (uint32_t)(ptfunxored[j+8] << 24);
1462 something |= (uint32_t)(ptfunxored[j+7] << 16);
1464 something |= (uint32_t)(ptfunxored[j+6] << 8);
1466 something |= (uint32_t)(ptfunxored[j+5]);
1472 std::string filename = string(name) + extension;
1476 (int64_t)(start*ratefactor),
1477 (int64_t)(length*ratefactor),
1480 if (strlen(name) == 0) {
1487 //printf("something=%d\n", something);
1489 vector<wav_t>::iterator begin = actualwavs.begin();
1490 vector<wav_t>::iterator finish = actualwavs.end();
1491 vector<wav_t>::iterator found;
1492 // Add file to list only if it is an actual wav
1493 if ((found = std::find(begin, finish, f)) != finish) {
1494 audiofiles.push_back(f);
1495 // Also add plain wav as region
1496 std::vector<midi_ev_t> m;
1500 (int64_t)(start*ratefactor),
1501 (int64_t)(sampleoffset*ratefactor),
1502 (int64_t)(length*ratefactor),
1506 regions.push_back(r);
1509 if (foundin(filename, string(".grp"))) {
1512 std::vector<midi_ev_t> m;
1516 (int64_t)(start*ratefactor),
1517 (int64_t)(sampleoffset*ratefactor),
1518 (int64_t)(length*ratefactor),
1522 regions.push_back(r);
1525 //printf("%s\n", name);
1530 uint32_t tracknumber = 0;
1531 uint32_t regionspertrack = 0;
1532 for (;k < len; k++) {
1533 if ( (ptfunxored[k ] == 0x5a) &&
1534 (ptfunxored[k+1] == 0x08)) {
1539 for (;k < len; k++) {
1540 if ( (ptfunxored[k ] == 0x5a) &&
1541 (ptfunxored[k+1] == 0x04)) {
1544 if ( (ptfunxored[k ] == 0x5a) &&
1545 (ptfunxored[k+1] == 0x02)) {
1547 uint8_t lengthofname = 0;
1548 lengthofname = ptfunxored[k+9];
1549 if (lengthofname == 0x5a) {
1554 regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
1556 //printf("regions/track=%d\n", regionspertrack);
1557 char name[256] = {0};
1558 for (j = 0; j < lengthofname; j++) {
1559 name[j] = ptfunxored[j+k+13];
1562 tr.name = string(name);
1563 tr.index = tracknumber++;
1565 for (j = k; regionspertrack > 0 && j < len; j++) {
1566 for (l = j; l < len; l++) {
1567 if ( (ptfunxored[l ] == 0x5a) &&
1568 (ptfunxored[l+1] == 0x08)) {
1575 if (regionspertrack == 0) {
1576 // tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
1580 tr.reg.index = (uint8_t)(ptfunxored[l+11]);
1581 vector<region_t>::iterator begin = regions.begin();
1582 vector<region_t>::iterator finish = regions.end();
1583 vector<region_t>::iterator found;
1584 if ((found = std::find(begin, finish, tr.reg)) != finish) {
1589 offset |= (uint32_t)(ptfunxored[i+3] << 24);
1590 offset |= (uint32_t)(ptfunxored[i+2] << 16);
1591 offset |= (uint32_t)(ptfunxored[i+1] << 8);
1592 offset |= (uint32_t)(ptfunxored[i]);
1593 tr.reg.startpos = (int64_t)(offset*ratefactor);
1594 if (tr.reg.length > 0) {
1595 tracks.push_back(tr);