```\subsubsection{Pitch}
\seclabel{pitch}

Perhaps the most basic musical idea is that of a \keyword{pitch},
which consists of an \keyword{octave} and a \keyword{pitch class}
(i.e. one of 12 semi-tones, cf. \secref{discussion:pitch}):

> module Haskore.Basic.Pitch where

> import Data.Ix(Ix)

> type T      = (Octave, Class)
> data Class  = Cf | C | Cs | Df | D | Ds | Ef | E | Es | Ff | F | Fs
>             | Gf | G | Gs | Af | A | As | Bf | B | Bs
> type Octave = Int

So a \type{Pitch.T} is a pair consisting of a pitch class and an octave.
Octaves are just integers, but we define a datatype for pitch classes,
since distinguishing enharmonics (such as \$G^\#\$ and \$A^b\$) may be important
(especially for notation).
\figref{note-freqs} shows the meaning of the some \type{Pitch.T} values.

\begin{figure}
\begin{center}
\begin{tabular}{llr}
\$A_2\$ & \code{(-3,A)} &  27.5 Hz \\
\$A_1\$ & \code{(-2,A)} &  55.0 Hz \\
\$A  \$ & \code{(-1,A)} & 110.0 Hz \\
\$a  \$ & \code{( 0,A)} & 220.0 Hz \\
\$a^1\$ & \code{( 1,A)} & 440.0 Hz \\
\$a^2\$ & \code{( 2,A)} & 880.0 Hz
\end{tabular}
\end{center}
\caption{Note names, Haskore representations and frequencies.}
\figlabel{note-freqs}
\end{figure}

Treating pitches simply as integers is useful in many settings,
so let's also define some functions for converting between \type{Pitch.T}
values and \type{Pitch.Absolute} values (integers):

> type Absolute = Int
> type Relative = Int
>
> toInt :: T -> Absolute
> toInt (oct,pc) = 12*oct + classToInt pc
>
> fromInt :: Absolute -> T
> fromInt ap =
>    let (oct, n) = divMod ap 12
>    in  (oct, [C,Cs,D,Ds,E,F,Fs,G,Gs,A,As,B] !! n)
>
> classToInt :: Class -> Relative
> classToInt pc = case pc of
>      Cf -> -1;  C ->  0; Cs ->  1   -- or should Cf be 11?
>      Df ->  1;  D ->  2; Ds ->  3
>      Ef ->  3;  E ->  4; Es ->  5
>      Ff ->  4;  F ->  5; Fs ->  6
>      Gf ->  6;  G ->  7; Gs ->  8
>      Af ->  8;  A ->  9; As -> 10
>      Bf -> 10;  B -> 11; Bs -> 12   -- or should Bs be 0?

Now two functions for parsing and formatting pitch classes
in a more human way, that is using '\#' and 'b' suffixes
instead of 's' and 'f'.
We do not simply use

> classParse :: ReadS Class
> classParse (p:'#':r) = reads (p:'s':r)
> classParse (p:'b':r) = reads (p:'f':r)
> classParse r = reads r

> classFormat :: Class -> ShowS
> classFormat pc =
>    let (p:r) = show pc
>    in  (p:) .
>        case r of
>           [] -> id
>           's':[] -> ('#':)
>           'f':[] -> ('b':)
>           _ -> error ("classFormat: Pitch.Class.show must not return suffixes" ++
>                       " other than 's' and 'f'")

Using \type{Pitch.Absolute} we can compute the frequency associated
with a pitch:

> intToFreq :: Floating a => Absolute -> a
> intToFreq ap = 440 * 2 ** (fromIntegral (ap - toInt (1,A)) / 12)

We can also define a function \function{Pitch.transpose},
which transposes pitches
(analogous to \function{Music.transpose},
which transposes values of type \type{Music.T}):

> transpose :: Relative -> T -> T
> transpose i p = fromInt (toInt p + i)

\begin{exercise}
Show that\ \ \code{toInt\ .\ fromInt = id}, and,
up to enharmonic equivalences,\newline \code{fromInt\ .\ toInt = id}.
\end{exercise}

\begin{exercise}
Show that\ \ \code{transpose i (transpose j p) = transpose (i+j) p}.
\end{exercise}
```