Unverified Commit 5f445854 authored by Wolle's avatar Wolle Committed by GitHub

Add files via upload

parent 8f5f4126
...@@ -32,8 +32,8 @@ float m_compressionRatio = 0; ...@@ -32,8 +32,8 @@ float m_compressionRatio = 0;
uint16_t m_rIndex=0; uint16_t m_rIndex=0;
uint64_t m_bitBuffer = 0; uint64_t m_bitBuffer = 0;
uint8_t m_bitBufferLen = 0; uint8_t m_bitBufferLen = 0;
bool m_f_OggS_found = false; bool s_f_flacParseOgg = false;
uint8_t m_psegm = 0; uint8_t m_flacPageSegments = 0;
uint8_t m_page0_len = 0; uint8_t m_page0_len = 0;
char *m_streamTitle= NULL; char *m_streamTitle= NULL;
boolean m_newSt = false; boolean m_newSt = false;
...@@ -132,7 +132,11 @@ void FLACDecoderReset(){ // set var to default ...@@ -132,7 +132,11 @@ void FLACDecoderReset(){ // set var to default
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int FLACFindSyncWord(unsigned char *buf, int nBytes) { int FLACFindSyncWord(unsigned char *buf, int nBytes) {
int i; int i;
i = FLAC_specialIndexOf(buf, "OggS", nBytes);
if(i == 0){
// flag has ogg wrapper
return 0;
}
/* find byte-aligned sync code - need 14 matching bits */ /* find byte-aligned sync code - need 14 matching bits */
for (i = 0; i < nBytes - 1; i++) { for (i = 0; i < nBytes - 1; i++) {
if ((buf[i + 0] & 0xFF) == 0xFF && (buf[i + 1] & 0xFC) == 0xF8) { // <14> Sync code '11111111111110xx' if ((buf[i + 0] & 0xFF) == 0xFF && (buf[i + 1] & 0xFC) == 0xF8) { // <14> Sync code '11111111111110xx'
...@@ -144,7 +148,7 @@ int FLACFindSyncWord(unsigned char *buf, int nBytes) { ...@@ -144,7 +148,7 @@ int FLACFindSyncWord(unsigned char *buf, int nBytes) {
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
boolean FLACFindMagicWord(unsigned char* buf, int nBytes){ boolean FLACFindMagicWord(unsigned char* buf, int nBytes){
int idx = specialIndexOf(buf, "fLaC", nBytes); int idx = FLAC_specialIndexOf(buf, "fLaC", nBytes);
if(idx >0){ // Metadatablock follows if(idx >0){ // Metadatablock follows
idx += 4; idx += 4;
boolean lmdbf = ((buf[idx + 1] & 0x80) == 0x80); // Last-metadata-block flag boolean lmdbf = ((buf[idx + 1] & 0x80) == 0x80); // Last-metadata-block flag
...@@ -162,7 +166,7 @@ boolean FLACFindMagicWord(unsigned char* buf, int nBytes){ ...@@ -162,7 +166,7 @@ boolean FLACFindMagicWord(unsigned char* buf, int nBytes){
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
boolean FLACFindStreamTitle(unsigned char* buf, int nBytes){ boolean FLACFindStreamTitle(unsigned char* buf, int nBytes){
int idx = specialIndexOf(buf, "title=", nBytes); int idx = FLAC_specialIndexOf(buf, "title=", nBytes);
if(idx >0){ if(idx >0){
idx += 6; idx += 6;
int len = nBytes - idx; int len = nBytes - idx;
...@@ -183,60 +187,70 @@ char* FLACgetStreamTitle(){ ...@@ -183,60 +187,70 @@ char* FLACgetStreamTitle(){
} }
return NULL; return NULL;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int FLACparseOggHeader(unsigned char *buf){ int FLACparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph.org/ogg/doc/rfc3533.txt
uint16_t i = 0;
uint8_t ssv = *(buf + i); // stream_structure_version s_f_flacParseOgg = false;
(void)ssv; int ret = 0;
i++; int idx = FLAC_specialIndexOf(inbuf, "OggS", 6);
uint8_t htf = *(buf + i); // header_type_flag
(void)htf; // if(idx != 0) return -1; //ERR_OPUS_DECODER_ASYNC;
i++;
uint32_t tmp = 0; // absolute granule position uint8_t version = *(inbuf + 4); (void) version;
for (int j = 0; j < 4; j++) { uint8_t headerType = *(inbuf + 5); (void) headerType;
tmp += *(buf + j + i) << (4 -j - 1) * 8; uint64_t granulePosition = (uint64_t)*(inbuf + 13) << 56; // granule_position: an 8 Byte field containing -
} granulePosition += (uint64_t)*(inbuf + 12) << 48; // position information. For an audio stream, it MAY
i += 4; granulePosition += (uint64_t)*(inbuf + 11) << 40; // contain the total number of PCM samples encoded
uint64_t agp = (uint64_t) tmp << 32; granulePosition += (uint64_t)*(inbuf + 10) << 32; // after including all frames finished on this page.
for (int j = 0; j < 4; j++) { granulePosition += *(inbuf + 9) << 24; // This is a hint for the decoder and gives it some timing
agp += *(buf + j + i) << (4 -j - 1) * 8; granulePosition += *(inbuf + 8) << 16; // and position information. A special value of -1 (in two's
} granulePosition += *(inbuf + 7) << 8; // complement) indicates that no packets finish on this page.
i += 4; granulePosition += *(inbuf + 6); (void) granulePosition;
uint32_t ssnr = 0; // stream serial number uint32_t bitstreamSerialNr = *(inbuf + 17) << 24; // bitstream_serial_number: a 4 Byte field containing the
for (int j = 0; j < 4; j++) { bitstreamSerialNr += *(inbuf + 16) << 16; // unique serial number by which the logical bitstream
ssnr += *(buf + j + i) << (4 -j - 1) * 8; bitstreamSerialNr += *(inbuf + 15) << 8; // is identified.
} bitstreamSerialNr += *(inbuf + 14); (void) bitstreamSerialNr;
i += 4; uint32_t pageSequenceNr = *(inbuf + 21) << 24; // page_sequence_number: a 4 Byte field containing the sequence
uint32_t psnr = 0; // page sequence no pageSequenceNr += *(inbuf + 20) << 16; // number of the page so the decoder can identify page loss
for (int j = 0; j < 4; j++) { pageSequenceNr += *(inbuf + 19) << 8; // This sequence number is increasing on each logical bitstream
psnr += *(buf + j + i) << (4 -j - 1) * 8; pageSequenceNr += *(inbuf + 18); (void) pageSequenceNr;
} uint32_t CRCchecksum = *(inbuf + 25) << 24;
i += 4; CRCchecksum += *(inbuf + 24) << 16;
uint32_t pchk = 0; // page checksum CRCchecksum += *(inbuf + 23) << 8;
for (int j = 0; j < 4; j++) { CRCchecksum += *(inbuf + 22); (void) CRCchecksum;
pchk += *(buf + j + i) << (4 -j - 1) * 8; uint8_t pageSegments = *(inbuf + 26); // giving the number of segment entries
}
i += 4; // read the segment table (contains pageSegments bytes), 1...251: Length of the frame in bytes,
m_psegm = *(buf + i); // 255: A second byte is needed. The total length is first_byte + second byte
i++;
uint8_t psegmBuff[256]; uint8_t psegmBuff[256];
uint32_t pageLen = 0;
for(uint8_t j = 0; j < m_psegm; j++){ int16_t segmentTableWrPtr = 0;
if(j == 0) m_page0_len = *(buf + i);;
psegmBuff[j] = *(buf + i); for(int i = 0; i < pageSegments; i++){
pageLen += psegmBuff[j]; int n = *(inbuf + 27 + i);
i++; while(*(inbuf + 27 + i) == 255){
} i++;
return i; n+= *(inbuf + 27 + i);
}
psegmBuff[segmentTableWrPtr] = n;
segmentTableWrPtr++;
// s_flacSegmentLength += n;
}
m_page0_len = psegmBuff[0];
uint16_t headerSize = pageSegments + 27;
if(pageSegments == 1) headerSize = pageSegments + psegmBuff[0] +27;
*bytesLeft -= headerSize;
return ERR_FLAC_NONE; // no error
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){ int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
if(m_f_OggS_found == true){ if(s_f_flacParseOgg == true){
m_f_OggS_found = false; int ret = FLACparseOGG(inbuf, bytesLeft);
*bytesLeft -= FLACparseOggHeader(inbuf); if(ret == ERR_FLAC_NONE) return FLAC_PARSE_OGG_DONE; // ok
return FLAC_PARSE_OGG_DONE; else return ret; // error
} }
if(m_status != OUT_SAMPLES){ if(m_status != OUT_SAMPLES){
...@@ -248,23 +262,10 @@ int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){ ...@@ -248,23 +262,10 @@ int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
if(m_status == DECODE_FRAME){ // Read a ton of header fields, and ignore most of them if(m_status == DECODE_FRAME){ // Read a ton of header fields, and ignore most of them
if ((inbuf[0] == 'O') && (inbuf[1] == 'g') && (inbuf[2] == 'g') && (inbuf[3] == 'S')){ if ((inbuf[0] == 'O') && (inbuf[1] == 'g') && (inbuf[2] == 'g') && (inbuf[3] == 'S')){
*bytesLeft -= 4; s_f_flacParseOgg = true;
m_f_OggS_found = true; return FLAC_PARSE_OGG_DONE;
return ERR_FLAC_NONE;
} }
if(!((inbuf[0] & 0xFF) == 0xFF && (inbuf[1] & 0xFC) == 0xF8)){
// log_i("m_psegm %d m_page0_len %d", m_psegm, m_page0_len);
if(m_psegm == 1){
if(!FLACFindMagicWord(inbuf, m_page0_len)){
FLACFindStreamTitle(inbuf, m_page0_len);
}
*bytesLeft -= m_page0_len; // can be FLAC or title
return FLAC_PARSE_OGG_DONE;
}
log_i("sync code not found");
return ERR_FLAC_SYNC_CODE_NOT_FOUND;
}
return flacDecodeFrame(inbuf, bytesLeft, outbuf); return flacDecodeFrame(inbuf, bytesLeft, outbuf);
} }
...@@ -580,7 +581,7 @@ void restoreLinearPrediction(uint8_t ch, uint8_t shift) { ...@@ -580,7 +581,7 @@ void restoreLinearPrediction(uint8_t ch, uint8_t shift) {
} }
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact){ int FLAC_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact){
int result; // seek for str in buffer or in header up to baselen, not nullterninated int result; // seek for str in buffer or in header up to baselen, not nullterninated
if (strlen(str) > baselen) return -1; // if exact == true seekstr in buffer must have "\0" at the end if (strlen(str) > baselen) return -1; // if exact == true seekstr in buffer must have "\0" at the end
for (int i = 0; i < baselen - strlen(str); i++){ for (int i = 0; i < baselen - strlen(str); i++){
......
...@@ -147,7 +147,7 @@ int FLACFindSyncWord(unsigned char *buf, int nBytes); ...@@ -147,7 +147,7 @@ int FLACFindSyncWord(unsigned char *buf, int nBytes);
boolean FLACFindMagicWord(unsigned char* buf, int nBytes); boolean FLACFindMagicWord(unsigned char* buf, int nBytes);
boolean FLACFindStreamTitle(unsigned char* buf, int nBytes); boolean FLACFindStreamTitle(unsigned char* buf, int nBytes);
char* FLACgetStreamTitle(); char* FLACgetStreamTitle();
int FLACparseOggHeader(unsigned char *buf); int FLACparseOGG(uint8_t *inbuf, int *bytesLeft);
bool FLACDecoder_AllocateBuffers(void); bool FLACDecoder_AllocateBuffers(void);
void FLACDecoder_ClearBuffer(); void FLACDecoder_ClearBuffer();
void FLACDecoder_FreeBuffers(); void FLACDecoder_FreeBuffers();
...@@ -172,5 +172,5 @@ int8_t decodeFixedPredictionSubframe(uint8_t predOrder, uint8_t sampleDepth, u ...@@ -172,5 +172,5 @@ int8_t decodeFixedPredictionSubframe(uint8_t predOrder, uint8_t sampleDepth, u
int8_t decodeLinearPredictiveCodingSubframe(int lpcOrder, int sampleDepth, uint8_t ch); int8_t decodeLinearPredictiveCodingSubframe(int lpcOrder, int sampleDepth, uint8_t ch);
int8_t decodeResiduals(uint8_t warmup, uint8_t ch); int8_t decodeResiduals(uint8_t warmup, uint8_t ch);
void restoreLinearPrediction(uint8_t ch, uint8_t shift); void restoreLinearPrediction(uint8_t ch, uint8_t shift);
int specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false); int FLAC_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment