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

📄 get_audio.c

📁 MP3编码的完整实现(源代码和使用例子都有)
💻 C
📖 第 1 页 / 共 2 页
字号:
 ************************************************************************
 ************************************************************************
 ************************************************************************
 ************************************************************************
 ************************************************************************
 *
 * OLD ISO/LAME routines follow.  Used if you dont have LIBSNDFILE
 * or for stdin/stdout support
 *
 ************************************************************************
 ************************************************************************
 ************************************************************************
 ************************************************************************
 ************************************************************************
 ************************************************************************/

/* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */
//int fskip(FILE *sf,long num_bytes,int dummy)
//{
//  char data[1024];
//  int nskip = 0;
//  while (num_bytes > 0) {
//    nskip = (num_bytes>1024) ? 1024 : num_bytes;
//    num_bytes -= fread(data,(size_t)1,(size_t)nskip,sf);
//  }
//  /* return 0 if last read was successful */
//  return num_bytes;
//}


//
//void CloseSndFile(lame_global_flags *gfp)
//{
//  if (fclose(musicin) != 0){
//    fprintf(stderr, "Could not close audio input file\n");
//    exit(2);
//  }



unsigned long GetSndSamples(void)
{
       return num_samples;
}
int GetSndSampleRate(void)
{
	return samp_freq;
}

int GetSndChannels(void)
{
	return num_channels;
}
  
/************************************************************************
*
* 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	= 0;
	int		Need_to_read	= samples_to_read*2;	
	int		rcode		= 0;
	int		iswav		= (gfp->input_format==sf_wave);


READ_PCM_DATA:
	if(gfp->nPcmDataLen<Need_to_read)
		{
		//没有足够数据,需要等待数据
		WaitForSingleObject(gfp->hDataEvent,INFINITE);

		//判断数据是否足够
		if(gfp->nPcmDataLen<Need_to_read) goto READ_PCM_DATA;		
		}
	 	
	EnterCriticalSection(&gfp->CriSection);
	//拷贝数据
	CopyMemory(sample_buffer,gfp->lpPcmData,Need_to_read);

	//移动数据
	CopyMemory(gfp->lpPcmData,gfp->lpPcmData+Need_to_read,gfp->nPcmDataLen-Need_to_read);
	gfp->nPcmDataLen-=Need_to_read;

	LeaveCriticalSection(&gfp->CriSection);
   
	samples_read = Need_to_read/2;
	if( NativeByteOrder == order_unknown )
		{
		NativeByteOrder = DetermineByteOrder();
		if (NativeByteOrder == order_unknown)
			{
			return -1;
			}
		}
	    /* intel=littleEndian */
	    if (!iswav && ( NativeByteOrder == order_littleEndian ))
		{
		    SwapBytesInWords( sample_buffer, samples_read );
		}

	    if (iswav && ( NativeByteOrder == order_bigEndian ))
		{
		    SwapBytesInWords( sample_buffer, samples_read );
		}

	    if (gfp->swapbytes==TRUE)
		{
		    SwapBytesInWords( sample_buffer, samples_read );
		}


	    rcode = samples_read;
	    if (samples_read < frame_size)
		{
		if (samples_read<0) samples_read=0;
		for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);
		}

	    return(rcode);
}


#define WAV_ID_RIFF 0x52494646 /* "RIFF" */
#define WAV_ID_WAVE 0x57415645 /* "WAVE" */
#define WAV_ID_FMT  0x666d7420 /* "fmt " */
#define WAV_ID_DATA 0x64617461 /* "data" */

typedef struct fmt_chunk_data_struct {
	short	format_tag;			 /* Format category */
	u_short channels;			 /* Number of channels */
	u_long	samples_per_sec;	 /* Sampling rate */
	u_long	avg_bytes_per_sec;	 /* For buffer estimation */
	u_short block_align;		 /* Data block size */
	u_short bits_per_sample;	 /* for PCM data, anyway... */
} fmt_chunk_data;

/************************************************************************
*
* wave_check
*
* PURPOSE:	Checks Wave header information to make sure it is valid.
*			Exits if not.
*
************************************************************************/

static void wave_check(char *file_name, fmt_chunk_data *wave_info)
{
	if (wave_info->bits_per_sample != 16)
		{
		fprintf(stderr, "%d-bit sample-size is not supported!\n",
			wave_info->bits_per_sample);
		exit(1);
		}
}


