93 lines
3.5 KiB
Kotlin
93 lines
3.5 KiB
Kotlin
package solutions.tretter.mindmachine.session
|
|
|
|
import solutions.tretter.mindmachine.domain.SessionConfig
|
|
import solutions.tretter.mindmachine.domain.SessionMode
|
|
import solutions.tretter.mindmachine.domain.SessionPreset
|
|
import kotlin.math.roundToInt
|
|
|
|
/**
|
|
* Lightweight model for the current (non-timeline) setup sliders.
|
|
*
|
|
* Note: Dana's spec introduces a full timeline editor; this model is just to keep
|
|
* the existing SetupScreen compiling while we wire the dedicated editor screen.
|
|
*/
|
|
|
|
data class TimelineModel(
|
|
val preset: SessionPreset,
|
|
val durationSeconds: Int,
|
|
val parameters: List<Parameter>
|
|
) {
|
|
|
|
data class Parameter(
|
|
val id: String,
|
|
val name: String,
|
|
val description: String,
|
|
val min: Float,
|
|
val max: Float,
|
|
val defaultValue: Float,
|
|
val value: Float,
|
|
val units: String = ""
|
|
)
|
|
|
|
companion object {
|
|
fun createForPreset(preset: SessionPreset, durationSeconds: Int): TimelineModel {
|
|
val flashSec = preset.flashIntervalMs.toFloat() / 1000f
|
|
val params = listOf(
|
|
Parameter(
|
|
id = "flash_interval",
|
|
name = "Flash Interval",
|
|
description = "Time between flashes in the visual pattern",
|
|
min = 0.05f,
|
|
max = 2.0f,
|
|
defaultValue = flashSec,
|
|
value = flashSec,
|
|
units = "s"
|
|
),
|
|
Parameter(
|
|
id = "carrier_frequency",
|
|
name = "Carrier Frequency",
|
|
description = "Base audio frequency for binaural beats",
|
|
min = 80f,
|
|
max = 400f,
|
|
defaultValue = preset.carrierFrequencyHz,
|
|
value = preset.carrierFrequencyHz,
|
|
units = "Hz"
|
|
),
|
|
Parameter(
|
|
id = "binaural_difference",
|
|
name = "Binaural Difference",
|
|
description = "Frequency difference between left/right audio channels",
|
|
min = 0.5f,
|
|
max = 20f,
|
|
defaultValue = preset.binauralDifferenceHz,
|
|
value = preset.binauralDifferenceHz,
|
|
units = "Hz"
|
|
)
|
|
)
|
|
return TimelineModel(preset = preset, durationSeconds = durationSeconds, parameters = params)
|
|
}
|
|
}
|
|
|
|
fun updateParameterValue(id: String, newValue: Float): TimelineModel {
|
|
return copy(parameters = parameters.map { if (it.id == id) it.copy(value = newValue) else it })
|
|
}
|
|
|
|
fun toSessionConfig(mode: SessionMode): SessionConfig {
|
|
val flashIntervalMs = ((parameters.firstOrNull { it.id == "flash_interval" }?.value
|
|
?: (preset.flashIntervalMs.toFloat() / 1000f)) * 1000f).roundToInt()
|
|
val carrier = parameters.firstOrNull { it.id == "carrier_frequency" }?.value ?: preset.carrierFrequencyHz
|
|
val diff = parameters.firstOrNull { it.id == "binaural_difference" }?.value ?: preset.binauralDifferenceHz
|
|
|
|
return SessionConfig(
|
|
presetId = preset.id,
|
|
durationSec = durationSeconds,
|
|
mode = mode,
|
|
visualPatternType = preset.visualPatternType,
|
|
flashIntervalMs = flashIntervalMs,
|
|
intensityPercent = preset.intensityPercent,
|
|
carrierFrequencyHz = carrier,
|
|
binauralDifferenceHz = diff
|
|
)
|
|
}
|
|
}
|