* How to add full duplex capture and playback?
@ 2006-05-19 9:29 Hans-Christian Egtvedt
2006-05-19 10:44 ` Hans-Christian Egtvedt
0 siblings, 1 reply; 6+ messages in thread
From: Hans-Christian Egtvedt @ 2006-05-19 9:29 UTC (permalink / raw)
To: alsa-devel
Hello
I'm strugling a bit with getting my AC97 driver to be full duplex. The
hardware supports it, but I can't seem to enable it correctly in the driver.
Is there anything I've missed other than this?
err = snd_pcm_new(chip->card, "Atmel AC97", 0, 1, 1, &pcm);
AFAIK this should give me two substreams, one for capture and one for
playback. Do I have to take some care with other calls?
When I try to playback and record simultaneously I get the following error:
ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not usable
aplay: set_params:879: Broken configuration for this PCM: no
configurations available
--
With kind regards,
Med vennlig hilsen,
Hans-Christian Egtvedt
Applications Engineer - AVR Applications Lab
Atmel Norway
-------------------------------------------------------
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: How to add full duplex capture and playback?
2006-05-19 9:29 How to add full duplex capture and playback? Hans-Christian Egtvedt
@ 2006-05-19 10:44 ` Hans-Christian Egtvedt
2006-05-19 12:54 ` Takashi Iwai
0 siblings, 1 reply; 6+ messages in thread
From: Hans-Christian Egtvedt @ 2006-05-19 10:44 UTC (permalink / raw)
To: alsa-devel
Hans-Christian Egtvedt wrote:
> Hello
>
> I'm strugling a bit with getting my AC97 driver to be full duplex. The
> hardware supports it, but I can't seem to enable it correctly in the driver.
>
> Is there anything I've missed other than this?
> err = snd_pcm_new(chip->card, "Atmel AC97", 0, 1, 1, &pcm);
This is actually correct I see, I have both a substream for capture and
a substream for playback:
~ # aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: AC97 [Atmel AVR32 AC97], device 0: Atmel AC97 [Atmel AC97]
Subdevices: 1/1
Subdevice #0: subdevice #0
~ # arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: AC97 [Atmel AVR32 AC97], device 0: Atmel AC97 [Atmel AC97]
Subdevices: 1/1
Subdevice #0: subdevice #0
I assume this is a "good" output from the utils.
> AFAIK this should give me two substreams, one for capture and one for
> playback. Do I have to take some care with other calls?
>
> When I try to playback and record simultaneously I get the following error:
> ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not usable
> aplay: set_params:879: Broken configuration for this PCM: no
> configurations available
This problem is due to the following open call, and was solved by
commenting it out, which is not an option for the final driver.
Open call:
static int
snd_atmel_ac97_playback_open(snd_pcm_substream_t *substream)
{
atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
chip->playback_active = 1;
printk(KERN_INFO "atmel-ac97: entering playback open\n");
runtime->hw = snd_atmel_ac97_playback_hw;
/* Setup hardware to match capture settings */
#if 0
if (chip->capture_active) {
int err = 0;
snd_pcm_runtime_t *capture_runtime =
chip->capture_substream->runtime;
hw_rates[0] = (unsigned int)capture_runtime->rate;
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;
printk(KERN_INFO "atmel_ac97: capture active, set limits to playback\n");
err = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&hw_constraint_rates);
err = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
&hw_constraint_formats);
printk(KERN_INFO "atmel-ac97: limiting playback rate to %d\n",
capture_runtime->rate);
if (err < 0)
return err;
}
#endif
chip->playback_substream = substream;
chip->period = 0;
return 0;
}
Seems like this open call (without #if 0) clear the configuration for
the PCM, basicly leaving it unusable.
Any comments?
--
With kind regards,
Med vennlig hilsen,
Hans-Christian Egtvedt
Applications Engineer - AVR Applications Lab
Atmel Norway
-------------------------------------------------------
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: How to add full duplex capture and playback?
2006-05-19 10:44 ` Hans-Christian Egtvedt
@ 2006-05-19 12:54 ` Takashi Iwai
2006-05-19 15:42 ` Hans-Christian Egtvedt
0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2006-05-19 12:54 UTC (permalink / raw)
To: Hans-Christian Egtvedt; +Cc: alsa-devel
At Fri, 19 May 2006 12:44:58 +0200,
Hans-Christian Egtvedt wrote:
>
> Hans-Christian Egtvedt wrote:
> > Hello
> >
> > I'm strugling a bit with getting my AC97 driver to be full duplex. The
> > hardware supports it, but I can't seem to enable it correctly in the driver.
> >
> > Is there anything I've missed other than this?
> > err = snd_pcm_new(chip->card, "Atmel AC97", 0, 1, 1, &pcm);
>
> This is actually correct I see, I have both a substream for capture and
> a substream for playback:
> ~ # aplay -l
> **** List of PLAYBACK Hardware Devices ****
> card 0: AC97 [Atmel AVR32 AC97], device 0: Atmel AC97 [Atmel AC97]
> Subdevices: 1/1
> Subdevice #0: subdevice #0
> ~ # arecord -l
> **** List of CAPTURE Hardware Devices ****
> card 0: AC97 [Atmel AVR32 AC97], device 0: Atmel AC97 [Atmel AC97]
> Subdevices: 1/1
> Subdevice #0: subdevice #0
>
> I assume this is a "good" output from the utils.
>
> > AFAIK this should give me two substreams, one for capture and one for
> > playback. Do I have to take some care with other calls?
> >
> > When I try to playback and record simultaneously I get the following error:
> > ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not usable
> > aplay: set_params:879: Broken configuration for this PCM: no
> > configurations available
>
> This problem is due to the following open call, and was solved by
> commenting it out, which is not an option for the final driver.
>
> Open call:
> static int
> snd_atmel_ac97_playback_open(snd_pcm_substream_t *substream)
> {
> atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
> snd_pcm_runtime_t *runtime = substream->runtime;
>
> chip->playback_active = 1;
>
> printk(KERN_INFO "atmel-ac97: entering playback open\n");
>
> runtime->hw = snd_atmel_ac97_playback_hw;
>
> /* Setup hardware to match capture settings */
> #if 0
> if (chip->capture_active) {
> int err = 0;
> snd_pcm_runtime_t *capture_runtime =
> chip->capture_substream->runtime;
>
> hw_rates[0] = (unsigned int)capture_runtime->rate;
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).
> 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;
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: How to add full duplex capture and playback?
2006-05-19 12:54 ` Takashi Iwai
@ 2006-05-19 15:42 ` Hans-Christian Egtvedt
2006-05-19 16:08 ` Takashi Iwai
0 siblings, 1 reply; 6+ messages in thread
From: Hans-Christian Egtvedt @ 2006-05-19 15:42 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
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.
In the prepare callback I set the endianess and rate for the hardware
controller based upon what's in the runtime->rate and runtime->format.
I did some printk's in the prepare callback and when playing a S16_LE
44100 Hz file I could record S16_BE 48000 Hz, and this will change the
hardware.
I.e. the runtime->hw.rate_min, rate_max and format was correct in the
prepare callback, but the runtime->rate and format was incorrect,
holding the values I gave from aplay/arecord in userspace.
>From what I've understood the limits you set in hw_params callback
should limit the values in the runtime when prepare callback is called?
I also did some printk's in the hw params callback, and there the format
in runtime->format and runtime->rate still 0, not the values given from
userspace.
Any feedback is greatly appreciated.
Sorry if this email is a bit untidy (-:
--
With kind regards,
Med vennlig hilsen,
Hans-Christian Egtvedt
Applications Engineer - AVR Applications Lab
Atmel Norway
-------------------------------------------------------
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: How to add full duplex capture and playback?
2006-05-19 15:42 ` Hans-Christian Egtvedt
@ 2006-05-19 16:08 ` Takashi Iwai
2006-05-23 12:57 ` Hans-Christian Egtvedt
0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2006-05-19 16:08 UTC (permalink / raw)
To: Hans-Christian Egtvedt; +Cc: alsa-devel
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: How to add full duplex capture and playback?
2006-05-19 16:08 ` Takashi Iwai
@ 2006-05-23 12:57 ` Hans-Christian Egtvedt
0 siblings, 0 replies; 6+ messages in thread
From: Hans-Christian Egtvedt @ 2006-05-23 12:57 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
Takashi Iwai wrote:
> 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:
<snipp code>
>> 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:
<snipp code example>
Thank you, this really clear things up. Driver is working as expected now.
> In addition, a proper mutex would be preferred around the operation.
>
> To be more strict, we may change hw_params like the following:
<snipp code example>
> 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.
I will leave this part out for now, since it dosn't work with OSS
emaulation.
--
With kind regards,
Med vennlig hilsen,
Hans-Christian Egtvedt
Applications Engineer - AVR Applications Lab
Atmel Norway
-------------------------------------------------------
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
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-05-23 12:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-19 9:29 How to add full duplex capture and playback? Hans-Christian Egtvedt
2006-05-19 10:44 ` Hans-Christian Egtvedt
2006-05-19 12:54 ` Takashi Iwai
2006-05-19 15:42 ` Hans-Christian Egtvedt
2006-05-19 16:08 ` Takashi Iwai
2006-05-23 12:57 ` Hans-Christian Egtvedt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.