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/Tape.ml.html
Source file Tape.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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93(* 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 Tape.mli *) type transport = Stopped | Playing | Recording of int type t = { reel : Signal.t array; (* a track each *) levels : float array; mutable head : float; mutable speed : float; mutable transport : transport; mutable loop : (int * int) option; mutable memory : Signal.t; (* what was lifted *) } let create ?(seconds = 360.) ?(tracks = 4) () : t = let n = Signal.samples seconds in { reel = Array.init tracks (fun _ -> Array.make n 0.); levels = Array.make tracks 1.; head = 0.; speed = 1.; transport = Stopped; loop = None; memory = [||]; } let tracks (t : t) : int = Array.length t.reel let length (t : t) : int = Array.length t.reel.(0) let track (t : t) (k : int) : Signal.t = t.reel.(k) let head (t : t) : float = t.head let set_head (t : t) (h : float) : unit = t.head <- Float.max 0. (Float.min (float_of_int (length t - 1)) h) let speed (t : t) : float = t.speed let set_speed (t : t) (s : float) : unit = t.speed <- s let play (t : t) : unit = t.transport <- Playing let record (t : t) (k : int) : unit = if k >= 0 && k < tracks t then t.transport <- Recording k let stop (t : t) : unit = t.transport <- Stopped let moving (t : t) : bool = t.transport <> Stopped let recording (t : t) : int option = match t.transport with Recording k -> Some k | _ -> None let set_level (t : t) (k : int) (level : float) : unit = t.levels.(k) <- Float.max 0. (Float.min 1. level) let set_loop (t : t) (l : (int * int) option) : unit = t.loop <- l (* [x] added at a position between two samples, spread over both *) let write (track : Signal.t) (position : float) (x : float) : unit = let i = Float.to_int (Float.floor position) in let frac = position -. float_of_int i in let n = Array.length track in if i >= 0 && i < n then track.(i) <- track.(i) +. ((1. -. frac) *. x); if i + 1 >= 0 && i + 1 < n && frac > 0. then track.(i + 1) <- track.(i + 1) +. (frac *. x) let process (t : t) ~(input : Signal.t) (out : Signal.t) : unit = let last = float_of_int (length t - 1) in Array.iteri (fun i _ -> match t.transport with | Stopped -> out.(i) <- 0. | Playing | Recording _ -> (* the tracks under the head, mixed *) let x = ref 0. in Array.iteri (fun k track -> x := !x +. (t.levels.(k) *. Resample.read Linear track t.head)) t.reel; out.(i) <- !x; (match t.transport with Recording k when i < Array.length input -> write t.reel.(k) t.head input.(i) | _ -> ()); (* the tape moves; a loop sends it back; its ends stop it *) t.head <- t.head +. t.speed; (match t.loop with | Some (a, b) when t.speed > 0. && t.head >= float_of_int b -> t.head <- t.head -. float_of_int (b - a) | Some (a, b) when t.speed < 0. && t.head < float_of_int a -> t.head <- t.head +. float_of_int (b - a) | _ -> ()); if t.head < 0. || t.head > last then begin t.head <- Float.max 0. (Float.min last t.head); t.transport <- Stopped end) out let lift (t : t) (k : int) ~(from : int) ~(until : int) : unit = let from = max 0 from and until = min (length t) until in if until > from then begin t.memory <- Array.sub t.reel.(k) from (until - from); Array.fill t.reel.(k) from (until - from) 0. end let drop (t : t) (k : int) : unit = let at = Float.to_int (Float.round t.head) in Array.iteri (fun i x -> if at + i < length t then t.reel.(k).(at + i) <- t.reel.(k).(at + i) +. x) t.memory
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>