# Exercise 1.14 A music language in Scheme ****

Design a simple and small Lisp (Scheme) language for music. In this assignment, music is basically modelled in terms of notes and pauses. A note is characterized by a pitch value, a duration, and an instrument. A pause is characterized by a duration. A pitch value is an integer between 0 and 127 (where 60 is middle C). Durations are integers; 960 time units correspond roughly to a second. Instruments are represented as symbols, where the following are supported: Piano, Organ, Guitar, Violin, Flute, Trumpet, Helicopter eller Telephone.

Notes and pauses can be composed sequentially and in parallel. Conceptually, a MusicElement is either a Note, a Pause, a SequentialMusicElement or a ParallelMusicElement. A SequentialMusicElement represents a collection of MusicElements which are played in a strict sequence (one after the other). A ParallelMusicElement represents a collection of MusicElements which are played together (all starting at the same time). Please notice the recursive nature of this modelling: A SequentialMusicElement or a ParallelMusicElement consist of parts, which themselves may be of type SequentialMusicElement and/or ParallelMusicElement. Notes and pauses terminate the recursion. This model of music is a composite (design pattern), and it can be illustrated as in the following class hierarchy:

You are asked to program the following functionality:

• Constructor functions for the Scheme Music Language - one for each of the four forms of music elements. Each such construction function should accept flexible parameters, and it should check its constituents such that a constructed music element is guaranteed to be well-formed. Music elements may be constructed in terms of the pich values, duration values and instrument values. Alternatively, or supplementary, you may prefer to introduce note names (such as C, CS, D), durations in terms of rational numbers (such as 1/2, 1/4, 1/8), octave numbers, and similar ideas.
• Predicates that identify each of the four music elements.
• Selectors that access the parts of each type of a music element.
• Functions that scales, transposes, and re-instruments a music element. Scaling multiplies durations with a scaling factor, transposition adds to the note pitch, and re-instrumentation changes instrument. Each of these must be implemented as pure functions that return modified music elements.
• A function that returns the duration of music element.
• A boolean function monophonic? that returns if a music element is monophonic (at most one note sounds at a time)
• An integer function degree-of-polyphony that returns the maxium number of notes that play at the same time in a music element. Please notice: The degree of polyphony of a parallel music element may be less than the count of its constituent music elements (due to pauses in some parts). Therefore you should be careful when you program degree-of-polyphony for ParallelMusicElements.
• A function that maps (linearizes) a music element object to a flat list of absolutely time note objects (a list which we conceive as a low level "event list"). Absolutely timed note objects can be constructed by the function note-abs-time-with-duration (already provided and implemented for you). A list of note-abs-time-with-duration forms can be transformed to a playable MIDI file in a number of different ways (see below).

Finally, your program must include an example of a simple canon song, and you must include the generated MIDI file in your submission.

The constructor function note-abs-time-with-duration takes the following parameters:

`   (note-abs-time-with-duration abs-time channel note-number velocity duration)`

where

• abs-time: A non-negative integer, in time ticks. The absolute start time of the note.
• channel: An integer between 1 and 16, which in reality is a MIDI channel allocated to the requested instrument. Channel 1 is a piano, channel 2 is an organ, channel 3 is a guitar, channel 4 is a violin, channel 5 is a flute, channel 6 is a trumpet, channel 7 is a helicopter, and channel 8 is a telephone.
• note-number: An integer between 0 and 127. In reality a MIDI note number.
• velocity: An integer between 0 and 127. The velocity (strength) of the note. Not controllable in this exercise. Therefore it can be given as a constant, such as 80.
• duration: A non-negative integer. The duration of this note (measured in time ticks).

The procedure transform-to-midi-file! transforms a list of note-abs-time-with-duration forms to a playable MIDI file. The procedure has the following signature:

`   (transform-to-midi-file-and-write-to-file! low-level-event-list filename)`

where

• low-level-event-list: A list of values, each of which are returned by the function note-abs-time-with-duration.
• filename: A MIDI file name, or a path to MIDI file name.

The low-level transformation functionality, which supports this exercise, can be downloaded from the course website in a number of different variants (depending on your Scheme platform).

Alternatively, a playable MIDI file can be generated by a web service from a list of note-abs-time-with-duration forms, provided that you use this simple implementation of the constructor function:

```  ; Construct the low-level internal representation of a note (with note-number)
; bound to a particular absolute time (in time ticks), and with a given duration
; (in time ticks). The channel parameter encodes the instrument used.
; The velocity represents the strengths of the node.
(define (note-abs-time-with-duration abs-time channel note-number velocity duration)
(cons 'note-abs-time-with-duration (list abs-time channel note-number velocity duration)))```

In case of inaccuracies in the formulation of this exercise, please state the conditions under which you have created you solution.

There is no solution to this exercise