annotate wdf/upsample.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
tomwalters@0 3 ===========================================================================
tomwalters@0 4
tomwalters@0 5 Permission to use, copy, modify, and distribute this software without fee
tomwalters@0 6 is hereby granted for research purposes, provided that this copyright
tomwalters@0 7 notice appears in all copies and in all supporting documentation, and that
tomwalters@0 8 the software is not redistributed for any fee (except for a nominal shipping
tomwalters@0 9 charge). Anyone wanting to incorporate all or part of this software in a
tomwalters@0 10 commercial product must obtain a license from the Medical Research Council.
tomwalters@0 11
tomwalters@0 12 The MRC makes no representations about the suitability of this
tomwalters@0 13 software for any purpose. It is provided "as is" without express or implied
tomwalters@0 14 warranty.
tomwalters@0 15
tomwalters@0 16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
tomwalters@0 17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
tomwalters@0 18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
tomwalters@0 19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
tomwalters@0 20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
tomwalters@0 21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
tomwalters@0 22 */
tomwalters@0 23
tomwalters@0 24 /*
tomwalters@0 25 Acknowledgment:
tomwalters@0 26 ==============
tomwalters@0 27
tomwalters@0 28 The source code provided in this file was originally developed by
tomwalters@0 29 Christian Giguere as part of a Ph.D degree at the Department of
tomwalters@0 30 Engineering of the University of Cambridge from April 1990 to
tomwalters@0 31 November 1993. The code was subsequently adapted under a grant
tomwalters@0 32 from the Hearing Research Trust for full compatibility with
tomwalters@0 33 AIM Release 6.15.
tomwalters@0 34
tomwalters@0 35 Christian Giguere 25/03/94
tomwalters@0 36
tomwalters@0 37 */
tomwalters@0 38
tomwalters@0 39 /*
tomwalters@0 40 ===========================================================
tomwalters@0 41 upsample.c
tomwalters@0 42 ===========================================================
tomwalters@0 43
tomwalters@0 44 Upsampling module (FIR filter interpolation method).
tomwalters@0 45
tomwalters@0 46 Author : Christian Giguere
tomwalters@0 47 First written : 23rd November, 1990
tomwalters@0 48 Last edited : 09th February, 1994
tomwalters@0 49
tomwalters@0 50 Reference:
tomwalters@0 51 (1) L.R.Rabiner and R.W.Schafer (1978). Digital Processing of
tomwalters@0 52 Speech Signals (Prentice-Hall), Section 2.4.2.
tomwalters@0 53 ===========================================================
tomwalters@0 54 */
tomwalters@0 55
tomwalters@0 56 /***** includes *****/
tomwalters@0 57
tomwalters@0 58 #include <math.h>
tomwalters@0 59 #include <stdio.h>
tomwalters@0 60 #include "stitch.h"
tomwalters@0 61 #include "source.h"
tomwalters@0 62 #include "calc.h"
tomwalters@0 63 #include "calc_tl.h"
tomwalters@0 64 #include "fir.h"
tomwalters@0 65 #include "upsample.h"
tomwalters@0 66
tomwalters@0 67
tomwalters@0 68 /***** defines *****/
tomwalters@0 69
tomwalters@0 70 #define SEGMENT ( 2048 ) /* number of new points allocated and retained */
tomwalters@0 71 /* on each call to input source */
tomwalters@0 72
tomwalters@0 73
tomwalters@0 74 /***** functions *****/
tomwalters@0 75
tomwalters@0 76 /*******************************************************************************
tomwalters@0 77 * name: function:
tomwalters@0 78 *
tomwalters@0 79 * upsample_callback() Callable procedure returning pointer to upsampled data.
tomwalters@0 80 *
tomwalters@0 81 * UpSample() Setup and initialization function for the design of an
tomwalters@0 82 * FIR interpolation filter. Returns pointer to a new source.
tomwalters@0 83 ********************************************************************************/
tomwalters@0 84
tomwalters@0 85 struct _upsample_state {
tomwalters@0 86 struct _fillable_source parent ;
tomwalters@0 87 Source source ;
tomwalters@0 88 Pointer input ;
tomwalters@0 89 int iptr, inout_size ;
tomwalters@0 90 int zerocount, upsample_factor, sample_delay, active ;
tomwalters@0 91 void (*proc)(), (*close)() ;
tomwalters@0 92 FIRfilterState *states ;
tomwalters@0 93 } ;
tomwalters@0 94
tomwalters@0 95
tomwalters@0 96 /************************* upsample_callback() ******************************/
tomwalters@0 97
tomwalters@0 98 static Pointer upsample_callback( state, bytes, buffer )
tomwalters@0 99 struct _upsample_state *state ;
tomwalters@0 100 ByteCount *bytes ;
tomwalters@0 101 Pointer buffer ;
tomwalters@0 102 {
tomwalters@0 103 register DataType *optr, *eptr, *pstart ;
tomwalters@0 104 register int last = *bytes == 0 ;
tomwalters@0 105 register int points, bytecount ;
tomwalters@0 106
tomwalters@0 107 /***** process *****/
tomwalters@0 108 if( !last ) {
tomwalters@0 109
tomwalters@0 110 for( bytecount=0 ; bytecount<*bytes ; ) {
tomwalters@0 111
tomwalters@0 112 /*** get input data ***/
tomwalters@0 113 points = ( *bytes - bytecount ) / state->inout_size ;
tomwalters@0 114 points = MIN( points, state->upsample_factor * SEGMENT ) ;
tomwalters@0 115
tomwalters@0 116 if( !state->active ) {
tomwalters@0 117
tomwalters@0 118 if( state->sample_delay == 0 )
tomwalters@0 119 state->active = 1 ;
tomwalters@0 120
tomwalters@0 121 else if( state->sample_delay > points )
tomwalters@0 122 state->sample_delay -= points ;
tomwalters@0 123
tomwalters@0 124 else {
tomwalters@0 125 points = state->sample_delay ;
tomwalters@0 126 state->sample_delay = 0 ;
tomwalters@0 127 }
tomwalters@0 128 }
tomwalters@0 129
tomwalters@0 130 if( state->iptr + ( points - 1 ) / state->upsample_factor >= SEGMENT ) {
tomwalters@0 131 state->input = Pull( state->source, SEGMENT * state->inout_size ) ;
tomwalters@0 132 state->iptr -= SEGMENT ;
tomwalters@0 133 }
tomwalters@0 134
tomwalters@0 135 /*** fill output buffer with input points interspaced with zeros prior to FIR filtering ***/
tomwalters@0 136 pstart = ( DataType * ) state->input ;
tomwalters@0 137 optr = ( DataType * ) ( buffer + bytecount ) ;
tomwalters@0 138 eptr = optr + points ;
tomwalters@0 139
tomwalters@0 140 while( optr < eptr ) {
tomwalters@0 141
tomwalters@0 142 if( ( state->zerocount %= state->upsample_factor ) > 0 )
tomwalters@0 143 *optr++ = 0 ;
tomwalters@0 144
tomwalters@0 145 else
tomwalters@0 146 *optr++ = pstart[state->iptr++] ;
tomwalters@0 147
tomwalters@0 148 state->zerocount++ ;
tomwalters@0 149 }
tomwalters@0 150
tomwalters@0 151 /*** filter data ***/
tomwalters@0 152 state->proc( state->states, buffer+bytecount, points ) ;
tomwalters@0 153
tomwalters@0 154 /*** loop counts ***/
tomwalters@0 155 bytecount += points * state->inout_size * state->active ;
tomwalters@0 156 }
tomwalters@0 157
tomwalters@0 158 return ( buffer ) ;
tomwalters@0 159 }
tomwalters@0 160
tomwalters@0 161
tomwalters@0 162 /***** close *****/
tomwalters@0 163 else {
tomwalters@0 164 Pull( state->source, 0 ) ;
tomwalters@0 165 state->close( state->states ) ;
tomwalters@0 166
tomwalters@0 167 return ( DeleteFillableSource( state ) ) ;
tomwalters@0 168 }
tomwalters@0 169
tomwalters@0 170 }
tomwalters@0 171
tomwalters@0 172
tomwalters@0 173 /****************************** UpSample() **********************************/
tomwalters@0 174
tomwalters@0 175 Source UpSample( source, oldsamplerate, cutoff_freq, upsample_factor )
tomwalters@0 176 Source source ;
tomwalters@0 177 double oldsamplerate, cutoff_freq ;
tomwalters@0 178 int upsample_factor ;
tomwalters@0 179 {
tomwalters@0 180 DeclareNew( struct _upsample_state *, state ) ;
tomwalters@0 181 double filterGain, wc ;
tomwalters@0 182
tomwalters@0 183 /***** initialise input-related parameters *****/
tomwalters@0 184 state->inout_size = sizeof ( DataType ) ;
tomwalters@0 185 state->input = ( Pointer ) 0 ;
tomwalters@0 186 state->iptr = SEGMENT ;
tomwalters@0 187 state->source = NewRetainingSource( source, SEGMENT * state->inout_size ) ;
tomwalters@0 188 state->zerocount = 0 ;
tomwalters@0 189 state->upsample_factor = upsample_factor ;
tomwalters@0 190
tomwalters@0 191 /***** Specify FIR filter design parameters *****/
tomwalters@0 192 wc = cutoff_freq / ( state->upsample_factor * oldsamplerate ) * TwoPi ;
tomwalters@0 193 state->states = NewLpFIRfilter( wc, upsample_factor, &state->sample_delay ) ;
tomwalters@0 194 state->active = 0 ;
tomwalters@0 195 state->proc = DoFIRfilter ;
tomwalters@0 196 state->close = CloseFIRfilter ;
tomwalters@0 197
tomwalters@0 198 /***** return *****/
tomwalters@0 199 source = SetFillableSource( state, upsample_callback, "upsample buffering" ) ;
tomwalters@0 200 return ( source ) ;
tomwalters@0 201
tomwalters@0 202 }
tomwalters@0 203