Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SettingsAudioFormatFragment : SettingsBaseFragment() {

private val encoding by lazy { findPreference<ListPreference>(getString(R.string.key_audioformat_encoding)) }
private val bufferSize by lazy { findPreference<MaterialSeekbarPreference>(getString(R.string.key_audioformat_buffersize)) }
private val allowLowSamples by lazy { findPreference<MaterialSwitchPreference>(getString(R.string.key_audioformat_allow_low_samples)) }
private val legacyMode by lazy { findPreference<MaterialSwitchPreference>(getString(R.string.key_audioformat_processing)) }
private val enhancedMode by lazy { findPreference<MaterialSwitchPreference>(getString(R.string.key_audioformat_enhanced_processing)) }
private val enhancedModeInfo by lazy { findPreference<Preference>(getString(R.string.key_audioformat_enhanced_processing_info)) }
Expand Down Expand Up @@ -107,22 +108,43 @@ class SettingsAudioFormatFragment : SettingsBaseFragment() {
}

bufferSize?.setDefaultValue(preferences.getDefault<Float>(R.string.key_audioformat_buffersize))
applyBufferSizeRange(preferences.get<Boolean>(R.string.key_audioformat_allow_low_samples))
bufferSize?.setOnPreferenceChangeListener { _, newValue ->
if((newValue as Float) <= 1024){
requireContext().toast(R.string.audio_format_buffer_size_warning_low_value, false)
}
context?.sendLocalBroadcast(Intent(Constants.ACTION_SERVICE_HARD_REBOOT_CORE))
true
}
allowLowSamples?.setOnPreferenceChangeListener { _, newValue ->
applyBufferSizeRange(newValue as Boolean)
true
}
Comment thread
JadenJSJ marked this conversation as resolved.
encoding?.setOnPreferenceChangeListener { _, _ ->
context?.sendLocalBroadcast(Intent(Constants.ACTION_SERVICE_HARD_REBOOT_CORE))
true
}
}

private fun applyBufferSizeRange(allowLow: Boolean) {
val minValue = if (allowLow) BUFFER_SIZE_MIN_LOW else BUFFER_SIZE_MIN_DEFAULT
val stepValue = if (allowLow) BUFFER_SIZE_STEP_LOW else BUFFER_SIZE_STEP_DEFAULT

bufferSize?.setMin(minValue.toFloat())
bufferSize?.setSeekBarIncrement(stepValue.toFloat())

val currentValue = preferences.get<Float>(R.string.key_audioformat_buffersize)
bufferSize?.setValue(if (currentValue < minValue) minValue.toFloat() else currentValue)
}

