@libraz/libsonare 1.5.0 → 1.5.2
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/README.md +1 -1
- package/dist/index.d.ts +108 -55
- package/dist/index.js +162 -27
- package/dist/index.js.map +1 -1
- package/dist/sonare.js +2 -2
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.js +8 -1
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/clip_page_streamer.ts +63 -15
- package/src/effects_voice_change.ts +7 -7
- package/src/feature_music.ts +110 -2
- package/src/features.ts +2 -0
- package/src/index.ts +15 -0
- package/src/mastering_core.ts +10 -0
- package/src/mixer.ts +9 -1
- package/src/project_class.ts +17 -7
- package/src/project_internal.ts +1 -0
- package/src/public_types_music.ts +1 -0
- package/src/public_types_realtime.ts +39 -39
- package/src/sonare.js.d.ts +70 -38
- package/src/stream_analyzer.ts +8 -1
- package/src/stream_types.ts +8 -0
package/dist/index.js
CHANGED
|
@@ -732,12 +732,19 @@ var Mixer = class _Mixer {
|
|
|
732
732
|
return this.mixer.toSceneJson();
|
|
733
733
|
}
|
|
734
734
|
/**
|
|
735
|
-
*
|
|
735
|
+
* Longest audible serial processor-tail path to the master, in samples. Lazily
|
|
736
736
|
* compiles the routing graph if the topology is dirty.
|
|
737
737
|
*/
|
|
738
738
|
tailSamples() {
|
|
739
739
|
return this.mixer.tailSamples();
|
|
740
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* Reported latency (samples) of the compiled mixer graph, for aligning
|
|
743
|
+
* dry/wet material. Lazily compiles the routing graph if the topology is dirty.
|
|
744
|
+
*/
|
|
745
|
+
latencySamples() {
|
|
746
|
+
return this.mixer.latencySamples();
|
|
747
|
+
}
|
|
741
748
|
/**
|
|
742
749
|
* Drain delayed / tail audio by processing a zero-input block of `numSamples`
|
|
743
750
|
* frames after the host stops feeding strip inputs. Returns the mixed stereo
|
|
@@ -1190,7 +1197,7 @@ function latencyCompensatedVoiceChange(changer, samples, channels, blockFrames)
|
|
|
1190
1197
|
const start = latencyFrames * 2;
|
|
1191
1198
|
return processed.slice(start, start + samples.length);
|
|
1192
1199
|
}
|
|
1193
|
-
function voiceChangeRealtime(samples, options = {}) {
|
|
1200
|
+
function voiceChangeRealtime(samples, sampleRate = 48e3, preset = "neutral-monitor", options = {}) {
|
|
1194
1201
|
assertSamples("voiceChangeRealtime", samples, options.validate !== false);
|
|
1195
1202
|
const channels = options.channels ?? 1;
|
|
1196
1203
|
if (channels !== 1 && channels !== 2) {
|
|
@@ -1199,9 +1206,8 @@ function voiceChangeRealtime(samples, options = {}) {
|
|
|
1199
1206
|
if (channels === 2 && samples.length % 2 !== 0) {
|
|
1200
1207
|
throw new Error("voiceChangeRealtime: stereo input length must be a multiple of 2.");
|
|
1201
1208
|
}
|
|
1202
|
-
const sampleRate = options.sampleRate ?? 48e3;
|
|
1203
1209
|
const blockSize = Math.max(1, Math.floor(options.blockSize ?? 512));
|
|
1204
|
-
const changer = new RealtimeVoiceChanger(
|
|
1210
|
+
const changer = new RealtimeVoiceChanger(preset);
|
|
1205
1211
|
try {
|
|
1206
1212
|
changer.prepare(sampleRate, blockSize, channels);
|
|
1207
1213
|
return latencyCompensatedVoiceChange(changer, samples, channels, blockSize);
|
|
@@ -1586,6 +1592,74 @@ function vqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257
|
|
|
1586
1592
|
}
|
|
1587
1593
|
return requireModule9().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);
|
|
1588
1594
|
}
|
|
1595
|
+
function validateCqtInverse(fnName, magnitude, nBins, nFrames, sampleRate, hopLength, fmin, binsPerOctave, nIter, options) {
|
|
1596
|
+
assertSampleRate(fnName, sampleRate);
|
|
1597
|
+
validatePositiveIntegers(fnName, { nBins, nFrames, hopLength, binsPerOctave, nIter });
|
|
1598
|
+
if (nIter > 256) {
|
|
1599
|
+
throw new RangeError(`${fnName}: nIter must be at most 256`);
|
|
1600
|
+
}
|
|
1601
|
+
validateFrequencyBounds(fnName, fmin);
|
|
1602
|
+
if (fmin === 0) {
|
|
1603
|
+
throw new RangeError(`${fnName}: fmin must be positive`);
|
|
1604
|
+
}
|
|
1605
|
+
if (magnitude.length !== nBins * nFrames) {
|
|
1606
|
+
throw new RangeError(`${fnName}: magnitude length must equal nBins * nFrames`);
|
|
1607
|
+
}
|
|
1608
|
+
assertSamples(fnName, magnitude, options.validate !== false);
|
|
1609
|
+
}
|
|
1610
|
+
function cqtToAudio(magnitude, nBins, nFrames, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, binsPerOctave = 12, nIter = 32, options = {}) {
|
|
1611
|
+
validateCqtInverse(
|
|
1612
|
+
"cqtToAudio",
|
|
1613
|
+
magnitude,
|
|
1614
|
+
nBins,
|
|
1615
|
+
nFrames,
|
|
1616
|
+
sampleRate,
|
|
1617
|
+
hopLength,
|
|
1618
|
+
fmin,
|
|
1619
|
+
binsPerOctave,
|
|
1620
|
+
nIter,
|
|
1621
|
+
options
|
|
1622
|
+
);
|
|
1623
|
+
return requireModule9().cqtToAudio(
|
|
1624
|
+
magnitude,
|
|
1625
|
+
nBins,
|
|
1626
|
+
nFrames,
|
|
1627
|
+
sampleRate,
|
|
1628
|
+
hopLength,
|
|
1629
|
+
fmin,
|
|
1630
|
+
binsPerOctave,
|
|
1631
|
+
nIter
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1634
|
+
function vqtToAudio(magnitude, nBins, nFrames, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, binsPerOctave = 12, gamma = 0, nIter = 32, options = {}) {
|
|
1635
|
+
validateCqtInverse(
|
|
1636
|
+
"vqtToAudio",
|
|
1637
|
+
magnitude,
|
|
1638
|
+
nBins,
|
|
1639
|
+
nFrames,
|
|
1640
|
+
sampleRate,
|
|
1641
|
+
hopLength,
|
|
1642
|
+
fmin,
|
|
1643
|
+
binsPerOctave,
|
|
1644
|
+
nIter,
|
|
1645
|
+
options
|
|
1646
|
+
);
|
|
1647
|
+
assertFiniteScalar("vqtToAudio", gamma, "gamma");
|
|
1648
|
+
if (gamma < 0) {
|
|
1649
|
+
throw new RangeError("vqtToAudio: gamma must be non-negative");
|
|
1650
|
+
}
|
|
1651
|
+
return requireModule9().vqtToAudio(
|
|
1652
|
+
magnitude,
|
|
1653
|
+
nBins,
|
|
1654
|
+
nFrames,
|
|
1655
|
+
sampleRate,
|
|
1656
|
+
hopLength,
|
|
1657
|
+
fmin,
|
|
1658
|
+
binsPerOctave,
|
|
1659
|
+
gamma,
|
|
1660
|
+
nIter
|
|
1661
|
+
);
|
|
1662
|
+
}
|
|
1589
1663
|
function analyzeSections(samples, sampleRate = 22050, options = {}) {
|
|
1590
1664
|
validateMusicSamples("analyzeSections", samples, sampleRate, options);
|
|
1591
1665
|
validatePositiveIntegers("analyzeSections", {
|
|
@@ -1650,11 +1724,11 @@ function fourierTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, w
|
|
|
1650
1724
|
validatePositiveIntegers("fourierTempogram", { hopLength, winLength });
|
|
1651
1725
|
return requireModule9().fourierTempogram(onsetEnvelope2, sampleRate, hopLength, winLength);
|
|
1652
1726
|
}
|
|
1653
|
-
function tempogramRatio(tempogramData, winLength = 384, sampleRate = 22050, hopLength = 512, options = {}) {
|
|
1727
|
+
function tempogramRatio(tempogramData, winLength = 384, sampleRate = 22050, hopLength = 512, factors, options = {}) {
|
|
1654
1728
|
assertSampleRate("tempogramRatio", sampleRate);
|
|
1655
1729
|
assertSamples("tempogramRatio", tempogramData, options.validate !== false, "tempogramData");
|
|
1656
1730
|
validatePositiveIntegers("tempogramRatio", { winLength, hopLength });
|
|
1657
|
-
return requireModule9().tempogramRatio(tempogramData, winLength, sampleRate, hopLength);
|
|
1731
|
+
return requireModule9().tempogramRatio(tempogramData, winLength, sampleRate, hopLength, factors);
|
|
1658
1732
|
}
|
|
1659
1733
|
function lufs(samples, sampleRate = 22050, options = {}) {
|
|
1660
1734
|
assertSampleRate("lufs", sampleRate);
|
|
@@ -2836,16 +2910,37 @@ var ClipPageStreamer = class {
|
|
|
2836
2910
|
throw new Error("pageFrames and numSamples must be positive");
|
|
2837
2911
|
}
|
|
2838
2912
|
const lastPage = Math.ceil(source.numSamples / source.pageFrames) - 1;
|
|
2913
|
+
const previous = this.sources.get(source.clipId);
|
|
2914
|
+
if (previous) {
|
|
2915
|
+
this.resetState(previous);
|
|
2916
|
+
}
|
|
2839
2917
|
this.sources.set(source.clipId, {
|
|
2840
2918
|
source,
|
|
2841
2919
|
lastPage,
|
|
2842
|
-
|
|
2920
|
+
generation: 0,
|
|
2921
|
+
lastFrontier: null,
|
|
2922
|
+
resident: new Map(Array.from(initialResidentPages, (page) => [page, 0]))
|
|
2843
2923
|
});
|
|
2844
2924
|
}
|
|
2845
2925
|
/** Stop tracking a clip. Does not close its binding (the caller owns that). */
|
|
2846
2926
|
removeSource(clipId) {
|
|
2927
|
+
const state = this.sources.get(clipId);
|
|
2928
|
+
if (state) {
|
|
2929
|
+
this.resetState(state);
|
|
2930
|
+
}
|
|
2847
2931
|
this.sources.delete(clipId);
|
|
2848
2932
|
}
|
|
2933
|
+
/**
|
|
2934
|
+
* Explicitly start a new playback generation after a host seek/loop. Resident
|
|
2935
|
+
* pages are evicted and any older in-flight fetch is cleared when it settles.
|
|
2936
|
+
* The next miss establishes the new bounded window.
|
|
2937
|
+
*/
|
|
2938
|
+
resetSource(clipId) {
|
|
2939
|
+
const state = this.sources.get(clipId);
|
|
2940
|
+
if (state) {
|
|
2941
|
+
this.resetState(state);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2849
2944
|
/**
|
|
2850
2945
|
* Drain pending page-miss requests, fetch the missing pages plus their
|
|
2851
2946
|
* read-ahead window, and evict out-of-window pages. Resolves once this round's
|
|
@@ -2866,10 +2961,7 @@ var ClipPageStreamer = class {
|
|
|
2866
2961
|
continue;
|
|
2867
2962
|
}
|
|
2868
2963
|
const page = Math.floor(request.sample / state.source.pageFrames);
|
|
2869
|
-
|
|
2870
|
-
if (previous === void 0 || page > previous) {
|
|
2871
|
-
frontiers.set(request.clipId, page);
|
|
2872
|
-
}
|
|
2964
|
+
frontiers.set(request.clipId, page);
|
|
2873
2965
|
}
|
|
2874
2966
|
const fetches = [];
|
|
2875
2967
|
for (const [clipId, frontier] of frontiers) {
|
|
@@ -2888,14 +2980,20 @@ var ClipPageStreamer = class {
|
|
|
2888
2980
|
}
|
|
2889
2981
|
this.closed = true;
|
|
2890
2982
|
for (const state of this.sources.values()) {
|
|
2983
|
+
this.resetState(state);
|
|
2891
2984
|
state.source.binding.close();
|
|
2892
2985
|
}
|
|
2893
2986
|
this.sources.clear();
|
|
2894
2987
|
}
|
|
2895
2988
|
serviceFrontier(state, frontier) {
|
|
2989
|
+
if (state.lastFrontier !== null && frontier < state.lastFrontier) {
|
|
2990
|
+
this.resetState(state);
|
|
2991
|
+
}
|
|
2992
|
+
state.lastFrontier = frontier;
|
|
2993
|
+
const generation = state.generation;
|
|
2896
2994
|
const low = Math.max(0, frontier - this.retainBehindPages);
|
|
2897
2995
|
const high = Math.min(state.lastPage, frontier + this.readAheadPages);
|
|
2898
|
-
for (const page of state.resident) {
|
|
2996
|
+
for (const page of state.resident.keys()) {
|
|
2899
2997
|
if (page < low || page > high) {
|
|
2900
2998
|
state.source.binding.provider.clear(page);
|
|
2901
2999
|
state.resident.delete(page);
|
|
@@ -2903,21 +3001,25 @@ var ClipPageStreamer = class {
|
|
|
2903
3001
|
}
|
|
2904
3002
|
const fetches = [];
|
|
2905
3003
|
for (let page = low; page <= high; ++page) {
|
|
2906
|
-
if (state.resident.
|
|
3004
|
+
if (state.resident.get(page) === generation) {
|
|
2907
3005
|
continue;
|
|
2908
3006
|
}
|
|
2909
|
-
state.resident.
|
|
3007
|
+
state.resident.set(page, generation);
|
|
2910
3008
|
const pageIndex = page;
|
|
2911
3009
|
fetches.push(
|
|
2912
3010
|
state.source.binding.supplyPage(pageIndex).then(
|
|
2913
3011
|
(ok) => {
|
|
2914
|
-
if (
|
|
3012
|
+
if (state.generation !== generation) {
|
|
3013
|
+
state.source.binding.provider.clear(pageIndex);
|
|
3014
|
+
} else if (!ok && state.resident.get(pageIndex) === generation) {
|
|
2915
3015
|
state.resident.delete(pageIndex);
|
|
2916
3016
|
}
|
|
2917
3017
|
return ok;
|
|
2918
3018
|
},
|
|
2919
3019
|
(error) => {
|
|
2920
|
-
state.resident.
|
|
3020
|
+
if (state.resident.get(pageIndex) === generation) {
|
|
3021
|
+
state.resident.delete(pageIndex);
|
|
3022
|
+
}
|
|
2921
3023
|
throw error;
|
|
2922
3024
|
}
|
|
2923
3025
|
)
|
|
@@ -2925,6 +3027,14 @@ var ClipPageStreamer = class {
|
|
|
2925
3027
|
}
|
|
2926
3028
|
return fetches;
|
|
2927
3029
|
}
|
|
3030
|
+
resetState(state) {
|
|
3031
|
+
state.generation += 1;
|
|
3032
|
+
state.lastFrontier = null;
|
|
3033
|
+
for (const page of state.resident.keys()) {
|
|
3034
|
+
state.source.binding.provider.clear(page);
|
|
3035
|
+
}
|
|
3036
|
+
state.resident.clear();
|
|
3037
|
+
}
|
|
2928
3038
|
};
|
|
2929
3039
|
async function attachOpfsClipStream(streamer, engine, options) {
|
|
2930
3040
|
const { clipId, primePages = 1, ...providerOptions } = options;
|
|
@@ -3532,8 +3642,10 @@ var Project = class _Project {
|
|
|
3532
3642
|
* built-in oscillator synth so a MIDI-only arrangement bounces to audible
|
|
3533
3643
|
* audio. Pass a {@link BuiltinSynthBinding} (or an array of them) to choose
|
|
3534
3644
|
* the patch and MIDI destination; omit it (or pass `{}`) for one
|
|
3535
|
-
* default-destination sine patch.
|
|
3536
|
-
*
|
|
3645
|
+
* default-destination sine patch. Because the parameter defaults to `{}`,
|
|
3646
|
+
* omission and explicit `undefined` both create that one default binding.
|
|
3647
|
+
* Use an explicitly empty array `[]` (or runtime `null`) for zero bindings,
|
|
3648
|
+
* so MIDI tracks render silently.
|
|
3537
3649
|
*
|
|
3538
3650
|
* Like {@link bounce}, omitting `totalFrames` auto-derives the render length
|
|
3539
3651
|
* from the arrangement plus the synth's release tail.
|
|
@@ -3558,9 +3670,10 @@ var Project = class _Project {
|
|
|
3558
3670
|
* string (`'saw-lead'` / `'va:saw-lead'`; see {@link synthPresetNames}), or
|
|
3559
3671
|
* an array of either; each object entry may carry a `destinationId` binding
|
|
3560
3672
|
* convenience (default 0), which is not part of the NativeSynth patch itself.
|
|
3561
|
-
*
|
|
3562
|
-
*
|
|
3563
|
-
*
|
|
3673
|
+
* Because the parameter defaults to `{}`, omission and explicit `undefined`
|
|
3674
|
+
* both create one default binding. Use an explicitly empty array `[]` (or
|
|
3675
|
+
* runtime `null`) for zero bindings. Unknown preset names throw.
|
|
3676
|
+
* Deterministic for a fixed project + options + patch.
|
|
3564
3677
|
*/
|
|
3565
3678
|
bounceWithSynthInstrument(instrument = {}, options = {}) {
|
|
3566
3679
|
return this.native.bounceWithSynthInstrument(instrument, options);
|
|
@@ -3602,8 +3715,10 @@ var Project = class _Project {
|
|
|
3602
3715
|
* honored. Programs the SoundFont does not cover — including bouncing with
|
|
3603
3716
|
* no SoundFont loaded at all — play through the built-in synthesizer GM
|
|
3604
3717
|
* fallback bank (the data-free floor; see {@link soundFontManifest} for the
|
|
3605
|
-
* per-program backend).
|
|
3606
|
-
* `
|
|
3718
|
+
* per-program backend). Because the parameter defaults to `{}`, omission and
|
|
3719
|
+
* explicit `undefined` both create one default binding. Use an explicitly
|
|
3720
|
+
* empty array `[]` (or runtime `null`) for zero bindings, so MIDI tracks
|
|
3721
|
+
* render silently.
|
|
3607
3722
|
*/
|
|
3608
3723
|
bounceWithSf2Instrument(instrument = {}, options = {}) {
|
|
3609
3724
|
return this.native.bounceWithSf2Instrument(instrument, options);
|
|
@@ -3749,6 +3864,10 @@ var Project = class _Project {
|
|
|
3749
3864
|
trackCount() {
|
|
3750
3865
|
return this.native.trackCount();
|
|
3751
3866
|
}
|
|
3867
|
+
/** Number of clips in the project. */
|
|
3868
|
+
clipCount() {
|
|
3869
|
+
return this.native.clipCount();
|
|
3870
|
+
}
|
|
3752
3871
|
/** Number of audio sources registered on the project. */
|
|
3753
3872
|
sourceCount() {
|
|
3754
3873
|
return this.native.sourceCount();
|
|
@@ -3875,14 +3994,14 @@ var SYNTH_MOD_DESTINATIONS = [
|
|
|
3875
3994
|
// src/realtime_engine.ts
|
|
3876
3995
|
var EXPECTED_ENGINE_ABI_VERSION = 3;
|
|
3877
3996
|
function engineCapabilities() {
|
|
3878
|
-
const
|
|
3997
|
+
const abiVersion2 = getSonareModule().engineAbiVersion();
|
|
3879
3998
|
const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === "function";
|
|
3880
3999
|
const atomics = typeof globalThis.Atomics === "object";
|
|
3881
4000
|
const audioWorklet = typeof AudioWorkletNode !== "undefined" || typeof globalThis.AudioWorkletProcessor !== "undefined";
|
|
3882
4001
|
return {
|
|
3883
|
-
engineAbiVersion:
|
|
4002
|
+
engineAbiVersion: abiVersion2,
|
|
3884
4003
|
expectedEngineAbiVersion: EXPECTED_ENGINE_ABI_VERSION,
|
|
3885
|
-
abiCompatible:
|
|
4004
|
+
abiCompatible: abiVersion2 === EXPECTED_ENGINE_ABI_VERSION,
|
|
3886
4005
|
sharedArrayBuffer,
|
|
3887
4006
|
atomics,
|
|
3888
4007
|
audioWorklet,
|
|
@@ -4528,6 +4647,8 @@ var StreamAnalyzer = class {
|
|
|
4528
4647
|
config.computeSpectral ?? defaults.computeSpectral,
|
|
4529
4648
|
config.emitEveryNFrames ?? defaults.emitEveryNFrames,
|
|
4530
4649
|
config.magnitudeDownsample ?? defaults.magnitudeDownsample,
|
|
4650
|
+
config.maxPendingFrames ?? defaults.maxPendingFrames,
|
|
4651
|
+
config.maxProgressionEntries ?? defaults.maxProgressionEntries,
|
|
4531
4652
|
config.keyUpdateIntervalSec ?? defaults.keyUpdateIntervalSec,
|
|
4532
4653
|
config.bpmUpdateIntervalSec ?? defaults.bpmUpdateIntervalSec,
|
|
4533
4654
|
config.window ?? defaults.window,
|
|
@@ -4543,7 +4664,8 @@ var StreamAnalyzer = class {
|
|
|
4543
4664
|
this.analyzer.process(samples);
|
|
4544
4665
|
}
|
|
4545
4666
|
/**
|
|
4546
|
-
* Process audio samples with explicit sample offset.
|
|
4667
|
+
* Process audio samples with a contiguous explicit sample offset. A gap,
|
|
4668
|
+
* seek, or switch from `process()` requires `reset()` first.
|
|
4547
4669
|
*
|
|
4548
4670
|
* @param samples - Audio samples (mono, float32)
|
|
4549
4671
|
* @param sampleOffset - Cumulative sample count at start of this chunk
|
|
@@ -4611,6 +4733,10 @@ var StreamAnalyzer = class {
|
|
|
4611
4733
|
totalFrames: s.totalFrames,
|
|
4612
4734
|
totalSamples: s.totalSamples,
|
|
4613
4735
|
durationSeconds: s.durationSeconds,
|
|
4736
|
+
pendingFrames: s.pendingFrames,
|
|
4737
|
+
droppedOutputFrames: s.droppedOutputFrames,
|
|
4738
|
+
droppedChordProgressionEntries: s.droppedChordProgressionEntries,
|
|
4739
|
+
droppedBarProgressionEntries: s.droppedBarProgressionEntries,
|
|
4614
4740
|
estimate: {
|
|
4615
4741
|
bpm: s.estimate.bpm,
|
|
4616
4742
|
bpmConfidence: s.estimate.bpmConfidence,
|
|
@@ -4972,6 +5098,12 @@ function version() {
|
|
|
4972
5098
|
}
|
|
4973
5099
|
return module.version();
|
|
4974
5100
|
}
|
|
5101
|
+
function abiVersion() {
|
|
5102
|
+
if (!module) {
|
|
5103
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
5104
|
+
}
|
|
5105
|
+
return module.abiVersion();
|
|
5106
|
+
}
|
|
4975
5107
|
function engineAbiVersion() {
|
|
4976
5108
|
if (!module) {
|
|
4977
5109
|
throw new Error("Module not initialized. Call init() first.");
|
|
@@ -5043,6 +5175,7 @@ export {
|
|
|
5043
5175
|
StreamingEqualizer,
|
|
5044
5176
|
StreamingMasteringChain,
|
|
5045
5177
|
StreamingRetune,
|
|
5178
|
+
abiVersion,
|
|
5046
5179
|
amplitudeToDb,
|
|
5047
5180
|
analyze,
|
|
5048
5181
|
analyzeBpm,
|
|
@@ -5062,6 +5195,7 @@ export {
|
|
|
5062
5195
|
chromaCens,
|
|
5063
5196
|
chromaCqt,
|
|
5064
5197
|
cqt,
|
|
5198
|
+
cqtToAudio,
|
|
5065
5199
|
createOpfsClipPageProvider,
|
|
5066
5200
|
createOpfsClipPageWorker,
|
|
5067
5201
|
cyclicTempogram,
|
|
@@ -5233,6 +5367,7 @@ export {
|
|
|
5233
5367
|
voiceChangerAbiVersion,
|
|
5234
5368
|
voiceCharacterPresetId,
|
|
5235
5369
|
vqt,
|
|
5370
|
+
vqtToAudio,
|
|
5236
5371
|
waveformPeakPyramid,
|
|
5237
5372
|
waveformPeaks,
|
|
5238
5373
|
zeroCrossingRate,
|