2015-07-31 23:41:26 -04:00
|
|
|
/*
|
2018-04-21 22:49:43 -04:00
|
|
|
* libptformat - a library to read ProTools sessions
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015 Damien Zammit
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*
|
|
|
|
*/
|
2015-07-31 23:41:26 -04:00
|
|
|
#ifndef PTFFORMAT_H
|
|
|
|
#define PTFFORMAT_H
|
|
|
|
|
|
|
|
#include <string>
|
2016-02-02 00:49:12 -05:00
|
|
|
#include <cstring>
|
2015-07-31 23:41:26 -04:00
|
|
|
#include <algorithm>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdint.h>
|
2015-08-10 12:15:53 -04:00
|
|
|
#include "ptformat/visibility.h"
|
|
|
|
|
|
|
|
class LIBPTFORMAT_API PTFFormat {
|
2015-07-31 23:41:26 -04:00
|
|
|
public:
|
|
|
|
PTFFormat();
|
|
|
|
~PTFFormat();
|
|
|
|
|
|
|
|
/* Return values: 0 success
|
2018-04-08 01:27:21 -04:00
|
|
|
-1 could not parse pt session
|
2015-07-31 23:41:26 -04:00
|
|
|
*/
|
2015-08-06 03:29:37 -04:00
|
|
|
int load(std::string path, int64_t targetsr);
|
2015-07-31 23:41:26 -04:00
|
|
|
|
2018-04-08 01:27:21 -04:00
|
|
|
/* Return values: 0 success
|
|
|
|
-1 could not decrypt pt session
|
|
|
|
*/
|
|
|
|
int unxor(std::string path);
|
|
|
|
|
2016-04-14 06:46:23 -04:00
|
|
|
struct wav_t {
|
2015-07-31 23:41:26 -04:00
|
|
|
std::string filename;
|
|
|
|
uint16_t index;
|
|
|
|
|
|
|
|
int64_t posabsolute;
|
|
|
|
int64_t length;
|
|
|
|
|
2016-04-14 06:46:23 -04:00
|
|
|
bool operator <(const struct wav_t& other) const {
|
2016-02-02 00:49:12 -05:00
|
|
|
return (strcasecmp(this->filename.c_str(),
|
|
|
|
other.filename.c_str()) < 0);
|
|
|
|
}
|
|
|
|
|
2016-04-14 06:46:23 -04:00
|
|
|
bool operator ==(const struct wav_t& other) const {
|
2015-08-09 07:53:15 -04:00
|
|
|
return (this->filename == other.filename ||
|
2015-08-08 01:00:11 -04:00
|
|
|
this->index == other.index);
|
2015-07-31 23:41:26 -04:00
|
|
|
}
|
|
|
|
|
2016-04-14 06:46:23 -04:00
|
|
|
};
|
2015-07-31 23:41:26 -04:00
|
|
|
|
2017-02-17 03:43:04 -05:00
|
|
|
struct midi_ev_t {
|
|
|
|
uint64_t pos;
|
|
|
|
uint64_t length;
|
|
|
|
uint8_t note;
|
|
|
|
uint8_t velocity;
|
|
|
|
};
|
|
|
|
|
2015-07-31 23:41:26 -04:00
|
|
|
typedef struct region {
|
|
|
|
std::string name;
|
|
|
|
uint16_t index;
|
|
|
|
int64_t startpos;
|
|
|
|
int64_t sampleoffset;
|
|
|
|
int64_t length;
|
|
|
|
wav_t wave;
|
2017-02-17 03:43:04 -05:00
|
|
|
std::vector<midi_ev_t> midi;
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
bool operator ==(const struct region& other) {
|
|
|
|
return (this->index == other.index);
|
|
|
|
}
|
2018-04-08 01:27:21 -04:00
|
|
|
|
|
|
|
bool operator <(const struct region& other) const {
|
|
|
|
return (strcasecmp(this->name.c_str(),
|
|
|
|
other.name.c_str()) < 0);
|
|
|
|
}
|
2015-07-31 23:41:26 -04:00
|
|
|
} region_t;
|
|
|
|
|
2018-04-08 01:27:21 -04:00
|
|
|
typedef struct compound {
|
|
|
|
uint16_t curr_index;
|
|
|
|
uint16_t unknown1;
|
|
|
|
uint16_t level;
|
|
|
|
uint16_t ontopof_index;
|
|
|
|
uint16_t next_index;
|
|
|
|
std::string name;
|
|
|
|
} compound_t;
|
|
|
|
|
2015-07-31 23:41:26 -04:00
|
|
|
typedef struct track {
|
|
|
|
std::string name;
|
|
|
|
uint16_t index;
|
|
|
|
uint8_t playlist;
|
|
|
|
region_t reg;
|
|
|
|
|
|
|
|
bool operator ==(const struct track& other) {
|
2015-08-08 01:00:11 -04:00
|
|
|
return (this->name == other.name);
|
2015-07-31 23:41:26 -04:00
|
|
|
}
|
|
|
|
} track_t;
|
|
|
|
|
|
|
|
std::vector<wav_t> audiofiles;
|
|
|
|
std::vector<region_t> regions;
|
2018-03-17 07:40:16 -04:00
|
|
|
std::vector<region_t> midiregions;
|
2018-04-08 01:27:21 -04:00
|
|
|
std::vector<compound_t> compounds;
|
2015-07-31 23:41:26 -04:00
|
|
|
std::vector<track_t> tracks;
|
2018-03-17 07:40:16 -04:00
|
|
|
std::vector<track_t> miditracks;
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2015-08-08 01:00:11 -04:00
|
|
|
wav_t w = { std::string(""), 0, 0, 0 };
|
2017-02-17 03:43:04 -05:00
|
|
|
std::vector<midi_ev_t> m;
|
|
|
|
region_t r = { std::string(""), index, 0, 0, 0, w, m};
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
if ((found = std::find(begin, finish, r)) != finish) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool wavexistsin(std::vector<wav_t> wv, uint16_t index) {
|
|
|
|
std::vector<wav_t>::iterator begin = wv.begin();
|
|
|
|
std::vector<wav_t>::iterator finish = wv.end();
|
|
|
|
std::vector<wav_t>::iterator found;
|
|
|
|
|
2015-08-08 01:00:11 -04:00
|
|
|
wav_t w = { std::string(""), index, 0, 0 };
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
if ((found = std::find(begin, finish, w)) != finish) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-06 03:29:37 -04:00
|
|
|
int64_t sessionrate;
|
|
|
|
int64_t targetrate;
|
2015-07-31 23:41:26 -04:00
|
|
|
uint8_t version;
|
2017-02-17 03:43:04 -05:00
|
|
|
uint8_t *product;
|
2018-09-28 09:33:12 -04:00
|
|
|
std::string path;
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
unsigned char c0;
|
|
|
|
unsigned char c1;
|
|
|
|
unsigned char *ptfunxored;
|
2016-02-04 03:39:11 -05:00
|
|
|
uint64_t len;
|
2015-07-31 23:41:26 -04:00
|
|
|
|
|
|
|
private:
|
2018-04-08 01:27:21 -04:00
|
|
|
bool jumpback(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen);
|
|
|
|
bool jumpto(uint32_t *currpos, unsigned char *buf, const uint32_t maxoffset, const unsigned char *needle, const uint32_t needlelen);
|
2015-07-31 23:41:26 -04:00
|
|
|
bool foundin(std::string haystack, std::string needle);
|
2017-10-15 02:12:38 -04:00
|
|
|
int64_t foundat(unsigned char *haystack, uint64_t n, const char *needle);
|
2016-04-16 02:31:44 -04:00
|
|
|
int parse(void);
|
2017-02-17 03:43:04 -05:00
|
|
|
bool parse_version();
|
|
|
|
uint8_t gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative);
|
2015-08-06 03:29:37 -04:00
|
|
|
void setrates(void);
|
2018-09-28 09:33:12 -04:00
|
|
|
void cleanup(void);
|
2015-08-08 01:00:11 -04:00
|
|
|
void parse5header(void);
|
|
|
|
void parse7header(void);
|
2015-07-31 23:41:26 -04:00
|
|
|
void parse8header(void);
|
|
|
|
void parse9header(void);
|
2015-08-08 01:00:11 -04:00
|
|
|
void parse10header(void);
|
|
|
|
void parserest5(void);
|
|
|
|
void parserest89(void);
|
2018-04-08 01:27:21 -04:00
|
|
|
void parserest12(void);
|
2015-08-08 01:00:11 -04:00
|
|
|
void parseaudio5(void);
|
|
|
|
void parseaudio(void);
|
2017-02-17 03:43:04 -05:00
|
|
|
void parsemidi(void);
|
2018-04-08 01:27:21 -04:00
|
|
|
void parsemidi12(void);
|
2016-04-14 06:46:23 -04:00
|
|
|
void resort(std::vector<wav_t>& ws);
|
2018-04-08 01:27:21 -04:00
|
|
|
void resort(std::vector<region_t>& rs);
|
|
|
|
void filter(std::vector<region_t>& rs);
|
2015-07-31 23:41:26 -04:00
|
|
|
std::vector<wav_t> actualwavs;
|
2015-08-06 03:29:37 -04:00
|
|
|
float ratefactor;
|
2015-08-08 01:00:11 -04:00
|
|
|
std::string extension;
|
2015-07-31 23:41:26 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|