@speech-sdk/core 0.8.1-alpha → 0.8.1
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 +63 -1
- package/dist/audio-decode.d.ts +7 -0
- package/dist/audio-decode.d.ts.map +1 -0
- package/dist/audio-decode.js +109 -0
- package/dist/audio-decode.js.map +1 -0
- package/dist/audio-duration.d.ts.map +1 -1
- package/dist/audio-duration.js +3 -12
- package/dist/audio-duration.js.map +1 -1
- package/dist/audio-output.d.ts +39 -0
- package/dist/audio-output.d.ts.map +1 -0
- package/dist/audio-output.js +111 -0
- package/dist/audio-output.js.map +1 -0
- package/dist/audio-utils.d.ts +2 -0
- package/dist/audio-utils.d.ts.map +1 -1
- package/dist/audio-utils.js +55 -1
- package/dist/audio-utils.js.map +1 -1
- package/dist/conversation/pcm-concat.d.ts +0 -1
- package/dist/conversation/pcm-concat.d.ts.map +1 -1
- package/dist/conversation/pcm-concat.js +6 -143
- package/dist/conversation/pcm-concat.js.map +1 -1
- package/dist/conversation/stitch.d.ts +4 -0
- package/dist/conversation/stitch.d.ts.map +1 -1
- package/dist/conversation/stitch.js +30 -15
- package/dist/conversation/stitch.js.map +1 -1
- package/dist/conversation/types.d.ts +6 -2
- package/dist/conversation/types.d.ts.map +1 -1
- package/dist/encoders/mp3.d.ts +6 -0
- package/dist/encoders/mp3.d.ts.map +1 -0
- package/dist/encoders/mp3.js +54 -0
- package/dist/encoders/mp3.js.map +1 -0
- package/dist/errors.d.ts +15 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +37 -1
- package/dist/errors.js.map +1 -1
- package/dist/generate-conversation.d.ts +2 -2
- package/dist/generate-conversation.d.ts.map +1 -1
- package/dist/generate-conversation.js +106 -44
- package/dist/generate-conversation.js.map +1 -1
- package/dist/generate-speech.d.ts +6 -2
- package/dist/generate-speech.d.ts.map +1 -1
- package/dist/generate-speech.js +130 -60
- package/dist/generate-speech.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/pronunciations/errors.d.ts +5 -0
- package/dist/pronunciations/errors.d.ts.map +1 -0
- package/dist/pronunciations/errors.js +8 -0
- package/dist/pronunciations/errors.js.map +1 -0
- package/dist/pronunciations/index.d.ts +5 -0
- package/dist/pronunciations/index.d.ts.map +1 -0
- package/dist/pronunciations/index.js +5 -0
- package/dist/pronunciations/index.js.map +1 -0
- package/dist/pronunciations/inverse-align.d.ts +4 -0
- package/dist/pronunciations/inverse-align.d.ts.map +1 -0
- package/dist/pronunciations/inverse-align.js +54 -0
- package/dist/pronunciations/inverse-align.js.map +1 -0
- package/dist/pronunciations/merge.d.ts +4 -0
- package/dist/pronunciations/merge.d.ts.map +1 -0
- package/dist/pronunciations/merge.js +13 -0
- package/dist/pronunciations/merge.js.map +1 -0
- package/dist/pronunciations/substitute.d.ts +6 -0
- package/dist/pronunciations/substitute.d.ts.map +1 -0
- package/dist/pronunciations/substitute.js +67 -0
- package/dist/pronunciations/substitute.js.map +1 -0
- package/dist/pronunciations/types.d.ts +18 -0
- package/dist/pronunciations/types.d.ts.map +1 -0
- package/dist/pronunciations/types.js +2 -0
- package/dist/pronunciations/types.js.map +1 -0
- package/dist/pronunciations/validate.d.ts +3 -0
- package/dist/pronunciations/validate.d.ts.map +1 -0
- package/dist/pronunciations/validate.js +26 -0
- package/dist/pronunciations/validate.js.map +1 -0
- package/dist/provider-utils.d.ts +1 -0
- package/dist/provider-utils.d.ts.map +1 -1
- package/dist/provider-utils.js +26 -0
- package/dist/provider-utils.js.map +1 -1
- package/dist/providers/cartesia/index.d.ts +22 -0
- package/dist/providers/cartesia/index.d.ts.map +1 -1
- package/dist/providers/cartesia/index.js +48 -0
- package/dist/providers/cartesia/index.js.map +1 -1
- package/dist/providers/deepgram/index.d.ts +16 -0
- package/dist/providers/deepgram/index.d.ts.map +1 -1
- package/dist/providers/deepgram/index.js +34 -0
- package/dist/providers/deepgram/index.js.map +1 -1
- package/dist/providers/elevenlabs/index.d.ts +7 -0
- package/dist/providers/elevenlabs/index.d.ts.map +1 -1
- package/dist/providers/elevenlabs/index.js +25 -0
- package/dist/providers/elevenlabs/index.js.map +1 -1
- package/dist/providers/fal/index.d.ts +5 -3
- package/dist/providers/fal/index.d.ts.map +1 -1
- package/dist/providers/fal/index.js +13 -7
- package/dist/providers/fal/index.js.map +1 -1
- package/dist/providers/fish-audio/index.d.ts +7 -0
- package/dist/providers/fish-audio/index.d.ts.map +1 -1
- package/dist/providers/fish-audio/index.js +24 -0
- package/dist/providers/fish-audio/index.js.map +1 -1
- package/dist/providers/gateway/index.d.ts +8 -0
- package/dist/providers/gateway/index.d.ts.map +1 -1
- package/dist/providers/gateway/index.js +16 -1
- package/dist/providers/gateway/index.js.map +1 -1
- package/dist/providers/google/index.d.ts +5 -0
- package/dist/providers/google/index.d.ts.map +1 -1
- package/dist/providers/google/index.js +19 -11
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/hume/index.d.ts +9 -0
- package/dist/providers/hume/index.d.ts.map +1 -1
- package/dist/providers/hume/index.js +24 -0
- package/dist/providers/hume/index.js.map +1 -1
- package/dist/providers/inworld/index.d.ts +10 -0
- package/dist/providers/inworld/index.d.ts.map +1 -1
- package/dist/providers/inworld/index.js +32 -8
- package/dist/providers/inworld/index.js.map +1 -1
- package/dist/providers/mistral/index.d.ts +7 -0
- package/dist/providers/mistral/index.d.ts.map +1 -1
- package/dist/providers/mistral/index.js +24 -10
- package/dist/providers/mistral/index.js.map +1 -1
- package/dist/providers/murf/index.d.ts +8 -0
- package/dist/providers/murf/index.d.ts.map +1 -1
- package/dist/providers/murf/index.js +40 -1
- package/dist/providers/murf/index.js.map +1 -1
- package/dist/providers/openai/index.d.ts +7 -0
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +24 -0
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/resemble/index.d.ts +14 -0
- package/dist/providers/resemble/index.d.ts.map +1 -1
- package/dist/providers/resemble/index.js +35 -1
- package/dist/providers/resemble/index.js.map +1 -1
- package/dist/providers/smallest-ai/index.d.ts +47 -0
- package/dist/providers/smallest-ai/index.d.ts.map +1 -0
- package/dist/providers/smallest-ai/index.js +107 -0
- package/dist/providers/smallest-ai/index.js.map +1 -0
- package/dist/providers/xai/index.d.ts +18 -0
- package/dist/providers/xai/index.d.ts.map +1 -1
- package/dist/providers/xai/index.js +26 -0
- package/dist/providers/xai/index.js.map +1 -1
- package/dist/providers.d.ts +2 -0
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +1 -0
- package/dist/providers.js.map +1 -1
- package/dist/retry-options.d.ts +6 -0
- package/dist/retry-options.d.ts.map +1 -0
- package/dist/retry-options.js +48 -0
- package/dist/retry-options.js.map +1 -0
- package/dist/speech-provider.d.ts +15 -0
- package/dist/speech-provider.d.ts.map +1 -1
- package/dist/speech-provider.js.map +1 -1
- package/dist/stream-speech.d.ts +4 -2
- package/dist/stream-speech.d.ts.map +1 -1
- package/dist/stream-speech.js +36 -21
- package/dist/stream-speech.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/volume-adjust.d.ts.map +1 -1
- package/dist/volume-adjust.js +4 -10
- package/dist/volume-adjust.js.map +1 -1
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -255,6 +255,32 @@ result.audio.mediaType; // "audio/wav" — re-encoded after normalization
|
|
|
255
255
|
|
|
256
256
|
`generateConversation` always normalizes; override the target with `volumeDbfs`. A warning is surfaced (and the raw mix passes through) if the provider has no decodable PCM/WAV mode.
|
|
257
257
|
|
|
258
|
+
### Output format
|
|
259
|
+
|
|
260
|
+
By default, `generateSpeech` preserves the provider or gateway response format.
|
|
261
|
+
`generateConversation` returns WAV when the SDK stitches direct-provider audio.
|
|
262
|
+
|
|
263
|
+
Pass `output` to request a specific final format:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const result = await generateSpeech({
|
|
267
|
+
model: createOpenAI()('tts-1'),
|
|
268
|
+
voice: 'alloy',
|
|
269
|
+
text: 'Hello',
|
|
270
|
+
output: { format: 'mp3', bitrate: 96 },
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
result.audio.mediaType; // "audio/mpeg"
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Supported explicit formats are `wav`, `mp3`, and `pcm`.
|
|
277
|
+
|
|
278
|
+
For direct providers, the SDK first asks each provider whether it can natively produce the requested format. If yes, the provider returns it directly and the SDK passes the bytes through unchanged. If the provider can return WAV/PCM but not the requested format (e.g. ElevenLabs has no native WAV output, Cartesia has no native MP3), the SDK requests a decodable format and converts via mediabunny. The SDK never decodes compressed audio (mp3/opus/aac) — providers must return wav/pcm for any local conversion to succeed.
|
|
279
|
+
|
|
280
|
+
For gateway models, the SDK forwards `output` to the gateway API unchanged.
|
|
281
|
+
|
|
282
|
+
MP3 encoding uses [`@mediabunny/mp3-encoder`](https://mediabunny.dev/guide/extensions/mp3-encoder), loaded dynamically only when MP3 output is requested and the host environment does not already provide native MP3 encoding.
|
|
283
|
+
|
|
258
284
|
## Audio tags
|
|
259
285
|
|
|
260
286
|
Bracket syntax `[tag]` adds expressive cues. Each provider handles tags natively where supported, maps them to its closest equivalent, or strips them and surfaces a warning in `result.warnings`.
|
|
@@ -267,6 +293,41 @@ await generateSpeech({
|
|
|
267
293
|
});
|
|
268
294
|
```
|
|
269
295
|
|
|
296
|
+
## Pronunciations
|
|
297
|
+
|
|
298
|
+
Customize how specific words are pronounced. Rules are applied as text substitution before the request is sent to the provider; word timestamps are inverse-mapped on return so the substitution is invisible to the caller.
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
import { generateSpeech } from '@speech-sdk/core';
|
|
302
|
+
|
|
303
|
+
await generateSpeech({
|
|
304
|
+
model: 'openai/tts-1', // gateway path; or use createOpenAI()(...)
|
|
305
|
+
voice: 'alloy',
|
|
306
|
+
text: 'What is LLM?',
|
|
307
|
+
pronunciations: {
|
|
308
|
+
rules: [{ word: 'LLM', replacement: 'el el em' }],
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Stored dictionaries are referenced by ID and resolved server-side (gateway path only):
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
await generateSpeech({
|
|
317
|
+
model: 'openai/tts-1',
|
|
318
|
+
voice: 'alloy',
|
|
319
|
+
text: 'What is LLM?',
|
|
320
|
+
pronunciations: {
|
|
321
|
+
dictionaryIds: ['dict_company_terms'],
|
|
322
|
+
rules: [{ word: 'LLM', replacement: 'el el em' }], // overrides dict matches
|
|
323
|
+
},
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`dictionaryIds` requires the gateway path. On the direct-provider path, passing dictionary IDs throws `DictionaryIdsRequireGatewayError`. Inline `rules` work on both paths.
|
|
328
|
+
|
|
329
|
+
The same option is available on `streamSpeech` and `generateConversation`. On `generateConversation`, the option applies globally to every turn.
|
|
330
|
+
|
|
270
331
|
## Voice cloning
|
|
271
332
|
|
|
272
333
|
Some providers support reference-audio cloning. Pass a voice object instead of a string.
|
|
@@ -389,6 +450,7 @@ try {
|
|
|
389
450
|
error.statusCode; // 401, 429, 500, ...
|
|
390
451
|
error.responseBody;
|
|
391
452
|
error.code; // stable machine-readable code (optional)
|
|
453
|
+
error.retryAfterMs; // parsed Retry-After header in ms (optional)
|
|
392
454
|
}
|
|
393
455
|
}
|
|
394
456
|
```
|
|
@@ -406,7 +468,7 @@ try {
|
|
|
406
468
|
| `ConversationInputError` / `DialogueConstraintError` / `StitchUnsupportedError` | `generateConversation` validation / native caps / stitch incompatibility |
|
|
407
469
|
| `SpeechSDKError` | Base class |
|
|
408
470
|
|
|
409
|
-
Retries 5xx and network errors with exponential backoff ([p-retry](https://github.com/sindresorhus/p-retry));
|
|
471
|
+
Retries 5xx (except 501), 429, and network errors with jittered exponential backoff ([p-retry](https://github.com/sindresorhus/p-retry)); other 4xx and 501 are terminal. When a retriable error carries a `Retry-After` header, the SDK sleeps that long before the next attempt — capped at 60s to avoid pathological waits. The parsed value is surfaced as `ApiError.retryAfterMs` whenever the header is present, even on terminal errors that aren't retried. Default 2 retries; override via `maxRetries`.
|
|
410
472
|
|
|
411
473
|
## Development
|
|
412
474
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface DecodedPcm16 {
|
|
2
|
+
readonly channels: 1;
|
|
3
|
+
readonly pcm: Int16Array;
|
|
4
|
+
readonly sampleRate: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function decodeAudioToPcm16(bytes: Uint8Array, mediaType: string): Promise<DecodedPcm16>;
|
|
7
|
+
//# sourceMappingURL=audio-decode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-decode.d.ts","sourceRoot":"","sources":["../src/audio-decode.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAQvB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ALL_FORMATS, AudioSample, AudioSampleSink, BlobSource, Input, } from "mediabunny";
|
|
2
|
+
import { parseMediaTypeParam } from "./audio-utils.js";
|
|
3
|
+
export async function decodeAudioToPcm16(bytes, mediaType) {
|
|
4
|
+
const lower = mediaType.toLowerCase();
|
|
5
|
+
if (lower.startsWith("audio/pcm") || lower.startsWith("audio/x-pcm")) {
|
|
6
|
+
return decodeRawPcm(bytes, mediaType);
|
|
7
|
+
}
|
|
8
|
+
return await decodeContainerized(bytes, mediaType);
|
|
9
|
+
}
|
|
10
|
+
const ENCODING_PARAM_RE = /(?:^|;)\s*encoding=([a-z0-9_-]+)(?=$|;|\s)/i;
|
|
11
|
+
function decodeRawPcm(bytes, mediaType) {
|
|
12
|
+
const sampleRate = parseMediaTypeParam(mediaType, "rate") ?? 24_000;
|
|
13
|
+
const channels = parseMediaTypeParam(mediaType, "channels") ?? 1;
|
|
14
|
+
const encoding = mediaType.toLowerCase().match(ENCODING_PARAM_RE)?.[1];
|
|
15
|
+
const format = encoding === "float32" ? "f32" : "s16";
|
|
16
|
+
const bytesPerSample = format === "f32" ? 4 : 2;
|
|
17
|
+
const numberOfFrames = Math.floor(bytes.byteLength / bytesPerSample / channels);
|
|
18
|
+
if (numberOfFrames === 0) {
|
|
19
|
+
return { pcm: new Int16Array(0), sampleRate, channels: 1 };
|
|
20
|
+
}
|
|
21
|
+
const data = format === "f32"
|
|
22
|
+
? new Float32Array(copyAligned(bytes, 4).buffer, 0, numberOfFrames * channels)
|
|
23
|
+
: new Int16Array(copyAligned(bytes, 2).buffer, 0, numberOfFrames * channels);
|
|
24
|
+
const sample = new AudioSample({
|
|
25
|
+
data,
|
|
26
|
+
format,
|
|
27
|
+
numberOfChannels: channels,
|
|
28
|
+
sampleRate,
|
|
29
|
+
timestamp: 0,
|
|
30
|
+
});
|
|
31
|
+
const monoFrames = sample.numberOfFrames;
|
|
32
|
+
const out = new Int16Array(monoFrames);
|
|
33
|
+
if (channels === 1) {
|
|
34
|
+
sample.copyTo(out, { format: "s16", planeIndex: 0 });
|
|
35
|
+
return { pcm: out, sampleRate, channels: 1 };
|
|
36
|
+
}
|
|
37
|
+
const interleaved = new Int16Array(monoFrames * channels);
|
|
38
|
+
sample.copyTo(interleaved, { format: "s16", planeIndex: 0 });
|
|
39
|
+
for (let f = 0; f < monoFrames; f++) {
|
|
40
|
+
let sum = 0;
|
|
41
|
+
for (let c = 0; c < channels; c++) {
|
|
42
|
+
sum += interleaved[f * channels + c];
|
|
43
|
+
}
|
|
44
|
+
out[f] = Math.round(sum / channels);
|
|
45
|
+
}
|
|
46
|
+
return { pcm: out, sampleRate, channels: 1 };
|
|
47
|
+
}
|
|
48
|
+
async function decodeContainerized(bytes, mediaType) {
|
|
49
|
+
// .slice() copies into a fresh ArrayBuffer (Blob accepts ArrayBuffer-backed views, not SharedArrayBuffer).
|
|
50
|
+
const blob = new Blob([bytes.slice()], { type: mediaType });
|
|
51
|
+
const input = new Input({
|
|
52
|
+
source: new BlobSource(blob),
|
|
53
|
+
formats: ALL_FORMATS,
|
|
54
|
+
});
|
|
55
|
+
const track = await input.getPrimaryAudioTrack();
|
|
56
|
+
if (!track) {
|
|
57
|
+
throw new Error(`audio-decode: no audio track found in input (mediaType="${mediaType}")`);
|
|
58
|
+
}
|
|
59
|
+
const sampleRate = track.sampleRate;
|
|
60
|
+
const sourceChannels = track.numberOfChannels;
|
|
61
|
+
const sink = new AudioSampleSink(track);
|
|
62
|
+
const chunks = [];
|
|
63
|
+
let totalMonoFrames = 0;
|
|
64
|
+
for await (const sample of sink.samples()) {
|
|
65
|
+
const frames = sample.numberOfFrames;
|
|
66
|
+
if (frames === 0) {
|
|
67
|
+
sample.close();
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (sourceChannels === 1) {
|
|
71
|
+
const buf = new Int16Array(frames);
|
|
72
|
+
sample.copyTo(buf, { format: "s16", planeIndex: 0 });
|
|
73
|
+
chunks.push(buf);
|
|
74
|
+
totalMonoFrames += frames;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const interleaved = new Int16Array(frames * sourceChannels);
|
|
78
|
+
sample.copyTo(interleaved, { format: "s16", planeIndex: 0 });
|
|
79
|
+
const mono = new Int16Array(frames);
|
|
80
|
+
for (let f = 0; f < frames; f++) {
|
|
81
|
+
let sum = 0;
|
|
82
|
+
for (let c = 0; c < sourceChannels; c++) {
|
|
83
|
+
sum += interleaved[f * sourceChannels + c];
|
|
84
|
+
}
|
|
85
|
+
mono[f] = Math.round(sum / sourceChannels);
|
|
86
|
+
}
|
|
87
|
+
chunks.push(mono);
|
|
88
|
+
totalMonoFrames += frames;
|
|
89
|
+
}
|
|
90
|
+
sample.close();
|
|
91
|
+
}
|
|
92
|
+
const pcm = new Int16Array(totalMonoFrames);
|
|
93
|
+
let offset = 0;
|
|
94
|
+
for (const chunk of chunks) {
|
|
95
|
+
pcm.set(chunk, offset);
|
|
96
|
+
offset += chunk.length;
|
|
97
|
+
}
|
|
98
|
+
return { pcm, sampleRate, channels: 1 };
|
|
99
|
+
}
|
|
100
|
+
function copyAligned(bytes, alignment) {
|
|
101
|
+
if (bytes.byteOffset % alignment === 0 &&
|
|
102
|
+
bytes.byteLength % alignment === 0) {
|
|
103
|
+
return bytes;
|
|
104
|
+
}
|
|
105
|
+
const aligned = new Uint8Array(bytes.byteLength - (bytes.byteLength % alignment));
|
|
106
|
+
aligned.set(bytes.subarray(0, aligned.length));
|
|
107
|
+
return aligned;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=audio-decode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-decode.js","sourceRoot":"","sources":["../src/audio-decode.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-duration.d.ts","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audio-duration.d.ts","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAGA,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB7B"}
|
package/dist/audio-duration.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { ALL_FORMATS, BlobSource, Input } from "mediabunny";
|
|
2
|
+
import { base64ToUint8Array } from "./audio-utils.js";
|
|
2
3
|
export async function computeAudioDuration(data, mediaType) {
|
|
3
4
|
try {
|
|
4
5
|
const bytes = data instanceof Uint8Array ? data : base64ToUint8Array(data);
|
|
5
|
-
//
|
|
6
|
-
const
|
|
7
|
-
new Uint8Array(ab).set(bytes);
|
|
8
|
-
const blob = new Blob([ab], { type: mediaType });
|
|
6
|
+
// .slice() copies into a fresh ArrayBuffer (Blob accepts ArrayBuffer-backed views, not SharedArrayBuffer).
|
|
7
|
+
const blob = new Blob([bytes.slice()], { type: mediaType });
|
|
9
8
|
const input = new Input({
|
|
10
9
|
source: new BlobSource(blob),
|
|
11
10
|
formats: ALL_FORMATS,
|
|
@@ -21,12 +20,4 @@ export async function computeAudioDuration(data, mediaType) {
|
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
|
-
function base64ToUint8Array(b64) {
|
|
25
|
-
const binaryString = atob(b64);
|
|
26
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
27
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
28
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
29
|
-
}
|
|
30
|
-
return bytes;
|
|
31
|
-
}
|
|
32
23
|
//# sourceMappingURL=audio-duration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-duration.js","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"audio-duration.js","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAyB,EACzB,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC3E,2GAA2G;QAC3G,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;YACtB,MAAM,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC;YAC5B,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE,CAAC;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type AudioOutput = {
|
|
2
|
+
readonly format: "wav";
|
|
3
|
+
} | {
|
|
4
|
+
readonly format: "pcm";
|
|
5
|
+
} | {
|
|
6
|
+
readonly format: "mp3";
|
|
7
|
+
readonly bitrate?: number;
|
|
8
|
+
};
|
|
9
|
+
export type AudioOutputFormat = AudioOutput["format"];
|
|
10
|
+
export declare const DEFAULT_MP3_BITRATE_KBPS = 96;
|
|
11
|
+
export type ResolvedAudioOutput = {
|
|
12
|
+
readonly format: "wav";
|
|
13
|
+
} | {
|
|
14
|
+
readonly format: "pcm";
|
|
15
|
+
readonly sampleRate?: number;
|
|
16
|
+
} | {
|
|
17
|
+
readonly format: "mp3";
|
|
18
|
+
readonly bitrate: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function validateOutput<T extends AudioOutput | undefined>(output: T): T;
|
|
21
|
+
export declare function resolveOutputForLocalConversion(output: AudioOutput): ResolvedAudioOutput;
|
|
22
|
+
export declare function mediaTypeForOutput(output: ResolvedAudioOutput): string;
|
|
23
|
+
export declare function convertDecodableAudioToOutput(args: {
|
|
24
|
+
readonly audio: Uint8Array;
|
|
25
|
+
readonly mediaType: string;
|
|
26
|
+
readonly output: ResolvedAudioOutput;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
readonly audio: Uint8Array;
|
|
29
|
+
readonly mediaType: string;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function applyOptionalOutputConversion(args: {
|
|
32
|
+
readonly audio: Uint8Array;
|
|
33
|
+
readonly mediaType: string;
|
|
34
|
+
readonly output: AudioOutput | undefined;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
readonly audio: Uint8Array;
|
|
37
|
+
readonly mediaType: string;
|
|
38
|
+
}>;
|
|
39
|
+
//# sourceMappingURL=audio-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-output.d.ts","sourceRoot":"","sources":["../src/audio-output.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;AAEtD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,SAAS,EAC9D,MAAM,EAAE,CAAC,GACR,CAAC,CAOH;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,WAAW,GAClB,mBAAmB,CASrB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAQtE;AAuCD,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC,GAAG,OAAO,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDtE;AAED,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;CAC1C,GAAG,OAAO,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAStE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { decodeAudioToPcm16 } from "./audio-decode.js";
|
|
2
|
+
import { parseMediaTypeParam, wrapPcm16Mono } from "./audio-utils.js";
|
|
3
|
+
import { encodePcm16ToMp3 } from "./encoders/mp3.js";
|
|
4
|
+
import { AudioOutputInputError } from "./errors.js";
|
|
5
|
+
const DEFAULT_PCM_RATE = 24_000;
|
|
6
|
+
export const DEFAULT_MP3_BITRATE_KBPS = 96;
|
|
7
|
+
export function validateOutput(output) {
|
|
8
|
+
if (output?.format !== "mp3" && output != null && "bitrate" in output) {
|
|
9
|
+
throw new AudioOutputInputError(`audio-output: bitrate is only valid for format "mp3" (got format="${output.format}")`);
|
|
10
|
+
}
|
|
11
|
+
return output;
|
|
12
|
+
}
|
|
13
|
+
export function resolveOutputForLocalConversion(output) {
|
|
14
|
+
validateOutput(output);
|
|
15
|
+
if (output.format === "mp3") {
|
|
16
|
+
return {
|
|
17
|
+
format: "mp3",
|
|
18
|
+
bitrate: output.bitrate ?? DEFAULT_MP3_BITRATE_KBPS,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return output;
|
|
22
|
+
}
|
|
23
|
+
export function mediaTypeForOutput(output) {
|
|
24
|
+
if (output.format === "wav") {
|
|
25
|
+
return "audio/wav";
|
|
26
|
+
}
|
|
27
|
+
if (output.format === "mp3") {
|
|
28
|
+
return "audio/mpeg";
|
|
29
|
+
}
|
|
30
|
+
return `audio/pcm;rate=${output.sampleRate ?? 24_000}`;
|
|
31
|
+
}
|
|
32
|
+
function isDecodableSourceMediaType(mediaType) {
|
|
33
|
+
const lower = mediaType.toLowerCase();
|
|
34
|
+
return (lower.startsWith("audio/wav") ||
|
|
35
|
+
lower.startsWith("audio/x-wav") ||
|
|
36
|
+
lower.startsWith("audio/pcm") ||
|
|
37
|
+
lower.startsWith("audio/x-pcm"));
|
|
38
|
+
}
|
|
39
|
+
function isWavSource(mediaType) {
|
|
40
|
+
const lower = mediaType.toLowerCase();
|
|
41
|
+
return lower.startsWith("audio/wav") || lower.startsWith("audio/x-wav");
|
|
42
|
+
}
|
|
43
|
+
function isMp3Source(mediaType) {
|
|
44
|
+
const lower = mediaType.toLowerCase();
|
|
45
|
+
return lower.startsWith("audio/mpeg") || lower.startsWith("audio/mp3");
|
|
46
|
+
}
|
|
47
|
+
function isPcmSource(mediaType) {
|
|
48
|
+
const lower = mediaType.toLowerCase();
|
|
49
|
+
return lower.startsWith("audio/pcm") || lower.startsWith("audio/x-pcm");
|
|
50
|
+
}
|
|
51
|
+
async function decodeToPcmBytes(audio, mediaType) {
|
|
52
|
+
const segment = await decodeAudioToPcm16(audio, mediaType);
|
|
53
|
+
return {
|
|
54
|
+
pcmBytes: new Uint8Array(segment.pcm.buffer, segment.pcm.byteOffset, segment.pcm.byteLength),
|
|
55
|
+
sampleRate: segment.sampleRate,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export async function convertDecodableAudioToOutput(args) {
|
|
59
|
+
const { audio, mediaType, output } = args;
|
|
60
|
+
if (output.format === "wav" && isWavSource(mediaType)) {
|
|
61
|
+
return { audio, mediaType: "audio/wav" };
|
|
62
|
+
}
|
|
63
|
+
if (output.format === "mp3" && isMp3Source(mediaType)) {
|
|
64
|
+
return { audio, mediaType: "audio/mpeg" };
|
|
65
|
+
}
|
|
66
|
+
if (output.format === "pcm" && isPcmSource(mediaType)) {
|
|
67
|
+
// Some providers (e.g. OpenAI) return bare "audio/pcm" without rate;
|
|
68
|
+
// normalize to mediaTypeForOutput so callers always know the rate.
|
|
69
|
+
const sampleRate = parseMediaTypeParam(mediaType, "rate") ?? DEFAULT_PCM_RATE;
|
|
70
|
+
return {
|
|
71
|
+
audio,
|
|
72
|
+
mediaType: mediaTypeForOutput({ format: "pcm", sampleRate }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!isDecodableSourceMediaType(mediaType)) {
|
|
76
|
+
throw new AudioOutputInputError(`convertDecodableAudioToOutput: source mediaType "${mediaType}" is not decodable. Only audio/wav, audio/x-wav, audio/pcm, and audio/x-pcm are supported.`);
|
|
77
|
+
}
|
|
78
|
+
if (output.format === "wav") {
|
|
79
|
+
const { pcmBytes, sampleRate } = await decodeToPcmBytes(audio, mediaType);
|
|
80
|
+
const wav = await wrapPcm16Mono(pcmBytes, sampleRate);
|
|
81
|
+
return { audio: wav, mediaType: "audio/wav" };
|
|
82
|
+
}
|
|
83
|
+
if (output.format === "pcm") {
|
|
84
|
+
const { pcmBytes, sampleRate } = await decodeToPcmBytes(audio, mediaType);
|
|
85
|
+
return {
|
|
86
|
+
audio: pcmBytes,
|
|
87
|
+
mediaType: mediaTypeForOutput({
|
|
88
|
+
format: "pcm",
|
|
89
|
+
sampleRate,
|
|
90
|
+
}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const { pcmBytes, sampleRate } = await decodeToPcmBytes(audio, mediaType);
|
|
94
|
+
const mp3 = await encodePcm16ToMp3({
|
|
95
|
+
pcm: pcmBytes,
|
|
96
|
+
sampleRate,
|
|
97
|
+
bitrateKbps: output.bitrate,
|
|
98
|
+
});
|
|
99
|
+
return { audio: mp3, mediaType: "audio/mpeg" };
|
|
100
|
+
}
|
|
101
|
+
export async function applyOptionalOutputConversion(args) {
|
|
102
|
+
if (!args.output) {
|
|
103
|
+
return { audio: args.audio, mediaType: args.mediaType };
|
|
104
|
+
}
|
|
105
|
+
return await convertDecodableAudioToOutput({
|
|
106
|
+
audio: args.audio,
|
|
107
|
+
mediaType: args.mediaType,
|
|
108
|
+
output: resolveOutputForLocalConversion(args.output),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=audio-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-output.js","sourceRoot":"","sources":["../src/audio-output.ts"],"names":[],"mappings":"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"}
|
package/dist/audio-utils.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare function parseMediaTypeParam(mediaType: string, name: string): number | undefined;
|
|
2
2
|
export declare function wrapPcm16Mono(pcm: Uint8Array, sampleRate: number): Promise<Uint8Array>;
|
|
3
|
+
export declare function resamplePcm16(pcm: Int16Array, fromRate: number, toRate: number): Promise<Int16Array>;
|
|
4
|
+
export declare function uint8ArrayToBase64(bytes: Uint8Array): string;
|
|
3
5
|
export declare function base64ToUint8Array(b64: string): Uint8Array;
|
|
4
6
|
//# sourceMappingURL=audio-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAcA,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAapB;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CA0BrB;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,CAmDrB;AAKD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAS5D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAO1D"}
|
package/dist/audio-utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BufferTarget, EncodedAudioPacketSource, EncodedPacket, Output, WavOutputFormat, } from "mediabunny";
|
|
1
|
+
import { ALL_FORMATS, BlobSource, BufferTarget, Conversion, EncodedAudioPacketSource, EncodedPacket, Input, Output, WavOutputFormat, } from "mediabunny";
|
|
2
2
|
const PARAM_REGEX_CACHE = new Map();
|
|
3
3
|
export function parseMediaTypeParam(mediaType, name) {
|
|
4
4
|
let re = PARAM_REGEX_CACHE.get(name);
|
|
@@ -39,6 +39,60 @@ export async function wrapPcm16Mono(pcm, sampleRate) {
|
|
|
39
39
|
}
|
|
40
40
|
return new Uint8Array(buffer);
|
|
41
41
|
}
|
|
42
|
+
export async function resamplePcm16(pcm, fromRate, toRate) {
|
|
43
|
+
if (fromRate === toRate || pcm.length === 0) {
|
|
44
|
+
return pcm;
|
|
45
|
+
}
|
|
46
|
+
const sourceWav = await wrapPcm16Mono(new Uint8Array(pcm.buffer, pcm.byteOffset, pcm.byteLength), fromRate);
|
|
47
|
+
const blob = new Blob([sourceWav.slice()], { type: "audio/wav" });
|
|
48
|
+
const input = new Input({
|
|
49
|
+
source: new BlobSource(blob),
|
|
50
|
+
formats: ALL_FORMATS,
|
|
51
|
+
});
|
|
52
|
+
// Output is required by Conversion.init; we drop samples in `process` so
|
|
53
|
+
// no encode happens — the buffer stays empty and we never read it.
|
|
54
|
+
const output = new Output({
|
|
55
|
+
format: new WavOutputFormat(),
|
|
56
|
+
target: new BufferTarget(),
|
|
57
|
+
});
|
|
58
|
+
const captured = [];
|
|
59
|
+
let totalFrames = 0;
|
|
60
|
+
const conversion = await Conversion.init({
|
|
61
|
+
input,
|
|
62
|
+
output,
|
|
63
|
+
audio: {
|
|
64
|
+
sampleRate: toRate,
|
|
65
|
+
numberOfChannels: 1,
|
|
66
|
+
// WaveMuxer asserts on empty output, so samples pass through to the encoder;
|
|
67
|
+
// we capture s16 here to skip decoding the output WAV.
|
|
68
|
+
process: (sample) => {
|
|
69
|
+
const buf = new Int16Array(sample.numberOfFrames);
|
|
70
|
+
sample.copyTo(buf, { format: "s16", planeIndex: 0 });
|
|
71
|
+
captured.push(buf);
|
|
72
|
+
totalFrames += buf.length;
|
|
73
|
+
return sample;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
showWarnings: false,
|
|
77
|
+
});
|
|
78
|
+
await conversion.execute();
|
|
79
|
+
const out = new Int16Array(totalFrames);
|
|
80
|
+
let offset = 0;
|
|
81
|
+
for (const chunk of captured) {
|
|
82
|
+
out.set(chunk, offset);
|
|
83
|
+
offset += chunk.length;
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
// Chunked to avoid call-stack overflow on large payloads (~32k arg limit).
|
|
88
|
+
const BASE64_CHUNK = 0x80_00;
|
|
89
|
+
export function uint8ArrayToBase64(bytes) {
|
|
90
|
+
let s = "";
|
|
91
|
+
for (let i = 0; i < bytes.length; i += BASE64_CHUNK) {
|
|
92
|
+
s += String.fromCharCode.apply(null, Array.from(bytes.subarray(i, i + BASE64_CHUNK)));
|
|
93
|
+
}
|
|
94
|
+
return btoa(s);
|
|
95
|
+
}
|
|
42
96
|
export function base64ToUint8Array(b64) {
|
|
43
97
|
const binary = atob(b64);
|
|
44
98
|
const bytes = new Uint8Array(binary.length);
|
package/dist/audio-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,MAAM,EACN,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,IAAY;IAEZ,IAAI,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,kDAAkD;QAClD,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,IAAI,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC7D,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAe,EACf,UAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,IAAI,eAAe,EAAE;QAC7B,MAAM,EAAE,IAAI,YAAY,EAAE;KAC3B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;QACvB,aAAa,EAAE;YACb,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU;SACX;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ export interface Pcm16Segment {
|
|
|
3
3
|
readonly pcm: Int16Array;
|
|
4
4
|
readonly sampleRate: number;
|
|
5
5
|
}
|
|
6
|
-
export declare function decodeToPcm16(data: Uint8Array, mediaType: string): Pcm16Segment;
|
|
7
6
|
export declare const DEFAULT_VOLUME_DBFS = -20;
|
|
8
7
|
export declare function dbfsToInt16Rms(dbfs: number): number;
|
|
9
8
|
export declare function normalizeRms(segments: readonly Pcm16Segment[], targetRmsAmplitude?: number): Pcm16Segment[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcm-concat.d.ts","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"pcm-concat.d.ts","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAwCD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAKD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,kBAAkB,SAA2B,GAC5C,YAAY,EAAE,CAQhB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
|