/*****************************************************************************
 *
 *	Read Microsoft Wave headers
 *
 *	By the time we get here the first 32-bits of the file have already been
 *	read, and we're pretty sure that we're looking at a WAV file.
 *
 *****************************************************************************/
//static int parse_wave_header(FILE *sf)
//{
//	fmt_chunk_data wave_info;
//	int is_wav = 0;
//	long data_length = 0, file_length, subSize = 0;
//	int loop_sanity = 0;
//
//	memset(&wave_info, 0, sizeof(wave_info));
//
//	file_length = Read32BitsHighLow(sf);
//
//	if (Read32BitsHighLow(sf) != WAV_ID_WAVE)
//		return 0;
//
//	for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) {
//		u_int type = Read32BitsHighLow(sf);
//
//		if (type == WAV_ID_FMT) {
//			subSize = Read32BitsLowHigh(sf);
//			if (subSize < 16) {
//			  /*fprintf(stderr,
//			    "'fmt' chunk too short (only %ld bytes)!", subSize);  */
//				return 0;
//			}
//
//			wave_info.format_tag		= Read16BitsLowHigh(sf);
//			subSize -= 2;
//			wave_info.channels			= Read16BitsLowHigh(sf);
//			subSize -= 2;
//			wave_info.samples_per_sec	= Read32BitsLowHigh(sf);
//			subSize -= 4;
//			wave_info.avg_bytes_per_sec = Read32BitsLowHigh(sf);
//			subSize -= 4;
//			wave_info.block_align		= Read16BitsLowHigh(sf);
//			subSize -= 2;
//			wave_info.bits_per_sample	= Read16BitsLowHigh(sf);
//			subSize -= 2;
//
//			/* fprintf(stderr, "   skipping %d bytes\n", subSize); */
//
//			if (subSize > 0) {
//				if (fskip(sf, (long)subSize, SEEK_CUR) != 0 )
//					return 0;
//			};
//
//		} else if (type == WAV_ID_DATA) {
//			subSize = Read32BitsLowHigh(sf);
//			data_length = subSize;
//			is_wav = 1;
//			/* We've found the audio data.	Read no further! */
//			break;
//
//		} else {
//			subSize = Read32BitsLowHigh(sf);
//			if (fskip(sf, (long) subSize, SEEK_CUR) != 0 ) return 0;
//		}
//	}
//
//	if (is_wav) {
//		/* make sure the header is sane */
//		wave_check("name", &wave_info);
//
//		num_channels  = wave_info.channels;
//		samp_freq     = wave_info.samples_per_sec;
//		num_samples   = data_length / (wave_info.channels * wave_info.bits_per_sample / 8);
//	}
//	return is_wav;

/************************************************************************
*
* aiff_check
*
* PURPOSE:	Checks AIFF header information to make sure it is valid.
*			Exits if not.
*
************************************************************************/

static void aiff_check2(const char *file_name, IFF_AIFF *pcm_aiff_data)
{
	if (pcm_aiff_data->sampleType != IFF_ID_SSND)
		{
	   fprintf(stderr, "Sound data is not PCM in \"%s\".\n", file_name);
	   exit(1);
	}

	if (pcm_aiff_data->sampleSize != sizeof(short) * BITS_IN_A_BYTE) {
		fprintf(stderr, "Sound data is not %d bits in \"%s\".\n",
				(unsigned int) sizeof(short) * BITS_IN_A_BYTE, file_name);
		exit(1);
	}

	if (pcm_aiff_data->numChannels != 1 &&
		pcm_aiff_data->numChannels != 2) {
	   fprintf(stderr, "Sound data is not mono or stereo in \"%s\".\n",
			   file_name);
	   exit(1);
	}

	if (pcm_aiff_data->blkAlgn.blockSize != 0) {
	   fprintf(stderr, "Block size is not %d bytes in \"%s\".\n",
			   0, file_name);
	   exit(1);
	}

	if (pcm_aiff_data->blkAlgn.offset != 0) {
	   fprintf(stderr, "Block offset is not %d bytes in \"%s\".\n",
			   0, file_name);
	   exit(1);
	}
}

/*****************************************************************************
 *
 *	Read Audio Interchange File Format (AIFF) headers.
 *
 *	By the time we get here the first 32-bits of the file have already been
 *	read, and we're pretty sure that we're looking at an AIFF file.
 *
 *****************************************************************************/
