<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/technology/cnxml/schema/dtd/0.5/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:bib="http://bibtexml.sf.net/" xmlns:m="http://www.w3.org/1998/Math/MathML" id="new">
  <name>Karplus-Strong Plucked String Algorithm with Improved Pitch Accuracy</name>
  <metadata>
  <md:version>1.2</md:version>
  <md:created>2007/09/28 09:47:34 GMT-5</md:created>
  <md:revised>2008/03/18 09:45:14.439 GMT-5</md:revised>
  <md:authorlist>
      <md:author id="doering">
      <md:firstname>Ed</md:firstname>
      
      <md:surname>Doering</md:surname>
      <md:email>doering@rose-hulman.edu</md:email>
    </md:author>
  </md:authorlist>

  <md:maintainerlist>
    <md:maintainer id="doering">
      <md:firstname>Ed</md:firstname>
      
      <md:surname>Doering</md:surname>
      <md:email>doering@rose-hulman.edu</md:email>
    </md:maintainer>
    <md:maintainer id="eluther">
      <md:firstname>Erik</md:firstname>
      <md:othername>B</md:othername>
      <md:surname>Luther</md:surname>
      <md:email>erik.luther@ni.com</md:email>
    </md:maintainer>
    <md:maintainer id="SShearman">
      <md:firstname>Sam</md:firstname>
      <md:othername>D.</md:othername>
      <md:surname>Shearman</md:surname>
      <md:email>sam.shearman@ni.com</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist>
    <md:keyword>all-pass filter</md:keyword>
    <md:keyword>filter delay</md:keyword>
    <md:keyword>Karplus-Strong plucked string algorithm</md:keyword>
    <md:keyword>LabVIEW</md:keyword>
    <md:keyword>loop delay</md:keyword>
    <md:keyword>lowpass filter</md:keyword>
    <md:keyword>MIDI JamSession</md:keyword>
    <md:keyword>virtual musical instrument</md:keyword>
  </md:keywordlist>

  <md:abstract>The basic Karplus-Strong plucked string algorithm must be modified with a continuously adjustable loop delay to produce an arbitrary pitch with high accuracy. An all-pass filter provides a continuously-adjustable fractional delay, and is an ideal device to insert into the closed loop. The delay characteristics of both the lowpass and all-pass filters are explored, and the modified digital filter coefficients are derived. The filter is then implemented as a LabVIEW "virtual musical instrument" (VMI) to be played from a MIDI file using "MIDI JamSession."</md:abstract>
</metadata>

<content>

<table id="labview_banner" frame="none"><tgroup cols="2">
<colspec rowsep="0" colsep="0"/> <colspec colwidth="6in" rowsep="0" colsep="0"/>
<tbody>
  <row>
    <entry morerows="3"><media type="image/png" src="LabVIEWq.png"/></entry>
    <entry> This module refers to LabVIEW, a software development environment that features a graphical programming language.
       Please see the <cnxn document="m15428">LabVIEW QuickStart Guide</cnxn> module for tutorials and documentation that will help you:</entry>
  </row>
  <row> <entry>• Apply LabVIEW to Audio Signal Processing </entry> </row>
  <row> <entry>• Get started with LabVIEW</entry> </row>
  <row> <entry>• Obtain a fully-functional evaluation edition of LabVIEW</entry> </row>
</tbody>
</tgroup>
</table>


<section id="sec1">
<name>Introduction</name>

<para id="par2">
		In the project activity of the prerequisite module <cnxn document="m15489">Karplus-Strong Plucked String Algorithm</cnxn>,
		you undoubtedly noticed that
		the pitch accuracy of the basic Karplus-Strong algorithm needs improvement. For example,
		listen to the short MIDI test sequence <link src="ksdemo.mid">ksdemo.mid</link>
		rendered to audio with the basic algorithm using a sampling frequency of 20 kHz: 
		<link src="ksdemo_20kHz.wav">ksdemo_20kHz.wav</link>. The individual notes sound reasonable,
		but when the notes are played simultaneously as a chord, the pitch inaccuracy becomes noticeable. 
		The accuracy gets worse at lower sampling frequencies such as 10 kHz: 
		<link src="ksdemo_10kHz.wav">ksdemo_10kHz.wav</link>; increasing the sampling frequency
		improves the accuracy, as at 44.1 kHz: <link src="ksdemo_44kHz.wav">ksdemo_44kHz.wav</link>,
		however, a discerning ear can still detect some problems.</para>

<para id="par3">		The pitch of the plucked string tone is determined by the loop time, which must be made continuously
		variable in order to precisely control the pitch. In the basic algorithm, the length of the delay line
		determines the loop time, and the delay line can only be varied in integer amounts. The <term>all-pass filter</term> 
		will be introduced and studied in this module as a means to introduce an adjustable fractional delay into the loop.</para>

<para id="par4">		As a preview of the results that you can achieve, consider the same MIDI test sequence rendered to audio using
		the techniques introduced in this section: <link src="ks2demo_10kHz.wav">ks2demo_10kHz.wav</link> and
		<link src="ks2demo_20kHz.wav">ks2demo_20kHz.wav</link>.
</para>

</section>

<section id="sec5">
<name>Lowpass Filter Delay</name>

<para id="par6">
		In the <cnxn document="m15489">prerequisite module</cnxn>, the loop time was determined to be the product of the delay line length and the sampling interval.
		The reciprocal of the loop time is the pitch (frequency) of the output signal
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mn>0</m:mn>
   </m:msub>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aqatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8srps0lbbf9q8WrFfeuY=Hhbbf9v8qqaqFr0xc9pk0xbba9q8WqFfea0=yr0RYxir=Jbba9q8aq0=yq=He9q8qqQ8frFve9Fve9Ff0dmeaabaqaciGacaGaaeqabaWaaeaaeaaakeaacaWGMbWaaSbaaSqaaiaaicdaaeqaaaaa@3718@</m:annotation>
 </m:semantics>
</m:math>:
</para>

<equation id="eqn-pitch">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mn>0</m:mn>
   </m:msub>
   <m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:msub>
      <m:mi>f</m:mi>
      <m:mi>S</m:mi>
     </m:msub>
    </m:mrow>
    <m:mi>N</m:mi>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaakiabg2da9maalaaabaGaamOzamaaBaaaleaacaWGtbaabeaaaOqaaiaad6eaaaaaaa@3AF8@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par8">
		where 
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mi>S</m:mi>
   </m:msub>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOzamaaBaaaleaacaWGtbaabeaaaaa@372A@</m:annotation>
 </m:semantics>
</m:math> is the sampling frequency in Hz and
<m:math>
 <m:semantics>
  <m:mi>N</m:mi>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOtaaaa@360E@</m:annotation>
 </m:semantics>
</m:math> is the length of the delay line in samples. Because the delay line length must be an integer number of samples, the
pitch cannot be set arbitrarily.</para>

<para id="par9">Try the following exercises to explore this concept in more detail.
</para>

<exercise id="exer10">
<problem>
<para id="par11">
			The sampling frequency is 40.00 kHz, and the length of the delay line is 40 samples.
			What is the pitch of the output signal? If the delay line length is decreased by one sample,
			what is the new pitch?
	</para>
</problem>
<solution>
<para id="par12">
			1000 Hz (40 kHz divided by 40 samples); 1026 Hz
	</para>
</solution>
</exercise>
<exercise id="exer13">
<problem>
<para id="par14">
			The sampling frequency is 10.00 kHz, and the length of the delay line is 10 samples.
			What is the pitch of the output signal? If the delay line length is decreased by one sample,
			what is the new pitch?
	</para>
</problem>
<solution>
<para id="par15">
			1000 Hz (10 kHz divided by 10 samples); 1111 Hz
	</para>
