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

📄 get_audio.c

📁 MP3编码的完整实现(源代码和使用例子都有)
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "util.h"
#include "get_audio.h"
#include "lame.h"

#if (defined LIBSNDFILE || defined LAMESNDFILE)

#ifdef _WIN32
	/* needed to set stdin to binary on windoze machines */
	#include <io.h>
#endif

static HFILE hSave;
static HFILE hWav = 0;//_lopen("C:\\test\\test.wav",0);
static FILE *musicin=NULL;  /* input file pointer */
static unsigned long num_samples;
static int samp_freq;
static int input_bitrate;
static int num_channels;
static int count_samples_carefully;

int read_samples_pcm(lame_global_flags *gfp,short sample_buffer[2304],int frame_size, int samples_to_read);
//int read_samples_mp3(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int num_chan);

//void lame_init_infile(lame_global_flags *gfp)
//{
//	/* open the input file */
//	count_samples_carefully=0;
//	
//	OpenSndFile(gfp,gfp->inPath,gfp->in_samplerate,gfp->num_channels);  
//	
//	
//	/* if GetSndSampleRate is non zero, use it to overwrite the default */
//	if (GetSndSampleRate()) gfp->in_samplerate=GetSndSampleRate();
//	if (GetSndChannels()) gfp->num_channels=GetSndChannels();
//	gfp->num_samples = GetSndSamples();


//void lame_close_infile(lame_global_flags *gfp)
//{
////  CloseSndFile(gfp);


/************************************************************************
*
* lame_readframe()
*
* PURPOSE:  reads a frame of audio data from a file to the buffer,
*   aligns the data for future processing, and separates the
*   left and right channels
*
*
************************************************************************/
int lame_readframe(lame_global_flags *gfp,short int Buffer[2][1152])
{
	int iread	 = 0;
	
	/* note: if input is gfp->stereo and output is mono, get_audio() 
	* will return  .5*(L+R) in channel 0,  and nothing in channel 1. */
	iread = get_audio(gfp,Buffer,gfp->stereo);
	
	/* check to see if we overestimated/underestimated totalframes */
	if (iread==0)  gfp->totalframes = Min(gfp->totalframes,gfp->frameNum+2);
	if (gfp->frameNum > (gfp->totalframes-1)) gfp->totalframes = gfp->frameNum;
	
	return iread;
}

/************************************************************************
*
* get_audio()
*
* PURPOSE:  reads a frame of audio data from a file to the buffer,
*   aligns the data for future processing, and separates the
*   left and right channels
*
*
************************************************************************/
int get_audio(lame_global_flags *gfp,short buffer[2][1152],int stereo)
{
	static unsigned long	 num_samples_read	= 0;
	int	framesize,samples_to_read		= 0;
	unsigned long remaining				= 0;
	short	insamp[2304]				= {0};
	int	samples_read				= 0;
	int	num_channels				= gfp->num_channels;
	int	j					= 0;
	
	if (gfp->frameNum==0) 
		{
		num_samples_read=0;
		num_samples= GetSndSamples();
		}

	framesize = gfp->mode_gr*576;
	
	samples_to_read = framesize;
	if (count_samples_carefully)
		{ 
		/* if this flag has been set, then we are carefull to read 
		* exactly num_samples and no more.  This is usefull for .wav and .aiff
		* files which have id3 or other tags at the end.  Note that if you
			* are using LIBSNDFILE, this is not necessary */
		remaining=num_samples-Min(num_samples,num_samples_read);
		if (remaining < (unsigned long)framesize) 
			samples_to_read = remaining;
		}
	
	
	if (gfp->input_format==sf_mp3)
		{
		/* decode an mp3 file for the input */
		// samples_read=read_samples_mp3(gfp,musicin,buffer,num_channels);
		}
	else	{
		samples_read = read_samples_pcm(gfp,insamp,num_channels*framesize,num_channels*samples_to_read);
		samples_read /=num_channels;
		
		for(j=0;j<framesize;j++)
			{
			buffer[0][j] = insamp[num_channels*j];
			if (num_channels==2) buffer[1][j] = insamp[2*j+1];
			else buffer[1][j]=0;
			}
		}
	
	/* dont count things in this case to avoid overflows */
	if (num_samples!=MAX_U_32_NUM) num_samples_read += samples_read;
	
	return(samples_read);
}
  
int GetSndBitrate(void)
{
	return input_bitrate;
}

//int read_samples_mp3(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int stereo)
//{
//#if (defined  AMIGA_MPEGA || defined HAVEMPGLIB) 
//  int j,out=0;
//
//
//  out=lame_decode_fromfile(musicin,mpg123pcm[0],mpg123pcm[1]);
//  /* out = -1:  error, probably EOF */
//  /* out = 0:   not possible with lame_decode_fromfile() */
//  /* out = number of output samples */
//
//  if (out==-1) {
//    for ( j = 0; j < 1152; j++ ) {
//      mpg123pcm[0][j] = 0;
//      mpg123pcm[1][j] = 0;
//    }
//  }
//
//
//#ifdef HAVEGTK
//  if (gfp->gtkflag) {
//    framesize=1152;
//    if (out==576) framesize=576;
//    
//    /* add a delay of framesize-DECDELAY, which will make the total delay
//     * exactly one frame, so we can sync MP3 output with WAV input */
//    
//    for ( ch = 0; ch < stereo; ch++ ) {
//      for ( j = 0; j < framesize-DECDELAY; j++ )
//	pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j+framesize];
//      for ( j = 0; j < framesize; j++ ) 
//	pinfo->pcmdata2[ch][j+framesize-DECDELAY] = mpg123pcm[ch][j];
//    }
//  
//  pinfo->frameNum123 = gfp->frameNum-1;
//  pinfo->frameNum = gfp->frameNum;
//  }
//#endif
//  if (out==-1) return 0;
//  else return out;
//#else
//  //fprintf(stderr,"Error: libmp3lame was not compiled with I/O support \n");
//  //exit(1);
//#endif
//}
#endif  /* LAMESNDFILE or LIBSNDFILE */

#ifdef LIBSNDFILE 
/*
** Copyright (C) 1999 Albert Faber
**  
 * 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.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */


#include <stdio.h>

/* External references */

static SNDFILE*	gs_pSndFileIn=NULL;
static SF_INFO	gs_wfInfo={0};


unsigned long GetSndSamples(void)
{
       return gs_wfInfo.samples;
}
int GetSndSampleRate(void)
{
	return gs_wfInfo.samplerate;
}

int GetSndChannels(void)
{
	return gs_wfInfo.channels;
}

//void CloseSndFile(lame_global_flags *gfp)
//{
//  if (gfp->input_format==sf_mp3) {
//#ifndef AMIGA_MPEGA
//    if (fclose(musicin) != 0){
//      fprintf(stderr, "Could not close audio input file\n");
//      exit(2);
//    }
//#endif
//  }else{
//	if (gs_pSndFileIn)
//	{
//		if (sf_close(gs_pSndFileIn) !=0)
//		{
//			fprintf(stderr, "Could not close sound file \n");
//			exit(2);
//		}
//	}
//  }
}


//FILE * OpenSndFile(lame_global_flags *gfp,const char* lpszFileName, int default_samp,
//int default_channels)
//{
//
//
//  input_bitrate=0;
//  if (gfp->input_format==sf_mp3) {
//#ifdef AMIGA_MPEGA
//    if (-1==lame_decode_initfile(lpszFileName,&num_channels,&samp_freq,&input_bitrate,&num_samples)) {
//      fprintf(stderr,"Error reading headers in mp3 input file %s.\n", lpszFileName);
//      exit(1);
//    }
//#endif
//#ifdef HAVEMPGLIB
//    if ((musicin = fopen(lpszFileName, "rb")) == NULL) {
//      fprintf(stderr, "Could not find \"%s\".\n", lpszFileName);
//      exit(1);
//    }
//    if (-1==lame_decode_initfile(musicin,&num_channels,&samp_freq,&input_bitrate,&num_samples)) {
//      fprintf(stderr,"Error reading headers in mp3 input file %s.\n", lpszFileName);
//      exit(1);
//    }
//#endif
//    gs_wfInfo.samples=num_samples;
//    gs_wfInfo.channels=num_channels;
//    gs_wfInfo.samplerate=samp_freq;
//
//  } else {
//
//    /* Try to open the sound file */
//    /* set some defaults incase input is raw PCM */
//    gs_wfInfo.seekable=(gfp->input_format!=sf_raw);  /* if user specified -r, set to not seekable */
//    gs_wfInfo.samplerate=default_samp;
//    gs_wfInfo.pcmbitwidth=16;
//    gs_wfInfo.channels=default_channels;
//    if (DetermineByteOrder()==order_littleEndian) {
//      if (gfp->swapbytes) gs_wfInfo.format=SF_FORMAT_RAW_BE;
//      else gs_wfInfo.format=SF_FORMAT_RAW_LE;
//    } else {
//      if (gfp->swapbytes) gs_wfInfo.format=SF_FORMAT_RAW_LE;
//      else gs_wfInfo.format=SF_FORMAT_RAW_BE;
//    }
//
//    gs_pSndFileIn=sf_open_read(lpszFileName,&gs_wfInfo);
//
//        /* Check result */
//	if (gs_pSndFileIn==NULL)
//	{
//	        sf_perror(gs_pSndFileIn);
//		fprintf(stderr, "Could not open sound file \"%s\".\n", lpszFileName);
//		exit(1);
//	}
//
//    if ((gs_wfInfo.format==SF_FORMAT_RAW_LE) || 
//	(gs_wfInfo.format==SF_FORMAT_RAW_BE)) 
//      gfp->input_format=sf_raw;
//
//#ifdef _DEBUG_SND_FILE
//	printf("\n\nSF_INFO structure\n");
//	printf("samplerate        :%d\n",gs_wfInfo.samplerate);
//	printf("samples           :%d\n",gs_wfInfo.samples);
//	printf("channels          :%d\n",gs_wfInfo.channels);
//	printf("pcmbitwidth       :%d\n",gs_wfInfo.pcmbitwidth);
//	printf("format            :");
//
//	/* new formats from sbellon@sbellon.de  1/2000 */
//        if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_WAV)
//	  printf("Microsoft WAV format (big endian). ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_AIFF)
//	  printf("Apple/SGI AIFF format (little endian). ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_AU)
//	  printf("Sun/NeXT AU format (big endian). ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_AULE)
//	  printf("DEC AU format (little endian). ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_RAW)
//	  printf("RAW PCM data. ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_PAF)
//	  printf("Ensoniq PARIS file format. ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_SVX)
//	  printf("Amiga IFF / SVX8 / SV16 format. ");
//	if ((gs_wfInfo.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_NIST)
//	  printf("Sphere NIST format. ");
//
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM)
//	  printf("PCM data in 8, 16, 24 or 32 bits.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_FLOAT)
//	  printf("32 bit Intel x86 floats.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_ULAW)
//	  printf("U-Law encoded.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_ALAW)
//	  printf("A-Law encoded.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_IMA_ADPCM)
//	  printf("IMA ADPCM.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_MS_ADPCM)
//	  printf("Microsoft ADPCM.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_BE)
//	  printf("Big endian PCM data.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_LE)
//	  printf("Little endian PCM data.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_S8)
//	  printf("Signed 8 bit PCM.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8)
//	  printf("Unsigned 8 bit PCM.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_SVX_FIB)
//	  printf("SVX Fibonacci Delta encoding.");
//	if ((gs_wfInfo.format&SF_FORMAT_SUBMASK)==SF_FORMAT_SVX_EXP)
//	  printf("SVX Exponential Delta encoding.");
//
//
//
//
//	printf("\n");
//	printf("pcmbitwidth       :%d\n",gs_wfInfo.pcmbitwidth);
//	printf("sections          :%d\n",gs_wfInfo.sections);
//	printf("seekable          :\n",gs_wfInfo.seekable);
//#endif
//  }
//
//  if (gs_wfInfo.samples==MAX_U_32_NUM) {
//    struct stat sb;
//    /* try to figure out num_samples */
//    if (0==stat(lpszFileName,&sb)) {
//      /* try file size, assume 2 bytes per sample */
//      if (gfp->input_format == sf_mp3) {
//	FLOAT totalseconds = (sb.st_size*8.0/(1000.0*GetSndBitrate()));
//	gs_wfInfo.samples= totalseconds*GetSndSampleRate();
//      }else{
//	gs_wfInfo.samples = sb.st_size/(2*GetSndChannels());
//      }
//    }
//  }
//  return musicin;    



/************************************************************************
*
* read_samples()
*
* PURPOSE:  reads the PCM samples from a file to the buffer
*
*  SEMANTICS:
* Reads #samples_read# number of shorts from #musicin# filepointer
* into #sample_buffer[]#.  Returns the number of samples read.
*
************************************************************************/
//
//int read_samples_pcm(lame_global_flags *gfp,short sample_buffer[2304],int frame_size,int samples_to_read)
//{
//    int 		samples_read;
//    int			rcode;
//
//    samples_read=sf_read_short(gs_pSndFileIn,sample_buffer,samples_to_read);
//    
//    rcode = samples_read;
//    if (samples_read < frame_size)
//      {
//	/*fprintf(stderr,"Insufficient PCM input for one frame - fillout with zeros\n"); 
//	*/
//	if (samples_read<0) samples_read=0;
//	for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);
//      }
//
//	if (8==gs_wfInfo.pcmbitwidth)
//	  for (; samples_read >= 0; sample_buffer[samples_read] = sample_buffer[samples_read--] * 256);
//
//    return(rcode);



#endif /* ifdef LIBSNDFILE */

#ifdef LAMESNDFILE 

/************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -