Added pt5 pt7 ptx initial format support
authorDamien Zammit <damien@zamaudio.com>
Sat, 8 Aug 2015 05:00:11 +0000 (15:00 +1000)
committerDamien Zammit <damien@zamaudio.com>
Sat, 8 Aug 2015 14:48:16 +0000 (00:48 +1000)
Signed-off-by: Damien Zammit <damien@zamaudio.com>
gtk2_ardour/editor_pt_import.cc
libs/ptformat/ptfformat.cc
libs/ptformat/ptfformat.h

index c1ae3a3bb150aeff216ba8d2e8612196fa2973c0..17c46be24499fcb329957df4fe8933fba2e50894 100644 (file)
@@ -128,11 +128,18 @@ Editor::do_ptimport (std::string ptpath,
        vector<ptflookup_t> ptfregpair;
 
        if (ptf.load(ptpath, _session->frame_rate()) == -1) {
-               MessageDialog msg (_("Doesn't seem to be a valid PT session file (.ptf only currently supported)"));
+               MessageDialog msg (_("Doesn't seem to be a valid PT session file"));
                msg.run ();
                return;
-       }
+       } else {
+               MessageDialog msg (string_compose (_("PT v%1 Session @ %2Hz\n\n%3 audio files\n%4 regions\n%5 active regions\n\nContinue..."), (int)(ptf.version+0), ptf.sessionrate, ptf.audiofiles.size(), ptf.regions.size(), ptf.tracks.size()));
+               msg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
 
+               int result = msg.run ();
+               if (result != Gtk::RESPONSE_OK) {
+                       return;
+               }
+       }
        current_interthread_info = &import_status;
        import_status.current = 1;
        import_status.total = ptf.audiofiles.size ();
index 42bb3f175ae3f7ac49a106d63a8d836c5832b791..21c6dcaae79a159ce94653e5892aa5002e73b3ec 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <stdio.h>
 #include <string>
+#include <string.h>
 #include <assert.h>
 
 using namespace std;
@@ -36,7 +37,7 @@ static const uint32_t xorlut[16] = {
        0xbab0b0ba, 0xb0abaaba, 0xba0aabaa, 0xbaaaaaaa
 };
 
