[alsa-devel] [Alsa-user] Status of CM6631 USB
Daniel Mack
zonque at gmail.com
Sat Mar 2 13:21:46 CET 2013
Hi Torstein,
(+ alsa-devel)
On 02.03.2013 12:09, Torstein Hegge wrote:
> Daniel Mack <zonque <at> gmail.com> writes:
>>>> This is a known bug, also most probably flaw in the CMEDIA chip,
>>>> and not yet properly worked around in the snd-usb driver. If you
>>>> want to investigate, have a look at the feedback format
>>>> autodetection code in sound/usb/endpoint.c.
>>>
>>> Thanks, I'll have a look.
>>
>> I believe what's going on here is that the device is confused after
>> sample rate changes and keeps sending back feedback data for the old
>> rate on its feedback endpoint. That causes the autodetection algorithm,
>> which kicks in on every first packet of a stream, to go nuts, which
>> causes the part of the driver that sends the data assume a very wrong
>> rate. Some printk() there should give you a hint.
>
> I had a look at this using another C-Media CM6631 based device, the Corda
> Daccord (usbid 0x0d8c, 0x0309). As far as I can see, what happens in the
> feedback format auto-detection is:
>
> When starting playback of a file with a different sampling frequency than the
> previous file, the reported feedback frequency is in the same range as the
> previously played file, varying within +-1%.
>
> The feedback format detection gives a shift of -1 and reports the feedback
> frequency as ~48kHz when playing a 44.1kHz file after a 96kHz file. Same thing
> happens when playing a 96kHz file after a 44.1kHz file, the device reports
> feedback frequency in the 44.1kHz range, the feedback format detection gives a
> shift of +1 and reports the feedback frequency as ~88kHz.
That's what I suspected.
> Bypassing the feedback format detection by hard-coding the frequency shift to
> zero and setting the feedback frequency ep->freqm equal to the nominal
> frequency ep->freqn if the feedback frequency is far off from the expected
> value (like 48kHz when expecting 44.1kHz) does not change the distortion.
>
> Similarly, forcing the feedback detection to run multiple times until it
> reaches an acceptable value just keeps the feedback detection to repeatedly
> until playback is stopped. This probably means any amount of skipping packages
> early in the stream won't work.
Ok.
> It seems like the device stays in the previous frequency until the interface
> is reset. One possible workaround is to call usb_set_interface() again after
> snd_usb_init_sample_rate(), like this:
I see - that also explains why explicitly stopping and restarting the
stream fixes the problem in most cases, right?
>
> diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
> index d82e378..01978a6 100644
> --- a/sound/usb/pcm.c
> +++ b/sound/usb/pcm.c
> @@ -710,6 +710,16 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream
> *substream)
> subs->need_setup_ep = false;
> }
>
> + /* Some devices doesn't respond to sample rate changes while the
> + * interface is active. */
> + switch (subs->stream->chip->usb_id) {
> + case USB_ID(0x0d8c, 0x0304): /* C-Media - Schiit USB Interface */
> + case USB_ID(0x0d8c, 0x0309): /* C-Media CM6631 */
> + usb_set_interface(subs->dev, subs->cur_audiofmt->iface,
> + subs->cur_audiofmt->altset_idx);
> + break;
> + }
> +
> /* some unit conversions in runtime */
> subs->data_endpoint->maxframesize =
> bytes_to_frames(runtime, subs->data_endpoint->maxpacksize);
>
> This fixes all problems related to sample rate changes for me. I have only
> tested with the Daccord, but it should work for the Schiit and other CM6631
> based devices as well.
Many thanks for looking into this! Much appreciated.
Could you cook a real patch please and send it to alsa-devel? Have a
look at Documentation/SubmittingPatches if that's your first submission.
Best,
Daniel
More information about the Alsa-devel
mailing list