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

📄 audio_in.c

📁 mp3编码库
💻 C
字号:
#include	<stdlib.h>
#include	<stdio.h>
#include	<string.h>
#include	"./libmp3enc/libmp3enc.h"
#include    "audio_in.h"
#include	"portableio.h"

/*****************************************************************************
*
*  Routines to determine byte order and swap bytes
*
*****************************************************************************/

enum byte_order DetermineByteOrder()
{
    i8 s[ sizeof(i32) + 1 ];
    union
    {
        i32 longval;
        i8 charval[ sizeof(i32) ];
    } probe;
    probe.longval = 0x41424344L;  /* ABCD in ASCII */
    strncpy( s, probe.charval, sizeof(i32) );
    s[ sizeof(i32) ] = '\0';
    /* fprintf( stderr, "byte order is %s\n", s ); */
    if ( strcmp(s, "ABCD") == 0 )
	{
		printf("Big Endian\n");
        return order_bigEndian;
	}
    else
        if ( strcmp(s, "DCBA") == 0 )
		{
			printf("Little Endian\n");
            return order_littleEndian;
		}
        else
		{
			printf("Order_unknown\n");
            return order_unknown;
		}
}

static __inline void SwapBytesInWords( i16 *loc, i32 words )
{
    i32 i;    
    i8 *data;
    data = (i8 *) loc;	
	//printf("swapping...");
    for ( i = 0; i < words; i++ )
    {
		i8 tmp0, tmp1;
		tmp0 = data[0];
		tmp1 = data[1];
        data[0] = tmp1;
        data[1] = tmp0;
		data += 2;
    }
	//printf("done...");
}
 
/************************************************************************
*
* 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.
*
************************************************************************/

enum byte_order NativeByteOrder = order_unknown;

u32 read_samples(FILE *musicin, i16 sample_buffer[2304], u32 frame_size, i32 file_type)
{
    u32 samples_read;

    if ((samples_read =
         fread(sample_buffer, sizeof(i16), frame_size, musicin)) == 0)
	{
        printf("Hit end of audio data %d\n", samples_read);
		return 0;
	}

    /*
       Samples are big-endian. If this is a little-endian machine
       we must swap
     */
    if ( NativeByteOrder == order_unknown )
	{
		NativeByteOrder = DetermineByteOrder();
		if ( NativeByteOrder == order_unknown )
		{
			fprintf( stderr, "byte order not determined\n" );
			exit( 1 );
		}
		printf("order known\n");

	}

    if(file_type != FILE_WAVE)
	{
//#ifndef WIN32
    if ( NativeByteOrder == order_littleEndian )
      SwapBytesInWords( sample_buffer, samples_read );
	}
//#endif

    if (samples_read < frame_size && samples_read > 0) {
        printf("Insufficient PCM input for one frame - fillout with zeros\n");
        for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);
    }
    return(samples_read);
}

/************************************************************************
*
* 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
*
*
************************************************************************/
 
u32 get_audio( FILE *musicin, i16 buffer[2][1152], u32 num_samples, i32 stereo, layer *info, i32 file_type )
{
    i32 j;
    i16 insamp[2304];
    u32 samples_read;
    i32 lay;
    lay = info->lay;

	//printf("lay=%d, version=%d\n", lay, info->version);
    if ( (lay == 3) && (info->version == 0) )
    {
	  if ( stereo == 2 )
	  {
	    samples_read = read_samples( musicin, insamp, 1152, file_type);

	    for ( j = 0; j < 576; j++ )
	    {
		buffer[0][j] = insamp[2 * j];
		buffer[1][j] = insamp[2 * j + 1];
	    }
	  }
	  else
	  {
	    samples_read = read_samples( musicin, insamp, 576, file_type);
	    for ( j = 0; j < 576; j++ )
	    {
		buffer[0][j] = insamp[j];
		buffer[1][j] = 0;
	    }
	  }
    }
    else
    {
	if (lay == 1){
	    if(stereo == 2){ /* layer 1, stereo */
		samples_read = read_samples(musicin, insamp, 768, file_type);
		for(j=0;j<448;j++) {
		    if(j<64) {
			buffer[0][j] = buffer[0][j+384];
			buffer[1][j] = buffer[1][j+384];
		    }
		    else {
			buffer[0][j] = insamp[2*j-128];
			buffer[1][j] = insamp[2*j-127];
		    }
		}
	    }
	    else { /* layer 1, mono */
		samples_read = read_samples(musicin, insamp, 384, file_type);
		for(j=0;j<448;j++){
		    if(j<64) {
			buffer[0][j] = buffer[0][j+384];
			buffer[1][j] = 0;
		    }
		    else {
			buffer[0][j] = insamp[j-64];
			buffer[1][j] = 0;
		    }
		}
	    }
	}
	else {
	    if(stereo == 2){ /* layer 2 (or 3), stereo */
		samples_read = read_samples(musicin, insamp, 2304, file_type);
		for(j=0;j<1152;j++) {
		    buffer[0][j] = insamp[2*j];
		    buffer[1][j] = insamp[2*j+1];
		}
	    }
	    else { /* layer 2 (or 3), mono */
		samples_read = read_samples(musicin, insamp, 1152, file_type);
		for(j=0;j<1152;j++){
		    buffer[0][j] = insamp[j];
		    buffer[1][j] = 0;
		}
	    }
	}
    }
    return(samples_read);
}


/*
   By David Zheng
   To get file type : AIFF or WAVE file
   Input : Handle of file
   Output: File type (FILE_AIFF, FILE_WAVE, FILE_RAW, defined in typedef.h)
 */
