Figure 1 depicts a linear system characterized by an impulse
response h(n)h(n), driven by an input signal s(n)s(n), and producing the
output signal r(n)r(n). The system identification problem is to
estimate h(n)h(n) given known input/output signals s(n)s(n) and r(n)r(n). A
practical method for identifying finite impulse responses is the
Golay-code measurement technique, described below. Maximum length sequences may be alternatively used for this type of measurement, as they are also noise signals consisting of 1's and -1's, but perfectly inverse filtering the measurement is more computationally intensive.
The length LL bilevel sequences a(n)a(n) and b(n)b(n) are Golay if
and only if the following condition holds, where ¤¤ denotes the
autocorrelation operator Entry 1:
a
(
n
)
¤
a
(
n
)
+
b
(
n
)
¤
b
(
n
)
=
2
L
δ
(
n
)
a
(
n
)
¤
a
(
n
)
+
b
(
n
)
¤
b
(
n
)
=
2
L
δ
(
n
)
(1)
and δ(n)δ(n) is the Kronecker delta function. Recall that
(Equation 1) can also be written using **, the convolution
operator:
a
(
-
n
)
*
a
(
n
)
+
b
(
-
n
)
*
b
(
n
)
=
2
L
δ
(
n
)
a
(
-
n
)
*
a
(
n
)
+
b
(
-
n
)
*
b
(
n
)
=
2
L
δ
(
n
)
(2)
Given that aL(n)aL(n) and bL(n)bL(n) are Golay, it turns out that
a2L(n)=[aL(n)bL(n)]a2L(n)=[aL(n)bL(n)] and
b2L(n)=[aL(n)-bL(n)]b2L(n)=[aL(n)-bL(n)] are also Golay. This means
that Golay sequences can be constructed recursively given Golay seed
sequences such as a2(n)=[11]a2(n)=[11] and
b2(n)=[1-1]b2(n)=[1-1]. See the
MATLAB/Octave source code generate_golay.m
for details. Notice also that the resulting bilevel sequences consist
of only 1's and -1-1's. This means that the signal contains the
maximum possible power level given that |s(n)|≤1∀n|s(n)|≤1∀n.
This property is helpful for minimizing measurement noise.
Let ra(n)=a(n)*h(n)ra(n)=a(n)*h(n) be the response due to the Golay code input
a(n)a(n), and let rb(n)=b(n)*h(n)rb(n)=b(n)*h(n) be the response due to the Golay code input
b(n)b(n). Due to (Equation 1), the impulse response h(n)h(n) may be
determined as follows:
h
(
n
)
=
1
2
L
(
a
(
n
)
¤
r
a
(
n
)
+
b
(
n
)
¤
r
b
(
n
)
)
h
(
n
)
=
1
2
L
(
a
(
n
)
¤
r
a
(
n
)
+
b
(
n
)
¤
r
b
(
n
)
)
(3)
See
golay_response.m
for more details.
- Generate the Golay codes
golayA.wav
and
golayB.wav
using
generate_golay.m.
- Open the pd
patch
golay.pd,
in pd.
- Ensure that the patch is not in editing mode, and check the
“compute audio” box in the main pd
window.
- Adjust the “Output Volume” so that when you click on “Record
Response to Golay A”, the system under test is behaving linearly
(i.e. not clipping), but so that the input signal to the sound
interface is not too noisy.
- If there is an input volume on the sound interface, adjust it so
that the levels approximately match those shown in Figure 2
when you click on “Record Response to Golay A” and “Record
Response to Golay B.” If the sound interface has no input volume,
then you will need to adjust the “Output Volume” accordingly.
- Once you are satisfied with the results, click the “Write Responses
to Disk” button.
- pd
will write the files RespA.wav
and
RespB.wav
to disk. Rename these files so that the names
match the measurement you just made. For instance, you might rename
them to
hpfRespA.wav
and
hpfRespB.wav
if they corresponded to the measurement of a high-pass filter.
- Run
golay_response('hpf')
in
MATLAB
or
Octave
to analyze the measured response.
Plots will be created, and the file
hpfImpResp.wav
will be written to disk.
-
Abel, J. and Berners, D. (2005). Signal Processing Techniques for Digital Audio Effects. http://ccrma.stanford.edu/courses/424/.