</solution>
</exercise>
<para id="par16">
		For each of the two exercises, the first pitch is exactly the same, i.e., 1000 Hz. However, the
		change in pitch caused by decreasing the delay line by only one sample is substantial (1026 Hz compared
		to 1111 Hz). But how perceptible is this difference? The module 
		<cnxn document="m15440">Musical Intervals and the Equal-Tempered Scale</cnxn> includes a
		LabVIEW interactive front panel that displays the frequency of each key on a standard 88-key piano.
		Pitch C6 is 1046 Hz while pitch C♯6 (a half-step higher) is 1109 Hz. These values are similar
		to the change from 1000 Hz to 1111 Hz caused by altering the delay line length by only one sample,
		so the change is certainly very audible. The abrupt "jump" in frequency becomes less pronounced
		at lower pitches where the delay line length is longer.</para>

<para id="par17">		Flexibility to adjust the overall loop time in a 
		continuous fashion is required to improve pitch accuracy. Moreover, any sources of delay in the loop must be accurately known.
		So far the delay of the low pass filter has been taken as zero, but in fact the low pass filter
		introduces a delay of its own.</para>

<para id="par18">		The <cnxn target="video-delay"/> screencast video describes first how to calculate
		the delay of an arbitrary digital filter with transfer function 
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>H</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisaiaacIcacaWG6bGaaiykaaaa@3860@</m:annotation>
 </m:semantics>
</m:math>.
</para>

<figure id="video-delay">
<media type="image/png" src="sub_ks2-delay.html">
   <param name="thumbnail" value="sub_ks2-delay.png"/>
   </media>
<caption>
   [video] Calculating the delay of a filter given H(z)
</caption>
</figure>

<para id="par20">
		In general, therefore, the delay is the negated slope of the filter's phase function, and the
		delay varies with frequency.</para>

<para id="par21">		Now, consider the specific low pass filter used in the basic Karplus-Strong algorithm. The
		filter coefficient "g" will be taken as 0.5, making the filter a true two-point averager:
</para>

<equation id="eqn-lpf">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>H</m:mi>
    <m:mrow>
     <m:mtext>LPF</m:mtext>
    </m:mrow>
   </m:msub>
   <m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mn>1</m:mn>
      </m:mrow>
     </m:msup>
    </m:mrow>
    <m:mn>2</m:mn>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisamaaBaaaleaacaqGmbGaaeiuaiaabAeaaeqaaOGaaiikaiaadQhacaGGPaGaeyypa0ZaaSaaaeaacaaIXaGaey4kaSIaamOEamaaCaaaleqabaGaeyOeI0IaaGymaaaaaOqaaiaaikdaaaaaaa@414E@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par23">
		The <cnxn target="video-lpfdelay"/> screencast video continues the discussion by
		deriving the delay of the low pass filter of <cnxn target="eqn-lpf"/>. 
		Several techniques for working with complex
		numbers in LabVIEW are presented and used to visualize the magnitude and
		phase response of the filter.
</para>

<figure id="video-lpfdelay">
<media type="image/png" src="sub_ks2-lpfdelay.html">
   <param name="thumbnail" value="sub_ks2-lpfdelay.png"/>
   </media>
<caption>
   [video] Calculating the delay of the low pass filter
</caption>
</figure>

<para id="par25">
		Because the delay of the low pass filter is always 1/2, the pitch may be expressed more precisely as
</para>

<equation id="eqn-almost">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mn>0</m:mn>
   </m:msub>
   <m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:msub>
      <m:mi>f</m:mi>
      <m:mi>S</m:mi>
     </m:msub>
    </m:mrow>
    <m:mrow>
     <m:mi>N</m:mi><m:mo>+</m:mo><m:mfrac>
      <m:mn>1</m:mn>
      <m:mn>2</m:mn>
     </m:mfrac>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaakiabg2da9maalaaabaGaamOzamaaBaaaleaacaWGtbaabeaaaOqaaiaad6eacqGHRaWkdaWcaaqaaiaaigdaaeaacaaIYaaaaaaaaaa@3D61@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par27">
		While this result more accurately calculates the pitch, it does nothing to address the frequency 
		resolution problem. 
</para>

</section>

<section id="sec28">
<name>All-Pass Filter Delay</name>

<para id="par29">
		Now, consider the <term>all-pass filter</term> (<term>APF</term>) as a means to introduce a variable
		and fractional delay into the loop. The all-pass filter has a unit magnitude response over all
		frequencies, so it does not "color" the signal passing through. However, the all-pass filter has
		a phase response that is approximately linear for all but the highest frequencies, so it introduces 
		an approximately constant delay. Even better, the slope of the phase response is continuously variable,
		making it possible to adjust the delay as needed between 0 and 1 samples.</para>

