<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/cnxml/0.5/DTD/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" xmlns:md="http://cnx.rice.edu/mdml/0.4" id="id2255528">
  <name>Golay Code Impulse Response Measurement</name>
  <metadata>
  <md:version>1.8</md:version>
  <md:created>2008/03/28 13:21:41 GMT-5</md:created>
  <md:revised>2008/06/23 11:25:01.785 GMT-5</md:revised>
  <md:authorlist>
      <md:author id="eberdahl">
      <md:firstname>Edgar</md:firstname>
      <md:othername>Joseph</md:othername>
      <md:surname>Berdahl</md:surname>
      <md:email>eberdahl@stanford.edu</md:email>
    </md:author>
      <md:author id="jos">
      <md:firstname>Julius</md:firstname>
      <md:othername>O.</md:othername>
      <md:surname>Smith</md:surname>
      <md:email>jos@ccrma.stanford.edu</md:email>
    </md:author>
  </md:authorlist>

  <md:maintainerlist>
    <md:maintainer id="eberdahl">
      <md:firstname>Edgar</md:firstname>
      <md:othername>Joseph</md:othername>
      <md:surname>Berdahl</md:surname>
      <md:email>eberdahl@stanford.edu</md:email>
    </md:maintainer>
    <md:maintainer id="jos">
      <md:firstname>Julius</md:firstname>
      <md:othername>O.</md:othername>
      <md:surname>Smith</md:surname>
      <md:email>jos@ccrma.stanford.edu</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist>
    <md:keyword>Golay</md:keyword>
    <md:keyword>system identification</md:keyword>
  </md:keywordlist>

  <md:abstract>The Golay code measurement technique is used for measuring impulse
responses.  Compared to the swept-sine method, it is more robust to
additive white noise.  Free, open-source software is provided in
Matlab (or Octave) and Pure Data (PD) for carrying out Golay-code
impulse-response measurements using the sound hardware found on a
typical personal-computer.</md:abstract>
</metadata>
  <content>
    <para id="id2255608"/>
    
    <section id="uid1">
      <name>Introduction</name>
      <figure id="uid2" orient="horizontal">
        <media type="application/postscript" src="linsystem2.eps">
          <param name="print-width" value="2.2in"/>
<!--NOTE: printwidth changes size of image in printed PDF (if specified in .tex file)-->
          <media type="image/png" src="linsystem2.png"><!-- NOTE: width parameter changes size of image online (pixels). original width is 218. --><param name="width" value="218"/></media>
        </media>
        <caption>Linear system to be measured</caption>
      </figure>
      <para id="id2255676"><cnxn target="uid2"/> depicts a linear system characterized by an impulse
response <m:math overflow="scroll"><m:mrow><m:mi>h</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>, driven by an input signal <m:math overflow="scroll"><m:mrow><m:mi>s</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>, and producing the
output signal <m:math overflow="scroll"><m:mrow><m:mi>r</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>. The <emphasis>system identification</emphasis> problem is to
estimate <m:math overflow="scroll"><m:mrow><m:mi>h</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> given known input/output signals <m:math overflow="scroll"><m:mrow><m:mi>s</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> and <m:math overflow="scroll"><m:mrow><m:mi>r</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>. A
practical method for identifying finite impulse responses is the
<emphasis>Golay-code</emphasis> measurement technique, described below.  <link src="http://en.wikipedia.org/wiki/Maximum_length_sequence">Maximum length sequences</link> 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.</para>
    </section>
    <section id="uid3">
      <name>Golay Code Theory</name>
      <para id="id2255807">The length <m:math overflow="scroll"><m:mi>L</m:mi></m:math> bilevel sequences <m:math overflow="scroll"><m:mrow><m:mi>a</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> and <m:math overflow="scroll"><m:mrow><m:mi>b</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> are <emphasis>Golay</emphasis> if
and only if the following condition holds, where <m:math overflow="scroll"><m:mo>¤</m:mo></m:math> denotes the
autocorrelation operator <cnxn target="bid0"/>:
</para>
      <equation id="uid4"><m:math mode="display" overflow="scroll">
          <m:mrow>
            <m:mi>a</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>¤</m:mo>
            <m:mi>a</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>+</m:mo>
            <m:mi>b</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>¤</m:mo>
            <m:mi>b</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>=</m:mo>
            <m:mn>2</m:mn>
            <m:mi>L</m:mi>
            <m:mi>δ</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
          </m:mrow>
        </m:math>
      </equation>
      <para id="id2255943">and <m:math overflow="scroll"><m:mrow><m:mi>δ</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> is the Kronecker delta function. Recall that
