@@ -32,8 +32,8 @@ float m_compressionRatio = 0;
3232uint16_t m_rIndex=0 ;
3333uint64_t m_bitBuffer = 0 ;
3434uint8_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 ;
3737uint8_t m_page0_len = 0 ;
3838char *m_streamTitle= NULL ;
3939boolean m_newSt = false ;
@@ -132,7 +132,11 @@ void FLACDecoderReset(){ // set var to default
132132// ----------------------------------------------------------------------------------------------------------------------
133133int 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// ----------------------------------------------------------------------------------------------------------------------
146150boolean 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// ----------------------------------------------------------------------------------------------------------------------
164168boolean 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// ----------------------------------------------------------------------------------------------------------------------
234248int8_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++){
0 commit comments