<para id="par30">		The all-pass filter transfer function is
</para>

<equation id="eqn-apf">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>H</m:mi>
    <m:mrow>
     <m:mtext>APF</m:mtext>
    </m:mrow>
   </m:msub>
   <m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:mi>C</m:mi><m:mo>+</m:mo><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mn>1</m:mn>
      </m:mrow>
     </m:msup>
    </m:mrow>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:mi>C</m:mi><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mn>1</m:mn>
      </m:mrow>
     </m:msup>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisamaaBaaaleaacaqGbbGaaeiuaiaabAeaaeqaaOGaaiikaiaadQhacaGGPaGaeyypa0ZaaSaaaeaacaWGdbGaey4kaSIaamOEamaaCaaaleqabaGaeyOeI0IaaGymaaaaaOqaaiaaigdacqGHRaWkcaWGdbGaamOEamaaCaaaleqabaGaeyOeI0IaaGymaaaaaaaaaa@45CD@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par32">
		where 
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mrow><m:mo>|</m:mo> <m:mi>C</m:mi> <m:mo>|</m:mo></m:mrow><m:mo>&lt;</m:mo><m:mn>1</m:mn>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaWaaqWaaeaacaWGdbaacaGLhWUaayjcSdGaeyipaWJaaGymaaaa@3AE4@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
to ensure stability.</para>

<para id="par33">		The <cnxn target="video-apfdelay"/> screencast video continues the discussion by
		exploring the delay of the all-pass filter of <cnxn target="eqn-apf"/> as a function
		of the parameter C.
</para>

<figure id="video-apfdelay">
<media type="image/png" src="sub_ks2-apfdelay.html">
   <param name="thumbnail" value="sub_ks2-apfdelay.png"/>
   </media>
<caption>
   [video] Calculating the delay of the low pass filter
</caption>
</figure>

</section>

<section id="sec35">
<name>Implementing the Pitch-Accurate Algorithm</name>

<para id="par36">
		Including the all-pass filter in the basic Karplus-Strong algorithm allows the loop time to be
		set to an arbitrary value, making it possible to sound a tone with any desired pitch.</para>

<para id="par37">		This section guides you through the necessary steps to augment the basic algorithm with an
		all-pass filter, including the derivation of necessary equations to calculate the delay line
		length and the fractional delay. Work through the derivations requested by each of the exercises.</para>

<para id="par38">		To begin, the pitch of the output signal is the sampling frequency
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mn>S</m:mn>
   </m:msub>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaaaaa@370C@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
divided by the total loop delay in samples:
</para>

<equation id="eqn-loopdelay">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>f</m:mi>
    <m:mn>0</m:mn>
   </m:msub>
   <m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:msub>
      <m:mi>f</m:mi>
      <m:mi>S</m:mi>
     </m:msub>
    </m:mrow>
    <m:mrow>
     <m:mi>N</m:mi><m:mo>+</m:mo><m:mfrac>
      <m:mn>1</m:mn>
      <m:mn>2</m:mn>
     </m:mfrac>
     <m:mo>+</m:mo><m:mi>Δ</m:mi>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaakiabg2da9maalaaabaGaamOzamaaBaaaleaacaWGtbaabeaaaOqaaiaad6eacqGHRaWkdaWcaaqaaiaaigdaaeaacaaIYaaaaiabgUcaRiabfs5aebaaaaa@3FA9@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par40">
		where
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mi>Δ</m:mi>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaeuiLdqeaaa@36A1@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
is the fractional delay introduced by the all-pass filter. 
</para>

<exercise id="exer41">
<problem>
<para id="par42">
			Refer to <cnxn target="eqn-loopdelay"/>. Derive a pair of equations that can be used to calculate the length of
			the delay line
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mi>N</m:mi>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOtaaaa@360E@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ --> and the value of the fractional delay 
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mi>Δ</m:mi>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaeuiLdqeaaa@36A1@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->.
	</para>
