> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ai-coustics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js analysis API

> Collect mono audio and analyze the retained window with Tyto.

**Version:** `@ai-coustics/aic-sdk` 0.24.0, Core SDK 0.24.0. [API index](/reference/sdk/api/node/index) · [Node.js quickstart](/reference/sdk/language-bindings/nodejs).

<span id="node-analyzer" />

## `Analyzer`

A mono audio collector and analysis engine combined in one JavaScript object. Use an analysis model such as Tyto. Initialize, buffer original audio and analyze the retained window. Only the model's maximum window is retained; new audio replaces older audio. Short histories are zero-padded.

<span id="node-analyzer-constructor" />

### `Analyzer.constructor`

```typescript theme={null}
constructor(model: Model, licenseKey: string)
```

`model` must be a live analysis model, not an enhancement or VAD model. `licenseKey` is an SDK credential. Construction synchronously creates the collector/analyzer pair and can throw for credentials, model type or disposal errors. There is no per-instance `OtelConfig` constructor argument. Call `initialize` before `buffer`.

<span id="node-analyzer-dispose" />

### `Analyzer.dispose`

```typescript theme={null}
dispose(): void
```

Synchronously releases the collector and analyzer; repeated calls are harmless. It waits for the analyzer lock if analysis is running, so it can block the event loop. Queued analysis that obtains the lock afterward rejects. Later operations throw `Analyzer has been disposed`. Await outstanding analysis first.

<span id="node-analyzer-initialize" />

### `Analyzer.initialize`

```typescript theme={null}
initialize(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): void
```

`sampleRate` is a whole-number rate in Hz; `blockSize` is a positive whole-number mono sample count. Query `model.getOptimalBlockSize(sampleRate)` for the preferred size. Omitted, `undefined` or `null` `variableBlockSize` means `false`, requiring exactly `blockSize` samples. Variable mode allows shorter blocks, with possible buffering delay, but rejects larger blocks. Unsupported configurations throw an SDK error. Initialization allocates memory. Configures the collector synchronously. For Tyto, use its native 16 kHz input and the block size returned by the model query. A failed reinitialization leaves the collector uninitialized; correct the configuration before buffering again.

<span id="node-analyzer-buffer" />

### `Analyzer.buffer`

```typescript theme={null}
buffer(audio: Float32Array): void
```

Reads a mono `Float32Array` without modifying it and collects samples for later analysis. Returns `void`; it does not run the analysis model. Requires successful initialization and the configured block length. It can continue while `analyzeAsync` runs because collection does not take the analyzer lock. Older audio is discarded as the model window fills.

<span id="node-analyzer-analyze" />

### `Analyzer.analyze`

```typescript theme={null}
analyze(): AnalysisResult
```

Synchronously analyzes the latest buffered window and returns `AnalysisResult`. Blocks the calling thread and can wait for an earlier async analysis. Short or empty histories are zero-padded; the SDK does not provide a readiness check here. Track the amount of real buffered audio yourself. Throws for disallowed processing or native analysis failure.

<span id="node-analyzer-analyzeasync" />

### `Analyzer.analyzeAsync`

```typescript theme={null}
analyzeAsync(): Promise<AnalysisResult>
```

Queues analysis on the libuv pool and resolves to `AnalysisResult`. The worker reads the available buffered snapshot when it executes; submission does not freeze the collector. Collection can continue in parallel. Await before assuming completion or disposing. Native analysis failures reject the promise. This is expensive analysis, not an audio-callback operation.

<span id="node-analyzer-reset" />

### `Analyzer.reset`

```typescript theme={null}
reset(): void
```

Synchronously requests clearing of the collector state while retaining audio settings. Until the next `buffer` applies that reset, analysis uses a zero-filled snapshot instead of stale audio. Waits for the analyzer lock and can block during async analysis.

<span id="node-analyzer-updatebearertoken" />

### `Analyzer.updateBearerToken`

```typescript theme={null}
updateBearerToken(token: string): void
```

`token` replaces a bearer token on a JWT-authenticated session. Both the original credential and replacement must be JWT-form licenses. A synchronous failure preserves the previous token. Return without error confirms local format acceptance, not backend acceptance; subsequent reporting can reject the token and eventually disable work. Obtain a valid replacement to recover. This operation allocates and takes a lock; keep it outside audio callbacks. See [authentication](/models/get-started/authenticate-apps). This synchronous method also waits for any active analysis holding the analyzer lock.

<span id="node-analyzer-terminatesession" />

### `Analyzer.terminateSession`

```typescript theme={null}
terminateSession(): void
```

Requests termination of the associated session. Once termination is handled, further analysis is disallowed. This does not release the native object; still call `dispose()`. Completion may involve asynchronous session handling when another session remains active. Do not use it as a flush operation. Synchronous; can block on the analyzer lock and session handling.

<span id="node-analysisresult" />

## `AnalysisResult`

A returned object with seven `number` fields, not a class to construct. Values are normalized scores from 0 to 1. Lower values indicate less problematic audio except for `speakerLoudness`, where loudness itself is measured. These are model estimates, not a guarantee of transcription quality. See [Tyto](/models/audio-insight/tyto) for interpretation.

<span id="node-analysisresult-riskscore" />

### `AnalysisResult.riskScore`

```typescript theme={null}
riskScore: number
```

Estimate of risk to downstream speech-model performance. Evaluate against observed failures; it is not a word error rate or a probability guarantee for an individual request.

<span id="node-analysisresult-speakerreverb" />

### `AnalysisResult.speakerReverb`

```typescript theme={null}
speakerReverb: number
```

Speaker distance/reverberation score. Lower values indicate less problematic reverberation.

<span id="node-analysisresult-speakerloudness" />

### `AnalysisResult.speakerLoudness`

```typescript theme={null}
speakerLoudness: number
```

Speaker loudness score. Interpret it separately from the other risk dimensions; lower is not universally better.

<span id="node-analysisresult-interferingspeech" />

### `AnalysisResult.interferingSpeech`

```typescript theme={null}
interferingSpeech: number
```

Score for speech from sources other than the main speaker.

<span id="node-analysisresult-noise" />

### `AnalysisResult.noise`

```typescript theme={null}
noise: number
```

Ambient or environmental noise score.

<span id="node-analysisresult-codecdegradation" />

### `AnalysisResult.codecDegradation`

```typescript theme={null}
codecDegradation: number
```

Score for lossy speech-codec artifacts, including narrowband or low-bitrate degradation.

<span id="node-analysisresult-packetloss" />

### `AnalysisResult.packetLoss`

```typescript theme={null}
packetLoss: number
```

Score for dropouts and discontinuities, such as packet loss, frame erasure, jitter or CPU overload. It is not a network packet counter.

## Example

With the pinned package installed, set `AIC_SDK_LICENSE` and run `node analyze-window.cjs path/to/tyto.aicmodel`. It collects at least 5 s of silence and prints seven score fields. For call-quality evaluation, use representative audio and follow [real-time analysis](/models/audio-insight/real-time-analysis) for window interpretation.

```javascript analyze-window.cjs theme={null}
const { Analyzer, Model } = require('@ai-coustics/aic-sdk');

async function main() {
  const key = process.env.AIC_SDK_LICENSE;
  const modelPath = process.argv[2];
  if (!key || !modelPath) throw new Error('Set AIC_SDK_LICENSE and pass a Tyto model path');
  const model = Model.fromFile(modelPath);
  let analyzer;
  try {
    analyzer = new Analyzer(model, key);
    const rate = model.getOptimalSampleRate();
    const size = model.getOptimalBlockSize(rate);
    analyzer.initialize(rate, size);
    const silence = new Float32Array(size);
    for (let samples = 0; samples < 5 * rate; samples += size) analyzer.buffer(silence);
    const result = await analyzer.analyzeAsync();
    console.log(result);
  } finally {
    if (analyzer) analyzer.dispose();
    model.dispose();
  }
}
main().catch((error) => { console.error(error.message); process.exitCode = 1; });
```

## Related

[Node.js API index](/reference/sdk/api/node/index) · [Errors and recovery](/reference/sdk/api/node/errors) · [Stream lifecycle](/reference/concepts/streams-and-state).
