Use session.mic to receive raw audio chunks from the glasses microphone and detect when the user is speaking. This is separate from transcription - subscribing to session.mic gives you raw audio data, not text.

Audio Chunks

Receive raw PCM audio data from the microphone:
const cleanup = session.mic.onChunk((chunk) => {
  // chunk.arrayBuffer - raw PCM audio data
  // chunk.sampleRate  - sample rate (typically 16000 Hz)
  const buffer = chunk.arrayBuffer;
  const sampleRate = chunk.sampleRate || 16000;
});

// Stop receiving audio chunks
cleanup();
Audio chunks arrive continuously while the microphone is active. Each chunk is a small buffer of PCM audio data (typically 20ms worth at 16kHz).

Voice Activity Detection

Detect when the user starts or stops speaking:
const cleanup = session.mic.onVoiceActivity((isSpeaking) => {
  if (isSpeaking) {
    session.display.showText("Listening...");
  } else {
    session.display.showText("Silent");
  }
});
You can also check the current state:
const speaking = session.mic.isSpeaking;  // true/false
const active = session.mic.isActive;       // true if mic is streaming

Stop the Microphone

Call session.mic.stop() to turn off the microphone and stop all audio chunk and voice activity callbacks:
session.mic.stop();
This is useful when your app no longer needs audio input and you want to conserve battery. Subscribing to onChunk or onVoiceActivity again will restart the microphone.

Check Permission

Use session.mic.hasPermission to check whether your app has microphone access before subscribing:
if (session.mic.hasPermission) {
  session.mic.onChunk((chunk) => {
    // process audio
  });
} else {
  session.logger.warn("Microphone permission not granted");
}

When to Use Mic vs Transcription

Use caseUse this
Show what the user said as textsession.transcription
Run your own speech recognition modelsession.mic
Detect when the user is speaking (VAD)session.mic
Record audio for later processingsession.mic
Build a voice command systemsession.transcription
Stream audio to an external API (Whisper, Deepgram, etc.)session.mic
Stop the mic to save batterysession.mic.stop()
Subscribing to session.transcription does NOT give you raw audio. Subscribing to session.mic does NOT give you transcription text. They are independent. Either one activates the hardware microphone. If you want both, subscribe to both.

Common Patterns

Send audio to an external API

session.mic.onChunk(async (chunk) => {
  await fetch("https://your-api.com/audio", {
    method: "POST",
    body: chunk.arrayBuffer,
    headers: { "Content-Type": "application/octet-stream" },
  });
});

Buffer audio while speaking

const audioBuffers: ArrayBuffer[] = [];
let recording = false;

session.mic.onVoiceActivity((isSpeaking) => {
  if (isSpeaking) {
    recording = true;
    audioBuffers.length = 0;
  } else if (recording) {
    recording = false;
    processRecording(audioBuffers);
  }
});

session.mic.onChunk((chunk) => {
  if (recording) {
    audioBuffers.push(chunk.arrayBuffer);
  }
});

Permissions

Your app needs the microphone permission to receive audio chunks. Add it in the Developer Console when creating or editing your app.

Migrating from v2

// v2
session.events.onAudioChunk((chunk) => { ... });

// v3
session.mic.onChunk((chunk) => { ... });
Voice activity detection (session.mic.onVoiceActivity, session.mic.isSpeaking), session.mic.stop(), and session.mic.hasPermission are new in v3 and have no v2 equivalent. See the Migration Guide for the full list of changes.