|
1 |
| -function sig = delayline(sig,dt,weight,conf) |
| 1 | +function [sig,delay_offset] = delayline(sig,dt,weight,conf) |
2 | 2 | %DELAYLINE implements a (fractional) delay line with weights
|
3 | 3 | %
|
4 |
| -% Usage: sig = delayline(sig,dt,weight,conf) |
| 4 | +% Usage: [sig,delay_offset] = delayline(sig,dt,weight,conf) |
5 | 5 | %
|
6 | 6 | % Input parameter:
|
7 | 7 | % sig - input signal (vector), can be in the form of [N C], or
|
|
17 | 17 | % conf - configuration struct (see SFS_config).
|
18 | 18 | %
|
19 | 19 | % Output parameter:
|
20 |
| -% sig - delayed signal |
| 20 | +% sig - delayed signal |
| 21 | +% delay_offset - additional delay, added by the fractional delayline |
| 22 | +% filters to all channels. For integer delays this is 0. |
21 | 23 | %
|
22 | 24 | % DELAYLINE(sig,dt,weight,conf) implementes a delayline, that delays the given
|
23 | 25 | % signal by dt samples and applies an amplitude weighting factor. The delay is
|
|
100 | 102 | switch delay.resampling
|
101 | 103 | case 'none'
|
102 | 104 | rfactor = 1.0;
|
| 105 | + delay_offset = 0.0; |
103 | 106 | case 'matlab'
|
104 | 107 | rfactor = delay.resamplingfactor;
|
| 108 | + delay_offset = 0.0; |
105 | 109 | sig = resample(sig,rfactor,1);
|
106 | 110 | case 'pm'
|
107 | 111 | % === Parks-McClellan linear phase FIR filter ===
|
108 | 112 | rfactor = delay.resamplingfactor;
|
| 113 | + delay_offset = delay.resamplingorder / 2; |
109 | 114 | a = [1 1 0 0];
|
110 | 115 | f = [0.0 0.9/rfactor 1/rfactor 1.0];
|
111 | 116 | b = firpm(delay.resamplingorder,f,a);
|
|
128 | 133 | case 'integer'
|
129 | 134 | % === Integer delays ===
|
130 | 135 | idt = ceil(dt); % round up to next integer delay
|
| 136 | + delay_offset = delay_offset + 0; |
131 | 137 | case 'lagrange'
|
132 | 138 | % === Lagrange polynomial interpolator ===
|
133 | 139 | if iseven(delay.filterorder)
|
|
138 | 144 | fdt = dt - idt; % fractional part of delays
|
139 | 145 | b = lagrange_filter(delay.filterorder,fdt);
|
140 | 146 | a = ones(1,channels);
|
| 147 | + delay_offset = delay_offset + delay.filterorder / 2; |
141 | 148 | case 'thiran'
|
142 | 149 | % === Thiran's allpass filter for maximally flat group delay ===
|
143 | 150 | idt = round(dt); % integer part of delays
|
144 | 151 | fdt = dt - idt; % fractional part of delays
|
145 | 152 | [b,a] = thiran_filter(delay.filterorder,fdt);
|
| 153 | + delay_offset = delay_offset + delay.filterorder; |
146 | 154 | case 'least_squares'
|
147 | 155 | % ==== Least squares interpolation filter ===
|
148 | 156 | idt = floor(dt); % integer part of delays
|
|
152 | 160 | b(:,ii) = general_least_squares(delay.filterorder+1,fdt(ii),0.90);
|
153 | 161 | end
|
154 | 162 | a = ones(1,channels);
|
| 163 | + delay_offset = delay_offset + delay.filterorder / 2; |
155 | 164 | case 'farrow'
|
156 | 165 | % === Farrow-structure ===
|
157 | 166 | % Based on the assumption, that each coefficient h(n) of the fractional
|
|
207 | 216 | %% ===== Postprocessing ==================================================
|
208 | 217 | % --- Downsampling ---
|
209 | 218 | if rfactor~=1
|
210 |
| - sig = sig(1:rfactor:samples,:); |
| 219 | + sig = sig(1:rfactor:samples,:); |
| 220 | + delay_offset = delay_offset ./ rfactor; |
211 | 221 | end
|
212 | 222 | % --- Undo reshape ---
|
213 | 223 | % [N M*C] => [M C N]
|
|
0 commit comments