Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354;;; Audio synthesis — oscillators, envelopes
(in-package :ac-native.audio)
(defconstant +twopi+ (* 2.0d0 pi))
(declaim (inline osc-sine osc-square osc-triangle osc-sawtooth))
(defun osc-sine (phase) (declare (optimize (speed 3) (safety 0)) (type double-float phase)) (sin phase))
(defun osc-square (phase) (declare (optimize (speed 3) (safety 0)) (type double-float phase)) (if (< (mod phase +twopi+) pi) 1.0d0 -1.0d0))
(defun osc-triangle (phase) (declare (optimize (speed 3) (safety 0)) (type double-float phase)) (let ((p (mod (/ phase +twopi+) 1.0d0))) (if (< p 0.5d0) (- (* 4.0d0 p) 1.0d0) (- 3.0d0 (* 4.0d0 p)))))
(defun osc-sawtooth (phase) (declare (optimize (speed 3) (safety 0)) (type double-float phase)) (- (* 2.0d0 (mod (/ phase +twopi+) 1.0d0)) 1.0d0))
(defstruct voice "A synthesizer voice." (active nil :type boolean) (osc-type 0 :type fixnum) ; 0=sine 1=square 2=tri 3=saw 4=noise (phase 0.0d0 :type double-float) (phase-inc 0.0d0 :type double-float) (volume 0.7d0 :type double-float) (pan 0.0d0 :type double-float) (attack 0.01d0 :type double-float) (decay 0.1d0 :type double-float) (duration 0.0d0 :type double-float) ; 0 = infinite (elapsed 0.0d0 :type double-float) (fade 1.0d0 :type double-float) (id 0 :type fixnum))
(defun generate-sample (v) "Generate one sample from voice V." (declare (optimize (speed 3) (safety 0)) (type voice v)) (case (voice-osc-type v) (0 (osc-sine (voice-phase v))) (1 (osc-square (voice-phase v))) (2 (osc-triangle (voice-phase v))) (3 (osc-sawtooth (voice-phase v))) (4 (- (random 2.0d0) 1.0d0)) ; white noise (t 0.0d0)))