📄 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 + -