Kodio 0.2.0 Help

AudioWaveform

AudioWaveform is a Compose component that visualizes audio amplitudes. Use it during recording (via RecorderState.liveAmplitudes) or to show a static waveform with playback progress.

Basic usage

Connect to RecorderState.liveAmplitudes for real-time visualization during recording:

val recorderState = rememberRecorderState() if (recorderState.isRecording) { AudioWaveform( amplitudes = recorderState.liveAmplitudes, modifier = Modifier.fillMaxWidth().height(64.dp) ) }

The amplitudes parameter expects a List<Float> where each value is between 0.0 (silence) and 1.0 (maximum). Values outside that range are clamped.

Waveform styles

Pass a WaveformStyle to change how amplitudes are drawn. The modifier must include size constraints (for example fillMaxWidth() and height()).

Classic vertical bars:

AudioWaveform( amplitudes = amplitudes, style = WaveformStyle.Bar( width = 3.dp, spacing = 2.dp, cornerRadius = 1.5.dp, alignment = WaveformAlignment.Center, minHeight = 2.dp, ), modifier = Modifier.fillMaxWidth().height(64.dp) )

Thin spikes, similar to SoundCloud:

AudioWaveform( amplitudes = amplitudes, style = WaveformStyle.Spike( width = 2.dp, spacing = 1.dp, ), modifier = Modifier.fillMaxWidth().height(64.dp) )

Smooth connected line:

AudioWaveform( amplitudes = amplitudes, style = WaveformStyle.Line( strokeWidth = 2.dp, smoothing = 0.5f, ), modifier = Modifier.fillMaxWidth().height(64.dp) )

Symmetric bars above and below center. Useful for live recording:

AudioWaveform( amplitudes = amplitudes, style = WaveformStyle.Mirrored( barWidth = 4.dp, gap = 4.dp, ), modifier = Modifier.fillMaxWidth().height(80.dp) )

Filled area under a smooth curve:

AudioWaveform( amplitudes = amplitudes, style = WaveformStyle.Filled( smoothing = 0.3f, alignment = WaveformAlignment.Bottom, ), modifier = Modifier.fillMaxWidth().height(64.dp) )

Color customization

Colors are configured with WaveformColors, not individual Color parameters on AudioWaveform.

AudioWaveform( amplitudes = amplitudes, colors = WaveformColors.solidColor(Color.Blue), modifier = Modifier.fillMaxWidth().height(64.dp) )
AudioWaveform( amplitudes = amplitudes, colors = WaveformColors.gradient( colors = listOf(Color.Cyan, Color.Magenta) ), modifier = Modifier.fillMaxWidth().height(64.dp) )
AudioWaveform( amplitudes = amplitudes, colors = WaveformColors.solidColor(MaterialTheme.colorScheme.primary), modifier = Modifier.fillMaxWidth().height(64.dp) )

Preset colors

Preset

Type

Description

WaveformColors.Green

Solid

Default green theme

WaveformColors.Blue

Solid

Blue

WaveformColors.Red

Solid

Red

WaveformColors.Purple

Solid

Purple

WaveformColors.Orange

Solid

Orange

WaveformColors.Cyan

Solid

Cyan

WaveformColors.GreenGradient

Gradient

Green to light green

WaveformColors.BlueGradient

Gradient

Blue to cyan

WaveformColors.PurpleGradient

Gradient

Purple to pink

WaveformColors.SunsetGradient

Gradient

Orange to yellow

WaveformColors.OceanGradient

Gradient

Deep teal to light cyan

WaveformColors.NeonGradient

Gradient

Magenta to cyan

AudioWaveform( amplitudes = amplitudes, colors = WaveformColors.PurpleGradient, modifier = Modifier.fillMaxWidth().height(64.dp) )

Playback progress

When progress is less than 1f, bars before the progress point use progressColor (or waveColor if unset). Pass onProgressChange to enable tap and drag seeking:

AudioWaveform( amplitudes = amplitudes, progress = playbackProgress, onProgressChange = { newProgress -> seekTo(newProgress) }, colors = WaveformColors( waveColor = SolidColor(Color.Gray), progressColor = SolidColor(Color.Green), ), modifier = Modifier.fillMaxWidth().height(48.dp) )

Set animate = false to snap amplitudes without animation.

Full example

A recording screen with a mirrored waveform:

@Composable fun WaveformDemo() { val recorderState = rememberRecorderState() Column( modifier = Modifier.fillMaxSize().padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Box( modifier = Modifier .fillMaxWidth() .height(120.dp) .background( color = MaterialTheme.colorScheme.surfaceVariant, shape = RoundedCornerShape(12.dp) ) .padding(16.dp), contentAlignment = Alignment.Center ) { if (recorderState.isRecording) { AudioWaveform( amplitudes = recorderState.liveAmplitudes, modifier = Modifier.fillMaxSize(), style = WaveformStyle.Mirrored(), colors = WaveformColors.gradient( colors = listOf( MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.tertiary ) ), ) } else { Text( "Tap to record", color = MaterialTheme.colorScheme.onSurfaceVariant ) } } Spacer(Modifier.height(24.dp)) Button(onClick = { recorderState.toggle() }) { Text(if (recorderState.isRecording) "Stop" else "Record") } } }

Parameters reference

amplitudes: List<Float>

Audio amplitude values between 0.0 and 1.0.

modifier: Modifier

Compose modifier. Must include size constraints (for example fillMaxWidth() and height()).

style: WaveformStyle

Visualization style. Default: WaveformStyle.Bar().

colors: WaveformColors

Color configuration. Default: WaveformColors.default().

progress: Float

Playback progress from 0.0 to 1.0. Default: 1f (fully played).

onProgressChange: ((Float) -> Unit)?

Callback when the user seeks via tap or drag. Pass null to disable interaction.

animate: Boolean

Whether amplitude changes animate. Default: true.

animationSpec: AnimationSpec<Float>

Animation spec for amplitude transitions when animate is true.

Last modified: 03 July 2026