remove debug output
[ardour.git] / libs / ptformat / ptfformat.cc
index 21c6dcaae79a159ce94653e5892aa5002e73b3ec..1dba1ac31a6e7a11726e1640ce34f141a4f5398f 100644 (file)
 
 */
 
-#include "ptfformat.h"
-
 #include <stdio.h>
+#include <stdlib.h>
 #include <string>
 #include <string.h>
 #include <assert.h>
 
+#include <glib/gstdio.h>
+
+#include "ptfformat.h"
+
 using namespace std;
 
 static const uint32_t baselut[16] = {
@@ -73,7 +76,7 @@ static uint64_t gen_secret (int i) {
 
        if (idx & 0x20) {
                lo ^= 0xaaaaaaab;
-               xk ^= 0x10000000; 
+               xk ^= 0x10000000;
        }
        uint32_t hi = swapbytes32 (lo) ^ xk;
        return  ((uint64_t)hi << 32) | (lo ^ xor_lo);
@@ -107,14 +110,15 @@ 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;
+       int err;
 
-       if (! (fp = fopen(path.c_str(), "rb"))) {
+       if (! (fp = g_fopen(path.c_str(), "rb"))) {
                return -1;
        }
 
@@ -139,37 +143,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 +176,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 +190,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 +202,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,70 +209,173 @@ 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();
+       }
+
+       // Special case when ptx is exported to ptf in PT
+       if (v == 3) {
+               version = 11;
+               unxor_ptx_to_ptf();
+       }
+
+       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;
+               }
+       }
+
+       if (version < 5 || version > 12)
+               return -1;
        targetrate = targetsr;
-       parse();
+       err = parse();
+       if (err)
+               return -1;
        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;
+PTFFormat::unxor_ptx_to_ptf(void)
+{
+       unsigned char keyy[16] = {      0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
+                                       0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0
+       };
+       uint64_t j;
+       uint8_t i;
+
+       for (i = 0, j = 0x10; j < len; j++,i++) {
+               ptfunxored[j] ^= keyy[i];
+               if ((j % 16) == 0) {
+                       i = 0;
+                       if (ptfunxored[j] % 2 == 0) {
+                               ptfunxored[j]++;
+                       } else {
+                               ptfunxored[j]--;
+                       }
+               }
+       }
+}
 
+int
+PTFFormat::parse(void) {
        if (version == 5) {
                parse5header();
                setrates();
+               if (sessionrate < 44100 || sessionrate > 192000)
+                 return -1;
                parseaudio5();
                parserest5();
        } else if (version == 7) {
                parse7header();
                setrates();
+               if (sessionrate < 44100 || sessionrate > 192000)
+                 return -1;
                parseaudio();
                parserest89();
        } else if (version == 8) {
                parse8header();
                setrates();
+               if (sessionrate < 44100 || sessionrate > 192000)
+                 return -1;
                parseaudio();
                parserest89();
        } else if (version == 9) {
                parse9header();
                setrates();
+               if (sessionrate < 44100 || sessionrate > 192000)
+                 return -1;
                parseaudio();
                parserest89();
-       } else if (version == 10) {
-               unxor10();
+       } else if (version == 10 || version == 11 || version == 12) {
                parse10header();
                setrates();
+               if (sessionrate < 44100 || sessionrate > 192000)
+                 return -1;
                parseaudio();
                parserest10();
        } else {
                // Should not occur
+               return -1;
        }
+       return 0;
 }
 
 void