</problem>
<solution>
<para id="par43">
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>N</m:mi><m:mo>=</m:mo><m:mrow><m:mo>⌊</m:mo> <m:mrow>
    <m:mfrac>
     <m:mrow>
      <m:msub>
       <m:mi>f</m:mi>
       <m:mi>S</m:mi>
      </m:msub>
     </m:mrow>
     <m:mrow>
      <m:msub>
       <m:mi>f</m:mi>
       <m:mn>0</m:mn>
      </m:msub>
     </m:mrow>
    </m:mfrac>
    <m:mo>−</m:mo><m:mfrac>
     <m:mn>1</m:mn>
     <m:mn>2</m:mn>
    </m:mfrac>
   </m:mrow> <m:mo>⌋</m:mo></m:mrow>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamOtaiabg2da9maagmaabaWaaSaaaeaacaWGMbWaaSbaaSqaaiaadofaaeqaaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaaaaGccqGHsisldaWcaaqaaiaaigdaaeaacaaIYaaaaaGaayj84laawUp+aaaa@4284@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ --> (the "floor" operator converts the operand to an integer by selecting the largest integer that is less than the operand);
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>Δ</m:mi><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:msub>
      <m:mi>f</m:mi>
      <m:mi>S</m:mi>
     </m:msub>
    </m:mrow>
    <m:mrow>
     <m:msub>
      <m:mi>f</m:mi>
      <m:mn>0</m:mn>
     </m:msub>
    </m:mrow>
   </m:mfrac>
   <m:mo>−</m:mo><m:mi>N</m:mi>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaeuiLdqKaeyypa0ZaaSaaaeaacaWGMbWaaSbaaSqaaiaadofaaeqaaaGcbaGaamOzamaaBaaaleaacaaIWaaabeaaaaGccqGHsislcaWGobaaaa@3D4B@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
	</para>
</solution>
</exercise>
<para id="par44">
		The all-pass filter delay can be approximated by <cnxn target="eqn-apfdelay"/> (see Moore):
</para>

<equation id="eqn-apfdelay">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>Δ</m:mi><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>−</m:mo><m:mi>C</m:mi>
    </m:mrow>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:mi>C</m:mi>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaeuiLdqKaeyypa0ZaaSaaaeaacaaIXaGaeyOeI0Iaam4qaaqaaiaaigdacqGHRaWkcaWGdbaaaaaa@3C8C@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<exercise id="exer46">
<problem>
<para id="par47">Refer to <cnxn target="eqn-apfdelay"/>. Solve the equation for the all-pass filter coefficient C in terms of the
	required fractional delay.</para>
</problem>
<solution>
<para id="par48">
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>C</m:mi><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>−</m:mo><m:mi>Δ</m:mi>
    </m:mrow>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:mi>Δ</m:mi>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaam4qaiabg2da9maalaaabaGaaGymaiabgkHiTiabfs5aebqaaiaaigdacqGHRaWkcqqHuoaraaaaaa@3D2A@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
</para>
</solution>
</exercise>
<para id="par49">
		The all-pass filter can be inserted at any point in the loop; <cnxn target="img-blockdgm"/> shows the all-pass filter placed after
		the low pass filter.
</para>

<figure id="img-blockdgm">
<media type="image/png" src="sub_ks2-blockdgm.png">
   </media>
<caption>
   Block diagram of the pitch-accurate Karplus-Strong algorithm
</caption>
</figure>

<exercise id="exer51">
<problem>
<para id="par52">
		To simplify the derivation of the overall filter transfer function that relates y(n) to x(n), consider the three feedback elements (delay line, low pass filter,
		and all-pass filter) to be a single element with transfer function 
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>G</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaam4raiaacIcacaWG6bGaaiykaaaa@385F@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->. Derive the transfer function of the combined element.
</para>
</problem>
<solution>
<para id="par53">
		The elements are in cascade, so the individual transfer functions multiply together:
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>G</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:msup>
    <m:mi>z</m:mi>
    <m:mrow>
     <m:mo>−</m:mo><m:mi>N</m:mi>
    </m:mrow>
   </m:msup>
   <m:msub>
    <m:mi>H</m:mi>
    <m:mrow>
     <m:mi>L</m:mi><m:mi>P</m:mi><m:mi>F</m:mi>
    </m:mrow>
   </m:msub>
   <m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:msub>
    <m:mi>H</m:mi>
    <m:mrow>
     <m:mi>A</m:mi><m:mi>P</m:mi><m:mi>F</m:mi>
    </m:mrow>
   </m:msub>
   <m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaam4raiaacIcacaWG6bGaaiykaiabg2da9iaadQhadaahaaWcbeqaaiabgkHiTiaad6eaaaGccaWGibWaaSbaaSqaaiaadYeacaWGqbGaamOraaqabaGccaGGOaGaamOEaiaacMcacaWGibWaaSbaaSqaaiaadgeacaWGqbGaamOraaqabaGccaGGOaGaamOEaiaacMcaaaa@47E8@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
</para>
</solution>
</exercise>
<exercise id="exer54">
<problem>
<para id="par55">
			Refer to the block diagram of <cnxn target="img-blockdgm"/>. Considering that all three elements are represented by a single feedback element G(z), 
			derive the overall transfer function H(z) for the digital filter in terms of G(z).
	</para>
</problem>
<solution>
<para id="par56">
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>H</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:mfrac>
    <m:mn>1</m:mn>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>−</m:mo><m:mi>G</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisaiaacIcacaWG6bGaaiykaiabg2da9maalaaabaGaaGymaaqaaiaaigdacqGHsislcaWGhbGaaiikaiaadQhacaGGPaaaaaaa@3EFD@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
	</para>
</solution>
</exercise>
<para id="par57">
		Recall the low pass filter transfer function (<cnxn target="eqn-lpftf"/>):
</para>

<equation id="eqn-lpftf">


<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:msub>
    <m:mi>H</m:mi>
    <m:mrow>
     <m:mi>L</m:mi><m:mi>P</m:mi><m:mi>F</m:mi>
    </m:mrow>
   </m:msub>
   <m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:mi>g</m:mi><m:mo stretchy="false">(</m:mo><m:mn>1</m:mn><m:mo>+</m:mo><m:msup>
    <m:mi>z</m:mi>
    <m:mrow>
     <m:mo>−</m:mo><m:mn>1</m:mn>
    </m:mrow>
   </m:msup>
   <m:mo stretchy="false">)</m:mo>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisamaaBaaaleaacaWGmbGaamiuaiaadAeaaeqaaOGaaiikaiaadQhacaGGPaGaeyypa0Jaam4zaiaacIcacaaIXaGaey4kaSIaamOEamaaCaaaleqabaGaeyOeI0IaaGymaaaakiaacMcaaaa@42CD@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->

</equation>

<para id="par59">
		The all-pass filter transfer function is described by <cnxn target="eqn-apf"/>.
</para>

<exercise id="exer60">
<problem>
<para id="par61">Derive the overall transfer function H(z) in terms of the filter parameters g and C. Write the transfer function
	in standard form as the ratio of two polynomials in z.</para>
