Improvements to FLAC library and analyser

This commit is contained in:
Thulinma 2023-02-27 00:48:16 +01:00
parent a7183aedc5
commit dc0ec77f26
4 changed files with 442 additions and 180 deletions

View file

@ -1,128 +1,344 @@
#include "bitfields.h"
#include "defines.h"
#include "encode.h"
#include "flac.h" #include "flac.h"
#include <sstream>
/// Checks the first 4 bytes for the string "flaC". Implementing a basic FLAC header check, namespace FLAC{
/// returning true if it is, false if not.
bool FLAC::is_header(const char *header){
if (header[0] != 'f') return false;
if (header[1] != 'L') return false;
if (header[2] != 'a') return false;
if (header[3] != 'C') return false;
return true;
}// FLAC::is_header
size_t FLAC::utfBytes(char p){ /// Checks the first 4 bytes for the string "flaC". Implementing a basic FLAC header check,
if ((p & 0x80) == 0x00){return 1;} /// returning true if it is, false if not.
if ((p & 0xE0) == 0xC0){return 2;} bool is_header(const char *header){
if ((p & 0xF0) == 0xE0){return 3;} if (header[0] != 'f') return false;
if ((p & 0xF8) == 0xF0){return 4;} if (header[1] != 'L') return false;
if ((p & 0xFC) == 0xF8){return 5;} if (header[2] != 'a') return false;
if ((p & 0xFE) == 0xFC){return 6;} if (header[3] != 'C') return false;
if ((p & 0xFF) == 0xFE){return 7;} return true;
return 9; }// FLAC::is_header
}
uint32_t FLAC::utfVal(char *p){ size_t utfBytes(char p){
size_t bytes = utfBytes(*p); if ((p & 0x80) == 0x00){return 1;}
uint32_t ret = 0; if ((p & 0xE0) == 0xC0){return 2;}
if ((p & 0xF0) == 0xE0){return 3;}
if (bytes == 1){ if ((p & 0xF8) == 0xF0){return 4;}
ret = (uint32_t)*p; if ((p & 0xFC) == 0xF8){return 5;}
}else if (bytes == 2){ if ((p & 0xFE) == 0xFC){return 6;}
ret = (uint32_t)(*p & 0x1F) << 6; if ((p & 0xFF) == 0xFE){return 7;}
ret = ret | (*(p + 1) & 0x3f); return 9;
}else if (bytes == 3){
ret = (uint32_t)(*p & 0x1F) << 6;
ret = (ret | (*(p + 1) & 0x3f)) << 6;
ret = ret | (*(p + 2) & 0x3f);
}else if (bytes == 4){
ret = (uint32_t)(*p & 0x1F) << 6;
ret = (ret | (*(p + 1) & 0x3f)) << 6;
ret = (ret | (*(p + 2) & 0x3f)) << 6;
ret = ret | (*(p + 3) & 0x3f);
} }
return ret; uint32_t utfVal(char *p){
} size_t bytes = utfBytes(*p);
uint32_t ret = 0;
FLAC::Frame::Frame(char *pkt){ if (bytes == 1){
data = pkt; ret = (uint32_t)*p;
if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8){ }else if (bytes == 2){
WARN_MSG("Sync code incorrect! Ignoring FLAC frame"); ret = (uint32_t)(*p & 0x1F) << 6;
FAIL_MSG("%x %x", data[0], data[1]); ret = ret | (*(p + 1) & 0x3f);
data = 0; }else if (bytes == 3){
ret = (uint32_t)(*p & 0x1F) << 6;
ret = (ret | (*(p + 1) & 0x3f)) << 6;
ret = ret | (*(p + 2) & 0x3f);
}else if (bytes == 4){
ret = (uint32_t)(*p & 0x1F) << 6;
ret = (ret | (*(p + 1) & 0x3f)) << 6;
ret = (ret | (*(p + 2) & 0x3f)) << 6;
ret = ret | (*(p + 3) & 0x3f);
}
return ret;
} }
}
uint16_t FLAC::Frame::samples(){ Frame::Frame(char *pkt){
if (!data){return 0;} data = pkt;
switch ((data[2] & 0xF0) >> 4){ if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8){
case 0: return 0; // reserved WARN_MSG("Sync code incorrect! Ignoring FLAC frame");
case 1: return 192; FAIL_MSG("%x %x", data[0], data[1]);
case 2: return 576; data = 0;
case 3: return 1152; }
case 4: return 2304;
case 5: return 4608;
case 6: return 1; // 1b at end
case 7: return 2; // 2b at end
default: return 256 << (((data[2] & 0xf0) >> 4) - 8);
} }
}
uint32_t FLAC::Frame::rate(){ uint16_t Frame::samples(){
if (!data){return 0;} if (!data){return 0;}
switch (data[2] & 0x0F){ switch ((data[2] & 0xF0) >> 4){
case 0: return 0; // get from STREAMINFO case 0: return 0; // reserved
case 1: return 88200; case 1: return 192;
case 2: return 176400; case 2: return 576;
case 3: return 192000; case 3: return 1152;
case 4: return 8000; case 4: return 2304;
case 5: return 16000; case 5: return 4608;
case 6: return 22050; case 6: return 1; // 1b at end
case 7: return 24000; case 7: return 2; // 2b at end
case 8: return 32000; default: return 256 << (((data[2] & 0xf0) >> 4) - 8);
case 9: return 44100; }
case 10: return 48000;
case 11: return 96000;
case 12: return 1; // 1b at end, *1000
case 13: return 2; // 2b at end
case 14: return 3; // 2b at end, *10
case 15: return 0; // invalid, get from STREAMINFO
default: return 0;
} }
} uint32_t Frame::rate(){
if (!data){return 0;}
uint8_t FLAC::Frame::channels(){ switch (data[2] & 0x0F){
if (!data){return 0;} case 0: return 0; // get from STREAMINFO
uint8_t ret = ((data[3] & 0xF0) >> 4) + 1; case 1: return 88200;
if (ret > 8 && ret < 12){return 2;}// special stereo case 2: return 176400;
return ret; case 3: return 192000;
} case 4: return 8000;
uint8_t FLAC::Frame::size(){ case 5: return 16000;
if (!data){return 0;} case 6: return 22050;
switch (data[3] & 0x0E){ case 7: return 24000;
case 0: return 0; // get from STREAMINFO case 8: return 32000;
case 1: return 8; case 9: return 44100;
case 2: return 12; case 10: return 48000;
case 3: return 0; // reserved case 11: return 96000;
case 4: return 16; case 12: return 1; // 1b at end, *1000
case 5: return 20; case 13: return 2; // 2b at end
case 6: return 24; case 14: return 3; // 2b at end, *10
case 7: return 0; // reserved case 15: return 0; // invalid, get from STREAMINFO
default: return 0; default: return 0;
}
} }
}
uint32_t FLAC::Frame::utfVal(){ uint8_t Frame::channels(){
return FLAC::utfVal(data + 4); if (!data){return 0;}
} uint8_t ret = ((data[3] & 0xF0) >> 4) + 1;
if (ret > 8 && ret < 12){return 2;}// special stereo
return ret;
}
uint8_t Frame::size(){
if (!data){return 0;}
switch (data[3] & 0x0E){
case 0: return 0; // get from STREAMINFO
case 1: return 8;
case 2: return 12;
case 3: return 0; // reserved
case 4: return 16;
case 5: return 20;
case 6: return 24;
case 7: return 0; // reserved
default: return 0;
}
}
std::string FLAC::Frame::toPrettyString(){ uint32_t Frame::utfVal(){
if (!data){return "Invalid frame";} return ::FLAC::utfVal(data + 4);
std::stringstream r; }
r << "FLAC frame" << std::endl;
r << " Block size: " << ((data[1] & 0x1) ? "variable" : "fixed") << std::endl; std::string Frame::toPrettyString(){
r << " Samples: " << samples() << std::endl; if (!data){return "Invalid frame";}
r << " Rate: " << rate() << "Hz" << std::endl; std::stringstream r;
r << " Channels: " << (int)channels() << std::endl; r << "FLAC frame, " << ((data[1] & 0x1) ? "variable" : "fixed") << " block size, " << samples() << " samples, "
r << " Size: " << (int)size() << "-bit" << std::endl; << rate() << " Hz, " << (int)channels() << " Ch, " << (int)size() << "-bit" << std::endl;
return r.str(); return r.str();
} }
MetaBlock::MetaBlock() : ptr(0), len(0){}
MetaBlock::MetaBlock(const char *_ptr, size_t _len) : ptr(_ptr), len(_len){}
std::string MetaBlock::getType(){
if (!ptr || !len){return "";}
switch (ptr[0] & 0x7F){
case 0: return "STREAMINFO";
case 1: return "PADDING";
case 2: return "APPLICATION";
case 3: return "SEEKTABLE";
case 4: return "VORBIS_COMMENT";
case 5: return "CUESHEET";
case 6: return "PICTURE";
case 127: return "INVALID";
default: return "UNKNOWN";
}
}
size_t MetaBlock::getSize(){
if (!ptr || len < 4){return 0;}
return Bit::btoh24(ptr + 1);
}
bool MetaBlock::getLast(){
if (!ptr || !len){return false;}
return ptr[0] & 0x80;
}
void MetaBlock::toPrettyString(std::ostream &out){
if (len < 4){return;}
out << getType() << " metadata block (" << getSize() << "b, "
<< (getLast() ? "last" : "non-last") << ")" << std::endl;
}
/// Helper function that calls the other toPrettyString function and returns the output as a string
std::string MetaBlock::toPrettyString(){
std::stringstream str;
toPrettyString(str);
return str.str();
}
uint16_t StreamInfo::getMinBlockSize(){
return Bit::btohs(ptr + 4);
}
uint16_t StreamInfo::getMaxBlockSize(){
return Bit::btohs(ptr + 6);
}
uint32_t StreamInfo::getMinFrameSize(){
return Bit::btoh24(ptr + 8);
}
uint32_t StreamInfo::getMaxFrameSize(){
return Bit::btoh24(ptr + 11);
}
uint32_t StreamInfo::getSampleRate(){
return ((uint64_t)ptr[14] << 12) + ((uint64_t)ptr[15] << 4) + ((ptr[16] & 0xf0) >> 4);
}
uint8_t StreamInfo::getChannels(){
return ((ptr[16] & 0x0e) >> 1) + 1;
}
uint8_t StreamInfo::getBits(){
return ((ptr[17] & 0xf0) >> 4) + (ptr[16] & 1) * 16 + 1;
}
uint64_t StreamInfo::getSamples(){
return ((uint64_t)(ptr[17] & 0x0f) << 32) + ((uint64_t)ptr[18] << 24) +
((uint64_t)ptr[19] << 16) + ((uint64_t)ptr[20] << 8) + ptr[21];
}
std::string StreamInfo::getMD5(){
return Encodings::Hex::encode(std::string(ptr + 19, 16));
}
void StreamInfo::toPrettyString(std::ostream &out){
if (len < 4){return;}
out << getType() << " metadata block (" << getSize() << "b, "
<< (getLast() ? "last" : "non-last") << "):" << std::endl;
out << " Min block size: " << getMinBlockSize() << std::endl;
out << " Max block size: " << getMaxBlockSize() << std::endl;
out << " Min frame size: " << getMinFrameSize() << std::endl;
out << " Max frame size: " << getMaxFrameSize() << std::endl;
out << " Sample rate: " << getSampleRate() << std::endl;
out << " Channels: " << (size_t)getChannels() << std::endl;
out << " Bits: " << (size_t)getBits() << std::endl;
out << " Samples: " << getSamples() << std::endl;
out << " Checksum: " << getMD5() << std::endl;
}
std::string Picture::getPicType(){
uint32_t t = Bit::btohl(ptr + 4);
switch (t){
case 0: return "Other";
case 1: return "File icon";
case 2: return "Other file icon";
case 3: return "Cover (front)";
case 4: return "Cover (back)";
case 5: return "Leaflet";
case 6: return "Media";
case 7: return "Lead artist";
case 8: return "Artist";
case 9: return "Conductor";
case 10: return "Band";
case 11: return "Composer";
case 12: return "Text writer";
case 13: return "Recording location";
case 14: return "During recording";
case 15: return "During performance";
case 16: return "Movie capture";
case 17: return "A bright coloured fish";
case 18: return "Illustration";
case 19: return "Band logo";
case 20: return "Publisher logo";
}
return "Unknown";
}
std::string Picture::getMime(){
return std::string(ptr + 12, getMimeLen());
}
uint32_t Picture::getMimeLen(){
return Bit::btohl(ptr + 8);
}
std::string Picture::getDesc(){
return std::string(ptr + 16 + getMimeLen(), getDescLen());
}
uint32_t Picture::getDescLen(){
return Bit::btohl(ptr + 12 + getMimeLen());
}
uint32_t Picture::getWidth(){
return Bit::btohl(ptr + 16 + getMimeLen() + getDescLen());
}
uint32_t Picture::getHeight(){
return Bit::btohl(ptr + 20 + getMimeLen() + getDescLen());
}
uint32_t Picture::getDepth(){
return Bit::btohl(ptr + 24 + getMimeLen() + getDescLen());
}
uint32_t Picture::getColors(){
return Bit::btohl(ptr + 28 + getMimeLen() + getDescLen());
}
uint32_t Picture::getDataLen(){
return Bit::btohl(ptr + 32 + getMimeLen() + getDescLen());
}
const char *Picture::getData(){
return ptr + 36 + getMimeLen() + getDescLen();
}
void Picture::toPrettyString(std::ostream &out){
if (len < 4){return;}
out << getType() << " metadata block (" << getSize() << "b, "
<< (getLast() ? "last" : "non-last") << "):" << std::endl;
out << " Picture type: " << getPicType() << std::endl;
out << " Mime type: " << getMime() << std::endl;
out << " Description: " << getDesc() << std::endl;
out << " Dimensions: " << getWidth() << "x" << getHeight() << std::endl;
out << " Color depth: " << getDepth() << std::endl;
out << " Color count: " << getColors() << std::endl;
out << " Picture data size: " << getDataLen() << "b" << std::endl;
}
uint32_t VorbisComment::getVendorSize(){
return Bit::btohl_le(ptr + 4);
}
std::string VorbisComment::getVendor(){
return std::string(ptr + 8, getVendorSize());
}
std::string VorbisComment::getComment(uint32_t _num){
size_t offset = 12 + getVendorSize();
size_t i = 0;
while (offset < getSize() - 4){
size_t len = Bit::btohl_le(ptr + offset);
if (i == _num){return std::string(ptr + offset + 4, len);}
offset += 4 + len;
++i;
}
return "";
}
uint32_t VorbisComment::getCommentCount(){
return Bit::btohl_le(ptr + 8 + getVendorSize());
}
void VorbisComment::toPrettyString(std::ostream &out){
if (len < 4){return;}
out << getType() << " metadata block (" << getSize() << "b, "
<< (getLast() ? "last" : "non-last") << "):" << std::endl;
out << " Vendor: " << getVendor() << std::endl;
out << " Comment count: " << getCommentCount() << std::endl;
size_t offset = 12 + getVendorSize();
while (offset < getSize() - 4){
size_t len = Bit::btohl_le(ptr + offset);
out << " " << std::string(ptr + offset + 4, len) << std::endl;
offset += 4 + len;
}
}
}; // Namespace FLAC

