@libraz/libsonare 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +132 -12
- package/dist/index.js +103 -8
- package/dist/index.js.map +1 -1
- package/dist/sonare-rt.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +44 -5
- package/dist/worklet.js +348 -73
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +189 -8
- package/src/public_types.ts +67 -0
- package/src/sonare.js.d.ts +84 -0
- package/src/stream_types.ts +4 -1
- package/src/worklet.ts +525 -81
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
5
|
* ```typescript
|
|
6
|
-
* import { init, detectBpm, detectKey, analyze } from '@libraz/
|
|
6
|
+
* import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';
|
|
7
7
|
*
|
|
8
8
|
* await init();
|
|
9
9
|
*
|
|
@@ -60,6 +60,11 @@ import type {
|
|
|
60
60
|
PitchResult,
|
|
61
61
|
RealtimeVoiceChangerConfigInput,
|
|
62
62
|
RealtimeVoiceChangerPodConfig,
|
|
63
|
+
RirResult,
|
|
64
|
+
RirSynthOptions,
|
|
65
|
+
RoomEstimateOptions,
|
|
66
|
+
RoomEstimateResult,
|
|
67
|
+
RoomMorphOptions,
|
|
63
68
|
Section,
|
|
64
69
|
SectionType,
|
|
65
70
|
SendTiming,
|
|
@@ -151,6 +156,7 @@ export type {
|
|
|
151
156
|
MasteringStereoResult,
|
|
152
157
|
MelodyPoint,
|
|
153
158
|
MelodyResult,
|
|
159
|
+
MelPowerResult,
|
|
154
160
|
MelSpectrogramResult,
|
|
155
161
|
MeterTap,
|
|
156
162
|
MfccResult,
|
|
@@ -164,15 +170,24 @@ export type {
|
|
|
164
170
|
PanMode,
|
|
165
171
|
PitchResult,
|
|
166
172
|
RealtimeVoiceChangerConfigInput,
|
|
173
|
+
RealtimeVoiceChangerPodConfig,
|
|
167
174
|
RhythmFeatures,
|
|
175
|
+
RirResult,
|
|
176
|
+
RirSynthOptions,
|
|
177
|
+
RoomEstimateOptions,
|
|
178
|
+
RoomEstimateResult,
|
|
179
|
+
RoomGeometryOptions,
|
|
180
|
+
RoomMorphOptions,
|
|
168
181
|
Section,
|
|
169
182
|
SendTiming,
|
|
170
183
|
SoloProcessor,
|
|
171
184
|
StereoAnalysis,
|
|
185
|
+
StftPowerResult,
|
|
172
186
|
StftResult,
|
|
173
187
|
StreamingEqualizerConfig,
|
|
174
188
|
StreamingPlatform,
|
|
175
189
|
StreamingRetuneConfig,
|
|
190
|
+
TempogramMode,
|
|
176
191
|
Timbre,
|
|
177
192
|
TimeSignature,
|
|
178
193
|
VoicePresetId,
|
|
@@ -712,6 +727,34 @@ export class RealtimeEngine {
|
|
|
712
727
|
return this.native.process(channels);
|
|
713
728
|
}
|
|
714
729
|
|
|
730
|
+
/**
|
|
731
|
+
* Allocates persistent per-channel WASM-heap scratch for the zero-copy
|
|
732
|
+
* `getChannelBuffer` / `processPrepared` realtime path. Call once (off the
|
|
733
|
+
* audio thread) before driving `processPrepared` from an AudioWorklet so the
|
|
734
|
+
* render callback never allocates on the C++/JS heap.
|
|
735
|
+
*/
|
|
736
|
+
prepareChannels(numChannels: number, maxFrames: number): void {
|
|
737
|
+
this.native.prepareChannels(numChannels, maxFrames);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Returns a Float32Array view onto the persistent WASM-heap scratch for one
|
|
742
|
+
* channel (valid for up to `numFrames`). Fill it, call `processPrepared`, then
|
|
743
|
+
* read the same view back. Re-acquire after WASM memory growth.
|
|
744
|
+
*/
|
|
745
|
+
getChannelBuffer(channel: number, numFrames: number): Float32Array {
|
|
746
|
+
return this.native.getChannelBuffer(channel, numFrames);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Runs the engine in place over the prepared per-channel scratch buffers.
|
|
751
|
+
* Allocation-free: safe to call on the AudioWorklet render thread after
|
|
752
|
+
* `prepareChannels`.
|
|
753
|
+
*/
|
|
754
|
+
processPrepared(numFrames: number): void {
|
|
755
|
+
this.native.processPrepared(numFrames);
|
|
756
|
+
}
|
|
757
|
+
|
|
715
758
|
processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult {
|
|
716
759
|
return this.native.processWithMonitor(channels);
|
|
717
760
|
}
|
|
@@ -1086,6 +1129,57 @@ export function detectAcoustic(
|
|
|
1086
1129
|
return result;
|
|
1087
1130
|
}
|
|
1088
1131
|
|
|
1132
|
+
/**
|
|
1133
|
+
* Synthesize a room impulse response from shoebox geometry. `hasError` is true
|
|
1134
|
+
* when the source/listener falls outside the room (the RIR is then empty).
|
|
1135
|
+
*/
|
|
1136
|
+
export function synthesizeRir(options: RirSynthOptions = {}): RirResult {
|
|
1137
|
+
if (!module) {
|
|
1138
|
+
throw new Error('Module not initialized. Call init() first.');
|
|
1139
|
+
}
|
|
1140
|
+
if (typeof module.synthesizeRir !== 'function') {
|
|
1141
|
+
throw new Error('libsonare was built without acoustic-simulation support');
|
|
1142
|
+
}
|
|
1143
|
+
return module.synthesizeRir(options);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* Estimate an equivalent room (volume/dimensions/absorption/DRR) from a
|
|
1148
|
+
* recording or impulse response.
|
|
1149
|
+
*/
|
|
1150
|
+
export function estimateRoom(
|
|
1151
|
+
samples: Float32Array,
|
|
1152
|
+
sampleRate = 48000,
|
|
1153
|
+
options: RoomEstimateOptions = {},
|
|
1154
|
+
): RoomEstimateResult {
|
|
1155
|
+
if (!module) {
|
|
1156
|
+
throw new Error('Module not initialized. Call init() first.');
|
|
1157
|
+
}
|
|
1158
|
+
if (typeof module.estimateRoom !== 'function') {
|
|
1159
|
+
throw new Error('libsonare was built without acoustic-simulation support');
|
|
1160
|
+
}
|
|
1161
|
+
return module.estimateRoom(samples, sampleRate, options);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* Morph a recording's reverberation toward a target room (creative FX, not
|
|
1166
|
+
* dereverberation). Returns the morphed samples (input length plus the target
|
|
1167
|
+
* room's reverb tail).
|
|
1168
|
+
*/
|
|
1169
|
+
export function roomMorph(
|
|
1170
|
+
samples: Float32Array,
|
|
1171
|
+
sampleRate: number,
|
|
1172
|
+
options: RoomMorphOptions = {},
|
|
1173
|
+
): Float32Array {
|
|
1174
|
+
if (!module) {
|
|
1175
|
+
throw new Error('Module not initialized. Call init() first.');
|
|
1176
|
+
}
|
|
1177
|
+
if (typeof module.roomMorph !== 'function') {
|
|
1178
|
+
throw new Error('libsonare was built without acoustic-simulation support');
|
|
1179
|
+
}
|
|
1180
|
+
return module.roomMorph(samples, sampleRate, options);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1089
1183
|
/**
|
|
1090
1184
|
* Perform complete music analysis with progress reporting.
|
|
1091
1185
|
*
|
|
@@ -1286,10 +1380,15 @@ export function hpss(
|
|
|
1286
1380
|
* @param sampleRate - Sample rate in Hz
|
|
1287
1381
|
* @returns Harmonic component
|
|
1288
1382
|
*/
|
|
1289
|
-
export function harmonic(
|
|
1383
|
+
export function harmonic(
|
|
1384
|
+
samples: Float32Array,
|
|
1385
|
+
sampleRate: number,
|
|
1386
|
+
options: ValidateOptions = {},
|
|
1387
|
+
): Float32Array {
|
|
1290
1388
|
if (!module) {
|
|
1291
1389
|
throw new Error('Module not initialized. Call init() first.');
|
|
1292
1390
|
}
|
|
1391
|
+
assertSamples('harmonic', samples, options.validate !== false);
|
|
1293
1392
|
return module.harmonic(samples, sampleRate);
|
|
1294
1393
|
}
|
|
1295
1394
|
|
|
@@ -1300,10 +1399,15 @@ export function harmonic(samples: Float32Array, sampleRate: number): Float32Arra
|
|
|
1300
1399
|
* @param sampleRate - Sample rate in Hz
|
|
1301
1400
|
* @returns Percussive component
|
|
1302
1401
|
*/
|
|
1303
|
-
export function percussive(
|
|
1402
|
+
export function percussive(
|
|
1403
|
+
samples: Float32Array,
|
|
1404
|
+
sampleRate: number,
|
|
1405
|
+
options: ValidateOptions = {},
|
|
1406
|
+
): Float32Array {
|
|
1304
1407
|
if (!module) {
|
|
1305
1408
|
throw new Error('Module not initialized. Call init() first.');
|
|
1306
1409
|
}
|
|
1410
|
+
assertSamples('percussive', samples, options.validate !== false);
|
|
1307
1411
|
return module.percussive(samples, sampleRate);
|
|
1308
1412
|
}
|
|
1309
1413
|
|
|
@@ -1315,10 +1419,16 @@ export function percussive(samples: Float32Array, sampleRate: number): Float32Ar
|
|
|
1315
1419
|
* @param rate - Time stretch rate (0.5 = double duration, 2.0 = half duration)
|
|
1316
1420
|
* @returns Time-stretched audio
|
|
1317
1421
|
*/
|
|
1318
|
-
export function timeStretch(
|
|
1422
|
+
export function timeStretch(
|
|
1423
|
+
samples: Float32Array,
|
|
1424
|
+
sampleRate: number,
|
|
1425
|
+
rate: number,
|
|
1426
|
+
options: ValidateOptions = {},
|
|
1427
|
+
): Float32Array {
|
|
1319
1428
|
if (!module) {
|
|
1320
1429
|
throw new Error('Module not initialized. Call init() first.');
|
|
1321
1430
|
}
|
|
1431
|
+
assertSamples('timeStretch', samples, options.validate !== false);
|
|
1322
1432
|
return module.timeStretch(samples, sampleRate, rate);
|
|
1323
1433
|
}
|
|
1324
1434
|
|
|
@@ -1334,10 +1444,12 @@ export function pitchShift(
|
|
|
1334
1444
|
samples: Float32Array,
|
|
1335
1445
|
sampleRate: number,
|
|
1336
1446
|
semitones: number,
|
|
1447
|
+
options: ValidateOptions = {},
|
|
1337
1448
|
): Float32Array {
|
|
1338
1449
|
if (!module) {
|
|
1339
1450
|
throw new Error('Module not initialized. Call init() first.');
|
|
1340
1451
|
}
|
|
1452
|
+
assertSamples('pitchShift', samples, options.validate !== false);
|
|
1341
1453
|
return module.pitchShift(samples, sampleRate, semitones);
|
|
1342
1454
|
}
|
|
1343
1455
|
|
|
@@ -1355,10 +1467,12 @@ export function pitchCorrectToMidi(
|
|
|
1355
1467
|
sampleRate = 22050,
|
|
1356
1468
|
currentMidi = 69.0,
|
|
1357
1469
|
targetMidi = 69.0,
|
|
1470
|
+
options: ValidateOptions = {},
|
|
1358
1471
|
): Float32Array {
|
|
1359
1472
|
if (!module) {
|
|
1360
1473
|
throw new Error('Module not initialized. Call init() first.');
|
|
1361
1474
|
}
|
|
1475
|
+
assertSamples('pitchCorrectToMidi', samples, options.validate !== false);
|
|
1362
1476
|
return module.pitchCorrectToMidi(samples, sampleRate, currentMidi, targetMidi);
|
|
1363
1477
|
}
|
|
1364
1478
|
|
|
@@ -1378,10 +1492,12 @@ export function noteStretch(
|
|
|
1378
1492
|
onsetSample = 0,
|
|
1379
1493
|
offsetSample = 0,
|
|
1380
1494
|
stretchRatio = 1.0,
|
|
1495
|
+
options: ValidateOptions = {},
|
|
1381
1496
|
): Float32Array {
|
|
1382
1497
|
if (!module) {
|
|
1383
1498
|
throw new Error('Module not initialized. Call init() first.');
|
|
1384
1499
|
}
|
|
1500
|
+
assertSamples('noteStretch', samples, options.validate !== false);
|
|
1385
1501
|
return module.noteStretch(samples, sampleRate, onsetSample, offsetSample, stretchRatio);
|
|
1386
1502
|
}
|
|
1387
1503
|
|
|
@@ -1408,6 +1524,65 @@ export function voiceChange(
|
|
|
1408
1524
|
return module.voiceChange(samples, sampleRate, pitchSemitones, formantFactor);
|
|
1409
1525
|
}
|
|
1410
1526
|
|
|
1527
|
+
/** Options for the offline {@link voiceChangeRealtime} convenience wrapper. */
|
|
1528
|
+
export interface VoiceChangeRealtimeOptions extends ValidateOptions {
|
|
1529
|
+
sampleRate?: number;
|
|
1530
|
+
/** Voice-changer preset id or full config object. */
|
|
1531
|
+
preset?: RealtimeVoiceChangerConfigInput;
|
|
1532
|
+
/** Channel count (1 = mono, 2 = interleaved stereo). */
|
|
1533
|
+
channels?: 1 | 2;
|
|
1534
|
+
/** Block size for the internal render loop (default 512). */
|
|
1535
|
+
blockSize?: number;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* Applies the realtime voice-changer chain to a whole buffer in one call.
|
|
1540
|
+
*
|
|
1541
|
+
* Constructs and prepares a {@link RealtimeVoiceChanger}, runs the block loop
|
|
1542
|
+
* for the caller, then disposes it — matching the Python `voice_change_realtime`
|
|
1543
|
+
* and Node `voiceChangeRealtime` convenience wrappers. For mono, `samples` is a
|
|
1544
|
+
* plain mono buffer; for stereo, `samples` is interleaved (L0,R0,L1,R1,...).
|
|
1545
|
+
*
|
|
1546
|
+
* @returns The processed buffer (same layout/length as the input).
|
|
1547
|
+
*/
|
|
1548
|
+
export function voiceChangeRealtime(
|
|
1549
|
+
samples: Float32Array,
|
|
1550
|
+
options: VoiceChangeRealtimeOptions = {},
|
|
1551
|
+
): Float32Array {
|
|
1552
|
+
if (!module) {
|
|
1553
|
+
throw new Error('Module not initialized. Call init() first.');
|
|
1554
|
+
}
|
|
1555
|
+
assertSamples('voiceChangeRealtime', samples, options.validate !== false);
|
|
1556
|
+
const channels = options.channels ?? 1;
|
|
1557
|
+
if (channels !== 1 && channels !== 2) {
|
|
1558
|
+
throw new Error('voiceChangeRealtime: channels must be 1 or 2.');
|
|
1559
|
+
}
|
|
1560
|
+
// 48000 matches the Python voice_change_realtime and Node voiceChangeRealtime
|
|
1561
|
+
// convenience wrappers (and the RealtimeVoiceChanger default).
|
|
1562
|
+
const sampleRate = options.sampleRate ?? 48000;
|
|
1563
|
+
const blockSize = Math.max(1, Math.floor(options.blockSize ?? 512));
|
|
1564
|
+
const changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');
|
|
1565
|
+
try {
|
|
1566
|
+
changer.prepare(sampleRate, blockSize, channels);
|
|
1567
|
+
const out = new Float32Array(samples.length);
|
|
1568
|
+
if (channels === 1) {
|
|
1569
|
+
for (let offset = 0; offset < samples.length; offset += blockSize) {
|
|
1570
|
+
const block = samples.subarray(offset, Math.min(offset + blockSize, samples.length));
|
|
1571
|
+
out.set(changer.processMono(block), offset);
|
|
1572
|
+
}
|
|
1573
|
+
} else {
|
|
1574
|
+
const frameStride = blockSize * 2;
|
|
1575
|
+
for (let offset = 0; offset < samples.length; offset += frameStride) {
|
|
1576
|
+
const block = samples.subarray(offset, Math.min(offset + frameStride, samples.length));
|
|
1577
|
+
out.set(changer.processInterleaved(block, 2), offset);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
return out;
|
|
1581
|
+
} finally {
|
|
1582
|
+
changer.delete();
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1411
1586
|
/**
|
|
1412
1587
|
* Normalize audio to target peak level.
|
|
1413
1588
|
*
|
|
@@ -1416,10 +1591,16 @@ export function voiceChange(
|
|
|
1416
1591
|
* @param targetDb - Target peak level in dB (default: 0 dB = full scale)
|
|
1417
1592
|
* @returns Normalized audio
|
|
1418
1593
|
*/
|
|
1419
|
-
export function normalize(
|
|
1594
|
+
export function normalize(
|
|
1595
|
+
samples: Float32Array,
|
|
1596
|
+
sampleRate: number,
|
|
1597
|
+
targetDb = 0.0,
|
|
1598
|
+
options: ValidateOptions = {},
|
|
1599
|
+
): Float32Array {
|
|
1420
1600
|
if (!module) {
|
|
1421
1601
|
throw new Error('Module not initialized. Call init() first.');
|
|
1422
1602
|
}
|
|
1603
|
+
assertSamples('normalize', samples, options.validate !== false);
|
|
1423
1604
|
return module.normalize(samples, sampleRate, targetDb);
|
|
1424
1605
|
}
|
|
1425
1606
|
|
|
@@ -4535,7 +4716,7 @@ export function resample(samples: Float32Array, srcSr: number, targetSr: number)
|
|
|
4535
4716
|
*
|
|
4536
4717
|
* @example
|
|
4537
4718
|
* ```typescript
|
|
4538
|
-
* import { init, Audio } from '@libraz/
|
|
4719
|
+
* import { init, Audio } from '@libraz/libsonare';
|
|
4539
4720
|
*
|
|
4540
4721
|
* await init();
|
|
4541
4722
|
*
|
|
@@ -4802,7 +4983,7 @@ export class Audio {
|
|
|
4802
4983
|
*
|
|
4803
4984
|
* @example
|
|
4804
4985
|
* ```typescript
|
|
4805
|
-
* import { init, StreamAnalyzer } from '@libraz/
|
|
4986
|
+
* import { init, StreamAnalyzer } from '@libraz/libsonare';
|
|
4806
4987
|
*
|
|
4807
4988
|
* await init();
|
|
4808
4989
|
*
|
|
@@ -4831,7 +5012,7 @@ export class StreamAnalyzer {
|
|
|
4831
5012
|
throw new Error('Module not initialized. Call init() first.');
|
|
4832
5013
|
}
|
|
4833
5014
|
this.analyzer = new module.StreamAnalyzer(
|
|
4834
|
-
config.sampleRate,
|
|
5015
|
+
config.sampleRate ?? 44100,
|
|
4835
5016
|
config.nFft ?? 2048,
|
|
4836
5017
|
config.hopLength ?? 512,
|
|
4837
5018
|
config.nMels ?? 128,
|
package/src/public_types.ts
CHANGED
|
@@ -421,6 +421,69 @@ export interface AcousticResult {
|
|
|
421
421
|
isBlind: boolean;
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
+
/** Shoebox geometry + placement shared by RIR synthesis and the room morph. */
|
|
425
|
+
export interface RoomGeometryOptions {
|
|
426
|
+
lengthM?: number;
|
|
427
|
+
widthM?: number;
|
|
428
|
+
heightM?: number;
|
|
429
|
+
absorption?: number;
|
|
430
|
+
sourceX?: number;
|
|
431
|
+
sourceY?: number;
|
|
432
|
+
sourceZ?: number;
|
|
433
|
+
listenerX?: number;
|
|
434
|
+
listenerY?: number;
|
|
435
|
+
listenerZ?: number;
|
|
436
|
+
ismOrder?: number;
|
|
437
|
+
seed?: number;
|
|
438
|
+
maxSeconds?: number;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export interface RirSynthOptions extends RoomGeometryOptions {
|
|
442
|
+
sampleRate?: number;
|
|
443
|
+
/** Use the Eyring statistical late-tail model (default true); false = Sabine. */
|
|
444
|
+
preferEyring?: boolean;
|
|
445
|
+
/** Early/late crossover in ms (0 = auto, ~sqrt(V) ms). */
|
|
446
|
+
mixingTimeMs?: number;
|
|
447
|
+
/** Equal-power crossfade width around the mixing time in ms (0 = default). */
|
|
448
|
+
crossfadeMs?: number;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export interface RirResult {
|
|
452
|
+
rir: Float32Array;
|
|
453
|
+
sampleRate: number;
|
|
454
|
+
hasError: boolean;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export interface RoomEstimateOptions {
|
|
458
|
+
aspectHintLw?: number;
|
|
459
|
+
aspectHintLh?: number;
|
|
460
|
+
referenceAbsorption?: number;
|
|
461
|
+
preferEyring?: boolean;
|
|
462
|
+
nOctaveBands?: number;
|
|
463
|
+
/** Analyzer routing: 0 = auto, 1 = blind, 2 = impulse-response. */
|
|
464
|
+
mode?: number;
|
|
465
|
+
/** Analyzer decay-fit span in dB (0 = library default). */
|
|
466
|
+
minDecayDb?: number;
|
|
467
|
+
/** Analyzer noise-floor margin in dB (0 = library default). */
|
|
468
|
+
noiseFloorMarginDb?: number;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export interface RoomEstimateResult {
|
|
472
|
+
volume: number;
|
|
473
|
+
length: number;
|
|
474
|
+
width: number;
|
|
475
|
+
height: number;
|
|
476
|
+
drrDb: number;
|
|
477
|
+
confidence: number;
|
|
478
|
+
absorptionBands: Float32Array;
|
|
479
|
+
rt60Bands: Float32Array;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
export interface RoomMorphOptions extends RoomGeometryOptions {
|
|
483
|
+
wet?: number;
|
|
484
|
+
sourceTailSuppression?: number;
|
|
485
|
+
}
|
|
486
|
+
|
|
424
487
|
/**
|
|
425
488
|
* HPSS (Harmonic-Percussive Source Separation) result
|
|
426
489
|
*/
|
|
@@ -914,6 +977,10 @@ export interface RealtimeVoiceChangerPodConfig {
|
|
|
914
977
|
reverb_seed: number;
|
|
915
978
|
limiter_ceiling_db: number;
|
|
916
979
|
limiter_release_ms: number;
|
|
980
|
+
/** Non-zero enables the 4x-oversampled inter-sample-peak limiter (default enabled). */
|
|
981
|
+
limiter_enable_isp_limiter: boolean;
|
|
982
|
+
/** True-peak ceiling in dBTP applied by the ISP limiter (default -1.0). */
|
|
983
|
+
limiter_isp_ceiling_dbtp: number;
|
|
917
984
|
}
|
|
918
985
|
|
|
919
986
|
/** Options for {@link StreamingEqualizer.match}. */
|
package/src/sonare.js.d.ts
CHANGED
|
@@ -60,6 +60,8 @@ export interface WasmRealtimeVoiceChangerPodConfig {
|
|
|
60
60
|
reverb_seed: number;
|
|
61
61
|
limiter_ceiling_db: number;
|
|
62
62
|
limiter_release_ms: number;
|
|
63
|
+
limiter_enable_isp_limiter: boolean;
|
|
64
|
+
limiter_isp_ceiling_dbtp: number;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
export interface WasmBeatResult {
|
|
@@ -199,6 +201,62 @@ export interface WasmAcousticResult {
|
|
|
199
201
|
isBlind: boolean;
|
|
200
202
|
}
|
|
201
203
|
|
|
204
|
+
export interface WasmRoomGeometryOptions {
|
|
205
|
+
lengthM?: number;
|
|
206
|
+
widthM?: number;
|
|
207
|
+
heightM?: number;
|
|
208
|
+
absorption?: number;
|
|
209
|
+
sourceX?: number;
|
|
210
|
+
sourceY?: number;
|
|
211
|
+
sourceZ?: number;
|
|
212
|
+
listenerX?: number;
|
|
213
|
+
listenerY?: number;
|
|
214
|
+
listenerZ?: number;
|
|
215
|
+
ismOrder?: number;
|
|
216
|
+
seed?: number;
|
|
217
|
+
maxSeconds?: number;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface WasmRirSynthOptions extends WasmRoomGeometryOptions {
|
|
221
|
+
sampleRate?: number;
|
|
222
|
+
preferEyring?: boolean;
|
|
223
|
+
mixingTimeMs?: number;
|
|
224
|
+
crossfadeMs?: number;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export interface WasmRirResult {
|
|
228
|
+
rir: Float32Array;
|
|
229
|
+
sampleRate: number;
|
|
230
|
+
hasError: boolean;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface WasmRoomEstimateOptions {
|
|
234
|
+
aspectHintLw?: number;
|
|
235
|
+
aspectHintLh?: number;
|
|
236
|
+
referenceAbsorption?: number;
|
|
237
|
+
preferEyring?: boolean;
|
|
238
|
+
nOctaveBands?: number;
|
|
239
|
+
mode?: number;
|
|
240
|
+
minDecayDb?: number;
|
|
241
|
+
noiseFloorMarginDb?: number;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface WasmRoomEstimateResult {
|
|
245
|
+
volume: number;
|
|
246
|
+
length: number;
|
|
247
|
+
width: number;
|
|
248
|
+
height: number;
|
|
249
|
+
drrDb: number;
|
|
250
|
+
confidence: number;
|
|
251
|
+
absorptionBands: Float32Array;
|
|
252
|
+
rt60Bands: Float32Array;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface WasmRoomMorphOptions extends WasmRoomGeometryOptions {
|
|
256
|
+
wet?: number;
|
|
257
|
+
sourceTailSuppression?: number;
|
|
258
|
+
}
|
|
259
|
+
|
|
202
260
|
export interface WasmHpssResult {
|
|
203
261
|
harmonic: Float32Array;
|
|
204
262
|
percussive: Float32Array;
|
|
@@ -450,6 +508,8 @@ export interface WasmEngineMetronomeConfig {
|
|
|
450
508
|
beatGain?: number;
|
|
451
509
|
accentGain?: number;
|
|
452
510
|
clickSamples?: number;
|
|
511
|
+
/** Optional click length in seconds; > 0 overrides the engine 2 ms default. */
|
|
512
|
+
clickSeconds?: number;
|
|
453
513
|
}
|
|
454
514
|
|
|
455
515
|
export interface WasmEngineGraphNode {
|
|
@@ -528,6 +588,12 @@ export interface WasmEngineTransportState {
|
|
|
528
588
|
loopStartPpq: number;
|
|
529
589
|
loopEndPpq: number;
|
|
530
590
|
sampleRate: number;
|
|
591
|
+
/** PPQ of the current bar's downbeat (derived from the tempo map). */
|
|
592
|
+
barStartPpq: number;
|
|
593
|
+
/** Zero-based index of the current bar. */
|
|
594
|
+
barCount: number;
|
|
595
|
+
/** Time signature in effect at the current PPQ. */
|
|
596
|
+
timeSignature: { numerator: number; denominator: number; confidence: number };
|
|
531
597
|
}
|
|
532
598
|
|
|
533
599
|
export interface WasmEngineBounceOptions {
|
|
@@ -615,6 +681,9 @@ export interface WasmRealtimeEngine {
|
|
|
615
681
|
captureStatus: () => WasmEngineCaptureStatus;
|
|
616
682
|
capturedAudio: () => Float32Array[];
|
|
617
683
|
process: (channels: Float32Array[]) => Float32Array[];
|
|
684
|
+
prepareChannels: (numChannels: number, maxFrames: number) => void;
|
|
685
|
+
getChannelBuffer: (channel: number, numFrames: number) => Float32Array;
|
|
686
|
+
processPrepared: (numFrames: number) => void;
|
|
618
687
|
processWithMonitor: (channels: Float32Array[]) => WasmEngineProcessWithMonitorResult;
|
|
619
688
|
renderOffline: (channels: Float32Array[], blockSize: number) => Float32Array[];
|
|
620
689
|
bounceOffline: (options: WasmEngineBounceOptions) => WasmEngineBounceResult;
|
|
@@ -690,6 +759,19 @@ export interface SonareModule {
|
|
|
690
759
|
minDecayDb: number,
|
|
691
760
|
noiseFloorMarginDb: number,
|
|
692
761
|
) => WasmAcousticResult;
|
|
762
|
+
// Acoustic-simulation entry points are present only in builds compiled with
|
|
763
|
+
// SONARE_WITH_ACOUSTIC_SIM; absent otherwise (the wrappers throw a clear error).
|
|
764
|
+
synthesizeRir?: (options: WasmRirSynthOptions) => WasmRirResult;
|
|
765
|
+
estimateRoom?: (
|
|
766
|
+
samples: Float32Array,
|
|
767
|
+
sampleRate: number,
|
|
768
|
+
options: WasmRoomEstimateOptions,
|
|
769
|
+
) => WasmRoomEstimateResult;
|
|
770
|
+
roomMorph?: (
|
|
771
|
+
samples: Float32Array,
|
|
772
|
+
sampleRate: number,
|
|
773
|
+
options: WasmRoomMorphOptions,
|
|
774
|
+
) => Float32Array;
|
|
693
775
|
analyzeWithProgress: (
|
|
694
776
|
samples: Float32Array,
|
|
695
777
|
sampleRate: number,
|
|
@@ -1703,6 +1785,8 @@ export interface WasmAnalyzerStats {
|
|
|
1703
1785
|
|
|
1704
1786
|
export interface WasmFrameBuffer {
|
|
1705
1787
|
nFrames: number;
|
|
1788
|
+
/** Number of mel bands; flat `mel` is `[nFrames * nMels]` row-major. */
|
|
1789
|
+
nMels: number;
|
|
1706
1790
|
timestamps: Float32Array;
|
|
1707
1791
|
mel: Float32Array;
|
|
1708
1792
|
chroma: Float32Array;
|
package/src/stream_types.ts
CHANGED
|
@@ -72,6 +72,8 @@ export interface AnalyzerStats {
|
|
|
72
72
|
*/
|
|
73
73
|
export interface FrameBuffer {
|
|
74
74
|
nFrames: number;
|
|
75
|
+
/** Number of mel bands; flat `mel` is `[nFrames * nMels]` row-major. */
|
|
76
|
+
nMels: number;
|
|
75
77
|
timestamps: Float32Array;
|
|
76
78
|
mel: Float32Array;
|
|
77
79
|
chroma: Float32Array;
|
|
@@ -112,7 +114,8 @@ export interface StreamFramesI16 {
|
|
|
112
114
|
* Configuration for StreamAnalyzer
|
|
113
115
|
*/
|
|
114
116
|
export interface StreamConfig {
|
|
115
|
-
|
|
117
|
+
/** Sample rate in Hz. Optional for parity with the Node/Python bindings (default 44100). */
|
|
118
|
+
sampleRate?: number;
|
|
116
119
|
nFft?: number;
|
|
117
120
|
hopLength?: number;
|
|
118
121
|
nMels?: number;
|