Skip to content

Conversation

@vishesh-sachan
Copy link
Member

Summary

Adds an in-app microphone testing component to the Recording Settings page, allowing users to verify their microphone is working and check audio levels without leaving the app or using external tools.

Type of Change

  • feat: New feature

Related Issue

Closes #965

Changes Made

New Component: MicTest.svelte

  • Built a standalone microphone testing component for the Recording Settings page
  • Integrates Web Audio API (AudioContext, AnalyserNode) for real-time audio level detection
  • Features device selection dropdown with refresh capability
  • Displays real-time volume visualization with color-coded progress bar (green/yellow/red)
  • Shows percentage display for precise level reading

Technical Implementation

  • Audio Processing: RMS (Root Mean Square) calculation with noise gate (threshold: 30) to filter background noise, wind, and breath sounds
  • Device Enumeration: Uses vadRecorder.enumerateDevices (browser device IDs) instead of rpc.recorder.enumerateDevices (CPAL/FFmpeg names) for Web Audio API compatibility
  • Device Selection: Exact device constraint (deviceId: { exact: String(selectedTestDevice) }) prevents device fallback
  • State Management: Svelte 5 runes ($state, $derived, $effect) for reactive state
  • Error Handling: wellcrafted tryAsync pattern with clear error messages for permissions and device issues
  • Cleanup: Proper disposal of AudioContext, MediaStream, and animation frames

Integration

  • Added to Recording Settings page (+page.svelte) after device selection
  • Conditionally rendered for manual and VAD recording modes only
  • Defaults device selector to currently selected recording device

Code Quality

  • Follows repository conventions (TypeScript style, Svelte patterns, error handling)
  • Uses top-level constant for noiseGateThreshold (30) for consistency

Testing

How to Test This Feature

Prerequisites:

  1. Navigate to Settings → Recording
  2. Ensure recording method is set to "Manual" or "VAD" (test component won't show for other modes)

Testing Steps:

  1. Basic Functionality

    • Scroll to the "Test Microphone" card
    • Verify device selector shows available microphones
    • Default device should match your current recording device
    • Click "Start Test" button
    • Speak into your microphone
    • Volume bar should animate and show percentage (0-100%)
    • Click "Stop Test" to end
  2. Device Selection

    • Select different microphones from the dropdown
    • Click refresh button to update device list
    • Start test with each device
    • Verify audio levels respond only to the selected device (no cross-talk)
  3. Noise Gate

    • Start test
    • Stay silent - volume should remain at 0%
    • Make quiet sounds (gentle breath, typing) - should still show 0%
    • Speak normally - volume should register above 0%
  4. No Audio Warning

    • Start test
    • Stay completely silent for 3+ seconds
    • Warning should appear: "No audio detected. Try speaking into the microphone or check your device settings."
    • Speak - warning should disappear
  5. Error Scenarios

    • Deny microphone permission when prompted - should show "Microphone permission denied" error
    • Disconnect microphone during test - should show "Device not found" error
    • Device selector should disable while test is active
  6. Cleanup

    • Start test, then navigate away from settings
    • Return to settings - test should not be running
    • No memory leaks or hanging audio contexts

Desktop App Testing

  • Tested on macOS

General Testing

  • Tested with multiple microphone devices
  • Verified exact device selection (no cross-talk between devices)
  • Checked for console errors
  • Tested UI responsiveness and color transitions
  • Verified proper cleanup on component unmount
  • Tested permission denied scenario
  • Tested no audio detected warning
  • Verified noise gate filtering works correctly

Checklist

  • My code follows the project's coding standards (see CONTRIBUTING.md)
  • I've used type instead of interface in TypeScript
  • I've used absolute imports where applicable
  • I've tested my changes thoroughly
  • My changes don't break existing functionality
  • I've updated documentation (if needed)

Screenshots/Recordings

Screenshot 2025-12-06 at 12 13 54 PM Screenshot 2025-12-06 at 12 14 21 PM

Copy link
Member

@rupokghosh rupokghosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test Microphone option in the App

2 participants