📄 layer3.c
字号:
for (i = 0; i < 6; ++i) { z[i + 0] = 0; z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]); MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]); z[i + 12] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]); z[i + 18] = MAD_F_MLZ(hi, lo); z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]); z[i + 30] = 0; ++yptr; ++wptr; }}/* * NAME: III_overlap() * DESCRIPTION: perform overlap-add of windowed IMDCT outputs */staticvoid III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb){ unsigned int i;# if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + tmp1; overlap[i + 0] = output[i + 0 + 18]; tmp1 = overlap[i + 2]; sample[i + 1][sb] = output[i + 1 + 0] + tmp2; overlap[i + 1] = output[i + 1 + 18]; tmp2 = overlap[i + 3]; } sample[16][sb] = output[16 + 0] + tmp1; overlap[16] = output[16 + 18]; sample[17][sb] = output[17 + 0] + tmp2; overlap[17] = output[17 + 18]; }# elif 0 for (i = 0; i < 18; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0]; overlap[i + 0] = output[i + 0 + 18]; sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1]; overlap[i + 1] = output[i + 1 + 18]; }# else for (i = 0; i < 18; ++i) { sample[i][sb] = output[i + 0] + overlap[i]; overlap[i] = output[i + 18]; }# endif}/* * NAME: III_overlap_z() * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs */static __inlinevoid III_overlap_z(mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb){ unsigned int i;# if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = tmp1; overlap[i + 0] = 0; tmp1 = overlap[i + 2]; sample[i + 1][sb] = tmp2; overlap[i + 1] = 0; tmp2 = overlap[i + 3]; } sample[16][sb] = tmp1; overlap[16] = 0; sample[17][sb] = tmp2; overlap[17] = 0; }# else for (i = 0; i < 18; ++i) { sample[i][sb] = overlap[i]; overlap[i] = 0; }# endif}/* * NAME: III_freqinver() * DESCRIPTION: perform subband frequency inversion for odd sample lines */staticvoid III_freqinver(mad_fixed_t sample[18][32], unsigned int sb){ unsigned int i;# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = sample[1][sb]; tmp2 = sample[3][sb]; for (i = 1; i < 13; i += 4) { sample[i + 0][sb] = -tmp1; tmp1 = sample[i + 4][sb]; sample[i + 2][sb] = -tmp2; tmp2 = sample[i + 6][sb]; } sample[13][sb] = -tmp1; tmp1 = sample[17][sb]; sample[15][sb] = -tmp2; sample[17][sb] = -tmp1; }# else for (i = 1; i < 18; i += 2) sample[i][sb] = -sample[i][sb];# endif}/* * NAME: III_decode() * DESCRIPTION: decode frame main_data */staticenum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, struct sideinfo *si, unsigned int nch){ struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; { unsigned int sfreq; sfreq = header->samplerate; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreq *= 2; /* 48000 => 0, 44100 => 1, 32000 => 2, 24000 => 3, 22050 => 4, 16000 => 5 */ sfreqi = ((sfreq >> 7) & 0x000f) + ((sfreq >> 15) & 0x0001) - 8; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreqi += 3; } /* scalefactors, Huffman decoding, requantization */ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; unsigned int part2_length; sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } if (header->flags & MAD_FLAG_LSF_EXT) { part2_length = III_scalefactors_lsf(ptr, channel, ch == 0 ? 0 : &si->gr[1].ch[1], header->mode_extension); } else { part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], gr == 0 ? 0 : si->scfsi[ch]); } error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ for (ch = 0; ch < nch; ++ch) { struct channel const *channel = &granule->ch[ch]; mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; unsigned int sb, l, i, sblimit; mad_fixed_t output[36]; if (channel->block_type == 2) { III_reorder(xr[ch], channel, sfbwidth[ch]);# if !defined(OPT_STRICT) /* * According to ISO/IEC 11172-3, "Alias reduction is not applied for * granules with block_type == 2 (short block)." However, other * sources suggest alias reduction should indeed be performed on the * lower two subbands of mixed blocks. Most other implementations do * this, so by default we will too. */ if (channel->flags & mixed_block_flag) III_aliasreduce(xr[ch], 36);# endif } else III_aliasreduce(xr[ch], 576); l = 0; /* subbands 0-1 */ if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { unsigned int block_type; block_type = channel->block_type; if (channel->flags & mixed_block_flag) block_type = 0; /* long blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } else { /* short blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } III_freqinver(sample, 1); /* (nonzero) subbands 2-31 */ i = 576; while (i > 36 && xr[ch][i - 1] == 0) --i; sblimit = 32 - (576 - i) / 18; if (channel->block_type != 2) { /* long blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, channel->block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } else { /* short blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } /* remaining (zero) subbands */ for (sb = sblimit; sb < 32; ++sb) { III_overlap_z((*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } } return MAD_ERROR_NONE;}/* * NAME: layer->III() * DESCRIPTION: decode a single Layer III frame */int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame){ struct mad_header *header = &frame->header; unsigned int nch, priv_bitlen, next_md_begin = 0; unsigned int si_len, data_bitlen, md_len; unsigned int frame_space, frame_used, frame_free; struct mad_bitptr ptr; struct sideinfo si; enum mad_error error; int result = 0; /* allocate Layer III dynamic structures */ if (stream->main_data == 0) { stream->main_data = malloc(MAD_BUFFER_MDLEN); if (stream->main_data == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } if (frame->overlap == 0) { //frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t));
frame->overlap = malloc(2 * 32 * 18 * sizeof(mad_fixed_t));
memset(frame->overlap, 0, 2 * 32 * 18 * sizeof(mad_fixed_t)); if (frame->overlap == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } nch = MAD_NCHANNELS(header); si_len = (header->flags & MAD_FLAG_LSF_EXT) ? (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); /* check frame sanity */ if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < (signed int) si_len) { stream->error = MAD_ERROR_BADFRAMELEN; stream->md_len = 0; return -1; } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; result = -1; } } /* decode frame side information */ error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, &si, &data_bitlen, &priv_bitlen); if (error && result == 0) { stream->error = error; result = -1; } header->flags |= priv_bitlen; header->private_bits |= si.private_bits; /* find main_data of next frame */ { struct mad_bitptr peek; unsigned long header; mad_bit_init(&peek, stream->next_frame); header = mad_bit_read(&peek, 32); if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { if (!(header & 0x00010000L)) /* protection_bit */ mad_bit_skip(&peek, 16); /* crc_check */ next_md_begin = mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); } mad_bit_finish(&peek); } /* find main_data of this frame */ frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); if (next_md_begin > si.main_data_begin + frame_space) next_md_begin = 0; md_len = si.main_data_begin + frame_space - next_md_begin; frame_used = 0; if (si.main_data_begin == 0) { ptr = stream->ptr; stream->md_len = 0; frame_used = md_len; } else { if (si.main_data_begin > stream->md_len) { if (result == 0) { stream->error = MAD_ERROR_BADDATAPTR; result = -1; } } else { mad_bit_init(&ptr, *stream->main_data + stream->md_len - si.main_data_begin); if (md_len > si.main_data_begin) { assert(stream->md_len + md_len - si.main_data_begin <= MAD_BUFFER_MDLEN); memcpy(*stream->main_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.main_data_begin); stream->md_len += frame_used; } } } frame_free = frame_space - frame_used; /* decode main_data */ if (result == 0) { error = III_decode(&ptr, frame, &si, nch); if (error) { stream->error = error; result = -1; } /* designate ancillary bits */ stream->anc_ptr = ptr; stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; }# if 0 && defined(DEBUG) fprintf(stderr, "main_data_begin:%u, md_len:%u, frame_free:%u, " "data_bitlen:%u, anc_bitlen: %u\n", si.main_data_begin, md_len, frame_free, data_bitlen, stream->anc_bitlen);# endif /* preload main_data buffer with up to 511 bytes for next frame(s) */ if (frame_free >= next_md_begin) { memcpy(*stream->main_data, stream->next_frame - next_md_begin, next_md_begin); stream->md_len = next_md_begin; } else { if (md_len < si.main_data_begin) { unsigned int extra; extra = si.main_data_begin - md_len; if (extra + frame_free > next_md_begin) extra = next_md_begin - frame_free; if (extra < stream->md_len) { memmove(*stream->main_data, *stream->main_data + stream->md_len - extra, extra); stream->md_len = extra; } } else stream->md_len = 0; memcpy(*stream->main_data + stream->md_len, stream->next_frame - frame_free, frame_free); stream->md_len += frame_free; } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -