Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nabu] Adds software volume limits #118

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion esphome/components/nabu/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
CONF_FILES = "files"
CONF_SAMPLE_RATE = "sample_rate"
CONF_VOLUME_INCREMENT = "volume_increment"
CONF_VOLUME_MIN = "volume_min"
CONF_VOLUME_MAX = "volume_max"

CONF_ON_MUTE = "on_mute"
CONF_ON_UNMUTE = "on_unmute"
Expand Down Expand Up @@ -198,6 +200,8 @@ def _file_schema(value):
_validate_bits, cv.enum(I2S_BITS_PER_SAMPLE)
),
cv.Optional(CONF_VOLUME_INCREMENT, default=0.05): cv.percentage,
cv.Optional(CONF_VOLUME_MAX, default=1.0): cv.percentage,
cv.Optional(CONF_VOLUME_MIN, default=0.0): cv.percentage,
cv.Optional(CONF_FILES): cv.ensure_list(MEDIA_FILE_TYPE_SCHEMA),
cv.Optional(CONF_ON_MUTE): automation.validate_automation(single=True),
cv.Optional(CONF_ON_UNMUTE): automation.validate_automation(single=True),
Expand Down Expand Up @@ -252,7 +256,7 @@ async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await media_player.register_media_player(var, config)

cg.add_define("USE_OTA_STATE_CALLBACK")

await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
Expand All @@ -262,6 +266,8 @@ async def to_code(config):
cg.add(var.set_i2s_mode(config[CONF_I2S_MODE]))

cg.add(var.set_volume_increment(config[CONF_VOLUME_INCREMENT]))
cg.add(var.set_volume_max(config[CONF_VOLUME_MAX]))
cg.add(var.set_volume_min(config[CONF_VOLUME_MIN]))

if on_mute := config.get(CONF_ON_MUTE):
await automation.build_automation(
Expand Down
27 changes: 18 additions & 9 deletions esphome/components/nabu/nabu_media_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ void NabuMediaPlayer::watch_media_commands_() {

if (media_command.volume.has_value()) {
this->set_volume_(media_command.volume.value());
this->set_mute_state_(false);
this->publish_state();
}

Expand Down Expand Up @@ -608,12 +607,12 @@ media_player::MediaPlayerTraits NabuMediaPlayer::get_traits() {
.num_channels = 2,
.purpose = media_player::MediaPlayerFormatPurpose::PURPOSE_DEFAULT,
.sample_bytes = 2});
traits.get_supported_formats().push_back(media_player::MediaPlayerSupportedFormat{
.format = "flac",
.sample_rate = 48000,
.num_channels = 1,
.purpose = media_player::MediaPlayerFormatPurpose::PURPOSE_ANNOUNCEMENT,
.sample_bytes = 2});
traits.get_supported_formats().push_back(
media_player::MediaPlayerSupportedFormat{.format = "flac",
.sample_rate = 48000,
.num_channels = 1,
.purpose = media_player::MediaPlayerFormatPurpose::PURPOSE_ANNOUNCEMENT,
.sample_bytes = 2});
return traits;
};

Expand Down Expand Up @@ -657,14 +656,17 @@ void NabuMediaPlayer::set_mute_state_(bool mute_state) {
}

void NabuMediaPlayer::set_volume_(float volume, bool publish) {
// Remap the volume to fit with in the configured limits
float bounded_volume = remap<float, float>(volume, 0.0f, 1.0f, this->volume_min_, this->volume_max_);

#ifdef USE_AUDIO_DAC
if (this->audio_dac_ != nullptr) {
this->audio_dac_->set_volume(volume);
this->audio_dac_->set_volume(bounded_volume);
} else
#endif
{ // Fall back to software volume control if there is no audio_dac or if it isn't configured
// Use the decibel reduction table from audio_mixer.h for software volume control
ssize_t decibel_index = remap<ssize_t, float>(volume, 1.0f, 0.0f, 0, decibel_reduction_table.size() - 1);
ssize_t decibel_index = remap<ssize_t, float>(bounded_volume, 1.0f, 0.0f, 0, decibel_reduction_table.size() - 1);
this->software_volume_scale_factor_ = decibel_reduction_table[decibel_index];
}

Expand All @@ -673,6 +675,13 @@ void NabuMediaPlayer::set_volume_(float volume, bool publish) {
this->save_volume_restore_state_();
}

// Turn on the mute state if the volume is effectively zero, off otherwise
if (volume < 0.001) {
this->set_mute_state_(true);
} else {
this->set_mute_state_(false);
}

this->defer([this, volume]() { this->volume_trigger_->trigger(volume); });
}

Expand Down
8 changes: 7 additions & 1 deletion esphome/components/nabu/nabu_media_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class NabuMediaPlayer : public Component, public media_player::MediaPlayer, publ
// Percentage to increase or decrease the volume for volume up or volume down commands
void set_volume_increment(float volume_increment) { this->volume_increment_ = volume_increment; }

void set_volume_max(float volume_max) { this->volume_max_ = volume_max; }
void set_volume_min(float volume_min) { this->volume_min_ = volume_min; }

#ifdef USE_AUDIO_DAC
void set_audio_dac(audio_dac::AudioDac *audio_dac) { this->audio_dac_ = audio_dac; }
#endif
Expand Down Expand Up @@ -125,7 +128,7 @@ class NabuMediaPlayer : public Component, public media_player::MediaPlayer, publ
optional<std::string> announcement_url_{}; // only modified by control function
optional<media_player::MediaFile *> media_file_{}; // only modified by control fucntion
optional<media_player::MediaFile *> announcement_file_{}; // only modified by control fucntion

QueueHandle_t media_control_command_queue_;

i2s_bits_per_sample_t bits_per_sample_;
Expand All @@ -139,6 +142,9 @@ class NabuMediaPlayer : public Component, public media_player::MediaPlayer, publ
// The amount to change the volume on volume up/down commands
float volume_increment_;

float volume_max_;
float volume_min_;

#ifdef USE_AUDIO_DAC
audio_dac::AudioDac *audio_dac_{nullptr};
#endif
Expand Down
5 changes: 4 additions & 1 deletion home-assistant-voice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,9 @@ media_player:
bits_per_sample: 32bit
i2s_mode: secondary
i2s_audio_id: i2s_output
volume_increment: 0.05
volume_min: 0.4
volume_max: 0.85
on_mute:
- script.execute: control_leds
on_unmute:
Expand Down Expand Up @@ -1302,7 +1305,7 @@ external_components:
- source:
type: git
url: https://github.com/esphome/voice-kit
ref: dev
ref: kahrendt-20240916-volume-limits
components:
- aic3204
- audio_dac
Expand Down