> ## 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 enhancement API

> Process mono audio synchronously or asynchronously and control enhancement state.

**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-processor" />

## `Processor`

Synchronous mono enhancement on the calling JavaScript thread. Use an enhancement or bypass model and a separate instance for each stream. Initialize before processing. The input buffer is modified in place.

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

### `Processor.constructor`

```typescript theme={null}
constructor(model: Model, licenseKey: string, otelConfig?: OtelConfig | undefined | null)
```

`model` must be a live model handle of the required type. `licenseKey` is the SDK credential string; see [authentication](/models/get-started/authenticate-apps). Construction is synchronous and can throw for an invalid key, a disposed model or a model-type mismatch. Omitted or `null` `otelConfig` uses environment settings; otherwise pass an [OtelConfig](/reference/sdk/api/node/models-and-config#node-otelconfig) object. There is no automatic initialization.

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

### `Processor.dispose`

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

Destroys the native processor synchronously. Repeated calls have no effect. Later methods on this object throw `Processor has been disposed`. A context retained separately no longer reaches a live processor.

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

### `Processor.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. The streaming SDK accepts supported rates from 8,000 through 192,000 Hz. Call on the setup path before `process`.

<span id="node-processor-process" />

### `Processor.process`

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

`audio` must be a mono `Float32Array` of normalized samples, nominally -1 to 1, matching initialization. Writes enhanced samples directly into the caller's array and returns `void`. Throws before initialization, after disposal, for a block mismatch or when processing is disallowed. If the underlying buffer is shared with another worker, prevent all concurrent access while this call runs. Copy input yourself if you need the original.

<span id="node-processor-getcontext" />

### `Processor.getContext`

```typescript theme={null}
getContext(): ProcessorContext
```

Returns an independent JavaScript handle to this processor's shared control state. Throws after processor disposal. Releasing the context does not destroy the processor.

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

### `Processor.terminateSession`

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

Requests termination of the associated session. Once termination is handled, further processing 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. Runs synchronously and may block.

<span id="node-processorasync" />

## `ProcessorAsync`

Mono enhancement through Node's shared libuv worker pool. Construction and disposal remain synchronous. Await initialization, then await each block before submitting the next block on the same instance. A mutex protects native access but does not guarantee submission order for overlapping calls. Use separate instances for concurrent streams.

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

### `ProcessorAsync.constructor`

```typescript theme={null}
constructor(model: Model, licenseKey: string, otelConfig?: OtelConfig | undefined | null)
```

`model` must be a live model handle of the required type. `licenseKey` is the SDK credential string; see [authentication](/models/get-started/authenticate-apps). Construction is synchronous and can throw for an invalid key, a disposed model or a model-type mismatch. Omitted or `null` `otelConfig` uses environment settings; otherwise pass an [OtelConfig](/reference/sdk/api/node/models-and-config#node-otelconfig) object. There is no automatic initialization.

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

### `ProcessorAsync.dispose`

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

Synchronous and idempotent. Waits if a worker holds the instance lock, so it can block the JavaScript thread. It invalidates all handles sharing this instance, including one returned by `withConfig`. Queued operations that acquire the lock after disposal reject. Await pending operations before disposing.

<span id="node-processorasync-withconfig" />

### `ProcessorAsync.withConfig`

```typescript theme={null}
withConfig(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): Promise<ProcessorAsync>
```

`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 reject the promise with an SDK error. Initialization allocates memory. Runs initialization on a worker and resolves to another handle to the same native instance, not a cloned processor. Disposing either handle invalidates both. Retain the original handle until initialization succeeds so a rejection can still be cleaned up.

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

### `ProcessorAsync.initialize`

```typescript theme={null}
initialize(sampleRate: number, blockSize: number, variableBlockSize?: boolean | undefined | null): Promise<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 reject the promise with an SDK error. Initialization allocates memory. Runs on a libuv worker and resolves to `void`. Await it before any processing. SDK initialization failures reject the promise.

<span id="node-processorasync-process" />

### `ProcessorAsync.process`

```typescript theme={null}
process(audio: Float32Array): Promise<Float32Array<ArrayBuffer>>
```

Copies `audio` into worker-owned memory on the JavaScript thread before queuing work. Resolves to a new `Float32Array<ArrayBuffer>` of enhanced samples; the caller's array stays unchanged. The result never uses `SharedArrayBuffer`. Input must meet the same mono format and block-length contract as `Processor.process`. Native errors reject the promise. Await each block to preserve stream order; do not queue an unbounded audio backlog.

<span id="node-processorasync-getcontext" />

### `ProcessorAsync.getContext`

```typescript theme={null}
getContext(): Promise<ProcessorContext>
```

Resolves to a `ProcessorContext`. The worker waits for the instance lock. Context methods are synchronous after the handle resolves. Rejects if the processor was disposed before the worker acquired it.

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

### `ProcessorAsync.terminateSession`

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

Requests termination of the associated session. Once termination is handled, further processing 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. Runs on a libuv worker; await the returned promise before disposal.

<span id="node-processorcontext" />

## `ProcessorContext`

Control handle obtained from `Processor.getContext()` or `await ProcessorAsync.getContext()`. There is no public constructor or `dispose()` method. Its synchronous methods use the shared control state and may be called while processing runs. A retained handle remains valid after the processor is disposed, but no longer controls a live processor. Keep lifecycle changes outside audio callbacks.

<span id="node-processorcontext-setparameter" />

### `ProcessorContext.setParameter`

```typescript theme={null}
setParameter(parameter: ProcessorParameter, value: number): void
```

`parameter` selects a `ProcessorParameter`; `value` must meet its range. Converts the JavaScript number to a 32-bit float before setting it. Invalid enum/value arguments throw. See the enum below for bypass's boolean readback behavior.

<span id="node-processorcontext-getparameter" />

### `ProcessorContext.getParameter`

```typescript theme={null}
getParameter(parameter: ProcessorParameter): number
```

Returns the current stored value for `parameter`, widened from a 32-bit float. For example, setting `0.8` can read back as `Math.fround(0.8)`. Invalid parameter values throw.

<span id="node-processorcontext-getaudiodelay" />

### `ProcessorContext.getAudioDelay`

```typescript theme={null}
getAudioDelay(): number
```

Returns audio delay in samples at the configured input rate, including model and block-adaptation buffering. Before initialization, it reports delay at the model's default audio configuration. Convert to milliseconds with `samples * 1000 / sampleRate`. It is not wall-clock inference time.

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

### `ProcessorContext.reset`

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

Requests clearing of processing state and delay buffers before subsequent processing. Audio configuration is preserved. Use at a seek or stream discontinuity, not between adjacent blocks. It neither emits nor flushes delayed output.

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

### `ProcessorContext.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).

<span id="node-processorparameter" />

## `ProcessorParameter`

Exported numeric enum used by `ProcessorContext`. Parameters are stored as 32-bit floats even though JavaScript exposes `number`. Read back the value when exact comparison matters. Changes are observed by subsequent processing; they do not rewrite already produced audio.

<span id="node-processorparameter-bypass" />

### `ProcessorParameter.Bypass`

```typescript theme={null}
Bypass = 0
```

Numeric enum value `0`. The parameter accepts values from 0 to 1: `0` enables enhancement and any value greater than `0` enables bypass. Readback is exactly `0` or `1`. Default is `0`. Bypass preserves processing delay; it is not an undelayed raw-audio path.

<span id="node-processorparameter-enhancementlevel" />

### `ProcessorParameter.EnhancementLevel`

```typescript theme={null}
EnhancementLevel = 1
```

Numeric enum value `1`. Accepts 0 to 1. Defaults are taken from model metadata, falling back to `1` where no model default is supplied; read the effective value from the context. The effect depends on the model: compare Quail model suppression and Rook Multi Speaker listening quality on representative audio.

## Example

With the pinned package installed, set `AIC_SDK_LICENSE` and run `node enhance-block.cjs path/to/enhancement.aicmodel`. This processes one silent block and reports its length and `newBuffer: true`. It demonstrates buffer ownership, not enhancement quality. Use the [WAV quickstart](/reference/sdk/language-bindings/nodejs) for meaningful audio output.

```javascript enhance-block.cjs theme={null}
const { Model, ProcessorAsync } = 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 an enhancement model path');
  const model = Model.fromFile(modelPath);
  let processor;
  try {
    processor = new ProcessorAsync(model, key);
    const rate = model.getOptimalSampleRate();
    const size = model.getOptimalBlockSize(rate);
    await processor.initialize(rate, size);
    const input = new Float32Array(size);
    const enhanced = await processor.process(input);
    console.log({ samples: enhanced.length, newBuffer: enhanced.buffer !== input.buffer });
  } finally {
    if (processor) processor.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).
