From patchwork Tue Mar 13 08:34:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Wischer X-Patchwork-Id: 10277919 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 DDD43602C2 for ; Tue, 13 Mar 2018 08:35:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF40728F22 for ; Tue, 13 Mar 2018 08:35:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D343B28F24; Tue, 13 Mar 2018 08:35:53 +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 DB84228F22 for ; Tue, 13 Mar 2018 08:35:52 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id D0E07267277; Tue, 13 Mar 2018 09:35:46 +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 A444C267281; Tue, 13 Mar 2018 09:35:44 +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 01B2E267275 for ; Tue, 13 Mar 2018 09:35:42 +0100 (CET) Received: from localhost (smtp1.de.adit-jv.com [127.0.0.1]) by smtp1.de.adit-jv.com (Postfix) with ESMTP id A45683C0BA6; Tue, 13 Mar 2018 09:35:42 +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 duqcTREs39Pp; Tue, 13 Mar 2018 09:35:30 +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 481183C09AB; Tue, 13 Mar 2018 09:35:24 +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:23 +0100 From: To: Date: Tue, 13 Mar 2018 09:34:44 +0100 Message-ID: <1520930084-17449-4-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 - JACK 1/1] jack: Do not Xrun the ALSA buffer 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 when the JACK thread is requesting too many audio frames Playback: Without this commit the ALSA audio buffer will be played with endless repeats as long as the user application has not provided new audio data. Therefore this garbage will be played as long as the user application has not called snd_pcm_stop() after an Xrun. With this fix the rest of the JACK buffer will be filled with silence. Capture: Without this commit the audio data in the ALSA buffer would be overwritten. With this commit the new data from the JACK buffer will not be copied. Therefore the existing data in the ALSA buffer will not be overwritten. Signed-off-by: Timo Wischer diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c index c547cbb..7c7c230 100644 --- a/jack/pcm_jack.c +++ b/jack/pcm_jack.c @@ -54,6 +54,7 @@ typedef struct { static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io); + static int pcm_poll_block_check(snd_pcm_ioplug_t *io) { static char buf[32]; @@ -143,8 +144,6 @@ static int snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io) { snd_pcm_jack_t *jack = io->private_data; - snd_pcm_uframes_t hw_ptr; - const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t xfer = 0; unsigned int channel; @@ -154,39 +153,50 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io) jack->areas[channel].first = 0; jack->areas[channel].step = jack->sample_bits; } - - if (io->state != SND_PCM_STATE_RUNNING) { - if (io->stream == SND_PCM_STREAM_PLAYBACK) { - for (channel = 0; channel < io->channels; channel++) - snd_pcm_area_silence(&jack->areas[channel], 0, nframes, io->format); - return 0; - } - } - hw_ptr = jack->hw_ptr; - areas = snd_pcm_ioplug_mmap_areas(io); + if (io->state == SND_PCM_STATE_RUNNING) { + snd_pcm_uframes_t hw_ptr = jack->hw_ptr; + const snd_pcm_uframes_t hw_avail = snd_pcm_ioplug_hw_avail(io, hw_ptr, + io->appl_ptr); - while (xfer < nframes) { - snd_pcm_uframes_t frames = nframes - xfer; - snd_pcm_uframes_t offset = hw_ptr % io->buffer_size; - snd_pcm_uframes_t cont = io->buffer_size - offset; + if (hw_avail > 0) { + const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io); + const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size; - if (cont < frames) - frames = cont; + xfer = nframes; + if (xfer > hw_avail) + xfer = hw_avail; - for (channel = 0; channel < io->channels; channel++) { if (io->stream == SND_PCM_STREAM_PLAYBACK) - snd_pcm_area_copy(&jack->areas[channel], xfer, &areas[channel], offset, frames, io->format); + snd_pcm_areas_copy_wrap(jack->areas, 0, nframes, + areas, offset, + io->buffer_size, + io->channels, xfer, + io->format); else - snd_pcm_area_copy(&areas[channel], offset, &jack->areas[channel], xfer, frames, io->format); + snd_pcm_areas_copy_wrap(areas, offset, + io->buffer_size, + jack->areas, 0, nframes, + io->channels, xfer, + io->format); + + hw_ptr += xfer; + if (hw_ptr >= jack->boundary) + hw_ptr -= jack->boundary; + jack->hw_ptr = hw_ptr; + } + } + + /* check if requested frames were copied */ + if (xfer < nframes) { + /* always fill the not yet written JACK buffer with silence */ + if (io->stream == SND_PCM_STREAM_PLAYBACK) { + const snd_pcm_uframes_t frames = nframes - xfer; + + snd_pcm_areas_silence(jack->areas, io->channels, xfer, + frames, io->format); } - - hw_ptr += frames; - if (hw_ptr >= jack->boundary) - hw_ptr -= jack->boundary; - xfer += frames; } - jack->hw_ptr = hw_ptr; pcm_poll_unblock_check(io); /* unblock socket for polling if needed */