Re: usb: u_audio: Notifying gadget audio device about starting/stopping capture/playback on the host

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

 



Dne 12. 05. 21 v 10:47 Pavel Hofman napsal(a):
> Hi,
> 
> I am trying to notify the user-space code running on USB audio gadget
> that the USB host has started/stopped capture/playback.
> 
> For stopping action, I am enclosing a patch snippet. I used snd_pcm_stop
> code when alsa SPDIF receivers detect a change in the stream
> https://github.com/torvalds/linux/blob/master/sound/i2c/other/ak4117.c#L505
> When testing the code, aplay/arecord ends, sox just reports alsa device
> warning and does not stop. IMO that is the desired outcome - the
> snd_pcm_read/write methods returned errors when capture/playback on the
> host side stopped.
> 
> For starting the capture/playback on the host, perhaps some
> snd_ctl_notify on some dedicated alsa control could be used, notifying
> the user space application that it can open the gadget audio device?
> 
> The patch below does not compile on upstream kernel as it uses changes
> not included in upstream yet (explicit feedback EP, samplerate
> switching), but I am just discussing principles and options now.
> 
> Thank you very much for your opinion and recommendations.
> 

Hi, please may I ask for some feedback? The gadget has a great potential
but it's still missing features important for a smooth usage. I want to
add more patches but have not gotten any feedback in the last months. I
am "hoarding" audio gadget-related patches (not proper commit
descriptions in commits authored by me yet) in my repo
https://github.com/pavhofman/linux-rpi/commits/rpi-5.12.y for now. When
Ruslan's/Jerome's async feedback EP patches finally make it upstream I
will rebase accordingly.

Thank you,

Pavel.


> 
> 
> 
> 
> diff --git a/drivers/usb/gadget/function/u_audio.c
> b/drivers/usb/gadget/function/u_audio.c
> index 45367d650c5a..c6cdb844fec1 100644
> --- a/drivers/usb/gadget/function/u_audio.c
> +++ b/drivers/usb/gadget/function/u_audio.c
> @@ -565,6 +565,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
>  	struct uac_params *params = &audio_dev->params;
>  	int req_len, i;
> 
> +  dev_dbg(dev, "starting capture with rate %d\n", params->c_srate_active);
>  	ep = audio_dev->out_ep;
>  	prm = &uac->c_prm;
>  	config_ep_by_speed(gadget, &audio_dev->func, ep);
> @@ -635,6 +636,23 @@ EXPORT_SYMBOL_GPL(u_audio_start_capture);
>  void u_audio_stop_capture(struct g_audio *audio_dev)
>  {
>  	struct snd_uac_chip *uac = audio_dev->uac;
> +	unsigned long _flags;
> +	struct snd_pcm_substream *substream;
> +	struct uac_rtd_params *prm;
> +
> +  dev_dbg(uac->card->dev, "stopping capture\n");
> +  prm = &uac->c_prm;
> +  if (prm) {
> +    substream = prm->ss;
> +    if (substream) {
> +      dev_dbg(uac->card->dev, "stopping capture substream\n");
> +      snd_pcm_stream_lock_irqsave(substream, _flags);
> +      if (snd_pcm_running(substream)) {
> +        snd_pcm_stop(substream, SNDRV_PCM_STATE_DRAINING);
> +      }
> +      snd_pcm_stream_unlock_irqrestore(substream, _flags);
> +    }
> +  }
> 
>  	if (audio_dev->in_ep_fback)
>  		free_ep_fback(&uac->c_prm, audio_dev->in_ep_fback);
> @@ -655,7 +673,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
>  	const struct usb_endpoint_descriptor *ep_desc;
>  	int req_len, i;
> 
> -  dev_dbg(dev, "start playback with rate %d\n", params->p_srate_active);
> +  dev_dbg(dev, "starting playback with rate %d\n", params->p_srate_active);
>  	ep = audio_dev->in_ep;
>  	prm = &uac->p_prm;
>  	config_ep_by_speed(gadget, &audio_dev->func, ep);
> @@ -715,6 +733,23 @@ EXPORT_SYMBOL_GPL(u_audio_start_playback);
>  void u_audio_stop_playback(struct g_audio *audio_dev)
>  {
>  	struct snd_uac_chip *uac = audio_dev->uac;
> +  unsigned long _flags;
> +  struct snd_pcm_substream *substream;
> +  struct uac_rtd_params *prm;
> +
> +  dev_dbg(uac->card->dev, "stopping playback\n");
> +  prm = &uac->p_prm;
> +  if (prm) {
> +    substream = prm->ss;
> +    if (substream) {
> +      dev_dbg(uac->card->dev, "stopping playback substream\n");
> +      snd_pcm_stream_lock_irqsave(substream, _flags);
> +      if (snd_pcm_running(substream)) {
> +        snd_pcm_stop(substream, SNDRV_PCM_STATE_DRAINING);
> +      }
> +      snd_pcm_stream_unlock_irqrestore(substream, _flags);
> +    }
> +  }
> 
>  	free_ep(&uac->p_prm, audio_dev->in_ep);
>  }
> 



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux