mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	tlv: fix returned dB information for min-is-mute controls
For TLV information that indicates that the minimum value is actually muted, the returned range used the wrong minimum dB value, and converting dB values to raw control values did not round up correctly near the minimum. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									c6a81e21c0
								
							
						
					
					
						commit
						2f6206da0c
					
				
					 1 changed files with 20 additions and 6 deletions
				
			
		| 
						 | 
					@ -167,17 +167,23 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	case SND_CTL_TLVT_DB_SCALE: {
 | 
						case SND_CTL_TLVT_DB_SCALE: {
 | 
				
			||||||
		int step;
 | 
							int step;
 | 
				
			||||||
		*min = (int)tlv[2];
 | 
							if (tlv[3] & 0x10000)
 | 
				
			||||||
 | 
								*min = SND_CTL_TLV_DB_GAIN_MUTE;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								*min = (int)tlv[2];
 | 
				
			||||||
		step = (tlv[3] & 0xffff);
 | 
							step = (tlv[3] & 0xffff);
 | 
				
			||||||
		*max = *min + (long)(step * (rangemax - rangemin));
 | 
							*max = (int)tlv[2] + step * (rangemax - rangemin);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	case SND_CTL_TLVT_DB_MINMAX:
 | 
						case SND_CTL_TLVT_DB_MINMAX:
 | 
				
			||||||
	case SND_CTL_TLVT_DB_MINMAX_MUTE:
 | 
					 | 
				
			||||||
	case SND_CTL_TLVT_DB_LINEAR:
 | 
						case SND_CTL_TLVT_DB_LINEAR:
 | 
				
			||||||
		*min = (int)tlv[2];
 | 
							*min = (int)tlv[2];
 | 
				
			||||||
		*max = (int)tlv[3];
 | 
							*max = (int)tlv[3];
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
						case SND_CTL_TLVT_DB_MINMAX_MUTE:
 | 
				
			||||||
 | 
							*min = SND_CTL_TLV_DB_GAIN_MUTE;
 | 
				
			||||||
 | 
							*max = (int)tlv[3];
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return -EINVAL;
 | 
						return -EINVAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -217,7 +223,7 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax,
 | 
				
			||||||
		min = tlv[2];
 | 
							min = tlv[2];
 | 
				
			||||||
		step = (tlv[3] & 0xffff);
 | 
							step = (tlv[3] & 0xffff);
 | 
				
			||||||
		mute = (tlv[3] >> 16) & 1;
 | 
							mute = (tlv[3] >> 16) & 1;
 | 
				
			||||||
		if (mute && volume == rangemin)
 | 
							if (mute && volume <= rangemin)
 | 
				
			||||||
			*db_gain = SND_CTL_TLV_DB_GAIN_MUTE;
 | 
								*db_gain = SND_CTL_TLV_DB_GAIN_MUTE;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			*db_gain = (volume - rangemin) * step + min;
 | 
								*db_gain = (volume - rangemin) * step + min;
 | 
				
			||||||
| 
						 | 
					@ -327,7 +333,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
 | 
				
			||||||
		step = (tlv[3] & 0xffff);
 | 
							step = (tlv[3] & 0xffff);
 | 
				
			||||||
		max = min + (int)(step * (rangemax - rangemin));
 | 
							max = min + (int)(step * (rangemax - rangemin));
 | 
				
			||||||
		if (db_gain <= min)
 | 
							if (db_gain <= min)
 | 
				
			||||||
			*value = rangemin;
 | 
								if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
 | 
				
			||||||
 | 
								    (tlv[3] & 0x10000))
 | 
				
			||||||
 | 
									*value = rangemin + 1;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									*value = rangemin;
 | 
				
			||||||
		else if (db_gain >= max)
 | 
							else if (db_gain >= max)
 | 
				
			||||||
			*value = rangemax;
 | 
								*value = rangemax;
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
| 
						 | 
					@ -345,7 +355,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
 | 
				
			||||||
		min = tlv[2];
 | 
							min = tlv[2];
 | 
				
			||||||
		max = tlv[3];
 | 
							max = tlv[3];
 | 
				
			||||||
		if (db_gain <= min)
 | 
							if (db_gain <= min)
 | 
				
			||||||
			*value = rangemin;
 | 
								if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 &&
 | 
				
			||||||
 | 
								    tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE)
 | 
				
			||||||
 | 
									*value = rangemin + 1;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									*value = rangemin;
 | 
				
			||||||
		else if (db_gain >= max)
 | 
							else if (db_gain >= max)
 | 
				
			||||||
			*value = rangemax;
 | 
								*value = rangemax;
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue