From d678ac94163d57190e2626c0abf3fb8a618b3150 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Mon, 13 Sep 2021 15:01:53 -0400 Subject: [PATCH] Add nonlinear sliders; show values --- src/audio.ts | 12 +++-- src/components/NodeNumberProp.vue | 74 ++++++++++++++++++++++++++++ src/components/NodeProps.vue | 38 ++++++--------- src/components/NodeRangeProp.vue | 80 +++++++++++++++++++++++++++++++ src/filters/HighpassFilter.ts | 7 ++- src/filters/LowpassFilter.ts | 7 ++- src/sources/IntervalSource.ts | 21 +++----- src/sources/LoopingSource.ts | 10 +--- src/sources/PremadeSources.ts | 2 + src/sources/Source.ts | 10 ++++ 10 files changed, 209 insertions(+), 52 deletions(-) create mode 100644 src/components/NodeNumberProp.vue create mode 100644 src/components/NodeRangeProp.vue diff --git a/src/audio.ts b/src/audio.ts index 89156b6..393ec79 100644 --- a/src/audio.ts +++ b/src/audio.ts @@ -48,18 +48,24 @@ export abstract class Node { constructor(public name: string) {} } -export type NumberMetadata = { +export type PropMetadata = { name: string; +}; + +export type NumberMetadata = PropMetadata & { min: number; max: number; format?: (value: number) => string; + map?: (value: number) => number; + unmap?: (value: number) => number; }; -export type RangeMetadata = { - name: string; +export type RangeMetadata = PropMetadata & { min: number; max: number; format?: (value: number) => string; + map?: (value: number) => number; + unmap?: (value: number) => number; }; export const exposedMetadataNumber = Symbol("exposedNumber"); diff --git a/src/components/NodeNumberProp.vue b/src/components/NodeNumberProp.vue new file mode 100644 index 0000000..edec406 --- /dev/null +++ b/src/components/NodeNumberProp.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/components/NodeProps.vue b/src/components/NodeProps.vue index 93c5875..2b30e63 100644 --- a/src/components/NodeProps.vue +++ b/src/components/NodeProps.vue @@ -1,31 +1,17 @@ @@ -39,6 +25,8 @@ import { import { Options, Vue } from "vue-class-component"; import Slider from "@vueform/slider"; import { Node } from "@/audio"; +import NodeNumberProp from "@/components/NodeNumberProp.vue"; +import NodeRangeProp from "@/components/NodeRangeProp.vue"; @Options({ props: { @@ -46,6 +34,8 @@ import { Node } from "@/audio"; }, components: { Slider, + NodeNumberProp, + NodeRangeProp, }, }) export default class NodeProps extends Vue { diff --git a/src/components/NodeRangeProp.vue b/src/components/NodeRangeProp.vue new file mode 100644 index 0000000..92d8736 --- /dev/null +++ b/src/components/NodeRangeProp.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/src/filters/HighpassFilter.ts b/src/filters/HighpassFilter.ts index 9b7abd4..b94a0d8 100644 --- a/src/filters/HighpassFilter.ts +++ b/src/filters/HighpassFilter.ts @@ -8,7 +8,12 @@ export class HighpassFilter extends Filter { name: "Cutoff Frequency", min: 10, max: 10000, - format: (value: number) => value + "Hz", + format: (value: number) => + Math.pow(2, value).toLocaleString(undefined, { + maximumFractionDigits: 0, + }) + "Hz", + map: (value: number) => Math.log(value) / Math.log(2), + unmap: (value: number) => Math.pow(2, value), }) public cutoff = 500; diff --git a/src/filters/LowpassFilter.ts b/src/filters/LowpassFilter.ts index 745af1e..ece6c39 100644 --- a/src/filters/LowpassFilter.ts +++ b/src/filters/LowpassFilter.ts @@ -8,7 +8,12 @@ export class BiquadFilter extends Filter { name: "Cutoff Frequency", min: 10, max: 10000, - format: (value: number) => value + "Hz", + format: (value: number) => + Math.pow(2, value).toLocaleString(undefined, { + maximumFractionDigits: 0, + }) + "Hz", + map: (value: number) => Math.log(value) / Math.log(2), + unmap: (value: number) => Math.pow(2, value), }) public cutoff = 1000; diff --git a/src/sources/IntervalSource.ts b/src/sources/IntervalSource.ts index 4eca741..28903d0 100644 --- a/src/sources/IntervalSource.ts +++ b/src/sources/IntervalSource.ts @@ -1,29 +1,22 @@ import { Source } from "./Source"; -import { exposedNumber, context, exposedRange } from "../audio"; +import { context, exposedRange } from "../audio"; export class IntervalSource extends Source { kind = "Interval"; - @exposedNumber({ - name: "Pitch", - min: 0.25, - max: 4, - format: (value: number) => Math.round(value * 100) + "%", - }) - public pitch = 1; - - // - @exposedNumber({ + @exposedRange({ name: "Interval", min: 0.25, - max: 30, + max: 300, format: (value: number) => { return ( - value.toLocaleString(undefined, { + Math.pow(2, value).toLocaleString(undefined, { maximumFractionDigits: 2, }) + "s" ); }, + map: (value: number) => Math.log(value) / Math.log(2), + unmap: (value: number) => Math.pow(2, value), }) public interval: [number, number] = [4, 6]; @@ -33,7 +26,7 @@ export class IntervalSource extends Source { max: 1, format: (value: number) => { if (value < 0) { - return Math.round(value * 100) + "L"; + return Math.round(-value * 100) + "L"; } else if (value > 0) { return Math.round(value * 100) + "R"; } else { diff --git a/src/sources/LoopingSource.ts b/src/sources/LoopingSource.ts index d159128..e184437 100644 --- a/src/sources/LoopingSource.ts +++ b/src/sources/LoopingSource.ts @@ -1,5 +1,5 @@ import { Source } from "./Source"; -import { context, exposedNumber } from "../audio"; +import { context } from "../audio"; export class LoopingSource extends Source { kind = "Looping"; @@ -7,14 +7,6 @@ export class LoopingSource extends Source { private started = false; private running = false; - @exposedNumber({ - name: "Pitch", - min: 0.25, - max: 4, - format: (value: number) => Math.round(value * 100) + "%", - }) - public pitch = 1; - constructor(name: string) { super(name); } diff --git a/src/sources/PremadeSources.ts b/src/sources/PremadeSources.ts index 3695a04..173cd2e 100644 --- a/src/sources/PremadeSources.ts +++ b/src/sources/PremadeSources.ts @@ -14,6 +14,8 @@ export function makeGlorps(): Source { source.loadSound("bowels-churn-safe"); source.loadSound("bowels-churn-danger"); + console.log(source); + return source; } diff --git a/src/sources/Source.ts b/src/sources/Source.ts index f3228d5..301ae6f 100644 --- a/src/sources/Source.ts +++ b/src/sources/Source.ts @@ -28,6 +28,16 @@ export abstract class Source extends Node { }) public volume = 1; + @exposedNumber({ + name: "Pitch", + min: 0.25, + max: 4, + format: (value: number) => Math.round(Math.pow(4, value) * 100) + "%", + map: (value: number) => Math.log(value) / Math.log(4), + unmap: (value: number) => Math.pow(4, value), + }) + public pitch = 1; + constructor(name: string) { super(name); this.gain = context.createGain();