<?phpnamespace App\Audio;/** Scales as semitone steps: every note of a pentatonic scale sounds right with the others, so overlapping bounces never clash. */final class Scale{ public const MAJOR_PENTA = [0, 2, 4, 7, 9]; public const MINOR_PENTA = [0, 3, 5, 7, 10]; public const HIRAJOSHI = [0, 2, 3, 7, 8]; public const WHOLE_TONE = [0, 2, 4, 6, 8, 10]; public const LYDIAN = [0, 2, 4, 6, 7, 9, 11]; public const MAJOR = [0, 2, 4, 5, 7, 9, 11]; /** Frequency of degree $degree (0 = the root, 5 on a pentatonic scale = the root an octave up; negative goes down). */ public static function freq(array $scale, int $degree, int $rootMidi = 60): float { $n = count($scale); $octave = intdiv($degree, $n) - ($degree % $n < 0 ? 1 : 0); $step = (($degree % $n) + $n) % $n; return 440 * 2 ** (($rootMidi + $octave * 12 + $scale[$step] - 69) / 12); }}