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