/ proof-of-concept / plate-dynamics-lab
Sign in
proof-of-concept / plate-dynamics-lab
plate-dynamics-lab / packages / core / src / audio / buffer.ts
36 lines · 1.2 KBBlameHistoryRaw
1/**
2 * Turn a pressure signal into something Web Audio can play. Peak normalization
3 * is a playback convenience (the absolute level of the Rayleigh estimate is not
4 * calibrated anyway) and is reported so the interface can say so.
5 */
6export interface AudioPrep {
7 samples: Float32Array;
8 fs: number;
9 /** Peak of the original signal [Pa] */
10 peakPa: number;
11 /** Gain applied so the peak sits at `target` */
12 gain: number;
13 durationS: number;
16export function prepareAudio(p: Float64Array, fs: number, target = 0.8): AudioPrep {
17 let peak = 0;
18 for (let i = 0; i < p.length; i++) {
19 const a = Math.abs(p[i]);
20 if (a > peak) peak = a;
21 }
22 const gain = peak > 0 ? target / peak : 1;
23 const samples = new Float32Array(p.length);
24 for (let i = 0; i < p.length; i++) samples[i] = Number.isFinite(p[i]) ? p[i] * gain : 0;
25 return { samples, fs, peakPa: peak, gain, durationS: p.length / fs };
28export function toAudioBuffer(ctx: BaseAudioContext, prep: AudioPrep): AudioBuffer {
29 const n = Math.max(1, prep.samples.length);
30 const buf = ctx.createBuffer(1, n, prep.fs);
31 const data = (
32 prep.samples.length ? prep.samples : new Float32Array(1)
33 ) as Float32Array<ArrayBuffer>;
34 buf.copyToChannel(data, 0);
35 return buf;
↑↓ move↵openescclose