On Mon, May 17, 2010 at 11:42 PM, Jaroslav Kysela perex@perex.cz wrote:
On Mon, 17 May 2010, Jassi Brar wrote:
On Mon, May 17, 2010 at 8:16 PM, Clemens Ladisch clemens@ladisch.de wrote:
Jassi Brar wrote:
I am in favor of support variable hw_interrupt at lowest level, i.e, in ring buffer driver, instead of disabling hw_interrupt altogether.
Removing the constant-sized periods restriction would certainly be useful. However, it doesn't look as if anybody has the time to redesign the ALSA API, the kernel framework and all the drivers.
No need to redesign ALSA API and certainly no need to change _any_ driver, just like this interrupt disable call is optional so would period resize be.
I only ask to make this newly added call as period-resize rather than a special case of period-disable.
This is very good point. But I have two comments:
- Period-disable function is OK, but it should not have a name "no
period irq": SNDRV_PCM_INFO_PERIOD_DISABLE or DISABLE_PERIOD looks better. This change does imply to set the period size automatically in the driver - probably to highest value (applications cannot choose/set the period size in this operation mode - it's useless anyway). 2) The avail_min parameter in sw_params was overlooked. The lowlevel drivers can use this value to compute the wake-up point and set hw appropriately, to do wake-up at requested time. We can add a support functions like "return how many samples are expected to be transferred for next wake-up point" to linux/sound/pcm.h. In case when this value is high, no interrupts (wake ups) will be processed in the driver. If hardware cannot do the precise transfers, we can program a system timer as the wake-up source.
Sounds good, though I had a different implementation in mind... A new _optionally_ supported call to set the ratio of h/w period to ring buffer. The fields are returned with actually set ratio by the low level driver upon call return. The boundary case of say 0/0 can be interpreted as intr disable and n/n as period := ring The call can be used to query current ratio by asking for a/b where a > b i.e, invalid ratio. Depending upon the capability of the h/w and it's driver, fine-tuning can be achieved to max possible extent.
something like....
snd_pcm_uframes_t prd, ring;
/* Get current ratio */ prd = 257, ring = 256; /* Invalid ratio */ snd_pcm_set_ratio(&prd, &ring);
/* Increase the period by desirable amount */ prd += incr; snd_pcm_set_ratio(&prd, &ring);
/* Disable period interrupts */ prd = 0, ring = 0; snd_pcm_set_ratio(&prd, &ring); if (!prd && !ring) { Interrupts are successfull disabled; } else { prd/ring ratio is max supported by h/w }