View file

@ -1,5 +1,4 @@
#pragma once #pragma once
#include <mist/defines.h>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -11,9 +10,6 @@ namespace FLAC{
size_t utfBytes(char p); // UTF encoding byte size size_t utfBytes(char p); // UTF encoding byte size
uint32_t utfVal(char *p); // UTF encoding value uint32_t utfVal(char *p); // UTF encoding value
size_t rate();
uint8_t channels();
class Frame{ class Frame{
public: public:
Frame(char *pkt); Frame(char *pkt);
@ -29,4 +25,64 @@ namespace FLAC{
char *data; char *data;
}; };
class MetaBlock{
public:
MetaBlock();
MetaBlock(const char *_ptr, size_t _len);
std::string getType();
size_t getSize();
bool getLast();
std::string toPrettyString();
virtual void toPrettyString(std::ostream &out);
protected:
const char *ptr;
size_t len;
};
class StreamInfo : public MetaBlock{
public:
StreamInfo() : MetaBlock(){};
StreamInfo(const char *_ptr, size_t _len) : MetaBlock(_ptr, _len){};
uint16_t getMinBlockSize();
uint16_t getMaxBlockSize();
uint32_t getMinFrameSize();
uint32_t getMaxFrameSize();
uint32_t getSampleRate();
uint8_t getChannels();
uint8_t getBits();
uint64_t getSamples();
std::string getMD5();
void toPrettyString(std::ostream &out);
};
class Picture : public MetaBlock{
public:
Picture() : MetaBlock(){};
Picture(const char *_ptr, size_t _len) : MetaBlock(_ptr, _len){};
std::string getPicType();
std::string getMime();
uint32_t getMimeLen();
std::string getDesc();
uint32_t getDescLen();
uint32_t getWidth();
uint32_t getHeight();
uint32_t getDepth();
uint32_t getColors();
uint32_t getDataLen();
const char *getData();
void toPrettyString(std::ostream &out);
};
class VorbisComment : public MetaBlock{
public:
VorbisComment() : MetaBlock(){};
VorbisComment(const char *_ptr, size_t _len) : MetaBlock(_ptr, _len){};
uint32_t getVendorSize();
std::string getVendor();
std::string getComment(uint32_t _num);
uint32_t getCommentCount();
void toPrettyString(std::ostream &out);
};
}// namespace FLAC }// namespace FLAC

