From f6da063898738514d14461206b0b90a9ada296b7 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Thu, 4 Feb 2016 19:39:11 +1100 Subject: Add preliminary PTX support for Protools 10 and 11 Signed-off-by: Damien Zammit --- libs/ptformat/ptfformat.cc | 210 +++++++++++++++++++++++---------------------- libs/ptformat/ptfformat.h | 3 +- 2 files changed, 110 insertions(+), 103 deletions(-) diff --git a/libs/ptformat/ptfformat.cc b/libs/ptformat/ptfformat.cc index 99c89510dc..62fc0293c7 100644 --- a/libs/ptformat/ptfformat.cc +++ b/libs/ptformat/ptfformat.cc @@ -107,12 +107,12 @@ PTFFormat::load(std::string path, int64_t targetsr) { FILE *fp; unsigned char xxor[256]; unsigned char ct; - unsigned char px; + unsigned char v; + unsigned char voff; uint64_t key; - uint16_t i; - int j; + uint64_t i; + uint64_t j; int inv; - unsigned char message; if (! (fp = fopen(path.c_str(), "rb"))) { return -1; @@ -139,37 +139,20 @@ PTFFormat::load(std::string path, int64_t targetsr) { return -1; } - fseek(fp, 0x0, SEEK_SET); - switch (c0) { case 0x00: // Success! easy one xxor[0] = c0; xxor[1] = c1; - //fprintf(stderr, "%02x %02x", c0, c1); + //fprintf(stderr, "0 %02x\n1 %02x\n", c0, c1); - for (i = 2; i < 64; i++) { - xxor[i] = (xxor[i-1] + c1 - c0) & 0xff; - //fprintf(stderr, "%02x ", xxor[i]); - } - px = xxor[0]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[0] = message; - px = xxor[1]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[1] = message; - i = 2; - j = 2; - while (fread(&ct, 1, 1, fp) != 0) { + for (i = 2; i < 256; i++) { if (i%64 == 0) { - i = 0; + xxor[i] = c0; + } else { + xxor[i] = (xxor[i-1] + c1 - c0) & 0xff; + //fprintf(stderr, "%x %02x\n", i, xxor[i]); } - message = xxor[i] ^ ct; - ptfunxored[j] = message; - i++; - j++; } break; case 0x80: @@ -189,25 +172,6 @@ PTFFormat::load(std::string path, int64_t targetsr) { for (i = 128; i < 192; i++) { xxor[i] ^= 0x80; } - px = xxor[0]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[0] = message; - px = xxor[1]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[1] = message; - i = 2; - j = 2; - while (fread(&ct, 1, 1, fp) != 0) { - if (i%256 == 0) { - i = 0; - } - message = xxor[i] ^ ct; - ptfunxored[j] = message; - i++; - j++; - } break; case 0x40: case 0xc0: @@ -222,6 +186,7 @@ PTFFormat::load(std::string path, int64_t targetsr) { } key = gen_secret(c1); + for (i = 0; i < 64; i++) { xxor[i] ^= (((key >> i) & 1) * 2 * 0x40) + 0x40; } @@ -233,25 +198,6 @@ PTFFormat::load(std::string path, int64_t targetsr) { for (i = 192; i < 256; i++) { xxor[i] ^= 0x80; } - px = xxor[0]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[0] = message; - px = xxor[1]; - fread(&ct, 1, 1, fp); - message = px ^ ct; - ptfunxored[1] = message; - i = 2; - j = 2; - while (fread(&ct, 1, 1, fp) != 0) { - if (i%256 == 0) { - i = 0; - } - message = xxor[i] ^ ct; - ptfunxored[j] = message; - i++; - j++; - } break; break; default: @@ -259,41 +205,101 @@ PTFFormat::load(std::string path, int64_t targetsr) { return -1; break; } + + /* Read file */ + i = 0; + fseek(fp, 0, SEEK_SET); + while (fread(&ct, 1, 1, fp) != 0) { + ptfunxored[i++] = ct; + } fclose(fp); + + /* version detection */ + voff = 0x36; + v = ptfunxored[voff]; + if (v == 0x20) { + voff += 7; + } else if (v == 0x03) { + voff += 4; + } else { + voff = 0; + } + v = ptfunxored[voff]; + if (v == 10 || v == 11 || v == 12) { + version = v; + unxor10(); + } + + if (version == 0 || version == 5 || version == 7) { + /* Haven't detected version yet so decipher */ + j = 0; + for (i = 0; i < len; i++) { + if (j%256 == 0) { + j = 0; + } + ptfunxored[i] ^= xxor[j]; + j++; + } + + /* version detection */ + voff = 0x36; + v = ptfunxored[voff]; + if (v == 0x20) { + voff += 7; + } else if (v == 0x03) { + voff += 4; + } else { + voff = 0; + } + v = ptfunxored[voff]; + if (v == 5 || v == 7 || v == 8 || v == 9) { + version = v; + } + } + targetrate = targetsr; parse(); return 0; } -void -PTFFormat::unxor10(void) +uint8_t +PTFFormat::mostfrequent(uint32_t start, uint32_t stop) { - key10a = ptfunxored[0x9f]; - key10b = ptfunxored[0x9e] - ptfunxored[0x9b]; - int j, k, currkey; + uint32_t counts[256] = {0}; + uint64_t i; + uint32_t max = 0; + uint8_t maxi = 0; - k = 0x1000; - for (j = k; j < k + 0x1000 && j < len; j++) { - ptfunxored[j] ^= key10a; + for (i = start; i < stop; i++) { + counts[ptfunxored[i]]++; } - k = 0x2000; - for (j = k; j < k + 0x1000 && j < len; j++) { - ptfunxored[j] ^= key10b; + + for (i = 0; i < 256; i++) { + if (counts[i] > max) { + maxi = i; + max = counts[i]; + } } - currkey = key10b; - while (k < len) { - k += 0x1000; - currkey = (key10a + currkey) & 0xff; - for (j = k; j < k + 0x1000 && j < len; j++) { - ptfunxored[j] ^= currkey; + return maxi; +} + +void +PTFFormat::unxor10(void) +{ + uint64_t j; + uint8_t x = mostfrequent(0x1000, 0x2000); + uint8_t dx = 0x100-x; + + for (j = 0x1000; j < len; j++) { + if(j % 0x1000 == 0xfff) { + x = (x - dx) & 0xff; } + ptfunxored[j] ^= x; } } void PTFFormat::parse(void) { - version = (version == 0) ? ptfunxored[61] : version; - if (version == 5) { parse5header(); setrates(); @@ -314,8 +320,7 @@ PTFFormat::parse(void) { setrates(); parseaudio(); parserest89(); - } else if (version == 10) { - unxor10(); + } else if (version == 10 || version == 11 || version == 12) { parse10header(); setrates(); parseaudio(); @@ -335,7 +340,7 @@ PTFFormat::setrates(void) { void PTFFormat::parse5header(void) { - int k; + uint32_t k; // Find session sample rate k = 0x100; @@ -356,7 +361,7 @@ PTFFormat::parse5header(void) { void PTFFormat::parse7header(void) { - int k; + uint64_t k; // Find session sample rate k = 0x100; @@ -377,7 +382,7 @@ PTFFormat::parse7header(void) { void PTFFormat::parse8header(void) { - int k; + uint64_t k; // Find session sample rate k = 0; @@ -397,7 +402,7 @@ PTFFormat::parse8header(void) { void PTFFormat::parse9header(void) { - int k; + uint64_t k; // Find session sample rate k = 0x100; @@ -417,10 +422,10 @@ PTFFormat::parse9header(void) { void PTFFormat::parse10header(void) { - int k; + uint64_t k; // Find session sample rate - k = 0; + k = 0x100; while (k < len) { if ( (ptfunxored[k ] == 0x5a) && (ptfunxored[k+1] == 0x09)) { @@ -437,9 +442,9 @@ PTFFormat::parse10header(void) { void PTFFormat::parserest5(void) { - int i, j, k; - int regionspertrack, lengthofname; - int startbytes, lengthbytes, offsetbytes; + uint64_t i, j, k; + uint64_t regionspertrack, lengthofname; + uint64_t startbytes, lengthbytes, offsetbytes; uint16_t tracknumber = 0; uint16_t findex; uint16_t rindex; @@ -459,7 +464,7 @@ PTFFormat::parserest5(void) { k--; for (i = 0; i < 2; i++) { - while (k > 0) { + while (k) { if ( (ptfunxored[k ] == 0x5a) && (ptfunxored[k+1] == 0x00) && (ptfunxored[k+2] == 0x01)) { @@ -467,7 +472,8 @@ PTFFormat::parserest5(void) { } k--; } - k--; + if (k) + k--; } k++; @@ -643,8 +649,8 @@ PTFFormat::resort(std::vector *ws) { void PTFFormat::parseaudio5(void) { - int i,k,l; - int lengthofname, wavnumber; + uint64_t i,k,l; + uint64_t lengthofname, wavnumber; // Find end of wav file list k = 0; @@ -733,7 +739,7 @@ PTFFormat::parseaudio5(void) { void PTFFormat::parseaudio(void) { - int i,j,k,l; + uint64_t i,j,k,l; // Find end of wav file list k = 0; @@ -808,7 +814,7 @@ PTFFormat::parseaudio(void) { void PTFFormat::parserest89(void) { - int i,j,k,l; + uint64_t i,j,k,l; // Find Regions uint8_t startbytes = 0; uint8_t lengthbytes = 0; @@ -1057,7 +1063,7 @@ PTFFormat::parserest89(void) { void PTFFormat::parserest10(void) { - int i,j,k,l; + uint64_t i,j,k,l; // Find Regions uint8_t startbytes = 0; uint8_t lengthbytes = 0; diff --git a/libs/ptformat/ptfformat.h b/libs/ptformat/ptfformat.h index 1d3dac2ba3..f2c51d9830 100644 --- a/libs/ptformat/ptfformat.h +++ b/libs/ptformat/ptfformat.h @@ -113,7 +113,7 @@ public: unsigned char c0; unsigned char c1; unsigned char *ptfunxored; - int len; + uint64_t len; private: bool foundin(std::string haystack, std::string needle); @@ -131,6 +131,7 @@ private: void parseaudio5(void); void parseaudio(void); void resort(std::vector *ws); + uint8_t mostfrequent(uint32_t start, uint32_t stop); std::vector actualwavs; float ratefactor; std::string extension; -- cgit v1.2.3