@libraz/libsonare 1.3.2 → 1.4.0
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 +45 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +403 -70
- package/dist/index.js.map +1 -1
- package/dist/sonare-rt-module.js +2 -2
- package/dist/sonare-rt.js +2 -2
- package/dist/sonare-rt.wasm +0 -0
- package/dist/sonare.js +2 -2
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +907 -144
- package/dist/worklet.js +1803 -207
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/codes.ts +6 -1
- package/src/effects_mastering.ts +103 -1
- package/src/feature_music.ts +18 -4
- package/src/feature_spectral.ts +7 -1
- package/src/index.ts +27 -1
- package/src/mixer.ts +9 -0
- package/src/module_state.ts +82 -17
- package/src/opfs_clip_pages.ts +43 -9
- package/src/project.ts +74 -0
- package/src/public_types.ts +52 -0
- package/src/realtime_engine.ts +313 -109
- package/src/sonare.js.d.ts +140 -0
- package/src/stream_types.ts +7 -0
- package/src/validation.ts +7 -0
- package/src/web_midi.ts +15 -11
- package/src/worklet/audio_types.ts +2 -0
- package/src/worklet/guards.ts +146 -0
- package/src/worklet/messages.ts +461 -0
- package/src/worklet/protocol.ts +767 -0
- package/src/worklet.ts +1659 -888
package/src/sonare.js.d.ts
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
* Type declarations for the Emscripten-generated WASM module with embind
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { SpectralRegionOp, SurroundPan } from './public_types';
|
|
6
|
+
|
|
5
7
|
export interface SonareModuleOptions {
|
|
6
8
|
locateFile?: (path: string, prefix: string) => string;
|
|
9
|
+
wasmBinary?: ArrayBuffer | Uint8Array;
|
|
7
10
|
onRuntimeInitialized?: () => void;
|
|
8
11
|
print?: (text: string) => void;
|
|
9
12
|
printErr?: (text: string) => void;
|
|
@@ -518,6 +521,7 @@ export interface WasmMixResult {
|
|
|
518
521
|
|
|
519
522
|
export interface WasmEngineClip {
|
|
520
523
|
id?: number;
|
|
524
|
+
trackId?: number;
|
|
521
525
|
channels?: Float32Array[];
|
|
522
526
|
startPpq: number;
|
|
523
527
|
lengthSamples?: number;
|
|
@@ -531,6 +535,33 @@ export interface WasmEngineClip {
|
|
|
531
535
|
pageProvider?: number | { readonly id: number };
|
|
532
536
|
}
|
|
533
537
|
|
|
538
|
+
export interface WasmEngineTrackSend {
|
|
539
|
+
busId: number;
|
|
540
|
+
levelDb?: number;
|
|
541
|
+
enabled?: boolean;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export interface WasmEngineTrackLane {
|
|
545
|
+
trackId: number;
|
|
546
|
+
sends?: WasmEngineTrackSend[];
|
|
547
|
+
/**
|
|
548
|
+
* Bus the lane's post-fader output sums into instead of the master mix
|
|
549
|
+
* (group/folder routing); 0 or absent keeps the lane on the master mix.
|
|
550
|
+
*/
|
|
551
|
+
outputBusId?: number;
|
|
552
|
+
/**
|
|
553
|
+
* Input channel layout of the source feeding this lane (`SonareChannelLayout`:
|
|
554
|
+
* 0 mono, 1 stereo, 2 5.1, 3 7.1). Absent defaults to stereo.
|
|
555
|
+
*/
|
|
556
|
+
sourceChannelLayout?: number;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export interface WasmEngineBus {
|
|
560
|
+
busId: number;
|
|
561
|
+
gainDb?: number;
|
|
562
|
+
channelLayout?: number;
|
|
563
|
+
}
|
|
564
|
+
|
|
534
565
|
export interface WasmClipPageRequest {
|
|
535
566
|
clipId: number;
|
|
536
567
|
channel: number;
|
|
@@ -558,6 +589,18 @@ export interface WasmEngineMarker {
|
|
|
558
589
|
id: number;
|
|
559
590
|
ppq: number;
|
|
560
591
|
name?: string;
|
|
592
|
+
kind?: number;
|
|
593
|
+
keyFifths?: number;
|
|
594
|
+
keyMinor?: boolean;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export interface WasmProjectMarker {
|
|
598
|
+
id: number;
|
|
599
|
+
ppq: number;
|
|
600
|
+
name?: string;
|
|
601
|
+
kind?: number;
|
|
602
|
+
keyFifths?: number;
|
|
603
|
+
keyMinor?: boolean;
|
|
561
604
|
}
|
|
562
605
|
|
|
563
606
|
export interface WasmEngineMetronomeConfig {
|
|
@@ -628,6 +671,38 @@ export interface WasmEngineMeterTelemetry {
|
|
|
628
671
|
droppedRecords: number;
|
|
629
672
|
}
|
|
630
673
|
|
|
674
|
+
export interface WasmEngineMeterTelemetryWide {
|
|
675
|
+
targetId: number;
|
|
676
|
+
renderFrame: number;
|
|
677
|
+
seq: number;
|
|
678
|
+
channelCount: number;
|
|
679
|
+
peakDb: number[];
|
|
680
|
+
rmsDb: number[];
|
|
681
|
+
truePeakDb: number[];
|
|
682
|
+
maxTruePeakDb: number;
|
|
683
|
+
correlation: number;
|
|
684
|
+
monoCompatWidth: number;
|
|
685
|
+
momentaryLufs: number;
|
|
686
|
+
shortTermLufs: number;
|
|
687
|
+
integratedLufs: number;
|
|
688
|
+
gainReductionDb: number;
|
|
689
|
+
droppedRecords: number;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export interface WasmEngineScopeTelemetry {
|
|
693
|
+
targetId: number;
|
|
694
|
+
renderFrame: number;
|
|
695
|
+
seq: number;
|
|
696
|
+
droppedRecords: number;
|
|
697
|
+
bands: number[];
|
|
698
|
+
/**
|
|
699
|
+
* Goniometer/vectorscope sample points as `{ left, right }` objects. The
|
|
700
|
+
* Python surface exposes the same data as `(left, right)` tuples; this
|
|
701
|
+
* representation difference is intentional, the values match.
|
|
702
|
+
*/
|
|
703
|
+
points: { left: number; right: number }[];
|
|
704
|
+
}
|
|
705
|
+
|
|
631
706
|
export interface WasmEngineCaptureStatus {
|
|
632
707
|
capturedFrames: number;
|
|
633
708
|
overflowCount: number;
|
|
@@ -696,6 +771,18 @@ export interface WasmEngineProcessWithMonitorResult {
|
|
|
696
771
|
monitor: Float32Array[];
|
|
697
772
|
}
|
|
698
773
|
|
|
774
|
+
export interface WasmEngineTempoSegment {
|
|
775
|
+
startPpq: number;
|
|
776
|
+
bpm: number;
|
|
777
|
+
endBpm?: number;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
export interface WasmEngineTimeSignatureSegment {
|
|
781
|
+
startPpq: number;
|
|
782
|
+
numerator: number;
|
|
783
|
+
denominator: number;
|
|
784
|
+
}
|
|
785
|
+
|
|
699
786
|
export interface WasmRealtimeEngine {
|
|
700
787
|
prepare: (
|
|
701
788
|
sampleRate: number,
|
|
@@ -705,13 +792,18 @@ export interface WasmRealtimeEngine {
|
|
|
705
792
|
) => void;
|
|
706
793
|
setParameter: (paramId: number, value: number, renderFrame: number) => void;
|
|
707
794
|
setParameterSmoothed: (paramId: number, value: number, renderFrame: number) => void;
|
|
795
|
+
setSoloMute: (laneIndex: number, solo: boolean, mute: boolean, renderFrame: number) => void;
|
|
708
796
|
getTransportState: () => WasmEngineTransportState;
|
|
709
797
|
play: (renderFrame: number) => void;
|
|
710
798
|
stop: (renderFrame: number) => void;
|
|
711
799
|
seekSample: (timelineSample: number, renderFrame: number) => void;
|
|
800
|
+
settleParameters: () => void;
|
|
712
801
|
seekPpq: (ppq: number, renderFrame: number) => void;
|
|
713
802
|
setTempo: (bpm: number) => void;
|
|
803
|
+
setTempoSegments: (segments: WasmEngineTempoSegment[]) => void;
|
|
714
804
|
setTimeSignature: (numerator: number, denominator: number) => void;
|
|
805
|
+
setTimeSignatureSegments: (segments: WasmEngineTimeSignatureSegment[]) => void;
|
|
806
|
+
sampleAtPpq: (ppq: number) => number;
|
|
715
807
|
setLoop: (startPpq: number, endPpq: number, enabled: boolean) => void;
|
|
716
808
|
addParameter: (info: WasmEngineParameterInfo) => void;
|
|
717
809
|
parameterCount: () => number;
|
|
@@ -733,6 +825,37 @@ export interface WasmRealtimeEngine {
|
|
|
733
825
|
graphConnectionCount: () => number;
|
|
734
826
|
setClips: (clips: WasmEngineClip[]) => void;
|
|
735
827
|
clipCount: () => number;
|
|
828
|
+
setTrackLanes: (lanes: Array<number | WasmEngineTrackLane>) => void;
|
|
829
|
+
setLaneSidechain: (trackId: number, insertIndex: number, sourceTrackId: number) => void;
|
|
830
|
+
setTrackBuses: (buses: WasmEngineBus[]) => void;
|
|
831
|
+
setBusStripJson: (busId: number, sceneJson: string) => void;
|
|
832
|
+
setTrackStripJson: (trackId: number, sceneJson: string) => void;
|
|
833
|
+
setTrackStripEqBandJson: (trackId: number, bandIndex: number, bandJson: string) => void;
|
|
834
|
+
setTrackStripInsertBypassed: (
|
|
835
|
+
trackId: number,
|
|
836
|
+
insertIndex: number,
|
|
837
|
+
bypassed: boolean,
|
|
838
|
+
resetOnBypass: boolean,
|
|
839
|
+
) => void;
|
|
840
|
+
setMasterStripJson: (sceneJson: string) => void;
|
|
841
|
+
setMasterStripEqBandJson: (bandIndex: number, bandJson: string) => void;
|
|
842
|
+
setMasterStripInsertBypassed: (
|
|
843
|
+
insertIndex: number,
|
|
844
|
+
bypassed: boolean,
|
|
845
|
+
resetOnBypass: boolean,
|
|
846
|
+
) => void;
|
|
847
|
+
setTrackStripInsertParamByName: (
|
|
848
|
+
trackId: number,
|
|
849
|
+
insertIndex: number,
|
|
850
|
+
paramName: string,
|
|
851
|
+
value: number,
|
|
852
|
+
) => void;
|
|
853
|
+
setMasterStripInsertParamByName: (insertIndex: number, paramName: string, value: number) => void;
|
|
854
|
+
setTrackStripPan: (trackId: number, pan: number) => void;
|
|
855
|
+
setTrackStripPanLaw: (trackId: number, panLaw: number) => void;
|
|
856
|
+
setTrackStripPanMode: (trackId: number, panMode: number) => void;
|
|
857
|
+
setTrackStripDualPan: (trackId: number, leftPan: number, rightPan: number) => void;
|
|
858
|
+
setTrackStripChannelDelaySamples: (trackId: number, delaySamples: number) => void;
|
|
736
859
|
createClipPageProvider: (numChannels: number, numSamples: number, pageFrames: number) => number;
|
|
737
860
|
supplyClipPage: (providerId: number, pageIndex: number, channels: Float32Array[]) => void;
|
|
738
861
|
clearClipPage: (providerId: number, pageIndex: number) => void;
|
|
@@ -747,7 +870,11 @@ export interface WasmRealtimeEngine {
|
|
|
747
870
|
resetCapture: () => void;
|
|
748
871
|
captureStatus: () => WasmEngineCaptureStatus;
|
|
749
872
|
capturedAudio: () => Float32Array[];
|
|
873
|
+
setMidiClips: (clips: readonly object[]) => void;
|
|
750
874
|
setBuiltinInstrument: (destinationId: number, config: object) => void;
|
|
875
|
+
setSynthInstrument: (destinationId: number, patch: object | string) => void;
|
|
876
|
+
loadSoundFont: (data: Uint8Array) => void;
|
|
877
|
+
setSf2Instrument: (destinationId: number, config: object) => void;
|
|
751
878
|
clearMidiInstrument: (destinationId: number) => void;
|
|
752
879
|
midiInstrumentCount: () => number;
|
|
753
880
|
bindMidiCc: (
|
|
@@ -759,6 +886,8 @@ export interface WasmRealtimeEngine {
|
|
|
759
886
|
) => void;
|
|
760
887
|
clearMidiCcBindings: () => void;
|
|
761
888
|
midiCcBindingCount: () => number;
|
|
889
|
+
setMidiFx: (destinationId: number, configJson: string) => void;
|
|
890
|
+
clearMidiFx: (destinationId: number) => void;
|
|
762
891
|
setMidiInputSource: (destinationId: number) => void;
|
|
763
892
|
clearMidiInputSource: () => void;
|
|
764
893
|
midiInputPendingCount: () => number;
|
|
@@ -808,6 +937,7 @@ export interface WasmRealtimeEngine {
|
|
|
808
937
|
renderFrame: number,
|
|
809
938
|
) => void;
|
|
810
939
|
pushMidiPanic: (renderFrame: number) => void;
|
|
940
|
+
clearParameters: () => void;
|
|
811
941
|
process: (channels: Float32Array[]) => Float32Array[];
|
|
812
942
|
prepareChannels: (numChannels: number, maxFrames: number) => void;
|
|
813
943
|
getChannelBuffer: (channel: number, numFrames: number) => Float32Array;
|
|
@@ -818,6 +948,9 @@ export interface WasmRealtimeEngine {
|
|
|
818
948
|
freezeOffline: (options: WasmEngineFreezeOptions) => WasmEngineFreezeResult;
|
|
819
949
|
drainTelemetry: (maxRecords: number) => WasmEngineTelemetry[];
|
|
820
950
|
drainMeterTelemetry: (maxRecords: number) => WasmEngineMeterTelemetry[];
|
|
951
|
+
drainMeterTelemetryWide: (maxRecords: number) => WasmEngineMeterTelemetryWide[];
|
|
952
|
+
configureScopeTelemetry: (intervalFrames: number, bandCount: number) => number;
|
|
953
|
+
drainScopeTelemetry: (maxRecords: number) => WasmEngineScopeTelemetry[];
|
|
821
954
|
delete: () => void;
|
|
822
955
|
}
|
|
823
956
|
|
|
@@ -1390,6 +1523,12 @@ export interface SonareModule {
|
|
|
1390
1523
|
options: Record<string, unknown>,
|
|
1391
1524
|
) => WasmMixResult;
|
|
1392
1525
|
trim: (samples: Float32Array, sampleRate: number, thresholdDb: number) => Float32Array;
|
|
1526
|
+
spectralEdit: (
|
|
1527
|
+
samples: Float32Array,
|
|
1528
|
+
sampleRate: number,
|
|
1529
|
+
ops: SpectralRegionOp[],
|
|
1530
|
+
options: Record<string, unknown>,
|
|
1531
|
+
) => Float32Array;
|
|
1393
1532
|
|
|
1394
1533
|
// Features - Spectrogram
|
|
1395
1534
|
stft: (
|
|
@@ -1974,6 +2113,7 @@ export interface WasmMixer {
|
|
|
1974
2113
|
setChannelDelaySamples: (stripIndex: number, delaySamples: number) => void;
|
|
1975
2114
|
setVcaOffsetDb: (stripIndex: number, offsetDb: number) => void;
|
|
1976
2115
|
setDualPan: (stripIndex: number, leftPan: number, rightPan: number) => void;
|
|
2116
|
+
setSurroundPan: (stripIndex: number, pan: SurroundPan) => void;
|
|
1977
2117
|
addSend: (
|
|
1978
2118
|
stripIndex: number,
|
|
1979
2119
|
id: string,
|
package/src/stream_types.ts
CHANGED
|
@@ -75,6 +75,11 @@ export interface FrameBuffer {
|
|
|
75
75
|
/** Number of mel bands; flat `mel` is `[nFrames * nMels]` row-major. */
|
|
76
76
|
nMels: number;
|
|
77
77
|
timestamps: Float32Array;
|
|
78
|
+
/**
|
|
79
|
+
* Mel spectrogram in LINEAR power (not dB) — the raw per-frame mel energies.
|
|
80
|
+
* The quantized read paths (`readFramesU8` / `readFramesI16`) convert to dB
|
|
81
|
+
* before packing, so their `mel` is dB-scaled; this float buffer is not.
|
|
82
|
+
*/
|
|
78
83
|
mel: Float32Array;
|
|
79
84
|
chroma: Float32Array;
|
|
80
85
|
onsetStrength: Float32Array;
|
|
@@ -109,6 +114,7 @@ export interface StreamFramesU8 {
|
|
|
109
114
|
nFrames: number;
|
|
110
115
|
nMels: number;
|
|
111
116
|
timestamps: Float32Array;
|
|
117
|
+
/** Row-major `[nFrames * nMels]` mel in dB, quantized over `[melDbMin, melDbMax]`. */
|
|
112
118
|
mel: Uint8Array;
|
|
113
119
|
chroma: Uint8Array;
|
|
114
120
|
onsetStrength: Uint8Array;
|
|
@@ -121,6 +127,7 @@ export interface StreamFramesI16 {
|
|
|
121
127
|
nFrames: number;
|
|
122
128
|
nMels: number;
|
|
123
129
|
timestamps: Float32Array;
|
|
130
|
+
/** Row-major `[nFrames * nMels]` mel in dB, quantized over `[melDbMin, melDbMax]`. */
|
|
124
131
|
mel: Int16Array;
|
|
125
132
|
chroma: Int16Array;
|
|
126
133
|
onsetStrength: Int16Array;
|
package/src/validation.ts
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
* Per-call validation options accepted by guarded wrappers. Empty-buffer
|
|
3
3
|
* checks are always performed; pass `{ validate: false }` to opt out of the
|
|
4
4
|
* O(n) NaN/Inf scan on hot paths.
|
|
5
|
+
*
|
|
6
|
+
* `{ validate: false }` only skips this JS-side pre-scan (which raises a
|
|
7
|
+
* `RangeError` naming the exact offending index). It is NOT a way to push
|
|
8
|
+
* non-finite samples into the core: the native layer always re-validates the
|
|
9
|
+
* buffer (see `validate_offline_audio_input` in the C++ core), matching the C
|
|
10
|
+
* ABI / Node / Python surfaces, so an NaN/Inf buffer still throws — just with a
|
|
11
|
+
* generic native message instead of the indexed JS one.
|
|
5
12
|
*/
|
|
6
13
|
export interface ValidateOptions {
|
|
7
14
|
validate?: boolean;
|
package/src/web_midi.ts
CHANGED
|
@@ -93,6 +93,7 @@ export interface WebMidiBinding {
|
|
|
93
93
|
type BoundInput = {
|
|
94
94
|
input: MidiInputLike;
|
|
95
95
|
listener: (event: MidiMessageEventLike) => void;
|
|
96
|
+
runningStatus: number;
|
|
96
97
|
};
|
|
97
98
|
|
|
98
99
|
export function isWebMidiAvailable(): boolean {
|
|
@@ -128,7 +129,6 @@ export async function bindWebMidi(
|
|
|
128
129
|
|
|
129
130
|
const bound = new Map<string, BoundInput>();
|
|
130
131
|
let closed = false;
|
|
131
|
-
let runningStatus = 0;
|
|
132
132
|
|
|
133
133
|
const shouldBind = (input: MidiInputLike) =>
|
|
134
134
|
input.state !== 'disconnected' && (selectedIds.size === 0 || selectedIds.has(input.id));
|
|
@@ -147,22 +147,26 @@ export async function bindWebMidi(
|
|
|
147
147
|
if (bound.has(input.id) || !shouldBind(input)) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
const entry: BoundInput = {
|
|
151
|
+
input,
|
|
152
|
+
listener: (event: MidiMessageEventLike) => {
|
|
153
|
+
entry.runningStatus = dispatchMidiMessage(
|
|
154
|
+
engine,
|
|
155
|
+
event,
|
|
156
|
+
group,
|
|
157
|
+
entry.runningStatus,
|
|
158
|
+
options.timestampToSamples,
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
runningStatus: 0,
|
|
159
162
|
};
|
|
163
|
+
const listener = entry.listener;
|
|
160
164
|
if (input.addEventListener) {
|
|
161
165
|
input.addEventListener('midimessage', listener);
|
|
162
166
|
} else {
|
|
163
167
|
input.onmidimessage = listener;
|
|
164
168
|
}
|
|
165
|
-
bound.set(input.id,
|
|
169
|
+
bound.set(input.id, entry);
|
|
166
170
|
};
|
|
167
171
|
|
|
168
172
|
const unbindInput = (input: MidiInputLike) => {
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SonareEngineCaptureRequestMessage,
|
|
3
|
+
SonareEngineCaptureResponseMessage,
|
|
4
|
+
SonareEngineSyncMessage,
|
|
5
|
+
SonareEngineTransportRequestMessage,
|
|
6
|
+
SonareEngineTransportResponseMessage,
|
|
7
|
+
SonareRealtimeVoiceChangerMessage,
|
|
8
|
+
SonareWorkletMessage,
|
|
9
|
+
} from './messages';
|
|
10
|
+
import {
|
|
11
|
+
isRecord,
|
|
12
|
+
type SonareEngineCommandRecord,
|
|
13
|
+
type SonareEngineTelemetryRecord,
|
|
14
|
+
type SonareWorkletMeterSnapshot,
|
|
15
|
+
} from './protocol';
|
|
16
|
+
|
|
17
|
+
export function isWorkletMessage(value: unknown): value is SonareWorkletMessage {
|
|
18
|
+
if (!isRecord(value) || typeof value.type !== 'string') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
value.type === 'scheduleInsertAutomation' ||
|
|
23
|
+
value.type === 'setMeterInterval' ||
|
|
24
|
+
value.type === 'destroy'
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function isEngineCommandRecord(value: unknown): value is SonareEngineCommandRecord {
|
|
29
|
+
return isRecord(value) && typeof value.type === 'number';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isEngineSyncMessage(value: unknown): value is SonareEngineSyncMessage {
|
|
33
|
+
if (!isRecord(value) || typeof value.type !== 'string') {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return (
|
|
37
|
+
value.type === 'syncClips' ||
|
|
38
|
+
value.type === 'syncClipsDelta' ||
|
|
39
|
+
value.type === 'syncMidiClips' ||
|
|
40
|
+
value.type === 'syncMarkers' ||
|
|
41
|
+
value.type === 'syncMetronome' ||
|
|
42
|
+
value.type === 'syncAutomation' ||
|
|
43
|
+
value.type === 'syncTempo' ||
|
|
44
|
+
value.type === 'syncMixer' ||
|
|
45
|
+
value.type === 'syncCapture' ||
|
|
46
|
+
value.type === 'syncTrackStripEqBand' ||
|
|
47
|
+
value.type === 'syncMasterStripEqBand' ||
|
|
48
|
+
value.type === 'syncTrackStripInsertBypassed' ||
|
|
49
|
+
value.type === 'syncMasterStripInsertBypassed' ||
|
|
50
|
+
value.type === 'syncTrackStripInsertParamByName' ||
|
|
51
|
+
value.type === 'syncMasterStripInsertParamByName' ||
|
|
52
|
+
value.type === 'syncTrackStripPan' ||
|
|
53
|
+
value.type === 'syncTrackStripPanLaw' ||
|
|
54
|
+
value.type === 'syncTrackStripPanMode' ||
|
|
55
|
+
value.type === 'syncTrackStripDualPan' ||
|
|
56
|
+
value.type === 'syncTrackStripChannelDelaySamples' ||
|
|
57
|
+
value.type === 'syncBuiltinInstrument' ||
|
|
58
|
+
value.type === 'syncSynthInstrument' ||
|
|
59
|
+
value.type === 'syncSf2Instrument' ||
|
|
60
|
+
value.type === 'syncLoadSoundFont' ||
|
|
61
|
+
value.type === 'syncMidiNoteOn' ||
|
|
62
|
+
value.type === 'syncMidiNoteOff' ||
|
|
63
|
+
value.type === 'syncMidiCc' ||
|
|
64
|
+
value.type === 'syncMidiPanic'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function isEngineCaptureRequestMessage(
|
|
69
|
+
value: unknown,
|
|
70
|
+
): value is SonareEngineCaptureRequestMessage {
|
|
71
|
+
return (
|
|
72
|
+
isRecord(value) &&
|
|
73
|
+
value.type === 'captureRequest' &&
|
|
74
|
+
typeof value.requestId === 'number' &&
|
|
75
|
+
(value.op === 'status' || value.op === 'read' || value.op === 'reset')
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function isEngineCaptureResponseMessage(
|
|
80
|
+
value: unknown,
|
|
81
|
+
): value is SonareEngineCaptureResponseMessage {
|
|
82
|
+
return (
|
|
83
|
+
isRecord(value) &&
|
|
84
|
+
value.type === 'captureResponse' &&
|
|
85
|
+
typeof value.requestId === 'number' &&
|
|
86
|
+
typeof value.ok === 'boolean'
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function isEngineTransportRequestMessage(
|
|
91
|
+
value: unknown,
|
|
92
|
+
): value is SonareEngineTransportRequestMessage {
|
|
93
|
+
return (
|
|
94
|
+
isRecord(value) &&
|
|
95
|
+
value.type === 'transportRequest' &&
|
|
96
|
+
typeof value.requestId === 'number' &&
|
|
97
|
+
value.op === 'state'
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function isEngineTransportResponseMessage(
|
|
102
|
+
value: unknown,
|
|
103
|
+
): value is SonareEngineTransportResponseMessage {
|
|
104
|
+
return (
|
|
105
|
+
isRecord(value) &&
|
|
106
|
+
value.type === 'transportResponse' &&
|
|
107
|
+
typeof value.requestId === 'number' &&
|
|
108
|
+
typeof value.ok === 'boolean'
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function isRealtimeVoiceChangerMessage(
|
|
113
|
+
value: unknown,
|
|
114
|
+
): value is SonareRealtimeVoiceChangerMessage {
|
|
115
|
+
if (!isRecord(value) || typeof value.type !== 'string') {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return value.type === 'setConfig' || value.type === 'reset' || value.type === 'destroy';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function isEngineTelemetryRecord(value: unknown): value is SonareEngineTelemetryRecord {
|
|
122
|
+
return (
|
|
123
|
+
isRecord(value) &&
|
|
124
|
+
typeof value.type === 'number' &&
|
|
125
|
+
typeof value.error === 'number' &&
|
|
126
|
+
typeof value.renderFrame === 'number' &&
|
|
127
|
+
typeof value.timelineSample === 'number' &&
|
|
128
|
+
typeof value.audibleTimelineSample === 'number' &&
|
|
129
|
+
typeof value.graphLatencySamplesQ8 === 'number' &&
|
|
130
|
+
typeof value.value === 'number'
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function isMeterSnapshot(value: unknown): value is SonareWorkletMeterSnapshot {
|
|
135
|
+
return (
|
|
136
|
+
isRecord(value) &&
|
|
137
|
+
value.type === 'meter' &&
|
|
138
|
+
typeof value.frame === 'number' &&
|
|
139
|
+
typeof value.peakDbL === 'number' &&
|
|
140
|
+
typeof value.peakDbR === 'number' &&
|
|
141
|
+
typeof value.rmsDbL === 'number' &&
|
|
142
|
+
typeof value.rmsDbR === 'number' &&
|
|
143
|
+
typeof value.correlation === 'number' &&
|
|
144
|
+
(typeof value.targetId === 'number' || value.targetId === undefined)
|
|
145
|
+
);
|
|
146
|
+
}
|