| @@ -0,0 +1 @@ | |||||
| declare module "soundbank-reverb" | |||||
| @@ -14,6 +14,7 @@ | |||||
| "mobile-drag-drop": "^2.3.0-rc.2", | "mobile-drag-drop": "^2.3.0-rc.2", | ||||
| "postcss": "^8.3.6", | "postcss": "^8.3.6", | ||||
| "reflect-metadata": "^0.1.13", | "reflect-metadata": "^0.1.13", | ||||
| "soundbank-reverb": "^1.1.2", | |||||
| "vue": "^3.0.0", | "vue": "^3.0.0", | ||||
| "vue-class-component": "^8.0.0-0", | "vue-class-component": "^8.0.0-0", | ||||
| "vue-slider-component": "^3.2.14" | "vue-slider-component": "^3.2.14" | ||||
| @@ -15445,6 +15446,11 @@ | |||||
| "node": ">=0.10.0" | "node": ">=0.10.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/soundbank-reverb": { | |||||
| "version": "1.1.2", | |||||
| "resolved": "https://registry.npmjs.org/soundbank-reverb/-/soundbank-reverb-1.1.2.tgz", | |||||
| "integrity": "sha1-uBspdgt5B7jIuuEMDZEz2Oxk+/c=" | |||||
| }, | |||||
| "node_modules/source-list-map": { | "node_modules/source-list-map": { | ||||
| "version": "2.0.1", | "version": "2.0.1", | ||||
| "resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz", | "resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz", | ||||
| @@ -30432,6 +30438,11 @@ | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "soundbank-reverb": { | |||||
| "version": "1.1.2", | |||||
| "resolved": "https://registry.npmjs.org/soundbank-reverb/-/soundbank-reverb-1.1.2.tgz", | |||||
| "integrity": "sha1-uBspdgt5B7jIuuEMDZEz2Oxk+/c=" | |||||
| }, | |||||
| "source-list-map": { | "source-list-map": { | ||||
| "version": "2.0.1", | "version": "2.0.1", | ||||
| "resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz", | "resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz", | ||||
| @@ -14,6 +14,7 @@ | |||||
| "mobile-drag-drop": "^2.3.0-rc.2", | "mobile-drag-drop": "^2.3.0-rc.2", | ||||
| "postcss": "^8.3.6", | "postcss": "^8.3.6", | ||||
| "reflect-metadata": "^0.1.13", | "reflect-metadata": "^0.1.13", | ||||
| "soundbank-reverb": "^1.1.2", | |||||
| "vue": "^3.0.0", | "vue": "^3.0.0", | ||||
| "vue-class-component": "^8.0.0-0", | "vue-class-component": "^8.0.0-0", | ||||
| "vue-slider-component": "^3.2.14" | "vue-slider-component": "^3.2.14" | ||||
| @@ -17,6 +17,7 @@ | |||||
| :node="filter" | :node="filter" | ||||
| /> | /> | ||||
| </div> | </div> | ||||
| <button v-on:click="$emit('permalink')">Permalink</button> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -57,6 +57,7 @@ export default class FilterNode extends Vue { | |||||
| font-size: 24pt; | font-size: 24pt; | ||||
| margin: 4pt; | margin: 4pt; | ||||
| color: #fcf; | color: #fcf; | ||||
| margin-top: 30pt; | |||||
| } | } | ||||
| .node-properties { | .node-properties { | ||||
| @@ -56,6 +56,7 @@ export default class SourceNode extends Vue { | |||||
| font-size: 24pt; | font-size: 24pt; | ||||
| margin: 4pt; | margin: 4pt; | ||||
| color: #fcf; | color: #fcf; | ||||
| margin-top: 30pt; | |||||
| } | } | ||||
| .node-properties { | .node-properties { | ||||
| @@ -102,6 +102,15 @@ export const PresetFilters: Array<{ name: string; [x: string]: any }> = [ | |||||
| kind: "filter", | kind: "filter", | ||||
| type: "StereoWidthFilter", | type: "StereoWidthFilter", | ||||
| }, | }, | ||||
| { | |||||
| time: 1, | |||||
| decay: 1, | |||||
| dry: 1, | |||||
| wet: 0.5, | |||||
| name: "Reverb", | |||||
| kind: "filter", | |||||
| type: "ReverbFilter", | |||||
| }, | |||||
| ]; | ]; | ||||
| export const DemoScene = [ | export const DemoScene = [ | ||||
| @@ -0,0 +1,81 @@ | |||||
| import { Filter } from "./Filter"; | |||||
| import { context, exposedNumber } from "../audio"; | |||||
| import Reverb from "soundbank-reverb"; | |||||
| export class ReverbFilter extends Filter { | |||||
| private reverb: any; | |||||
| @exposedNumber({ | |||||
| name: "Reverb Time", | |||||
| min: 0.1, | |||||
| max: 5, | |||||
| format: (value: number) => | |||||
| Math.pow(2, value).toLocaleString(undefined, { | |||||
| maximumFractionDigits: 1, | |||||
| }) + "s", | |||||
| map: (value: number) => Math.log(value) / Math.log(2), | |||||
| unmap: (value: number) => Math.pow(2, value), | |||||
| }) | |||||
| public time = 1; | |||||
| private oldTime = -1; | |||||
| @exposedNumber({ | |||||
| name: "Decay Rate", | |||||
| min: 0.1, | |||||
| max: 5, | |||||
| format: (value: number) => | |||||
| Math.pow(2, value).toLocaleString(undefined, { | |||||
| maximumFractionDigits: 1, | |||||
| }), | |||||
| map: (value: number) => Math.log(value) / Math.log(2), | |||||
| unmap: (value: number) => Math.pow(2, value), | |||||
| }) | |||||
| public decay = 1; | |||||
| private oldDecay = -1; | |||||
| @exposedNumber({ | |||||
| name: "Dry Mix", | |||||
| min: 0, | |||||
| max: 1, | |||||
| format: (value: number) => | |||||
| (value * 100).toLocaleString(undefined, { | |||||
| maximumFractionDigits: 0, | |||||
| }) + "%", | |||||
| }) | |||||
| public dry = 1; | |||||
| @exposedNumber({ | |||||
| name: "Wet Mix", | |||||
| min: 0, | |||||
| max: 1, | |||||
| format: (value: number) => | |||||
| (value * 100).toLocaleString(undefined, { | |||||
| maximumFractionDigits: 0, | |||||
| }) + "%", | |||||
| }) | |||||
| public wet = 0.5; | |||||
| constructor() { | |||||
| super("Reverb Filter"); | |||||
| this.reverb = Reverb(context); | |||||
| this.reverb.time = 1; | |||||
| this.input.connect(this.reverb); | |||||
| this.reverb.connect(this.output); | |||||
| } | |||||
| public tick(dt: number): void { | |||||
| super.tick(dt); | |||||
| if (this.oldTime != this.time) { | |||||
| this.reverb.time = this.time; | |||||
| this.oldTime = this.time; | |||||
| } | |||||
| if (this.oldDecay != this.decay) { | |||||
| this.reverb.decay = this.decay; | |||||
| this.oldDecay = this.decay; | |||||
| } | |||||
| this.reverb.dry.setTargetAtTime(this.dry, context.currentTime, 0.3); | |||||
| this.reverb.wet.setTargetAtTime(this.wet, context.currentTime, 0.3); | |||||
| } | |||||
| } | |||||
| @@ -17,6 +17,7 @@ const constructors: { [key: string]: new (name: string) => Node } = { | |||||
| LowpassFilter: LowpassFilter, | LowpassFilter: LowpassFilter, | ||||
| HighpassFilter: HighpassFilter, | HighpassFilter: HighpassFilter, | ||||
| StereoWidthFilter: StereoWidthFilter, | StereoWidthFilter: StereoWidthFilter, | ||||
| ReverbFilter: ReverbFilter, | |||||
| }; | }; | ||||
| import { SoundSet, Source } from "./sources/Source"; | import { SoundSet, Source } from "./sources/Source"; | ||||
| @@ -25,6 +26,7 @@ import { LowpassFilter } from "./filters/LowpassFilter"; | |||||
| import { HighpassFilter } from "./filters/HighpassFilter"; | import { HighpassFilter } from "./filters/HighpassFilter"; | ||||
| import { StereoWidthFilter } from "./filters/StereoWidthFilter"; | import { StereoWidthFilter } from "./filters/StereoWidthFilter"; | ||||
| import { PresetSoundSets } from "./data/sound-sets"; | import { PresetSoundSets } from "./data/sound-sets"; | ||||
| import { ReverbFilter } from "./filters/ReverbFilter"; | |||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||
| export function serializeNode<T extends Node>(_node: T): any { | export function serializeNode<T extends Node>(_node: T): any { | ||||
| @@ -32,7 +32,8 @@ | |||||
| "src/**/*.tsx", | "src/**/*.tsx", | ||||
| "src/**/*.vue", | "src/**/*.vue", | ||||
| "tests/**/*.ts", | "tests/**/*.ts", | ||||
| "tests/**/*.tsx" | |||||
| "tests/**/*.tsx", | |||||
| "decs.d.ts", | |||||
| ], | ], | ||||
| "exclude": [ | "exclude": [ | ||||
| "node_modules" | "node_modules" | ||||