View file

@ -10,7 +10,6 @@
#include <mist/flac.h> #include <mist/flac.h>
AnalyserFLAC::AnalyserFLAC(Util::Config &conf) : Analyser(conf){ AnalyserFLAC::AnalyserFLAC(Util::Config &conf) : Analyser(conf){
a = conf.getInteger("filter");
headerParsed = false; headerParsed = false;
curPos = 0; curPos = 0;
bufferSize = 0; bufferSize = 0;
@ -19,89 +18,76 @@ AnalyserFLAC::AnalyserFLAC(Util::Config &conf) : Analyser(conf){
prev_header_size = 0; prev_header_size = 0;
pos = NULL; pos = NULL;
forceFill = false; forceFill = false;
sampleNo = 0;
sampleRate = 1;
} }
bool AnalyserFLAC::readMagicPacket(){ bool AnalyserFLAC::readMagicPacket(){
char magic[4]; char magic[4];
if (fread(magic, 4, 1, stdin) != 1){ if (fread(magic, 4, 1, stdin) != 1){
std::cout << "Could not read magic word - aborting!" << std::endl; FAIL_MSG("Could not read magic word - aborting!");
return false; return false;
} }
if (FLAC::is_header(magic)){ if (!FLAC::is_header(magic)){
std::cout << "Found magic packet" << std::endl; FAIL_MSG("Not a FLAC file - aborting!");
curPos = 4; return false;
return true;
} }
std::cout << "Not a FLAC file - aborting!" << std::endl; curPos = 4;
return false; return true;
} }
void AnalyserFLAC::init(Util::Config &conf){ void AnalyserFLAC::init(Util::Config &conf){
Analyser::init(conf); Analyser::init(conf);
JSON::Value opt;
opt["long"] = "filter";
opt["short"] = "F";
opt["arg"] = "num";
opt["default"] = "0";
opt["help"] =
"Only print information about this tag type (8 = audio, 9 = video, 18 = meta, 0 = all)";
conf.addOption("filter", opt);
opt.null();
if (feof(stdin)){
WARN_MSG("cannot open stdin");
return;
}
} }
bool AnalyserFLAC::readMeta(){ bool AnalyserFLAC::readMeta(){
if (!readMagicPacket()){return false;} if (!readMagicPacket()){return false;}
bool lastMeta = false; bool lastMeta = false;
char metahead[4]; Util::ResizeablePointer flacmeta;
flacmeta.allocate(4);
while (!feof(stdin) && !lastMeta){ while (!feof(stdin) && !lastMeta){
if (fread(metahead, 4, 1, stdin) != 1){ flacmeta.truncate(0);
std::cout << "Could not read metadata block header - aborting!" << std::endl; if (fread(flacmeta, 4, 1, stdin) != 1){
FAIL_MSG("Could not read metadata block header - aborting!");
return 1; return 1;
} }
flacmeta.append(0, 4);
curPos += 4; curPos += 4;
lastMeta = (metahead[0] & 0x80); // check for last metadata block flag lastMeta = FLAC::MetaBlock(flacmeta, 4).getLast(); // check for last metadata block flag
std::string mType; std::string mType = FLAC::MetaBlock(flacmeta, 4).getType();
switch (metahead[0] & 0x7F){ flacmeta.allocate(FLAC::MetaBlock(flacmeta, 4).getSize() + 4);
case 0: mType = "STREAMINFO"; break;
case 1: mType = "PADDING"; break; // This variable is not created earlier because flacmeta.allocate updates the pointer and would invalidate it
case 2: mType = "APPLICATION"; break; FLAC::MetaBlock mb(flacmeta, 4);
case 3: mType = "SEEKTABLE"; break;
case 4: mType = "VORBIS_COMMENT"; break; if (fread(((char *)flacmeta) + 4, mb.getSize(), 1, stdin) != 1){
case 5: mType = "CUESHEET"; break; FAIL_MSG("Could not read metadata block contents: %s", strerror(errno));
case 6: mType = "PICTURE"; break; return false;
case 127: mType = "INVALID"; break; }
default: mType = "UNKNOWN"; break; flacmeta.append(0, mb.getSize());
curPos += mb.getSize();
if (mType == "STREAMINFO"){
FLAC::StreamInfo si(flacmeta, flacmeta.size());
sampleRate = si.getSampleRate();
si.toPrettyString(std::cout);
}else if (mType == "VORBIS_COMMENT"){
FLAC::VorbisComment(flacmeta, flacmeta.size()).toPrettyString(std::cout);
}else if (mType == "PICTURE"){
FLAC::Picture(flacmeta, flacmeta.size()).toPrettyString(std::cout);
}else{
mb.toPrettyString(std::cout);
} }
unsigned int bytes = Bit::btoh24(metahead + 1);
curPos += bytes;
fseek(stdin, bytes, SEEK_CUR);
std::cout << "Found metadata block of type " << mType << ", skipping " << bytes << " bytes" << std::endl;
if (mType == "STREAMINFO"){FAIL_MSG("streaminfo");}
} }
INFO_MSG("last metadata");
headerParsed = true; headerParsed = true;
return true; return true;
} }
bool AnalyserFLAC::parsePacket(){ bool AnalyserFLAC::parsePacket(){
if (feof(stdin) && flacBuffer.size() < 100){ if (feof(stdin) && flacBuffer.size() < 100){return false;}
stop(); if (!headerParsed && !readMeta()){return false;}
return false;
}
if (!headerParsed){
if (!readMeta()){
stop();
return false;
}
}
uint64_t needed = 40000; uint64_t needed = 40000;
// fill up buffer as we go // fill up buffer as we go
@ -114,7 +100,7 @@ bool AnalyserFLAC::parsePacket(){
flacBuffer += tmp; flacBuffer += tmp;
if (!std::cin.good()){ if (!std::cin.good()){
WARN_MSG("End, process remaining buffer data: %zu bytes", flacBuffer.size()); INFO_MSG("End, process remaining buffer data: %zu bytes", flacBuffer.size());
if (flacBuffer.size() < 1){ if (flacBuffer.size() < 1){
FAIL_MSG("eof"); FAIL_MSG("eof");
@ -141,11 +127,11 @@ bool AnalyserFLAC::parsePacket(){
int utfv = FLAC::utfVal(start + 4); // read framenumber int utfv = FLAC::utfVal(start + 4); // read framenumber
if (utfv + 1 != FLAC::utfVal(a + 4)){ if (utfv + 1 != FLAC::utfVal(a + 4)){
FAIL_MSG("framenr: %d, end framenr: %d, size: %zu curPos: %" PRIu64, FLAC::utfVal(start + 4), HIGH_MSG("framenr: %d, end framenr: %d, size: %zu curPos: %" PRIu64,
FLAC::utfVal(a + 4), (size_t)(pos - start), curPos); FLAC::utfVal(start + 4), FLAC::utfVal(a + 4), (size_t)(pos - start), curPos);
}else{ }else{
INFO_MSG("framenr: %d, end framenr: %d, size: %zu curPos: %" PRIu64, FLAC::utfVal(start + 4), DONTEVEN_MSG("framenr: %d, end framenr: %d, size: %zu curPos: %" PRIu64,
FLAC::utfVal(a + 4), (size_t)(pos - start), curPos); FLAC::utfVal(start + 4), FLAC::utfVal(a + 4), (size_t)(pos - start), curPos);
} }
int skip = FLAC::utfBytes(u); int skip = FLAC::utfBytes(u);
@ -154,7 +140,7 @@ bool AnalyserFLAC::parsePacket(){
if (checksum::crc8(0, pos, prev_header_size) == *(a + prev_header_size)){ if (checksum::crc8(0, pos, prev_header_size) == *(a + prev_header_size)){
// checksum pass, valid startframe found // checksum pass, valid startframe found
if (((utfv + 1 != FLAC::utfVal(a + 4))) && (utfv != 0)){ if (((utfv + 1 != FLAC::utfVal(a + 4))) && (utfv != 0)){
WARN_MSG("error frame, found: %d, expected: %d, ignore.. ", FLAC::utfVal(a + 4), utfv + 1); HIGH_MSG("error frame, found: %d, expected: %d, ignore.. ", FLAC::utfVal(a + 4), utfv + 1);
}else{ }else{
FLAC::Frame f(start); FLAC::Frame f(start);
@ -164,10 +150,13 @@ bool AnalyserFLAC::parsePacket(){
start = &flacBuffer[0]; start = &flacBuffer[0];
end = &flacBuffer[flacBuffer.size()]; end = &flacBuffer[flacBuffer.size()];
pos = start + 2; pos = start + 2;
std::cout << f.toPrettyString();
sampleNo += f.samples();
mediaTime = sampleNo / (sampleRate / 10);
return true; return true;
} }
}else{ }else{
WARN_MSG("Checksum mismatch! %x - %x, curPos: %" PRIu64, *(a + prev_header_size), HIGH_MSG("Checksum mismatch! %x - %x, curPos: %" PRIu64, *(a + prev_header_size),
checksum::crc8(0, pos, prev_header_size), curPos + (pos - start)); checksum::crc8(0, pos, prev_header_size), curPos + (pos - start));
} }
} }

View file

@ -12,7 +12,6 @@ public:
bool readMeta(); bool readMeta();
private: private:
int64_t a;
uint64_t neededBytes(); uint64_t neededBytes();
void newFrame(char *data); void newFrame(char *data);
bool headerParsed; bool headerParsed;
@ -24,6 +23,8 @@ private:
bool forceFill; bool forceFill;
char *ptr; char *ptr;
uint64_t sampleNo;
uint64_t sampleRate;
bool stopProcessing; bool stopProcessing;
char *start; // = &flacBuffer[0]; char *start; // = &flacBuffer[0];