Next: , Previous: Abspielen der Aufnahme , Up: Einführung , Home: Einführung

musikinformatik-wise-24.org

Bangs

(in-package :clamps)

(in-package :clamps)

(progn
  (defparameter *bottom01* (make-ref 0.0))
  (defparameter *top01* (make-ref 127.0))
  (defparameter *speed01* (make-ref 0.5))
  (defparameter *dur01* (make-ref 0.5))
  (defparameter *vol01* (make-ref 80))
  (defparameter *start01* (make-ref 0))
  (defparameter *downtime01* (make-ref 10.0))
  (defparameter *uptime01* (make-ref 10.0))
  (defparameter *shrinktime01* (make-ref 10.0))
  (defparameter *spreadtime01* (make-ref 10.0))
  (defparameter *down01* (make-ref 0.0))
  (defparameter *up01* (make-ref 0.0))
  (defparameter *shrink01* (make-ref 0.0))
  (defparameter *spread01* (make-ref 0.0)))

;;; Definition einer Struktur, die alle Parameter eines Prozesses enthält:

(defstruct (p-params
            (:constructor make-proc-params (lower-start lower-end upper-start upper-end duration)))
    (lower-start 0)
    (lower-end 127)
    (upper-start 0)
    (upper-end 127)
    (duration 10))

;;; (make-proc-params 1 2 3 4 5)

