// The interface shared by the CPU and the GPU time loops. export interface ChunkResult { firstSample: number; // audio index of pressureFront[0] pressureFront: Float32Array; // baffled Rayleigh pressure [Pa] pressureBack: Float32Array; // diffracted back term [Pa]; unbaffled = front - back frames: Float32Array[]; // displacement w at every node, captured every `movieEvery` audio samples frameSamples: number[]; // audio sample index of each frame /** Normal acceleration of every node [m/s^2] for the samples [firstSample, firstSample + count), row-major (count, N); present when recording. */ acceleration: Float32Array | null; dispFrames: Float32Array[]; // displacement w for the .cymsim record, every `dispEvery` audio samples dispSamples: number[]; } export interface HitState { peakForce: number; contactTime: number; velocity: number; height: number } export interface Diagnostics { time: number; kinetic: number; membrane: number; bending: number; exciters: number; maxWoverH: number; hits: HitState[]; } /** What a backend needs to continue a run: its own arrays, opaque to everything but the same backend kind. */ export interface BackendState { kind: "cpu" | "gpu"; step: number; // sub-steps done samplesDone: number; arrays: Record; } export interface BackendOptions { /** > 0 captures w for the replay movie every that many audio samples. */ movieEvery?: number; /** > 0 captures w for the .cymsim displacement record every that many audio samples. */ dispEvery?: number; /** Keep the audio-rate normal acceleration of every node (returned per chunk). */ recordAcceleration?: boolean; } export interface SimulatorBackend { readonly kind: "cpu" | "gpu"; readonly samplesDone: number; /** Largest chunk (audio samples) runChunk accepts. */ readonly maxChunk: number; /** Advance by nSamples audio samples and return the pressure samples completed meanwhile. */ runChunk(nSamples: number): Promise; diagnostics(): Promise; /** Transverse displacement w at every node, for the plate view. */ displacement(): Promise; /** The integrator state, for a .cymsim file; ``importState`` continues from one (same backend kind and set-up). */ exportState(): Promise; importState(state: BackendState): Promise; dispose(): void; } /** Sub-steps per audio sample times audio samples between file displacement frames, for a frame rate [fps]. */ export function dispEveryFor(fs: number, rate: number): number { return rate > 0 ? Math.max(1, Math.round(fs / rate)) : 0; }