At Thu, 31 Jan 2013 11:24:04 -0800, Brent Weatherall wrote:
Clemens/Liam,
Liam, I address your question below. Clemens, stepping through the
ALSA code, it seems the error *might* be in the ALSA code, but I am probably reading the code incorrectly:
pcm/interval.c:
105 int snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin) 106 { 107 int changed = 0; 108 if (snd_interval_empty(i)) 109 return -ENOENT; 110 if (i->min < min) { 111 i->min = min; <-- Is this statement reversed or do I not understand the code well enough? 112 i->openmin = openmin; 113 changed = 1; 114 } else if (i->min == min && !i->openmin && openmin) { 115 i->openmin = 1; 116 changed = 1; 117 } 118 if (i->integer) { 119 if (i->openmin) { 120 i->min++; 121 i->openmin = 0; 122 } 123 } 124 if (snd_interval_checkempty(i)) { 125 snd_interval_none(i); 126 127 } 128 return changed; 129 } 130
Lines 110 - 113 appear to check if the hw params returned structure's minimum value (i->min) is less than the current min value (which is set to the requested rate in pcm.c:827 min = max = best). Then if true, it appears to set the hardware reported min value to the current min, instead of the other way around.
The code is correct. In general, hw_refine() code works like the following:
- The configuration space begins with the full space
- When a hw constraint is given, it tries to shrink the configuration space to fit within the given constraint; it never expands in general (exceptions allowed, though, like in usb-audio's special code).
This is the point you suggested in the above. snd_internval_refine_min() tries to shrink the config space to fit wit with the condition (min <= i->min).
- Loop until all hw constraints are satisfied
- Then pick up either max or min value from the configuration space as the final value; it depends on the parameter type whether to pick max or min value
Takashi