From patchwork Tue Mar 13 08:34:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Wischer X-Patchwork-Id: 10277917 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5A22B602C2 for ; Tue, 13 Mar 2018 08:35:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59724284C9 for ; Tue, 13 Mar 2018 08:35:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E16C28F22; Tue, 13 Mar 2018 08:35:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77768284C9 for ; Tue, 13 Mar 2018 08:35:44 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 4644C267233; Tue, 13 Mar 2018 09:35:40 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 7AFFB2671E9; Tue, 13 Mar 2018 09:35:35 +0100 (CET) Received: from smtp1.de.adit-jv.com (smtp1.de.adit-jv.com [62.225.105.245]) by alsa0.perex.cz (Postfix) with ESMTP id DBD27267198 for ; Tue, 13 Mar 2018 09:35:33 +0100 (CET) Received: from localhost (smtp1.de.adit-jv.com [127.0.0.1]) by smtp1.de.adit-jv.com (Postfix) with ESMTP id B4CC33C09A1; Tue, 13 Mar 2018 09:35:33 +0100 (CET) Received: from smtp1.de.adit-jv.com ([127.0.0.1]) by localhost (smtp1.de.adit-jv.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CjDIuCOqxqJm; Tue, 13 Mar 2018 09:35:21 +0100 (CET) Received: from HI2EXCH01.adit-jv.com (hi2exch01.adit-jv.com [10.72.92.24]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp1.de.adit-jv.com (Postfix) with ESMTPS id D59E93C09A2; Tue, 13 Mar 2018 09:35:21 +0100 (CET) Received: from vmlxhi-087.adit-jv.com (10.72.93.172) by HI2EXCH01.adit-jv.com (10.72.92.24) with Microsoft SMTP Server (TLS) id 14.3.382.0; Tue, 13 Mar 2018 09:35:21 +0100 From: To: Date: Tue, 13 Mar 2018 09:34:43 +0100 Message-ID: <1520930084-17449-3-git-send-email-twischer@de.adit-jv.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520930084-17449-1-git-send-email-twischer@de.adit-jv.com> References: <1520007674-14618-4-git-send-email-twischer@de.adit-jv.com> <1520930084-17449-1-git-send-email-twischer@de.adit-jv.com> MIME-Version: 1.0 X-Originating-IP: [10.72.93.172] Cc: Timo Wischer , alsa-devel@alsa-project.org Subject: [alsa-devel] [PATCH - PCM 2/2] pcm: Provide areas_copy function which handles buffer wrap around X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Timo Wischer The already existing areas_copy functions do not care about the end of the source and destination buffer. Therefore the caller has to take care that the requested offset+size is not exceeding any buffer limit. This additional function will take care about the end of an buffer and will continue at the beginning of the buffer. For example this is required when copying between buffers with different sizes (not multiple of). This is often the case in IO plugins like the JACK plugin. Signed-off-by: Timo Wischer diff --git a/include/pcm.h b/include/pcm.h index 2619c8c..e2a5343 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -1147,6 +1147,15 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); +int snd_pcm_areas_copy_wrap(const snd_pcm_channel_area_t *dst_channels, + snd_pcm_uframes_t dst_offset, + const snd_pcm_uframes_t dst_size, + const snd_pcm_channel_area_t *src_channels, + snd_pcm_uframes_t src_offset, + const snd_pcm_uframes_t src_size, + const unsigned int channels, + snd_pcm_uframes_t frames, + const snd_pcm_format_t format); /** \} */ diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index d53ed98..ed47cb5 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -3289,6 +3289,55 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_ return 0; } +/** + * \brief Copy one or more areas + * \param dst_areas destination areas specification (one for each channel) + * \param dst_offset offset in frames inside destination area + * \param dst_size size in frames of the destination buffer + * \param src_areas source areas specification (one for each channel) + * \param src_offset offset in frames inside source area + * \param dst_size size in frames of the source buffer + * \param channels channels count + * \param frames frames to copy + * \param format PCM sample format + * \return 0 on success otherwise a negative error code + */ +int snd_pcm_areas_copy_wrap(const snd_pcm_channel_area_t *dst_channels, + snd_pcm_uframes_t dst_offset, + const snd_pcm_uframes_t dst_size, + const snd_pcm_channel_area_t *src_channels, + snd_pcm_uframes_t src_offset, + const snd_pcm_uframes_t src_size, + const unsigned int channels, + snd_pcm_uframes_t frames, + const snd_pcm_format_t format) +{ + while (frames > 0) { + int err; + snd_pcm_uframes_t xfer = frames; + /* do not write above the destination buffer */ + if ((dst_offset + xfer) > dst_size) + xfer = dst_size - dst_offset; + /* do not read from above the source buffer */ + if ((src_offset + xfer) > src_size) + xfer = src_size - src_offset; + err = snd_pcm_areas_copy(dst_channels, dst_offset, src_channels, + src_offset, channels, xfer, format); + if (err < 0) + return err; + + dst_offset += xfer; + if (dst_offset >= dst_size) + dst_offset = 0; + src_offset += xfer; + if (src_offset >= src_size) + src_offset = 0; + frames -= xfer; + } + + return 0; +} + static void dump_one_param(snd_pcm_hw_params_t *params, unsigned int k, snd_output_t *out) { snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k));