Kodio 0.1.1 Help

RecorderState

RecorderState is a Compose state holder that makes building recording UIs simple. It handles recording lifecycle, permission requests, error states, and provides live amplitude data for waveform visualizations.

Basic usage

Create a recording UI in just a few lines:

@Composable fun VoiceRecorder() { val recorderState = rememberRecorderState() Button(onClick = { recorderState.toggle() }) { Text(if (recorderState.isRecording) "⏹ Stop" else "🎙 Record") } }

The state automatically triggers recomposition when recording starts, stops, or errors occur.

Configuration

Customize the recorder with quality presets and callbacks:

val recorderState = rememberRecorderState( quality = AudioQuality.High, onRecordingComplete = { recording -> // Called when recording stops viewModel.save(recording) } )

Waveform visualization

RecorderState provides liveAmplitudes—a list of normalized amplitude values (0.0 to 1.0) updated in real-time during recording:

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

Permission handling

RecorderState tracks permission status and can request it:

@Composable fun RecorderWithPermission() { val recorderState = rememberRecorderState() if (recorderState.needsPermission) { // Show permission request UI Column(horizontalAlignment = Alignment.CenterHorizontally) { Text("🎤 Microphone access required") Button(onClick = { recorderState.requestPermission() }) { Text("Grant Access") } } } else { // Show recording UI RecordButton(recorderState) } }

Error handling

Display errors when they occur:

recorderState.error?.let { error -> AlertDialog( onDismissRequest = { recorderState.clearError() }, title = { Text("Recording Error") }, text = { Text(error.message ?: "Unknown error") }, confirmButton = { TextButton(onClick = { recorderState.clearError() }) { Text("OK") } } ) }

Complete example

Here's a full recording UI with permission handling, waveform, and error display:

@Composable fun CompleteRecorder() { val recorderState = rememberRecorderState( quality = AudioQuality.Voice, onRecordingComplete = { recording -> println("Recorded ${recording.calculatedDuration}") } ) Column( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { // Permission check if (recorderState.needsPermission) { Text("🎤 Microphone access needed") Spacer(Modifier.height(8.dp)) Button(onClick = { recorderState.requestPermission() }) { Text("Grant Access") } return@Column } // Waveform if (recorderState.isRecording) { AudioWaveform( amplitudes = recorderState.liveAmplitudes, modifier = Modifier.fillMaxWidth().height(80.dp), barColor = MaterialTheme.colorScheme.primary ) Spacer(Modifier.height(16.dp)) } // Record button Button( onClick = { recorderState.toggle() }, colors = ButtonDefaults.buttonColors( containerColor = if (recorderState.isRecording) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary ) ) { Text(if (recorderState.isRecording) "⏹ Stop Recording" else "🎙 Start Recording") } // Error dialog recorderState.error?.let { error -> AlertDialog( onDismissRequest = { recorderState.clearError() }, title = { Text("Error") }, text = { Text(error.message ?: "Recording failed") }, confirmButton = { TextButton(onClick = { recorderState.clearError() }) { Text("OK") } } ) } } }

API reference

Properties

isRecording: Boolean

Currently recording audio.

isProcessing: Boolean

Processing after stop (encoding, etc.).

recording: AudioRecording?

The completed recording, if available.

hasRecording: Boolean

true if recording is not null.

liveAmplitudes: List<Float>

Real-time amplitude values (0.0-1.0) for waveform display.

error: AudioError?

Current error, if any.

needsPermission: Boolean

true if microphone permission hasn't been granted.

Methods

start()

Start recording.

stop()

Stop recording.

toggle()

Start if stopped, stop if recording.

reset()

Discard the current recording.

requestPermission()

Request microphone permission from the OS.

clearError()

Clear the current error state.

Last modified: 13 January 2026