Its time for config files to come out of the wiring closet.

June 4th, 2008

Config files have a tough time. They start out trying to fit in by looking really ordinary. They try to look like

parameter = value

or

parameter: value

but they need more freedom to be their true selves. So, they try to add a little order to their lives. They add a little structure with section headings like

[section1]
parameter = value
[section2]
other-parameter = other-value

but they still feel constrained. Some of their Native American breathren, from the Apache tribe, go a little further, with

<section>
  parameter = value
</section>

but face scorn for being a little on the wild side. Well, its time they broke free, came out of the wiring closet, and admitted they were XML all along. Can you imagine the freedom it brings to finally admit that what you’ve always wanted to say to the world is

<?xml version="1.0"?>
<!DOCTYPE global-tones SYSTEM "../tones.dtd">
<global-tones>
  <tone-set country="United States" uncode="us">
    <dial-tone>
      <step freq="350+440 || 480+720" level="-13 [1.5dB]"/>
    </dial-tone>
    <dial-tone domain="PABX">
      <step freq="350+440 || 480+720" level="-16 [0.75dB]"/>
    </dial-tone>
    <dial-tone type="recall">
      <step cycles="3">
        <step freq="350+440" level="-13 [1.5dB]" length="0.1"/>
        <step length="0.1"/>
      </step>
      <step freq="350+440" level="-13 [1.5dB]"/>
    </dial-tone>
    <dial-tone domain="PABX" type="recall">
      <step cycles="3">
        <step freq="350+440" level="-16 [0.75dB]" length="0.1"/>
        <step length="0.1"/>
      </step>
      <step freq="350+440" level="-16 [0.75dB]"/>
    </dial-tone>
    <ringback-tone>
      <step cycles="endless">
        <step freq="440+480 || 380+460" level="-19 [1.5dB]" length="2.0"/>
        <step length="4.0"/>
      </step>
    </ringback-tone>
    <ringback-tone domain="PABX">
      <step cycles="endless">
        <step freq="440+480" level="-16 [1.5dB]" length="1.0"/>
        <step length="3.0"/>
      </step>
    </ringback-tone>
    <busy-tone>
      <step cycles="endless">
        <step freq="480+620 || 480+720" level="-24 [1.5dB]" length="0.5"/>
        <step length="0.5"/>
      </step>
    </busy-tone>
    <busy-tone domain="PABX">
      <step cycles="endless">
        <step freq="480+620 || 480+720" level="-21 [1.5dB]" length="0.5"/>
        <step length="0.5"/>
      </step>
    </busy-tone>
    <congestion-tone>
      <step cycles="endless">
        <step freq="480+620 || 480+720" level="-24 [1.5dB]" length="0.25"/>
        <step length="0.25"/>
      </step>
    </congestion-tone>
    <congestion-tone domain="PABX">
      <step cycles="endless">
        <step freq="480+620 || 480+720" level="-21 [1.5dB]" length="0.25"/>
        <step length="0.25"/>
      </step>
    </congestion-tone>
    <call-waiting-tone>
      <step cycles="endless">
        <step freq="480+620" level="-13 [1.5dB]" length="0.3"/>
        <step length="10.0"/>
      </step>
    </call-waiting-tone>
    <call-waiting-tone domain="PABX" type="station-call">
      <step freq="480+620" level="-16 [1.5dB]" length="0.3"/>
    </call-waiting-tone>
    <call-waiting-tone domain="PABX" type="outside-call">
      <step cycles="2">
        <step freq="480+620" level="-16 [1.5dB]" length="0.1"/>
        <step length="0.1"/>
      </step>
    </call-waiting-tone>
    <call-waiting-tone domain="PABX" type="urgent-call">
      <step cycles="3">
        <step freq="480+620" level="-16 [1.5dB]" length="0.1"/>
        <step length="0.1"/>
      </step>
    </call-waiting-tone>
    <special-information-tone>
      <step freq="950" level="-13 [1.5dB]" length="0.33"/>
      <step freq="1400" level="-13 [1.5dB]" length="0.33"/>
      <step freq="1800" level="-13 [1.5dB]" length="0.33"/>
    </special-information-tone>
    <warning-tone type="operator-intervening">
      <step freq="440" level="-13 [1.5dB]" length="2.0"/>
      <step length="10.0"/>
      <step freq="440" level="-13 [1.5dB]" length="0.5"/>
      <step length="10.0"/>
    </warning-tone>
    <warning-tone type="operator-intervening" domain="PABX">
      <step freq="440" level="-13 [1.5dB]" length="1.5"/>
      <step length="8.0"/>
      <step freq="440" level="-13 [1.5dB]" length="0.5"/>
      <step length="8.0"/>
    </warning-tone>
    <waiting-tone domain="PABX">
      <step freq="440" level="-13 [1.5dB]" length="0.3"/>
      <step length="10.0"/>
    </waiting-tone>
    <record-tone>
      <step freq="1400" level="-13 [1.5dB]" length="0.5"/>
      <step length="15.0"/>
    </record-tone>
    <executive-override-tone domain="PABX">
      <step freq="440" level="-14 [1.5dB]" length="3.0"/>
    </executive-override-tone>
    <intercept-tone domain="PABX">
      <step freq="440" level="-13 [1.5dB]" length="0.25"/>
      <step freq="620" level="-13 [1.5dB]" length="0.25"/>
    </intercept-tone>
    <confirmation-tone>
      <step freq="350+440" level="-13 [1.5dB]" length="0.1"/>
      <step length="0.1"/>
      <step freq="350+440" level="-13 [1.5dB]" length="0.3"/>
    </confirmation-tone>
    <confirmation-tone domain="PABX">
      <step cycles="2">
        <step freq="350+440" level="-16 [1.5dB]" length="0.1"/>
        <step length="0.1"/>
      </step>
      <step freq="350+440" level="-16 [1.5dB]" length="0.1"/>
    </confirmation-tone>
  </tone-set>
