package tiny_libs
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
From-scratch libraries for teaching: graphics, audio, compression, crypto, networking and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_libs.audio_effects/Modulated_delay.ml.html
Source file Modulated_delay.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Modulated_delay.mli *) type settings = { center : float; depth : float; rate : float; feedback : float; mix : float } let chorus = { center = 0.015; depth = 0.003; rate = 0.5; feedback = 0.; mix = 0.5 } let flanger = { center = 0.0025; depth = 0.002; rate = 0.2; feedback = 0.5; mix = 0.7 } let longest = 0.05 let rate = float_of_int Signal.rate (* the last [size] samples written, [at] the next to write *) type line = { samples : float array; mutable at : int; mutable last : float (* the last copy, fed back *) } let size = Signal.samples longest + 4 let line () = { samples = Array.make size 0.; at = 0; last = 0. } (* [d] samples ago (d >= 1), between two samples: linear *) let read (l : line) (d : float) : float = let back = Float.to_int d in let frac = d -. float_of_int back in let at k = l.samples.((l.at - k + (2 * size)) mod size) in ((1. -. frac) *. at back) +. (frac *. at (back + 1)) let write (l : line) (x : float) : unit = l.samples.(l.at) <- x; l.at <- (l.at + 1) mod size type t = { left : line; right : line; mutable phase : float; (* the LFO's, in turns *) (* the last block's, ramped from (nan: none yet) *) mutable last_mix : float; mutable last_feedback : float; } let create () : t = { left = line (); right = line (); phase = 0.; last_mix = Float.nan; last_feedback = Float.nan } let process (t : t) (s : settings) (out : Signal.stereo) : unit = let n = Array.length out.left in let feedback = Float.min 0.95 (Float.max (-0.95) s.feedback) in let from_mix = if Float.is_nan t.last_mix then s.mix else t.last_mix and from_feedback = if Float.is_nan t.last_feedback then feedback else t.last_feedback in (* the delay in samples at an LFO phase, kept within the line *) let delay phase = let d = (s.center +. (s.depth *. sin (2. *. Float.pi *. phase))) *. rate in Float.max 1. (Float.min (float_of_int (size - 3)) d) in let side (l : line) (x : float) (phase : float) (mix : float) (feedback : float) : float = let copy = read l (delay phase) in write l (x +. (feedback *. l.last)); l.last <- copy; x +. (mix *. copy) in for i = 0 to n - 1 do let mix = Effect.ramp from_mix s.mix i n and feedback = Effect.ramp from_feedback feedback i n in out.left.(i) <- side t.left out.left.(i) t.phase mix feedback; (* the right side's LFO a quarter turn ahead *) out.right.(i) <- side t.right out.right.(i) (t.phase +. 0.25) mix feedback; t.phase <- t.phase +. (s.rate /. rate); if t.phase >= 1. then t.phase <- t.phase -. 1. done; t.last_mix <- s.mix; t.last_feedback <- feedback
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>