summaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_lib.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-12-21 17:07:08 +0100
committerTakashi Iwai <tiwai@suse.de>2009-12-22 07:58:07 +0100
commit8374e24c23448cabf6e78db2c83841c56c5df1e1 (patch)
tree5cef080d34dc41313473e65760395fa61e38b3df /sound/core/pcm_lib.c
parentcb3b04debbb70de7b266f75777ac2b9ff567c460 (diff)
downloadop-kernel-dev-8374e24c23448cabf6e78db2c83841c56c5df1e1.zip
op-kernel-dev-8374e24c23448cabf6e78db2c83841c56c5df1e1.tar.gz
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>
Diffstat (limited to 'sound/core/pcm_lib.c')
-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 a27545b2..b07cc36 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,
unsigned int rats_count, struct snd_ratnum *rats,
unsigned int *nump, unsigned int *denp)
{
- unsigned int best_num, best_diff, best_den;
+ unsigned int best_num, best_den;
+ int best_diff;
unsigned int k;
struct snd_interval t;
int err;
+ unsigned int result_num, result_den;
+ int result_diff;
best_num = best_den = best_diff = 0;
for (k = 0; k < rats_count; ++k) {
@@ -770,6 +773,8 @@ int snd_interval_ratnum(struct snd_interval *i,
den -= r;
}
diff = num - q * den;
+ if (diff < 0)
+ diff = -diff;
if (best_num == 0 ||
diff * best_den < best_diff * den) {
best_diff = diff;
@@ -784,6 +789,9 @@ int snd_interval_ratnum(struct snd_interval *i,
t.min = div_down(best_num, best_den);
t.openmin = !!(best_num % best_den);
+ result_num = best_num;
+ result_diff = best_diff;
+ result_den = best_den;
best_num = best_den = best_diff = 0;
for (k = 0; k < rats_count; ++k) {
unsigned int num = rats[k].num;
@@ -806,6 +814,8 @@ int snd_interval_ratnum(struct snd_interval *i,
den += rats[k].den_step - r;
}
diff = q * den - num;
+ if (diff < 0)
+ diff = -diff;
if (best_num == 0 ||
diff * best_den < best_diff * den) {
best_diff = diff;
@@ -825,10 +835,14 @@ int snd_interval_ratnum(struct snd_interval *i,
return err;
if (snd_interval_single(i)) {
+ if (best_diff * result_den < result_diff * best_den) {
+ result_num = best_num;
+ result_den = best_den;
+ }
if (nump)
- *nump = best_num;
+ *nump = result_num;
if (denp)
- *denp = best_den;
+ *denp = result_den;
}
return err;
}
OpenPOWER on IntegriCloud