loadIncienso method
Load an Incienso preset into the generator, configuring all parameters (frequencies, binaural beat, isochronic, visual, breathing) and optionally auto-starting playback.
For multi-phase inciensos, starts a timer-driven phase runner that transitions between phases at the scheduled times.
Implementation
Future<void> loadIncienso(Incienso incienso, {bool autoStart = true}) async {
_activeIncienso = incienso;
// ── Base frequencies ──
currentFreq.value = incienso.leftFrequencyHz;
chamberPreset.mainFrequency ??= NeomFrequency();
chamberPreset.mainFrequency!.frequency = incienso.leftFrequencyHz;
final beat = incienso.rightFrequencyHz - incienso.leftFrequencyHz;
setBinauralBeat(beat: beat);
// ── Isochronic pulse ──
if (incienso.pulseFrequencyHz > 0) {
setIsochronicFrequency(incienso.pulseFrequencyHz);
await setIsochronicEnabled(true);
} else {
await setIsochronicEnabled(false);
}
// ── Neuro state (from binaural beat) ──
setNeuroState(incienso.targetState);
// ── Breathing guide ──
setBreathMode(NeomBreathMode.box);
// ── Phase runner / timeline playback ──
_stopPhaseRunner();
_stopTimelinePlayback();
if (incienso.isRecorded) {
// Recorded incienso — use timeline keyframe playback
// (skip phase runner entirely; the timeline contains everything)
} else if (incienso.isMultiPhase) {
_currentPhaseIndex = 0;
_applyPhase(incienso.phases.first);
}
// ── Auto-start playback ──
if (autoStart && !isPlaying.value) {
await playStopPreview();
}
// ── Schedule phase transitions or timeline playback ──
if (incienso.isRecorded) {
_startTimelinePlayback(incienso);
} else if (incienso.isMultiPhase) {
_startPhaseRunner(incienso);
}
update([AppPageIdConstants.generator]);
}