companion object {
private const val BUFFER_SIZE_MIN_DEFAULT = 128
private const val BUFFER_SIZE_STEP_DEFAULT = 128
private const val BUFFER_SIZE_MIN_LOW = 2
private const val BUFFER_SIZE_STEP_LOW = 2

fun newInstance(): SettingsAudioFormatFragment {
return SettingsAudioFormatFragment()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,13 @@ class RootlessAudioProcessorService : BaseAudioProcessorService() {
val encoding = AudioEncoding.fromInt(
preferences.get<String>(R.string.key_audioformat_encoding).toIntOrNull() ?: 1
)
val bufferSize = preferences.get<Float>(R.string.key_audioformat_buffersize).toInt()
val allowLowSamples = preferences.get<Boolean>(R.string.key_audioformat_allow_low_samples)
val minBufferSize = if (allowLowSamples) 2 else 128
val requestedBufferSize = preferences.get<Float>(R.string.key_audioformat_buffersize).toInt()
var bufferSize = if (requestedBufferSize < minBufferSize) minBufferSize else requestedBufferSize
if ((bufferSize % 2) != 0) {
bufferSize += 1
}
val bufferSizeBytes = when (encoding) {
AudioEncoding.PcmFloat -> bufferSize * Float.SIZE_BYTES
else -> bufferSize * Short.SIZE_BYTES
Expand All @@ -434,7 +440,8 @@ class RootlessAudioProcessorService : BaseAudioProcessorService() {
val sampleRate = clamp(determineSamplingRate(), 44100, 48000)

Timber.i("Sample rate: $sampleRate; Encoding: ${encoding.name}; " +
"Buffer size: $bufferSize; Buffer size (bytes): $bufferSizeBytes ; " +
"Buffer size: $bufferSize (requested: $requestedBufferSize); " +
"Buffer size (bytes): $bufferSizeBytes ; " +
"HAL buffer size (bytes): ${determineBufferSize()}")

// Create recorder and track
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values/defaults.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<bool name="default_powersave_suspend" translatable="false">true</bool>
<string name="default_audioformat_encoding" translatable="false">1</string>
<integer name="default_audioformat_buffersize" translatable="false">8192</integer>
<bool name="default_audioformat_allow_low_samples" translatable="false">false</bool>
<bool name="default_audioformat_processing" translatable="false">true</bool>
<bool name="default_audioformat_enhanced_processing" translatable="false">false</bool>
<bool name="default_audioformat_optimization_benchmark" translatable="false">false</bool>
Expand All @@ -55,4 +56,4 @@
<!-- Script editor -->
<integer name="default_editor_font_size" translatable="false" tools:keep="@integer/default_editor_font_size">13</integer>

</resources>
</resources>
1 change: 1 addition & 0 deletions app/src/main/res/values/keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<string name="key_powersave_suspend" translatable="false">powersave_suspend</string>
<string name="key_audioformat_encoding" translatable="false">audioformat_encoding</string>
<string name="key_audioformat_buffersize" translatable="false">audioformat_buffersize</string>
<string name="key_audioformat_allow_low_samples" translatable="false">audioformat_allow_low_samples</string>
<string name="key_audioformat_processing" translatable="false">audioformat_processing</string>
<string name="key_audioformat_enhanced_processing" translatable="false">audioformat_enhanced_processing</string>
<string name="key_audioformat_optimization_benchmark" translatable="false">audioformat_optimization_benchmark</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@
<string name="audio_format_buffer_size">Buffer size</string>
<string name="audio_format_buffer_size_unit">&#xa0;samples</string>
<string name="audio_format_buffer_size_warning_low_value">Warning: Low buffer sizes may cause audio issues such as clipping!</string>
<string name="audio_format_allow_low_samples">Allow low buffer sizes (&lt;128 samples)</string>
<string name="audio_format_allow_low_samples_summary">Experimental. Allows down to 2 samples with finer steps. May cause dropouts, crackling, or instability.</string>
<string name="audio_format_optimization_header">Convolver module optimizations</string>
<string name="audio_format_optimization_refresh">Refresh benchmarking data</string>
<string name="audio_format_optimization_benchmark">Use benchmarks to optimize performance</string>
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/res/xml/app_audio_format_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
app:updatesContinuously="false"
app:showSeekBarValue="true"
app:iconSpaceReserved="false"/>
Comment on lines +16 to 26
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, find the XML file to confirm the hardcoded values
find . -name "app_audio_format_preferences.xml" -type f

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 131


🏁 Script executed:

# Find the SettingsAudioFormatFragment to verify the clamping logic
find . -name "SettingsAudioFormatFragment.kt" -type f

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 180


🏁 Script executed:

# Search for MaterialSeekbarPreference implementation
find . -name "*MaterialSeekbar*" -o -name "*Seekbar*" | grep -E "\.(kt|java)$"

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 171


🏁 Script executed:

# Read the XML file to confirm the hardcoded values
cat -n ./app/src/main/res/xml/app_audio_format_preferences.xml

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 4868


🏁 Script executed:

# Read the SettingsAudioFormatFragment to check for change listeners and clamping
wc -l ./app/src/main/java/me/timschneeberger/rootlessjamesdsp/fragment/settings/SettingsAudioFormatFragment.kt

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 184


🏁 Script executed:

# Read the MaterialSeekbarPreference to see if minValue can be set dynamically
cat -n ./app/src/main/java/me/timschneeberger/rootlessjamesdsp/preference/MaterialSeekbarPreference.kt

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 21634


🏁 Script executed:

# Read the SettingsAudioFormatFragment to find the change listener and applyBufferSizeRange method
cat -n ./app/src/main/java/me/timschneeberger/rootlessjamesdsp/fragment/settings/SettingsAudioFormatFragment.kt

Repository: JSJ-Experiments/RootlessJamesDSP

Length of output: 8635


UI allows selecting invalid buffer sizes when "Allow low buffer sizes" is disabled.

The seekbar is configured with minValue="2" in XML, but when the toggle is off, the fragment's change listener (lines 115-118 in SettingsAudioFormatFragment.kt) clamps values below 128. Users can slide to invalid values like 64 only to have them silently adjusted to 128.

The applyBufferSizeRange() method currently only clamps the stored value but doesn't update the seekbar's visible minimum. Since MaterialSeekbarPreference exposes a public setMin() method that triggers UI updates via notifyChanged(), you should call it to reflect the effective range:

♻️ Update applyBufferSizeRange() to dynamically set seekbar minimum
private fun applyBufferSizeRange(allowLow: Boolean) {
    val minValue = if (allowLow) {
        Constants.AUDIO_BUFFER_MIN_LOW.toFloat()
    } else {
        Constants.AUDIO_BUFFER_MIN_DEFAULT.toFloat()
    }
    
    bufferSize?.setMin(minValue)
    
    val currentValue = preferences.get<Float>(R.string.key_audioformat_buffersize)
    if(currentValue < minValue) {
        bufferSize?.setValue(minValue)
        context?.sendLocalBroadcast(Intent(Constants.ACTION_SERVICE_HARD_REBOOT_CORE))
    }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/res/xml/app_audio_format_preferences.xml` around lines 16 - 26,
The seekbar still allows sliding to values below the effective minimum because
applyBufferSizeRange() only clamps stored values; update
applyBufferSizeRange(allowLow: Boolean) to call bufferSize?.setMin(...) (using
Constants.AUDIO_BUFFER_MIN_LOW or Constants.AUDIO_BUFFER_MIN_DEFAULT) so the UI
minimum updates, then read the current value via preferences.get(...) and if
it's below the new min call bufferSize?.setValue(...) and send the reboot
broadcast Intent(Constants.ACTION_SERVICE_HARD_REBOOT_CORE); this uses
MaterialSeekbarPreference.setMin(), bufferSize, preferences.get,
bufferSize.setValue, and the ACTION_SERVICE_HARD_REBOOT_CORE constant.

<me.timschneeberger.rootlessjamesdsp.preference.MaterialSwitchPreference
android:key="@string/key_audioformat_allow_low_samples"
android:defaultValue="@bool/default_audioformat_allow_low_samples"
android:title="@string/audio_format_allow_low_samples"
android:summary="@string/audio_format_allow_low_samples_summary"
app:iconSpaceReserved="false" />
</PreferenceCategory>

<PreferenceCategory
Expand Down Expand Up @@ -73,4 +79,4 @@
app:iconSpaceReserved="false"/>

</PreferenceCategory>
</PreferenceScreen>
</PreferenceScreen>
Loading
Loading