⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 musicin.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -