Euterpea Reading Notes II


This guide is a little log that I wrote am writing while reading the book The Haskell School of Music, by Paul Hudak and Donya Quick.

Chapter 2

2.1 Preliminaries

I’ve found that good practice when starting a session with Euterpea is to check which device Euterpea will be talking to:

> devices

Input devices:
  InputDeviceID 0       IAC Driver Bus 1

Output devices:
  OutputDeviceID 1      IAC Driver Bus 1
  OutputDeviceID 2      sforzando

Channel 1, doesn’t work for me, so I use channel 2, like this:

> playDev 2 $ c 4 qn

This will play a quarter note C in octave 4. For convenience, I define p = playDev 2 so that it is enough to say

> p $ c 4 qn

2.2 Note

My reading of the text is that note (1/2) (C,4) should produce a Music Pitch value and therefore be playable. Alas, this is not the case:

> :t note (1/2) (C,4)
note (1/2) (C,4) :: Num b => Music (PitchClass, b)

By comparison, we have this, which does produce a playable value:

> :t note (1/2) (mp C 4)
note (1/2) (mp C 4) :: Music Pitch

Go figure! So we introduce the function mp (make pitch):

mp :: PitchClass -> Int ->  Pitch
mp  pitchClass octave =
    (pitchClass, octave)

Let’s check it out:

> import Experiments
> p $ note (1/2) (mp C 4)
-- A half note C in octave 4 is played

Note, however, that one has convenient functions for constructing notes:

c :: Octave -> Dur -> Music Pitch
cf :: Octave -> Dur -> Music Pitch
cs :: Octave -> Dur -> Music Pitch

2.3 Making Music: Notes in Sequence

Let’s put some notes together to make a simple melody. First, some useful (to me abbreviations):

do1 = c 4 qn  -- can't use "do". It is reserved word.
> re = d 4 qn
> mi = e 4 qn

The operator :+: is used to glue notes together in sequence:

> mel = do1 :+: re :+: mi :+: do1
> p mel

Recognize it?

Note: it is important to always know the types of the things you are working with. It is easy to recall these. For example:

> :t (:+:)
(:+:) :: Music a -> Music a -> Music a


We complete the scale for later use.

> fa = f 4 qn
> sol = g 4 qn
> la = a 4
> la = a 4 qn
> si = b 4 qn

2.4 Making Music: Notes in Parallel

Next, let’s harmonize our melody. To do this, we use the operator :=: to play notes in parallel. Thus, we can construct a C major triad like this

> triad = do1 :=: mi :=: sol

Let’s harmonize our melody in parallel thirds:

> mel2 = mi :+: fa :+: sol :+: mi
> hmel = mel :=: mel2

We could have done this in another way, first constructing do1 :=: mi, then re :=: fa, etc., and then putting them in sequence.

You could also construct the second line like this:

mel2' = transpose 4 mel

Here transpose 4 is a function that raises the pitch of each note in the melody by four semitones (half-steps), that is, by a major third:

> :t transpose
transpose :: AbsPitch -> Music a -> Music a

Now we can do this:

> p $ mel :=: mel2

Does the new harmonization sound like the old one? What is the theoretical reason for your answer?

2.5 Some Other Music Functions

Euterpea has functions for modifying melodies. Suppose, for example, that we want to speed a melody up or slow it down. We can use this:

> :t tempo
tempo :: Dur -> Music a -> Music a

With tempo it is easy play our test melody faster or slower:

> p $ tempo (2) mel    -- play it faster
> p $ tempo (1/2) mel  -- play it slower

We can also change the instrument which plays the melody:

> p $ instrument Trombone mel