tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE tomwalters@0: A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY tomwalters@0: DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN tomwalters@0: AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF tomwalters@0: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: tomwalters@0: ==================================================================== tomwalters@0: gamma_tone.c - backward compatable interface to new filter release tomwalters@0: ==================================================================== tomwalters@0: tomwalters@0: J. Holdsworth - 28th January 1989. tomwalters@0: tomwalters@0: tomwalters@0: Copywright (c) Applied Psychology Unit, Medical Research Council. 1989. tomwalters@0: ======================================================================= tomwalters@0: tomwalters@0: tomwalters@0: Release 2: 5th July 1988. tomwalters@0: Release 3: 20th September 1988. tomwalters@0: Release 4: 28th January 1989. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: tomwalters@0: #ifndef _STITCH_H_ tomwalters@0: #include "stitch.h" tomwalters@0: #endif tomwalters@0: #ifndef _GAMMA_TONE_H_ tomwalters@0: #include "gamma_tone.h" tomwalters@0: #endif tomwalters@0: #ifndef _FORMULAE_H_ tomwalters@0: #include "formulae.h" tomwalters@0: #endif tomwalters@0: #ifndef _RECURSE_H_ tomwalters@0: #include "recurse.h" tomwalters@0: #endif tomwalters@0: #ifndef _SCALES_H_ tomwalters@0: #include "scales.h" tomwalters@0: #endif tomwalters@0: #ifndef _PHASE_H_ tomwalters@0: #include "phase.h" tomwalters@0: #endif tomwalters@0: tomwalters@0: /* identify object file */ tomwalters@0: tomwalters@0: #ifndef lint tomwalters@0: static char *gt_object_ident = GT_IDENT_STRING ; tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: /* base center frequency */ tomwalters@0: tomwalters@0: #define Pi ( 3.1415926535 ) tomwalters@0: #define TwoPi ( 2*Pi ) tomwalters@0: tomwalters@0: double bankBaseFrequency = 1000. ; tomwalters@0: double filterDefaultGain = 4. ; tomwalters@0: int filterDefaultInputBits = bits_significant ; tomwalters@0: tomwalters@0: tomwalters@0: /* generate array of filter center frequencies between the frequencies specified */ tomwalters@0: tomwalters@0: double *GenerateCenterFrequencies( min_cf, max_cf, erb_density ) tomwalters@0: double min_cf, max_cf, erb_density ; tomwalters@0: { tomwalters@0: return ( GenerateScale( ErbScale( min_cf ), ErbScale( max_cf ), erb_density, ErbScale( bankBaseFrequency ), FofErbScale ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: int NumberCenterFrequencies( min_cf, max_cf, erb_density ) tomwalters@0: double min_cf, max_cf, erb_density ; tomwalters@0: { tomwalters@0: return ( NumberOnScale( ErbScale( min_cf ), ErbScale( max_cf ), erb_density, ErbScale( bankBaseFrequency ) ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: double *NumberedCenterFrequencies( min_cf, max_cf, channels ) tomwalters@0: double min_cf, max_cf ; tomwalters@0: int channels ; tomwalters@0: { tomwalters@0: return ( NumberedScale( ErbScale( min_cf ), ErbScale( max_cf ), channels, FofErbScale ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* initialise gamma tone filter code */ tomwalters@0: tomwalters@0: FilterBankInfo *InitGammaToneFilterBank( samplerate, order, b_scalar, phase_comp, min_filter_cf ) tomwalters@0: double samplerate ; tomwalters@0: int order ; tomwalters@0: double b_scalar ; tomwalters@0: int phase_comp ; tomwalters@0: double min_filter_cf ; tomwalters@0: { tomwalters@0: DeclareNew( FilterBankInfo *, filter_info ) ; tomwalters@0: extern int n_using_sin_table ; tomwalters@0: tomwalters@0: filter_info->samplerate = samplerate ; tomwalters@0: filter_info->order = order ; tomwalters@0: filter_info->b_scalar = b_scalar ; tomwalters@0: filter_info->phase_comp = phase_comp ; tomwalters@0: tomwalters@0: /* store maximum required time shift for whole filter bank */ tomwalters@0: /* originally time advance was implemented as delay of */ tomwalters@0: /* maximum advance minus desired advance (still supported) */ tomwalters@0: tomwalters@0: if( filter_info->phase_comp >= 0 ) tomwalters@0: filter_info->max_desired_advance_time = 1. / min_filter_cf * filter_info->phase_comp ; tomwalters@0: else tomwalters@0: filter_info->max_desired_advance_time = ( filter_info->order - 1. ) / ( TwoPi * filter_info->b_scalar * Erb( min_filter_cf ) ) ; tomwalters@0: tomwalters@0: return ( filter_info ) ; tomwalters@0: } tomwalters@0: tomwalters@0: FilterChannelInfo *InitGammaToneFilterChannel( filter_info, cf ) tomwalters@0: FilterBankInfo *filter_info ; tomwalters@0: double cf ; tomwalters@0: { tomwalters@0: RecursiveFilterState *filter_state ; tomwalters@0: double sample_delay ; tomwalters@0: tomwalters@0: if( filter_info->phase_comp > 0 || filter_info->phase_comp == ENVELOPE_ALIGNMENT || filter_info->phase_comp == FINE_ALIGNMENT ) tomwalters@0: sample_delay = filter_info->max_desired_advance_time * filter_info->samplerate ; tomwalters@0: else tomwalters@0: sample_delay = 0. ; tomwalters@0: tomwalters@0: filter_state = NewRecursiveFilter( tomwalters@0: filter_info->samplerate, tomwalters@0: cf, tomwalters@0: Erb( cf ) * filter_info->b_scalar, tomwalters@0: filterDefaultGain, tomwalters@0: filter_info->order, tomwalters@0: filter_info->phase_comp, tomwalters@0: filterDefaultInputBits, tomwalters@0: & sample_delay ) ; tomwalters@0: tomwalters@0: return( ( FilterChannelInfo * ) NewPhaseCompensator( tomwalters@0: ( FilterState ) filter_state, tomwalters@0: ( FilterModule ) 0, tomwalters@0: sample_delay ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* end processing of channel - free state varibales */ tomwalters@0: tomwalters@0: void EndChannel( channel_info ) tomwalters@0: FilterChannelInfo *channel_info ; tomwalters@0: { tomwalters@0: FreeCompensatedFilter( ( PhaseCompensatorState * ) channel_info ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: /* free up filter state variables and sin table if finished with it */ tomwalters@0: tomwalters@0: void EndFilter( filter_info ) tomwalters@0: FilterBankInfo *filter_info ; tomwalters@0: { tomwalters@0: Delete( filter_info ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: