1
$\begingroup$

I am trying to write a function which takes an input signal and delays it by a non-integer index. The function is based on the ideal bandlimited fractional delay filter technique, already available in Matlab, by calling the function designFracDelayFIR.

I really do not understand why the output signal, instead of being a delayed version of the input signal is a scaled version of it, with much lower amplitude. Also, the scaling factor seems to depend on the fractional delay used.

The input sequence is an audio signal of 4000 samples, at sampling frequency Fs=8 kHz.

The code below shows the function implementation

function [y] = fractionaDelaySequence(fd,x)

%design fractional delay filter
[h,i0,bw] = designFracDelayFIR(fd)
fdf = dsp.FIRFilter(h);

y = fdf(x);

subplot(2,1,1);
stem(x(1:256));
title('Input Sequence');
xlabel('n')
subplot(2,1,2)
stem(y(1:256));
title('FIR Output Sequence');
xlabel('n')

end

EDIT: As a further test, I gave the function as signal input a unit impulse constructed by a 1 followed by a 1023 zeros, and set fd=1/3. I would expect to have as output the same impulse delayed by the desired amount, but instead I get a non-delayed and scaled down version of the input, as depicted in the figure below. The function returns i0=24 and bw=0.9033.

enter image description here

enter image description here

$\endgroup$
6
  • $\begingroup$ I don't have access to the DSP System Tool box. I suggest you run this code with a unit impulse of length 1024 as an input signal, plot input and output and after, add the graphs to you question and explain (using the graphs) what specifically you don't understand. Frist rule of debugging: start with something simple that you already know the answer to. $\endgroup$
    – Hilmar
    Commented Mar 2, 2022 at 12:56
  • $\begingroup$ This does indeed look wrong. Can you just plot the impulse response h? What is your input argument fd. What are the values of the other outputs i0 and bw ? $\endgroup$
    – Hilmar
    Commented Mar 2, 2022 at 14:01
  • $\begingroup$ Your impulse response looks fine, the problem is probably with the filter operation. Try y = filter(h,1,x) instead. $\endgroup$
    – Hilmar
    Commented Mar 2, 2022 at 15:23
  • $\begingroup$ filter function solves the problem! Does this means Matlab dsp.FIRFilter module is broken ? $\endgroup$ Commented Mar 2, 2022 at 15:26
  • $\begingroup$ I get the same issue. Looks like a bug in dsp.FIRFilter. I've added a bug report on the MathWorks website. $\endgroup$
    – Peter K.
    Commented Mar 2, 2022 at 15:28

4 Answers 4

2
$\begingroup$

The MathWorks got back to me.

The issue is that dsp.FIRFilter expects the signal to be a column vector.

If I do

x = [1 ones(1,1023)]';
fd = 1/3;

%design fractional delay filter
[h,i0,bw] = designFracDelayFIR(fd);
fdf = dsp.FIRFilter(h);

y = fdf(x);

subplot(2,1,1);
stem(x(1:256));
title('Input Sequence');
xlabel('n')
subplot(2,1,2)
stem(y(1:256));
title('FIR Output Sequence');
xlabel('n')

ensuring that x is a column vector, then the result is as below (which is expected).

Revised output

$\endgroup$
2
  • $\begingroup$ What is the motivation for x = [1 ones(1,1023)]'? $\endgroup$ Commented Mar 6, 2022 at 22:11
  • 1
    $\begingroup$ @LaurentDuval I was mistypeing [1 zeros(1,1023)] :-) $\endgroup$
    – Peter K.
    Commented Mar 6, 2022 at 23:14
1
$\begingroup$

It seems that the Matlab module dsp.FIRFilter has a bug, and the solution is to replace

y = fdf(x);

with

y = filter(h,1,x)

Thanks to @Hilmar for his support.

$\endgroup$
1
$\begingroup$

As asked by a commenter here is quick write up of the comments that helped solving the problem.

For general usefulness we treat this as "My code is not doing what I expect, how do I debug this?"

  1. Start with a simple input signal where the answer is already known
  2. Compare step by step against a known good reference, do NOT go the next step until all previous steps have been fully verified

In this particular case we

  1. Simplified the input to a simple delta
  2. verfied that the fractional delay impulse response looked "plausible".
  3. Compared the filter operation to a known good reference filter()

Turns out it was item three, something appears to be wrong with the dsp.FIRFilter() class. It's either a bug in the code or the documentation.

$\endgroup$
0
$\begingroup$

I think you need to use column vector instead of row vector. DSP treats each columns as single channels.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.