Skip to content

Commit 5f44585

Browse files
authored
Add files via upload
1 parent 8f5f412 commit 5f44585

File tree

2 files changed

+72
-71
lines changed

2 files changed

+72
-71
lines changed

src/flac_decoder/flac_decoder.cpp

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ float m_compressionRatio = 0;
3232
uint16_t m_rIndex=0;
3333
uint64_t m_bitBuffer = 0;
3434
uint8_t m_bitBufferLen = 0;
35-
bool m_f_OggS_found = false;
36-
uint8_t m_psegm = 0;
35+
bool s_f_flacParseOgg = false;
36+
uint8_t m_flacPageSegments = 0;
3737
uint8_t m_page0_len = 0;
3838
char *m_streamTitle= NULL;
3939
boolean m_newSt = false;
@@ -132,7 +132,11 @@ void FLACDecoderReset(){ // set var to default
132132
//----------------------------------------------------------------------------------------------------------------------
133133
int FLACFindSyncWord(unsigned char *buf, int nBytes) {
134134
int i;
135-
135+
i = FLAC_specialIndexOf(buf, "OggS", nBytes);
136+
if(i == 0){
137+
// flag has ogg wrapper
138+
return 0;
139+
}
136140
/* find byte-aligned sync code - need 14 matching bits */
137141
for (i = 0; i < nBytes - 1; i++) {
138142
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) {
144148
}
145149
//----------------------------------------------------------------------------------------------------------------------
146150
boolean FLACFindMagicWord(unsigned char* buf, int nBytes){
147-
int idx = specialIndexOf(buf, "fLaC", nBytes);
151+
int idx = FLAC_specialIndexOf(buf, "fLaC", nBytes);
148152
if(idx >0){ // Metadatablock follows
149153
idx += 4;
150154
boolean lmdbf = ((buf[idx + 1] & 0x80) == 0x80); // Last-metadata-block flag
@@ -162,7 +166,7 @@ boolean FLACFindMagicWord(unsigned char* buf, int nBytes){
162166
}
163167
//----------------------------------------------------------------------------------------------------------------------
164168
boolean FLACFindStreamTitle(unsigned char* buf, int nBytes){
165-
int idx = specialIndexOf(buf, "title=", nBytes);
169+
int idx = FLAC_specialIndexOf(buf, "title=", nBytes);
166170
if(idx >0){
167171
idx += 6;
168172
int len = nBytes - idx;
@@ -183,60 +187,70 @@ char* FLACgetStreamTitle(){
183187
}
184188
return NULL;
185189
}
186-
187190
//----------------------------------------------------------------------------------------------------------------------
188-
int FLACparseOggHeader(unsigned char *buf){
189-
uint16_t i = 0;
190-
uint8_t ssv = *(buf + i); // stream_structure_version
191-
(void)ssv;
192-
i++;
193-
uint8_t htf = *(buf + i); // header_type_flag
194-
(void)htf;
195-
i++;
196-
uint32_t tmp = 0; // absolute granule position
197-
for (int j = 0; j < 4; j++) {
198-
tmp += *(buf + j + i) << (4 -j - 1) * 8;
199-
}
200-
i += 4;
201-
uint64_t agp = (uint64_t) tmp << 32;
202-
for (int j = 0; j < 4; j++) {
203-
agp += *(buf + j + i) << (4 -j - 1) * 8;
204-
}
205-
i += 4;
206-
uint32_t ssnr = 0; // stream serial number
207-
for (int j = 0; j < 4; j++) {
208-
ssnr += *(buf + j + i) << (4 -j - 1) * 8;
209-
}
210-
i += 4;
211-
uint32_t psnr = 0; // page sequence no
212-
for (int j = 0; j < 4; j++) {
213-
psnr += *(buf + j + i) << (4 -j - 1) * 8;
214-
}
215-
i += 4;
216-
uint32_t pchk = 0; // page checksum
217-
for (int j = 0; j < 4; j++) {
218-
pchk += *(buf + j + i) << (4 -j - 1) * 8;
219-
}
220-
i += 4;
221-
m_psegm = *(buf + i);
222-
i++;
191+
int FLACparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph.org/ogg/doc/rfc3533.txt
192+
193+
s_f_flacParseOgg = false;
194+
int ret = 0;
195+
int idx = FLAC_specialIndexOf(inbuf, "OggS", 6);
196+
197+
// if(idx != 0) return -1; //ERR_OPUS_DECODER_ASYNC;
198+
199+
uint8_t version = *(inbuf + 4); (void) version;
200+
uint8_t headerType = *(inbuf + 5); (void) headerType;
201+
uint64_t granulePosition = (uint64_t)*(inbuf + 13) << 56; // granule_position: an 8 Byte field containing -
202+
granulePosition += (uint64_t)*(inbuf + 12) << 48; // position information. For an audio stream, it MAY
203+
granulePosition += (uint64_t)*(inbuf + 11) << 40; // contain the total number of PCM samples encoded
204+
granulePosition += (uint64_t)*(inbuf + 10) << 32; // after including all frames finished on this page.
205+
granulePosition += *(inbuf + 9) << 24; // This is a hint for the decoder and gives it some timing
206+
granulePosition += *(inbuf + 8) << 16; // and position information. A special value of -1 (in two's
207+
granulePosition += *(inbuf + 7) << 8; // complement) indicates that no packets finish on this page.
208+
granulePosition += *(inbuf + 6); (void) granulePosition;
209+
uint32_t bitstreamSerialNr = *(inbuf + 17) << 24; // bitstream_serial_number: a 4 Byte field containing the
210+
bitstreamSerialNr += *(inbuf + 16) << 16; // unique serial number by which the logical bitstream
211+
bitstreamSerialNr += *(inbuf + 15) << 8; // is identified.
212+
bitstreamSerialNr += *(inbuf + 14); (void) bitstreamSerialNr;
213+
uint32_t pageSequenceNr = *(inbuf + 21) << 24; // page_sequence_number: a 4 Byte field containing the sequence
214+
pageSequenceNr += *(inbuf + 20) << 16; // number of the page so the decoder can identify page loss
215+
pageSequenceNr += *(inbuf + 19) << 8; // This sequence number is increasing on each logical bitstream
216+
pageSequenceNr += *(inbuf + 18); (void) pageSequenceNr;
217+
uint32_t CRCchecksum = *(inbuf + 25) << 24;
218+
CRCchecksum += *(inbuf + 24) << 16;
219+
CRCchecksum += *(inbuf + 23) << 8;
220+
CRCchecksum += *(inbuf + 22); (void) CRCchecksum;
221+
uint8_t pageSegments = *(inbuf + 26); // giving the number of segment entries
222+
223+
// read the segment table (contains pageSegments bytes), 1...251: Length of the frame in bytes,
224+
// 255: A second byte is needed. The total length is first_byte + second byte
223225
uint8_t psegmBuff[256];
224-
uint32_t pageLen = 0;
225-
for(uint8_t j = 0; j < m_psegm; j++){
226-
if(j == 0) m_page0_len = *(buf + i);;
227-
psegmBuff[j] = *(buf + i);
228-
pageLen += psegmBuff[j];
229-
i++;
230-
}
231-
return i;
226+
227+
int16_t segmentTableWrPtr = 0;
228+
229+
for(int i = 0; i < pageSegments; i++){
230+
int n = *(inbuf + 27 + i);
231+
while(*(inbuf + 27 + i) == 255){
232+
i++;
233+
n+= *(inbuf + 27 + i);
234+
}
235+
psegmBuff[segmentTableWrPtr] = n;
236+
segmentTableWrPtr++;
237+
// s_flacSegmentLength += n;
238+
}
239+
m_page0_len = psegmBuff[0];
240+
241+
uint16_t headerSize = pageSegments + 27;
242+
if(pageSegments == 1) headerSize = pageSegments + psegmBuff[0] +27;
243+
*bytesLeft -= headerSize;
244+
245+
return ERR_FLAC_NONE; // no error
232246
}
233247
//----------------------------------------------------------------------------------------------------------------------
234248
int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
235249

236-
if(m_f_OggS_found == true){
237-
m_f_OggS_found = false;
238-
*bytesLeft -= FLACparseOggHeader(inbuf);
239-
return FLAC_PARSE_OGG_DONE;
250+
if(s_f_flacParseOgg == true){
251+
int ret = FLACparseOGG(inbuf, bytesLeft);
252+
if(ret == ERR_FLAC_NONE) return FLAC_PARSE_OGG_DONE; // ok
253+
else return ret; // error
240254
}
241255

242256
if(m_status != OUT_SAMPLES){
@@ -248,23 +262,10 @@ int8_t FLACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
248262
if(m_status == DECODE_FRAME){ // Read a ton of header fields, and ignore most of them
249263

250264
if ((inbuf[0] == 'O') && (inbuf[1] == 'g') && (inbuf[2] == 'g') && (inbuf[3] == 'S')){
251-
*bytesLeft -= 4;
252-
m_f_OggS_found = true;
253-
return ERR_FLAC_NONE;
265+
s_f_flacParseOgg = true;
266+
return FLAC_PARSE_OGG_DONE;
254267
}
255268

256-
if(!((inbuf[0] & 0xFF) == 0xFF && (inbuf[1] & 0xFC) == 0xF8)){
257-
// log_i("m_psegm %d m_page0_len %d", m_psegm, m_page0_len);
258-
if(m_psegm == 1){
259-
if(!FLACFindMagicWord(inbuf, m_page0_len)){
260-
FLACFindStreamTitle(inbuf, m_page0_len);
261-
}
262-
*bytesLeft -= m_page0_len; // can be FLAC or title
263-
return FLAC_PARSE_OGG_DONE;
264-
}
265-
log_i("sync code not found");
266-
return ERR_FLAC_SYNC_CODE_NOT_FOUND;
267-
}
268269
return flacDecodeFrame(inbuf, bytesLeft, outbuf);
269270
}
270271

@@ -580,7 +581,7 @@ void restoreLinearPrediction(uint8_t ch, uint8_t shift) {
580581
}
581582
}
582583
//----------------------------------------------------------------------------------------------------------------------
583-
int specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact){
584+
int FLAC_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact){
584585
int result; // seek for str in buffer or in header up to baselen, not nullterninated
585586
if (strlen(str) > baselen) return -1; // if exact == true seekstr in buffer must have "\0" at the end
586587
for (int i = 0; i < baselen - strlen(str); i++){

src/flac_decoder/flac_decoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ int FLACFindSyncWord(unsigned char *buf, int nBytes);
147147
boolean FLACFindMagicWord(unsigned char* buf, int nBytes);
148148
boolean FLACFindStreamTitle(unsigned char* buf, int nBytes);
149149
char* FLACgetStreamTitle();
150-
int FLACparseOggHeader(unsigned char *buf);
150+
int FLACparseOGG(uint8_t *inbuf, int *bytesLeft);
151151
bool FLACDecoder_AllocateBuffers(void);
152152
void FLACDecoder_ClearBuffer();
153153
void FLACDecoder_FreeBuffers();
@@ -172,5 +172,5 @@ int8_t decodeFixedPredictionSubframe(uint8_t predOrder, uint8_t sampleDepth, u
172172
int8_t decodeLinearPredictiveCodingSubframe(int lpcOrder, int sampleDepth, uint8_t ch);
173173
int8_t decodeResiduals(uint8_t warmup, uint8_t ch);
174174
void restoreLinearPrediction(uint8_t ch, uint8_t shift);
175-
int specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false);
175+
int FLAC_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false);
176176

0 commit comments

Comments
 (0)