(defparameter *running-proc* nil
  "Global Variable to store the instance of a process to run.

   Create the instance with (make-orgel-process params).

   Start the process with (funcall *running-proc* :start)

   Stop the process with (funcall *running-proc* :stop)")

(defun make-orgel-process (params &key (res 0.01))
  "define a function for a process with params, which can get started by
calling it with a :start and stopped by calling it with a :stop
argument."
  (let* ((running nil))
    (labels ((orgel-proc (params res)
                (process
                  while running
                  for x from 0 to 1 by (/ res (p-params-duration params))
                  do (set-val *bottom01* (n-lin x (p-params-lower-start params) (p-params-lower-end params)))
                  do (set-val *top01* (n-lin x (p-params-upper-start params) (p-params-upper-end params)))
                  wait res)))
      (lambda (cmd)
        (case cmd
          (:start
           (setf running t)
           (msg :warn "hallo")
           (sprout (orgel-proc params res)))
          (:stop
           (setf running nil)))))))

(defun run-orgel-process (params)
  "run a process with params of type p-params after stopping a previously
running process."
  (if *running-proc* (funcall *running-proc* :stop))
  (setf *running-proc* (make-orgel-process params))
  (funcall *running-proc* :start))

;;; (run-orgel-process (make-proc-params 0 127 127 0 10))

(sprout (process repeat 3 do (msg :warn "Hallo") wait 0.5))

;;; Parametersettings für 8 Programme/Knöpfe:


(defparameter *performer-params*
  (map 'vector
       (lambda (params) (apply #'make-proc-params params))
       '((0 127 127 0 10) ;; program 0
         (64 80 127 81 6)
         (0 63 71 64 14)
         (0 120 0 127 4)
         (120 0 127 10 12)
         (64 0 64 127 8)
         (20 80 127 81 10)
         (0 20 127 20 10))))

(defparameter *performer-bangs*
  (coerce
   (loop
     for count below 8
     collect (let ((count count))
               (make-bang (lambda () (run-orgel-process (aref *performer-params* count))))))
   'vector))

(defparameter *proc-stop-bang*
  (make-bang (lambda () (funcall *running-proc* :stop))))

#|
;;; Exkurs: Alles ohne eine globale Variable *running-proc*:

(defun make-orgel-process-runner ()
  (let ((running-proc nil))
    (lambda (params)
      (if running-proc (funcall running-proc :stop))
      (setf running-proc (make-orgel-process params))
      (funcall running-proc :start))))

(defparameter *proc-runner* (make-orgel-process-runner))

(funcall *proc-runner* (make-proc-params 0 127 127 0 10))
|#

;;; Definition des GUIs:

(defun sliders-gui (body)
  "handler for /sliders"
  (let* ((bounds (clog:create-div body :style "display: flex; height: 50%; width: 100%;margin-top: 1em;"))
         (panel1 (clog:create-div bounds :style "display: flex; flex-direction: column; height: 100%; width: 15%;"))
         (panel2 (clog:create-div bounds :style "display: flex; flex-direction: column; height: 100%; width: 15%;"))
         (panel1b (clog:create-div bounds :style "display: flex; flex-direction: column; height: 100%; width: 15%;"))
         (panel2b (clog:create-div bounds :style "display: flex; flex-direction: column; height: 100%; width: 15%;"))
         (panel3 (clog:create-div bounds :style "display: inline-block; height: 100%; width: 60%;"))
         (panel4 (clog:create-div body :style "display: flex; flex-direction: column; width: 100%; margin-top: 1em"))
         )

    (setf (title (html-document body)) "orgel randomizer gui")
    (setf (style body :display) "flex")
    (setf (style body :flex-direction) "column")
    (setf (style body :height) "100vh")

    (clog:create-div panel1 :content "lower bound" :css `(:width 100% :font-size "2em"))
    (create-o-slider panel1 (bind-refs-to-attrs *bottom01* "value")
                     :min 0 :max 127 :direction :up
                     :css `(:display "inline-block" :margin-top "1em"
                            :background "white" :height "90%" :width "1.5em"))
    (create-o-numbox panel1 (bind-refs-to-attrs *bottom01* "value")
                     :min 0 :max 127 :css `(:height "1.5em" :width "3em" :margin-top "1em"))
    (clog:create-div panel2 :content "upper bound" :css `(:width 100% :font-size "2em"))
    (create-o-slider panel2 (bind-refs-to-attrs *top01* "value")
                     :min 0 :max 127 :direction :up
                     :css `(:display "inline-block" :margin-top "1em"
                            :background "white" :height "80%" :width "1.5em"))
    (create-o-numbox panel2 (bind-refs-to-attrs *top01* "value")
                     :min 0 :max 127 :css `(:height "1.5em" :width "3em" :margin-top "1em"))

    (create-o-toggle panel1b (bind-refs-to-attrs *down01* "value")
                     :label "ramp down"
                     :css `(:width "80%" :height "1.5em"))
    (create-o-knob panel1b (bind-refs-to-attrs *downtime01* "value")
                   :min 0 :max 20 :css `())
    (create-o-toggle panel1b (bind-refs-to-attrs *shrink01* "value")
                     :label "shrink"
                     :css `(:width "80%" :height "1.5em"))
    (create-o-knob panel1b (bind-refs-to-attrs *shrinktime01* "value")
                   :min 0 :max 20 :css `())
    (create-o-toggle panel2b (bind-refs-to-attrs *up01* "value")
                     :label "ramp up"
                     :css `(:width "80%" :height "1.5em"))
    (create-o-knob panel2b (bind-refs-to-attrs *uptime01* "value")
                   :min 0 :max 20 :css `())
    (create-o-toggle panel2b (bind-refs-to-attrs *spread01* "value")
                     :label "spread"
                     :css `(:width "80%" :height "1.5em"))
    (create-o-knob panel2b (bind-refs-to-attrs *spreadtime01* "value")
                   :min 0 :max 20 :css `())
    ;;; 8 Bangs im Hauptgui
    (loop
      for count below 8
      do (progn
           (create-o-bang
            panel3 (bind-refs-to-attrs (aref *performer-bangs* count) "bang")
            :label (format nil "~s" (1+ count))
            :css `(:display "inline-block" :width "3em" :height "3em" :margin-bottom "1em" :margin-left "1em"))
           (when (zerop (mod (1+ count) 4))
             (clog:create-br panel3))))
    (create-o-bang
            panel3 (bind-refs-to-attrs *proc-stop-bang* "bang")
            :label "stop"
            :css `(:display "inline-block" :width "3em" :height "3em" :margin-bottom "1em" :margin-left "1em"))
    (create-o-slider panel4 (bind-refs-to-attrs *speed01* "value")
                     :min 0.01 :max 2 :direction :right :label "sequence speed"
                     :css `(:display "inline-block"
                            :background "white" :height "1.5em" :width "60%"))
    (create-o-numbox panel4 (bind-refs-to-attrs *speed01* "value")
                     :min 0.01 :max 2 :css `(:height "1.5em" :width "3em" :margin-bottom "1em"))
    (create-o-slider panel4 (bind-refs-to-attrs *dur01* "value")
                     :min 0.01 :max 2 :direction :right :label "note duration"
                     :css `(:display "inline-block"
                            :background "white" :height "1.5em" :width "60%"))
    (create-o-numbox panel4 (bind-refs-to-attrs *dur01* "value")
                     :min 0.01 :max 2 :css `(:height "1.5em" :width "3em" :margin-bottom "1em"))
    (create-o-slider panel4 (bind-refs-to-attrs *vol01* "value")
                     :min 0 :max 100 :direction :right :label "volume"
                     :css `(:display "inline-block"
                            :background "white" :height "1.5em" :width "60%"))
    (create-o-numbox panel4 (bind-refs-to-attrs *vol01* "value")
                     :min 0 :max 100 :css `(:height "1.5em" :width "3em" :margin-bottom "1em"))
    (create-o-toggle panel4 (bind-refs-to-attrs *start01* "value")
                     :label '("off" "on")
                     :css `(:width "1.5em" :height "1.5em"))
    ))

;;; Collegamento GUI e START PLAY

(defun call-current-gui-def (body)
  "helper function calling the current definition of #'orgel-randomizer-gui at the
time of URL reload."
  (sliders-gui body))

(set-on-new-window #'call-current-gui-def :path "/orgel-randomizer-gui")

;;; performer gui

(defun set-page-dimensions (body width height &key (scale 1.0))
  (let ((html (clog:document-element (html-document body))))
    (setf (style html :font-size) (format nil "min(~,8fvw, ~,8fvh)" (/ 100 (* scale width)) (/ 100 (* scale height))))
    (setf (style body :height) (format nil "~arem" (* height scale)))
    (setf (style body :width) (format nil "~arem" (* width scale)))))

(defun performer1-gui (body)
  "handler for /sliders"
  (let* ((button-size 45)
         (btn-size (format nil "~arem" button-size))
         (font-size (format nil "~arem" (* 0.5 button-size)))
         (line-width (format nil "solid ~arem" (* 0.04 button-size)))
         (panel (clog:create-div
                 body
                 :css `(:width "100%"
                        :height "100%"
                        :display "grid"
                        :place-content "space-around"
                        :grid-template-columns ,(format nil "repeat(4, ~a)" btn-size)))))
    (let ((html (html-document body)))
      (setf (title html) "Performer 1"))
    ;;  (setf (style body :grid-gap) "10em")
    (set-page-dimensions body 256 144)
    (let ()
      (loop
        for count below 8
        do (progn
             (create-o-bang
              panel (bind-refs-to-attrs (aref *performer-bangs* count) "bang")
              :label (format nil "~s" (1+ count))
              :css `(:font-size ,font-size
                     :border ,line-width :min-width "0em" :min-height "0em"
                     :width ,btn-size :height ,btn-size)))))))

(defun performer1-gui-portrait (body)
  "handler for /sliders"
  (let* ((button-size 45)
         (btn-size (format nil "~arem" button-size))
         (font-size (format nil "~arem" (* 0.5 button-size)))
         (line-width (format nil "solid ~arem" (* 0.04 button-size)))
         (panel (clog:create-div
                 body
                 :css `(:width "100%"
                        :height "100%"
                        :display "grid"
                        :place-content "space-around"
                        :grid-template-columns ,(format nil "repeat(2, ~a)" btn-size)))))
    (let ((html (html-document body)))
      (setf (title html) "Performer 1"))
    ;;  (setf (style body :grid-gap) "10em")
    (set-page-dimensions body 144 256)
    (let ()
      (loop
        for count below 8
        do (progn
             (create-o-bang
              panel (bind-refs-to-attrs (aref *performer-bangs* count) "bang")
              :label (format nil "~s" (1+ count))
              :css `(:font-size ,font-size
                     :border ,line-width :min-width "0em" :min-height "0em"
                     :width ,btn-size :height ,btn-size)))))))

(defun call-performer1-def (body)
  "helper function calling the current definition of #'3sliders-numboxes-gui at the
time of URL reload."
  (performer1-gui body))

(defun call-performer1-portrait-def (body)
  "helper function calling the current definition of #'3sliders-numboxes-gui at the
time of URL reload."
  (performer1-gui-portrait body))

(set-on-new-window #'call-performer1-def :path "/performer1-gui")
(set-on-new-window #'call-performer1-portrait-def :path "/performer1-gui-portrait")
(* 3 4) ; => 12 (4 bits, #xC, #o14, #b1100)

(add-buffer)

Bah Blah Blah

Created: 2025-02-12 Mi 20:35

Validate