yyyriyriy ppp[i6riy (#3603) Bruception

* Add new synth click sounds

* Use key codes instead

* Fix Sound preview

* Check for caps lock

* Add new quote - imperial march
This commit is contained in:
Bruce Berrios 2022-09-26 04:41:31 -04:00 committed by GitHub
parent 4f146ae5a8
commit e6a8747d41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 235 additions and 3 deletions

View file

@ -75,7 +75,9 @@ const CONFIG_SCHEMA = joi.object({
singleListCommandLine: joi.string().valid("manual", "on"),
capsLockWarning: joi.boolean(),
playSoundOnError: joi.boolean(),
playSoundOnClick: joi.string().valid("off", ..._.range(1, 8).map(_.toString)),
playSoundOnClick: joi
.string()
.valid("off", ..._.range(1, 11).map(_.toString)),
soundVolume: joi.string().valid("0.1", "0.5", "1.0"),
startGraphsAtZero: joi.boolean(),
showOutOfFocusWarning: joi.boolean(),

View file

@ -97,6 +97,54 @@ const subgroup: MonkeyTypes.CommandsSubgroup = {
SoundController.playClick();
},
},
{
id: "setSoundOnClick8",
display: "sine",
configValue: "8",
hover: (): void => {
SoundController.playNote("KeyQ", "sine");
},
exec: (): void => {
UpdateConfig.setPlaySoundOnClick("8");
SoundController.playNote("KeyQ", "sine");
},
},
{
id: "setSoundOnClick9",
display: "sawtooth",
configValue: "9",
hover: (): void => {
SoundController.playNote("KeyQ", "sawtooth");
},
exec: (): void => {
UpdateConfig.setPlaySoundOnClick("9");
SoundController.playNote("KeyQ", "sawtooth");
},
},
{
id: "setSoundOnClick10",
display: "square",
configValue: "10",
hover: (): void => {
SoundController.playNote("KeyQ", "square");
},
exec: (): void => {
UpdateConfig.setPlaySoundOnClick("10");
SoundController.playNote("KeyQ", "square");
},
},
{
id: "setSoundOnClick11",
display: "triangle",
configValue: "11",
hover: (): void => {
SoundController.playNote("KeyQ", "triangle");
},
exec: (): void => {
UpdateConfig.setPlaySoundOnClick("11");
SoundController.playNote("KeyQ", "triangle");
},
},
],
};

View file

@ -166,7 +166,7 @@ export function setPlaySoundOnClick(
): boolean {
if (
!isConfigValueValid("play sound on click", val, [
["off", "1", "2", "3", "4", "5", "6", "7"],
["off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"],
])
) {
return false;

View file

@ -2,6 +2,8 @@ import Config from "../config";
import Howler, { Howl } from "howler";
import * as ConfigEvent from "../observables/config-event";
import { randomElementFromArray } from "../utils/misc";
import { leftState, rightState } from "../test/shift-tracker";
import { capsState } from "../test/caps-warning";
interface ClickSounds {
[key: string]: {
@ -233,8 +235,134 @@ export function previewClick(val: string): void {
(clickSounds as ClickSounds)[val][0].sounds[0].play();
}
let currentCode = "KeyA";
$(document).on("keydown", (event) => {
currentCode = event.code || "KeyA";
});
const notes = {
C: [16.35, 32.7, 65.41, 130.81, 261.63, 523.25, 1046.5, 2093.0, 4186.01],
Db: [17.32, 34.65, 69.3, 138.59, 277.18, 554.37, 1108.73, 2217.46, 4434.92],
D: [18.35, 36.71, 73.42, 146.83, 293.66, 587.33, 1174.66, 2349.32, 4698.64],
Eb: [19.45, 38.89, 77.78, 155.56, 311.13, 622.25, 1244.51, 2489.02, 4978.03],
E: [20.6, 41.2, 82.41, 164.81, 329.63, 659.26, 1318.51, 2637.02],
F: [21.83, 43.65, 87.31, 174.61, 349.23, 698.46, 1396.91, 2793.83],
Gb: [23.12, 46.25, 92.5, 185.0, 369.99, 739.99, 1479.98, 2959.96],
G: [24.5, 49.0, 98.0, 196.0, 392.0, 783.99, 1567.98, 3135.96],
Ab: [25.96, 51.91, 103.83, 207.65, 415.3, 830.61, 1661.22, 3322.44],
A: [27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0],
Bb: [29.14, 58.27, 116.54, 233.08, 466.16, 932.33, 1864.66, 3729.31],
B: [30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07],
};
type GetNoteFrequencyCallback = (octave: number) => number;
function bindToNote(
noteFrequencies: number[],
octaveOffset = 0
): GetNoteFrequencyCallback {
return (octave: number): number => {
return noteFrequencies[octave + octaveOffset];
};
}
const codeToNote: Record<string, GetNoteFrequencyCallback> = {
KeyZ: bindToNote(notes.C),
KeyS: bindToNote(notes.Db),
KeyX: bindToNote(notes.D),
KeyD: bindToNote(notes.Eb),
KeyC: bindToNote(notes.E),
KeyV: bindToNote(notes.F),
KeyG: bindToNote(notes.Gb),
KeyB: bindToNote(notes.G),
KeyH: bindToNote(notes.Ab),
KeyN: bindToNote(notes.A),
KeyJ: bindToNote(notes.Bb),
KeyM: bindToNote(notes.B),
Comma: bindToNote(notes.C, 1),
KeyL: bindToNote(notes.Db, 1),
Period: bindToNote(notes.D, 1),
Semicolon: bindToNote(notes.Eb, 1),
Slash: bindToNote(notes.E, 1),
KeyQ: bindToNote(notes.C, 1),
Digit2: bindToNote(notes.Db, 1),
KeyW: bindToNote(notes.D, 1),
Digit3: bindToNote(notes.Eb, 1),
KeyE: bindToNote(notes.E, 1),
KeyR: bindToNote(notes.F, 1),
Digit5: bindToNote(notes.Gb, 1),
KeyT: bindToNote(notes.G, 1),
Digit6: bindToNote(notes.Ab, 1),
KeyY: bindToNote(notes.A, 1),
Digit7: bindToNote(notes.Bb, 1),
KeyU: bindToNote(notes.B, 1),
KeyI: bindToNote(notes.C, 2),
Digit9: bindToNote(notes.Db, 2),
KeyO: bindToNote(notes.D, 2),
Digit0: bindToNote(notes.Eb, 2),
KeyP: bindToNote(notes.E, 2),
BracketLeft: bindToNote(notes.F, 2),
Equal: bindToNote(notes.Gb, 2),
BracketRight: bindToNote(notes.G, 2),
};
type DynamicClickSounds = Extract<
MonkeyTypes.PlaySoundOnClick,
"8" | "9" | "10" | "11"
>;
type SupportedOscillatorTypes = Exclude<OscillatorType, "custom">;
const clickSoundIdsToOscillatorType: Record<
DynamicClickSounds,
SupportedOscillatorTypes
> = {
"8": "sine",
"9": "sawtooth",
"10": "square",
"11": "triangle",
};
const audioCtx = new AudioContext();
export function playNote(
codeOverride?: string,
oscillatorTypeOverride?: SupportedOscillatorTypes
): void {
currentCode = codeOverride ?? currentCode;
if (!(currentCode in codeToNote)) {
return;
}
const baseOctave = 3;
const octave = baseOctave + (leftState || rightState || capsState ? 1 : 0);
const currentFrequency = codeToNote[currentCode](octave);
const oscillatorNode = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillatorNode.type =
oscillatorTypeOverride ??
clickSoundIdsToOscillatorType[
Config.playSoundOnClick as DynamicClickSounds
];
gainNode.gain.value = parseFloat(Config.soundVolume) / 10;
oscillatorNode.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillatorNode.frequency.value = currentFrequency;
oscillatorNode.start(audioCtx.currentTime);
oscillatorNode.stop(audioCtx.currentTime + 0.15);
}
export function playClick(): void {
if (Config.playSoundOnClick === "off") return;
if (Config.playSoundOnClick in clickSoundIdsToOscillatorType) {
playNote();
return;
}
if (clickSounds === null) init();
const randomSound = randomElementFromArray(

View file

@ -87,8 +87,24 @@ declare namespace MonkeyTypes {
5 = typewriter
6 = osu
7 = hitmarker
8 = sine
9 = sawtooth
10 = square
11 = triangle
*/
type PlaySoundOnClick = "off" | "1" | "2" | "3" | "4" | "5" | "6" | "7";
type PlaySoundOnClick =
| "off"
| "1"
| "2"
| "3"
| "4"
| "5"
| "6"
| "7"
| "8"
| "9"
| "10"
| "11";
type SoundVolume = "0.1" | "0.5" | "1.0";

View file

@ -894,6 +894,38 @@
>
hitmarker
</div>
<div
class="button"
playSoundOnClick="8"
tabindex="0"
onclick="this.blur();"
>
sine
</div>
<div
class="button"
playSoundOnClick="9"
tabindex="0"
onclick="this.blur();"
>
sawtooth
</div>
<div
class="button"
playSoundOnClick="10"
tabindex="0"
onclick="this.blur();"
>
square
</div>
<div
class="button"
playSoundOnClick="11"
tabindex="0"
onclick="this.blur();"
>
triangle
</div>
</div>
</div>
<div class="section playSoundOnError">

View file

@ -35466,6 +35466,12 @@
"source": "Fight Club",
"length": 827,
"id": 6231
},
{
"text": "yyy riy riy ppp [i6 riy",
"source": "John Williams - The Imperial March",
"length": 23,
"id": 6232
}
]
}