FastLED 3.9.15
Loading...
Searching...
No Matches

◆ MP3Decode()

int fl::third_party::MP3Decode ( HMP3Decoder hMP3Decoder,
const unsigned char ** inbuf,
size_t * bytesLeft,
short * outbuf,
int useSize )

Definition at line 292 of file mp3dec.hpp.

293{
294 int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes;
295 int prevBitOffset, sfBlockBits, huffBlockBits;
296 const unsigned char *mainPtr;
297 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
298
299 #ifdef PROFILE
300 long time;
301 #endif
302
303 if (!mp3DecInfo)
305
306 /* unpack frame header */
307 fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf);
308 if (fhBytes < 0)
309 return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */
310 *inbuf += fhBytes;
311
312#ifdef PROFILE
313 time = systime_get();
314#endif
315 /* unpack side info */
316 siBytes = UnpackSideInfo(mp3DecInfo, *inbuf);
317 if (siBytes < 0) {
318 MP3ClearBadFrame(mp3DecInfo, outbuf);
320 }
321 *inbuf += siBytes;
322 *bytesLeft -= (fhBytes + siBytes);
323#ifdef PROFILE
324 time = systime_get() - time;
325 printf("UnpackSideInfo: %i ms\n", time);
326#endif
327
328
329 /* if free mode, need to calculate bitrate and nSlots manually, based on frame size */
330 if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) {
331 if (!mp3DecInfo->freeBitrateFlag) {
332 /* first time through, need to scan for next sync word and figure out frame size */
333 mp3DecInfo->freeBitrateFlag = 1;
334 mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft);
335 if (mp3DecInfo->freeBitrateSlots < 0) {
336 MP3ClearBadFrame(mp3DecInfo, outbuf);
338 }
339 freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes;
340 mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps);
341 }
342 mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo); /* add pad byte, if required */
343 }
344
345 /* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119)
346 * - calling function assembles "self-contained" MP3 frames by shifting any main_data
347 * from the bit reservoir (in previous frames) to AFTER the sync word and side info
348 * - calling function should set mainDataBegin to 0, and tell us exactly how large this
349 * frame is (in bytesLeft)
350 */
351 if (useSize) {
352 mp3DecInfo->nSlots = *bytesLeft;
353 if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) {
354 /* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */
355 MP3ClearBadFrame(mp3DecInfo, outbuf);
357 }
358
359 /* can operate in-place on reformatted frames */
360 mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots;
361 mainPtr = *inbuf;
362 *inbuf += mp3DecInfo->nSlots;
363 *bytesLeft -= (mp3DecInfo->nSlots);
364 } else {
365 /* out of data - assume last or truncated frame */
366 if (mp3DecInfo->nSlots > (int)*bytesLeft) {
367 MP3ClearBadFrame(mp3DecInfo, outbuf);
369 }
370
371#ifdef PROFILE
372 time = systime_get();
373#endif
374 /* fill main data buffer with enough new data for this frame */
375 if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) {
376 /* adequate "old" main data available (i.e. bit reservoir) */
377 ::fl::memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, static_cast<fl::size>(mp3DecInfo->mainDataBegin));
378 ::fl::memcopy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, static_cast<fl::size>(mp3DecInfo->nSlots));
379
380 mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots;
381 *inbuf += mp3DecInfo->nSlots;
382 *bytesLeft -= (mp3DecInfo->nSlots);
383 mainPtr = mp3DecInfo->mainBuf;
384 } else {
385 /* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */
386 ::fl::memcopy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, static_cast<fl::size>(mp3DecInfo->nSlots));
387 mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots;
388 *inbuf += mp3DecInfo->nSlots;
389 *bytesLeft -= (mp3DecInfo->nSlots);
390 MP3ClearBadFrame(mp3DecInfo, outbuf);
392 }
393#ifdef PROFILE
394 time = systime_get() - time;
395 printf("data buffer filling: %i ms\n", time);
396#endif
397
398 }
399 bitOffset = 0;
400 mainBits = mp3DecInfo->mainDataBytes * 8;
401
402 /* decode one complete frame */
403 for (gr = 0; gr < mp3DecInfo->nGrans; gr++) {
404 for (ch = 0; ch < mp3DecInfo->nChans; ch++) {
405
406 #ifdef PROFILE
407 time = systime_get();
408 #endif
409 /* unpack scale factors and compute size of scale factor block */
410 prevBitOffset = bitOffset;
411 offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch);
412 #ifdef PROFILE
413 time = systime_get() - time;
414 printf("UnpackScaleFactors: %i ms\n", time);
415 #endif
416
417 sfBlockBits = 8*offset - prevBitOffset + bitOffset;
418 huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits;
419 mainPtr += offset;
420 mainBits -= sfBlockBits;
421
422 if (offset < 0 || mainBits < huffBlockBits) {
423 MP3ClearBadFrame(mp3DecInfo, outbuf);
425 }
426
427 #ifdef PROFILE
428 time = systime_get();
429 #endif
430 /* decode Huffman code words */
431 prevBitOffset = bitOffset;
432 offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch);
433 if (offset < 0) {
434 MP3ClearBadFrame(mp3DecInfo, outbuf);
436 }
437 #ifdef PROFILE
438 time = systime_get() - time;
439 printf("Huffman: %i ms\n", time);
440 #endif
441
442 mainPtr += offset;
443 mainBits -= (8*offset - prevBitOffset + bitOffset);
444 }
445
446 #ifdef PROFILE
447 time = systime_get();
448 #endif
449 /* dequantize coefficients, decode stereo, reorder short blocks */
450 if (Dequantize(mp3DecInfo, gr) < 0) {
451 MP3ClearBadFrame(mp3DecInfo, outbuf);
453 }
454 #ifdef PROFILE
455 time = systime_get() - time;
456 printf("Dequantize: %i ms\n", time);
457 #endif
458
459 /* alias reduction, inverse MDCT, overlap-add, frequency inversion */
460 for (ch = 0; ch < mp3DecInfo->nChans; ch++)
461 {
462 #ifdef PROFILE
463 time = systime_get();
464 #endif
465 if (IMDCT(mp3DecInfo, gr, ch) < 0) {
466 MP3ClearBadFrame(mp3DecInfo, outbuf);
467 return ERR_MP3_INVALID_IMDCT;
468 }
469 #ifdef PROFILE
470 time = systime_get() - time;
471 printf("IMDCT: %i ms\n", time);
472 #endif
473 }
474
475 #ifdef PROFILE
476 time = systime_get();
477 #endif
478 /* subband transform - if stereo, interleaves pcm LRLRLR */
479 if (Subband(mp3DecInfo, outbuf + gr*mp3DecInfo->nGranSamps*mp3DecInfo->nChans) < 0) {
480 MP3ClearBadFrame(mp3DecInfo, outbuf);
482 }
483 #ifdef PROFILE
484 time = systime_get() - time;
485 printf("Subband: %i ms\n", time);
486 #endif
487
488 }
489 return ERR_MP3_NONE;
490}
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
struct _MP3DecInfo MP3DecInfo
int part23Length[MAX_NGRAN][MAX_NCHAN]
Definition mp3common.h:96
int mainDataBegin
Definition mp3common.h:93
int mainDataBytes
Definition mp3common.h:94
int freeBitrateSlots
Definition mp3common.h:81
unsigned char mainBuf[MAINBUF_SIZE]
Definition mp3common.h:77
int freeBitrateFlag
Definition mp3common.h:80
int nGranSamps
Definition mp3common.h:88
@ ERR_MP3_INVALID_SCALEFACT
Definition mp3dec.h:99
@ ERR_MP3_INVALID_IMDCT
Definition mp3dec.h:102
@ ERR_MP3_NONE
Definition mp3dec.h:91
@ ERR_MP3_INDATA_UNDERFLOW
Definition mp3dec.h:92
@ ERR_MP3_MAINDATA_UNDERFLOW
Definition mp3dec.h:93
@ ERR_MP3_INVALID_HUFFCODES
Definition mp3dec.h:100
@ ERR_MP3_INVALID_FRAMEHEADER
Definition mp3dec.h:97
@ ERR_MP3_INVALID_SUBBAND
Definition mp3dec.h:103
@ ERR_MP3_INVALID_DEQUANTIZE
Definition mp3dec.h:101
@ ERR_MP3_FREE_BITRATE_SYNC
Definition mp3dec.h:94
@ ERR_MP3_INVALID_SIDEINFO
Definition mp3dec.h:98
@ ERR_MP3_NULL_POINTER
Definition mp3dec.h:96
int Dequantize(MP3DecInfo *mp3DecInfo, int gr) FL_NOEXCEPT
Definition dequant.hpp:78
static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf) FL_NOEXCEPT
Definition mp3dec.hpp:260
int UnpackFrameHeader(MP3DecInfo *mp3DecInfo, const unsigned char *buf) FL_NOEXCEPT
int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, const unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch) FL_NOEXCEPT
Definition scalfact.hpp:357
static int MP3FindFreeSync(const unsigned char *buf, const unsigned char firstFH[4], int nBytes) FL_NOEXCEPT
Definition mp3dec.hpp:153
int UnpackSideInfo(MP3DecInfo *mp3DecInfo, const unsigned char *buf) FL_NOEXCEPT
int DecodeHuffman(MP3DecInfo *mp3DecInfo, const unsigned char *buf, int *bitOffset, int huffBlockBits, int gr, int ch) FL_NOEXCEPT
Definition huffman.hpp:385
int IMDCT(MP3DecInfo *mp3DecInfo, int gr, int ch) FL_NOEXCEPT
int Subband(MP3DecInfo *mp3DecInfo, short *pcmBuf) FL_NOEXCEPT
Definition subband.hpp:65
int CheckPadBit(MP3DecInfo *mp3DecInfo) FL_NOEXCEPT
fl::u64 time() FL_NOEXCEPT
Alias for millis64() - returns 64-bit millisecond time.
Definition chrono.h:346
void printf(const char *format, const Args &... args) FL_NOEXCEPT
Printf-like formatting function that prints directly to the platform output.
Definition stdio.h:635
void * memcopy(void *dest, const void *src, size_t n) FL_NOEXCEPT
Definition cstring.h:103
void * memmove(void *dest, const void *src, size_t n) FL_NOEXCEPT

