Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (require rsound)
- (require 2htdp/universe)
- ;;; PRE PROCESSING ;;;
- (define TICK_RATE 1/40)
- (define SAMPLE (resample-to-rate FRAME-RATE (rs-read "sample.wav")))
- (define FRAMES (rs-frames SAMPLE))
- (define NUMBER_OF_INTERVALS (floor (/ FRAMES (* TICK_RATE FRAME-RATE))))
- (define INTERVAL_LENGTH (* TICK_RATE FRAME-RATE))
- (define TRACK (rs-append SAMPLE (silence 48000))) ; might not be needed, but the padding might be necessary. keep for now just in case
- ;;; HELPER FUNCTIONS ;;;
- ; return the frame value of the amount of seconds given
- ; Number -> Natural Number
- (define (sec x) (* x FRAME-RATE))
- (check-expect (sec 1) FRAME-RATE)
- (check-expect (sec 2) (* FRAME-RATE 2))
- ; return the tick rate times a given value
- ; Number -> Number
- (define (interval x) (* x TICK_RATE))
- (check-expect (interval 1) TICK_RATE)
- (check-expect (interval 2) (* 2 TICK_RATE))
- ; return the sum of the squares of all rs-ith values in the given frame interval
- ; Natural Number, Natural Number -> Number
- (define (sum-of-squares upper lower)
- (cond [(<= upper lower) 0]
- [else
- (+ (expt (rs-ith/left SAMPLE upper) 2) (sum-of-squares (- upper 1) lower))
- ]
- ))
- (check-within (sum-of-squares (sec 10) (sec 9)) 1703 10)
- ; a list of intervals has a length of NUMBER_OF_INTERVALS
- ; the 0th entry is the sum of squares between (1/20 * FRAMES) and (0/20 * FRAMES)
- ; the 1st entry is the sum of squares between (2/20 * FRAMES) and (1/20 * FRAMES)
- ; the 2nd entry is the sum of squares between (3/20 * FRAMES) and (2/20 * FRAMES)
- ; the 3rd entry is the sum of squares between (4/20 * FRAMES) and (3/20 * FRAMES)
- ; and so on
- ; a list-of-intervals is one of:
- ; - '()
- ; - (cons Number list-of-intervals)
- ; ex:
- (cons 5 '())
- ; Task: develop a function that will return a list of intervals that follows the above pattern
- ; generate a list of intervals of length NUMBER_OF_INTERVALS - ***NUMBER_OF_INTERVALS IS THE ONLY ACCEPTABLE ARGUMENT***
- ; NUMBER_OF_INTERVALS -> list-of-intervals
- (define (genIntervalList max)
- (cond [(= max 0) '()]
- [else
- (cons (sum-of-squares (floor (* FRAME-RATE max TICK_RATE)) (floor (* FRAME-RATE (- max 1) TICK_RATE))) (genIntervalList (- max 1)))
- ]
- ))
- (define TRACK_INTERVAL_LIST (genIntervalList NUMBER_OF_INTERVALS))
- ;;; END OF PRE-PROCESSING ;;;
- ;;; playing sound stuff ;;;
- (define PLAY_SECONDS 1/20)
- (define PLAY_FRAMES (* PLAY_SECONDS FRAME-RATE))
- (define PLAY_POSNFRAC (/ PLAY_SECONDS (/ (rs-frames SAMPLE) FRAME-RATE)))
- (define MAX_QUEUE_INTERVAL (* 3/80 FRAME-RATE))
- (define STREAM (make-pstream))
- ;;; Drawing Stuff ;;;
- ;;; button box stuff ;;;
- (define BUTTON_BOX_WIDTH 1080)
- (define BUTTON_BOX_HEIGHT 90)
- (define BUTTON_BOX (rectangle BUTTON_BOX_WIDTH
- BUTTON_BOX_HEIGHT
- "outline"
- "black"))
- ;;; button stuff ;;;
- (define BUTTON_WIDTH 150)
- (define BUTTON_HEIGHT 80)
- ; make a button array
- ; mode -> Image
- (define (buttons mode)
- (cond [(= mode 1)
- (beside
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "green")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- )
- ]
- [(= mode 2)
- (beside
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "green")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- )
- ]
- [(= mode 3)
- (beside
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "green")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- )
- ]
- [(= mode 4)
- (beside
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "red")
- (rectangle BUTTON_WIDTH
- BUTTON_HEIGHT
- "solid"
- "green")
- )
- ]
- ))
- ;;; visualizer box stuff ;;;
- (define VISUALIZER_BOX_WIDTH 1080)
- (define VISUALIZER_BOX_HEIGHT 560)
- (define VISUALIZER_BOX (rectangle VISUALIZER_BOX_WIDTH
- VISUALIZER_BOX_HEIGHT
- "outline"
- "black"))
- ;;; slider box stuff ;;;
- (define SLIDER_BOX_WIDTH 1080)
- (define SLIDER_BOX_HEIGHT 90)
- (define SLIDER_BOX (rectangle SLIDER_BOX_WIDTH
- SLIDER_BOX_HEIGHT
- "outline"
- "black"))
- ;;; slider stuff ;;;
- (define SLIDER_HEIGHT 160)
- (define SLIDER_WIDTH 9)
- (define SLIDER (rectangle SLIDER_WIDTH
- SLIDER_HEIGHT
- "solid"
- "black"))
- ; a posn-list is one of:
- ; - '()
- ; - (cons (make-posn x y) posn-list)
- ; ex:
- (cons (make-posn 5 10) '())
- ; a vstate is a (make-vstate mode slider-frac last-frame points current-sample index)
- ; where mode is a Number between 1 and 4
- ; and slider-frac is a Number between 0 and 1
- ; and last-frame is a Natural Number
- ; and points is a posn-list
- ; and current-sample is a Number
- ; and index is a number
- (define-struct vstate (mode slider-frac last-frame points current-sample index))
- ; ex:
- (make-vstate 1 0.0 0 (cons (make-posn 5 10) '()) 0.0 0)
- (define INIT (make-vstate 1
- 0.0
- 0
- '()
- (list-ref TRACK_INTERVAL_LIST 0)
- 0))
- ; switch the mode of the given vs to the given number
- ; vs number -> vs
- (define (vstate-switch-mode vs n)
- (make-vstate n
- (vstate-slider-frac vs)
- (vstate-last-frame vs)
- (vstate-points vs)
- (vstate-current-sample vs)
- (vstate-index vs)))
- ; reset the slider frac and index of the given vs to 0
- ; vs -> vs
- (define (vstate-reset-slider-frac&index&points vs)
- (make-vstate (vstate-mode vs)
- 0.0
- (vstate-last-frame vs)
- '()
- (vstate-current-sample vs)
- 0))
- ; increment index by 1
- ; vs -> vs
- (define (vstate-index+ vs)
- (make-vstate (vstate-mode vs)
- (vstate-slider-frac vs)
- (vstate-last-frame vs)
- (vstate-points vs)
- (list-ref TRACK_INTERVAL_LIST (vstate-index vs))
- (+ 1 (vstate-index vs))))
- ; a Signal is a number between
- ; -1 and 1
- ; representing audio
- ; get percentage from sum of squares of signals
- ; Number -> Number
- (define (sumofsquares% s)
- (* (/ s (* FRAME-RATE TICK_RATE 10)) 100)
- )
- ;;; TASK: Develop a function that accepts a list of posns and draws them all
- ; a list-of-posns is one of
- ; - '()
- ; - (cons (make-posn x y) list-of-posns)
- ; example
- (cons (make-posn 10 8) '())
- ; draw the entirety of a list of posns onto a surface
- ; list-of-posns -> Image
- (define (drawPosns lop)
- (cond [(empty? lop) (add-line VISUALIZER_BOX 1 1 1 1 "black")]
- [else
- (if (empty? (rest lop)) (add-line VISUALIZER_BOX 1 1 1 1 "black")
- (place-image
- (add-line VISUALIZER_BOX (posn-x (first lop)) (posn-y (first lop)) (posn-x (first (rest lop))) (posn-y (first (rest lop))) "black")
- (/ VISUALIZER_BOX_WIDTH 2)
- (/ VISUALIZER_BOX_HEIGHT 2)
- (drawPosns (rest lop))))
- ]))
- ; do this stuff whenever big bang wakes up
- ; vs -> vs
- (define (tock vs) ; wake up
- (cond [(queue? (vstate-last-frame vs)
- (pstream-current-frame STREAM)) ; determine whether its go-time
- (if (< (+ (round (* (vstate-slider-frac vs)
- FRAMES)) PLAY_FRAMES) FRAMES)
- (queue-next-fragment
- (round (* (vstate-slider-frac vs)
- FRAMES))
- (vstate-last-frame vs)
- (make-vstate (vstate-mode vs)
- (+ (vstate-slider-frac vs) PLAY_POSNFRAC)
- (+ (vstate-last-frame vs) PLAY_FRAMES)
- (append (vstate-points vs) (list (make-posn
- (* (vstate-slider-frac vs) VISUALIZER_BOX_WIDTH)
- (* VISUALIZER_BOX_HEIGHT (sumofsquares% (vstate-current-sample vs)))
- )))
- (vstate-current-sample vs)
- (vstate-index vs)))
- (vstate-reset-slider-frac&index&points vs))]
- [else (vstate-index+ vs)]))
- ; determine whether it's time to queue up a fragment
- ; number number -> boolean
- (define (queue? last-frame current-frame)
- (< (- last-frame current-frame) MAX_QUEUE_INTERVAL))
- ; queue the next song fragment
- ; number number vs -> vs
- (define (queue-next-fragment song-frame frame-to-play val)
- (andqueue STREAM
- (clip TRACK song-frame (+ song-frame PLAY_FRAMES))
- frame-to-play
- (vstate-index+ val)))
- ; draw this on the screen whenever vs changes
- ; vs -> Image
- (define (render vs) (above
- (place-image (text (number->string (vstate-current-sample vs)) 24 "black") 150 50 (place-image (buttons (vstate-mode vs))
- 700
- 60
- BUTTON_BOX))
- (cond [(= (vstate-mode vs) 1)
- (place-image (circle (* 2 (floor (vstate-current-sample vs))) "solid" "red") (/ VISUALIZER_BOX_WIDTH 2) (/ VISUALIZER_BOX_HEIGHT 2)
- VISUALIZER_BOX)
- ]
- [(= (vstate-mode vs) 2)
- (add-line VISUALIZER_BOX
- (/ VISUALIZER_BOX_WIDTH 2)
- (/ VISUALIZER_BOX_HEIGHT 2)
- (* (vstate-slider-frac vs) VISUALIZER_BOX_WIDTH)
- (* VISUALIZER_BOX_HEIGHT (sumofsquares% (vstate-current-sample vs)))
- "black")
- ]
- [(= (vstate-mode vs) 3)
- (drawPosns (vstate-points vs))
- ]
- [(= (vstate-mode vs) 4)
- VISUALIZER_BOX
- ]
- [else VISUALIZER_BOX])
- (place-image SLIDER (* (vstate-slider-frac vs) SLIDER_BOX_WIDTH) 90 SLIDER_BOX)
- ))
- ; return a new vs based on key input
- ; vs ke -> vs
- (define (keyhandler vs ke)
- (cond [(string=? ke "1") (vstate-switch-mode vs 1)]
- [(string=? ke "2") (vstate-switch-mode vs 2)]
- [(string=? ke "3") (vstate-switch-mode vs 3)]
- [(string=? ke "4") (vstate-switch-mode vs 4)]
- [else vs]))
- (define (main x)
- (big-bang INIT
- [on-tick tock TICK_RATE]
- [to-draw render]
- [on-key keyhandler]))
- (main 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement