<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="MSP MIDI Tutorial 2: MIDI Synthesizer">
	<previous module="msp"  name="10_midichapter01"></previous>
	<next module="msp" name="10_midichapter03"></next>
	<parent name="00_mspindex">MSP Tutorials</parent>

<setdocpatch name="02iMIDISynthesizer" patch="02iMIDISynthesizer.maxpat"/>

	<h1>
		MIDI Tutorial 2: MIDI Synthesizer
	</h1>

	<p>
		In this tutorial we show how to create and work with a simple 4-voice
		MIDI-controllable synthesizer. Along the way, we discuss simple methods
		of polyphonic routing as well as using a variety of common MIDI messages
		to control synthesis parameters.
	</p>

	<bullet>
		To use the tutorial patchers in this section of the tutorial, make sure
		you have a correctly configured MIDI controller connected to your computer.
		The tutorials in this section use a variety of MIDI messages as example
		input; if your controller lacks any of these features, you can simulate
		their input with user interface objects in the tutorial.
	</bullet>



	<h2>
		Playing our synthesizer
	</h2>

	<bullet>
		Take a look at the tutorial patcher. Notice that it contains a fair bit
		of patcher logic involving four different categories of MIDI input objects
		sending messages and signals to four copies of an
		abstraction
		called <m>synthvoice~</m>. Turn on audio by clicking the <o>ezdac~</o>,
		turn up the <o>gain~</o> slider, and play some notes on your MIDI keyboard.
		The <o>kslider</o> object should animate in response to your actions.
		While holding a note, adjust the pitch bend wheel on your keyboard.
		Adjust the modulation wheel or another controller that can send CC#1.
		Listen to the different changes to the sound.
	</bullet>

	<p>
		Our tutorial patcher deals with MIDI through a number of methods.
		Let's look through these one at a time.
	</p>

	<bullet>
		Play notes on your keyboard one at a time and look at the area of
		the tutorial patcher labeled <m>1</m>. Notice what the <o>poly</o> object
		does to the values. Try playing a note and holding it, then adding
		another while the first key is still down.
	</bullet>

	<p>
		Our tutorial patcher is capable of playing four sounds at the same time, due
		to there being four different copies of the <m>synthvoice~</m> abstraction in
		our patch. In order to take advantage of the polyphony however, we need to
		figure out how to <i>route</i> our MIDI values to the different voices so
		that the appropriate copy of the <m>synthvoice~</m> abstraction receives
		each message. The <o>poly</o> object takes MIDI pitch and velocity and
		performs <i>voice assignment</i> on the values based on the arguments to
		the object. The first note the object receives will be given voice
		number <m>1</m>, the second note voice <m>2</m>, and so on. Once we
		exceed the polyphony the object is programmed for (in our case, <m>4</m> voices),
		the object will roll around and start again at voice <m>1</m>. Note-off events
		will map to the <i>same voice</i> as their corresponding note-on events, guaranteeing
		that the message to stop a MIDI event goes to the same destination as the one
		that started it.
	</p>

	<bullet>
		Using your MIDI keyboard, play a four-note chord. Now, without releasing any
		of the keys, press a fifth note. Notice what happens.
	</bullet>

	<p>
		The second argument to <o>poly</o> (<m>1</m>) tells it to <i>steal</i> voices
		if the polyphony is exceeded. If we attempt to sound more notes than the <o>poly</o> object
		allows for, the <i>oldest</i> note will be dropped and its voice will be recycled.
	</p>

	<p>
		The output for our <o>poly</o> object is sent into a <o>pack</o> object
		and then through a <o>route</o> object to send the remaining lists of pitches
		and velocities to the appropriate copy of our <m>synthvoice~</m> abstraction.
	</p>

	<bullet>
		Take a look at tutorial area <m>2</m>. Move the pitch bend wheel on your
		keyboard controller. Notice that, unlike most controllers, its resting
		point is at the middle of the range at <m>63</m>. See what the patcher
		logic below does to scale the values between <m>-2.</m> and <m>2.</m>
	</bullet>

	<p>
		To create our pitch bend value, we take the MIDI pitch bend wheel
		and <o>split</o> its range to two different <o>scale</o> objects. The
		left-hand <o>scale</o> object takes the lower half of the MIDI range and
		scales it from <m>-2.</m> to <m>0.</m>; the right-hand object scales the
		upper range between <m>0.</m> and <m>2.</m> This guarantees that the center
		value in the range (<m>63</m>) maps to a value of <m>0.</m> in all cases.
	</p>

	<bullet>
		Take a look at the tutorial area labeled <m>3</m>. Move the continuous
		controller and look how it's scaled. Look at the tutorial area labeled <m>4</m>.
		If you have a MIDI controller with real-time transport capabilities (i.e. it
		can send MIDI beat clock), set it up to transmit at any tempo you like and start
		the transport on the controller. If you like, you could also use an inter-application
		MIDI routing utility and a software sequencer on your computer to do this. If not,
		click in the <o>number</o> box labeled <m>tick speed</m> and enter the value <m>20.</m>
		Change the continuous controller and play some notes. Listen to the result.
		Change the <m>tick speed</m> to something faster (like <m>10.</m>). Notice what happens.
	</bullet>

	<p>
		The MIDI CC# and the real-time messages are sent in by the <o>ctlin</o>
		and <o>rtin</o> objects, respectively, to work together controlling a low-frequency
		oscillator (LFO). The real-time messages that define the <i>beat clock</i>
		control the <i>rate</i> of the LFO; the controller messages change the <i>depth</i>.
		MIDI beat clock typically runs at 96 PPQ; the <o>timer</o> object measures the intervals
		between ticks, which are then scaled to derive the rate of the LFO so that it lasts
		one measure. MIDI real-time message <m>250</m> (the 'start' message on a sequencer)
		resets the phase of the <o>cycle~</o> object so that the LFO will re-synch with a
		sequence if it starts on a barline.
	</p>

	<p>
		Note how the output of the LFO is scaled so that even with the depth sending a
		signal of <m>0.</m>, the signal sent into the <m>synthvoice~</m> abstraction is
		guaranteed to be centered around <m>1.</m> Let's take a look at what's in that
		patch.
	</p>

	<h2>
		The <m>synthvoice~</m> abstraction
	</h2>

	<bullet>
		Double-click any of the abstractions named <m>synthvoice~</m> and look
		at the patcher logic inside.
	</bullet>

	<p>
		Our <m>synthvoice~</m> abstraction has three inLets. The first inlet
		takes lists of pitch and velocity values from our MIDI keyboard input.
		The <i>pitch</i> value is sent to drive a constant signal (<o>sig~</o>)
		which has the signal from inlet #2 added to it (<o>+~</o>). This value
		is then interpreted as a MIDI number and converted to a frequency in the
		signal domain by an object called <o>mtof~</o>, which behaves just like
		the <o>mtof</o> object but operates on continuous MSP signals instead of
		Max numbers. This frequency value then feeds two band-limited oscillators:
		a square wave (<o>rect~</o>) and a sawtooth wave (<o>saw~</o>) which are mixed
		together. The <i>frequency</i> of the <o>rect~</o> object is multiplied by
		the LFO signal coming in inlet #3 so that a rich, chorused tone can be acheived
		when the depth of the LFO is increased.
	</p>

	<h2>
		Standard synthesizer envelopes: <o>adsr~</o>
	</h2>

	<p>
		Meanwhile, the <i>velocity</i> output of the MIDI notes is scaled
		between <m>0.</m> and <m>1.</m> and sent to an object called <o>adsr~</o>. The
		object stands for <i>Attack, Decay, Sustain, Release,</i> and generates
		signal ramps in a standard configuration borrowed from analog synthesizer
		design:
	</p>

	<illustration>
		<img src="images/midichapter02a.png"/>
	</illustration>

	<caption>
		<i>A standard ADSR curve.</i>
	</caption>

	<p>
		The arguments to <o>adsr~</o> are interpreted as an attack time, a decay
		time, a sustain <i>level</i>, and a release time. The sustain level is a
		multiplier of the overall amplitude which the object outputs during a sustaining note.
	</p>

	<p>
		The <o>adsr~</o> object takes a value and interprets it as an envelope
		trigger of a certain amplitude. Any number higher than <m>0.</m> triggers
		the attack, decay, and sustain phases, scaled to match the amplitude of the
		trigger (e.g. an input value of <m>0.5</m> will trigger a softer envelope
		than a trigger of <m>0.8</m>). The object then stays at the sustain phase,
		putting out a constant value until it receives a <m>0.</m> It then continues
		to the release phase of the envelope and ramps to <m>0</m>.
	</p>

	<bullet>
		Now that we understand how the synthesizer elements work, return to the
		main patcher and see if the controllable parameters make sense. Try
		exploring the full range of the MIDI control to see how expressive it is.
	</bullet>

	<h2>
		Summary
	</h2>

	<p>
		Within a patcher, MIDI note events can be routed polyphonically to different
		copies of the same abstraction using a <o>poly</o> object. Objects such
		as <o>bendin</o> and <o>ctlin</o> can be scaled to match different synthesizer
		parameter ranges, and real-time MIDI commands can be used to derive tempo
		data for LFOs and sequencers within Max. The <o>adsr~</o> object generates
		envelope ramps based on triggers for a note-on and a note-off, making it
		ideal for use with MIDI note-based systems.
	</p>

	<seealsolist>
		<seealso name="poly">Allocate notes to different voices</seealso>
		<seealso name="mtof~">Convert a MIDI note number to frequency at signal rate</seealso>
		<seealso name="adsr~">ADSR envelope generator</seealso>
	</seealsolist>
</chapter>
