Sonix Recorder
Unified audio recorder for capturing microphone input.
What is SonixRecorder?
SonixRecorder captures audio from the device microphone and saves it to a file. It provides:
Multiple formats: M4A (AAC), MP3, WAV
Quality presets: Voice (16kHz), Standard (44.1kHz), High (48kHz)
Real-time level: Monitor audio levels during recording
Echo cancellation: Remove echo when used with playback
Segment recording: Record specific portions for practice apps
Use it for:
Voice recording apps: Capture voice memos, podcasts
Karaoke apps: Record vocals along with backing track
Practice apps: Record student performances for analysis
Audio analysis: Feed audio to pitch detection in real-time
Quick Start
Kotlin
val recorder = SonixRecorder.create("/path/to/output.m4a")
recorder.start()
// ... record for a while ...
recorder.stop()
recorder.release()Swift
let recorder = SonixRecorder.create(outputPath: "/path/to/output.m4a")
recorder.start()
// ... record for a while ...
recorder.stop()
recorder.release()Usage Tiers
Tier 1: Zero-Config (80% of users)
Kotlin
val recorder = SonixRecorder.create("/path/to/output.m4a")
recorder.start()
// ...
recorder.stop()Swift
let recorder = SonixRecorder.create(outputPath: "/path/to/output.m4a")
recorder.start()
// ...
recorder.stop()Tier 2: With Config (15% of users)
Kotlin
val config = SonixRecorderConfig.Builder()
.preset(SonixRecorderConfig.STANDARD)
.format(AudioFormat.MP3)
.echoCancellation(true)
.onRecordingStarted { println("Started!") }
.onRecordingStopped { path -> println("Saved to: $path") }
.build()
val recorder = SonixRecorder.create("/path/to/output.mp3", config)Swift
let config = SonixRecorderConfig.Builder()
.preset(.standard)
.format(.mp3)
.echoCancellation(true)
.onRecordingStarted { print("Started!") }
.onRecordingStopped { path in print("Saved to: \(path)") }
.build()
let recorder = SonixRecorder.create(outputPath: "/path/to/output.mp3", config: config)Tier 3: Real-time Audio Access (5% of users)
Kotlin
// Access raw audio buffers for real-time processing
recorder.audioBuffers.collect { buffer ->
val samples = buffer.toFloatArray()
pitchDetector.detect(samples, buffer.sampleRate)
}Swift
// Access raw audio buffers for real-time processing
for await buffer in recorder.audioBuffers {
let samples = buffer.toFloatArray()
pitchDetector.detect(samples: samples, sampleRate: buffer.sampleRate)
}Platform Notes
iOS
Requires microphone permission in Info.plist
Audio session automatically configured for recording
Hardware sample rate may differ from requested (check
actualSampleRate)Echo cancellation uses iOS AEC
Android
Requires RECORD_AUDIO permission
Audio focus handled automatically
Sample rate depends on device capabilities
Echo cancellation uses Android AEC
Common Pitfalls
Forgetting to release: Call
recorder.release()to free resourcesMissing permissions: Ensure microphone permission is granted before recording
Wrong file extension: Extension determines format;
.m4a= M4A,.mp3= MP3Not calling stop: Recording continues until
stop()is calledIgnoring actualSampleRate: Hardware may use different rate than requested
See also
Configuration options for recording
For playing recorded audio
For coordinated recording with live evaluation
For pitch detection on recorded audio
Types
Listener interface for recording events. Alternative to StateFlow observation and Builder callbacks.
Properties
The actual sample rate being used by the hardware. On iOS, this may differ from the configured rate. Use this value for encoding to ensure correct playback speed.
Raw audio buffer flow for advanced use cases (visualization, analysis). Each buffer contains PCM data that can be converted to floats.
Number of buffers currently available in the pool. Use this to monitor zero-allocation audio processing health.
Whether the buffer pool was ever exhausted during recording. If true, the pool size may need to be increased for optimal real-time performance. This is critical for Calibra DSP integration where allocations cause latency spikes.
Error state, null if no error
Whether currently recording
Most recent audio buffer for polling-style access. Prefer audioBuffers flow for reactive processing.
Full recording state machine
Playback-synchronized time when using playback sync. Returns recording duration if no sync provider is set.
Functions
Clear all segment data (for retry).
Get all recorded segments in this session.
Set playback provider for timeline synchronization. Can be changed during recording.
Set a listener for recording events.
Start recording a segment within the current session. Requires enableSegmentRecording() in Builder.
Stop recording segment and save to file.
Sync recording timeline with current playback position. Call after seeking in backing track.