Re: How to add full duplex capture and playback?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At Fri, 19 May 2006 17:42:55 +0200,
Hans-Christian Egtvedt wrote:
> 
> Takashi Iwai wrote:
> > At Fri, 19 May 2006 12:44:58 +0200,
> > Hans-Christian Egtvedt wrote:
> >> Hans-Christian Egtvedt wrote:
> 
> <snipp>
> 
> > capture->runtime->rate isn't set properly unless hw_params is called
> > in the capture side.  That is, if your app opens both sides at the
> > same time but not set up each by other, it doesn't work.
> > 
> > It's better to set chip->cur_rate and chip->cur_format in hw_params
> > callback (with care of number of opened streams).
> 
> Ok
> 
> >> 		hw_constraint_rates.count	= ARRAY_SIZE(hw_rates);
> >> 		hw_constraint_rates.list	= hw_rates;
> >> 		hw_constraint_rates.mask	= 0;
> >>
> >> 		hw_formats[0] = (unsigned int)capture_runtime->format;
> >> 		hw_constraint_formats.count	= ARRAY_SIZE(hw_formats);
> >> 		hw_constraint_formats.list	= hw_formats;
> >> 		hw_constraint_formats.mask	= 0;
> > 
> > They can be more easily done by overwriting runtime->hw entries, for
> > example,
> > 	runtime->hw.rate_min = runtime->hw.rate_max = chip->cur_rate;
> > and
> > 	runtime->hw.formats = chip->cur_format_mask;
> 
> To the capture and playback hw_param callbacks I've added:
> 
> /* Set restrictions to params */
> if (chip->playback_active) { /* capture_active for playback callback */
> 	runtime->hw.rate_min = runtime->hw.rate_max = chip->cur_rate;
> 	runtime->hw.formats = chip->cur_format;
> }
> 
> But it does not work quite as expected. I'm still able to set rate and
> format from userspace (aplay/arecord), and this again will alter the
> hardware setup when the prepare callback is called.

Right.  The restriction of configuration space is defined by the rules
set in open callback.  hw_params callback just follows the given
parameter and returns the success or the failure code.

A typical code is like below:

	hw_params(substream, params)
	{
		...
		chip->cur_rate = params_rate(params);
		chip->cur_format = params_format(params);
		...
	}

	open(substream)
	{
		...
		chip->opened++;
		runtime->hw = hardware_info;
		if (chip->cur_rate) {
			runtime->hw.rate_min = chip->cur_rate;
			runtime->hw.rate_max = chip->cur_rate;
		}
		if (chip->cur_format)
			runtime->hw.formats = (1ULL << chip->cur_format);
		...
	}

	close(substream)
	{
		...
		chip->opened--;
		if (! chip->opened) {
			chip->cur_rate = 0;
			chip->cur_format = 0;
		}
		...
	}

In addition, a proper mutex would be preferred around the operation.

To be more strict, we may change hw_params like the following:

	hw_params()
	{
		...
		if (chip->opened > 1) {
			/* we are not alone, check the conflicts */
			if (chip->cur_rate &&
			    chip->cur_rate != params_rate(params))
				return -EBUSY;
			if (chip->cur_format &&
			    chip->cur_format != params_format(params))
				return -EBUSY;
		}
		chip->cur_rate = params_rate(params);
		chip->cur_format = params_format(params);
		...
	}

However, this doesn't work with OSS emulation because OSS emulation
initializes the rate to a certain default one.  If app tries to change
the rate in the full-duplex mode, then it's refused.


Takashi


-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux