📄 musicin.c
字号:
memset((char *) snr32, 0, sizeof(snr32));
memset((char *) sam, 0, sizeof(sam));
fr_ps.header = &info;
fr_ps.tab_num = -1; /* no table loaded */
fr_ps.alloc = NULL;
info.version = MPEG_AUDIO_ID; /* Default: MPEG-1 */
programName = argv[0];
if(argc==1) /* no command-line args */
obtain_parameters(&fr_ps, &model, &num_samples,
original_file_name, encoded_file_name);
else
parse_args(argc, argv, &fr_ps, &model, &num_samples,
original_file_name, encoded_file_name);
print_config(&fr_ps, &model,
original_file_name, encoded_file_name);
hdr_to_frps(&fr_ps);
stereo = fr_ps.stereo;
error_protection = info.error_protection;
if (info.lay == 1)
{ bitsPerSlot = 32; samplesPerFrame = 384; }
else
if ( info.lay == 2 )
{ bitsPerSlot = 8; samplesPerFrame = 1152; }
else
{ /* layer 3 */
bitsPerSlot = 8;
samplesPerFrame = info.version == 1 ? 1152 : 576;
/* Apologize for missing features */
if ( info.mode == MPG_MD_JOINT_STEREO )
{
fprintf( stderr, "Sorry, joint stereo not yet available for layer3\n" );
exit( 1 );
}
#if 0
if ( info.version != MPEG_AUDIO_ID )
{
fprintf( stderr, "Sorry, MPEG2-LSF not yet available for layer3\n" );
exit( 1 );
}
#endif
if ( model != 2 )
{
fprintf( stderr, "Sorry, psycho model 1 not available for layer3\n" );
exit( 1 );
}
}
/* Figure average number of 'slots' per frame. */
/* Bitrate means TOTAL for both channels, not per side. */
avg_slots_per_frame = ((double)samplesPerFrame /
s_freq[info.version][info.sampling_frequency]) *
((double)bitrate[info.version][info.lay-1][info.bitrate_index] /
(double)bitsPerSlot);
whole_SpF = (int) avg_slots_per_frame;
printf("slots/frame = %d\n",whole_SpF);
frac_SpF = avg_slots_per_frame - (double)whole_SpF;
slot_lag = -frac_SpF;
printf("frac SpF=%.3f, tot bitrate=%d kbps, s freq=%.1f kHz\n",
frac_SpF, bitrate[info.version][info.lay-1][info.bitrate_index],
s_freq[info.version][info.sampling_frequency]);
if (frac_SpF != 0)
printf("Fractional number of slots, padding required\n");
else info.padding = 0;
while ( get_audio(musicin, buffer, num_samples, stereo, &info) > 0 )
{
fprintf(stderr, "{%4lu}", frameNum++); fflush(stderr);
win_buf[0] = &buffer[0][0];
win_buf[1] = &buffer[1][0];
if (frac_SpF != 0) {
if (slot_lag > (frac_SpF-1.0) ) {
slot_lag -= frac_SpF;
extra_slot = 0;
info.padding = 0;
/* printf("No padding for this frame\n"); */
}
else {
extra_slot = 1;
info.padding = 1;
slot_lag += (1-frac_SpF);
/* printf("Padding for this frame\n"); */
}
}
adb = (whole_SpF+extra_slot) * bitsPerSlot;
switch (info.lay)
{
/***************************** Layer I **********************************/
case 1 :
for (j=0;j<SCALE_BLOCK;j++)
for (k=0;k<stereo;k++) {
window_subband(&win_buf[k], &(*win_que)[k][0], k);
filter_subband(&(*win_que)[k][0], &(*sb_sample)[k][0][j][0]);
}
I_scale_factor_calc(*sb_sample, scalar, stereo);
if(fr_ps.actual_mode == MPG_MD_JOINT_STEREO) {
I_combine_LR(*sb_sample, *j_sample);
I_scale_factor_calc(j_sample, &j_scale, 1);
}
put_scale(scalar, &fr_ps, max_sc);
if (model == 1) I_Psycho_One(buffer, max_sc, ltmin, &fr_ps);
else {
for (k=0;k<stereo;k++) {
psycho_anal(&buffer[k][0],&sam[k][0], k, info.lay, snr32,
(FLOAT)s_freq[info.version][info.sampling_frequency]*1000);
for (i=0;i<SBLIMIT;i++) ltmin[k][i] = (double) snr32[i];
}
}
I_main_bit_allocation(ltmin, bit_alloc, &adb, &fr_ps);
if (error_protection) I_CRC_calc(&fr_ps, bit_alloc, &crc);
encode_info(&fr_ps, &bs);
if (error_protection) encode_CRC(crc, &bs);
I_encode_bit_alloc(bit_alloc, &fr_ps, &bs);
I_encode_scale(scalar, bit_alloc, &fr_ps, &bs);
I_subband_quantization(scalar, *sb_sample, j_scale, *j_sample,
bit_alloc, *subband, &fr_ps);
I_sample_encoding(*subband, bit_alloc, &fr_ps, &bs);
for (i=0;i<adb;i++) put1bit(&bs, 0);
break;
/***************************** Layer 2 **********************************/
case 2 :
for (i=0;i<3;i++) for (j=0;j<SCALE_BLOCK;j++)
for (k=0;k<stereo;k++) {
window_subband(&win_buf[k], &(*win_que)[k][0], k);
filter_subband(&(*win_que)[k][0], &(*sb_sample)[k][i][j][0]);
}
II_scale_factor_calc(*sb_sample, scalar, stereo, fr_ps.sblimit);
pick_scale(scalar, &fr_ps, max_sc);
if(fr_ps.actual_mode == MPG_MD_JOINT_STEREO) {
II_combine_LR(*sb_sample, *j_sample, fr_ps.sblimit);
II_scale_factor_calc(j_sample, &j_scale, 1, fr_ps.sblimit);
} /* this way we calculate more mono than we need */
/* but it is cheap */
if (model == 1) II_Psycho_One(buffer, max_sc, ltmin, &fr_ps);
else {
for (k=0;k<stereo;k++) {
psycho_anal(&buffer[k][0],&sam[k][0], k,
info.lay, snr32,
(FLOAT)s_freq[info.version][info.sampling_frequency]*1000);
for (i=0;i<SBLIMIT;i++) ltmin[k][i] = (double) snr32[i];
}
}
II_transmission_pattern(scalar, scfsi, &fr_ps);
II_main_bit_allocation(ltmin, scfsi, bit_alloc, &adb, &fr_ps);
if (error_protection)
II_CRC_calc(&fr_ps, bit_alloc, scfsi, &crc);
encode_info(&fr_ps, &bs);
if (error_protection) encode_CRC(crc, &bs);
II_encode_bit_alloc(bit_alloc, &fr_ps, &bs);
II_encode_scale(bit_alloc, scfsi, scalar, &fr_ps, &bs);
II_subband_quantization(scalar, *sb_sample, j_scale,
*j_sample, bit_alloc, *subband, &fr_ps);
II_sample_encoding(*subband, bit_alloc, &fr_ps, &bs);
for (i=0;i<adb;i++) put1bit(&bs, 0);
break;
/***************************** Layer 3 **********************************/
case 3:
{
/*
large "auto" vars are static due to the Macintosh linker
*/
static double xr[2][2][576];
static double xr_dec[2][2][576];
static double pe[2][2];
static int l3_enc[2][2][576];
static III_psy_ratio ratio;
static III_side_info_t l3_side;
static III_scalefac_t scalefac;
int gr, mode_gr, ch;
int mean_bits, sideinfo_len;
int bitsPerFrame = 8 * whole_SpF + (info.padding * 8);
mode_gr = (info.version == 1) ? 2 : 1;
/*
determine the mean bitrate for main data
*/
sideinfo_len = 32;
if ( info.version == 1 )
{ /* MPEG 1 */
if ( stereo == 1 )
sideinfo_len += 136;
else
sideinfo_len += 256;
}
else
{ /* MPEG 2 */
if ( stereo == 1 )
sideinfo_len += 72;
else
sideinfo_len += 136;
}
if ( info.error_protection )
sideinfo_len += 16;
mean_bits = (bitsPerFrame - sideinfo_len) / mode_gr;
/*
psychoacoustic model
*/
for ( gr = 0; gr < mode_gr; gr++ )
for ( ch = 0; ch < stereo; ch++ )
{
L3psycho_anal( &buffer[ch][gr*576], &sam[ch][0], ch, info.lay,
snr32, s_freq[info.version][info.sampling_frequency] * 1000.0,
&ratio.l[gr][ch][0], &ratio.s[gr][ch][0],
&pe[gr][ch], &l3_side.gr[gr].ch[ch].tt );
}
/*
polyphase filtering
*/
for( gr = 0; gr < mode_gr; gr++ )
for ( ch = 0; ch < stereo; ch++ )
for ( j = 0; j < 18; j++ )
{
window_subband( &win_buf[ch], &(*win_que)[ch][0], ch );
filter_subband( &(*win_que)[ch][0], &(*l3_sb_sample)[ch][gr+1][j][0] );
}
/*
apply mdct to the polyphase outputs
*/
mdct_sub( l3_sb_sample, xr, stereo, &l3_side, mode_gr );
#if 0
delay( xr, stereo );
#endif
/*
bit and noise allocation
*/
iteration_loop( pe, xr, &ratio, &l3_side, l3_enc, mean_bits,
stereo, xr_dec, &scalefac, &fr_ps, 0, bitsPerFrame );
/*
write the frame to the bitstream
*/
III_format_bitstream( bitsPerFrame, &fr_ps, l3_enc, &l3_side, &scalefac, &bs,
xr, NULL, 0 );
}
break; /* end of layer 3 */
} /* end switch */
frameBits = sstell( &bs ) - sentBits;
if ( frameBits % bitsPerSlot ) /* a program failure */
fprintf( stderr, "Sent %ld bits = %ld slots plus %ld\n",
frameBits, frameBits/bitsPerSlot,
frameBits%bitsPerSlot );
sentBits += frameBits;
}
if ( info.lay == 3 )
III_FlushBitstream();
close_bit_stream_w( &bs );
printf("Avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
(FLOAT) sentBits / (frameNum * bitsPerSlot),
(FLOAT) sentBits / (frameNum * samplesPerFrame),
(FLOAT) sentBits / (frameNum * samplesPerFrame) *
s_freq[info.version][info.sampling_frequency]);
if (fclose(musicin) != 0){
printf("Could not close \"%s\".\n", original_file_name);
exit(2);
}
#ifdef MACINTOSH
set_mac_file_attr( encoded_file_name, VOL_REF_NUM, CREATOR_ENCODE,
FILETYPE_ENCODE );
#endif
printf("Encoding of \"%s\" with psychoacoustic model %d is finished\n",
original_file_name, model);
printf("The MPEG encoded output file name is \"%s\"\n",
encoded_file_name);
exit(0);
}
/************************************************************************
*
* usage
*
* PURPOSE: Writes command line syntax to the file specified by #stderr#
*
************************************************************************/
void usage() /* print syntax & exit */
{
fprintf(stderr,
"usage: %s queries for all arguments, or\n",
programName);
fprintf(stderr,
" %s [-l lay][-m mode][-p psy][-s sfrq][-b br][-d emp]\n",
programName);
fprintf(stderr,
" [-c][-o][-e] inputPCM [outBS]\n");
fprintf(stderr,"where\n");
fprintf(stderr," -l lay use layer <lay> coding (dflt %4u)\n",DFLT_LAY);
fprintf(stderr," -m mode channel mode : s/d/j/m (dflt %4c)\n",DFLT_MOD);
fprintf(stderr," -p psy psychoacoustic model 1/2 (dflt %4u)\n",DFLT_PSY);
fprintf(stderr," -s sfrq input smpl rate in kHz (dflt %4.1f)\n",DFLT_SFQ);
fprintf(stderr," -b br total bitrate in kbps (dflt highest)\n");
fprintf(stderr," -d emp de-emphasis n/5/c (dflt %4c)\n",DFLT_EMP);
fprintf(stderr," -c mark as copyright\n");
fprintf(stderr," -o mark as original\n");
fprintf(stderr," -e add error protection\n");
fprintf(stderr," inputPCM input PCM sound file (standard or AIFF)\n");
fprintf(stderr," outBS output bit stream of encoded audio (dflt inName+%s)\n",
DFLT_EXT);
exit(1);
}
/************************************************************************
*
* aiff_check
*
* PURPOSE: Checks AIFF header information to make sure it is valid.
* Exits if not.
*
************************************************************************/
void aiff_check( char *file_name, IFF_AIFF *pcm_aiff_data, int *version)
{
if (pcm_aiff_data->sampleType != IFF_ID_SSND) {
printf("Sound data is not PCM in \"%s\".\n", file_name);
exit(1);
}
if(SmpFrqIndex((long)pcm_aiff_data->sampleRate, version) < 0) {
printf("in \"%s\".\n", file_name);
exit(1);
}
if (pcm_aiff_data->sampleSize != sizeof(short) * BITS_IN_A_BYTE) {
printf("Sound data is not %d bits in \"%s\".\n",
sizeof(short) * BITS_IN_A_BYTE, file_name);
exit(1);
}
if (pcm_aiff_data->numChannels != MONO &&
pcm_aiff_data->numChannels != STEREO) {
printf("Sound data is not mono or stereo in \"%s\".\n", file_name);
exit(1);
}
if (pcm_aiff_data->blkAlgn.blockSize != 0) {
printf("Block size is not %d bytes in \"%s\".\n", 0, file_name);
exit(1);
}
if (pcm_aiff_data->blkAlgn.offset != 0) {
printf("Block offset is not %d bytes in \"%s\".\n", 0, file_name);
exit(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -