Skip to content

Commit

Permalink
Add tap-in BPM
Browse files Browse the repository at this point in the history
 * Fix issue with standalone multi-ADSR module after adding the bezier curve type
  • Loading branch information
Ameobea committed Jan 18, 2025
1 parent 3d8d6df commit 5e6a12b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 4 deletions.
6 changes: 3 additions & 3 deletions public/ADSR2AWP.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ class MultiADSR2AWP extends AudioWorkletProcessor {
}

setEncodedSteps(encodedSteps) {
if (encodedSteps.length % 4 !== 0) {
throw new Error('Expected encoded steps length to be divisible by 4');
if (encodedSteps.length % 7 !== 0) {
throw new Error('Expected encoded steps length to be divisible by 47');
}
const encodedStepBufPtr = this.wasmInstance.exports.get_encoded_adsr_step_buf_ptr(
encodedSteps.length / 4
encodedSteps.length / 7
);
this.wasmMemoryBuffer = new Float32Array(this.wasmInstance.exports.memory.buffer);
const stepBuf = this.wasmMemoryBuffer.subarray(
Expand Down
2 changes: 1 addition & 1 deletion src/fmSynth/FMSynthUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ const ConnectedFMSynthUIInner: React.FC<ConnectedFMSynthUIProps> = ({
},
[synth]
)}
adsrs={dbg(synth.getAdsrs())}
adsrs={synth.getAdsrs()}
onAdsrChange={useCallback(
(adsrIx: number, newAdsr: AdsrParams) => synth.handleAdsrChange(adsrIx, newAdsr),
[synth]
Expand Down
11 changes: 11 additions & 0 deletions src/globalMenu/GlobalMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import { noop } from 'src/util';
import HamburgerMenuIcon from '../ViewContextManager/Icons/HamburgerMenu.svg';
import HelpIcon from 'src/misc/HelpIcon';
import type { ControlPanelSetting } from 'src/controls/SvelteControlPanel/SvelteControlPanel.svelte';
import TapInBPMSvelte from './TapInBPM.svelte';
import { mkSvelteComponentShim } from 'src/svelteUtils';

const TapInBPM = mkSvelteComponentShim<{ onSubmit: (bpm: number) => void }>(TapInBPMSvelte);

const ctx = new AudioContext();

Expand Down Expand Up @@ -79,6 +83,13 @@ const GlobalTempoControl: React.FC = () => {
}
}}
/>

<TapInBPM
onSubmit={newBPM => {
setTempo(newBPM.toFixed(2));
setGlobalBpm(newBPM);
}}
/>
</div>
);
};
Expand Down
76 changes: 76 additions & 0 deletions src/globalMenu/TapInBPM.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
export let onSubmit: (bpm: number) => void;
let isOpen = false;
let lastTapTime: number | null = null;
let intervalsMs: number[] = [];
$: bpm =
intervalsMs.length > 0
? 60000 / (intervalsMs.reduce((acc, curr) => acc + curr) / intervalsMs.length)
: null;
const handleTap = () => {
const now = Date.now();
if (lastTapTime !== null) {
intervalsMs = [...intervalsMs, now - lastTapTime];
}
lastTapTime = now;
};
const handleKeyDown = (evt: KeyboardEvent) => {
if (evt.key === '\\') {
handleTap();
}
};
const reset = () => {
lastTapTime = null;
intervalsMs = [];
};
onMount(() => {
document.addEventListener('keydown', handleKeyDown);
});
onDestroy(() => {
document.removeEventListener('keydown', handleKeyDown);
});
</script>

<div class="root">
{#if isOpen}
<p>Click the button below to the beat or press the <code>\</code> key.</p>
<button on:click={handleTap}>Tap</button>
{#if lastTapTime !== null}
<p>BPM: {bpm === null ? '-' : bpm.toFixed(2)}</p>
<button on:click={reset}>Reset</button>
{#if bpm !== null}
<button
on:click={() => {
isOpen = false;
onSubmit(bpm);
}}
>
Submit
</button>
{/if}
{/if}
{:else}
<button
on:click={() => {
isOpen = true;
}}
>
Tap in BPM
</button>
{/if}
</div>

<style lang="css">
.root {
display: flex;
flex-direction: column;
}
</style>

0 comments on commit 5e6a12b

Please sign in to comment.