(defvar *out* (cl-out123:connect (cl-out123:make-output NIL :channels 1 :encoding :float))) (defun square-wave (position length) (if (= 1 (floor (mod position length) (/ length 2))) 1.0s0 0.0s0)) (defun sawtooth-wave (position length) (coerce (/ (mod position length) length) 'single-float)) (defun sine-wave (position length) (sin (* (/ position length) (coerce pi 'single-float)))) (defmacro modincf (i mod &optional (delta 1)) `(setf ,i (mod (+ ,i ,delta) ,mod))) (defun play (wave-type frequency &key (buffer-size 1024)) (cl-out123:start *out*) (unwind-protect (let* ((sample-rate (cl-out123:playback-format *out*)) (sample-length (floor sample-rate frequency)) (j 0)) (cffi:with-foreign-object (buffer :float buffer-size) (loop (loop for i from 0 below buffer-size do (setf (cffi:mem-aref buffer :float i) (funcall wave-type j sample-length)) (modincf j sample-length)) (cl-out123:play-directly *out* buffer buffer-size)))) (cl-out123:stop *out*)))