diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt index 385f1e4..5ce1e0a 100644 --- a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt +++ b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt @@ -228,10 +228,10 @@ data class AudioRecorderSettings( return copy(forceExactMaxDuration = forceExactMaxDuration) } - fun isOutputFormatCompatible(format: Int): Boolean { - val supportedFormats = ENCODER_SUPPORTED_OUTPUT_FORMATS_MAP[getEncoder()]!! + fun isEncoderCompatible(encoder: Int): Boolean { + val supportedFormats = ENCODER_SUPPORTED_OUTPUT_FORMATS_MAP[encoder]!! - return supportedFormats.contains(format) + return supportedFormats.contains(getOutputFormat()) } companion object { @@ -326,5 +326,16 @@ data class AudioRecorderSettings( put(MediaRecorder.AudioEncoder.OPUS, arrayOf(MediaRecorder.OutputFormat.OGG)) } }.toMap() + val OUTPUT_FORMATS_SUPPORTED_ENCODER_MAP = (mutableMapOf>().also { map -> + ENCODER_SUPPORTED_OUTPUT_FORMATS_MAP.forEach { (encoder, formats) -> + formats.forEach { format -> + if (map.containsKey(format)) { + map[format]!!.plus(encoder) + } else { + map[format] = arrayOf(encoder) + } + } + } + }).toMap() } } diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/EncoderTile.kt b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/EncoderTile.kt index c8b345e..e574e54 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/EncoderTile.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/SettingsScreen/atoms/EncoderTile.kt @@ -1,12 +1,16 @@ package app.myzel394.alibi.ui.components.SettingsScreen.atoms +import android.media.MediaRecorder import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AudioFile import androidx.compose.material.icons.filled.Memory import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -19,6 +23,9 @@ import app.myzel394.alibi.db.AppSettings import app.myzel394.alibi.db.AudioRecorderSettings import app.myzel394.alibi.ui.components.atoms.ExampleListRoulette import app.myzel394.alibi.ui.components.atoms.SettingsTile +import app.myzel394.alibi.ui.utils.IconResource +import com.maxkeppeker.sheets.core.models.base.Header +import com.maxkeppeker.sheets.core.models.base.IconSource import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState import com.maxkeppeler.sheets.list.ListDialog import com.maxkeppeler.sheets.list.models.ListOption @@ -27,7 +34,9 @@ import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable -fun EncoderTile() { +fun EncoderTile( + snackbarHostState: SnackbarHostState +) { val scope = rememberCoroutineScope() val showDialog = rememberUseCaseState() val dataStore = LocalContext.current.dataStore @@ -36,18 +45,45 @@ fun EncoderTile() { .collectAsState(initial = AppSettings.getDefaultInstance()) .value + val updatedOutputFormatLabel = stringResource(R.string.ui_settings_option_encoder_extra_outputFormatChanged) + fun updateValue(encoder: Int?) { scope.launch { + val isCompatible = if (encoder == null || encoder == MediaRecorder.AudioEncoder.DEFAULT) + true + else settings.audioRecorderSettings.isEncoderCompatible(encoder) + dataStore.updateData { it.setAudioRecorderSettings( it.audioRecorderSettings.setEncoder(encoder) ) } + + if (!isCompatible) { + dataStore.updateData { + it.setAudioRecorderSettings( + it.audioRecorderSettings.setOutputFormat(null) + ) + } + + snackbarHostState.showSnackbar( + message = updatedOutputFormatLabel, + withDismissAction = true, + duration = SnackbarDuration.Long, + ) + } } } ListDialog( state = showDialog, + header = Header.Default( + title = stringResource(R.string.ui_settings_option_encoder_title), + icon = IconSource( + painter = IconResource.fromImageVector(Icons.Default.Memory).asPainterResource(), + contentDescription = null, + ) + ), selection = ListSelection.Single( showRadioButtons = true, options = IntRange(0, 7).map { index -> diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt index 3287df1..463c4b7 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/screens/SettingsScreen.kt @@ -129,7 +129,7 @@ fun SettingsScreen( ) BitrateTile() SamplingRateTile() - EncoderTile() + EncoderTile(snackbarHostState = snackbarHostState) OutputFormatTile() } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 210bcf0..ae619fc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,11 +52,11 @@ A higher bitrate means better quality but also larger file size Set the bitrate for the audio recording Output Format - Encoder has been changed because the current one was incompatible with this output format Sampling rate Define how many samples per second are taken from the audio signal Set the sampling rate Encoder + Output Format has been changed because the current one was incompatible with this encoder Auto Recording paused Audio Recording has been paused