📄 get_audio.c
字号:
#include "util.h"#include "get_audio.h"#include "portableio.h"#include "gtkanal.h"#include "timestatus.h"#if (defined LIBSNDFILE || defined LAMESNDFILE)#ifdef _WIN32/* needed to set stdin to binary on windoze machines */#include <io.h>#endif#ifdef __riscos__#include <kernel.h>#include <sys/swis.h>#endifint read_samples_pcm(lame_global_flags *gfp,short sample_buffer[2304],int frame_size, int samples_to_read);int read_samples_mp3(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int num_chan);int read_samples_ogg(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int num_chan);void lame_init_infile(lame_global_flags *gfp){ lame_internal_flags *gfc=gfp->internal_flags; /* open the input file */ gfc->count_samples_carefully=0; gfp->musicin=OpenSndFile(gfp);}void lame_close_infile(lame_global_flags *gfp){ CloseSndFile(gfp->input_format,gfp->musicin);}/************************************************************************** lame_readframe()** 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**************************************************************************/int lame_readframe(lame_global_flags *gfp,short int Buffer[2][1152]){ int iread; lame_internal_flags *gfc=gfp->internal_flags; /* note: if input is gfp->stereo and output is mono, get_audio() * will return .5*(L+R) in channel 0, and nothing in channel 1. */ iread = get_audio(gfp,Buffer,gfc->stereo); /* check to see if we overestimated/underestimated totalframes */ if (iread==0) gfp->totalframes = Min(gfp->totalframes,gfp->frameNum+2); if (gfp->frameNum > (gfp->totalframes-1)) gfp->totalframes = gfp->frameNum; /* normally, frame counter is incremented every time we encode a frame, but: */ if (gfp->decode_only) ++gfp->frameNum; return iread;}/************************************************************************** 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**************************************************************************/int get_audio(lame_global_flags *gfp,short buffer[2][1152],int stereo){ int j; short insamp[2304]; int samples_read; int framesize,samples_to_read; unsigned long remaining; lame_internal_flags *gfc=gfp->internal_flags; int num_channels = gfp->num_channels; /* NOTE: LAME can now handle arbritray size input data packets, * so there is no reason to read the input data in chuncks of * size "gfp->framesize". EXCEPT: the LAME graphical frame analyzer * will get out of sync if we read more than framesize worth of data. */ framesize = gfp->framesize; samples_to_read = framesize; if (gfc->count_samples_carefully) { /* if this flag has been set, then we are carefull to read * exactly num_samples and no more. This is usefull 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 */ remaining=gfp->num_samples-Min(gfp->num_samples,gfc->num_samples_read); if (remaining < (unsigned long)framesize) samples_to_read = remaining; } if (gfp->input_format==sf_mp3) { /* decode an mp3 file for the input */ samples_read=read_samples_mp3(gfp,gfp->musicin,buffer,num_channels); } else if (gfp->input_format==sf_ogg) { samples_read=read_samples_ogg(gfp,gfp->musicin,buffer,num_channels); }else{ samples_read = read_samples_pcm(gfp,insamp,num_channels*framesize,num_channels*samples_to_read); samples_read /=num_channels; for(j=0;j<framesize;j++) { buffer[0][j] = insamp[num_channels*j]; if (num_channels==2) buffer[1][j] = insamp[2*j+1]; else buffer[1][j]=0; } } /* dont count things in this case to avoid overflows */ if (gfp->num_samples!=MAX_U_32_NUM) gfc->num_samples_read += samples_read; return(samples_read);} int read_samples_ogg(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int stereo){#ifdef HAVEVORBIS int j,out=0; lame_internal_flags *gfc=gfp->internal_flags; mp3data_struct mp3data; out=lame_decode_ogg_fromfile(musicin,mpg123pcm[0],mpg123pcm[1],&mp3data); /* out = -1: error, probably EOF */ /* out = 0: not possible with lame_decode_fromfile() */ /* out = number of output samples */ if (out==-1) { for ( j = 0; j < 1152; j++ ) { mpg123pcm[0][j] = 0; mpg123pcm[1][j] = 0; } } if (out==-1) return 0; gfp->brate=mp3data.bitrate; if (gfp->num_channels != mp3data.stereo) { ERRORF("Error: number of channels has changed in mp3 file - not supported. \n"); } if (gfp->in_samplerate != mp3data.samplerate) { ERRORF("Error: samplerate has changed in mp3 file - not supported. \n"); } return out;#else return -1; /* wanna read ogg without vorbis support? */#endif}int read_samples_mp3(lame_global_flags *gfp,FILE *musicin,short int mpg123pcm[2][1152],int stereo){#if (defined AMIGA_MPEGA || defined HAVEMPGLIB) int j,out=0; lame_internal_flags *gfc=gfp->internal_flags; mp3data_struct mp3data; out=lame_decode_fromfile(musicin,mpg123pcm[0],mpg123pcm[1],&mp3data); /* out = -1: error, probably EOF */ /* out = 0: not possible with lame_decode_fromfile() */ /* out = number of output samples */ if (out==-1) { for ( j = 0; j < 1152; j++ ) { mpg123pcm[0][j] = 0; mpg123pcm[1][j] = 0; } } if (gfc->pinfo != NULL) { int ch; /* add a delay of framesize-DECDELAY, which will make the total delay * exactly one frame, so we can sync MP3 output with WAV input */ for ( ch = 0; ch < stereo; ch++ ) { for ( j = 0; j < gfp->framesize-DECDELAY; j++ ) gfc->pinfo->pcmdata2[ch][j] = gfc->pinfo->pcmdata2[ch][j+gfp->framesize]; for ( j = 0; j < gfp->framesize; j++ ) gfc->pinfo->pcmdata2[ch][j+gfp->framesize-DECDELAY] = mpg123pcm[ch][j]; } gfc->pinfo->frameNum123 = gfp->frameNum-1; gfc->pinfo->frameNum = gfp->frameNum; } if (out==-1) return 0; gfp->brate=mp3data.bitrate; if (gfp->num_channels != mp3data.stereo) { ERRORF("Error: number of channels has changed in mp3 file - not supported. \n"); } if (gfp->in_samplerate != mp3data.samplerate) { ERRORF("Error: samplerate has changed in mp3 file - not supported. \n"); } return out;#endif}void WriteWav(FILE *f,long bytes,int srate,int ch){ /* quick and dirty */ fwrite("RIFF",1,4,f); /* 0-3 */ Write32BitsLowHigh(f,bytes+44-8); fwrite("WAVEfmt ",1,8,f); /* 8-15 */ Write32BitsLowHigh(f,16); Write16BitsLowHigh(f,1); Write16BitsLowHigh(f,ch); Write32BitsLowHigh(f,srate); Write32BitsLowHigh(f,srate*ch*2); Write16BitsLowHigh(f,4); Write16BitsLowHigh(f,16); fwrite("data",1,4,f); /* 36-39 */ Write32BitsLowHigh(f,bytes);}/* the simple lame decoder *//* After calling lame_init(), lame_init_params() and * lame_init_infile(), call this routine to read the input MP3 file * and output .wav data to the specified file pointer*//* lame_decoder will ignore the first 528 samples, since these samples * represent the mpglib delay (and are all 0). skip = number of additional * samples to skip, to (for example) compensate for the encoder delay */int lame_decoder(lame_global_flags *gfp,FILE *outf,int skip){ short int Buffer[2][1152]; int iread; long wavsize=2147483647L; /* max for a signed long */ if (gfp->input_format==sf_mp3) { /* mp3 decoder has a 528 sample delay, plus user supplied "skip" */ skip+=528; MSGF("input: %s %.1fkHz MPEG%i %i channel LayerIII\n", (strcmp(gfp->inPath, "-")? gfp->inPath : "stdin"), gfp->in_samplerate/1000.0,2-gfp->version,gfp->num_channels); }else{ /* other formats have no delay */ skip=0; MSGF("input: %s %.1fkHz %i channel\n", (strcmp(gfp->inPath, "-")? gfp->inPath : "stdin"), gfp->in_samplerate/1000.0,gfp->num_channels); } MSGF("output: %s (wav format)\n", (strcmp(gfp->outPath, "-")? gfp->outPath : "stdout")); if (skip>0) MSGF("skipping initial %i samples (encoder + decoder delay)\n",skip); WriteWav(outf,wavsize,gfp->in_samplerate,gfp->num_channels); wavsize=-skip; do { int i; /* read in 'iread' samples */ iread=lame_readframe(gfp,Buffer); wavsize += iread; if (!gfp->silent) decoder_progress(gfp); for (i=0; i<iread; ++i) { if (skip) { --skip; }else{ Write16BitsLowHigh(outf,Buffer[0][i]); if (gfp->num_channels==2) Write16BitsLowHigh(outf,Buffer[1][i]); } } } while (iread); if (wavsize<0) wavsize=0; wavsize *= 2*gfp->num_channels; decoder_progress_finish(gfp); /* if outf is seekable, rewind and adjust length */ if (!fseek(outf,0,SEEK_SET)) WriteWav(outf,wavsize,gfp->in_samplerate,gfp->num_channels); fclose(outf); return 0;}#endif /* LAMESNDFILE or LIBSNDFILE */#ifdef LIBSNDFILE/*** Copyright (C) 1999 Albert 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. */#include <stdio.h>void CloseSndFile(sound_file_format input,FILE *musicin){ SNDFILE *gs_pSndFileIn=(SNDFILE*)musicin; if (input==sf_mp3) {#ifndef AMIGA_MPEGA if (fclose(musicin) != 0){ ERRORF("Could not close audio input file\n"); LAME_FATAL_EXIT(); }#endif }else{ if (gs_pSndFileIn) { if (sf_close(gs_pSndFileIn) !=0) { ERRORF("Could not close sound file \n"); LAME_FATAL_EXIT(); } } }}FILE * OpenSndFile(lame_global_flags *gfp){ lame_internal_flags *gfc=gfp->internal_flags;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -