120 likes | 187 Views
Chapter 21. Interpreting Functional Music. Motivation. A program written in any language, including a DSL, must have a meaning , i.e. an interpretation , or denotation, or model , or semantics (all of these terms are equivalent).
E N D
Chapter 21 Interpreting Functional Music
Motivation • A program written in any language, including a DSL, must have a meaning, i.e. an interpretation, or denotation, or model, or semantics (all of these terms are equivalent). • A FAL program denotes a time-varying animation, captured concretely in the type “Behavior” and the function “reactimate”. • An IRL program denotes a state transformer, captured concretely in the type “Robot” and the function “runRobot”. • What is the meaning of an MDL program? • Abstractly, an MDL program denotes a piece of music. • Concretely, it will denote a performance, which is a sequence of musical events.
Performance • An MDL program denotes a performance:type Performance = [ Event ] data Event = Event { eTime :: Time, eInst :: IName, ePitch :: AbsPitch, eDur :: DurT } deriving (Eq, Ord, Show) type Time = Float type DurT = Float • An event “Event t i p d” means that instrument i sounds pitch p at time t for duration d. • A performance p is assumed to be time-ordered, and simultaneous events are allowed.
From Music to Performance • To convert a Music value to a Performance, we need to know the start time, default instrument, tempo, and key. This is called the context:data Context = Context { cTime :: Time, -- start time cInst :: IName, -- instrument cDur :: DurT, -- tempo cKey :: Key } -- key deriving Showtype Key = AbsPitch • Then a Music value’s meaning is captured by:perform :: Context -> Music -> Performance
Tempo and Metronomes • The “tempo” is the duration, in seconds, of a whole note. • For convenience, we define a metronome function:metro :: Float -> Dur -> DurT metro setting dur = 60 / (setting * ratioToFloat dur) • For example, “metro 96 qn” corresponds to a tempo of 96 quarter notes per minute.
Time to Perform perform :: Context -> Music -> Performance perform c@(Context t i dt k) m =case m of Note p d -> let d' = rtf d * dt in [Event t i (transpose p k i) d'] Rest d -> [] m1 :+: m2 -> perform c m1 ++ perform (c {cTime = t + rtf (dur m1) * dt}) m2 m1 :=: m2 -> merge (perform c m1) (perform c m2) Tempo a m -> perform (c {cDur = dt / rtf a}) m Trans p m -> perform (c {cKey = k + p}) m Instr nm m -> perform (c {cInst = nm}) mwhere transpose p k Percussion = absPitch p transpose p k _ = absPitch p + k rtf = ratioToFloat [ Note: the treatment of (:+:) is inefficient (why?). See the text for a more efficient solution. ]
Merge • The function “merge” must preserve the time-ordered nature of its arguments. • A correct but inefficient solution would be:merge :: Performance -> Performance -> Performance merge es1 es2 = sort (es1 ++ es2) • A more efficient solution is:merge a@(e1:es1) b@(e2:es2) = if e1 < e2 then e1 : merge es1 b else e2 : merge a es2 merge [] es2 = es2 merge es1 [] = es1 • If we are willing to give up a certain algebraic property (discussed later), the text gives an even more efficient solution.
An Algebra of Music • Consider these two Music values:(m1 :+: m2) :+: m3 m1 :+: (m2 :+: m3) • As Haskell values, they are not equal. But under any reasonable interpretation of music, they should be. “If they sound the same, they are the same.” • Definition:Two musical values m1 and m2 are equivalent, written m1 ≡ m2, if and only if: (∀c) perform c m1 = perform c m2 • Thus we expect that:(m1 :+: m2) :+: m3 ≡ m1 :+: (m2 :+: m3) • [ Note similarity to equivalence of regions in Ch. 8. ]
Axioms and Theorems • The associative law just given can be proved by unfolding “perform”.[ This is left as an exercise, but see the text for other examples of this technique. ] • Laws that can only be proved by appealing to the model are called axioms. • Laws that can be proved using only the axioms are called theorems. • If an axiom is true it is said to be sound. • If any equivalence can be expressed using the set of axioms, the set is said to be complete. • A sound and complete set of axioms is called an axiomatic semantics.
Axioms for Music • Tempo is multiplicative and Transpose is additive.Tempo r1 (Tempo r2 m) ≡ Tempo (r1*r2) m Trans p1 (Trans p2 m) ≡ Trans (p1+p2) m • Function composition is commutative with respect to both tempo scaling and transposition.Tempo r1 . Tempo r2 ≡ Tempo r2 . Tempo r1 Trans p1 . Trans p2 ≡ Trans p2 . Trans p1 Tempo r1 . Trans p1 ≡ Trans p1 . Tempo r1 • Tempo scaling and transposition are distributive over both sequential and parallel composition.Tempo r (m1 :+: m2) ≡ Tempo r m1 :+: Tempo r m2 Tempo r (m1 :=: m2) ≡ Tempo r m1 :=: Tempo r m2 Trans p (m1 :+: m2) ≡ Trans p m1 :+: Trans p m2 Trans p (m1 :=: m2) ≡ Trans p m1 :=: Trans p m2
More Axioms • Sequential and parallel composition are associative. m0 :+: (m1 :+: m2) ≡ (m0 :+: m1) :+: m2 m0 :=: (m1 :=: m2) ≡ (m0 :=: m1) :=: m2 • Parallel composition is commutative. m0 :=: m1 ≡ m1 :=: m0 • Rest 0 is a unit for Tempo and Trans, and a zero for sequential and parallel composition. Tempo r (Rest 0) ≡ Rest 0 Trans p (Rest 0) ≡ Rest 0 m :+: Rest 0 ≡ m ≡ Rest 0 :+: m m :=: Rest 0 ≡ m ≡ Rest 0 :=: m
m0 m1 m0 m1 m2 m3 m2 m3 Completeness • The set of axioms so far is sound. • Adding this axiom (stated as an exercise in the text) makes the set complete: (m0 :+: m1) :=: (m2 :+: m3) ≡ (m0 :=: m2) :+: (m1 :=: m3) if dur m0 = dur m2 • This is called the “serial-parallel axiom”. • Pictorially: ≡