Skip to content

Commit

Permalink
Add display settings to disable or enable fft
Browse files Browse the repository at this point in the history
  • Loading branch information
reckter committed Dec 28, 2024
1 parent 99a9be6 commit 2d4a062
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 13 deletions.
20 changes: 20 additions & 0 deletions packages/web/src/components/display-settings-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ export default function DisplaySettingsDialog({
}
/>
</div>
<div className="">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="name" className="text-right">
Use FFT for visualization
</Label>
<input
id="showCanvas"
type="checkbox"
checked={unsavedSettings.enableFft ?? true}
className="w-5"
onChange={(e) =>
sanitizeAndSetUnsavedSettings({
...unsavedSettings,
enableFft: e.target.checked,
})
}
/>
</div>
<p>You need to reload the page to apply changes to fft</p>
</div>
</div>
<DialogFooter>
<Button type="submit">Save changes</Button>
Expand Down
3 changes: 3 additions & 0 deletions packages/web/src/lib/display-settings.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export interface DisplaySettings {
canvasPixelSize: number;
showCanvas: boolean;
enableFft: boolean;
}

export const defaultDisplaySettings: DisplaySettings = {
canvasPixelSize: 1,
showCanvas: true,
enableFft: true,
}

export function sanitizeDisplaySettings(settings: DisplaySettings): DisplaySettings {
Expand All @@ -16,6 +18,7 @@ export function sanitizeDisplaySettings(settings: DisplaySettings): DisplaySetti
// canvas; should be low enough
const maxPixelSize = 50;


return {
...settings,
canvasPixelSize: Math.max(
Expand Down
20 changes: 20 additions & 0 deletions packages/web/src/lib/hydra-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Hydra from "hydra-synth";
import { isWebglSupported } from "@/lib/webgl-detector.js";
import {DisplaySettings} from "@/lib/display-settings.ts";

declare global {
interface Window {
Expand All @@ -20,19 +21,27 @@ export class HydraWrapper {
protected _hydra: any;
protected _onError: ErrorHandler;
protected _onWarning: ErrorHandler;
protected _displaySettings: DisplaySettings;

constructor({
canvas,
onError,
onWarning,
displaySettings,
}: {
canvas: HTMLCanvasElement;
onError?: ErrorHandler;
onWarning?: ErrorHandler;
displaySettings: DisplaySettings;
}) {
this._canvas = canvas;
this._onError = onError || (() => {});
this._onWarning = onWarning || (() => {});
this._displaySettings = displaySettings;
}

setDisplaySettings(displaySettings: DisplaySettings) {
this._displaySettings = displaySettings;
}

async initialize() {
Expand Down Expand Up @@ -77,9 +86,20 @@ export class HydraWrapper {
const scale = options?.scale ?? 1
const max = options?.max ?? 0

// Strudel is not initialized yet, so we just return a default value
if(window.strudel == undefined) return .5;

// If display settings are not enabled, we just return a default value
if(!this._displaySettings.enableFft) return .5;

// Enable auto-analyze
window.strudel.enableAutoAnalyze = true;

// If the analyzerId is not defined, we just return a default value
if(window.strudel.webaudio.analysers[analyzerId] == undefined) {
return .5
}

const freq = window.strudel.webaudio.getAnalyzerData("frequency", analyzerId) as Array<number>;
const bucketSize = (freq.length) / buckets

Expand Down
15 changes: 2 additions & 13 deletions packages/web/src/lib/strudel-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,14 @@ export class StrudelWrapper {
}
}

hapAnalyzeSnippet = `
all(x =>
x.fmap(hap => {
if(hap.analyze == undefined) {
// all strings get converted to mini patterns, but we do just need the raw string.
hap.analyze = "flok-master".__pure;
}
return hap
})
)
`;

async tryEval(msg: EvalMessage) {
if (!this.initialized) await this.initialize();
try {
const { body: code, docId } = msg;
const {body: code, docId} = msg;
// little hack that injects the docId at the end of the code to make it available in afterEval
// also add ann analyser node to all patterns, for fft data in hydra
const pattern = await this._repl.evaluate(`${code}\n${this.hapAnalyzeSnippet}\n//${docId}`);
const pattern = await this._repl.evaluate(`${code}\n${this.enableAutoAnalyze ? this.hapAnalyzeSnippet : ""}\n//${docId}`);
if (pattern) {
this._docPatterns[docId] = pattern.docId(docId); // docId is needed for highlighting
const allPatterns = stack(...Object.values(this._docPatterns));
Expand Down
5 changes: 5 additions & 0 deletions packages/web/src/routes/frames/hydra.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function Component() {
onWarning: (msg) => {
sendToast("warning", "Hydra warning", msg);
},
displaySettings: displaySettings,
});

await hydra.initialize();
Expand All @@ -60,6 +61,10 @@ export function Component() {
}, [])
);

useEffect(() => {
instance?.setDisplaySettings(displaySettings);
}, [displaySettings]);

useEvalHandler(
useCallback(
(msg) => {
Expand Down

0 comments on commit 2d4a062

Please sign in to comment.