Skip to content

Commit

Permalink
ALSA: refine rate selection in snd_interval_ratnum()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
Krzysztof-H authored and tiwai committed Dec 22, 2009
1 parent cb3b04d commit 8374e24
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 8374e24

Please sign in to comment.