@absolutejs/voice 0.0.22-beta.503 → 0.0.22-beta.504
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/client/browserNoiseSuppression.d.ts +42 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +64 -9
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type BrowserNoiseSuppressorOptions = {
|
|
2
|
+
/** Existing AudioContext to reuse. If omitted, a fresh one is created at 48kHz. */
|
|
3
|
+
audioContext?: AudioContext;
|
|
4
|
+
/** Optional message sent to the worklet via port.postMessage on init. */
|
|
5
|
+
initialPort?: Record<string, unknown>;
|
|
6
|
+
/** AudioWorkletNode options forwarded to the constructor. */
|
|
7
|
+
nodeOptions?: AudioWorkletNodeOptions;
|
|
8
|
+
/** Registered AudioWorkletProcessor name to instantiate. */
|
|
9
|
+
processorName: string;
|
|
10
|
+
/** Caller-supplied input stream from getUserMedia or similar. */
|
|
11
|
+
stream: MediaStream;
|
|
12
|
+
/** URL of the AudioWorklet script that registers `processorName`. */
|
|
13
|
+
workletUrl: string;
|
|
14
|
+
};
|
|
15
|
+
export type BrowserNoiseSuppressorHandle = {
|
|
16
|
+
/** The worklet node — operators can postMessage to tune at runtime. */
|
|
17
|
+
node: AudioWorkletNode;
|
|
18
|
+
/** A MediaStream containing the denoised audio track. */
|
|
19
|
+
stream: MediaStream;
|
|
20
|
+
/** Tears down the worklet + closes the AudioContext when this helper created it. */
|
|
21
|
+
stop: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
export declare const applyBrowserNoiseSuppression: (options: BrowserNoiseSuppressorOptions) => Promise<BrowserNoiseSuppressorHandle>;
|
|
24
|
+
export type BrowserNoiseSuppressorPreset = {
|
|
25
|
+
initialPort?: Record<string, unknown>;
|
|
26
|
+
/** Display label for UI affordances. */
|
|
27
|
+
label: string;
|
|
28
|
+
nodeOptions?: AudioWorkletNodeOptions;
|
|
29
|
+
processorName: string;
|
|
30
|
+
workletUrl: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Convenience presets pointing at well-known open-source worklets. Operators
|
|
34
|
+
* still install the underlying npm package and copy the worklet file to a
|
|
35
|
+
* URL their site can serve.
|
|
36
|
+
*/
|
|
37
|
+
export declare const BROWSER_NOISE_SUPPRESSOR_PRESETS: {
|
|
38
|
+
/** DeepFilterNet 2023 model — best quality open-source pick. */
|
|
39
|
+
readonly deepfilternet: (workletUrl: string) => BrowserNoiseSuppressorPreset;
|
|
40
|
+
/** Jitsi @jitsi/rnnoise-wasm — ships a `rnnoise-processor` worklet. */
|
|
41
|
+
readonly rnnoise: (workletUrl: string) => BrowserNoiseSuppressorPreset;
|
|
42
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -110,6 +110,8 @@ export { createInMemoryVoiceCallQuota } from "./callQuota";
|
|
|
110
110
|
export type { CreateInMemoryVoiceCallQuotaOptions, VoiceCallQuota, VoiceCallQuotaRejection, VoiceCallQuotaResult, VoiceCallQuotaTier, VoiceCallReservation, } from "./callQuota";
|
|
111
111
|
export { createVoiceBearerAuthVerifier, createVoiceHMACAuthVerifier, createVoiceRouteAuth, } from "./routeAuth";
|
|
112
112
|
export type { VoiceRouteAuthDecision, VoiceRouteAuthInput, VoiceRouteAuthOptions, VoiceRouteAuthVerifier, } from "./routeAuth";
|
|
113
|
+
export { BROWSER_NOISE_SUPPRESSOR_PRESETS, applyBrowserNoiseSuppression, } from "./client/browserNoiseSuppression";
|
|
114
|
+
export type { BrowserNoiseSuppressorHandle, BrowserNoiseSuppressorOptions, BrowserNoiseSuppressorPreset, } from "./client/browserNoiseSuppression";
|
|
113
115
|
export { buildVoiceHTMXAttributes, wrapVoiceHTMLInHTMXContainer, wrapVoiceHTMLWithHTMXPolling, } from "./client/htmxAttributes";
|
|
114
116
|
export type { VoiceHTMXPollingAttributes } from "./client/htmxAttributes";
|
|
115
117
|
export { createLiveCallViewerFromOptions, renderVoiceCostDashboardFromEvents, renderVoiceCostDashboardHTMX, renderVoiceLiveCallViewerFromState, renderVoiceLiveCallViewerFromViewer, renderVoiceLiveCallViewerHTMX, renderVoiceReplayTimelineFromArtifact, renderVoiceReplayTimelineHTMX, resolveVoiceDashboardRenderers, } from "./client/htmxDashboardRenderers";
|
package/dist/index.js
CHANGED
|
@@ -7017,13 +7017,13 @@ var getCampaignWindowMinute = (at, offsetMinutes = 0) => {
|
|
|
7017
7017
|
minuteOfDay: date.getUTCHours() * 60 + date.getUTCMinutes()
|
|
7018
7018
|
};
|
|
7019
7019
|
};
|
|
7020
|
-
var isWithinCampaignTimeWindow = (
|
|
7021
|
-
const { dayOfWeek, minuteOfDay } = getCampaignWindowMinute(at,
|
|
7022
|
-
if (
|
|
7020
|
+
var isWithinCampaignTimeWindow = (window2, at) => {
|
|
7021
|
+
const { dayOfWeek, minuteOfDay } = getCampaignWindowMinute(at, window2.timeZoneOffsetMinutes ?? 0);
|
|
7022
|
+
if (window2.daysOfWeek && !window2.daysOfWeek.includes(dayOfWeek)) {
|
|
7023
7023
|
return false;
|
|
7024
7024
|
}
|
|
7025
|
-
const start = normalizeHour(
|
|
7026
|
-
const end = normalizeHour(
|
|
7025
|
+
const start = normalizeHour(window2.startHour) * 60;
|
|
7026
|
+
const end = normalizeHour(window2.endHour) * 60;
|
|
7027
7027
|
if (start === end) {
|
|
7028
7028
|
return true;
|
|
7029
7029
|
}
|
|
@@ -36781,6 +36781,59 @@ var createVoiceRouteAuth = (options) => {
|
|
|
36781
36781
|
}
|
|
36782
36782
|
});
|
|
36783
36783
|
};
|
|
36784
|
+
// src/client/browserNoiseSuppression.ts
|
|
36785
|
+
var isBrowser = () => typeof window !== "undefined" && typeof window.AudioContext !== "undefined";
|
|
36786
|
+
var applyBrowserNoiseSuppression = async (options) => {
|
|
36787
|
+
if (!isBrowser()) {
|
|
36788
|
+
throw new Error("applyBrowserNoiseSuppression requires a browser environment with AudioContext");
|
|
36789
|
+
}
|
|
36790
|
+
const ownsContext = !options.audioContext;
|
|
36791
|
+
const audioContext = options.audioContext ?? new AudioContext({ sampleRate: 48000 });
|
|
36792
|
+
if (audioContext.state === "suspended") {
|
|
36793
|
+
try {
|
|
36794
|
+
await audioContext.resume();
|
|
36795
|
+
} catch {}
|
|
36796
|
+
}
|
|
36797
|
+
await audioContext.audioWorklet.addModule(options.workletUrl);
|
|
36798
|
+
const source = audioContext.createMediaStreamSource(options.stream);
|
|
36799
|
+
const node = new AudioWorkletNode(audioContext, options.processorName, options.nodeOptions);
|
|
36800
|
+
if (options.initialPort) {
|
|
36801
|
+
node.port.postMessage(options.initialPort);
|
|
36802
|
+
}
|
|
36803
|
+
const destination = audioContext.createMediaStreamDestination();
|
|
36804
|
+
source.connect(node);
|
|
36805
|
+
node.connect(destination);
|
|
36806
|
+
return {
|
|
36807
|
+
node,
|
|
36808
|
+
stop: async () => {
|
|
36809
|
+
try {
|
|
36810
|
+
node.disconnect();
|
|
36811
|
+
} catch {}
|
|
36812
|
+
try {
|
|
36813
|
+
source.disconnect();
|
|
36814
|
+
} catch {}
|
|
36815
|
+
try {
|
|
36816
|
+
destination.disconnect();
|
|
36817
|
+
} catch {}
|
|
36818
|
+
if (ownsContext) {
|
|
36819
|
+
await audioContext.close();
|
|
36820
|
+
}
|
|
36821
|
+
},
|
|
36822
|
+
stream: destination.stream
|
|
36823
|
+
};
|
|
36824
|
+
};
|
|
36825
|
+
var BROWSER_NOISE_SUPPRESSOR_PRESETS = {
|
|
36826
|
+
deepfilternet: (workletUrl) => ({
|
|
36827
|
+
label: "DeepFilterNet",
|
|
36828
|
+
processorName: "deepfilter-suppressor",
|
|
36829
|
+
workletUrl
|
|
36830
|
+
}),
|
|
36831
|
+
rnnoise: (workletUrl) => ({
|
|
36832
|
+
label: "RNNoise",
|
|
36833
|
+
processorName: "rnnoise-processor",
|
|
36834
|
+
workletUrl
|
|
36835
|
+
})
|
|
36836
|
+
};
|
|
36784
36837
|
// src/client/htmxAttributes.ts
|
|
36785
36838
|
var escapeAttr = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
36786
36839
|
var normalizeHxKey = (key) => key.startsWith("hx-") ? key : `hx-${key}`;
|
|
@@ -39020,10 +39073,10 @@ var readRecentJsonFiles = async (directory, limit) => {
|
|
|
39020
39073
|
};
|
|
39021
39074
|
const existingRecords = [];
|
|
39022
39075
|
for (let index = 0;index < files.length && existingRecords.length < limit; ) {
|
|
39023
|
-
const
|
|
39024
|
-
const records = await Promise.all(
|
|
39076
|
+
const window2 = files.slice(index, index + limit - existingRecords.length);
|
|
39077
|
+
const records = await Promise.all(window2.map((file) => readRecentFile(file)));
|
|
39025
39078
|
existingRecords.push(...records.filter(isDefined));
|
|
39026
|
-
index +=
|
|
39079
|
+
index += window2.length;
|
|
39027
39080
|
}
|
|
39028
39081
|
if (missingPaths.size > 0) {
|
|
39029
39082
|
await writeRecentJsonFileIndex(directory, (await readRecentJsonFileIndex(directory)).filter((entry) => !missingPaths.has(entry.path)));
|
|
@@ -48418,6 +48471,7 @@ export {
|
|
|
48418
48471
|
applyVoiceCampaignTelephonyOutcome,
|
|
48419
48472
|
applyRiskTieredPhraseHintCorrections,
|
|
48420
48473
|
applyPhraseHintCorrections,
|
|
48474
|
+
applyBrowserNoiseSuppression,
|
|
48421
48475
|
appendVoiceRealCallProfileRecoveryEvidence,
|
|
48422
48476
|
appendVoiceProviderRouterTraceEvent,
|
|
48423
48477
|
appendVoiceIOProviderRouterTraceEvent,
|
|
@@ -48431,5 +48485,6 @@ export {
|
|
|
48431
48485
|
DEFAULT_VOICE_REDACTION_PATTERNS,
|
|
48432
48486
|
DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS,
|
|
48433
48487
|
DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS,
|
|
48434
|
-
DEFAULT_VOICE_PRICE_BOOK
|
|
48488
|
+
DEFAULT_VOICE_PRICE_BOOK,
|
|
48489
|
+
BROWSER_NOISE_SUPPRESSOR_PRESETS
|
|
48435
48490
|
};
|