feat: Automatically select "Auto" output format on incompatible encoder change

This commit is contained in:
Myzel394 2023-08-09 22:06:02 +02:00
parent 6c16928896
commit 236a0d04e7
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
4 changed files with 53 additions and 6 deletions

View File

@ -228,10 +228,10 @@ data class AudioRecorderSettings(
return copy(forceExactMaxDuration = forceExactMaxDuration) return copy(forceExactMaxDuration = forceExactMaxDuration)
} }
fun isOutputFormatCompatible(format: Int): Boolean { fun isEncoderCompatible(encoder: Int): Boolean {
val supportedFormats = ENCODER_SUPPORTED_OUTPUT_FORMATS_MAP[getEncoder()]!! val supportedFormats = ENCODER_SUPPORTED_OUTPUT_FORMATS_MAP[encoder]!!
return supportedFormats.contains(format) return supportedFormats.contains(getOutputFormat())
} }
companion object { companion object {
@ -326,5 +326,16 @@ data class AudioRecorderSettings(
put(MediaRecorder.AudioEncoder.OPUS, arrayOf(MediaRecorder.OutputFormat.OGG)) put(MediaRecorder.AudioEncoder.OPUS, arrayOf(MediaRecorder.OutputFormat.OGG))
} }
}.toMap() }.toMap()
val OUTPUT_FORMATS_SUPPORTED_ENCODER_MAP = (mutableMapOf<Int, Array<Int>>().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()
} }
} }

View File

@ -1,12 +1,16 @@
package app.myzel394.alibi.ui.components.SettingsScreen.atoms package app.myzel394.alibi.ui.components.SettingsScreen.atoms
import android.media.MediaRecorder
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AudioFile
import androidx.compose.material.icons.filled.Memory import androidx.compose.material.icons.filled.Memory
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState 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.db.AudioRecorderSettings
import app.myzel394.alibi.ui.components.atoms.ExampleListRoulette import app.myzel394.alibi.ui.components.atoms.ExampleListRoulette
import app.myzel394.alibi.ui.components.atoms.SettingsTile 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.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.list.ListDialog import com.maxkeppeler.sheets.list.ListDialog
import com.maxkeppeler.sheets.list.models.ListOption import com.maxkeppeler.sheets.list.models.ListOption
@ -27,7 +34,9 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun EncoderTile() { fun EncoderTile(
snackbarHostState: SnackbarHostState
) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val showDialog = rememberUseCaseState() val showDialog = rememberUseCaseState()
val dataStore = LocalContext.current.dataStore val dataStore = LocalContext.current.dataStore
@ -36,18 +45,45 @@ fun EncoderTile() {
.collectAsState(initial = AppSettings.getDefaultInstance()) .collectAsState(initial = AppSettings.getDefaultInstance())
.value .value
val updatedOutputFormatLabel = stringResource(R.string.ui_settings_option_encoder_extra_outputFormatChanged)
fun updateValue(encoder: Int?) { fun updateValue(encoder: Int?) {
scope.launch { scope.launch {
val isCompatible = if (encoder == null || encoder == MediaRecorder.AudioEncoder.DEFAULT)
true
else settings.audioRecorderSettings.isEncoderCompatible(encoder)
dataStore.updateData { dataStore.updateData {
it.setAudioRecorderSettings( it.setAudioRecorderSettings(
it.audioRecorderSettings.setEncoder(encoder) it.audioRecorderSettings.setEncoder(encoder)
) )
} }
if (!isCompatible) {
dataStore.updateData {
it.setAudioRecorderSettings(
it.audioRecorderSettings.setOutputFormat(null)
)
}
snackbarHostState.showSnackbar(
message = updatedOutputFormatLabel,
withDismissAction = true,
duration = SnackbarDuration.Long,
)
}
} }
} }
ListDialog( ListDialog(
state = showDialog, 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( selection = ListSelection.Single(
showRadioButtons = true, showRadioButtons = true,
options = IntRange(0, 7).map { index -> options = IntRange(0, 7).map { index ->

View File

@ -129,7 +129,7 @@ fun SettingsScreen(
) )
BitrateTile() BitrateTile()
SamplingRateTile() SamplingRateTile()
EncoderTile() EncoderTile(snackbarHostState = snackbarHostState)
OutputFormatTile() OutputFormatTile()
} }
} }

View File

@ -52,11 +52,11 @@
<string name="ui_settings_option_bitrate_description">A higher bitrate means better quality but also larger file size</string> <string name="ui_settings_option_bitrate_description">A higher bitrate means better quality but also larger file size</string>
<string name="ui_settings_option_bitrate_explanation">Set the bitrate for the audio recording</string> <string name="ui_settings_option_bitrate_explanation">Set the bitrate for the audio recording</string>
<string name="ui_settings_option_outputFormat_title">Output Format</string> <string name="ui_settings_option_outputFormat_title">Output Format</string>
<string name="ui_settings_option_outputFormat_extra_encoderChanged">Encoder has been changed because the current one was incompatible with this output format</string>
<string name="ui_settings_option_samplingRate_title">Sampling rate</string> <string name="ui_settings_option_samplingRate_title">Sampling rate</string>
<string name="ui_settings_option_samplingRate_description">Define how many samples per second are taken from the audio signal</string> <string name="ui_settings_option_samplingRate_description">Define how many samples per second are taken from the audio signal</string>
<string name="ui_settings_option_samplingRate_explanation">Set the sampling rate</string> <string name="ui_settings_option_samplingRate_explanation">Set the sampling rate</string>
<string name="ui_settings_option_encoder_title">Encoder</string> <string name="ui_settings_option_encoder_title">Encoder</string>
<string name="ui_settings_option_encoder_extra_outputFormatChanged">Output Format has been changed because the current one was incompatible with this encoder</string>
<string name="ui_settings_value_auto_label">Auto</string> <string name="ui_settings_value_auto_label">Auto</string>
<string name="ui_audioRecorder_state_paused_title">Recording paused</string> <string name="ui_audioRecorder_state_paused_title">Recording paused</string>
<string name="ui_audioRecorder_state_paused_description">Audio Recording has been paused</string> <string name="ui_audioRecorder_state_paused_description">Audio Recording has been paused</string>