</global-tones>

Doesn’t that feel good? You can build your own little nest where you feel at home. You are no longer limited in the depths you can express.

Narrow band detection

December 18th, 2007

Detecting the presence of narrow band signals - not the actual signal, but merely that the signal in the channel is not broad band - is a vital or useful task in a number of telephony DSP situations. Really robust echo cancellers need to detect narrow band energy, and freeze their adaption when it is present. Here the compute cost is secondary to robust operation, but keeping the compute down is obviously important. If a really lightweight narrow band detector is practical, then things like supervisory tone detectors could potentially be enabled only when the narrow band detector says there is something suspicious in the channel. That might reduce their average compute load.

There are various obvious ways to assess narrowbandiness. The auto-correlation function of the signal will be peaky if the energy is predominantly narrow band. That peakiness is not hard to detect, but the total compute load is quite high. A really low compute method has eluded me, to date. The Teager Kaiser Energy Operator (TKEO) is a very low compute calculation, which produces a constant output for a single tone of constant amplitude. For a single tone, x(n) = A cos(ωn + φ), TKEO is simply:

Ψ(x(n)) = x(n)2 – x(n)x(n – 2) = A2 sin2(ω)

Where ω is the usual suspect, and A is the amplitude of the tone. The following modified form is more robust, though it produces the same answer for more than one frequency - not really a problem if you are only trying to detect that some fairly constant amplitude narrow band energy is present:

Ψk(x(n)) = x(n – k)2 – x(n)x(n – 2k) = A2 sin2(kω)

Where k is an integer constant. The larger k is, the more frequencies map to the same value, but the less noise affects the result. If there are two tones (typical maximum for supervisory tones) it produces a sine wave output at the difference frequency. That’s not hard to assess, so TKEO looks like a good basis for a detector. The snag is it is horribly sensitive to noise. The up side is each calculation involves only 3 samples. The down side is each calculation involves only 3 samples. You are highly dependent on the accuracy of those 3 samples, and even small amounts of noise mess up the answers rather badly. If you apply a simple pole or two of LPF to the output of the TKEO you can damp the effects of noise quite a lot. However, I can’t seem to come up with a robust scheme that remains low compute.

Freescale have some application notes (e.g. http://www.freescale.com/files/dsp/doc/app_note/AN2384.pdf) on the web describing tone detection using TKEO. They even have what appears to be a detailed description of the algorithms they use. However, when I try modelling what they describe, I can’t seem to get an adequate result. Lots of application notes are complete drivel, describing things that can never work. These Freescale notes are tantalisingly plausible :-) . Of course, if it works well for them, they have probably created a patent minefield for people like me, following behind.