-static const uint32_t swapbytes32 (const uint32_t v) {
+static uint32_t swapbytes32 (const uint32_t v) {
        uint32_t rv = 0;
        rv |= ((v >>  0) & 0xf) << 28;
        rv |= ((v >>  4) & 0xf) << 24;
@@ -49,7 +50,7 @@ static const uint32_t swapbytes32 (const uint32_t v) {
        return rv;
 }
 
-static const uint64_t gen_secret (int i) {
+static uint64_t gen_secret (int i) {
        assert (i > 0 && i < 256);
        int iwrap = i & 0x7f; // wrap at 0x80;
        uint32_t xor_lo = 0;  // 0x40 flag
@@ -127,6 +128,10 @@ PTFFormat::load(std::string path, int64_t targetsr) {
        fread(&c0, 1, 1, fp);
        fread(&c1, 1, 1, fp);
 
+       // For version <= 7 support:
+       version = c0 & 0x0f;
+       c0 = c0 & 0xc0;
+
        if (! (ptfunxored = (unsigned char*) malloc(len * sizeof(unsigned char)))) {
                /* Silently fail -- out of memory*/
                fclose(fp);
@@ -134,8 +139,6 @@ PTFFormat::load(std::string path, int64_t targetsr) {
                return -1;
        }
 
-       i = 2;
-
        fseek(fp, 0x0, SEEK_SET);
 
        switch (c0) {
@@ -143,8 +146,11 @@ PTFFormat::load(std::string path, int64_t targetsr) {
                // Success! easy one
                xxor[0] = c0;
                xxor[1] = c1;
+               //fprintf(stderr, "%02x %02x", 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);
@@ -223,7 +229,7 @@ PTFFormat::load(std::string path, int64_t targetsr) {
                        inv = (((key >> (i-128)) & 1) == 1) ? 1 : 3;
                        xxor[i] ^= (inv * 0x40);
                }
-               
+
                for (i = 192; i < 256; i++) {
                        xxor[i] ^= 0x80;
                }
@@ -254,34 +260,119 @@ PTFFormat::load(std::string path, int64_t targetsr) {
                break;
        }
        fclose(fp);
-       this->targetrate = targetsr;
+       targetrate = targetsr;
        parse();
        return 0;
 }
 
+void
+PTFFormat::unxor10(void)
+{
+       key10a = ptfunxored[0x9f];
+       key10b = ptfunxored[0x9e] - ptfunxored[0x9b];
+       int j, k, currkey;
+
+       k = 0x1000;
+       for (j = k; j < k + 0x1000 && j < len; j++) {
+               ptfunxored[j] ^= key10a;
+       }
+       k = 0x2000;
+       for (j = k; j < k + 0x1000 && j < len; j++) {
+               ptfunxored[j] ^= key10b;
+       }
+       currkey = key10b;
+       while (k < len) {
+               k += 0x1000;
+               currkey = (key10a + currkey) & 0xff;
+               for (j = k; j < k + 0x1000 && j < len; j++) {
+                       ptfunxored[j] ^= currkey;
+               }
+       }
+}
+
 void
 PTFFormat::parse(void) {
-       this->version = ptfunxored[61];
+       version = (version == 0) ? ptfunxored[61] : version;
 
-       if (this->version == 8) {
+       if (version == 5) {
+               parse5header();
+               setrates();
+               parseaudio5();
+               parserest5();
+       } else if (version == 7) {
+               parse7header();
+               setrates();
+               parseaudio();
+               parserest89();
+       } else if (version == 8) {
                parse8header();
                setrates();
-               parserest();
-       } else if (this->version == 9) {
+               parseaudio();
+               parserest89();
+       } else if (version == 9) {
                parse9header();
                setrates();
-               parserest();
+               parseaudio();
+               parserest89();
+       } else if (version == 10) {
+               unxor10();
+               parse10header();
+               setrates();
+               parseaudio();
+               parserest10();
        } else {
                // Should not occur
-       }       
+       }
 }
 
 void
 PTFFormat::setrates(void) {
-       this->ratefactor = 1.f;
+       ratefactor = 1.f;
        if (sessionrate != 0) {
-               this->ratefactor = (float)this->targetrate / this->sessionrate;
+               ratefactor = (float)targetrate / sessionrate;
+       }
+}
+
+void
+PTFFormat::parse5header(void) {
+       int k;
+
+       // Find session sample rate
+       k = 0x100;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0x5a) &&
+                               (ptfunxored[k+1] == 0x00) &&
+                               (ptfunxored[k+2] == 0x02)) {
+                       break;
+               }
+               k++;
        }
+
+       sessionrate = 0;
+       sessionrate |= ptfunxored[k+12] << 16;
+       sessionrate |= ptfunxored[k+13] << 8;
+       sessionrate |= ptfunxored[k+14];
+}
+
+void
+PTFFormat::parse7header(void) {
+       int k;
+
+       // Find session sample rate
+       k = 0x100;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0x5a) &&
+                               (ptfunxored[k+1] == 0x00) &&
+                               (ptfunxored[k+2] == 0x05)) {
+                       break;
+               }
+               k++;
+       }
+
+       sessionrate = 0;
+       sessionrate |= ptfunxored[k+12] << 16;
+       sessionrate |= ptfunxored[k+13] << 8;
+       sessionrate |= ptfunxored[k+14];
 }
 
 void
@@ -298,10 +389,10 @@ PTFFormat::parse8header(void) {
                k++;
        }
 
-       this->sessionrate = 0;
-       this->sessionrate |= ptfunxored[k+11];
-       this->sessionrate |= ptfunxored[k+12] << 8;
-       this->sessionrate |= ptfunxored[k+13] << 16;
+       sessionrate = 0;
+       sessionrate |= ptfunxored[k+11];
+       sessionrate |= ptfunxored[k+12] << 8;
+       sessionrate |= ptfunxored[k+13] << 16;
 }
 
 void
