aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-12-21 11:07:08 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-22 01:58:07 -0500
commit8374e24c23448cabf6e78db2c83841c56c5df1e1 (patch)
tree5cef080d34dc41313473e65760395fa61e38b3df
parentcb3b04debbb70de7b266f75777ac2b9ff567c460 (diff)
ALSA: refine rate selection in snd_interval_ratnum()
Refine the rate selection by choosing the rate closer to the requested one in case of selecting single frequency. Previously, the higher rate was always selected. Also, fix problem with the best_diff unsigned int value wrapping (turning negative). Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/core/pcm_lib.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a27545b23ee9..b07cc361afb1 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -745,10 +745,13 @@ int snd_interval_ratnum(struct snd_interval *i,
745 unsigned int rats_count, struct snd_ratnum *rats, 745 unsigned int rats_count, struct snd_ratnum *rats,
746 unsigned int *nump, unsigned int *denp) 746 unsigned int *nump, unsigned int *denp)
747{ 747{
748 unsigned int best_num, best_diff, best_den; 748 unsigned int best_num, best_den;
749 int best_diff;
749 unsigned int k; 750 unsigned int k;
750 struct snd_interval t; 751 struct snd_interval t;
751 int err; 752 int err;
753 unsigned int result_num, result_den;
754 int result_diff;
752 755
753 best_num = best_den = best_diff = 0; 756 best_num = best_den = best_diff = 0;
754 for (k = 0; k < rats_count; ++k) { 757 for (k = 0; k < rats_count; ++k) {
@@ -770,6 +773,8 @@ int snd_interval_ratnum(struct snd_interval *i,
770 den -= r; 773 den -= r;
771 } 774 }
772 diff = num - q * den; 775 diff = num - q * den;
776 if (diff < 0)
777 diff = -diff;
773 if (best_num == 0 || 778 if (best_num == 0 ||
774 diff * best_den < best_diff * den) { 779 diff * best_den < best_diff * den) {
775 best_diff = diff; 780 best_diff = diff;
@@ -784,6 +789,9 @@ int snd_interval_ratnum(struct snd_interval *i,
784 t.min = div_down(best_num, best_den); 789 t.min = div_down(best_num, best_den);
785 t.openmin = !!(best_num % best_den); 790 t.openmin = !!(best_num % best_den);
786 791
792 result_num = best_num;
793 result_diff = best_diff;
794 result_den = best_den;
787 best_num = best_den = best_diff = 0; 795 best_num = best_den = best_diff = 0;
788 for (k = 0; k < rats_count; ++k) { 796 for (k = 0; k < rats_count; ++k) {
789 unsigned int num = rats[k].num; 797 unsigned int num = rats[k].num;
@@ -806,6 +814,8 @@ int snd_interval_ratnum(struct snd_interval *i,
806 den += rats[k].den_step - r; 814 den += rats[k].den_step - r;
807 } 815 }
808 diff = q * den - num; 816 diff = q * den - num;
817 if (diff < 0)
818 diff = -diff;
809 if (best_num == 0 || 819 if (best_num == 0 ||
810 diff * best_den < best_diff * den) { 820 diff * best_den < best_diff * den) {
811 best_diff = diff; 821 best_diff = diff;
@@ -825,10 +835,14 @@ int snd_interval_ratnum(struct snd_interval *i,
825 return err; 835 return err;
826 836
827 if (snd_interval_single(i)) { 837 if (snd_interval_single(i)) {
838 if (best_diff * result_den < result_diff * best_den) {
839 result_num = best_num;
840 result_den = best_den;
841 }
828 if (nump) 842 if (nump)
829 *nump = best_num; 843 *nump = result_num;
830 if (denp) 844 if (denp)
831 *denp = best_den; 845 *denp = result_den;
832 } 846 }
833 return err; 847 return err;
834} 848}