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

📄 aflibconverter.cc

📁 一个共享源码的音频库2
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright: (C) 2000 Julius O. Smith * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or 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 *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser 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 * *   Julius O. Smith  jos@ccrma.stanford.edu * *//* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it   into a C++ class*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h>#include "aflibConverter.h"#include "aflibConverterLargeFilter.h"#include "aflibConverterSmallFilter.h"#include "aflibDebug.h"#if (!defined(TRUE) || !defined(FALSE))# define TRUE 1# define FALSE 0#endif                                                                                   /* * The configuration constants below govern * the number of bits in the input sample and filter coefficients, the * number of bits to the right of the binary-point for fixed-point math, etc. *//* Conversion constants */#define Nhc       8#define Na        7#define Np       (Nhc+Na)#define Npc      (1<<Nhc)#define Amask    ((1<<Na)-1)#define Pmask    ((1<<Np)-1)#define Nh       16#define Nb       16#define Nhxn     14#define Nhg      (Nh-Nhxn)#define NLpScl   13/* Description of constants: * * Npc - is the number of look-up values available for the lowpass filter *    between the beginning of its impulse response and the "cutoff time" *    of the filter.  The cutoff time is defined as the reciprocal of the *    lowpass-filter cut off frequence in Hz.  For example, if the *    lowpass filter were a sinc function, Npc would be the index of the *    impulse-response lookup-table corresponding to the first zero- *    crossing of the sinc function.  (The inverse first zero-crossing *    time of a sinc function equals its nominal cutoff frequency in Hz.) *    Npc must be a power of 2 due to the details of the current *    implementation. The default value of 512 is sufficiently high that *    using linear interpolation to fill in between the table entries *    gives approximately 16-bit accuracy in filter coefficients. * * Nhc - is log base 2 of Npc. * * Na - is the number of bits devoted to linear interpolation of the *    filter coefficients. * * Np - is Na + Nhc, the number of bits to the right of the binary point *    in the integer "time" variable. To the left of the point, it indexes *    the input array (X), and to the right, it is interpreted as a number *    between 0 and 1 sample of the input X.  Np must be less than 16 in *    this implementation. * * Nh - is the number of bits in the filter coefficients. The sum of Nh and *    the number of bits in the input data (typically 16) cannot exceed 32. *    Thus Nh should be 16.  The largest filter coefficient should nearly *    fill 16 bits (32767). * * Nb - is the number of bits in the input data. The sum of Nb and Nh cannot *    exceed 32. * * Nhxn - is the number of bits to right shift after multiplying each input *    sample times a filter coefficient. It can be as great as Nh and as *    small as 0. Nhxn = Nh-2 gives 2 guard bits in the multiply-add *    accumulation.  If Nhxn=0, the accumulation will soon overflow 32 bits. * * Nhg - is the number of guard bits in mpy-add accumulation (equal to Nh-Nhxn) * * NLpScl - is the number of bits allocated to the unity-gain normalization *    factor.  The output of the lowpass filter is multiplied by LpScl and *    then right-shifted NLpScl bits. To avoid overflow, we must have *    Nb+Nhg+NLpScl < 32. */aflibConverter::aflibConverter(   bool  high_quality,   bool  linear_interpolation,   bool  filter_interpolation){	/* TODO put all these into an enum as it only makes sense to have 	 * one true at a time. - DAS	 */   interpFilt = filter_interpolation;   largeFilter = high_quality;   linearInterp = linear_interpolation;   _X = NULL;   _Y = NULL;   _vol = 1.0;}aflibConverter::~aflibConverter(){   deleteMemory();}voidaflibConverter::deleteMemory(){   int i;   // Delete memory for the input and output arrays   if (_X != NULL)   {      for (i = 0; i < _nChans; i++)      {         delete [] _X[i];         _X[i] = NULL;         delete [] _Y[i];         _Y[i] = NULL;      }      delete [] _X;      _X = NULL;      delete [] _Y;      _Y = NULL;   }}voidaflibConverter::initialize(   double fac,   int    channels,   double volume){// This function will allow one to stream data. When a new data stream is to// be input then this function should be called. Even if the factor and number// of channels don't change. Otherwise each new data block sent to resample// will be considered part of the previous data block. This function also allows// one to specified a multiplication factor to adjust the final output. This// applies to the small and large filter.   int i;   // Delete all previous allocated input and output buffer memory   deleteMemory();   _factor = fac;   _nChans = channels;   _initial = TRUE;   _vol = volume;   // Allocate all new memory   _X = new short * [_nChans];   _Y = new short * [_nChans];   for (i = 0; i < _nChans; i++)   {      // Add extra to allow of offset of input data (Xoff in main routine)      _X[i] = new short[IBUFFSIZE + 256];      _Y[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];      memset(_X[i], 0, sizeof(short) * (IBUFFSIZE + 256));       }}intaflibConverter::resample(       /* number of output samples returned */    int& inCount,               /* number of input samples to convert */    int outCount,               /* number of output samples to compute */    short inArray[],            /* input data */    short outArray[])           /* output data */{   int Ycount;   // Use fast method with no filtering. Poor quality   if (linearInterp == TRUE)      Ycount = resampleFast(inCount,outCount,inArray,outArray);   // Use small filtering. Good qulaity   else if (largeFilter == FALSE)      Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,         SMALL_FILTER_IMP, SMALL_FILTER_IMPD, 	(unsigned short)(SMALL_FILTER_SCALE * _vol),         SMALL_FILTER_NMULT, SMALL_FILTER_NWING);   // Use large filtering Great quality   else      Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,         LARGE_FILTER_IMP, LARGE_FILTER_IMPD, 	(unsigned short)(LARGE_FILTER_SCALE * _vol),         LARGE_FILTER_NMULT, LARGE_FILTER_NWING);                                  _initial = FALSE;   return (Ycount);}intaflibConverter::err_ret(char *s){    aflib_debug("resample: %s \n\n",s); /* Display error message  */    return -1;}intaflibConverter::readData(         int   inCount,       /* _total_ number of frames in input file */         short inArray[],     /* input data */         short *outPtr[],     /* array receiving chan samps */         int   dataArraySize, /* size of these arrays */         int   Xoff,          /* read into input array starting at this index */         bool  init_count) {   int    i, Nsamps, c;   static unsigned int framecount;  /* frames previously read */   short *ptr;   if (init_count == TRUE)      framecount = 0;       /* init this too */   Nsamps = dataArraySize - Xoff;   /* Calculate number of samples to get */   // Don't overrun input buffers   if (Nsamps > (inCount - (int)framecount))   {      Nsamps = inCount - framecount;   }   for (c = 0; c < _nChans; c++)   {      ptr = outPtr[c];      ptr += Xoff;        /* Start at designated sample number */      for (i = 0; i < Nsamps; i++)         *ptr++ = (short) inArray[c * inCount + i + framecount];   }   framecount += Nsamps;   if ((int)framecount >= inCount)            /* return index of last samp */      return (((Nsamps - (framecount - inCount)) - 1) + Xoff);   else      return 0;}intaflibConverter::SrcLinear(   short X[],   short Y[],   double factor,   unsigned int *Time,   unsigned short& Nx,   unsigned short Nout){	short iconst;	short *Xp, *Ystart;	int v,x1,x2;	double dt;                  /* Step through input signal */ 	unsigned int dtb;           /* Fixed-point version of Dt *///	unsigned int endTime;       /* When Time reaches EndTime, return to user */	unsigned int start_sample, end_sample;	dt = 1.0/factor;            /* Output sampling period */	dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */	start_sample = (*Time)>>Np;	Ystart = Y;//	endTime = *Time + (1<<Np)*(int)Nx;	/* 	* TODO	* DAS: not sure why this was changed from *Time < endTime	* update: *Time < endTime causes seg fault.  Also adds a clicking sound.	*/	while (Y - Ystart != Nout)//	while (*Time < endTime)	{		iconst = (*Time) & Pmask;		Xp = &X[(*Time)>>Np];      /* Ptr to current input sample */		x1 = *Xp++;		x2 = *Xp;		x1 *= ((1<<Np)-iconst);		x2 *= iconst;		v = x1 + x2;		*Y++ = WordToHword(v,Np);   /* Deposit output */		*Time += dtb;		    /* Move to next sample by time increment */	}	end_sample = (*Time)>>Np;	Nx = end_sample - start_sample;	return (Y - Ystart);            /* Return number of output samples */}intaflibConverter::SrcUp(   short X[],   short Y[],   double factor,   unsigned int *Time,   unsigned short& Nx,   unsigned short Nout,   unsigned short Nwing,   unsigned short LpScl,   short Imp[],   short ImpD[],   bool Interp){	short *Xp, *Ystart;	int v;	double dt;                  /* Step through input signal */ 	unsigned int dtb;           /* Fixed-point version of Dt *///	unsigned int endTime;       /* When Time reaches EndTime, return to user */	unsigned int start_sample, end_sample;	dt = 1.0/factor;            /* Output sampling period */	dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */	start_sample = (*Time)>>Np;	Ystart = Y;//	endTime = *Time + (1<<Np)*(int)Nx;	/* 	* TODO	* DAS: not sure why this was changed from *Time < endTime	* update: *Time < endTime causes seg fault.  Also adds a clicking sound.	*/	while (Y - Ystart != Nout)//	while (*Time < endTime)	{		Xp = &X[*Time>>Np];      /* Ptr to current input sample */		/* Perform left-wing inner product */		v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),-1);		/* Perform right-wing inner product */		v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1,                        (short)((((*Time)^Pmask)+1)&Pmask), 1);		v >>= Nhg;		/* Make guard bits */		v *= LpScl;		/* Normalize for unity filter gain */		*Y++ = WordToHword(v,NLpScl);   /* strip guard bits, deposit output */		*Time += dtb;		/* Move to next sample by time increment */	}	end_sample = (*Time)>>Np;	Nx = end_sample - start_sample;	return (Y - Ystart);        /* Return the number of output samples */}intaflibConverter::SrcUD(   short X[],   short Y[],   double factor,   unsigned int *Time,   unsigned short& Nx,   unsigned short Nout,   unsigned short Nwing,   unsigned short LpScl,   short Imp[],   short ImpD[],   bool Interp){	short *Xp, *Ystart;	int v;	double dh;                  /* Step through filter impulse response */	double dt;                  /* Step through input signal *///	unsigned int endTime;       /* When Time reaches EndTime, return to user */	unsigned int dhb, dtb;      /* Fixed-point versions of Dh,Dt */	unsigned int start_sample, end_sample;

⌨️ 快捷键说明

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