Some functions that you may need are provided in the file Cons.java, and you will need some of your functions from the last assignment. Question 1 may be done in Java or in Lisp; the rest should be done in Java.
This function will do the same thing as the earlier version of solve; in this version, use patterns to rewrite the given expression. The three base cases are the same as before, and you can copy your earlier code for those cases.
(solve '(= f (* m a)) 'f) => (= f (* m a))
(solve '(= (* m a) f) 'f) => (= f (* m a))
An initial list of patterns is provided; add patterns to complete the set.
The class should be created using new Memoizer(Functor f) where f is a functor that wraps the function associated with the memoizer.
Use a HashMap within the Memoizer to associate function values with argument values. You can Google "java hashmap" to get documentation of a HashMap.
Memoizer should have a method Object call(Object x) to perform the wrapped function call. The call method should operate as follows:
Reference: http://en.wikipedia.org/wiki/Memoization
The drum synthesizer driver program is implemented as a discrete-event simulator, based on a PriorityQueue. You can Google "java priorityqueue" to get documentation of a PriorityQueue.
A discrete-event simulator processes a sequence of events which are scheduled at particular clock times. The PriorityQueue is used to hold the pending events, with the priority being the time at which an event is scheduled to occur. In operation, the simulator removes the highest-priority (smallest time value) event from the queue, sets the current time to the time of the event, and executes it; the event will typically perform some action, and it may schedule other events for the future. The simulation stops if the queue becomes empty.
We will assume that time values are integers. Events that occur at the same integer time are considered to be simultaneous, regardless of their order, since the computer is much faster than the drum units. A time duration of 1 represents a 1/16 note duration.
An Event has a scheduled .time() and an .action(); this class is provided. An action is a list, consisting of a command followed by parameters; usually there is only one parameter, the length of time the command lasts. An event is added to the queue by the call addevent(PriorityQueue pq, Cons action, int time) .
Execution of a command may emit an I/O command to the drum unit. Write a function execute(PriorityQueue pq, Cons act, int time) that executes an action by emitting appropriate commands.
The function emit(instrument, time, duration) sends a command to a drum instrument; the arguments are all int. The instrument values are as follows:
| 4 | [bass_drum] | boom |
| 5 | [acoustic_snare] | snare |
| 6 | [pedal_hi_hat] | hat |
| 7 | [crash_cymbal_1] | cymbal |
| 8 | [cowbell] | cowbell |
| 9 | [ride_bell] | bell |
| 10 | [hand_clap] | clap |
| 11 | [tambourine] | tambourine |
Commands are as follows, with d representing the duration of the action; usually a duration should be a power of 2, except for rest.
Examples:
(seq (boom 4) (bell 4)) (seq (repeat 2 (kaboom 4)) (repeat 3 (cymbal 2))) (repeat 2 (seq (piano 0 C5 4) (piano 0 D5 4) (piano 0 E5 4)))
Write a function int totaltime(Cons action) that calculates the total time required for an action. For most actions, the time is simply the duration of the action. A repeat action has a time that is the repeat count times the time of the sub-action. A seq action takes the sum of the times of its sub-actions. A sync action takes the maximum time of its sub-actions.
The jFugue system, http://jfugue.org, allows sounds to be produced from Java. An interface has been written to allow the output of your program to produce sounds through jFugue. If you would like to use jFugue, download it from the jFugue site and install it in the same directory that you use for your program. Rename the file Cons.jfugue.java to be Cons.java .
Reference: http://en.wikipedia.org/wiki/Discrete_event_simulation