📄 get_audio.c
字号:
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;
}
FILE * OpenSndFile(lame_global_flags *gfp,const char* inPath, int default_samp,
int default_channels)
{
struct stat sb;
void parse_file_header(lame_global_flags *gfp,FILE *sf);
/* set the defaults from info incase we cannot determine them from file */
num_samples=MAX_U_32_NUM;
samp_freq=default_samp;
num_channels = default_channels;
if (!strcmp(inPath, "-")) {
/* Read from standard input. */
#ifdef __EMX__
_fsetmode(stdin,"b");
#elif (defined __BORLANDC__)
setmode(_fileno(stdin), O_BINARY);
#elif (defined __CYGWIN__)
setmode(fileno(stdin), _O_BINARY);
#elif (defined _WIN32)
_setmode(_fileno(stdin), _O_BINARY);
#endif
musicin = stdin;
} else {
if ((musicin = fopen(inPath, "rb")) == NULL) {
fprintf(stderr, "Could not find \"%s\".\n", inPath);
exit(1);
}
}
input_bitrate=0;
if (gfp->input_format==sf_mp3) {
#ifdef AMIGA_MPEGA
if (-1==lame_decode_initfile(inPath,&num_channels,&samp_freq,&input_bitrate,&num_samples)) {
fprintf(stderr,"Error reading headers in mp3 input file %s.\n", inPath);
exit(1);
}
#endif
#ifdef HAVEMPGLIB
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", inPath);
exit(1);
}
#endif
}else{
if (gfp->input_format != sf_raw) {
parse_file_header(gfp,musicin);
}
if (gfp->input_format==sf_raw) {
/* assume raw PCM */
fprintf(stderr, "Assuming raw pcm input file");
if (gfp->swapbytes==TRUE)
fprintf(stderr, " : Forcing byte-swapping\n");
else
fprintf(stderr, "\n");
}
}
if (num_samples==MAX_U_32_NUM && musicin != stdin) {
/* try to figure out num_samples */
if (0==stat(inPath,&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()));
num_samples= totalseconds*GetSndSampleRate();
}else{
num_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;
int iswav=(gfp->input_format==sf_wave);
samples_read = fread(sample_buffer, sizeof(short), samples_to_read, musicin);
if (ferror(musicin)) {
fprintf(stderr, "Error reading input file\n");
exit(2);
}
/*
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 );
}
}
/* 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;
/*fprintf(stderr,"Insufficient PCM input for one frame - fillout with zeros\n");
*/
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 + -