Alsaloop: sync mode PLAYSHIFT + Loopback on playback side
Pavel Hofman
pavel.hofman at ivitera.com
Fri Oct 1 10:35:34 CEST 2021
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.
More information about the Alsa-devel
mailing list