package de.waypointaudio.data import android.content.Context import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map /** * Aufnahmeformat für PTT-Mitschnitt. * M4A_AAC wird produktiv unterstützt; WAV ist in v2.1.0 absichtlich deaktiviert * (siehe Handoff). Der enum-Wert bleibt vorhanden für künftige Erweiterung. */ enum class PttRecordingFormat { M4A_AAC, WAV } /** * Globale Audio-Routing- und PTT-Einstellungen für Live/PTT. * * Gerätekennungen (AudioDeviceInfo.id) sind Sitzungs-spezifisch und können sich nach * einem Neustart oder nach dem Trennen/Verbinden von Bluetooth-Geräten ändern. * Wenn ein gespeichertes Gerät nicht mehr verfügbar ist, wird automatisch der * Systemstandard verwendet. * * @param selectedInputDeviceId ID des Eingabegeräts, null = Systemstandard * @param selectedOutputDeviceId ID des Ausgabegeräts, null = Systemstandard * @param liveOutputEnabled Mikrofon-Loop auf Ausgabegerät (klassische PTT). * Standard: true (rückwärtskompatibel zu v2.0.8). * @param recordingEnabled PTT-Aufnahme aktiv. Standard: false. * @param recordingFormat Aufnahmeformat. Standard: M4A_AAC. */ data class AudioRoutingSettings( val selectedInputDeviceId: Int? = null, val selectedOutputDeviceId: Int? = null, val liveOutputEnabled: Boolean = true, val recordingEnabled: Boolean = false, val recordingFormat: PttRecordingFormat = PttRecordingFormat.M4A_AAC ) private val Context.audioRoutingDataStore by preferencesDataStore(name = "audio_routing_settings") /** * Persistenz-Schicht für Audio-Routing- und PTT-Einstellungen via DataStore. */ class AudioRoutingStore(private val context: Context) { private companion object { val KEY_INPUT_DEVICE_ID = intPreferencesKey("selected_input_device_id") val KEY_OUTPUT_DEVICE_ID = intPreferencesKey("selected_output_device_id") val KEY_LIVE_OUTPUT = booleanPreferencesKey("ptt_live_output_enabled") val KEY_RECORDING_ENABLED = booleanPreferencesKey("ptt_recording_enabled") val KEY_RECORDING_FORMAT = stringPreferencesKey("ptt_recording_format") // Sentinel: -1 means "use system default" (null cannot be stored as Int) const val NO_DEVICE = -1 } val settings: Flow = context.audioRoutingDataStore.data .map { prefs -> AudioRoutingSettings( selectedInputDeviceId = prefs[KEY_INPUT_DEVICE_ID].takeIf { it != null && it != NO_DEVICE }, selectedOutputDeviceId = prefs[KEY_OUTPUT_DEVICE_ID].takeIf { it != null && it != NO_DEVICE }, liveOutputEnabled = prefs[KEY_LIVE_OUTPUT] ?: true, recordingEnabled = prefs[KEY_RECORDING_ENABLED] ?: false, recordingFormat = prefs[KEY_RECORDING_FORMAT] ?.let { runCatching { PttRecordingFormat.valueOf(it) }.getOrNull() } ?: PttRecordingFormat.M4A_AAC ) } suspend fun save(settings: AudioRoutingSettings) { context.audioRoutingDataStore.edit { prefs -> prefs[KEY_INPUT_DEVICE_ID] = settings.selectedInputDeviceId ?: NO_DEVICE prefs[KEY_OUTPUT_DEVICE_ID] = settings.selectedOutputDeviceId ?: NO_DEVICE prefs[KEY_LIVE_OUTPUT] = settings.liveOutputEnabled prefs[KEY_RECORDING_ENABLED] = settings.recordingEnabled prefs[KEY_RECORDING_FORMAT] = settings.recordingFormat.name } } suspend fun clearInputDevice() { context.audioRoutingDataStore.edit { prefs -> prefs[KEY_INPUT_DEVICE_ID] = NO_DEVICE } } suspend fun clearOutputDevice() { context.audioRoutingDataStore.edit { prefs -> prefs[KEY_OUTPUT_DEVICE_ID] = NO_DEVICE } } }