Toggling volume error

Godot Version

Godot 4.3

Description

When I start the game, the volume is set to its maximum value, which I called max_db. When I go to the settings menu, the volume is displayed as 100, corresponding to max_db. If I adjust the volume to 90, 80, or lower, instead of decreasing, the volume suddenly increases and stays increased when I take it back to 100. I’ve identified the functions causing this issue, and here they are:

func linear_to_db(value: float) -> float:
	if value == 0:
		return -80  # Minimum volume (mute)
	return -80 + (value / 100) * (max_db - (-80))  # Scale between -80 dB and max_db

# Helper function to convert decibels back to slider values (0-100)
func db_to_linear(db: float) -> float:
	if db <= -80:
		return 0  # Mute
	return ((db - (-80)) / (max_db - (-80))) * 100

Because that names is the built-in functions from Godot, when you call that you’ll call the Godot functions, not the one you created. I recommend just use the built-in functions for that or if you really want to do it by yourself, change for other name to not conflict with the built-in names.

db_to_linear
linear_to_db

2 Likes

I tried to use the build-in functions and I fell into more problems the slider for the volume stopped working. This is what I have right now (settings_menu.gd), I have been stuck on this problem for a while:

extends Control # This script is attached to the Control node of the settings menu

var max_db: float = 0 # Variable to store the game’s maximum volume (initial volume)

Save the slider value (volume) to a persistent file

func save_volume_setting(value: float) → void:
var config = ConfigFile.new()
config.set_value(“audio”, “volume”, value) # Save slider value under “audio”
config.save(“user://settings.cfg”) # Save to user settings file

Convert slider value (0-100) to decibels (strictly scaling between -80 and max_db)

func linear_to_db(value: float) → float:
return -80 + (value / 100) * (max_db - (-80)) # Scale between -80 dB and max_db

Convert decibels back to slider values (0-100)

func db_to_linear(db: float) → float:
return ((db - (-80)) / (max_db - (-80))) * 100 # Scale back to slider range

Initialize the settings menu

func _ready() → void:
# Get the current audio bus volume as the max_db (initial game’s volume)
max_db = AudioServer.get_bus_volume_db(0)

# Check if a saved slider value exists
var saved_slider_value: float = 100  # Default to 100 (max volume)
var config = ConfigFile.new()
if config.load("user://settings.cfg") == OK:
	saved_slider_value = config.get_value("audio", "volume", 100)

# Set the slider to the saved value and update volume
$HSlider.value = saved_slider_value
$VolumeValue.text = str(int(saved_slider_value))
AudioServer.set_bus_volume_db(0, linear_to_db(saved_slider_value))  # Apply volume

Called when the slider value changes

func _on_h_slider_value_changed(value: float) → void:
# Adjust the audio bus volume based on the slider value
AudioServer.set_bus_volume_db(0, linear_to_db(value))
$VolumeValue.text = str(int(value)) # Update the slider display
save_volume_setting(value) # Save the current slider value

Go back to the main menu

func _on_back_button_pressed() → void:
get_tree().change_scene_to_file(“res://scenes/main_menu.tscn”)

You setted your code to work between 0.0 and 1.0 with the built-in functions?

1 Like

This is what I had with the built in functions:
extends Control # This script is attached to the Control node of the settings menu

var max_db: float = 0 # Variable to store the game’s maximum volume (initial volume)

Save the slider value (volume) to a persistent file

func save_volume_setting(value: float) → void:
var config = ConfigFile.new()
config.set_value(“audio”, “volume”, value) # Save slider value under “audio”
config.save(“user://settings.cfg”) # Save to user settings file

Convert slider value (0-100) to decibels using Godot’s built-in function

func slider_to_db(value: float) → float:
# Convert 0-100 to a linear scale (0.0 - 1.0) before passing to linear_to_db
return AudioServer.linear_to_db(value / 100.0)

Convert decibels back to slider value (0-100) using Godot’s built-in function

func db_to_slider(db: float) → float:
# Convert decibels to linear scale and scale to 0-100
return AudioServer.db_to_linear(db) * 100.0

Initialize the settings menu

func _ready() → void:
# Get the current audio bus volume as the max_db (initial game’s volume)
max_db = AudioServer.get_bus_volume_db(0)

# Check if a saved slider value exists
var saved_slider_value: float = 100  # Default to 100 (max volume)
var config = ConfigFile.new()
if config.load("user://settings.cfg") == OK:
	saved_slider_value = config.get_value("audio", "volume", 100)

# Set the slider to the saved value and update volume
$HSlider.value = saved_slider_value
$VolumeValue.text = str(int(saved_slider_value))
AudioServer.set_bus_volume_db(0, slider_to_db(saved_slider_value))  # Apply volume

Called when the slider value changes

func _on_h_slider_value_changed(value: float) → void:
# Adjust the audio bus volume based on the slider value
AudioServer.set_bus_volume_db(0, slider_to_db(value))
$VolumeValue.text = str(int(value)) # Update the slider display
save_volume_setting(value) # Save the current slider value

Go back to the main menu

func _on_back_button_pressed() → void:
get_tree().change_scene_to_file(“res://scenes/main_menu.tscn”)

The built-in functions i said are in the global scope, not in the AudioServer class, that will throw an error in your editor. Just use db_to_linear/linear_to_db