From patchwork Wed Sep 13 14:21:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?J=C3=B6rg_Krause?= X-Patchwork-Id: 9951491 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 5E7BE6038F for ; Wed, 13 Sep 2017 14:21:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E2612870E for ; Wed, 13 Sep 2017 14:21:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 40BB628743; Wed, 13 Sep 2017 14:21:49 +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 2BB3A2870E for ; Wed, 13 Sep 2017 14:21:47 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id A31FA266CA1; Wed, 13 Sep 2017 16:21:42 +0200 (CEST) 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 8DE64266CC8; Wed, 13 Sep 2017 16:21:40 +0200 (CEST) Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.142]) by alsa0.perex.cz (Postfix) with ESMTP id B43A1266986 for ; Wed, 13 Sep 2017 16:21:38 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 3xskPC5czkz10HY; Wed, 13 Sep 2017 16:21:35 +0200 (CEST) Received: from mail.embedded.rocks ([127.0.0.1]) by localhost (mail.embedded.rocks [127.0.0.1]) (amavisd-new, port 10025) with ESMTP id tHa_kvyDE8DQ; Wed, 13 Sep 2017 16:21:33 +0200 (CEST) Received: from nzxt.fritz.box (port-92-195-68-97.dynamic.qsc.de [92.195.68.97]) (Authenticated sender: joerg.krause@embedded.rocks) by mail.embedded.rocks (Postfix) with ESMTPSA; Wed, 13 Sep 2017 16:21:33 +0200 (CEST) From: =?UTF-8?q?J=C3=B6rg=20Krause?= To: alsa-devel@alsa-project.org Date: Wed, 13 Sep 2017 16:21:10 +0200 Message-Id: <20170913142110.31072-1-joerg.krause@embedded.rocks> X-Mailer: git-send-email 2.14.1 MIME-Version: 1.0 Cc: Takashi Iwai , =?UTF-8?q?J=C3=B6rg=20Krause?= , Clemens Ladisch , Takashi Sakamoto Subject: [alsa-devel] [PATCH v2] pcm: softvol: add support for S24_LE 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 Tested with the Wolfson WM8524 DAC on a i.MX6UL board and the following ALSA configuration file using the pcm test utility from alsa-lib: """ $ cat /etc/asound.conf pcm.!default { type plug slave.pcm "softvol" } pcm.softvol { type softvol slave { pcm "hw:0" } control { name "Master" card 0 } } ctl.!default { type hw card 0 } ctl.softvol { type hw card 0 } $ pcm -D softvol -o S24_LE -c 2 -r 48000 """ The data in the Synchronous Audio Interface (SAI) of the i.MX6UL is aligned the following way: """ 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0 ## ## ## ## ## ## ## ## [ DATA[23:0] ] """ Signed-off-by: Jörg Krause --- v2: * add CONVERT_AREA_S24_LE algorithm instead of using the same one as S32_LE --- src/pcm/pcm_softvol.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c index 1fe5784d..68a35b56 100644 --- a/src/pcm/pcm_softvol.c +++ b/src/pcm/pcm_softvol.c @@ -251,6 +251,44 @@ static inline short MULTI_DIV_short(short a, unsigned int b, int swap) } \ } \ } while (0) + +#define CONVERT_AREA_S24_LE() do { \ + unsigned int ch, fr; \ + int *src, *dst; \ + int tmp; \ + for (ch = 0; ch < channels; ch++) { \ + src_area = &src_areas[ch]; \ + dst_area = &dst_areas[ch]; \ + src = snd_pcm_channel_area_addr(src_area, src_offset); \ + dst = snd_pcm_channel_area_addr(dst_area, dst_offset); \ + src_step = snd_pcm_channel_area_step(src_area) \ + / sizeof(int); \ + dst_step = snd_pcm_channel_area_step(dst_area) \ + / sizeof(int); \ + GET_VOL_SCALE; \ + fr = frames; \ + if (! vol_scale) { \ + while (fr--) { \ + *dst = 0; \ + dst += dst_step; \ + } \ + } else if (vol_scale == 0xffff) { \ + while (fr--) { \ + *dst = *src; \ + src += dst_step; \ + dst += src_step; \ + } \ + } else { \ + while (fr--) { \ + tmp = *src << 8; \ + tmp = (signed int) tmp >> 8; \ + *dst = MULTI_DIV_24(tmp, vol_scale); \ + src += dst_step; \ + dst += src_step; \ + } \ + } \ + } \ +} while (0) #define GET_VOL_SCALE \ switch (ch) { \ @@ -315,6 +353,10 @@ static void softvol_convert_stereo_vol(snd_pcm_softvol_t *svol, CONVERT_AREA(int, !snd_pcm_format_cpu_endian(svol->sformat)); break; + case SND_PCM_FORMAT_S24_LE: + /* 24bit samples */ + CONVERT_AREA_S24_LE(); + break; case SND_PCM_FORMAT_S24_3LE: CONVERT_AREA_S24_3LE(); break; @@ -366,6 +408,10 @@ static void softvol_convert_mono_vol(snd_pcm_softvol_t *svol, CONVERT_AREA(int, !snd_pcm_format_cpu_endian(svol->sformat)); break; + case SND_PCM_FORMAT_S24_LE: + /* 24bit samples */ + CONVERT_AREA_S24_LE(); + break; case SND_PCM_FORMAT_S24_3LE: CONVERT_AREA_S24_3LE(); break; @@ -422,6 +468,7 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm, { (1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S16_BE) | + (1ULL << SND_PCM_FORMAT_S24_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) | (1ULL << SND_PCM_FORMAT_S32_BE), (1ULL << (SND_PCM_FORMAT_S24_3LE - 32)) @@ -577,10 +624,11 @@ static int snd_pcm_softvol_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * param if (slave->format != SND_PCM_FORMAT_S16_LE && slave->format != SND_PCM_FORMAT_S16_BE && slave->format != SND_PCM_FORMAT_S24_3LE && + slave->format != SND_PCM_FORMAT_S24_LE && slave->format != SND_PCM_FORMAT_S32_LE && slave->format != SND_PCM_FORMAT_S32_BE) { - SNDERR("softvol supports only S16_LE, S16_BE, S24_3LE, S32_LE " - " or S32_BE"); + SNDERR("softvol supports only S16_LE, S16_BE, S24_LE, S24_3LE, " + "S32_LE or S32_BE"); return -EINVAL; } svol->sformat = slave->format; @@ -863,6 +911,7 @@ int snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name, sformat != SND_PCM_FORMAT_S16_LE && sformat != SND_PCM_FORMAT_S16_BE && sformat != SND_PCM_FORMAT_S24_3LE && + sformat != SND_PCM_FORMAT_S24_LE && sformat != SND_PCM_FORMAT_S32_LE && sformat != SND_PCM_FORMAT_S32_BE) return -EINVAL; @@ -1082,9 +1131,10 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name, sformat != SND_PCM_FORMAT_S16_LE && sformat != SND_PCM_FORMAT_S16_BE && sformat != SND_PCM_FORMAT_S24_3LE && + sformat != SND_PCM_FORMAT_S24_LE && sformat != SND_PCM_FORMAT_S32_LE && sformat != SND_PCM_FORMAT_S32_BE) { - SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format is supported"); + SNDERR("only S16_LE, S16_BE, S24_LE, S24_3LE, S32_LE or S32_BE format is supported"); snd_config_delete(sconf); return -EINVAL; }