From: Marcel van der Veldt Date: Mon, 10 Mar 2025 22:12:17 +0000 (+0100) Subject: Fix: output bit depth should be as high as possibe X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=44fc8fe91e173c9102d1f2f1545d9bfe9e139947;p=music-assistant-server.git Fix: output bit depth should be as high as possibe If a player supports >16 bits we should use that as output format as well because internally we use 32bits to leave headroom for processing --- diff --git a/music_assistant/controllers/streams.py b/music_assistant/controllers/streams.py index f4f5f31e..3f3efa87 100644 --- a/music_assistant/controllers/streams.py +++ b/music_assistant/controllers/streams.py @@ -315,12 +315,20 @@ class StreamsController(CoreController): ) queue_item.available = False raise web.HTTPNotFound(reason=f"No streamdetails for Queue item: {queue_item_id}") + + # pick pcm format based on the streamdetails and player capabilities + pcm_format = AudioFormat( + content_type=DEFAULT_PCM_FORMAT.content_type, + sample_rate=queue_item.streamdetails.audio_format.sample_rate, + bit_depth=DEFAULT_PCM_FORMAT.bit_depth, + channels=2, + ) # work out output format/details output_format = await self.get_output_format( output_format_str=request.match_info["fmt"], player=queue_player, - default_sample_rate=queue_item.streamdetails.audio_format.sample_rate, - default_bit_depth=queue_item.streamdetails.audio_format.bit_depth, + content_sample_rate=pcm_format.sample_rate, + content_bit_depth=pcm_format.bit_depth, ) # prepare request, add some DLNA/UPNP compatible headers @@ -359,13 +367,6 @@ class StreamsController(CoreController): queue.display_name, ) - # pick pcm format based on the streamdetails and player capabilities - pcm_format = AudioFormat( - content_type=DEFAULT_PCM_FORMAT.content_type, - sample_rate=queue_item.streamdetails.audio_format.sample_rate, - bit_depth=DEFAULT_PCM_FORMAT.bit_depth, - channels=2, - ) chunk_num = 0 # inform the queue that the track is now loaded in the buffer @@ -425,8 +426,8 @@ class StreamsController(CoreController): output_format = await self.get_output_format( output_format_str=request.match_info["fmt"], player=queue_player, - default_sample_rate=flow_pcm_format.sample_rate, - default_bit_depth=flow_pcm_format.bit_depth, + content_sample_rate=flow_pcm_format.sample_rate, + content_bit_depth=flow_pcm_format.bit_depth, ) # work out ICY metadata support icy_preference = self.mass.config.get_raw_player_config_value( @@ -615,8 +616,7 @@ class StreamsController(CoreController): output_format = await self.get_output_format( output_format_str=request.match_info["fmt"], player=player, - default_sample_rate=plugin_source.audio_format.sample_rate, - default_bit_depth=plugin_source.audio_format.bit_depth, + content_sample_rate=plugin_source.audio_format.sample_rate, ) headers = { **DEFAULT_STREAM_HEADERS, @@ -715,7 +715,7 @@ class StreamsController(CoreController): queue_track = start_queue_item else: try: - queue_track = await self.mass.player_queues.load_next_item( + queue_track = await self.mass.player_queues.get_next_queue_item( queue.queue_id, queue_track.queue_item_id ) except QueueEmpty: @@ -991,8 +991,8 @@ class StreamsController(CoreController): self, output_format_str: str, player: Player, - default_sample_rate: int, - default_bit_depth: int, + content_sample_rate: int, + content_bit_depth: int, ) -> AudioFormat: """Parse (player specific) output format details for given format string.""" content_type: ContentType = ContentType.try_parse(output_format_str) @@ -1001,20 +1001,21 @@ class StreamsController(CoreController): ] = await self.mass.config.get_player_config_value( player.player_id, CONF_SAMPLE_RATES, unpack_splitted_values=True ) + output_channels_str = self.mass.config.get_raw_player_config_value( + player.player_id, CONF_OUTPUT_CHANNELS, "stereo" + ) supported_sample_rates: tuple[int] = tuple(int(x[0]) for x in supported_rates_conf) supported_bit_depths: tuple[int] = tuple(int(x[1]) for x in supported_rates_conf) player_max_bit_depth = max(supported_bit_depths) - if default_sample_rate in supported_sample_rates: - output_sample_rate = default_sample_rate + output_bit_depth = min(content_bit_depth, player_max_bit_depth) + if content_sample_rate in supported_sample_rates: + output_sample_rate = content_sample_rate else: output_sample_rate = max(supported_sample_rates) - output_bit_depth = min(default_bit_depth, player_max_bit_depth) - output_channels_str = self.mass.config.get_raw_player_config_value( - player.player_id, CONF_OUTPUT_CHANNELS, "stereo" - ) - output_channels = 1 if output_channels_str != "stereo" else 2 + if not content_type.is_lossless(): + # no point in having a higher bit depth for lossy formats output_bit_depth = 16 output_sample_rate = min(48000, output_sample_rate) if output_format_str == "pcm": @@ -1023,7 +1024,7 @@ class StreamsController(CoreController): content_type=content_type, sample_rate=output_sample_rate, bit_depth=output_bit_depth, - channels=output_channels, + channels=1 if output_channels_str != "stereo" else 2, ) async def _select_flow_format(