---
title: Audio & microfono
description: Come l'SDK gestisce microfono e audio full-duplex, mute, vincoli del device input e diagnosi dei problemi audio.
---

L'SDK si occupa interamente della parte audio: cattura il **microfono**,
riproduce l'**audio** della controparte e gestisce la conversione di formato e lo
streaming sul canale della chiamata. L'audio è **full-duplex** (operatore e
controparte si sentono contemporaneamente). Tu non gestisci stream o codec: ti
basta dare i permessi e, se vuoi, scegliere il device di input.

<Callout type="info">
  La pagina deve essere servita su **HTTPS** (o `localhost`) perché il browser
  conceda l'accesso al microfono. La **prima chiamata** può inoltre richiedere un
  **gesto dell'utente** (es. un click) per sbloccare l'audio sotto le policy di
  autoplay del browser.
</Callout>

## Mute / unmute

Durante una chiamata attiva puoi silenziare e riattivare il microfono
dell'operatore con `mute(on)`:

```ts
call.mute(true);   // silenzia il microfono
call.mute(false);  // riattiva
console.log(call.muted); // stato corrente: true | false
```

`mute` agisce sul microfono verso la controparte; l'audio in arrivo continua a
essere riprodotto. La proprietà `call.muted` riflette lo stato corrente.

## Vincoli del device input

I vincoli del microfono sono `MediaTrackConstraints` (gli stessi che passeresti a
`getUserMedia({ audio })`). Per impostazione predefinita l'SDK abilita
cancellazione dell'eco, soppressione del rumore e guadagno automatico.

### In configurazione (`audioConstraints`)

Puoi impostare i vincoli iniziali alla creazione dell'istanza:

```ts
const op = new AudinOperator({
  coreUrl: "https://core.audin.ai",
  getToken,
  audioConstraints: {
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true,
  },
});
```

### A runtime (`setAudioConstraints`)

Per **cambiare device input** (o qualsiasi altro vincolo) mentre l'SDK è in uso,
usa `setAudioConstraints(constraints)`:

```ts
op.setAudioConstraints({
  deviceId: { exact: selectedDeviceId },
  echoCancellation: true,
});
```

<Callout type="info">
  I nuovi vincoli vengono letti quando si apre il canale audio della **prossima**
  chiamata. Il cambio ha quindi effetto dal **prossimo** `dial()` o dalla
  prossima chiamata in entrata accettata: una chiamata **già in corso** mantiene
  il device con cui il suo bridge è stato aperto (il microfono non viene
  riaperto a metà chiamata).
</Callout>

## Selezionare il device nel browser

Per offrire all'operatore la scelta del microfono, enumera i device audio di
input con le API standard del browser e passa il `deviceId` scelto a
`setAudioConstraints`:

```ts
// Richiede prima il permesso microfono, poi elenca gli input audio.
const devices = await navigator.mediaDevices.enumerateDevices();
const microfoni = devices.filter((d) => d.kind === "audioinput");

// L'operatore sceglie nella tua UI → applica il device.
op.setAudioConstraints({ deviceId: { exact: microfoni[0].deviceId } });
```

<Callout type="info">
  Le etichette dei device (`label`) sono visibili solo **dopo** che è stato
  concesso il permesso microfono. Tipicamente si richiede una volta il permesso
  (anche con una breve chiamata a `getUserMedia`), poi si ri-enumera per
  popolare il menu di scelta.
</Callout>

## Diagnosi: "non si sente l'operatore"

Se la controparte non sente l'operatore (o viceversa), procedi così:

<Steps>
<Step>
**Verifica i permessi del microfono.** Controlla che il browser **e** il sistema
operativo abbiano concesso l'accesso al microfono per il sito. Un permesso negato
si manifesta tipicamente con un evento `error` di codice `MIC_PERMISSION_DENIED`.
</Step>

<Step>
**Controlla che sia selezionato il device giusto.** Se ci sono più microfoni
(integrato, cuffie USB, webcam…), assicurati che `setAudioConstraints` punti al
device effettivamente in uso. Ricorda che il cambio device ha effetto dalla
**prossima** chiamata.
</Step>

<Step>
**Prova un indicatore di livello (VU meter).** Nella tua UI puoi mostrare il
livello del microfono in tempo reale per confermare che l'input arrivi: è un modo
rapido per distinguere "microfono muto" da "audio non instradato".
</Step>

<Step>
**Verifica lo stato di `mute`.** Controlla `call.muted`: una chiamata può essere
semplicemente silenziata.
</Step>

<Step>
**Conferma il contesto sicuro e il gesto utente.** La pagina deve essere su
**HTTPS** (o `localhost`) e la prima chiamata può richiedere un click per
sbloccare l'audio. Vedi anche la pagina
[Troubleshooting](/docs/operator-sdk/troubleshooting).
</Step>
</Steps>

## DTMF

L'oggetto `OperatorCall` espone `sendDtmf(digit)` per i toni DTMF (`0`-`9`, `*`,
`#`):

```ts
call.sendDtmf("5");
```

<Callout type="info">
  **`sendDtmf` inoltra la cifra alla rete telefonica.** La cifra viene validata,
  emessa come messaggio di controllo sul canale della chiamata e il server
  inietta il corrispondente tono DTMF **in-band sulla tratta telefonica**: la
  controparte (es. un IVR) lo sente, quindi la navigazione IVR funziona. Nota:
  l'operatore **non** sente il proprio tono — il feedback locale alla pressione
  dei tasti è a carico della tua UI.
</Callout>

## Prossimi passi

<Cards>
  <Card href="/docs/operator-sdk/api-reference" title="API reference" description="audioConstraints, setAudioConstraints, mute e sendDtmf al completo." />
  <Card href="/docs/operator-sdk/troubleshooting" title="Troubleshooting" description="Errori comuni (microfono, WebSocket, token) e FAQ." />
</Cards>
