1 Notes
2 Keyboard Control

Lab 9

In this lab, you must write a program that uses a signal to play a melody, with keyboard control over the volume (on/off) and pitch (up/down an octave).

First, here’s the code for a (tiny, somewhat inadequate) event channel mechanism, as discussed in class:

"event-channel.rkt"

#lang racket
 
(provide make-event-channel
         send-event
         try-get-event)
 
; ;; these event channels are fast, but not synchronized;
; ;; race conditions are definitely possible.
 
; ;; -> event-channel
(define (make-event-channel)
  (box #f))
 
; ;; event-channel event -> void
(define (send-event channel event)
  (set-box! channel event))
 
; ;; event-channel -> (false event)
(define (try-get-event channel)
  (define gotten (unbox channel))
  (when gotten (set-box! channel #f))
  gotten)

Paste this code into a new buffer, and change the language level in this buffer to "Use Language Specified in Source". Make sure it runs (it shouldn’t produce any output), then save it as "event-channel.rkt" in the same directory that your lab will be in.

Next, it might be a good idea to make sure that the code from class on November 14th runs successfully.

Note that this code includes a representation for note-start and note-stop events, so that you can send these to the network. You’re welcome to use the representation we came up with in class:

; an event is oneof
; -(make-note-start pitch)
; -(make-note-stop)
(define-struct note-start (pitch))
(define-struct note-stop ())

1 Notes

Next, your big-bang world will have to deliver these events, according to some kind of schedule. I suggest that a "schedule" should be a list of "future-events", where a future event contains a time and an event, and indicates that the given event is to occur at the given time.

Once you’ve developed these representations, you can define your song as a schedule. Make your first song simple—two or three notes, perhaps.

In order to play these notes, your world will need to contain at least two things: the current time in seconds, and the remaining schedule. Then, your tick-handler will have to compare the current time to the events at the beginning of the list, to see whether it’s time to deliver one or more of the events in the list. If so, use send-event to deliver these events, then return a world that has an updated time, and where the issued events are no longer on the schedule.

2 Keyboard Control

Once you have the notes being played, we want to extend the framework so that it can handle play/no-play and octave-up/down triggers from the keyboard.

In order to do this, your world state will need to include two additional pieces; the on/off toggle, and the octave shift. The keyboard handler will need to update these two based on keypresses, and the on-tick handler will need to use this information to modify the events being sent to the network.