i32 get_file_type(FILE *file)
{
	u32 file_ID;
	i32 file_type;

	file_type = FILE_RAW;

    file_ID = Read32BitsHighLow(file);

	if(file_ID == IFF_ID_FORM)
		file_type = FILE_AIFF;
	else if(file_ID == WAV_ID_RIFF)
		file_type = FILE_WAVE;	

    return file_type;

}


/*****************************************************************************
 *
 *  Read Audio Interchange File Format (AIFF) headers.
 *
 *****************************************************************************/

i32 aiff_read_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
{
    i32 chunkSize, subSize, sound_position;
    
	// seek back to beginning
    if ( fseek(file_ptr, 0, SEEK_SET) != 0 )
        return -1;
    
    if ( Read32BitsHighLow(file_ptr) != IFF_ID_FORM )
        return -1;
    
    chunkSize = Read32BitsHighLow( file_ptr );
    
    if ( Read32BitsHighLow(file_ptr) != IFF_ID_AIFF )
        return -1;
    
    sound_position = 0;
    while ( chunkSize > 0 )
    {
        chunkSize -= 4;
        switch ( Read32BitsHighLow(file_ptr) )
		{
            
          case IFF_ID_COMM:
            chunkSize -= subSize = Read32BitsHighLow( file_ptr );
            aiff_ptr->numChannels = Read16BitsHighLow( file_ptr );
            subSize -= 2;
            aiff_ptr->numSampleFrames = Read32BitsHighLow( file_ptr );
            subSize -= 4;
            aiff_ptr->sampleSize = Read16BitsHighLow( file_ptr );
            subSize -= 2;
            aiff_ptr->sampleRate  = ReadIeeeExtendedHighLow( file_ptr );
            subSize -= 10;
            while ( subSize > 0 )
			{
                getc( file_ptr );
                subSize -= 1;
			}

            break;
            
          case IFF_ID_SSND:
            chunkSize -= subSize = Read32BitsHighLow( file_ptr );
            aiff_ptr->blkAlgn.offset = Read32BitsHighLow( file_ptr );
            subSize -= 4;
            aiff_ptr->blkAlgn.blockSize = Read32BitsHighLow( file_ptr );
            subSize -= 4;
            /*sound_position = ftell( file_ptr ) + aiff_ptr->blkAlgn.offset;
            if ( fseek(file_ptr, (i32) subSize, SEEK_CUR) != 0 )
                return -1;
				*/
			sound_position = 0;
			if (fseek(file_ptr, (long) aiff_ptr->blkAlgn.offset, SEEK_CUR) != 0)
                return 0;

            aiff_ptr->sampleType = IFF_ID_SSND;
            break;
            
          default:
            chunkSize -= subSize = Read32BitsHighLow( file_ptr );
            while ( subSize > 0 )
			{
                getc( file_ptr );
                subSize -= 1;
			}

            break;
		}
    }

    return sound_position;
}


/*****************************************************************************
 *
 *  Read WAVE (.wav) headers.
 *
 *****************************************************************************/

i32 wave_read_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
{
	i32 chunk_length = Read32BitsHighLow( file_ptr );
	i32 sub_type;
	i32 sub_size;  
	i32 loop = 20;
	i32 format, block_align, avg_bytes_per_sec;
    
    if (Read32BitsHighLow(file_ptr) != WAV_ID_WAVE)
        return 0;
            
	chunk_length -= 8;
    while ( loop )
    {
		loop --;
		sub_type = Read32BitsHighLow(file_ptr);
        chunk_length -= 4;
        switch ( sub_type )
		{
            
          case WAV_ID_FMT:

            sub_size = Read32BitsLowHigh(file_ptr);

            if (sub_size < 16) {
				printf("WAV_ID_FMT chunk too short!\nERROR\nEXIT\n");
                return -1;
            }

			chunk_length -= sub_size;

			format = Read16BitsLowHigh( file_ptr );
			if(format != 1)
			{
				printf("WAVE parser doesn't support this format\n");
				exit(0);
			}
			sub_size -= 2;
            aiff_ptr->numChannels = Read16BitsLowHigh( file_ptr );
            sub_size -= 2;

            aiff_ptr->sampleRate  = Read32BitsLowHigh( file_ptr );
            sub_size -= 4;

            avg_bytes_per_sec = Read32BitsLowHigh(file_ptr);
            sub_size -= 4;
			printf("avg_bytes_per_sec = %d\n", avg_bytes_per_sec); 

            block_align = Read16BitsLowHigh(file_ptr);
            sub_size -= 2;
			printf("block_align = %d\n", block_align);
			
            aiff_ptr->sampleSize = Read16BitsLowHigh( file_ptr );
            sub_size -= 2;
			printf("sampleSize = %d\n", aiff_ptr->sampleSize);

            while ( sub_size > 0 )
			{
                getc( file_ptr );
                sub_size -= 1;
			}

            break;
            
          case WAV_ID_DATA:
            sub_size = Read32BitsLowHigh( file_ptr );
			aiff_ptr->numSampleFrames = sub_size / (aiff_ptr->numChannels * ((aiff_ptr->sampleSize+7) / 8));
            return 1;
            
          default:
            sub_size = Read32BitsLowHigh( file_ptr );
            while ( sub_size > 0 )
			{
                getc( file_ptr );
                sub_size -= 1;
			}
            return -1;
	}
    }
    return 1;
}

/*****************************************************************************
 *
 *  Seek past some Audio Interchange File Format (AIFF) headers to sound data.
 *
 *****************************************************************************/

i32 aiff_seek_to_sound_data( FILE *file_ptr )
{
	if ( fseek(file_ptr, AIFF_FORM_HEADER_SIZE + AIFF_SSND_HEADER_SIZE, SEEK_SET) != 0 )
        return(-1);
    return(0);
}

⌨️ 快捷键说明

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