Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package alsa-plugins for openSUSE:Factory 
checked in at 2021-12-08 22:08:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/alsa-plugins (Old)
 and      /work/SRC/openSUSE:Factory/.alsa-plugins.new.31177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "alsa-plugins"

Wed Dec  8 22:08:39 2021 rev:112 rq:936044 version:1.2.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/alsa-plugins/alsa-plugins.changes        
2021-06-05 23:30:50.396365752 +0200
+++ /work/SRC/openSUSE:Factory/.alsa-plugins.new.31177/alsa-plugins.changes     
2021-12-08 22:09:03.594865511 +0100
@@ -1,0 +2,8 @@
+Mon Dec  6 15:02:33 CET 2021 - [email protected]
+
+- Update to version 1.2.6:
+  Fixes for a52 plugin, jack, rate-lav.  For details, see URL:
+    https://alsa-project.org/wiki/Changes_v1.2.5.1_v1.2.6#alsa-plugins
+- Add *.sig file for the source tarball
+
+-------------------------------------------------------------------

Old:
----
  alsa-plugins-1.2.5.tar.bz2

New:
----
  alsa-plugins-1.2.6.tar.bz2
  alsa-plugins-1.2.6.tar.bz2.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ alsa-plugins.spec ++++++
--- /var/tmp/diff_new_pack.4a1sYk/_old  2021-12-08 22:09:04.202865796 +0100
+++ /var/tmp/diff_new_pack.4a1sYk/_new  2021-12-08 22:09:04.206865798 +0100
@@ -23,14 +23,15 @@
 %endif
 
 Name:           alsa-plugins
-Version:        1.2.5
+Version:        1.2.6
 Release:        0
 Summary:        Extra Plug-Ins for ALSA Library
 License:        LGPL-2.1-or-later
 Group:          System/Libraries
-Url:            https://www.alsa-project.org
+URL:            https://www.alsa-project.org
 Source:         
https://www.alsa-project.org/files/pub/plugins/alsa-plugins-%{version}.tar.bz2
-Source1:        baselibs.conf
+Source1:        
https://www.alsa-project.org/files/pub/plugins/alsa-plugins-%{version}.tar.bz2.sig
+Source2:        baselibs.conf
 BuildRequires:  libtool
 BuildRequires:  pkgconfig(alsa) >= 1.2.5
 %if %{build_aaf}

++++++ alsa-plugins-1.2.5.tar.bz2 -> alsa-plugins-1.2.6.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/a52/60-a52-encoder.conf 
new/alsa-plugins-1.2.6/a52/60-a52-encoder.conf
--- old/alsa-plugins-1.2.5/a52/60-a52-encoder.conf      2021-05-27 
19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/a52/60-a52-encoder.conf      2021-12-06 
11:17:29.000000000 +0100
@@ -36,3 +36,10 @@
                 description "Plugin to convert multichannel stream to A52 
(AC3) bitstream"
        }
 }
+
+#
+# A quick test command:
+#   CARD=1         # replace with your IEC958 card
+#   DEVICE=1       # replace with your IEC958 PCM device number
+#   speaker-test -d -b 2000000 -c 6 
-D"plug:{SLAVE=\"a52:${CARD},'hw:${CARD},${DEVICE}'\"}"
+#
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/a52/pcm_a52.c 
new/alsa-plugins-1.2.6/a52/pcm_a52.c
--- old/alsa-plugins-1.2.5/a52/pcm_a52.c        2021-05-27 19:18:39.000000000 
+0200
+++ new/alsa-plugins-1.2.6/a52/pcm_a52.c        2021-12-06 11:17:29.000000000 
+0100
@@ -41,7 +41,12 @@
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 34, 0)
 #include <libavutil/channel_layout.h>
 #include <libavutil/mem.h>
-#define USE_AVCODEC_FRAME
+#define USE_AVCODEC_FRAME 1
+#endif
+
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 91, 0)
+#include <libavcodec/packet.h>
+#define USE_AVCODEC_PACKET_ALLOC
 #endif
 
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 0, 0)
@@ -62,6 +67,12 @@
 #define AV_CODEC_ID_AC3 CODEC_ID_AC3
 #endif
 
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56, 56, 0)
+#ifndef AV_INPUT_BUFFER_PADDING_SIZE
+#define AV_INPUT_BUFFER_PADDING_SIZE   FF_INPUT_BUFFER_PADDING_SIZE
+#endif
+#endif
+
 #if LIBAVCODEC_VERSION_INT < 0x371c01
 #define av_frame_alloc avcodec_alloc_frame
 #define av_frame_free avcodec_free_frame
@@ -72,20 +83,29 @@
        snd_pcm_t *slave;
        AVCodec *codec;
        AVCodecContext *avctx;
+       snd_pcm_format_t src_format;
+       unsigned int src_sample_bits;
+       unsigned int src_sample_bytes;
        snd_pcm_format_t format;
        int av_format;
        unsigned int channels;
        unsigned int rate;
        unsigned int bitrate;
-       short *inbuf;
+       void *inbuf;
        unsigned char *outbuf;
+       unsigned char *outbuf1;
+       unsigned char *outbuf2;
        int outbuf_size;
-       snd_pcm_uframes_t transfer;
        int remain;
        int filled;
        unsigned int slave_period_size;
        unsigned int slave_buffer_size;
+       snd_pcm_uframes_t pointer;
+       snd_pcm_uframes_t boundary;
        snd_pcm_hw_params_t *hw_params;
+#ifdef USE_AVCODEC_PACKET_ALLOC
+       AVPacket *pkt;
+#endif
 #ifdef USE_AVCODEC_FRAME
        AVFrame *frame;
        int is_planar;
@@ -98,70 +118,103 @@
 #define use_planar(rec)                0
 #endif
 
-#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 34, 0)
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 91, 0)
+static int do_encode(struct a52_ctx *rec)
+{
+       AVPacket *pkt = rec->pkt;
+       int ret;
+
+       ret = avcodec_send_frame(rec->avctx, rec->frame);
+       if (ret < 0)
+               return -EINVAL;
+       ret = avcodec_receive_packet(rec->avctx, pkt);
+       if (ret < 0)
+               return -EINVAL;
+
+       if (pkt->size > rec->outbuf_size - 8)
+               return -EINVAL;
+       memcpy(rec->outbuf1 + 8, pkt->data, pkt->size);
+
+       return pkt->size;
+}
+#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 34, 0)
 static int do_encode(struct a52_ctx *rec)
 {
        AVPacket pkt = {
-               .data = rec->outbuf + 8,
+               .data = rec->outbuf1 + 8,
                .size = rec->outbuf_size - 8
        };
-       int got_frame;
+       int ret, got_frame;
+
+       ret = avcodec_encode_audio2(rec->avctx, &pkt, rec->frame, &got_frame);
+       if (ret < 0)
+               return -EINVAL;
 
-       avcodec_encode_audio2(rec->avctx, &pkt, rec->frame, &got_frame);
        return pkt.size;
 }
 #else
 static int do_encode(struct a52_ctx *rec)
 {
-       return avcodec_encode_audio(rec->avctx, rec->outbuf + 8,
-                                   rec->outbuf_size - 8,
-                                   rec->inbuf);
+       int ret = avcodec_encode_audio(rec->avctx, rec->outbuf1 + 8,
+                                      rec->outbuf_size - 8,
+                                      rec->inbuf);
+       if (ret < 0)
+               return -EINVAL;
+
+       return ret;
 }
 #endif
 
 /* convert the PCM data to A52 stream in IEC958 */
-static void convert_data(struct a52_ctx *rec)
+static int convert_data(struct a52_ctx *rec)
 {
+       unsigned char *buf;
        int out_bytes = do_encode(rec);
 
-       rec->outbuf[0] = 0xf8; /* sync words */
-       rec->outbuf[1] = 0x72;
-       rec->outbuf[2] = 0x4e;
-       rec->outbuf[3] = 0x1f;
-       rec->outbuf[4] = rec->outbuf[13] & 7; /* bsmod */
-       rec->outbuf[5] = 0x01; /* data type */
-       rec->outbuf[6] = ((out_bytes * 8) >> 8) & 0xff;
-       rec->outbuf[7] = (out_bytes * 8) & 0xff;
+       if (out_bytes < 0)
+               return out_bytes;
+
+       buf = rec->outbuf1;
+       buf[0] = 0xf8; /* sync words */
+       buf[1] = 0x72;
+       buf[2] = 0x4e;
+       buf[3] = 0x1f;
+       buf[4] = buf[13] & 7; /* bsmod */
+       buf[5] = 0x01; /* data type */
+       buf[6] = ((out_bytes * 8) >> 8) & 0xff;
+       buf[7] = (out_bytes * 8) & 0xff;
        /* swap bytes for little-endian 16bit */
-       if (rec->format == SND_PCM_FORMAT_S16_LE)
-               swab(rec->outbuf, rec->outbuf, out_bytes + 8);
-       memset(rec->outbuf +  8 + out_bytes, 0,
+       if (rec->format == SND_PCM_FORMAT_S16_LE) {
+               swab(rec->outbuf1, rec->outbuf2, out_bytes + 8);
+               buf = rec->outbuf2;
+       }
+       rec->outbuf = buf;
+       memset(buf + 8 + out_bytes, 0,
               rec->outbuf_size - 8 - out_bytes);
        rec->remain = rec->outbuf_size / 4;
        rec->filled = 0;
+
+       return 0;
 }
 
 /* write pending encoded data to the slave pcm */
 static int write_out_pending(snd_pcm_ioplug_t *io, struct a52_ctx *rec)
 {
-       int err, ofs = (rec->avctx->frame_size - rec->remain) * 4;
-
-       if (! rec->remain)
-               return 0;
+       snd_pcm_sframes_t ret;
+       unsigned int ofs;
 
        while (rec->remain) {
-               err = snd_pcm_writei(rec->slave, rec->outbuf + ofs, 
rec->remain);
-               if (err < 0) {
-                       if (err == -EPIPE)
+               ofs = (rec->avctx->frame_size - rec->remain) * 4;
+               ret = snd_pcm_writei(rec->slave, rec->outbuf + ofs, 
rec->remain);
+               if (ret < 0) {
+                       if (ret == -EPIPE)
                                io->state = SND_PCM_STATE_XRUN;
-                       if (err == -EAGAIN)
+                       if (ret == -EAGAIN)
                                break;
-                       return err;
-               } else if (! err)
+                       return ret;
+               } else if (! ret)
                        break;
-               if (err < rec->remain)
-                       ofs += (rec->remain - err) * 4;
-               rec->remain -= err;
+               rec->remain -= ret;
        }
        return 0;
 }
@@ -176,8 +229,8 @@
        unsigned int i;
 
        for (i = 0; i < io->channels; i++)
-               memset(rec->frame->data[i] + rec->filled * 2, 0,
-                      (rec->avctx->frame_size - rec->filled) * 2);
+               memset(rec->frame->data[i] + rec->filled * 
rec->src_sample_bytes, 0,
+                      (rec->avctx->frame_size - rec->filled) * 
rec->src_sample_bytes);
 }
 #else
 #define clear_remaining_planar_data(io) /*NOP*/
@@ -195,10 +248,12 @@
                if (use_planar(rec))
                        clear_remaining_planar_data(io);
                else {
-                       memset(rec->inbuf + rec->filled * io->channels, 0,
-                              (rec->avctx->frame_size - rec->filled) * 
io->channels * 2);
+                       memset(rec->inbuf + rec->filled * io->channels * 
rec->src_sample_bytes, 0,
+                              (rec->avctx->frame_size - rec->filled) * 
io->channels * rec->src_sample_bytes);
                }
-               convert_data(rec);
+               err = convert_data(rec);
+               if (err < 0)
+                       return err;
        }
        err = write_out_pending(io, rec);
        if (err < 0)
@@ -208,7 +263,8 @@
 }
 
 /* check whether the areas consist of a continuous interleaved stream */
-static int check_interleaved(const snd_pcm_channel_area_t *areas,
+static int check_interleaved(struct a52_ctx *rec,
+                            const snd_pcm_channel_area_t *areas,
                             unsigned int channels)
 {
        unsigned int ch;
@@ -218,8 +274,8 @@
 
        for (ch = 0; ch < channels; ch++) {
                if (areas[ch].addr != areas[0].addr ||
-                   areas[ch].first != ch * 16 ||
-                   areas[ch].step != channels * 16)
+                   areas[ch].first != ch * rec->src_sample_bits ||
+                   areas[ch].step != channels * rec->src_sample_bits)
                        return 0;
        }
        return 1;
@@ -237,8 +293,7 @@
 {
        struct a52_ctx *rec = io->private_data;
        unsigned int len = rec->avctx->frame_size - rec->filled;
-       short *src, *dst;
-       unsigned int src_step;
+       void *_dst;
        int err;
        static unsigned int ch_index[3][6] = {
                { 0, 1 },
@@ -257,20 +312,23 @@
 
        /* If there are still frames left in outbuf, we can't
         * accept a full a52 frame, because this would overwrite
-        * the frames in outbuf. */
-       if (rec->remain && len)
+        * the frames in outbuf. This should not happen! The a52_pointer()
+        * callback should limit the transferred frames correctly. */
+       if (rec->remain && len) {
+               SNDERR("fill data issue (remain is %i)", rec->remain);
                len--;
+       }
 
        if (size > len)
                size = len;
 
-       dst = rec->inbuf + rec->filled * io->channels;
+       _dst = rec->inbuf + rec->filled * io->channels * rec->src_sample_bytes;
        if (!use_planar(rec) && interleaved) {
-               memcpy(dst, areas->addr + offset * io->channels * 2,
-                      size * io->channels * 2);
-       } else {
-               unsigned int i, ch, dst_step;
-               short *dst1;
+               memcpy(_dst, areas->addr + offset * io->channels * 
rec->src_sample_bytes,
+                      size * io->channels * rec->src_sample_bytes);
+       } else if (rec->src_sample_bits == 16) {
+               unsigned int i, ch, src_step, dst_step;
+               short *src, *dst = _dst, *dst1;
 
                /* flatten copy to n-channel interleaved */
                dst_step = io->channels;
@@ -281,8 +339,8 @@
                                        (ap->first + offset * ap->step) / 8);
 
 #ifdef USE_AVCODEC_FRAME
-                       if (use_planar(rec)) {
-                               memcpy(rec->frame->data[ch], src, size * 2);
+                       if (use_planar(rec) && !interleaved) {
+                               memcpy(rec->frame->data[ch] + rec->filled * 2, 
src, size * 2);
                                continue;
                        }
 #endif
@@ -294,10 +352,40 @@
                                dst1 += dst_step;
                        }
                }
+       } else if (rec->src_sample_bits == 32) {
+               unsigned int i, ch, src_step, dst_step;
+               int *src, *dst = _dst, *dst1;
+
+               /* flatten copy to n-channel interleaved */
+               dst_step = io->channels;
+               for (ch = 0; ch < io->channels; ch++, dst++) {
+                       const snd_pcm_channel_area_t *ap;
+                       ap = &areas[ch_index[io->channels / 2 - 1][ch]];
+                       src = (int *)(ap->addr +
+                                       (ap->first + offset * ap->step) / 8);
+
+#ifdef USE_AVCODEC_FRAME
+                       if (use_planar(rec) && !interleaved) {
+                               memcpy(rec->frame->data[ch] + rec->filled * 4, 
src, size * 4);
+                               continue;
+                       }
+#endif
+                       dst1 = dst;
+                       src_step = ap->step / 32; /* in word */
+                       for (i = 0; i < size; i++) {
+                               *dst1 = *src;
+                               src += src_step;
+                               dst1 += dst_step;
+                       }
+               }
+       } else {
+               return -EIO;
        }
        rec->filled += size;
        if (rec->filled == rec->avctx->frame_size) {
-               convert_data(rec);
+               err = convert_data(rec);
+               if (err < 0)
+                       return err;
                write_out_pending(io, rec);
        }
        return (int)size;
@@ -314,7 +402,7 @@
        struct a52_ctx *rec = io->private_data;
        snd_pcm_sframes_t result = 0;
        int err = 0;
-       int interleaved = check_interleaved(areas, io->channels);
+       int interleaved = check_interleaved(rec, areas, io->channels);
 
        do {
                err = fill_data(io, areas, offset, size, interleaved);
@@ -323,7 +411,8 @@
                offset += (unsigned int)err;
                size -= (unsigned int)err;
                result += err;
-               rec->transfer += err;
+               rec->pointer += err;
+               rec->pointer %= rec->boundary;
        } while (size);
        return result > 0 ? result : err;
 }
@@ -336,7 +425,7 @@
 static snd_pcm_sframes_t a52_pointer(snd_pcm_ioplug_t *io)
 {
        struct a52_ctx *rec = io->private_data;
-       snd_pcm_sframes_t avail;
+       snd_pcm_sframes_t avail, delay;
        snd_pcm_state_t state;
 
        state = snd_pcm_state(rec->slave);
@@ -345,31 +434,31 @@
        case SND_PCM_STATE_DRAINING:
                break;
        case SND_PCM_STATE_XRUN:
-       case SND_PCM_STATE_SUSPENDED:
                return -EPIPE;
+       case SND_PCM_STATE_SUSPENDED:
+               return -ESTRPIPE;
        default:
                return 0;
        }
 
-       avail = 0;
-
        /* Write what we have from outbuf. */
        write_out_pending(io, rec);
 
-       /* If there is anything remaining in outbuf, we can't
-        * accept any full packets. */
-       if (rec->remain == 0)
-       {
-               /* Round the slave frames to multiples of the packet size. */
-               avail += (snd_pcm_avail_update(rec->slave) / 
rec->avctx->frame_size) * rec->avctx->frame_size;
-       }
-
+       avail = snd_pcm_avail(rec->slave);
        if (avail < 0)
-               avail = 0;
-       else if (avail >= io->buffer_size)
-               avail = io->buffer_size - 1;
+               return avail;
 
-       return (io->appl_ptr + avail) % io->buffer_size;
+       /* get buffer delay without additional FIFO information */
+       delay = rec->slave_buffer_size - avail;
+       while (delay < 0)
+               delay += rec->slave_buffer_size;
+
+       avail = rec->pointer - delay - rec->remain - rec->filled;
+#ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA
+       return avail % rec->boundary;
+#else
+       return avail % io->buffer_size;
+#endif
 }
 
 /* set up the fixed parameters of slave PCM hw_parmas */
@@ -463,6 +552,25 @@
 }
 
 /*
+ * dump callback
+ */
+static void a52_dump(snd_pcm_ioplug_t *io, snd_output_t *out)
+{
+       struct a52_ctx *rec = io->private_data;
+       snd_pcm_t *pcm = io->pcm;
+
+       snd_output_printf(out, "%s\n", io->name);
+       snd_output_printf(out, "Its setup is:\n");
+       snd_pcm_dump_setup(pcm, out);
+       snd_output_printf(out, "  %-13s: %s\n", "av_format", 
av_get_sample_fmt_name(rec->av_format));
+       snd_output_printf(out, "  %-13s: %i\n", "av_frame_size", rec->avctx ? 
rec->avctx->frame_size : -1);
+       snd_output_printf(out, "  %-13s: %i\n", "remain", rec->remain);
+       snd_output_printf(out, "  %-13s: %i\n", "filled", rec->filled);
+       snd_output_printf(out, "Slave: ");
+       snd_pcm_dump(rec->slave, out);
+}
+
+/*
  * sw_params callback
  *
  * Set up slave PCM sw_params
@@ -476,6 +584,7 @@
 
        snd_pcm_sw_params_get_avail_min(params, &avail_min);
        snd_pcm_sw_params_get_start_threshold(params, &start_threshold);
+       snd_pcm_sw_params_get_boundary(params, &rec->boundary);
 
        len = avail_min;
        len += (int)rec->slave_buffer_size - (int)io->buffer_size;
@@ -525,21 +634,27 @@
        }
 
 #ifdef USE_AVCODEC_FRAME
-       if (rec->frame) {
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 91, 0)
+       if (rec->frame)
                av_freep(&rec->frame->data[0]);
-               rec->inbuf = NULL;
-       }
+#endif
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
        av_frame_free(&rec->frame);
 #else
        av_freep(&rec->frame);
 #endif
-#endif
-
+#else /* USE_AVCODEC_FRAME */
        free(rec->inbuf);
        rec->inbuf = NULL;
