95 lines
4.1 KiB
Kotlin
95 lines
4.1 KiB
Kotlin
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<AudioRoutingSettings> = 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
|
|
}
|
|
}
|
|
}
|