<!-- Converted to DocBook/SGML by Kevin Conder -->
<refentry id="specptrk">
  <refmeta>
    <refentrytitle>specptrk</refentrytitle>
  </refmeta>
 
  <refnamediv>
    <refname>spectrk</refname>
    <refpurpose>
      Estimates the pitch of the most prominent complex tone in the spectrum.
      <indexterm id="IndexSpecptrk"><primary>specptrk</primary></indexterm>
    </refpurpose>
  </refnamediv>
 
  <refsect1>
    <title>Description</title>
    <para>
      Estimate the pitch of the most prominent complex tone in the spectrum.
    </para>
  </refsect1>
 
  <refsect1>
    <title>Syntax</title>
    <synopsis>koct, kamp <command>specptrk</command> wsig, kvar, ilo, ihi, istr, idbthresh, inptls, irolloff [, iodd] [, iconfs] [, interp] [, ifprd] [, iwtflg]</synopsis>
  </refsect1>
 
  <refsect1>
    <title>Initialization</title>
    <para>
      <emphasis>ilo, ihi, istr</emphasis> -- pitch range conditioners (low, high, and starting) expressed in decimal octave form.
    </para>

    <para>
      <emphasis>idbthresh</emphasis> -- energy threshold (in decibels) for pitch tracking to occur.  Once begun, tracking will be continuous until the energy falls below one half the threshold (6 dB down), whence the <emphasis>koct</emphasis> and <emphasis>kamp</emphasis> outputs will be zero until the full threshold is again surpassed. <emphasis>idbthresh</emphasis> is a guiding value. At initialization it is first converted to the <emphasis>idbout</emphasis> mode of the source spectrum (and the 6 dB down point becomes .5, .25, or 1/root 2 for modes 0, 2 and 3). The values are also further scaled to allow for the weighted partial summation used during correlation.The actual thresholding is done using the internal weighted and summed <emphasis>kamp</emphasis> value that is visible as the second output parameter.
    </para>

    <para>
      <emphasis>inptls, irolloff</emphasis> -- number of harmonic partials used as a matching template in the spectrally-based pitch detection, and an amplitude rolloff for the set expressed as some fraction per octave (linear, so don't roll off to negative).  Since the partials and rolloff fraction can affect the pitch following, some experimentation will be useful: try 4 or 5 partials with .6 rolloff as an initial setting; raise to 10 or 12 partials with rolloff .75 for complex timbres like the bassoon (weak fundamental). Computation time is dependent on the number of partials sought. The maximum number is 16.
    </para>

    <para>
      <emphasis>iodd</emphasis> (optional) -- if non-zero, employ only odd partials in the above set (e.g. <emphasis>inptls</emphasis> of 4 would employ partials 1,3,5,7). This improves the tracking of some instruments like the clarinet The default value is 0 (employ all partials).
    </para>

    <para>
      <emphasis>iconfs</emphasis> (optional) -- number of confirmations required for the pitch tracker to jump an octave, pro-rated for fractions of an octave (i.e. the value 12 implies a semitone change needs 1 confirmation (two hits) at the <emphasis>spectrum</emphasis> generating <emphasis>iprd</emphasis>). This parameter limits spurious pitch analyses such as octave errors. A value of 0 means no confirmations required; the default value is 10.
    </para>

    <para>
      <emphasis>interp</emphasis> (optional) -- if non-zero, interpolate each output signal (<emphasis>koct</emphasis>, <emphasis>kamp</emphasis>) between incoming <emphasis>wsig</emphasis> frames. The default value is 0 (repeat the signal values between frames).
    </para>

    <para>
      <emphasis>ifprd</emphasis> (optional) -- if non-zero, display the internally computed spectrum of candidate fundamentals.  The default value is 0 (no display).
    </para>

    <para>
      <emphasis>iwtftg</emphasis> (optional) -- wait flag. If non-zero, hold each display until released by the user. The default value is 0 (no wait).
    </para>
  </refsect1>
 
  <refsect1>
    <title>Performance</title>
    <para>
      At note initialization this unit creates a template of <emphasis>inptls</emphasis> harmonically related partials (odd partials, if <emphasis>iodd</emphasis> non-zero) with amplitude rolloff to the fraction <emphasis>irolloff</emphasis> per octave. At each new frame of <emphasis>wsig</emphasis>, the spectrum is cross-correlated with this template to provide an internal spectrum of candidate fundamentals (optionally displayed). A likely pitch/amp pair (<emphasis>koct</emphasis>, <emphasis>kamp</emphasis>, in decimal octave and summed <emphasis>idbout</emphasis> form) is then estimated. <emphasis>koct</emphasis> varies from the previous <emphasis>koct</emphasis> by no more than plus or minus <emphasis>kvar</emphasis> decimal octave units. It is also guaranteed to lie within the hard limit range <emphasis>ilo</emphasis> -- <emphasis>ihi</emphasis> (decimal octave low and high pitch). <emphasis>kvar</emphasis> can be dynamic, e.g. onset amp dependent.  Pitch resolution uses the originating <emphasis>spectrum</emphasis> <emphasis>ifrqs</emphasis> bins/octave, with further parabolic interpolation between adjacent bins. Settings of root magnitude, <emphasis>ifrqs</emphasis> = 24, <emphasis>iq</emphasis> = 15 should capture all the inflections of interest. Between frames, the output is either repeated or interpolated at the k-rate. (See <link linkend="spectrum"><citetitle>spectrum</citetitle></link>.)
    </para>
  </refsect1>
 
  <refsect1>
    <title>Examples</title>
    <para>
      <informalexample>
        <programlisting>
  a1,a2   <emphasis>ins</emphasis>                                                         ; read a stereo clarinet input
  krms    <emphasis>rms</emphasis>        a1, 20                                           ; find a monaural rms value
  kvar    =          0.6 + krms/8000                                  ; &amp; use to gate the pitch variance
  wsig    <emphasis>spectrum</emphasis>   a1, .01, 7, 24, 15, 0, 3                         ; get a 7-oct spectrum, 24 bibs/oct
          <emphasis>specdisp</emphasis>   wsig, .2                                         ; display this and now estimate
  koct,ka <emphasis>spectrk</emphasis>    wsig, kvar, 7.0, 10, 9, 20,  4, .7, 1, 5, 1, .2  ; the pch and amp
  aosc    <emphasis>oscil</emphasis>      ka*ka*10, cpsoct(koct),2                         ; &amp; generate \ new tone with these
  koct    =          (koct&lt;7.0?7.0:koct)                           ; replace non pitch with low C
          <emphasis>display</emphasis>    koct-7.0, .25, 20                                ; &amp; display the pitch track
          <emphasis>display</emphasis>    ka, .25, 20                                      ; plus the summed root mag
          <emphasis>outs</emphasis>       a1, aosc                                         ; output 1 original and 1 new track
        </programlisting>
      </informalexample>
    </para>
  </refsect1>
</refentry>
