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