/* * L3_compress: * ------------ */ void L3_compress(void) { int frames_processed; int ch; int i; int gr; static short buffer[2][1152]; short *buffer_window[2]; int remainder; int bytes_per_frame; int lag; int mean_bits; int sideinfo_len; static int l3_enc[2][2][samp_per_frame2]; static int l3_sb_sample[2][3][18][SBLIMIT]; static int mdct_freq[2][2][samp_per_frame2]; static L3_side_info_t side_info; if(config.mpeg.type == MPEG1) { config.mpeg.granules = 2; config.mpeg.samples_per_frame = samp_per_frame; config.mpeg.resv_limit = ((1<<9)-1)<<3; sideinfo_len = (config.mpeg.channels == 1) ? 168 : 288; } else /* mpeg 2/2.5 */ { config.mpeg.granules = 1; config.mpeg.samples_per_frame = samp_per_frame2; config.mpeg.resv_limit = ((1<<8)-1)<<3; sideinfo_len = (config.mpeg.channels == 1) ? 104 : 168; } scalefac_band_long = sfBandIndex[config.mpeg.type][config.mpeg.samplerate_index]; #ifdef NO_RESERVOIR config.mpeg.resv_limit = 0; #endif { /* find number of whole bytes per frame and the remainder */ int x = config.mpeg.samples_per_frame * config.mpeg.bitr * (1000/8); bytes_per_frame = x / config.wave.samplerate; remainder = x % config.wave.samplerate; } config.mpeg.total_frames = /* round up */ (config.wave.total_samples + config.mpeg.samples_per_frame - 1) / config.mpeg.samples_per_frame; printf("%d frames\n",config.mpeg.total_frames); frames_processed = lag = 0; open_bit_stream(config.outfile); while(wave_get(buffer)) { frames_processed++; if(((frames_processed & 7)==0) || (frames_processed >= config.mpeg.total_frames)) printf("\015[%d] %d%%", frames_processed,(frames_processed*100)/config.mpeg.total_frames); buffer_window[0] = buffer[0]; buffer_window[1] = buffer[1]; /* sort out padding */ config.mpeg.padding = (lag += remainder) >= config.wave.samplerate; if (config.mpeg.padding) lag -= config.wave.samplerate; config.mpeg.bits_per_frame = 8*(bytes_per_frame + config.mpeg.padding); /* bits per channel per granule */ mean_bits = (config.mpeg.bits_per_frame - sideinfo_len) >> (config.mpeg.granules + config.mpeg.channels - 2); /* polyphase filtering */ for(gr=0; gr<config.mpeg.granules; gr++) for(ch=0; ch<config.mpeg.channels; ch++) for(i=0;i<18;i++) L3_window_filter_subband(&buffer_window[ch], &l3_sb_sample[ch][gr+1][i][0] ,ch); /* apply mdct to the polyphase output */ L3_mdct_sub(l3_sb_sample, mdct_freq); /* bit and noise allocation */ L3_iteration_loop(mdct_freq, &side_info, l3_enc, mean_bits); /* write the frame to the bitstream */ L3_format_bitstream(l3_enc, &side_info); } close_bit_stream(); }
/*! Compress a given smplFrame at a given bitRate * * \param smplFrame a buffer containing samples to be compressed to layer3 * \param cfg pointer to an initialized config_t structure * \param bitRate bitRate to encode sample at * \return status : * - 0 => Success * < 0 => any error code */ int kb_mp3_Compress( unsigned short *smplFrame, unsigned long smplNmbr, struct config_t *cfg, int bitRate, char *filePath ) { int frames_processed; int channel; int i; int gr; double pe[2][2]; short *buffer_window[2]; double avg_slots_per_frame; double frac_slots_per_frame; long whole_slots_per_frame; double slot_lag; int mean_bits; int sideinfo_len; static short buffer[2][samp_per_frame]; static int l3_enc[2][2][samp_per_frame2]; static long l3_sb_sample[2][3][18][SBLIMIT]; static long mdct_freq[2][2][samp_per_frame2]; static L3_psy_ratio_t ratio; static L3_side_info_t side_info; static L3_scalefac_t scalefactor; static bitstream_t bs; if(cfg) cfg->mpeg.bitr = bitRate; /* Override the default bitRate */ if(filePath && cfg) cfg->outfile = filePath; else return -1; /* outfile related error */ open_bit_stream_w(&bs, cfg->outfile, BUFFER_SIZE); memset((char *)&side_info,0,sizeof(L3_side_info_t)); /* some mpeg layer 3 initialisations */ L3_subband_initialise(); L3_mdct_initialise(); L3_loop_initialise(); cfg->mpeg.samples_per_frame = samp_per_frame; cfg->mpeg.total_frames = smplNmbr /cfg->mpeg.samples_per_frame; cfg->mpeg.bits_per_slot = 8; frames_processed = 0; sideinfo_len = 288; /* Stereo assumed */ /* (config.wave.channels==1) ? 168 : 288; */ /* Figure average number of 'slots' per frame. */ avg_slots_per_frame = ((double)cfg->mpeg.samples_per_frame / ((double)smplNmbr/1000)) * ((double)cfg->mpeg.bitr / (double)cfg->mpeg.bits_per_slot); whole_slots_per_frame = (int)avg_slots_per_frame; frac_slots_per_frame = avg_slots_per_frame - (double)whole_slots_per_frame; slot_lag = -frac_slots_per_frame; if(frac_slots_per_frame==0) cfg->mpeg.padding = 0; //while(wave_get(buffer)) for( i = 0; i < smplNmbr; i++) { kb_mp3_updStatus(cfg, ++frames_processed); buffer_window[0] = buffer[0]; buffer_window[1] = buffer[1]; if(frac_slots_per_frame) if(slot_lag>(frac_slots_per_frame-1.0)) { /* No padding for this frame */ slot_lag -= frac_slots_per_frame; cfg->mpeg.padding = 0; } else { /* Padding for this frame */ slot_lag += (1-frac_slots_per_frame); cfg->mpeg.padding = 1; } cfg->mpeg.bits_per_frame = 8*(whole_slots_per_frame + cfg->mpeg.padding); mean_bits = (cfg->mpeg.bits_per_frame - sideinfo_len)>>1; /* polyphase filtering */ for(gr=0;gr<2;gr++) for(channel=2; channel-- ; ) /* assumed stereo */ /* for(channel=cfg->wave.channels; channel--; ) */ for(i=0;i<18;i++) L3_window_filter_subband(&buffer_window[channel], &l3_sb_sample[channel][gr+1][i][0] ,channel); /* apply mdct to the polyphase output */ L3_mdct_sub(cfg, l3_sb_sample, mdct_freq); /* bit and noise allocation */ L3_iteration_loop(cfg, pe,mdct_freq,&ratio,&side_info, l3_enc, mean_bits,&scalefactor); /* write the frame to the bitstream */ L3_format_bitstream(cfg, l3_enc,&side_info,&scalefactor, &bs,mdct_freq,NULL,0); } close_bit_stream(&bs); }
/* * L3_compress: * ------------ */ void L3_compress(config_t *config) { int frames_processed; int channel; int i; int gr; double pe[2][2]; short *buffer_window[2]; double avg_slots_per_frame; double frac_slots_per_frame; long whole_slots_per_frame; double slot_lag; int mean_bits; int sideinfo_len; static short buffer[2][samp_per_frame]; static int l3_enc[2][2][samp_per_frame2]; static long l3_sb_sample[2][3][18][SBLIMIT]; static long mdct_freq[2][2][samp_per_frame2]; static L3_psy_ratio_t ratio; static L3_side_info_t side_info; static L3_scalefac_t scalefactor; static bitstream_t bs; open_bit_stream_w(&bs, config->outfile, BUFFER_SIZE); memset((char *)&side_info,0,sizeof(L3_side_info_t)); L3_subband_initialise(); L3_mdct_initialise(); L3_loop_initialise(); config->mpeg.samples_per_frame = samp_per_frame; config->mpeg.total_frames = config->wave.total_samples/config->mpeg.samples_per_frame; config->mpeg.bits_per_slot = 8; frames_processed = 0; sideinfo_len = (config->wave.channels==1) ? 168 : 288; /* Figure average number of 'slots' per frame. */ avg_slots_per_frame = ((double)config->mpeg.samples_per_frame / ((double)config->wave.samplerate/1000)) * ((double)config->mpeg.bitr / (double)config->mpeg.bits_per_slot); whole_slots_per_frame = (int)avg_slots_per_frame; frac_slots_per_frame = avg_slots_per_frame - (double)whole_slots_per_frame; slot_lag = -frac_slots_per_frame; if(frac_slots_per_frame==0) config->mpeg.padding = 0; while(config->get_pcm(buffer, config)) { update_status(++frames_processed, config); buffer_window[0] = buffer[0]; buffer_window[1] = buffer[1]; if(frac_slots_per_frame) { if(slot_lag>(frac_slots_per_frame-1.0)) { /* No padding for this frame */ slot_lag -= frac_slots_per_frame; config->mpeg.padding = 0; } else { /* Padding for this frame */ slot_lag += (1-frac_slots_per_frame); config->mpeg.padding = 1; } } config->mpeg.bits_per_frame = 8*(whole_slots_per_frame + config->mpeg.padding); mean_bits = (config->mpeg.bits_per_frame - sideinfo_len)>>1; /* polyphase filtering */ for(gr=0;gr<2;gr++) for(channel=config->wave.channels; channel--; ) for(i=0;i<18;i++) L3_window_filter_subband(&buffer_window[channel], &l3_sb_sample[channel][gr+1][i][0] ,channel); /* apply mdct to the polyphase output */ L3_mdct_sub(l3_sb_sample, mdct_freq, config); /* bit and noise allocation */ L3_iteration_loop(pe,mdct_freq,&ratio,&side_info, l3_enc, mean_bits,&scalefactor, config); /* write the frame to the bitstream */ L3_format_bitstream(l3_enc,&side_info,&scalefactor, &bs,mdct_freq,NULL,0, config); } close_bit_stream(&bs); }