Advertisement
Guest User

lol

a guest
Oct 16th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 5.14 KB | None | 0 0
  1. #lang racket
  2. ;Base class for music elements
  3. (define (music-element)
  4.   (let ((typeof (lambda () 'music-element)))
  5.     (lambda (message)
  6.       (cond ((eq? message 'typeof) typeof)
  7.             (else (error "Member" message " not found"))))))
  8.  
  9. ;Pauses for duretion of length. Useful in sequences.
  10. (define (pause length)
  11.   (if (and (number? length) (< 0 length))
  12.       (let ((super (music-element))
  13.             (getlength (lambda () length))
  14.             (typeof (lambda () 'pause))
  15.             (scale (lambda (factor) (pause (* length factor)))))
  16.         (lambda (message)
  17.           (cond ((eq? message 'getlength) getlength)
  18.                 ((eq? message 'typeof) typeof)
  19.                 ((eq? message 'scale) scale)
  20.                 ((eq? message 'transpose) (pause length))
  21.                 (else (super message)))))
  22.       (error "Malformed pause")))
  23.  
  24. (define (pause? obj)
  25.   (eq? (send 'typeof obj) 'pause))
  26.  
  27. ;Note is the building block of the melody
  28. (define (note length pitch instrument)
  29.   (if (and (number-in-interval 0 127 pitch) (number-in-interval 0 8 instrument))
  30.       (letrec ((super (pause length))
  31.                (buildfromsuper (lambda (newpause) (note (send 'getlength newpause) pitch instrument)))
  32.                (getpitch (lambda () pitch))
  33.                (getinstrument (lambda () instrument))
  34.                (typeof (lambda () 'note))
  35.                (scale (lambda (factor) (buildfromsuper (send 'scale super factor))))
  36.                (transpose (lambda (addition) (note length (+ addition pitch) instrument))))
  37.         (lambda (message)
  38.           (cond ((eq? message 'getpitch) getpitch)
  39.                 ((eq? message 'getinstrument) getinstrument)
  40.                 ((eq? message 'typeof) typeof)
  41.                 ((eq? message 'scale) scale)
  42.                 ((eq? message 'transpose) transpose)
  43.                 (else (super message)))))
  44.   (error "Malformed note")))
  45.  
  46. (define (note? obj)
  47.   (eq? (send 'typeof obj) 'note))
  48. ;A sequence of music elements played one after the other. For most basic use, a sequence of notes and pauses.
  49. (define (music-sequence elementlist)
  50.   (if (and (list? elementlist)
  51.            (andmap (lambda (element) (or (pause? element) (note? element) (music-sequence? element) (music-parallel? element))) elementlist))
  52.       (letrec ((super (music-element))
  53.                (getelementlist (lambda () elementlist))
  54.                (typeof (lambda () 'music-sequence))
  55.                (getlength (lambda ()
  56.                             (apply + (map (create-caller 'getlength) elementlist))))
  57.                (scale (lambda (factor)
  58.                         (music-sequence (map (create-caller 'scale factor) elementlist))))
  59.                (transpose (lambda (addition) (music-sequence (map (create-caller 'transpose addition) elementlist)))))
  60.         (lambda (message)
  61.           (cond ((eq? message 'getlength) getlength)
  62.                 ((eq? message 'typeof) typeof)
  63.                 ((eq? message 'scale) scale)
  64.                 ((eq? message 'getelementlist) getelementlist)
  65.                 ((eq? message 'transpose) transpose)
  66.                 (else (super message)))))
  67.       (error "Malformed sequence")))
  68.            
  69.            
  70.  
  71. (define (music-sequence? obj)
  72.   (eq? (send 'typeof obj) 'music-sequence))          
  73. ;A set of music elements that start playing at the same time
  74. (define (music-parallel elementlist)
  75.   (letrec ((super (music-sequence elementlist))
  76.            (buildfromsuper (lambda (newsequence) (music-parallel (send 'getelementlist newsequence))))
  77.            (getlength (lambda () (apply max (map (create-caller 'getlength) elementlist))))
  78.            (scale (lambda (factor) (buildfromsuper (send 'scale super factor))))
  79.            (transpose (lambda (factor) (buildfromsuper (send 'scale super factor))))
  80.            (typeof (lambda () 'music-parallel)))
  81.     (lambda (message)
  82.       (cond ((eq? message 'getlength) getlength)
  83.             ((eq? message 'typeof) typeof)
  84.             ((eq? message 'scale) scale)
  85.             ((eq? message 'transpose) transpose)
  86.             (else (super message))))))
  87. (define (music-parallel? obj)
  88.   (eq? (send 'typeof obj) 'parallel))
  89.  
  90. ;Helper for calling members
  91. (define (send message obj . par)
  92.   (let ((method (obj message)))
  93.     (apply method par)))
  94.  
  95. ;Returns a function that given an object will call the given member of that object
  96. (define (create-caller class-member . args)
  97.   (lambda (object)
  98.     (apply (object class-member) args)))
  99.  
  100. ;Checks if a number is within interval (including min and max)
  101. (define (number-in-interval min max number)
  102.   (if (andmap number? (list min max number))
  103.       (and (>= number min) (<= number max))
  104.       (error "Parameter is not a number")))
  105. ;Tries to transpose an
  106. ;test
  107. (define testpause (pause 5))
  108. (define testnote (note 7 5 3))
  109. (define testnote2 (note 1 6 4))
  110. (define testsequence (music-sequence (list testnote2 testnote testnote testnote2)))
  111. (define testparallel (music-parallel (list testpause testnote testnote testpause)))
  112. (map (create-caller 'getpitch) (send 'getelementlist (send 'transpose testsequence 4)))
  113. (map (create-caller 'getpitch) (send 'getelementlist testsequence))
  114. (send 'typeof (send 'scale testparallel 1))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement