filter_params = []
extra_input_args = streamdetails.extra_input_args or []
# handle volume normalization
- enable_volume_normalization = (
- streamdetails.target_loudness is not None
- and streamdetails.volume_normalization_mode != VolumeNormalizationMode.DISABLED
- )
- dynamic_volume_normalization = (
- streamdetails.volume_normalization_mode == VolumeNormalizationMode.DYNAMIC
- and enable_volume_normalization
- )
- if dynamic_volume_normalization:
+ if streamdetails.volume_normalization_mode == VolumeNormalizationMode.DYNAMIC:
# volume normalization using loudnorm filter (in dynamic mode)
# which also collects the measurement on the fly during playback
# more info: https://k.ylo.ph/2016/04/04/loudnorm.html
filter_rule = f"loudnorm=I={streamdetails.target_loudness}:TP=-2.0:LRA=10.0:offset=0.0"
filter_rule += ":print_format=json"
filter_params.append(filter_rule)
- elif (
- enable_volume_normalization
- and streamdetails.volume_normalization_mode == VolumeNormalizationMode.FIXED_GAIN
- ):
+ elif streamdetails.volume_normalization_mode == VolumeNormalizationMode.FIXED_GAIN:
# apply used defined fixed volume/gain correction
gain_correct: float = await self.mass.config.get_core_config_value(
self.domain,
- CONF_VOLUME_NORMALIZATION_FIXED_GAIN_RADIO
- if streamdetails.media_type == MediaType.RADIO
- else CONF_VOLUME_NORMALIZATION_FIXED_GAIN_TRACKS,
+ CONF_VOLUME_NORMALIZATION_FIXED_GAIN_TRACKS
+ if streamdetails.media_type == MediaType.TRACK
+ else CONF_VOLUME_NORMALIZATION_FIXED_GAIN_RADIO,
)
gain_correct = round(gain_correct, 2)
filter_params.append(f"volume={gain_correct}dB")
- elif enable_volume_normalization and streamdetails.loudness is not None:
+ elif streamdetails.volume_normalization_mode == VolumeNormalizationMode.MEASUREMENT_ONLY:
# volume normalization with known loudness measurement
# apply volume/gain correction
gain_correct = streamdetails.target_loudness - streamdetails.loudness
# pad some silence before the radio stream starts to create some headroom
# for radio stations that do not provide any look ahead buffer
# without this, some radio streams jitter a lot, especially with dynamic normalization
- pad_seconds = 5 if dynamic_volume_normalization else 2
+ pad_seconds = (
+ 5
+ if streamdetails.volume_normalization_mode == VolumeNormalizationMode.DYNAMIC
+ else 2
+ )
async for chunk in get_silence(pad_seconds, pcm_format):
yield chunk
streamdetails.prefer_album_loudness = prefer_album_loudness
player_settings = await mass.config.get_player_config(streamdetails.queue_id)
core_config = await mass.config.get_core_config("streams")
+ streamdetails.target_loudness = player_settings.get_value(CONF_VOLUME_NORMALIZATION_TARGET)
streamdetails.volume_normalization_mode = _get_normalization_mode(
core_config, player_settings, streamdetails
)
- streamdetails.target_loudness = player_settings.get_value(CONF_VOLUME_NORMALIZATION_TARGET)
process_time = int((time.time() - time_start) * 1000)
LOGGER.debug(
await ffmpeg_proc.start()
logger.debug(
"Started media stream for %s"
- " - using streamtype: %s "
+ " - using streamtype: %s"
" - volume normalization: %s"
" - pcm format: %s"
" - ffmpeg PID: %s",
if not player_config.get_value(CONF_VOLUME_NORMALIZATION):
# disabled for this player
return VolumeNormalizationMode.DISABLED
+ if streamdetails.target_loudness is None:
+ # no target loudness set, disable normalization
+ return VolumeNormalizationMode.DISABLED
# work out preference for track or radio
preference = VolumeNormalizationMode(
core_config.get_value(
if streamdetails.loudness is None and preference == VolumeNormalizationMode.FALLBACK_FIXED_GAIN:
return VolumeNormalizationMode.FIXED_GAIN
+ # handle measurement available - chosen mode is measurement
+ if streamdetails.loudness and preference not in (
+ VolumeNormalizationMode.DISABLED,
+ VolumeNormalizationMode.FIXED_GAIN,
+ ):
+ return VolumeNormalizationMode.MEASUREMENT_ONLY
+
# simply return the preference
return preference