void mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int gr, k, ch; const sample_t *wk; wk = w0 + 286; /* thinking cache performance, ch->gr loop is better than gr->ch loop */ for (ch = 0; ch < cfg->channels_out; ch++) { for (gr = 0; gr < cfg->mode_gr; gr++) { int band; gr_info *const gi = &(gfc->l3_side.tt[gr][ch]); FLOAT *mdct_enc = gi->xr; FLOAT *samp = esv->sb_sample[ch][1 - gr][0]; for (k = 0; k < 18 / 2; k++) { window_subband(wk, samp); window_subband(wk + 32, samp + 32); samp += 64; wk += 64; /* * Compensate for inversion in the analysis filter */ for (band = 1; band < 32; band += 2) { samp[band - 32] *= -1; } } /* * Perform imdct of 18 previous subband samples * + 18 current subband samples */ for (band = 0; band < 32; band++, mdct_enc += 18) { int type = gi->block_type; FLOAT const *const band0 = esv->sb_sample[ch][gr][0] + order[band]; FLOAT *const band1 = esv->sb_sample[ch][1 - gr][0] + order[band]; if (gi->mixed_block_flag && band < 2) type = 0; if (esv->amp_filter[band] < 1e-12) { memset(mdct_enc, 0, 18 * sizeof(FLOAT)); } else { if (esv->amp_filter[band] < 1.0) { for (k = 0; k < 18; k++) band1[k * 32] *= esv->amp_filter[band]; } if (type == SHORT_TYPE) { for (k = -NS / 4; k < 0; k++) { FLOAT const w = win[SHORT_TYPE][k + 3]; mdct_enc[k * 3 + 9] = band0[(9 + k) * 32] * w - band0[(8 - k) * 32]; mdct_enc[k * 3 + 18] = band0[(14 - k) * 32] * w + band0[(15 + k) * 32]; mdct_enc[k * 3 + 10] = band0[(15 + k) * 32] * w - band0[(14 - k) * 32]; mdct_enc[k * 3 + 19] = band1[(2 - k) * 32] * w + band1[(3 + k) * 32]; mdct_enc[k * 3 + 11] = band1[(3 + k) * 32] * w - band1[(2 - k) * 32]; mdct_enc[k * 3 + 20] = band1[(8 - k) * 32] * w + band1[(9 + k) * 32]; } mdct_short(mdct_enc); } else { FLOAT work[18]; for (k = -NL / 4; k < 0; k++) { FLOAT a, b; a = win[type][k + 27] * band1[(k + 9) * 32] + win[type][k + 36] * band1[(8 - k) * 32]; b = win[type][k + 9] * band0[(k + 9) * 32] - win[type][k + 18] * band0[(8 - k) * 32]; work[k + 9] = a - b * tantab_l[k + 9]; work[k + 18] = a * tantab_l[k + 9] + b; } mdct_long(mdct_enc, work); } } /* * Perform aliasing reduction butterfly */ if (type != SHORT_TYPE && band != 0) { for (k = 7; k >= 0; --k) { FLOAT bu, bd; bu = mdct_enc[k] * ca[k] + mdct_enc[-1 - k] * cs[k]; bd = mdct_enc[k] * cs[k] - mdct_enc[-1 - k] * ca[k]; mdct_enc[-1 - k] = bu; mdct_enc[k] = bd; } } } } wk = w1 + 286; if (cfg->mode_gr == 1) { memcpy(esv->sb_sample[ch][0], esv->sb_sample[ch][1], 576 * sizeof(FLOAT)); } } }
int update_compress() { int count = 0; static short buffer[2][samp_per_frame]; int channel; int i; int gr; short *buffer_window[2]; double win_que[2][HAN_SIZE]; double sb_sample[2][3][18][SBLIMIT]; double mdct_freq[2][2][samp_per_frame2]; int enc[2][2][samp_per_frame2]; scalefac_t scalefactor; int mean_bits; unsigned long sent_bits = 0; unsigned long frame_bits = 0; while(wave_get(buffer)) { buffer_window[0] = buffer[0]; buffer_window[1] = buffer[1]; if(l3.frac_slots_per_frame) { if(l3.slot_lag>(l3.frac_slots_per_frame-1.0)) { /* No padding for this frame */ l3.slot_lag -= l3.frac_slots_per_frame; config.mpeg.padding = 0; } else { /* Padding for this frame */ l3.slot_lag += (1-l3.frac_slots_per_frame); config.mpeg.padding = 1; } } config.mpeg.bits_per_frame = 8*(l3.whole_slots_per_frame + config.mpeg.padding); mean_bits = (config.mpeg.bits_per_frame - l3.sideinfo_len)>>1; /* polyphase filtering */ for(gr=0;gr<2;gr++) for(channel=config.wave.channels; channel--; ) for(i=0;i<18;i++) { window_subband(&buffer_window[channel], &win_que[channel][0], channel); filter_subband(&win_que[channel][0], &sb_sample[channel][gr+1][i][0]); } /* apply mdct to the polyphase output */ mdct_sub(sb_sample, mdct_freq, &l3.side_info); /* bit and noise allocation */ iteration_loop(mdct_freq,&l3.side_info, enc, mean_bits,&scalefactor); /* write the frame to the bitstream */ format_bitstream(enc,&l3.side_info,&scalefactor, &l3_bs,mdct_freq); frame_bits = sstell(&l3_bs) - sent_bits; sent_bits += frame_bits; count ++; l3.frames_processed++; if (count==30) { return ((double)l3.frames_processed/config.mpeg.total_frames)*100; } } flush_bitstream(); return 100; //update_status(frames_processed); }
void mdct_sub48( lame_internal_flags *gfc, const sample_t *w0, const sample_t *w1, FLOAT8 mdct_freq[2][2][576] ) { int gr, k, ch; const sample_t *wk; wk = w0 + 286; /* thinking cache performance, ch->gr loop is better than gr->ch loop */ for (ch = 0; ch < gfc->channels_out; ch++) { for (gr = 0; gr < gfc->mode_gr; gr++) { int band; FLOAT8 *mdct_enc = &mdct_freq[gr][ch][0]; gr_info *gi = &(gfc->l3_side.gr[gr].ch[ch].tt); FLOAT8 *samp = gfc->sb_sample[ch][1 - gr][0]; for (k = 0; k < 18 / 2; k++) { window_subband(wk, samp); window_subband(wk + 32, samp + 32); samp += 64; wk += 64; /* * Compensate for inversion in the analysis filter */ for (band = 1; band < 32; band+=2) { samp[band-32] *= -1; } } /* apply filters on the polyphase filterbank outputs */ /* bands <= gfc->highpass_band will be zeroed out below */ /* bands >= gfc->lowpass_band will be zeroed out below */ if (gfc->filter_type==0) { for (band=gfc->highpass_start_band; band <= gfc->highpass_end_band; band++) { for (k=0; k<18; k++) gfc->sb_sample[ch][1-gr][k][order[band]]*=gfc->amp_highpass[band]; } for (band=gfc->lowpass_start_band; band <= gfc->lowpass_end_band; band++) { for (k=0; k<18; k++) gfc->sb_sample[ch][1-gr][k][order[band]]*=gfc->amp_lowpass[band]; } } /* * Perform imdct of 18 previous subband samples * + 18 current subband samples */ for (band = 0; band < 32; band++, mdct_enc += 18) { int type = gi->block_type; FLOAT8 *band0, *band1; band0 = gfc->sb_sample[ch][ gr][0] + order[band]; band1 = gfc->sb_sample[ch][1-gr][0] + order[band]; if (gi->mixed_block_flag && band < 2) type = 0; if (band >= gfc->lowpass_band || band <= gfc->highpass_band) { memset((char *)mdct_enc,0,18*sizeof(FLOAT8)); } else { if (type == SHORT_TYPE) { for (k = -NS/4; k < 0; k++) { FLOAT8 w = win[SHORT_TYPE][k+3]; mdct_enc[k*3+ 9] = band0[( 9+k)*32] * w - band0[( 8-k)*32]; mdct_enc[k*3+18] = band0[(14-k)*32] * w + band0[(15+k)*32]; mdct_enc[k*3+10] = band0[(15+k)*32] * w - band0[(14-k)*32]; mdct_enc[k*3+19] = band1[( 2-k)*32] * w + band1[( 3+k)*32]; mdct_enc[k*3+11] = band1[( 3+k)*32] * w - band1[( 2-k)*32]; mdct_enc[k*3+20] = band1[( 8-k)*32] * w + band1[( 9+k)*32]; } mdct_short(mdct_enc); } else { FLOAT8 work[18]; for (k = -NL/4; k < 0; k++) { FLOAT8 a, b; a = win[type][k+27] * band1[(k+9)*32] + win[type][k+36] * band1[(8-k)*32]; b = win[type][k+ 9] * band0[(k+9)*32] - win[type][k+18] * band0[(8-k)*32]; work[k+ 9] = a - b*tantab_l[k+9]; work[k+18] = a*tantab_l[k+9] + b; } mdct_long(mdct_enc, work); } } /* * Perform aliasing reduction butterfly */ if (type != SHORT_TYPE) { if (band == 0) continue; for (k = 7; k >= 0; --k) { FLOAT8 bu,bd; bu = mdct_enc[k] * ca[k] + mdct_enc[-1-k] * cs[k]; bd = mdct_enc[k] * cs[k] - mdct_enc[-1-k] * ca[k]; mdct_enc[-1-k] = bu; mdct_enc[k] = bd; } } } } wk = w1 + 286; if (gfc->mode_gr == 1) { memcpy(gfc->sb_sample[ch][0], gfc->sb_sample[ch][1], 576 * sizeof(FLOAT8)); } } }
int toolame_encode_frame( short buffer[2][1152], unsigned char *xpad_data, unsigned char *output_buffer, size_t output_buffer_size) { extern int minimum; if (encode_first_call) { hdr_to_frps(&frame); encode_first_call = 0; } const int nch = frame.nch; const int error_protection = header.error_protection; bs.output_buffer = output_buffer; bs.output_buffer_size = output_buffer_size; bs.output_buffer_written = 0; #ifdef REFERENCECODE short *win_buf[2] = {&buffer[0][0], &buffer[1][0]}; #endif int adb = available_bits (&header, &glopts); int lg_frame = adb / 8; if (header.dab_extension) { /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + (xpad_len ? xpad_len : FPAD_LENGTH) * 8; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (int ch = 0; ch < nch; ch++) { for (int sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (int ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (int ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (int ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) { /* copy the smr values and reuse them later */ for (int ch = 0; ch < nch; ch++) { for (int sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } } if (glopts.verbosity > 4) { smr_dump(smr, nch); } } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) { CRC_calc (&frame, bit_alloc, scfsi, &crc); } write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) { putbits (&bs, crc, 16); } write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) { CRC_calc (&frame, bit_alloc, scfsi, &crc); } encode_info (&frame, &bs); if (error_protection) { encode_CRC (crc, &bs); } encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (int i = 0; i < adb; i++) { put1bit (&bs, 0); } if (xpad_len) { assert(xpad_len > 2); // insert available X-PAD for (int i = header.dab_length - xpad_len; i < header.dab_length - FPAD_LENGTH; i++) { putbits (&bs, xpad_data[i], 8); } } for (int i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } if (xpad_len) { /* The F-PAD is also given us by mot-encoder */ putbits (&bs, xpad_data[header.dab_length - 2], 8); putbits (&bs, xpad_data[header.dab_length - 1], 8); } else { putbits (&bs, 0, 16); // FPAD is all-zero } return bs.output_buffer_written; }
int main (int argc, char **argv) { typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT]; SBS *sb_sample; typedef double JSBS[3][SCALE_BLOCK][SBLIMIT]; JSBS *j_sample; #ifdef REFERENCECODE typedef double IN[2][HAN_SIZE]; IN *win_que; #endif typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT]; SUB *subband; frame_info frame; frame_header header; char original_file_name[MAX_NAME_SIZE]; char encoded_file_name[MAX_NAME_SIZE]; short **win_buf; static short buffer[2][1152]; static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT]; static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT]; static double smr[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT]; // FLOAT snr32[32]; short sam[2][1344]; /* was [1056]; */ int model, nch, error_protection; static unsigned int crc; int sb, ch, adb; unsigned long frameBits, sentBits = 0; unsigned long num_samples; int lg_frame; int i; /* Keep track of peaks */ int peak_left = 0; int peak_right = 0; char* mot_file = NULL; char* icy_file = NULL; /* Used to keep the SNR values for the fast/quick psy models */ static FLOAT smrdef[2][32]; static int psycount = 0; extern int minimum; sb_sample = (SBS *) mem_alloc (sizeof (SBS), "sb_sample"); j_sample = (JSBS *) mem_alloc (sizeof (JSBS), "j_sample"); #ifdef REFERENCECODE win_que = (IN *) mem_alloc (sizeof (IN), "Win_que"); #endif subband = (SUB *) mem_alloc (sizeof (SUB), "subband"); win_buf = (short **) mem_alloc (sizeof (short *) * 2, "win_buf"); /* clear buffers */ memset ((char *) buffer, 0, sizeof (buffer)); memset ((char *) bit_alloc, 0, sizeof (bit_alloc)); memset ((char *) scalar, 0, sizeof (scalar)); memset ((char *) j_scale, 0, sizeof (j_scale)); memset ((char *) scfsi, 0, sizeof (scfsi)); memset ((char *) smr, 0, sizeof (smr)); memset ((char *) lgmin, 0, sizeof (lgmin)); memset ((char *) max_sc, 0, sizeof (max_sc)); //memset ((char *) snr32, 0, sizeof (snr32)); memset ((char *) sam, 0, sizeof (sam)); global_init (); header.extension = 0; frame.header = &header; frame.tab_num = -1; /* no table loaded */ frame.alloc = NULL; header.version = MPEG_AUDIO_ID; /* Default: MPEG-1 */ programName = argv[0]; if (argc == 1) /* no command-line args */ short_usage (); else parse_args (argc, argv, &frame, &model, &num_samples, original_file_name, encoded_file_name, &mot_file, &icy_file); print_config (&frame, &model, original_file_name, encoded_file_name); uint8_t* xpad_data = NULL; if (mot_file) { if (header.dab_length <= 0) { fprintf(stderr, "Invalid XPAD length specified\n"); return 1; } int err = xpad_init(mot_file, header.dab_length + 1); if (err == -1) { fprintf(stderr, "XPAD reader initialisation failed\n"); return 1; } xpad_data = malloc(header.dab_length + 1); } /* this will load the alloc tables and do some other stuff */ hdr_to_frps (&frame); nch = frame.nch; error_protection = header.error_protection; unsigned long samps_read; while ((samps_read = get_audio(&musicin, buffer, num_samples, nch, &header)) > 0) { /* Check if we have new PAD data */ int xpad_len = 0; if (mot_file) { xpad_len = xpad_read_len(xpad_data, header.dab_length + 1); if (xpad_len == -1) { fprintf(stderr, "Error reading XPAD data\n"); xpad_len = 0; } else if (xpad_len == 0) { // no PAD available } else if (xpad_len == header.dab_length + 1) { // everything OK xpad_len = xpad_data[header.dab_length]; } else { fprintf(stderr, "xpad length=%d\n", xpad_len); abort(); } } unsigned long j; for (j = 0; j < samps_read; j++) { peak_left = MAX(peak_left, buffer[0][j]); } for (j = 0; j < samps_read; j++) { peak_right = MAX(peak_right, buffer[1][j]); } // We can always set the zmq peaks, even if the output is not // used, it just writes some variables zmqoutput_set_peaks(peak_left, peak_right); if (glopts.verbosity > 1) if (++frameNum % 10 == 0) { fprintf(stderr, "[%4u", frameNum); if (mot_file) { fprintf(stderr, " %s", xpad_len > 0 ? "p" : " "); } if (glopts.show_level) { fprintf(stderr, " (%6d|%-6d) ", peak_left, peak_right); fprintf(stderr, "] [%6s|%-6s]\r", level(0, &peak_left), level(1, &peak_right) ); } else { fprintf(stderr, "]\r"); } } fflush(stderr); win_buf[0] = &buffer[0][0]; win_buf[1] = &buffer[1][0]; adb = available_bits (&header, &glopts); lg_frame = adb / 8; if (header.dab_extension) { /* in 24 kHz we always have 4 bytes */ if (header.sampling_frequency == 1) header.dab_extension = 4; /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + (xpad_len ? xpad_len : FPAD_LENGTH) * 8; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) /* copy the smr values and reuse them later */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } if (glopts.verbosity > 4) smr_dump(smr, nch); } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) putbits (&bs, crc, 16); write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); encode_info (&frame, &bs); if (error_protection) encode_CRC (crc, &bs); encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (i = 0; i < adb; i++) put1bit (&bs, 0); if (xpad_len) { assert(xpad_len > 2); // insert available X-PAD for (i = header.dab_length - xpad_len; i < header.dab_length - FPAD_LENGTH; i++) putbits (&bs, xpad_data[i], 8); } for (i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } if (xpad_len) { /* The F-PAD is also given us by mot-encoder */ putbits (&bs, xpad_data[header.dab_length - 2], 8); putbits (&bs, xpad_data[header.dab_length - 1], 8); } else { putbits (&bs, 0, 16); // FPAD is all-zero } #if defined(VLC_INPUT) if (glopts.input_select == INPUT_SELECT_VLC) { vlc_in_write_icy(); } #endif frameBits = sstell (&bs) - sentBits; if (frameBits % 8) { /* a program failure */ fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits / 8, frameBits % 8); fprintf (stderr, "If you are reading this, the program is broken\n"); fprintf (stderr, "Please report a bug.\n"); exit(1); } sentBits += frameBits; // Reset peak measurement peak_left = 0; peak_right = 0; } fprintf(stdout, "Main loop has quit with samps_read = %zu\n", samps_read); close_bit_stream_w (&bs); if ((glopts.verbosity > 1) && (glopts.vbr == TRUE)) { int i; #ifdef NEWENCODE extern int vbrstats_new[15]; #else extern int vbrstats[15]; #endif fprintf (stdout, "VBR stats:\n"); for (i = 1; i < 15; i++) fprintf (stdout, "%4i ", bitrate[header.version][i]); fprintf (stdout, "\n"); for (i = 1; i < 15; i++) #ifdef NEWENCODE fprintf (stdout,"%4i ",vbrstats_new[i]); #else fprintf (stdout, "%4i ", vbrstats[i]); #endif fprintf (stdout, "\n"); } fprintf (stderr, "Avg slots/frame = %.3f; b/smp = %.2f; bitrate = %.3f kbps\n", (FLOAT) sentBits / (frameNum * 8), (FLOAT) sentBits / (frameNum * 1152), (FLOAT) sentBits / (frameNum * 1152) * s_freq[header.version][header.sampling_frequency]); if (glopts.input_select == INPUT_SELECT_WAV) { if ( fclose (musicin.wav_input) != 0) { fprintf (stderr, "Could not close \"%s\".\n", original_file_name); exit (2); } } fprintf (stderr, "\nDone\n"); exit (0); }
int main (int argc, char **argv) { typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT]; SBS *sb_sample; typedef double JSBS[3][SCALE_BLOCK][SBLIMIT]; JSBS *j_sample; typedef double IN[2][HAN_SIZE]; IN *win_que; typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT]; SUB *subband; frame_info frame; frame_header header; char original_file_name[MAX_NAME_SIZE]; char encoded_file_name[MAX_NAME_SIZE]; short **win_buf; static short buffer[2][1152]; static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT]; static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT]; static double smr[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT]; // FLOAT snr32[32]; short sam[2][1344]; /* was [1056]; */ int model, nch, error_protection; static unsigned int crc; int sb, ch, adb; unsigned long frameBits, sentBits = 0; unsigned long num_samples; int lg_frame; int i; /* Used to keep the SNR values for the fast/quick psy models */ static FLOAT smrdef[2][32]; static int psycount = 0; extern int minimum; sb_sample = (SBS *) mem_alloc (sizeof (SBS), "sb_sample"); j_sample = (JSBS *) mem_alloc (sizeof (JSBS), "j_sample"); win_que = (IN *) mem_alloc (sizeof (IN), "Win_que"); subband = (SUB *) mem_alloc (sizeof (SUB), "subband"); win_buf = (short **) mem_alloc (sizeof (short *) * 2, "win_buf"); /* clear buffers */ memset ((char *) buffer, 0, sizeof (buffer)); memset ((char *) bit_alloc, 0, sizeof (bit_alloc)); memset ((char *) scalar, 0, sizeof (scalar)); memset ((char *) j_scale, 0, sizeof (j_scale)); memset ((char *) scfsi, 0, sizeof (scfsi)); memset ((char *) smr, 0, sizeof (smr)); memset ((char *) lgmin, 0, sizeof (lgmin)); memset ((char *) max_sc, 0, sizeof (max_sc)); //memset ((char *) snr32, 0, sizeof (snr32)); memset ((char *) sam, 0, sizeof (sam)); global_init (); header.extension = 0; frame.header = &header; frame.tab_num = -1; /* no table loaded */ frame.alloc = NULL; header.version = MPEG_AUDIO_ID; /* Default: MPEG-1 */ programName = argv[0]; if (argc == 1) /* no command-line args */ short_usage (); else parse_args (argc, argv, &frame, &model, &num_samples, original_file_name, encoded_file_name); print_config (&frame, &model, original_file_name, encoded_file_name); /* this will load the alloc tables and do some other stuff */ hdr_to_frps (&frame); nch = frame.nch; error_protection = header.error_protection; while (get_audio (musicin, buffer, num_samples, nch, &header) > 0) { if (glopts.verbosity > 1) if (++frameNum % 10 == 0) fprintf (stderr, "[%4u]\r", frameNum); fflush (stderr); win_buf[0] = &buffer[0][0]; win_buf[1] = &buffer[1][0]; adb = available_bits (&header, &glopts); lg_frame = adb / 8; if (header.dab_extension) { /* in 24 kHz we always have 4 bytes */ if (header.sampling_frequency == 1) header.dab_extension = 4; /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + header.dab_length * 8 + 16; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) /* copy the smr values and reuse them later */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } if (glopts.verbosity > 4) smr_dump(smr, nch); } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) putbits (&bs, crc, 16); write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); encode_info (&frame, &bs); if (error_protection) encode_CRC (crc, &bs); encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (i = 0; i < adb; i++) put1bit (&bs, 0); if (header.dab_extension) { /* Reserve some bytes for X-PAD in DAB mode */ putbits (&bs, 0, header.dab_length * 8); for (i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } putbits (&bs, 0, 16); } frameBits = sstell (&bs) - sentBits; if (frameBits % 8) { /* a program failure */ fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits / 8, frameBits % 8); fprintf (stderr, "If you are reading this, the program is broken\n"); fprintf (stderr, "email [mfc at NOTplanckenerg.com] without the NOT\n"); fprintf (stderr, "with the command line arguments and other info\n"); exit (0); } sentBits += frameBits; } close_bit_stream_w (&bs); if ((glopts.verbosity > 1) && (glopts.vbr == TRUE)) { int i; #ifdef NEWENCODE extern int vbrstats_new[15]; #else extern int vbrstats[15]; #endif fprintf (stdout, "VBR stats:\n"); for (i = 1; i < 15; i++) fprintf (stdout, "%4i ", bitrate[header.version][i]); fprintf (stdout, "\n"); for (i = 1; i < 15; i++) #ifdef NEWENCODE fprintf (stdout,"%4i ",vbrstats_new[i]); #else fprintf (stdout, "%4i ", vbrstats[i]); #endif fprintf (stdout, "\n"); } fprintf (stderr, "Avg slots/frame = %.3f; b/smp = %.2f; bitrate = %.3f kbps\n", (FLOAT) sentBits / (frameNum * 8), (FLOAT) sentBits / (frameNum * 1152), (FLOAT) sentBits / (frameNum * 1152) * s_freq[header.version][header.sampling_frequency]); if (fclose (musicin) != 0) { fprintf (stderr, "Could not close \"%s\".\n", original_file_name); exit (2); } fprintf (stderr, "\nDone\n"); exit (0); }