diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-12-21 11:07:08 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-12-22 01:58:07 -0500 |
commit | 8374e24c23448cabf6e78db2c83841c56c5df1e1 (patch) | |
tree | 5cef080d34dc41313473e65760395fa61e38b3df | |
parent | cb3b04debbb70de7b266f75777ac2b9ff567c460 (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.c | 20 |
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 | } |