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 phase.c
|
tomwalters@0
|
26 =======
|
tomwalters@0
|
27
|
tomwalters@0
|
28 looks after phase compensation of all filter types
|
tomwalters@0
|
29
|
tomwalters@0
|
30
|
tomwalters@0
|
31 */
|
tomwalters@0
|
32
|
tomwalters@0
|
33 #include "stitch.h"
|
tomwalters@0
|
34 #include "phase.h"
|
tomwalters@0
|
35
|
tomwalters@0
|
36
|
tomwalters@0
|
37 PhaseCompensatorState *NewPhaseCompensator( filter_state, filter_module, sample_delay )
|
tomwalters@0
|
38 FilterState filter_state ;
|
tomwalters@0
|
39 FilterModule filter_module ;
|
tomwalters@0
|
40 double sample_delay ;
|
tomwalters@0
|
41 {
|
tomwalters@0
|
42 DeclareNew( PhaseCompensatorState *, compensator_state ) ;
|
tomwalters@0
|
43
|
tomwalters@0
|
44 compensator_state->filter_state = filter_state ;
|
tomwalters@0
|
45 compensator_state->filter_module = filter_module ;
|
tomwalters@0
|
46 compensator_state->sample_delay = sample_delay + 0.5 ;
|
tomwalters@0
|
47
|
tomwalters@0
|
48 compensator_state->delay_buffer = ( Pointer ) 0 ;
|
tomwalters@0
|
49
|
tomwalters@0
|
50 return( compensator_state ) ;
|
tomwalters@0
|
51 }
|
tomwalters@0
|
52
|
tomwalters@0
|
53 PointCount PhaseCompensateFilter( compensator_state, input, output, points )
|
tomwalters@0
|
54 PhaseCompensatorState *compensator_state ;
|
tomwalters@0
|
55 Pointer input ;
|
tomwalters@0
|
56 Pointer output ;
|
tomwalters@0
|
57 PointCount points ;
|
tomwalters@0
|
58 {
|
tomwalters@0
|
59 unsigned output_size ;
|
tomwalters@0
|
60 int byte_delay, bytes ;
|
tomwalters@0
|
61 PointCount process ;
|
tomwalters@0
|
62 Pointer input_ptr ;
|
tomwalters@0
|
63 static int zero = 0 ;
|
tomwalters@0
|
64
|
tomwalters@0
|
65 /* support for new and old zero point transfers to get any remaining
|
tomwalters@0
|
66 data from filters - in short a mess */
|
tomwalters@0
|
67
|
tomwalters@0
|
68 if( compensator_state->sample_delay < 0 && ( input == ( Pointer ) 0 || points == 0 ) ) {
|
tomwalters@0
|
69 process = - ( int ) compensator_state->sample_delay ;
|
tomwalters@0
|
70
|
tomwalters@0
|
71 if( process > points && points != 0 )
|
tomwalters@0
|
72 process = points ;
|
tomwalters@0
|
73
|
tomwalters@0
|
74 compensator_state->sample_delay = ( int ) compensator_state->sample_delay + process ;
|
tomwalters@0
|
75
|
tomwalters@0
|
76 input_ptr = ( Pointer ) 0 ;
|
tomwalters@0
|
77 }
|
tomwalters@0
|
78 else {
|
tomwalters@0
|
79 process = points ;
|
tomwalters@0
|
80 input_ptr = input ;
|
tomwalters@0
|
81 }
|
tomwalters@0
|
82
|
tomwalters@0
|
83 /* call filter pod */
|
tomwalters@0
|
84
|
tomwalters@0
|
85 output_size = compensator_state->filter_module(
|
tomwalters@0
|
86 &compensator_state->filter_state,
|
tomwalters@0
|
87 &zero,
|
tomwalters@0
|
88 input_ptr,
|
tomwalters@0
|
89 output,
|
tomwalters@0
|
90 process,
|
tomwalters@0
|
91 1
|
tomwalters@0
|
92 ) ;
|
tomwalters@0
|
93
|
tomwalters@0
|
94 byte_delay = ( int ) compensator_state->sample_delay * output_size ;
|
tomwalters@0
|
95 bytes = points * output_size ;
|
tomwalters@0
|
96
|
tomwalters@0
|
97 if( compensator_state->delay_buffer == ( Pointer ) 0 )
|
tomwalters@0
|
98 if( ( int ) compensator_state->sample_delay < 0 ) {
|
tomwalters@0
|
99 stitch_bcopy( output - byte_delay, output, bytes - byte_delay ) ;
|
tomwalters@0
|
100 compensator_state->delay_buffer = ( Pointer ) 0 + 1 ;
|
tomwalters@0
|
101
|
tomwalters@0
|
102 return( points + ( int ) compensator_state->sample_delay ) ;
|
tomwalters@0
|
103 }
|
tomwalters@0
|
104 else
|
tomwalters@0
|
105 compensator_state->delay_buffer = stitch_calloc(
|
tomwalters@0
|
106 ( unsigned ) compensator_state->sample_delay * 2,
|
tomwalters@0
|
107 output_size, "phase.c for delay buffer\n" ) ;
|
tomwalters@0
|
108
|
tomwalters@0
|
109 if( byte_delay > bytes ) {
|
tomwalters@0
|
110 stitch_bcopy( output, compensator_state->delay_buffer + byte_delay, bytes ) ;
|
tomwalters@0
|
111 stitch_bcopy( compensator_state->delay_buffer, output, bytes ) ;
|
tomwalters@0
|
112 stitch_bcopy( compensator_state->delay_buffer + bytes, compensator_state->delay_buffer, byte_delay ) ;
|
tomwalters@0
|
113 }
|
tomwalters@0
|
114 else if( byte_delay > 0 ) {
|
tomwalters@0
|
115 stitch_bcopy( output + bytes - byte_delay, compensator_state->delay_buffer + byte_delay, byte_delay ) ;
|
tomwalters@0
|
116 stitch_bcopy( output, output + byte_delay, bytes - byte_delay ) ;
|
tomwalters@0
|
117 stitch_bcopy( compensator_state->delay_buffer, output, byte_delay ) ;
|
tomwalters@0
|
118 stitch_bcopy( compensator_state->delay_buffer + byte_delay, compensator_state->delay_buffer, byte_delay ) ;
|
tomwalters@0
|
119 }
|
tomwalters@0
|
120
|
tomwalters@0
|
121 return( process ) ;
|
tomwalters@0
|
122 }
|
tomwalters@0
|
123
|
tomwalters@0
|
124 void FreeCompensatedFilter( compensator_state )
|
tomwalters@0
|
125 PhaseCompensatorState *compensator_state ;
|
tomwalters@0
|
126 {
|
tomwalters@0
|
127 stitch_free( compensator_state->filter_state ) ;
|
tomwalters@0
|
128 stitch_free( ( Pointer ) compensator_state ) ;
|
tomwalters@0
|
129
|
tomwalters@0
|
130 return ;
|
tomwalters@0
|
131 }
|
tomwalters@0
|
132
|