On the phone
Microphone audio
Stream audio from the glasses microphone into your phone companion.
Capture works while your app is running. MIRA decodes the audio on the phone for you, so there’s no browser microphone permission to request.
Start and stop
| Method | Does |
|---|---|
onCapture(handler) | Registers a handler for audio frames and returns an unsubscribe function. Register it before you start. |
startCapture() | Starts capture, or joins one that’s already running, and resolves with {sampleRate: 16000, channels: 1, format: "s16le"}. It rejects if the glasses microphone isn’t available. |
stopCapture() | Releases your app’s capture and resolves with {ok: true}. Anything else using the microphone keeps running. |
Audio frames
Each call to your handler receives {samples, sampleRate, channels, sampleOffset}:
samplesis anInt16Arrayof signed 16-bit mono audio at 16 kHz, with the phone’s microphone gain already applied. Divide by 32768 to get values between -1 and 1.sampleOffsetis the position of the first sample since capture started. Use it to spot gaps before you stitch frames into a recording.- Frames hold roughly 100 to 256 ms of audio. While your page is busy, MIRA keeps at most 256 ms waiting and drops the oldest audio beyond that, so keep handlers short.
Example: a level meter
Phone screen
<button id="mic-start">Start mic</button>
<button id="mic-stop">Stop mic</button>
<output id="mic-level">0%</output>
<script>
const level = document.getElementById("mic-level");
const unsubscribe = miraCompanion.onCapture(({ samples }) => {
let peak = 0;
for (const sample of samples) peak = Math.max(peak, Math.abs(sample));
level.textContent = Math.round(peak / 32768 * 100) + "%";
});
document.getElementById("mic-start").onclick = () => miraCompanion.startCapture()
.catch((error) => { level.textContent = error.message || String(error); });
document.getElementById("mic-stop").onclick = () => miraCompanion.stopCapture()
.then(() => { level.textContent = "0%"; });
window.addEventListener("pagehide", unsubscribe);
</script>When capture stops
- Muting the microphone pauses delivery.
- Leaving the page, replacing the app or disconnecting the glasses stops capture. After the glasses reconnect, call
startCapture()again. - Closing the phone sheet keeps your companion running, so call
stopCapture()as soon as your recording or analysis ends. - Unsubscribing removes your handler but doesn’t stop capture.
Send results, not audio
Do the audio work on the phone. Draw waveforms and levels in your companion, and send the glasses small summaries with setLatestForApp and companion::Realtime. Raw audio is too big for the glasses module’s memory and for companion messages.
For speech to text, use MIRA’s live transcription from the glasses app (see Phone requests) rather than the browser’s SpeechRecognition, which isn’t a supported backend for MIRA apps.