📄 mp3onlydec.c
字号:
/* * Decode the current MPEG Audio frame * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open * Output: pcm[] = 16-bit samples * pcm[0] is mono or left voice or channel 1 * pcm[1] is right or channel 2 * Return the number of samples * * Note: pcm[]'s be at least arrays of MPEGDEC_PCM_SIZE * number of samples can be 0 if current frame is skipped, in case * of error in crc or not enough data for decoding (layer III) * number of samples = 0 does not indicate end of stream ! */INT32 MPEGDEC_decode_frame(MPEGDEC_STREAM *mpds, INT16 *pcm[MPEGDEC_MAX_CHANNELS]){ MPA_STREAM *mps; INT32 count; int err; mps = (MPA_STREAM *) mpds->handle; mps->pcm[0] = pcm[0]; mps->pcm[1] = pcm[1]; if (mps->need_sync) { err = synchronize(mps); if (err) return(err); mps->need_sync = FALSE; } else { // FALSE: don't fail if MPEG Audio sync not at first err = MPEGDEC_read_header(mps, FALSE); if (err) return(err); } count = 0; switch (mps->header.layer) { case 3: count = MPEG3_decode_frame( mps ); break; case 1: case 2: default: break; } mps->frame++; return(count);}/****************************************************************************//* * Reset the decoder * Inputs: mpds = mpeg audio stream ptr returned by MPEGDEC_open */static int decoder_reset(MPEGDEC_STREAM *mpds){ int err; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; // Reset layer 3 decoder err = MPEG3_reset(mps); if (err) return(err); // Reset subband buffers & offsets err = MPEGSUB_reset(mps->mpegsub); if (err) return(err); err = MPEGIMDCT_reset(mps->mpegimdct); return(err);}/****************************************************************************//* * Seek into an MPEG Audio stream * Inputs: mpds = mpeg audio stream ptr returned by MPEGDEC_open * ms_time_position = absolute time position in ms */int MPEGDEC_seek(MPEGDEC_STREAM *mpds, UINT32 ms_time_position){ int err = -1; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; if (mps) { BITSTREAM *bs = mps->bitstream; REAL exact_seek; REAL slots; INT32 seek_pos; INT32 frame_bytes; INT32 frame; exact_seek = ((REAL)mps->bitrate * (REAL)ms_time_position) * 0.125; // Calculate nearest # of frames if (mps->header.layer == 1) frame_bytes = 48000; // 384/8*1000 else if ((mps->header.layer == 3) && (mps->header.ID == MPA_ID_2)) frame_bytes = 72000; else frame_bytes = 144000; slots = (REAL)(frame_bytes * mps->bitrate) / (REAL)mps->sfreq; frame = (INT32)(exact_seek / slots); // Calcultate seek pos in multiple of frames seek_pos = (INT32)((REAL)frame * slots); // Here sub 1 to be sure to get header seek_pos--; if (seek_pos < 0) seek_pos = 0; seek_pos += mps->bitstream_start_pos; err = BSTR_seek(bs, seek_pos); if (!err) { mps->frame = frame; decoder_reset(mpds); mps->need_sync = TRUE; } } return(err);}/****************************************************************************//* * Get the current time position of an MPEG Audio stream * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open * Output: ms_time_position = absolute time position in ms * Return 0 if Ok */int MPEGDEC_time(MPEGDEC_STREAM *mpds, UINT32 *ms_time_position){ int err = -1; MPA_STREAM *mps; if (!mpds) return(MPEGDEC_ERR_EOF); mps = (MPA_STREAM *) mpds->handle; if (mps) { INT32 frame_bits; if (mps->header.layer == 1) frame_bits = 384000; // 384*1000 else if((mps->header.layer == 3) && (mps->header.ID == MPA_ID_2)) frame_bits = 576000; else frame_bits = 1152000; *ms_time_position = (UINT32)(((REAL)mps->frame * (REAL)frame_bits ) / (REAL)mps->sfreq); err = 0; } return(err);}/****************************************************************************//* * Close an MPEG Audio stream * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open */void MPEGDEC_close(MPEGDEC_STREAM *mpds){ MPA_STREAM *mps; if (!mpds) return; mps = (MPA_STREAM *) mpds->handle; if (mps) { if (mps->mpegimdct) MPEGIMDCT_close(mps->mpegimdct); if (mps->mpegsub) MPEGSUB_close(mps->mpegsub); if (mps->huffman) HUFF_close(mps->huffman); if (mps->bitstream) BSTR_close(mps->bitstream); //ffree(mps); free(mps); } free(mpds);}/****************************************************************************//* * Open an MPEG Audio stream * Inputs: filename = stream filename to decode * ctrl = decoding controls * Return the mpeg audio stream ptr or NULL if failed to open stream */MPEGDEC_STREAM *MPEGDEC_open(char *filename, MPEGDEC_CTRL *ctrl){ MPEGDEC_STREAM *mpds; MPA_STREAM *mps; INT16 freq_div; INT16 quality; INT32 freq_max; INT32 buffer_size; MPEGDEC_LAYER *dec_lay; MPEGDEC_OUTPUT *dec_out; mpds = (MPEGDEC_STREAM *) malloc(sizeof(MPEGDEC_STREAM)); if (!mpds) return(NULL); memset(mpds, 0, sizeof(MPEGDEC_STREAM));// mps = (MPA_STREAM *) fmalloc(sizeof(MPA_STREAM)); mps = (MPA_STREAM *) malloc(sizeof(MPA_STREAM)); if (!mps) { MPEGDEC_close(mpds); return(NULL); } memset(mps, 0, sizeof(MPA_STREAM)); mpds->handle = mps; // Multiple of 4 bytes buffer_size = ctrl->stream_buffer_size & (INT32)(~3); if (buffer_size <= 0) buffer_size = MPEGDEC_BITSTREAM_BUFFER_SIZE; mps->bitstream = BSTR_open((BITSTREAM_ACCESS *)ctrl->bs_access, filename, buffer_size); if (!mps->bitstream) { MPEGDEC_close(mpds); return(NULL); } mps->stream_size = mps->bitstream->bitstream_size; mps->huffman = HUFF_open(); if(!mps->huffman) { MPEGDEC_close(mpds); return(NULL); } mps->current_table = -1;#if 0 /* * Don't skip start frame, bad for de-cryption... */ if (synchronize(mps)) { (void)MPEGDEC_close( mpds ); return NULL; } mps->need_sync = FALSE; mps->bitstream_start_pos = mps->header.header_pos; mps->stream_size = mps->bitstream->bitstream_size - mps->bitstream_start_pos;#else if (MPEGDEC_read_header(mps, (BOOL)ctrl->check_mpeg)){ MPEGDEC_close(mpds); return(NULL); }#endif if (mps->header.layer < 3) dec_lay = &ctrl->layer_1_2; else dec_lay = &ctrl->layer_3; mps->force_mono = dec_lay->force_mono; if (mps->stereo) dec_out = &dec_lay->stereo; else dec_out = &dec_lay->mono; freq_div = dec_out->freq_div; quality = dec_out->quality; freq_max = dec_out->freq_max; if (freq_div == 0) { INT32 freq = mps->sfreq; mps->freq_div = 1; do { if (freq <= freq_max) break; mps->freq_div <<= 1; freq >>= 1; } while (mps->freq_div < 4); } else { mps->freq_div = freq_div; } switch (mps->freq_div) { case 2: mps->sb_max = MPA_SBLIMIT/2; break; case 4: mps->sb_max = MPA_SBLIMIT/4; break; default: mps->freq_div = 1; mps->sb_max = MPA_SBLIMIT; break; } mps->quality = quality; if (mps->quality < MPEGDEC_QUALITY_LOW) mps->quality = MPEGDEC_QUALITY_LOW; else if (mps->quality > MPEGDEC_QUALITY_HIGH) mps->quality = MPEGDEC_QUALITY_HIGH; mps->mpegsub = MPEGSUB_open(mps->freq_div, mps->quality); if (!mps->mpegsub) { MPEGDEC_close(mpds); return(NULL); } mps->mpegimdct = MPEGIMDCT_open(); if (!mps->mpegimdct) { MPEGDEC_close(mpds); return(NULL); } fill_info(mpds); BSTR_seek(mps->bitstream, mps->bitstream_start_pos); decoder_reset(mpds); return(mpds);}/****************************************************************************/#ifdef USE_RC4static RC4_KEY MPEGDEC_rc4_key;/* * Set an RC4 key an MPEG Audio stream * Input: mpds = mpeg audio stream ptr returned by MPEGDEC_open * key = RC4 key data * len = length of RC4 key data */void MPEGDEC_setkey(MPEGDEC_STREAM *mpds, unsigned char *key, int len){ MPA_STREAM *mps; if (!mpds) return; mps = (MPA_STREAM *) mpds->handle; if (mps) { mps->keyp = (void *) &MPEGDEC_rc4_key; RC4_set_key(mps->keyp, len, key); }}#endif /* USE_RC4 *//****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -