www.pudn.com > shine.zip > layer3.c


//    Shine is an MP3 encoder 
//    Copyright (C) 1999-2000  Gabriel Bouvigne 
// 
//    This library is free software; you can redistribute it and/or 
//    modify it under the terms of the GNU Library General Public 
//    License as published by the Free Software Foundation; either 
//    version 2 of the License, or (at your option) any later version. 
// 
//    This library is distributed in the hope that it will be useful, 
//    but WITHOUT ANY WARRANTY; without even the implied warranty of 
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
//    Library General Public License for more details. 
 
 
#include  
#include  
 
#include "types.h" 
#include "wave.h" 
#include "error.h" 
 
#include "layer3.h" 
#include "l3subband.h" 
#include "l3mdct.h" 
#include "l3loop.h" 
#include "l3bitstream.h" 
#include "bitstream.h" 
 
static void update_status(int frames_processed) 
{ 
    printf("\015[Frame %6d of %6ld] (%2.2f%%)",  
            frames_processed,config.mpeg.total_frames, 
            (double)((double)frames_processed/config.mpeg.total_frames)*100);  
    fflush(stdout); 
} 
 
 
void compress() 
{ 
    int             frames_processed; 
    static short    buffer[2][samp_per_frame]; 
    int             channel; 
 
    int             i; 
    int             gr; 
    short           sam[2][1344]; 
    double           snr32[32]; 
    side_info_t  side_info; 
    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; 
    bitstream_t     bs; 
  
    double          avg_slots_per_frame; 
    double          frac_slots_per_frame; 
    long            whole_slots_per_frame; 
    double          slot_lag; 
     
    int             mean_bits; 
    unsigned long   sent_bits  = 0; 
    unsigned long   frame_bits = 0; 
    int             sideinfo_len; 
 
    open_bit_stream_w(&bs, config.outfile, BUFFER_SIZE); 
     
    memset((char*)snr32,0,sizeof(snr32)); 
    memset((char *)sam,0,sizeof(sam)); 
    memset((char *)&side_info,0,sizeof(side_info_t)); 
 
    subband_initialise(); 
    mdct_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 = 32; 
  
	if(config.wave.channels==1) 
			sideinfo_len += 136; 
        else 
			sideinfo_len += 256; 
 
/* 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(wave_get(buffer)) 
    { 
        if ((frames_processed++)%7==0) 
			update_status(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; 
                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++) 
                { 
                    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, &side_info); 
 
 
/* bit and noise allocation */ 
        iteration_loop(mdct_freq,&side_info, 
                          enc, mean_bits,&scalefactor); 
 
 
/* write the frame to the bitstream */ 
 
       format_bitstream(enc,&side_info,&scalefactor,  
                           &bs,mdct_freq); 
 
       frame_bits = sstell(&bs) - sent_bits; 
 
       sent_bits += frame_bits; 
    }     
 
 
}