@@ -318,16 +409,312 @@ PTFFormat::parse9header(void) {
                k++;
        }
 
-       this->sessionrate = 0;
-       this->sessionrate |= ptfunxored[k+11];
-       this->sessionrate |= ptfunxored[k+12] << 8;
-       this->sessionrate |= ptfunxored[k+13] << 16;
+       sessionrate = 0;
+       sessionrate |= ptfunxored[k+11];
+       sessionrate |= ptfunxored[k+12] << 8;
+       sessionrate |= ptfunxored[k+13] << 16;
+}
+
+void
+PTFFormat::parse10header(void) {
+       int k;
+
+       // Find session sample rate
+       k = 0;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0x5a) &&
+                               (ptfunxored[k+1] == 0x09)) {
+                       break;
+               }
+               k++;
+       }
+
+       sessionrate = 0;
+       sessionrate |= ptfunxored[k+11];
+       sessionrate |= ptfunxored[k+12] << 8;
+       sessionrate |= ptfunxored[k+13] << 16;
+}
+
+void
+PTFFormat::parserest5(void) {
+       int i, j, k;
+       int regionspertrack, lengthofname;
+       int startbytes, lengthbytes, offsetbytes, somethingbytes;
+       uint16_t tracknumber = 0;
+       uint16_t findex;
+       uint16_t rindex;
+
+       k = 0;
+       for (i = 0; i < 5; i++) {
+               while (k < len) {
+                       if (            (ptfunxored[k  ] == 0x5a) &&
+                                       (ptfunxored[k+1] == 0x00) &&
+                                       (ptfunxored[k+2] == 0x03)) {
+                               break;
+                       }
+                       k++;
+               }
+               k++;
+       }
+       k--;
+
+       for (i = 0; i < 2; i++) {
+               while (k > 0) {
+                       if (            (ptfunxored[k  ] == 0x5a) &&
+                                       (ptfunxored[k+1] == 0x00) &&
+                                       (ptfunxored[k+2] == 0x01)) {
+                               break;
+                       }
+                       k--;
+               }
+               k--;
+       }
+       k++;
+
+       rindex = 0;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0xff) &&
+                               (ptfunxored[k+1] == 0xff)) {
+                       break;
+               }
+               while (k < len) {
+                       if (            (ptfunxored[k  ] == 0x5a) &&
+                                       (ptfunxored[k+1] == 0x00) &&
+                                       (ptfunxored[k+2] == 0x01)) {
+                               break;
+                       }
+                       k++;
+               }
+
+               lengthofname = ptfunxored[k+12];
+               if (ptfunxored[k+13] == 0x5a) {
+                       k++;
+                       break;
+               }
+               char name[256] = {0};
+               for (j = 0; j < lengthofname; j++) {
+                       name[j] = ptfunxored[k+13+j];
+               }
+               name[j] = '\0';
+               regionspertrack = ptfunxored[k+13+j+3];
+               for (i = 0; i < regionspertrack; i++) {
+                       while (k < len) {
+                               if (            (ptfunxored[k  ] == 0x5a) &&
+                                               (ptfunxored[k+1] == 0x00) &&
+                                               (ptfunxored[k+2] == 0x03)) {
+                                       break;
+                               }
+                               k++;
+                       }
+                       j = k+16;
+                       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
+                                       ];
+                       j--;
+                       uint32_t start = 0;
+                       switch (startbytes) {
+                       case 4:
+                               start |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               start |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               start |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               start |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=startbytes;
+                       uint32_t length = 0;
+                       switch (lengthbytes) {
+                       case 4:
+                               length |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               length |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               length |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               length |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=lengthbytes;
+                       uint32_t sampleoffset = 0;
+                       switch (offsetbytes) {
+                       case 4:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=offsetbytes;
+
+                       //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 = { 
+                               filename,
+                               findex,
+                               (int64_t)(start*ratefactor),
+                               (int64_t)(length*ratefactor),
+                       };
+
+                       vector<wav_t>::iterator begin = audiofiles.begin();
+                       vector<wav_t>::iterator finish = audiofiles.end();
+                       vector<wav_t>::iterator found;
+                       // Add file to lists
+                       if ((found = std::find(begin, finish, f)) != finish) {
+                               region_t r = {
+                                       name,
+                                       rindex,
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
+                                       *found,
+                               };
+                               regions.push_back(r);
+                               vector<track_t>::iterator ti;
+                               vector<track_t>::iterator bt = tracks.begin();
+                               vector<track_t>::iterator et = tracks.end();
+                               track_t tr = { name, 0, 0, r };
+                               if ((ti = std::find(bt, et, tr)) != et) {
+                                       tracknumber = (*ti).index;
+                               } else {
+                                       tracknumber = tracks.size() + 1;
+                               }
+                               track_t t = {
+                                       name,
+                                       (uint16_t)tracknumber,
+                                       uint8_t(0),
+                                       r
+                               };
+                               tracks.push_back(t);
+                       } else {
+                               audiofiles.push_back(f);
+                               region_t r = {
+                                       name,
+                                       rindex,
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
+                                       f,
+                               };
+                               regions.push_back(r);
+                               vector<track_t>::iterator ti;
+                               vector<track_t>::iterator bt = tracks.begin();
+                               vector<track_t>::iterator et = tracks.end();
+                               track_t tr = { name, 0, 0, r };
+                               if ((ti = std::find(bt, et, tr)) != et) {
+                                       tracknumber = (*ti).index;
+                               } else {
+                                       tracknumber = tracks.size() + 1;
+                               }
+                               track_t t = {
+                                       name,
+                                       (uint16_t)tracknumber,
+                                       uint8_t(0),
+                                       r
+                               };
+                               tracks.push_back(t);
+                       }
+                       rindex++;
+                       k++;
+               }
+               k++;
+       }
+}
+
+void
+PTFFormat::parseaudio5(void) {
+       int i,j,k,l;
+
+       // Find end of wav file list
+       k = 0;
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 0x5a) &&
+                               (ptfunxored[k+1] == 0x00) &&
+                               (ptfunxored[k+2] == 0x05)) {
+                       break;
+               }
+               k++;
+       }
+
+       // Find actual wav names
+       bool first = true;
+       uint16_t numberofwavs;
+       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--;
+                               }
+                       }
+
+                       std::string wave = string(wavname);
+                       std::reverse(wave.begin(), wave.end());
+                       wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
+
+                       if (foundin(wave, string(".grp"))) {
+                               continue;
+                       }
+
+                       actualwavs.push_back(f);
+                       //printf("done\n");
+                       numberofwavs--;
+                       if (numberofwavs <= 0)
+                               break;
+               }
+       }
 }
 
 void