</problem>
<solution>
<para id="par62">
<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ -->
<m:math>
 <m:semantics>
  <m:mrow>
   <m:mi>H</m:mi><m:mo stretchy="false">(</m:mo><m:mi>z</m:mi><m:mo stretchy="false">)</m:mo><m:mo>=</m:mo><m:mfrac>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:mi>C</m:mi><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mn>1</m:mn>
      </m:mrow>
     </m:msup>
    </m:mrow>
    <m:mrow>
     <m:mn>1</m:mn><m:mo>+</m:mo><m:mi>C</m:mi><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mn>1</m:mn>
      </m:mrow>
     </m:msup>
     <m:mo>−</m:mo><m:mi>g</m:mi><m:mi>C</m:mi><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mi>N</m:mi>
      </m:mrow>
     </m:msup>
     <m:mo>−</m:mo><m:mi>g</m:mi><m:mo stretchy="false">(</m:mo><m:mn>1</m:mn><m:mo>+</m:mo><m:mi>C</m:mi><m:mo stretchy="false">)</m:mo><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mo stretchy="false">(</m:mo><m:mi>N</m:mi><m:mo>+</m:mo><m:mn>1</m:mn><m:mo stretchy="false">)</m:mo>
      </m:mrow>
     </m:msup>
     <m:mo>−</m:mo><m:mi>g</m:mi><m:msup>
      <m:mi>z</m:mi>
      <m:mrow>
       <m:mo>−</m:mo><m:mo stretchy="false">(</m:mo><m:mi>N</m:mi><m:mo>+</m:mo><m:mn>2</m:mn><m:mo stretchy="false">)</m:mo>
      </m:mrow>
     </m:msup>
    </m:mrow>
   </m:mfrac>
  </m:mrow>
 <m:annotation encoding="MathType-MTEF">
 MathType@MTEF@5@5@+=feaagaart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLnhiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYb1uaebbnrfifHhDYfgasaacH8YjY=vipgYlh9vqqj=hEeeu0xXdbba9frFj0=OqFfea0dXdd9vqai=hGuQ8kuc9pgc9q8qqaq=dir=f0=yqaiVgFr0xfr=xfr=xb9adbaqaaeGaciGaaiaabeqaamaabaabaaGcbaGaamisaiaacIcacaWG6bGaaiykaiabg2da9maalaaabaGaaGymaiabgUcaRiaadoeacaWG6bWaaWbaaSqabeaacqGHsislcaaIXaaaaaGcbaGaaGymaiabgUcaRiaadoeacaWG6bWaaWbaaSqabeaacqGHsislcaaIXaaaaOGaeyOeI0Iaam4zaiaadoeacaWG6bWaaWbaaSqabeaacqGHsislcaWGobaaaOGaeyOeI0Iaam4zaiaacIcacaaIXaGaey4kaSIaam4qaiaacMcacaWG6bWaaWbaaSqabeaacqGHsislcaGGOaGaamOtaiabgUcaRiaaigdacaGGPaaaaOGaeyOeI0Iaam4zaiaadQhadaahaaWcbeqaaiabgkHiTiaacIcacaWGobGaey4kaSIaaGOmaiaacMcaaaaaaaaa@5CD2@</m:annotation>
 </m:semantics>
</m:math>
<!-- MathType@End@5@5@ -->
</para>
</solution>
</exercise>
</section>

<section id="sec63">
<name>Project Activity: Karplus-Strong VMI</name>

<para id="par64">
		As in the <cnxn document="m15489">prerequisite module</cnxn>, convert the pitch-accurate Karplus-Strong algorithm
		into a <term>virtual musical instrument</term> (<term>VMI</term>) 
		that can be played by "MIDI Jam Session." If necessary, visit 
		<cnxn document="m15053">MIDI JamSession</cnxn>, download the application VI .zip file, and view the 
		screencast video in that module to learn more about the application and how to create your 
		own virtual musical instrument. Your VMI will accept parameters that specify 
		frequency, amplitude, and duration of a single note, and will produce a corresponding array of 
		audio samples using the Karplus-Strong algorithm described in the previous section.</para>

<para id="par65">		For best results, select a MIDI music file that contains a solo instrument or perhaps a duet.
		For example, try "Sonata in A Minor for Cello and Bass Continuo" by Antonio Vivaldi. 
		A MIDI version of the sonata is available at the 
		<link src="http://www.classicalguitarmidi.com">Classical Guitar MIDI Archives</link>, specifically 
		<link src="http://www.classicalguitarmidi.com/subivic/Vivaldi_Sonata_Cello_Bass.mid">Vivaldi_Sonata_Cello_Bass.mid</link>.
</para>

</section>

<section id="sec66">
<name>References</name>

<list id="list67" type="bulleted">

<item> Moore, F.R., "Elements of Computer Music," Prentice-Hall, 1990, ISBN 0-13-252552-6. </item>
<item> Karplus, K., and A. Strong, "Digital Synthesis of Plucked String and Drum Timbres," 
			Computer Music Journal 7(2): 43-55, 1983. </item>

</list>

</section>

</content>
</document>
