loadIncienso method

Future<void> loadIncienso(
  1. Incienso incienso, {
  2. bool autoStart = true,
})

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]);
}