Begin implementing (perform)

This commit is contained in:
Jeremy Dormitzer 2018-08-08 21:44:37 -04:00
parent 44511732c0
commit 83524851fd

View File

@ -1,4 +1,15 @@
(ns performance) (ns performance
(:require [clojure.core.match :refer [match]]))
;; A player is an entity that knows how to interpret music in a certain ways
;; I need to flesh most of this out -- see section 8.3 on page 141
(def a-player
{:name "player1" ;; player name
:play-note
(fn [context note] ()) ;; function to play a note with a context, returns Performance
:interp-phrase
(fn [p-map context attrs music]) ;; function to interpret a Music value, returns performance
:notate [context note]}) ;; function to transcribe a note - not implemented in Euterpea
;; A performance is a data structure that describes the act ;; A performance is a data structure that describes the act
;; of performing a piece of music. It is a vector of events, ;; of performing a piece of music. It is a vector of events,
@ -17,13 +28,41 @@
;; changing tempo, key signature, tempo, etc. ;; changing tempo, key signature, tempo, etc.
(def my-context (def my-context
{:time 0 ;; time at which the performance starts in seconds {:time 0 ;; time at which the performance starts in seconds
:player {:?? :??} ;; not sure what this is :player a-player ;; player currently interpreting the music
:instrument "Cello" ;; instrument currently playing (?) :instrument "Cello" ;; instrument currently playing (?)
:duration-t 2 ;; the duration in seconds of a whole note :duration-t 2 ;; the duration in seconds of a whole note
:pitch-offset 0 ;; a pitch offset -- number of semitones to transpose notes up or down :pitch-offset 0 ;; a pitch offset -- number of semitones to transpose notes up or down
:volume 50 ;; volume of performance :volume 50 ;; volume of performance
:key [:C :major]}) ;; current key signature :key [:C :major]}) ;; current key signature
(defn perform
"Convert a music value to a performance value"
[player-map context music]
(first (perf player-map context music)))
(defn perf
"Implementation of perform, returns a tuple of (performance, duration)"
[player-map context music]
(let [{:keys [player duration-t]} context]
(match music
{:duration duration
:pitch pitch} (apply (:play-note player)
context
duration
pitch
(* duration duration-t))
{:duration duration} [[] (* duration duration-t)]
[:+ & ms] (reduce (fn [[events-acc dur-acc] m]
(let [[events dur] (perf player-map
context
m)]
[(concat events-acc dur-acc)
(+ dur-acc dur)]))
[[] 0]
ms)
[:= & ms] :TODO
[:modify control m] :TODO)))
(defn metro (defn metro
"Generates a duration-t value (the duration in seconds of a whole note) "Generates a duration-t value (the duration in seconds of a whole note)
from the number of beats per minute and the duration of a beat (1/4 for from the number of beats per minute and the duration of a beat (1/4 for