-PTFFormat::parserest(void) {
+PTFFormat::parseaudio(void) {
        int i,j,k,l;
-       
+
        // Find end of wav file list
        k = 0;
        while (k < len) {
@@ -340,18 +727,15 @@ PTFFormat::parserest(void) {
                k++;
        }
 
-       j = 0;
-       l = 0;
-
        // Find actual wav names
        bool first = true;
        uint16_t numberofwavs;
        char wavname[256];
        for (i = k; i > 4; i--) {
-               if (            (ptfunxored[i  ] == 'W') &&
-                               (ptfunxored[i-1] == 'A') &&
-                               (ptfunxored[i-2] == 'V') &&
-                               (ptfunxored[i-3] == 'E')) {
+               if (            ((ptfunxored[i  ] == 'W') || (ptfunxored[i  ] == 'A')) &&
+                               ((ptfunxored[i-1] == 'A') || (ptfunxored[i-1] == 'I')) &&
+                               ((ptfunxored[i-2] == 'V') || (ptfunxored[i-2] == 'F')) &&
+                               ((ptfunxored[i-3] == 'E') || (ptfunxored[i-3] == 'F'))) {
                        j = i-4;
                        l = 0;
                        while (ptfunxored[j] != '\0') {
@@ -360,6 +744,11 @@ PTFFormat::parserest(void) {
                                j--;
                        }
                        wavname[l] = 0;
+                       if (ptfunxored[i] == 'W') {
+                               extension = string(".wav");
+                       } else {
+                               extension = string(".aif");
+                       }
                        //uint8_t playlist = ptfunxored[j-8];
 
                        if (first) {
@@ -382,7 +771,7 @@ PTFFormat::parserest(void) {
 
                        std::string wave = string(wavname);
                        std::reverse(wave.begin(), wave.end());
-                       wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0 };
+                       wav_t f = { wave, (uint16_t)(numberofwavs - 1), 0, 0 };
 
                        if (foundin(wave, string(".grp"))) {
                                continue;
@@ -395,7 +784,11 @@ PTFFormat::parserest(void) {
                                break;
                }
        }
+}
 
+void
+PTFFormat::parserest89(void) {
+       int i,j,k,l;
        // Find Regions
        uint8_t startbytes = 0;
        uint8_t lengthbytes = 0;
@@ -412,7 +805,6 @@ PTFFormat::parserest(void) {
                }
                k++;
        }
-       first = true;
        uint16_t rindex = 0;
        uint32_t findex = 0;
        for (i = k; i < len-70; i++) {
@@ -495,6 +887,7 @@ PTFFormat::parserest(void) {
                                break;
                        }
                        j+=startbytes;
+                       /*
                        uint32_t something = 0;
                        switch (somethingbytes) {
                        case 4:
@@ -509,33 +902,34 @@ PTFFormat::parserest(void) {
                                break;
                        }
                        j+=somethingbytes;
-                       std::string filename = string(name) + ".wav";
+                       */
+                       std::string filename = string(name) + extension;
                        wav_t f = { 
                                filename,
                                0,
-                               (int64_t)(start*this->ratefactor),
-                               (int64_t)(length*this->ratefactor),
+                               (int64_t)(start*ratefactor),
+                               (int64_t)(length*ratefactor),
                        };
 
                        f.index = findex;
                        //printf("something=%d\n", something);
 
-                       vector<wav_t>::iterator begin = this->actualwavs.begin();
-                       vector<wav_t>::iterator finish = this->actualwavs.end();
+                       vector<wav_t>::iterator begin = actualwavs.begin();
+                       vector<wav_t>::iterator finish = actualwavs.end();
                        vector<wav_t>::iterator found;
                        // Add file to list only if it is an actual wav
                        if ((found = std::find(begin, finish, f)) != finish) {
-                               this->audiofiles.push_back(f);
+                               audiofiles.push_back(f);
                                // Also add plain wav as region
                                region_t r = {
                                        name,
                                        rindex,
-                                       (int64_t)(start*this->ratefactor),
-                                       (int64_t)(sampleoffset*this->ratefactor),
-                                       (int64_t)(length*this->ratefactor),
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
                                        f
                                };
-                               this->regions.push_back(r);
+                               regions.push_back(r);
                        // Region only
                        } else {
                                if (foundin(filename, string(".grp"))) {
@@ -544,12 +938,12 @@ PTFFormat::parserest(void) {
                                region_t r = {
                                        name,
                                        rindex,
-                                       (int64_t)(start*this->ratefactor),
-                                       (int64_t)(sampleoffset*this->ratefactor),
-                                       (int64_t)(length*this->ratefactor),
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
                                        f
                                };
-                               this->regions.push_back(r);
+                               regions.push_back(r);
                        }
                        rindex++;
                }
@@ -617,8 +1011,272 @@ PTFFormat::parserest(void) {
                                } else {
 
                                        tr.reg.index = (uint8_t)(ptfunxored[l+11]);
-                                       vector<region_t>::iterator begin = this->regions.begin();
-                                       vector<region_t>::iterator finish = this->regions.end();
+                                       vector<region_t>::iterator begin = regions.begin();
+                                       vector<region_t>::iterator finish = regions.end();
+                                       vector<region_t>::iterator found;
+                                       if ((found = std::find(begin, finish, tr.reg)) != finish) {
+                                               tr.reg = (*found);
+                                       }
+                                       i = l+16;
+                                       offset = 0;
+                                       offset |= (uint32_t)(ptfunxored[i+3] << 24);
+                                       offset |= (uint32_t)(ptfunxored[i+2] << 16);
+                                       offset |= (uint32_t)(ptfunxored[i+1] << 8);
+                                       offset |= (uint32_t)(ptfunxored[i]);
+                                       tr.reg.startpos = (int64_t)(offset*ratefactor);
+                                       if (tr.reg.length > 0) {
+                                               tracks.push_back(tr);
+                                       }
+                                       regionspertrack--;
+                               }
+                       }
+               }
+       }
+}
+
+void
+PTFFormat::parserest10(void) {
+       int i,j,k,l;
+       // Find Regions
+       uint8_t startbytes = 0;
+       uint8_t lengthbytes = 0;
+       uint8_t offsetbytes = 0;
+       uint8_t somethingbytes = 0;
+       uint8_t skipbytes = 0;
+
+       while (k < len) {
+               if (            (ptfunxored[k  ] == 'S') &&
+                               (ptfunxored[k+1] == 'n') &&
+                               (ptfunxored[k+2] == 'a') &&
+                               (ptfunxored[k+3] == 'p')) {
+                       break;
+               }
+               k++;
+       }
+       for (i = k; i < len-70; i++) {
+               if (            (ptfunxored[i  ] == 0x5a) &&
+                               (ptfunxored[i+1] == 0x02)) {
+                               k = i;
+                               break;
+               }
+       }
+       k++;
+       for (i = k; i < len-70; i++) {
+               if (            (ptfunxored[i  ] == 0x5a) &&
+                               (ptfunxored[i+1] == 0x02)) {
+                               k = i;
+                               break;
+               }
+       }
+       k++;
+       uint16_t rindex = 0;
+       uint32_t findex = 0;
+       for (i = k; i < len-70; i++) {
+               if (            (ptfunxored[i  ] == 0x5a) &&
+                               (ptfunxored[i+1] == 0x08)) {
+                               break;
+               }
+               if (            (ptfunxored[i  ] == 0x5a) &&
+                               (ptfunxored[i+1] == 0x01)) {
+
+                       uint8_t lengthofname = ptfunxored[i+9];
+                       if (ptfunxored[i+13] == 0x5a) {
+                               continue;
+                       }
+                       char name[256] = {0};
+                       for (j = 0; j < lengthofname; j++) {
+                               name[j] = ptfunxored[i+13+j];
+                       }
+                       name[j] = '\0';
+                       j += i+13;
+                       //uint8_t disabled = ptfunxored[j];
+                       //printf("%s\n", name);
+
+                       offsetbytes = (ptfunxored[j+1] & 0xf0) >> 4;
+                       lengthbytes = (ptfunxored[j+2] & 0xf0) >> 4;
+                       startbytes = (ptfunxored[j+3] & 0xf0) >> 4;
+                       somethingbytes = (ptfunxored[j+3] & 0xf);
+                       skipbytes = ptfunxored[j+4];
+                       findex = ptfunxored[j+5
+                                       +startbytes
+                                       +lengthbytes
+                                       +offsetbytes
+                                       +somethingbytes
+                                       +skipbytes
+                                       +37];
+                       /*rindex = ptfunxored[j+5
+                                       +startbytes
+                                       +lengthbytes
+                                       +offsetbytes
+                                       +somethingbytes
+                                       +skipbytes
+                                       +24];
+                       */
+                       uint32_t sampleoffset = 0;
+                       switch (offsetbytes) {
+                       case 4:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               sampleoffset |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=offsetbytes;
+                       uint32_t length = 0;
+                       switch (lengthbytes) {
+                       case 4:
+                               length |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               length |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               length |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               length |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=lengthbytes;
+                       uint32_t start = 0;
+                       switch (startbytes) {
+                       case 4:
+                               start |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               start |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               start |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               start |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=startbytes;
+                       /*
+                       uint32_t something = 0;
+                       switch (somethingbytes) {
+                       case 4:
+                               something |= (uint32_t)(ptfunxored[j+8] << 24);
+                       case 3:
+                               something |= (uint32_t)(ptfunxored[j+7] << 16);
+                       case 2:
+                               something |= (uint32_t)(ptfunxored[j+6] << 8);
+                       case 1:
+                               something |= (uint32_t)(ptfunxored[j+5]);
+                       default:
+                               break;
+                       }
+                       j+=somethingbytes;
+                       */
+                       std::string filename = string(name) + extension;
+                       wav_t f = { 
+                               filename,
+                               0,
+                               (int64_t)(start*ratefactor),
+                               (int64_t)(length*ratefactor),
+                       };
+
+                       if (strlen(name) == 0) {
+                               continue;
+                       }
+                       if (length == 0) {
+                               continue;
+                       }
+                       f.index = findex;
+                       //printf("something=%d\n", something);
+
+                       vector<wav_t>::iterator begin = actualwavs.begin();
+                       vector<wav_t>::iterator finish = actualwavs.end();
+                       vector<wav_t>::iterator found;
+                       // Add file to list only if it is an actual wav
+                       if ((found = std::find(begin, finish, f)) != finish) {
+                               audiofiles.push_back(f);
+                               // Also add plain wav as region
+                               region_t r = {
+                                       name,
+                                       rindex,
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
+                                       f
+                               };
+                               regions.push_back(r);
+                       // Region only
+                       } else {
+                               if (foundin(filename, string(".grp"))) {
+                                       continue;
+                               }
+                               region_t r = {
+                                       name,
+                                       rindex,
+                                       (int64_t)(start*ratefactor),
+                                       (int64_t)(sampleoffset*ratefactor),
+                                       (int64_t)(length*ratefactor),
+                                       f
+                               };
+                               regions.push_back(r);
+                       }
+                       rindex++;
+                       //printf("%s\n", name);
+               }
+       }
+       //  Tracks
+       uint32_t offset;
+       uint32_t tracknumber = 0;
+       uint32_t regionspertrack = 0;
+       for (;k < len; k++) {
+               if (    (ptfunxored[k  ] == 0x5a) &&
+                       (ptfunxored[k+1] == 0x08)) {
+                       break;
+               }
+       }
+       k++;
+       for (;k < len; k++) {
+               if (    (ptfunxored[k  ] == 0x5a) &&
+                       (ptfunxored[k+1] == 0x04)) {
+                       break;
+               }
+               if (    (ptfunxored[k  ] == 0x5a) &&
+                       (ptfunxored[k+1] == 0x02)) {
+
+                       uint8_t lengthofname = 0;
+                       lengthofname = ptfunxored[k+9];
+                       if (lengthofname == 0x5a) {
+                               continue;
+                       }
+                       track_t tr;
+
+                       regionspertrack = (uint8_t)(ptfunxored[k+13+lengthofname]);
+
+                       //printf("regions/track=%d\n", regionspertrack);
+                       char name[256] = {0};
+                       for (j = 0; j < lengthofname; j++) {
+                               name[j] = ptfunxored[j+k+13];
+                       }
+                       name[j] = '\0';
+                       tr.name = string(name);
+                       tr.index = tracknumber++;
+
+                       for (j = k; regionspertrack > 0 && j < len; j++) {
+                               for (l = j; l < len; l++) {
+                                       if (    (ptfunxored[l  ] == 0x5a) &&
+                                               (ptfunxored[l+1] == 0x08)) {
+                                               j = l+1;
+                                               break;
+                                       }
+                               }
+
+
+                               if (regionspertrack == 0) {
+                               //      tr.reg.index = (uint8_t)ptfunxored[j+13+lengthofname+5];
+                                       break;
+                               } else {
+
+                                       tr.reg.index = (uint8_t)(ptfunxored[l+11]);
+                                       vector<region_t>::iterator begin = regions.begin();
+                                       vector<region_t>::iterator finish = regions.end();
                                        vector<region_t>::iterator found;
                                        if ((found = std::find(begin, finish, tr.reg)) != finish) {
                                                tr.reg = (*found);
@@ -629,9 +1287,9 @@ PTFFormat::parserest(void) {
                                        offset |= (uint32_t)(ptfunxored[i+2] << 16);
                                        offset |= (uint32_t)(ptfunxored[i+1] << 8);
                                        offset |= (uint32_t)(ptfunxored[i]);
-                                       tr.reg.startpos = (int64_t)(offset*this->ratefactor);
+                                       tr.reg.startpos = (int64_t)(offset*ratefactor);
                                        if (tr.reg.length > 0) {
-                                               this->tracks.push_back(tr);
+                                               tracks.push_back(tr);
                                        }
                                        regionspertrack--;
                                }
index 394b727add7dfa9e0f762473d7cb8d5f7e41ab1b..e8267bcf59c7c439f2a3cb516801f8730cf82eff 100644 (file)
@@ -38,7 +38,8 @@ public:
                int64_t     length;
 
                bool operator ==(const struct wav& other) {
-                       return (this->index == other.index);
+                       return (this->filename != std::string("") &&
+                               this->index == other.index);
                }
 
        } wav_t;
@@ -63,7 +64,7 @@ public:
                region_t    reg;
 
                bool operator ==(const struct track& other) {
-                       return (this->index == other.index);
+                       return (this->name == other.name);
                }
        } track_t;
 
@@ -71,25 +72,13 @@ public:
        std::vector<region_t> regions;
        std::vector<track_t> tracks;
 
-       static bool trackexistsin(std::vector<track_t> tr, uint16_t index) {
-               std::vector<track_t>::iterator begin = tr.begin();
-               std::vector<track_t>::iterator finish = tr.end();
-               std::vector<track_t>::iterator found;
-
-               track_t f = { std::string(""), index };
-
-               if ((found = std::find(begin, finish, f)) != finish) {
-                       return true;
-               }
-               return false;
-       }
-
        static bool regionexistsin(std::vector<region_t> reg, uint16_t index) {
                std::vector<region_t>::iterator begin = reg.begin();
                std::vector<region_t>::iterator finish = reg.end();
                std::vector<region_t>::iterator found;
 
-               region_t r = { std::string(""), index };
+               wav_t w = { std::string(""), 0, 0, 0 };
+               region_t r = { std::string(""), index, 0, 0, 0, w };
 
                if ((found = std::find(begin, finish, r)) != finish) {
                        return true;
@@ -102,7 +91,7 @@ public:
                std::vector<wav_t>::iterator finish = wv.end();
                std::vector<wav_t>::iterator found;
 
-               wav_t w = { std::string(""), index };
+               wav_t w = { std::string(""), index, 0, 0 };
 
                if ((found = std::find(begin, finish, w)) != finish) {
                        return true;
@@ -122,12 +111,23 @@ public:
 private:
        bool foundin(std::string haystack, std::string needle);
        void parse(void);
+       void unxor10(void);
        void setrates(void);
+       void parse5header(void);
+       void parse7header(void);
        void parse8header(void);
        void parse9header(void);
-       void parserest(void);
+       void parse10header(void);
+       void parserest5(void);
+       void parserest89(void);
+       void parserest10(void);
+       void parseaudio5(void);
+       void parseaudio(void);
        std::vector<wav_t> actualwavs;
        float ratefactor;
+       std::string extension;
+       unsigned char key10a;
+       unsigned char key10b;
 };