tomwalters@0
|
1 /*
|
tomwalters@0
|
2 integrate.c
|
tomwalters@0
|
3 ===========
|
tomwalters@0
|
4
|
tomwalters@0
|
5 */
|
tomwalters@0
|
6
|
tomwalters@0
|
7 #include <math.h>
|
tomwalters@0
|
8
|
tomwalters@0
|
9 #include "stitch.h"
|
tomwalters@0
|
10 #include "source.h"
|
tomwalters@0
|
11 #include "calc.h"
|
tomwalters@0
|
12
|
tomwalters@0
|
13 #include "integrate.h"
|
tomwalters@0
|
14
|
tomwalters@0
|
15
|
tomwalters@0
|
16 struct _integral_state { ScalarType state, upward, downward, igain ; } ;
|
tomwalters@0
|
17
|
tomwalters@0
|
18 static int new_integral_callback( state, buffer, end, input, skip )
|
tomwalters@0
|
19 struct _integral_state *state ;
|
tomwalters@0
|
20 DataType *buffer, *end, *input ;
|
tomwalters@0
|
21 int skip ;
|
tomwalters@0
|
22 {
|
tomwalters@0
|
23 register struct _integral_state *sptr = state ;
|
tomwalters@0
|
24 register DataType *iptr = input ;
|
tomwalters@0
|
25 register DataType *optr = buffer ;
|
tomwalters@0
|
26 register DataType *eptr = end ;
|
tomwalters@0
|
27
|
tomwalters@0
|
28 while( optr < eptr ) {
|
tomwalters@0
|
29
|
tomwalters@0
|
30 /* the more accurate later version */
|
tomwalters@0
|
31
|
tomwalters@0
|
32 *optr = DESCALE( sptr->state ) ;
|
tomwalters@0
|
33
|
tomwalters@0
|
34 sptr->state += sptr->upward * DESCALE( *iptr * sptr->igain - sptr->state ) ;
|
tomwalters@0
|
35
|
tomwalters@0
|
36 iptr += skip ;
|
tomwalters@0
|
37 optr += skip ;
|
tomwalters@0
|
38 }
|
tomwalters@0
|
39
|
tomwalters@0
|
40 return ( sizeof ( DataType ) ) ;
|
tomwalters@0
|
41 }
|
tomwalters@0
|
42
|
tomwalters@0
|
43 static int old_integral_callback( state, buffer, end, input, skip )
|
tomwalters@0
|
44 struct _integral_state *state ;
|
tomwalters@0
|
45 DataType *buffer, *end, *input ;
|
tomwalters@0
|
46 int skip ;
|
tomwalters@0
|
47 {
|
tomwalters@0
|
48 register struct _integral_state *sptr = state ;
|
tomwalters@0
|
49 register DataType *iptr = input ;
|
tomwalters@0
|
50 register DataType *optr = buffer ;
|
tomwalters@0
|
51 register DataType *eptr = end ;
|
tomwalters@0
|
52
|
tomwalters@0
|
53 while( optr < eptr ) {
|
tomwalters@0
|
54
|
tomwalters@0
|
55 /* the "interesting" one */
|
tomwalters@0
|
56
|
tomwalters@0
|
57 *optr = sptr->state ;
|
tomwalters@0
|
58 sptr->state += DESCALE( sptr->upward * ( DESCALE( *iptr * sptr->igain ) - sptr->state ) ) ;
|
tomwalters@0
|
59
|
tomwalters@0
|
60 iptr += skip ;
|
tomwalters@0
|
61 optr += skip ;
|
tomwalters@0
|
62 }
|
tomwalters@0
|
63
|
tomwalters@0
|
64 return ( sizeof ( DataType ) ) ;
|
tomwalters@0
|
65 }
|
tomwalters@0
|
66
|
tomwalters@0
|
67 static void integral_close( state )
|
tomwalters@0
|
68 struct _integral_state *state ;
|
tomwalters@0
|
69 {
|
tomwalters@0
|
70 Delete( state ) ;
|
tomwalters@0
|
71
|
tomwalters@0
|
72 return ;
|
tomwalters@0
|
73 }
|
tomwalters@0
|
74
|
tomwalters@0
|
75 Source LowpassDataTypeSource( source, stages, channels, upward, downward, igain )
|
tomwalters@0
|
76 Source source ;
|
tomwalters@0
|
77 int stages, channels ;
|
tomwalters@0
|
78 double upward, downward, igain ;
|
tomwalters@0
|
79 {
|
tomwalters@0
|
80 struct _integral_state **states ;
|
tomwalters@0
|
81 int stage, chan ;
|
tomwalters@0
|
82
|
tomwalters@0
|
83 for( stage=0 ; stage < abs( stages ) ; stage++ ) {
|
tomwalters@0
|
84
|
tomwalters@0
|
85 states = NewArray( struct _integral_state *, channels, "for states" ) ;
|
tomwalters@0
|
86
|
tomwalters@0
|
87 for( chan=0 ; chan<channels ; chan++ ) {
|
tomwalters@0
|
88
|
tomwalters@0
|
89 states[chan] = New( struct _integral_state * ) ;
|
tomwalters@0
|
90
|
tomwalters@0
|
91 states[chan]->state = 0 ;
|
tomwalters@0
|
92 states[chan]->upward = SCALAR( 1. - exp( -1. / upward ) ) ;
|
tomwalters@0
|
93 states[chan]->downward = SCALAR( 1. - exp( -1. / downward ) ) ;
|
tomwalters@0
|
94 states[chan]->igain = SCALAR( igain ) ;
|
tomwalters@0
|
95
|
tomwalters@0
|
96 }
|
tomwalters@0
|
97
|
tomwalters@0
|
98 if( stages > 0 )
|
tomwalters@0
|
99 source = NewMultiplexedSource( states, new_integral_callback, integral_close, channels, source, "integrate.c integration" ) ;
|
tomwalters@0
|
100 else
|
tomwalters@0
|
101 source = NewMultiplexedSource( states, old_integral_callback, integral_close, channels, source, "integrate.c integration" ) ;
|
tomwalters@0
|
102 }
|
tomwalters@0
|
103
|
tomwalters@0
|
104 return ( source ) ;
|
tomwalters@0
|
105 }
|
tomwalters@0
|
106
|
tomwalters@0
|
107
|
tomwalters@0
|
108
|
tomwalters@0
|
109
|
tomwalters@0
|
110
|
tomwalters@0
|
111 struct _blocksample_state { struct _fillable_source parent ; Source source ; int spacing, channels ; } ;
|
tomwalters@0
|
112
|
tomwalters@0
|
113 static Pointer blocksample_callback( state, bytes, buffer )
|
tomwalters@0
|
114 struct _blocksample_state *state ;
|
tomwalters@0
|
115 ByteCount *bytes ;
|
tomwalters@0
|
116 DataType *buffer ;
|
tomwalters@0
|
117 {
|
tomwalters@0
|
118 register int last = *bytes == 0 ;
|
tomwalters@0
|
119 register StoreType sum ;
|
tomwalters@0
|
120 register DataType *iptr ;
|
tomwalters@0
|
121 register DataType *input = (DataType *) Pull( state->source, *bytes * state->spacing ) ;
|
tomwalters@0
|
122 register DataType *end = (DataType *) ( (Pointer) input + *bytes * state->spacing ) ;
|
tomwalters@0
|
123 int channel ;
|
tomwalters@0
|
124
|
tomwalters@0
|
125 for( channel=0 ; channel<state->channels ; channel++ ) {
|
tomwalters@0
|
126
|
tomwalters@0
|
127 sum=0 ;
|
tomwalters@0
|
128
|
tomwalters@0
|
129 for( iptr=input+channel ; iptr < end ; iptr += state->channels )
|
tomwalters@0
|
130 sum += *iptr ;
|
tomwalters@0
|
131
|
tomwalters@0
|
132 buffer[channel] = sum / state->spacing ;
|
tomwalters@0
|
133 }
|
tomwalters@0
|
134
|
tomwalters@0
|
135 if( !last )
|
tomwalters@0
|
136 return ( (Pointer) buffer ) ;
|
tomwalters@0
|
137 else
|
tomwalters@0
|
138 return ( DeleteFillableSource( state ) ) ;
|
tomwalters@0
|
139 }
|
tomwalters@0
|
140
|
tomwalters@0
|
141 Source BlockSampleSource( source, spacing, channels )
|
tomwalters@0
|
142 Source source ;
|
tomwalters@0
|
143 int spacing, channels ;
|
tomwalters@0
|
144 {
|
tomwalters@0
|
145 DeclareNew( struct _blocksample_state *, state ) ;
|
tomwalters@0
|
146
|
tomwalters@0
|
147 state->source = source ;
|
tomwalters@0
|
148 state->spacing = spacing ;
|
tomwalters@0
|
149 state->channels = channels ;
|
tomwalters@0
|
150
|
tomwalters@0
|
151 source = SetFillableSource( state, blocksample_callback, "integrate.c block sampling" ) ;
|
tomwalters@0
|
152
|
tomwalters@0
|
153 source = NewSegmentingSource( source, channels * sizeof ( DataType ) ) ;
|
tomwalters@0
|
154
|
tomwalters@0
|
155 return ( source ) ;
|
tomwalters@0
|
156 }
|
tomwalters@0
|
157
|
tomwalters@0
|
158
|
tomwalters@0
|
159 struct _downsample_state { struct _pullable_source parent ; Source source ; int spacing, channels ; } ;
|
tomwalters@0
|
160
|
tomwalters@0
|
161 static Pointer downsample_callback( state, bytes )
|
tomwalters@0
|
162 struct _downsample_state *state ;
|
tomwalters@0
|
163 ByteCount *bytes ;
|
tomwalters@0
|
164 {
|
tomwalters@0
|
165 register int last = *bytes == 0 ;
|
tomwalters@0
|
166 Pointer output = Pull( state->source, *bytes * state->spacing ) + *bytes * state->spacing - state->channels * sizeof ( DataType ) ;
|
tomwalters@0
|
167
|
tomwalters@0
|
168 if( !last )
|
tomwalters@0
|
169 return ( output ) ;
|
tomwalters@0
|
170 else
|
tomwalters@0
|
171 return ( DeletePullableSource( state ) ) ;
|
tomwalters@0
|
172 }
|
tomwalters@0
|
173
|
tomwalters@0
|
174 Source DownSampleSource( source, spacing, channels )
|
tomwalters@0
|
175 Source source ;
|
tomwalters@0
|
176 int spacing, channels ;
|
tomwalters@0
|
177 {
|
tomwalters@0
|
178 DeclareNew( struct _downsample_state *, state ) ;
|
tomwalters@0
|
179
|
tomwalters@0
|
180 state->source = source ;
|
tomwalters@0
|
181 state->spacing = spacing ;
|
tomwalters@0
|
182 state->channels = channels ;
|
tomwalters@0
|
183
|
tomwalters@0
|
184 source = SetPullableSource( state, downsample_callback, "integrate.c down sampling" ) ;
|
tomwalters@0
|
185
|
tomwalters@0
|
186 source = NewSegmentingSource( source, channels * sizeof ( DataType ) ) ;
|
tomwalters@0
|
187
|
tomwalters@0
|
188 return ( source ) ;
|
tomwalters@0
|
189 }
|
tomwalters@0
|
190
|