@@ -1222,6 +1222,69 @@ def right_dac_channel_volume(self, db: float) -> None:
12221222 """
12231223 self ._page0 ._set_channel_volume (True , db )
12241224
1225+ @staticmethod
1226+ def _convert_reg_to_db (reg_val : int ) -> float :
1227+ """
1228+ Convert a register value to decibel volume.
1229+
1230+ :param reg_val: 8-bit register value
1231+ :return: Volume in dB
1232+ """
1233+ if reg_val & 0x80 :
1234+ reg_val = reg_val - 256
1235+
1236+ return reg_val * 0.5
1237+
1238+ @staticmethod
1239+ def _convert_db_to_reg (db : float ) -> int :
1240+ """
1241+ Convert decibel volume to register value.
1242+
1243+ :param db: Volume in dB (-63.5 to 24 dB)
1244+ :return: 8-bit register value
1245+ """
1246+ reg_val = int (db * 2 )
1247+ if reg_val > 0x30 :
1248+ reg_val = 0x30
1249+ elif reg_val < - 0x80 :
1250+ reg_val = 0x80
1251+
1252+ if reg_val < 0 :
1253+ reg_val += 256
1254+
1255+ return reg_val & 0xFF
1256+
1257+ @property
1258+ def dac_volume (self ) -> float :
1259+ """
1260+ Get the current DAC digital volume in dB.
1261+
1262+ :return: Volume in dB (-63.5 to 24 dB)
1263+ """
1264+ left_vol = self ._page0 ._read_register (_DAC_LVOL )
1265+ right_vol = self ._page0 ._read_register (_DAC_RVOL )
1266+
1267+ left_db = self ._convert_reg_to_db (left_vol )
1268+ right_db = self ._convert_reg_to_db (right_vol )
1269+
1270+ return (left_db + right_db ) / 2
1271+
1272+ @dac_volume .setter
1273+ def dac_volume (self , db : float ) -> None :
1274+ """
1275+ Set the DAC digital volume in dB.
1276+
1277+ :param db: Volume in dB (-63.5 to 24 dB)
1278+ """
1279+ db = max (- 63.5 , min (24 , db ))
1280+ reg_val = self ._convert_db_to_reg (db )
1281+ self ._page0 ._set_page ()
1282+ self ._page0 ._write_register (_DAC_LVOL , reg_val )
1283+ self ._page0 ._write_register (_DAC_RVOL , reg_val )
1284+
1285+ self .left_dac_mute = False
1286+ self .right_dac_mute = False
1287+
12251288 def manual_headphone_driver (
12261289 self ,
12271290 left_powered : bool ,
@@ -1834,28 +1897,32 @@ def speaker_output(self, enabled: bool) -> None:
18341897 @property
18351898 def headphone_volume (self ) -> float :
18361899 """The current headphone volume in dB.
1837-
1838- :return: The volume in dB (0 = max, -63.5 = min)
1900+ :return: The volume in dB (0 = max, -78.3 = min)
18391901 """
18401902 left_gain = self ._page1 ._read_register (_HPL_VOL ) & 0x7F
18411903 right_gain = self ._page1 ._read_register (_HPR_VOL ) & 0x7F
1842- avg_gain = (left_gain + right_gain ) / 2
1843- # Convert from register value to dB
1844- # 55 ≈ 0dB, 0 ≈ -63.5dB
1845- db = (avg_gain - 55 ) / 1.14
1846- return db
1904+
1905+ if left_gain == right_gain :
1906+ db = - left_gain / 2.0
1907+ db = max (- 78.3 , min (0 , db ))
1908+ return db
1909+ else :
1910+ avg_gain = (left_gain + right_gain ) / 2
1911+ db = - avg_gain / 2.0
1912+ db = max (- 78.3 , min (0 , db ))
1913+ return db
18471914
18481915 @headphone_volume .setter
18491916 def headphone_volume (self , db : float ) -> None :
18501917 """
1851-
1852- :param db: Volume in dB (0 = max, -63.5 = min)
1918+ Set headphone volume in dB (0 to -78.3 dB)
1919+ :param db: Volume in dB (0 = max, -78.3 = min)
18531920 """
1854- # Convert from dB to register gain value (0-127)
1855- # 0dB = ~55, -63.5dB = 0
18561921 if db > 0 :
1857- db = 0 # Limit to 0dB to prevent distortion
1858- gain = int (55 + (db * 1.14 ))
1922+ db = 0
1923+ elif db < - 78.3 :
1924+ db = - 78.3
1925+ gain = int (- 2 * db )
18591926 gain = max (0 , min (gain , 127 ))
18601927 self ._page1 ._set_hpl_volume (route_enabled = True , gain = gain )
18611928 self ._page1 ._set_hpr_volume (route_enabled = True , gain = gain )
0 commit comments