📄 get_audio.c
字号:
/* * Get Audio routines source file * * Copyright (c) 1999 Albert L 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. *//* $Id: get_audio.c,v 1.102 2005/05/25 14:17:51 takehiro Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <assert.h>#ifdef HAVE_LIMITS_H# include <limits.h>#endif#include <stdio.h>#ifdef STDC_HEADERS# include <stdlib.h># include <string.h>#else# ifndef HAVE_STRCHR# define strchr index# define strrchr rindex# endifchar *strchr(), *strrchr();# ifndef HAVE_MEMCPY# define memcpy(d, s, n) bcopy ((s), (d), (n))# define memmove(d, s, n) bcopy ((s), (d), (n))# endif#endif#define MAX_U_32_NUM 0xFFFFFFFF#include <math.h>#include <sys/stat.h>#ifdef __sun__/* woraround for SunOS 4.x, it has SEEK_* defined here */#include <unistd.h>#endif#include "lame.h"#include "main.h"#include "get_audio.h"#include "portableio.h"#include "timestatus.h"#include "lametime.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif/* global data for get_audio.c. */int count_samples_carefully;int pcmbitwidth;int pcmswapbytes = 0;unsigned int num_samples_read;FILE *musicin;#ifdef AMIGA_MPEGAint lame_decode_initfile(const char *fullname, mp3data_struct * const mp3data);#elseint lame_decode_initfile(FILE * fd, mp3data_struct * mp3data);#endif/* read mp3 file until mpglib returns one frame of PCM data */int lame_decode_fromfile(FILE * fd, short int pcm_l[], short int pcm_r[], mp3data_struct * mp3data);static int read_samples_pcm(FILE * musicin, int sample_buffer[2304], int frame_size, int samples_to_read);static int read_samples_mp3(lame_global_flags * const gfp, FILE * const musicin, short int mpg123pcm[2][1152], int num_chan);void CloseSndFile(sound_file_format input, FILE * musicin);FILE *OpenSndFile(lame_global_flags * gfp, char *);/* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */static intfskip(FILE * fp, long offset, int whence){#ifndef PIPE_BUF char buffer[4096];#else char buffer[PIPE_BUF];#endif int read; if (0 == fseek(fp, offset, whence)) return 0; if (whence != SEEK_CUR || offset < 0) { if( silent < 10 ) { fprintf(stderr, "fskip problem: Mostly the return status of functions is not evaluate so it is more secure to polute <stderr>.\n"); } return -1; } while (offset > 0) { read = offset > sizeof(buffer) ? sizeof(buffer) : offset; if ((read = fread(buffer, 1, read, fp)) <= 0) return -1; offset -= read; } return 0;}FILE *init_outfile(char *outPath, int decode){ FILE *outf;#ifdef __riscos__ char *p;#endif /* open the output file */ if (0 == strcmp(outPath, "-")) { lame_set_stream_binary_mode(outf = stdout); } else { if ((outf = fopen(outPath, "wb+")) == NULL) return NULL;#ifdef __riscos__ /* Assign correct file type */ for (p = outPath; *p; p++) /* ugly, ugly to modify a string */ switch (*p) { case '.': *p = '/'; break; case '/': *p = '.'; break; } SetFiletype(outPath, decode ? 0xFB1 /*WAV*/ : 0x1AD /*AMPEG*/);#endif } return outf;}voidinit_infile(lame_global_flags * gfp, char *inPath){ /* open the input file */ count_samples_carefully = 0; num_samples_read=0; pcmbitwidth=in_bitwidth; pcmswapbytes=swapbytes; musicin = OpenSndFile(gfp, inPath);}voidclose_infile(void){ CloseSndFile(input_format, musicin);}voidSwapBytesInWords(short *ptr, int short_words){ /* Some speedy code */ unsigned long val; unsigned long *p = (unsigned long *) ptr;#ifndef lint# if defined(CHAR_BIT)# if CHAR_BIT != 8# error CHAR_BIT != 8# endif# else# error can not determine number of bits in a char# endif#endif /* lint */ assert(sizeof(short) == 2);#if defined(SIZEOF_UNSIGNED_LONG) && SIZEOF_UNSIGNED_LONG == 4 for (; short_words >= 2; short_words -= 2, p++) { val = *p; *p = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0x00FF00FF); } ptr = (short *) p; for (; short_words >= 1; short_words -= 1, ptr++) { val = *ptr; *ptr = ((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF); }#elif defined(SIZEOF_UNSIGNED_LONG) && SIZEOF_UNSIGNED_LONG == 8 for (; short_words >= 4; short_words -= 4, p++) { val = *p; *p = ((val << 8) & 0xFF00FF00FF00FF00) | ((val >> 8) & 0x00FF00FF00FF00FF); } ptr = (short *) p; for (; short_words >= 1; short_words -= 1, ptr++) { val = *ptr; *ptr = ((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF); }#else# ifdef SIZEOF_UNSIGNED_LONG# warning Using unoptimized SwapBytesInWords().# endif for (; short_words >= 1; short_words -= 1, ptr++) { val = *ptr; *ptr = ((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF); }#endif assert(short_words == 0);}static intget_audio_common( lame_global_flags * const gfp, int buffer[2][1152], short buffer16[2][1152] );/************************************************************************** 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*************************************************************************/intget_audio( lame_global_flags * const gfp, int buffer[2][1152] ){ return( get_audio_common( gfp, buffer, NULL ) );}/* get_audio16 - behave as the original get_audio function, with a limited 16 bit per sample output*/intget_audio16( lame_global_flags * const gfp, short buffer[2][1152] ){ return( get_audio_common( gfp, NULL, buffer ) );}/************************************************************************ get_audio_common - central functionality of get_audio* in: gfp buffer output to the int buffer or 16-bit buffer out: buffer int output (if buffer != NULL) buffer16 16-bit output (if buffer == NULL) returns: samples readnote: either buffer or buffer16 must be allocated upon call*/static intget_audio_common( lame_global_flags * const gfp, int buffer[2][1152], short buffer16[2][1152] ){ int num_channels = lame_get_num_channels( gfp ); int insamp[2 * 1152]; short buf_tmp16[2][1152]; int samples_read; int framesize; int samples_to_read; unsigned int remaining, tmp_num_samples; int i; int *p; /* * NOTE: LAME can now handle arbritray size input data packets, * so there is no reason to read the input data in chuncks of * size "framesize". EXCEPT: the LAME graphical frame analyzer * will get out of sync if we read more than framesize worth of data. */ samples_to_read = framesize = lame_get_framesize(gfp); assert(framesize <= 1152); /* get num_samples */ tmp_num_samples = lame_get_num_samples( gfp ); /* if this flag has been set, then we are carefull to read * exactly num_samples and no more. This is useful 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 */ if (count_samples_carefully) { remaining = tmp_num_samples - Min(tmp_num_samples, num_samples_read); if (remaining < framesize && 0 != tmp_num_samples) /* in case the input is a FIFO (at least it's reproducible with a FIFO) tmp_num_samples may be 0 and therefore remaining would be 0, but we need to read some samples, so don't change samples_to_read to the wrong value in this case */ samples_to_read = remaining; } switch (input_format) { case sf_mp1: case sf_mp2: case sf_mp3: if( buffer != NULL ) samples_read = read_samples_mp3( gfp, musicin, buf_tmp16, num_channels ); else samples_read = read_samples_mp3( gfp, musicin, buffer16, num_channels ); break; default: samples_read = read_samples_pcm(musicin, insamp, num_channels * framesize, num_channels * samples_to_read); p = insamp + samples_read; samples_read /= num_channels; if( buffer != NULL ) { /* output to int buffer */ if( num_channels == 2 ) { for( i = samples_read; --i >= 0; ) { buffer[1][i] = *--p; buffer[0][i] = *--p; } } else if( num_channels == 1 ) { memset( buffer[1], 0, samples_read * sizeof(int) ); for( i = samples_read; --i >= 0; ) { buffer[0][i] = *--p; } } else assert(0); } else { /* convert from int; output to 16-bit buffer */ if( num_channels == 2 ) { for( i = samples_read; --i >= 0; ) { buffer16[1][i] = *--p >> (8 * sizeof(int) - 16); buffer16[0][i] = *--p >> (8 * sizeof(int) - 16); } } else if( num_channels == 1 ) { memset( buffer16[1], 0, samples_read * sizeof(short) ); for( i = samples_read; --i >= 0; ) { buffer16[0][i] = *--p >> (8 * sizeof(int) - 16); } } else assert(0); } } /* LAME mp3 output 16bit - convert to int, if necessary */ if( input_format == sf_mp1 || input_format == sf_mp2 || input_format == sf_mp3) { if( buffer != NULL ) { for( i = samples_read; --i >= 0; ) buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16); if( num_channels == 2 ) { for( i = samples_read; --i >= 0; ) buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16); } else if( num_channels == 1 ) { memset( buffer[1], 0, samples_read * sizeof(int) ); } else assert(0); } } /* if num_samples = MAX_U_32_NUM, then it is considered infinitely long. Don't count the samples */ if ( tmp_num_samples != MAX_U_32_NUM ) num_samples_read += samples_read; return samples_read;}int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -