@ryohey/wavelet
Advanced tools
Comparing version 0.4.1 to 0.4.2
import { LoadSampleEvent, SynthEvent } from "../SynthEvent"; | ||
export declare type InMessage = StartMessage; | ||
export declare type InMessage = StartMessage | CancelMessage; | ||
export declare type OutMessage = ProgressMessage | CompleteMessage; | ||
export interface StartMessage { | ||
type: "start"; | ||
samples: LoadSampleEvent[]; | ||
@@ -9,2 +10,5 @@ events: SynthEvent[]; | ||
} | ||
export interface CancelMessage { | ||
type: "cancel"; | ||
} | ||
export interface ProgressMessage { | ||
@@ -11,0 +15,0 @@ type: "progress"; |
import { AudioData, LoadSampleEvent, SynthEvent } from ".."; | ||
export declare const renderAudio: (samples: LoadSampleEvent[], events: SynthEvent[], sampleRate: number, onProgress?: ((numFrames: number, totalFrames: number) => void) | undefined) => Promise<AudioData>; | ||
export interface CancellationToken { | ||
cancelled: boolean; | ||
} | ||
export declare const renderAudio: (samples: LoadSampleEvent[], events: SynthEvent[], sampleRate: number, onProgress?: ((numFrames: number, totalFrames: number) => void) | undefined, cancel?: Readonly<CancellationToken> | undefined) => Promise<AudioData>; |
@@ -5,3 +5,3 @@ import { SynthProcessorCore } from "../processor/SynthProcessorCore"; | ||
const Sleep = (time) => new Promise((resolve) => setTimeout(resolve, time)); | ||
export const renderAudio = async (samples, events, sampleRate, onProgress) => { | ||
export const renderAudio = async (samples, events, sampleRate, onProgress, cancel) => { | ||
let currentFrame = 0; | ||
@@ -28,2 +28,5 @@ const synth = new SynthProcessorCore(sampleRate, () => currentFrame); | ||
await Sleep(0); | ||
if (cancel?.cancelled) { | ||
throw new Error("renderAudio cancelled"); | ||
} | ||
} | ||
@@ -30,0 +33,0 @@ } |
import { renderAudio } from "./renderAudio"; | ||
let cancel = null; | ||
onmessage = async (e) => { | ||
const { samples, events, sampleRate } = e.data; | ||
const audioData = await renderAudio(samples, events, sampleRate, (numBytes, totalBytes) => postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
})); | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]); | ||
switch (e.data.type) { | ||
case "cancel": { | ||
if (cancel !== null) { | ||
cancel.cancelled = true; | ||
} | ||
break; | ||
} | ||
case "start": { | ||
if (cancel !== null) { | ||
throw new Error("rendering is already started."); | ||
} | ||
const { samples, events, sampleRate } = e.data; | ||
cancel = { | ||
cancelled: false, | ||
}; | ||
try { | ||
const audioData = await renderAudio(samples, events, sampleRate, (numBytes, totalBytes) => postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
}), cancel); | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]); | ||
} | ||
catch (e) { | ||
console.error(e.message); | ||
} | ||
close(); | ||
break; | ||
} | ||
} | ||
}; | ||
//# sourceMappingURL=rendererWorker.js.map |
import { LoadSampleEvent, SynthEvent } from "../SynthEvent"; | ||
export declare type InMessage = StartMessage; | ||
export declare type InMessage = StartMessage | CancelMessage; | ||
export declare type OutMessage = ProgressMessage | CompleteMessage; | ||
export interface StartMessage { | ||
type: "start"; | ||
samples: LoadSampleEvent[]; | ||
@@ -9,2 +10,5 @@ events: SynthEvent[]; | ||
} | ||
export interface CancelMessage { | ||
type: "cancel"; | ||
} | ||
export interface ProgressMessage { | ||
@@ -11,0 +15,0 @@ type: "progress"; |
import { AudioData, LoadSampleEvent, SynthEvent } from ".."; | ||
export declare const renderAudio: (samples: LoadSampleEvent[], events: SynthEvent[], sampleRate: number, onProgress?: ((numFrames: number, totalFrames: number) => void) | undefined) => Promise<AudioData>; | ||
export interface CancellationToken { | ||
cancelled: boolean; | ||
} | ||
export declare const renderAudio: (samples: LoadSampleEvent[], events: SynthEvent[], sampleRate: number, onProgress?: ((numFrames: number, totalFrames: number) => void) | undefined, cancel?: Readonly<CancellationToken> | undefined) => Promise<AudioData>; |
@@ -738,3 +738,3 @@ (function () { | ||
const Sleep = (time) => new Promise((resolve) => setTimeout(resolve, time)); | ||
const renderAudio = async (samples, events, sampleRate, onProgress) => { | ||
const renderAudio = async (samples, events, sampleRate, onProgress, cancel) => { | ||
let currentFrame = 0; | ||
@@ -761,2 +761,5 @@ const synth = new SynthProcessorCore(sampleRate, () => currentFrame); | ||
await Sleep(0); | ||
if (cancel?.cancelled) { | ||
throw new Error("renderAudio cancelled"); | ||
} | ||
} | ||
@@ -772,13 +775,37 @@ } | ||
let cancel = null; | ||
onmessage = async (e) => { | ||
const { samples, events, sampleRate } = e.data; | ||
const audioData = await renderAudio(samples, events, sampleRate, (numBytes, totalBytes) => postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
})); | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]); | ||
switch (e.data.type) { | ||
case "cancel": { | ||
if (cancel !== null) { | ||
cancel.cancelled = true; | ||
} | ||
break; | ||
} | ||
case "start": { | ||
if (cancel !== null) { | ||
throw new Error("rendering is already started."); | ||
} | ||
const { samples, events, sampleRate } = e.data; | ||
cancel = { | ||
cancelled: false, | ||
}; | ||
try { | ||
const audioData = await renderAudio(samples, events, sampleRate, (numBytes, totalBytes) => postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
}), cancel); | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]); | ||
} | ||
catch (e) { | ||
console.error(e.message); | ||
} | ||
close(); | ||
break; | ||
} | ||
} | ||
}; | ||
@@ -785,0 +812,0 @@ |
{ | ||
"name": "@ryohey/wavelet", | ||
"version": "0.4.1", | ||
"version": "0.4.2", | ||
"description": "A wavetable synthesizer that never stops the UI thread created by AudioWorklet.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
import { LoadSampleEvent, SynthEvent } from "../SynthEvent" | ||
export type InMessage = StartMessage | ||
export type InMessage = StartMessage | CancelMessage | ||
export type OutMessage = ProgressMessage | CompleteMessage | ||
export interface StartMessage { | ||
type: "start" | ||
samples: LoadSampleEvent[] | ||
@@ -12,2 +13,6 @@ events: SynthEvent[] | ||
export interface CancelMessage { | ||
type: "cancel" | ||
} | ||
export interface ProgressMessage { | ||
@@ -14,0 +19,0 @@ type: "progress" |
@@ -11,2 +11,6 @@ import { AudioData, LoadSampleEvent, SynthEvent } from ".." | ||
export interface CancellationToken { | ||
cancelled: boolean | ||
} | ||
export const renderAudio = async ( | ||
@@ -16,3 +20,4 @@ samples: LoadSampleEvent[], | ||
sampleRate: number, | ||
onProgress?: (numFrames: number, totalFrames: number) => void | ||
onProgress?: (numFrames: number, totalFrames: number) => void, | ||
cancel?: Readonly<CancellationToken> | ||
): Promise<AudioData> => { | ||
@@ -45,2 +50,6 @@ let currentFrame = 0 | ||
await Sleep(0) | ||
if (cancel?.cancelled) { | ||
throw new Error("renderAudio cancelled") | ||
} | ||
} | ||
@@ -47,0 +56,0 @@ } |
@@ -1,3 +0,4 @@ | ||
import { CompleteMessage, ProgressMessage, StartMessage } from "./message" | ||
import { renderAudio } from "./renderAudio" | ||
import { InMessage } from ".." | ||
import { CompleteMessage, ProgressMessage } from "./message" | ||
import { CancellationToken, renderAudio } from "./renderAudio" | ||
@@ -11,19 +12,47 @@ declare global { | ||
onmessage = async (e: MessageEvent<StartMessage>) => { | ||
const { samples, events, sampleRate } = e.data | ||
const audioData = await renderAudio( | ||
samples, | ||
events, | ||
sampleRate, | ||
(numBytes, totalBytes) => | ||
postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
}) | ||
) | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]) | ||
let cancel: CancellationToken | null = null | ||
onmessage = async (e: MessageEvent<InMessage>) => { | ||
switch (e.data.type) { | ||
case "cancel": { | ||
if (cancel !== null) { | ||
cancel.cancelled = true | ||
} | ||
break | ||
} | ||
case "start": { | ||
if (cancel !== null) { | ||
throw new Error("rendering is already started.") | ||
} | ||
const { samples, events, sampleRate } = e.data | ||
cancel = { | ||
cancelled: false, | ||
} | ||
try { | ||
const audioData = await renderAudio( | ||
samples, | ||
events, | ||
sampleRate, | ||
(numBytes, totalBytes) => | ||
postMessage({ | ||
type: "progress", | ||
numBytes, | ||
totalBytes, | ||
}), | ||
cancel | ||
) | ||
postMessage({ type: "complete", audioData }, [ | ||
audioData.leftData, | ||
audioData.rightData, | ||
]) | ||
} catch (e) { | ||
console.error((e as Error).message) | ||
} | ||
close() | ||
break | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
523890
4789