(<cnxn target="uid4"/>) can also be written using <m:math overflow="scroll"><m:mo>*</m:mo></m:math>, the convolution
operator:</para>
      <equation id="id2255979">
        <m:math mode="display" overflow="scroll">
          <m:mrow>
            <m:mi>a</m:mi>
            <m:mo>(</m:mo>
            <m:mo>-</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>*</m:mo>
            <m:mi>a</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>+</m:mo>
            <m:mi>b</m:mi>
            <m:mo>(</m:mo>
            <m:mo>-</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>*</m:mo>
            <m:mi>b</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
            <m:mo>=</m:mo>
            <m:mn>2</m:mn>
            <m:mi>L</m:mi>
            <m:mi>δ</m:mi>
            <m:mo>(</m:mo>
            <m:mi>n</m:mi>
            <m:mo>)</m:mo>
          </m:mrow>
        </m:math>
      </equation>
      <para id="id2256048">Given that <m:math overflow="scroll"><m:mrow><m:msub><m:mi>a</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:math> and <m:math overflow="scroll"><m:mrow><m:msub><m:mi>b</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:math> are Golay, it turns out that
<m:math overflow="scroll"><m:mrow><m:msub><m:mi>a</m:mi><m:mrow><m:mn>2</m:mn><m:mi>L</m:mi></m:mrow></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mrow><m:mo>[</m:mo><m:mtable><m:mtr><m:mtd><m:mrow><m:msub><m:mi>a</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:mtd><m:mtd><m:mrow><m:msub><m:mi>b</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:mtd></m:mtr></m:mtable><m:mo>]</m:mo></m:mrow></m:mrow></m:math> and
<m:math overflow="scroll"><m:mrow><m:msub><m:mi>b</m:mi><m:mrow><m:mn>2</m:mn><m:mi>L</m:mi></m:mrow></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mrow><m:mo>[</m:mo><m:mtable><m:mtr><m:mtd><m:mrow><m:msub><m:mi>a</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:mtd><m:mtd><m:mrow><m:mo>-</m:mo><m:msub><m:mi>b</m:mi><m:mi>L</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:mtd></m:mtr></m:mtable><m:mo>]</m:mo></m:mrow></m:mrow></m:math> are also Golay. This means
that Golay sequences can be constructed recursively given Golay seed
sequences such as <m:math overflow="scroll"><m:mrow><m:msub><m:mi>a</m:mi><m:mn>2</m:mn></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mrow><m:mo>[</m:mo><m:mtable><m:mtr><m:mtd><m:mn>1</m:mn></m:mtd><m:mtd><m:mn>1</m:mn></m:mtd></m:mtr></m:mtable><m:mo>]</m:mo></m:mrow></m:mrow></m:math> and
<m:math overflow="scroll"><m:mrow><m:msub><m:mi>b</m:mi><m:mn>2</m:mn></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mrow><m:mo>[</m:mo><m:mtable><m:mtr><m:mtd><m:mn>1</m:mn></m:mtd><m:mtd><m:mrow><m:mo>-</m:mo><m:mn>1</m:mn></m:mrow></m:mtd></m:mtr></m:mtable><m:mo>]</m:mo></m:mrow></m:mrow></m:math>. See the
<link src="http://www.mathworks.com/">MATLAB</link>/<link src="http://www.octave.org/">Octave</link> source code <link src="http://ccrma.stanford.edu/realsimple/imp_meas/generate_golay.m">generate_golay.m</link>
for details. Notice also that the resulting bilevel sequences consist
of only 1's and <m:math overflow="scroll"><m:mrow><m:mo>-</m:mo><m:mn>1</m:mn></m:mrow></m:math>'s. This means that the signal contains the
maximum possible power level given that <m:math overflow="scroll"><m:mrow><m:mo>|</m:mo><m:mi>s</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo><m:mo>|</m:mo><m:mo>≤</m:mo><m:mn>1</m:mn><m:mo>∀</m:mo><m:mi>n</m:mi></m:mrow></m:math>.
This property is helpful for minimizing measurement noise.</para>
      <para id="id2254910">Let <m:math overflow="scroll"><m:mrow><m:msub><m:mi>r</m:mi><m:mi>a</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mi>a</m:mi><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>*</m:mo><m:mi>h</m:mi><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:math> be the response due to the Golay code input
<m:math overflow="scroll"><m:mrow><m:mi>a</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>, and let <m:math overflow="scroll"><m:mrow><m:msub><m:mi>r</m:mi><m:mi>b</m:mi></m:msub><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>=</m:mo><m:mi>b</m:mi><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow><m:mo>*</m:mo><m:mi>h</m:mi><m:mrow><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:mrow></m:math> be the response due to the Golay code input
<m:math overflow="scroll"><m:mrow><m:mi>b</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math>. Due to (<cnxn target="uid4"/>), the impulse response <m:math overflow="scroll"><m:mrow><m:mi>h</m:mi><m:mo>(</m:mo><m:mi>n</m:mi><m:mo>)</m:mo></m:mrow></m:math> may be
determined as follows:</para>
      <equation id="id2256801"><m:math mode="display" overflow="scroll">
          <m:mrow>
            <m:mi>h</m:mi>
            <m:mrow>
              <m:mo>(</m:mo>
              <m:mi>n</m:mi>
              <m:mo>)</m:mo>
            </m:mrow>
            <m:mo>=</m:mo>
            <m:mfrac>
              <m:mn>1</m:mn>
              <m:mrow>
                <m:mn>2</m:mn>
                <m:mi>L</m:mi>
              </m:mrow>
            </m:mfrac>
            <m:mrow>
              <m:mo>(</m:mo>
              <m:mi>a</m:mi>
              <m:mrow>
                <m:mo>(</m:mo>
                <m:mi>n</m:mi>
                <m:mo>)</m:mo>
              </m:mrow>
              <m:mo>¤</m:mo>
              <m:msub>
                <m:mi>r</m:mi>
                <m:mi>a</m:mi>
              </m:msub>
              <m:mrow>
                <m:mo>(</m:mo>
                <m:mi>n</m:mi>
                <m:mo>)</m:mo>
              </m:mrow>
              <m:mo>+</m:mo>
              <m:mi>b</m:mi>
              <m:mrow>
                <m:mo>(</m:mo>
                <m:mi>n</m:mi>
                <m:mo>)</m:mo>
              </m:mrow>
              <m:mo>¤</m:mo>
              <m:msub>
                <m:mi>r</m:mi>
                <m:mi>b</m:mi>
              </m:msub>
              <m:mrow>
                <m:mo>(</m:mo>
                <m:mi>n</m:mi>
                <m:mo>)</m:mo>
              </m:mrow>
              <m:mo>)</m:mo>
            </m:mrow>
          </m:mrow>
        </m:math>
      </equation>
      <para id="id2256892">See
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/golay_response.m">golay_response.m</link>
for more details.</para>
    </section>
    <section id="uid5">
      <name>Golay Code Measurement Procedure and Software</name>
      <list id="id2256918" type="enumerated"><item id="uid6">Generate the Golay codes
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/golayA.wav">golayA.wav</link>

and
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/golayB.wav">golayB.wav</link>

using
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/generate_golay.m">generate_golay.m</link>.
</item>
        <item id="uid7">Open the pd
 patch
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/golay.pd">golay.pd</link>,
in pd.
</item>
        <item id="uid8">Ensure that the patch is not in editing mode, and check the
“compute audio” box in the main pd
 window.
</item>
        <item id="uid9">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.
</item>
        <item id="uid10">If there is an input volume on the sound interface, adjust it so
that the levels approximately match those shown in <cnxn target="uid11"/>
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.
<figure id="uid11" orient="horizontal"><media type="application/postscript" src="golayScale.eps"><param name="print-width" value="4in"/><!--NOTE: printwidth changes size of image in printed PDF (if specified in .tex file)--><media type="image/png" src="golayScale.png"><!-- NOTE: width parameter changes size of image online (pixels). original width is 622. --><param name="width" value="622"/></media></media><caption>golay.pd
 after
making a measurement with an appropriate input level</caption></figure></item>
        <item id="uid12">Once you are satisfied with the results, click the “Write Responses
to Disk” button.
</item>
        <item id="uid13">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
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/hpfRespA.wav">hpfRespA.wav</link>

and
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/hpfRespB.wav">hpfRespB.wav</link>
if they corresponded to the measurement of a high-pass filter.
</item>
        <item id="uid14">Run
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/golay_response.m">golay_response('hpf')</link>
in 
<link src="http://www.mathworks.com/">MATLAB</link>
or 
<link src="http://www.octave.org/ ">Octave</link>
to analyze the measured response.
Plots will be created, and the file
<link src="http://ccrma.stanford.edu/realsimple/imp_meas/hpfImpResp.wav">hpfImpResp.wav</link>
will be written to disk.
</item>
      
</list>
    </section>
  </content>
  <bib:file>
    <bib:entry id="bid0">
      <bib:book>
<!--required fields-->
        <bib:author>Abel, J. and Berners, D.</bib:author>
        <bib:title>Signal Processing Techniques for Digital Audio Effects</bib:title>
        <bib:publisher>http://ccrma.stanford.edu/courses/424/</bib:publisher>
        <bib:year>2005</bib:year>
<!--optional fields-->
        <bib:volume/>
        <bib:series/>
        <bib:address/>
        <bib:edition/>
        <bib:month/>
        <bib:note/>
      </bib:book>
    </bib:entry>
  </bib:file>
</document>