@@ -335,7 +388,7 @@ PTFFormat::setrates(void) {
 
 void
 PTFFormat::parse5header(void) {
-       int k;
+       uint32_t k;
 
        // Find session sample rate
        k = 0x100;
@@ -356,7 +409,7 @@ PTFFormat::parse5header(void) {
 
 void
 PTFFormat::parse7header(void) {
-       int k;
+       uint64_t k;
 
        // Find session sample rate
        k = 0x100;
@@ -377,7 +430,7 @@ PTFFormat::parse7header(void) {
 
 void
 PTFFormat::parse8header(void) {
-       int k;
+       uint64_t k;
 
        // Find session sample rate
        k = 0;
@@ -397,7 +450,7 @@ PTFFormat::parse8header(void) {
 
 void
 PTFFormat::parse9header(void) {
-       int k;
+       uint64_t k;
 
        // Find session sample rate
        k = 0x100;
@@ -417,10 +470,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 +490,9 @@ PTFFormat::parse10header(void) {
 
 void
 PTFFormat::parserest5(void) {
-       int i, j, k;
-       int regionspertrack, lengthofname;
-       int startbytes, lengthbytes, offsetbytes, somethingbytes;
+       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 +512,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 +520,8 @@ PTFFormat::parserest5(void) {
                        }
                        k--;
                }
-               k--;
+               if (k)
+                       k--;
        }
        k++;
 
@@ -510,13 +564,8 @@ PTFFormat::parserest5(void) {
                        startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
                        lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
                        offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
-                       somethingbytes = (ptfunxored[j+1] & 0xf);
-                       findex = ptfunxored[j+4
-                                       +startbytes
-                                       +lengthbytes
-                                       +offsetbytes
-                                       +somethingbytes
-                                       ];
+                       //somethingbytes = (ptfunxored[j+1] & 0xf);
+                       findex = ptfunxored[k+14];
                        j--;
                        uint32_t start = 0;
                        switch (startbytes) {
@@ -564,7 +613,7 @@ PTFFormat::parserest5(void) {
                        //printf("name=`%s` start=%04x length=%04x offset=%04x findex=%d\n", name,start,length,sampleoffset,findex);
 
                        std::string filename = string(name) + extension;
-                       wav_t f = { 
+                       wav_t f = {
                                filename,
                                findex,
                                (int64_t)(start*ratefactor),
@@ -602,7 +651,6 @@ PTFFormat::parserest5(void) {
                                };
                                tracks.push_back(t);
                        } else {
-                               audiofiles.push_back(f);
                                region_t r = {
                                        name,
                                        rindex,
@@ -636,84 +684,109 @@ PTFFormat::parserest5(void) {
        }
 }
 
+void
+PTFFormat::resort(std::vector<wav_t>& ws) {
+       int j = 0;
+       std::sort(ws.begin(), ws.end());
+       for (std::vector<wav_t>::iterator i = ws.begin(); i != ws.end(); ++i) {
+               (*i).index = j;
+               j++;
+       }
+}
+
 void
 PTFFormat::parseaudio5(void) {
-       int i,j,k,l;
+       uint64_t i,k,l;
+       uint64_t lengthofname, wavnumber;
 
        // Find end of wav file list
        k = 0;
        while (k < len) {
-               if (            (ptfunxored[k  ] == 0x5a) &&
-                               (ptfunxored[k+1] == 0x00) &&
-                               (ptfunxored[k+2] == 0x05)) {
+               if (            (ptfunxored[k  ] == 0x5f) &&
+                               (ptfunxored[k+1] == 0x50) &&
+                               (ptfunxored[k+2] == 0x35)) {
+                       break;
+               }
+               k++;
+       }
+       k++;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0x5f) &&
+                               (ptfunxored[k+1] == 0x50) &&
+                               (ptfunxored[k+2] == 0x35)) {
                        break;
                }
                k++;
        }
 
        // Find actual wav names
-       bool first = true;
-       uint16_t numberofwavs;
+       uint16_t numberofwavs = ptfunxored[k-23];
        char wavname[256];
-       for (i = k; i > 4; i--) {
-               if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'F')) &&
-                               ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'F')) &&
-                               ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'I')) &&
-                               ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'A'))) {
-                       j = i-4;
-                       l = 0;
-                       while (ptfunxored[j] != '\0') {
-                               wavname[l] = ptfunxored[j];
-                               l++;
-                               j--;
-                       }
-                       wavname[l] = 0;
-                       if (ptfunxored[i] == 'W') {
-                               extension = string(".wav");
-                       } else {
-                               extension = string(".aif");
-                       }
-                       //uint8_t playlist = ptfunxored[j-8];
-
-                       if (first) {
-                               first = false;
-                               for (j = k; j > 4; j--) {
-                                       if (    (ptfunxored[j  ] == 0x01) &&
-                                               (ptfunxored[j-1] == 0x00) &&
-                                               (ptfunxored[j-2] == 0x5a)) {
-
-                                               numberofwavs = 0;
-                                               numberofwavs |= (uint32_t)(ptfunxored[j-6] << 24);
-                                               numberofwavs |= (uint32_t)(ptfunxored[j-5] << 16);
-                                               numberofwavs |= (uint32_t)(ptfunxored[j-4] << 8);
-                                               numberofwavs |= (uint32_t)(ptfunxored[j-3]);
-                                               //printf("%d wavs\n", numberofwavs);
-                                               break;
-                                       }
-                               k--;
-                               }
-                       }
+       for (i = k; i < len; i++) {
+               if (            (ptfunxored[i  ] == 'F') &&
+                               (ptfunxored[i+1] == 'i') &&
+                               (ptfunxored[i+2] == 'l') &&
+                               (ptfunxored[i+3] == 'e') &&
+                               (ptfunxored[i+4] == 's')) {
+                       break;
+               }
+       }
 
-                       std::string wave = string(wavname);
-                       std::reverse(wave.begin(), wave.end());
-                       wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
+       wavnumber = 0;
+       i+=16;
+       char ext[5];
+       while (i < len && numberofwavs > 0) {
+               i++;
+               if (            (ptfunxored[i  ] == 0x5a) &&
+                               (ptfunxored[i+1] == 0x00) &&
+                               (ptfunxored[i+2] == 0x05)) {
+                       break;
+               }
+               lengthofname = ptfunxored[i];
+               i++;
+               l = 0;
+               while (l < lengthofname) {
+                       wavname[l] = ptfunxored[i+l];
+                       l++;
+               }
+               i+=lengthofname;
+               ext[0] = ptfunxored[i++];
+               ext[1] = ptfunxored[i++];
+               ext[2] = ptfunxored[i++];
+               ext[3] = ptfunxored[i++];
+               ext[4] = '\0';
+
+               wavname[l] = 0;
+               if (foundin(wavname, ".L") || foundin(wavname, ".R")) {
+                       extension = string("");
+               } else if (foundin(wavname, ".wav") || foundin(ext, "WAVE")) {
+                       extension = string(".wav");
+               } else if (foundin(wavname, ".aif") || foundin(ext, "AIFF")) {
+                       extension = string(".aif");
+               } else {
+                       extension = string("");
+               }
 
-                       if (foundin(wave, string(".grp"))) {
-                               continue;
-                       }
+               std::string wave = string(wavname);
+               wav_t f = { wave, (uint16_t)(wavnumber++), 0, 0 };
 
-                       actualwavs.push_back(f);
-                       //printf("done\n");
-                       numberofwavs--;
-                       if (numberofwavs <= 0)
-                               break;
+               if (foundin(wave, string(".grp"))) {
+                       continue;
                }
+
+               actualwavs.push_back(f);
+               audiofiles.push_back(f);
+               //printf("done\n");
+               numberofwavs--;
+               i += 7;
        }
+       resort(actualwavs);
+       resort(audiofiles);
 }
 
 void
 PTFFormat::parseaudio(void) {
-       int i,j,k,l;
+       uint64_t i,j,k,l;
 
        // Find end of wav file list
        k = 0;
@@ -788,7 +861,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;
@@ -796,6 +869,7 @@ PTFFormat::parserest89(void) {
        uint8_t somethingbytes = 0;
        uint8_t skipbytes = 0;
 
+       k = 0;
        while (k < len) {
                if (            (ptfunxored[k  ] == 'S') &&
                                (ptfunxored[k+1] == 'n') &&
@@ -904,7 +978,7 @@ PTFFormat::parserest89(void) {
                        j+=somethingbytes;
                        */
                        std::string filename = string(name) + extension;
-                       wav_t f = { 
+                       wav_t f = {
                                filename,
                                0,
                                (int64_t)(start*ratefactor),
@@ -1036,7 +1110,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;
@@ -1044,6 +1118,7 @@ PTFFormat::parserest10(void) {
        uint8_t somethingbytes = 0;
        uint8_t skipbytes = 0;
 
+       k = 0;
        while (k < len) {
                if (            (ptfunxored[k  ] == 'S') &&
                                (ptfunxored[k+1] == 'n') &&
@@ -1171,7 +1246,7 @@ PTFFormat::parserest10(void) {
                        j+=somethingbytes;
                        */
                        std::string filename = string(name) + extension;
-                       wav_t f = { 
+                       wav_t f = {
                                filename,
                                0,
                                (int64_t)(start*ratefactor),