-       free(rec->outbuf);
-       rec->outbuf = NULL;
+#endif /* USE_AVCODEC_FRAME */
+
+#ifdef USE_AVCODEC_PACKET_ALLOC
+       av_packet_free(&rec->pkt);
+#endif
+       free(rec->outbuf2);
+       rec->outbuf2 = NULL;
+       free(rec->outbuf1);
+       rec->outbuf1 = NULL;
 }
 
 /*
@@ -577,14 +692,22 @@
        rec->frame = av_frame_alloc();
        if (!rec->frame)
                return -ENOMEM;
+       rec->frame->nb_samples = rec->avctx->frame_size;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 91, 0)
+       rec->frame->format = rec->avctx->sample_fmt;
+       rec->frame->channels = rec->avctx->channels;
+       rec->frame->channel_layout = rec->avctx->channel_layout;
+       if (av_frame_get_buffer(rec->frame, 0))
+               return -ENOMEM;
+#else
        if (av_samples_alloc(rec->frame->data, rec->frame->linesize,
                             io->channels, rec->avctx->frame_size,
                             rec->avctx->sample_fmt, 0) < 0)
                return -ENOMEM;
-       rec->frame->nb_samples = rec->avctx->frame_size;
-       rec->inbuf = (short *)rec->frame->data[0];
+#endif
+       rec->inbuf = rec->frame->data[0];
 #else
-       rec->inbuf = malloc(rec->avctx->frame_size * 2 * io->channels);
+       rec->inbuf = malloc(rec->avctx->frame_size * io->channels * 
rec->src_sample_bytes);
 #endif
        if (!rec->inbuf)
                return -ENOMEM;
@@ -622,15 +745,28 @@
        if (err < 0)
                return -EINVAL;
 
+#ifdef USE_AVCODEC_PACKET_ALLOC
+       rec->pkt = av_packet_alloc();
+       if (!rec->pkt)
+               return -ENOMEM;
+#endif
+
        rec->outbuf_size = rec->avctx->frame_size * 4;
-       rec->outbuf = malloc(rec->outbuf_size);
-       if (! rec->outbuf)
+       rec->outbuf1 = malloc(rec->outbuf_size + AV_INPUT_BUFFER_PADDING_SIZE);
+       if (! rec->outbuf1)
                return -ENOMEM;
+       memset(rec->outbuf1 + rec->outbuf_size, 0, 
AV_INPUT_BUFFER_PADDING_SIZE);
+
+       if (rec->format == SND_PCM_FORMAT_S16_LE) {
+               rec->outbuf2 = malloc(rec->outbuf_size);
+               if ( !rec->outbuf2)
+                       return -ENOMEM;
+       }
 
        if (alloc_input_buffer(io))
                return -ENOMEM;
 
-       rec->transfer = 0;
+       rec->pointer = 0;
        rec->remain = 0;
        rec->filled = 0;
 
@@ -669,10 +805,9 @@
        snd_pcm_t *slave = rec->slave;
 
        a52_free(rec);
-       if (slave) {
-               rec->slave = NULL;
+       free(rec);
+       if (slave)
                return snd_pcm_close(slave);
-       }
        return 0;
 }
                              
@@ -737,6 +872,7 @@
        .close = a52_close,
        .hw_params = a52_hw_params,
        .hw_free = a52_hw_free,
+       .dump = a52_dump,
        .sw_params = a52_sw_params,
        .prepare = a52_prepare,
        .drain = a52_drain,
@@ -773,8 +909,20 @@
                SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
                SND_PCM_ACCESS_RW_NONINTERLEAVED
        };
-       unsigned int formats[] = { SND_PCM_FORMAT_S16 };
-       int err;
+       static struct format {
+               int av;
+               snd_pcm_format_t alib;
+       } formats[] = {
+               { .av = AV_SAMPLE_FMT_S16, .alib = SND_PCM_FORMAT_S16 },
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 95, 0) && USE_AVCODEC_FRAME
+               { .av = AV_SAMPLE_FMT_S16P, .alib = SND_PCM_FORMAT_S16 },
+               { .av = AV_SAMPLE_FMT_S32, .alib = SND_PCM_FORMAT_S32 },
+               { .av = AV_SAMPLE_FMT_S32P, .alib = SND_PCM_FORMAT_S32 },
+               { .av = AV_SAMPLE_FMT_FLTP, .alib = SND_PCM_FORMAT_FLOAT }
+#endif
+       };
+       int err, dir;
+       unsigned int i, fmt;
        snd_pcm_uframes_t buffer_max;
        unsigned int period_bytes, max_periods;
 
@@ -791,8 +939,22 @@
        if (err < 0)
                return err;
 
+       rec->src_format = SND_PCM_FORMAT_UNKNOWN;
+       for (i = 0; i < ARRAY_SIZE(formats); i++)
+               if (formats[i].av == rec->av_format) {
+                       rec->src_format = formats[i].alib;
+                       break;
+               }
+       if (rec->src_format == SND_PCM_FORMAT_UNKNOWN) {
+               SNDERR("A/V format '%s' is not supported", 
av_get_sample_fmt_name(rec->av_format));
+               return -EINVAL;
+       }
+       fmt = rec->src_format;
+       rec->src_sample_bits = snd_pcm_format_physical_width(rec->src_format);
+       rec->src_sample_bytes = rec->src_sample_bits / 8;
+
        if ((err = snd_pcm_ioplug_set_param_list(&rec->io, 
SND_PCM_IOPLUG_HW_FORMAT,
-                                                ARRAY_SIZE(formats), formats)) 
< 0 ||
+                                                1, &fmt)) < 0 ||
            (err = snd_pcm_ioplug_set_param_minmax(&rec->io, 
SND_PCM_IOPLUG_HW_CHANNELS,
                                                   rec->channels, 
rec->channels)) < 0 ||
            (err = snd_pcm_ioplug_set_param_minmax(&rec->io, 
SND_PCM_IOPLUG_HW_RATE,
@@ -803,8 +965,11 @@
                return err;
 
        snd_pcm_hw_params_get_buffer_size_max(rec->hw_params, &buffer_max);
+       dir = -1;
+       snd_pcm_hw_params_get_periods_max(rec->hw_params, &max_periods, &dir);
        period_bytes = A52_FRAME_SIZE * 2 * rec->channels;
-       max_periods = buffer_max / A52_FRAME_SIZE;
+       if (buffer_max / A52_FRAME_SIZE < max_periods)
+               max_periods = buffer_max / A52_FRAME_SIZE;
 
        if ((err = snd_pcm_ioplug_set_param_minmax(&rec->io, 
SND_PCM_IOPLUG_HW_PERIOD_BYTES,
                                                   period_bytes, period_bytes)) 
< 0 ||
@@ -824,11 +989,12 @@
        int err;
        const char *card = NULL;
        const char *pcm_string = NULL;
+       const char *avcodec = NULL;
        unsigned int rate = 48000;
        unsigned int bitrate = 448;
        unsigned int channels = 6;
        snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
-       char devstr[128], tmpcard[8];
+       char devstr[128], tmpcard[16];
        struct a52_ctx *rec;
        
        if (stream != SND_PCM_STREAM_PLAYBACK) {
@@ -921,6 +1087,16 @@
                        }
                        continue;
                }
+               if (strcmp(id, "avcodec") == 0) {
+                       const char *str;
+                       err = snd_config_get_string(n, &str);
+                       if (err < 0) {
+                               SNDERR("invalid type for %s", id);
+                               return -EINVAL;
+                       }
+                       avcodec = str;
+                       continue;
+               }
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
@@ -931,6 +1107,7 @@
                return -ENOMEM;
        }
 
+       rec->src_format = SND_PCM_FORMAT_UNKNOWN;
        rec->rate = rate;
        rec->bitrate = bitrate;
        rec->channels = channels;
@@ -939,11 +1116,17 @@
 #ifndef USE_AVCODEC_FRAME
        avcodec_init();
 #endif
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 91, 0)
        avcodec_register_all();
+#endif
 
-       rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
-       if (rec->codec == NULL)
-               rec->codec = avcodec_find_encoder_by_name("ac3");
+       if (avcodec) {
+               rec->codec = avcodec_find_encoder_by_name(avcodec);
+       } else {
+               rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
+               if (rec->codec == NULL)
+                       rec->codec = avcodec_find_encoder_by_name("ac3");
+       }
        if (rec->codec == NULL) 
                rec->codec = avcodec_find_encoder(AV_CODEC_ID_AC3);
        if (rec->codec == NULL) {
@@ -954,7 +1137,7 @@
 
        if (! pcm_string || pcm_string[0] == '\0') {
                snprintf(devstr, sizeof(devstr),
-                        "iec958:{AES0 0x%x AES1 0x%x AES2 0x%x AES3 0x%x 
%s%s}",
+                        "iec958:{AES0 0x%x AES1 0x%x AES2 0x%x AES3 0x%x%s%s}",
                         IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO |
                         IEC958_AES0_CON_NOT_COPYRIGHT,
                         IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
@@ -980,6 +1163,9 @@
        rec->io.mmap_rw = 0;
        rec->io.callback = &a52_ops;
        rec->io.private_data = rec;
+#ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA
+       rec->io.flags = SND_PCM_IOPLUG_FLAG_BOUNDARY_WA;
+#endif
 #ifdef USE_AVCODEC_FRAME
        rec->av_format = rec->codec->sample_fmts[0];
        rec->is_planar = av_sample_fmt_is_planar(rec->av_format);
@@ -993,7 +1179,7 @@
 
        if ((err = a52_set_hw_constraint(rec)) < 0) {
                snd_pcm_ioplug_delete(&rec->io);
-               goto error;
+               return err;
        }
 
        *pcmp = rec->io.pcm;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/configure 
new/alsa-plugins-1.2.6/configure
--- old/alsa-plugins-1.2.5/configure    2021-05-27 22:06:36.000000000 +0200
+++ new/alsa-plugins-1.2.6/configure    2021-12-06 12:44:24.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for alsa-plugins 1.2.5.
+# Generated by GNU Autoconf 2.69 for alsa-plugins 1.2.6.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
 # Identity of this package.
 PACKAGE_NAME='alsa-plugins'
 PACKAGE_TARNAME='alsa-plugins'
-PACKAGE_VERSION='1.2.5'
-PACKAGE_STRING='alsa-plugins 1.2.5'
+PACKAGE_VERSION='1.2.6'
+PACKAGE_STRING='alsa-plugins 1.2.6'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1421,7 +1421,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures alsa-plugins 1.2.5 to adapt to many kinds of systems.
+\`configure' configures alsa-plugins 1.2.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1492,7 +1492,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of alsa-plugins 1.2.5:";;
+     short | recursive ) echo "Configuration of alsa-plugins 1.2.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1660,7 +1660,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-alsa-plugins configure 1.2.5
+alsa-plugins configure 1.2.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2025,7 +2025,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by alsa-plugins $as_me 1.2.5, which was
+It was created by alsa-plugins $as_me 1.2.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2888,7 +2888,7 @@
 
 # Define the identity of the package.
  PACKAGE='alsa-plugins'
- VERSION='1.2.5'
+ VERSION='1.2.6'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13031,12 +13031,12 @@
     pkg_cv_LIBAV_CFLAGS="$LIBAV_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists 
--print-errors \"libavcodec libavutil libavresample\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libavcodec libavutil libavresample") 
2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists 
--print-errors \"libavcodec libavutil libswresample\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libavcodec libavutil libswresample") 
2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBAV_CFLAGS=`$PKG_CONFIG --cflags "libavcodec libavutil 
libavresample" 2>/dev/null`
+  pkg_cv_LIBAV_CFLAGS=`$PKG_CONFIG --cflags "libavcodec libavutil 
libswresample" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -13048,12 +13048,12 @@
     pkg_cv_LIBAV_LIBS="$LIBAV_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists 
--print-errors \"libavcodec libavutil libavresample\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libavcodec libavutil libavresample") 
2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists 
--print-errors \"libavcodec libavutil libswresample\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libavcodec libavutil libswresample") 
2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBAV_LIBS=`$PKG_CONFIG --libs "libavcodec libavutil libavresample" 
2>/dev/null`
+  pkg_cv_LIBAV_LIBS=`$PKG_CONFIG --libs "libavcodec libavutil libswresample" 
2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -13074,9 +13074,9 @@
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               LIBAV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors 
--cflags --libs "libavcodec libavutil libavresample" 2>&1`
+               LIBAV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors 
--cflags --libs "libavcodec libavutil libswresample" 2>&1`
         else
-               LIBAV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs 
"libavcodec libavutil libavresample" 2>&1`
+               LIBAV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs 
"libavcodec libavutil libswresample" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$LIBAV_PKG_ERRORS" >&5
@@ -14217,7 +14217,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by alsa-plugins $as_me 1.2.5, which was
+This file was extended by alsa-plugins $as_me 1.2.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -14283,7 +14283,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-alsa-plugins config.status 1.2.5
+alsa-plugins config.status 1.2.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/configure.ac 
new/alsa-plugins-1.2.6/configure.ac
--- old/alsa-plugins-1.2.5/configure.ac 2021-05-27 19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/configure.ac 2021-12-06 11:17:29.000000000 +0100
@@ -1,5 +1,5 @@
 AC_PREREQ(2.59)
-AC_INIT(alsa-plugins, 1.2.5)
+AC_INIT(alsa-plugins, 1.2.6)
 AM_INIT_AUTOMAKE
 AC_PREFIX_DEFAULT(/usr)
 
@@ -93,7 +93,7 @@
       AS_HELP_STRING([--disable-libav], [Do not build plugins depending on 
libav/ffmpeg (a52,lavrate...)]))
 
 if test "x$enable_libav" != "xno"; then
-  PKG_CHECK_MODULES(LIBAV, [libavcodec libavutil libavresample], 
[HAVE_LIBAV=yes], [HAVE_LIBAV=no])
+  PKG_CHECK_MODULES(LIBAV, [libavcodec libavutil libswresample], 
[HAVE_LIBAV=yes], [HAVE_LIBAV=no])
 fi
 
 if test "x$HAVE_LIBAV" = "xno"; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/doc/a52.txt 
new/alsa-plugins-1.2.6/doc/a52.txt
--- old/alsa-plugins-1.2.5/doc/a52.txt  2021-05-27 19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/doc/a52.txt  2021-12-06 11:17:29.000000000 +0100
@@ -1,11 +1,17 @@
 A52 OUTPUT PLUGIN
 =================
 
-This plugin converts S16 linear format to A52 compressed stream and
-send to an SPDIF output.  It requires libavcodec for encoding the
-audio stream.
+This plugin converts S16(P), S32P, or FLTP formats to an A52 compressed
+stream and sends it to an S/PDIF output.  It requires libavcodec for
+encoding the audio stream.
 
-A PCM using this plugin can be defined like below:
+The input format is determined by the version of libavcodec it is
+compiled against and which ac3 codec libavcodec is configured to use.
+
+A global configuration, /usr/share/alsa/alsa.conf.d/60-a52-encoder.conf
+defines a52 PCMs for devices with the IEC958 non-audio status bit set.
+
+A PCM using this plugin can be manually defined like below:
 
        pcm.myout {
                type a52
@@ -61,5 +67,6 @@
        }
 
 
-The plugin reads always S16 format (i.e. native-endian) as input, so
-you'd need plug layer appropriately to covert it.
+The plugin only reads the format determined by libavcodec (native-
+endian S16(P), S32P or FLTP) as input, so you'll need a plug layer to 
+appropriately convert it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/doc/lavrate.txt 
new/alsa-plugins-1.2.6/doc/lavrate.txt
--- old/alsa-plugins-1.2.5/doc/lavrate.txt      2021-05-27 19:18:39.000000000 
+0200
+++ new/alsa-plugins-1.2.6/doc/lavrate.txt      2021-12-06 11:17:29.000000000 
+0100
@@ -2,7 +2,7 @@
 =========================================0
 
 The plugin in rate-lavr subdirectory is an external rate converter using
-libavresample library. You can use this rate converter plugin by defining a
+libswresample library. You can use this rate converter plugin by defining a
 rate PCM with "converter" parameter, such as:
 
        pcm.my_rate {
@@ -16,7 +16,7 @@
 Or, more easily, define a global variable "defaults.pcm.rate_converter",
 which is used as the default converter type by plug and rate plugins:
 
-       defaults.pcm.rate_converter "lavcrate"
+       defaults.pcm.rate_converter "lavrate"
 
 Write the above in your ~/.asoundrc or /etc/asound.conf.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/jack/Makefile.am 
new/alsa-plugins-1.2.6/jack/Makefile.am
--- old/alsa-plugins-1.2.5/jack/Makefile.am     2021-05-27 19:18:39.000000000 
+0200
+++ new/alsa-plugins-1.2.6/jack/Makefile.am     2021-12-06 11:17:29.000000000 
+0100
@@ -12,7 +12,7 @@
 AM_LDFLAGS = -module -avoid-version -export-dynamic -no-undefined 
$(LDFLAGS_NOUNDEFINED)
 
 libasound_module_pcm_jack_la_SOURCES = pcm_jack.c
-libasound_module_pcm_jack_la_LIBADD = @ALSA_LIBS@ @JACK_LIBS@
+libasound_module_pcm_jack_la_LIBADD = @ALSA_LIBS@ @JACK_LIBS@ -lpthread
 
 include ../install-hooks.am
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/jack/Makefile.in 
new/alsa-plugins-1.2.6/jack/Makefile.in
--- old/alsa-plugins-1.2.5/jack/Makefile.in     2021-05-27 22:06:35.000000000 
+0200
+++ new/alsa-plugins-1.2.6/jack/Makefile.in     2021-12-06 12:44:23.000000000 
+0100
@@ -358,7 +358,7 @@
 AM_CFLAGS = -Wall -g @ALSA_CFLAGS@ @JACK_CFLAGS@
 AM_LDFLAGS = -module -avoid-version -export-dynamic -no-undefined 
$(LDFLAGS_NOUNDEFINED)
 libasound_module_pcm_jack_la_SOURCES = pcm_jack.c
-libasound_module_pcm_jack_la_LIBADD = @ALSA_LIBS@ @JACK_LIBS@
+libasound_module_pcm_jack_la_LIBADD = @ALSA_LIBS@ @JACK_LIBS@ -lpthread
 all: all-am
 
 .SUFFIXES:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/jack/pcm_jack.c 
new/alsa-plugins-1.2.6/jack/pcm_jack.c
--- old/alsa-plugins-1.2.5/jack/pcm_jack.c      2021-05-27 19:18:39.000000000 
+0200
+++ new/alsa-plugins-1.2.6/jack/pcm_jack.c      2021-12-06 11:17:29.000000000 
+0100
@@ -28,6 +28,7 @@
 #include <jack/jack.h>
 #include <alsa/asoundlib.h>
 #include <alsa/pcm_external.h>
+#include <pthread.h>
 
 #define MAX_PERIODS_MULTIPLE 64
 
@@ -44,6 +45,8 @@
 
        int fd;
        int activated;          /* jack is activated? */
+       pthread_mutex_t running_mutex;
+       int running;            /* jack is running? */
 
        snd_pcm_jack_port_list_t **port_names;
        unsigned int num_ports;
@@ -159,6 +162,7 @@
                free(jack->port_names);
                jack->port_names = NULL;
        }
+       pthread_mutex_destroy (&jack->running_mutex);
        if (jack->fd >= 0)
                close(jack->fd);
        if (jack->io.poll_fd >= 0)
@@ -207,6 +211,18 @@
        snd_pcm_jack_t *jack = io->private_data;
        snd_pcm_uframes_t xfer = 0;
        unsigned int channel;
+
+       if (pthread_mutex_trylock (&jack->running_mutex) == EBUSY) {
+               /* Note that locking should only ever fail if
+                * snd_pcm_jack_start or snd_pcm_jack_stop is called at the
+                * same time, in which case dropping the current buffer is not
+                * an issue. */
+               return 0;
+       }
+       if (!jack->running) {
+               pthread_mutex_unlock (&jack->running_mutex);
+               return 0;
+       }
        
        for (channel = 0; channel < io->channels; channel++) {
                jack->areas[channel].addr = 
@@ -268,6 +284,8 @@
 
        pcm_poll_unblock_check(io); /* unblock socket for polling if needed */
 
+       pthread_mutex_unlock (&jack->running_mutex);
+
        return 0;
 }
 