//static int parse_aiff_header(FILE *sf)
//{
//	int is_aiff = 0;
//	long chunkSize = 0, subSize = 0;
//	IFF_AIFF aiff_info;
//
//	memset(&aiff_info, 0, sizeof(aiff_info));
//	chunkSize = Read32BitsHighLow(sf);
//	
//	if ( Read32BitsHighLow(sf) != IFF_ID_AIFF )
//		return 0;
//	
//	while ( chunkSize > 0 )
//	{
//		u_int type = 0;
//		chunkSize -= 4;
//
//		type = Read32BitsHighLow(sf);
//
//		/* fprintf(stderr,
//			"found chunk type %08x '%4.4s'\n", type, (char*)&type); */
//
//		/* don't use a switch here to make it easier to use 'break' for SSND */
//		if (type == IFF_ID_COMM) {
//			subSize = Read32BitsHighLow(sf);
//			chunkSize -= subSize;
//
//			aiff_info.numChannels	  = Read16BitsHighLow(sf);
//			subSize -= 2;
//			aiff_info.numSampleFrames = Read32BitsHighLow(sf);
//			subSize -= 4;
//			aiff_info.sampleSize	  = Read16BitsHighLow(sf);
//			subSize -= 2;
//			aiff_info.sampleRate	  = ReadIeeeExtendedHighLow(sf);
//			subSize -= 10;
//
//			if (fskip(sf, (long) subSize, SEEK_CUR) != 0 )
//				return 0;
//
//		} else if (type == IFF_ID_SSND) {
//			subSize = Read32BitsHighLow(sf);
//			chunkSize -= subSize;
//
//			aiff_info.blkAlgn.offset	= Read32BitsHighLow(sf);
//			subSize -= 4;
//			aiff_info.blkAlgn.blockSize = Read32BitsHighLow(sf);
//			subSize -= 4;
//
//			if (fskip(sf, aiff_info.blkAlgn.offset, SEEK_CUR) != 0 )
//				return 0;
//
//			aiff_info.sampleType = IFF_ID_SSND;
//			is_aiff = 1;
//
//			/* We've found the audio data.	Read no further! */
//			break;
//			
//		} else {
//			subSize = Read32BitsHighLow(sf);
//			chunkSize -= subSize;
//
//			if (fskip(sf, (long) subSize, SEEK_CUR) != 0 )
//				return 0;
//		}
//	}
//
//	/* fprintf(stderr, "Parsed AIFF %d\n", is_aiff); */
//	if (is_aiff) {
//		/* make sure the header is sane */
//		aiff_check2("name", &aiff_info);
//		num_channels  = aiff_info.numChannels;
//		samp_freq     = aiff_info.sampleRate;
//		num_samples   = aiff_info.numSampleFrames;
//	}
//	return is_aiff;


/************************************************************************
*
* parse_file_header
*
* PURPOSE: Read the header from a bytestream.  Try to determine whether
*		   it's a WAV file or AIFF without rewinding, since rewind
*		   doesn't work on pipes and there's a good chance we're reading
*		   from stdin (otherwise we'd probably be using libsndfile).
*
* When this function returns, the file offset will be positioned at the
* beginning of the sound data.
*
************************************************************************/

//void parse_file_header(lame_global_flags *gfp,FILE *sf)
//{
//	u_int type = 0;
//	type = Read32BitsHighLow(sf);
//
//	/* fprintf(stderr,
//		"First word of input stream: %08x '%4.4s'\n", type, (char*) &type); */
//
//	count_samples_carefully=0;
//	gfp->input_format = sf_raw;
//
//	if (type == WAV_ID_RIFF) {
//		/* It's probably a WAV file */
//		if (parse_wave_header(sf)) {
//			gfp->input_format = sf_wave;
//			count_samples_carefully=1;
//		}
//
//	} else if (type == IFF_ID_FORM) {
//		/* It's probably an AIFF file */
//		if (parse_aiff_header(sf)) {
//			gfp->input_format = sf_aiff;
//			count_samples_carefully=1;
//		}
//	}
//	if (gfp->input_format==sf_raw) {
//	  /*
//	  ** Assume it's raw PCM.	 Since the audio data is assumed to begin
//	  ** at byte zero, this will unfortunately require seeking.
//	  */
//	  if (fseek(sf, 0L, SEEK_SET) != 0) {
//	    /* ignore errors */
//	  }
//	  gfp->input_format = sf_raw;
//	}
//}
#endif  /* LAMESNDFILE */



⌨️ 快捷键说明

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