diff options
author | Robin Gareus <robin@gareus.org> | 2019-06-20 18:13:34 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2019-06-20 18:13:34 +0200 |
commit | 4f2708e4d29e54f2e8d2d5c5fbf8002905bc1021 (patch) | |
tree | ef48d91dcf1788afb1b4dbe9fe325d218f8d6c42 | |
parent | 12faf930828aad1beca8f9f548a2d2469537ced6 (diff) |
Prefer explicit initialization of structs
* Remove c-style typedefs
* Use C++ style structs with constructors
* Prefer struct variable names to set data
-rw-r--r-- | ptfformat.cc | 74 | ||||
-rw-r--r-- | ptformat/ptfformat.h | 276 |
2 files changed, 301 insertions, 49 deletions
diff --git a/ptfformat.cc b/ptfformat.cc index bec4c30..9a160b4 100644 --- a/ptfformat.cc +++ b/ptfformat.cc @@ -761,7 +761,8 @@ PTFFormat::parseaudio(void) { continue; } } - wav_t f = { wavname, (uint16_t)n, 0, 0 }; + wav_t f (n); + f.filename = wavname; n++; audiofiles.push_back(f); } @@ -885,12 +886,9 @@ PTFFormat::parse_region_info(uint32_t j, block_t& blk, region_t& r) { parse_three_point(j, start, sampleoffset, length); findex = u_endian_read4(&ptfunxored[blk.offset + blk.block_size], is_bigendian); - wav_t f = { - "", - (uint16_t)findex, - (int64_t)(start*ratefactor), - (int64_t)(length*ratefactor), - }; + wav_t f (findex); + f.posabsolute = start * ratefactor; + f.length = length * ratefactor; vector<wav_t>::iterator found; if (find_wav(findex, found)) { @@ -967,16 +965,10 @@ PTFFormat::parserest(void) { std::vector<track_t>::iterator ti; if (!find_track(ch_map[i], ti)) { // Add a dummy region for now - wav_t w = { std::string(""), 0, 0, 0 }; - std::vector<midi_ev_t> m; - region_t r = { std::string(""), 65535, 0, 0, 0, w, m}; - - track_t t = { - trackname, - ch_map[i], - uint8_t(0), - r - }; + region_t r (65535); + track_t t (ch_map[i]); + t.name = trackname; + t.reg = r; tracks.push_back(t); } //verbose_printf("%s : %d(%d)\n", reg, nch, ch_map[0]); @@ -1008,16 +1000,10 @@ PTFFormat::parserest(void) { std::vector<track_t>::iterator ti; // Add a dummy region for now - wav_t w = { std::string(""), 0, 0, 0 }; - std::vector<midi_ev_t> m; - region_t r = { std::string(""), 65535, 0, 0, 0, w, m}; - - track_t t = { - trackname, - mindex, - uint8_t(0), - r - }; + region_t r (65535); + track_t t (mindex); + t.name = trackname; + t.reg = r; // If the current track is not an audio track, insert as midi track if (!(find_track(tindex, ti) && foundin(trackname, (*ti).name))) { @@ -1215,17 +1201,13 @@ PTFFormat::parsemidi(void) { rindex = u_endian_read4(&ptfunxored[j], is_bigendian); struct mchunk mc = *(midichunks.begin()+rindex); - wav_t w = { std::string(""), 0, 0, 0 }; - region_t r = { - midiregionname, - regionnumber++, - (int64_t)0xe8d4a51000ULL, - (int64_t)0, - //(int64_t)(max_pos*sessionrate*60/(960000*120)), - (int64_t)mc.maxlen, - w, - mc.chunk, - }; + region_t r (regionnumber++); + r.name = midiregionname; + r.startpos = (int64_t)0xe8d4a51000ULL; + r.sampleoffset = 0; + r.length = mc.maxlen; + r.midi = mc.chunk; + midiregions.push_back(r); //verbose_printf("MIDI %s : r(%d) (%llu, %llu, %llu)\n", str, rindex, zero_ticks, region_pos, midi_len); //dump_block(*d, 1); @@ -1289,17 +1271,11 @@ PTFFormat::parsemidi(void) { // Plain MIDI region struct mchunk mc = *(midichunks.begin()+n); - wav_t w = { std::string(""), 0, 0, 0 }; - region_t r = { - midiregionname, - (uint16_t)n, - (int64_t)0xe8d4a51000ULL, - (int64_t)0, - //(int64_t)(max_pos*sessionrate*60/(960000*120)), - (int64_t)mc.maxlen, - w, - mc.chunk, - }; + region_t r (n); + r.name = midiregionname; + r.startpos = (int64_t)0xe8d4a51000ULL; + r.length = mc.maxlen; + r.midi = mc.chunk; midiregions.push_back(r); verbose_printf("%s : MIDI region mr(%d) ?(%d) (%llu %llu %llu)\n", str, mindex, n, start, offset, length); mindex++; diff --git a/ptformat/ptfformat.h b/ptformat/ptfformat.h index 40d6025..d4f9c88 100644 --- a/ptformat/ptfformat.h +++ b/ptformat/ptfformat.h @@ -0,0 +1,276 @@ +/* + * 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 + * + */ +#ifndef PTFFORMAT_H +#define PTFFORMAT_H + +#include <string> +#include <cstring> +#include <algorithm> +#include <vector> +#include <stdint.h> +#include "ptformat/visibility.h" + +#define BITCODE "0010111100101011" +#define ZMARK '\x5a' +#define ZERO_TICKS 0xe8d4a51000ULL +#define MAX_CONTENT_TYPE 0x3000 +#define MAX_CHANNELS_PER_TRACK 8 + +class LIBPTFORMAT_API PTFFormat { +public: + PTFFormat(); + ~PTFFormat(); + + /* Return values: 0 success + -1 could not parse pt session + */ + int load(std::string path, int64_t targetsr); + + /* Return values: 0 success + -1 could not decrypt pt session + */ + int unxor(std::string path); + + struct wav_t { + std::string filename; + uint16_t index; + + int64_t posabsolute; + int64_t length; + + bool operator <(const struct wav_t& other) const { + return (strcasecmp(this->filename.c_str(), + other.filename.c_str()) < 0); + } + + bool operator ==(const struct wav_t& other) const { + return (this->filename == other.filename || + this->index == other.index); + } + + wav_t (uint16_t idx = 0) : index (idx), posabsolute (0), length (0) {} + }; + + struct midi_ev_t { + uint64_t pos; + uint64_t length; + uint8_t note; + uint8_t velocity; + midi_ev_t () : pos (0), length (0), note (0), velocity (0) {} + }; + + struct region_t { + std::string name; + uint16_t index; + int64_t startpos; + int64_t sampleoffset; + int64_t length; + wav_t wave; + std::vector<midi_ev_t> midi; + + bool operator ==(const region_t& other) const { + return (this->index == other.index); + } + + bool operator <(const region_t& other) const { + return (strcasecmp(this->name.c_str(), + other.name.c_str()) < 0); + } + region_t (uint16_t idx = 0) : index (idx), startpos (0), sampleoffset (0), length (0) {} + }; + + struct track_t { + std::string name; + uint16_t index; + uint8_t playlist; + region_t reg; + + bool operator <(const track_t& other) const { + return (this->index < other.index); + } + + bool operator ==(const track_t& other) const { + return (this->index == other.index); + } + track_t (uint16_t idx = 0) : index (idx), playlist (0) {} + }; + + bool find_track(uint16_t index, std::vector<track_t>::iterator& ti) { + std::vector<track_t>::iterator begin = tracks.begin(); + std::vector<track_t>::iterator finish = tracks.end(); + std::vector<track_t>::iterator found; + + track_t t (index); + + if ((found = std::find(begin, finish, t)) != finish) { + ti = found; + return true; + } + return false; + } + + bool find_region(uint16_t index, std::vector<region_t>::iterator& ri) { + std::vector<region_t>::iterator begin = regions.begin(); + std::vector<region_t>::iterator finish = regions.end(); + std::vector<region_t>::iterator found; + + region_t r; + r.index = index; + + if ((found = std::find(begin, finish, r)) != finish) { + ri = found; + return true; + } + return false; + } + + bool find_miditrack(uint16_t index, std::vector<track_t>::iterator& ti) { + std::vector<track_t>::iterator begin = miditracks.begin(); + std::vector<track_t>::iterator finish = miditracks.end(); + std::vector<track_t>::iterator found; + + track_t t (index); + + if ((found = std::find(begin, finish, t)) != finish) { + ti = found; + return true; + } + return false; + } + + bool find_midiregion(uint16_t index, std::vector<region_t>::iterator& ri) { + std::vector<region_t>::iterator begin = midiregions.begin(); + std::vector<region_t>::iterator finish = midiregions.end(); + std::vector<region_t>::iterator found; + + region_t r (index); + + if ((found = std::find(begin, finish, r)) != finish) { + ri = found; + return true; + } + return false; + } + + bool find_wav(uint16_t index, std::vector<wav_t>::iterator& wi) { + std::vector<wav_t>::iterator begin = audiofiles.begin(); + std::vector<wav_t>::iterator finish = audiofiles.end(); + std::vector<wav_t>::iterator found; + + wav_t w (index); + + if ((found = std::find(begin, finish, w)) != finish) { + wi = found; + 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 (index); + + 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; + + wav_t w (index); + + if ((found = std::find(begin, finish, w)) != finish) { + return true; + } + return false; + } + + std::vector<wav_t> audiofiles; + std::vector<region_t> regions; + std::vector<region_t> midiregions; + std::vector<track_t> tracks; + std::vector<track_t> miditracks; + + std::string path; + unsigned char *ptfunxored; + uint64_t len; + int64_t sessionrate; + uint8_t version; + +private: + struct block_t; + + struct block_t { + uint8_t zmark; // 'Z' + uint16_t block_type; // type of block + uint32_t block_size; // size of block + uint16_t content_type; // type of content + uint32_t offset; // offset in file + std::vector<block_t> child; // vector of child blocks + }; + std::vector<block_t> blocks; + + unsigned char c0; + unsigned char c1; + uint8_t *product; + bool is_bigendian; + int64_t targetrate; + float ratefactor; + + 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); + bool foundin(std::string haystack, std::string needle); + int64_t foundat(unsigned char *haystack, uint64_t n, const char *needle); + uint16_t u_endian_read2(unsigned char *buf, bool); + uint32_t u_endian_read3(unsigned char *buf, bool); + uint32_t u_endian_read4(unsigned char *buf, bool); + uint64_t u_endian_read5(unsigned char *buf, bool); + uint64_t u_endian_read8(unsigned char *buf, bool); + + char *parsestring(uint32_t pos); + std::string get_content_description(uint16_t ctype); + int parse(void); + void parseblocks(void); + bool parseheader(void); + bool parserest(void); + bool parseaudio(void); + bool parsemidi(void); + void dump(void); + bool parse_block_at(uint32_t pos, struct block_t *b, int level); + void dump_block(struct block_t& b, int level); + bool parse_version(); + void parse_region_info(uint32_t j, block_t& blk, region_t& r); + void parse_three_point(uint32_t j, uint64_t& start, uint64_t& offset, uint64_t& length); + uint8_t gen_xor_delta(uint8_t xor_value, uint8_t mul, bool negative); + void setrates(void); + void cleanup(void); + void free_block(struct block_t& b); + void free_all_blocks(void); +}; + +#endif |