Calibra Live Eval
Real-time singing evaluation session with segment support.
What is Live Evaluation?
Live evaluation scores a singer's performance in real-time by comparing their pitch to a reference melody. Use it for:
Karaoke apps: Score singing as users perform
Music education: Provide instant feedback on pitch accuracy
Practice apps: Track improvement across attempts
The session breaks a song into segments (phrases or sections), evaluates each one, and tracks the user's progress.
When to Use
| Scenario | Use This? | Why |
|---|---|---|
| Score singing against reference | Yes | Core use case |
| Just detect pitch (no scoring) | No | Use CalibraPitch.createDetector() |
| Analyze recorded audio (not live) | No | Use CalibraMelodyEval |
| Voice activity detection only | No | Use CalibraVAD |
Quick Start
Kotlin
// 1. Create detector and session
val detector = CalibraPitch.createDetector()
val session = CalibraLiveEval.create(lessonMaterial, detector = detector)
// 2. Prepare (loads reference, extracts features)
session.prepareSession()
// 3. Start segment and feed audio
session.startPracticingSegment(0)
recorder.audioBuffers.collect { buffer ->
session.feedAudioSamples(buffer.toFloatArray(), sampleRate = 48000)
}
// 4. Get result
val result = session.finishPracticingSegment()
println("Score: ${result?.score}")
// 5. Cleanup
session.closeSession()Swift
// 1. Create detector and session
let detector = CalibraPitch.createDetector()
let session = CalibraLiveEval.create(
reference: lessonMaterial,
detector: detector
)
// 2. Prepare (loads reference, extracts features)
try await session.prepareSession()
// 3. Start segment and feed audio
session.startPracticingSegment(index: 0)
for await buffer in recorder.audioBuffers {
session.feedAudioSamples(samples: buffer.toFloatArray(), sampleRate: 48000)
}
// 4. Get result
if let result = session.finishPracticingSegment() {
print("Score: \(result.score)")
}
// 5. Cleanup
session.closeSession()Usage Tiers
Tier 1: Convenience API (80% of users)
Pass player and recorder handles; the session coordinates everything.
val session = CalibraLiveEval.create(
reference = lessonMaterial,
detector = CalibraPitch.createDetector(),
player = player,
recorder = recorder
)
session.prepareSession()
session.onSegmentComplete { result -> showScore(result) }
session.startPracticingSegment(0) // Seeks, plays, records, scores automaticallyTier 2: Low-Level API (15% of users)
Manually manage audio; full control over timing.
val session = CalibraLiveEval.create(reference, detector = detector)
session.prepareSession()
session.startPracticingSegment(0)
recorder.audioBuffers.collect { buffer ->
session.feedAudioSamples(buffer.toFloatArray(), buffer.sampleRate)
}
val result = session.finishPracticingSegment()Phase Progressions
Singalong:
IDLE → SINGING → EVALUATEDSingafter:
IDLE → LISTENING → SINGING → EVALUATED
Observe phase StateFlow for UI updates.
State Machine
IDLE ──prepareSession()──► READY
READY ──startPracticingSegment()──► PRACTICING
PRACTICING ──finishPracticingSegment()──► BETWEEN (or COMPLETED if last)
PRACTICING ──discardCurrentSegment()──► BETWEEN
PRACTICING ──seekToSegment()──► PRACTICING (new segment)
BETWEEN ──startPracticingSegment()──► PRACTICING
BETWEEN ──advanceToNextSegment()──► PRACTICING (or COMPLETED if last)
BETWEEN ──finishSession()──► COMPLETED
* ──closeSession()──► (released)Ownership Model
| Dependency | Ownership | Rationale |
|---|---|---|
detector | Owned - session closes it | Created specifically for this session |
player | Borrowed - caller manages | Shared resource, UI may need direct access |
recorder | Borrowed - caller manages | Shared resource, may be reused |
See also
For pitch detection without scoring
Input format with reference audio and segments
Configuration for auto-advance, thresholds, etc.
Per-segment scoring results
Properties
Current active segment state, or null if not practicing.
Map of segment index to list of attempts (from SegmentResultStore).
Current playback position in seconds (from player or clock in manual mode).
Whether recording is active.
Real-time pitch point for visualization (includes time and confidence).
Live pitch contour accumulated during the current segment.
Current practice phase. Observe this for unified singalong/singafter UI.
Whether pitch processing is currently enabled
Reference key in Hz from LessonMaterial.
Current session state. Observe this in your UI.
Current student key in Hz. 0 = same as reference.
Functions
Advance to the next segment.
Manually trigger LISTENING → SINGING transition.
Close the session and release all resources.
Discard the current segment without scoring.
Feed audio samples to the session.
Finish the current segment and get its result.
Finish the session and get aggregated results.
Get all results for a specific segment.
Check if a segment has been completed at least once.
Register callback for phase changes. Called when practice phase transitions (e.g., LISTENING → SINGING).
Register callback for reference end (singafter mode). Called when reference audio finishes playing, before student starts singing.
Register callback for segment completion. Called when a segment finishes with its result.
Register callback for session completion. Called when all segments are finished.
Pause playback and recording.
Prepare the session for practice.
Restart the session from a clean state.
Resume from paused state.
Retry the current segment.
Seek to a specific segment (discards current attempt if practicing).
Seek to a specific time position.
Enable or disable pitch processing (smoothing + octave correction) at runtime.
Set student key for transposition.
Start practicing a specific segment.