References _MP3DecInfo::bitrate, CheckPadBit(), DecodeHuffman(), Dequantize(), ERR_MP3_FREE_BITRATE_SYNC, ERR_MP3_INDATA_UNDERFLOW, ERR_MP3_INVALID_DEQUANTIZE, ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_HUFFCODES, ERR_MP3_INVALID_IMDCT, ERR_MP3_INVALID_SCALEFACT, ERR_MP3_INVALID_SIDEINFO, ERR_MP3_INVALID_SUBBAND, ERR_MP3_MAINDATA_UNDERFLOW, ERR_MP3_NONE, ERR_MP3_NULL_POINTER, FL_NOEXCEPT, _MP3DecInfo::freeBitrateFlag, _MP3DecInfo::freeBitrateSlots, IMDCT(), _MP3DecInfo::mainBuf, _MP3DecInfo::mainDataBegin, _MP3DecInfo::mainDataBytes, fl::memcopy(), fl::memmove(), MP3ClearBadFrame(), MP3FindFreeSync(), _MP3DecInfo::nChans, _MP3DecInfo::nGrans, _MP3DecInfo::nGranSamps, _MP3DecInfo::nSlots, offset(), _MP3DecInfo::part23Length, fl::printf(), _MP3DecInfo::samprate, Subband(), fl::time(), UnpackFrameHeader(), UnpackScaleFactors(), and UnpackSideInfo().

Referenced by fl::third_party::Mp3HelixDecoder::decodeFrame().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: