Hi,
I added support for "Playback Pitch 1000000" ctl elem to UAC2 gadget (not submitted to USB yet) and now I am working on alsaloop support for this ctl elem. The changes are simple (tested to work perfectly, patch to follow), but during the work I hit the following issue with playback Loopback "PCM Rate Shift 100000".
If the snd-aloop device is on playback side (i.e. capture from soundcard -> Loopback), the required sync mode is PLAYSHIFT. That means Loopback ctl elem "PCM Rate Shift 100000" should be controlled (by a reciprocal). That is simple by a patch like this:
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c index 845ab82..619bf35 100644 --- a/alsaloop/pcmjob.c +++ b/alsaloop/pcmjob.c @@ -1061,7 +1061,13 @@ static int set_rate_shift(struct loopback_handle *lhandle, double pitch) int err;
if (lhandle->ctl_rate_shift) { - snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000); + long value; + if (lhandle->loopback->play == lhandle) + // playback => reciprocal + value = 1/(pitch) * 100000; + else + value = pitch * 100000; + snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, value); err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_rate_shift); } else if (lhandle->capt_pitch) { snd_ctl_elem_value_set_integer(lhandle->capt_pitch, 0, (1 / pitch) * 1000000); @@ -1205,15 +1211,18 @@ static int openctl(struct loopback_handle *lhandle, int device, int subdevice) int err;
lhandle->ctl_rate_shift = NULL; + // both play and capture + openctl_elem(lhandle, device, subdevice, "PCM Notify", + &lhandle->ctl_notify); + openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000", + &lhandle->ctl_rate_shift); if (lhandle->loopback->play == lhandle) { + // play only if (lhandle->loopback->controls) goto __events; return 0; } - openctl_elem(lhandle, device, subdevice, "PCM Notify", - &lhandle->ctl_notify); - openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000", - &lhandle->ctl_rate_shift); + // capture only openctl_elem(lhandle, device, subdevice, "Capture Pitch 1000000", &lhandle->capt_pitch); set_rate_shift(lhandle, 1);
However, IIUC how the Loopback device works, the "PCM Rate Shift 100000" ctl elem applicable to device=0 on playback side is that of the capture side, i.e. for device=1. The patch above would pick the playback-side device=0 ctl elem in pcmjob.c:openctl_elem. Hard-coding the device=0 -> device=1 is possible, but Loopback supports more devices.
Please what solution for picking the correct "PCM Rate Shift 100000" ctl elem for the PLAYSHIFT sync mode would you recommend?
Thanks a lot,
Pavel.