Alsaloop: sync mode PLAYSHIFT + Loopback on playback side

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

 



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.



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux