# Visualizer (Android)

A tiny Jetpack Compose demo that visualizes the device audio output using the Android `Visualizer` API.

It attaches to audio session 0 (global output mix) and renders:
- Waveform view (time-domain samples)
- FFT magnitude bars (frequency-domain snapshot)
- Simple metrics (sample count, RMS, peak, first bytes)

The UI is written with Jetpack Compose and organized into small composables.

## Features
- VisualizerController wrapper around `android.media.audiofx.Visualizer`
- Global output (session 0) capture for convenience
- Waveform and FFT visualizations
- Permission handling (RECORD_AUDIO)
- Basic controls to Start/Stop capture

## Requirements
- Android 7.0 (API 24) or later
- Microphone permission (RECORD_AUDIO)
- Audio playing on the device (e.g., music app) to see the visualization

## How it works
- `VisualizerController` sets up the `Visualizer` with the maximum supported capture size and a reasonable capture rate (half of the device max).
- It registers `OnDataCaptureListener` to receive waveform and FFT byte arrays.
- The app processes those bytes in Compose to draw a waveform path and magnitude bars for FFT bins.

Key parts of the UI:
- `PermissionSection` asks for RECORD_AUDIO when missing.
- `WaveformView` draws the latest waveform as a continuous path.
- `FftBarsView` computes magnitude per bin and draws vertical bars.
- `MetricsSection` shows simple stats and a short hex-ish dump of the first bytes.
- `ControlButtons` exposes Start/Stop buttons.

## Build & Run
1. Open the project in Android Studio (Giraffe or newer recommended) and let it sync.
2. Select a connected device or emulator running API 24+.
3. Run the app.

Or via command line:

```bash
./gradlew :app:assembleDebug
```

Then install the generated APK on a device.

## Permissions
This app requests `android.permission.RECORD_AUDIO` at runtime.

Note: The `Visualizer` API reads audio data for visualization — it does not record or store audio.

## Limitations & Notes
- Some OEMs/devices restrict or alter access to the global output mix (session 0). On such devices the visualizer may return zeros or fail to initialize.
- You need active audio playback from another app to see non-zero data.
- Bluetooth/headphones/audio effects may influence sampling output.
- The FFT values are raw magnitudes derived from interleaved real/imag bytes and are not calibrated to physical units.

## KDocs
Public classes and composables are documented with KDoc in the source:
- `VisualizerController` (class, start/stop)
- `MainActivity` and `VisualizerScreen`
- Composables: `WaveformView`, `FftBarsView`, `PermissionSection`, `ControlButtons`, `MetricsSection`
- `AudioSessionsTracker` (placeholder)

You can browse KDocs directly in code. There is no generated site output configured for this sample.

## Project Info
- Min SDK: 24
- Target/Compile SDK: 36
- Kotlin/JVM target: 11
- UI: Jetpack Compose Material 3

This is a learning/demo project — feel free to adapt it to your needs.