]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsaloop: Support "Capture Pitch 1000000" rate shift
authorYunhao Tian <t123yh@outlook.com>
Tue, 27 Jul 2021 15:52:30 +0000 (23:52 +0800)
committerJaroslav Kysela <perex@perex.cz>
Mon, 23 Aug 2021 14:55:36 +0000 (16:55 +0200)
In Linux 5.14, a new feedback mechanism for USB Audio
Gadget is introduced (commit e89bb428), along with a
new control element "Capture Pitch 1000000". This patch
adds support for this feature. Note that this property
seems to be the reverse of PCM Rate Shift, so we have
to take reciprocal of pitch.

Signed-off-by: Yunhao Tian <t123yh@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
alsaloop/alsaloop.h
alsaloop/pcmjob.c

index c4aa6180757f970ae90f9778dffcc8c3f9497187..1dbcefe68b966af5a21f9090c0ea150518bba8b2 100644 (file)
@@ -122,6 +122,7 @@ struct loopback_handle {
        unsigned int ctl_pollfd_count;
        snd_ctl_elem_value_t *ctl_notify;
        snd_ctl_elem_value_t *ctl_rate_shift;
+       snd_ctl_elem_value_t *capt_pitch;
        snd_ctl_elem_value_t *ctl_active;
        snd_ctl_elem_value_t *ctl_format;
        snd_ctl_elem_value_t *ctl_rate;
index 4efdd63f25217c7d35893ce6dedd97c0ee9d0634..8b72af4dad3ac25c41ebc6b9572ef7b0575cbe9e 100644 (file)
@@ -1060,10 +1060,15 @@ static int set_rate_shift(struct loopback_handle *lhandle, double pitch)
 {
        int err;
 
-       if (lhandle->ctl_rate_shift == NULL)
+       if (lhandle->ctl_rate_shift) {
+               snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000);
+               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);
+               err = snd_ctl_elem_write(lhandle->ctl, lhandle->capt_pitch);
+       } else {
                return 0;
-       snd_ctl_elem_value_set_integer(lhandle->ctl_rate_shift, 0, pitch * 100000);
-       err = snd_ctl_elem_write(lhandle->ctl, lhandle->ctl_rate_shift);
+       }
        if (err < 0) {
                logit(LOG_CRIT, "Cannot set PCM Rate Shift element for %s: %s\n", lhandle->id, snd_strerror(err));
                return err;
@@ -1204,6 +1209,8 @@ static int openctl(struct loopback_handle *lhandle, int device, int subdevice)
                        &lhandle->ctl_notify);
        openctl_elem(lhandle, device, subdevice, "PCM Rate Shift 100000",
                        &lhandle->ctl_rate_shift);
+       openctl_elem(lhandle, device, subdevice, "Capture Pitch 1000000",
+                       &lhandle->capt_pitch);
        set_rate_shift(lhandle, 1);
        openctl_elem(lhandle, device, subdevice, "PCM Slave Active",
                        &lhandle->ctl_active);
@@ -1289,6 +1296,9 @@ static int closeit(struct loopback_handle *lhandle)
        if (lhandle->ctl_rate_shift)
                snd_ctl_elem_value_free(lhandle->ctl_rate_shift);
        lhandle->ctl_rate_shift = NULL;
+       if (lhandle->capt_pitch)
+               snd_ctl_elem_value_free(lhandle->capt_pitch);
+       lhandle->capt_pitch = NULL;
        if (lhandle->ctl)
                err = snd_ctl_close(lhandle->ctl);
        lhandle->ctl = NULL;
@@ -1334,7 +1344,7 @@ int pcmjob_init(struct loopback *loop)
        snprintf(id, sizeof(id), "%s/%s", loop->play->id, loop->capt->id);
        id[sizeof(id)-1] = '\0';
        loop->id = strdup(id);
-       if (loop->sync == SYNC_TYPE_AUTO && loop->capt->ctl_rate_shift)
+       if (loop->sync == SYNC_TYPE_AUTO && (loop->capt->ctl_rate_shift || loop->capt->capt_pitch))
                loop->sync = SYNC_TYPE_CAPTRATESHIFT;
        if (loop->sync == SYNC_TYPE_AUTO && loop->play->ctl_rate_shift)
                loop->sync = SYNC_TYPE_PLAYRATESHIFT;