@@ -365,7 +383,10 @@
 
 static int snd_pcm_jack_start(snd_pcm_ioplug_t *io)
 {
-       (void)io;
+       snd_pcm_jack_t *jack = io->private_data;
+       pthread_mutex_lock (&jack->running_mutex);
+       jack->running = 1;
+       pthread_mutex_unlock (&jack->running_mutex);
        /*
         * Since the processing of jack_activate() and jack_connect() take a
         * while longer, snd_pcm_jack_start() was blocked.
@@ -382,7 +403,10 @@
 
 static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io)
 {
-       (void)io;
+       snd_pcm_jack_t *jack = io->private_data;
+       pthread_mutex_lock (&jack->running_mutex);
+       jack->running = 0;
+       pthread_mutex_unlock (&jack->running_mutex);
        return 0;
 }
 
@@ -548,6 +572,8 @@
        if (!jack)
                return -ENOMEM;
 
+       pthread_mutex_init (&jack->running_mutex, NULL);
+
        jack->fd = -1;
        jack->io.poll_fd = -1;
        jack->use_period_alignment = use_period_alignment;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/rate/rate_samplerate.c 
new/alsa-plugins-1.2.6/rate/rate_samplerate.c
--- old/alsa-plugins-1.2.5/rate/rate_samplerate.c       2021-05-27 
19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/rate/rate_samplerate.c       2021-12-06 
11:17:29.000000000 +0100
@@ -40,9 +40,12 @@
 #include <alsa/pcm_rate.h>
 
 struct rate_src {
+       unsigned int version;
        double ratio;
        int converter;
        unsigned int channels;
+       int in_int;
+       int out_int;
        float *src_buf;
        float *dst_buf;
        SRC_STATE *state;
@@ -109,6 +112,13 @@
        rate->data.src_ratio = rate->ratio;
        rate->data.end_of_input = 0;
 
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       if (rate->version >= 0x010003) {
+               rate->in_int = info->in.format == SND_PCM_FORMAT_S32;
+               rate->out_int = info->out.format == SND_PCM_FORMAT_S32;
+       }
+#endif
+
        return 0;
 }
 
@@ -128,24 +138,56 @@
        src_reset(rate->state);
 }
 
-static void pcm_src_convert_s16(void *obj, int16_t *dst, unsigned int 
dst_frames,
-                               const int16_t *src, unsigned int src_frames)
+static void do_convert(struct rate_src *rate,
+                      void *dst, unsigned int dst_frames,
+                      const void *src, unsigned int src_frames)
 {
-       struct rate_src *rate = obj;
        unsigned int ofs;
 
        rate->data.input_frames = src_frames;
        rate->data.output_frames = dst_frames;
        rate->data.end_of_input = 0;
        
-       src_short_to_float_array(src, rate->src_buf, src_frames * 
rate->channels);
+       if (rate->in_int)
+               src_int_to_float_array(src, rate->src_buf, src_frames * 
rate->channels);
+       else
+               src_short_to_float_array(src, rate->src_buf, src_frames * 
rate->channels);
        src_process(rate->state, &rate->data);
        if (rate->data.output_frames_gen < dst_frames)
                ofs = dst_frames - rate->data.output_frames_gen;
        else
                ofs = 0;
-       src_float_to_short_array(rate->dst_buf, dst + ofs * rate->channels,
-                                rate->data.output_frames_gen * rate->channels);
+       if (rate->out_int)
+               src_float_to_int_array(rate->dst_buf, dst + ofs * 
rate->channels * 4,
+                                      rate->data.output_frames_gen * 
rate->channels);
+       else
+               src_float_to_short_array(rate->dst_buf, dst + ofs * 
rate->channels * 2,
+                                        rate->data.output_frames_gen * 
rate->channels);
+}
+
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+static void pcm_src_convert(void *obj,
+                           const snd_pcm_channel_area_t *dst_areas,
+                           snd_pcm_uframes_t dst_offset,
+                           unsigned int dst_frames,
+                           const snd_pcm_channel_area_t *src_areas,
+                           snd_pcm_uframes_t src_offset,
+                           unsigned int src_frames)
+{
+       struct rate_src *rate = obj;
+       const void *src = snd_pcm_channel_area_addr(src_areas, src_offset);
+       void *dst = snd_pcm_channel_area_addr(dst_areas, dst_offset);
+
+       do_convert(rate, dst, dst_frames, src, src_frames);
+}
+#endif
+
+static void pcm_src_convert_s16(void *obj, int16_t *dst, unsigned int 
dst_frames,
+                               const int16_t *src, unsigned int src_frames)
+{
+       struct rate_src *rate = obj;
+
+       do_convert(rate, dst, dst_frames, src, src_frames);
 }
 
 static void pcm_src_close(void *obj)
@@ -167,12 +209,28 @@
 }
 #endif
 
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+static int get_supported_formats(void *obj, uint64_t *in_formats,
+                                uint64_t *out_formats,
+                                unsigned int *flags)
+{
+       *in_formats = *out_formats =
+               (1ULL << SND_PCM_FORMAT_S16) |
+               (1ULL << SND_PCM_FORMAT_S32);
+       *flags = SND_PCM_RATE_FLAG_INTERLEAVED;
+       return 0;
+}
+#endif
+
 static snd_pcm_rate_ops_t pcm_src_ops = {
        .close = pcm_src_close,
        .init = pcm_src_init,
        .free = pcm_src_free,
        .reset = pcm_src_reset,
        .adjust_pitch = pcm_src_adjust_pitch,
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       .convert = pcm_src_convert,
+#endif
        .convert_s16 = pcm_src_convert_s16,
        .input_frames = input_frames,
        .output_frames = output_frames,
@@ -181,6 +239,9 @@
        .get_supported_rates = get_supported_rates,
        .dump = dump,
 #endif
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       .get_supported_formats = get_supported_formats,
+#endif
 };
 
 static int pcm_src_open(unsigned int version, void **objp,
@@ -188,24 +249,27 @@
 {
        struct rate_src *rate;
 
-#if SND_PCM_RATE_PLUGIN_VERSION < 0x010002
-       if (version != SND_PCM_RATE_PLUGIN_VERSION) {
-               fprintf(stderr, "Invalid rate plugin version %x\n", version);
-               return -EINVAL;
-       }
-#endif
        rate = calloc(1, sizeof(*rate));
        if (! rate)
                return -ENOMEM;
+
+       rate->version = version;
        rate->converter = type;
 
        *objp = rate;
 #if SND_PCM_RATE_PLUGIN_VERSION >= 0x010002
-       if (version == 0x010001)
+       if (version == 0x010001) {
                memcpy(ops, &pcm_src_ops, sizeof(snd_pcm_rate_old_ops_t));
-       else
+               return 0;
+       }
+#endif
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       if (version == 0x010002) {
+               memcpy(ops, &pcm_src_ops, sizeof(snd_pcm_rate_v2_ops_t));
+               return 0;
+       }
 #endif
-               *ops = pcm_src_ops;
+       *ops = pcm_src_ops;
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/rate-lav/rate_lavrate.c 
new/alsa-plugins-1.2.6/rate-lav/rate_lavrate.c
--- old/alsa-plugins-1.2.5/rate-lav/rate_lavrate.c      2021-05-27 
19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/rate-lav/rate_lavrate.c      2021-12-06 
11:17:29.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * Rate converter plugin using libavresample
+ * Rate converter plugin using libswresample
  * Copyright (c) 2014 by Anton Khirnov
  *
  * This library is free software; you can redistribute it and/or
@@ -17,7 +17,7 @@
 #include <alsa/asoundlib.h>
 #include <alsa/pcm_rate.h>
 
-#include <libavresample/avresample.h>
+#include <libswresample/swresample.h>
 #include <libavutil/channel_layout.h>
 #include <libavutil/opt.h>
 #include <libavutil/mathematics.h>
@@ -25,15 +25,15 @@
 
 
 static unsigned int filter_size = 16;
-static unsigned int phase_shift = 10; /* auto-adjusts */
-static double cutoff = 0; /* auto-adjusts */
 
 struct rate_src {
-       AVAudioResampleContext *avr;
+       SwrContext *avr;
 
        unsigned int in_rate;
        unsigned int out_rate;
        unsigned int channels;
+
+       unsigned int version;
 };
 
 static snd_pcm_uframes_t input_frames(void *obj ATTRIBUTE_UNUSED,
@@ -51,51 +51,67 @@
 static void pcm_src_free(void *obj)
 {
        struct rate_src *rate = obj;
-       avresample_free(&rate->avr);
+       swr_free(&rate->avr);
+}
+
+static int to_av_format(snd_pcm_format_t f)
+{
+       switch (f) {
+       case SND_PCM_FORMAT_FLOAT:
+               return AV_SAMPLE_FMT_FLT;
+       case SND_PCM_FORMAT_U8:
+               return AV_SAMPLE_FMT_U8;
+       case SND_PCM_FORMAT_S16:
+               return AV_SAMPLE_FMT_S16;
+       case SND_PCM_FORMAT_S32:
+       default:
+               return AV_SAMPLE_FMT_S32;
+       }
+}
+
+static int support_multi_format(struct rate_src *rate)
+{
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       return rate->version >= 0x010003;
+#else
+       return 0;
+#endif
 }
 
 static int pcm_src_init(void *obj, snd_pcm_rate_info_t *info)
 {
        struct rate_src *rate = obj;
-       int i, ir, or;
+       int fmt;
 
        if (!rate->avr || rate->channels != info->channels) {
                int ret;
 
                pcm_src_free(rate);
                rate->channels = info->channels;
-               ir = rate->in_rate = info->in.rate;
-               or = rate->out_rate = info->out.rate;
-               i = av_gcd(or, ir);
-               if (or > ir) {
-                       phase_shift = or/i;
-               } else {
-                       phase_shift = ir/i;
-               }
-               if (cutoff <= 0.0) {
-                       cutoff = 1.0 - 1.0/filter_size;
-                       if (cutoff < 0.80)
-                               cutoff = 0.80;
-               }
+               rate->in_rate = info->in.rate;
+               rate->out_rate = info->out.rate;
 
-               rate->avr = avresample_alloc_context();
+               rate->avr = swr_alloc();
                if (!rate->avr)
                        return -ENOMEM;
 
-               av_opt_set_int(rate->avr, "in_sample_rate",     info->in.rate,  
0);
-               av_opt_set_int(rate->avr, "out_sample_rate",    info->out.rate, 
0);
-               av_opt_set_int(rate->avr, "in_sample_format",   
AV_SAMPLE_FMT_S16, 0);
-               av_opt_set_int(rate->avr, "out_sample_format",  
AV_SAMPLE_FMT_S16, 0);
-               av_opt_set_int(rate->avr, "in_channel_layout",  
av_get_default_channel_layout(rate->channels), 0);
-               av_opt_set_int(rate->avr, "out_channel_layout", 
av_get_default_channel_layout(rate->channels), 0);
-
-               av_opt_set_int(rate->avr, "filter_size",        filter_size, 0);
-               av_opt_set_int(rate->avr, "phase_shift",        phase_shift, 0);
-               av_opt_set_double(rate->avr, "cutoff",          cutoff,      0);
+               av_opt_set_channel_layout(rate->avr, "in_channel_layout",
+                                         
av_get_default_channel_layout(rate->channels), 0);
+               av_opt_set_channel_layout(rate->avr, "out_channel_layout",
+                                         
av_get_default_channel_layout(rate->channels), 0);
+               av_opt_set_int(rate->avr, "in_sample_rate", rate->in_rate, 0);
+               av_opt_set_int(rate->avr, "out_sample_rate", rate->out_rate, 0);
+               fmt = support_multi_format(rate) ? info->in.format : 
SND_PCM_FORMAT_S16;
+               av_opt_set_sample_fmt(rate->avr, "in_sample_fmt",
+                                     to_av_format(fmt), 0);
+               fmt = support_multi_format(rate) ? info->out.format : 
SND_PCM_FORMAT_S16;
+               av_opt_set_sample_fmt(rate->avr, "out_sample_fmt",
+                                     to_av_format(fmt), 0);
 
-               ret = avresample_open(rate->avr);
+               ret = swr_init(rate->avr);
                if (ret < 0) {
-                       avresample_free(&rate->avr);
+                       SNDERR("sw_init() error %d\n", ret);
+                       swr_free(&rate->avr);
                        return -EINVAL;
                }
        }
@@ -118,26 +134,51 @@
 
        if (rate->avr) {
 #if 0
-               avresample_close(rate->avr);
-               avresample_open(rate->avr);
+               swr_free(rate->avr);
+               swr_init(rate->avr);
 #endif
        }
 }
 
+static void do_convert(struct rate_src *rate,
+                      void *dst, unsigned int dst_frames,
+                      const void *src, unsigned int src_frames)
+{
+       unsigned int total_in = swr_get_delay(rate->avr, rate->in_rate) + 
src_frames;
+
+       swr_convert(rate->avr, (uint8_t **)&dst, dst_frames,
+                   (const uint8_t **)&src, src_frames);
+
+       swr_set_compensation(rate->avr,
+                            total_in - src_frames > filter_size ? 0 : 1,
+                            src_frames);
+}
+
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+static void pcm_src_convert(void *obj,
+                           const snd_pcm_channel_area_t *dst_areas,
+                           snd_pcm_uframes_t dst_offset,
+                           unsigned int dst_frames,
+                           const snd_pcm_channel_area_t *src_areas,
+                           snd_pcm_uframes_t src_offset,
+                           unsigned int src_frames)
+{
+       struct rate_src *rate = obj;
+       const void *src = snd_pcm_channel_area_addr(src_areas, src_offset);
+       void *dst = snd_pcm_channel_area_addr(dst_areas, dst_offset);
+
+       do_convert(rate, dst, dst_frames, src, src_frames);
+}
+#endif
+
 static void pcm_src_convert_s16(void *obj, int16_t *dst,
                                unsigned int dst_frames,
                                const int16_t *src,
                                unsigned int src_frames)
 {
        struct rate_src *rate = obj;
-       int chans = rate->channels;
-       unsigned int total_in = avresample_get_delay(rate->avr) + src_frames;
 
-       avresample_convert(rate->avr, (uint8_t **)&dst, dst_frames * chans * 2, 
dst_frames,
-                          (uint8_t **)&src, src_frames * chans * 2, 
src_frames);
-
-       avresample_set_compensation(rate->avr,
-                                    total_in - src_frames > filter_size ? 0 : 
1, src_frames);
+       do_convert(rate, dst, dst_frames, src, src_frames);
 }
 
 static void pcm_src_close(void *obj)
@@ -156,7 +197,21 @@
 
 static void dump(void *obj ATTRIBUTE_UNUSED, snd_output_t *out)
 {
-       snd_output_printf(out, "Converter: libavr\n");
+       snd_output_printf(out, "Converter: libswresample\n");
+}
+#endif
+
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+static int get_supported_formats(void *obj, uint64_t *in_formats,
+                                uint64_t *out_formats,
+                                unsigned int *flags)
+{
+       *in_formats = *out_formats =
+               (1ULL << SND_PCM_FORMAT_U8) |
+               (1ULL << SND_PCM_FORMAT_S16) |
+               (1ULL << SND_PCM_FORMAT_S32);
+       *flags = SND_PCM_RATE_FLAG_INTERLEAVED;
+       return 0;
 }
 #endif
 
@@ -166,6 +221,9 @@
        .free = pcm_src_free,
        .reset = pcm_src_reset,
        .adjust_pitch = pcm_src_adjust_pitch,
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       .convert = pcm_src_convert,
+#endif
        .convert_s16 = pcm_src_convert_s16,
        .input_frames = input_frames,
        .output_frames = output_frames,
@@ -174,31 +232,35 @@
        .get_supported_rates = get_supported_rates,
        .dump = dump,
 #endif
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       .get_supported_formats = get_supported_formats,
+#endif
 };
 
 int pcm_src_open(unsigned int version, void **objp, snd_pcm_rate_ops_t *ops)
-
 {
        struct rate_src *rate;
 
-#if SND_PCM_RATE_PLUGIN_VERSION < 0x010002
-       if (version != SND_PCM_RATE_PLUGIN_VERSION) {
-               fprintf(stderr, "Invalid rate plugin version %x\n", version);
-               return -EINVAL;
-       }
-#endif
        rate = calloc(1, sizeof(*rate));
        if (!rate)
                return -ENOMEM;
 
        *objp = rate;
        rate->avr = NULL;
+       rate->version = version;
 #if SND_PCM_RATE_PLUGIN_VERSION >= 0x010002
-       if (version == 0x010001)
+       if (version == 0x010001) {
                memcpy(ops, &pcm_src_ops, sizeof(snd_pcm_rate_old_ops_t));
-       else
+               return 0;
+       }
+#endif
+#if SND_PCM_RATE_PLUGIN_VERSION >= 0x010003
+       if (version == 0x010002) {
+               memcpy(ops, &pcm_src_ops, sizeof(snd_pcm_rate_v2_ops_t));
+               return 0;
+       }
 #endif
-               *ops = pcm_src_ops;
+       *ops = pcm_src_ops;
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/usb_stream/pcm_usb_stream.c 
new/alsa-plugins-1.2.6/usb_stream/pcm_usb_stream.c
--- old/alsa-plugins-1.2.5/usb_stream/pcm_usb_stream.c  2021-05-27 
19:18:39.000000000 +0200
+++ new/alsa-plugins-1.2.6/usb_stream/pcm_usb_stream.c  2021-12-06 
11:17:29.000000000 +0100
@@ -474,7 +474,7 @@
                if (snd_config_get_id(n, &id) < 0)
                        continue;
 
-               if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0)
+               if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || 
strcmp(id, "hint") == 0)
                        continue;
                if (strcmp(id, "card") == 0) {
                        card = snd_config_get_card(n);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/alsa-plugins-1.2.5/version 
new/alsa-plugins-1.2.6/version
--- old/alsa-plugins-1.2.5/version      2021-05-27 22:06:40.000000000 +0200
+++ new/alsa-plugins-1.2.6/version      2021-12-06 12:44:28.000000000 +0100
@@ -1 +1 @@
-1.2.5
+1.2.6

Reply via email to