From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570996842; cv=none; d=zoho.com; s=zohoarc; b=mg0yTtgNy7k6zfLFRTh++V2ZP5FxBPun56p1GHVf9nxmCmqtkaSAVGq9RhEoC9L/0QrpRK1s7JN2A7mhRdvSY2lVMCHoutTfoTLkAls3oM3aqDYQCtKTmC0OznHYTiJBQK1oYVq63pzwpIyrMFEG4+IDe26Zhoemx9wVaArcg0o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570996842; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=O2uLlaB2iMQO6FRsn1QrUOJ58Hsp0rMaMzhWkW836BQ=; b=Ubv/dZ3nqzCSLY5foYPeI6YsG7JKiU9S+rZMT1ABPI9vcXx7Qav49qUFEMTF+/QLFfGgJR6HCHw786meMf3P/L+S9Gr5MmiZ4chn/PKQiVvYSjv76DOuWJT2vXADRwOyGdwDWsLOmvxQTJ/bYXMu+EWOAYTPG2Zx+JGbpwNWsjM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570996842407904.1828740522532; Sun, 13 Oct 2019 13:00:42 -0700 (PDT) Received: from localhost ([::1]:41998 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk2f-0007B2-Gz for importer@patchew.org; Sun, 13 Oct 2019 16:00:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37213) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0L-0005Rv-0H for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0J-0003Cx-CO for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:12 -0400 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]:38046) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0J-0003Ao-5R for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:11 -0400 Received: by mail-wm1-x32e.google.com with SMTP id 3so14699635wmi.3 for ; Sun, 13 Oct 2019 12:58:10 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=O2uLlaB2iMQO6FRsn1QrUOJ58Hsp0rMaMzhWkW836BQ=; b=mdbT2xQobZMzb6qaSiPo9omprrYjacleWt4K1NetJdPntOUMEhiMNURRubrFuf0cC2 Jkn7ng31clHRMvLmi93J9R2ttQeM9RnUGoZ4c231PEqH5nSQs5Cd9ZXeN6mlqvrOBYtn bBouOEIzK9dEkgHvYYDURpi7xAZQKr+1YpdUl1BQeHQROHVSHqwkQabKC1J4EEf1tInz 0mwCUIWrm+/z236gAOaFFVEjmV/kU87zXWCtV0OCtE/BJA4VNhb7DbNdM9Y1FevAPDJ8 FhhedYExGxKF35DxYRhQOrO8fsoWVu2NiWEqKUFG9/qiwiCgDZgmOEssB0SGZXKRLv/N LQPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O2uLlaB2iMQO6FRsn1QrUOJ58Hsp0rMaMzhWkW836BQ=; b=VXwfenNJLIOxQmNoqIO7HGANqR2gtaV9ZbljC+gXt69vlaB6zC+lBhRCqS8vundSQG PwIgGlgyoCJRAvdXJWYPX4fsy71mEW7lcnJlSi/qO/vkZ0muQsG1h8imSGXQTRjTVPzU PTQRx8xJ3XBFSpx6KxObGxaWRKL1v2Aj9PUwseRJV2qFq7jr4lvxlx4kh+G6MEI+4eVV zcwXIgMeqSn6dypkGf9UCloHNTILRe9dg2yC+CQmnyKE7PpSQiC8jz6ZIOoPqvEW6d8B ng37koCElPXgEpTMXBlA9yd/loCaC6RyDWXBIwCE0lFe6O9pUsfQu4YXufNXA+wp7Ypx Da4Q== X-Gm-Message-State: APjAAAXU6V441QVrLQJquH9tfijnxVHYgeIw7GAHY9roEaHpyTYo4hj+ O6Prdk5FbPEFDtZnIMN8i1ssfhmC X-Google-Smtp-Source: APXvYqynUB3SzIhGUhXpYrvOJpQWhbjdoCmV7TPWg+eCG/txhdLNF43i0USbC6MLpJaTRc9/w8+lnw== X-Received: by 2002:a1c:bc07:: with SMTP id m7mr12459476wmf.103.1570996689319; Sun, 13 Oct 2019 12:58:09 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 01/10] audio: add mixing-engine option (documentation) Date: Sun, 13 Oct 2019 21:57:58 +0200 Message-Id: <5765186a7aadd51a72bc7d3e804307f0ee8a34ce.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32e X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann , Markus Armbruster Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) This will allow us to disable mixeng when we use a decent backend. Disabling mixeng have a few advantages: * we no longer convert the audio output from one format to another, when the underlying audio system would just convert it to a third format. We no longer convert, only the underlying system, when needed. * the underlying system probably has better resampling and sample format converting methods anyway... * we may support formats that the mixeng currently does not support (S24 or float samples, more than two channels) * when using an audio server (like pulseaudio) different sound card outputs will show up as separate streams, even if we use only one backend Disadvantages: * audio capturing no longer works (wavcapture, and vnc audio extension) * some backends only support a single playback stream or very picky about the audio format. In this case we can't disable mixeng. Originally thw two main use cases of the disabled option was: using unsupported audio formats (5.1 and 7.1 audio) and having different pulseaudio streams per audio frontend. Since we can have multiple -audiodevs, the latter is not that important, so currently you only need this option if you want to use 5.1 or 7.1 audio (implemented in a later patch), otherwise it's probably better to stick to the old and tried mixeng, since it's less picky about the backends. The ideal solution would be to port as much as possible to gstreamer, but this is currently out of scope: https://wiki.qemu.org/Internships/ProjectIdeas/AudioGStreamer Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- Notes: Changes from v1: =20 * renamed mixeng to mixing-engine =20 Changes from v5: =20 * better documentation =20 Changes from v1: =20 * renamed mixeng to mixing-engine qapi/audio.json | 6 ++++++ qemu-options.hx | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/qapi/audio.json b/qapi/audio.json index 9fefdf5186..23bbbe4b6a 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -11,6 +11,11 @@ # General audio backend options that are used for both playback and # recording. # +# @mixing-engine: use QEMU's mixing engine to mix all streams inside QEMU = and +# convert audio formats when not supported by the backend.= When +# set to off, fixed-settings must be also off (default on, +# since 4.2) +# # @fixed-settings: use fixed settings for host input/output. When off, # frequency, channels and format must not be # specified (default true) @@ -31,6 +36,7 @@ ## { 'struct': 'AudiodevPerDirectionOptions', 'data': { + '*mixing-engine': 'bool', '*fixed-settings': 'bool', '*frequency': 'uint32', '*channels': 'uint32', diff --git a/qemu-options.hx b/qemu-options.hx index 2a04ca6ac5..3f2aecc99c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -433,6 +433,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, " specifies the audio backend to use\n" " id=3D identifier of the backend\n" " timer-period=3D timer period in microseconds\n" + " in|out.mixing-engine=3D use mixing engine to mix stre= ams inside QEMU\n" " in|out.fixed-settings=3D use fixed settings for host = audio\n" " in|out.frequency=3D frequency to use with fixed setti= ngs\n" " in|out.channels=3D number of channels to use with fix= ed settings\n" @@ -493,6 +494,10 @@ output's property with @code{out.@var{prop}}. For exam= ple: -audiodev alsa,id=3Dexample,out.channels=3D1 # leaves in.channels unspecif= ied @end example =20 +NOTE: parameter validation is known to be incomplete, in many cases +specifying an invalid option causes QEMU to print an error message and +continue emulation without sound. + Valid global options are: =20 @table @option @@ -503,6 +508,16 @@ Identifies the audio backend. Sets the timer @var{period} used by the audio subsystem in microseconds. Default is 10000 (10 ms). =20 +@item in|out.mixing-engine=3Don|off +Use QEMU's mixing engine to mix all streams inside QEMU and convert +audio formats when not supported by the backend. When off, +@var{fixed-settings} must be off too. Note that disabling this option +means that the selected backend must support multiple streams and the +audio formats used by the virtual cards, otherwise you'll get no sound. +It's not recommended to disable this option unless you want to use 5.1 +or 7.1 audio, as mixing engine only supports mono and stereo audio. +Default is on. + @item in|out.fixed-settings=3Don|off Use fixed settings for host audio. When off, it will change based on how the guest opens the sound card. In this case you must not specify --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570996840; cv=none; d=zoho.com; s=zohoarc; b=RkJ2p5EMVSGcDWOJ1ayIWKS3Q8Uj2LS5/Yl3Wk49R27HAVJ5LaFVuDmpXRNLRZmTEOPh0SdqNmVUP20ZSw3iWYaKqlvgMtslkmDdMFy1vSO8d2Qwd4XOfHMU4bSWHoxSGt3YlYpq8ZwoAFZ5eCd2U7cR/AJGugoOtG2yrCJF9UE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570996840; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Pbln1L0UWMrKENno8JQoLEo0GwL8LqG6fEqEAAIjnjc=; b=TKoiCBvFh5tOPN/g3RL3OUH8inpniPPAJt+m9bQEXKkmuoeV9FNg/eUog4rFHFpYP4HbB+L4PcNil4d7OqOQUvpyJD/vt1L64l2uG+T43h+ijuFNoW4bemIPiR2iEcZnNqjSK1f9XoStG1NoIPRe5IDm+4m8UTOK18+piBDHomM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570996840105194.02528411179708; Sun, 13 Oct 2019 13:00:40 -0700 (PDT) Received: from localhost ([::1]:41996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk2d-00076H-Gl for importer@patchew.org; Sun, 13 Oct 2019 16:00:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37211) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0K-0005Ru-W7 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0J-0003D6-EI for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:12 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:38375) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0J-0003Bf-7D for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:11 -0400 Received: by mail-wm1-x343.google.com with SMTP id 3so14699648wmi.3 for ; Sun, 13 Oct 2019 12:58:11 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pbln1L0UWMrKENno8JQoLEo0GwL8LqG6fEqEAAIjnjc=; b=nVgp24+nyLNzusx+x/ZxFkJjLmz1egwa9jJ7oPTDSIBTce8IM5RYfzMAuY1tMtOLil HcYDVT3Aq/fmGZGX+pNhobpVHcQ1fntNI7V28ZA6T9TvHpmrrrwYIhwO3P/z89gEaV79 vk0P5ZbFfLlMZ0MPmtYh73eT9/7Hr0f0ihGvh8JuPMmqAykBJ0RampL6U759rD5Djf7Q Ky+3+FavUX6Q78dW8C7nXPsD8bF+y++2spC9zfsUi4A5e3coJ30be2dRC+QO01d/9ptY vwPtDl0mfT76MqU4/Usz9DG1UINdeJOkmo5nFrUcGrbbEY0pmTSR+MtHcS0fe5Ylus+a u8Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pbln1L0UWMrKENno8JQoLEo0GwL8LqG6fEqEAAIjnjc=; b=dEG3GBP7wSj4OvExZ8rbGgSyEU5CDDAHJc/ZmchR+Wbf0SZTYww3xMCNs9oYWBFGbt CcOMTmgd/lvzdS97PgnPKvGAmZ99FkrHSqueMxR2/xnFwEW+6ntKG8xinjxOsS0egNWe bn6k/enDzI1LXC7fcPHOuG9vbnwveDPAjRn2SNivfFDHept4fQjKIu41gzvJ5nK0o8cd IS2Kyld0+5aqev1H5sYJxFj1qM8Hc4Mbu1x5nd5nNlXxLX4FhDMc8BqC5zILDdufZ6yq oarRKGNV1k6q0q9PiedstfkH0Wln2y0zFgLHaJXECR4wzkE6SnQMZNy//rkWE6ELoVXn dZPg== X-Gm-Message-State: APjAAAVmhhf56aPjdsDPBHYVRXZKsJ09J7UWpXBUPexFrl7nlqOrgTdT 8bCXYndzaDD9ZLPdsX2K3RalvL7X X-Google-Smtp-Source: APXvYqwRKxHDG6qbY8ddmHLI0wmrYP4pF9ouvMbMkWaXBFYmPx/a5RIFppMemGstYsu2YbMa1zuqaA== X-Received: by 2002:a7b:cb42:: with SMTP id v2mr4555199wmj.165.1570996689971; Sun, 13 Oct 2019 12:58:09 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 02/10] audio: make mixeng optional Date: Sun, 13 Oct 2019 21:57:59 +0200 Message-Id: X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) Implementation of the previously added mixing-engine option. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- Notes: Changes from v4: =20 * audio_pcm_hw_add_* always returns a new HW (or fails) when not using = mixeng audio/audio.c | 70 ++++++++++++++++++++++++++++++++++++++---- audio/audio_template.h | 24 ++++++++++----- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 7128ee98dc..d616a4af98 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -838,32 +838,46 @@ static void audio_timer (void *opaque) */ size_t AUD_write(SWVoiceOut *sw, void *buf, size_t size) { + HWVoiceOut *hw; + if (!sw) { /* XXX: Consider options */ return size; } + hw =3D sw->hw; =20 - if (!sw->hw->enabled) { + if (!hw->enabled) { dolog ("Writing to disabled voice %s\n", SW_NAME (sw)); return 0; } =20 - return audio_pcm_sw_write(sw, buf, size); + if (audio_get_pdo_out(hw->s->dev)->mixing_engine) { + return audio_pcm_sw_write(sw, buf, size); + } else { + return hw->pcm_ops->write(hw, buf, size); + } } =20 size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) { + HWVoiceIn *hw; + if (!sw) { /* XXX: Consider options */ return size; } + hw =3D sw->hw; =20 - if (!sw->hw->enabled) { + if (!hw->enabled) { dolog ("Reading from disabled voice %s\n", SW_NAME (sw)); return 0; } =20 - return audio_pcm_sw_read(sw, buf, size); + if (audio_get_pdo_in(hw->s->dev)->mixing_engine) { + return audio_pcm_sw_read(sw, buf, size); + } else { + return hw->pcm_ops->read(hw, buf, size); + } } =20 int AUD_get_buffer_size_out (SWVoiceOut *sw) @@ -1090,6 +1104,26 @@ static void audio_run_out (AudioState *s) HWVoiceOut *hw =3D NULL; SWVoiceOut *sw; =20 + if (!audio_get_pdo_out(s->dev)->mixing_engine) { + while ((hw =3D audio_pcm_hw_find_any_enabled_out(s, hw))) { + /* there is exactly 1 sw for each hw with no mixeng */ + sw =3D hw->sw_head.lh_first; + + if (hw->pending_disable) { + hw->enabled =3D 0; + hw->pending_disable =3D 0; + if (hw->pcm_ops->enable_out) { + hw->pcm_ops->enable_out(hw, false); + } + } + + if (sw->active) { + sw->callback.fn(sw->callback.opaque, INT_MAX); + } + } + return; + } + while ((hw =3D audio_pcm_hw_find_any_enabled_out(s, hw))) { size_t played, live, prev_rpos, free; int nb_live, cleanup_required; @@ -1227,6 +1261,17 @@ static void audio_run_in (AudioState *s) { HWVoiceIn *hw =3D NULL; =20 + if (!audio_get_pdo_in(s->dev)->mixing_engine) { + while ((hw =3D audio_pcm_hw_find_any_enabled_in(s, hw))) { + /* there is exactly 1 sw for each hw with no mixeng */ + SWVoiceIn *sw =3D hw->sw_head.lh_first; + if (sw->active) { + sw->callback.fn(sw->callback.opaque, INT_MAX); + } + } + return; + } + while ((hw =3D audio_pcm_hw_find_any_enabled_in(s, hw))) { SWVoiceIn *sw; size_t captured =3D 0, min; @@ -1751,6 +1796,11 @@ CaptureVoiceOut *AUD_add_capture( s =3D audio_init(NULL, NULL); } =20 + if (!audio_get_pdo_out(s->dev)->mixing_engine) { + dolog("Can't capture with mixeng disabled\n"); + return NULL; + } + if (audio_validate_settings (as)) { dolog ("Invalid settings were passed when trying to add capture\n"= ); audio_print_settings (as); @@ -1905,9 +1955,13 @@ void audio_create_pdos(Audiodev *dev) static void audio_validate_per_direction_opts( AudiodevPerDirectionOptions *pdo, Error **errp) { + if (!pdo->has_mixing_engine) { + pdo->has_mixing_engine =3D true; + pdo->mixing_engine =3D true; + } if (!pdo->has_fixed_settings) { pdo->has_fixed_settings =3D true; - pdo->fixed_settings =3D true; + pdo->fixed_settings =3D pdo->mixing_engine; } if (!pdo->fixed_settings && (pdo->has_frequency || pdo->has_channels || pdo->has_format)) { @@ -1915,6 +1969,10 @@ static void audio_validate_per_direction_opts( "You can't use frequency, channels or format with fixed= -settings=3Doff"); return; } + if (!pdo->mixing_engine && pdo->fixed_settings) { + error_setg(errp, "You can't use fixed-settings without mixeng"); + return; + } =20 if (!pdo->has_frequency) { pdo->has_frequency =3D true; @@ -1926,7 +1984,7 @@ static void audio_validate_per_direction_opts( } if (!pdo->has_voices) { pdo->has_voices =3D true; - pdo->voices =3D 1; + pdo->voices =3D pdo->mixing_engine ? 1 : INT_MAX; } if (!pdo->has_format) { pdo->has_format =3D true; diff --git a/audio/audio_template.h b/audio/audio_template.h index 235d1acbbe..3709a4431c 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -78,13 +78,17 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (= HW *hw) =20 static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { - size_t samples =3D hw->samples; - if (audio_bug(__func__, samples =3D=3D 0)) { - dolog("Attempted to allocate empty buffer\n"); - } + if (glue(audio_get_pdo_, TYPE)(hw->s->dev)->mixing_engine) { + size_t samples =3D hw->samples; + if (audio_bug(__func__, samples =3D=3D 0)) { + dolog("Attempted to allocate empty buffer\n"); + } =20 - HWBUF =3D g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * sampl= es); - HWBUF->size =3D samples; + HWBUF =3D g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * s= amples); + HWBUF->size =3D samples; + } else { + HWBUF =3D NULL; + } } =20 static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) @@ -103,6 +107,10 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) = (SW *sw) { int samples; =20 + if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) { + return 0; + } + samples =3D ((int64_t) sw->HWBUF->size << 32) / sw->ratio; =20 sw->buf =3D audio_calloc(__func__, samples, sizeof(struct st_sample)); @@ -328,9 +336,9 @@ static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s,= struct audsettings *as) HW *hw; AudiodevPerDirectionOptions *pdo =3D glue(audio_get_pdo_, TYPE)(s->dev= ); =20 - if (pdo->fixed_settings) { + if (!pdo->mixing_engine || pdo->fixed_settings) { hw =3D glue(audio_pcm_hw_add_new_, TYPE)(s, as); - if (hw) { + if (!pdo->mixing_engine || hw) { return hw; } } --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570996842; cv=none; d=zoho.com; s=zohoarc; b=h95ZH27dK5H4nMAZGy2syIrS+I9AAEbHyZmN95lwppbQ4lJJSQ+wxJiS6Da1UoGGcfr5vgRnIOdUAEQ8DTvea/fQEf6w0of2wwzEPYNE/AVrfi5gQPYLumZRvq8Hj08Mp2B0DgnW4zgsnVacHnSOgLQecs/hN2F8dfQKrrQbuc4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570996842; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=i9UxN713GW0ghifGTVMxk9JG2fJFSnFStux97zyYILs=; b=k8sUlepN5UdJRcvIrX7ZrgPVt0LbBP3KI/r5VSLKhdSBpNExCAvSIaAc1H+Q4st+IWo4jzinV8kOb6uXi5xkbwBD64zQmyvapbRvm1n0fJcrKmXOx3q2e0CwDBp9+CM5HVK+ThdvWlVLSwv/DetF8BBCve3iS8wbn7xI++HocWo= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570996842402642.2577276299625; Sun, 13 Oct 2019 13:00:42 -0700 (PDT) Received: from localhost ([::1]:41994 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk2Z-00074p-CD for importer@patchew.org; Sun, 13 Oct 2019 16:00:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37221) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0L-0005Rx-D2 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0K-0003Dx-2W for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:13 -0400 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:42907) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0J-0003Cc-Sd for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:12 -0400 Received: by mail-wr1-x441.google.com with SMTP id n14so17210503wrw.9 for ; Sun, 13 Oct 2019 12:58:11 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=i9UxN713GW0ghifGTVMxk9JG2fJFSnFStux97zyYILs=; b=acxTYtJ3G8iRF1Ul0GcaXhNMFG+EBRGtgkeDqrRJBljer96HCCQ8E4e/X16aHRnpi4 47S89VCg+/TK1MP4j4l1wYkFGME4Gc0t/ZzuAAxklRGDXKaQwZhZE8XKCx6sLrzejLFX dIbydwN0gzrkoADa7U++zWOs8lQFp5BYV1yY+eP7U0hfYDjeq8qaHitOts+iWMgMXWul dOu+IzVPkOm7oe21ZABVuYRlLwh6uszW2PdiSGBUYP1NIa9ES8f5sbkIgRwNkkmMCL6K t4GjCKw4ph/+NwybeKNC48X+OkAyVbk2Bwx0SAhiCljUQFgoyyeFqEn3N56bGB0Aohje w8rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=i9UxN713GW0ghifGTVMxk9JG2fJFSnFStux97zyYILs=; b=UyMfU2YikX9erOWcklo3+aS7YMyqjA2XLgBDM787aUFrHN0DZw12VZlINZeIz0AFgy Y16FvnZuVX4Mu8EwPRprEFiNo6lHKc+jb7ZTL/utTxQEayA2+VCcXp0DP4a55EmpBb9C 4oMOBHdOAIXcR8x8p05M7dfuP5NSKEd8D3tBEsGIAbtYEQckbODXIQ5zXTYxi2XQHlUK 2Pff9Gjimum+8hR3epOQnnvJqj9ekLySnrhJ+N2gN76Tm+oZduCeN9oMQ3eSTxlqDtEg RcFnCK2o9I7eZpgurE5BQJ7zoUFv4ioN73PSW/fK3isUY2uSEN6c+o1JF76HCkN1L9Pk pelQ== X-Gm-Message-State: APjAAAWYWeY/jM1wA+qTIaE5ZDlgX5DlUUzU8/d52kRAjaDKA2RsBtYt hWIlQR7MEHZsi9mVD3zTC1H7juES X-Google-Smtp-Source: APXvYqwcXxP2/lBlsyPRPQBvmFAgOY1pUEeS6QLBHXReU7kAPfkbc8b5K8ukHj33+Vx4uS/YnFW6AQ== X-Received: by 2002:adf:f64f:: with SMTP id x15mr2184659wrp.381.1570996690789; Sun, 13 Oct 2019 12:58:10 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 03/10] paaudio: get/put_buffer functions Date: Sun, 13 Oct 2019 21:58:00 +0200 Message-Id: X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) This lets us avoid some buffer copying when using mixeng. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- audio/paaudio.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/audio/paaudio.c b/audio/paaudio.c index ed31f863f7..6ccdf31415 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -98,6 +98,59 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) } \ } while (0) =20 +static void *qpa_get_buffer_in(HWVoiceIn *hw, size_t *size) +{ + PAVoiceIn *p =3D (PAVoiceIn *) hw; + PAConnection *c =3D p->g->conn; + int r; + + pa_threaded_mainloop_lock(c->mainloop); + + CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail, + "pa_threaded_mainloop_lock failed\n"); + + if (!p->read_length) { + r =3D pa_stream_peek(p->stream, &p->read_data, &p->read_length); + CHECK_SUCCESS_GOTO(c, r =3D=3D 0, unlock_and_fail, + "pa_stream_peek failed\n"); + } + + *size =3D MIN(p->read_length, *size); + + pa_threaded_mainloop_unlock(c->mainloop); + return (void *) p->read_data; + +unlock_and_fail: + pa_threaded_mainloop_unlock(c->mainloop); + *size =3D 0; + return NULL; +} + +static void qpa_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size) +{ + PAVoiceIn *p =3D (PAVoiceIn *) hw; + PAConnection *c =3D p->g->conn; + int r; + + pa_threaded_mainloop_lock(c->mainloop); + + CHECK_DEAD_GOTO(c, p->stream, unlock, + "pa_threaded_mainloop_lock failed\n"); + + assert(buf =3D=3D p->read_data && size <=3D p->read_length); + + p->read_data +=3D size; + p->read_length -=3D size; + + if (size && !p->read_length) { + r =3D pa_stream_drop(p->stream); + CHECK_SUCCESS_GOTO(c, r =3D=3D 0, unlock, "pa_stream_drop failed\n= "); + } + +unlock: + pa_threaded_mainloop_unlock(c->mainloop); +} + static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length) { PAVoiceIn *p =3D (PAVoiceIn *) hw; @@ -136,6 +189,32 @@ unlock_and_fail: return 0; } =20 +static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + PAVoiceOut *p =3D (PAVoiceOut *) hw; + PAConnection *c =3D p->g->conn; + void *ret; + int r; + + pa_threaded_mainloop_lock(c->mainloop); + + CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail, + "pa_threaded_mainloop_lock failed\n"); + + *size =3D -1; + r =3D pa_stream_begin_write(p->stream, &ret, size); + CHECK_SUCCESS_GOTO(c, r >=3D 0, unlock_and_fail, + "pa_stream_begin_write failed\n"); + + pa_threaded_mainloop_unlock(c->mainloop); + return ret; + +unlock_and_fail: + pa_threaded_mainloop_unlock(c->mainloop); + *size =3D 0; + return NULL; +} + static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length) { PAVoiceOut *p =3D (PAVoiceOut *) hw; @@ -698,11 +777,15 @@ static struct audio_pcm_ops qpa_pcm_ops =3D { .init_out =3D qpa_init_out, .fini_out =3D qpa_fini_out, .write =3D qpa_write, + .get_buffer_out =3D qpa_get_buffer_out, + .put_buffer_out =3D qpa_write, /* pa handles it */ .volume_out =3D qpa_volume_out, =20 .init_in =3D qpa_init_in, .fini_in =3D qpa_fini_in, .read =3D qpa_read, + .get_buffer_in =3D qpa_get_buffer_in, + .put_buffer_in =3D qpa_put_buffer_in, .volume_in =3D qpa_volume_in }; =20 --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997112; cv=none; d=zoho.com; s=zohoarc; b=IvlBitBHWB71BH667Q3F7urnQ5ZbMGz8oAtjYxUZT6hXK8i4SlsPW0POnoascd1WZgdMKS0UACaswokRuX3OKA8Y5887H80HMTLivz8g8wEQdhDP4THZaiA8TECpwJsVlJ/MVIhCcJgN31lnwnxbT8IcituAFEl2QNPzxQYWC+A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997112; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=hBNbSNYdRxpi4YPwJzeBrQcOF4eLYJl4drOoaIZgmh0=; b=SX9vFs2NkzxHcU+kNDD2Au+ylG4WchySgXeyzx03/D/kDftizc9BI5KND9DY2ReJ8IKw/y6RksAb00jIvWwokEKWrsIZbhRr7ALtWnpLvhBqfmT11uZJyHAR6cvJKJgyhiJbJX3MsYRXx5JC2MJeRgELIcCf8VxFBVsM2UZsT4M= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997112645989.2595860188079; Sun, 13 Oct 2019 13:05:12 -0700 (PDT) Received: from localhost ([::1]:42034 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk75-0002Rn-48 for importer@patchew.org; Sun, 13 Oct 2019 16:05:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37248) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0M-0005SA-Qf for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0L-0003Fe-3N for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:35719) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0K-0003EN-T4 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:13 -0400 Received: by mail-wr1-x443.google.com with SMTP id v8so17255140wrt.2 for ; Sun, 13 Oct 2019 12:58:12 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hBNbSNYdRxpi4YPwJzeBrQcOF4eLYJl4drOoaIZgmh0=; b=PBXdWNFzUkyjmNRugR4G7C1VODFBO7+giz6OiOV1A8WqaqZ+gkZURKZAZwutTB9AwO bJAhLA33EFucfYVEGhltwwyhI2PV7Vi0gkeD3ZN5D1Egf7iY80EOY7kOJidsctufM3/w /JmhwlkyO9G1EVkdaY3fj8dBeYhaxl/7qXdEFbnUGupmc1xKTDJnc7iEkI/CyJccbUKR PKJFGRBuNDa8fjBkJdc11eGJUajRaUqyIfx2FWV72PWzLvMXYdskUELeMck5nyRj3aq2 TXV7ggi4T69HuQFdcJa3SyX245bJ5kXogROib+oMHB2Uwe8yHbpCCcxUScXiFODULj/n 19xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hBNbSNYdRxpi4YPwJzeBrQcOF4eLYJl4drOoaIZgmh0=; b=jPl8ja4QVeE77RTMPQRPJcEvgICJe2nR79OrQqX4LKMIfRVDi79pCkD6aZB+raD0lq cM+u9Fhm78n3IWPUylgAuCboSGWp46WCnUH+olumnQlcpqwe5/KRZinQ5hLnXuOvjN4i SRYuLfV2Q/hNu/QjN7qp/TUeZ9NYPaVsiaYWAYOYVWwa3Wp97sG8Gdj84WrmvsjD/FaV CDRNWVNkzNxgKYREZu2OMyS/evXGRSTrb9LG4xTnHb6l02wK1Zp/22/5Unn9/RDUc0DP g96hD0KLBf6ldDk/IkgJW8RbGNiAx5DKhHi3dxOfn3ocYWLFb5WbDp84WbwQR4eJ6LTa UiLg== X-Gm-Message-State: APjAAAV1ZBxtSyT5LPbDIZ/t4D9EuAwK09yLcCi17iRQ9hFTbHqXX9nE QhwMreD5PDsA1+YSNcAPjoubfNIm X-Google-Smtp-Source: APXvYqx2kLo+WBVKqnH2TfDqWEWdI1mVAl91yNb8ALMatjo8Wfg4NGpjODZ88S1YWaAcKuYHag2V+g== X-Received: by 2002:a5d:420c:: with SMTP id n12mr22103076wrq.85.1570996691684; Sun, 13 Oct 2019 12:58:11 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 04/10] audio: support more than two channels in volume setting Date: Sun, 13 Oct 2019 21:58:01 +0200 Message-Id: <5d3dd2ee3baaa62805e79c3901abb7415ae32461.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- audio/audio.c | 30 ++++++++++++++++++++++-------- audio/audio.h | 10 ++++++++++ audio/audio_int.h | 4 ++-- audio/paaudio.c | 20 ++++++++++++-------- audio/spiceaudio.c | 14 ++++++++------ 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index d616a4af98..f1c145dfcd 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1891,31 +1891,45 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *c= b_opaque) } =20 void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t r= vol) +{ + Volume vol =3D { .mute =3D mute, .channels =3D 2, .vol =3D { lvol, rvo= l } }; + audio_set_volume_out(sw, &vol); +} + +void audio_set_volume_out(SWVoiceOut *sw, Volume *vol) { if (sw) { HWVoiceOut *hw =3D sw->hw; =20 - sw->vol.mute =3D mute; - sw->vol.l =3D nominal_volume.l * lvol / 255; - sw->vol.r =3D nominal_volume.r * rvol / 255; + sw->vol.mute =3D vol->mute; + sw->vol.l =3D nominal_volume.l * vol->vol[0] / 255; + sw->vol.r =3D nominal_volume.l * vol->vol[vol->channels > 1 ? 1 : = 0] / + 255; =20 if (hw->pcm_ops->volume_out) { - hw->pcm_ops->volume_out(hw, &sw->vol); + hw->pcm_ops->volume_out(hw, vol); } } } =20 void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvo= l) +{ + Volume vol =3D { .mute =3D mute, .channels =3D 2, .vol =3D { lvol, rvo= l } }; + audio_set_volume_in(sw, &vol); +} + +void audio_set_volume_in(SWVoiceIn *sw, Volume *vol) { if (sw) { HWVoiceIn *hw =3D sw->hw; =20 - sw->vol.mute =3D mute; - sw->vol.l =3D nominal_volume.l * lvol / 255; - sw->vol.r =3D nominal_volume.r * rvol / 255; + sw->vol.mute =3D vol->mute; + sw->vol.l =3D nominal_volume.l * vol->vol[0] / 255; + sw->vol.r =3D nominal_volume.r * vol->vol[vol->channels > 1 ? 1 : = 0] / + 255; =20 if (hw->pcm_ops->volume_in) { - hw->pcm_ops->volume_in(hw, &sw->vol); + hw->pcm_ops->volume_in(hw, vol); } } } diff --git a/audio/audio.h b/audio/audio.h index c74abb8c47..0db3c7dd5e 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -124,6 +124,16 @@ uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEM= UAudioTimeStamp *ts); void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t r= vol); void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvo= l); =20 +#define AUDIO_MAX_CHANNELS 16 +typedef struct Volume { + bool mute; + int channels; + uint8_t vol[AUDIO_MAX_CHANNELS]; +} Volume; + +void audio_set_volume_out(SWVoiceOut *sw, Volume *vol); +void audio_set_volume_in(SWVoiceIn *sw, Volume *vol); + SWVoiceIn *AUD_open_in ( QEMUSoundCard *card, SWVoiceIn *sw, diff --git a/audio/audio_int.h b/audio/audio_int.h index 22a703c13e..9176db249b 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -166,7 +166,7 @@ struct audio_pcm_ops { */ size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size); void (*enable_out)(HWVoiceOut *hw, bool enable); - void (*volume_out)(HWVoiceOut *hw, struct mixeng_volume *vol); + void (*volume_out)(HWVoiceOut *hw, Volume *vol); =20 int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); @@ -174,7 +174,7 @@ struct audio_pcm_ops { void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); void (*enable_in)(HWVoiceIn *hw, bool enable); - void (*volume_in)(HWVoiceIn *hw, struct mixeng_volume *vol); + void (*volume_in)(HWVoiceIn *hw, Volume *vol); }; =20 void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size); diff --git a/audio/paaudio.c b/audio/paaudio.c index 6ccdf31415..d195b1caa8 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -531,20 +531,22 @@ static void qpa_fini_in (HWVoiceIn *hw) } } =20 -static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol) +static void qpa_volume_out(HWVoiceOut *hw, Volume *vol) { PAVoiceOut *pa =3D (PAVoiceOut *) hw; pa_operation *op; pa_cvolume v; PAConnection *c =3D pa->g->conn; + int i; =20 #ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */ pa_cvolume_init (&v); /* function is present in 0.9.13+ */ #endif =20 - v.channels =3D 2; - v.values[0] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32= _MAX; - v.values[1] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32= _MAX; + v.channels =3D vol->channels; + for (i =3D 0; i < vol->channels; ++i) { + v.values[i] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i])= / 255; + } =20 pa_threaded_mainloop_lock(c->mainloop); =20 @@ -571,20 +573,22 @@ static void qpa_volume_out(HWVoiceOut *hw, struct mix= eng_volume *vol) pa_threaded_mainloop_unlock(c->mainloop); } =20 -static void qpa_volume_in(HWVoiceIn *hw, struct mixeng_volume *vol) +static void qpa_volume_in(HWVoiceIn *hw, Volume *vol) { PAVoiceIn *pa =3D (PAVoiceIn *) hw; pa_operation *op; pa_cvolume v; PAConnection *c =3D pa->g->conn; + int i; =20 #ifdef PA_CHECK_VERSION pa_cvolume_init (&v); #endif =20 - v.channels =3D 2; - v.values[0] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32= _MAX; - v.values[1] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32= _MAX; + v.channels =3D vol->channels; + for (i =3D 0; i < vol->channels; ++i) { + v.values[i] =3D ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i])= / 255; + } =20 pa_threaded_mainloop_lock(c->mainloop); =20 diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 9860f9c5e1..6ed7f7a79e 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -179,13 +179,14 @@ static void line_out_enable(HWVoiceOut *hw, bool enab= le) } =20 #if ((SPICE_INTERFACE_PLAYBACK_MAJOR >=3D 1) && (SPICE_INTERFACE_PLAYBACK_= MINOR >=3D 2)) -static void line_out_volume(HWVoiceOut *hw, struct mixeng_volume *vol) +static void line_out_volume(HWVoiceOut *hw, Volume *vol) { SpiceVoiceOut *out =3D container_of(hw, SpiceVoiceOut, hw); uint16_t svol[2]; =20 - svol[0] =3D vol->l / ((1ULL << 16) + 1); - svol[1] =3D vol->r / ((1ULL << 16) + 1); + assert(vol->channels =3D=3D 2); + svol[0] =3D vol->vol[0] * 257; + svol[1] =3D vol->vol[1] * 257; spice_server_playback_set_volume(&out->sin, 2, svol); spice_server_playback_set_mute(&out->sin, vol->mute); } @@ -262,13 +263,14 @@ static void line_in_enable(HWVoiceIn *hw, bool enable) } =20 #if ((SPICE_INTERFACE_RECORD_MAJOR >=3D 2) && (SPICE_INTERFACE_RECORD_MINO= R >=3D 2)) -static void line_in_volume(HWVoiceIn *hw, struct mixeng_volume *vol) +static void line_in_volume(HWVoiceIn *hw, Volume *vol) { SpiceVoiceIn *in =3D container_of(hw, SpiceVoiceIn, hw); uint16_t svol[2]; =20 - svol[0] =3D vol->l / ((1ULL << 16) + 1); - svol[1] =3D vol->r / ((1ULL << 16) + 1); + assert(vol->channels =3D=3D 2); + svol[0] =3D vol->vol[0] * 257; + svol[1] =3D vol->vol[1] * 257; spice_server_record_set_volume(&in->sin, 2, svol); spice_server_record_set_mute(&in->sin, vol->mute); } --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997227; cv=none; d=zoho.com; s=zohoarc; b=AqNXMJZhtsNtznl7YKcWl9SuTTqoUmpVA9bb3bvTIi4UfAd+wDI1BJS+GhrRueKxN0yAwLPt7eJjqmrloc5lve0awCbKSwmjzNa0cq8eM+SLzjvG/+YexX1NBzFVsDX1FOx4RlOgKt6JAejNaBiW8Ic1Si36W2DCp3fEhw8xIkE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997227; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=FZBJxE6vgXiUYQRHq25EgBqFYd27odUS2eGRI60cvzc=; b=KC/wPE7+wnJBhGPGw1AIIJUv6cNDapwe48DaNkKEziV9/5Lz7yy25gGDZ4P7QMrN41kLxJeAbZaHjj9W4Li/7LN+tL54Li3qHcCzOo3QHDJ7R2UUtPcLwwoHfzqS/NhX+piVR/VU4KwBQvcoUHAnT1COhc9kh1eT4XLKH+iCPYU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997226996718.1350996614633; Sun, 13 Oct 2019 13:07:06 -0700 (PDT) Received: from localhost ([::1]:42054 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk8v-0004xv-Sy for importer@patchew.org; Sun, 13 Oct 2019 16:07:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37289) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0O-0005Ub-NT for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0M-0003HA-2W for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:54284) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0L-0003Fu-Pu for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: by mail-wm1-x32d.google.com with SMTP id p7so15065194wmp.4 for ; Sun, 13 Oct 2019 12:58:13 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FZBJxE6vgXiUYQRHq25EgBqFYd27odUS2eGRI60cvzc=; b=j9WWdzXQvOAbfxnY6Q7siDlc2Wp684F54O6cHZdPiFO7bO+2MueQ7h6CDj3/Zmns/s yyaZeg9KOiodEnaXz7u0oZe3LfBjAZnGWLexTjOlElYIYPHDC4j+GD8+XgtpAu7Ftzig z+nKdgBxMY5zLAvwTTHbky612X/jRMdt8d2R/BSpUav2ggUvu0z0m5/5kFw43+S06NwO /Rx+V6lI/66Nm7Eu4C3LnGBACvGDa+c29uiImQCMtMaO56qTm7nSSOWi67Whj2Yn4RsQ 1ujKKN8ioKCm0f1FHZaF1BdAnuW6M0t5Epj9ZFlspj/BguyIuG6zVaNJmPdTuUVb1tMu zYmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FZBJxE6vgXiUYQRHq25EgBqFYd27odUS2eGRI60cvzc=; b=l2IDzPhHilab+406n0DzrJsztu6pFhzL1YOemf0wpDMjDy93KcYNo5BaMxBO5AvGpC 7aGU3ilgIipGlCjg1WLNlRallos/DjAlueplqxvadDNdTgTVwfJx0Qx74vz3qq1nkr1W jKaE6ltdtTslXt/OVgY8FhMxBTszHGUAwn4olURe5Xy1DbRozKcZT3eYyfBmk0DZRFSl 5x3ewhIL45YjjXl5dIDFtBw0HiR+8Y1EWVrPT4NcGwoAr7fSwS1sXhy13ervHGH2KSh3 3vd3GPRTFIQRxSPvwPFJ+x4q87CFmAe5MqC52fAwdeqUB5bhnET53Iqk6c8izHMWGjkZ AKyA== X-Gm-Message-State: APjAAAU0U5NK3agL5/K1lodoPpxjzEs8ZGVsFgR7BYgnyxlhe5CW9iNo Bo5MBFi9BZo1wy8v6uGsxnEskWOB X-Google-Smtp-Source: APXvYqzIOf/OJoHYKdfT1aOGIZWI9u176blMGRUKCJP5BEM2nWiqbncmf6+MRqBiB7oHzG6hEzmc+A== X-Received: by 2002:a1c:7e10:: with SMTP id z16mr11919966wmc.11.1570996692382; Sun, 13 Oct 2019 12:58:12 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 05/10] audio: replace shift in audio_pcm_info with bytes_per_frame Date: Sun, 13 Oct 2019 21:58:02 +0200 Message-Id: <1351fd9bcce0ff20d81850c5292722194329de02.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32d X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) The bit shifting trick worked because the number of bytes per frame was always a power-of-two (since QEMU only supports mono, stereo and 8, 16 and 32 bit samples). But if we want to add support for surround sound, this no longer holds true. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- audio/alsaaudio.c | 11 +++--- audio/audio.c | 74 ++++++++++++++++++++--------------------- audio/audio_int.h | 3 +- audio/coreaudio.c | 4 +-- audio/dsound_template.h | 10 +++--- audio/dsoundaudio.c | 4 +-- audio/noaudio.c | 2 +- audio/ossaudio.c | 14 ++++---- audio/spiceaudio.c | 3 +- audio/wavaudio.c | 6 ++-- 10 files changed, 66 insertions(+), 65 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index cfe42284a6..eddf013a53 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -602,7 +602,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, siz= e_t len) { ALSAVoiceOut *alsa =3D (ALSAVoiceOut *) hw; size_t pos =3D 0; - size_t len_frames =3D len >> hw->info.shift; + size_t len_frames =3D len / hw->info.bytes_per_frame; =20 while (len_frames) { char *src =3D advance(buf, pos); @@ -648,7 +648,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, siz= e_t len) } } =20 - pos +=3D written << hw->info.shift; + pos +=3D written * hw->info.bytes_per_frame; if (written < len_frames) { break; } @@ -802,7 +802,8 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_= t len) void *dst =3D advance(buf, pos); snd_pcm_sframes_t nread; =20 - nread =3D snd_pcm_readi(alsa->handle, dst, len >> hw->info.shift); + nread =3D snd_pcm_readi( + alsa->handle, dst, len / hw->info.bytes_per_frame); =20 if (nread <=3D 0) { switch (nread) { @@ -828,8 +829,8 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_= t len) } } =20 - pos +=3D nread << hw->info.shift; - len -=3D nread << hw->info.shift; + pos +=3D nread * hw->info.bytes_per_frame; + len -=3D nread * hw->info.bytes_per_frame; } =20 return pos; diff --git a/audio/audio.c b/audio/audio.c index f1c145dfcd..c00f4deddd 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -299,12 +299,13 @@ static int audio_pcm_info_eq (struct audio_pcm_info *= info, struct audsettings *a =20 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings = *as) { - int bits =3D 8, sign =3D 0, shift =3D 0; + int bits =3D 8, sign =3D 0, mul; =20 switch (as->fmt) { case AUDIO_FORMAT_S8: sign =3D 1; case AUDIO_FORMAT_U8: + mul =3D 1; break; =20 case AUDIO_FORMAT_S16: @@ -312,7 +313,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, = struct audsettings *as) /* fall through */ case AUDIO_FORMAT_U16: bits =3D 16; - shift =3D 1; + mul =3D 2; break; =20 case AUDIO_FORMAT_S32: @@ -320,7 +321,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, = struct audsettings *as) /* fall through */ case AUDIO_FORMAT_U32: bits =3D 32; - shift =3D 2; + mul =3D 4; break; =20 default: @@ -331,9 +332,8 @@ void audio_pcm_init_info (struct audio_pcm_info *info, = struct audsettings *as) info->bits =3D bits; info->sign =3D sign; info->nchannels =3D as->nchannels; - info->shift =3D (as->nchannels =3D=3D 2) + shift; - info->align =3D (1 << info->shift) - 1; - info->bytes_per_second =3D info->freq << info->shift; + info->bytes_per_frame =3D as->nchannels * mul; + info->bytes_per_second =3D info->freq * info->bytes_per_frame; info->swap_endianness =3D (as->endianness !=3D AUDIO_HOST_ENDIANNESS); } =20 @@ -344,26 +344,25 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info = *info, void *buf, int len) } =20 if (info->sign) { - memset (buf, 0x00, len << info->shift); + memset(buf, 0x00, len * info->bytes_per_frame); } else { switch (info->bits) { case 8: - memset (buf, 0x80, len << info->shift); + memset(buf, 0x80, len * info->bytes_per_frame); break; =20 case 16: { int i; uint16_t *p =3D buf; - int shift =3D info->nchannels - 1; short s =3D INT16_MAX; =20 if (info->swap_endianness) { s =3D bswap16 (s); } =20 - for (i =3D 0; i < len << shift; i++) { + for (i =3D 0; i < len * info->nchannels; i++) { p[i] =3D s; } } @@ -373,14 +372,13 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info = *info, void *buf, int len) { int i; uint32_t *p =3D buf; - int shift =3D info->nchannels - 1; int32_t s =3D INT32_MAX; =20 if (info->swap_endianness) { s =3D bswap32 (s); } =20 - for (i =3D 0; i < len << shift; i++) { + for (i =3D 0; i < len * info->nchannels; i++) { p[i] =3D s; } } @@ -558,7 +556,7 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void = *pcm_buf, size_t len) =20 while (len) { st_sample *src =3D hw->mix_buf->samples + pos; - uint8_t *dst =3D advance(pcm_buf, clipped << hw->info.shift); + uint8_t *dst =3D advance(pcm_buf, clipped * hw->info.bytes_per_fra= me); size_t samples_till_end_of_buf =3D hw->mix_buf->size - pos; size_t samples_to_clip =3D MIN(len, samples_till_end_of_buf); =20 @@ -607,7 +605,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *bu= f, size_t size) return 0; } =20 - samples =3D size >> sw->info.shift; + samples =3D size / sw->info.bytes_per_frame; if (!live) { return 0; } @@ -642,7 +640,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *bu= f, size_t size) =20 sw->clip (buf, sw->buf, ret); sw->total_hw_samples_acquired +=3D total; - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } =20 /* @@ -715,7 +713,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *= buf, size_t size) } =20 wpos =3D (sw->hw->mix_buf->pos + live) % hwsamples; - samples =3D size >> sw->info.shift; + samples =3D size / sw->info.bytes_per_frame; =20 dead =3D hwsamples - live; swlim =3D ((int64_t) dead << 32) / sw->ratio; @@ -759,13 +757,13 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void= *buf, size_t size) dolog ( "%s: write size %zu ret %zu total sw %zu\n", SW_NAME (sw), - size >> sw->info.shift, + size / sw->info.bytes_per_frame, ret, sw->total_hw_samples_mixed ); #endif =20 - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } =20 #ifdef DEBUG_AUDIO @@ -882,7 +880,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) =20 int AUD_get_buffer_size_out (SWVoiceOut *sw) { - return sw->hw->mix_buf->size << sw->hw->info.shift; + return sw->hw->mix_buf->size * sw->hw->info.bytes_per_frame; } =20 void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -998,10 +996,10 @@ static size_t audio_get_avail (SWVoiceIn *sw) ldebug ( "%s: get_avail live %d ret %" PRId64 "\n", SW_NAME (sw), - live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift + live, (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_fr= ame ); =20 - return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_frame; } =20 static size_t audio_get_free(SWVoiceOut *sw) @@ -1025,10 +1023,11 @@ static size_t audio_get_free(SWVoiceOut *sw) #ifdef DEBUG_OUT dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n", SW_NAME (sw), - live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.sh= ift); + live, dead, (((int64_t) dead << 32) / sw->ratio) * + sw->info.bytes_per_frame); #endif =20 - return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) dead << 32) / sw->ratio) * sw->info.bytes_per_frame; } =20 static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, @@ -1047,7 +1046,7 @@ static void audio_capture_mix_and_clear(HWVoiceOut *h= w, size_t rpos, while (n) { size_t till_end_of_hw =3D hw->mix_buf->size - rpos2; size_t to_write =3D MIN(till_end_of_hw, n); - size_t bytes =3D to_write << hw->info.shift; + size_t bytes =3D to_write * hw->info.bytes_per_frame; size_t written; =20 sw->buf =3D hw->mix_buf->samples + rpos2; @@ -1082,10 +1081,11 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, = size_t live) return clipped + live; } =20 - decr =3D MIN(size >> hw->info.shift, live); + decr =3D MIN(size / hw->info.bytes_per_frame, live); audio_pcm_hw_clip_out(hw, buf, decr); - proc =3D hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shi= ft) >> - hw->info.shift; + proc =3D hw->pcm_ops->put_buffer_out(hw, buf, + decr * hw->info.bytes_per_frame= ) / + hw->info.bytes_per_frame; =20 live -=3D proc; clipped +=3D proc; @@ -1234,16 +1234,16 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, si= ze_t samples) =20 while (samples) { size_t proc; - size_t size =3D samples << hw->info.shift; + size_t size =3D samples * hw->info.bytes_per_frame; void *buf =3D hw->pcm_ops->get_buffer_in(hw, &size); =20 - assert((size & hw->info.align) =3D=3D 0); + assert(size % hw->info.bytes_per_frame =3D=3D 0); if (size =3D=3D 0) { hw->pcm_ops->put_buffer_in(hw, buf, size); break; } =20 - proc =3D MIN(size >> hw->info.shift, + proc =3D MIN(size / hw->info.bytes_per_frame, conv_buf->size - conv_buf->pos); =20 hw->conv(conv_buf->samples + conv_buf->pos, buf, proc); @@ -1251,7 +1251,7 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size= _t samples) =20 samples -=3D proc; conv +=3D proc; - hw->pcm_ops->put_buffer_in(hw, buf, proc << hw->info.shift); + hw->pcm_ops->put_buffer_in(hw, buf, proc * hw->info.bytes_per_fram= e); } =20 return conv; @@ -1325,7 +1325,7 @@ static void audio_run_capture (AudioState *s) =20 for (cb =3D cap->cb_head.lh_first; cb; cb =3D cb->entries.le_n= ext) { cb->ops.capture (cb->opaque, cap->buf, - to_capture << hw->info.shift); + to_capture * hw->info.bytes_per_frame); } rpos =3D (rpos + to_capture) % hw->mix_buf->size; live -=3D to_capture; @@ -1378,7 +1378,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size= _t *size) ssize_t start; =20 if (unlikely(!hw->buf_emul)) { - size_t calc_size =3D hw->conv_buf->size << hw->info.shift; + size_t calc_size =3D hw->conv_buf->size * hw->info.bytes_per_frame; hw->buf_emul =3D g_malloc(calc_size); hw->size_emul =3D calc_size; hw->pos_emul =3D hw->pending_emul =3D 0; @@ -1414,7 +1414,7 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void = *buf, size_t size) void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size) { if (unlikely(!hw->buf_emul)) { - size_t calc_size =3D hw->mix_buf->size << hw->info.shift; + size_t calc_size =3D hw->mix_buf->size * hw->info.bytes_per_frame; =20 hw->buf_emul =3D g_malloc(calc_size); hw->size_emul =3D calc_size; @@ -1833,7 +1833,7 @@ CaptureVoiceOut *AUD_add_capture( =20 audio_pcm_init_info (&hw->info, as); =20 - cap->buf =3D g_malloc0_n(hw->mix_buf->size, 1 << hw->info.shift); + cap->buf =3D g_malloc0_n(hw->mix_buf->size, hw->info.bytes_per_fra= me); =20 hw->clip =3D mixeng_clip [hw->info.nchannels =3D=3D 2] @@ -2153,14 +2153,14 @@ size_t audio_rate_get_bytes(struct audio_pcm_info *= info, RateCtl *rate, now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks =3D now - rate->start_ticks; bytes =3D muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECO= ND); - samples =3D (bytes - rate->bytes_sent) >> info->shift; + samples =3D (bytes - rate->bytes_sent) / info->bytes_per_frame; if (samples < 0 || samples > 65536) { AUD_log(NULL, "Resetting rate control (%" PRId64 " samples)\n", sa= mples); audio_rate_start(rate); samples =3D 0; } =20 - ret =3D MIN(samples << info->shift, bytes_avail); + ret =3D MIN(samples * info->bytes_per_frame, bytes_avail); rate->bytes_sent +=3D ret; return ret; } diff --git a/audio/audio_int.h b/audio/audio_int.h index 9176db249b..5ba2078346 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -43,8 +43,7 @@ struct audio_pcm_info { int sign; int freq; int nchannels; - int align; - int shift; + int bytes_per_frame; int bytes_per_second; int swap_endianness; }; diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 1427c9f622..66f0f459cf 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -440,7 +440,7 @@ static OSStatus audioDeviceIOProc( } =20 frameCount =3D core->audioDevicePropertyBufferFrameSize; - pending_frames =3D hw->pending_emul >> hw->info.shift; + pending_frames =3D hw->pending_emul / hw->info.bytes_per_frame; =20 /* if there are not enough samples, set signal and return */ if (pending_frames < frameCount) { @@ -449,7 +449,7 @@ static OSStatus audioDeviceIOProc( return 0; } =20 - len =3D frameCount << hw->info.shift; + len =3D frameCount * hw->info.bytes_per_frame; while (len) { size_t write_len; ssize_t start =3D ((ssize_t) hw->pos_emul) - hw->pending_emul; diff --git a/audio/dsound_template.h b/audio/dsound_template.h index 9f10b688df..7a15f91ce5 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -98,8 +98,8 @@ static int glue (dsound_lock_, TYPE) ( goto fail; } =20 - if ((p1p && *p1p && (*blen1p & info->align)) || - (p2p && *p2p && (*blen2p & info->align))) { + if ((p1p && *p1p && (*blen1p % info->bytes_per_frame)) || + (p2p && *p2p && (*blen2p % info->bytes_per_frame))) { dolog("DirectSound returned misaligned buffer %ld %ld\n", *blen1p, *blen2p); glue(dsound_unlock_, TYPE)(buf, *p1p, p2p ? *p2p : NULL, *blen1p, @@ -247,14 +247,14 @@ static int dsound_init_out(HWVoiceOut *hw, struct aud= settings *as, obt_as.endianness =3D 0; audio_pcm_init_info (&hw->info, &obt_as); =20 - if (bc.dwBufferBytes & hw->info.align) { + if (bc.dwBufferBytes % hw->info.bytes_per_frame) { dolog ( "GetCaps returned misaligned buffer size %ld, alignment %d\n", - bc.dwBufferBytes, hw->info.align + 1 + bc.dwBufferBytes, hw->info.bytes_per_frame ); } hw->size_emul =3D bc.dwBufferBytes; - hw->samples =3D bc.dwBufferBytes >> hw->info.shift; + hw->samples =3D bc.dwBufferBytes / hw->info.bytes_per_frame; ds->s =3D s; =20 #ifdef DEBUG_DSOUND diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index d4a4757445..c265c0094b 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -320,8 +320,8 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRE= CTSOUNDBUFFER dsb, return; } =20 - len1 =3D blen1 >> hw->info.shift; - len2 =3D blen2 >> hw->info.shift; + len1 =3D blen1 / hw->info.bytes_per_frame; + len2 =3D blen2 / hw->info.bytes_per_frame; =20 #ifdef DEBUG_DSOUND dolog ("clear %p,%ld,%ld %p,%ld,%ld\n", diff --git a/audio/noaudio.c b/audio/noaudio.c index ec8a287f36..ff99b253ff 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -91,7 +91,7 @@ static size_t no_read(HWVoiceIn *hw, void *buf, size_t si= ze) NoVoiceIn *no =3D (NoVoiceIn *) hw; int64_t bytes =3D audio_rate_get_bytes(&hw->info, &no->rate, size); =20 - audio_pcm_info_clear_buf(&hw->info, buf, bytes >> hw->info.shift); + audio_pcm_info_clear_buf(&hw->info, buf, bytes / hw->info.bytes_per_fr= ame); return bytes; } =20 diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 0c4451e972..c43faeeea4 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -506,16 +506,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audset= tings *as, oss->nfrags =3D obt.nfrags; oss->fragsize =3D obt.fragsize; =20 - if (obt.nfrags * obt.fragsize & hw->info.align) { + if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) { dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n", - obt.nfrags * obt.fragsize, hw->info.align + 1); + obt.nfrags * obt.fragsize, hw->info.bytes_per_frame); } =20 - hw->samples =3D (obt.nfrags * obt.fragsize) >> hw->info.shift; + hw->samples =3D (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; =20 oss->mmapped =3D 0; if (oopts->has_try_mmap && oopts->try_mmap) { - hw->size_emul =3D hw->samples << hw->info.shift; + hw->size_emul =3D hw->samples * hw->info.bytes_per_frame; hw->buf_emul =3D mmap( NULL, hw->size_emul, @@ -644,12 +644,12 @@ static int oss_init_in(HWVoiceIn *hw, struct audsetti= ngs *as, void *drv_opaque) oss->nfrags =3D obt.nfrags; oss->fragsize =3D obt.fragsize; =20 - if (obt.nfrags * obt.fragsize & hw->info.align) { + if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) { dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n", - obt.nfrags * obt.fragsize, hw->info.align + 1); + obt.nfrags * obt.fragsize, hw->info.bytes_per_frame); } =20 - hw->samples =3D (obt.nfrags * obt.fragsize) >> hw->info.shift; + hw->samples =3D (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; =20 oss->fd =3D fd; oss->dev =3D dev; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 6ed7f7a79e..b6b5da4812 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -131,7 +131,8 @@ static void *line_out_get_buffer(HWVoiceOut *hw, size_t= *size) =20 if (out->frame) { *size =3D audio_rate_get_bytes( - &hw->info, &out->rate, (out->fsize - out->fpos) << hw->info.sh= ift); + &hw->info, &out->rate, + (out->fsize - out->fpos) * hw->info.bytes_per_frame); } else { audio_rate_start(&out->rate); } diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 47efdc1b1e..e46d834bd3 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -43,14 +43,14 @@ static size_t wav_write_out(HWVoiceOut *hw, void *buf, = size_t len) { WAVVoiceOut *wav =3D (WAVVoiceOut *) hw; int64_t bytes =3D audio_rate_get_bytes(&hw->info, &wav->rate, len); - assert(bytes >> hw->info.shift << hw->info.shift =3D=3D bytes); + assert(bytes % hw->info.bytes_per_frame =3D=3D 0); =20 if (bytes && fwrite(buf, bytes, 1, wav->f) !=3D 1) { dolog("wav_write_out: fwrite of %" PRId64 " bytes failed\nReason: = %s\n", bytes, strerror(errno)); } =20 - wav->total_samples +=3D bytes >> hw->info.shift; + wav->total_samples +=3D bytes / hw->info.bytes_per_frame; return bytes; } =20 @@ -134,7 +134,7 @@ static void wav_fini_out (HWVoiceOut *hw) WAVVoiceOut *wav =3D (WAVVoiceOut *) hw; uint8_t rlen[4]; uint8_t dlen[4]; - uint32_t datalen =3D wav->total_samples << hw->info.shift; + uint32_t datalen =3D wav->total_samples * hw->info.bytes_per_frame; uint32_t rifflen =3D datalen + 36; =20 if (!wav->f) { --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997192; cv=none; d=zoho.com; s=zohoarc; b=KzaUzn0jnFm6pytRX3Xa8qKPnFCD2FqJ5ePOP9B0gfHIdM+B+HXom0X3wkT3OvcgsBGFit1GN22gLbMTy5+V6aYK+v8dMPBkL+ES2v68EMgFDzddUtnZNE34vW+0qN8qEoYLTIW1w/+zdOOmfdIAMS+2+z+7k1k6kVs+7Y7rB/c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997192; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=I/J8Dq/+F7R0/J6BZwd7lt84Aly4P3hEz64ceVDIF5c=; b=GGzlv0cb9FECyGaWPFuT+MAhEsHkQzINlz+1DDfbSkOFsYqY8OgdUcpn1/a2StTqp+AB7XVAH0bNxUDzUOpF4cvvtVow0MkZ2if+gQtMa7/7i676U1WmLdac1x5h1CXxWQmghwljQfQ4jrASsCP/3X5TLvK9RiC7KQPloNnyrH4= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997192973397.1564674494181; Sun, 13 Oct 2019 13:06:32 -0700 (PDT) Received: from localhost ([::1]:42046 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk8N-0004Ou-VN for importer@patchew.org; Sun, 13 Oct 2019 16:06:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37256) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0N-0005ST-9S for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0M-0003HY-8o for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:15 -0400 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]:42449) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0M-0003GW-34 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: by mail-wr1-x430.google.com with SMTP id n14so17210568wrw.9 for ; Sun, 13 Oct 2019 12:58:14 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I/J8Dq/+F7R0/J6BZwd7lt84Aly4P3hEz64ceVDIF5c=; b=UQMcAN1saSM6BhMkpDnD/DLaxnxTqZ0i+JK64gPzjROixw9xZlODptRlTnZBWVG/dB kZIQjK8R8fRz4D7l3v3IBFyy+PiY10UPYd9xTx3QqGNcufL2HJ+Gl94o41LUBOsdh4bE Pycd8WRVDfPzecrfxCu4bBVTlyWPzsfQVVq0vjAIuv4h4pZFlAGormOhUblva1MQ6/ex EWHfF7OwMtF10EW1nVV3FfuUinE75d999AAe8mRWDJFjHB/10JPs126jsRytXvQZHllG 3aC1iF9r2JcwWJMGisrSXL+uzM5YWrwL7OLd6uiRbZU2sSrYbDAHyYKjl7iMblWys1I1 n4PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=I/J8Dq/+F7R0/J6BZwd7lt84Aly4P3hEz64ceVDIF5c=; b=AgeuHzhGvuxhMSCx8SfKbFpUQmXz5Yd8MPs998ARVjMr4iJ5Q3aIIJmwnYTjxBaw8V god03ZcN8484FLBEbH5z+E8x+/qYq/izZPJxyx/OYosh6+M1qJpcpnmCkgpUMJ1qLfpY nddXPh3DUzHuKPgctMdyCFzHiIeMyqplT3BvMpdQ8byCpZN1eSVzGbyTb3DCvZXliLNV lhcQpbBl0+ODOsSfk+olPs0jcEuSrZpbwvBWZROpuNsrz6KK4t3W0Zkn8S2Hgaj0rQgm wtDFWXuum3Yld8S68461c+01h3ztngXAGQTs2MZ58Imy7lrR5EV+UbGzboHRnGePCwST QWyQ== X-Gm-Message-State: APjAAAXaCLgD6PlpCE9qumlszhcLRe/Wsxx+glO1pV2AniNBwxkRJNeR VkPaoj98XuikeoQvWy2AJeDZ9IwU X-Google-Smtp-Source: APXvYqws10uyMYDBwQV/MOgpbo80z1fsv80qiS3nKrFRPUczZ/oBC8Fy7qMuOC1ouCx/anudy0Ihmw== X-Received: by 2002:adf:f30b:: with SMTP id i11mr21261264wro.377.1570996692989; Sun, 13 Oct 2019 12:58:12 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 06/10] audio: basic support for multichannel audio Date: Sun, 13 Oct 2019 21:58:03 +0200 Message-Id: <7e53be1f97e939ed3bb729ef39e76b775643118a.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::430 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) Which currently only means removing some checks. Old code won't require more than two channels, but new code will need it. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- audio/alsaaudio.c | 7 ------- audio/audio.c | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index eddf013a53..f37ce1ce85 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -493,13 +493,6 @@ static int alsa_open(bool in, struct alsa_params_req *= req, goto err; } =20 - if (nchannels !=3D 1 && nchannels !=3D 2) { - alsa_logerr2 (err, typ, - "Can not handle obtained number of channels %d\n", - nchannels); - goto err; - } - if (apdo->buffer_length) { int dir =3D 0; unsigned int btime =3D apdo->buffer_length; diff --git a/audio/audio.c b/audio/audio.c index c00f4deddd..7fc3aa9d16 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -242,7 +242,7 @@ static int audio_validate_settings (struct audsettings = *as) { int invalid; =20 - invalid =3D as->nchannels !=3D 1 && as->nchannels !=3D 2; + invalid =3D as->nchannels < 1; invalid |=3D as->endianness !=3D 0 && as->endianness !=3D 1; =20 switch (as->fmt) { --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997280; cv=none; d=zoho.com; s=zohoarc; b=Ra0FUk5GwDo9FcNpq8PjsA4C5+RICDH4e9x4Q/01A+7Nr1MLDP6hA+/Zfy2NNpNc7DSqOpVtlPouqwO+qZW3nHMJY6YYB+or69fRPhojDzDnsg6qploa+o3srvdfjj9jkJ0dVkQZIwtNGmLmi+RE4Tm6QFDWq+KUzpVpetepvAY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997280; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8TTUthXqXhh1DdLxMpTCEbLpELmMAAhIVdhapb9+b1E=; b=KNdlOOfVAYs4E7Th1cskijYK9oFMlynxqfAhhaTxw9LxkM7B/9CelqsySz1iGxN2lzfzviwsjC0AFIWvBJ0Au1WH1LCDFxH2RUgkZw9YfXhXdVntvZgS5sKBiu8PvW+Wnr1RlRMxGUTq0NjxmZuwfqlScyev+tt/vZw76sTZEL0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997280516631.6940334032362; Sun, 13 Oct 2019 13:08:00 -0700 (PDT) Received: from localhost ([::1]:42066 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk9n-0006JR-Fj for importer@patchew.org; Sun, 13 Oct 2019 16:07:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37277) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0O-0005TU-3g for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0N-0003IZ-1W for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:34570) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0M-0003HU-S2 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:14 -0400 Received: by mail-wr1-x444.google.com with SMTP id j11so17263360wrp.1 for ; Sun, 13 Oct 2019 12:58:14 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8TTUthXqXhh1DdLxMpTCEbLpELmMAAhIVdhapb9+b1E=; b=j3AAwwsMmK1wBGCWAY08+feGmI9W/OiiQxbXFLKlgUIqJBfMggl4hQ20inpDRNnH0z oziaZ2dlzqEvRXy6fbCVXTDWBNnPy0HzCSe8M6d646AJ0ihFvWTlxuxYKFn8H3SZMQSG ZzSGTnClL1R+g2IFX8PUBHUzf//NTGboiKKie9iZS5bFyXL5qwMHqWNycqZUR+cf+eVa PwL9m8XwtAoHUotI8Qiz1E4WAcyJDCEp21E6IWlweOu85WDWIEbiyoVpNcYsf9VvyUhM JMr/ZonTEgL2TR4z2+lq5ZY+OI0unmg41TqKahXXrzCAukmjtsZxLAyTRImkCVIcHpNK e7hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8TTUthXqXhh1DdLxMpTCEbLpELmMAAhIVdhapb9+b1E=; b=lj595W5ttyZen2dkzFVcBiPZwcMAeBKRIGg5YHPn/5MRb6uHdUJ1eZY6rmr6nG4Oww mqpuQ0KwQdsaCAbPjW/1khksx0Jg3J24Yt0/vuQvDrDokJE5ppbJkzEVSU2Qd2mBdyBj aDdHiZUtVMsmH57qPE0p7PaSJG6XjTv9ouV1ZJlntyTapFgLvwhSPkZuA26MOEJoyJwC +9FbT/vsjk9+mtUikcoqLv4LVqPcZFJe71s/aq7yZVS9USQ0J/O6xJ6H1rm/HVXXFyfc J7DDlVKsBl8tKxrlZY0CdLoBE0P+z+3CnaJHocGJ9gB/bpVzweDibOZ6sOKjWcZxQTtd gwbw== X-Gm-Message-State: APjAAAV/cwEB/wkLzR3OPogVdo17o1GCjd3OZ4ZsyvoGKALPh9M3YeDC V1KOmyfMMIJ9yNuo9nCJZUwykiw6 X-Google-Smtp-Source: APXvYqxONJH4A4co2xrTivkqxeS61xKWlPRBwR/iJL71RP6wV3pPYu4qd2itDZy82VelvOuuUzyqKQ== X-Received: by 2002:a5d:51d2:: with SMTP id n18mr22694214wrv.225.1570996693775; Sun, 13 Oct 2019 12:58:13 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 07/10] usb-audio: do not count on avail bytes actually available Date: Sun, 13 Oct 2019 21:58:04 +0200 Message-Id: X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) This assumption is no longer true when mixeng is turned off. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- hw/usb/dev-audio.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index ae42e5a2f1..74c99b1f12 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -319,30 +319,31 @@ static int streambuf_put(struct streambuf *buf, USBPa= cket *p) { uint32_t free =3D buf->size - (buf->prod - buf->cons); =20 - if (!free) { + if (free < USBAUDIO_PACKET_SIZE) { return 0; } if (p->iov.size !=3D USBAUDIO_PACKET_SIZE) { return 0; } - assert(free >=3D USBAUDIO_PACKET_SIZE); + usb_packet_copy(p, buf->data + (buf->prod % buf->size), USBAUDIO_PACKET_SIZE); buf->prod +=3D USBAUDIO_PACKET_SIZE; return USBAUDIO_PACKET_SIZE; } =20 -static uint8_t *streambuf_get(struct streambuf *buf) +static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) { uint32_t used =3D buf->prod - buf->cons; uint8_t *data; =20 if (!used) { + *len =3D 0; return NULL; } - assert(used >=3D USBAUDIO_PACKET_SIZE); data =3D buf->data + (buf->cons % buf->size); - buf->cons +=3D USBAUDIO_PACKET_SIZE; + *len =3D MIN(buf->prod - buf->cons, + buf->size - (buf->cons % buf->size)); return data; } =20 @@ -374,16 +375,21 @@ static void output_callback(void *opaque, int avail) USBAudioState *s =3D opaque; uint8_t *data; =20 - for (;;) { - if (avail < USBAUDIO_PACKET_SIZE) { + while (avail) { + size_t written, len; + + data =3D streambuf_get(&s->out.buf, &len); + if (!data) { return; } - data =3D streambuf_get(&s->out.buf); - if (!data) { + + written =3D AUD_write(s->out.voice, data, len); + avail -=3D written; + s->out.buf.cons +=3D written; + + if (written < len) { return; } - AUD_write(s->out.voice, data, USBAUDIO_PACKET_SIZE); - avail -=3D USBAUDIO_PACKET_SIZE; } } =20 --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997387; cv=none; d=zoho.com; s=zohoarc; b=dNpZzHrbKiF5Du7tvB1zlrLhn9aIdTLc8zCxVdYtvcLqiVqHQiJu8DpUzhjm65JgHoQvMaaOJTjvgmF7zhZa2crb53FWz5bLzDvkO0UNGaIUKHbWVX+f/c5dWvlPq2PK3ai6/AiC8wUqmyHj6e+MaOCLoW7rwXiW2hc8UzrshRg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997387; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1xbpHh712sivYhk5HmhmXHkxPur7dIJpK6QrNTW7BR0=; b=mspohEb/57O/0TVS95Z0TEw6Ixp8t6SQ7ygiS91qBh7xMTNsAbedOUy18CRgz2Q6j0WfNHkEhF+4rLz4OsUNhBEfLT/cYJWDlxGYI7Gh1tx7lvlJkp2lNgS4mq3hJMOoC1mHf6kTGzK5FsCtiUnAWiRk9XFvouUyUYkRs6xmhyM= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997387004836.6513697349063; Sun, 13 Oct 2019 13:09:47 -0700 (PDT) Received: from localhost ([::1]:42078 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJkBV-00082S-Vc for importer@patchew.org; Sun, 13 Oct 2019 16:09:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37328) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0R-0005Yr-8d for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0O-0003Kd-GO for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:19 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:34570) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0O-0003JR-5S for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: by mail-wr1-x443.google.com with SMTP id j11so17263387wrp.1 for ; Sun, 13 Oct 2019 12:58:16 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1xbpHh712sivYhk5HmhmXHkxPur7dIJpK6QrNTW7BR0=; b=Xzi6bvSbYyboubJNp5M8xLxAzCjyMBD+PZnMsSV+M8/dzGR1tA1eObUi+xFox87Aqn tUrj0GEyr/twVt5j6X7PArNbV36i2Eu1CV5AecmjA7h2ci7Ph0ODbPMb/bVeleSrLVX2 VA58plTK2gE0y5LvbkLyqVlG/5ZvSpUEg7uK+QYE2mjdxezE40pmvvfyFNnTQKQ9q+/Y c7Go0MWCgdpzz16itCnSFsH1L/f9ALZljM89HE4ERlAJ3fzTUTjhuoIGTRZvUQtM1otZ NMh+AUjZME6XrOfaMCsxT09xRC/yWNNJo6XVcfMEanyZg7lRo7MBDpSf16xmjyrXLqlM Vcig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1xbpHh712sivYhk5HmhmXHkxPur7dIJpK6QrNTW7BR0=; b=Yn+FvB2UgY5EPjDVYXocHdCO89KNafXDU4xu7+hfxrfMSBmxlG5OzsHjYbU8djeRlC njN7FF4zuutTXrtc1FoVzgTZdWHlqiPIhpgbkqyhx2RNpVyNjhAAYLGqW0jDvpQXh9G5 hD6lldpTuJ9JIASUNAXXMfY7gs2YskC/nYDkYMraW01rGBNZoM/E8Qx3SymJas3l+aeo A+indUPtSCogS6vShvtv9faxXBEp/E1wGaGfA+d3bkqCyii5TkUSHVkWk5yhrJFVklcf Mp4C49BnQ9zYe0O5/5GebXvNqxphAW2Vs1XXJ268zm8Nm7SAJewLv8OXG61wcSgGpfxs BQ2Q== X-Gm-Message-State: APjAAAWASuUBAz3KQFEc8Tet1Dsm6yylw9h1A3I/wGt9JYJejiG5k4ph UpXAOp8Y0HnPX/+kIO85Rkd4o5P3 X-Google-Smtp-Source: APXvYqyZDRhjS2zM8XjE0Z71Z3psS2b7+/s8g+mfM52yT5gDz9F0/dbHQLlTP99phxI5VskZjGdORQ== X-Received: by 2002:adf:f68f:: with SMTP id v15mr22182149wrp.234.1570996694744; Sun, 13 Oct 2019 12:58:14 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 08/10] usb-audio: support more than two channels of audio Date: Sun, 13 Oct 2019 21:58:05 +0200 Message-Id: <98e96606228afa907fa238eac26573d5af63434a.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) This commit adds support for 5.1 and 7.1 audio playback. This commit adds a new property to usb-audio: * multi=3Don|off Whether to enable the 5.1 and 7.1 audio support. When off (default) it continues to emulate the old stereo-only device. When on, it emulates a slightly different audio device that supports 5.1 and 7.1 audio. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- Notes: According to the spec the channel order is front left, front right, center, lfe, surround left, surround right for 5.1 sound. But alsa uses front left, front right, surround left, surround right, center, lfe. This means if you simply use an alsa device as -audiodev, the surround and center/lfe channels will be swapped. There is not much to do sort of writing a mini mixeng or something like that, but you can easily add a new device to /etc/asound.conf that swaps the channels: =20 pcm.swap { type route slave.pcm "default" # or whatever slave.channels 6 =20 ttable.0.0 1 ttable.1.1 1 ttable.2.4 1 ttable.3.5 1 ttable.4.2 1 ttable.5.3 1 } =20 and use -audiodev alsa,id=3Dfoo,out.mixing-engine=3Doff,alsa-out.dev=3D= swap,... =20 (due to how usb and usb-audio works, you'll probably need alsa-out.try-poll=3Doff and some playing with threshold) =20 Pulseaudio allows us to specify channel order, and we default to a compatible order so it should work correctly without extra setup. hw/usb/dev-audio.c | 419 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 366 insertions(+), 53 deletions(-) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 74c99b1f12..e42bdfbdc1 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -37,11 +37,15 @@ #include "desc.h" #include "audio/audio.h" =20 +static void usb_audio_reinit(USBDevice *dev, unsigned channels); + #define USBAUDIO_VENDOR_NUM 0x46f4 /* CRC16() of "QEMU" */ #define USBAUDIO_PRODUCT_NUM 0x0002 =20 #define DEV_CONFIG_VALUE 1 /* The one and only */ =20 +#define USBAUDIO_MAX_CHANNELS(s) (s->multi ? 8 : 2) + /* Descriptor subtypes for AC interfaces */ #define DST_AC_HEADER 1 #define DST_AC_INPUT_TERMINAL 2 @@ -80,6 +84,27 @@ static const USBDescStrings usb_audio_stringtable =3D { [STRING_REAL_STREAM] =3D "Audio Output - 48 kHz Stereo", }; =20 +/* + * A USB audio device supports an arbitrary number of alternate + * interface settings for each interface. Each corresponds to a block + * diagram of parameterized blocks. This can thus refer to things like + * number of channels, data rates, or in fact completely different + * block diagrams. Alternative setting 0 is always the null block diagram, + * which is used by a disabled device. + */ +enum usb_audio_altset { + ALTSET_OFF =3D 0x00, /* No endpoint */ + ALTSET_STEREO =3D 0x01, /* Single endpoint */ + ALTSET_51 =3D 0x02, + ALTSET_71 =3D 0x03, +}; + +static unsigned altset_channels[] =3D { + [ALTSET_STEREO] =3D 2, + [ALTSET_51] =3D 6, + [ALTSET_71] =3D 8, +}; + #define U16(x) ((x) & 0xff), (((x) >> 8) & 0xff) #define U24(x) U16(x), (((x) >> 16) & 0xff) #define U32(x) U24(x), (((x) >> 24) & 0xff) @@ -87,7 +112,8 @@ static const USBDescStrings usb_audio_stringtable =3D { /* * A Basic Audio Device uses these specific values */ -#define USBAUDIO_PACKET_SIZE 192 +#define USBAUDIO_PACKET_SIZE_BASE 96 +#define USBAUDIO_PACKET_SIZE(channels) (USBAUDIO_PACKET_SIZE_BASE * channe= ls) #define USBAUDIO_SAMPLE_RATE 48000 #define USBAUDIO_PACKET_INTERVAL 1 =20 @@ -121,7 +147,7 @@ static const USBDescIface desc_iface[] =3D { 0x01, /* u8 bTerminalID */ U16(0x0101), /* u16 wTerminalType */ 0x00, /* u8 bAssocTerminal */ - 0x02, /* u16 bNrChannels */ + 0x02, /* u8 bNrChannels */ U16(0x0003), /* u16 wChannelConfig */ 0x00, /* u8 iChannelNames */ STRING_INPUT_TERMINAL, /* u8 iTerminal */ @@ -156,14 +182,14 @@ static const USBDescIface desc_iface[] =3D { }, },{ .bInterfaceNumber =3D 1, - .bAlternateSetting =3D 0, + .bAlternateSetting =3D ALTSET_OFF, .bNumEndpoints =3D 0, .bInterfaceClass =3D USB_CLASS_AUDIO, .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, .iInterface =3D STRING_NULL_STREAM, },{ .bInterfaceNumber =3D 1, - .bAlternateSetting =3D 1, + .bAlternateSetting =3D ALTSET_STEREO, .bNumEndpoints =3D 1, .bInterfaceClass =3D USB_CLASS_AUDIO, .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, @@ -199,7 +225,7 @@ static const USBDescIface desc_iface[] =3D { { .bEndpointAddress =3D USB_DIR_OUT | 0x01, .bmAttributes =3D 0x0d, - .wMaxPacketSize =3D USBAUDIO_PACKET_SIZE, + .wMaxPacketSize =3D USBAUDIO_PACKET_SIZE(2), .bInterval =3D 1, .is_audio =3D 1, /* Stereo Headphone Class-specific @@ -247,17 +273,274 @@ static const USBDesc desc_audio =3D { .str =3D usb_audio_stringtable, }; =20 -/* - * A USB audio device supports an arbitrary number of alternate - * interface settings for each interface. Each corresponds to a block - * diagram of parameterized blocks. This can thus refer to things like - * number of channels, data rates, or in fact completely different - * block diagrams. Alternative setting 0 is always the null block diagram, - * which is used by a disabled device. - */ -enum usb_audio_altset { - ALTSET_OFF =3D 0x00, /* No endpoint */ - ALTSET_ON =3D 0x01, /* Single endpoint */ +/* multi channel compatible desc */ + +static const USBDescIface desc_iface_multi[] =3D { + { + .bInterfaceNumber =3D 0, + .bNumEndpoints =3D 0, + .bInterfaceClass =3D USB_CLASS_AUDIO, + .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_CONTROL, + .bInterfaceProtocol =3D 0x04, + .iInterface =3D STRING_USBAUDIO_CONTROL, + .ndesc =3D 4, + .descs =3D (USBDescOther[]) { + { + /* Headphone Class-Specific AC Interface Header Descriptor= */ + .data =3D (uint8_t[]) { + 0x09, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AC_HEADER, /* u8 bDescriptorSubtype= */ + U16(0x0100), /* u16 bcdADC */ + U16(0x38), /* u16 wTotalLength */ + 0x01, /* u8 bInCollection */ + 0x01, /* u8 baInterfaceNr */ + } + },{ + /* Generic Stereo Input Terminal ID1 Descriptor */ + .data =3D (uint8_t[]) { + 0x0c, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AC_INPUT_TERMINAL, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bTerminalID */ + U16(0x0101), /* u16 wTerminalType */ + 0x00, /* u8 bAssocTerminal */ + 0x08, /* u8 bNrChannels */ + U16(0x063f), /* u16 wChannelConfig */ + 0x00, /* u8 iChannelNames */ + STRING_INPUT_TERMINAL, /* u8 iTerminal */ + } + },{ + /* Generic Stereo Feature Unit ID2 Descriptor */ + .data =3D (uint8_t[]) { + 0x19, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AC_FEATURE_UNIT, /* u8 bDescriptorSubtype= */ + 0x02, /* u8 bUnitID */ + 0x01, /* u8 bSourceID */ + 0x02, /* u8 bControlSize */ + U16(0x0001), /* u16 bmaControls(0) */ + U16(0x0002), /* u16 bmaControls(1) */ + U16(0x0002), /* u16 bmaControls(2) */ + U16(0x0002), /* u16 bmaControls(3) */ + U16(0x0002), /* u16 bmaControls(4) */ + U16(0x0002), /* u16 bmaControls(5) */ + U16(0x0002), /* u16 bmaControls(6) */ + U16(0x0002), /* u16 bmaControls(7) */ + U16(0x0002), /* u16 bmaControls(8) */ + STRING_FEATURE_UNIT, /* u8 iFeature */ + } + },{ + /* Headphone Ouptut Terminal ID3 Descriptor */ + .data =3D (uint8_t[]) { + 0x09, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AC_OUTPUT_TERMINAL, /* u8 bDescriptorSubtype= */ + 0x03, /* u8 bUnitID */ + U16(0x0301), /* u16 wTerminalType (SPK= ) */ + 0x00, /* u8 bAssocTerminal */ + 0x02, /* u8 bSourceID */ + STRING_OUTPUT_TERMINAL, /* u8 iTerminal */ + } + } + }, + },{ + .bInterfaceNumber =3D 1, + .bAlternateSetting =3D ALTSET_OFF, + .bNumEndpoints =3D 0, + .bInterfaceClass =3D USB_CLASS_AUDIO, + .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, + .iInterface =3D STRING_NULL_STREAM, + },{ + .bInterfaceNumber =3D 1, + .bAlternateSetting =3D ALTSET_STEREO, + .bNumEndpoints =3D 1, + .bInterfaceClass =3D USB_CLASS_AUDIO, + .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, + .iInterface =3D STRING_REAL_STREAM, + .ndesc =3D 2, + .descs =3D (USBDescOther[]) { + { + /* Headphone Class-specific AS General Interface Descripto= r */ + .data =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_GENERAL, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bTerminalLink */ + 0x00, /* u8 bDelay */ + 0x01, 0x00, /* u16 wFormatTag */ + } + },{ + /* Headphone Type I Format Type Descriptor */ + .data =3D (uint8_t[]) { + 0x0b, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_FORMAT_TYPE, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bFormatType */ + 0x02, /* u8 bNrChannels */ + 0x02, /* u8 bSubFrameSize */ + 0x10, /* u8 bBitResolution */ + 0x01, /* u8 bSamFreqType */ + U24(USBAUDIO_SAMPLE_RATE), /* u24 tSamFreq */ + } + } + }, + .eps =3D (USBDescEndpoint[]) { + { + .bEndpointAddress =3D USB_DIR_OUT | 0x01, + .bmAttributes =3D 0x0d, + .wMaxPacketSize =3D USBAUDIO_PACKET_SIZE(2), + .bInterval =3D 1, + .is_audio =3D 1, + /* Stereo Headphone Class-specific + AS Audio Data Endpoint Descriptor */ + .extra =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_ENDPOINT, /* u8 bDescriptorType */ + DST_EP_GENERAL, /* u8 bDescriptorSubtype= */ + 0x00, /* u8 bmAttributes */ + 0x00, /* u8 bLockDelayUnits */ + U16(0x0000), /* u16 wLockDelay */ + }, + }, + } + },{ + .bInterfaceNumber =3D 1, + .bAlternateSetting =3D ALTSET_51, + .bNumEndpoints =3D 1, + .bInterfaceClass =3D USB_CLASS_AUDIO, + .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, + .iInterface =3D STRING_REAL_STREAM, + .ndesc =3D 2, + .descs =3D (USBDescOther[]) { + { + /* Headphone Class-specific AS General Interface Descripto= r */ + .data =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_GENERAL, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bTerminalLink */ + 0x00, /* u8 bDelay */ + 0x01, 0x00, /* u16 wFormatTag */ + } + },{ + /* Headphone Type I Format Type Descriptor */ + .data =3D (uint8_t[]) { + 0x0b, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_FORMAT_TYPE, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bFormatType */ + 0x06, /* u8 bNrChannels */ + 0x02, /* u8 bSubFrameSize */ + 0x10, /* u8 bBitResolution */ + 0x01, /* u8 bSamFreqType */ + U24(USBAUDIO_SAMPLE_RATE), /* u24 tSamFreq */ + } + } + }, + .eps =3D (USBDescEndpoint[]) { + { + .bEndpointAddress =3D USB_DIR_OUT | 0x01, + .bmAttributes =3D 0x0d, + .wMaxPacketSize =3D USBAUDIO_PACKET_SIZE(6), + .bInterval =3D 1, + .is_audio =3D 1, + /* Stereo Headphone Class-specific + AS Audio Data Endpoint Descriptor */ + .extra =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_ENDPOINT, /* u8 bDescriptorType */ + DST_EP_GENERAL, /* u8 bDescriptorSubtype= */ + 0x00, /* u8 bmAttributes */ + 0x00, /* u8 bLockDelayUnits */ + U16(0x0000), /* u16 wLockDelay */ + }, + }, + } + },{ + .bInterfaceNumber =3D 1, + .bAlternateSetting =3D ALTSET_71, + .bNumEndpoints =3D 1, + .bInterfaceClass =3D USB_CLASS_AUDIO, + .bInterfaceSubClass =3D USB_SUBCLASS_AUDIO_STREAMING, + .iInterface =3D STRING_REAL_STREAM, + .ndesc =3D 2, + .descs =3D (USBDescOther[]) { + { + /* Headphone Class-specific AS General Interface Descripto= r */ + .data =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_GENERAL, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bTerminalLink */ + 0x00, /* u8 bDelay */ + 0x01, 0x00, /* u16 wFormatTag */ + } + },{ + /* Headphone Type I Format Type Descriptor */ + .data =3D (uint8_t[]) { + 0x0b, /* u8 bLength */ + USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ + DST_AS_FORMAT_TYPE, /* u8 bDescriptorSubtype= */ + 0x01, /* u8 bFormatType */ + 0x08, /* u8 bNrChannels */ + 0x02, /* u8 bSubFrameSize */ + 0x10, /* u8 bBitResolution */ + 0x01, /* u8 bSamFreqType */ + U24(USBAUDIO_SAMPLE_RATE), /* u24 tSamFreq */ + } + } + }, + .eps =3D (USBDescEndpoint[]) { + { + .bEndpointAddress =3D USB_DIR_OUT | 0x01, + .bmAttributes =3D 0x0d, + .wMaxPacketSize =3D USBAUDIO_PACKET_SIZE(8), + .bInterval =3D 1, + .is_audio =3D 1, + /* Stereo Headphone Class-specific + AS Audio Data Endpoint Descriptor */ + .extra =3D (uint8_t[]) { + 0x07, /* u8 bLength */ + USB_DT_CS_ENDPOINT, /* u8 bDescriptorType */ + DST_EP_GENERAL, /* u8 bDescriptorSubtype= */ + 0x00, /* u8 bmAttributes */ + 0x00, /* u8 bLockDelayUnits */ + U16(0x0000), /* u16 wLockDelay */ + }, + }, + } + } +}; + +static const USBDescDevice desc_device_multi =3D { + .bcdUSB =3D 0x0100, + .bMaxPacketSize0 =3D 64, + .bNumConfigurations =3D 1, + .confs =3D (USBDescConfig[]) { + { + .bNumInterfaces =3D 2, + .bConfigurationValue =3D DEV_CONFIG_VALUE, + .iConfiguration =3D STRING_CONFIG, + .bmAttributes =3D USB_CFG_ATT_ONE | USB_CFG_ATT_SELFP= OWER, + .bMaxPower =3D 0x32, + .nif =3D ARRAY_SIZE(desc_iface_multi), + .ifs =3D desc_iface_multi, + } + }, +}; + +static const USBDesc desc_audio_multi =3D { + .id =3D { + .idVendor =3D USBAUDIO_VENDOR_NUM, + .idProduct =3D USBAUDIO_PRODUCT_NUM, + .bcdDevice =3D 0, + .iManufacturer =3D STRING_MANUFACTURER, + .iProduct =3D STRING_PRODUCT, + .iSerialNumber =3D STRING_SERIALNUMBER, + }, + .full =3D &desc_device_multi, + .str =3D usb_audio_stringtable, }; =20 /* @@ -300,10 +583,11 @@ struct streambuf { uint32_t cons; }; =20 -static void streambuf_init(struct streambuf *buf, uint32_t size) +static void streambuf_init(struct streambuf *buf, uint32_t size, + uint32_t channels) { g_free(buf->data); - buf->size =3D size - (size % USBAUDIO_PACKET_SIZE); + buf->size =3D size - (size % USBAUDIO_PACKET_SIZE(channels)); buf->data =3D g_malloc(buf->size); buf->prod =3D 0; buf->cons =3D 0; @@ -315,21 +599,21 @@ static void streambuf_fini(struct streambuf *buf) buf->data =3D NULL; } =20 -static int streambuf_put(struct streambuf *buf, USBPacket *p) +static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t cha= nnels) { uint32_t free =3D buf->size - (buf->prod - buf->cons); =20 - if (free < USBAUDIO_PACKET_SIZE) { + if (free < USBAUDIO_PACKET_SIZE(channels)) { return 0; } - if (p->iov.size !=3D USBAUDIO_PACKET_SIZE) { + if (p->iov.size !=3D USBAUDIO_PACKET_SIZE(channels)) { return 0; } =20 usb_packet_copy(p, buf->data + (buf->prod % buf->size), - USBAUDIO_PACKET_SIZE); - buf->prod +=3D USBAUDIO_PACKET_SIZE; - return USBAUDIO_PACKET_SIZE; + USBAUDIO_PACKET_SIZE(channels)); + buf->prod +=3D USBAUDIO_PACKET_SIZE(channels); + return USBAUDIO_PACKET_SIZE(channels); } =20 static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) @@ -357,14 +641,15 @@ typedef struct USBAudioState { enum usb_audio_altset altset; struct audsettings as; SWVoiceOut *voice; - bool mute; - uint8_t vol[2]; + Volume vol; struct streambuf buf; + uint32_t channels; } out; =20 /* properties */ uint32_t debug; - uint32_t buffer; + uint32_t buffer_user, buffer; + bool multi; } USBAudioState; =20 #define TYPE_USB_AUDIO "usb-audio" @@ -397,10 +682,15 @@ static int usb_audio_set_output_altset(USBAudioState = *s, int altset) { switch (altset) { case ALTSET_OFF: - streambuf_init(&s->out.buf, s->buffer); AUD_set_active_out(s->out.voice, false); break; - case ALTSET_ON: + case ALTSET_STEREO: + case ALTSET_51: + case ALTSET_71: + if (s->out.channels !=3D altset_channels[altset]) { + usb_audio_reinit(USB_DEVICE(s), altset_channels[altset]); + } + streambuf_init(&s->out.buf, s->buffer, s->out.channels); AUD_set_active_out(s->out.voice, true); break; default: @@ -431,33 +721,33 @@ static int usb_audio_get_control(USBAudioState *s, ui= nt8_t attrib, =20 switch (aid) { case ATTRIB_ID(MUTE_CONTROL, CR_GET_CUR, 0x0200): - data[0] =3D s->out.mute; + data[0] =3D s->out.vol.mute; ret =3D 1; break; case ATTRIB_ID(VOLUME_CONTROL, CR_GET_CUR, 0x0200): - if (cn < 2) { - uint16_t vol =3D (s->out.vol[cn] * 0x8800 + 127) / 255 + 0x800= 0; + if (cn < USBAUDIO_MAX_CHANNELS(s)) { + uint16_t vol =3D (s->out.vol.vol[cn] * 0x8800 + 127) / 255 + 0= x8000; data[0] =3D vol; data[1] =3D vol >> 8; ret =3D 2; } break; case ATTRIB_ID(VOLUME_CONTROL, CR_GET_MIN, 0x0200): - if (cn < 2) { + if (cn < USBAUDIO_MAX_CHANNELS(s)) { data[0] =3D 0x01; data[1] =3D 0x80; ret =3D 2; } break; case ATTRIB_ID(VOLUME_CONTROL, CR_GET_MAX, 0x0200): - if (cn < 2) { + if (cn < USBAUDIO_MAX_CHANNELS(s)) { data[0] =3D 0x00; data[1] =3D 0x08; ret =3D 2; } break; case ATTRIB_ID(VOLUME_CONTROL, CR_GET_RES, 0x0200): - if (cn < 2) { + if (cn < USBAUDIO_MAX_CHANNELS(s)) { data[0] =3D 0x88; data[1] =3D 0x00; ret =3D 2; @@ -479,16 +769,17 @@ static int usb_audio_set_control(USBAudioState *s, ui= nt8_t attrib, =20 switch (aid) { case ATTRIB_ID(MUTE_CONTROL, CR_SET_CUR, 0x0200): - s->out.mute =3D data[0] & 1; + s->out.vol.mute =3D data[0] & 1; set_vol =3D true; ret =3D 0; break; case ATTRIB_ID(VOLUME_CONTROL, CR_SET_CUR, 0x0200): - if (cn < 2) { + if (cn < USBAUDIO_MAX_CHANNELS(s)) { uint16_t vol =3D data[0] + (data[1] << 8); =20 if (s->debug) { - fprintf(stderr, "usb-audio: vol %04x\n", (uint16_t)vol); + fprintf(stderr, "usb-audio: cn %d vol %04x\n", cn, + (uint16_t)vol); } =20 vol -=3D 0x8000; @@ -497,7 +788,7 @@ static int usb_audio_set_control(USBAudioState *s, uint= 8_t attrib, vol =3D 255; } =20 - s->out.vol[cn] =3D vol; + s->out.vol.vol[cn] =3D vol; set_vol =3D true; ret =3D 0; } @@ -506,11 +797,14 @@ static int usb_audio_set_control(USBAudioState *s, ui= nt8_t attrib, =20 if (set_vol) { if (s->debug) { - fprintf(stderr, "usb-audio: mute %d, lvol %3d, rvol %3d\n", - s->out.mute, s->out.vol[0], s->out.vol[1]); + int i; + fprintf(stderr, "usb-audio: mute %d", s->out.vol.mute); + for (i =3D 0; i < USBAUDIO_MAX_CHANNELS(s); ++i) { + fprintf(stderr, ", vol[%d] %3d", i, s->out.vol.vol[i]); + } + fprintf(stderr, "\n"); } - AUD_set_volume_out(s->out.voice, s->out.mute, - s->out.vol[0], s->out.vol[1]); + audio_set_volume_out(s->out.voice, &s->out.vol); } =20 return ret; @@ -603,7 +897,7 @@ static void usb_audio_handle_dataout(USBAudioState *s, = USBPacket *p) return; } =20 - streambuf_put(&s->out.buf, p); + streambuf_put(&s->out.buf, p, s->out.channels); if (p->actual_length < p->iov.size && s->debug > 1) { fprintf(stderr, "usb-audio: output overrun (%zd bytes)\n", p->iov.size - p->actual_length); @@ -645,6 +939,9 @@ static void usb_audio_unrealize(USBDevice *dev, Error *= *errp) static void usb_audio_realize(USBDevice *dev, Error **errp) { USBAudioState *s =3D USB_AUDIO(dev); + int i; + + dev->usb_desc =3D s->multi ? &desc_audio_multi : &desc_audio; =20 usb_desc_create_serial(dev); usb_desc_init(dev); @@ -652,18 +949,35 @@ static void usb_audio_realize(USBDevice *dev, Error *= *errp) AUD_register_card(TYPE_USB_AUDIO, &s->card); =20 s->out.altset =3D ALTSET_OFF; - s->out.mute =3D false; - s->out.vol[0] =3D 240; /* 0 dB */ - s->out.vol[1] =3D 240; /* 0 dB */ + s->out.vol.mute =3D false; + for (i =3D 0; i < USBAUDIO_MAX_CHANNELS(s); ++i) { + s->out.vol.vol[i] =3D 240; /* 0 dB */ + } + + usb_audio_reinit(dev, 2); +} + +static void usb_audio_reinit(USBDevice *dev, unsigned channels) +{ + USBAudioState *s =3D USB_AUDIO(dev); + + s->out.channels =3D channels; + if (!s->buffer_user) { + s->buffer =3D 32 * USBAUDIO_PACKET_SIZE(s->out.channels); + } else { + s->buffer =3D s->buffer_user; + } + + s->out.vol.channels =3D s->out.channels; s->out.as.freq =3D USBAUDIO_SAMPLE_RATE; - s->out.as.nchannels =3D 2; + s->out.as.nchannels =3D s->out.channels; s->out.as.fmt =3D AUDIO_FORMAT_S16; s->out.as.endianness =3D 0; - streambuf_init(&s->out.buf, s->buffer); + streambuf_init(&s->out.buf, s->buffer, s->out.channels); =20 s->out.voice =3D AUD_open_out(&s->card, s->out.voice, TYPE_USB_AUDIO, s, output_callback, &s->out.as); - AUD_set_volume_out(s->out.voice, s->out.mute, s->out.vol[0], s->out.vo= l[1]); + audio_set_volume_out(s->out.voice, &s->out.vol); AUD_set_active_out(s->out.voice, 0); } =20 @@ -675,8 +989,8 @@ static const VMStateDescription vmstate_usb_audio =3D { static Property usb_audio_properties[] =3D { DEFINE_AUDIO_PROPERTIES(USBAudioState, card), DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0), - DEFINE_PROP_UINT32("buffer", USBAudioState, buffer, - 32 * USBAUDIO_PACKET_SIZE), + DEFINE_PROP_UINT32("buffer", USBAudioState, buffer_user, 0), + DEFINE_PROP_BOOL("multi", USBAudioState, multi, false), DEFINE_PROP_END_OF_LIST(), }; =20 @@ -689,7 +1003,6 @@ static void usb_audio_class_init(ObjectClass *klass, v= oid *data) dc->props =3D usb_audio_properties; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); k->product_desc =3D "QEMU USB Audio Interface"; - k->usb_desc =3D &desc_audio; k->realize =3D usb_audio_realize; k->handle_reset =3D usb_audio_handle_reset; k->handle_control =3D usb_audio_handle_control; --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997152; cv=none; d=zoho.com; s=zohoarc; b=Nh/864zD0YTz7MxXwCZAjVnX2SWLVlN3AyM3C1A3PQXJ4USAwynoPn4jvz1nsv382yuEDg5TIGqPvSxLj6HWeT2YE9UrAsXqjTdbuhQdwrM00N7LACnZ4SVDFe6/XHoRPccuUYV1wiU9Qns8HISCSUYVEantfU5XqWDErOrxXKE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997152; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=csUz3G+oANfAghQDvskgbpzawb3MHELRqPU8L59Mp1o=; b=Q71u+EfVS/k+Fk22yqnDG5eZYXT7XgPyv1cax0MhHsUtgNZgrTPBbf9+RySptdx2xs3adKybMCbXp9BAPzjDK8xKq3LZc3Qqv2d2ZXHN8ykNknpNETDfb27PKWnPcb+wgk+TIrtkW94DKCxX0EeslEYiP0XzBBOBPBA6l69evgY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1570997152656992.1606878761804; Sun, 13 Oct 2019 13:05:52 -0700 (PDT) Received: from localhost ([::1]:42040 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk7g-00037a-RQ for importer@patchew.org; Sun, 13 Oct 2019 16:05:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37303) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0P-0005WL-NR for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0O-0003Kk-HZ for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:17 -0400 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:36259) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0O-0003Jj-Bg for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:16 -0400 Received: by mail-wr1-x444.google.com with SMTP id y19so17263611wrd.3 for ; Sun, 13 Oct 2019 12:58:16 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=csUz3G+oANfAghQDvskgbpzawb3MHELRqPU8L59Mp1o=; b=Yi0EIOp+W2VbjGAlZL5lS6f+iUizXeLfTrpgMXCWZdyqW6va867y6ITHu1sx+RO74a JyYp8WhoZ31zGaLiY4Z8RT2gQagCYu9Pa/qu34qnoXlqP1d4L6ANVS5yNNdpa0v5d4We VqNZW1YYKAPIbvDgXW7iFaS1JlokPqZLUgDSJ2s7XTAH9pd7t+VCjyHsZTjuzoqZ1t71 L7ePEUZ8vNA3eUtJfrIv7SuBWzOwjTobL4LXb7Tnl6z2Zrd9+JxIbkC3zG1mRiPDqMAg 5vHMy1bX6uNispzjP4kVwO7XfznunHch4RpJMGbPvCUAd66FAEws39bhmUKYeoYmKJYg lPug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=csUz3G+oANfAghQDvskgbpzawb3MHELRqPU8L59Mp1o=; b=tYW5dsLPKZJO4ntUFV1WsTCT5A37GSmE+jMj+uW6ifNHFGpeEtSuah+e3qMJy9mahf 2qIWZfn+Q+6VCZ8fSWYWpwr4P/rORJYAyQ8CdGIPB2uimiyX0Gt8VYJQHQykcY/3WU8K 7qW2zNTF2VANSRt+O94fsBW0a6JNPed72byvEWnt2Jq8mtJYRWkeKrMosmdeccTD5yLD NF7qDczyxFrP+cVI9lIfJDk4HqQOKd5i05IQb140RJYifbQ68CoC4C4MzAUR7DYW7oj0 imXMzjODZq7mByLBT3lJZkOdf+4Sk0hFekZEjStxnbj4kLFvMFbw9y8Fv6dBrhikQQmw Niww== X-Gm-Message-State: APjAAAVcTD88G3FlWRktAhRQUTdJRhzubeN1GhIZZ9SN/xoJC1O8vZet G4OSxv3ZGsqDuPNehJn+DmviNHgB X-Google-Smtp-Source: APXvYqxAaRjfAcjAiLZ0hDfCoX7klP8WJQk2+2vFf4dNWuj4IpNVkSFkHVw8vUQRGxISKz+IUL75hg== X-Received: by 2002:a5d:6a49:: with SMTP id t9mr21131198wrw.58.1570996695338; Sun, 13 Oct 2019 12:58:15 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 09/10] usbaudio: change playback counters to 64 bit Date: Sun, 13 Oct 2019 21:58:06 +0200 Message-Id: X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) With stereo playback, they need about 375 minutes of continuous audio playback to overflow, which is usually not a problem (as stopping and later resuming playback resets the counters). But with 7.1 audio, they only need about 95 minutes to overflow. After the overflow, the buf->prod % USBAUDIO_PACKET_SIZE(channels) assertion no longer holds true, which will result in overflowing the buffer. With 64 bit variables, it would take about 762000 years to overflow. Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- hw/usb/dev-audio.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index e42bdfbdc1..ea604bbb8e 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -578,9 +578,9 @@ static const USBDesc desc_audio_multi =3D { =20 struct streambuf { uint8_t *data; - uint32_t size; - uint32_t prod; - uint32_t cons; + size_t size; + uint64_t prod; + uint64_t cons; }; =20 static void streambuf_init(struct streambuf *buf, uint32_t size, @@ -601,7 +601,7 @@ static void streambuf_fini(struct streambuf *buf) =20 static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t cha= nnels) { - uint32_t free =3D buf->size - (buf->prod - buf->cons); + int64_t free =3D buf->size - (buf->prod - buf->cons); =20 if (free < USBAUDIO_PACKET_SIZE(channels)) { return 0; @@ -610,6 +610,8 @@ static int streambuf_put(struct streambuf *buf, USBPack= et *p, uint32_t channels) return 0; } =20 + /* can happen if prod overflows */ + assert(buf->prod % USBAUDIO_PACKET_SIZE(channels) =3D=3D 0); usb_packet_copy(p, buf->data + (buf->prod % buf->size), USBAUDIO_PACKET_SIZE(channels)); buf->prod +=3D USBAUDIO_PACKET_SIZE(channels); @@ -618,10 +620,10 @@ static int streambuf_put(struct streambuf *buf, USBPa= cket *p, uint32_t channels) =20 static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) { - uint32_t used =3D buf->prod - buf->cons; + int64_t used =3D buf->prod - buf->cons; uint8_t *data; =20 - if (!used) { + if (used <=3D 0) { *len =3D 0; return NULL; } --=20 2.23.0 From nobody Tue Apr 30 02:43:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1570997305; cv=none; d=zoho.com; s=zohoarc; b=eBJGjzT/Is4KOh2UMPsZcRF/2osvSRzmuJ5VAdXZyyMcmzhZZpyvZt6h2cTq9btkrjDEvsn10J0gTHvlzO6LJB+2Dfsk/avzu2xSYWGl9dX80wJwAQfOuAcXPAmGK4G1PwXCxhSbGwLVOxEt5yayTNLR15QbaNSkM4KCH0RfQgo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570997305; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9lJbQYocXSR3LzW21RYjme2hTgIUpvB0ikUNj0SmxGA=; b=VERvCenwAGB9r1e9Wf6o2YtuG5E3yON5ezZb9mzIA6KZ4ol0I28BUBdcEF9FHT9aUtRC/jtZubOFVPs86JClgg7aaEtJa1jxPRnfFH/lXwNY+MxzlEZ0nDtsMpzsD5CaIcyNHfJuvTKoVAN+ipRcmkr64wTdDTThRfplN8qhiiU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157099730565072.74183753575358; Sun, 13 Oct 2019 13:08:25 -0700 (PDT) Received: from localhost ([::1]:42068 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJkAC-0006uu-Jm for importer@patchew.org; Sun, 13 Oct 2019 16:08:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37312) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iJk0Q-0005Xd-A6 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iJk0P-0003Lh-49 for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:18 -0400 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:45798) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iJk0O-0003KX-UO for qemu-devel@nongnu.org; Sun, 13 Oct 2019 15:58:17 -0400 Received: by mail-wr1-x441.google.com with SMTP id r5so17198619wrm.12 for ; Sun, 13 Oct 2019 12:58:16 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-0052-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:52::5]) by smtp.gmail.com with ESMTPSA id x129sm29941857wmg.8.2019.10.13.12.58.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 12:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9lJbQYocXSR3LzW21RYjme2hTgIUpvB0ikUNj0SmxGA=; b=DjbRjquZ0ds8nxZcqtmlxMqFs1xiWcRKq3mgn2DrkKUy7rpoR/Noka6PjcoJlygBdi +G1frdLT158/qpHMJgay/lz0J7oXDY8lFQ8cCbOXF2y7cX3kLObpKIbko9DbGTYUeqZc sbI+IOdSvXZDchMwNKBx9/fB62rSoX+yn6EbgarzrDElgA7/bgv2BRyXs1VC2x8R4ywc na/23Vi9/gdT0OaXF/iNZkD7HEykrP1YeDyUFyoyAoWWP4orDR/O0Sw+EjQEGz6ofLfX uQ0tVchsMhrrgBuDt0IGmNqSa7sflfL3C/TnSOHLLZZl5oMA1gu1r0HMaB5Hp3yKfhP/ G7fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9lJbQYocXSR3LzW21RYjme2hTgIUpvB0ikUNj0SmxGA=; b=BpD7ytFO7+YUg45Oey4+Yku+GJGWvU6tpBn9IQ6zk9VeXLIa8KV3ZcmOLhY6486W3b gzIjklMGDj5k9RvsXKsaQNwKYAsrJNKFUW3Rjz8hwXB4apyq8J78eQCXC7HuagajJR6p PEqClyPvtYml1rl1FplGwpXKFEPVl79PGV7FzXbEkJlkqo9OhPGal0SlxonhDj45YMUB Rpw1HbBFjXTjnx9ASs3xQIEe0uSjse1y8ucDm56xJ8zzJtaP7sPAf0pF1Z+UqsdPbReP fFUsV43iYSVhUI9dwPXdTDyw1xdWBsJefMXlOotDobPSa3QVnSWm+8bRrbHTuho6H17F 81wQ== X-Gm-Message-State: APjAAAVSZCsJXq338KaPA7lFelIMkdBctLfBirlMvnKGDNS1Rn1cUK75 clrgV8P7ta09iRR8yxj613A8Qy5b X-Google-Smtp-Source: APXvYqyOz0CBXAYZT/dPe+20V5grppwrurzAKFd+NVGj1yQf4iCbgOCtK49HxRomohE+eN+zwaPhHg== X-Received: by 2002:a5d:4ed2:: with SMTP id s18mr22015510wrv.52.1570996695891; Sun, 13 Oct 2019 12:58:15 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Subject: [PATCH v6 10/10] paaudio: fix channel order for usb-audio 5.1 and 7.1 streams Date: Sun, 13 Oct 2019 21:58:07 +0200 Message-Id: <2900e462d27bd73277ae083d037c32b1b4451ee2.1570996490.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) Signed-off-by: K=C5=91v=C3=A1g=C3=B3, Zolt=C3=A1n --- audio/paaudio.c | 50 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/audio/paaudio.c b/audio/paaudio.c index d195b1caa8..6ff0d17537 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -338,17 +338,59 @@ static pa_stream *qpa_simple_new ( pa_stream_direction_t dir, const char *dev, const pa_sample_spec *ss, - const pa_channel_map *map, const pa_buffer_attr *attr, int *rerror) { int r; - pa_stream *stream; + pa_stream *stream =3D NULL; pa_stream_flags_t flags; + pa_channel_map map; =20 pa_threaded_mainloop_lock(c->mainloop); =20 - stream =3D pa_stream_new(c->context, name, ss, map); + pa_channel_map_init(&map); + map.channels =3D ss->channels; + + /* + * TODO: This currently expects the only frontend supporting more than= 2 + * channels is the usb-audio. We will need some means to set channel + * order when a new frontend gains multi-channel support. + */ + switch (ss->channels) { + case 1: + map.map[0] =3D PA_CHANNEL_POSITION_MONO; + break; + + case 2: + map.map[0] =3D PA_CHANNEL_POSITION_LEFT; + map.map[1] =3D PA_CHANNEL_POSITION_RIGHT; + break; + + case 6: + map.map[0] =3D PA_CHANNEL_POSITION_FRONT_LEFT; + map.map[1] =3D PA_CHANNEL_POSITION_FRONT_RIGHT; + map.map[2] =3D PA_CHANNEL_POSITION_CENTER; + map.map[3] =3D PA_CHANNEL_POSITION_LFE; + map.map[4] =3D PA_CHANNEL_POSITION_REAR_LEFT; + map.map[5] =3D PA_CHANNEL_POSITION_REAR_RIGHT; + break; + + case 8: + map.map[0] =3D PA_CHANNEL_POSITION_FRONT_LEFT; + map.map[1] =3D PA_CHANNEL_POSITION_FRONT_RIGHT; + map.map[2] =3D PA_CHANNEL_POSITION_CENTER; + map.map[3] =3D PA_CHANNEL_POSITION_LFE; + map.map[4] =3D PA_CHANNEL_POSITION_REAR_LEFT; + map.map[5] =3D PA_CHANNEL_POSITION_REAR_RIGHT; + map.map[6] =3D PA_CHANNEL_POSITION_SIDE_LEFT; + map.map[7] =3D PA_CHANNEL_POSITION_SIDE_RIGHT; + + default: + dolog("Internal error: unsupported channel count %d\n", ss->channe= ls); + goto fail; + } + + stream =3D pa_stream_new(c->context, name, ss, &map); if (!stream) { goto fail; } @@ -421,7 +463,6 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsetti= ngs *as, PA_STREAM_PLAYBACK, ppdo->has_name ? ppdo->name : NULL, &ss, - NULL, /* channel map */ &ba, /* buffering attributes */ &error ); @@ -470,7 +511,6 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsetting= s *as, void *drv_opaque) PA_STREAM_RECORD, ppdo->has_name ? ppdo->name : NULL, &ss, - NULL, /* channel map */ &ba, /* buffering attributes */ &error ); --=20 2.23.0