From patchwork Wed Jan 16 23:36:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767107 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4FFB414E5 for ; Wed, 16 Jan 2019 23:39:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3F7DB2EC77 for ; Wed, 16 Jan 2019 23:39:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 313712EC94; Wed, 16 Jan 2019 23:39:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 70F862EC77 for ; Wed, 16 Jan 2019 23:39:30 +0000 (UTC) Received: from localhost ([127.0.0.1]:59801 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjumP-0005cp-O5 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:39:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukj-00042P-7b for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukf-0002nY-D2 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:38058) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukd-0002Zc-HY for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:41 -0500 Received: by mail-wr1-x444.google.com with SMTP id v13so8965029wrw.5 for ; Wed, 16 Jan 2019 15:37:27 -0800 (PST) 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=FDB/hWwJr0F3fHBv+QJQDk1NqMyj+yM0hRTu3qS/kxY=; b=kMEcjWkhlqOVII+rRm5uSuwznFl6RN1kXjSESF7cVH+JeE7UpGIcCRF4w5EDZUTf4D bjOZUHDCY5UrEYKhJWHtEav0OvuKustZsLFgm0l07fwSAft69n9pEw8ggZKkKZwQpHkp JlsYlWj0n/VqBrRGu+V6nhHoajEYIMxLP6dPR0nETx8ehOZp8rhN8wKl1eLBxP0dkOIk 7Mq5reCJspn3ZENthoa4tEBNMA/R5ZdqSFzRpmNAdj2Fbp9/2xG2ja/juD66F89u6sN6 es5hwYjk/n3UCmUQcD6/jGaIce78reWl4Jsr5g/1cTyY1tHTxg7M4P/yBaYfq0UFbBpd vSfw== 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=FDB/hWwJr0F3fHBv+QJQDk1NqMyj+yM0hRTu3qS/kxY=; b=mQFwF7pFffn0KjT5cXb9GDjGX+v18xc2S/yZcx8we1mbt5xfJUDtu0l4WhooejMQwH tlweagQ3KqHV7kTzQbfM4LLBnMTdgmB6IetqmhDYF/0nUY6PHHMnVmpneEzHvPQEu/Vt r5kUCGwZVmP+Xmrxt32SPgS5XBUyXn/CIhSC5kYn9H7PjIgo/b8098Ne0L9svk//0+KG M7CF0+idjGc1BfQm6XB3X9NMLzwDmGXKBys2UqUdak+fs8M6I7X5cqjpS8WZ0Xc83UON T/lQHM0SqQERhu+jfKzskFzi8It5IKSd36BWt+gRfZnMnunEB4/ifGyAIoELQKjs19le 4rmQ== X-Gm-Message-State: AJcUukey9mNrCW/nkPzswFVCa1t8WT2YSeApH0e6364oCcDSAKcViCBW NKIbgK19kyNt2L/dGszSF1wLHzB3 X-Google-Smtp-Source: ALg8bN4yjjt7Ee7BDBl3ZoPqG+PNMd0Tc1ZG3cFf6yFcUxSUDV7ASW+3S7YkGOamx1qZlpiL16oXaw== X-Received: by 2002:adf:9361:: with SMTP id 88mr9221457wro.204.1547681845815; Wed, 16 Jan 2019 15:37:25 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:25 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:34 +0100 Message-Id: <0d2685bb2c3f9a7182aa99b8218f3e4bb223522d.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 01/50] qapi: qapi for audio backends X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann , Markus Armbruster Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds structures into qapi to replace the existing configuration structures used by audio backends currently. This qapi will be the base of the -audiodev command line parameter (that replaces the old environment variables based config). This is not a 1:1 translation of the old options, I've tried to make them much more consistent (e.g. almost every backend had an option to specify buffer size, but the name was different for every backend, and some backends required usecs, while some other required frames, samples or bytes). Also tried to reduce the number of abbreviations used by the config keys. Some of the more important changes: * use `in` and `out` instead of `ADC` and `DAC`, as the former is more user friendly imho * moved buffer settings into the global setting area (so it's the same for all backends that support it. Backends that can't change buffer size will simply ignore them). Also using usecs, as it's probably more user friendly than samples or bytes. * try-poll is now an alsa backend specific option (as all other backends currently ignore it) Signed-off-by: Kővágó, Zoltán --- Notes: Changes from v2: * update copyright, version numbers * remove #optional * per-direction options are now optional (needed for qobject_object_visitor_new_str) * removed unnecessary AudiodevNoOptions * changed integers to unsigned Makefile.objs | 6 +- qapi/audio.json | 233 ++++++++++++++++++++++++++++++++++++++++++ qapi/qapi-schema.json | 1 + 3 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 qapi/audio.json diff --git a/Makefile.objs b/Makefile.objs index 456115992a..e830cdbafc 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -1,6 +1,6 @@ -QAPI_MODULES = block-core block char common crypto introspect job migration -QAPI_MODULES += misc net rdma rocker run-state sockets tpm trace transaction -QAPI_MODULES += ui +QAPI_MODULES = audio block-core block char common crypto introspect job +QAPI_MODULES += migration misc net rdma rocker run-state sockets tpm trace +QAPI_MODULES += transaction ui ####################################################################### # Common libraries for tools and emulators diff --git a/qapi/audio.json b/qapi/audio.json new file mode 100644 index 0000000000..bd6e2494bd --- /dev/null +++ b/qapi/audio.json @@ -0,0 +1,233 @@ +# -*- mode: python -*- +# +# Copyright (C) 2015-2019 Zoltán Kővágó +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# @AudiodevAlsaPerDirectionOptions: +# +# Options of the alsa backend that are used for both playback and recording. +# +# @dev: the name of the alsa device to use (default 'default') +# +# @try-poll: attempt to use poll mode, falling back to non polling access on +# failure (default on) +# +# Since: 4.0 +## +{ 'struct': 'AudiodevAlsaPerDirectionOptions', + 'data': { + '*dev': 'str', + '*try-poll': 'bool' } } + +## +# @AudiodevAlsaOptions: +# +# Options of the alsa audio backend. +# +# @alsa-in: options of the capture stream +# +# @alsa-out: options of the playback stream +# +# @threshold: set the threshold (in microseconds) when playback starts +# +# Since: 4.0 +## +{ 'struct': 'AudiodevAlsaOptions', + 'data': { + '*alsa-in': 'AudiodevAlsaPerDirectionOptions', + '*alsa-out': 'AudiodevAlsaPerDirectionOptions', + '*threshold': 'uint32' } } + +## +# @AudiodevDsoundOptions: +# +# Options of the dsound audio backend. +# +# @latency: add extra latency to playback in microseconds (default 10000) +# +# Since: 4.0 +## +{ 'struct': 'AudiodevDsoundOptions', + 'data': { + '*latency': 'uint32' } } + +## +# @AudiodevOssPerDirectionOptions: +# +# Options of the oss backend that are used for both playback and recording. +# +# @dev: file name of the oss device (default '/dev/dsp') +# +# @try-poll: attempt to use poll mode, falling back to non polling access on +# failure (default on) +# +# Since: 4.0 +## +{ 'struct': 'AudiodevOssPerDirectionOptions', + 'data': { + '*dev': 'str', + '*try-poll': 'bool' } } + +## +# @AudiodevOssOptions: +# +# Options of the oss audio backend. +# +# @oss-in: options of the capture stream +# +# @oss-out: options of the playback stream +# +# @try-mmap: try using memory mapped access, falling back to non +# memory mapped access on failure (default off) +# +# @exclusive: open device in exclusive mode (vmix won't work) (default off) +# +# @dsp-policy: set the timing policy of the device (between 0 and 10, where +# smaller number means smaller latency but higher CPU usage) or -1 +# to use fragment mode (option ignored on some platforms) +# (default 5) +# +# Since: 4.0 +## +{ 'struct': 'AudiodevOssOptions', + 'data': { + '*oss-in': 'AudiodevOssPerDirectionOptions', + '*oss-out': 'AudiodevOssPerDirectionOptions', + '*try-mmap': 'bool', + '*exclusive': 'bool', + '*dsp-policy': 'uint32' } } + +## +# @AudiodevPaPerDirectionOptions: +# +# Options of the pa backend that are used for both playback and recording. +# +# @name: name of the sink/source to use +# +# Since: 4.0 +## +{ 'struct': 'AudiodevPaPerDirectionOptions', + 'data': { + '*name': 'str' } } + +## +# @AudiodevPaOptions: +# +# Options of the pa (PulseAudio) audio backend. +# +# @server: PulseAudio server address (default: let PulseAudio choose) +# +# @sink: name of the sink to use +# +# @source: name of the source to use +# +# Since: 4.0 +## +{ 'struct': 'AudiodevPaOptions', + 'data': { + '*server': 'str', + '*sink': 'AudiodevPaPerDirectionOptions', + '*source': 'AudiodevPaPerDirectionOptions' } } + +## +# @AudiodevWavOptions: +# +# Options of the wav audio backend. +# +# @path: name of the wav file to record (default 'qemu.wav') +# +# Since: 4.0 +## +{ 'struct': 'AudiodevWavOptions', + 'data': { + '*path': 'str' } } + + +## +# @AudioFormat: +# +# An enumeration of possible audio formats. +# +# Since: 4.0 +## +{ 'enum': 'AudioFormat', + 'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] } + +## +# @AudiodevDriver: +# +# An enumeration of possible audio backend drivers. +# +# Since: 4.0 +## +{ 'enum': 'AudiodevDriver', + 'data': [ 'none', 'alsa', 'coreaudio', 'dsound', 'oss', 'pa', 'sdl', 'spice', + 'wav' ] } + +## +# @AudiodevPerDirectionOptions: +# +# General audio backend options that are used for both playback and recording. +# +# @fixed-settings: use fixed settings for host input/output. When off, +# frequency, channels and format must not be specified +# (default on) +# +# @frequency: frequency to use when using fixed settings (default 44100) +# +# @channels: number of channels when using fixed settings (default 2) +# +# @voices: number of voices to use (default 1) +# +# @format: sample format to use when using fixed settings (default s16) +# +# @buffer-len: the buffer size in microseconds +# +# @buffer-count: number of buffers +# +# Since: 4.0 +## +{ 'struct': 'AudiodevPerDirectionOptions', + 'data': { + '*fixed-settings': 'bool', + '*frequency': 'uint32', + '*channels': 'uint32', + '*voices': 'uint32', + '*format': 'AudioFormat', + '*buffer-len': 'uint32', + '*buffer-count': 'uint32' } } + +## +# @Audiodev: +# +# Options of an audio backend. +# +# @id: identifier of the backend +# +# @driver: the backend driver to use +# +# @in: options of the capture stream +# +# @out: options of the playback stream +# +# @timer-period: timer period (in microseconds, 0: use lowest possible) +# +# Since: 4.0 +## +{ 'union': 'Audiodev', + 'base': { + 'id': 'str', + 'driver': 'AudiodevDriver', + '*in': 'AudiodevPerDirectionOptions', + '*out': 'AudiodevPerDirectionOptions', + '*timer-period': 'uint32' }, + 'discriminator': 'driver', + 'data': { + 'alsa': 'AudiodevAlsaOptions', + 'dsound': 'AudiodevDsoundOptions', + 'oss': 'AudiodevOssOptions', + 'pa': 'AudiodevPaOptions', + 'wav': 'AudiodevWavOptions' } } diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 3bbdfcee84..d5f9856be7 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -95,3 +95,4 @@ { 'include': 'trace.json' } { 'include': 'introspect.json' } { 'include': 'misc.json' } +{ 'include': 'audio.json' } From patchwork Wed Jan 16 23:36:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767167 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C48836C2 for ; Wed, 16 Jan 2019 23:58:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFB212FC37 for ; Wed, 16 Jan 2019 23:58:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A2D1B2FC81; Wed, 16 Jan 2019 23:58:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AAE342FC37 for ; Wed, 16 Jan 2019 23:58:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:36370 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv4y-0003n1-UT for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:58:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58062) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukt-000495-Nj for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002ua-3I for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:54 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:34216) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002ap-Dz; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wm1-x341.google.com with SMTP id y185so2236953wmd.1; Wed, 16 Jan 2019 15:37:29 -0800 (PST) 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=RDH+NZgRRnyRdfZ9+efRl5sYXWz/AXTQrkqr/kW2eFo=; b=h49ZnjAeDOOiET+h7BPtEjugxv0KZcXBH+hlCoz7Dmf4UMh/CVupPuygbCFRYjh2Gx hgQ9AuUbknrwEWtMZL/3kkp5qxUvN7cnFRHEFwxnpLUgUtKEA0QfgIDdhBtVurSn4NPc Vb3ehtCjZWy/yMdoU+lU16873f8gfv/kFCZJRHmCrjCGy85a6Id3YfwaK6Sx9D4HmJ6q L0zYm5EWrIBp4Ta3tcVHinCB09IGQeV1tjji7AKibJTLMLzII533uk+wELkakqDndk9B iC/5V7jPwxhsQoOX0Yp68TzrGqe/YiRLuvogWOnJiznVQmM35h4i6Mhcar9Nw2lGyKIm 7gjA== 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=RDH+NZgRRnyRdfZ9+efRl5sYXWz/AXTQrkqr/kW2eFo=; b=hAalNJTGPx6EEdtk4kOJW+Im7OlvYEETJtBhhM3Y2SR31QcMUVArBBYrR65EDGrg19 WaSYfh8tuzygu8vv6tTOTwUgZ4Fd7tqUB7jiIjpvoHRqVX+wfxY99vriUvSwSwMH+1Kt 5RxZy9vx0dwZHmKz3qLiPEKq9qLLi3kiiOn0G+yE9dVNv61LpU3fYqP6yQsISnIltGuz b8LBlwmI6TsXByEdjgQ7j6M5Ov8v0antgDGNqnw8PjAADJ96mdW/v28g3d4AbJHmKXXg lbSOD0ZhpgutPzt0rJJh8VUvnwB26tH6mO4iG3lF+nVxiSDRyYmVmG3EQ5BwAY87OKY+ Qjtw== X-Gm-Message-State: AJcUukfxoNTeDFiiplJISh1R/QCV7Y12CtC0zpFDI9hZKejL/XpS/1tt VO1jbsCopPqj/v4gkWzEjt2m/y1U+Ek= X-Google-Smtp-Source: ALg8bN5TvyicAhBZ0N2MT4cbPIOwXSYcZloemDe7d2lGoIWPu8Db2Bxak/Euli/hpAUs2l2s7GdvqQ== X-Received: by 2002:a1c:aa0f:: with SMTP id t15mr9203284wme.108.1547681847208; Wed, 16 Jan 2019 15:37:27 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:26 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:35 +0100 Message-Id: <3fef4dae7ac1e3ac346ffaaff51ae64eebd8ab24.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v3 02/50] audio: use qapi AudioFormat instead of audfmt_e X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Alistair Francis , Michael Walle , "open list:ARM" , Gerd Hoffmann , "Edgar E. Iglesias" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP I had to include an enum for audio sampling formats into qapi, but that meant duplicating the audfmt_e enum. This patch replaces audfmt_e and associated values with the qapi generated AudioFormat enum. This patch is mostly a search-and-replace, except for switches where the qapi generated AUDIO_FORMAT_MAX caused problems. Signed-off-by: Kővágó, Zoltán --- audio/audio.h | 12 +---- audio/alsaaudio.c | 53 +++++++++++---------- audio/audio.c | 97 +++++++++++++++++++++------------------ audio/audio_win_int.c | 18 ++++---- audio/ossaudio.c | 30 ++++++------ audio/paaudio.c | 28 +++++------ audio/sdlaudio.c | 26 +++++------ audio/spiceaudio.c | 4 +- audio/wavaudio.c | 17 ++++--- audio/wavcapture.c | 2 +- hw/arm/omap2.c | 2 +- hw/audio/ac97.c | 2 +- hw/audio/adlib.c | 2 +- hw/audio/cs4231a.c | 6 +-- hw/audio/es1370.c | 4 +- hw/audio/gus.c | 2 +- hw/audio/hda-codec.c | 18 ++++---- hw/audio/lm4549.c | 6 +-- hw/audio/milkymist-ac97.c | 2 +- hw/audio/pcspk.c | 2 +- hw/audio/sb16.c | 14 +++--- hw/audio/wm8750.c | 6 +-- hw/display/xlnx_dp.c | 2 +- hw/input/tsc210x.c | 2 +- hw/usb/dev-audio.c | 2 +- ui/vnc.c | 26 +++++------ 26 files changed, 196 insertions(+), 189 deletions(-) diff --git a/audio/audio.h b/audio/audio.h index f4339a185e..02f29a3b3e 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -26,18 +26,10 @@ #define QEMU_AUDIO_H #include "qemu/queue.h" +#include "qapi/qapi-types-audio.h" typedef void (*audio_callback_fn) (void *opaque, int avail); -typedef enum { - AUD_FMT_U8, - AUD_FMT_S8, - AUD_FMT_U16, - AUD_FMT_S16, - AUD_FMT_U32, - AUD_FMT_S32 -} audfmt_e; - #ifdef HOST_WORDS_BIGENDIAN #define AUDIO_HOST_ENDIANNESS 1 #else @@ -47,7 +39,7 @@ typedef enum { struct audsettings { int freq; int nchannels; - audfmt_e fmt; + AudioFormat fmt; int endianness; }; diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 635be73bf4..5bd034267f 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -87,7 +87,7 @@ struct alsa_params_req { struct alsa_params_obt { int freq; - audfmt_e fmt; + AudioFormat fmt; int endianness; int nchannels; snd_pcm_uframes_t samples; @@ -294,16 +294,16 @@ static int alsa_write (SWVoiceOut *sw, void *buf, int len) return audio_pcm_sw_write (sw, buf, len); } -static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) +static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness) { switch (fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: return SND_PCM_FORMAT_S8; - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: return SND_PCM_FORMAT_U8; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: if (endianness) { return SND_PCM_FORMAT_S16_BE; } @@ -311,7 +311,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) return SND_PCM_FORMAT_S16_LE; } - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: if (endianness) { return SND_PCM_FORMAT_U16_BE; } @@ -319,7 +319,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) return SND_PCM_FORMAT_U16_LE; } - case AUD_FMT_S32: + case AUDIO_FORMAT_S32: if (endianness) { return SND_PCM_FORMAT_S32_BE; } @@ -327,7 +327,7 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) return SND_PCM_FORMAT_S32_LE; } - case AUD_FMT_U32: + case AUDIO_FORMAT_U32: if (endianness) { return SND_PCM_FORMAT_U32_BE; } @@ -344,58 +344,58 @@ static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) } } -static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt, +static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt, int *endianness) { switch (alsafmt) { case SND_PCM_FORMAT_S8: *endianness = 0; - *fmt = AUD_FMT_S8; + *fmt = AUDIO_FORMAT_S8; break; case SND_PCM_FORMAT_U8: *endianness = 0; - *fmt = AUD_FMT_U8; + *fmt = AUDIO_FORMAT_U8; break; case SND_PCM_FORMAT_S16_LE: *endianness = 0; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case SND_PCM_FORMAT_U16_LE: *endianness = 0; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; case SND_PCM_FORMAT_S16_BE: *endianness = 1; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case SND_PCM_FORMAT_U16_BE: *endianness = 1; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; case SND_PCM_FORMAT_S32_LE: *endianness = 0; - *fmt = AUD_FMT_S32; + *fmt = AUDIO_FORMAT_S32; break; case SND_PCM_FORMAT_U32_LE: *endianness = 0; - *fmt = AUD_FMT_U32; + *fmt = AUDIO_FORMAT_U32; break; case SND_PCM_FORMAT_S32_BE: *endianness = 1; - *fmt = AUD_FMT_S32; + *fmt = AUDIO_FORMAT_S32; break; case SND_PCM_FORMAT_U32_BE: *endianness = 1; - *fmt = AUD_FMT_U32; + *fmt = AUDIO_FORMAT_U32; break; default: @@ -638,19 +638,22 @@ static int alsa_open (int in, struct alsa_params_req *req, bytes_per_sec = freq << (nchannels == 2); switch (obt->fmt) { - case AUD_FMT_S8: - case AUD_FMT_U8: + case AUDIO_FORMAT_S8: + case AUDIO_FORMAT_U8: break; - case AUD_FMT_S16: - case AUD_FMT_U16: + case AUDIO_FORMAT_S16: + case AUDIO_FORMAT_U16: bytes_per_sec <<= 1; break; - case AUD_FMT_S32: - case AUD_FMT_U32: + case AUDIO_FORMAT_S32: + case AUDIO_FORMAT_U32: bytes_per_sec <<= 2; break; + + default: + abort(); } threshold = (conf->threshold * bytes_per_sec) / 1000; diff --git a/audio/audio.c b/audio/audio.c index 1ace47f510..96cbd57c37 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -113,7 +113,7 @@ static struct { .settings = { .freq = 44100, .nchannels = 2, - .fmt = AUD_FMT_S16, + .fmt = AUDIO_FORMAT_S16, .endianness = AUDIO_HOST_ENDIANNESS, } }, @@ -125,7 +125,7 @@ static struct { .settings = { .freq = 44100, .nchannels = 2, - .fmt = AUD_FMT_S16, + .fmt = AUDIO_FORMAT_S16, .endianness = AUDIO_HOST_ENDIANNESS, } }, @@ -257,58 +257,61 @@ static char *audio_alloc_prefix (const char *s) return r; } -static const char *audio_audfmt_to_string (audfmt_e fmt) +static const char *audio_audfmt_to_string (AudioFormat fmt) { switch (fmt) { - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: return "U8"; - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: return "U16"; - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: return "S8"; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: return "S16"; - case AUD_FMT_U32: + case AUDIO_FORMAT_U32: return "U32"; - case AUD_FMT_S32: + case AUDIO_FORMAT_S32: return "S32"; + + default: + abort(); } dolog ("Bogus audfmt %d returning S16\n", fmt); return "S16"; } -static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, +static AudioFormat audio_string_to_audfmt (const char *s, AudioFormat defval, int *defaultp) { if (!strcasecmp (s, "u8")) { *defaultp = 0; - return AUD_FMT_U8; + return AUDIO_FORMAT_U8; } else if (!strcasecmp (s, "u16")) { *defaultp = 0; - return AUD_FMT_U16; + return AUDIO_FORMAT_U16; } else if (!strcasecmp (s, "u32")) { *defaultp = 0; - return AUD_FMT_U32; + return AUDIO_FORMAT_U32; } else if (!strcasecmp (s, "s8")) { *defaultp = 0; - return AUD_FMT_S8; + return AUDIO_FORMAT_S8; } else if (!strcasecmp (s, "s16")) { *defaultp = 0; - return AUD_FMT_S16; + return AUDIO_FORMAT_S16; } else if (!strcasecmp (s, "s32")) { *defaultp = 0; - return AUD_FMT_S32; + return AUDIO_FORMAT_S32; } else { dolog ("Bogus audio format `%s' using %s\n", @@ -318,8 +321,8 @@ static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, } } -static audfmt_e audio_get_conf_fmt (const char *envname, - audfmt_e defval, +static AudioFormat audio_get_conf_fmt (const char *envname, + AudioFormat defval, int *defaultp) { const char *var = getenv (envname); @@ -421,7 +424,7 @@ static void audio_print_options (const char *prefix, case AUD_OPT_FMT: { - audfmt_e *fmtp = opt->valp; + AudioFormat *fmtp = opt->valp; printf ( "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n", state, @@ -508,7 +511,7 @@ static void audio_process_options (const char *prefix, case AUD_OPT_FMT: { - audfmt_e *fmtp = opt->valp; + AudioFormat *fmtp = opt->valp; *fmtp = audio_get_conf_fmt (optname, *fmtp, &def); } break; @@ -539,22 +542,22 @@ static void audio_print_settings (struct audsettings *as) dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels); switch (as->fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: AUD_log (NULL, "S8"); break; - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: AUD_log (NULL, "U8"); break; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: AUD_log (NULL, "S16"); break; - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: AUD_log (NULL, "U16"); break; - case AUD_FMT_S32: + case AUDIO_FORMAT_S32: AUD_log (NULL, "S32"); break; - case AUD_FMT_U32: + case AUDIO_FORMAT_U32: AUD_log (NULL, "U32"); break; default: @@ -585,12 +588,12 @@ static int audio_validate_settings (struct audsettings *as) invalid |= as->endianness != 0 && as->endianness != 1; switch (as->fmt) { - case AUD_FMT_S8: - case AUD_FMT_U8: - case AUD_FMT_S16: - case AUD_FMT_U16: - case AUD_FMT_S32: - case AUD_FMT_U32: + case AUDIO_FORMAT_S8: + case AUDIO_FORMAT_U8: + case AUDIO_FORMAT_S16: + case AUDIO_FORMAT_U16: + case AUDIO_FORMAT_S32: + case AUDIO_FORMAT_U32: break; default: invalid = 1; @@ -606,25 +609,28 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *a int bits = 8, sign = 0; switch (as->fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: sign = 1; /* fall through */ - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: break; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: sign = 1; /* fall through */ - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: bits = 16; break; - case AUD_FMT_S32: + case AUDIO_FORMAT_S32: sign = 1; /* fall through */ - case AUD_FMT_U32: + case AUDIO_FORMAT_U32: bits = 32; break; + + default: + abort(); } return info->freq == as->freq && info->nchannels == as->nchannels @@ -638,24 +644,27 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) int bits = 8, sign = 0, shift = 0; switch (as->fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: sign = 1; - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: break; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: sign = 1; - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: bits = 16; shift = 1; break; - case AUD_FMT_S32: + case AUDIO_FORMAT_S32: sign = 1; - case AUD_FMT_U32: + case AUDIO_FORMAT_U32: bits = 32; shift = 2; break; + + default: + abort(); } info->freq = as->freq; diff --git a/audio/audio_win_int.c b/audio/audio_win_int.c index 6900008d0c..b938fd667b 100644 --- a/audio/audio_win_int.c +++ b/audio/audio_win_int.c @@ -24,20 +24,20 @@ int waveformat_from_audio_settings (WAVEFORMATEX *wfx, wfx->cbSize = 0; switch (as->fmt) { - case AUD_FMT_S8: - case AUD_FMT_U8: + case AUDIO_FORMAT_S8: + case AUDIO_FORMAT_U8: wfx->wBitsPerSample = 8; break; - case AUD_FMT_S16: - case AUD_FMT_U16: + case AUDIO_FORMAT_S16: + case AUDIO_FORMAT_U16: wfx->wBitsPerSample = 16; wfx->nAvgBytesPerSec <<= 1; wfx->nBlockAlign <<= 1; break; - case AUD_FMT_S32: - case AUD_FMT_U32: + case AUDIO_FORMAT_S32: + case AUDIO_FORMAT_U32: wfx->wBitsPerSample = 32; wfx->nAvgBytesPerSec <<= 2; wfx->nBlockAlign <<= 2; @@ -85,15 +85,15 @@ int waveformat_to_audio_settings (WAVEFORMATEX *wfx, switch (wfx->wBitsPerSample) { case 8: - as->fmt = AUD_FMT_U8; + as->fmt = AUDIO_FORMAT_U8; break; case 16: - as->fmt = AUD_FMT_S16; + as->fmt = AUDIO_FORMAT_S16; break; case 32: - as->fmt = AUD_FMT_S32; + as->fmt = AUDIO_FORMAT_S32; break; default: diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 6c69622b4c..355e8fbda5 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -70,7 +70,7 @@ typedef struct OSSVoiceIn { struct oss_params { int freq; - audfmt_e fmt; + AudioFormat fmt; int nchannels; int nfrags; int fragsize; @@ -148,16 +148,16 @@ static int oss_write (SWVoiceOut *sw, void *buf, int len) return audio_pcm_sw_write (sw, buf, len); } -static int aud_to_ossfmt (audfmt_e fmt, int endianness) +static int aud_to_ossfmt (AudioFormat fmt, int endianness) { switch (fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: return AFMT_S8; - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: return AFMT_U8; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: if (endianness) { return AFMT_S16_BE; } @@ -165,7 +165,7 @@ static int aud_to_ossfmt (audfmt_e fmt, int endianness) return AFMT_S16_LE; } - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: if (endianness) { return AFMT_U16_BE; } @@ -182,37 +182,37 @@ static int aud_to_ossfmt (audfmt_e fmt, int endianness) } } -static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness) +static int oss_to_audfmt (int ossfmt, AudioFormat *fmt, int *endianness) { switch (ossfmt) { case AFMT_S8: *endianness = 0; - *fmt = AUD_FMT_S8; + *fmt = AUDIO_FORMAT_S8; break; case AFMT_U8: *endianness = 0; - *fmt = AUD_FMT_U8; + *fmt = AUDIO_FORMAT_U8; break; case AFMT_S16_LE: *endianness = 0; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case AFMT_U16_LE: *endianness = 0; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; case AFMT_S16_BE: *endianness = 1; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case AFMT_U16_BE: *endianness = 1; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; default: @@ -500,7 +500,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, int endianness; int err; int fd; - audfmt_e effective_fmt; + AudioFormat effective_fmt; struct audsettings obt_as; OSSConf *conf = drv_opaque; @@ -667,7 +667,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) int endianness; int err; int fd; - audfmt_e effective_fmt; + AudioFormat effective_fmt; struct audsettings obt_as; OSSConf *conf = drv_opaque; diff --git a/audio/paaudio.c b/audio/paaudio.c index 4c100bc318..f1f9a741ac 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -385,21 +385,21 @@ static int qpa_read (SWVoiceIn *sw, void *buf, int len) return audio_pcm_sw_read (sw, buf, len); } -static pa_sample_format_t audfmt_to_pa (audfmt_e afmt, int endianness) +static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness) { int format; switch (afmt) { - case AUD_FMT_S8: - case AUD_FMT_U8: + case AUDIO_FORMAT_S8: + case AUDIO_FORMAT_U8: format = PA_SAMPLE_U8; break; - case AUD_FMT_S16: - case AUD_FMT_U16: + case AUDIO_FORMAT_S16: + case AUDIO_FORMAT_U16: format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE; break; - case AUD_FMT_S32: - case AUD_FMT_U32: + case AUDIO_FORMAT_S32: + case AUDIO_FORMAT_U32: format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE; break; default: @@ -410,26 +410,26 @@ static pa_sample_format_t audfmt_to_pa (audfmt_e afmt, int endianness) return format; } -static audfmt_e pa_to_audfmt (pa_sample_format_t fmt, int *endianness) +static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness) { switch (fmt) { case PA_SAMPLE_U8: - return AUD_FMT_U8; + return AUDIO_FORMAT_U8; case PA_SAMPLE_S16BE: *endianness = 1; - return AUD_FMT_S16; + return AUDIO_FORMAT_S16; case PA_SAMPLE_S16LE: *endianness = 0; - return AUD_FMT_S16; + return AUDIO_FORMAT_S16; case PA_SAMPLE_S32BE: *endianness = 1; - return AUD_FMT_S32; + return AUDIO_FORMAT_S32; case PA_SAMPLE_S32LE: *endianness = 0; - return AUD_FMT_S32; + return AUDIO_FORMAT_S32; default: dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt); - return AUD_FMT_U8; + return AUDIO_FORMAT_U8; } } diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index 9db5ac92bc..aa42ea26bf 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -137,19 +137,19 @@ static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn) return sdl_post (s, forfn); } -static int aud_to_sdlfmt (audfmt_e fmt) +static int aud_to_sdlfmt (AudioFormat fmt) { switch (fmt) { - case AUD_FMT_S8: + case AUDIO_FORMAT_S8: return AUDIO_S8; - case AUD_FMT_U8: + case AUDIO_FORMAT_U8: return AUDIO_U8; - case AUD_FMT_S16: + case AUDIO_FORMAT_S16: return AUDIO_S16LSB; - case AUD_FMT_U16: + case AUDIO_FORMAT_U16: return AUDIO_U16LSB; default: @@ -161,37 +161,37 @@ static int aud_to_sdlfmt (audfmt_e fmt) } } -static int sdl_to_audfmt(int sdlfmt, audfmt_e *fmt, int *endianness) +static int sdl_to_audfmt(int sdlfmt, AudioFormat *fmt, int *endianness) { switch (sdlfmt) { case AUDIO_S8: *endianness = 0; - *fmt = AUD_FMT_S8; + *fmt = AUDIO_FORMAT_S8; break; case AUDIO_U8: *endianness = 0; - *fmt = AUD_FMT_U8; + *fmt = AUDIO_FORMAT_U8; break; case AUDIO_S16LSB: *endianness = 0; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case AUDIO_U16LSB: *endianness = 0; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; case AUDIO_S16MSB: *endianness = 1; - *fmt = AUD_FMT_S16; + *fmt = AUDIO_FORMAT_S16; break; case AUDIO_U16MSB: *endianness = 1; - *fmt = AUD_FMT_U16; + *fmt = AUDIO_FORMAT_U16; break; default: @@ -386,7 +386,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, SDL_AudioSpec req, obt; int endianness; int err; - audfmt_e effective_fmt; + AudioFormat effective_fmt; struct audsettings obt_as; req.freq = as->freq; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 6ad0eafbc6..3aeb0cb357 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -130,7 +130,7 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ; #endif settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN; - settings.fmt = AUD_FMT_S16; + settings.fmt = AUDIO_FORMAT_S16; settings.endianness = AUDIO_HOST_ENDIANNESS; audio_pcm_init_info (&hw->info, &settings); @@ -258,7 +258,7 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) settings.freq = SPICE_INTERFACE_RECORD_FREQ; #endif settings.nchannels = SPICE_INTERFACE_RECORD_CHAN; - settings.fmt = AUD_FMT_S16; + settings.fmt = AUDIO_FORMAT_S16; settings.endianness = AUDIO_HOST_ENDIANNESS; audio_pcm_init_info (&hw->info, &settings); diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 40adfa30c3..35a614785e 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -117,20 +117,23 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, stereo = wav_as.nchannels == 2; switch (wav_as.fmt) { - case AUD_FMT_S8: - case AUD_FMT_U8: + case AUDIO_FORMAT_S8: + case AUDIO_FORMAT_U8: bits16 = 0; break; - case AUD_FMT_S16: - case AUD_FMT_U16: + case AUDIO_FORMAT_S16: + case AUDIO_FORMAT_U16: bits16 = 1; break; - case AUD_FMT_S32: - case AUD_FMT_U32: + case AUDIO_FORMAT_S32: + case AUDIO_FORMAT_U32: dolog ("WAVE files can not handle 32bit formats\n"); return -1; + + default: + abort(); } hdr[34] = bits16 ? 0x10 : 0x08; @@ -225,7 +228,7 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...) static WAVConf glob_conf = { .settings.freq = 44100, .settings.nchannels = 2, - .settings.fmt = AUD_FMT_S16, + .settings.fmt = AUDIO_FORMAT_S16, .wav_path = "qemu.wav" }; diff --git a/audio/wavcapture.c b/audio/wavcapture.c index cf31ed652c..e943565210 100644 --- a/audio/wavcapture.c +++ b/audio/wavcapture.c @@ -139,7 +139,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, as.freq = freq; as.nchannels = 1 << stereo; - as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8; + as.fmt = bits16 ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_U8; as.endianness = 0; ops.notify = wav_notify; diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 3c7d1364a9..96e84f6e7e 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -273,7 +273,7 @@ static void omap_eac_format_update(struct omap_eac_s *s) * does I2S specify it? */ /* All register writes are 16 bits so we we store 16-bit samples * in the buffers regardless of AGCFR[B8_16] value. */ - fmt.fmt = AUD_FMT_U16; + fmt.fmt = AUDIO_FORMAT_U16; s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice, "eac.codec.in", s, omap_eac_in_cb, &fmt); diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index d799533aa9..2265622d44 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -365,7 +365,7 @@ static void open_voice (AC97LinkState *s, int index, int freq) as.freq = freq; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; if (freq > 0) { diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 97b876c7e0..0957780a3d 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -269,7 +269,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) as.freq = s->freq; as.nchannels = SHIFT; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = AUDIO_HOST_ENDIANNESS; AUD_register_card ("adlib", &s->card); diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index 9089dcb47e..62da75eefe 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -288,7 +288,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) switch ((val >> 5) & ((s->dregs[MODE_And_ID] & MODE2) ? 7 : 3)) { case 0: - as.fmt = AUD_FMT_U8; + as.fmt = AUDIO_FORMAT_U8; s->shift = as.nchannels == 2; break; @@ -298,7 +298,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) case 3: s->tab = ALawDecompressTable; x_law: - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = AUDIO_HOST_ENDIANNESS; s->shift = as.nchannels == 2; break; @@ -307,7 +307,7 @@ static void cs_reset_voices (CSState *s, uint32_t val) as.endianness = 1; /* fall through */ case 2: - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; s->shift = as.nchannels; break; diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 97789a0771..a5314d66fd 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -414,14 +414,14 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) i, new_freq, 1 << (new_fmt & 1), - (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8, + (new_fmt & 2) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_U8, d->shift); if (new_freq) { struct audsettings as; as.freq = new_freq; as.nchannels = 1 << (new_fmt & 1); - as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8; + as.fmt = (new_fmt & 2) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_U8; as.endianness = 0; if (i == ADC_CHANNEL) { diff --git a/hw/audio/gus.c b/hw/audio/gus.c index 8e0b27e0f2..b3e2a7fdd5 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -251,7 +251,7 @@ static void gus_realizefn (DeviceState *dev, Error **errp) as.freq = s->freq; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = GUS_ENDIANNESS; s->voice = AUD_open_out ( diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index 617a1c1016..c25bfa38b1 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -99,9 +99,9 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) } switch (format & AC_FMT_BITS_MASK) { - case AC_FMT_BITS_8: as->fmt = AUD_FMT_S8; break; - case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break; - case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break; + case AC_FMT_BITS_8: as->fmt = AUDIO_FORMAT_S8; break; + case AC_FMT_BITS_16: as->fmt = AUDIO_FORMAT_S16; break; + case AC_FMT_BITS_32: as->fmt = AUDIO_FORMAT_S32; break; } as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1; @@ -134,12 +134,12 @@ static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as) /* -------------------------------------------------------------------------- */ static const char *fmt2name[] = { - [ AUD_FMT_U8 ] = "PCM-U8", - [ AUD_FMT_S8 ] = "PCM-S8", - [ AUD_FMT_U16 ] = "PCM-U16", - [ AUD_FMT_S16 ] = "PCM-S16", - [ AUD_FMT_U32 ] = "PCM-U32", - [ AUD_FMT_S32 ] = "PCM-S32", + [ AUDIO_FORMAT_U8 ] = "PCM-U8", + [ AUDIO_FORMAT_S8 ] = "PCM-S8", + [ AUDIO_FORMAT_U16 ] = "PCM-U16", + [ AUDIO_FORMAT_S16 ] = "PCM-S16", + [ AUDIO_FORMAT_U32 ] = "PCM-U32", + [ AUDIO_FORMAT_S32 ] = "PCM-S32", }; typedef struct HDAAudioState HDAAudioState; diff --git a/hw/audio/lm4549.c b/hw/audio/lm4549.c index a46f2301af..af8b22b541 100644 --- a/hw/audio/lm4549.c +++ b/hw/audio/lm4549.c @@ -185,7 +185,7 @@ void lm4549_write(lm4549_state *s, struct audsettings as; as.freq = value; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; s->voice = AUD_open_out( @@ -255,7 +255,7 @@ static int lm4549_post_load(void *opaque, int version_id) struct audsettings as; as.freq = freq; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; s->voice = AUD_open_out( @@ -292,7 +292,7 @@ void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque) /* Open a default voice */ as.freq = 48000; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; s->voice = AUD_open_out( diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c index bc8db71ae0..90cce1e6ed 100644 --- a/hw/audio/milkymist-ac97.c +++ b/hw/audio/milkymist-ac97.c @@ -308,7 +308,7 @@ static void milkymist_ac97_realize(DeviceState *dev, Error **errp) as.freq = 48000; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 1; s->voice_in = AUD_open_in(&s->card, s->voice_in, diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 908696d483..4a7386a689 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -114,7 +114,7 @@ static void pcspk_callback(void *opaque, int free) static int pcspk_audio_init(ISABus *bus) { PCSpkState *s = pcspk_state; - struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0}; + struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUDIO_FORMAT_U8, 0}; AUD_register_card(s_spk, &s->card); diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index c5b9bf79e8..65ea0cd938 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -66,7 +66,7 @@ typedef struct SB16State { int fmt_stereo; int fmt_signed; int fmt_bits; - audfmt_e fmt; + AudioFormat fmt; int dma_auto; int block_size; int fifo; @@ -224,7 +224,7 @@ static void continue_dma8 (SB16State *s) static void dma_cmd8 (SB16State *s, int mask, int dma_len) { - s->fmt = AUD_FMT_U8; + s->fmt = AUDIO_FORMAT_U8; s->use_hdma = 0; s->fmt_bits = 8; s->fmt_signed = 0; @@ -319,18 +319,18 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len) if (16 == s->fmt_bits) { if (s->fmt_signed) { - s->fmt = AUD_FMT_S16; + s->fmt = AUDIO_FORMAT_S16; } else { - s->fmt = AUD_FMT_U16; + s->fmt = AUDIO_FORMAT_U16; } } else { if (s->fmt_signed) { - s->fmt = AUD_FMT_S8; + s->fmt = AUDIO_FORMAT_S8; } else { - s->fmt = AUD_FMT_U8; + s->fmt = AUDIO_FORMAT_U8; } } @@ -852,7 +852,7 @@ static void legacy_reset (SB16State *s) as.freq = s->freq; as.nchannels = 1; - as.fmt = AUD_FMT_U8; + as.fmt = AUDIO_FORMAT_U8; as.endianness = 0; s->voice = AUD_open_out ( diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c index f4aa838f62..d563f31e7c 100644 --- a/hw/audio/wm8750.c +++ b/hw/audio/wm8750.c @@ -201,7 +201,7 @@ static void wm8750_set_format(WM8750State *s) in_fmt.endianness = 0; in_fmt.nchannels = 2; in_fmt.freq = s->adc_hz; - in_fmt.fmt = AUD_FMT_S16; + in_fmt.fmt = AUDIO_FORMAT_S16; s->adc_voice[0] = AUD_open_in(&s->card, s->adc_voice[0], CODEC ".input1", s, wm8750_audio_in_cb, &in_fmt); @@ -214,7 +214,7 @@ static void wm8750_set_format(WM8750State *s) out_fmt.endianness = 0; out_fmt.nchannels = 2; out_fmt.freq = s->dac_hz; - out_fmt.fmt = AUD_FMT_S16; + out_fmt.fmt = AUDIO_FORMAT_S16; s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0], CODEC ".speaker", s, wm8750_audio_out_cb, &out_fmt); @@ -681,7 +681,7 @@ uint32_t wm8750_adc_dat(void *opaque) if (s->idx_in >= sizeof(s->data_in)) { wm8750_in_load(s); if (s->idx_in >= sizeof(s->data_in)) { - return 0x80008000; /* silence in AUD_FMT_S16 sample format */ + return 0x80008000; /* silence in AUDIO_FORMAT_S16 sample format */ } } diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index cc0f9bc9cc..11b09bd18c 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1260,7 +1260,7 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) as.freq = 44100; as.nchannels = 2; - as.fmt = AUD_FMT_S16; + as.fmt = AUDIO_FORMAT_S16; as.endianness = 0; AUD_register_card("xlnx_dp.audio", &s->aud_card); diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c index ded0db9351..885f71366c 100644 --- a/hw/input/tsc210x.c +++ b/hw/input/tsc210x.c @@ -318,7 +318,7 @@ static void tsc2102_audio_output_update(TSC210xState *s) fmt.endianness = 0; fmt.nchannels = 2; fmt.freq = s->codec.tx_rate; - fmt.fmt = AUD_FMT_S16; + fmt.fmt = AUDIO_FORMAT_S16; s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0], "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt); diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 28ac7c5165..c46d5eeb79 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -650,7 +650,7 @@ static void usb_audio_realize(USBDevice *dev, Error **errp) s->out.vol[1] = 240; /* 0 dB */ s->out.as.freq = USBAUDIO_SAMPLE_RATE; s->out.as.nchannels = 2; - s->out.as.fmt = AUD_FMT_S16; + s->out.as.fmt = AUDIO_FORMAT_S16; s->out.as.endianness = 0; streambuf_init(&s->out.buf, s->buffer); diff --git a/ui/vnc.c b/ui/vnc.c index 9e4b2beb71..48c1b95aae 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -994,16 +994,16 @@ static void vnc_update_throttle_offset(VncState *vs) int bps; switch (vs->as.fmt) { default: - case AUD_FMT_U8: - case AUD_FMT_S8: + case AUDIO_FORMAT_U8: + case AUDIO_FORMAT_S8: bps = 1; break; - case AUD_FMT_U16: - case AUD_FMT_S16: + case AUDIO_FORMAT_U16: + case AUDIO_FORMAT_S16: bps = 2; break; - case AUD_FMT_U32: - case AUD_FMT_S32: + case AUDIO_FORMAT_U32: + case AUDIO_FORMAT_S32: bps = 4; break; } @@ -2409,12 +2409,12 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) if (len == 4) return 10; switch (read_u8(data, 4)) { - case 0: vs->as.fmt = AUD_FMT_U8; break; - case 1: vs->as.fmt = AUD_FMT_S8; break; - case 2: vs->as.fmt = AUD_FMT_U16; break; - case 3: vs->as.fmt = AUD_FMT_S16; break; - case 4: vs->as.fmt = AUD_FMT_U32; break; - case 5: vs->as.fmt = AUD_FMT_S32; break; + case 0: vs->as.fmt = AUDIO_FORMAT_U8; break; + case 1: vs->as.fmt = AUDIO_FORMAT_S8; break; + case 2: vs->as.fmt = AUDIO_FORMAT_U16; break; + case 3: vs->as.fmt = AUDIO_FORMAT_S16; break; + case 4: vs->as.fmt = AUDIO_FORMAT_U32; break; + case 5: vs->as.fmt = AUDIO_FORMAT_S32; break; default: VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4)); vnc_client_error(vs); @@ -3145,7 +3145,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, vs->as.freq = 44100; vs->as.nchannels = 2; - vs->as.fmt = AUD_FMT_S16; + vs->as.fmt = AUDIO_FORMAT_S16; vs->as.endianness = 0; qemu_mutex_init(&vs->output_mutex); From patchwork Wed Jan 16 23:36:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3765513A4 for ; Wed, 16 Jan 2019 23:45:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 22FE82AB24 for ; Wed, 16 Jan 2019 23:45:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1707B2ADEB; Wed, 16 Jan 2019 23:45:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4FA412AD09 for ; Wed, 16 Jan 2019 23:45:12 +0000 (UTC) Received: from localhost ([127.0.0.1]:33143 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjurv-000262-FX for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:45:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57765) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukj-00042K-4H for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukf-0002nc-Cw for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:43 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:52845) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjuke-0002av-R4 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:41 -0500 Received: by mail-wm1-x343.google.com with SMTP id m1so3893764wml.2 for ; Wed, 16 Jan 2019 15:37:29 -0800 (PST) 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=4M4jP2lGrRHceFTjoX2pbEyNqUXT5ZXmaJ8jLTsK1zo=; b=U3BDcEZJVxN6qaxtlh2RzfB6GqlhDjveavt/zuTdb32TWnVrNUuJ8e4DMdg7uo2Z0Q VfKeMiMcKmWdU6RsJhCrnQQlmiiUGY+yXLOdKpU4Ro1vjiGpmYLQ7IjkGGp0SiI9Femq NRUuuKiZOWOxTrRD/BYZI13WcvJQmB5e03PkFWBjsoP+tUA+n0boDPSADo2JZJ6mHOSb RQo9MDKQqxx/F/IxIbjWXtXrPwB1TveeoyjISEipzaSvrNbppbDypnT6vT2vVSSdw8+D +4/2WTJGrKf+4Vc5Kps7NfEnfOrMHQz3LLFBuOpC+JhWReVUi239kzg11rnT6NsHX87D p1ug== 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=4M4jP2lGrRHceFTjoX2pbEyNqUXT5ZXmaJ8jLTsK1zo=; b=YblWrqihMuksRiDbUXM2wtGtF9Fdz6ylS6xIKDKXoxBwqxuuD3ACRhrugwajdiXP1p vMc6zUPDKy+3BZWOQmvGtnFSDvASntpcFUtXiWf27xv5k0aO+U6puDIxWPHQsuSLKo29 HxkVy8RyT+suHR+9dSIfetJOAuIjNfBqwPKNWkMU1gZwiRHl7cjHDp0dXRuvGYZ1Yv+i B73LrXSNVkLyBVo35Ap70iWTbsod2SjSU6BVTGcxJtAau7bW0wpeUVIRFvv6aadzmiQ0 t4iOLc4Kr4hctTbVWK2FwSDNOXdY4xcb/miEXKh9IvZutNVpB6Yd1y/G2QuR/pRoQF31 JXdA== X-Gm-Message-State: AJcUuke5AC4uD3+nFPPvm29xfohmEg9RBzezpqFctLfumxZvAWND6oCz eU0kNRJyz/kOtrM4YKiqFfsSyBbQ X-Google-Smtp-Source: ALg8bN72hz8NchR+8JZWJ1GgwvSdhjjPu3Z+/CZiMFdLSyYm3MSj6THDb6Vrv7uUxhr/ByTHIKHyTA== X-Received: by 2002:a1c:4955:: with SMTP id w82mr9824162wma.33.1547681847942; Wed, 16 Jan 2019 15:37:27 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:27 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:36 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 03/50] audio: -audiodev command line option: documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds documentation of an -audiodev command line option, that deprecates the old QEMU_* environment variables for audio backend configuration. It's syntax is similar to existing options (-netdev, -device, etc): -audiodev driver_name,property=value,... Although now it's possible to specify multiple -audiodev options on command line, multiple audio backends are not supported yet. Signed-off-by: Kővágó, Zoltán --- qemu-options.hx | 222 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 521511ec13..a12931899b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -416,14 +416,230 @@ The default is @code{en-us}. ETEXI +HXCOMM Deprecated by -audiodev DEF("audio-help", 0, QEMU_OPTION_audio_help, - "-audio-help print list of audio drivers and their options\n", + "-audio-help show -audiodev equivalent of the currently specified audio settings\n", QEMU_ARCH_ALL) STEXI @item -audio-help @findex -audio-help -Will show the audio subsystem help: list of drivers, tunable -parameters. +Will show the -audiodev equivalent of the currently specified +(deprecated) environment variables. +ETEXI + +DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, + "-audiodev [driver=]driver,id=id[,prop[=value][,...]]\n" + " specifies the audio backend to use\n" + " id= identifier of the backend\n" + " timer-period= timer period in microseconds\n" + " in|out.fixed-settings= use fixed settings for host audio\n" + " in|out.frequency= frequency to use with fixed settings\n" + " in|out.channels= number of channels to use with fixed settings\n" + " in|out.format= sample format to use with fixed settings\n" + " valid values: s8, s16, s32, u8, u16, u32\n" + " in|out.voices= number of voices to use\n" + " in|out.buffer-len= size of buffer in microseconds\n" + " in|out.buffer-count= number of buffers\n" + "-audiodev none,id=id,[,prop[=value][,...]]\n" + " dummy driver that discards all output\n" +#ifdef CONFIG_ALSA + "-audiodev alsa,id=id[,prop[=value][,...]]\n" + " alsa-in|alsa-out.dev= name of the audio device to use\n" + " alsa-in|alsa-out.try-poll= attempt to use poll mode\n" + " threshold= threshold (in microseconds) when playback starts\n" +#endif +#ifdef CONFIG_COREAUDIO + "-audiodev coreaudio,id=id[,prop[=value][,...]]\n" +#endif +#ifdef CONFIG_DSOUND + "-audiodev dsound,id=id[,prop[=value][,...]]\n" + " latency= add extra latency to playback in microseconds\n" +#endif +#ifdef CONFIG_OSS + "-audiodev oss,id=id[,prop[=value][,...]]\n" + " oss-in|oss-out.dev= path of the audio device to use\n" + " oss-in|oss-out.try-poll= attempt to use poll mode\n" + " try-mmap= try using memory mapped access\n" + " exclusive= open device in exclusive mode\n" + " dsp-policy= set timing policy (0..10), -1 to use fragment mode\n" +#endif +#ifdef CONFIG_PA + "-audiodev pa,id=id[,prop[=value][,...]]\n" + " server= PulseAudio server address\n" + " sink|source.name= sink/source device name\n" +#endif +#ifdef CONFIG_SDL + "-audiodev sdl,id=id[,prop[=value][,...]]\n" +#endif +#ifdef CONFIG_SPICE + "-audiodev spice,id=id[,prop[=value][,...]]\n" +#endif + "-audiodev wav,id=id[,prop[=value][,...]]\n" + " path= path of wav file to record\n", + QEMU_ARCH_ALL) +STEXI +@item -audiodev [driver=]@var{driver},id=@var{id}[,@var{prop}[=@var{value}][,...]] +@findex -audiodev +Adds a new audio backend @var{driver} identified by @var{id}. There are +global and driver specific properties. Some values can be set +differently for input and output, they're marked with @code{in|out.}. +You can set the input's property with @code{in.@var{prop}} and the +output's property with @code{out.@var{prop}}. For example: +@example +-audiodev alsa,id=example,in.frequency=44110,out.frequency=8000 +-audiodev alsa,id=example,out.channels=1 # leaves in.channels unspecified +@end example + +Valid global options are: + +@table @option +@item id=@var{identifier} +Identifies the audio backend. + +@item timer-period=@var{period} +Sets the timer @var{period} used by the audio subsystem in microseconds. +Default is 10000 (10 ms). + +@item in|out.fixed-settings=on|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 +@var{frequency}, @var{channels} or @var{format}. Default is on. + +@item in|out.frequency=@var{frequency} +Specify the @var{frequency} to use when using @var{fixed-settings}. +Default is 44100Hz. + +@item in|out.channels=@var{channels} +Specify the number of @var{channels} to use when using +@var{fixed-settings}. Default is 2 (stereo). + +@item in|out.format=@var{format} +Specify the sample @var{format} to use when using @var{fixed-settings}. +Valid values are: @code{s8}, @code{s16}, @code{s32}, @code{u8}, +@code{u16}, @code{u32}. Default is @code{s16}. + +@item in|out.voices=@var{voices} +Specify the number of @var{voices} to use. Default is 1. + +@item in|out.buffer=@var{usecs} +Sets the size of the buffer in microseconds. + +@item in|out.buffer-count=@var{count} +Sets the @var{count} of the buffers. + +@end table + +@item -audiodev none,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a dummy backend that discards all outputs. This backend has no +backend specific properties. + +@item -audiodev alsa,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates backend using the ALSA. This backend is only available on +Linux. + +ALSA specific options are: + +@table @option +@item alsa-in|alsa-out.dev=@var{device} +Specify the ALSA @var{device} to use for input and/or output. Default +is @code{default}. + +@item alsa-in|alsa-out.try-poll=on|off +Attempt to use poll mode with the device. Default is on. + +@item threshold=@var{threshold} +Threshold (in microseconds) when playback starts. Default is 0. + +@end table + +@item -audiodev coreaudio,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using Apple's Core Audio. This backend is only +available on Mac OS and only supports playback. This backend has no +backend specific properties. + +@item -audiodev dsound,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using Microsoft's DirectSound. This backend is only +available on Windows and only supports playback. + +Backend specific options are: + +@table @option + +@item latency=@var{usecs} +Add extra @var{usecs} microseconds latency to playback. Default is +10000 (10 ms). + +@end table + +@item -audiodev oss,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using OSS. This backend is available on most +Unix-like systems. + +OSS specific options are: + +@table @option + +@item oss-in|oss-out.dev=@var{device} +Specify the file name of the OSS @var{device} to use. Default is +@code{/dev/dsp}. + +@item oss-in|oss-out.try-poll=on|of +Attempt to use poll mode with the device. Default is on. + +@item try-mmap=on|off +Try using memory mapped device access. Default is off. + +@item exclusive=on|off +Open the device in exclusive mode (vmix won't work in this case). +Default is off. + +@item dsp-policy=@var{policy} +Sets the timing policy (between 0 and 10, where smaller number means +smaller latency but higher CPU usage). Use -1 to use buffer sizes +specified by @code{buffer} and @code{buffer-count}. This option is +ignored if you do not have OSS 4. Default is 5. + +@end table + +@item -audiodev pa,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using PulseAudio. This backend is available on most +systems. + +PulseAudio specific options are: + +@table @option + +@item server=@var{server} +Sets the PulseAudio @var{server} to connect to. + +@item sink|source.name=@var{sink} +Use the specified sink/source for playback/recording. + +@end table + +@item -audiodev sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend using SDL. This backend is available on most systems, +but you should use your platform's native backend if possible. This +backend has no backend specific properties. + +@item -audiodev spice,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend that sends audio through SPICE. This backend requires +@code{-spice} and automatically selected in that case, so usually you +can ignore this option. This backend has no backend specific +properties. + +@item -audiodev wav,id=@var{id}[,@var{prop}[=@var{value}][,...]] +Creates a backend that writes audio to a WAV file. + +Backend specific options are: + +@table @option + +@item path=@var{path} +Write recorded audio into the specified file. Default is +@code{qemu.wav}. + +@end table ETEXI DEF("soundhw", HAS_ARG, QEMU_OPTION_soundhw, From patchwork Wed Jan 16 23:36:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767175 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BEAEF6C2 for ; Thu, 17 Jan 2019 00:04:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1309D2B25A for ; Thu, 17 Jan 2019 00:03:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 035772B270; Thu, 17 Jan 2019 00:03:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B82042FCAF for ; Thu, 17 Jan 2019 00:03:47 +0000 (UTC) Received: from localhost ([127.0.0.1]:37500 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv9u-0007g3-Pr for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:03:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58106) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuky-0004EJ-Pk for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002vU-8p for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:57 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:39774) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002dG-Lr for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:46 -0500 Received: by mail-wm1-x341.google.com with SMTP id y8so3853470wmi.4 for ; Wed, 16 Jan 2019 15:37:31 -0800 (PST) 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=ic+7d1rGpfuAmmsZU/KZ999/PazRmhO3gSqIoBkcvVs=; b=rdEH1fKFNwHTqtw+Ad/HE+viJOkbKO8OvNnIuJ9xLUOPct926LGTopVnKQGYSAlsyT zS9a7TArpyPZ80vFrIIhGY5dyNWqg0/CdRwrR+1C0c8NWm8FGxwfFSp/S+gJ2SgsTR+8 4s0AbsvEANM3epdBHlY+HkmIS2D7cMqX2/AamSea4JIx6wWW78PQUk8hbLUbOz8wukjF 4ReiZdimmG4NlPeBAwV+W3/Y6FuCItbUribX+nvocSG0Is84US/uDBbjxIAVOvUmwi3V bz9HKWSRhekzZlWzUoGKUNGBiRJ7CFzhpkR2gvlCPYZQknJc8bxxWwPvxBUL0TnPS6Bf +vIA== 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=ic+7d1rGpfuAmmsZU/KZ999/PazRmhO3gSqIoBkcvVs=; b=oZ/HmRdBlzz6f0sISAXD7gsoNzdeva8TzfDQw7poa2pmKvOSPB7I8GTcAZr7Qr68vz UKPY4a1vDMXjsGwOy1EDR1hvGD43CnyYN382beypSeOqbyQn/79kJWKJw9Bi0YfS3xOz dOh3wdVp3n8EDInVh8P2fsgZ+ygSD/EXpWJ5MLOZUM42PS8XkBf1nd1K6yEhmkeTVlqT K4qxtqT6JXhu4dK6X7oWETfIEao3nghn5whi+0EzKl372K39vU48GavE2BN42aFOtd13 67/98r9twNW2hlDIJbt6TunOwSYEVsPofiuEzLlMU+ltCDGz/DrVQIdm47jUNMoIpWzY d3gw== X-Gm-Message-State: AJcUuke1gyssVSNtBW07MQM1HONVMxeS0FMZdSqskP1lSqzaEa+grwH1 47ybNSasMa4ufW3qn7yaDUSDsjQj1QA= X-Google-Smtp-Source: ALg8bN6Hvtzq+GY6jzyZhv1gP6PTpLuVCKJk/N7nzI4VNm0CmswRZD5GNqjvI23xN3JtMImfvIlO9g== X-Received: by 2002:a7b:c44d:: with SMTP id l13mr9478953wmi.144.1547681849285; Wed, 16 Jan 2019 15:37:29 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:28 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:37 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v3 04/50] audio: -audiodev command line option basic implementation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Audio drivers now get an Audiodev * as config paramters, instead of the global audio_option structs. There is some code in audio/audio_legacy.c that converts the old environment variables to audiodev options (this way backends do not have to worry about legacy options). It also contains a replacement of -audio-help, which prints out the equivalent -audiodev based config of the currently specified environment variables. Note that backends are not updated and still rely on environment variables. Also note that (due to moving try-poll from global to backend specific option) currently ALSA and OSS will always try poll mode, regardless of environment variables or -audiodev options. Signed-off-by: Kővágó, Zoltán --- Notes: Changes from v2: * MAJOR: use qobject_input_visitor instead of QemuOpts * almost completely rewrote legacy options handling * added missing license comment to audio_legacy.c0 audio/audio.h | 18 +- audio/audio_int.h | 16 +- audio/audio_template.h | 13 +- audio/alsaaudio.c | 2 +- audio/audio.c | 600 ++++++++++++++++------------------------- audio/audio_legacy.c | 294 ++++++++++++++++++++ audio/coreaudio.c | 2 +- audio/dsoundaudio.c | 2 +- audio/noaudio.c | 2 +- audio/ossaudio.c | 2 +- audio/paaudio.c | 2 +- audio/sdlaudio.c | 2 +- audio/spiceaudio.c | 2 +- audio/wavaudio.c | 2 +- vl.c | 7 +- audio/Makefile.objs | 2 +- 16 files changed, 588 insertions(+), 380 deletions(-) create mode 100644 audio/audio_legacy.c diff --git a/audio/audio.h b/audio/audio.h index 02f29a3b3e..64b0f761bc 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -36,12 +36,21 @@ typedef void (*audio_callback_fn) (void *opaque, int avail); #define AUDIO_HOST_ENDIANNESS 0 #endif -struct audsettings { +typedef struct audsettings { int freq; int nchannels; AudioFormat fmt; int endianness; -}; +} audsettings; + +audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo); +int audioformat_bytes_per_sample(AudioFormat fmt); +int audio_buffer_frames(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs); +int audio_buffer_samples(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs); +int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs); typedef enum { AUD_CNOTIFY_ENABLE, @@ -81,7 +90,6 @@ typedef struct QEMUAudioTimeStamp { void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -void AUD_help (void); void AUD_register_card (const char *name, QEMUSoundCard *card); void AUD_remove_card (QEMUSoundCard *card); CaptureVoiceOut *AUD_add_capture ( @@ -163,4 +171,8 @@ void audio_sample_to_uint64(void *samples, int pos, void audio_sample_from_uint64(void *samples, int pos, uint64_t left, uint64_t right); +void audio_parse_option(const char *opt); +void audio_init_audiodevs(void); +void audio_legacy_help(void); + #endif /* QEMU_AUDIO_H */ diff --git a/audio/audio_int.h b/audio/audio_int.h index 244b454012..353467b505 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -146,7 +146,7 @@ struct audio_driver { const char *name; const char *descr; struct audio_option *options; - void *(*init) (void); + void *(*init) (Audiodev *); void (*fini) (void *); struct audio_pcm_ops *pcm_ops; int can_be_default; @@ -193,6 +193,7 @@ struct SWVoiceCap { struct AudioState { struct audio_driver *drv; + Audiodev *dev; void *drv_opaque; QEMUTimer *ts; @@ -203,10 +204,13 @@ struct AudioState { int nb_hw_voices_out; int nb_hw_voices_in; int vm_running; + int64_t period_ticks; }; extern const struct mixeng_volume nominal_volume; +extern const char *audio_prio_list[]; + void audio_driver_register(audio_driver *drv); audio_driver *audio_driver_lookup(const char *name); @@ -248,4 +252,14 @@ static inline int audio_ring_dist (int dst, int src, int len) #define AUDIO_STRINGIFY_(n) #n #define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n) +typedef struct AudiodevListEntry { + Audiodev *dev; + QSIMPLEQ_ENTRY(AudiodevListEntry) next; +} AudiodevListEntry; + +typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead; +AudiodevListHead audio_handle_legacy_opts(void); + +void audio_free_audiodev_list(AudiodevListHead *head); + #endif /* QEMU_AUDIO_INT_H */ diff --git a/audio/audio_template.h b/audio/audio_template.h index 7de227d2d1..c1d7207abd 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -302,8 +302,10 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as) { HW *hw; + AudioState *s = &glob_audio_state; + AudiodevPerDirectionOptions *pdo = s->dev->TYPE; - if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) { + if (pdo->fixed_settings) { hw = glue (audio_pcm_hw_add_new_, TYPE) (as); if (hw) { return hw; @@ -331,9 +333,11 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( SW *sw; HW *hw; struct audsettings hw_as; + AudioState *s = &glob_audio_state; + AudiodevPerDirectionOptions *pdo = s->dev->TYPE; - if (glue (conf.fixed_, TYPE).enabled) { - hw_as = glue (conf.fixed_, TYPE).settings; + if (pdo->fixed_settings) { + hw_as = audiodev_to_audsettings(pdo); } else { hw_as = *as; @@ -398,6 +402,7 @@ SW *glue (AUD_open_, TYPE) ( ) { AudioState *s = &glob_audio_state; + AudiodevPerDirectionOptions *pdo = s->dev->TYPE; if (audio_bug(__func__, !card || !name || !callback_fn || !as)) { dolog ("card=%p name=%p callback_fn=%p as=%p\n", @@ -422,7 +427,7 @@ SW *glue (AUD_open_, TYPE) ( return sw; } - if (!glue (conf.fixed_, TYPE).enabled && sw) { + if (!pdo->fixed_settings && sw) { glue (AUD_close_, TYPE) (card, sw); sw = NULL; } diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 5bd034267f..8302f3e882 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -1125,7 +1125,7 @@ static ALSAConf glob_conf = { .pcm_name_in = "default", }; -static void *alsa_audio_init (void) +static void *alsa_audio_init(Audiodev *dev) { ALSAConf *conf = g_malloc(sizeof(ALSAConf)); *conf = glob_conf; diff --git a/audio/audio.c b/audio/audio.c index 96cbd57c37..159b049ceb 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -26,6 +26,9 @@ #include "audio.h" #include "monitor/monitor.h" #include "qemu/timer.h" +#include "qapi/error.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qapi-visit-audio.h" #include "sysemu/sysemu.h" #include "qemu/cutils.h" #include "sysemu/replay.h" @@ -46,14 +49,16 @@ The 1st one is the one used by default, that is the reason that we generate the list. */ -static const char *audio_prio_list[] = { +const char *audio_prio_list[] = { "spice", CONFIG_AUDIO_DRIVERS "none", "wav", + NULL }; static QLIST_HEAD(, audio_driver) audio_drivers; +static AudiodevListHead audiodevs = QSIMPLEQ_HEAD_INITIALIZER(audiodevs); void audio_driver_register(audio_driver *drv) { @@ -80,61 +85,6 @@ audio_driver *audio_driver_lookup(const char *name) return NULL; } -static void audio_module_load_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(audio_prio_list); i++) { - audio_driver_lookup(audio_prio_list[i]); - } -} - -struct fixed_settings { - int enabled; - int nb_voices; - int greedy; - struct audsettings settings; -}; - -static struct { - struct fixed_settings fixed_out; - struct fixed_settings fixed_in; - union { - int hertz; - int64_t ticks; - } period; - int try_poll_in; - int try_poll_out; -} conf = { - .fixed_out = { /* DAC fixed settings */ - .enabled = 1, - .nb_voices = 1, - .greedy = 1, - .settings = { - .freq = 44100, - .nchannels = 2, - .fmt = AUDIO_FORMAT_S16, - .endianness = AUDIO_HOST_ENDIANNESS, - } - }, - - .fixed_in = { /* ADC fixed settings */ - .enabled = 1, - .nb_voices = 1, - .greedy = 1, - .settings = { - .freq = 44100, - .nchannels = 2, - .fmt = AUDIO_FORMAT_S16, - .endianness = AUDIO_HOST_ENDIANNESS, - } - }, - - .period = { .hertz = 100 }, - .try_poll_in = 1, - .try_poll_out = 1, -}; - static AudioState glob_audio_state; const struct mixeng_volume nominal_volume = { @@ -151,9 +101,6 @@ const struct mixeng_volume nominal_volume = { #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED #error No its not #else -static void audio_print_options (const char *prefix, - struct audio_option *opt); - int audio_bug (const char *funcname, int cond) { if (cond) { @@ -161,16 +108,9 @@ int audio_bug (const char *funcname, int cond) AUD_log (NULL, "A bug was just triggered in %s\n", funcname); if (!shown) { - struct audio_driver *d; - shown = 1; AUD_log (NULL, "Save all your work and restart without audio\n"); - AUD_log (NULL, "Please send bug report to av1474@comtv.ru\n"); AUD_log (NULL, "I am sorry\n"); - d = glob_audio_state.drv; - if (d) { - audio_print_options (d->name, d->options); - } } AUD_log (NULL, "Context:\n"); @@ -232,31 +172,6 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size) return g_malloc0 (len); } -static char *audio_alloc_prefix (const char *s) -{ - const char qemu_prefix[] = "QEMU_"; - size_t len, i; - char *r, *u; - - if (!s) { - return NULL; - } - - len = strlen (s); - r = g_malloc (len + sizeof (qemu_prefix)); - - u = r + sizeof (qemu_prefix) - 1; - - pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix); - pstrcat (r, len + sizeof (qemu_prefix), s); - - for (i = 0; i < len; ++i) { - u[i] = qemu_toupper(u[i]); - } - - return r; -} - static const char *audio_audfmt_to_string (AudioFormat fmt) { switch (fmt) { @@ -382,78 +297,6 @@ void AUD_log (const char *cap, const char *fmt, ...) va_end (ap); } -static void audio_print_options (const char *prefix, - struct audio_option *opt) -{ - char *uprefix; - - if (!prefix) { - dolog ("No prefix specified\n"); - return; - } - - if (!opt) { - dolog ("No options\n"); - return; - } - - uprefix = audio_alloc_prefix (prefix); - - for (; opt->name; opt++) { - const char *state = "default"; - printf (" %s_%s: ", uprefix, opt->name); - - if (opt->overriddenp && *opt->overriddenp) { - state = "current"; - } - - switch (opt->tag) { - case AUD_OPT_BOOL: - { - int *intp = opt->valp; - printf ("boolean, %s = %d\n", state, *intp ? 1 : 0); - } - break; - - case AUD_OPT_INT: - { - int *intp = opt->valp; - printf ("integer, %s = %d\n", state, *intp); - } - break; - - case AUD_OPT_FMT: - { - AudioFormat *fmtp = opt->valp; - printf ( - "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n", - state, - audio_audfmt_to_string (*fmtp) - ); - } - break; - - case AUD_OPT_STR: - { - const char **strp = opt->valp; - printf ("string, %s = %s\n", - state, - *strp ? *strp : "(not set)"); - } - break; - - default: - printf ("???\n"); - dolog ("Bad value tag for option %s_%s %d\n", - uprefix, opt->name, opt->tag); - break; - } - printf (" %s\n", opt->descr); - } - - g_free (uprefix); -} - static void audio_process_options (const char *prefix, struct audio_option *opt) { @@ -1161,11 +1004,11 @@ static void audio_reset_timer (AudioState *s) { if (audio_is_timer_needed ()) { timer_mod_anticipate_ns(s->ts, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks); + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->period_ticks); if (!audio_timer_running) { audio_timer_running = true; audio_timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - trace_audio_timer_start(conf.period.ticks / SCALE_MS); + trace_audio_timer_start(s->period_ticks / SCALE_MS); } } else { timer_del(s->ts); @@ -1179,16 +1022,17 @@ static void audio_reset_timer (AudioState *s) static void audio_timer (void *opaque) { int64_t now, diff; + AudioState *s = opaque; now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); diff = now - audio_timer_last; - if (diff > conf.period.ticks * 3 / 2) { + if (diff > s->period_ticks * 3 / 2) { trace_audio_timer_delayed(diff / SCALE_MS); } audio_timer_last = now; - audio_run ("timer"); - audio_reset_timer (opaque); + audio_run("timer"); + audio_reset_timer(s); } /* @@ -1248,7 +1092,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out); + hw->pcm_ops->ctl_out(hw, VOICE_ENABLE, true /* todo */); audio_reset_timer (s); } } @@ -1293,7 +1137,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in); + hw->pcm_ops->ctl_in(hw, VOICE_ENABLE, true /* todo */); audio_reset_timer (s); } } @@ -1614,169 +1458,13 @@ void audio_run (const char *msg) #endif } -static struct audio_option audio_options[] = { - /* DAC */ - { - .name = "DAC_FIXED_SETTINGS", - .tag = AUD_OPT_BOOL, - .valp = &conf.fixed_out.enabled, - .descr = "Use fixed settings for host DAC" - }, - { - .name = "DAC_FIXED_FREQ", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_out.settings.freq, - .descr = "Frequency for fixed host DAC" - }, - { - .name = "DAC_FIXED_FMT", - .tag = AUD_OPT_FMT, - .valp = &conf.fixed_out.settings.fmt, - .descr = "Format for fixed host DAC" - }, - { - .name = "DAC_FIXED_CHANNELS", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_out.settings.nchannels, - .descr = "Number of channels for fixed DAC (1 - mono, 2 - stereo)" - }, - { - .name = "DAC_VOICES", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_out.nb_voices, - .descr = "Number of voices for DAC" - }, - { - .name = "DAC_TRY_POLL", - .tag = AUD_OPT_BOOL, - .valp = &conf.try_poll_out, - .descr = "Attempt using poll mode for DAC" - }, - /* ADC */ - { - .name = "ADC_FIXED_SETTINGS", - .tag = AUD_OPT_BOOL, - .valp = &conf.fixed_in.enabled, - .descr = "Use fixed settings for host ADC" - }, - { - .name = "ADC_FIXED_FREQ", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_in.settings.freq, - .descr = "Frequency for fixed host ADC" - }, - { - .name = "ADC_FIXED_FMT", - .tag = AUD_OPT_FMT, - .valp = &conf.fixed_in.settings.fmt, - .descr = "Format for fixed host ADC" - }, - { - .name = "ADC_FIXED_CHANNELS", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_in.settings.nchannels, - .descr = "Number of channels for fixed ADC (1 - mono, 2 - stereo)" - }, - { - .name = "ADC_VOICES", - .tag = AUD_OPT_INT, - .valp = &conf.fixed_in.nb_voices, - .descr = "Number of voices for ADC" - }, - { - .name = "ADC_TRY_POLL", - .tag = AUD_OPT_BOOL, - .valp = &conf.try_poll_in, - .descr = "Attempt using poll mode for ADC" - }, - /* Misc */ - { - .name = "TIMER_PERIOD", - .tag = AUD_OPT_INT, - .valp = &conf.period.hertz, - .descr = "Timer period in HZ (0 - use lowest possible)" - }, - { /* End of list */ } -}; - -static void audio_pp_nb_voices (const char *typ, int nb) -{ - switch (nb) { - case 0: - printf ("Does not support %s\n", typ); - break; - case 1: - printf ("One %s voice\n", typ); - break; - case INT_MAX: - printf ("Theoretically supports many %s voices\n", typ); - break; - default: - printf ("Theoretically supports up to %d %s voices\n", nb, typ); - break; - } - -} - -void AUD_help (void) -{ - struct audio_driver *d; - - /* make sure we print the help text for modular drivers too */ - audio_module_load_all(); - - audio_process_options ("AUDIO", audio_options); - QLIST_FOREACH(d, &audio_drivers, next) { - if (d->options) { - audio_process_options (d->name, d->options); - } - } - - printf ("Audio options:\n"); - audio_print_options ("AUDIO", audio_options); - printf ("\n"); - - printf ("Available drivers:\n"); - - QLIST_FOREACH(d, &audio_drivers, next) { - - printf ("Name: %s\n", d->name); - printf ("Description: %s\n", d->descr); - - audio_pp_nb_voices ("playback", d->max_voices_out); - audio_pp_nb_voices ("capture", d->max_voices_in); - - if (d->options) { - printf ("Options:\n"); - audio_print_options (d->name, d->options); - } - else { - printf ("No options\n"); - } - printf ("\n"); - } - - printf ( - "Options are settable through environment variables.\n" - "Example:\n" -#ifdef _WIN32 - " set QEMU_AUDIO_DRV=wav\n" - " set QEMU_WAV_PATH=c:\\tune.wav\n" -#else - " export QEMU_AUDIO_DRV=wav\n" - " export QEMU_WAV_PATH=$HOME/tune.wav\n" - "(for csh replace export with setenv in the above)\n" -#endif - " qemu ...\n\n" - ); -} - -static int audio_driver_init (AudioState *s, struct audio_driver *drv) +static int audio_driver_init(AudioState *s, struct audio_driver *drv, + Audiodev *dev) { if (drv->options) { audio_process_options (drv->name, drv->options); } - s->drv_opaque = drv->init (); + s->drv_opaque = drv->init(dev); if (s->drv_opaque) { audio_init_nb_voices_out (drv); @@ -1800,11 +1488,11 @@ static void audio_vm_change_state_handler (void *opaque, int running, s->vm_running = running; while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { - hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out); + hwo->pcm_ops->ctl_out(hwo, op, true /* todo */); } while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { - hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in); + hwi->pcm_ops->ctl_in(hwi, op, true /* todo */); } audio_reset_timer (s); } @@ -1854,6 +1542,11 @@ void audio_cleanup(void) s->drv->fini (s->drv_opaque); s->drv = NULL; } + + if (s->dev) { + qapi_free_Audiodev(s->dev); + s->dev = NULL; + } } static const VMStateDescription vmstate_audio = { @@ -1865,19 +1558,58 @@ static const VMStateDescription vmstate_audio = { } }; -static void audio_init (void) +static void audio_validate_opts(Audiodev *dev, Error **errp); + +static AudiodevListEntry *audiodev_find( + AudiodevListHead *head, const char *drvname) +{ + AudiodevListEntry *e; + QSIMPLEQ_FOREACH(e, head, next) { + if (strcmp(AudiodevDriver_str(e->dev->driver), drvname) == 0) { + return e; + } + } + + return NULL; +} + +static int audio_init(Audiodev *dev) { size_t i; int done = 0; - const char *drvname; + const char *drvname = NULL; VMChangeStateEntry *e; AudioState *s = &glob_audio_state; struct audio_driver *driver; + /* silence gcc warning about uninitialized variable */ + AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head); if (s->drv) { - return; + if (dev) { + dolog("Cannot create more than one audio backend, sorry\n"); + qapi_free_Audiodev(dev); + } + return -1; } + if (dev) { + /* -audiodev option */ + drvname = AudiodevDriver_str(dev->driver); + } else { + /* legacy implicit initialization */ + head = audio_handle_legacy_opts(); + /* + * In case of legacy initialization, all Audiodevs in the list will have + * the same configuration (except the driver), so it does't matter which + * one we chose. We need an Audiodev to set up AudioState before we can + * init a driver. Also note that dev at this point is still in the + * list. + */ + dev = QSIMPLEQ_FIRST(&head)->dev; + audio_validate_opts(dev, &error_abort); + } + s->dev = dev; + QLIST_INIT (&s->hw_head_out); QLIST_INIT (&s->hw_head_in); QLIST_INIT (&s->cap_head); @@ -1885,10 +1617,8 @@ static void audio_init (void) s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s); - audio_process_options ("AUDIO", audio_options); - - s->nb_hw_voices_out = conf.fixed_out.nb_voices; - s->nb_hw_voices_in = conf.fixed_in.nb_voices; + s->nb_hw_voices_out = dev->out->voices; + s->nb_hw_voices_in = dev->in->voices; if (s->nb_hw_voices_out <= 0) { dolog ("Bogus number of playback voices %d, setting to 1\n", @@ -1902,46 +1632,41 @@ static void audio_init (void) s->nb_hw_voices_in = 0; } - { - int def; - drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def); - } - if (drvname) { driver = audio_driver_lookup(drvname); if (driver) { - done = !audio_driver_init(s, driver); + done = !audio_driver_init(s, driver, dev); } else { dolog ("Unknown audio driver `%s'\n", drvname); - dolog ("Run with -audio-help to list available drivers\n"); } - } - - if (!done) { - for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) { + } else { + for (i = 0; audio_prio_list[i]; i++) { + AudiodevListEntry *e = audiodev_find(&head, audio_prio_list[i]); driver = audio_driver_lookup(audio_prio_list[i]); - if (driver && driver->can_be_default) { - done = !audio_driver_init(s, driver); + + if (e && driver) { + s->dev = dev = e->dev; + audio_validate_opts(dev, &error_abort); + if ((done = !audio_driver_init(s, driver, dev))) { + e->dev = NULL; + break; + } } } } + audio_free_audiodev_list(&head); if (!done) { driver = audio_driver_lookup("none"); - done = !audio_driver_init(s, driver); + done = !audio_driver_init(s, driver, dev); assert(done); dolog("warning: Using timer based audio emulation\n"); } - if (conf.period.hertz <= 0) { - if (conf.period.hertz < 0) { - dolog ("warning: Timer period is negative - %d " - "treating as zero\n", - conf.period.hertz); - } - conf.period.ticks = 1; + if (dev->timer_period <= 0) { + s->period_ticks = 1; } else { - conf.period.ticks = NANOSECONDS_PER_SECOND / conf.period.hertz; + s->period_ticks = NANOSECONDS_PER_SECOND / dev->timer_period; } e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s); @@ -1952,11 +1677,22 @@ static void audio_init (void) QLIST_INIT (&s->card_head); vmstate_register (NULL, 0, &vmstate_audio, s); + return 0; +} + +void audio_free_audiodev_list(AudiodevListHead *head) +{ + AudiodevListEntry *e; + while ((e = QSIMPLEQ_FIRST(head))) { + QSIMPLEQ_REMOVE_HEAD(head, next); + qapi_free_Audiodev(e->dev); + g_free(e); + } } void AUD_register_card (const char *name, QEMUSoundCard *card) { - audio_init (); + audio_init(NULL); card->name = g_strdup (name); memset (&card->entries, 0, sizeof (card->entries)); QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries); @@ -2127,3 +1863,145 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) } } } + +static void audio_validate_per_direction_opts( + AudiodevPerDirectionOptions **pdo, bool *has_pdo, Error **errp) +{ + if (!*has_pdo) { + *pdo = g_malloc0(sizeof(AudiodevPerDirectionOptions)); + *has_pdo = true; + } + + if (!(*pdo)->has_fixed_settings) { + (*pdo)->has_fixed_settings = true; + (*pdo)->fixed_settings = true; + } + if (!(*pdo)->fixed_settings && + ((*pdo)->has_frequency || (*pdo)->has_channels || (*pdo)->has_format)) { + error_setg(errp, + "You can't use frequency, channels or format with fixed-settings=off"); + return; + } + + if (!(*pdo)->has_frequency) { + (*pdo)->has_frequency = true; + (*pdo)->frequency = 44100; + } + if (!(*pdo)->has_channels) { + (*pdo)->has_channels = true; + (*pdo)->channels = 2; + } + if (!(*pdo)->has_voices) { + (*pdo)->has_voices = true; + (*pdo)->voices = 1; + } + if (!(*pdo)->has_format) { + (*pdo)->has_format = true; + (*pdo)->format = AUDIO_FORMAT_S16; + } +} + +static void audio_validate_opts(Audiodev *dev, Error **errp) +{ + Error *err = NULL; + + audio_validate_per_direction_opts(&dev->in, &dev->has_in, &err); + if (err) { + error_propagate(errp, err); + return; + } + + audio_validate_per_direction_opts(&dev->out, &dev->has_out, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (!dev->has_timer_period) { + dev->has_timer_period = true; + dev->timer_period = 10000; /* 100Hz -> 10ms */ + } +} + +void audio_parse_option(const char *opt) +{ + AudiodevListEntry *e; + Audiodev *dev = NULL; + + Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal); + visit_type_Audiodev(v, NULL, &dev, &error_fatal); + visit_free(v); + + audio_validate_opts(dev, &error_fatal); + + e = g_malloc0(sizeof(AudiodevListEntry)); + e->dev = dev; + QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next); +} + +void audio_init_audiodevs(void) +{ + AudiodevListEntry *e; + + QSIMPLEQ_FOREACH(e, &audiodevs, next) { + audio_init(e->dev); + } +} + +audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo) +{ + return (audsettings) { + .freq = pdo->frequency, + .nchannels = pdo->channels, + .fmt = pdo->format, + .endianness = AUDIO_HOST_ENDIANNESS, + }; +} + +int audioformat_bytes_per_sample(AudioFormat fmt) +{ + switch (fmt) { + case AUDIO_FORMAT_U8: + case AUDIO_FORMAT_S8: + return 1; + + case AUDIO_FORMAT_U16: + case AUDIO_FORMAT_S16: + return 2; + + case AUDIO_FORMAT_U32: + case AUDIO_FORMAT_S32: + return 4; + + case AUDIO_FORMAT__MAX: + ; + } + abort(); +} + + +/* frames = freq * usec / 1e6 */ +int audio_buffer_frames(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs) +{ + uint64_t usecs = pdo->has_buffer_len ? pdo->buffer_len : def_usecs; + return (as->freq * usecs + 500000) / 1000000; +} + +/* samples = channels * frames = channels * freq * usec / 1e6 */ +int audio_buffer_samples(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs) +{ + return as->nchannels * audio_buffer_frames(pdo, as, def_usecs); +} + +/* + * bytes = bytes_per_sample * samples = + * bytes_per_sample * channels * freq * usec / 1e6 + */ +int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo, + audsettings *as, int def_usecs) +{ + return audio_buffer_samples(pdo, as, def_usecs) * + audioformat_bytes_per_sample(as->fmt); +} diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c new file mode 100644 index 0000000000..e094b2bd61 --- /dev/null +++ b/audio/audio_legacy.c @@ -0,0 +1,294 @@ +/* + * QEMU Audio subsystem: legacy configuration handling + * + * Copyright (c) 2015-2019 Zoltán Kővágó + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "audio.h" +#include "audio_int.h" +#include "qemu-common.h" +#include "qemu/cutils.h" +#include "qapi/error.h" +#include "qapi/qapi-visit-audio.h" +#include "qapi/visitor-impl.h" + +#define AUDIO_CAP "audio-legacy" +#include "audio_int.h" + +static uint32_t toui32(const char *str) +{ + unsigned long long ret; + if (parse_uint_full(str, &ret, 10) || ret > UINT32_MAX) { + dolog("Invalid integer value `%s'\n", str); + exit(1); + } + return ret; +} + +/* helper functions to convert env variables */ +static void get_bool(const char *env, bool *dst, bool *has_dst) +{ + const char *val = getenv(env); + if (val) { + *dst = toui32(val) != 0; + *has_dst = true; + } +} + +static void get_int(const char *env, uint32_t *dst, bool *has_dst) +{ + const char *val = getenv(env); + if (val) { + *dst = toui32(val); + *has_dst = true; + } +} + +static void get_fmt(const char *env, AudioFormat *dst, bool *has_dst) +{ + const char *val = getenv(env); + if (val) { + size_t i; + for (i = 0; AudioFormat_lookup.size; ++i) { + if (strcasecmp(val, AudioFormat_lookup.array[i]) == 0) { + *dst = i; + *has_dst = true; + return; + } + } + + dolog("Invalid audio format `%s'\n", val); + exit(1); + } +} + +/* backend specific functions */ +/* todo */ + +/* general */ +static void handle_per_direction( + AudiodevPerDirectionOptions *pdo, const char *prefix) +{ + char buf[64]; + size_t len = strlen(prefix); + + memcpy(buf, prefix, len); + strcpy(buf + len, "FIXED_SETTINGS"); + get_bool(buf, &pdo->fixed_settings, &pdo->has_fixed_settings); + + strcpy(buf + len, "FIXED_FREQ"); + get_int(buf, &pdo->frequency, &pdo->has_frequency); + + strcpy(buf + len, "FIXED_FMT"); + get_fmt(buf, &pdo->format, &pdo->has_format); + + strcpy(buf + len, "FIXED_CHANNELS"); + get_int(buf, &pdo->channels, &pdo->has_channels); + + strcpy(buf + len, "VOICES"); + get_int(buf, &pdo->voices, &pdo->has_voices); +} + +static AudiodevListEntry *legacy_opt(const char *drvname) +{ + AudiodevListEntry *e = g_malloc0(sizeof(AudiodevListEntry)); + e->dev = g_malloc0(sizeof(Audiodev)); + e->dev->id = g_strdup(drvname); + e->dev->driver = qapi_enum_parse( + &AudiodevDriver_lookup, drvname, -1, &error_abort); + e->dev->in = g_malloc0(sizeof(AudiodevPerDirectionOptions)); + e->dev->has_in = true; + e->dev->out = g_malloc0(sizeof(AudiodevPerDirectionOptions)); + e->dev->has_out = true; + + handle_per_direction(e->dev->in, "QEMU_AUDIO_ADC_"); + handle_per_direction(e->dev->out, "QEMU_AUDIO_DAC_"); + + get_int("QEMU_AUDIO_TIMER_PERIOD", + &e->dev->timer_period, &e->dev->has_timer_period); + + return e; +} + +AudiodevListHead audio_handle_legacy_opts(void) +{ + const char *drvname = getenv("QEMU_AUDIO_DRV"); + AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head); + + if (drvname) { + AudiodevListEntry *e; + audio_driver *driver = audio_driver_lookup(drvname); + if (!driver) { + dolog("Unknown audio driver `%s'\n", drvname); + exit(1); + } + e = legacy_opt(drvname); + QSIMPLEQ_INSERT_TAIL(&head, e, next); + } else { + for (int i = 0; audio_prio_list[i]; i++) { + audio_driver *driver = audio_driver_lookup(audio_prio_list[i]); + if (driver && driver->can_be_default) { + AudiodevListEntry *e = legacy_opt(driver->name); + QSIMPLEQ_INSERT_TAIL(&head, e, next); + } + } + if (QSIMPLEQ_EMPTY(&head)) { + dolog("Internal error: no default audio driver available\n"); + exit(1); + } + } + + return head; +} + +/* visitor to print -audiodev option */ +typedef struct { + Visitor visitor; + + bool comma; + GList *path; +} LegacyPrintVisitor; + +static void lv_start_struct(Visitor *v, const char *name, void **obj, + size_t size, Error **errp) +{ + LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; + lv->path = g_list_append(lv->path, g_strdup(name)); +} + +static void lv_end_struct(Visitor *v, void **obj) +{ + LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; + lv->path = g_list_delete_link(lv->path, g_list_last(lv->path)); +} + +static void lv_print_key(Visitor *v, const char *name) +{ + GList *e; + LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; + if (lv->comma) { + putchar(','); + } else { + lv->comma = true; + } + + for (e = lv->path; e; e = e->next) { + if (e->data) { + printf("%s.", (const char *) e->data); + } + } + + printf("%s=", name); +} + +static void lv_type_int64(Visitor *v, const char *name, int64_t *obj, + Error **errp) +{ + lv_print_key(v, name); + printf("%" PRIi64, *obj); +} + +static void lv_type_uint64(Visitor *v, const char *name, uint64_t *obj, + Error **errp) +{ + lv_print_key(v, name); + printf("%" PRIu64, *obj); +} + +static void lv_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) +{ + lv_print_key(v, name); + printf("%s", *obj ? "on" : "off"); +} + +static void lv_type_str(Visitor *v, const char *name, char **obj, Error **errp) +{ + const char *str = *obj; + lv_print_key(v, name); + + while (*str) { + if (*str == ',') { + putchar(','); + } + putchar(*str++); + } +} + +static void lv_complete(Visitor *v, void *opaque) +{ + LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; + assert(lv->path == NULL); +} + +static void lv_free(Visitor *v) +{ + LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; + + g_list_free_full(lv->path, g_free); + g_free(lv); +} + +static Visitor *legacy_visitor_new(void) +{ + LegacyPrintVisitor *lv = g_malloc0(sizeof(LegacyPrintVisitor)); + + lv->visitor.start_struct = lv_start_struct; + lv->visitor.end_struct = lv_end_struct; + /* lists not supported */ + lv->visitor.type_int64 = lv_type_int64; + lv->visitor.type_uint64 = lv_type_uint64; + lv->visitor.type_bool = lv_type_bool; + lv->visitor.type_str = lv_type_str; + + lv->visitor.type = VISITOR_OUTPUT; + lv->visitor.complete = lv_complete; + lv->visitor.free = lv_free; + + return &lv->visitor; +} + +void audio_legacy_help(void) +{ + AudiodevListHead head; + AudiodevListEntry *e; + + printf("Environment variable based configuration deprecated.\n"); + printf("Please use the new -audiodev option.\n"); + + head = audio_handle_legacy_opts(); + printf("\nEquivalent -audiodev to your current environment variables:\n"); + if (!getenv("QEMU_AUDIO_DRV")) { + printf("(Since you didn't specify QEMU_AUDIO_DRV, I'll list all possibilities)\n"); + } + + QSIMPLEQ_FOREACH(e, &head, next) { + Visitor *v; + Audiodev *dev = e->dev; + printf("-audiodev "); + + v = legacy_visitor_new(); + visit_type_Audiodev(v, NULL, &dev, &error_abort); + visit_free(v); + + printf("\n"); + } + audio_free_audiodev_list(&head); +} diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 638c60b300..7d4225dbee 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -685,7 +685,7 @@ static CoreaudioConf glob_conf = { .nbuffers = 4, }; -static void *coreaudio_audio_init (void) +static void *coreaudio_audio_init(Audiodev *dev) { CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf)); *conf = glob_conf; diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index 3ed73a30d1..02fe777cba 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -783,7 +783,7 @@ static void dsound_audio_fini (void *opaque) g_free(s); } -static void *dsound_audio_init (void) +static void *dsound_audio_init(Audiodev *dev) { int err; HRESULT hr; diff --git a/audio/noaudio.c b/audio/noaudio.c index 1bfebeca7d..79690af1ea 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -136,7 +136,7 @@ static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static void *no_audio_init (void) +static void *no_audio_init(Audiodev *dev) { return &no_audio_init; } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 355e8fbda5..e0cadbef29 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -842,7 +842,7 @@ static OSSConf glob_conf = { .policy = 5 }; -static void *oss_audio_init (void) +static void *oss_audio_init(Audiodev *dev) { OSSConf *conf = g_malloc(sizeof(OSSConf)); *conf = glob_conf; diff --git a/audio/paaudio.c b/audio/paaudio.c index f1f9a741ac..0981f010c9 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -812,7 +812,7 @@ static PAConf glob_conf = { .samples = 4096, }; -static void *qpa_audio_init (void) +static void *qpa_audio_init(Audiodev *dev) { paaudio *g = g_malloc(sizeof(paaudio)); g->conf = glob_conf; diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index aa42ea26bf..097841fde1 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -436,7 +436,7 @@ static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static void *sdl_audio_init (void) +static void *sdl_audio_init(Audiodev *dev) { SDLAudioState *s = &glob_sdl; if (s->driver_created) { diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 3aeb0cb357..affc3df17f 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -77,7 +77,7 @@ static const SpiceRecordInterface record_sif = { .base.minor_version = SPICE_INTERFACE_RECORD_MINOR, }; -static void *spice_audio_init (void) +static void *spice_audio_init(Audiodev *dev) { if (!using_spice) { return NULL; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 35a614785e..9eff3555b3 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -232,7 +232,7 @@ static WAVConf glob_conf = { .wav_path = "qemu.wav" }; -static void *wav_audio_init (void) +static void *wav_audio_init(Audiodev *dev) { WAVConf *conf = g_malloc(sizeof(WAVConf)); *conf = glob_conf; diff --git a/vl.c b/vl.c index bc9fbec654..80aa0458fc 100644 --- a/vl.c +++ b/vl.c @@ -3302,9 +3302,12 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_BT, optarg); break; case QEMU_OPTION_audio_help: - AUD_help (); + audio_legacy_help(); exit (0); break; + case QEMU_OPTION_audiodev: + audio_parse_option(optarg); + break; case QEMU_OPTION_soundhw: select_soundhw (optarg); break; @@ -4533,6 +4536,8 @@ int main(int argc, char **argv, char **envp) /* do monitor/qmp handling at preconfig state if requested */ main_loop(); + audio_init_audiodevs(); + /* from here on runstate is RUN_STATE_PRELAUNCH */ machine_run_board_init(current_machine); diff --git a/audio/Makefile.objs b/audio/Makefile.objs index db4fa7f18f..dca87f6347 100644 --- a/audio/Makefile.objs +++ b/audio/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o +common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o common-obj-$(CONFIG_SPICE) += spiceaudio.o common-obj-$(CONFIG_AUDIO_COREAUDIO) += coreaudio.o common-obj-$(CONFIG_AUDIO_DSOUND) += dsoundaudio.o From patchwork Wed Jan 16 23:36:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767151 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE60813A4 for ; Wed, 16 Jan 2019 23:51:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E8492FC0E for ; Wed, 16 Jan 2019 23:51:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92E5E2FBF5; Wed, 16 Jan 2019 23:51:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 670C72F735 for ; Wed, 16 Jan 2019 23:51:53 +0000 (UTC) Received: from localhost ([127.0.0.1]:34707 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuyN-00072k-IT for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:51:51 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58020) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000478-6K for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002vl-BA for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:40774) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002dB-TM for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:46 -0500 Received: by mail-wr1-x444.google.com with SMTP id p4so8949704wrt.7 for ; Wed, 16 Jan 2019 15:37:31 -0800 (PST) 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=Z0gemdiqWr5j1o7uvbo5hwDZJrCLSWw9wq8pleLXRSs=; b=QJzLN4IJAFNd94ZE9sPxMwtkYDV8Eu8wTS6TzLNMejpDredxNbLYPXm6Ci+WI7Rg7q LS6WDKBY9yj9K50fV4k+SMKvwyJrW0/jyxsoDfN5FpktyJKhs+GcnbRUd5/9gwwKvOEt LajAwxKpKIEE57F3gdu+hrcDY73S6WqXe0dZlQVxciy8OUKJ/p+WJS1wg/sdAkZ1eMQi VaVt9V/EJyoxNuegR7Od8+nbydjzN4NIzHft8ZJcPXg/Iks3jdApa+tq8mKCO7mZxJtn rOrFdGiEOUzSYZmvHjGAEMUh9AoHuJEV/fqaRytORwFOF75VI+jOv5wmiT6VlvwjFaHB Nxlg== 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=Z0gemdiqWr5j1o7uvbo5hwDZJrCLSWw9wq8pleLXRSs=; b=rouo270BD6GEtHKb525aiX1d4CmG8TKUQKC9YRO7ZLy/KipTPugmYj2Kde2jrZZVVf U2kMaQaRT+wImCU+Ozry7DvEhGa19Cg15p/rSVLbUC8EDWfX0PAgKmZpmOtcxqT9m0aW 5S4xgRl8sbKTDvCr6hAFV+MA2S7E5DBQOYSkfjuoKWFp5T6PVXY66EWVOXtNVyDtqfye 3AFB+1LDqsR6EaOkO23YgiYfzdBsJsNQeH8lsTlvAOyAR9t3QCmfgMwZacXQSMPYLgrR NcQzXQrotVJLPdYW3+puLeJqPp4lEIGicIjPeErl9xB9NUTmpPhJTF7t5O4fezCcTDC/ 8ReQ== X-Gm-Message-State: AJcUukdr+MGMp1N7grDt5WNQHFUFbCfI6R7SkSASBw/q7GIqRq+X7WNX JWqKnFUG8+wLXGfoQ+qr/pPDNt/ZU3I= X-Google-Smtp-Source: ALg8bN59F8qx0DO+fzeesl42SBo0DTNuwZOVORKeCARViViCTBltRlxi2V4rXuARQFLFagKKblXE0Q== X-Received: by 2002:adf:8323:: with SMTP id 32mr9137214wrd.176.1547681850045; Wed, 16 Jan 2019 15:37:30 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:29 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:38 +0100 Message-Id: <3c15ec783e0143566b75215843872a0bdc186af5.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 05/50] alsaaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/alsaaudio.c | 330 ++++++++++++++----------------------------- audio/audio_legacy.c | 94 +++++++++++- 2 files changed, 198 insertions(+), 226 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 8302f3e882..6b43a06180 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -33,28 +33,9 @@ #define AUDIO_CAP "alsa" #include "audio_int.h" -typedef struct ALSAConf { - int size_in_usec_in; - int size_in_usec_out; - const char *pcm_name_in; - const char *pcm_name_out; - unsigned int buffer_size_in; - unsigned int period_size_in; - unsigned int buffer_size_out; - unsigned int period_size_out; - unsigned int threshold; - - int buffer_size_in_overridden; - int period_size_in_overridden; - - int buffer_size_out_overridden; - int period_size_out_overridden; -} ALSAConf; - struct pollhlp { snd_pcm_t *handle; struct pollfd *pfds; - ALSAConf *conf; int count; int mask; }; @@ -66,6 +47,7 @@ typedef struct ALSAVoiceOut { void *pcm_buf; snd_pcm_t *handle; struct pollhlp pollhlp; + Audiodev *dev; } ALSAVoiceOut; typedef struct ALSAVoiceIn { @@ -73,16 +55,13 @@ typedef struct ALSAVoiceIn { snd_pcm_t *handle; void *pcm_buf; struct pollhlp pollhlp; + Audiodev *dev; } ALSAVoiceIn; struct alsa_params_req { int freq; snd_pcm_format_t fmt; int nchannels; - int size_in_usec; - int override_mask; - unsigned int buffer_size; - unsigned int period_size; }; struct alsa_params_obt { @@ -408,7 +387,8 @@ static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt, static void alsa_dump_info (struct alsa_params_req *req, struct alsa_params_obt *obt, - snd_pcm_format_t obtfmt) + snd_pcm_format_t obtfmt, + AudiodevPerDirectionOptions *pdo) { dolog ("parameter | requested value | obtained value\n"); dolog ("format | %10d | %10d\n", req->fmt, obtfmt); @@ -416,8 +396,9 @@ static void alsa_dump_info (struct alsa_params_req *req, req->nchannels, obt->nchannels); dolog ("frequency | %10d | %10d\n", req->freq, obt->freq); dolog ("============================================\n"); - dolog ("requested: buffer size %d period size %d\n", - req->buffer_size, req->period_size); + dolog ("requested: buffer len %" PRId32 " buffer count %" PRId32 "\n", + pdo->has_buffer_len ? pdo->buffer_len : 0, + pdo->has_buffer_count ? pdo->buffer_count : 0); dolog ("obtained: samples %ld\n", obt->samples); } @@ -451,23 +432,25 @@ static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) } } -static int alsa_open (int in, struct alsa_params_req *req, - struct alsa_params_obt *obt, snd_pcm_t **handlep, - ALSAConf *conf) +static int alsa_open(bool in, struct alsa_params_req *req, + struct alsa_params_obt *obt, snd_pcm_t **handlep, + Audiodev *dev) { + AudiodevPerDirectionOptions *pdo = in ? dev->in : dev->out; + AudiodevAlsaOptions *aopts = &dev->u.alsa; + AudiodevAlsaPerDirectionOptions *apdo = + in ? aopts->alsa_in : aopts->alsa_out; snd_pcm_t *handle; snd_pcm_hw_params_t *hw_params; int err; - int size_in_usec; unsigned int freq, nchannels; - const char *pcm_name = in ? conf->pcm_name_in : conf->pcm_name_out; + const char *pcm_name = apdo->has_dev ? apdo->dev : "default"; snd_pcm_uframes_t obt_buffer_size; const char *typ = in ? "ADC" : "DAC"; snd_pcm_format_t obtfmt; freq = req->freq; nchannels = req->nchannels; - size_in_usec = req->size_in_usec; snd_pcm_hw_params_alloca (&hw_params); @@ -527,79 +510,49 @@ static int alsa_open (int in, struct alsa_params_req *req, goto err; } - if (req->buffer_size) { - unsigned long obt; + if (pdo->buffer_count) { + if (pdo->buffer_len) { + int64_t req = pdo->buffer_len * pdo->buffer_count; - if (size_in_usec) { int dir = 0; - unsigned int btime = req->buffer_size; + unsigned int btime = req; - err = snd_pcm_hw_params_set_buffer_time_near ( - handle, - hw_params, - &btime, - &dir - ); - obt = btime; - } - else { - snd_pcm_uframes_t bsize = req->buffer_size; + err = snd_pcm_hw_params_set_buffer_time_near( + handle, hw_params, &btime, &dir); - err = snd_pcm_hw_params_set_buffer_size_near ( - handle, - hw_params, - &bsize - ); - obt = bsize; - } - if (err < 0) { - alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n", - size_in_usec ? "time" : "size", req->buffer_size); - goto err; - } + if (err < 0) { + alsa_logerr2(err, typ, + "Failed to set buffer time to %" PRId64 "\n", + req); + goto err; + } - if ((req->override_mask & 2) && (obt - req->buffer_size)) - dolog ("Requested buffer %s %u was rejected, using %lu\n", - size_in_usec ? "time" : "size", req->buffer_size, obt); + if (pdo->has_buffer_count && btime != req) { + dolog("Requested buffer time %" PRId64 + " was rejected, using %u\n", req, btime); + } + } else { + dolog("Can't set buffer-count without buffer-len!\n"); + } } - if (req->period_size) { - unsigned long obt; + if (pdo->buffer_len) { + int dir = 0; + unsigned int ptime = pdo->buffer_len; - if (size_in_usec) { - int dir = 0; - unsigned int ptime = req->period_size; - - err = snd_pcm_hw_params_set_period_time_near ( - handle, - hw_params, - &ptime, - &dir - ); - obt = ptime; - } - else { - int dir = 0; - snd_pcm_uframes_t psize = req->period_size; - - err = snd_pcm_hw_params_set_period_size_near ( - handle, - hw_params, - &psize, - &dir - ); - obt = psize; - } + err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &ptime, + &dir); if (err < 0) { - alsa_logerr2 (err, typ, "Failed to set period %s to %d\n", - size_in_usec ? "time" : "size", req->period_size); + alsa_logerr2(err, typ, "Failed to set period time to %" PRId32 "\n", + pdo->buffer_len); goto err; } - if (((req->override_mask & 1) && (obt - req->period_size))) - dolog ("Requested period %s %u was rejected, using %lu\n", - size_in_usec ? "time" : "size", req->period_size, obt); + if (pdo->has_buffer_len && ptime != pdo->buffer_len) { + dolog("Requested period time %" PRId32 " was rejected, using %d\n", + pdo->buffer_len, ptime); + } } err = snd_pcm_hw_params (handle, hw_params); @@ -631,33 +584,10 @@ static int alsa_open (int in, struct alsa_params_req *req, goto err; } - if (!in && conf->threshold) { - snd_pcm_uframes_t threshold; - int bytes_per_sec; - - bytes_per_sec = freq << (nchannels == 2); - - switch (obt->fmt) { - case AUDIO_FORMAT_S8: - case AUDIO_FORMAT_U8: - break; - - case AUDIO_FORMAT_S16: - case AUDIO_FORMAT_U16: - bytes_per_sec <<= 1; - break; - - case AUDIO_FORMAT_S32: - case AUDIO_FORMAT_U32: - bytes_per_sec <<= 2; - break; - - default: - abort(); - } - - threshold = (conf->threshold * bytes_per_sec) / 1000; - alsa_set_threshold (handle, threshold); + if (!in && aopts->has_threshold && aopts->threshold) { + struct audsettings as = { .freq = freq }; + alsa_set_threshold(handle, + audio_buffer_frames(pdo, &as, aopts->threshold)); } obt->nchannels = nchannels; @@ -670,11 +600,11 @@ static int alsa_open (int in, struct alsa_params_req *req, obt->nchannels != req->nchannels || obt->freq != req->freq) { dolog ("Audio parameters for %s\n", typ); - alsa_dump_info (req, obt, obtfmt); + alsa_dump_info (req, obt, obtfmt, pdo); } #ifdef DEBUG - alsa_dump_info (req, obt, obtfmt); + alsa_dump_info (req, obt, obtfmt, pdo); #endif return 0; @@ -800,19 +730,13 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, struct alsa_params_obt obt; snd_pcm_t *handle; struct audsettings obt_as; - ALSAConf *conf = drv_opaque; + Audiodev *dev = drv_opaque; req.fmt = aud_to_alsafmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.period_size = conf->period_size_out; - req.buffer_size = conf->buffer_size_out; - req.size_in_usec = conf->size_in_usec_out; - req.override_mask = - (conf->period_size_out_overridden ? 1 : 0) | - (conf->buffer_size_out_overridden ? 2 : 0); - if (alsa_open (0, &req, &obt, &handle, conf)) { + if (alsa_open (0, &req, &obt, &handle, dev)) { return -1; } @@ -833,7 +757,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, } alsa->handle = handle; - alsa->pollhlp.conf = conf; + alsa->dev = dev; return 0; } @@ -873,16 +797,12 @@ static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl) static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; + AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.alsa_out; switch (cmd) { case VOICE_ENABLE: { - va_list ap; - int poll_mode; - - va_start (ap, cmd); - poll_mode = va_arg (ap, int); - va_end (ap); + bool poll_mode = apdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode && alsa_poll_out (hw)) { @@ -911,19 +831,13 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) struct alsa_params_obt obt; snd_pcm_t *handle; struct audsettings obt_as; - ALSAConf *conf = drv_opaque; + Audiodev *dev = drv_opaque; req.fmt = aud_to_alsafmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.period_size = conf->period_size_in; - req.buffer_size = conf->buffer_size_in; - req.size_in_usec = conf->size_in_usec_in; - req.override_mask = - (conf->period_size_in_overridden ? 1 : 0) | - (conf->buffer_size_in_overridden ? 2 : 0); - if (alsa_open (1, &req, &obt, &handle, conf)) { + if (alsa_open (1, &req, &obt, &handle, dev)) { return -1; } @@ -944,7 +858,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } alsa->handle = handle; - alsa->pollhlp.conf = conf; + alsa->dev = dev; return 0; } @@ -1086,16 +1000,12 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size) static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; + AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.alsa_in; switch (cmd) { case VOICE_ENABLE: { - va_list ap; - int poll_mode; - - va_start (ap, cmd); - poll_mode = va_arg (ap, int); - va_end (ap); + bool poll_mode = apdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode && alsa_poll_in (hw)) { @@ -1118,88 +1028,59 @@ static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) return -1; } -static ALSAConf glob_conf = { - .buffer_size_out = 4096, - .period_size_out = 1024, - .pcm_name_out = "default", - .pcm_name_in = "default", -}; +static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions **apdo, + bool *has_apdo) +{ + if (!*has_apdo) { + *apdo = g_malloc0(sizeof(AudiodevAlsaPerDirectionOptions)); + *has_apdo = true; + } + + if (!(*apdo)->has_try_poll) { + (*apdo)->try_poll = true; + (*apdo)->has_try_poll = true; + } +} static void *alsa_audio_init(Audiodev *dev) { - ALSAConf *conf = g_malloc(sizeof(ALSAConf)); - *conf = glob_conf; - return conf; + AudiodevAlsaOptions *aopts; + assert(dev->driver == AUDIODEV_DRIVER_ALSA); + + aopts = &dev->u.alsa; + alsa_init_per_direction(&aopts->alsa_in, &aopts->has_alsa_in); + alsa_init_per_direction(&aopts->alsa_out, &aopts->has_alsa_out); + + /* + * need to define them, as otherwise alsa produces no sound + * doesn't set has_* so alsa_open can identify it wasn't set by the user + */ + if (!dev->out->has_buffer_count) { + dev->out->buffer_count = 4; + } + if (!dev->out->has_buffer_len) { + /* 1024 frames assuming 44100Hz */ + dev->out->buffer_len = 1024 * 1000000 / 44100; + } + + /* + * OptsVisitor sets unspecified optional fields to zero, but do not depend + * on it... + */ + if (!dev->in->has_buffer_count) { + dev->in->buffer_count = 0; + } + if (!dev->in->has_buffer_len) { + dev->in->buffer_len = 0; + } + + return dev; } static void alsa_audio_fini (void *opaque) { - g_free(opaque); } -static struct audio_option alsa_options[] = { - { - .name = "DAC_SIZE_IN_USEC", - .tag = AUD_OPT_BOOL, - .valp = &glob_conf.size_in_usec_out, - .descr = "DAC period/buffer size in microseconds (otherwise in frames)" - }, - { - .name = "DAC_PERIOD_SIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.period_size_out, - .descr = "DAC period size (0 to go with system default)", - .overriddenp = &glob_conf.period_size_out_overridden - }, - { - .name = "DAC_BUFFER_SIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.buffer_size_out, - .descr = "DAC buffer size (0 to go with system default)", - .overriddenp = &glob_conf.buffer_size_out_overridden - }, - { - .name = "ADC_SIZE_IN_USEC", - .tag = AUD_OPT_BOOL, - .valp = &glob_conf.size_in_usec_in, - .descr = - "ADC period/buffer size in microseconds (otherwise in frames)" - }, - { - .name = "ADC_PERIOD_SIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.period_size_in, - .descr = "ADC period size (0 to go with system default)", - .overriddenp = &glob_conf.period_size_in_overridden - }, - { - .name = "ADC_BUFFER_SIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.buffer_size_in, - .descr = "ADC buffer size (0 to go with system default)", - .overriddenp = &glob_conf.buffer_size_in_overridden - }, - { - .name = "THRESHOLD", - .tag = AUD_OPT_INT, - .valp = &glob_conf.threshold, - .descr = "(undocumented)" - }, - { - .name = "DAC_DEV", - .tag = AUD_OPT_STR, - .valp = &glob_conf.pcm_name_out, - .descr = "DAC device name (for instance dmix)" - }, - { - .name = "ADC_DEV", - .tag = AUD_OPT_STR, - .valp = &glob_conf.pcm_name_in, - .descr = "ADC device name" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, @@ -1217,7 +1098,6 @@ static struct audio_pcm_ops alsa_pcm_ops = { static struct audio_driver alsa_audio_driver = { .name = "alsa", .descr = "ALSA http://www.alsa-project.org", - .options = alsa_options, .init = alsa_audio_init, .fini = alsa_audio_fini, .pcm_ops = &alsa_pcm_ops, diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index e094b2bd61..5117bdecb7 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -62,6 +62,18 @@ static void get_int(const char *env, uint32_t *dst, bool *has_dst) } } +static void get_str(const char *env, char **dst, bool *has_dst) +{ + const char *val = getenv(env); + if (val) { + if (*has_dst) { + g_free(*dst); + } + *dst = g_strdup(val); + *has_dst = true; + } +} + static void get_fmt(const char *env, AudioFormat *dst, bool *has_dst) { const char *val = getenv(env); @@ -80,8 +92,79 @@ static void get_fmt(const char *env, AudioFormat *dst, bool *has_dst) } } + +static void get_millis_to_usecs(const char *env, uint32_t *dst, bool *has_dst) +{ + const char *val = getenv(env); + if (val) { + *dst = toui32(val) * 1000; + *has_dst = true; + } +} + +static uint32_t frames_to_usecs(uint32_t frames, + AudiodevPerDirectionOptions *pdo) +{ + uint32_t freq = pdo->has_frequency ? pdo->frequency : 44100; + return (frames * 1000000 + freq / 2) / freq; +} + /* backend specific functions */ -/* todo */ +/* ALSA */ +static void handle_alsa_per_direction( + AudiodevPerDirectionOptions *pdo, AudiodevAlsaPerDirectionOptions **apdo, + bool *has_apdo, const char *prefix) +{ + char buf[64]; + size_t len = strlen(prefix); + bool size_in_usecs = false; + uint32_t buffer_size; + bool has_buffer_size = false; + bool dummy; + + *apdo = g_malloc0(sizeof(AudiodevAlsaPerDirectionOptions)); + *has_apdo = true; + + memcpy(buf, prefix, len); + strcpy(buf + len, "TRY_POLL"); + get_bool(buf, &(*apdo)->try_poll, &(*apdo)->has_try_poll); + + strcpy(buf + len, "DEV"); + get_str(buf, &(*apdo)->dev, &(*apdo)->has_dev); + + strcpy(buf + len, "SIZE_IN_USEC"); + get_bool(buf, &size_in_usecs, &dummy); + + strcpy(buf + len, "PERIOD_SIZE"); + get_int(buf, &pdo->buffer_len, &pdo->has_buffer_len); + + if (pdo->has_buffer_len && !size_in_usecs) { + pdo->buffer_len = frames_to_usecs(pdo->buffer_len, pdo); + } + + strcpy(buf + len, "BUFFER_SIZE"); + get_int(buf, &buffer_size, &has_buffer_size); + if (has_buffer_size) { + if (!size_in_usecs) { + buffer_size = frames_to_usecs(buffer_size, pdo); + } + + pdo->buffer_count = buffer_size; + pdo->has_buffer_count = true; + } +} + +static void handle_alsa(Audiodev *dev) +{ + AudiodevAlsaOptions *aopt = &dev->u.alsa; + handle_alsa_per_direction(dev->in, &aopt->alsa_in, &aopt->has_alsa_in, + "QEMU_ALSA_ADC_"); + handle_alsa_per_direction(dev->out, &aopt->alsa_out, &aopt->has_alsa_out, + "QEMU_ALSA_DAC_"); + + get_millis_to_usecs("QEMU_ALSA_THRESHOLD", + &aopt->threshold, &aopt->has_threshold); +} /* general */ static void handle_per_direction( @@ -125,6 +208,15 @@ static AudiodevListEntry *legacy_opt(const char *drvname) get_int("QEMU_AUDIO_TIMER_PERIOD", &e->dev->timer_period, &e->dev->has_timer_period); + switch (e->dev->driver) { + case AUDIODEV_DRIVER_ALSA: + handle_alsa(e->dev); + break; + + default: + break; + } + return e; } From patchwork Wed Jan 16 23:36:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767103 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 57BA991E for ; Wed, 16 Jan 2019 23:39:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 494D22E4EB for ; Wed, 16 Jan 2019 23:39:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D90B2E509; Wed, 16 Jan 2019 23:39:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B05AB2E4EB for ; Wed, 16 Jan 2019 23:39:12 +0000 (UTC) Received: from localhost ([127.0.0.1]:59733 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjum7-0005S5-SS for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:39:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57723) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukf-00040A-Ae for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukd-0002ls-Cq for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:41 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:52844) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukc-0002el-QX for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:39 -0500 Received: by mail-wm1-x341.google.com with SMTP id m1so3893853wml.2 for ; Wed, 16 Jan 2019 15:37:32 -0800 (PST) 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=lDoXiYIV/EvJD3wV7LMocT/bjRg8AZPAp31z7dESMdg=; b=BSytpkVe36YMEd5lv9HkHoig0vMClfA+N+rZepmERPxtZG1+7f8Q3yahiKs+3fycHt vL+5tbKY4tln87VUsrSwSVEFGWdWZ415PNUrlF2MahPO26SHgbLjZ/jWwy6pTGCdLXZP fq7q9YNrwgLhcdoVl72k7zkT4r9m2EAgTdbTezlf8jRVFMWu2nP7qtexqZuT5mlL5A82 e6+r4fQS/OhoVKQi8Rf2IYxQ/KBpRtmWUGiC4Zg7BwGe6z8uRLMbO/7Zg/OpKf6kk9yj hYmSD2IBVu5QYNdRa9c2au0GHYN0v/2GXH0Ic+m9CRJg6sht3tLMxoLXW1E+tp0hmpmv 3USg== 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=lDoXiYIV/EvJD3wV7LMocT/bjRg8AZPAp31z7dESMdg=; b=Oud7QDpzZiVM9TY4+74R/1uTRtwGqIA+8BN6ltkMh0sJ0sO0Ep0pseVoCQN6y1uLcv dQZG/wj1+6HiL7xwsF5mV5IHzUYLoQVY7mxRFU5cilDOMZqu9umOvTIrCn71peRMhWlL okgNmLEBgvZh8/85H/lNnXMImZTUC9D0VU4m4VVS1F4UE1RtSWn3LEIc5RLbB8N4BZFz bgBNp5WHmfBwLlTa7cT7WxCO74jusjBMGuo17yCYIZ0z5BhYcEV+/JS8Ibz7OwAXXjyX 5xBei+6VMXcYPB6YF2ECC1kcrbB1iFhLz+YG+VT7t9uCHVLInzGNWkP2EqFcAq0Y9t5l GjrA== X-Gm-Message-State: AJcUukej1OvP+LSN46Y8nKBDGKMxXnzLvFjbLnn80QJsIo1+WEJftR6M xx5ZDpKd/zyBc3KbMrfp3Q62Zj3yccs= X-Google-Smtp-Source: ALg8bN4U7Y6WpyG4gPTKZLLgSebzxzNN11DKKg4X+gCNOExS+vErWpab3uaFHSBYXpbI6SitfxU9Rw== X-Received: by 2002:a1c:888d:: with SMTP id k135mr9723776wmd.137.1547681851000; Wed, 16 Jan 2019 15:37:31 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:30 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:39 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v3 06/50] coreaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_legacy.c | 24 ++++++++++++++++++++++ audio/coreaudio.c | 47 ++++++++++---------------------------------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 5117bdecb7..955fb18241 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -109,6 +109,17 @@ static uint32_t frames_to_usecs(uint32_t frames, return (frames * 1000000 + freq / 2) / freq; } + +static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst, + AudiodevPerDirectionOptions *pdo) +{ + const char *val = getenv(env); + if (val) { + *dst = frames_to_usecs(toui32(val), pdo); + *has_dst = true; + } +} + /* backend specific functions */ /* ALSA */ static void handle_alsa_per_direction( @@ -166,6 +177,15 @@ static void handle_alsa(Audiodev *dev) &aopt->threshold, &aopt->has_threshold); } +/* coreaudio */ +static void handle_coreaudio(Audiodev *dev) +{ + get_frames_to_usecs("QEMU_COREAUDIO_BUFFER_SIZE", &dev->out->buffer_len, + &dev->out->has_buffer_len, dev->out); + get_int("QEMU_COREAUDIO_BUFFER_COUNT", + &dev->out->buffer_count, &dev->out->has_buffer_count); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -213,6 +233,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_alsa(e->dev); break; + case AUDIODEV_DRIVER_COREAUDIO: + handle_coreaudio(e->dev); + break; + default: break; } diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 7d4225dbee..e00b8847d7 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -36,11 +36,6 @@ #define MAC_OS_X_VERSION_10_6 1060 #endif -typedef struct { - int buffer_frames; - int nbuffers; -} CoreaudioConf; - typedef struct coreaudioVoiceOut { HWVoiceOut hw; pthread_mutex_t mutex; @@ -507,7 +502,9 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, int err; const char *typ = "playback"; AudioValueRange frameRange; - CoreaudioConf *conf = drv_opaque; + Audiodev *dev = drv_opaque; + AudiodevPerDirectionOptions *pdo = dev->out; + int frames; /* create mutex */ err = pthread_mutex_init(&core->mutex, NULL); @@ -538,16 +535,17 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, return -1; } - if (frameRange.mMinimum > conf->buffer_frames) { + frames = audio_buffer_frames(pdo, as, 11610); + if (frameRange.mMinimum > frames) { core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum; dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum); } - else if (frameRange.mMaximum < conf->buffer_frames) { + else if (frameRange.mMaximum < frames) { core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum; dolog ("warning: Downsizing Buffer Frames to %f\n", frameRange.mMaximum); } else { - core->audioDevicePropertyBufferFrameSize = conf->buffer_frames; + core->audioDevicePropertyBufferFrameSize = frames; } /* set Buffer Frame Size */ @@ -568,7 +566,8 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, "Could not get device buffer frame size\n"); return -1; } - hw->samples = conf->nbuffers * core->audioDevicePropertyBufferFrameSize; + hw->samples = (pdo->has_buffer_count ? pdo->buffer_count : 4) * + core->audioDevicePropertyBufferFrameSize; /* get StreamFormat */ status = coreaudio_get_streamformat(core->outputDeviceID, @@ -680,40 +679,15 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static CoreaudioConf glob_conf = { - .buffer_frames = 512, - .nbuffers = 4, -}; - static void *coreaudio_audio_init(Audiodev *dev) { - CoreaudioConf *conf = g_malloc(sizeof(CoreaudioConf)); - *conf = glob_conf; - - return conf; + return dev; } static void coreaudio_audio_fini (void *opaque) { - g_free(opaque); } -static struct audio_option coreaudio_options[] = { - { - .name = "BUFFER_SIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.buffer_frames, - .descr = "Size of the buffer in frames" - }, - { - .name = "BUFFER_COUNT", - .tag = AUD_OPT_INT, - .valp = &glob_conf.nbuffers, - .descr = "Number of buffers" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, @@ -725,7 +699,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { static struct audio_driver coreaudio_audio_driver = { .name = "coreaudio", .descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html", - .options = coreaudio_options, .init = coreaudio_audio_init, .fini = coreaudio_audio_fini, .pcm_ops = &coreaudio_pcm_ops, From patchwork Wed Jan 16 23:36:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767163 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4473D13A4 for ; Wed, 16 Jan 2019 23:58:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32D652FC1C for ; Wed, 16 Jan 2019 23:58:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 226A62FC47; Wed, 16 Jan 2019 23:58:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6B2EC2FC1C for ; Wed, 16 Jan 2019 23:58:20 +0000 (UTC) Received: from localhost ([127.0.0.1]:36286 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv4d-0003Y0-II for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:58:19 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58004) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000470-4k for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002uX-35 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:40772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002fD-I4 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wr1-x441.google.com with SMTP id p4so8949772wrt.7 for ; Wed, 16 Jan 2019 15:37:33 -0800 (PST) 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=nNnSsiL/Q+z2BtxGrPZXQb9y8jhBsSVuCot0JiDGGZ8=; b=rmrCUUtUsJfVXNEeiJXjL3J4mJw5R9aqnUYmbOuOg/+0AXicVBMC4g7a38souWtcIl fDJstxtPmlqxjf7xM28tNBLJ20yyDkg5JE7FpEW5ybR0r5Etr6s8oCx81wnQBabK8TvF Ifk/Nz701HLhjzY59OKwHtJYS/G2F2UjJE5j/6fkz4QAi2BrzTMGsV9st8m/17SHkVuu T8KCcLe8T88VHaygm3lnc0yM8SI3iksNsgy49WwbZCbyddLOMkbx94DWt4GPUHRc5CkD ZoD4GwglMa1nZzGfIc8rX++Cn9qp6xQr/2amwW5FHy+CTO2CuSI3yLlsb/P0ZRPDNV5/ cMOA== 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=nNnSsiL/Q+z2BtxGrPZXQb9y8jhBsSVuCot0JiDGGZ8=; b=DH360Xqf5B26QPmHKCIgYDRW6E6LJ9iAGrdv79cCSLBUGqY0rkrGe1NTWU3mlKN66C JenDXDoemizKiOJZx1UbGI3eYMd2r5OKr2p2Br/h7n/SsxSgeYbIZJxv/r9s6HLwBH1G +2EeaIgbkEh1zsiVrn2U/5IQIjIh7XN+rQOVD4BR8JazZ/Fbr4eQlTkAqXYx+8CGyQjv a7ODZgriI9oZ/sG8POuAr2ULgofxuisz5ywLbowvplNJf84b78aaeo36h4KLSOoLGmOh 3ZiXRaBFHXW2e4adJir+qcmoWWXNNysD7U2Sk8tnPZ+7yvzuWLVqi+2WxxcKlt8m/6LV 33TA== X-Gm-Message-State: AJcUukdUycAshrLp0q2frjLNOcBAnleGPQNZBCUZcz6qalnSBZ1k3SSq aGE2rm3G/nMsMij/ZkUeIU/BIEfOz1I= X-Google-Smtp-Source: ALg8bN79pA95DfJJGa8soVACkTUsOrYAMvcPqW4ql1GoHTrZ6XrkLZDPZUgtYF8e23eKKP6n/JiysA== X-Received: by 2002:adf:dfd1:: with SMTP id q17mr9966902wrn.27.1547681851928; Wed, 16 Jan 2019 15:37:31 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:31 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:40 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 07/50] dsoundaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/dsound_template.h | 6 ++--- audio/audio_legacy.c | 39 +++++++++++++++++++++++++++ audio/dsoundaudio.c | 59 ++++++++++++----------------------------- 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/audio/dsound_template.h b/audio/dsound_template.h index b439f33f58..96181efb36 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -167,17 +167,18 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, dsound *s = drv_opaque; WAVEFORMATEX wfx; struct audsettings obt_as; - DSoundConf *conf = &s->conf; #ifdef DSBTYPE_IN const char *typ = "ADC"; DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; DSCBUFFERDESC bd; DSCBCAPS bc; + AudiodevPerDirectionOptions *pdo = s->dev->in; #else const char *typ = "DAC"; DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; DSBUFFERDESC bd; DSBCAPS bc; + AudiodevPerDirectionOptions *pdo = s->dev->out; #endif if (!s->FIELD2) { @@ -193,8 +194,8 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, memset (&bd, 0, sizeof (bd)); bd.dwSize = sizeof (bd); bd.lpwfxFormat = &wfx; + bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880); #ifdef DSBTYPE_IN - bd.dwBufferBytes = conf->bufsize_in; hr = IDirectSoundCapture_CreateCaptureBuffer ( s->dsound_capture, &bd, @@ -203,7 +204,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, ); #else bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2; - bd.dwBufferBytes = conf->bufsize_out; hr = IDirectSound_CreateSoundBuffer ( s->dsound, &bd, diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 955fb18241..601a68fab6 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -120,6 +120,30 @@ static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst, } } +static uint32_t samples_to_usecs(uint32_t samples, + AudiodevPerDirectionOptions *pdo) +{ + uint32_t channels = pdo->has_channels ? pdo->channels : 2; + return frames_to_usecs(samples / channels, pdo); +} + +static uint32_t bytes_to_usecs(uint32_t bytes, AudiodevPerDirectionOptions *pdo) +{ + AudioFormat fmt = pdo->has_format ? pdo->format : AUDIO_FORMAT_S16; + uint32_t bytes_per_sample = audioformat_bytes_per_sample(fmt); + return samples_to_usecs(bytes / bytes_per_sample, pdo); +} + +static void get_bytes_to_usecs(const char *env, uint32_t *dst, bool *has_dst, + AudiodevPerDirectionOptions *pdo) +{ + const char *val = getenv(env); + if (val) { + *dst = bytes_to_usecs(toui32(val), pdo); + *has_dst = true; + } +} + /* backend specific functions */ /* ALSA */ static void handle_alsa_per_direction( @@ -186,6 +210,17 @@ static void handle_coreaudio(Audiodev *dev) &dev->out->buffer_count, &dev->out->has_buffer_count); } +/* dsound */ +static void handle_dsound(Audiodev *dev) +{ + get_millis_to_usecs("QEMU_DSOUND_LATENCY_MILLIS", + &dev->u.dsound.latency, &dev->u.dsound.has_latency); + get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_OUT", &dev->out->buffer_len, + &dev->out->has_buffer_len, dev->out); + get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_IN", &dev->in->buffer_len, + &dev->in->has_buffer_len, dev->in); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -237,6 +272,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_coreaudio(e->dev); break; + case AUDIODEV_DRIVER_DSOUND: + handle_dsound(e->dev); + break; + default: break; } diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index 02fe777cba..a7d04b5033 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -32,6 +32,7 @@ #define AUDIO_CAP "dsound" #include "audio_int.h" +#include "qemu/host-utils.h" #include #include @@ -42,17 +43,11 @@ /* #define DEBUG_DSOUND */ -typedef struct { - int bufsize_in; - int bufsize_out; - int latency_millis; -} DSoundConf; - typedef struct { LPDIRECTSOUND dsound; LPDIRECTSOUNDCAPTURE dsound_capture; struct audsettings settings; - DSoundConf conf; + Audiodev *dev; } dsound; typedef struct { @@ -248,9 +243,9 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 ( dsound_log_hresult (hr); } -static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis) +static uint64_t usecs_to_bytes(struct audio_pcm_info *info, uint32_t usecs) { - return (millis * info->bytes_per_second) / 1000; + return muldiv64(usecs, info->bytes_per_second, 1000000); } #ifdef DEBUG_DSOUND @@ -478,7 +473,7 @@ static int dsound_run_out (HWVoiceOut *hw, int live) LPVOID p1, p2; int bufsize; dsound *s = ds->s; - DSoundConf *conf = &s->conf; + AudiodevDsoundOptions *dso = &s->dev->u.dsound; if (!dsb) { dolog ("Attempt to run empty with playback buffer\n"); @@ -501,14 +496,14 @@ static int dsound_run_out (HWVoiceOut *hw, int live) len = live << hwshift; if (ds->first_time) { - if (conf->latency_millis) { + if (dso->latency) { DWORD cur_blat; cur_blat = audio_ring_dist (wpos, ppos, bufsize); ds->first_time = 0; old_pos = wpos; old_pos += - millis_to_bytes (&hw->info, conf->latency_millis) - cur_blat; + usecs_to_bytes(&hw->info, dso->latency) - cur_blat; old_pos %= bufsize; old_pos &= ~hw->info.align; } @@ -747,12 +742,6 @@ static int dsound_run_in (HWVoiceIn *hw) return decr; } -static DSoundConf glob_conf = { - .bufsize_in = 16384, - .bufsize_out = 16384, - .latency_millis = 10 -}; - static void dsound_audio_fini (void *opaque) { HRESULT hr; @@ -788,8 +777,17 @@ static void *dsound_audio_init(Audiodev *dev) int err; HRESULT hr; dsound *s = g_malloc0(sizeof(dsound)); + AudiodevDsoundOptions *dso; + + assert(dev->driver == AUDIODEV_DRIVER_DSOUND); + s->dev = dev; + dso = &dev->u.dsound; + + if (!dso->has_latency) { + dso->has_latency = true; + dso->latency = 10000; /* 10 ms */ + } - s->conf = glob_conf; hr = CoInitialize (NULL); if (FAILED (hr)) { dsound_logerr (hr, "Could not initialize COM\n"); @@ -854,28 +852,6 @@ static void *dsound_audio_init(Audiodev *dev) return s; } -static struct audio_option dsound_options[] = { - { - .name = "LATENCY_MILLIS", - .tag = AUD_OPT_INT, - .valp = &glob_conf.latency_millis, - .descr = "(undocumented)" - }, - { - .name = "BUFSIZE_OUT", - .tag = AUD_OPT_INT, - .valp = &glob_conf.bufsize_out, - .descr = "(undocumented)" - }, - { - .name = "BUFSIZE_IN", - .tag = AUD_OPT_INT, - .valp = &glob_conf.bufsize_in, - .descr = "(undocumented)" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, @@ -893,7 +869,6 @@ static struct audio_pcm_ops dsound_pcm_ops = { static struct audio_driver dsound_audio_driver = { .name = "dsound", .descr = "DirectSound http://wikipedia.org/wiki/DirectSound", - .options = dsound_options, .init = dsound_audio_init, .fini = dsound_audio_fini, .pcm_ops = &dsound_pcm_ops, From patchwork Wed Jan 16 23:36:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767105 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE03414E5 for ; Wed, 16 Jan 2019 23:39:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE13B2EC77 for ; Wed, 16 Jan 2019 23:39:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C1DD32EC94; Wed, 16 Jan 2019 23:39:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7E0DE2EC77 for ; Wed, 16 Jan 2019 23:39:22 +0000 (UTC) Received: from localhost ([127.0.0.1]:59770 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjumH-0005XQ-Ld for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:39:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57828) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukl-00043G-1n for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukj-0002tM-MW for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:46 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:38421) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002fc-D5 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wm1-x343.google.com with SMTP id m22so3885887wml.3 for ; Wed, 16 Jan 2019 15:37:33 -0800 (PST) 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=5xK9dVHrb98gQfhXePE10y7ks65rcNRmc5Tmv6NvGfs=; b=oSRWS0iifunh9Y+y2/1Q2ioB1XLt7ZKvVir95JdjtvCnxQORcoMtHDg+wD51+lzUp5 S8Ogoe5ytqwEPEKD9ec176714qJjDVptx1RCOHTfnWtPix3l43yYoB29qYz+wRMp/TDb 4p1qwbfmfdbuv06ZzsB3h5aBSUoce4W0GtoGSdlSEEdU/hBjJRTm4A5KvY4nGhaJsfD8 gcLeyJ1KjXf0q9qX3ZxaTUJdC5TKJ8ZL9Vl+RSPWnaJ1i9ieRprRhs1/Fh3kJRExFGXR mOUU6XrJgR1jpUgCPka2/1AQxVcaENzKm8Ea95feg3CX606v1m+AXrgPTQ6OaoFNL4ZU ++hw== 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=5xK9dVHrb98gQfhXePE10y7ks65rcNRmc5Tmv6NvGfs=; b=OuaU7KTkPtgadDdd7fKKXPCh9RcCR0emMsN6yGCdvCuRCYtWtpF7rI/y1CCymJJlCx sfkjul29QhGsRD4IfcTgw2SIzjE3KRNQ15EGJKR9D0MPOucReHVF91KifUvln7qylTVv 85Ta2U61xIVw3SzN2078M0NEQdVfvTP4lKSt5G1isyC5GUohhqvW8BoW7x0+YlxODK9n DiyL1wFccrqc6ZNPmG9jLdcezt60BwbdPT5y4iURACSbyfGBbnp4imvJXDyo+oqJ0Jh6 1ufT9dZ3NLyN+pom3VTvQwiOjuoLXWHF0et8J5ByaMI5b8cVvw7LwNyH0hCH9rmTO7f1 m+8g== X-Gm-Message-State: AJcUukc+E0AD1Bz7NTdSvSK+mO/M3PxhWkE3mb9hq7LHG/bnlm/5y92k +q5oiHg4qmhUkqVCIHF3nBwABCSi3+8= X-Google-Smtp-Source: ALg8bN4q2HvrXBD1bBCB1HyGuwK6zZTT6BJ/dNn2kDy68ConyasfyjRDR1A4RQr9pnhXO/U4beFOog== X-Received: by 2002:a1c:20cb:: with SMTP id g194mr9145359wmg.77.1547681852791; Wed, 16 Jan 2019 15:37:32 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:32 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:41 +0100 Message-Id: <1aba321d3f73c7145a2331ce27f36c52570ceec6.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 08/50] noaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/noaudio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/audio/noaudio.c b/audio/noaudio.c index 79690af1ea..ccc611fc84 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -163,7 +163,6 @@ static struct audio_pcm_ops no_pcm_ops = { static struct audio_driver no_audio_driver = { .name = "none", .descr = "Timer based audio emulation", - .options = NULL, .init = no_audio_init, .fini = no_audio_fini, .pcm_ops = &no_pcm_ops, From patchwork Wed Jan 16 23:36:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767115 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EBF7A91E for ; Wed, 16 Jan 2019 23:42:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD9E62F951 for ; Wed, 16 Jan 2019 23:42:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DBEED2F9AB; Wed, 16 Jan 2019 23:42:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 055162F951 for ; Wed, 16 Jan 2019 23:42:16 +0000 (UTC) Received: from localhost ([127.0.0.1]:60544 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjup6-0007xa-3t for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:42:16 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57768) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukj-00042L-4h for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukf-0002nF-A6 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:43 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:36102) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukd-0002gH-Bx for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:40 -0500 Received: by mail-wr1-x443.google.com with SMTP id u4so8967135wrp.3 for ; Wed, 16 Jan 2019 15:37:35 -0800 (PST) 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=5mQNVmyKpl1ZdkPNGWJNL3EAL1B1BT/ZGOUeuFpeS4s=; b=Rvvqh8/pwpMQxWc4ND1oqqemyHXNvUNRmU1ADY/Vx9fm12CoRL9hVWkGke3ZIGntnL VqdVodw+zk5c8Wc5ujR1vFIyCceFitzfPhjovMVqvpB6npOWrzeRpFWGfci905/T2hNx 2BoxMhQn0+1b/22jy+vi8CFKJ2q0tN7zdgiWxsJBug+iVTXNBivvFNqvlMYm8/vZ8Vnt mQC9eDuCZsjWj4SlpKjcZ/dbW3FOJ2IpZFNyjqjEjH9bifK22xhoD9yqJ6XARPIV+izP 52OFukpg5CkzoYYLGyeOeoBoJeZiR2Qcl+vu+yYzgaE8Z+M09YuOiMONtd0DmbdgnnDk pGZA== 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=5mQNVmyKpl1ZdkPNGWJNL3EAL1B1BT/ZGOUeuFpeS4s=; b=BKeiMwbS2OGb5fHYuRVehb5FpPkrLlV+W1H2GsDIXDpLEF5oVlrLrQymPwYJWw83T6 N7sZ//IssN4fQ/9Mm6Z0BOBktfCE8KoqH76rzr98y1zPCWz+O2FBkPJs49gRjm0kDWx2 +hhwUoC0g/ziP6fLYl6I0zAFj4hmQILhm1B5IaR9eJkOPvXqcja3ns3KCF37HPw4fhMi bkEMQz0+ysPzJZwwwsEHHhCPQaZFfF4ZDUXD/i4yjOrBpGIjZquY20OYicBPf0d/gVgE U7bK2BMtcPdVQDKglrTZx59Lw6BRsgMtgqxyGB2nLc3G/UZ8bosyvS3m4dPvn3+19WJK xR+g== X-Gm-Message-State: AJcUukfALFP3tQZGmK82+d0Lscw7GjsanaPVRYhWEttKiDvYB0UUnmxS 4un8hhKDPRByvoICCKEitOtohi+aIks= X-Google-Smtp-Source: ALg8bN5VeLvp80IY0h1WFEUX5VNpgHEDaaLZUw3tJfLaM3s6Ksh0NchdtJ7SAIMu9BMAqgPSUEkRcA== X-Received: by 2002:a5d:6b81:: with SMTP id n1mr10134261wrx.149.1547681853535; Wed, 16 Jan 2019 15:37:33 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:33 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:42 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PATCH v3 09/50] ossaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_legacy.c | 33 +++++++++ audio/ossaudio.c | 167 +++++++++++++++---------------------------- 2 files changed, 90 insertions(+), 110 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 601a68fab6..70b46cbcc1 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -221,6 +221,35 @@ static void handle_dsound(Audiodev *dev) &dev->in->has_buffer_len, dev->in); } +/* OSS */ +static void handle_oss_per_direction( + AudiodevPerDirectionOptions *pdo, AudiodevOssPerDirectionOptions **opdo, + bool *has_opdo, const char *try_poll_env, const char *dev_env) +{ + *opdo = g_malloc0(sizeof(AudiodevOssPerDirectionOptions)); + *has_opdo = true; + + get_bool(try_poll_env, &(*opdo)->try_poll, &(*opdo)->has_try_poll); + get_str(dev_env, &(*opdo)->dev, &(*opdo)->has_dev); + + get_bytes_to_usecs("QEMU_OSS_FRAGSIZE", + &pdo->buffer_len, &pdo->has_buffer_len, pdo); + get_int("QEMU_OSS_NFRAGS", &pdo->buffer_count, &pdo->has_buffer_count); +} + +static void handle_oss(Audiodev *dev) +{ + AudiodevOssOptions *oopt = &dev->u.oss; + handle_oss_per_direction(dev->in, &oopt->oss_in, &oopt->has_oss_in, + "QEMU_AUDIO_ADC_TRY_POLL", "QEMU_OSS_ADC_DEV"); + handle_oss_per_direction(dev->out, &oopt->oss_out, &oopt->has_oss_out, + "QEMU_AUDIO_DAC_TRY_POLL", "QEMU_OSS_DAC_DEV"); + + get_bool("QEMU_OSS_MMAP", &oopt->try_mmap, &oopt->has_try_mmap); + get_bool("QEMU_OSS_EXCLUSIVE", &oopt->exclusive, &oopt->has_exclusive); + get_int("QEMU_OSS_POLICY", &oopt->dsp_policy, &oopt->has_dsp_policy); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -276,6 +305,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_dsound(e->dev); break; + case AUDIODEV_DRIVER_OSS: + handle_oss(e->dev); + break; + default: break; } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index e0cadbef29..d56c705dc0 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -37,16 +37,6 @@ #define USE_DSP_POLICY #endif -typedef struct OSSConf { - int try_mmap; - int nfrags; - int fragsize; - const char *devpath_out; - const char *devpath_in; - int exclusive; - int policy; -} OSSConf; - typedef struct OSSVoiceOut { HWVoiceOut hw; void *pcm_buf; @@ -56,7 +46,7 @@ typedef struct OSSVoiceOut { int fragsize; int mmapped; int pending; - OSSConf *conf; + Audiodev *dev; } OSSVoiceOut; typedef struct OSSVoiceIn { @@ -65,12 +55,12 @@ typedef struct OSSVoiceIn { int fd; int nfrags; int fragsize; - OSSConf *conf; + Audiodev *dev; } OSSVoiceIn; struct oss_params { int freq; - AudioFormat fmt; + int fmt; int nchannels; int nfrags; int fragsize; @@ -262,19 +252,26 @@ static int oss_get_version (int fd, int *version, const char *typ) } #endif -static int oss_open (int in, struct oss_params *req, - struct oss_params *obt, int *pfd, OSSConf* conf) +static int oss_open(int in, struct oss_params *req, audsettings *as, + struct oss_params *obt, int *pfd, Audiodev *dev) { + AudiodevOssOptions *oopts = &dev->u.oss; + AudiodevOssPerDirectionOptions *opdo = in ? oopts->oss_in : oopts->oss_out; + AudiodevPerDirectionOptions *pdo = in ? dev->in : dev->out; int fd; - int oflags = conf->exclusive ? O_EXCL : 0; + int oflags = (oopts->has_exclusive && oopts->exclusive) ? O_EXCL : 0; audio_buf_info abinfo; int fmt, freq, nchannels; int setfragment = 1; - const char *dspname = in ? conf->devpath_in : conf->devpath_out; + const char *dspname = opdo->has_dev ? opdo->dev : "/dev/dsp"; const char *typ = in ? "ADC" : "DAC"; +#ifdef USE_DSP_POLICY + int policy = oopts->has_dsp_policy ? oopts->dsp_policy : 5; +#endif /* Kludge needed to have working mmap on Linux */ - oflags |= conf->try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY); + oflags |= (oopts->has_try_mmap && oopts->try_mmap) ? + O_RDWR : (in ? O_RDONLY : O_WRONLY); fd = open (dspname, oflags | O_NONBLOCK); if (-1 == fd) { @@ -285,6 +282,8 @@ static int oss_open (int in, struct oss_params *req, freq = req->freq; nchannels = req->nchannels; fmt = req->fmt; + req->nfrags = pdo->has_buffer_count ? pdo->buffer_count : 4; + req->fragsize = audio_buffer_bytes(pdo, as, 23220); if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) { oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt); @@ -308,18 +307,18 @@ static int oss_open (int in, struct oss_params *req, } #ifdef USE_DSP_POLICY - if (conf->policy >= 0) { + if (policy >= 0) { int version; if (!oss_get_version (fd, &version, typ)) { trace_oss_version(version); if (version >= 0x040000) { - int policy = conf->policy; - if (ioctl (fd, SNDCTL_DSP_POLICY, &policy)) { + int policy2 = policy; + if (ioctl (fd, SNDCTL_DSP_POLICY, &policy2)) { oss_logerr2 (errno, typ, "Failed to set timing policy to %d\n", - conf->policy); + policy); goto err; } setfragment = 0; @@ -502,17 +501,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, int fd; AudioFormat effective_fmt; struct audsettings obt_as; - OSSConf *conf = drv_opaque; + Audiodev *dev = drv_opaque; + AudiodevOssOptions *oopts = &dev->u.oss; oss->fd = -1; req.fmt = aud_to_ossfmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.fragsize = conf->fragsize; - req.nfrags = conf->nfrags; - if (oss_open (0, &req, &obt, &fd, conf)) { + if (oss_open(0, &req, as, &obt, &fd, dev)) { return -1; } @@ -539,7 +537,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->mmapped = 0; - if (conf->try_mmap) { + if (oopts->has_try_mmap && oopts->try_mmap) { oss->pcm_buf = mmap ( NULL, hw->samples << hw->info.shift, @@ -597,7 +595,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, } oss->fd = fd; - oss->conf = conf; + oss->dev = dev; return 0; } @@ -605,16 +603,12 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) { int trig; OSSVoiceOut *oss = (OSSVoiceOut *) hw; + AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out; switch (cmd) { case VOICE_ENABLE: { - va_list ap; - int poll_mode; - - va_start (ap, cmd); - poll_mode = va_arg (ap, int); - va_end (ap); + bool poll_mode = opdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode) { @@ -669,16 +663,14 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) int fd; AudioFormat effective_fmt; struct audsettings obt_as; - OSSConf *conf = drv_opaque; + Audiodev *dev = drv_opaque; oss->fd = -1; req.fmt = aud_to_ossfmt (as->fmt, as->endianness); req.freq = as->freq; req.nchannels = as->nchannels; - req.fragsize = conf->fragsize; - req.nfrags = conf->nfrags; - if (oss_open (1, &req, &obt, &fd, conf)) { + if (oss_open(1, &req, as, &obt, &fd, dev)) { return -1; } @@ -712,7 +704,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } oss->fd = fd; - oss->conf = conf; + oss->dev = dev; return 0; } @@ -803,16 +795,12 @@ static int oss_read (SWVoiceIn *sw, void *buf, int size) static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; + AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out; switch (cmd) { case VOICE_ENABLE: { - va_list ap; - int poll_mode; - - va_start (ap, cmd); - poll_mode = va_arg (ap, int); - va_end (ap); + bool poll_mode = opdo->try_poll; if (poll_mode) { oss_poll_in (hw); @@ -832,82 +820,42 @@ static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static OSSConf glob_conf = { - .try_mmap = 0, - .nfrags = 4, - .fragsize = 4096, - .devpath_out = "/dev/dsp", - .devpath_in = "/dev/dsp", - .exclusive = 0, - .policy = 5 -}; +static void oss_init_per_direction(AudiodevOssPerDirectionOptions **opdo, + bool *has_opdo) +{ + if (!*has_opdo) { + *opdo = g_malloc0(sizeof(AudiodevOssPerDirectionOptions)); + *has_opdo = true; + } + + if (!(*opdo)->has_try_poll) { + (*opdo)->try_poll = true; + (*opdo)->has_try_poll = true; + } +} static void *oss_audio_init(Audiodev *dev) { - OSSConf *conf = g_malloc(sizeof(OSSConf)); - *conf = glob_conf; + AudiodevOssOptions *oopts; + assert(dev->driver == AUDIODEV_DRIVER_OSS); - if (access(conf->devpath_in, R_OK | W_OK) < 0 || - access(conf->devpath_out, R_OK | W_OK) < 0) { - g_free(conf); + oopts = &dev->u.oss; + oss_init_per_direction(&oopts->oss_in, &oopts->has_oss_in); + oss_init_per_direction(&oopts->oss_out, &oopts->has_oss_out); + + if (access(oopts->oss_in->has_dev ? oopts->oss_in->dev : "/dev/dsp", + R_OK | W_OK) < 0 || + access(oopts->oss_out->has_dev ? oopts->oss_out->dev : "/dev/dsp", + R_OK | W_OK) < 0) { return NULL; } - return conf; + return dev; } static void oss_audio_fini (void *opaque) { - g_free(opaque); } -static struct audio_option oss_options[] = { - { - .name = "FRAGSIZE", - .tag = AUD_OPT_INT, - .valp = &glob_conf.fragsize, - .descr = "Fragment size in bytes" - }, - { - .name = "NFRAGS", - .tag = AUD_OPT_INT, - .valp = &glob_conf.nfrags, - .descr = "Number of fragments" - }, - { - .name = "MMAP", - .tag = AUD_OPT_BOOL, - .valp = &glob_conf.try_mmap, - .descr = "Try using memory mapped access" - }, - { - .name = "DAC_DEV", - .tag = AUD_OPT_STR, - .valp = &glob_conf.devpath_out, - .descr = "Path to DAC device" - }, - { - .name = "ADC_DEV", - .tag = AUD_OPT_STR, - .valp = &glob_conf.devpath_in, - .descr = "Path to ADC device" - }, - { - .name = "EXCLUSIVE", - .tag = AUD_OPT_BOOL, - .valp = &glob_conf.exclusive, - .descr = "Open device in exclusive mode (vmix won't work)" - }, -#ifdef USE_DSP_POLICY - { - .name = "POLICY", - .tag = AUD_OPT_INT, - .valp = &glob_conf.policy, - .descr = "Set the timing policy of the device, -1 to use fragment mode", - }, -#endif - { /* End of list */ } -}; - static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, @@ -925,7 +873,6 @@ static struct audio_pcm_ops oss_pcm_ops = { static struct audio_driver oss_audio_driver = { .name = "oss", .descr = "OSS http://www.opensound.com", - .options = oss_options, .init = oss_audio_init, .fini = oss_audio_fini, .pcm_ops = &oss_pcm_ops, From patchwork Wed Jan 16 23:36:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767127 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A8C6713A4 for ; Wed, 16 Jan 2019 23:45:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 413992AB24 for ; Wed, 16 Jan 2019 23:45:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 314192ADEB; Wed, 16 Jan 2019 23:45:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 737912AB24 for ; Wed, 16 Jan 2019 23:45:02 +0000 (UTC) Received: from localhost ([127.0.0.1]:33065 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjurl-0001uo-NF for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:45:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046v-4B for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukj-0002ts-Sg for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:45494) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002hx-DH for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wr1-x443.google.com with SMTP id t6so8903510wrr.12 for ; Wed, 16 Jan 2019 15:37:35 -0800 (PST) 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=V1RGCp9xhLDikvB38j9gPHnz1eckoONO6UVeTZFRyRg=; b=rW9ClZnZJVOFo/j8eQ79acJdfIV+NfC4vqS1XgaJkBHFaiuoBYa08GyP8uVBU66Rba Ie4KnmiuDa9amkP7PyLMHYcvxVqY0mvSTANK4xV4PXnAxEITA4jk9Hh8euMxtSPvimh3 icTxdz5fRERYRZI6wSw390J5GxCaqnJ3hbpLOXAUddT1UBCUzeAr5/7kThe1rkkKh4w5 5OcLzLRFgqdSjTh1kkUfHMxZAJVNsM0PFeclTD0nwbkJls0bq8hHBy66G4Cn9j5X3WFU DD474v91Qyz7ZCHSyf4WEd7r1RxxC+N8HnhCIemwKHMWTcS8N87l+jPoDjDNahAyKK9b pn0A== 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=V1RGCp9xhLDikvB38j9gPHnz1eckoONO6UVeTZFRyRg=; b=h+FGw2N2aacByAZexnu8P48eqiS8l8N4faHGkMm0epgTvYJxoThhgoQ96RAU79gx6n MXrtB0jCR5Mta1aO0HQBaSX9PTfMm0uZcRZyicg57AupgChqGg4fwOXqebYMZpokrpRb GtpUfuoEMfbndw01UV7ziuxFW1Id6eL0b8n9bCEpf3AMCDHxOfX+Rbz50FsoDobj435n OpNbNp8SkB05eFNNQOXBMTuQXhwww+jSo3nc1aQB7waSBm425TjqIqVeDdmj775rEZ33 4z95II/i+DBPeawJlDvvqopSeoYbs3o0QovQc7Xlh1FYn5APHdNDjHJdYElah8SVXzUA FF7w== X-Gm-Message-State: AJcUuke1UMATMIpQzxe0G8ur0Jc8sEWIIgTMVHoOhHigOD21lTZqAWOo J5u6unNlf0M1oqfXDH8EdBJo3nwmiV4= X-Google-Smtp-Source: ALg8bN5QmcEFrHKiyTvZz4VZkqsA9AhhxS/rXZSkpMHh34fano7WQ1tzCYRnPX/YdRNK6ipsiGhTxA== X-Received: by 2002:adf:8484:: with SMTP id 4mr9392882wrg.249.1547681854513; Wed, 16 Jan 2019 15:37:34 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:33 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:43 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PATCH v3 10/50] paaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_legacy.c | 39 +++++++++++++++++++ audio/paaudio.c | 90 ++++++++++++++++++++------------------------ 2 files changed, 79 insertions(+), 50 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 70b46cbcc1..d173ff042e 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -127,6 +127,16 @@ static uint32_t samples_to_usecs(uint32_t samples, return frames_to_usecs(samples / channels, pdo); } +static void get_samples_to_usecs(const char *env, uint32_t *dst, bool *has_dst, + AudiodevPerDirectionOptions *pdo) +{ + const char *val = getenv(env); + if (val) { + *dst = samples_to_usecs(toui32(val), pdo); + *has_dst = true; + } +} + static uint32_t bytes_to_usecs(uint32_t bytes, AudiodevPerDirectionOptions *pdo) { AudioFormat fmt = pdo->has_format ? pdo->format : AUDIO_FORMAT_S16; @@ -250,6 +260,31 @@ static void handle_oss(Audiodev *dev) get_int("QEMU_OSS_POLICY", &oopt->dsp_policy, &oopt->has_dsp_policy); } +/* pulseaudio */ +static void handle_pa_per_direction( + AudiodevPaPerDirectionOptions **ppdo, bool *has_ppdo, const char *env) +{ + *ppdo = g_malloc0(sizeof(AudiodevPaPerDirectionOptions)); + *has_ppdo = true; + + get_str(env, &(*ppdo)->name, &(*ppdo)->has_name); +} + +static void handle_pa(Audiodev *dev) +{ + handle_pa_per_direction(&dev->u.pa.sink, &dev->u.pa.has_sink, + "QEMU_PA_SINK"); + handle_pa_per_direction(&dev->u.pa.source, &dev->u.pa.has_source, + "QEMU_PA_SOURCE"); + + get_samples_to_usecs("QEMU_PA_SAMPLES", &dev->in->buffer_len, + &dev->in->has_buffer_len, dev->in); + get_samples_to_usecs("QEMU_PA_SAMPLES", &dev->out->buffer_len, + &dev->out->has_buffer_len, dev->out); + + get_str("QEMU_PA_SERVER", &dev->u.pa.server, &dev->u.pa.has_server); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -309,6 +344,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_oss(e->dev); break; + case AUDIODEV_DRIVER_PA: + handle_pa(e->dev); + break; + default: break; } diff --git a/audio/paaudio.c b/audio/paaudio.c index 0981f010c9..33e0e5d9be 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -2,6 +2,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "audio.h" +#include "qapi/opts-visitor.h" #include @@ -10,14 +11,7 @@ #include "audio_pt_int.h" typedef struct { - int samples; - char *server; - char *sink; - char *source; -} PAConf; - -typedef struct { - PAConf conf; + Audiodev *dev; pa_threaded_mainloop *mainloop; pa_context *context; } paaudio; @@ -32,6 +26,7 @@ typedef struct { void *pcm_buf; struct audio_pt pt; paaudio *g; + int samples; } PAVoiceOut; typedef struct { @@ -46,6 +41,7 @@ typedef struct { const void *read_data; size_t read_index, read_length; paaudio *g; + int samples; } PAVoiceIn; static void qpa_audio_fini(void *opaque); @@ -227,7 +223,7 @@ static void *qpa_thread_out (void *arg) } } - decr = to_mix = audio_MIN(pa->live, pa->g->conf.samples >> 5); + decr = to_mix = audio_MIN(pa->live, pa->samples >> 5); rpos = pa->rpos; if (audio_pt_unlock(&pa->pt, __func__)) { @@ -319,7 +315,7 @@ static void *qpa_thread_in (void *arg) } } - incr = to_grab = audio_MIN(pa->dead, pa->g->conf.samples >> 5); + incr = to_grab = audio_MIN(pa->dead, pa->samples >> 5); wpos = pa->wpos; if (audio_pt_unlock(&pa->pt, __func__)) { @@ -546,6 +542,8 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, struct audsettings obt_as = *as; PAVoiceOut *pa = (PAVoiceOut *) hw; paaudio *g = pa->g = drv_opaque; + AudiodevPaOptions *popts = &g->dev->u.pa; + AudiodevPaPerDirectionOptions *ppdo = popts->sink; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; @@ -566,7 +564,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, g, "qemu", PA_STREAM_PLAYBACK, - g->conf.sink, + ppdo->has_name ? ppdo->name : NULL, &ss, NULL, /* channel map */ &ba, /* buffering attributes */ @@ -578,7 +576,8 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, } audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = g->conf.samples; + hw->samples = pa->samples = audio_buffer_samples(g->dev->out, &obt_as, + 46440); pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->rpos = hw->rpos; if (!pa->pcm_buf) { @@ -612,6 +611,8 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) struct audsettings obt_as = *as; PAVoiceIn *pa = (PAVoiceIn *) hw; paaudio *g = pa->g = drv_opaque; + AudiodevPaOptions *popts = &g->dev->u.pa; + AudiodevPaPerDirectionOptions *ppdo = popts->source; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; @@ -623,7 +624,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) g, "qemu", PA_STREAM_RECORD, - g->conf.source, + ppdo->has_name ? ppdo->name : NULL, &ss, NULL, /* channel map */ NULL, /* buffering attributes */ @@ -635,7 +636,8 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = g->conf.samples; + hw->samples = pa->samples = audio_buffer_samples(g->dev->in, &obt_as, + 46440); pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->wpos = hw->wpos; if (!pa->pcm_buf) { @@ -808,14 +810,31 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) } /* common */ -static PAConf glob_conf = { - .samples = 4096, -}; +static void qpa_init_per_direction(AudiodevPaPerDirectionOptions **ppdo, + bool *has_ppdo) +{ + if (!*has_ppdo) { + *ppdo = g_malloc0(sizeof(AudiodevPaPerDirectionOptions)); + *has_ppdo = true; + } +} static void *qpa_audio_init(Audiodev *dev) { - paaudio *g = g_malloc(sizeof(paaudio)); - g->conf = glob_conf; + paaudio *g; + AudiodevPaOptions *popts; + const char *server; + + assert(dev->driver == AUDIODEV_DRIVER_PA); + + qpa_init_per_direction(&dev->u.pa.sink, &dev->u.pa.has_sink); + qpa_init_per_direction(&dev->u.pa.source, &dev->u.pa.has_source); + + g = g_malloc(sizeof(paaudio)); + popts = &dev->u.pa; + server = popts->has_server ? popts->server : NULL; + + g->dev = dev; g->mainloop = NULL; g->context = NULL; @@ -825,14 +844,14 @@ static void *qpa_audio_init(Audiodev *dev) } g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), - g->conf.server); + server); if (!g->context) { goto fail; } pa_context_set_state_callback (g->context, context_state_cb, g); - if (pa_context_connect (g->context, g->conf.server, 0, NULL) < 0) { + if (pa_context_connect (g->context, server, 0, NULL) < 0) { qpa_logerr (pa_context_errno (g->context), "pa_context_connect() failed\n"); goto fail; @@ -895,34 +914,6 @@ static void qpa_audio_fini (void *opaque) g_free(g); } -struct audio_option qpa_options[] = { - { - .name = "SAMPLES", - .tag = AUD_OPT_INT, - .valp = &glob_conf.samples, - .descr = "buffer size in samples" - }, - { - .name = "SERVER", - .tag = AUD_OPT_STR, - .valp = &glob_conf.server, - .descr = "server address" - }, - { - .name = "SINK", - .tag = AUD_OPT_STR, - .valp = &glob_conf.sink, - .descr = "sink device name" - }, - { - .name = "SOURCE", - .tag = AUD_OPT_STR, - .valp = &glob_conf.source, - .descr = "source device name" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, @@ -940,7 +931,6 @@ static struct audio_pcm_ops qpa_pcm_ops = { static struct audio_driver pa_audio_driver = { .name = "pa", .descr = "http://www.pulseaudio.org/", - .options = qpa_options, .init = qpa_audio_init, .fini = qpa_audio_fini, .pcm_ops = &qpa_pcm_ops, From patchwork Wed Jan 16 23:36:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767111 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F3B214E5 for ; Wed, 16 Jan 2019 23:42:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10A4D2F960 for ; Wed, 16 Jan 2019 23:42:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0ED042F97B; Wed, 16 Jan 2019 23:42:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8A82B2F981 for ; Wed, 16 Jan 2019 23:42:05 +0000 (UTC) Received: from localhost ([127.0.0.1]:60507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuou-0007qZ-C6 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:42:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57998) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046w-4h for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002v9-5o for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:42513) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002ik-Qy for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:46 -0500 Received: by mail-wr1-x441.google.com with SMTP id q18so8927777wrx.9 for ; Wed, 16 Jan 2019 15:37:36 -0800 (PST) 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=u6ZAZabkyvPqDFL2JNe3x51ANLXtVEqROa82KNWp6DA=; b=vbqLK5aM168IoLu3PAtj4Pv1Otgv9+K1DeAMgHTAngfa0pv2Fo+hV833xnabeggfK2 Bp8etncg3dYbSIfwXcsnjuMUFv4z6yQCXRGFAyq7hKxiaopMIvfqumQCoc7VGIufG/MH GxWq1DBftoRLQG1a2mg4Epz8a0NeeMl3oYmJYt5fqOWsRLCTdWa3mbohquPvZjj98Y7o 6ahT9egecaTQ7d2rXCpWEFaD9TS/dG4BjK3vje4GyDUh34GK8OX5G78lw7VcLSO758id ComPwBJ1fyl1I2COaEDjRw2uC+mzW6eYuTdbw/rlrdR4Ohm2MBDIUNyT4fXbp6C2uVBu IWYw== 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=u6ZAZabkyvPqDFL2JNe3x51ANLXtVEqROa82KNWp6DA=; b=mOZ446+uvXdrkNTcKbTSjMuDi39fax/EMXvH960hy4gzIIA6jQMTn0NlSGQjLvs8T8 OyCYUP3ADyR+qDLRewHWb6CiXfhY9jrVdLVJR6zn+j/3NRg7Fsx6MuL830apAx68hNdL Gh3hAt8SbVfccfCFSSuKADgUscm3/w2cZn0zfGeEtzZTT/coc+u+KwXb3Tih5C9arYzw P1UEM6uIG/5bqKFADQRMhwARTZ8uEI4HWWfcHFvrmDdtMBrWDnmIRaAxkTRub38mdlMd xuu18iS+FgRMNUd9eFHf2wqVQ4ZUi1vuDGdg1Drap6nKzkh/XP0SjLtR/UK9G5BVMi/t eNhQ== X-Gm-Message-State: AJcUukfAIMj+JtHqprLJDwSyHLXNxvUMSxYLS5OmIwmHYid6piafsB1T F1aFXbFuqN8QST7vbBRfuaOMywZPt8c= X-Google-Smtp-Source: ALg8bN5SFiQyuGphFaCROPWZCo8ZRJBYyEptlHqme9DQdzWjzuEIs2mHh+EJF0ujFub2l6R+0RifUA== X-Received: by 2002:adf:f550:: with SMTP id j16mr9381203wrp.258.1547681855304; Wed, 16 Jan 2019 15:37:35 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:34 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:44 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 11/50] sdlaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_legacy.c | 12 ++++++++++++ audio/sdlaudio.c | 22 ++++------------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index d173ff042e..aa6c789096 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -285,6 +285,14 @@ static void handle_pa(Audiodev *dev) get_str("QEMU_PA_SERVER", &dev->u.pa.server, &dev->u.pa.has_server); } +/* SDL */ +static void handle_sdl(Audiodev *dev) +{ + /* SDL is output only */ + get_samples_to_usecs("QEMU_SDL_SAMPLES", &dev->out->buffer_len, + &dev->out->has_buffer_len, dev->out); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -348,6 +356,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_pa(e->dev); break; + case AUDIODEV_DRIVER_SDL: + handle_sdl(e->dev); + break; + default: break; } diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index 097841fde1..cf6ac19927 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -49,12 +49,6 @@ typedef struct SDLVoiceOut { int decr; } SDLVoiceOut; -static struct { - int nb_samples; -} conf = { - .nb_samples = 1024 -}; - static struct SDLAudioState { int exit; #if USE_SEMAPHORE @@ -63,6 +57,7 @@ static struct SDLAudioState { #endif int initialized; bool driver_created; + Audiodev *dev; } glob_sdl; typedef struct SDLAudioState SDLAudioState; @@ -392,7 +387,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, req.freq = as->freq; req.format = aud_to_sdlfmt (as->fmt); req.channels = as->nchannels; - req.samples = conf.nb_samples; + req.samples = audio_buffer_samples(s->dev->out, as, 11610); req.callback = sdl_callback; req.userdata = sdl; @@ -467,6 +462,7 @@ static void *sdl_audio_init(Audiodev *dev) #endif s->driver_created = true; + s->dev = dev; return s; } @@ -480,18 +476,9 @@ static void sdl_audio_fini (void *opaque) #endif SDL_QuitSubSystem (SDL_INIT_AUDIO); s->driver_created = false; + s->dev = NULL; } -static struct audio_option sdl_options[] = { - { - .name = "SAMPLES", - .tag = AUD_OPT_INT, - .valp = &conf.nb_samples, - .descr = "Size of SDL buffer in samples" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, @@ -503,7 +490,6 @@ static struct audio_pcm_ops sdl_pcm_ops = { static struct audio_driver sdl_audio_driver = { .name = "sdl", .descr = "SDL http://www.libsdl.org", - .options = sdl_options, .init = sdl_audio_init, .fini = sdl_audio_fini, .pcm_ops = &sdl_pcm_ops, From patchwork Wed Jan 16 23:36:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767133 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0CEE813A4 for ; Wed, 16 Jan 2019 23:45:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F137F2E0A0 for ; Wed, 16 Jan 2019 23:45:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E4E092E550; Wed, 16 Jan 2019 23:45:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9E96E2E0A0 for ; Wed, 16 Jan 2019 23:45:18 +0000 (UTC) Received: from localhost ([127.0.0.1]:33172 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjus1-0002DA-SR for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:45:17 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57995) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046t-45 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukj-0002tn-Th for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:54050) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002jO-FY for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wm1-x343.google.com with SMTP id d15so3885269wmb.3 for ; Wed, 16 Jan 2019 15:37:37 -0800 (PST) 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=gFlI6J52EuSN1uBwYtC2z1Nd0p5GKE1yjn2uKwH4Jm0=; b=Kyt6CSObOzIgbptLSicN8kAG4eeC0XgqLaKcYsCtbfgfQlciDa1k4ght6rNlF4VR/3 QKuPmVHiv48eH7L5RMiR27IsbWWFVnPKUsS5ih0KaZhTjlwIc6la9tknOqloMO+fRm+C UAJBujRBmvw+JJpfq4nRzXmNwq0UgbbIC01VoVRVuJj3Qu+NGrOYCM7WYxDWMXMkiRkP MG5qbYC1XqgJZuS1+CZIfKnzwkK2jGd92i0PcZo8Ho0PfIZn9bEnWryQr1z3hn3Cs9Q5 Pv/z530t36vyA4FsWz4pcTyAM0qHmID1YOVfPP7JJVdZeZfq96eIJnhcMy0ScDuXRWFU 4ryg== 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=gFlI6J52EuSN1uBwYtC2z1Nd0p5GKE1yjn2uKwH4Jm0=; b=clXaW7bTFdjyeLgqaDn23A2YacByji77bbUJdQwVkKo41oHg/ycjkHdinLt5xrKARG UOCFMlVfAK16dgWl1HxBe00uYbZC5JFW4nHLt/xwz5UUIDh4y60lc9X+2FvPTT7eKbJj cOMwI9p9oLZaMmUG6/aHhKlajUSIrP6jl7Z3E/HVt77zQNEwSqYmbxHE25PG5PVraE5i nmrKjnDrNkN9B4KqVeAd9yuG4Qd8KZuUOQvVpXliC1v+KsPCgmMnf3y7dz65uPPaWJzE KcKcfSb3lyzzSnnTO4FMjpCNjJhIzsPz8hUoGqEfccxVnjt8oFOzqcfJKKubUIhG7spF svqg== X-Gm-Message-State: AJcUukc6bUJQp0qEM1l/JiwTYECP1aSz3Sq0VhonXYhz6Fjllb86tMG7 QkbjRXNDXE3A4/xpDwCII+x4s7R0Gt8= X-Google-Smtp-Source: ALg8bN4EnpOAk7LS/H+EeiEq7fm6Pg7nuoyYevGB6U2ystl1KoViRGvvrJPbYTFesEzRSSkWKvyv1A== X-Received: by 2002:a1c:a68f:: with SMTP id p137mr8758883wme.64.1547681856254; Wed, 16 Jan 2019 15:37:36 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:35 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:45 +0100 Message-Id: <9389fad919c0e8401972103016839b20ba91941b.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 12/50] spiceaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/spiceaudio.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index affc3df17f..4f7873af5a 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -373,10 +373,6 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) return 0; } -static struct audio_option audio_options[] = { - { /* end of list */ }, -}; - static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, @@ -394,7 +390,6 @@ static struct audio_pcm_ops audio_callbacks = { static struct audio_driver spice_audio_driver = { .name = "spice", .descr = "spice audio driver", - .options = audio_options, .init = spice_audio_init, .fini = spice_audio_fini, .pcm_ops = &audio_callbacks, From patchwork Wed Jan 16 23:36:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2059291E for ; Wed, 16 Jan 2019 23:42:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12EB02F806 for ; Wed, 16 Jan 2019 23:42:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1132B2FA2C; Wed, 16 Jan 2019 23:42:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7361D2F806 for ; Wed, 16 Jan 2019 23:42:25 +0000 (UTC) Received: from localhost ([127.0.0.1]:60586 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjupE-00084P-R0 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:42:24 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukj-00042Q-80 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukh-0002pL-A1 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:52847) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukf-0002kL-7E for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:41 -0500 Received: by mail-wm1-x344.google.com with SMTP id m1so3894011wml.2 for ; Wed, 16 Jan 2019 15:37:38 -0800 (PST) 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=oD+l5pRm3zAapkGSUkdP10UgT9autl9VfiCZsWaNs7Y=; b=lTrumOnSGVG40D2/scxcUkMN4bqSZrGN/xEQP9746uUQCHMa9fE604JnAOqsVDmpYf JvIKB6Nt2n5EEl8pt+HcDX78eQYYEXNuTegtCLTps8GCEwjL4hiO74ee5Oxbws2Px892 /K0Je+O6e1uIjgrz9CJud4q7XoOrbNE02s1oexblMKRhhQCkAcrxx22EI2U+ayHfUAC1 4AMEzFptmKQ/oRqPvKneA0Gossokmk7Ng+TX1nYSP014cOumywd3p+W/otplxGl8Yj4p VeqqMHHVMvM7/lG58poKGwiQpqT5Z1VHfO8kogiI5r9Rfv8WIKMi2+kLEUO4ajiZ7eeV suDA== 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=oD+l5pRm3zAapkGSUkdP10UgT9autl9VfiCZsWaNs7Y=; b=lY1rm6Ag+BHheTMVGy4nZ58y7ISwhg/jVfPkJpPkeLQqX5iYp4c/K7voRLaNtoaggc tY9+kG2T8x0wNqUi2yuSPtfWfY8zU6LYu849EAQG9EW2FBbreV1RfPoEoGlOIU+K0TjN N1qID4QZ3ZpX/NgatGxTUnnmpc2CfkAzECPsGxVmYjUZYVReVN7C/F8frE98B6ii1FFi lnYCD1IKqnB5A1PhBKVMZ6wEJ52MonulA7sA1BRAaZ64OsP5s+9QtWFLZQaOTlkNvJ9r 5LNpPCkAcSYzxbpCf7H3NxDQ7acgxodrmEKex6UrFr5SXUJOLTSKJUwv5Et/MINxRjT3 j7Sg== X-Gm-Message-State: AJcUukcgXp6INJ0Ov/6OHbm248KRwyDj5xLfOtDj67sGosAh9gnTwK9E 4ECKJgAYRMmNtwip6tTRt+uMlEQK9c0= X-Google-Smtp-Source: ALg8bN5CGt4JmQ6c+L72DlG6euDVvwe1ljRJpux6veIMp7ecK2D1uUt07K/gls6unEPVDyvNWPnZ6Q== X-Received: by 2002:a1c:35ca:: with SMTP id c193mr9182159wma.146.1547681857050; Wed, 16 Jan 2019 15:37:37 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:36 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:46 +0100 Message-Id: <1c70f5a379f55049a1d427060ac18171b621cbfc.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v3 13/50] wavaudio: port to -audiodev config X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_legacy.c | 15 ++++++++++++ audio/wavaudio.c | 58 +++++++------------------------------------- 2 files changed, 24 insertions(+), 49 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index aa6c789096..cf0fc4df90 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -293,6 +293,17 @@ static void handle_sdl(Audiodev *dev) &dev->out->has_buffer_len, dev->out); } +/* wav */ +static void handle_wav(Audiodev *dev) +{ + get_int("QEMU_WAV_FREQUENCY", + &dev->out->frequency, &dev->out->has_frequency); + get_fmt("QEMU_WAV_FORMAT", &dev->out->format, &dev->out->has_format); + get_int("QEMU_WAV_DAC_FIXED_CHANNELS", + &dev->out->channels, &dev->out->has_channels); + get_str("QEMU_WAV_PATH", &dev->u.wav.path, &dev->u.wav.has_path); +} + /* general */ static void handle_per_direction( AudiodevPerDirectionOptions *pdo, const char *prefix) @@ -360,6 +371,10 @@ static AudiodevListEntry *legacy_opt(const char *drvname) handle_sdl(e->dev); break; + case AUDIODEV_DRIVER_WAV: + handle_wav(e->dev); + break; + default: break; } diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 9eff3555b3..214e30ccd9 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/host-utils.h" #include "qemu/timer.h" +#include "qapi/opts-visitor.h" #include "audio.h" #define AUDIO_CAP "wav" @@ -37,11 +38,6 @@ typedef struct WAVVoiceOut { int total_samples; } WAVVoiceOut; -typedef struct { - struct audsettings settings; - const char *wav_path; -} WAVConf; - static int wav_run_out (HWVoiceOut *hw, int live) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; @@ -112,8 +108,10 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00 }; - WAVConf *conf = drv_opaque; - struct audsettings wav_as = conf->settings; + Audiodev *dev = drv_opaque; + AudiodevWavOptions *wopts = &dev->u.wav; + struct audsettings wav_as = audiodev_to_audsettings(dev->out); + const char *wav_path = wopts->has_path ? wopts->path : "qemu.wav"; stereo = wav_as.nchannels == 2; switch (wav_as.fmt) { @@ -154,10 +152,10 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4); le_store (hdr + 32, 1 << (bits16 + stereo), 2); - wav->f = fopen (conf->wav_path, "wb"); + wav->f = fopen(wav_path, "wb"); if (!wav->f) { dolog ("Failed to open wave file `%s'\nReason: %s\n", - conf->wav_path, strerror (errno)); + wav_path, strerror(errno)); g_free (wav->pcm_buf); wav->pcm_buf = NULL; return -1; @@ -225,54 +223,17 @@ static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static WAVConf glob_conf = { - .settings.freq = 44100, - .settings.nchannels = 2, - .settings.fmt = AUDIO_FORMAT_S16, - .wav_path = "qemu.wav" -}; - static void *wav_audio_init(Audiodev *dev) { - WAVConf *conf = g_malloc(sizeof(WAVConf)); - *conf = glob_conf; - return conf; + assert(dev->driver == AUDIODEV_DRIVER_WAV); + return dev; } static void wav_audio_fini (void *opaque) { ldebug ("wav_fini"); - g_free(opaque); } -static struct audio_option wav_options[] = { - { - .name = "FREQUENCY", - .tag = AUD_OPT_INT, - .valp = &glob_conf.settings.freq, - .descr = "Frequency" - }, - { - .name = "FORMAT", - .tag = AUD_OPT_FMT, - .valp = &glob_conf.settings.fmt, - .descr = "Format" - }, - { - .name = "DAC_FIXED_CHANNELS", - .tag = AUD_OPT_INT, - .valp = &glob_conf.settings.nchannels, - .descr = "Number of channels (1 - mono, 2 - stereo)" - }, - { - .name = "PATH", - .tag = AUD_OPT_STR, - .valp = &glob_conf.wav_path, - .descr = "Path to wave file" - }, - { /* End of list */ } -}; - static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, @@ -284,7 +245,6 @@ static struct audio_pcm_ops wav_pcm_ops = { static struct audio_driver wav_audio_driver = { .name = "wav", .descr = "WAV renderer http://wikipedia.org/wiki/WAV", - .options = wav_options, .init = wav_audio_init, .fini = wav_audio_fini, .pcm_ops = &wav_pcm_ops, From patchwork Wed Jan 16 23:36:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767155 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6F4B36C2 for ; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5AE692FBFF for ; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4F25C2FC35; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F6BA2FBFF for ; Wed, 16 Jan 2019 23:55:06 +0000 (UTC) Received: from localhost ([127.0.0.1]:35500 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv1V-00017g-Ka for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:55:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046x-4e for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002ug-2M for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:35798) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002kz-JV for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wr1-x444.google.com with SMTP id 96so8979591wrb.2 for ; Wed, 16 Jan 2019 15:37:39 -0800 (PST) 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=+KLdYVHXyb++yJyEvEl+SHTMWf4MHgf4Ka8Rlav/6ss=; b=TIqUWPaEu5pGDSz5SIRG+80LnsfarZ6aY5xphWe+Hux4xmM0wIKruvkE5eUK5Xgg4n O110UwreMj29pqTwugjAhspsGAH/m6Nlztzq2JHg63ltFGjP3E/plFbRj3ae7P8RgJdy s7ONfCV4IF8+TT6k+beJc2o08UhgblGKgyNtVIjrBH43btTHVguGZrV9yD6FoEqwylT4 GnbAw656r+MCuhTHcycilzIkDMYrzgAnfLg+n4SVtdXLdfIXljTsu5LP4hXmphLgiX4B 98sF35LzYE4d/m0cOPd0cUaXaMWTVPvA7l85A4vlmC0MzenCiBOBynFjP3JoBqBEyL3P Yocw== 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=+KLdYVHXyb++yJyEvEl+SHTMWf4MHgf4Ka8Rlav/6ss=; b=RRwwsW8R6bTpt0WFeu5YYjLu2LXgOiMSnTgZ5pALANBuqpZaU1xkClmDRBNg+Zy8Y3 0IiutMHpaURJhGyDVlACAP0sbhcChpoONAqF8VykFBF0ZdQ0odEYblaqxMHIcDgo8k8/ D47l4fUAtpdvBrCZP7rVNYvfXHmUqruUELMnUiFQMCjGgeyUDCCxft0OCpw8216Eqcd6 j13tTEUH9uYj6KH4p0lwlqNesAa4YEjCA26+vFI0uExeozXkuFK4/8aOOQXJJP1k/iX6 hKBbpfjkWVoRryPWRUTwePc89HpB21tHeb0ghWLeluXqjyqjPVtSPxSoxMcgrU4jATLU N1Ng== X-Gm-Message-State: AJcUukdIR/0qnvnS1tKo8jNYBRuktEW3hA6g5CQJxZJf0iVqzgrOXfOV qJDmSQWrXQA001k0Sgp1Fs3caMGwMsw= X-Google-Smtp-Source: ALg8bN7hEH4kMb3uAH/HRPaeSZy7myi2qaHmyOehUEZSpHtl30xaoJEW96fY+RHLQGBuNZ17F+lr1A== X-Received: by 2002:adf:ca13:: with SMTP id o19mr9418210wrh.148.1547681857884; Wed, 16 Jan 2019 15:37:37 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:37 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:47 +0100 Message-Id: <9b1d639f82f26aff6a87db6f195b6dc0c7b0f29e.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 14/50] audio: -audiodev command line option: cleanup X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Remove no longer needed code. Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 17 ---- audio/audio.c | 201 +--------------------------------------------- 2 files changed, 4 insertions(+), 214 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 353467b505..66214199f0 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -33,22 +33,6 @@ struct audio_pcm_ops; -typedef enum { - AUD_OPT_INT, - AUD_OPT_FMT, - AUD_OPT_STR, - AUD_OPT_BOOL -} audio_option_tag_e; - -struct audio_option { - const char *name; - audio_option_tag_e tag; - void *valp; - const char *descr; - int *overriddenp; - int overridden; -}; - struct audio_callback { void *opaque; audio_callback_fn fn; @@ -145,7 +129,6 @@ typedef struct audio_driver audio_driver; struct audio_driver { const char *name; const char *descr; - struct audio_option *options; void *(*init) (Audiodev *); void (*fini) (void *); struct audio_pcm_ops *pcm_ops; diff --git a/audio/audio.c b/audio/audio.c index 159b049ceb..77bd8386d0 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -172,113 +172,6 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size) return g_malloc0 (len); } -static const char *audio_audfmt_to_string (AudioFormat fmt) -{ - switch (fmt) { - case AUDIO_FORMAT_U8: - return "U8"; - - case AUDIO_FORMAT_U16: - return "U16"; - - case AUDIO_FORMAT_S8: - return "S8"; - - case AUDIO_FORMAT_S16: - return "S16"; - - case AUDIO_FORMAT_U32: - return "U32"; - - case AUDIO_FORMAT_S32: - return "S32"; - - default: - abort(); - } - - dolog ("Bogus audfmt %d returning S16\n", fmt); - return "S16"; -} - -static AudioFormat audio_string_to_audfmt (const char *s, AudioFormat defval, - int *defaultp) -{ - if (!strcasecmp (s, "u8")) { - *defaultp = 0; - return AUDIO_FORMAT_U8; - } - else if (!strcasecmp (s, "u16")) { - *defaultp = 0; - return AUDIO_FORMAT_U16; - } - else if (!strcasecmp (s, "u32")) { - *defaultp = 0; - return AUDIO_FORMAT_U32; - } - else if (!strcasecmp (s, "s8")) { - *defaultp = 0; - return AUDIO_FORMAT_S8; - } - else if (!strcasecmp (s, "s16")) { - *defaultp = 0; - return AUDIO_FORMAT_S16; - } - else if (!strcasecmp (s, "s32")) { - *defaultp = 0; - return AUDIO_FORMAT_S32; - } - else { - dolog ("Bogus audio format `%s' using %s\n", - s, audio_audfmt_to_string (defval)); - *defaultp = 1; - return defval; - } -} - -static AudioFormat audio_get_conf_fmt (const char *envname, - AudioFormat defval, - int *defaultp) -{ - const char *var = getenv (envname); - if (!var) { - *defaultp = 1; - return defval; - } - return audio_string_to_audfmt (var, defval, defaultp); -} - -static int audio_get_conf_int (const char *key, int defval, int *defaultp) -{ - int val; - char *strval; - - strval = getenv (key); - if (strval && !qemu_strtoi(strval, NULL, 10, &val)) { - *defaultp = 0; - return val; - } - else { - *defaultp = 1; - return defval; - } -} - -static const char *audio_get_conf_str (const char *key, - const char *defval, - int *defaultp) -{ - const char *val = getenv (key); - if (!val) { - *defaultp = 1; - return defval; - } - else { - *defaultp = 0; - return val; - } -} - void AUD_vlog (const char *cap, const char *fmt, va_list ap) { if (cap) { @@ -297,89 +190,6 @@ void AUD_log (const char *cap, const char *fmt, ...) va_end (ap); } -static void audio_process_options (const char *prefix, - struct audio_option *opt) -{ - char *optname; - const char qemu_prefix[] = "QEMU_"; - size_t preflen, optlen; - - if (audio_bug(__func__, !prefix)) { - dolog ("prefix = NULL\n"); - return; - } - - if (audio_bug(__func__, !opt)) { - dolog ("opt = NULL\n"); - return; - } - - preflen = strlen (prefix); - - for (; opt->name; opt++) { - size_t len, i; - int def; - - if (!opt->valp) { - dolog ("Option value pointer for `%s' is not set\n", - opt->name); - continue; - } - - len = strlen (opt->name); - /* len of opt->name + len of prefix + size of qemu_prefix - * (includes trailing zero) + zero + underscore (on behalf of - * sizeof) */ - optlen = len + preflen + sizeof (qemu_prefix) + 1; - optname = g_malloc (optlen); - - pstrcpy (optname, optlen, qemu_prefix); - - /* copy while upper-casing, including trailing zero */ - for (i = 0; i <= preflen; ++i) { - optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]); - } - pstrcat (optname, optlen, "_"); - pstrcat (optname, optlen, opt->name); - - def = 1; - switch (opt->tag) { - case AUD_OPT_BOOL: - case AUD_OPT_INT: - { - int *intp = opt->valp; - *intp = audio_get_conf_int (optname, *intp, &def); - } - break; - - case AUD_OPT_FMT: - { - AudioFormat *fmtp = opt->valp; - *fmtp = audio_get_conf_fmt (optname, *fmtp, &def); - } - break; - - case AUD_OPT_STR: - { - const char **strp = opt->valp; - *strp = audio_get_conf_str (optname, *strp, &def); - } - break; - - default: - dolog ("Bad value tag for option `%s' - %d\n", - optname, opt->tag); - break; - } - - if (!opt->overriddenp) { - opt->overriddenp = &opt->overridden; - } - *opt->overriddenp = !def; - g_free (optname); - } -} - static void audio_print_settings (struct audsettings *as) { dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels); @@ -1092,7 +902,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_out(hw, VOICE_ENABLE, true /* todo */); + hw->pcm_ops->ctl_out(hw, VOICE_ENABLE); audio_reset_timer (s); } } @@ -1137,7 +947,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_in(hw, VOICE_ENABLE, true /* todo */); + hw->pcm_ops->ctl_in(hw, VOICE_ENABLE); audio_reset_timer (s); } } @@ -1461,9 +1271,6 @@ void audio_run (const char *msg) static int audio_driver_init(AudioState *s, struct audio_driver *drv, Audiodev *dev) { - if (drv->options) { - audio_process_options (drv->name, drv->options); - } s->drv_opaque = drv->init(dev); if (s->drv_opaque) { @@ -1488,11 +1295,11 @@ static void audio_vm_change_state_handler (void *opaque, int running, s->vm_running = running; while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { - hwo->pcm_ops->ctl_out(hwo, op, true /* todo */); + hwo->pcm_ops->ctl_out(hwo, op); } while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { - hwi->pcm_ops->ctl_in(hwi, op, true /* todo */); + hwi->pcm_ops->ctl_in(hwi, op); } audio_reset_timer (s); } From patchwork Wed Jan 16 23:36:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767129 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9318514E5 for ; Wed, 16 Jan 2019 23:45:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9463C2ABFA for ; Wed, 16 Jan 2019 23:45:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 84A372ADEB; Wed, 16 Jan 2019 23:45:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A76BA2ABFA for ; Wed, 16 Jan 2019 23:45:05 +0000 (UTC) Received: from localhost ([127.0.0.1]:33092 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuro-0001xm-OK for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:45:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57786) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukj-00042j-Me for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukh-0002qM-UT for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:34218) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukf-0002m4-CS for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:43 -0500 Received: by mail-wm1-x342.google.com with SMTP id y185so2237150wmd.1 for ; Wed, 16 Jan 2019 15:37:40 -0800 (PST) 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=qQUhR1tIf/3e+ZCVWzhhh2v2LRxghOI+I/dhckntsiI=; b=dEAO3aTr7HzSJ5VfNQVPGmlcGtemITfZqolXPOhy9LZCXcGiS7PGKQskqo2ahws5QW gaFui52xpbKxQidZwjRHDAXi/ugafDiwWbstZchMlB9friDQ1aDoXu9bvYZhBODSnk/M a1q0RZsfFHDqgp3HARd3VuhTt8T9KXQe8WsT2QXQtN90YDg/8X6qXItfvX/pgzLO5DzF 9N1uXKaZUVu7TBHqRCtf7+LuZ555ps8diuHGtSqtmvswrDPtRMGIl6I81ZlD3DsKwNKO 4SOBrS2kBzx+zKM0pwQcACKzfydXvNL4dMkC5JdaqegE8TzIOKa66mLSUsUEfdeUuRS3 bhsA== 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=qQUhR1tIf/3e+ZCVWzhhh2v2LRxghOI+I/dhckntsiI=; b=PgxzqWroqkr0+iVV5mtRijVU/I2uU8Bw8mjyapIL8Ixvf7+OSzKVurOabP8hXN3W9C a/uVqkQHMTwlJ00yYnk4s1vyz0LiG6VXaEu3ALHPafRpdrVb7l+w9MCRYjdgobB1ENCq kNjye1rY4+bZSlzpOIlbuN7YFhTVmENLwdHTT77GL5q/6bdoiXc+SL02VwQmhVp3FoCi 4ifg8+rtDsdPOE31ZX1obTzu1cD2hGOP+PwwxzOdFbJzB3yGI0ziStN5KBkI/R90IZHw 5kRwyNsPrfZUP+NI/Ekfo7BuG6VGdBOcc9UcslSxxROp9Mw43+CjmR8jnSkk3iixuNpq 7uVw== X-Gm-Message-State: AJcUukdUTJIjSHkNaUWn1RYgTXSPXlJAh9IRx34zdPwPz/bHDCOYAeLg JLSrwxCvSLiEGAenAYLZOjNJMoofRDw= X-Google-Smtp-Source: ALg8bN4STVtfJSB8dgFYoiLGJZ7S/UlaUTQ0yJjpSCkgcF1zcMULRLDQylY23COYoKZ3zelsPUzwvQ== X-Received: by 2002:a1c:bc82:: with SMTP id m124mr9196829wmf.77.1547681858739; Wed, 16 Jan 2019 15:37:38 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:38 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:48 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::342 Subject: [Qemu-devel] [PATCH v3 15/50] audio: reduce glob_audio_state usage X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Remove glob_audio_state from functions, where possible without breaking the API. This means that most static functions in audio.c now take an AudioState pointer instead of implicitly using glob_audio_state. Also included a pointer in SWVoice*, HWVoice* structs, so that functions dealing them can know the audio state without having to pass it around separately. This is required in order to support multiple simultaneous audio backends (added in a later commit). Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 7 +++++ audio/audio_template.h | 46 ++++++++++++++++---------------- audio/audio.c | 59 +++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 66214199f0..2a7556d113 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -52,6 +52,7 @@ struct audio_pcm_info { typedef struct SWVoiceCap SWVoiceCap; typedef struct HWVoiceOut { + AudioState *s; int enabled; int poll_mode; int pending_disable; @@ -73,6 +74,7 @@ typedef struct HWVoiceOut { } HWVoiceOut; typedef struct HWVoiceIn { + AudioState *s; int enabled; int poll_mode; struct audio_pcm_info info; @@ -94,6 +96,7 @@ typedef struct HWVoiceIn { struct SWVoiceOut { QEMUSoundCard *card; + AudioState *s; struct audio_pcm_info info; t_sample *conv; int64_t ratio; @@ -111,6 +114,7 @@ struct SWVoiceOut { struct SWVoiceIn { QEMUSoundCard *card; + AudioState *s; int active; struct audio_pcm_info info; int64_t ratio; @@ -188,6 +192,9 @@ struct AudioState { int nb_hw_voices_in; int vm_running; int64_t period_ticks; + + bool timer_running; + uint64_t timer_last; }; extern const struct mixeng_volume nominal_volume; diff --git a/audio/audio_template.h b/audio/audio_template.h index c1d7207abd..ccf6d810f7 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -36,9 +36,9 @@ #define HWBUF hw->conv_buf #endif -static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) +static void glue(audio_init_nb_voices_, TYPE)(AudioState *s, + struct audio_driver *drv) { - AudioState *s = &glob_audio_state; int max_voices = glue (drv->max_voices_, TYPE); int voice_size = glue (drv->voice_size_, TYPE); @@ -183,8 +183,8 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw) static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) { - AudioState *s = &glob_audio_state; HW *hw = *hwp; + AudioState *s = hw->s; if (!hw->sw_head.lh_first) { #ifdef DAC @@ -199,15 +199,14 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) } } -static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw) +static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw) { - AudioState *s = &glob_audio_state; return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first; } -static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw) +static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw) { - while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { + while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) { if (hw->enabled) { return hw; } @@ -215,12 +214,10 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw) return NULL; } -static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( - HW *hw, - struct audsettings *as - ) +static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw, + struct audsettings *as) { - while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { + while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) { if (audio_pcm_info_eq (&hw->info, as)) { return hw; } @@ -228,10 +225,10 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( return NULL; } -static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) +static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, + struct audsettings *as) { HW *hw; - AudioState *s = &glob_audio_state; struct audio_driver *drv = s->drv; if (!glue (s->nb_hw_voices_, TYPE)) { @@ -255,6 +252,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) return NULL; } + hw->s = s; hw->pcm_ops = drv->pcm_ops; hw->ctl_caps = drv->ctl_caps; @@ -299,33 +297,33 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) return NULL; } -static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as) +static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as) { HW *hw; - AudioState *s = &glob_audio_state; AudiodevPerDirectionOptions *pdo = s->dev->TYPE; if (pdo->fixed_settings) { - hw = glue (audio_pcm_hw_add_new_, TYPE) (as); + hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as); if (hw) { return hw; } } - hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as); + hw = glue(audio_pcm_hw_find_specific_, TYPE)(s, NULL, as); if (hw) { return hw; } - hw = glue (audio_pcm_hw_add_new_, TYPE) (as); + hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as); if (hw) { return hw; } - return glue (audio_pcm_hw_find_any_, TYPE) (NULL); + return glue(audio_pcm_hw_find_any_, TYPE)(s, NULL); } -static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( +static SW *glue(audio_pcm_create_voice_pair_, TYPE)( + AudioState *s, const char *sw_name, struct audsettings *as ) @@ -333,7 +331,6 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( SW *sw; HW *hw; struct audsettings hw_as; - AudioState *s = &glob_audio_state; AudiodevPerDirectionOptions *pdo = s->dev->TYPE; if (pdo->fixed_settings) { @@ -349,8 +346,9 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) ( sw_name ? sw_name : "unknown", sizeof (*sw)); goto err1; } + sw->s = s; - hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as); + hw = glue(audio_pcm_hw_add_, TYPE)(s, &hw_as); if (!hw) { goto err2; } @@ -447,7 +445,7 @@ SW *glue (AUD_open_, TYPE) ( } } else { - sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as); + sw = glue(audio_pcm_create_voice_pair_, TYPE)(s, name, as); if (!sw) { dolog ("Failed to create voice `%s'\n", name); return NULL; diff --git a/audio/audio.c b/audio/audio.c index 77bd8386d0..ef8ce3b91d 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -397,12 +397,10 @@ static void noop_conv (struct st_sample *dst, const void *src, int samples) (void) samples; } -static CaptureVoiceOut *audio_pcm_capture_find_specific ( - struct audsettings *as - ) +static CaptureVoiceOut *audio_pcm_capture_find_specific(AudioState *s, + struct audsettings *as) { CaptureVoiceOut *cap; - AudioState *s = &glob_audio_state; for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { if (audio_pcm_info_eq (&cap->hw.info, as)) { @@ -479,7 +477,7 @@ static void audio_detach_capture (HWVoiceOut *hw) static int audio_attach_capture (HWVoiceOut *hw) { - AudioState *s = &glob_audio_state; + AudioState *s = hw->s; CaptureVoiceOut *cap; audio_detach_capture (hw); @@ -792,19 +790,15 @@ static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info) /* * Timer */ - -static bool audio_timer_running; -static uint64_t audio_timer_last; - -static int audio_is_timer_needed (void) +static int audio_is_timer_needed(AudioState *s) { HWVoiceIn *hwi = NULL; HWVoiceOut *hwo = NULL; - while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { + while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) { if (!hwo->poll_mode) return 1; } - while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { + while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) { if (!hwi->poll_mode) return 1; } return 0; @@ -812,18 +806,18 @@ static int audio_is_timer_needed (void) static void audio_reset_timer (AudioState *s) { - if (audio_is_timer_needed ()) { + if (audio_is_timer_needed(s)) { timer_mod_anticipate_ns(s->ts, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->period_ticks); - if (!audio_timer_running) { - audio_timer_running = true; - audio_timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (!s->timer_running) { + s->timer_running = true; + s->timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); trace_audio_timer_start(s->period_ticks / SCALE_MS); } } else { timer_del(s->ts); - if (audio_timer_running) { - audio_timer_running = false; + if (s->timer_running) { + s->timer_running = false; trace_audio_timer_stop(); } } @@ -835,11 +829,11 @@ static void audio_timer (void *opaque) AudioState *s = opaque; now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - diff = now - audio_timer_last; + diff = now - s->timer_last; if (diff > s->period_ticks * 3 / 2) { trace_audio_timer_delayed(diff / SCALE_MS); } - audio_timer_last = now; + s->timer_last = now; audio_run("timer"); audio_reset_timer(s); @@ -893,7 +887,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) hw = sw->hw; if (sw->active != on) { - AudioState *s = &glob_audio_state; + AudioState *s = sw->s; SWVoiceOut *temp_sw; SWVoiceCap *sc; @@ -940,7 +934,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) hw = sw->hw; if (sw->active != on) { - AudioState *s = &glob_audio_state; + AudioState *s = sw->s; SWVoiceIn *temp_sw; if (on) { @@ -1063,7 +1057,7 @@ static void audio_run_out (AudioState *s) HWVoiceOut *hw = NULL; SWVoiceOut *sw; - while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) { + while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) { int played; int live, free, nb_live, cleanup_required, prev_rpos; @@ -1168,7 +1162,7 @@ static void audio_run_in (AudioState *s) { HWVoiceIn *hw = NULL; - while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) { + while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) { SWVoiceIn *sw; int captured = 0, min; @@ -1274,8 +1268,8 @@ static int audio_driver_init(AudioState *s, struct audio_driver *drv, s->drv_opaque = drv->init(dev); if (s->drv_opaque) { - audio_init_nb_voices_out (drv); - audio_init_nb_voices_in (drv); + audio_init_nb_voices_out(s, drv); + audio_init_nb_voices_in(s, drv); s->drv = drv; return 0; } @@ -1294,11 +1288,11 @@ static void audio_vm_change_state_handler (void *opaque, int running, int op = running ? VOICE_ENABLE : VOICE_DISABLE; s->vm_running = running; - while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { + while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) { hwo->pcm_ops->ctl_out(hwo, op); } - while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { + while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) { hwi->pcm_ops->ctl_in(hwi, op); } audio_reset_timer (s); @@ -1318,7 +1312,7 @@ void audio_cleanup(void) HWVoiceIn *hwi, *hwin; is_cleaning_up = true; - QLIST_FOREACH_SAFE(hwo, &glob_audio_state.hw_head_out, entries, hwon) { + QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) { SWVoiceCap *sc; if (hwo->enabled) { @@ -1337,7 +1331,7 @@ void audio_cleanup(void) QLIST_REMOVE(hwo, entries); } - QLIST_FOREACH_SAFE(hwi, &glob_audio_state.hw_head_in, entries, hwin) { + QLIST_FOREACH_SAFE(hwi, &s->hw_head_in, entries, hwin) { if (hwi->enabled) { hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE); } @@ -1537,7 +1531,7 @@ CaptureVoiceOut *AUD_add_capture ( cb->ops = *ops; cb->opaque = cb_opaque; - cap = audio_pcm_capture_find_specific (as); + cap = audio_pcm_capture_find_specific(s, as); if (cap) { QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); return cap; @@ -1554,6 +1548,7 @@ CaptureVoiceOut *AUD_add_capture ( } hw = &cap->hw; + hw->s = s; QLIST_INIT (&hw->sw_head); QLIST_INIT (&cap->cb_head); @@ -1586,7 +1581,7 @@ CaptureVoiceOut *AUD_add_capture ( QLIST_INSERT_HEAD (&s->cap_head, cap, entries); QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); - QLIST_FOREACH(hw, &glob_audio_state.hw_head_out, entries) { + QLIST_FOREACH(hw, &s->hw_head_out, entries) { audio_attach_capture (hw); } return cap; From patchwork Wed Jan 16 23:36:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767137 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF45314E5 for ; Wed, 16 Jan 2019 23:48:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CECDC2E0A0 for ; Wed, 16 Jan 2019 23:48:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C274A2E550; Wed, 16 Jan 2019 23:48:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C11352E0A0 for ; Wed, 16 Jan 2019 23:48:16 +0000 (UTC) Received: from localhost ([127.0.0.1]:33870 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuut-0004NK-Mk for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:48:15 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58000) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046y-4c for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukj-0002u6-VI for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:34220) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002mk-DF for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wm1-x344.google.com with SMTP id y185so2237189wmd.1 for ; Wed, 16 Jan 2019 15:37:41 -0800 (PST) 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=TI0EmIaSe+5Fe9B3nzKWXb3LkjtVy7CLlQBC1bWXfh4=; b=fBkHT5uiqiDET3rFa5N/PJ/KHs4q1HGX/BiCxv0/BIgc3pwHRkuv1E0L/YbqhmBvHG rfqG6qRrGXgAYw8HI5CYCrcfBM9vDy8zGOEGgD4hMQrvwhOp1yJ6Ruta/jUzbIs/g1z9 7J9E6DSp+5WFPpx7JHuqtoKSIkEIDg7PGKVKYtc0DKqKww+/DJn/BJGhYmdn8tGlbhDd yn+y37dlLRxgEhJB6RhXa9Pq0hwTiQCHQSDjh1ZinCjW7mOGbaPKoO2hAdg4NSz89pDs 4UPRWGhjvJVMlzetDpqgcnk4nIyCDjL/qAipZjsSGOyCksHQ0zdFwwqenLWVgTHD0FqM 4ngA== 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=TI0EmIaSe+5Fe9B3nzKWXb3LkjtVy7CLlQBC1bWXfh4=; b=mcBmIOC0Xzi2TAnjJXqVCvHj8IHgJdjv9/JCe551uk89JiVhvNwkLx5ZpzIl2Xyr0U JypNheVkhx+83m77g29hyAz7LR9+RzwBECv42L/BJCFDMmhmLa3LUwhC2UfkPqF9H8Ox fCwcorCN7F4r/k5KGeIYaAj4+52zo0I6gNMQQGg19o3w9rOtqefPPn6RIDZ+FvKJZ1Pq QqtgyuOnwtKyVcOlgQDmUgpw39BXCNi15tcSh55qWOZkD7hkyYcZiIOiRaddQFPVbTsi 8hjZ0IV0+55Nl2IXbY9zMgcDrsWBMuG3hQDqUtydi2+/Vrg+MUgpJFtEeechRJbLWiIX rYCA== X-Gm-Message-State: AJcUukcLXJfggloD3JJc4UfYi+xvrK56hOe+5YVC8rSCWT5gIkeKGFLh pRvxkvQHhMjYmLu7SaUUQC+ewAfxf2I= X-Google-Smtp-Source: ALg8bN71/RSzUpIOqEpK+LynWfIcqz58OwWIOQZzq0hyaGlkY/vFenERJI/n7xPrJnZdtQNf6Ya3PA== X-Received: by 2002:a1c:3282:: with SMTP id y124mr9719090wmy.134.1547681859703; Wed, 16 Jan 2019 15:37:39 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:39 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:49 +0100 Message-Id: <5e388f3dba2604567157f86ca83bad1fa28123d9.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v3 16/50] audio: basic support for multi backend audio X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Markus Armbruster , Gerd Hoffmann , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Audio functions no longer access glob_audio_state, instead they get an AudioState as a parameter. This is required in order to support multiple backends. glob_audio_state is also gone, and replaced with a tailq so we can store more than one states. Signed-off-by: Kővágó, Zoltán --- audio/audio.h | 12 +++-- audio/audio_int.h | 2 + audio/audio_template.h | 2 +- ui/vnc.h | 2 + audio/audio.c | 102 +++++++++++++++++++++++++++++++---------- audio/wavcapture.c | 6 +-- monitor.c | 12 ++++- ui/vnc.c | 15 +++++- hmp-commands.hx | 11 +++-- qemu-options.hx | 5 ++ 10 files changed, 131 insertions(+), 38 deletions(-) diff --git a/audio/audio.h b/audio/audio.h index 64b0f761bc..ad2457f4de 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -78,8 +78,10 @@ typedef struct SWVoiceOut SWVoiceOut; typedef struct CaptureVoiceOut CaptureVoiceOut; typedef struct SWVoiceIn SWVoiceIn; +typedef struct AudioState AudioState; typedef struct QEMUSoundCard { char *name; + AudioState *state; QLIST_ENTRY (QEMUSoundCard) entries; } QEMUSoundCard; @@ -92,7 +94,8 @@ void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void AUD_register_card (const char *name, QEMUSoundCard *card); void AUD_remove_card (QEMUSoundCard *card); -CaptureVoiceOut *AUD_add_capture ( +CaptureVoiceOut *AUD_add_capture( + AudioState *s, struct audsettings *as, struct audio_capture_ops *ops, void *opaque @@ -160,8 +163,8 @@ static inline void *advance (void *p, int incr) #define audio_MAX(a, b) ((a)<(b)?(b):(a)) #endif -int wav_start_capture (CaptureState *s, const char *path, int freq, - int bits, int nchannels); +int wav_start_capture(AudioState *state, CaptureState *s, const char *path, + int freq, int bits, int nchannels); bool audio_is_cleaning_up(void); void audio_cleanup(void); @@ -175,4 +178,7 @@ void audio_parse_option(const char *opt); void audio_init_audiodevs(void); void audio_legacy_help(void); +AudioState *audio_state_by_name(const char *name); +const char *audio_get_id(QEMUSoundCard *card); + #endif /* QEMU_AUDIO_H */ diff --git a/audio/audio_int.h b/audio/audio_int.h index 2a7556d113..5ceea76eda 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -195,6 +195,8 @@ struct AudioState { bool timer_running; uint64_t timer_last; + + QTAILQ_ENTRY(AudioState) list; }; extern const struct mixeng_volume nominal_volume; diff --git a/audio/audio_template.h b/audio/audio_template.h index ccf6d810f7..ce1e5d6559 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -399,7 +399,7 @@ SW *glue (AUD_open_, TYPE) ( struct audsettings *as ) { - AudioState *s = &glob_audio_state; + AudioState *s = card->state; AudiodevPerDirectionOptions *pdo = s->dev->TYPE; if (audio_bug(__func__, !card || !name || !callback_fn || !as)) { diff --git a/ui/vnc.h b/ui/vnc.h index a86e0610e8..0c9a2d82e0 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -181,6 +181,8 @@ struct VncDisplay #ifdef CONFIG_VNC_SASL VncDisplaySASL sasl; #endif + + AudioState *audio_state; }; typedef struct VncTight { diff --git a/audio/audio.c b/audio/audio.c index ef8ce3b91d..2f9f37afb8 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -85,7 +85,8 @@ audio_driver *audio_driver_lookup(const char *name) return NULL; } -static AudioState glob_audio_state; +static QTAILQ_HEAD(AudioStateHead, AudioState) audio_states = + QTAILQ_HEAD_INITIALIZER(audio_states); const struct mixeng_volume nominal_volume = { .mute = 0, @@ -1239,11 +1240,14 @@ static void audio_run_capture (AudioState *s) void audio_run (const char *msg) { - AudioState *s = &glob_audio_state; + AudioState *s; + + QTAILQ_FOREACH(s, &audio_states, list) { + audio_run_out (s); + audio_run_in (s); + audio_run_capture (s); + } - audio_run_out (s); - audio_run_in (s); - audio_run_capture (s); #ifdef DEBUG_POLL { static double prevtime; @@ -1305,13 +1309,11 @@ bool audio_is_cleaning_up(void) return is_cleaning_up; } -void audio_cleanup(void) +static void free_audio_state(AudioState *s) { - AudioState *s = &glob_audio_state; HWVoiceOut *hwo, *hwon; HWVoiceIn *hwi, *hwin; - is_cleaning_up = true; QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) { SWVoiceCap *sc; @@ -1348,6 +1350,17 @@ void audio_cleanup(void) qapi_free_Audiodev(s->dev); s->dev = NULL; } + g_free(s); +} + +void audio_cleanup(void) +{ + is_cleaning_up = true; + while (!QTAILQ_EMPTY(&audio_states)) { + AudioState *s = QTAILQ_FIRST(&audio_states); + QTAILQ_REMOVE(&audio_states, s, list); + free_audio_state(s); + } } static const VMStateDescription vmstate_audio = { @@ -1374,28 +1387,33 @@ static AudiodevListEntry *audiodev_find( return NULL; } -static int audio_init(Audiodev *dev) +/* + * if we have dev, this function was called because of an -audiodev argument => + * initialize a new state with it + * if dev == NULL => legacy implicit initialization, return the already created + * state or create a new one + */ +static AudioState *audio_init(Audiodev *dev) { + static bool atexit_registered; size_t i; int done = 0; const char *drvname = NULL; VMChangeStateEntry *e; - AudioState *s = &glob_audio_state; + AudioState *s; struct audio_driver *driver; /* silence gcc warning about uninitialized variable */ AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head); - if (s->drv) { - if (dev) { - dolog("Cannot create more than one audio backend, sorry\n"); - qapi_free_Audiodev(dev); - } - return -1; - } - if (dev) { /* -audiodev option */ drvname = AudiodevDriver_str(dev->driver); + } else if (!QTAILQ_EMPTY(&audio_states)) { + /* + * todo: check for -audiodev once we have normal audiodev selection + * support + */ + return QTAILQ_FIRST(&audio_states); } else { /* legacy implicit initialization */ head = audio_handle_legacy_opts(); @@ -1409,12 +1427,18 @@ static int audio_init(Audiodev *dev) dev = QSIMPLEQ_FIRST(&head)->dev; audio_validate_opts(dev, &error_abort); } + + s = g_malloc0(sizeof(AudioState)); s->dev = dev; QLIST_INIT (&s->hw_head_out); QLIST_INIT (&s->hw_head_in); QLIST_INIT (&s->cap_head); - atexit(audio_cleanup); + if (!atexit_registered) { + atexit(audio_cleanup); + atexit_registered = true; + } + QTAILQ_INSERT_TAIL(&audio_states, s, list); s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s); @@ -1478,7 +1502,7 @@ static int audio_init(Audiodev *dev) QLIST_INIT (&s->card_head); vmstate_register (NULL, 0, &vmstate_audio, s); - return 0; + return s; } void audio_free_audiodev_list(AudiodevListHead *head) @@ -1493,10 +1517,13 @@ void audio_free_audiodev_list(AudiodevListHead *head) void AUD_register_card (const char *name, QEMUSoundCard *card) { - audio_init(NULL); + if (!card->state) { + card->state = audio_init(NULL); + } + card->name = g_strdup (name); memset (&card->entries, 0, sizeof (card->entries)); - QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries); + QLIST_INSERT_HEAD (&card->state->card_head, card, entries); } void AUD_remove_card (QEMUSoundCard *card) @@ -1506,16 +1533,21 @@ void AUD_remove_card (QEMUSoundCard *card) } -CaptureVoiceOut *AUD_add_capture ( +CaptureVoiceOut *AUD_add_capture( + AudioState *s, struct audsettings *as, struct audio_capture_ops *ops, void *cb_opaque ) { - AudioState *s = &glob_audio_state; CaptureVoiceOut *cap; struct capture_callback *cb; + if (!s) { + /* todo: remove when we have normal audiodev selection support */ + s = audio_init(NULL); + } + if (audio_validate_settings (as)) { dolog ("Invalid settings were passed when trying to add capture\n"); audio_print_settings (as); @@ -1807,3 +1839,25 @@ int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo, return audio_buffer_samples(pdo, as, def_usecs) * audioformat_bytes_per_sample(as->fmt); } + +AudioState *audio_state_by_name(const char *name) +{ + AudioState *s; + QTAILQ_FOREACH(s, &audio_states, list) { + assert(s->dev); + if (strcmp(name, s->dev->id) == 0) { + return s; + } + } + return NULL; +} + +const char *audio_get_id(QEMUSoundCard *card) +{ + if (card->state) { + assert(card->state->dev); + return card->state->dev->id; + } else { + return ""; + } +} diff --git a/audio/wavcapture.c b/audio/wavcapture.c index e943565210..88d3141be5 100644 --- a/audio/wavcapture.c +++ b/audio/wavcapture.c @@ -107,8 +107,8 @@ static struct capture_ops wav_capture_ops = { .info = wav_capture_info }; -int wav_start_capture (CaptureState *s, const char *path, int freq, - int bits, int nchannels) +int wav_start_capture(AudioState *state, CaptureState *s, const char *path, + int freq, int bits, int nchannels) { Monitor *mon = cur_mon; WAVState *wav; @@ -175,7 +175,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, goto error_free; } - cap = AUD_add_capture (&as, &ops, wav); + cap = AUD_add_capture(state, &as, &ops, wav); if (!cap) { monitor_printf (mon, "Failed to add audio capture\n"); goto error_free; diff --git a/monitor.c b/monitor.c index eb39fb015b..d572b7aaed 100644 --- a/monitor.c +++ b/monitor.c @@ -2038,7 +2038,17 @@ static void hmp_wavcapture(Monitor *mon, const QDict *qdict) int bits = qdict_get_try_int(qdict, "bits", -1); int has_channels = qdict_haskey(qdict, "nchannels"); int nchannels = qdict_get_try_int(qdict, "nchannels", -1); + const char *audiodev = qdict_get_try_str(qdict, "audiodev"); CaptureState *s; + AudioState *as = NULL; + + if (audiodev) { + as = audio_state_by_name(audiodev); + if (!as) { + monitor_printf(mon, "Invalid audiodev specified\n"); + return; + } + } s = g_malloc0 (sizeof (*s)); @@ -2046,7 +2056,7 @@ static void hmp_wavcapture(Monitor *mon, const QDict *qdict) bits = has_bits ? bits : 16; nchannels = has_channels ? nchannels : 2; - if (wav_start_capture (s, path, freq, bits, nchannels)) { + if (wav_start_capture(as, s, path, freq, bits, nchannels)) { monitor_printf(mon, "Failed to add wave capture\n"); g_free (s); return; diff --git a/ui/vnc.c b/ui/vnc.c index 48c1b95aae..f388ff75fb 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1195,7 +1195,7 @@ static void audio_add(VncState *vs) ops.destroy = audio_capture_destroy; ops.capture = audio_capture; - vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs); + vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs); if (!vs->audio_cap) { error_report("Failed to add audio capture"); } @@ -3390,6 +3390,9 @@ static QemuOptsList qemu_vnc_opts = { },{ .name = "non-adaptive", .type = QEMU_OPT_BOOL, + },{ + .name = "audiodev", + .type = QEMU_OPT_STRING, }, { /* end of list */ } }, @@ -3825,6 +3828,7 @@ void vnc_display_open(const char *id, Error **errp) int acl = 0; int lock_key_sync = 1; int key_delay_ms; + const char *audiodev; if (!vd) { error_setg(errp, "VNC display not active"); @@ -3978,6 +3982,15 @@ void vnc_display_open(const char *id, Error **errp) vd->ledstate = 0; vd->key_delay_ms = key_delay_ms; + audiodev = qemu_opt_get(opts, "audiodev"); + if (audiodev) { + vd->audio_state = audio_state_by_name(audiodev); + if (!vd->audio_state) { + error_setg(errp, "Audiodev '%s' not found", audiodev); + goto fail; + } + } + device_id = qemu_opt_get(opts, "display"); if (device_id) { int head = qemu_opt_get_number(opts, "head", 0); diff --git a/hmp-commands.hx b/hmp-commands.hx index ba71558c25..dc339a5484 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -796,16 +796,17 @@ ETEXI { .name = "wavcapture", - .args_type = "path:F,freq:i?,bits:i?,nchannels:i?", - .params = "path [frequency [bits [channels]]]", + .args_type = "path:F,freq:i?,bits:i?,nchannels:i?,audiodev:s?", + .params = "path [frequency [bits [channels [audiodev]]]]", .help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)", .cmd = hmp_wavcapture, }, STEXI -@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]] +@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels} [@var{audiodev}]]]] @findex wavcapture -Capture audio into @var{filename}. Using sample rate @var{frequency} -bits per sample @var{bits} and number of channels @var{channels}. +Capture audio into @var{filename} from @var{audiodev}. Using sample rate +@var{frequency} bits per sample @var{bits} and number of channels +@var{channels}. Defaults: @itemize @minus diff --git a/qemu-options.hx b/qemu-options.hx index a12931899b..098508ce09 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1911,6 +1911,11 @@ can help the device and guest to keep up and not lose events in case events are arriving in bulk. Possible causes for the latter are flaky network connections, or scripts for automated testing. +@item audiodev=@var{audiodev} + +Use the specified @var{audiodev} when the VNC client requests audio +transmission. + @end table ETEXI From patchwork Wed Jan 16 23:36:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767139 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6812513A4 for ; Wed, 16 Jan 2019 23:48:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57A252E0A0 for ; Wed, 16 Jan 2019 23:48:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B50D2E550; Wed, 16 Jan 2019 23:48:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7A3062E0A0 for ; Wed, 16 Jan 2019 23:48:19 +0000 (UTC) Received: from localhost ([127.0.0.1]:33882 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuuw-0004PC-Ot for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:48:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046z-4h for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002vN-96 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:36103) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002nr-OY for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:46 -0500 Received: by mail-wr1-x444.google.com with SMTP id u4so8967341wrp.3 for ; Wed, 16 Jan 2019 15:37:42 -0800 (PST) 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=kZIvbiBfgpP/E3+rQermZlJ5HaP8zQzEtPimp+vQ+YM=; b=YM1s7iA6jBxFhyiCKhz14e0N7OoI7WaZZwiqVnumv9R0s7Kx/tE2a2POXd1A6c4Ywd SMK0cMsMhCBIGf31Ym6e1yRJ7um2atQRDxMz0DxFZGM7iu4UYGSe6p7dc5YDBVeLHq19 YKlZVqkvRvZNCwdCMZiUqeJuDdqxyjhAluWFrx4lA2Awbs8g9frjC1FLnjHO5cpibNBR RIdngUSjnRGndi/hQfWlREv30Vt250Ry0IjmuKYCz4SbiVnvBfpwtNDRiMaVPXV5O3KA tsTzwOqi/1FiQT6L1I5Z8WUjBsBlXhXqMEuLGUVgPY0Pp4SPswOwkcU5sh54a9oi1gbd nwww== 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=kZIvbiBfgpP/E3+rQermZlJ5HaP8zQzEtPimp+vQ+YM=; b=TMVCesCTtSKkz/K5yhlq4cXvtuwyC+S67WK/EO8TrkeRy4kQU+l2v5d575IT9l53EA AM10LBV47aCi/JtMFJpRXU6wwL/w2yBSKR652FBMDJYd9XrWfD7gHeviJ5UjqVjJdFpP beelS69XmpdXdDlLebw58vRlbLqcWlfWUEqdg5KdKhijk4rdN1CYJwTVBvRHAqWKcP5f /vSH+fZZUZJ/6FI08Q47jSCCxgtjHHrd6WvX7/WcGVEYK4e9MkjOiZzjZhDo8Mf5crPH IT4ZCUdv01ygXPsPGvM+VXlvCpxEbckhPLwu0fsUCOjL/g0CK6xEM9LXxWab2XmpptnK 1SuA== X-Gm-Message-State: AJcUukcbPcJlOY0ycp7qpG6fXAtwUYnyU8z9uRgWRjudZDdFhpeqfRYN DVJVJWAy6CBBykBsQEm54BScmmMtrdE= X-Google-Smtp-Source: ALg8bN6RQJuOTNStJoDn0R0kDk5FXInDNAHoSM4Brr49rIHVc2XaGf06DUUFz6tjCMvaJ4xEMA1WCg== X-Received: by 2002:adf:9205:: with SMTP id 5mr9437519wrj.189.1547681860809; Wed, 16 Jan 2019 15:37:40 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:40 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:50 +0100 Message-Id: <6d0d1750d8a588aee76d14b08bdef7948ed02d6c.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 17/50] audio: add audiodev properties to frontends X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Walle , Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Finally add audiodev= options to audio frontends so users can specify which backend to use when multiple backends exist. Not specifying an audiodev= option currently causes the first audiodev to be used, this is fixed in the next commit. Example usage: -audiodev pa,id=foo -device AC97,audiodev=foo Signed-off-by: Kővágó, Zoltán --- audio/audio.h | 3 ++ include/hw/qdev-properties.h | 3 ++ hw/audio/ac97.c | 1 + hw/audio/adlib.c | 1 + hw/audio/cs4231a.c | 1 + hw/audio/es1370.c | 7 +++- hw/audio/gus.c | 1 + hw/audio/hda-codec.c | 1 + hw/audio/milkymist-ac97.c | 6 ++++ hw/audio/pcspk.c | 1 + hw/audio/pl041.c | 1 + hw/audio/sb16.c | 1 + hw/audio/wm8750.c | 6 ++++ hw/core/qdev-properties-system.c | 57 ++++++++++++++++++++++++++++++++ hw/usb/dev-audio.c | 1 + 15 files changed, 90 insertions(+), 1 deletion(-) diff --git a/audio/audio.h b/audio/audio.h index ad2457f4de..c0722a5cda 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -181,4 +181,7 @@ void audio_legacy_help(void); AudioState *audio_state_by_name(const char *name); const char *audio_get_id(QEMUSoundCard *card); +#define DEFINE_AUDIO_PROPERTIES(_s, _f) \ + DEFINE_PROP_AUDIODEV("audiodev", _s, _f) + #endif /* QEMU_AUDIO_H */ diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index b6758c852e..6156409062 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -34,6 +34,7 @@ extern const PropertyInfo qdev_prop_blocksize; extern const PropertyInfo qdev_prop_pci_host_devaddr; extern const PropertyInfo qdev_prop_uuid; extern const PropertyInfo qdev_prop_arraylen; +extern const PropertyInfo qdev_prop_audiodev; extern const PropertyInfo qdev_prop_link; extern const PropertyInfo qdev_prop_off_auto_pcibar; extern const PropertyInfo qdev_prop_pcie_link_speed; @@ -233,6 +234,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width; + type_check(QemuUUID, typeof_field(_state, _field)), \ .set_default = true, \ } +#define DEFINE_PROP_AUDIODEV(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard) #define DEFINE_PROP_END_OF_LIST() \ {} diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 2265622d44..03e3da4f31 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -1408,6 +1408,7 @@ static int ac97_init (PCIBus *bus) } static Property ac97_properties[] = { + DEFINE_AUDIO_PROPERTIES(AC97LinkState, card), DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0), DEFINE_PROP_END_OF_LIST (), }; diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 0957780a3d..0d01cd07c5 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -298,6 +298,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) } static Property adlib_properties[] = { + DEFINE_AUDIO_PROPERTIES(AdlibState, card), DEFINE_PROP_UINT32 ("iobase", AdlibState, port, 0x220), DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100), DEFINE_PROP_END_OF_LIST (), diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index 62da75eefe..d25a120b0f 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -687,6 +687,7 @@ static int cs4231a_init (ISABus *bus) } static Property cs4231a_properties[] = { + DEFINE_AUDIO_PROPERTIES(CSState, card), DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534), DEFINE_PROP_UINT32 ("irq", CSState, irq, 9), DEFINE_PROP_UINT32 ("dma", CSState, dma, 3), diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index a5314d66fd..8c63912a82 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -886,6 +886,11 @@ static int es1370_init (PCIBus *bus) return 0; } +static Property es1370_properties[] = { + DEFINE_AUDIO_PROPERTIES(ES1370State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void es1370_class_init (ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS (klass); @@ -902,6 +907,7 @@ static void es1370_class_init (ObjectClass *klass, void *data) dc->desc = "ENSONIQ AudioPCI ES1370"; dc->vmsd = &vmstate_es1370; dc->reset = es1370_on_reset; + dc->props = es1370_properties; } static const TypeInfo es1370_info = { @@ -922,4 +928,3 @@ static void es1370_register_types (void) } type_init (es1370_register_types) - diff --git a/hw/audio/gus.c b/hw/audio/gus.c index b3e2a7fdd5..dfb74cf0d3 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -295,6 +295,7 @@ static int GUS_init (ISABus *bus) } static Property gus_properties[] = { + DEFINE_AUDIO_PROPERTIES(GUSState, card), DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100), DEFINE_PROP_UINT32 ("iobase", GUSState, port, 0x240), DEFINE_PROP_UINT32 ("irq", GUSState, emu.gusirq, 7), diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index c25bfa38b1..e66103aedf 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -839,6 +839,7 @@ static const VMStateDescription vmstate_hda_audio = { }; static Property hda_audio_properties[] = { + DEFINE_AUDIO_PROPERTIES(HDAAudioState, card), DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0), DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer, true), DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, true), diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c index 90cce1e6ed..8739cb376a 100644 --- a/hw/audio/milkymist-ac97.c +++ b/hw/audio/milkymist-ac97.c @@ -328,6 +328,11 @@ static const VMStateDescription vmstate_milkymist_ac97 = { } }; +static Property milkymist_ac97_properties[] = { + DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void milkymist_ac97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -335,6 +340,7 @@ static void milkymist_ac97_class_init(ObjectClass *klass, void *data) dc->realize = milkymist_ac97_realize; dc->reset = milkymist_ac97_reset; dc->vmsd = &vmstate_milkymist_ac97; + dc->props = milkymist_ac97_properties; } static const TypeInfo milkymist_ac97_info = { diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 4a7386a689..1457cd1ac6 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -208,6 +208,7 @@ static const VMStateDescription vmstate_spk = { }; static Property pcspk_properties[] = { + DEFINE_AUDIO_PROPERTIES(PCSpkState, card), DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1), DEFINE_PROP_BOOL("migrate", PCSpkState, migrate, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index c8cc503236..fca1dc8a54 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -621,6 +621,7 @@ static const VMStateDescription vmstate_pl041 = { }; static Property pl041_device_properties[] = { + DEFINE_AUDIO_PROPERTIES(PL041State, codec.card), /* Non-compact FIFO depth property */ DEFINE_PROP_UINT32("nc_fifo_depth", PL041State, fifo_depth, DEFAULT_FIFO_DEPTH), diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 65ea0cd938..5a6a880f2e 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1419,6 +1419,7 @@ static int SB16_init (ISABus *bus) } static Property sb16_properties[] = { + DEFINE_AUDIO_PROPERTIES(SB16State, card), DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */ DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220), DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5), diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c index d563f31e7c..0451ad87f1 100644 --- a/hw/audio/wm8750.c +++ b/hw/audio/wm8750.c @@ -700,6 +700,11 @@ void wm8750_set_bclk_in(void *opaque, int new_hz) wm8750_clk_update(s, 1); } +static Property wm8750_properties[] = { + DEFINE_AUDIO_PROPERTIES(WM8750State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void wm8750_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -710,6 +715,7 @@ static void wm8750_class_init(ObjectClass *klass, void *data) sc->recv = wm8750_rx; sc->send = wm8750_tx; dc->vmsd = &vmstate_wm8750; + dc->props = wm8750_properties; } static const TypeInfo wm8750_info = { diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index b45a7ef54b..4659b6986f 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "audio/audio.h" #include "net/net.h" #include "hw/qdev.h" #include "qapi/error.h" @@ -318,6 +319,62 @@ const PropertyInfo qdev_prop_netdev = { }; +/* --- audiodev --- */ +static void get_audiodev(Object *obj, Visitor *v, const char* name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); + char *p = g_strdup(audio_get_id(card)); + + visit_type_str(v, name, &p, errp); + g_free(p); +} + +static void set_audiodev(Object *obj, Visitor *v, const char* name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); + AudioState *state; + Error *local_err = NULL; + int err = 0; + char *str; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + state = audio_state_by_name(str); + + if (!state) { + err = -ENOENT; + goto out; + } + card->state = state; + +out: + error_set_from_qdev_prop_error(errp, err, dev, prop, str); + g_free(str); +} + +const PropertyInfo qdev_prop_audiodev = { + .name = "str", + .description = "ID of an audiodev to use as a backend", + /* release done on shutdown */ + .get = get_audiodev, + .set = set_audiodev, +}; + void qdev_prop_set_drive(DeviceState *dev, const char *name, BlockBackend *value, Error **errp) { diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index c46d5eeb79..84e737808c 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -666,6 +666,7 @@ static const VMStateDescription vmstate_usb_audio = { }; static Property usb_audio_properties[] = { + DEFINE_AUDIO_PROPERTIES(USBAudioState, card), DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0), DEFINE_PROP_UINT32("buffer", USBAudioState, buffer, 32 * USBAUDIO_PACKET_SIZE), From patchwork Wed Jan 16 23:36:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767153 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8539E6C2 for ; Wed, 16 Jan 2019 23:53:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 666DA29C84 for ; Wed, 16 Jan 2019 23:53:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59F6B2E4AB; Wed, 16 Jan 2019 23:53:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 14FE629C84 for ; Wed, 16 Jan 2019 23:53:51 +0000 (UTC) Received: from localhost ([127.0.0.1]:35201 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv0I-00005O-Oy for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:53:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58013) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000475-5I for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukl-0002yM-FN for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:54305) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukk-0002ok-MX for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:47 -0500 Received: by mail-wm1-x341.google.com with SMTP id a62so3880093wmh.4 for ; Wed, 16 Jan 2019 15:37:43 -0800 (PST) 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=L+CB8unO7bQwVogku0yg2X186UZgVPwFbGTfq0mECws=; b=aSjA1fcHtXmGqBZ+64gixou9z8pWMfKxhF2IRzfNJ/zHqHrWGjV9y19X5bCBLBebf4 rALMvJ45G3EUzUH5Vgmf1kz94DgkUWYUC+GsIcF/PYq6TH6tKW0HfySPELS1qSHbYuga oV57LjbxZUfI0Kk8c/bTK9/zMV+aTD1MZ0f+O6TMyPxptdXBBNJPDRiqUgxKa9U0ThYY iuFiickvwzzqOXUY3jRe/cZVIE9E3pEMeXz20CJcT1G7Wag6q//Jugmcn7+M0pqLZYs+ ESTffli0MQCA1gxJBEcrBwqPSsQl2nxKlrldaxcO+1MXSrgPRkH65XsgJNhJlsv+5EXY FpHQ== 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=L+CB8unO7bQwVogku0yg2X186UZgVPwFbGTfq0mECws=; b=LChTwRMUQWfR1wemzHWfHinwK2FDAoBKYnHYlkNTUpq3lc/xNnVg86yqTARPSBENl2 lv7dFAbuRgwXmyC9ZXKaKwk1p7eIoF7BBqs74J5XWd4nc+Uo1zQGzxgnUqeL1WKRqs1+ 9QePP4+PedQsWduF/2Bskua3vjWEBmxA1cQ4q//oSNJAwIob3N86ovzHoOC5o5JStf0/ gG+7WIwUhVFR8rrulYN2PsEkNp1pxdh2FlFfx0TOY2Jj5Ngjr5QetSqyQFOWgXKBxjGV 2M0Q8o7LSRP81JUd6D/FZWWQuYt3cut/KUwmaMdco8OR7+XPbe7Chmg/3K6x2OcATVuW iHhw== X-Gm-Message-State: AJcUukdNX3s1QC3MqKzsAml9qOqzbvJf9HPcJMFac2aoeJ3EOqcYciay tyVRfckbhTmjlJtuMa7NgWQpNMcsp18= X-Google-Smtp-Source: ALg8bN5IMl2s/9/Q701YH/PNMGvxR5b+s4Q/11mDw5EtgDpUwSZytYrPyd1m9AUtexByxM2od9Dz9w== X-Received: by 2002:a1c:bb04:: with SMTP id l4mr9402903wmf.142.1547681861791; Wed, 16 Jan 2019 15:37:41 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:41 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:51 +0100 Message-Id: <2770bdbdff44ea3ca88ab30378a8eddbd7e2ef52.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v3 18/50] audio: audiodev= parameters no longer optional when -audiodev present X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This means you should probably stop using -soundhw (as it doesn't allow you to specify any options) and add the device manually with -device. The exception is pcspk, it's currently not possible to manually add it. To use it with audiodev, use something like this: -audiodev id=foo,... -global isa-pcspk.audiodev=foo -soundhw pcspk Signed-off-by: Kővágó, Zoltán Signed-off-by: Gerd Hoffmann --- audio/audio.c | 24 ++-- audio/paaudio.c | 304 ++++++++++++++++++++++++++++-------------------- 2 files changed, 190 insertions(+), 138 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 2f9f37afb8..f768a6059d 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -99,6 +99,8 @@ const struct mixeng_volume nominal_volume = { #endif }; +static bool legacy_config = true; + #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED #error No its not #else @@ -1393,7 +1395,7 @@ static AudiodevListEntry *audiodev_find( * if dev == NULL => legacy implicit initialization, return the already created * state or create a new one */ -static AudioState *audio_init(Audiodev *dev) +static AudioState *audio_init(Audiodev *dev, const char *name) { static bool atexit_registered; size_t i; @@ -1407,12 +1409,13 @@ static AudioState *audio_init(Audiodev *dev) if (dev) { /* -audiodev option */ + legacy_config = false; drvname = AudiodevDriver_str(dev->driver); } else if (!QTAILQ_EMPTY(&audio_states)) { - /* - * todo: check for -audiodev once we have normal audiodev selection - * support - */ + if (!legacy_config) { + dolog("You must specify an audiodev= for the device %s\n", name); + exit(1); + } return QTAILQ_FIRST(&audio_states); } else { /* legacy implicit initialization */ @@ -1518,7 +1521,7 @@ void audio_free_audiodev_list(AudiodevListHead *head) void AUD_register_card (const char *name, QEMUSoundCard *card) { if (!card->state) { - card->state = audio_init(NULL); + card->state = audio_init(NULL, name); } card->name = g_strdup (name); @@ -1544,8 +1547,11 @@ CaptureVoiceOut *AUD_add_capture( struct capture_callback *cb; if (!s) { - /* todo: remove when we have normal audiodev selection support */ - s = audio_init(NULL); + if (!legacy_config) { + dolog("You must specify audiodev when trying to capture\n"); + goto err0; + } + s = audio_init(NULL, NULL); } if (audio_validate_settings (as)) { @@ -1778,7 +1784,7 @@ void audio_init_audiodevs(void) AudiodevListEntry *e; QSIMPLEQ_FOREACH(e, &audiodevs, next) { - audio_init(e->dev); + audio_init(e->dev, NULL); } } diff --git a/audio/paaudio.c b/audio/paaudio.c index 33e0e5d9be..1c20f8a7aa 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -10,10 +10,21 @@ #include "audio_int.h" #include "audio_pt_int.h" -typedef struct { - Audiodev *dev; +typedef struct PAConnection { + char *server; + int refcount; + QTAILQ_ENTRY(PAConnection) list; + pa_threaded_mainloop *mainloop; pa_context *context; +} PAConnection; + +static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns = + QTAILQ_HEAD_INITIALIZER(pa_conns); + +typedef struct { + Audiodev *dev; + PAConnection *conn; } paaudio; typedef struct { @@ -44,7 +55,7 @@ typedef struct { int samples; } PAVoiceIn; -static void qpa_audio_fini(void *opaque); +static void qpa_conn_fini(PAConnection *c); static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...) { @@ -107,11 +118,11 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror) { - paaudio *g = p->g; + PAConnection *c = p->g->conn; - pa_threaded_mainloop_lock (g->mainloop); + pa_threaded_mainloop_lock(c->mainloop); - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); while (length > 0) { size_t l; @@ -120,11 +131,11 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror int r; r = pa_stream_peek (p->stream, &p->read_data, &p->read_length); - CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail); + CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); if (!p->read_data) { - pa_threaded_mainloop_wait (g->mainloop); - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); + pa_threaded_mainloop_wait(c->mainloop); + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); } else { p->read_index = 0; } @@ -147,53 +158,53 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror p->read_length = 0; p->read_index = 0; - CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail); + CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); } } - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); return 0; unlock_and_fail: - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); return -1; } static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror) { - paaudio *g = p->g; + PAConnection *c = p->g->conn; - pa_threaded_mainloop_lock (g->mainloop); + pa_threaded_mainloop_lock(c->mainloop); - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); while (length > 0) { size_t l; int r; while (!(l = pa_stream_writable_size (p->stream))) { - pa_threaded_mainloop_wait (g->mainloop); - CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail); + pa_threaded_mainloop_wait(c->mainloop); + CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); } - CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail); + CHECK_SUCCESS_GOTO(c, rerror, l != (size_t) -1, unlock_and_fail); if (l > length) { l = length; } r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE); - CHECK_SUCCESS_GOTO (g, rerror, r >= 0, unlock_and_fail); + CHECK_SUCCESS_GOTO(c, rerror, r >= 0, unlock_and_fail); data = (const uint8_t *) data + l; length -= l; } - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); return 0; unlock_and_fail: - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); return -1; } @@ -431,13 +442,13 @@ static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness) static void context_state_cb (pa_context *c, void *userdata) { - paaudio *g = userdata; + PAConnection *conn = userdata; switch (pa_context_get_state(c)) { case PA_CONTEXT_READY: case PA_CONTEXT_TERMINATED: case PA_CONTEXT_FAILED: - pa_threaded_mainloop_signal (g->mainloop, 0); + pa_threaded_mainloop_signal(conn->mainloop, 0); break; case PA_CONTEXT_UNCONNECTED: @@ -450,14 +461,14 @@ static void context_state_cb (pa_context *c, void *userdata) static void stream_state_cb (pa_stream *s, void * userdata) { - paaudio *g = userdata; + PAConnection *c = userdata; switch (pa_stream_get_state (s)) { case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: - pa_threaded_mainloop_signal (g->mainloop, 0); + pa_threaded_mainloop_signal(c->mainloop, 0); break; case PA_STREAM_UNCONNECTED: @@ -468,13 +479,13 @@ static void stream_state_cb (pa_stream *s, void * userdata) static void stream_request_cb (pa_stream *s, size_t length, void *userdata) { - paaudio *g = userdata; + PAConnection *c = userdata; - pa_threaded_mainloop_signal (g->mainloop, 0); + pa_threaded_mainloop_signal(c->mainloop, 0); } static pa_stream *qpa_simple_new ( - paaudio *g, + PAConnection *c, const char *name, pa_stream_direction_t dir, const char *dev, @@ -485,50 +496,48 @@ static pa_stream *qpa_simple_new ( { int r; pa_stream *stream; + pa_stream_flags_t flags; - pa_threaded_mainloop_lock (g->mainloop); + pa_threaded_mainloop_lock(c->mainloop); - stream = pa_stream_new (g->context, name, ss, map); + stream = pa_stream_new(c->context, name, ss, map); if (!stream) { goto fail; } - pa_stream_set_state_callback (stream, stream_state_cb, g); - pa_stream_set_read_callback (stream, stream_request_cb, g); - pa_stream_set_write_callback (stream, stream_request_cb, g); + pa_stream_set_state_callback(stream, stream_state_cb, c); + pa_stream_set_read_callback(stream, stream_request_cb, c); + pa_stream_set_write_callback(stream, stream_request_cb, c); + + flags = + PA_STREAM_INTERPOLATE_TIMING +#ifdef PA_STREAM_ADJUST_LATENCY + |PA_STREAM_ADJUST_LATENCY +#endif + |PA_STREAM_AUTO_TIMING_UPDATE; if (dir == PA_STREAM_PLAYBACK) { - r = pa_stream_connect_playback (stream, dev, attr, - PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL); + r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL); } else { - r = pa_stream_connect_record (stream, dev, attr, - PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE); + r = pa_stream_connect_record(stream, dev, attr, flags); } if (r < 0) { goto fail; } - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); return stream; fail: - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); if (stream) { pa_stream_unref (stream); } - *rerror = pa_context_errno (g->context); + *rerror = pa_context_errno(c->context); return NULL; } @@ -544,6 +553,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, paaudio *g = pa->g = drv_opaque; AudiodevPaOptions *popts = &g->dev->u.pa; AudiodevPaPerDirectionOptions *ppdo = popts->sink; + PAConnection *c = g->conn; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; @@ -561,7 +571,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( - g, + c, "qemu", PA_STREAM_PLAYBACK, ppdo->has_name ? ppdo->name : NULL, @@ -613,6 +623,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) paaudio *g = pa->g = drv_opaque; AudiodevPaOptions *popts = &g->dev->u.pa; AudiodevPaPerDirectionOptions *ppdo = popts->source; + PAConnection *c = g->conn; ss.format = audfmt_to_pa (as->fmt, as->endianness); ss.channels = as->nchannels; @@ -621,7 +632,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness); pa->stream = qpa_simple_new ( - g, + c, "qemu", PA_STREAM_RECORD, ppdo->has_name ? ppdo->name : NULL, @@ -709,7 +720,7 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) PAVoiceOut *pa = (PAVoiceOut *) hw; pa_operation *op; pa_cvolume v; - paaudio *g = pa->g; + PAConnection *c = pa->g->conn; #ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */ pa_cvolume_init (&v); /* function is present in 0.9.13+ */ @@ -729,28 +740,28 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; - pa_threaded_mainloop_lock (g->mainloop); + pa_threaded_mainloop_lock(c->mainloop); - op = pa_context_set_sink_input_volume (g->context, + op = pa_context_set_sink_input_volume(c->context, pa_stream_get_index (pa->stream), &v, NULL, NULL); if (!op) - qpa_logerr (pa_context_errno (g->context), + qpa_logerr (pa_context_errno(c->context), "set_sink_input_volume() failed\n"); else pa_operation_unref (op); - op = pa_context_set_sink_input_mute (g->context, + op = pa_context_set_sink_input_mute(c->context, pa_stream_get_index (pa->stream), sw->vol.mute, NULL, NULL); if (!op) { - qpa_logerr (pa_context_errno (g->context), + qpa_logerr (pa_context_errno(c->context), "set_sink_input_mute() failed\n"); } else { pa_operation_unref (op); } - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); } } return 0; @@ -761,7 +772,7 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) PAVoiceIn *pa = (PAVoiceIn *) hw; pa_operation *op; pa_cvolume v; - paaudio *g = pa->g; + PAConnection *c = pa->g->conn; #ifdef PA_CHECK_VERSION pa_cvolume_init (&v); @@ -781,35 +792,96 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; - pa_threaded_mainloop_lock (g->mainloop); + pa_threaded_mainloop_lock(c->mainloop); - op = pa_context_set_source_output_volume (g->context, - pa_stream_get_index (pa->stream), + op = pa_context_set_source_output_volume(c->context, + pa_stream_get_index(pa->stream), &v, NULL, NULL); if (!op) { - qpa_logerr (pa_context_errno (g->context), - "set_source_output_volume() failed\n"); + qpa_logerr(pa_context_errno(c->context), + "set_source_output_volume() failed\n"); } else { pa_operation_unref(op); } - op = pa_context_set_source_output_mute (g->context, + op = pa_context_set_source_output_mute(c->context, pa_stream_get_index (pa->stream), sw->vol.mute, NULL, NULL); if (!op) { - qpa_logerr (pa_context_errno (g->context), - "set_source_output_mute() failed\n"); + qpa_logerr(pa_context_errno(c->context), + "set_source_output_mute() failed\n"); } else { pa_operation_unref (op); } - pa_threaded_mainloop_unlock (g->mainloop); + pa_threaded_mainloop_unlock(c->mainloop); } } return 0; } /* common */ +static void *qpa_conn_init(const char *server) +{ + PAConnection *c = g_malloc0(sizeof(PAConnection)); + QTAILQ_INSERT_TAIL(&pa_conns, c, list); + + c->mainloop = pa_threaded_mainloop_new(); + if (!c->mainloop) { + goto fail; + } + + c->context = pa_context_new(pa_threaded_mainloop_get_api(c->mainloop), + server); + if (!c->context) { + goto fail; + } + + pa_context_set_state_callback(c->context, context_state_cb, c); + + if (pa_context_connect(c->context, server, 0, NULL) < 0) { + qpa_logerr(pa_context_errno(c->context), + "pa_context_connect() failed\n"); + goto fail; + } + + pa_threaded_mainloop_lock(c->mainloop); + + if (pa_threaded_mainloop_start(c->mainloop) < 0) { + goto unlock_and_fail; + } + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(c->context); + + if (state == PA_CONTEXT_READY) { + break; + } + + if (!PA_CONTEXT_IS_GOOD (state)) { + qpa_logerr(pa_context_errno(c->context), + "Wrong context state\n"); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(c->mainloop); + } + + pa_threaded_mainloop_unlock(c->mainloop); + return c; + +unlock_and_fail: + pa_threaded_mainloop_unlock(c->mainloop); +fail: + AUD_log (AUDIO_CAP, "Failed to initialize PA context"); + qpa_conn_fini(c); + return NULL; +} + + static void qpa_init_per_direction(AudiodevPaPerDirectionOptions **ppdo, bool *has_ppdo) { @@ -824,91 +896,65 @@ static void *qpa_audio_init(Audiodev *dev) paaudio *g; AudiodevPaOptions *popts; const char *server; + PAConnection *c; assert(dev->driver == AUDIODEV_DRIVER_PA); qpa_init_per_direction(&dev->u.pa.sink, &dev->u.pa.has_sink); qpa_init_per_direction(&dev->u.pa.source, &dev->u.pa.has_source); - g = g_malloc(sizeof(paaudio)); + g = g_malloc0(sizeof(paaudio)); popts = &dev->u.pa; server = popts->has_server ? popts->server : NULL; g->dev = dev; - g->mainloop = NULL; - g->context = NULL; - g->mainloop = pa_threaded_mainloop_new (); - if (!g->mainloop) { - goto fail; - } - - g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop), - server); - if (!g->context) { - goto fail; - } - - pa_context_set_state_callback (g->context, context_state_cb, g); - - if (pa_context_connect (g->context, server, 0, NULL) < 0) { - qpa_logerr (pa_context_errno (g->context), - "pa_context_connect() failed\n"); - goto fail; - } - - pa_threaded_mainloop_lock (g->mainloop); - - if (pa_threaded_mainloop_start (g->mainloop) < 0) { - goto unlock_and_fail; - } - - for (;;) { - pa_context_state_t state; - - state = pa_context_get_state (g->context); - - if (state == PA_CONTEXT_READY) { + QTAILQ_FOREACH(c, &pa_conns, list) { + if (server == NULL || c->server == NULL ? + server == c->server : + strcmp(server, c->server) == 0) { + g->conn = c; break; } - - if (!PA_CONTEXT_IS_GOOD (state)) { - qpa_logerr (pa_context_errno (g->context), - "Wrong context state\n"); - goto unlock_and_fail; - } - - /* Wait until the context is ready */ - pa_threaded_mainloop_wait (g->mainloop); + } + if (!g->conn) { + g->conn = qpa_conn_init(server); + } + if (!g->conn) { + g_free(g); + return NULL; } - pa_threaded_mainloop_unlock (g->mainloop); - + ++g->conn->refcount; return g; +} -unlock_and_fail: - pa_threaded_mainloop_unlock (g->mainloop); -fail: - AUD_log (AUDIO_CAP, "Failed to initialize PA context"); - qpa_audio_fini(g); - return NULL; +static void qpa_conn_fini(PAConnection *c) +{ + if (c->mainloop) { + pa_threaded_mainloop_stop(c->mainloop); + } + + if (c->context) { + pa_context_disconnect(c->context); + pa_context_unref(c->context); + } + + if (c->mainloop) { + pa_threaded_mainloop_free(c->mainloop); + } + + QTAILQ_REMOVE(&pa_conns, c, list); + g_free(c); } static void qpa_audio_fini (void *opaque) { paaudio *g = opaque; + PAConnection *c = g->conn; - if (g->mainloop) { - pa_threaded_mainloop_stop (g->mainloop); - } - - if (g->context) { - pa_context_disconnect (g->context); - pa_context_unref (g->context); - } - - if (g->mainloop) { - pa_threaded_mainloop_free (g->mainloop); + if (--c->refcount == 0) { + qpa_conn_fini(c); } g_free(g); From patchwork Wed Jan 16 23:36:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C1DB3186E for ; Wed, 16 Jan 2019 23:42:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4CBC2F960 for ; Wed, 16 Jan 2019 23:42:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B353D2F9A6; Wed, 16 Jan 2019 23:42:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5B7AB2F981 for ; Wed, 16 Jan 2019 23:42:08 +0000 (UTC) Received: from localhost ([127.0.0.1]:60521 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuox-0007so-Jo for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:42:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57857) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukl-00043K-O1 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukj-0002tg-SS for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:47 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:35677) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002pd-Ef for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wm1-x344.google.com with SMTP id t200so3902618wmt.0 for ; Wed, 16 Jan 2019 15:37:43 -0800 (PST) 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=C35U8zbQkeepW8CJEAOXAWaqV2bg2NxGbRQ+s0W+GJM=; b=Lwk/QdKro1eT2fzz2NJ5EbT2hWpZLLtaaXAJQvGFWhxxEHvoFU3I4sUxdlUZNHPo8u 7IqadVNc5Wnkc+ehb/0Hx4/3jh6etXnnVCvv6bMlgqTIhOghLiSiht+r67ACdPK9sFB1 WmydxddwoPExf8ZDMLGMiInETkb2/zCy0LyACGmHlXkoKBlsTV2vBncKKOYwbQp1ePxw E6RvydMX56eAmWlMPe8X0nbEuBpsj4/EsuOSW7BSawZOlnPUxfFaoSoqxQCIG9uUxqQw M+Dgr/bTmUlNZuu2an7l9YBLWNgS5wquOOrRI0YasVWCYs6j+L+oYS9yVunR/lnw2fXU pwwg== 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=C35U8zbQkeepW8CJEAOXAWaqV2bg2NxGbRQ+s0W+GJM=; b=bvqBJNBO2mu2F9yYPwQn3aJkQrrmK4SRqQP/yARAUXDo833mIIjLJqSxiNS+4Kc4Bt VssFp+SwUtxHHys0P2dszIkJm5Vy2KzV41BzYXjjInWR4JTihjSBcFt4SWwhGV6Hz6Qr kQw8E1XnCWC3CpewppssoNqbXKdOjcw55lg/IjJd2Yek0MXsQW1IwVEn202H6QFLnF9Q IsMmpk8v81u6gRmaQSTYqOpFSsYt2Fhl1zAJ8yIko88vgAZzRJcdJWnQoO/cN9MOSRCn hiOC3UUjMM4LJfidPfhjC2lkdIYnQr4VmLWxzjSZ/9PGCPSyvrPG0aVrB9yrhSsvejHS UkIQ== X-Gm-Message-State: AJcUukdDnrLnbBVUW65nlWFsjYwbXvpPFIa7asiMmu828Y55M7fKJXey 1si/WQJvicHnksBLRW8m3MexsJOfy9M= X-Google-Smtp-Source: ALg8bN5UNd3BnRUWpCTsSgAy7yQIa8k4dVe0PLjBQTTEwsb7nqRqsSYVgiHKbYgNmVoGNU2WTXZA0g== X-Received: by 2002:a1c:9e4a:: with SMTP id h71mr9706301wme.82.1547681862866; Wed, 16 Jan 2019 15:37:42 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:42 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:52 +0100 Message-Id: <45bcd92296d27a5f3ec8938b396262b09395974e.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v3 19/50] paaudio: do not move stream when sink/source name is specified X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Unless we disable stream moving, pulseaudio can easily move the stream on connect, effectively ignoring the source/sink specified by the user. Signed-off-by: Kővágó, Zoltán --- audio/paaudio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/audio/paaudio.c b/audio/paaudio.c index 1c20f8a7aa..108d3158a6 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -516,6 +516,11 @@ static pa_stream *qpa_simple_new ( #endif |PA_STREAM_AUTO_TIMING_UPDATE; + if (dev) { + /* don't move the stream if the user specified a sink/source */ + flags |= PA_STREAM_DONT_MOVE; + } + if (dir == PA_STREAM_PLAYBACK) { r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL); } else { From patchwork Wed Jan 16 23:36:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767149 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1EE8A17FB for ; Wed, 16 Jan 2019 23:51:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0DD1D2F676 for ; Wed, 16 Jan 2019 23:51:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0C22C2FC22; Wed, 16 Jan 2019 23:51:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 992192F96F for ; Wed, 16 Jan 2019 23:51:51 +0000 (UTC) Received: from localhost ([127.0.0.1]:34713 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuyM-00073F-Um for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:51:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58007) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000472-4s for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukk-0002uo-3t for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:45493) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukj-0002qw-P7 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:45 -0500 Received: by mail-wr1-x441.google.com with SMTP id t6so8903769wrr.12 for ; Wed, 16 Jan 2019 15:37:44 -0800 (PST) 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=5vTKSbVynhXcM5xUP1q28wtIQJgz+4P+VLzqi4OziM4=; b=RgErAxYOVfWMQxZPNFVKXMFVrZY8y6mgZpglr7Tv2swFSF/SruT3KXgfb1WgjGW4RW Q2Dlu4guFwFvpzxddIIK2IBoxowQWtUslL4xDQjFev9Fb/UPhCRmEoIPM01XeESCWzIk KqLCuZGYItmqc/hvo62roz29/Agp2BJyZmazp1Cio98OKPj5hUL8i4kFvjxoIUS0ZTFn Yg90+VhFgy3Dgl5d6WbRdoScoktwS3m/MRVqHLqd/C+faQNe9Y/P+VRFkPlFyAfS+2fn RjRYGNy/OJqW185xu2bQsaUoHH1cXtMXzLsIxoncu9dops4DnbTiBBvXHVfDPJDdS/Ws ++Bg== 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=5vTKSbVynhXcM5xUP1q28wtIQJgz+4P+VLzqi4OziM4=; b=JUELHBsxXv/xwGDlwyAbZikHiflZmVxP7eR0t/JWsWcgsq4OplCeMi2bSMD73ny2eM nwmTHuhQjM03rsgcaeDENcOZHs6H6WVvwGlOFwGRbsHzNRstGYh4F/sx1aV0KCJZvT1w nII1cVLlSFiYamC5E7BamMLKQzhM8r8pX8QtDO0uhDGz2c8RYehHOZE5HAr6RViGW1RO KvV5Tecg7U8UtygqaelMu03+kCfW5OF8XxOrI2yyTmoy5s7mag8wSXvwmhopy9JQ/a7r 0xcN7E/2Ysle+Od9xFyIzX5uosQAOP7ilzkD8Kc4r8i4+cZ5Oo/HXyfSlBpJKmEWqVh4 vz0Q== X-Gm-Message-State: AJcUukfj9olUCQqrV3eqETHCO8EtoepgDhYGZfvSqCoh/7Vxi8VY9J8T x4m6g4jEC/86vnDIkkS2Iim83q86BUo= X-Google-Smtp-Source: ALg8bN7TZKPIwD8oT8gMxWf/b8oT0MeL7rAQkmwthTFZ3quBsKHdYBVwPkD2sns9pYdF+xZz2WyThg== X-Received: by 2002:adf:bc02:: with SMTP id s2mr9182249wrg.255.1547681863656; Wed, 16 Jan 2019 15:37:43 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:43 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:53 +0100 Message-Id: <0b2e43a405816f04fd3e603a263fdf901a42e900.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 20/50] paaudio: properly disconnect streams in fini_* X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Currently this needs a workaround due to bug #74624 in pulseaudio. Reviewed-by: Marc-André Lureau Signed-off-by: Kővágó, Zoltán --- audio/paaudio.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/audio/paaudio.c b/audio/paaudio.c index 108d3158a6..428c848863 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -680,6 +680,27 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) return -1; } +static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream) +{ + int err; + + pa_threaded_mainloop_lock(c->mainloop); + /* + * wait until actually connects. workaround pa bug #74624 + * https://bugs.freedesktop.org/show_bug.cgi?id=74624 + */ + while (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + pa_threaded_mainloop_wait(c->mainloop); + } + + err = pa_stream_disconnect(stream); + if (err != 0) { + dolog("Failed to dissconnect! err=%d\n", err); + } + pa_stream_unref(stream); + pa_threaded_mainloop_unlock(c->mainloop); +} + static void qpa_fini_out (HWVoiceOut *hw) { void *ret; @@ -691,7 +712,7 @@ static void qpa_fini_out (HWVoiceOut *hw) audio_pt_join(&pa->pt, &ret, __func__); if (pa->stream) { - pa_stream_unref (pa->stream); + qpa_simple_disconnect(pa->g->conn, pa->stream); pa->stream = NULL; } @@ -711,7 +732,7 @@ static void qpa_fini_in (HWVoiceIn *hw) audio_pt_join(&pa->pt, &ret, __func__); if (pa->stream) { - pa_stream_unref (pa->stream); + qpa_simple_disconnect(pa->g->conn, pa->stream); pa->stream = NULL; } From patchwork Wed Jan 16 23:36:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767159 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 58B0A13A4 for ; Wed, 16 Jan 2019 23:55:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AAFF2FC47 for ; Wed, 16 Jan 2019 23:55:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EAEB2FBDA; Wed, 16 Jan 2019 23:55:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9EDF02FC23 for ; Wed, 16 Jan 2019 23:55:14 +0000 (UTC) Received: from localhost ([127.0.0.1]:35550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv1d-0001Ch-Or for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:55:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58011) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000474-5i for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukl-0002ym-K1 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:46785) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukk-0002td-Ld for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:47 -0500 Received: by mail-wr1-x442.google.com with SMTP id l9so8888372wrt.13 for ; Wed, 16 Jan 2019 15:37:46 -0800 (PST) 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=Ibi85fwEqiR7d7dbiCHztkFvR/+8pmAEY9F2GyyDoE4=; b=BAo85Fooc8xPuPTMgYX81v59sK5uTQYra2V3ng7Bya4mEqHShHj4vz/bbKcaFFAxZD wnpjrmvCv+ZJOy9qK6j+MgxoIb71xO/OD4zKTdRgvvlBDkXNEeN3jZ93iSW54Reur0g0 N47ViqIo7axAw1sOl0CAZIZvF7XKtq0kPP8+i4yRhufxRWVNoGvXcY/CG12nuJjwke/e hs8+Fjlr6EHAH9sM1Rt3hyOiYUr/TS6L7vtU7xoNdBF2AoRHXeNjgiM0O/IYkqj1aaga ytTSvQ0uXqflG+1KSENorRcp1AZ2dkvWRAYoR07KEypu+RE0yHAjlUhVthLPuZ2LwPcX Q5LQ== 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=Ibi85fwEqiR7d7dbiCHztkFvR/+8pmAEY9F2GyyDoE4=; b=mbHU4SpkJOj233GiMkf8A5JEmu9E1wHK7crEQEepttP4Zh6mUYHFGUfr311g+EHWj8 NZ9SXsgnOoPpvegRySvpehS6rRbHb2Fhx95XxH0uyGucXXLG2mRguim/mCJtRqAMWXQu HlULR2RborXTb5MRNJ81AIiK5HSfgIHyse1mrwemlNtqRqxKhP7hGTHNH/WmWyglCCbx K3HFZs79k4SAjFRhiFJy0VRwKkjlsRmMbEeVx2Fg/AAcUePn8mwmJe/O87gDej/pxPuR +cjcj/mA+k7V6dfOeZXrx2tiKDPBODHAwHINndvYbGAlOmIuckcImoDtpmLUHkXXCsSO m0mg== X-Gm-Message-State: AJcUukeRC4GqCNALz/eXU2s1zdWFL8rXPuKw24p/m0tfl/+Tb+I+YjUH fyq/iVckrhRj+kRBoBkNvfpVKBFhdOA= X-Google-Smtp-Source: ALg8bN7OD39QFWUaloJkGAnZ3hVXrHAKDzsiDXwoDcyl6Ysg2TCD60USCWLvcxjk66eR1kzpDA93uw== X-Received: by 2002:a5d:68c3:: with SMTP id p3mr9806526wrw.34.1547681864683; Wed, 16 Jan 2019 15:37:44 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:44 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:54 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v3 21/50] audio: remove audio_MIN, audio_MAX X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Walle , Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP There's already a MIN and MAX macro in include/qemu/osdep.h, use them instead. Signed-off-by: Kővágó, Zoltán --- audio/audio.h | 17 ----------------- audio/alsaaudio.c | 6 +++--- audio/audio.c | 20 ++++++++++---------- audio/coreaudio.c | 2 +- audio/dsoundaudio.c | 2 +- audio/noaudio.c | 10 +++++----- audio/ossaudio.c | 6 +++--- audio/paaudio.c | 12 ++++++------ audio/sdlaudio.c | 6 +++--- audio/spiceaudio.c | 10 +++++----- audio/wavaudio.c | 4 ++-- hw/audio/ac97.c | 10 +++++----- hw/audio/adlib.c | 4 ++-- hw/audio/cs4231a.c | 4 ++-- hw/audio/es1370.c | 6 +++--- hw/audio/gus.c | 6 +++--- hw/audio/hda-codec.c | 16 ++++++++-------- hw/audio/milkymist-ac97.c | 8 ++++---- hw/audio/pcspk.c | 2 +- hw/audio/sb16.c | 2 +- hw/audio/wm8750.c | 4 ++-- 21 files changed, 70 insertions(+), 87 deletions(-) diff --git a/audio/audio.h b/audio/audio.h index c0722a5cda..4a95758516 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -146,23 +146,6 @@ static inline void *advance (void *p, int incr) return (d + incr); } -#ifdef __GNUC__ -#define audio_MIN(a, b) ( __extension__ ({ \ - __typeof (a) ta = a; \ - __typeof (b) tb = b; \ - ((ta)>(tb)?(tb):(ta)); \ -})) - -#define audio_MAX(a, b) ( __extension__ ({ \ - __typeof (a) ta = a; \ - __typeof (b) tb = b; \ - ((ta)<(tb)?(tb):(ta)); \ -})) -#else -#define audio_MIN(a, b) ((a)>(b)?(b):(a)) -#define audio_MAX(a, b) ((a)<(b)?(b):(a)) -#endif - int wav_start_capture(AudioState *state, CaptureState *s, const char *path, int freq, int bits, int nchannels); diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 6b43a06180..c68bd6bf8a 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -641,7 +641,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa) while (alsa->pending) { int left_till_end_samples = hw->samples - alsa->wpos; - int len = audio_MIN (alsa->pending, left_till_end_samples); + int len = MIN (alsa->pending, left_till_end_samples); char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift); while (len) { @@ -704,7 +704,7 @@ static int alsa_run_out (HWVoiceOut *hw, int live) return 0; } - decr = audio_MIN (live, avail); + decr = MIN (live, avail); decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); alsa->pending += decr; alsa_write_pending (alsa); @@ -922,7 +922,7 @@ static int alsa_run_in (HWVoiceIn *hw) } } - decr = audio_MIN (dead, avail); + decr = MIN (dead, avail); if (!decr) { return 0; } diff --git a/audio/audio.c b/audio/audio.c index f768a6059d..5f809d13f4 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -536,7 +536,7 @@ static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (sw->active) { - m = audio_MIN (m, sw->total_hw_samples_acquired); + m = MIN (m, sw->total_hw_samples_acquired); } } return m; @@ -556,14 +556,14 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, int live, int pending) { int left = hw->samples - pending; - int len = audio_MIN (left, live); + int len = MIN (left, live); int clipped = 0; while (len) { struct st_sample *src = hw->mix_buf + hw->rpos; uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift); int samples_till_end_of_buf = hw->samples - hw->rpos; - int samples_to_clip = audio_MIN (len, samples_till_end_of_buf); + int samples_to_clip = MIN (len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip); @@ -617,7 +617,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) } swlim = (live * sw->ratio) >> 32; - swlim = audio_MIN (swlim, samples); + swlim = MIN (swlim, samples); while (swlim) { src = hw->conv_buf + rpos; @@ -665,7 +665,7 @@ static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (sw->active || !sw->empty) { - m = audio_MIN (m, sw->total_hw_samples_mixed); + m = MIN (m, sw->total_hw_samples_mixed); nb_live += 1; } } @@ -728,7 +728,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) dead = hwsamples - live; swlim = ((int64_t) dead << 32) / sw->ratio; - swlim = audio_MIN (swlim, samples); + swlim = MIN (swlim, samples); if (swlim) { sw->conv (sw->buf, buf, swlim); @@ -740,7 +740,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) while (swlim) { dead = hwsamples - live; left = hwsamples - wpos; - blck = audio_MIN (dead, left); + blck = MIN (dead, left); if (!blck) { break; } @@ -1032,7 +1032,7 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) n = samples; while (n) { int till_end_of_hw = hw->samples - rpos2; - int to_write = audio_MIN (till_end_of_hw, n); + int to_write = MIN (till_end_of_hw, n); int bytes = to_write << hw->info.shift; int written; @@ -1050,7 +1050,7 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) } } - n = audio_MIN (samples, hw->samples - rpos); + n = MIN (samples, hw->samples - rpos); mixeng_clear (hw->mix_buf + rpos, n); mixeng_clear (hw->mix_buf, samples - n); } @@ -1206,7 +1206,7 @@ static void audio_run_capture (AudioState *s) rpos = hw->rpos; while (live) { int left = hw->samples - rpos; - int to_capture = audio_MIN (live, left); + int to_capture = MIN (live, left); struct st_sample *src; struct capture_callback *cb; diff --git a/audio/coreaudio.c b/audio/coreaudio.c index e00b8847d7..b6935359ee 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -413,7 +413,7 @@ static int coreaudio_run_out (HWVoiceOut *hw, int live) core->live); } - decr = audio_MIN (core->decr, live); + decr = MIN (core->decr, live); core->decr -= decr; core->live = live - decr; diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index a7d04b5033..6f074c6f94 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -707,7 +707,7 @@ static int dsound_run_in (HWVoiceIn *hw) if (!len) { return 0; } - len = audio_MIN (len, dead); + len = MIN (len, dead); err = dsound_lock_in ( dscb, diff --git a/audio/noaudio.c b/audio/noaudio.c index ccc611fc84..823780dacb 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -51,11 +51,11 @@ static int no_run_out (HWVoiceOut *hw, int live) now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - no->old_ticks; bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - bytes = audio_MIN(bytes, INT_MAX); + bytes = MIN(bytes, INT_MAX); samples = bytes >> hw->info.shift; no->old_ticks = now; - decr = audio_MIN (live, samples); + decr = MIN (live, samples); hw->rpos = (hw->rpos + decr) % hw->samples; return decr; } @@ -110,9 +110,9 @@ static int no_run_in (HWVoiceIn *hw) muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); no->old_ticks = now; - bytes = audio_MIN (bytes, INT_MAX); + bytes = MIN (bytes, INT_MAX); samples = bytes >> hw->info.shift; - samples = audio_MIN (samples, dead); + samples = MIN (samples, dead); } return samples; } @@ -123,7 +123,7 @@ static int no_read (SWVoiceIn *sw, void *buf, int size) * useless resampling/mixing */ int samples = size >> sw->info.shift; int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; - int to_clear = audio_MIN (samples, total); + int to_clear = MIN (samples, total); sw->total_hw_samples_acquired += total; audio_pcm_info_clear_buf (&sw->info, buf, to_clear); return to_clear << sw->info.shift; diff --git a/audio/ossaudio.c b/audio/ossaudio.c index d56c705dc0..b6ab3e83ef 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -387,7 +387,7 @@ static void oss_write_pending (OSSVoiceOut *oss) int samples_written; ssize_t bytes_written; int samples_till_end = hw->samples - oss->wpos; - int samples_to_write = audio_MIN (oss->pending, samples_till_end); + int samples_to_write = MIN (oss->pending, samples_till_end); int bytes_to_write = samples_to_write << hw->info.shift; void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift); @@ -436,7 +436,7 @@ static int oss_run_out (HWVoiceOut *hw, int live) pos = hw->rpos << hw->info.shift; bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize); - decr = audio_MIN (bytes >> hw->info.shift, live); + decr = MIN (bytes >> hw->info.shift, live); } else { err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo); @@ -455,7 +455,7 @@ static int oss_run_out (HWVoiceOut *hw, int live) return 0; } - decr = audio_MIN (abinfo.bytes >> hw->info.shift, live); + decr = MIN (abinfo.bytes >> hw->info.shift, live); if (!decr) { return 0; } diff --git a/audio/paaudio.c b/audio/paaudio.c index 428c848863..0a770fa57d 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -234,7 +234,7 @@ static void *qpa_thread_out (void *arg) } } - decr = to_mix = audio_MIN(pa->live, pa->samples >> 5); + decr = to_mix = MIN(pa->live, pa->samples >> 5); rpos = pa->rpos; if (audio_pt_unlock(&pa->pt, __func__)) { @@ -243,7 +243,7 @@ static void *qpa_thread_out (void *arg) while (to_mix) { int error; - int chunk = audio_MIN (to_mix, hw->samples - rpos); + int chunk = MIN (to_mix, hw->samples - rpos); struct st_sample *src = hw->mix_buf + rpos; hw->clip (pa->pcm_buf, src, chunk); @@ -281,7 +281,7 @@ static int qpa_run_out (HWVoiceOut *hw, int live) return 0; } - decr = audio_MIN (live, pa->decr); + decr = MIN (live, pa->decr); pa->decr -= decr; pa->live = live - decr; hw->rpos = pa->rpos; @@ -326,7 +326,7 @@ static void *qpa_thread_in (void *arg) } } - incr = to_grab = audio_MIN(pa->dead, pa->samples >> 5); + incr = to_grab = MIN(pa->dead, pa->samples >> 5); wpos = pa->wpos; if (audio_pt_unlock(&pa->pt, __func__)) { @@ -335,7 +335,7 @@ static void *qpa_thread_in (void *arg) while (to_grab) { int error; - int chunk = audio_MIN (to_grab, hw->samples - wpos); + int chunk = MIN (to_grab, hw->samples - wpos); void *buf = advance (pa->pcm_buf, wpos); if (qpa_simple_read (pa, buf, @@ -374,7 +374,7 @@ static int qpa_run_in (HWVoiceIn *hw) live = audio_pcm_hw_get_live_in (hw); dead = hw->samples - live; - incr = audio_MIN (dead, pa->incr); + incr = MIN (dead, pa->incr); pa->incr -= incr; pa->dead = dead - incr; hw->wpos = pa->wpos; diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index cf6ac19927..fc61038b77 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -288,10 +288,10 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) #endif /* dolog ("in callback live=%d\n", live); */ - to_mix = audio_MIN (samples, sdl->live); + to_mix = MIN (samples, sdl->live); decr = to_mix; while (to_mix) { - int chunk = audio_MIN (to_mix, hw->samples - hw->rpos); + int chunk = MIN (to_mix, hw->samples - hw->rpos); struct st_sample *src = hw->mix_buf + hw->rpos; /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ @@ -347,7 +347,7 @@ static int sdl_run_out (HWVoiceOut *hw, int live) sdl->live); } - decr = audio_MIN (sdl->decr, live); + decr = MIN (sdl->decr, live); sdl->decr -= decr; #if USE_SEMAPHORE diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 4f7873af5a..b9160991d2 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -163,20 +163,20 @@ static int line_out_run (HWVoiceOut *hw, int live) } decr = rate_get_samples (&hw->info, &out->rate); - decr = audio_MIN (live, decr); + decr = MIN (live, decr); samples = decr; rpos = hw->rpos; while (samples) { int left_till_end_samples = hw->samples - rpos; - int len = audio_MIN (samples, left_till_end_samples); + int len = MIN (samples, left_till_end_samples); if (!out->frame) { spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize); out->fpos = out->frame; } if (out->frame) { - len = audio_MIN (len, out->fsize); + len = MIN (len, out->fsize); hw->clip (out->fpos, hw->mix_buf + rpos, len); out->fsize -= len; out->fpos += len; @@ -294,7 +294,7 @@ static int line_in_run (HWVoiceIn *hw) } delta_samp = rate_get_samples (&hw->info, &in->rate); - num_samples = audio_MIN (num_samples, delta_samp); + num_samples = MIN (num_samples, delta_samp); ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples); samples = in->samples; @@ -304,7 +304,7 @@ static int line_in_run (HWVoiceIn *hw) ready = LINE_IN_SAMPLES; } - num_samples = audio_MIN (ready, num_samples); + num_samples = MIN (ready, num_samples); if (hw->wpos + num_samples > hw->samples) { len[0] = hw->samples - hw->wpos; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 214e30ccd9..723028a466 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -57,12 +57,12 @@ static int wav_run_out (HWVoiceOut *hw, int live) } wav->old_ticks = now; - decr = audio_MIN (live, samples); + decr = MIN (live, samples); samples = decr; rpos = hw->rpos; while (samples) { int left_till_end_samples = hw->samples - rpos; - int convert_samples = audio_MIN (samples, left_till_end_samples); + int convert_samples = MIN (samples, left_till_end_samples); src = hw->mix_buf + rpos; dst = advance (wav->pcm_buf, rpos << hw->info.shift); diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 03e3da4f31..1211541888 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -963,7 +963,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t temp = r->picb << 1; uint32_t written = 0; int to_copy = 0; - temp = audio_MIN (temp, max); + temp = MIN (temp, max); if (!temp) { *stop = 1; @@ -972,7 +972,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r, while (temp) { int copied; - to_copy = audio_MIN (temp, sizeof (tmpbuf)); + to_copy = MIN (temp, sizeof (tmpbuf)); pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (s->voice_po, tmpbuf, to_copy); dolog ("write_audio max=%x to_copy=%x copied=%x\n", @@ -1018,7 +1018,7 @@ static void write_bup (AC97LinkState *s, int elapsed) } while (elapsed) { - int temp = audio_MIN (elapsed, sizeof (s->silence)); + int temp = MIN (elapsed, sizeof (s->silence)); while (temp) { int copied = AUD_write (s->voice_po, s->silence, temp); if (!copied) @@ -1039,7 +1039,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r, int to_copy = 0; SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi; - temp = audio_MIN (temp, max); + temp = MIN (temp, max); if (!temp) { *stop = 1; @@ -1048,7 +1048,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r, while (temp) { int acquired; - to_copy = audio_MIN (temp, sizeof (tmpbuf)); + to_copy = MIN (temp, sizeof (tmpbuf)); acquired = AUD_read (voice, tmpbuf, to_copy); if (!acquired) { *stop = 1; diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 0d01cd07c5..06350abf2c 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -194,7 +194,7 @@ static void adlib_callback (void *opaque, int free) return; } - to_play = audio_MIN (s->left, samples); + to_play = MIN (s->left, samples); while (to_play) { written = write_audio (s, to_play); @@ -209,7 +209,7 @@ static void adlib_callback (void *opaque, int free) } } - samples = audio_MIN (samples, s->samples - s->pos); + samples = MIN (samples, s->samples - s->pos); if (!samples) { return; } diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index d25a120b0f..70d0947907 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -533,7 +533,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, int copied; size_t to_copy; - to_copy = audio_MIN (temp, left); + to_copy = MIN (temp, left); if (to_copy > sizeof (tmpbuf)) { to_copy = sizeof (tmpbuf); } @@ -576,7 +576,7 @@ static int cs_dma_read (void *opaque, int nchan, int dma_pos, int dma_len) till = (s->dregs[Playback_Lower_Base_Count] | (s->dregs[Playback_Upper_Base_Count] << 8)) << s->shift; till -= s->transferred; - copy = audio_MIN (till, copy); + copy = MIN (till, copy); } if ((copy <= 0) || (dma_len <= 0)) { diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 8c63912a82..234a05633e 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -644,7 +644,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int size = d->frame_cnt & 0xffff; int left = ((size - cnt + 1) << 2) + d->leftover; int transferred = 0; - int temp = audio_MIN (max, audio_MIN (left, csc_bytes)); + int temp = MIN (max, MIN (left, csc_bytes)); int index = d - &s->chan[0]; addr += (cnt << 2) + d->leftover; @@ -653,7 +653,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, while (temp) { int acquired, to_copy; - to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); + to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); acquired = AUD_read (s->adc_voice, tmpbuf, to_copy); if (!acquired) break; @@ -671,7 +671,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, while (temp) { int copied, to_copy; - to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); + to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); if (!copied) diff --git a/hw/audio/gus.c b/hw/audio/gus.c index dfb74cf0d3..2a2a24eacc 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -115,7 +115,7 @@ static void GUS_callback (void *opaque, int free) GUSState *s = opaque; samples = free >> s->shift; - to_play = audio_MIN (samples, s->left); + to_play = MIN (samples, s->left); while (to_play) { int written = write_audio (s, to_play); @@ -130,7 +130,7 @@ static void GUS_callback (void *opaque, int free) net += written; } - samples = audio_MIN (samples, s->samples); + samples = MIN (samples, s->samples); if (samples) { gus_mixvoices (&s->emu, s->freq, samples, s->mixbuf); @@ -190,7 +190,7 @@ static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len) ldebug ("read DMA %#x %d\n", dma_pos, dma_len); mode = k->has_autoinitialization(s->isa_dma, s->emu.gusdma); while (left) { - int to_copy = audio_MIN ((size_t) left, sizeof (tmpbuf)); + int to_copy = MIN ((size_t) left, sizeof (tmpbuf)); int copied; ldebug ("left=%d to_copy=%d pos=%d\n", left, to_copy, pos); diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index e66103aedf..88106f88b4 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -233,10 +233,10 @@ static void hda_audio_input_timer(void *opaque) goto out_timer; } - int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos); + int64_t to_transfer = MIN(wpos - rpos, wanted_rpos - rpos); while (to_transfer) { uint32_t start = (rpos & B_MASK); - uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); + uint32_t chunk = MIN(B_SIZE - start, to_transfer); int rc = hda_codec_xfer( &st->state->hda, st->stream, false, st->buf + start, chunk); if (!rc) { @@ -261,13 +261,13 @@ static void hda_audio_input_cb(void *opaque, int avail) int64_t wpos = st->wpos; int64_t rpos = st->rpos; - int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail); + int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), avail); hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1))); while (to_transfer) { uint32_t start = (uint32_t) (wpos & B_MASK); - uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); + uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer); uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk); wpos += read; to_transfer -= read; @@ -297,10 +297,10 @@ static void hda_audio_output_timer(void *opaque) goto out_timer; } - int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos); + int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos); while (to_transfer) { uint32_t start = (wpos & B_MASK); - uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer); + uint32_t chunk = MIN(B_SIZE - start, to_transfer); int rc = hda_codec_xfer( &st->state->hda, st->stream, true, st->buf + start, chunk); if (!rc) { @@ -325,7 +325,7 @@ static void hda_audio_output_cb(void *opaque, int avail) int64_t wpos = st->wpos; int64_t rpos = st->rpos; - int64_t to_transfer = audio_MIN(wpos - rpos, avail); + int64_t to_transfer = MIN(wpos - rpos, avail); if (wpos - rpos == B_SIZE) { /* drop buffer, reset timer adjust */ @@ -340,7 +340,7 @@ static void hda_audio_output_cb(void *opaque, int avail) while (to_transfer) { uint32_t start = (uint32_t) (rpos & B_MASK); - uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer); + uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer); uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk); rpos += written; to_transfer -= written; diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c index 8739cb376a..1a583fc3b9 100644 --- a/hw/audio/milkymist-ac97.c +++ b/hw/audio/milkymist-ac97.c @@ -183,7 +183,7 @@ static void ac97_in_cb(void *opaque, int avail_b) MilkymistAC97State *s = opaque; uint8_t buf[4096]; uint32_t remaining = s->regs[R_U_REMAINING]; - int temp = audio_MIN(remaining, avail_b); + int temp = MIN(remaining, avail_b); uint32_t addr = s->regs[R_U_ADDR]; int transferred = 0; @@ -197,7 +197,7 @@ static void ac97_in_cb(void *opaque, int avail_b) while (temp) { int acquired, to_copy; - to_copy = audio_MIN(temp, sizeof(buf)); + to_copy = MIN(temp, sizeof(buf)); acquired = AUD_read(s->voice_in, buf, to_copy); if (!acquired) { break; @@ -226,7 +226,7 @@ static void ac97_out_cb(void *opaque, int free_b) MilkymistAC97State *s = opaque; uint8_t buf[4096]; uint32_t remaining = s->regs[R_D_REMAINING]; - int temp = audio_MIN(remaining, free_b); + int temp = MIN(remaining, free_b); uint32_t addr = s->regs[R_D_ADDR]; int transferred = 0; @@ -240,7 +240,7 @@ static void ac97_out_cb(void *opaque, int free_b) while (temp) { int copied, to_copy; - to_copy = audio_MIN(temp, sizeof(buf)); + to_copy = MIN(temp, sizeof(buf)); cpu_physical_memory_read(addr, buf, to_copy); copied = AUD_write(s->voice_out, buf, to_copy); if (!copied) { diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 1457cd1ac6..94530c9265 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -102,7 +102,7 @@ static void pcspk_callback(void *opaque, int free) } while (free > 0) { - n = audio_MIN(s->samples - s->play_pos, (unsigned int)free); + n = MIN(s->samples - s->play_pos, (unsigned int)free); n = AUD_write(s->voice, &s->sample_buf[s->play_pos], n); if (!n) break; diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 5a6a880f2e..78bf0753bb 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1166,7 +1166,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos, int copied; size_t to_copy; - to_copy = audio_MIN (temp, left); + to_copy = MIN (temp, left); if (to_copy > sizeof (tmpbuf)) { to_copy = sizeof (tmpbuf); } diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c index 0451ad87f1..9ace0a78f6 100644 --- a/hw/audio/wm8750.c +++ b/hw/audio/wm8750.c @@ -68,7 +68,7 @@ static inline void wm8750_in_load(WM8750State *s) { if (s->idx_in + s->req_in <= sizeof(s->data_in)) return; - s->idx_in = audio_MAX(0, (int) sizeof(s->data_in) - s->req_in); + s->idx_in = MAX(0, (int) sizeof(s->data_in) - s->req_in); AUD_read(*s->in[0], s->data_in + s->idx_in, sizeof(s->data_in) - s->idx_in); } @@ -99,7 +99,7 @@ static void wm8750_audio_out_cb(void *opaque, int free_b) wm8750_out_flush(s); } else s->req_out = free_b - s->idx_out; - + s->data_req(s->opaque, s->req_out >> 2, s->req_in >> 2); } From patchwork Wed Jan 16 23:36:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767143 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B05BE14E5 for ; Wed, 16 Jan 2019 23:48:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A05622E0A0 for ; Wed, 16 Jan 2019 23:48:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 947F72E5A8; Wed, 16 Jan 2019 23:48:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1FB922E0A0 for ; Wed, 16 Jan 2019 23:48:27 +0000 (UTC) Received: from localhost ([127.0.0.1]:33909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuv4-0004UH-D8 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:48:26 -0500 Received: from eggs.gnu.org ([209.51.188.92]:57996) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-00046u-44 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukm-00031c-Je for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:43010) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukm-0002vJ-3C for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:48 -0500 Received: by mail-wr1-x443.google.com with SMTP id r10so8917008wrs.10 for ; Wed, 16 Jan 2019 15:37:47 -0800 (PST) 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=dFjyW9xM6m5+B/PcJyW3Y9EtG64ZLK+f0jcci6rvY0s=; b=EdnV/VPpIMmML0Z0/oUYMtMzVNqkcMiOgKdD5gXSwuCkBb2pcjj6WROF9YUF7vY6LQ u5ZBjrODtLlpoiDJ5h4D30Vo8pGo7FbInRbJc0JLyUAZcjfY84QRoZAxqFbxH9VqPudx Q23apbs7rvpXC45D30OQRbqAxxyLnJgHQRZCkxIfcAGKYbhjnWokw1X/jmqcYZ8klp1x ylmwzYKIPPP6+zVnXNPY50FhD2qHeVIKOzyE8DzZXrjNwicmOO+/EQop+8jpY+fskxYx fzUUDhSrR7NCT2JNbLSFWTTMu4FYIoLUjdR6gDeSF7R+eXtfInEiUY5zuIdWs8X95n6R FuHw== 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=dFjyW9xM6m5+B/PcJyW3Y9EtG64ZLK+f0jcci6rvY0s=; b=Ge5V1r+YmacVnGYnVXUZwg2sbON7xpB7ey81Q0XEQBILVkcvl46i9s8TxmjUUL8djd kPa8qYG7NDZ9irFzeX+32lAa97XUqQLRFx+dIAGA4hoUyHhbs0r9kOL1GXWtQOrkIwkh zHYnG9zxTdEyXk1hlP7o9w0kEco3rI4Ivm92s/N24sxTVS2f/qGwtLLlpM1ULASkF+DN B/dqkDOdGRiCjuaWJiNE4CBsybW88W9relBKLmjied8UYfZ1ZapPh5gr2+Cb505p6qeJ wTgiQfM8Nj2Xa1N2gvJNidjC/9Dmb/6BA/fFHNhcLopvT7zjra3sOLJ3ORgr8zK8+OFL KImw== X-Gm-Message-State: AJcUukenT5cUHPwLQi1e5NGae0/MzBOzWF2dmAiry5VBdN2K0FNy79iw KkaLI4W8kyWYgqIsbqhSm8SqQPq7luY= X-Google-Smtp-Source: ALg8bN6rynA7yJtRqlMbaJ+GqH0Mh4+nvAcs9td/I4J54aSYmiUOj0NqZr4jKkhpwKVJeo1TjjEGYA== X-Received: by 2002:adf:b102:: with SMTP id l2mr9191288wra.296.1547681865528; Wed, 16 Jan 2019 15:37:45 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:45 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:55 +0100 Message-Id: <9b2249817b15dc0d3e8772e01385c9973fe9b14c.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PATCH v3 22/50] audio: do not run each backend in audio_run X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP audio_run is called manually by alsa and oss backends when polling. In this case only the requesting backend should be run, not all of them. Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 2 +- audio/alsaaudio.c | 7 +++++-- audio/audio.c | 14 +++++--------- audio/ossaudio.c | 12 ++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 5ceea76eda..02ec6ea738 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -220,7 +220,7 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, int audio_bug (const char *funcname, int cond); void *audio_calloc (const char *funcname, int nmemb, size_t size); -void audio_run (const char *msg); +void audio_run(AudioState *s, const char *msg); #define VOICE_ENABLE 1 #define VOICE_DISABLE 2 diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index c68bd6bf8a..9dfd5fd26f 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -38,6 +38,7 @@ struct pollhlp { struct pollfd *pfds; int count; int mask; + AudioState *s; }; typedef struct ALSAVoiceOut { @@ -198,11 +199,11 @@ static void alsa_poll_handler (void *opaque) break; case SND_PCM_STATE_PREPARED: - audio_run ("alsa run (prepared)"); + audio_run(hlp->s, "alsa run (prepared)"); break; case SND_PCM_STATE_RUNNING: - audio_run ("alsa run (running)"); + audio_run (hlp->s, "alsa run (running)"); break; default: @@ -756,6 +757,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, return -1; } + alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev; return 0; @@ -857,6 +859,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) return -1; } + alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev; return 0; diff --git a/audio/audio.c b/audio/audio.c index 5f809d13f4..4d0d316ce3 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -838,7 +838,7 @@ static void audio_timer (void *opaque) } s->timer_last = now; - audio_run("timer"); + audio_run(s, "timer"); audio_reset_timer(s); } @@ -1240,15 +1240,11 @@ static void audio_run_capture (AudioState *s) } } -void audio_run (const char *msg) +void audio_run(AudioState *s, const char *msg) { - AudioState *s; - - QTAILQ_FOREACH(s, &audio_states, list) { - audio_run_out (s); - audio_run_in (s); - audio_run_capture (s); - } + audio_run_out(s); + audio_run_in(s); + audio_run_capture(s); #ifdef DEBUG_POLL { diff --git a/audio/ossaudio.c b/audio/ossaudio.c index b6ab3e83ef..bbcc44129d 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -109,28 +109,28 @@ static void oss_anal_close (int *fdp) static void oss_helper_poll_out (void *opaque) { - (void) opaque; - audio_run ("oss_poll_out"); + AudioState *s = opaque; + audio_run(s, "oss_poll_out"); } static void oss_helper_poll_in (void *opaque) { - (void) opaque; - audio_run ("oss_poll_in"); + AudioState *s = opaque; + audio_run(s, "oss_poll_in"); } static void oss_poll_out (HWVoiceOut *hw) { OSSVoiceOut *oss = (OSSVoiceOut *) hw; - qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL); + qemu_set_fd_handler(oss->fd, NULL, oss_helper_poll_out, hw->s); } static void oss_poll_in (HWVoiceIn *hw) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; - qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL); + qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s); } static int oss_write (SWVoiceOut *sw, void *buf, int len) From patchwork Wed Jan 16 23:36:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767145 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 194E414E5 for ; Wed, 16 Jan 2019 23:49:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A1682EFE8 for ; Wed, 16 Jan 2019 23:49:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1E442EFF7; Wed, 16 Jan 2019 23:49:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 94B222EFE8 for ; Wed, 16 Jan 2019 23:49:10 +0000 (UTC) Received: from localhost ([127.0.0.1]:34084 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuvl-00059x-SH for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:49:09 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58006) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuks-000471-4q for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukm-00030z-G8 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:52 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:42514) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukl-0002wg-Ov for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:48 -0500 Received: by mail-wr1-x441.google.com with SMTP id q18so8928081wrx.9 for ; Wed, 16 Jan 2019 15:37:47 -0800 (PST) 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=7BQBLAP2ndQEDvJdO6DNKAjZ70szS1/J5w8BeLsmcNk=; b=Sg0MULkV6ZzU0U2HddUAbXSZ2QBAjelmi2wvK4DpNyLDECgcEYpsm6h8S2MhPSe0jt EzVIKnU9JIJcxSJm7SvYSN0068nF6/6r3xJoaoLVquGVxYSyn7zh6smiDV3q+jiuy/Pp NYmSgSABM+KpArXXYVUd92XMA6g0S2i9CMmqYVRNSnD0qS9vjBu1sUD7y4dloak1IU/i m5HdKEJiCHY3b6EicF3wyggJKeH4G3jVeVT2RWY+4AbrBqv6E8Qc8KeKnm9txfcy+LsI BJkWEfXlvd2rNmbb+63lBUZqm2OCJh4/uB4dxF5XaeR+HB8dNjlVqCQ+GTmjVJ6GWzwB lVaw== 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=7BQBLAP2ndQEDvJdO6DNKAjZ70szS1/J5w8BeLsmcNk=; b=CMXV8orUB847O9fa10AcS14wKMNV/XgDFpr4YUTLudJEXh2uw2Edro+ybe0YWbUJWL 7N95aZFGjyoaeSq0AAePDx5FiWL7Nq8t5DNSqn+iTHSIgOYhAtizcQbFJBnlr+wBZkBi 77GREKhEZEYecKawCQNSK1IzAifFjPMGr45QAZUZwITAlIo5b+4T/zBWSzULy9492vWL AjlnyrOjuTv7+2KLPncNHLFZd5CQLDvTjUUGAImuiR3sLQX02Eq9AiI/SAl66xaesJus wCKlNM7HrNGHdZcyhzwnERnMFftvZnIIGBHsUq6Amdbnpv1FZWa6ywZ49SEZRSokbn5z HqxA== X-Gm-Message-State: AJcUukfAYC6ulIK739wvXUcebjBTu9a8xS34iim5bSyIyqvqDSinWVZl H1KFIA51g9Ak8YryXq2OPiFAtBG9xaw= X-Google-Smtp-Source: ALg8bN4d2bxvMeSB8RTbp8rhZaZI41aS02PFuVyjpK7fLIg52jTlbP7VFyO8izXBHkXXfcOtMLOFlg== X-Received: by 2002:a5d:4046:: with SMTP id w6mr9915527wrp.92.1547681866326; Wed, 16 Jan 2019 15:37:46 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:45 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:56 +0100 Message-Id: <369e7d44a4a351d3103033325afc12c339e031a5.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 23/50] paaudio: fix playback glitches X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Pulseaudio normally assumes that when the server wants it, the client can generate the audio samples and send it right away. Unfortunately this is not the case with QEMU -- it's up to the emulated system when does it generate the samples. Buffering the samples and sending them from a background thread is just a workaround, that doesn't work too well. Instead enable pa's compatibility support and let pa worry about the details. Signed-off-by: Kővágó, Zoltán --- audio/paaudio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/audio/paaudio.c b/audio/paaudio.c index 0a770fa57d..7758d304ca 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -511,10 +511,8 @@ static pa_stream *qpa_simple_new ( flags = PA_STREAM_INTERPOLATE_TIMING -#ifdef PA_STREAM_ADJUST_LATENCY - |PA_STREAM_ADJUST_LATENCY -#endif - |PA_STREAM_AUTO_TIMING_UPDATE; + |PA_STREAM_AUTO_TIMING_UPDATE + |PA_STREAM_EARLY_REQUESTS; if (dev) { /* don't move the stream if the user specified a sink/source */ From patchwork Wed Jan 16 23:36:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767209 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3AD5D13A4 for ; Thu, 17 Jan 2019 00:18:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2A79B2E05A for ; Thu, 17 Jan 2019 00:18:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1ED6E2E2A9; Thu, 17 Jan 2019 00:18:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3EFD02E05A for ; Thu, 17 Jan 2019 00:18:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:41238 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvOK-0002hx-7s for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:18:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58250) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul6-0004NG-I1 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul3-0003Op-JC for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:08 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:34220) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul1-000306-GC for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:05 -0500 Received: by mail-wm1-x343.google.com with SMTP id y185so2237343wmd.1 for ; Wed, 16 Jan 2019 15:37:48 -0800 (PST) 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=6ZxLsaXlgwJI+sD/WLHWfI8g2pWRFV1jJe5mp7A5j3o=; b=tfVqttm+fL0g2KjcNzc05amSaqXEc7D7FVVMNUBhibX1jq2SRaYfp57UngMYXot+nK doFIdtQEh641Wvn9XJCK4CNWjW2fmi0nJfq7PD9Fjt57Sa2rVL44u+L6/rVWgVTe2dz2 k98dZRUSFlr9oi5gGPMz/ujaFOnJSI/jz2lV1brXxTLNe8Wl1/K2xQa7VfwZPLgbdt6V QdcKE9tn4PlAM+svMLebBoRGxnp5r6NYQiItOZhXwsbbxvSlBveWrvZH4lvxOFE7flFG Z2nPbOT0a91ln4h7Lri2Qi1FyIse5mZW8kLj3LUsdYBziqbyWzzoSSiAVtOJVhSBqdSS rTYA== 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=6ZxLsaXlgwJI+sD/WLHWfI8g2pWRFV1jJe5mp7A5j3o=; b=XqEXzuuOEntnnqwOzocLgxoOL0sPuO9USehpClcDGXgmEWnHlt6KhTLwnbibU5rDxd Vs2FVnfo7iwc+Cen1Y0vO5suHABbYm/zI5979O3dVCQCOZRwrLD8DO7KJSydpRefOAz2 ixGKMAeZ6WdfzCBs+54Dg/y+tp1Z08HC6M+SoXI25xMoXaLd6JzXEcjrp26Ox9UYh8Em Pa1KN1/XTPKLWgWAmOPDM4njuMslFv17nukYjftllBQpJMnpK8ewHh6Vmy9NrF+eFUYG m1uVD/FgWmG+6hO6EHdeQcvik9ZsbfrsMVjZ2O2DfyudXHIAR4T74RG2En5PVQxNYZ9m zG+Q== X-Gm-Message-State: AJcUukeUtVo55p1hTiUEXur09VKEoEU6JuBJYBMVGZ5SC6mDpEKRmYzh SSexTkzam6xv2zLLarETFyq6EHBJepY= X-Google-Smtp-Source: ALg8bN6bAhRvbqjAZse1E5Rx0UkQ4yrhqtu+QZPL3tTcsNS1QlNMJG2gpEr/LE1V7VMKckf9ORys9g== X-Received: by 2002:a1c:e345:: with SMTP id a66mr9248713wmh.12.1547681867297; Wed, 16 Jan 2019 15:37:47 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:46 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:57 +0100 Message-Id: <75357b8d2adbf9aad6d5dd19fe6b9f9fa0964a94.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 24/50] audio: remove read and write pcm_ops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP They just called audio_pcm_sw_read/write anyway, so it makes no sense to have them too. (The noaudio's read is the only exception, but it should work with the generic code too.) Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 5 ----- audio/alsaaudio.c | 12 ------------ audio/audio.c | 8 ++++---- audio/coreaudio.c | 6 ------ audio/dsoundaudio.c | 12 ------------ audio/noaudio.c | 19 ------------------- audio/ossaudio.c | 12 ------------ audio/paaudio.c | 12 ------------ audio/sdlaudio.c | 6 ------ audio/spiceaudio.c | 12 ------------ audio/wavaudio.c | 6 ------ 11 files changed, 4 insertions(+), 106 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 02ec6ea738..40b3515b4e 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -149,13 +149,11 @@ struct audio_pcm_ops { int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque); void (*fini_out)(HWVoiceOut *hw); int (*run_out) (HWVoiceOut *hw, int live); - int (*write) (SWVoiceOut *sw, void *buf, int size); int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); int (*run_in) (HWVoiceIn *hw); - int (*read) (SWVoiceIn *sw, void *buf, int size); int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); }; @@ -209,11 +207,8 @@ audio_driver *audio_driver_lookup(const char *name); void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); -int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len); int audio_pcm_hw_get_live_in (HWVoiceIn *hw); -int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len); - int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, int live, int pending); diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 9dfd5fd26f..4c6bbdbc1d 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -269,11 +269,6 @@ static int alsa_poll_in (HWVoiceIn *hw) return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN); } -static int alsa_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness) { switch (fmt) { @@ -995,11 +990,6 @@ static int alsa_run_in (HWVoiceIn *hw) return read_samples; } -static int alsa_read (SWVoiceIn *sw, void *buf, int size) -{ - return audio_pcm_sw_read (sw, buf, size); -} - static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; @@ -1088,13 +1078,11 @@ static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, .run_out = alsa_run_out, - .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, .run_in = alsa_run_in, - .read = alsa_read, .ctl_in = alsa_ctl_in, }; diff --git a/audio/audio.c b/audio/audio.c index 4d0d316ce3..f844411d59 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -597,7 +597,7 @@ static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) } } -int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size) +static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size) { HWVoiceIn *hw = sw->hw; int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; @@ -699,7 +699,7 @@ static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) /* * Soft voice (playback) */ -int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) +static int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) { int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; int ret = 0, pos = 0, total = 0; @@ -857,7 +857,7 @@ int AUD_write (SWVoiceOut *sw, void *buf, int size) return 0; } - return sw->hw->pcm_ops->write(sw, buf, size); + return audio_pcm_sw_write(sw, buf, size); } int AUD_read (SWVoiceIn *sw, void *buf, int size) @@ -872,7 +872,7 @@ int AUD_read (SWVoiceIn *sw, void *buf, int size) return 0; } - return sw->hw->pcm_ops->read(sw, buf, size); + return audio_pcm_sw_read(sw, buf, size); } int AUD_get_buffer_size_out (SWVoiceOut *sw) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index b6935359ee..abbbb45d69 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -489,11 +489,6 @@ static OSStatus audioDeviceIOProc( return 0; } -static int coreaudio_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { @@ -692,7 +687,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .run_out = coreaudio_run_out, - .write = coreaudio_write, .ctl_out = coreaudio_ctl_out }; diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index 6f074c6f94..dfcb70c81a 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -454,11 +454,6 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static int dsound_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static int dsound_run_out (HWVoiceOut *hw, int live) { int err; @@ -645,11 +640,6 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static int dsound_read (SWVoiceIn *sw, void *buf, int len) -{ - return audio_pcm_sw_read (sw, buf, len); -} - static int dsound_run_in (HWVoiceIn *hw) { int err; @@ -856,13 +846,11 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, .run_out = dsound_run_out, - .write = dsound_write, .ctl_out = dsound_ctl_out, .init_in = dsound_init_in, .fini_in = dsound_fini_in, .run_in = dsound_run_in, - .read = dsound_read, .ctl_in = dsound_ctl_in }; diff --git a/audio/noaudio.c b/audio/noaudio.c index 823780dacb..4fe7720861 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -60,11 +60,6 @@ static int no_run_out (HWVoiceOut *hw, int live) return decr; } -static int no_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write(sw, buf, len); -} - static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { audio_pcm_init_info (&hw->info, as); @@ -117,18 +112,6 @@ static int no_run_in (HWVoiceIn *hw) return samples; } -static int no_read (SWVoiceIn *sw, void *buf, int size) -{ - /* use custom code here instead of audio_pcm_sw_read() to avoid - * useless resampling/mixing */ - int samples = size >> sw->info.shift; - int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; - int to_clear = MIN (samples, total); - sw->total_hw_samples_acquired += total; - audio_pcm_info_clear_buf (&sw->info, buf, to_clear); - return to_clear << sw->info.shift; -} - static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) { (void) hw; @@ -150,13 +133,11 @@ static struct audio_pcm_ops no_pcm_ops = { .init_out = no_init_out, .fini_out = no_fini_out, .run_out = no_run_out, - .write = no_write, .ctl_out = no_ctl_out, .init_in = no_init_in, .fini_in = no_fini_in, .run_in = no_run_in, - .read = no_read, .ctl_in = no_ctl_in }; diff --git a/audio/ossaudio.c b/audio/ossaudio.c index bbcc44129d..3eee7a3970 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -133,11 +133,6 @@ static void oss_poll_in (HWVoiceIn *hw) qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s); } -static int oss_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static int aud_to_ossfmt (AudioFormat fmt, int endianness) { switch (fmt) { @@ -787,11 +782,6 @@ static int oss_run_in (HWVoiceIn *hw) return read_samples; } -static int oss_read (SWVoiceIn *sw, void *buf, int size) -{ - return audio_pcm_sw_read (sw, buf, size); -} - static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; @@ -860,13 +850,11 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, .run_out = oss_run_out, - .write = oss_write, .ctl_out = oss_ctl_out, .init_in = oss_init_in, .fini_in = oss_fini_in, .run_in = oss_run_in, - .read = oss_read, .ctl_in = oss_ctl_in }; diff --git a/audio/paaudio.c b/audio/paaudio.c index 7758d304ca..f5b924d50c 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -294,11 +294,6 @@ static int qpa_run_out (HWVoiceOut *hw, int live) return decr; } -static int qpa_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - /* capture */ static void *qpa_thread_in (void *arg) { @@ -387,11 +382,6 @@ static int qpa_run_in (HWVoiceIn *hw) return incr; } -static int qpa_read (SWVoiceIn *sw, void *buf, int len) -{ - return audio_pcm_sw_read (sw, buf, len); -} - static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness) { int format; @@ -988,13 +978,11 @@ static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, .run_out = qpa_run_out, - .write = qpa_write, .ctl_out = qpa_ctl_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .run_in = qpa_run_in, - .read = qpa_read, .ctl_in = qpa_ctl_in }; diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index fc61038b77..ab9166d054 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -325,11 +325,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) #endif } -static int sdl_write_out (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static int sdl_run_out (HWVoiceOut *hw, int live) { int decr; @@ -483,7 +478,6 @@ static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, .run_out = sdl_run_out, - .write = sdl_write_out, .ctl_out = sdl_ctl_out, }; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index b9160991d2..f963853ed8 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -192,11 +192,6 @@ static int line_out_run (HWVoiceOut *hw, int live) return decr; } -static int line_out_write (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) { SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); @@ -325,11 +320,6 @@ static int line_in_run (HWVoiceIn *hw) return num_samples; } -static int line_in_read (SWVoiceIn *sw, void *buf, int size) -{ - return audio_pcm_sw_read (sw, buf, size); -} - static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); @@ -377,13 +367,11 @@ static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, .run_out = line_out_run, - .write = line_out_write, .ctl_out = line_out_ctl, .init_in = line_in_init, .fini_in = line_in_fini, .run_in = line_in_run, - .read = line_in_read, .ctl_in = line_in_ctl, }; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 723028a466..dda6993fb9 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -82,11 +82,6 @@ static int wav_run_out (HWVoiceOut *hw, int live) return decr; } -static int wav_write_out (SWVoiceOut *sw, void *buf, int len) -{ - return audio_pcm_sw_write (sw, buf, len); -} - /* VICE code: Store number as little endian. */ static void le_store (uint8_t *buf, uint32_t val, int len) { @@ -238,7 +233,6 @@ static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, .run_out = wav_run_out, - .write = wav_write_out, .ctl_out = wav_ctl_out, }; From patchwork Wed Jan 16 23:36:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767211 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 632C617FB for ; Thu, 17 Jan 2019 00:19:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DE692FAF1 for ; Thu, 17 Jan 2019 00:19:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4051D2FAF5; Thu, 17 Jan 2019 00:19:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EB3A32FAF1 for ; Thu, 17 Jan 2019 00:19:23 +0000 (UTC) Received: from localhost ([127.0.0.1]:41417 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvP1-0003IM-2T for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:19:23 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58562) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulD-0004WL-JF for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Qo-7I for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:37470) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-00033H-KU for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x443.google.com with SMTP id s12so8962902wrt.4 for ; Wed, 16 Jan 2019 15:37:50 -0800 (PST) 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=h5EUkLHHZhEzd3AOOCHgghQJayG76IbTLF2reJ6hFTo=; b=ip10gJHOz5dra8f27sVK19RS6jdVYsCo3phhhRh4PU/JNfXXJzu2XaX2zNK2Qk3tGB gsvqO2UhYRTl1LzcdGshTA0nA1bfmRDs9y0qJ7cnoAigEbb96Ke6l4jJV0Y2a9yKeX0J V+k62lj0zpakwNGm8oz9qCCgFzFwcXyYrXIthQIGI3mS6yfl3dx/J8wtvcRkmsGawYpu BUnCwoAfX2JkfBcn+DGT7aso3Oc8GoFM9xshS9b4AG7Ft1iKd4TeV6urNxCM7i+Vkdos cnbQAluu3kKMAYgualzxVeyDPbE1wc/uFZ5fw3v3jc2zgMshRTYPFqHHxNvMxPSt+391 a3sw== 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=h5EUkLHHZhEzd3AOOCHgghQJayG76IbTLF2reJ6hFTo=; b=fePYFF0UjPnlrpr1DxvA/alA1/rokSdbB+2v06ARL1A/81EfuROcmIKNvQ2uE6MQz7 VotFib/9r+mRYY5mGwY5uo0J4ygxSh89785GxFDqfQ+noicmq3OJ8IpTgt3oGP+708KH OEl0qsyN8r9j56pREcWDR5mnGt4gCgoIr+yaqFcRJGXqSNuJn/PWjBXXhP3oVD/W+Wl0 ePTX1oi0YE/wntol5Qsk0A3U+2IMci/AilaX8UXkisVweGHfEwABXGtHfHrLrnw9ctqA qV4KfNlsetuPaLXShiEwcwdPD8KIDJPJUVQZZ+p3OEgD0UNVgj5nZ1Zulv/de0hCO1KD +7Pw== X-Gm-Message-State: AJcUukdI8kBY46y/qaDu9LQ+ZMVny6pTiMO/zxxDveXSrZSEPrZGTTxu iSL4Lp27dTvhnEGnNSA+2q2wgZbYKR8= X-Google-Smtp-Source: ALg8bN7m+XwqE65HvJAYfh48oOtu5Y7nzkEDv04WqlLNS9bjAnkyVkGTIph0toiBdrdGJ4IVx9Smqg== X-Received: by 2002:a5d:488f:: with SMTP id g15mr9511863wrq.15.1547681868493; Wed, 16 Jan 2019 15:37:48 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:47 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:58 +0100 Message-Id: <158b6e78ba56fd24cc46685761d0fa4cf571997d.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PATCH v3 25/50] audio: use size_t where makes sense X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Gerd Hoffmann , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- Notes: Changes from v2: * Update REPLAY_VERSION * Fix run_in/run_out prototypes in audio_pcm_ops audio/audio.h | 4 +- audio/audio_int.h | 26 +++---- audio/audio_template.h | 14 ++-- audio/mixeng.h | 9 ++- audio/rate_template.h | 2 +- include/sysemu/replay.h | 4 +- audio/alsaaudio.c | 26 +++---- audio/audio.c | 162 ++++++++++++++++++++-------------------- audio/coreaudio.c | 10 +-- audio/dsoundaudio.c | 11 +-- audio/noaudio.c | 16 ++-- audio/ossaudio.c | 45 +++++------ audio/paaudio.c | 44 +++++------ audio/sdlaudio.c | 19 +++-- audio/spiceaudio.c | 12 +-- audio/wavaudio.c | 8 +- replay/replay-audio.c | 16 ++-- replay/replay.c | 2 +- 18 files changed, 214 insertions(+), 216 deletions(-) diff --git a/audio/audio.h b/audio/audio.h index 4a95758516..2db27bba7b 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -112,7 +112,7 @@ SWVoiceOut *AUD_open_out ( ); void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw); -int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size); +size_t AUD_write (SWVoiceOut *sw, void *pcm_buf, size_t size); int AUD_get_buffer_size_out (SWVoiceOut *sw); void AUD_set_active_out (SWVoiceOut *sw, int on); int AUD_is_active_out (SWVoiceOut *sw); @@ -133,7 +133,7 @@ SWVoiceIn *AUD_open_in ( ); void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw); -int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size); +size_t AUD_read (SWVoiceIn *sw, void *pcm_buf, size_t size); void AUD_set_active_in (SWVoiceIn *sw, int on); int AUD_is_active_in (SWVoiceIn *sw); diff --git a/audio/audio_int.h b/audio/audio_int.h index 40b3515b4e..9dcdf541fb 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -60,12 +60,12 @@ typedef struct HWVoiceOut { f_sample *clip; - int rpos; + size_t rpos; uint64_t ts_helper; struct st_sample *mix_buf; - int samples; + size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head; int ctl_caps; @@ -81,13 +81,13 @@ typedef struct HWVoiceIn { t_sample *conv; - int wpos; - int total_samples_captured; + size_t wpos; + size_t total_samples_captured; uint64_t ts_helper; struct st_sample *conv_buf; - int samples; + size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; int ctl_caps; struct audio_pcm_ops *pcm_ops; @@ -102,7 +102,7 @@ struct SWVoiceOut { int64_t ratio; struct st_sample *buf; void *rate; - int total_hw_samples_mixed; + size_t total_hw_samples_mixed; int active; int empty; HWVoiceOut *hw; @@ -119,7 +119,7 @@ struct SWVoiceIn { struct audio_pcm_info info; int64_t ratio; void *rate; - int total_hw_samples_acquired; + size_t total_hw_samples_acquired; struct st_sample *buf; f_sample *clip; HWVoiceIn *hw; @@ -148,12 +148,12 @@ struct audio_driver { struct audio_pcm_ops { int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque); void (*fini_out)(HWVoiceOut *hw); - int (*run_out) (HWVoiceOut *hw, int live); + size_t (*run_out)(HWVoiceOut *hw, size_t live); int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); - int (*run_in) (HWVoiceIn *hw); + size_t (*run_in)(HWVoiceIn *hw); int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); }; @@ -207,10 +207,10 @@ audio_driver *audio_driver_lookup(const char *name); void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); -int audio_pcm_hw_get_live_in (HWVoiceIn *hw); +size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw); -int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, - int live, int pending); +size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, + size_t live, size_t pending); int audio_bug (const char *funcname, int cond); void *audio_calloc (const char *funcname, int nmemb, size_t size); @@ -223,7 +223,7 @@ void audio_run(AudioState *s, const char *msg); #define VOICE_VOLUME_CAP (1 << VOICE_VOLUME) -static inline int audio_ring_dist (int dst, int src, int len) +static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len) { return (dst >= src) ? (dst - src) : (len - src + dst); } diff --git a/audio/audio_template.h b/audio/audio_template.h index ce1e5d6559..9a8aa1eebf 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -75,16 +75,16 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) HWBUF = NULL; } -static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) +static bool glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { HWBUF = audio_calloc(__func__, hw->samples, sizeof(struct st_sample)); if (!HWBUF) { - dolog ("Could not allocate " NAME " buffer (%d samples)\n", - hw->samples); - return -1; + dolog("Could not allocate " NAME " buffer (%zu samples)\n", + hw->samples); + return false; } - return 0; + return true; } static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) @@ -265,7 +265,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, } if (audio_bug(__func__, hw->samples <= 0)) { - dolog ("hw->samples=%d\n", hw->samples); + dolog("hw->samples=%zd\n", hw->samples); goto err1; } @@ -279,7 +279,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, [hw->info.swap_endianness] [audio_bits_to_index (hw->info.bits)]; - if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { + if (!glue(audio_pcm_hw_alloc_resources_, TYPE)(hw)) { goto err1; } diff --git a/audio/mixeng.h b/audio/mixeng.h index b53a5ef99a..18e62c7c49 100644 --- a/audio/mixeng.h +++ b/audio/mixeng.h @@ -33,6 +33,7 @@ struct st_sample { mixeng_real l; mixeng_real r; }; struct mixeng_volume { int mute; int64_t r; int64_t l; }; struct st_sample { int64_t l; int64_t r; }; #endif +typedef struct st_sample st_sample; typedef void (t_sample) (struct st_sample *dst, const void *src, int samples); typedef void (f_sample) (void *dst, const struct st_sample *src, int samples); @@ -41,10 +42,10 @@ extern t_sample *mixeng_conv[2][2][2][3]; extern f_sample *mixeng_clip[2][2][2][3]; void *st_rate_start (int inrate, int outrate); -void st_rate_flow (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, - int *isamp, int *osamp); -void st_rate_flow_mix (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, - int *isamp, int *osamp); +void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf, + size_t *isamp, size_t *osamp); +void st_rate_flow_mix(void *opaque, st_sample *ibuf, st_sample *obuf, + size_t *isamp, size_t *osamp); void st_rate_stop (void *opaque); void mixeng_clear (struct st_sample *buf, int len); void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol); diff --git a/audio/rate_template.h b/audio/rate_template.h index 6e93588877..f94c940c61 100644 --- a/audio/rate_template.h +++ b/audio/rate_template.h @@ -28,7 +28,7 @@ * Return number of samples processed. */ void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, - int *isamp, int *osamp) + size_t *isamp, size_t *osamp) { struct rate *rate = opaque; struct st_sample *istart, *iend; diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 3a7c58e423..5c0a91e44f 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -179,9 +179,9 @@ void replay_net_packet_event(ReplayNetState *rns, unsigned flags, /* Audio */ /*! Saves/restores number of played samples of audio out operation. */ -void replay_audio_out(int *played); +void replay_audio_out(size_t *played); /*! Saves/restores recorded samples of audio in operation. */ -void replay_audio_in(int *recorded, void *samples, int *wpos, int size); +void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size); /* VM state operations */ diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 4c6bbdbc1d..6ad2a09d16 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -688,10 +688,10 @@ static void alsa_write_pending (ALSAVoiceOut *alsa) } } -static int alsa_run_out (HWVoiceOut *hw, int live) +static size_t alsa_run_out(HWVoiceOut *hw, size_t live) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; - int decr; + size_t decr; snd_pcm_sframes_t avail; avail = alsa_get_avail (alsa->handle); @@ -746,8 +746,8 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift); if (!alsa->pcm_buf) { - dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); + dolog("Could not allocate DAC buffer (%zu samples, each %d bytes)\n", + hw->samples, 1 << hw->info.shift); alsa_anal_close1 (&handle); return -1; } @@ -848,8 +848,8 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); if (!alsa->pcm_buf) { - dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); + dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", + hw->samples, 1 << hw->info.shift); alsa_anal_close1 (&handle); return -1; } @@ -870,17 +870,17 @@ static void alsa_fini_in (HWVoiceIn *hw) alsa->pcm_buf = NULL; } -static int alsa_run_in (HWVoiceIn *hw) +static size_t alsa_run_in(HWVoiceIn *hw) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; int hwshift = hw->info.shift; int i; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; - int decr; + size_t live = audio_pcm_hw_get_live_in (hw); + size_t dead = hw->samples - live; + size_t decr; struct { - int add; - int len; + size_t add; + size_t len; } bufs[2] = { { .add = hw->wpos, .len = 0 }, { .add = 0, .len = 0 } @@ -920,7 +920,7 @@ static int alsa_run_in (HWVoiceIn *hw) } } - decr = MIN (dead, avail); + decr = MIN(dead, avail); if (!decr) { return 0; } diff --git a/audio/audio.c b/audio/audio.c index f844411d59..33b11e4feb 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -529,10 +529,10 @@ static int audio_attach_capture (HWVoiceOut *hw) /* * Hard voice (capture) */ -static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) +static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw) { SWVoiceIn *sw; - int m = hw->total_samples_captured; + size_t m = hw->total_samples_captured; for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (sw->active) { @@ -542,28 +542,28 @@ static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) return m; } -int audio_pcm_hw_get_live_in (HWVoiceIn *hw) +size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) { - int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); - if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog ("live=%d hw->samples=%d\n", live, hw->samples); + size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); + if (audio_bug(__func__, live > hw->samples)) { + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); return 0; } return live; } -int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, - int live, int pending) +size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, + size_t live, size_t pending) { - int left = hw->samples - pending; - int len = MIN (left, live); - int clipped = 0; + size_t left = hw->samples - pending; + size_t len = MIN (left, live); + size_t clipped = 0; while (len) { struct st_sample *src = hw->mix_buf + hw->rpos; uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift); - int samples_till_end_of_buf = hw->samples - hw->rpos; - int samples_to_clip = MIN (len, samples_till_end_of_buf); + size_t samples_till_end_of_buf = hw->samples - hw->rpos; + size_t samples_to_clip = MIN (len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip); @@ -577,14 +577,14 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf, /* * Soft voice (capture) */ -static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) +static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw) { HWVoiceIn *hw = sw->hw; - int live = hw->total_samples_captured - sw->total_hw_samples_acquired; - int rpos; + ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired; + ssize_t rpos; if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog ("live=%d hw->samples=%d\n", live, hw->samples); + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); return 0; } @@ -597,17 +597,17 @@ static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw) } } -static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size) +static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) { HWVoiceIn *hw = sw->hw; - int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; + size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; struct st_sample *src, *dst = sw->buf; rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; live = hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog ("live_in=%d hw->samples=%d\n", live, hw->samples); + if (audio_bug(__func__, live > hw->samples)) { + dolog("live_in=%zu hw->samples=%zu\n", live, hw->samples); return 0; } @@ -621,9 +621,9 @@ static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size) while (swlim) { src = hw->conv_buf + rpos; - isamp = hw->wpos - rpos; - /* XXX: <= ? */ - if (isamp <= 0) { + if (hw->wpos > rpos) { + isamp = hw->wpos - rpos; + } else { isamp = hw->samples - rpos; } @@ -632,11 +632,6 @@ static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size) } osamp = swlim; - if (audio_bug(__func__, osamp < 0)) { - dolog ("osamp=%d\n", osamp); - return 0; - } - st_rate_flow (sw->rate, src, dst, &isamp, &osamp); swlim -= osamp; rpos = (rpos + isamp) % hw->samples; @@ -657,10 +652,10 @@ static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size) /* * Hard voice (playback) */ -static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) +static size_t audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) { SWVoiceOut *sw; - int m = INT_MAX; + size_t m = SIZE_MAX; int nb_live = 0; for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { @@ -674,9 +669,9 @@ static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) return m; } -static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) +static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) { - int smin; + size_t smin; int nb_live1; smin = audio_pcm_hw_find_min_out (hw, &nb_live1); @@ -685,10 +680,10 @@ static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) } if (nb_live1) { - int live = smin; + size_t live = smin; - if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog ("live=%d hw->samples=%d\n", live, hw->samples); + if (audio_bug(__func__, live > hw->samples)) { + dolog("live=%zu hw->samples=%zu\n", live, hw->samples); return 0; } return live; @@ -699,10 +694,10 @@ static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) /* * Soft voice (playback) */ -static int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) +static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) { - int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; - int ret = 0, pos = 0, total = 0; + size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; + size_t ret = 0, pos = 0, total = 0; if (!sw) { return size; @@ -711,8 +706,8 @@ static int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) hwsamples = sw->hw->samples; live = sw->total_hw_samples_mixed; - if (audio_bug(__func__, live < 0 || live > hwsamples)) { - dolog ("live=%d hw->samples=%d\n", live, hwsamples); + if (audio_bug(__func__, live > hwsamples)) { + dolog("live=%zu hw->samples=%zu\n", live, hwsamples); return 0; } @@ -766,7 +761,7 @@ static int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size) #ifdef DEBUG_OUT dolog ( - "%s: write size %d ret %d total sw %d\n", + "%s: write size %zu ret %zu total sw %zu\n", SW_NAME (sw), size >> sw->info.shift, ret, @@ -845,7 +840,7 @@ static void audio_timer (void *opaque) /* * Public API */ -int AUD_write (SWVoiceOut *sw, void *buf, int size) +size_t AUD_write(SWVoiceOut *sw, void *buf, size_t size) { if (!sw) { /* XXX: Consider options */ @@ -860,7 +855,7 @@ int AUD_write (SWVoiceOut *sw, void *buf, int size) return audio_pcm_sw_write(sw, buf, size); } -int AUD_read (SWVoiceIn *sw, void *buf, int size) +size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) { if (!sw) { /* XXX: Consider options */ @@ -969,17 +964,17 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) } } -static int audio_get_avail (SWVoiceIn *sw) +static size_t audio_get_avail (SWVoiceIn *sw) { - int live; + size_t live; if (!sw) { return 0; } live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(__func__, live < 0 || live > sw->hw->samples)) { - dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); + if (audio_bug(__func__, live > sw->hw->samples)) { + dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); return 0; } @@ -992,9 +987,9 @@ static int audio_get_avail (SWVoiceIn *sw) return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; } -static int audio_get_free (SWVoiceOut *sw) +static size_t audio_get_free(SWVoiceOut *sw) { - int live, dead; + size_t live, dead; if (!sw) { return 0; @@ -1002,8 +997,8 @@ static int audio_get_free (SWVoiceOut *sw) live = sw->total_hw_samples_mixed; - if (audio_bug(__func__, live < 0 || live > sw->hw->samples)) { - dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); + if (audio_bug(__func__, live > sw->hw->samples)) { + dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); return 0; } @@ -1018,9 +1013,10 @@ static int audio_get_free (SWVoiceOut *sw) return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; } -static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) +static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, + size_t samples) { - int n; + size_t n; if (hw->enabled) { SWVoiceCap *sc; @@ -1031,17 +1027,17 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) n = samples; while (n) { - int till_end_of_hw = hw->samples - rpos2; - int to_write = MIN (till_end_of_hw, n); - int bytes = to_write << hw->info.shift; - int written; + size_t till_end_of_hw = hw->samples - rpos2; + size_t to_write = MIN(till_end_of_hw, n); + size_t bytes = to_write << hw->info.shift; + size_t written; sw->buf = hw->mix_buf + rpos2; written = audio_pcm_sw_write (sw, NULL, bytes); if (written - bytes) { - dolog ("Could not mix %d bytes into a capture " - "buffer, mixed %d\n", - bytes, written); + dolog("Could not mix %zu bytes into a capture " + "buffer, mixed %zu\n", + bytes, written); break; } n -= to_write; @@ -1050,9 +1046,9 @@ static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) } } - n = MIN (samples, hw->samples - rpos); - mixeng_clear (hw->mix_buf + rpos, n); - mixeng_clear (hw->mix_buf, samples - n); + n = MIN(samples, hw->samples - rpos); + mixeng_clear(hw->mix_buf + rpos, n); + mixeng_clear(hw->mix_buf, samples - n); } static void audio_run_out (AudioState *s) @@ -1061,16 +1057,16 @@ static void audio_run_out (AudioState *s) SWVoiceOut *sw; while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) { - int played; - int live, free, nb_live, cleanup_required, prev_rpos; + size_t played, live, prev_rpos, free; + int nb_live, cleanup_required; live = audio_pcm_hw_get_live_out (hw, &nb_live); if (!nb_live) { live = 0; } - if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog ("live=%d hw->samples=%d\n", live, hw->samples); + if (audio_bug(__func__, live > hw->samples)) { + dolog ("live=%zu hw->samples=%zu\n", live, hw->samples); continue; } @@ -1105,13 +1101,13 @@ static void audio_run_out (AudioState *s) played = hw->pcm_ops->run_out (hw, live); replay_audio_out(&played); if (audio_bug(__func__, hw->rpos >= hw->samples)) { - dolog ("hw->rpos=%d hw->samples=%d played=%d\n", - hw->rpos, hw->samples, played); + dolog("hw->rpos=%zu hw->samples=%zu played=%zu\n", + hw->rpos, hw->samples, played); hw->rpos = 0; } #ifdef DEBUG_OUT - dolog ("played=%d\n", played); + dolog("played=%zu\n", played); #endif if (played) { @@ -1126,8 +1122,8 @@ static void audio_run_out (AudioState *s) } if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) { - dolog ("played=%d sw->total_hw_samples_mixed=%d\n", - played, sw->total_hw_samples_mixed); + dolog("played=%zu sw->total_hw_samples_mixed=%zu\n", + played, sw->total_hw_samples_mixed); played = sw->total_hw_samples_mixed; } @@ -1167,7 +1163,7 @@ static void audio_run_in (AudioState *s) while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) { SWVoiceIn *sw; - int captured = 0, min; + size_t captured = 0, min; if (replay_mode != REPLAY_MODE_PLAY) { captured = hw->pcm_ops->run_in(hw); @@ -1182,7 +1178,7 @@ static void audio_run_in (AudioState *s) sw->total_hw_samples_acquired -= min; if (sw->active) { - int avail; + size_t avail; avail = audio_get_avail (sw); if (avail > 0) { @@ -1198,15 +1194,15 @@ static void audio_run_capture (AudioState *s) CaptureVoiceOut *cap; for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { - int live, rpos, captured; + size_t live, rpos, captured; HWVoiceOut *hw = &cap->hw; SWVoiceOut *sw; captured = live = audio_pcm_hw_get_live_out (hw, NULL); rpos = hw->rpos; while (live) { - int left = hw->samples - rpos; - int to_capture = MIN (live, left); + size_t left = hw->samples - rpos; + size_t to_capture = MIN(live, left); struct st_sample *src; struct capture_callback *cb; @@ -1229,8 +1225,8 @@ static void audio_run_capture (AudioState *s) } if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) { - dolog ("captured=%d sw->total_hw_samples_mixed=%d\n", - captured, sw->total_hw_samples_mixed); + dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n", + captured, sw->total_hw_samples_mixed); captured = sw->total_hw_samples_mixed; } @@ -1591,8 +1587,8 @@ CaptureVoiceOut *AUD_add_capture( hw->mix_buf = audio_calloc(__func__, hw->samples, sizeof(struct st_sample)); if (!hw->mix_buf) { - dolog ("Could not allocate capture mix buffer (%d samples)\n", - hw->samples); + dolog("Could not allocate capture mix buffer (%zu samples)\n", + hw->samples); goto err2; } @@ -1601,7 +1597,7 @@ CaptureVoiceOut *AUD_add_capture( cap->buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); if (!cap->buf) { dolog ("Could not allocate capture buffer " - "(%d samples, each %d bytes)\n", + "(%zu samples, each %d bytes)\n", hw->samples, 1 << hw->info.shift); goto err3; } diff --git a/audio/coreaudio.c b/audio/coreaudio.c index abbbb45d69..646aea06a0 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -43,9 +43,9 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; - int live; - int decr; - int rpos; + size_t live; + size_t decr; + size_t rpos; } coreaudioVoiceOut; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 @@ -397,9 +397,9 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name) return 0; } -static int coreaudio_run_out (HWVoiceOut *hw, int live) +static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live) { - int decr; + size_t decr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; if (coreaudio_lock (core, "coreaudio_run_out")) { diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index dfcb70c81a..906cca3235 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -454,19 +454,20 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static int dsound_run_out (HWVoiceOut *hw, int live) +static size_t dsound_run_out(HWVoiceOut *hw, size_t live) { int err; HRESULT hr; DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; - int len, hwshift; + size_t len; + int hwshift; DWORD blen1, blen2; DWORD len1, len2; DWORD decr; DWORD wpos, ppos, old_pos; LPVOID p1, p2; - int bufsize; + size_t bufsize; dsound *s = ds->s; AudiodevDsoundOptions *dso = &s->dev->u.dsound; @@ -640,13 +641,13 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static int dsound_run_in (HWVoiceIn *hw) +static size_t dsound_run_in(HWVoiceIn *hw) { int err; HRESULT hr; DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; - int live, len, dead; + size_t live, len, dead; DWORD blen1, blen2; DWORD len1, len2; DWORD decr; diff --git a/audio/noaudio.c b/audio/noaudio.c index 4fe7720861..59e680db6f 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -40,10 +40,10 @@ typedef struct NoVoiceIn { int64_t old_ticks; } NoVoiceIn; -static int no_run_out (HWVoiceOut *hw, int live) +static size_t no_run_out(HWVoiceOut *hw, size_t live) { NoVoiceOut *no = (NoVoiceOut *) hw; - int decr, samples; + size_t decr, samples; int64_t now; int64_t ticks; int64_t bytes; @@ -51,7 +51,7 @@ static int no_run_out (HWVoiceOut *hw, int live) now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - no->old_ticks; bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - bytes = MIN(bytes, INT_MAX); + bytes = MIN(bytes, SIZE_MAX); samples = bytes >> hw->info.shift; no->old_ticks = now; @@ -91,12 +91,12 @@ static void no_fini_in (HWVoiceIn *hw) (void) hw; } -static int no_run_in (HWVoiceIn *hw) +static size_t no_run_in(HWVoiceIn *hw) { NoVoiceIn *no = (NoVoiceIn *) hw; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; - int samples = 0; + size_t live = audio_pcm_hw_get_live_in(hw); + size_t dead = hw->samples - live; + size_t samples = 0; if (dead) { int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); @@ -105,7 +105,7 @@ static int no_run_in (HWVoiceIn *hw) muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); no->old_ticks = now; - bytes = MIN (bytes, INT_MAX); + bytes = MIN (bytes, SIZE_MAX); samples = bytes >> hw->info.shift; samples = MIN (samples, dead); } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 3eee7a3970..c6d4086573 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -410,13 +410,14 @@ static void oss_write_pending (OSSVoiceOut *oss) } } -static int oss_run_out (HWVoiceOut *hw, int live) +static size_t oss_run_out(HWVoiceOut *hw, size_t live) { OSSVoiceOut *oss = (OSSVoiceOut *) hw; - int err, decr; + int err; + size_t decr; struct audio_buf_info abinfo; struct count_info cntinfo; - int bufsize; + size_t bufsize; bufsize = hw->samples << hw->info.shift; @@ -475,8 +476,8 @@ static void oss_fini_out (HWVoiceOut *hw) if (oss->mmapped) { err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); if (err) { - oss_logerr (errno, "Failed to unmap buffer %p, size %d\n", - oss->pcm_buf, hw->samples << hw->info.shift); + oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n", + oss->pcm_buf, hw->samples << hw->info.shift); } } else { @@ -542,8 +543,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, 0 ); if (oss->pcm_buf == MAP_FAILED) { - oss_logerr (errno, "Failed to map %d bytes of DAC\n", - hw->samples << hw->info.shift); + oss_logerr(errno, "Failed to map %zu bytes of DAC\n", + hw->samples << hw->info.shift); } else { int err; @@ -567,8 +568,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, if (!oss->mmapped) { err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); if (err) { - oss_logerr (errno, "Failed to unmap buffer %p size %d\n", - oss->pcm_buf, hw->samples << hw->info.shift); + oss_logerr(errno, "Failed to unmap buffer %p size %zu\n", + oss->pcm_buf, hw->samples << hw->info.shift); } } } @@ -580,7 +581,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, 1 << hw->info.shift); if (!oss->pcm_buf) { dolog ( - "Could not allocate DAC buffer (%d samples, each %d bytes)\n", + "Could not allocate DAC buffer (%zu samples, each %d bytes)\n", hw->samples, 1 << hw->info.shift ); @@ -692,8 +693,8 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); if (!oss->pcm_buf) { - dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); + dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", + hw->samples, 1 << hw->info.shift); oss_anal_close (&fd); return -1; } @@ -713,17 +714,17 @@ static void oss_fini_in (HWVoiceIn *hw) oss->pcm_buf = NULL; } -static int oss_run_in (HWVoiceIn *hw) +static size_t oss_run_in(HWVoiceIn *hw) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; int hwshift = hw->info.shift; int i; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; + size_t live = audio_pcm_hw_get_live_in (hw); + size_t dead = hw->samples - live; size_t read_samples = 0; struct { - int add; - int len; + size_t add; + size_t len; } bufs[2] = { { .add = hw->wpos, .len = 0 }, { .add = 0, .len = 0 } @@ -750,9 +751,9 @@ static int oss_run_in (HWVoiceIn *hw) if (nread > 0) { if (nread & hw->info.align) { - dolog ("warning: Misaligned read %zd (requested %d), " - "alignment %d\n", nread, bufs[i].add << hwshift, - hw->info.align + 1); + dolog("warning: Misaligned read %zd (requested %zu), " + "alignment %d\n", nread, bufs[i].add << hwshift, + hw->info.align + 1); } read_samples += nread >> hwshift; hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift); @@ -765,9 +766,9 @@ static int oss_run_in (HWVoiceIn *hw) case EAGAIN: break; default: - oss_logerr ( + oss_logerr( errno, - "Failed to read %d bytes of audio (to %p)\n", + "Failed to read %zu bytes of audio (to %p)\n", bufs[i].len, p ); break; diff --git a/audio/paaudio.c b/audio/paaudio.c index f5b924d50c..a1be0726b7 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -29,30 +29,30 @@ typedef struct { typedef struct { HWVoiceOut hw; - int done; - int live; - int decr; - int rpos; + size_t done; + size_t live; + size_t decr; + size_t rpos; pa_stream *stream; void *pcm_buf; struct audio_pt pt; paaudio *g; - int samples; + size_t samples; } PAVoiceOut; typedef struct { HWVoiceIn hw; - int done; - int dead; - int incr; - int wpos; + size_t done; + size_t dead; + size_t incr; + size_t wpos; pa_stream *stream; void *pcm_buf; struct audio_pt pt; const void *read_data; size_t read_index, read_length; paaudio *g; - int samples; + size_t samples; } PAVoiceIn; static void qpa_conn_fini(PAConnection *c); @@ -218,7 +218,7 @@ static void *qpa_thread_out (void *arg) } for (;;) { - int decr, to_mix, rpos; + size_t decr, to_mix, rpos; for (;;) { if (pa->done) { @@ -243,7 +243,7 @@ static void *qpa_thread_out (void *arg) while (to_mix) { int error; - int chunk = MIN (to_mix, hw->samples - rpos); + size_t chunk = MIN (to_mix, hw->samples - rpos); struct st_sample *src = hw->mix_buf + rpos; hw->clip (pa->pcm_buf, src, chunk); @@ -272,9 +272,9 @@ static void *qpa_thread_out (void *arg) return NULL; } -static int qpa_run_out (HWVoiceOut *hw, int live) +static size_t qpa_run_out(HWVoiceOut *hw, size_t live) { - int decr; + size_t decr; PAVoiceOut *pa = (PAVoiceOut *) hw; if (audio_pt_lock(&pa->pt, __func__)) { @@ -305,7 +305,7 @@ static void *qpa_thread_in (void *arg) } for (;;) { - int incr, to_grab, wpos; + size_t incr, to_grab, wpos; for (;;) { if (pa->done) { @@ -330,7 +330,7 @@ static void *qpa_thread_in (void *arg) while (to_grab) { int error; - int chunk = MIN (to_grab, hw->samples - wpos); + size_t chunk = MIN (to_grab, hw->samples - wpos); void *buf = advance (pa->pcm_buf, wpos); if (qpa_simple_read (pa, buf, @@ -358,9 +358,9 @@ static void *qpa_thread_in (void *arg) return NULL; } -static int qpa_run_in (HWVoiceIn *hw) +static size_t qpa_run_in(HWVoiceIn *hw) { - int live, incr, dead; + size_t live, incr, dead; PAVoiceIn *pa = (PAVoiceIn *) hw; if (audio_pt_lock(&pa->pt, __func__)) { @@ -584,8 +584,8 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->rpos = hw->rpos; if (!pa->pcm_buf) { - dolog ("Could not allocate buffer (%d bytes)\n", - hw->samples << hw->info.shift); + dolog("Could not allocate buffer (%zu bytes)\n", + hw->samples << hw->info.shift); goto fail2; } @@ -645,8 +645,8 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); pa->wpos = hw->wpos; if (!pa->pcm_buf) { - dolog ("Could not allocate buffer (%d bytes)\n", - hw->samples << hw->info.shift); + dolog("Could not allocate buffer (%zu bytes)\n", + hw->samples << hw->info.shift); goto fail2; } diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index ab9166d054..ff19484430 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -42,11 +42,11 @@ typedef struct SDLVoiceOut { HWVoiceOut hw; - int live; + size_t live; #if USE_SEMAPHORE - int rpos; + size_t rpos; #endif - int decr; + size_t decr; } SDLVoiceOut; static struct SDLAudioState { @@ -252,14 +252,14 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) SDLVoiceOut *sdl = opaque; SDLAudioState *s = &glob_sdl; HWVoiceOut *hw = &sdl->hw; - int samples = len >> hw->info.shift; + size_t samples = len >> hw->info.shift; if (s->exit) { return; } while (samples) { - int to_mix, decr; + size_t to_mix, decr; /* dolog ("in callback samples=%d\n", samples); */ #if USE_SEMAPHORE @@ -273,8 +273,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) } if (audio_bug(__func__, sdl->live < 0 || sdl->live > hw->samples)) { - dolog ("sdl->live=%d hw->samples=%d\n", - sdl->live, hw->samples); + dolog("sdl->live=%d hw->samples=%zu\n", sdl->live, hw->samples); return; } @@ -291,7 +290,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) to_mix = MIN (samples, sdl->live); decr = to_mix; while (to_mix) { - int chunk = MIN (to_mix, hw->samples - hw->rpos); + size_t chunk = MIN(to_mix, hw->samples - hw->rpos); struct st_sample *src = hw->mix_buf + hw->rpos; /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ @@ -325,9 +324,9 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) #endif } -static int sdl_run_out (HWVoiceOut *hw, int live) +static size_t sdl_run_out(HWVoiceOut *hw, size_t live) { - int decr; + size_t decr; SDLVoiceOut *sdl = (SDLVoiceOut *) hw; SDLAudioState *s = &glob_sdl; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index f963853ed8..1a777bba17 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -152,11 +152,11 @@ static void line_out_fini (HWVoiceOut *hw) spice_server_remove_interface (&out->sin.base); } -static int line_out_run (HWVoiceOut *hw, int live) +static size_t line_out_run (HWVoiceOut *hw, size_t live) { SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); - int rpos, decr; - int samples; + size_t rpos, decr; + size_t samples; if (!live) { return 0; @@ -275,12 +275,12 @@ static void line_in_fini (HWVoiceIn *hw) spice_server_remove_interface (&in->sin.base); } -static int line_in_run (HWVoiceIn *hw) +static size_t line_in_run(HWVoiceIn *hw) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); - int num_samples; + size_t num_samples; int ready; - int len[2]; + size_t len[2]; uint64_t delta_samp; const uint32_t *samples; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index dda6993fb9..a805e5e94b 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -38,10 +38,10 @@ typedef struct WAVVoiceOut { int total_samples; } WAVVoiceOut; -static int wav_run_out (HWVoiceOut *hw, int live) +static size_t wav_run_out(HWVoiceOut *hw, size_t live) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; - int rpos, decr, samples; + size_t rpos, decr, samples; uint8_t *dst; struct st_sample *src; int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); @@ -137,8 +137,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, hw->samples = 1024; wav->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); if (!wav->pcm_buf) { - dolog ("Could not allocate buffer (%d bytes)\n", - hw->samples << hw->info.shift); + dolog("Could not allocate buffer (%zu bytes)\n", + hw->samples << hw->info.shift); return -1; } diff --git a/replay/replay-audio.c b/replay/replay-audio.c index b113836de4..efe1628727 100644 --- a/replay/replay-audio.c +++ b/replay/replay-audio.c @@ -16,18 +16,18 @@ #include "sysemu/sysemu.h" #include "audio/audio.h" -void replay_audio_out(int *played) +void replay_audio_out(size_t *played) { if (replay_mode == REPLAY_MODE_RECORD) { g_assert(replay_mutex_locked()); replay_save_instructions(); replay_put_event(EVENT_AUDIO_OUT); - replay_put_dword(*played); + replay_put_qword(*played); } else if (replay_mode == REPLAY_MODE_PLAY) { g_assert(replay_mutex_locked()); replay_account_executed_instructions(); if (replay_next_event_is(EVENT_AUDIO_OUT)) { - *played = replay_get_dword(); + *played = replay_get_qword(); replay_finish_event(); } else { error_report("Missing audio out event in the replay log"); @@ -36,7 +36,7 @@ void replay_audio_out(int *played) } } -void replay_audio_in(int *recorded, void *samples, int *wpos, int size) +void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size) { int pos; uint64_t left, right; @@ -44,8 +44,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size) g_assert(replay_mutex_locked()); replay_save_instructions(); replay_put_event(EVENT_AUDIO_IN); - replay_put_dword(*recorded); - replay_put_dword(*wpos); + replay_put_qword(*recorded); + replay_put_qword(*wpos); for (pos = (*wpos - *recorded + size) % size ; pos != *wpos ; pos = (pos + 1) % size) { audio_sample_to_uint64(samples, pos, &left, &right); @@ -56,8 +56,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size) g_assert(replay_mutex_locked()); replay_account_executed_instructions(); if (replay_next_event_is(EVENT_AUDIO_IN)) { - *recorded = replay_get_dword(); - *wpos = replay_get_dword(); + *recorded = replay_get_qword(); + *wpos = replay_get_qword(); for (pos = (*wpos - *recorded + size) % size ; pos != *wpos ; pos = (pos + 1) % size) { left = replay_get_qword(); diff --git a/replay/replay.c b/replay/replay.c index 8b172b2d1b..a1135a9943 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02007 +#define REPLAY_VERSION 0xe02008 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) From patchwork Wed Jan 16 23:36:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767181 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F371714E5 for ; Thu, 17 Jan 2019 00:07:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC8452E9BD for ; Thu, 17 Jan 2019 00:07:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D070B2F353; Thu, 17 Jan 2019 00:07:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 132F42E9BD for ; Thu, 17 Jan 2019 00:07:23 +0000 (UTC) Received: from localhost ([127.0.0.1]:38359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvDO-0001xj-AM for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:07:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58285) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul7-0004OE-CX for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Q0-19 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:09 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:32770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-00033b-J5 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:05 -0500 Received: by mail-wr1-x441.google.com with SMTP id c14so9004784wrr.0 for ; Wed, 16 Jan 2019 15:37:50 -0800 (PST) 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=frGGfUupsMLGHfC6WoV6MQFyciv6qtB55wmYj0epTGM=; b=aWHOOl2pWutzS4HVuj4hjAYX4vWIfZmhlzmGu1omflQgG97wunNdvrgaSkt7D2Y26t ZikwSCOcYZuDy65nao1ynbeH+ay1Em28XPFxE8G/2r1n42OVYU3xvJlp8zh8bNS4YseK guwI65tGY1HZ9UJMaKraHgmpHpo2QEDPBWsLRK2BURXUzxzkNOHCkynJWWGF6m+O5Iim 1kYO1+kK6JITdHR5O+iB/nkRL+0+T349R5oJh8uXowC8TOKQeIr8IzrNSzUaApEb61Sw pbsFQIK/7SYL24TZTgxjtaoUoiQQFDyKrGG4D0t2PsZlY6pOBKTiVWyyPXGoar5bfkvB zz8w== 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=frGGfUupsMLGHfC6WoV6MQFyciv6qtB55wmYj0epTGM=; b=uAIeLZ2GS/SR8mPPmv4fupZlGfn9E0OWPwE0mMPqYZQ5kI/dJ3dj3iL8DHSod74YDe a40T1WeD5Bu5V4v2WKqtknvl9dtBAfhJu/QBY6nuyXmOVrYTavSdHF88CFcKtFOsmWBr F/xRQ2et1m7SmoHYxDgZQluzOt1RRAs6TwJuADvL5EUXK3xmrpQMDsaP2vAeT4DRFNbN Fs0FT2ASWxOEjsf5BSRwuJMB94CQnOjwMf7fUuOjRuGSCkP5hTGAlUFTkOBYCEYA2eoD CgZUgBZrArOwUNvKuSFutuVuVJRiQh0o/G6eYYgYkQgkZEnMKrIwRT7E28MSvzbT8jFw 2LaQ== X-Gm-Message-State: AJcUuke2NDD5CFkJaJs7E6BOTuN/GJ0fWOX//gEBsSh5K9FNcKdnnZD4 wnrT1uu6CwqeH3wIvHYMMFN/4GUpxnU= X-Google-Smtp-Source: ALg8bN4QT14sUhiBebnGzKufZZyIAC3FScXpHkDgBrcSx3iePdWD8bhIxHdHM8ysSCBrjvg7rodNpw== X-Received: by 2002:a5d:4dc8:: with SMTP id f8mr9775189wru.45.1547681869364; Wed, 16 Jan 2019 15:37:49 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:48 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:36:59 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 26/50] audio: api for mixeng code free backends X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 41 ++++++-- audio/audio_template.h | 1 + audio/audio.c | 211 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 245 insertions(+), 8 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 9dcdf541fb..056c63d45c 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -64,6 +64,8 @@ typedef struct HWVoiceOut { uint64_t ts_helper; struct st_sample *mix_buf; + void *buf_emul; + size_t pos_emul, pending_emul, size_emul; size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; @@ -86,6 +88,8 @@ typedef struct HWVoiceIn { uint64_t ts_helper; struct st_sample *conv_buf; + void *buf_emul; + size_t pos_emul, pending_emul, size_emul; size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; @@ -146,17 +150,42 @@ struct audio_driver { }; struct audio_pcm_ops { - int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque); - void (*fini_out)(HWVoiceOut *hw); + int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque); + void (*fini_out)(HWVoiceOut *hw); size_t (*run_out)(HWVoiceOut *hw, size_t live); - int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); + size_t (*write) (HWVoiceOut *hw, void *buf, size_t size); + /* + * get a buffer that after later can be passed to put_buffer_out; optional + * returns the buffer, and writes it's size to size (in bytes) + * this is unrelated to the above buffer_size_out function + */ + void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size); + /* + * put back the buffer returned by get_buffer_out; optional + * buf must be equal the pointer returned by get_buffer_out, + * size may be smaller + */ + size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size); + int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); - int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque); - void (*fini_in) (HWVoiceIn *hw); + int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); + void (*fini_in) (HWVoiceIn *hw); size_t (*run_in)(HWVoiceIn *hw); - int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); + size_t (*read) (HWVoiceIn *hw, void *buf, size_t size); + void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); + void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); + int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); }; +void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size); +void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size); +void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size); +size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size); +size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf, + size_t size); +size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size); +size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size); + struct capture_callback { struct audio_capture_ops ops; void *opaque; diff --git a/audio/audio_template.h b/audio/audio_template.h index 9a8aa1eebf..fcab583cfc 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -71,6 +71,7 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s, static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) { + g_free(hw->buf_emul); g_free (HWBUF); HWBUF = NULL; } diff --git a/audio/audio.c b/audio/audio.c index 33b11e4feb..f4d538618f 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -574,6 +574,25 @@ size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, return clipped; } +static void audio_pcm_hw_clip_out2(HWVoiceOut *hw, void *pcm_buf, size_t len) +{ + size_t clipped = 0; + size_t pos = hw->rpos; + + while (len) { + st_sample *src = hw->mix_buf + pos; + uint8_t *dst = advance (pcm_buf, clipped << hw->info.shift); + size_t samples_till_end_of_buf = hw->samples - pos; + size_t samples_to_clip = MIN(len, samples_till_end_of_buf); + + hw->clip (dst, src, samples_to_clip); + + pos = (pos + samples_to_clip) % hw->samples; + len -= samples_to_clip; + clipped += samples_to_clip; + } +} + /* * Soft voice (capture) */ @@ -1051,6 +1070,31 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, mixeng_clear(hw->mix_buf, samples - n); } +static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) +{ + size_t clipped = 0; + + while (live) { + size_t size, decr, proc; + void *buf = hw->pcm_ops->get_buffer_out(hw, &size); + + decr = MIN(size >> hw->info.shift, live); + audio_pcm_hw_clip_out2(hw, buf, decr); + proc = hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shift) >> + hw->info.shift; + + live -= proc; + clipped += proc; + hw->rpos = (hw->rpos + proc) % hw->samples; + + if (proc == 0 || proc < decr) { + break; + } + } + + return clipped; +} + static void audio_run_out (AudioState *s) { HWVoiceOut *hw = NULL; @@ -1098,7 +1142,11 @@ static void audio_run_out (AudioState *s) } prev_rpos = hw->rpos; - played = hw->pcm_ops->run_out (hw, live); + if (hw->pcm_ops->run_out) { + played = hw->pcm_ops->run_out(hw, live); + } else { + played = audio_pcm_hw_run_out(hw, live); + } replay_audio_out(&played); if (audio_bug(__func__, hw->rpos >= hw->samples)) { dolog("hw->rpos=%zu hw->samples=%zu played=%zu\n", @@ -1157,6 +1205,35 @@ static void audio_run_out (AudioState *s) } } +static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) +{ + size_t conv = 0; + + while (samples) { + size_t proc; + size_t size = samples << hw->info.shift; + void *buf = hw->pcm_ops->get_buffer_in(hw, &size); + + assert((size & hw->info.align) == 0); + if (size == 0) { + hw->pcm_ops->put_buffer_in(hw, buf, size); + break; + } + + proc = MIN(size >> hw->info.shift, + hw->samples - hw->wpos); + + hw->conv(hw->conv_buf + hw->wpos, buf, proc); + hw->wpos = (hw->wpos + proc) % hw->samples; + + samples -= proc; + conv += proc; + hw->pcm_ops->put_buffer_in(hw, buf, proc << hw->info.shift); + } + + return conv; +} + static void audio_run_in (AudioState *s) { HWVoiceIn *hw = NULL; @@ -1166,7 +1243,12 @@ static void audio_run_in (AudioState *s) size_t captured = 0, min; if (replay_mode != REPLAY_MODE_PLAY) { - captured = hw->pcm_ops->run_in(hw); + if (hw->pcm_ops->run_in) { + captured = hw->pcm_ops->run_in(hw); + } else { + captured = audio_pcm_hw_run_in( + hw, hw->samples - audio_pcm_hw_get_live_in(hw)); + } } replay_audio_in(&captured, hw->conv_buf, &hw->wpos, hw->samples); @@ -1260,12 +1342,137 @@ void audio_run(AudioState *s, const char *msg) #endif } +void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) +{ + ssize_t start; + + if (unlikely(!hw->buf_emul)) { + size_t calc_size = hw->samples << hw->info.shift; + hw->buf_emul = g_malloc(calc_size); + hw->size_emul = calc_size; + hw->pos_emul = hw->pending_emul = 0; + } + + while (hw->pending_emul < hw->size_emul) { + size_t read_len = MIN(hw->size_emul - hw->pos_emul, + hw->size_emul - hw->pending_emul); + size_t read = hw->pcm_ops->read(hw, hw->buf_emul + hw->pos_emul, + read_len); + hw->pending_emul += read; + if (read < read_len) { + break; + } + } + + start = ((ssize_t) hw->pos_emul) - hw->pending_emul; + if (start < 0) { + start += hw->size_emul; + } + assert(start >= 0 && start < hw->size_emul); + + *size = MIN(hw->pending_emul, hw->size_emul - start); + return hw->buf_emul + start; +} + +void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size) +{ + assert(size <= hw->pending_emul); + hw->pending_emul -= size; +} + +void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + if (unlikely(!hw->buf_emul)) { + size_t calc_size = hw->samples << hw->info.shift; + + hw->buf_emul = g_malloc(calc_size); + hw->size_emul = calc_size; + hw->pos_emul = hw->pending_emul = 0; + } + + *size = MIN(hw->size_emul - hw->pending_emul, + hw->size_emul - hw->pos_emul); + return hw->buf_emul + hw->pos_emul; +} + +size_t audio_generic_put_buffer_out_nowrite(HWVoiceOut *hw, void *buf, + size_t size) +{ + assert(buf == hw->buf_emul + hw->pos_emul && + size + hw->pending_emul <= hw->size_emul); + + hw->pending_emul += size; + hw->pos_emul = (hw->pos_emul + size) % hw->size_emul; + + return size; +} + +size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size) +{ + audio_generic_put_buffer_out_nowrite(hw, buf, size); + + while (hw->pending_emul) { + size_t write_len, written; + ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; + if (start < 0) { + start += hw->size_emul; + } + assert(start >= 0 && start < hw->size_emul); + + write_len = MIN(hw->pending_emul, hw->size_emul - start); + + written = hw->pcm_ops->write(hw, hw->buf_emul + start, write_len); + hw->pending_emul -= written; + + if (written < write_len) { + break; + } + } + + /* + * fake we have written everything. non-written data remain in pending_emul, + * so we do not have to clip them multiple times + */ + return size; +} + +size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size) +{ + size_t dst_size, copy_size; + void *dst = hw->pcm_ops->get_buffer_out(hw, &dst_size); + copy_size = MIN(size, dst_size); + + memcpy(dst, buf, copy_size); + return hw->pcm_ops->put_buffer_out(hw, buf, copy_size); +} + +size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size) +{ + size_t dst_size, copy_size; + void *dst = hw->pcm_ops->get_buffer_in(hw, &dst_size); + copy_size = MIN(size, dst_size); + + memcpy(dst, buf, copy_size); + hw->pcm_ops->put_buffer_in(hw, buf, copy_size); + return copy_size; +} + + static int audio_driver_init(AudioState *s, struct audio_driver *drv, Audiodev *dev) { s->drv_opaque = drv->init(dev); if (s->drv_opaque) { + if (!drv->pcm_ops->get_buffer_in) { + drv->pcm_ops->get_buffer_in = audio_generic_get_buffer_in; + drv->pcm_ops->put_buffer_in = audio_generic_put_buffer_in; + } + if (!drv->pcm_ops->get_buffer_out) { + drv->pcm_ops->get_buffer_out = audio_generic_get_buffer_out; + drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out; + } + audio_init_nb_voices_out(s, drv); audio_init_nb_voices_in(s, drv); s->drv = drv; From patchwork Wed Jan 16 23:37:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767215 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B0A521390 for ; Thu, 17 Jan 2019 00:23:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B3F62DD89 for ; Thu, 17 Jan 2019 00:23:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 880602DFD8; Thu, 17 Jan 2019 00:23:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C79FC2DD89 for ; Thu, 17 Jan 2019 00:23:50 +0000 (UTC) Received: from localhost ([127.0.0.1]:42638 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvTJ-0006bd-Kg for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:23:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58344) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul8-0004Q7-Ls for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Qi-6v for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:10 -0500 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:33751) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-00035K-O9 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x42a.google.com with SMTP id c14so9004822wrr.0 for ; Wed, 16 Jan 2019 15:37:51 -0800 (PST) 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=Zx1p6GyzwETtEtCQIgOE0F7QzfqyZMpBgAxXbT1+unQ=; b=eYBjfWDaBdryYcEIYyf+5tOymi6ABGf53JAcfUQrgsI3A7J4ZOTZw0fBFqPJT6X379 WFRTd+iIE/ZPNl9vWKFMYC1L/xh09mn+j+25wT8XR+KSHl7I6ABB0agBflzUkIXbnoOS l97thKq7vBOy3BP4W87MeMsKG9QpL63QcU+rllAk1Gbb42JSErNNNWUi/qOrlVCMohXs FZKDx5g8LvZAwadKxeShBoPEex7Z0CNxw9T2fydnZYv6lgyuGkdRNqayofmzyukwnVx8 ba9JX+fhmcAoDNmyvHnz6mJc58de2y1vZTwn/xACbnJkQ8nf4FCintkEJbfWDXTAgxW2 H/GQ== 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=Zx1p6GyzwETtEtCQIgOE0F7QzfqyZMpBgAxXbT1+unQ=; b=Vd0ifrtTuNXrtAFp5JKnnsBwKvjAJbpUL83zM68bmUfoQDbIu5xbsbmHQQ73BxBusb +M1sMd6GIB3zHvD+wegIn4B5Qy4xHKoIez897tpN1MpCJgD1sfBGMkDsF5Hfu8HHp1zv BQkwgmSd2MYwhfCmYzVgOp81V2+znQVMF52e5WJZkDWpBPj2ARIWXTJoiUmcE+c973XH iws/G0JSLuAw3HN4ys9w0TwYXFGOvGsJDjJVH8pka33NOhTw3oWexaiucTV9p176yKo0 MuyAQSIm4sPAxOm5zxd4qcBt4P/TBoLH13D/MnT3UILlRHgFWKtFUb/2sf+mgsd02ZKa zc6w== X-Gm-Message-State: AJcUukdPNfemorQD0AuswSC35qNHe7BjA7jcRKfs+u3m9oNat6Zi3c7x dqmy7Jnc+Cha4qZ2/Gn6uh/QiZLF6FQ= X-Google-Smtp-Source: ALg8bN4/V/ii4QIg2zugdKAY8X332ATIs/fhYBEJaxPnM/GYbkpzhFLHU7gEIEkaew3qWCJ6NOVIbA== X-Received: by 2002:a5d:6105:: with SMTP id v5mr9216931wrt.63.1547681870211; Wed, 16 Jan 2019 15:37:50 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:49 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:00 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42a Subject: [Qemu-devel] [PATCH v3 27/50] alsaaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/alsaaudio.c | 306 ++++++++++++---------------------------------- 1 file changed, 81 insertions(+), 225 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 6ad2a09d16..c23dedd4bf 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -43,9 +43,6 @@ struct pollhlp { typedef struct ALSAVoiceOut { HWVoiceOut hw; - int wpos; - int pending; - void *pcm_buf; snd_pcm_t *handle; struct pollhlp pollhlp; Audiodev *dev; @@ -54,7 +51,6 @@ typedef struct ALSAVoiceOut { typedef struct ALSAVoiceIn { HWVoiceIn hw; snd_pcm_t *handle; - void *pcm_buf; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceIn; @@ -609,102 +605,62 @@ static int alsa_open(bool in, struct alsa_params_req *req, return -1; } -static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) -{ - snd_pcm_sframes_t avail; - - avail = snd_pcm_avail_update (handle); - if (avail < 0) { - if (avail == -EPIPE) { - if (!alsa_recover (handle)) { - avail = snd_pcm_avail_update (handle); - } - } - - if (avail < 0) { - alsa_logerr (avail, - "Could not obtain number of available frames\n"); - return -1; - } - } - - return avail; -} - -static void alsa_write_pending (ALSAVoiceOut *alsa) -{ - HWVoiceOut *hw = &alsa->hw; - - while (alsa->pending) { - int left_till_end_samples = hw->samples - alsa->wpos; - int len = MIN (alsa->pending, left_till_end_samples); - char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift); - - while (len) { - snd_pcm_sframes_t written; - - written = snd_pcm_writei (alsa->handle, src, len); - - if (written <= 0) { - switch (written) { - case 0: - trace_alsa_wrote_zero(len); - return; - - case -EPIPE: - if (alsa_recover (alsa->handle)) { - alsa_logerr (written, "Failed to write %d frames\n", - len); - return; - } - trace_alsa_xrun_out(); - continue; - - case -ESTRPIPE: - /* stream is suspended and waiting for an - application recovery */ - if (alsa_resume (alsa->handle)) { - alsa_logerr (written, "Failed to write %d frames\n", - len); - return; - } - trace_alsa_resume_out(); - continue; - - case -EAGAIN: - return; - - default: - alsa_logerr (written, "Failed to write %d frames from %p\n", - len, src); - return; - } - } - - alsa->wpos = (alsa->wpos + written) % hw->samples; - alsa->pending -= written; - len -= written; - } - } -} - -static size_t alsa_run_out(HWVoiceOut *hw, size_t live) +static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; - size_t decr; - snd_pcm_sframes_t avail; + size_t pos = 0; + size_t len_frames = len >> hw->info.shift; - avail = alsa_get_avail (alsa->handle); - if (avail < 0) { - dolog ("Could not get number of available playback frames\n"); - return 0; + while (len_frames) { + char *src = advance(buf, pos); + snd_pcm_sframes_t written; + + written = snd_pcm_writei(alsa->handle, src, len_frames); + + if (written <= 0) { + switch (written) { + case 0: + trace_alsa_wrote_zero(len_frames); + return pos; + + case -EPIPE: + if (alsa_recover(alsa->handle)) { + alsa_logerr(written, "Failed to write %zu frames\n", + len_frames); + return pos; + } + trace_alsa_xrun_out(); + continue; + + case -ESTRPIPE: + /* stream is suspended and waiting for an + application recovery */ + if (alsa_resume(alsa->handle)) { + alsa_logerr(written, "Failed to write %zu frames\n", + len_frames); + return pos; + } + trace_alsa_resume_out(); + continue; + + case -EAGAIN: + return pos; + + default: + alsa_logerr(written, "Failed to write %zu frames from %p\n", + len, src); + return pos; + } + } + + pos += written << hw->info.shift; + if (written < len_frames) { + break; + } + len_frames -= written; } - decr = MIN (live, avail); - decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); - alsa->pending += decr; - alsa_write_pending (alsa); - return decr; + return pos; } static void alsa_fini_out (HWVoiceOut *hw) @@ -713,9 +669,6 @@ static void alsa_fini_out (HWVoiceOut *hw) ldebug ("alsa_fini\n"); alsa_anal_close (&alsa->handle, &alsa->pollhlp); - - g_free(alsa->pcm_buf); - alsa->pcm_buf = NULL; } static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, @@ -744,14 +697,6 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; - alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift); - if (!alsa->pcm_buf) { - dolog("Could not allocate DAC buffer (%zu samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); - alsa_anal_close1 (&handle); - return -1; - } - alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev; @@ -846,14 +791,6 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; - alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); - if (!alsa->pcm_buf) { - dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); - alsa_anal_close1 (&handle); - return -1; - } - alsa->pollhlp.s = hw->s; alsa->handle = handle; alsa->dev = dev; @@ -865,129 +802,48 @@ static void alsa_fini_in (HWVoiceIn *hw) ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; alsa_anal_close (&alsa->handle, &alsa->pollhlp); - - g_free(alsa->pcm_buf); - alsa->pcm_buf = NULL; } -static size_t alsa_run_in(HWVoiceIn *hw) +static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; - int hwshift = hw->info.shift; - int i; - size_t live = audio_pcm_hw_get_live_in (hw); - size_t dead = hw->samples - live; - size_t decr; - struct { - size_t add; - size_t len; - } bufs[2] = { - { .add = hw->wpos, .len = 0 }, - { .add = 0, .len = 0 } - }; - snd_pcm_sframes_t avail; - snd_pcm_uframes_t read_samples = 0; + size_t pos = 0; - if (!dead) { - return 0; - } - - avail = alsa_get_avail (alsa->handle); - if (avail < 0) { - dolog ("Could not get number of captured frames\n"); - return 0; - } - - if (!avail) { - snd_pcm_state_t state; - - state = snd_pcm_state (alsa->handle); - switch (state) { - case SND_PCM_STATE_PREPARED: - avail = hw->samples; - break; - case SND_PCM_STATE_SUSPENDED: - /* stream is suspended and waiting for an application recovery */ - if (alsa_resume (alsa->handle)) { - dolog ("Failed to resume suspended input stream\n"); - return 0; - } - trace_alsa_resume_in(); - break; - default: - trace_alsa_no_frames(state); - return 0; - } - } - - decr = MIN(dead, avail); - if (!decr) { - return 0; - } - - if (hw->wpos + decr > hw->samples) { - bufs[0].len = (hw->samples - hw->wpos); - bufs[1].len = (decr - (hw->samples - hw->wpos)); - } - else { - bufs[0].len = decr; - } - - for (i = 0; i < 2; ++i) { - void *src; - struct st_sample *dst; + while (len) { + void *dst = advance(buf, pos); snd_pcm_sframes_t nread; - snd_pcm_uframes_t len; - len = bufs[i].len; + nread = snd_pcm_readi(alsa->handle, dst, len >> hw->info.shift); - src = advance (alsa->pcm_buf, bufs[i].add << hwshift); - dst = hw->conv_buf + bufs[i].add; + if (nread <= 0) { + switch (nread) { + case 0: + trace_alsa_read_zero(len); + return pos;; - while (len) { - nread = snd_pcm_readi (alsa->handle, src, len); - - if (nread <= 0) { - switch (nread) { - case 0: - trace_alsa_read_zero(len); - goto exit; - - case -EPIPE: - if (alsa_recover (alsa->handle)) { - alsa_logerr (nread, "Failed to read %ld frames\n", len); - goto exit; - } - trace_alsa_xrun_in(); - continue; - - case -EAGAIN: - goto exit; - - default: - alsa_logerr ( - nread, - "Failed to read %ld frames from %p\n", - len, - src - ); - goto exit; + case -EPIPE: + if (alsa_recover(alsa->handle)) { + alsa_logerr(nread, "Failed to read %zu frames\n", len); + return pos; } + trace_alsa_xrun_in(); + continue; + + case -EAGAIN: + return pos; + + default: + alsa_logerr(nread, "Failed to read %zu frames to %p\n", + len, dst); + return pos;; } - - hw->conv (dst, src, nread); - - src = advance (src, nread << hwshift); - dst += nread; - - read_samples += nread; - len -= nread; } + + pos += nread << hw->info.shift; + len -= nread << hw->info.shift; } - exit: - hw->wpos = (hw->wpos + read_samples) % hw->samples; - return read_samples; + return pos; } static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) @@ -1077,12 +933,12 @@ static void alsa_audio_fini (void *opaque) static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, - .run_out = alsa_run_out, + .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, - .run_in = alsa_run_in, + .read = alsa_read, .ctl_in = alsa_ctl_in, }; From patchwork Wed Jan 16 23:37:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767147 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 00CE56C2 for ; Wed, 16 Jan 2019 23:51:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E3E092F5DF for ; Wed, 16 Jan 2019 23:51:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E1F132FC13; Wed, 16 Jan 2019 23:51:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 38B422F5DF for ; Wed, 16 Jan 2019 23:51:51 +0000 (UTC) Received: from localhost ([127.0.0.1]:34710 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjuyM-00072w-Ev for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:51:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul3-0004M2-BB for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukx-0003GA-WC for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:01 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:36102) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjuku-00036U-1Z for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:57 -0500 Received: by mail-wr1-x442.google.com with SMTP id u4so8967667wrp.3 for ; Wed, 16 Jan 2019 15:37:52 -0800 (PST) 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=GKC4rdOIBB1pc4GkZxpNaZxDUvN/m8N0JZIr8gTmDkk=; b=UMagP2WABuRf0+g9UIzbW54Jk7n/90EQYsfzmEnoinDY8OhbdOSul6Ki00Zk0ODvak 7u4Oj5lExgOKFfGanv1t0RluEI7TreQrLxs3v3RvVO3/lBNVutM+iOJvn++73MDCeYpB WYCNL8RxP4c7NdokJ6L/9ZSj7oF4PdPQh3X6eo17Q1FzXxO32gpLtGXgQMNgxVkHnlDJ Gts2zsd360pGAGTR63lw0KJ/K9wA/E5KMmwNzeH5WzYYLhn/G/5eodZ3yLiD3xE4Mk55 vicnRMbqW3pWZx0x8dCP6Hh4Z3DlD/HuXMXDoAm/OCgise4nPsV6xC3BIZMT9p0J8ean gEwQ== 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=GKC4rdOIBB1pc4GkZxpNaZxDUvN/m8N0JZIr8gTmDkk=; b=Y9r1q41PNH4zyA0olmKnZGLHgqUv3uY5T3GQXQUSz2uaAuVdB4Z/hAfeGeejDh8BQD VqYKTyxBsLjnbtC0POPnMB1p6ir7eVClSkH1/lz1o7H7MIHqojFWV3S8QxmBLAKyXp8x Y5RLP2fx03yJhGUnbQnvyH5wF3SgLxJ4I7UFQ7U2eOsZeiG7xA7wAUv8XNw4PEfpz17z TKneBS1OeQXJNGagov22jL8RGyz8uHNc2G2mtkcSopoD7QZooJq1Lhw1MEfdmweOBfLP DN01GkZVQJRk0+n4r/DgbuaM+u3Wr/9dfFlQBScXjKaPh5H0EUpDIHU0tkTdVKaaFTky gMsQ== X-Gm-Message-State: AJcUukczmsY5jxsrevKqDRngkEQHw67We45iIYgZ3X/gzzLPPZFGqz8b 4FHiuEH/m7Sx1VQwnToBx2y7NB2tRy8= X-Google-Smtp-Source: ALg8bN4a55kR4YagYRf1rsScaVkojxUrSho84jRrvpFslfFQzCSlacFQmEAJfLm84jaAxpcuhsUVaw== X-Received: by 2002:adf:9361:: with SMTP id 88mr9222316wro.204.1547681871178; Wed, 16 Jan 2019 15:37:51 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:50 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:01 +0100 Message-Id: <49e0438fd738f019fa5b96941afe40ff247b132e.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v3 28/50] coreaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/coreaudio.c | 130 ++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 61 deletions(-) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 646aea06a0..e32c5b62fd 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -43,9 +43,6 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; - size_t live; - size_t decr; - size_t rpos; } coreaudioVoiceOut; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 @@ -397,31 +394,29 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name) return 0; } -static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live) -{ - size_t decr; - coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; - - if (coreaudio_lock (core, "coreaudio_run_out")) { - return 0; +#define COREAUDIO_WRAPPER_FUNC(name, ret_type, args_decl, args) \ + static ret_type glue(coreaudio_, name)args_decl \ + { \ + coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; \ + ret_type ret; \ + \ + if (coreaudio_lock(core, "coreaudio_" #name)) { \ + return 0; \ + } \ + \ + ret = glue(audio_generic_, name)args; \ + \ + coreaudio_unlock(core, "coreaudio_" #name); \ + return ret; \ } - - if (core->decr > live) { - ldebug ("core->decr %d live %d core->live %d\n", - core->decr, - live, - core->live); - } - - decr = MIN (core->decr, live); - core->decr -= decr; - - core->live = live - decr; - hw->rpos = core->rpos; - - coreaudio_unlock (core, "coreaudio_run_out"); - return decr; -} +COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size), + (hw, size)) +COREAUDIO_WRAPPER_FUNC(put_buffer_out_nowrite, size_t, + (HWVoiceOut *hw, void *buf, size_t size), + (hw, buf, size)) +COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size), + (hw, buf, size)) +#undef COREAUDIO_WRAPPER_FUNC /* callback to feed audiooutput buffer */ static OSStatus audioDeviceIOProc( @@ -433,19 +428,11 @@ static OSStatus audioDeviceIOProc( const AudioTimeStamp* inOutputTime, void* hwptr) { - UInt32 frame, frameCount; - float *out = outOutputData->mBuffers[0].mData; + UInt32 frameCount, pending_frames; + void *out = outOutputData->mBuffers[0].mData; HWVoiceOut *hw = hwptr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr; - int rpos, live; - struct st_sample *src; -#ifndef FLOAT_MIXENG -#ifdef RECIPROCAL - const float scale = 1.f / UINT_MAX; -#else - const float scale = UINT_MAX; -#endif -#endif + size_t len; if (coreaudio_lock (core, "audioDeviceIOProc")) { inInputTime = 0; @@ -453,42 +440,51 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; - live = core->live; + pending_frames = hw->pending_emul >> hw->info.shift; /* if there are not enough samples, set signal and return */ - if (live < frameCount) { + if (pending_frames < frameCount) { inInputTime = 0; coreaudio_unlock (core, "audioDeviceIOProc(empty)"); return 0; } - rpos = core->rpos; - src = hw->mix_buf + rpos; + len = frameCount << hw->info.shift; + while (len) { + size_t write_len; + ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; + if (start < 0) { + start += hw->size_emul; + } + assert(start >= 0 && start < hw->size_emul); - /* fill buffer */ - for (frame = 0; frame < frameCount; frame++) { -#ifdef FLOAT_MIXENG - *out++ = src[frame].l; /* left channel */ - *out++ = src[frame].r; /* right channel */ -#else -#ifdef RECIPROCAL - *out++ = src[frame].l * scale; /* left channel */ - *out++ = src[frame].r * scale; /* right channel */ -#else - *out++ = src[frame].l / scale; /* left channel */ - *out++ = src[frame].r / scale; /* right channel */ -#endif -#endif + write_len = MIN(MIN(hw->pending_emul, len), + hw->size_emul - start); + + memcpy(out, hw->buf_emul + start, write_len); + hw->pending_emul -= write_len; + len -= write_len; + out += write_len; } - rpos = (rpos + frameCount) % hw->samples; - core->decr += frameCount; - core->rpos = rpos; - coreaudio_unlock (core, "audioDeviceIOProc"); return 0; } +static UInt32 coreaudio_get_flags(struct audio_pcm_info *info, + struct audsettings *as) +{ + UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0; + if (as->endianness) { /* 0 = little, 1 = big */ + flags |= kAudioFormatFlagIsBigEndian; + } + + if (flags == 0) { /* must not be 0 */ + flags = kAudioFormatFlagsAreAllClear; + } + return flags; +} + static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { @@ -576,6 +572,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; + core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; + core->outputStreamBasicDescription.mFormatFlags = + coreaudio_get_flags(&hw->info, as); + core->outputStreamBasicDescription.mBytesPerPacket = + core->outputStreamBasicDescription.mBytesPerFrame = + hw->info.nchannels * hw->info.bits / 8; + core->outputStreamBasicDescription.mFramesPerPacket = 1; + core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels; + core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits; + status = coreaudio_set_streamformat(core->outputDeviceID, &core->outputStreamBasicDescription); if (status != kAudioHardwareNoError) { @@ -686,7 +692,9 @@ static void coreaudio_audio_fini (void *opaque) static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, - .run_out = coreaudio_run_out, + .write = coreaudio_write, + .get_buffer_out = coreaudio_get_buffer_out, + .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out }; From patchwork Wed Jan 16 23:37:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767191 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB4F01390 for ; Thu, 17 Jan 2019 00:10:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9BE2A2FB18 for ; Thu, 17 Jan 2019 00:10:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99D1D2FB2F; Thu, 17 Jan 2019 00:10:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 78C8A2FB19 for ; Thu, 17 Jan 2019 00:10:46 +0000 (UTC) Received: from localhost ([127.0.0.1]:39277 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvGf-0004xZ-OH for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:10:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58400) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004RD-MM for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003SC-Jd for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:38423) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-00037m-4a for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wm1-x344.google.com with SMTP id m22so3886383wml.3 for ; Wed, 16 Jan 2019 15:37:53 -0800 (PST) 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=XZQ1GQhoUXNlNiPpV6Uv7XqMhwV2NT+KcC7NV/DPmNc=; b=t8XY3YpWwuCzu01whSGTrNQ2ZdbhQajRVtz9N1pL+P9A5/3IBaeYQ53np+g+KRDSr1 tJMh2uY0thtB+nk8E5W3yP1ZESxxlOWl/l74juPA/+CbNwQysJBbKs4QEBCRpL3pLZJB mKHYzDIBaGUwKp/ZkHisnUWr5506yUTS/s5M5Zkv8N7H4gIi97ytfuBpi25OmVtQKm23 qdPWUzVDmPnlEEUvy8/DqD+wTnCJa6dbeSKZBkTvqDfX4l3PG5HmEHevHZb/hnmHjEgc xGMEh17iZNAuj2nFqN4j/QoNhHAu5WZAzrc+nKp16PBYAJoBnd+eQr+M1RabZ6DeYB3Z BeRA== 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=XZQ1GQhoUXNlNiPpV6Uv7XqMhwV2NT+KcC7NV/DPmNc=; b=PdGxlHUNnMsfERtG2yA8RzPqbWet4eBuATL+ELXqBQClcHQVO58WMS6Vw1/J/ueXQn 4aHbjAxF/59725XPKyvpS+IBeCZi3MzDYCJKAHp5v9sAZAZSWoFLwfvfBiJb0WQOwMUc t7waSvieOXgJp+yvQIlOepVKLTjlpD6a2bU78YFr7kMmawPQa3+MQWWfTFx3hGBMDCgG 1GewVtPvQMV6b2ZqpSucGlvNeeBHSvfz1/aU9n4xP3QcPMS1lQyLcEQFygklNfTkplaB 9EOtgDYZFyEWTr6vXqRC5e2gbKNfH+1nl5sad/mYYO6kpfb38TbFYGONFDTDznv3MzLa pnsA== X-Gm-Message-State: AJcUuke8oOJwtfould2aDzVYJQhX9/4t0lPXOUA0yUpBXoTZBSg/+TW8 e1t3JFajnr+rjt235ZJiaQ368jvYmtw= X-Google-Smtp-Source: ALg8bN4FylmyRvUwcN8h41DTFzm+C9Kny4Enhtv7VqVIN5JdqAoMfx8NyhHzUr/1gemimgE8zirkFw== X-Received: by 2002:a1c:f916:: with SMTP id x22mr9766876wmh.87.1547681872047; Wed, 16 Jan 2019 15:37:52 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:51 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:02 +0100 Message-Id: <2c553c7af6354961d100d7be7f8ea221cfdad243.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v3 29/50] dsoundaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/dsound_template.h | 45 +++--- audio/dsoundaudio.c | 329 ++++++++++------------------------------ 2 files changed, 102 insertions(+), 272 deletions(-) diff --git a/audio/dsound_template.h b/audio/dsound_template.h index 96181efb36..ff5a1f85fd 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -29,6 +29,8 @@ #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER #define FIELD dsound_capture_buffer #define FIELD2 dsound_capture +#define HWVOICE HWVoiceIn +#define DSOUNDVOICE DSoundVoiceIn #else #define NAME "playback buffer" #define NAME2 "DirectSound" @@ -37,6 +39,8 @@ #define BUFPTR LPDIRECTSOUNDBUFFER #define FIELD dsound_buffer #define FIELD2 dsound +#define HWVOICE HWVoiceOut +#define DSOUNDVOICE DSoundVoiceOut #endif static int glue (dsound_unlock_, TYPE) ( @@ -72,8 +76,6 @@ static int glue (dsound_lock_, TYPE) ( ) { HRESULT hr; - LPVOID p1 = NULL, p2 = NULL; - DWORD blen1 = 0, blen2 = 0; DWORD flag; #ifdef DSBTYPE_IN @@ -81,7 +83,7 @@ static int glue (dsound_lock_, TYPE) ( #else flag = entire ? DSBLOCK_ENTIREBUFFER : 0; #endif - hr = glue(IFACE, _Lock)(buf, pos, len, &p1, &blen1, &p2, &blen2, flag); + hr = glue(IFACE, _Lock)(buf, pos, len, p1p, blen1p, p2p, blen2p, flag); if (FAILED (hr)) { #ifndef DSBTYPE_IN @@ -96,34 +98,34 @@ static int glue (dsound_lock_, TYPE) ( goto fail; } - if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) { + if ((p1p && *p1p && (*blen1p & info->align)) || + (p2p && *p2p && (*blen2p & info->align))) { dolog ("DirectSound returned misaligned buffer %ld %ld\n", - blen1, blen2); - glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2); + *blen1p, *blen2p); + glue (dsound_unlock_, TYPE) (buf, *p1p, p2p ? *p2p : NULL, *blen1p, + blen2p ? *blen2p : 0); goto fail; } - if (!p1 && blen1) { - dolog ("warning: !p1 && blen1=%ld\n", blen1); - blen1 = 0; + if (p1p && !*p1p && *blen1p) { + dolog("warning: !p1 && blen1=%ld\n", *blen1p); + *blen1p = 0; } - if (!p2 && blen2) { - dolog ("warning: !p2 && blen2=%ld\n", blen2); - blen2 = 0; + if (p2p && !*p2p && *blen2p) { + dolog("warning: !p2 && blen2=%ld\n", *blen2p); + *blen2p = 0; } - *p1p = p1; - *p2p = p2; - *blen1p = blen1; - *blen2p = blen2; return 0; fail: *p1p = NULL - 1; - *p2p = NULL - 1; *blen1p = -1; - *blen2p = -1; + if (p2p) { + *p2p = NULL - 1; + *blen2p = -1; + } return -1; } @@ -242,7 +244,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, goto fail0; } - ds->first_time = 1; obt_as.endianness = 0; audio_pcm_init_info (&hw->info, &obt_as); @@ -252,15 +253,13 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, bc.dwBufferBytes, hw->info.align + 1 ); } + hw->size_emul = bc.dwBufferBytes; hw->samples = bc.dwBufferBytes >> hw->info.shift; ds->s = s; #ifdef DEBUG_DSOUND dolog ("caps %ld, desc %ld\n", bc.dwBufferBytes, bd.dwBufferBytes); - - dolog ("bufsize %d, freq %d, chan %d, fmt %d\n", - hw->bufsize, settings.freq, settings.nchannels, settings.fmt); #endif return 0; @@ -276,3 +275,5 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, #undef BUFPTR #undef FIELD #undef FIELD2 +#undef HWVOICE +#undef DSOUNDVOICE diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index 906cca3235..951152ecea 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -53,19 +53,11 @@ typedef struct { typedef struct { HWVoiceOut hw; LPDIRECTSOUNDBUFFER dsound_buffer; - DWORD old_pos; - int first_time; dsound *s; -#ifdef DEBUG_DSOUND - DWORD old_ppos; - DWORD played; - DWORD mixed; -#endif } DSoundVoiceOut; typedef struct { HWVoiceIn hw; - int first_time; LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer; dsound *s; } DSoundVoiceIn; @@ -243,11 +235,6 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 ( dsound_log_hresult (hr); } -static uint64_t usecs_to_bytes(struct audio_pcm_info *info, uint32_t usecs) -{ - return muldiv64(usecs, info->bytes_per_second, 1000000); -} - #ifdef DEBUG_DSOUND static void print_wave_format (WAVEFORMATEX *wfx) { @@ -312,33 +299,6 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb, return 0; } -static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len) -{ - int src_len1 = dst_len; - int src_len2 = 0; - int pos = hw->rpos + dst_len; - struct st_sample *src1 = hw->mix_buf + hw->rpos; - struct st_sample *src2 = NULL; - - if (pos > hw->samples) { - src_len1 = hw->samples - hw->rpos; - src2 = hw->mix_buf; - src_len2 = dst_len - src_len1; - pos = src_len2; - } - - if (src_len1) { - hw->clip (dst, src1, src_len1); - } - - if (src_len2) { - dst = advance (dst, src_len1 << hw->info.shift); - hw->clip (dst, src2, src_len2); - } - - hw->rpos = pos % hw->samples; -} - static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb, dsound *s) { @@ -350,7 +310,7 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb, dsb, &hw->info, 0, - hw->samples << hw->info.shift, + hw->size_emul, &p1, &p2, &blen1, &blen2, 1, @@ -454,139 +414,51 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static size_t dsound_run_out(HWVoiceOut *hw, size_t live) +static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size) { - int err; + DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; + LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; HRESULT hr; + DWORD ppos, act_size; + size_t req_size; + int err; + void *ret; + + hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL); + if (FAILED(hr)) { + dsound_logerr(hr, "Could not get playback buffer position\n"); + *size = 0; + return NULL; + } + + req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul); + req_size = MIN(req_size, hw->size_emul - hw->pos_emul); + + err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL, + &act_size, NULL, false, ds->s); + if (err) { + dolog("Failed to lock buffer\n"); + *size = 0; + return NULL; + } + + *size = act_size; + return ret; +} + +static size_t dsound_put_buffer_out(HWVoiceOut *hw, void *buf, size_t len) +{ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; - size_t len; - int hwshift; - DWORD blen1, blen2; - DWORD len1, len2; - DWORD decr; - DWORD wpos, ppos, old_pos; - LPVOID p1, p2; - size_t bufsize; - dsound *s = ds->s; - AudiodevDsoundOptions *dso = &s->dev->u.dsound; + int err = dsound_unlock_out(dsb, buf, NULL, len, 0); - if (!dsb) { - dolog ("Attempt to run empty with playback buffer\n"); - return 0; - } - - hwshift = hw->info.shift; - bufsize = hw->samples << hwshift; - - hr = IDirectSoundBuffer_GetCurrentPosition ( - dsb, - &ppos, - ds->first_time ? &wpos : NULL - ); - if (FAILED (hr)) { - dsound_logerr (hr, "Could not get playback buffer position\n"); - return 0; - } - - len = live << hwshift; - - if (ds->first_time) { - if (dso->latency) { - DWORD cur_blat; - - cur_blat = audio_ring_dist (wpos, ppos, bufsize); - ds->first_time = 0; - old_pos = wpos; - old_pos += - usecs_to_bytes(&hw->info, dso->latency) - cur_blat; - old_pos %= bufsize; - old_pos &= ~hw->info.align; - } - else { - old_pos = wpos; - } -#ifdef DEBUG_DSOUND - ds->played = 0; - ds->mixed = 0; -#endif - } - else { - if (ds->old_pos == ppos) { -#ifdef DEBUG_DSOUND - dolog ("old_pos == ppos\n"); -#endif - return 0; - } - -#ifdef DEBUG_DSOUND - ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize); -#endif - old_pos = ds->old_pos; - } - - if ((old_pos < ppos) && ((old_pos + len) > ppos)) { - len = ppos - old_pos; - } - else { - if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) { - len = bufsize - old_pos + ppos; - } - } - - if (audio_bug(__func__, len < 0 || len > bufsize)) { - dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n", - len, bufsize, old_pos, ppos); - return 0; - } - - len &= ~hw->info.align; - if (!len) { - return 0; - } - -#ifdef DEBUG_DSOUND - ds->old_ppos = ppos; -#endif - err = dsound_lock_out ( - dsb, - &hw->info, - old_pos, - len, - &p1, &p2, - &blen1, &blen2, - 0, - s - ); if (err) { + dolog("Failed to unlock buffer!!\n"); return 0; } + hw->pos_emul = (hw->pos_emul + len) % hw->size_emul; - len1 = blen1 >> hwshift; - len2 = blen2 >> hwshift; - decr = len1 + len2; - - if (p1 && len1) { - dsound_write_sample (hw, p1, len1); - } - - if (p2 && len2) { - dsound_write_sample (hw, p2, len2); - } - - dsound_unlock_out (dsb, p1, p2, blen1, blen2); - ds->old_pos = (old_pos + (decr << hwshift)) % bufsize; - -#ifdef DEBUG_DSOUND - ds->mixed += decr << hwshift; - - dolog ("played %lu mixed %lu diff %ld sec %f\n", - ds->played, - ds->mixed, - ds->mixed - ds->played, - abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second); -#endif - return decr; + return len; } static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) @@ -641,96 +513,49 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static size_t dsound_run_in(HWVoiceIn *hw) +static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) { - int err; + DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; + LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; HRESULT hr; + DWORD cpos, act_size; + size_t req_size; + int err; + void *ret; +n + hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL); + if (FAILED(hr)) { + dsound_logerr(hr, "Could not get capture buffer position\n"); + *size = 0; + return NULL; + } + + req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul); + req_size = MIN(req_size, hw->size_emul - hw->pos_emul); + + err = dsound_lock_in(dscb, &hw->info, hw->pos_emul, req_size, &ret, NULL, + &act_size, NULL, false, ds->s); + if (err) { + dolog("Failed to lock buffer\n"); + *size = 0; + return NULL; + } + + *size = act_size; + return ret; +} + +static void dsound_put_buffer_in(HWVoiceIn *hw, void *buf, size_t len) +{ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; - size_t live, len, dead; - DWORD blen1, blen2; - DWORD len1, len2; - DWORD decr; - DWORD cpos, rpos; - LPVOID p1, p2; - int hwshift; - dsound *s = ds->s; + int err = dsound_unlock_in(dscb, buf, NULL, len, 0); - if (!dscb) { - dolog ("Attempt to run without capture buffer\n"); - return 0; - } - - hwshift = hw->info.shift; - - live = audio_pcm_hw_get_live_in (hw); - dead = hw->samples - live; - if (!dead) { - return 0; - } - - hr = IDirectSoundCaptureBuffer_GetCurrentPosition ( - dscb, - &cpos, - ds->first_time ? &rpos : NULL - ); - if (FAILED (hr)) { - dsound_logerr (hr, "Could not get capture buffer position\n"); - return 0; - } - - if (ds->first_time) { - ds->first_time = 0; - if (rpos & hw->info.align) { - ldebug ("warning: Misaligned capture read position %ld(%d)\n", - rpos, hw->info.align); - } - hw->wpos = rpos >> hwshift; - } - - if (cpos & hw->info.align) { - ldebug ("warning: Misaligned capture position %ld(%d)\n", - cpos, hw->info.align); - } - cpos >>= hwshift; - - len = audio_ring_dist (cpos, hw->wpos, hw->samples); - if (!len) { - return 0; - } - len = MIN (len, dead); - - err = dsound_lock_in ( - dscb, - &hw->info, - hw->wpos << hwshift, - len << hwshift, - &p1, - &p2, - &blen1, - &blen2, - 0, - s - ); if (err) { - return 0; + dolog("Failed to unlock buffer!!\n"); + return; } - - len1 = blen1 >> hwshift; - len2 = blen2 >> hwshift; - decr = len1 + len2; - - if (p1 && len1) { - hw->conv (hw->conv_buf + hw->wpos, p1, len1); - } - - if (p2 && len2) { - hw->conv (hw->conv_buf, p2, len2); - } - - dsound_unlock_in (dscb, p1, p2, blen1, blen2); - hw->wpos = (hw->wpos + decr) % hw->samples; - return decr; + hw->pos_emul = (hw->pos_emul + len) % hw->size_emul; } static void dsound_audio_fini (void *opaque) @@ -846,12 +671,16 @@ static void *dsound_audio_init(Audiodev *dev) static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, - .run_out = dsound_run_out, + .write = audio_generic_write, + .get_buffer_out = dsound_get_buffer_out, + .put_buffer_out = dsound_put_buffer_out, .ctl_out = dsound_ctl_out, .init_in = dsound_init_in, .fini_in = dsound_fini_in, - .run_in = dsound_run_in, + .read = audio_generic_read, + .get_buffer_in = dsound_get_buffer_in, + .put_buffer_in = dsound_put_buffer_in, .ctl_in = dsound_ctl_in }; From patchwork Wed Jan 16 23:37:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767171 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 34E1A6C2 for ; Thu, 17 Jan 2019 00:01:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2600F2FC35 for ; Thu, 17 Jan 2019 00:01:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 241612FCBC; Thu, 17 Jan 2019 00:01:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9EFF62FCBC for ; Thu, 17 Jan 2019 00:01:49 +0000 (UTC) Received: from localhost ([127.0.0.1]:37070 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv80-0006Lu-OL for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:01:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58125) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjukz-0004IF-KA for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukv-0003DO-TY for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:59 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:33800) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukt-000388-Nb for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:56 -0500 Received: by mail-wr1-x444.google.com with SMTP id j2so9012949wrw.1 for ; Wed, 16 Jan 2019 15:37:53 -0800 (PST) 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=N+A2xH2hiqjAiUAulU3GcZpOwJkdZbBvxfkx4/ncV6I=; b=p4DC2PRmikouid9NHRD8/cur8aClFXuKkTv7HQtUmlOtvXwhYQ45JFehVzDd4TbgFO 6QuulUzhVkyRW0yU5yN0kg3FFgOb8pXlPFaxulZpVeMvdpugX12DxUb/MaC+opaHlD61 UA8Jnde8+WcWZtT9sSa+KZrl22mOk/MXiDwTmoV+o86S/6Aj3u89aOxQQbKPXz8ZqXmq OX6GP0AEG4ksuiO6SbUGGj16s0k+HQhFeJQrX3G3nkvzb0RIhdz4sNRtyzYzP26ds8ZE 2uPyJl8kyp6mKQP/ImAOfmIWIdcUCAV+FGleMaF0l5ouYC6HLKLc6SZrqMJQOBnZxRZX i03w== 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=N+A2xH2hiqjAiUAulU3GcZpOwJkdZbBvxfkx4/ncV6I=; b=SGEpsdAS44IaOkyltByeZzzqAzFZRQXli+9RwI7mn+86ck1b7vkjBdIXC2kM1oUmZR JXTqk8/Txxcndyv02c7pZZCuvOoRbEIMKAqfbCm4lh6fvPQntysoo+G/T0fbfZW5vyfG 8V+58K/NLDyzIABIV3XVczXY4mZ4MitwLyiqV1XZOMn7NxOGLVI/jVOIvEcKOGLyBDkG 1wv3kN8NB7Yf6K/IwvHhSuNL+c0wzMnVDP1OhFrpfN+cXcPwkBtBnG6xvTQAItTnFR5H 7G3jGpIC2gcuBAh1yzPR9f00GAGHlO2yNGM7btXR++uSDehVZGxnLMHpMlWptKXJY9W+ OeTA== X-Gm-Message-State: AJcUukeEWBYNyGkHaAMaym11UPtwK0ySccswJNxgFPBIc/xuBGFmoRms 0ZctXdJ1lOs28H3tokxv+RgO6weoAlk= X-Google-Smtp-Source: ALg8bN6dkFmbvhLF58Nnu7sJM079vaFDGohS1NN0DRz5krMKJ8QvhZu74CfdEufLdzn5mmLWdfac3w== X-Received: by 2002:adf:8228:: with SMTP id 37mr9232213wrb.160.1547681872722; Wed, 16 Jan 2019 15:37:52 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:52 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:03 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 30/50] noaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/noaudio.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/audio/noaudio.c b/audio/noaudio.c index 59e680db6f..647558f54c 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -40,10 +40,9 @@ typedef struct NoVoiceIn { int64_t old_ticks; } NoVoiceIn; -static size_t no_run_out(HWVoiceOut *hw, size_t live) +static size_t no_write(HWVoiceOut *hw, void *buf, size_t len) { NoVoiceOut *no = (NoVoiceOut *) hw; - size_t decr, samples; int64_t now; int64_t ticks; int64_t bytes; @@ -51,13 +50,9 @@ static size_t no_run_out(HWVoiceOut *hw, size_t live) now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - no->old_ticks; bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - bytes = MIN(bytes, SIZE_MAX); - samples = bytes >> hw->info.shift; no->old_ticks = now; - decr = MIN (live, samples); - hw->rpos = (hw->rpos + decr) % hw->samples; - return decr; + return MIN(len, bytes); } static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) @@ -91,25 +86,21 @@ static void no_fini_in (HWVoiceIn *hw) (void) hw; } -static size_t no_run_in(HWVoiceIn *hw) +static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) { + size_t to_clear; NoVoiceIn *no = (NoVoiceIn *) hw; - size_t live = audio_pcm_hw_get_live_in(hw); - size_t dead = hw->samples - live; - size_t samples = 0; - if (dead) { - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - int64_t ticks = now - no->old_ticks; - int64_t bytes = - muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + int64_t ticks = now - no->old_ticks; + int64_t bytes = + muldiv64 (ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - no->old_ticks = now; - bytes = MIN (bytes, SIZE_MAX); - samples = bytes >> hw->info.shift; - samples = MIN (samples, dead); - } - return samples; + no->old_ticks = now; + to_clear = MIN(bytes, size); + + audio_pcm_info_clear_buf(&hw->info, buf, to_clear >> hw->info.shift); + return to_clear; } static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) @@ -132,12 +123,12 @@ static void no_audio_fini (void *opaque) static struct audio_pcm_ops no_pcm_ops = { .init_out = no_init_out, .fini_out = no_fini_out, - .run_out = no_run_out, + .write = no_write, .ctl_out = no_ctl_out, .init_in = no_init_in, .fini_in = no_fini_in, - .run_in = no_run_in, + .read = no_read, .ctl_in = no_ctl_in }; From patchwork Wed Jan 16 23:37:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767173 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 257A291E for ; Thu, 17 Jan 2019 00:02:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 139962FCEA for ; Thu, 17 Jan 2019 00:02:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1104C2FD0F; Thu, 17 Jan 2019 00:02:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2C16B2FCEA for ; Thu, 17 Jan 2019 00:02:15 +0000 (UTC) Received: from localhost ([127.0.0.1]:37163 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv8Q-0006eS-Ag for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:02:14 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004RG-Nr for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Sz-Qn for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:32773) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-00039l-EV for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x444.google.com with SMTP id c14so9004925wrr.0 for ; Wed, 16 Jan 2019 15:37:54 -0800 (PST) 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=Mcju0fxZG2CfmaqB9Sb0ZdZGxm957N2Vwz/TnTv2mas=; b=q/7bcYuv6GDFauOz6KmyLoOT9y8WL8zSOKUPbM3fC7lnE2TPjdoMZ5R8rPwluKU42C DQga4DpfmETyktPWWk3GqnOMhKJdB9P2VDnzLSWpV7LzQGWfYnrsn4yEZ0n0mrhrDC2/ gArhtSF6o0mmwNc4JNsrOHXyiagmcz02XMbBxu9PlBN3NdoLP/Ao31AzkKXriZyO7qJg 0JhnRtomfYi8o0kotk0mrQ0pYU2xfEQK7bcEo3olKBope5T29TyWP0pyZ26sYMhYaqFN oOeSdaU4BHErASqCLzWIjPSYddSCSTq7KZ2Igl4a2NtQaiBQvP22SbK85WTQtIsnwCHo xs/w== 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=Mcju0fxZG2CfmaqB9Sb0ZdZGxm957N2Vwz/TnTv2mas=; b=tvcO2r0h/bxuNRdOWwypQ1eb3jWOh3oJ+KydmyLWvqyNWvw+YRGnsXHIAgZoDprBVD C/rr6WKmfGqju7naSs9j3loXXRr3No1IsZMDi8DpApyYe1nSrMXw9pRFAT5Mz2qCJTsp mlaWTkWiRRPYoce8Va5NdMFunWYWsRob2g5RJPOEHDaDCXtWiL+KPHqzpOzZvvwbJagN 3Pj5e0TCFmGLBWGcIvkNZ6pXa2KCYvHaIsMH4u6sOYAZPkHAYF9ohtwQp5P9+cTSAWSV QC/Nn1sssIVItBikUfU83Nfxwz4Zs9AcGZ2stQBTSy12+jzzyqDtSDLlqZXTPjcBKUX1 B7Gg== X-Gm-Message-State: AJcUuke1aDeZhwmUcpMZvMH+1zqmQ2mn0rVXVwTKvgQGC9XvqTFKS9x6 nzjqGFoRsqTZB5dxax+vPkzt+O2FIos= X-Google-Smtp-Source: ALg8bN7zrcBOHNer4k1q6qiYsRUsQj0s9RqaXSSv2W6uKt1/D/gY0cQw5ihJvnWiO10rtPbAOkOneA== X-Received: by 2002:adf:8421:: with SMTP id 30mr9754172wrf.153.1547681873496; Wed, 16 Jan 2019 15:37:53 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:53 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:04 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v3 31/50] ossaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/ossaudio.c | 288 +++++++++++++++++------------------------------ 1 file changed, 104 insertions(+), 184 deletions(-) diff --git a/audio/ossaudio.c b/audio/ossaudio.c index c6d4086573..774a41fbf9 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -39,19 +39,15 @@ typedef struct OSSVoiceOut { HWVoiceOut hw; - void *pcm_buf; int fd; - int wpos; int nfrags; int fragsize; int mmapped; - int pending; Audiodev *dev; } OSSVoiceOut; typedef struct OSSVoiceIn { HWVoiceIn hw; - void *pcm_buf; int fd; int nfrags; int fragsize; @@ -370,98 +366,87 @@ static int oss_open(int in, struct oss_params *req, audsettings *as, return -1; } -static void oss_write_pending (OSSVoiceOut *oss) +static size_t oss_get_available_bytes(OSSVoiceOut *oss) { - HWVoiceOut *hw = &oss->hw; + int err; + struct count_info cntinfo; + assert(oss->mmapped); + err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo); + if (err < 0) { + oss_logerr(errno, "SNDCTL_DSP_GETOPTR failed\n"); + return 0; + } + + return audio_ring_dist(cntinfo.ptr, oss->hw.pos_emul, oss->hw.size_emul); +} + +static void *oss_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + OSSVoiceOut *oss = (OSSVoiceOut *) hw; + if (oss->mmapped) { + *size = MIN(oss_get_available_bytes(oss), hw->size_emul - hw->pos_emul); + return hw->buf_emul + hw->pos_emul; + } else { + return audio_generic_get_buffer_out(hw, size); + } +} + +static size_t oss_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size) +{ + OSSVoiceOut *oss = (OSSVoiceOut *) hw; if (oss->mmapped) { - return; + assert(buf == hw->buf_emul + hw->pos_emul && size < hw->size_emul); + + hw->pos_emul = (hw->pos_emul + size) % hw->size_emul; + return size; + } else { + return audio_generic_put_buffer_out(hw, buf, size); + } +} + +static size_t oss_write(HWVoiceOut *hw, void *buf, size_t len) +{ + OSSVoiceOut *oss = (OSSVoiceOut *) hw; + size_t pos; + + if (oss->mmapped) { + size_t total_len; + len = MIN(len, oss_get_available_bytes(oss)); + + total_len = len; + while (len) { + size_t to_copy = MIN(len, hw->size_emul - hw->pos_emul); + memcpy(hw->buf_emul + hw->pos_emul, buf, to_copy); + + hw->pos_emul = (hw->pos_emul + to_copy) % hw->pos_emul; + buf += to_copy; + len -= to_copy; + } + return total_len; } - while (oss->pending) { - int samples_written; + pos = 0; + while (len) { ssize_t bytes_written; - int samples_till_end = hw->samples - oss->wpos; - int samples_to_write = MIN (oss->pending, samples_till_end); - int bytes_to_write = samples_to_write << hw->info.shift; - void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift); + void *pcm = advance(buf, pos); - bytes_written = write (oss->fd, pcm, bytes_to_write); + bytes_written = write(oss->fd, pcm, len); if (bytes_written < 0) { if (errno != EAGAIN) { - oss_logerr (errno, "failed to write %d bytes\n", - bytes_to_write); + oss_logerr(errno, "failed to write %zu bytes\n", + len); } - break; - } - - if (bytes_written & hw->info.align) { - dolog ("misaligned write asked for %d, but got %zd\n", - bytes_to_write, bytes_written); - return; + return pos; } - samples_written = bytes_written >> hw->info.shift; - oss->pending -= samples_written; - oss->wpos = (oss->wpos + samples_written) % hw->samples; - if (bytes_written - bytes_to_write) { + pos += bytes_written; + if (bytes_written < len) { break; } + len -= bytes_written; } -} - -static size_t oss_run_out(HWVoiceOut *hw, size_t live) -{ - OSSVoiceOut *oss = (OSSVoiceOut *) hw; - int err; - size_t decr; - struct audio_buf_info abinfo; - struct count_info cntinfo; - size_t bufsize; - - bufsize = hw->samples << hw->info.shift; - - if (oss->mmapped) { - int bytes, pos; - - err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo); - if (err < 0) { - oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n"); - return 0; - } - - pos = hw->rpos << hw->info.shift; - bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize); - decr = MIN (bytes >> hw->info.shift, live); - } - else { - err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo); - if (err < 0) { - oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n"); - return 0; - } - - if (abinfo.bytes > bufsize) { - trace_oss_invalid_available_size(abinfo.bytes, bufsize); - abinfo.bytes = bufsize; - } - - if (abinfo.bytes < 0) { - trace_oss_invalid_available_size(abinfo.bytes, bufsize); - return 0; - } - - decr = MIN (abinfo.bytes >> hw->info.shift, live); - if (!decr) { - return 0; - } - } - - decr = audio_pcm_hw_clip_out (hw, oss->pcm_buf, decr, oss->pending); - oss->pending += decr; - oss_write_pending (oss); - - return decr; + return pos; } static void oss_fini_out (HWVoiceOut *hw) @@ -472,18 +457,13 @@ static void oss_fini_out (HWVoiceOut *hw) ldebug ("oss_fini\n"); oss_anal_close (&oss->fd); - if (oss->pcm_buf) { - if (oss->mmapped) { - err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); - if (err) { - oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n", - oss->pcm_buf, hw->samples << hw->info.shift); - } + if (oss->mmapped && hw->buf_emul) { + err = munmap(hw->buf_emul, hw->size_emul); + if (err) { + oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n", + hw->buf_emul, hw->size_emul); } - else { - g_free (oss->pcm_buf); - } - oss->pcm_buf = NULL; + hw->buf_emul = NULL; } } @@ -534,19 +514,20 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, oss->mmapped = 0; if (oopts->has_try_mmap && oopts->try_mmap) { - oss->pcm_buf = mmap ( + hw->size_emul = hw->samples << hw->info.shift; + hw->buf_emul = mmap ( NULL, - hw->samples << hw->info.shift, + hw->size_emul, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); - if (oss->pcm_buf == MAP_FAILED) { + if (hw->buf_emul == MAP_FAILED) { oss_logerr(errno, "Failed to map %zu bytes of DAC\n", - hw->samples << hw->info.shift); - } - else { + hw->size_emul); + hw->buf_emul = NULL; + } else { int err; int trig = 0; if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { @@ -566,30 +547,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, } if (!oss->mmapped) { - err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); + err = munmap(hw->buf_emul, hw->size_emul); if (err) { oss_logerr(errno, "Failed to unmap buffer %p size %zu\n", - oss->pcm_buf, hw->samples << hw->info.shift); + hw->buf_emul, hw->size_emul); } + hw->buf_emul = NULL; } } } - if (!oss->mmapped) { - oss->pcm_buf = audio_calloc(__func__, - hw->samples, - 1 << hw->info.shift); - if (!oss->pcm_buf) { - dolog ( - "Could not allocate DAC buffer (%zu samples, each %d bytes)\n", - hw->samples, - 1 << hw->info.shift - ); - oss_anal_close (&fd); - return -1; - } - } - oss->fd = fd; oss->dev = dev; return 0; @@ -617,7 +584,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } - audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples); + audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->samples); trig = PCM_ENABLE_OUTPUT; if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { oss_logerr ( @@ -691,13 +658,6 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; - oss->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); - if (!oss->pcm_buf) { - dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); - oss_anal_close (&fd); - return -1; - } oss->fd = fd; oss->dev = dev; @@ -709,78 +669,36 @@ static void oss_fini_in (HWVoiceIn *hw) OSSVoiceIn *oss = (OSSVoiceIn *) hw; oss_anal_close (&oss->fd); - - g_free(oss->pcm_buf); - oss->pcm_buf = NULL; } -static size_t oss_run_in(HWVoiceIn *hw) +static size_t oss_read(HWVoiceIn *hw, void *buf, size_t len) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; - int hwshift = hw->info.shift; - int i; - size_t live = audio_pcm_hw_get_live_in (hw); - size_t dead = hw->samples - live; - size_t read_samples = 0; - struct { - size_t add; - size_t len; - } bufs[2] = { - { .add = hw->wpos, .len = 0 }, - { .add = 0, .len = 0 } - }; + size_t pos = 0; - if (!dead) { - return 0; - } - - if (hw->wpos + dead > hw->samples) { - bufs[0].len = (hw->samples - hw->wpos) << hwshift; - bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift; - } - else { - bufs[0].len = dead << hwshift; - } - - for (i = 0; i < 2; ++i) { + while (len) { ssize_t nread; - if (bufs[i].len) { - void *p = advance (oss->pcm_buf, bufs[i].add << hwshift); - nread = read (oss->fd, p, bufs[i].len); + void *dst = advance(buf, pos); + nread = read(oss->fd, dst, len); - if (nread > 0) { - if (nread & hw->info.align) { - dolog("warning: Misaligned read %zd (requested %zu), " - "alignment %d\n", nread, bufs[i].add << hwshift, - hw->info.align + 1); - } - read_samples += nread >> hwshift; - hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift); - } - - if (bufs[i].len - nread) { - if (nread == -1) { - switch (errno) { - case EINTR: - case EAGAIN: - break; - default: - oss_logerr( - errno, - "Failed to read %zu bytes of audio (to %p)\n", - bufs[i].len, p - ); - break; - } - } + if (nread == -1) { + switch (errno) { + case EINTR: + case EAGAIN: + break; + default: + oss_logerr(errno, "Failed to read %zu bytes of audio (to %p)\n", + len, dst); break; } } + + pos += nread; + len -= nread; } - hw->wpos = (hw->wpos + read_samples) % hw->samples; - return read_samples; + return pos; } static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) @@ -850,12 +768,14 @@ static void oss_audio_fini (void *opaque) static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, - .run_out = oss_run_out, + .write = oss_write, + .get_buffer_out = oss_get_buffer_out, + .put_buffer_out = oss_put_buffer_out, .ctl_out = oss_ctl_out, .init_in = oss_init_in, .fini_in = oss_fini_in, - .run_in = oss_run_in, + .read = oss_read, .ctl_in = oss_ctl_in }; From patchwork Wed Jan 16 23:37:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767161 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7F77513A4 for ; Wed, 16 Jan 2019 23:57:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6AF8F2FC1C for ; Wed, 16 Jan 2019 23:57:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 586482FC47; Wed, 16 Jan 2019 23:57:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1D5872FC1C for ; Wed, 16 Jan 2019 23:57:21 +0000 (UTC) Received: from localhost ([127.0.0.1]:36050 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv3e-0002m6-0T for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:57:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58157) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul3-0004M7-Hv for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjukx-0003Fk-Qc for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:03 -0500 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]:37798) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjuku-0003AN-0J for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:37:57 -0500 Received: by mail-wm1-x32f.google.com with SMTP id g67so3866295wmd.2 for ; Wed, 16 Jan 2019 15:37:55 -0800 (PST) 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=P0OO8Kwlrx6EygyedhMHJi/cTk9XPu0b/jHPZ0ktEN0=; b=APZ2ov4lstxYE4qyCBh+JAc0fnCuW/TWhNS6tj7xh8xUd2IxlEW9INADc9rO3voWlV KLrjKyDRYGN0ynIdKst87SkDXnVzsFdBn2CEmH9MqFzFTuA5eZOQSFl2g/f3ADIoJ3cg vgulU1eQ+jGZuhxojhYGttvaG37sI/EbGAFbp27D1I/MoNwNhN1kbY4Wv3Rl0ZOI/kBi bJEE3sUdQRSXTDLnXfKDTXH1hZGAF/I/EX0Fwpo5p8I9NZi1GBEDRwiQO+WJmRuxNh6x 166htOrx7q3nS/77DjAIoriF57eRk4Clvh/sVfZFvkqJE4uz5FgG+7mF0j7fC3OJBNtK SYpw== 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=P0OO8Kwlrx6EygyedhMHJi/cTk9XPu0b/jHPZ0ktEN0=; b=PdE0sBc5rDzgMUL/RSaqhI/NSFxTDRj2Diy8m1Q3NsJq3girCNA1RZNztYyeAZHvsw eGPrBKbxmnrS61xA7e9tK58GpdfTNNrSOwbb2xkWEzyRH1MMARgB4n5/LRkLHTBgMfzn Bl6to9kXK7+I4jl3rvBNdXdYhm4HQaduHYbNI1xanQ/8bAiok6bPRwGdVwpqDrphNcrU rexvAVcu4C8/NR9OehHlK0X69OEZhhPdR5mXJXSg6BQxz+8QAnMnaKpOF4drdaTO3KpO xtUi4j8wC+8AWh6++qsydzTq/p4rXt5JXcG2idhhatOasoiobcN78ECY8bmjVm440jTj nHBA== X-Gm-Message-State: AJcUukeInulnN+sSGokRqkBtem8lMEUSBeVpaXsOIe2lwwjZjSbZzv/V aP8fJOqufFC3uoVvh+u6BF3vfJOO3NU= X-Google-Smtp-Source: ALg8bN5D7YxdOEkkE9QovKbI7ZhQD7imq7iyuJXKOXaVRmzf+UO17ZKYGWCTO4oW5PrHZlKiyBF9uw== X-Received: by 2002:a1c:2884:: with SMTP id o126mr9739836wmo.17.1547681874308; Wed, 16 Jan 2019 15:37:54 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:53 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:05 +0100 Message-Id: <5233c2180027ffb2b859456785cb698ce7b60064.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32f Subject: [Qemu-devel] [PATCH v3 32/50] paaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- configure | 5 - audio/audio_pt_int.h | 22 --- audio/audio_pt_int.c | 174 -------------------- audio/paaudio.c | 372 ++++++------------------------------------- audio/Makefile.objs | 1 - 5 files changed, 45 insertions(+), 529 deletions(-) delete mode 100644 audio/audio_pt_int.h delete mode 100644 audio/audio_pt_int.c diff --git a/configure b/configure index 3eee3fcf70..e24e233458 100755 --- a/configure +++ b/configure @@ -286,7 +286,6 @@ block_drv_ro_whitelist="" host_cc="cc" libs_softmmu="" libs_tools="" -audio_pt_int="" audio_win_int="" libs_qga="" debug_info="yes" @@ -3329,7 +3328,6 @@ for drv in $audio_drv_list; do audio_drv_probe $drv pulse/pulseaudio.h "-lpulse" \ "pa_context_set_source_output_volume(NULL, 0, NULL, NULL, NULL); return 0;" pulse_libs="-lpulse" - audio_pt_int="yes" ;; sdl) @@ -6310,9 +6308,6 @@ echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak echo "COREAUDIO_LIBS=$coreaudio_libs" >> $config_host_mak echo "DSOUND_LIBS=$dsound_libs" >> $config_host_mak echo "OSS_LIBS=$oss_libs" >> $config_host_mak -if test "$audio_pt_int" = "yes" ; then - echo "CONFIG_AUDIO_PT_INT=y" >> $config_host_mak -fi if test "$audio_win_int" = "yes" ; then echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak fi diff --git a/audio/audio_pt_int.h b/audio/audio_pt_int.h deleted file mode 100644 index 4c0c15b9af..0000000000 --- a/audio/audio_pt_int.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef QEMU_AUDIO_PT_INT_H -#define QEMU_AUDIO_PT_INT_H - -#include - -struct audio_pt { - const char *drv; - pthread_t thread; - pthread_cond_t cond; - pthread_mutex_t mutex; -}; - -int audio_pt_init (struct audio_pt *, void *(*) (void *), void *, - const char *, const char *); -int audio_pt_fini (struct audio_pt *, const char *); -int audio_pt_lock (struct audio_pt *, const char *); -int audio_pt_unlock (struct audio_pt *, const char *); -int audio_pt_wait (struct audio_pt *, const char *); -int audio_pt_unlock_and_signal (struct audio_pt *, const char *); -int audio_pt_join (struct audio_pt *, void **, const char *); - -#endif /* QEMU_AUDIO_PT_INT_H */ diff --git a/audio/audio_pt_int.c b/audio/audio_pt_int.c deleted file mode 100644 index 3fe56d8514..0000000000 --- a/audio/audio_pt_int.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "qemu/osdep.h" -#include "qemu-common.h" -#include "audio.h" - -#define AUDIO_CAP "audio-pt" - -#include "audio_int.h" -#include "audio_pt_int.h" - -static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err, - const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - AUD_vlog (pt->drv, fmt, ap); - va_end (ap); - - AUD_log (NULL, "\n"); - AUD_log (pt->drv, "Reason: %s\n", strerror (err)); -} - -int audio_pt_init (struct audio_pt *p, void *(*func) (void *), - void *opaque, const char *drv, const char *cap) -{ - int err, err2; - const char *efunc; - sigset_t set, old_set; - - p->drv = drv; - - err = sigfillset (&set); - if (err) { - logerr(p, errno, "%s(%s): sigfillset failed", cap, __func__); - return -1; - } - - err = pthread_mutex_init (&p->mutex, NULL); - if (err) { - efunc = "pthread_mutex_init"; - goto err0; - } - - err = pthread_cond_init (&p->cond, NULL); - if (err) { - efunc = "pthread_cond_init"; - goto err1; - } - - err = pthread_sigmask (SIG_BLOCK, &set, &old_set); - if (err) { - efunc = "pthread_sigmask"; - goto err2; - } - - err = pthread_create (&p->thread, NULL, func, opaque); - - err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL); - if (err2) { - logerr(p, err2, "%s(%s): pthread_sigmask (restore) failed", - cap, __func__); - /* We have failed to restore original signal mask, all bets are off, - so terminate the process */ - exit (EXIT_FAILURE); - } - - if (err) { - efunc = "pthread_create"; - goto err2; - } - - return 0; - - err2: - err2 = pthread_cond_destroy (&p->cond); - if (err2) { - logerr(p, err2, "%s(%s): pthread_cond_destroy failed", cap, __func__); - } - - err1: - err2 = pthread_mutex_destroy (&p->mutex); - if (err2) { - logerr(p, err2, "%s(%s): pthread_mutex_destroy failed", cap, __func__); - } - - err0: - logerr(p, err, "%s(%s): %s failed", cap, __func__, efunc); - return -1; -} - -int audio_pt_fini (struct audio_pt *p, const char *cap) -{ - int err, ret = 0; - - err = pthread_cond_destroy (&p->cond); - if (err) { - logerr(p, err, "%s(%s): pthread_cond_destroy failed", cap, __func__); - ret = -1; - } - - err = pthread_mutex_destroy (&p->mutex); - if (err) { - logerr(p, err, "%s(%s): pthread_mutex_destroy failed", cap, __func__); - ret = -1; - } - return ret; -} - -int audio_pt_lock (struct audio_pt *p, const char *cap) -{ - int err; - - err = pthread_mutex_lock (&p->mutex); - if (err) { - logerr(p, err, "%s(%s): pthread_mutex_lock failed", cap, __func__); - return -1; - } - return 0; -} - -int audio_pt_unlock (struct audio_pt *p, const char *cap) -{ - int err; - - err = pthread_mutex_unlock (&p->mutex); - if (err) { - logerr(p, err, "%s(%s): pthread_mutex_unlock failed", cap, __func__); - return -1; - } - return 0; -} - -int audio_pt_wait (struct audio_pt *p, const char *cap) -{ - int err; - - err = pthread_cond_wait (&p->cond, &p->mutex); - if (err) { - logerr(p, err, "%s(%s): pthread_cond_wait failed", cap, __func__); - return -1; - } - return 0; -} - -int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap) -{ - int err; - - err = pthread_mutex_unlock (&p->mutex); - if (err) { - logerr(p, err, "%s(%s): pthread_mutex_unlock failed", cap, __func__); - return -1; - } - err = pthread_cond_signal (&p->cond); - if (err) { - logerr(p, err, "%s(%s): pthread_cond_signal failed", cap, __func__); - return -1; - } - return 0; -} - -int audio_pt_join (struct audio_pt *p, void **arg, const char *cap) -{ - int err; - void *ret; - - err = pthread_join (p->thread, &ret); - if (err) { - logerr(p, err, "%s(%s): pthread_join failed", cap, __func__); - return -1; - } - *arg = ret; - return 0; -} diff --git a/audio/paaudio.c b/audio/paaudio.c index a1be0726b7..bb1367fbae 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -8,7 +8,6 @@ #define AUDIO_CAP "pulseaudio" #include "audio_int.h" -#include "audio_pt_int.h" typedef struct PAConnection { char *server; @@ -29,28 +28,16 @@ typedef struct { typedef struct { HWVoiceOut hw; - size_t done; - size_t live; - size_t decr; - size_t rpos; pa_stream *stream; - void *pcm_buf; - struct audio_pt pt; paaudio *g; size_t samples; } PAVoiceOut; typedef struct { HWVoiceIn hw; - size_t done; - size_t dead; - size_t incr; - size_t wpos; pa_stream *stream; - void *pcm_buf; - struct audio_pt pt; const void *read_data; - size_t read_index, read_length; + size_t read_length; paaudio *g; size_t samples; } PAVoiceIn; @@ -88,298 +75,96 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) } #endif -#define CHECK_SUCCESS_GOTO(c, rerror, expression, label) \ +#define CHECK_SUCCESS_GOTO(c, expression, label, msg) \ do { \ if (!(expression)) { \ - if (rerror) { \ - *(rerror) = pa_context_errno ((c)->context); \ - } \ + qpa_logerr(pa_context_errno((c)->context), msg); \ goto label; \ } \ } while (0) -#define CHECK_DEAD_GOTO(c, stream, rerror, label) \ +#define CHECK_DEAD_GOTO(c, stream, label, msg) \ do { \ if (!(c)->context || !PA_CONTEXT_IS_GOOD (pa_context_get_state((c)->context)) || \ !(stream) || !PA_STREAM_IS_GOOD (pa_stream_get_state ((stream)))) { \ if (((c)->context && pa_context_get_state ((c)->context) == PA_CONTEXT_FAILED) || \ ((stream) && pa_stream_get_state ((stream)) == PA_STREAM_FAILED)) { \ - if (rerror) { \ - *(rerror) = pa_context_errno ((c)->context); \ - } \ + qpa_logerr(pa_context_errno((c)->context), msg); \ } else { \ - if (rerror) { \ - *(rerror) = PA_ERR_BADSTATE; \ - } \ + qpa_logerr(PA_ERR_BADSTATE, msg); \ } \ goto label; \ } \ } while (0) -static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror) +static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length) { + PAVoiceIn *p = (PAVoiceIn *) hw; PAConnection *c = p->g->conn; + size_t l; + int r; pa_threaded_mainloop_lock(c->mainloop); - CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); + CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail, + "pa_threaded_mainloop_lock failed\n"); - while (length > 0) { - size_t l; - - while (!p->read_data) { - int r; - - r = pa_stream_peek (p->stream, &p->read_data, &p->read_length); - CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); - - if (!p->read_data) { - pa_threaded_mainloop_wait(c->mainloop); - CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); - } else { - p->read_index = 0; - } - } - - l = p->read_length < length ? p->read_length : length; - memcpy (data, (const uint8_t *) p->read_data+p->read_index, l); - - data = (uint8_t *) data + l; - length -= l; - - p->read_index += l; - p->read_length -= l; + if (!p->read_length) { + r = pa_stream_peek (p->stream, &p->read_data, &p->read_length); + CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail, + "pa_stream_peek failed\n"); + } - if (!p->read_length) { - int r; + l = MIN(p->read_length, length); + memcpy(data, p->read_data, l); - r = pa_stream_drop (p->stream); - p->read_data = NULL; - p->read_length = 0; - p->read_index = 0; + p->read_data += l; + p->read_length -= l; - CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail); - } + if (!p->read_length) { + r = pa_stream_drop(p->stream); + CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail, + "pa_stream_drop failed\n"); } pa_threaded_mainloop_unlock(c->mainloop); - return 0; + return l; unlock_and_fail: pa_threaded_mainloop_unlock(c->mainloop); - return -1; + return 0; } -static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, int *rerror) +static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length) { + PAVoiceOut *p = (PAVoiceOut *) hw; PAConnection *c = p->g->conn; + size_t l; + int r; pa_threaded_mainloop_lock(c->mainloop); - CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); + CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail, + "pa_threaded_mainloop_lock failed\n"); - while (length > 0) { - size_t l; - int r; + l = pa_stream_writable_size(p->stream); - while (!(l = pa_stream_writable_size (p->stream))) { - pa_threaded_mainloop_wait(c->mainloop); - CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail); - } + CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail, + "pa_stream_writable_size failed\n"); - CHECK_SUCCESS_GOTO(c, rerror, l != (size_t) -1, unlock_and_fail); - - if (l > length) { - l = length; - } - - r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE); - CHECK_SUCCESS_GOTO(c, rerror, r >= 0, unlock_and_fail); - - data = (const uint8_t *) data + l; - length -= l; + if (l > length) { + l = length; } + r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE); + CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n"); + pa_threaded_mainloop_unlock(c->mainloop); - return 0; + return l; unlock_and_fail: pa_threaded_mainloop_unlock(c->mainloop); - return -1; -} - -static void *qpa_thread_out (void *arg) -{ - PAVoiceOut *pa = arg; - HWVoiceOut *hw = &pa->hw; - - if (audio_pt_lock(&pa->pt, __func__)) { - return NULL; - } - - for (;;) { - size_t decr, to_mix, rpos; - - for (;;) { - if (pa->done) { - goto exit; - } - - if (pa->live > 0) { - break; - } - - if (audio_pt_wait(&pa->pt, __func__)) { - goto exit; - } - } - - decr = to_mix = MIN(pa->live, pa->samples >> 5); - rpos = pa->rpos; - - if (audio_pt_unlock(&pa->pt, __func__)) { - return NULL; - } - - while (to_mix) { - int error; - size_t chunk = MIN (to_mix, hw->samples - rpos); - struct st_sample *src = hw->mix_buf + rpos; - - hw->clip (pa->pcm_buf, src, chunk); - - if (qpa_simple_write (pa, pa->pcm_buf, - chunk << hw->info.shift, &error) < 0) { - qpa_logerr (error, "pa_simple_write failed\n"); - return NULL; - } - - rpos = (rpos + chunk) % hw->samples; - to_mix -= chunk; - } - - if (audio_pt_lock(&pa->pt, __func__)) { - return NULL; - } - - pa->rpos = rpos; - pa->live -= decr; - pa->decr += decr; - } - - exit: - audio_pt_unlock(&pa->pt, __func__); - return NULL; -} - -static size_t qpa_run_out(HWVoiceOut *hw, size_t live) -{ - size_t decr; - PAVoiceOut *pa = (PAVoiceOut *) hw; - - if (audio_pt_lock(&pa->pt, __func__)) { - return 0; - } - - decr = MIN (live, pa->decr); - pa->decr -= decr; - pa->live = live - decr; - hw->rpos = pa->rpos; - if (pa->live > 0) { - audio_pt_unlock_and_signal(&pa->pt, __func__); - } - else { - audio_pt_unlock(&pa->pt, __func__); - } - return decr; -} - -/* capture */ -static void *qpa_thread_in (void *arg) -{ - PAVoiceIn *pa = arg; - HWVoiceIn *hw = &pa->hw; - - if (audio_pt_lock(&pa->pt, __func__)) { - return NULL; - } - - for (;;) { - size_t incr, to_grab, wpos; - - for (;;) { - if (pa->done) { - goto exit; - } - - if (pa->dead > 0) { - break; - } - - if (audio_pt_wait(&pa->pt, __func__)) { - goto exit; - } - } - - incr = to_grab = MIN(pa->dead, pa->samples >> 5); - wpos = pa->wpos; - - if (audio_pt_unlock(&pa->pt, __func__)) { - return NULL; - } - - while (to_grab) { - int error; - size_t chunk = MIN (to_grab, hw->samples - wpos); - void *buf = advance (pa->pcm_buf, wpos); - - if (qpa_simple_read (pa, buf, - chunk << hw->info.shift, &error) < 0) { - qpa_logerr (error, "pa_simple_read failed\n"); - return NULL; - } - - hw->conv (hw->conv_buf + wpos, buf, chunk); - wpos = (wpos + chunk) % hw->samples; - to_grab -= chunk; - } - - if (audio_pt_lock(&pa->pt, __func__)) { - return NULL; - } - - pa->wpos = wpos; - pa->dead -= incr; - pa->incr += incr; - } - - exit: - audio_pt_unlock(&pa->pt, __func__); - return NULL; -} - -static size_t qpa_run_in(HWVoiceIn *hw) -{ - size_t live, incr, dead; - PAVoiceIn *pa = (PAVoiceIn *) hw; - - if (audio_pt_lock(&pa->pt, __func__)) { - return 0; - } - - live = audio_pcm_hw_get_live_in (hw); - dead = hw->samples - live; - incr = MIN (dead, pa->incr); - pa->incr -= incr; - pa->dead = dead - incr; - hw->wpos = pa->wpos; - if (pa->dead > 0) { - audio_pt_unlock_and_signal(&pa->pt, __func__); - } - else { - audio_pt_unlock(&pa->pt, __func__); - } - return incr; + return 0; } static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness) @@ -467,13 +252,6 @@ static void stream_state_cb (pa_stream *s, void * userdata) } } -static void stream_request_cb (pa_stream *s, size_t length, void *userdata) -{ - PAConnection *c = userdata; - - pa_threaded_mainloop_signal(c->mainloop, 0); -} - static pa_stream *qpa_simple_new ( PAConnection *c, const char *name, @@ -496,8 +274,6 @@ static pa_stream *qpa_simple_new ( } pa_stream_set_state_callback(stream, stream_state_cb, c); - pa_stream_set_read_callback(stream, stream_request_cb, c); - pa_stream_set_write_callback(stream, stream_request_cb, c); flags = PA_STREAM_INTERPOLATE_TIMING @@ -581,28 +357,9 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, audio_pcm_init_info (&hw->info, &obt_as); hw->samples = pa->samples = audio_buffer_samples(g->dev->out, &obt_as, 46440); - pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); - pa->rpos = hw->rpos; - if (!pa->pcm_buf) { - dolog("Could not allocate buffer (%zu bytes)\n", - hw->samples << hw->info.shift); - goto fail2; - } - - if (audio_pt_init(&pa->pt, qpa_thread_out, hw, AUDIO_CAP, __func__)) { - goto fail3; - } return 0; - fail3: - g_free (pa->pcm_buf); - pa->pcm_buf = NULL; - fail2: - if (pa->stream) { - pa_stream_unref (pa->stream); - pa->stream = NULL; - } fail1: return -1; } @@ -642,28 +399,9 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) audio_pcm_init_info (&hw->info, &obt_as); hw->samples = pa->samples = audio_buffer_samples(g->dev->in, &obt_as, 46440); - pa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); - pa->wpos = hw->wpos; - if (!pa->pcm_buf) { - dolog("Could not allocate buffer (%zu bytes)\n", - hw->samples << hw->info.shift); - goto fail2; - } - - if (audio_pt_init(&pa->pt, qpa_thread_in, hw, AUDIO_CAP, __func__)) { - goto fail3; - } return 0; - fail3: - g_free (pa->pcm_buf); - pa->pcm_buf = NULL; - fail2: - if (pa->stream) { - pa_stream_unref (pa->stream); - pa->stream = NULL; - } fail1: return -1; } @@ -691,42 +429,22 @@ static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream) static void qpa_fini_out (HWVoiceOut *hw) { - void *ret; PAVoiceOut *pa = (PAVoiceOut *) hw; - audio_pt_lock(&pa->pt, __func__); - pa->done = 1; - audio_pt_unlock_and_signal(&pa->pt, __func__); - audio_pt_join(&pa->pt, &ret, __func__); - if (pa->stream) { qpa_simple_disconnect(pa->g->conn, pa->stream); pa->stream = NULL; } - - audio_pt_fini(&pa->pt, __func__); - g_free (pa->pcm_buf); - pa->pcm_buf = NULL; } static void qpa_fini_in (HWVoiceIn *hw) { - void *ret; PAVoiceIn *pa = (PAVoiceIn *) hw; - audio_pt_lock(&pa->pt, __func__); - pa->done = 1; - audio_pt_unlock_and_signal(&pa->pt, __func__); - audio_pt_join(&pa->pt, &ret, __func__); - if (pa->stream) { qpa_simple_disconnect(pa->g->conn, pa->stream); pa->stream = NULL; } - - audio_pt_fini(&pa->pt, __func__); - g_free (pa->pcm_buf); - pa->pcm_buf = NULL; } static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) @@ -977,12 +695,12 @@ static void qpa_audio_fini (void *opaque) static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, - .run_out = qpa_run_out, + .write = qpa_write, .ctl_out = qpa_ctl_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, - .run_in = qpa_run_in, + .read = qpa_read, .ctl_in = qpa_ctl_in }; diff --git a/audio/Makefile.objs b/audio/Makefile.objs index dca87f6347..d7490a379f 100644 --- a/audio/Makefile.objs +++ b/audio/Makefile.objs @@ -2,7 +2,6 @@ common-obj-y = audio.o audio_legacy.o noaudio.o wavaudio.o mixeng.o common-obj-$(CONFIG_SPICE) += spiceaudio.o common-obj-$(CONFIG_AUDIO_COREAUDIO) += coreaudio.o common-obj-$(CONFIG_AUDIO_DSOUND) += dsoundaudio.o -common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o common-obj-y += wavcapture.o From patchwork Wed Jan 16 23:37:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767177 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E5DF16C2 for ; Thu, 17 Jan 2019 00:04:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2023B2B25A for ; Thu, 17 Jan 2019 00:04:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0EC352E2C1; Thu, 17 Jan 2019 00:04:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7D3F12B25A for ; Thu, 17 Jan 2019 00:04:12 +0000 (UTC) Received: from localhost ([127.0.0.1]:37616 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvAJ-00082G-MJ for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:04:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58286) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul7-0004OF-Cw for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Re-FV for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:09 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:32771) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003BD-0h for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x441.google.com with SMTP id c14so9004973wrr.0 for ; Wed, 16 Jan 2019 15:37:56 -0800 (PST) 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=EYCybeHmc+O22DWbaV63rUle6kOdkCMtmKMz9xDtURs=; b=JnSdffWGft90jB29zLMyNjaZ+JCG7snKGoZfIqc36+ODrZ1txLR11Z4FOOSw864mKL QBgVk/SJgovFpaLX1mYTD5Cy81EyNgZdmufZGMrdIYyCLv/F2XCvta6WRZVIe6jRN36c wR/PqchL5/o2lqQLBCSZNGt9Cg7V/6T6DtLWLF+m9qk/bCKT6775F0Jy9+VvzRMwvNQr Ut0mYM2YQ0DC7X40H2Q08htwHIARGi6GtrgVEHcaRnMslUvSDQjr2lThwWpt/3gxU//7 3n5WIGhfK5g2YYhIDqG0/KWS9hDIU8zgV0WqsEdeABOKxBSTvtA/lKFFPn/g8JTY/4nI evOA== 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=EYCybeHmc+O22DWbaV63rUle6kOdkCMtmKMz9xDtURs=; b=mlp5VlhcmHngRA219eKNDkHfVacBSOrQ9xU03AQ3l8M1HbNUeKrW+SxuXORDjsrJ6I lUF5g+lW80DeM2MWFzorYJKqf8RsJjC23c6b+pglQo/bGG7oI52Jw8UkYGb9QE2qXU4w Zn8BdZ6NUN7PDg24gUfLsMtJ19qiqjt+c2hVIlBlArvumUj598spEjSWOP4VEONbvrMR stzDBpxzHnoo7ffZrRBcRlNYUNavP/hG16lXgJvPefG5rE5rVi5A3qbqC9icZwKG3Jha oOrz8eQ0dSNM5aF5D2FW3YUZpiMib+TInBQOqqHV14NUrqc7UFquqb4Mr+R0Sn71Lomd 66AA== X-Gm-Message-State: AJcUukfeOsIJ4gozk+sBNXNgUVr3p5i/gTz7qegbDtY7VQwG2Cpf2Dir 0l8T20QS7AgS7YQLSEUquKNlsnnTjuA= X-Google-Smtp-Source: ALg8bN5cESfGz+U/VenaG543ukQqZHIwNqXtG4AroMxmr9dzhSCNAc+RY2O32Gf2e+rAdNIKy0T2tg== X-Received: by 2002:adf:d0c9:: with SMTP id z9mr226590wrh.317.1547681875254; Wed, 16 Jan 2019 15:37:55 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:54 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:06 +0100 Message-Id: <0a16695365c4b7694b47ca5d7c6c286c560bbd44.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 33/50] sdlaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP SDL2 is still a big mess, but it's probably not worse than the current version. Signed-off-by: Kővágó, Zoltán --- audio/sdlaudio.c | 136 +++++++++++++++++------------------------------ 1 file changed, 50 insertions(+), 86 deletions(-) diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index ff19484430..685cbc83b8 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -42,11 +42,6 @@ typedef struct SDLVoiceOut { HWVoiceOut hw; - size_t live; -#if USE_SEMAPHORE - size_t rpos; -#endif - size_t decr; } SDLVoiceOut; static struct SDLAudioState { @@ -252,17 +247,13 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) SDLVoiceOut *sdl = opaque; SDLAudioState *s = &glob_sdl; HWVoiceOut *hw = &sdl->hw; - size_t samples = len >> hw->info.shift; if (s->exit) { return; } - while (samples) { - size_t to_mix, decr; - - /* dolog ("in callback samples=%d\n", samples); */ #if USE_SEMAPHORE + while (len) { sdl_wait (s, "sdl_callback"); if (s->exit) { return; @@ -271,95 +262,66 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len) if (sdl_lock (s, "sdl_callback")) { return; } - - if (audio_bug(__func__, sdl->live < 0 || sdl->live > hw->samples)) { - dolog("sdl->live=%d hw->samples=%zu\n", sdl->live, hw->samples); - return; - } - - if (!sdl->live) { - goto again; - } -#else - if (s->exit || !sdl->live) { - break; - } #endif - /* dolog ("in callback live=%d\n", live); */ - to_mix = MIN (samples, sdl->live); - decr = to_mix; - while (to_mix) { - size_t chunk = MIN(to_mix, hw->samples - hw->rpos); - struct st_sample *src = hw->mix_buf + hw->rpos; + while (hw->pending_emul && len) { + size_t write_len; + ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; + if (start < 0) { + start += hw->size_emul; + } + assert(start >= 0 && start < hw->size_emul); - /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */ - hw->clip (buf, src, chunk); -#if USE_SEMAPHORE - sdl->rpos = (sdl->rpos + chunk) % hw->samples; -#else - hw->rpos = (hw->rpos + chunk) % hw->samples; -#endif - to_mix -= chunk; - buf += chunk << hw->info.shift; + write_len = MIN(MIN(hw->pending_emul, len), + hw->size_emul - start); + + memcpy(buf, hw->buf_emul + start, write_len); + hw->pending_emul -= write_len; + len -= write_len; + buf += write_len; } - samples -= decr; - sdl->live -= decr; - sdl->decr += decr; #if USE_SEMAPHORE - again: if (sdl_unlock (s, "sdl_callback")) { return; } -#endif } - /* dolog ("done len=%d\n", len); */ - -#if (SDL_MAJOR_VERSION >= 2) - /* SDL2 does not clear the remaining buffer for us, so do it on our own */ - if (samples) { - memset(buf, 0, samples << hw->info.shift); - } -#endif -} - -static size_t sdl_run_out(HWVoiceOut *hw, size_t live) -{ - size_t decr; - SDLVoiceOut *sdl = (SDLVoiceOut *) hw; - SDLAudioState *s = &glob_sdl; - - if (sdl_lock (s, "sdl_run_out")) { - return 0; - } - - if (sdl->decr > live) { - ldebug ("sdl->decr %d live %d sdl->live %d\n", - sdl->decr, - live, - sdl->live); - } - - decr = MIN (sdl->decr, live); - sdl->decr -= decr; - -#if USE_SEMAPHORE - sdl->live = live - decr; - hw->rpos = sdl->rpos; #else - sdl->live = live; + /* clear remaining buffer that we couldn't fill with data */ + if (len) { + memset(buf, 0, len); + } #endif - - if (sdl->live > 0) { - sdl_unlock_and_post (s, "sdl_run_out"); - } - else { - sdl_unlock (s, "sdl_run_out"); - } - return decr; } +#define SDL_WRAPPER_FUNC(name, ret_type, args_decl, args, fail, unlock) \ + static ret_type glue(sdl_, name)args_decl \ + { \ + SDLAudioState *s = &glob_sdl; \ + ret_type ret; \ + \ + if (sdl_lock(s, "sdl_" #name)) { \ + fail; \ + return 0; /* implicitly casts to NULL */ \ + } \ + \ + ret = glue(audio_generic_, name)args; \ + \ + unlock(s, "sdl_" #name); \ + return ret; \ + } + +SDL_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size), + (hw, size), *size = 0, sdl_unlock) +SDL_WRAPPER_FUNC(put_buffer_out_nowrite, size_t, + (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size), + /*nothing*/, sdl_unlock_and_post) +SDL_WRAPPER_FUNC(write, size_t, + (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size), + /* nothing */, sdl_unlock_and_post) + +#undef SDL_WRAPPER_FUNC + static void sdl_fini_out (HWVoiceOut *hw) { (void) hw; @@ -476,7 +438,9 @@ static void sdl_audio_fini (void *opaque) static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, - .run_out = sdl_run_out, + .write = sdl_write, + .get_buffer_out = sdl_get_buffer_out, + .put_buffer_out = sdl_put_buffer_out_nowrite, .ctl_out = sdl_ctl_out, }; From patchwork Wed Jan 16 23:37:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EA3E71390 for ; Thu, 17 Jan 2019 00:08:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D69AC2E9BD for ; Thu, 17 Jan 2019 00:08:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C683B2F353; Thu, 17 Jan 2019 00:08:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3F6092E9BD for ; Thu, 17 Jan 2019 00:08:38 +0000 (UTC) Received: from localhost ([127.0.0.1]:38650 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvEb-0002uW-Fc for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:08:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58196) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul4-0004MC-Kf for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul3-0003Np-CR for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:45496) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukx-0003CT-V0 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:01 -0500 Received: by mail-wr1-x443.google.com with SMTP id t6so8904123wrr.12 for ; Wed, 16 Jan 2019 15:37:57 -0800 (PST) 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=zF9jMlzHsBdNCwHHF7vzCc2fZEfTsMZ58ERyVXP0OHU=; b=IZN03o+IklYWc32OnZtsiw2Vx91chi9o3e1k+egkolGqyEPid0s87VPvt1IcApUYxu l4g8Dla7ldwSmZ/HwuyqqwajSYrYYbC5SPjGwlyBcIrmbjebrtdE9drUn+8Ea/rx/fiZ Y0fFxY2DrqWvU+cTR7A6uraQXFgrScIR8YtI5w6ibbBqrHLjECr4nj9sYSF9nCVGHc8T YSGyBaxb0iTuO5cPEKyiu4Bjmlj2aKGb1qEHbMTP/sBjAKmItxilxhsok/D6SVioQ2ZP 3ta9Ic+5pABuZBbTb5JEML8Ttff7H7MaOhA5wRDbVuwaYbyQOZdePvl/+WIHcWUu5ym2 cjlA== 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=zF9jMlzHsBdNCwHHF7vzCc2fZEfTsMZ58ERyVXP0OHU=; b=QSAxZX/PBuMUKhRNKlhoxFB8JLN8GBP1vgIFrqhe67lWANFhMWeufsZGgKELgkqGk5 PBXBD78IohIRCwN8zZztAeFeAf2CSdKPdJq1EoX0fTg3Q8TxTwXBD04D1QzoOwkcRbK+ FkzGJwR97e8A9IUoz+lfSx5GpoW0vnUTZMjPE0vOleOwNveJqAxlzATezOGl7BESCXK6 PCNqqD+BLs/Y5ifCfnxfSOx3VaLG4OZMZvdU5+q+unUCwcTebWi9OfXGnrOfT2DnONdG cUH8jX/Z4uI0dsJY5LbANiNpyaXcTeEzax7ILYTo2xoLYuPOXeZenWOPe0qB6InJ9Jjh haUA== X-Gm-Message-State: AJcUukd59vGtX3cCW25vCcTuQHn4i8ENBsPDF8AB9RhiLjgJEkiqWQu7 Ix1vwRuiyf+58bAYmefvYecNzQfFIu8= X-Google-Smtp-Source: ALg8bN6mhWy3rAw5RrX1sXgbGm06bWXIQKw8XCiyqZ9UBWiFONyvyZvCV2LfkMW3HwGPYodbRCHhpg== X-Received: by 2002:adf:8323:: with SMTP id 32mr9138131wrd.176.1547681876187; Wed, 16 Jan 2019 15:37:56 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:55 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:07 +0100 Message-Id: <1735f2dd5b1825aaf294ff8f80dcd8d3c26a72c1.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PATCH v3 34/50] spiceaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/spiceaudio.c | 112 +++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 74 deletions(-) diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 1a777bba17..d1605d3939 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -51,7 +51,7 @@ typedef struct SpiceVoiceOut { SpiceRateCtl rate; int active; uint32_t *frame; - uint32_t *fpos; + uint32_t fpos; uint32_t fsize; } SpiceVoiceOut; @@ -60,7 +60,6 @@ typedef struct SpiceVoiceIn { SpiceRecordInstance sin; SpiceRateCtl rate; int active; - uint32_t samples[LINE_IN_SAMPLES]; } SpiceVoiceIn; static const SpicePlaybackInterface playback_sif = { @@ -152,44 +151,36 @@ static void line_out_fini (HWVoiceOut *hw) spice_server_remove_interface (&out->sin.base); } -static size_t line_out_run (HWVoiceOut *hw, size_t live) +static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) { - SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); - size_t rpos, decr; - size_t samples; + SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); + size_t decr; - if (!live) { - return 0; + if (!out->frame) { + spice_server_playback_get_buffer(&out->sin, &out->frame, &out->fsize); + out->fpos = 0; } - decr = rate_get_samples (&hw->info, &out->rate); - decr = MIN (live, decr); + decr = rate_get_samples(&hw->info, &out->rate); + decr = MIN(out->fsize - out->fpos, decr); - samples = decr; - rpos = hw->rpos; - while (samples) { - int left_till_end_samples = hw->samples - rpos; - int len = MIN (samples, left_till_end_samples); + *size = decr << hw->info.shift; + return out->frame + out->fpos; +} - if (!out->frame) { - spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize); - out->fpos = out->frame; - } - if (out->frame) { - len = MIN (len, out->fsize); - hw->clip (out->fpos, hw->mix_buf + rpos, len); - out->fsize -= len; - out->fpos += len; - if (out->fsize == 0) { - spice_server_playback_put_samples (&out->sin, out->frame); - out->frame = out->fpos = NULL; - } - } - rpos = (rpos + len) % hw->samples; - samples -= len; +static size_t line_out_put_buffer(HWVoiceOut *hw, void *buf, size_t size) +{ + SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); + + out->fpos += size >> 2; + assert(buf == out->frame + out->fpos && out->fpos <= out->fsize); + + if (out->fpos == out->fsize) { /* buffer full */ + spice_server_playback_put_samples(&out->sin, out->frame); + out->frame = NULL; } - hw->rpos = rpos; - return decr; + + return size; } static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) @@ -211,9 +202,9 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) } out->active = 0; if (out->frame) { - memset (out->fpos, 0, out->fsize << 2); + memset(out->frame + out->fpos, 0, (out->fsize - out->fpos) << 2); spice_server_playback_put_samples (&out->sin, out->frame); - out->frame = out->fpos = NULL; + out->frame = NULL; } spice_server_playback_stop (&out->sin); break; @@ -275,49 +266,20 @@ static void line_in_fini (HWVoiceIn *hw) spice_server_remove_interface (&in->sin.base); } -static size_t line_in_run(HWVoiceIn *hw) +static size_t line_in_read(HWVoiceIn *hw, void *buf, size_t len) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); - size_t num_samples; - int ready; - size_t len[2]; - uint64_t delta_samp; - const uint32_t *samples; + uint64_t delta_samp = rate_get_samples(&hw->info, &in->rate); + uint64_t to_read = MIN(len >> 2, delta_samp); + size_t ready = spice_server_record_get_samples(&in->sin, buf, to_read); - if (!(num_samples = hw->samples - audio_pcm_hw_get_live_in (hw))) { - return 0; - } - - delta_samp = rate_get_samples (&hw->info, &in->rate); - num_samples = MIN (num_samples, delta_samp); - - ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples); - samples = in->samples; + /* XXX: do we need this? */ if (ready == 0) { - static const uint32_t silence[LINE_IN_SAMPLES]; - samples = silence; - ready = LINE_IN_SAMPLES; + memset(buf, 0, to_read << 2); + ready = to_read; } - num_samples = MIN (ready, num_samples); - - if (hw->wpos + num_samples > hw->samples) { - len[0] = hw->samples - hw->wpos; - len[1] = num_samples - len[0]; - } else { - len[0] = num_samples; - len[1] = 0; - } - - hw->conv (hw->conv_buf + hw->wpos, samples, len[0]); - - if (len[1]) { - hw->conv (hw->conv_buf, samples + len[0], len[1]); - } - - hw->wpos = (hw->wpos + num_samples) % hw->samples; - - return num_samples; + return ready << 2; } static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) @@ -366,12 +328,14 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, - .run_out = line_out_run, + .write = audio_generic_write, + .get_buffer_out = line_out_get_buffer, + .put_buffer_out = line_out_put_buffer, .ctl_out = line_out_ctl, .init_in = line_in_init, .fini_in = line_in_fini, - .run_in = line_in_run, + .read = line_in_read, .ctl_in = line_in_ctl, }; From patchwork Wed Jan 16 23:37:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767157 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE0D317FB for ; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB7222EA0A for ; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF5072FC35; Wed, 16 Jan 2019 23:55:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F5B02FBFB for ; Wed, 16 Jan 2019 23:55:06 +0000 (UTC) Received: from localhost ([127.0.0.1]:35503 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv1V-00017k-LZ for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:55:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58308) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul7-0004Oo-Pd for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Qv-7L for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:09 -0500 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]:52815) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-0003Cs-SN for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wm1-x335.google.com with SMTP id m1so3894497wml.2 for ; Wed, 16 Jan 2019 15:37:58 -0800 (PST) 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=55fN8+hqn/TmcJPpmVmh6plQ0I0DVyWru4rpKyJEyLk=; b=vBTn70sESGWi3zBdSur1qVmagDkt8rln93hQG2/YMIhFVrSCgALgjB4/NZci0TDmQ9 f0QRFE+z1kpHaIUUMbZoXaHCxeO0FP+or8EOIpbtdkbDLWcQZGWjZpfMNz/8kNZtQj2V VE+T8b+Xo2YUcMMyF/Bb8u9sqAvdIDdyozXp8+ND4ycJhrQqkZajTGIb3MrI5IcR1+wF wGhkCXzUONuffYXkq3gvyGEOXmqIzstPro6X7pTOnG6qSSctqqYHzs7E+bo+kV+RQOYF HA7281IW2EhG613/Bpb0gu+m001MgIeIcUzDAv40zPys7zAu4ndEueQ37ZcgqggHSi6D 9rrw== 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=55fN8+hqn/TmcJPpmVmh6plQ0I0DVyWru4rpKyJEyLk=; b=TcNhlNHey6l6Ghf1VCOA/E+L7bezMJjltc6eXHPMorKaQ3PvuOq0SQ4Lm1q4eA+bzl 8KBPz2CMlRGoTyyT109dS0y/fG1wu4jsdOynW0N+mjdkQOCTfWvSFRURwLf1g8hwBl42 gYEDo/yZ/sQFrdV35Jvw/b3oU1CllCXF7xsIvXX1TP1V/yimzSt/28l1xbGNIp8CbhIn G6nsQB+AnzsOmfX2TBJbXfstSQVjcNPrmi6cIuPX/h2roGxGzPIQ7/2ux+mNbEC8J2Gv X2WX87wwVgctZTsHGbfFYoNWqqcm2msvPlTMx5ULI8+uF5u3eSmlELh0Ys2tENvolG0Q JDfA== X-Gm-Message-State: AJcUukdMSFcjvjM2x4y0MZvYicUJQ+4oBOtQ/9dnHlJFEJx8qDungYWb h3+fc2AnhyPTY9z4YRqlE80DJDjCXCg= X-Google-Smtp-Source: ALg8bN5IjlsRfTVMIaNZvgZd7zOxYuASrXwuQNXxHtR85c8t8qjYD6d5JjXs08YCJtwbjClaLcnwjQ== X-Received: by 2002:a1c:4955:: with SMTP id w82mr9825168wma.33.1547681876868; Wed, 16 Jan 2019 15:37:56 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:56 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:08 +0100 Message-Id: <25bee185c67bcaf474d9d0b87b2a15a98cbf0a01.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::335 Subject: [Qemu-devel] [PATCH v3 35/50] wavaudio: port to the new audio backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/wavaudio.c | 54 ++++++++---------------------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/audio/wavaudio.c b/audio/wavaudio.c index a805e5e94b..31db03aadb 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -34,52 +34,28 @@ typedef struct WAVVoiceOut { HWVoiceOut hw; FILE *f; int64_t old_ticks; - void *pcm_buf; int total_samples; } WAVVoiceOut; -static size_t wav_run_out(HWVoiceOut *hw, size_t live) +static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; - size_t rpos, decr, samples; - uint8_t *dst; - struct st_sample *src; int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t ticks = now - wav->old_ticks; int64_t bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - if (bytes > INT_MAX) { - samples = INT_MAX >> hw->info.shift; - } - else { - samples = bytes >> hw->info.shift; - } - + bytes = MIN(bytes, len); + bytes = bytes >> hw->info.shift << hw->info.shift; wav->old_ticks = now; - decr = MIN (live, samples); - samples = decr; - rpos = hw->rpos; - while (samples) { - int left_till_end_samples = hw->samples - rpos; - int convert_samples = MIN (samples, left_till_end_samples); - src = hw->mix_buf + rpos; - dst = advance (wav->pcm_buf, rpos << hw->info.shift); - - hw->clip (dst, src, convert_samples); - if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) { - dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n", - convert_samples << hw->info.shift, strerror (errno)); - } - - rpos = (rpos + convert_samples) % hw->samples; - samples -= convert_samples; - wav->total_samples += convert_samples; + if (bytes && fwrite(buf, bytes, 1, wav->f) != 1) { + dolog("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n", + bytes, strerror(errno)); } - hw->rpos = rpos; - return decr; + wav->total_samples += bytes >> hw->info.shift; + return bytes; } /* VICE code: Store number as little endian. */ @@ -135,13 +111,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, audio_pcm_init_info (&hw->info, &wav_as); hw->samples = 1024; - wav->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); - if (!wav->pcm_buf) { - dolog("Could not allocate buffer (%zu bytes)\n", - hw->samples << hw->info.shift); - return -1; - } - le_store (hdr + 22, hw->info.nchannels, 2); le_store (hdr + 24, hw->info.freq, 4); le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4); @@ -151,8 +120,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, if (!wav->f) { dolog ("Failed to open wave file `%s'\nReason: %s\n", wav_path, strerror(errno)); - g_free (wav->pcm_buf); - wav->pcm_buf = NULL; return -1; } @@ -206,9 +173,6 @@ static void wav_fini_out (HWVoiceOut *hw) wav->f, strerror (errno)); } wav->f = NULL; - - g_free (wav->pcm_buf); - wav->pcm_buf = NULL; } static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...) @@ -232,7 +196,7 @@ static void wav_audio_fini (void *opaque) static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, - .run_out = wav_run_out, + .write = wav_write_out, .ctl_out = wav_ctl_out, }; From patchwork Wed Jan 16 23:37:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767169 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45B8F91E for ; Thu, 17 Jan 2019 00:00:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 34C622FC03 for ; Thu, 17 Jan 2019 00:00:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 291CB2FC96; Thu, 17 Jan 2019 00:00:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 964172FC8E for ; Thu, 17 Jan 2019 00:00:29 +0000 (UTC) Received: from localhost ([127.0.0.1]:36801 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv6i-0005Fy-Gn for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:00:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58207) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul4-0004MD-Rx for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul3-0003Od-IH for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:39776) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjukz-0003Dw-Kj for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:03 -0500 Received: by mail-wm1-x341.google.com with SMTP id y8so3854222wmi.4 for ; Wed, 16 Jan 2019 15:37:58 -0800 (PST) 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=P3sISsyPGyI6dDd861yACBt9mzegFzKQghZpd8A4G8Q=; b=ZvF3OS5TZD0g+mR5tzAZzBZrS4SCSVaw3SAz+QeDctZ9uuHAxx+3TjEhIpNaz+EGdb T223Gknw2lapA2KbPGXcOgToTJ+/Rp0crvwMVx3mQl3hGa7maYFEBP8agJMB5QYoXfis qT2QMNbFTNOw21XvX/xzRlMvSVUyTGXN8vaOuXdR7tz17Xaf5gQ/FgyxsH2k9KjCo8x2 x/wqImueN5+rg8OltsHkydVMa0irRihtw6v1b8/LHwweRSG/J6eXMLP0kbaXYjdYtSb8 W/+CD7q6lKeN7drPuoveiSB+8ynHJIU+Bu1Z3QXxwkJ1RYcSI4PI3/Zyja8i5999Z3ul qbDQ== 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=P3sISsyPGyI6dDd861yACBt9mzegFzKQghZpd8A4G8Q=; b=IZfqB6a3hR025Brn5l/FJWRHx6GEqAVIdCV4seHz834gGhmXqBlGjcs10bcVPrG/f8 x2szjT31kQRkOfiXAj+rA3Y0B2zQAG1at29xzcvh1OC6ZAZc9skgR+GhJ2JsnCQZstKw 2aExVsiNKov89Js77fAdLF9ktX7DkkG9hTPwsDBOIYjawMZxeguzgUyKiTU/FhLAGGZ/ JwMgJhk9WBdGctRWylbCp7nzs1rs/ePV+TeHCUvHn0G2nBETLtaoSDsaDmrRRVnWAmJj IuPzIICRAilLULXkW5LtNmm69EcHr9niTszaMA0SyQOxeqIlTG0FQZrbPtOKA7lUYCot 3jiQ== X-Gm-Message-State: AJcUukcy1U8lfA3B7mwKW4JbHtK9rHFsIRJaOcEVaJT2WYGA3wEPM4Qi LP6uE/10dJycONb1AHCOXCw2MIWw7wY= X-Google-Smtp-Source: ALg8bN7jsG95eolsnyvXDKs0RDlhW5s8ggZIqIzpSl3bv9OstAPAcTh9gdKQatUcLVoyJKQO240y3g== X-Received: by 2002:a1c:7f0c:: with SMTP id a12mr9050991wmd.89.1547681877657; Wed, 16 Jan 2019 15:37:57 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:57 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:09 +0100 Message-Id: <145498a842625fd7e025660dafce06db2edaf196.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v3 36/50] audio: remove remains of the old backend api X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 7 ------- audio/audio.c | 42 ++++++------------------------------------ 2 files changed, 6 insertions(+), 43 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 056c63d45c..1f6ec15e18 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -152,7 +152,6 @@ struct audio_driver { struct audio_pcm_ops { int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque); void (*fini_out)(HWVoiceOut *hw); - size_t (*run_out)(HWVoiceOut *hw, size_t live); size_t (*write) (HWVoiceOut *hw, void *buf, size_t size); /* * get a buffer that after later can be passed to put_buffer_out; optional @@ -170,7 +169,6 @@ struct audio_pcm_ops { int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); - size_t (*run_in)(HWVoiceIn *hw); size_t (*read) (HWVoiceIn *hw, void *buf, size_t size); void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); @@ -236,11 +234,6 @@ audio_driver *audio_driver_lookup(const char *name); void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); -size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw); - -size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, - size_t live, size_t pending); - int audio_bug (const char *funcname, int cond); void *audio_calloc (const char *funcname, int nmemb, size_t size); diff --git a/audio/audio.c b/audio/audio.c index f4d538618f..8bfc122e60 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -542,7 +542,7 @@ static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw) return m; } -size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) +static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) { size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); if (audio_bug(__func__, live > hw->samples)) { @@ -552,29 +552,7 @@ size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) return live; } -size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, - size_t live, size_t pending) -{ - size_t left = hw->samples - pending; - size_t len = MIN (left, live); - size_t clipped = 0; - - while (len) { - struct st_sample *src = hw->mix_buf + hw->rpos; - uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift); - size_t samples_till_end_of_buf = hw->samples - hw->rpos; - size_t samples_to_clip = MIN (len, samples_till_end_of_buf); - - hw->clip (dst, src, samples_to_clip); - - hw->rpos = (hw->rpos + samples_to_clip) % hw->samples; - len -= samples_to_clip; - clipped += samples_to_clip; - } - return clipped; -} - -static void audio_pcm_hw_clip_out2(HWVoiceOut *hw, void *pcm_buf, size_t len) +static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) { size_t clipped = 0; size_t pos = hw->rpos; @@ -1079,7 +1057,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) void *buf = hw->pcm_ops->get_buffer_out(hw, &size); decr = MIN(size >> hw->info.shift, live); - audio_pcm_hw_clip_out2(hw, buf, decr); + audio_pcm_hw_clip_out(hw, buf, decr); proc = hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shift) >> hw->info.shift; @@ -1142,11 +1120,7 @@ static void audio_run_out (AudioState *s) } prev_rpos = hw->rpos; - if (hw->pcm_ops->run_out) { - played = hw->pcm_ops->run_out(hw, live); - } else { - played = audio_pcm_hw_run_out(hw, live); - } + played = audio_pcm_hw_run_out(hw, live); replay_audio_out(&played); if (audio_bug(__func__, hw->rpos >= hw->samples)) { dolog("hw->rpos=%zu hw->samples=%zu played=%zu\n", @@ -1243,12 +1217,8 @@ static void audio_run_in (AudioState *s) size_t captured = 0, min; if (replay_mode != REPLAY_MODE_PLAY) { - if (hw->pcm_ops->run_in) { - captured = hw->pcm_ops->run_in(hw); - } else { - captured = audio_pcm_hw_run_in( - hw, hw->samples - audio_pcm_hw_get_live_in(hw)); - } + captured = audio_pcm_hw_run_in( + hw, hw->samples - audio_pcm_hw_get_live_in(hw)); } replay_audio_in(&captured, hw->conv_buf, &hw->wpos, hw->samples); From patchwork Wed Jan 16 23:37:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767201 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E1681390 for ; Thu, 17 Jan 2019 00:13:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3BBD2FC3B for ; Thu, 17 Jan 2019 00:13:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1D7A2FC61; Thu, 17 Jan 2019 00:13:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CDBB52FC3B for ; Thu, 17 Jan 2019 00:13:46 +0000 (UTC) Received: from localhost ([127.0.0.1]:40046 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvJa-0007RR-1Z for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:13:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58416) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulA-0004Rk-25 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003QW-5q for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]:46712) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-0003F2-Ne for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x431.google.com with SMTP id l9so8888786wrt.13 for ; Wed, 16 Jan 2019 15:37:59 -0800 (PST) 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=aNKDEwsuARmI/kp7YXNTmsNsmLKMPGDdDxXvRErSqaw=; b=e5q3KXsL3dJswiowVMnwF7fYMXaqMMN0reobBw/reI6QhX/ldi9VvCx0D8O9ABte4E 0l6+9t+6kONoO2gbrhN6dewJZLu3GHhtoCDoFLG9FXQ7a7lN1VQcp0GRmVWHqJ0JocZj HuHUfscaLsPomlqUfGPghMgf8V3T/FY1ig8vkzv04uTLl3gkk6yBvIqDUWaOd9jra9t0 n7+fhEXNbuQW4hO4Qa3nAZKtqq6tIUeNzekCx/IOtrDrRc19+AauTNXdph2TQGdCODvN GtriVhZD4l2OT2Tx44cOmL55rDGQxpiP/mv6ql0v5b0UlSoxCg5DPlhhmixhAtRr15rA Rmqw== 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=aNKDEwsuARmI/kp7YXNTmsNsmLKMPGDdDxXvRErSqaw=; b=l4FBmwn5MV5JH61Nfp9YtmxcBi3g4wrlH9jejYSI8zEOm67QHDbVQpPwIEdpW1gV23 XlIHAp12ve5cmbavkk19oTThbjdOlHkmDFKoRdPRyzNsgbx6ZoqjAjHLllKd/FW27V22 71cdSZwnMSD2wX6NYAF1nT29JiaV++LOcdYxHzFj0u0GnAOMkaHSR+Td4wp6ejo8g591 s1mTPNw2NqG0F+iHkKVPP1BKmGiI4CXX6h0l/72ak0GG80wxq/bAwQJbQIukXORPUsGX oNE+ViqLeBBcD2HdnyudEW0xhWQ6Yr40DvOi+5f9Y2pyQ7cJ+TCFRUtkYjUn3AKu3Ikv QIhw== X-Gm-Message-State: AJcUukfQvpX18Ybh3eAdBdrEqKWg8Xh6nclmKLxPGSxLUHiPgbzAv+nI hiBT5CnuuhTH7XBy7snnRxedJCEcFi4= X-Google-Smtp-Source: ALg8bN6SH5/S1mVCwzuRzyQG7Jcy8FzJnVPisGrGwfEsH37b0hY4dhNqkbFq+SrtGmTyzI4ee2vGqw== X-Received: by 2002:adf:dfd1:: with SMTP id q17mr9967922wrn.27.1547681878400; Wed, 16 Jan 2019 15:37:58 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:58 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:10 +0100 Message-Id: <4d2457aead94211b435d153732e987cc75b0eabd.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::431 Subject: [Qemu-devel] [PATCH v3 37/50] audio: unify input and output mixeng buffer management X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Usage notes: hw->samples became hw->{mix,conv}_buf->size, except before initialization (audio_pcm_hw_alloc_resources_*), hw->samples gives the initial size of the STSampleBuffer. The next commit tries to fix this inconsistency. Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 12 ++-- audio/audio_template.h | 19 +++--- audio/audio.c | 130 ++++++++++++++++++++--------------------- audio/ossaudio.c | 2 +- 4 files changed, 80 insertions(+), 83 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 1f6ec15e18..97d159f28e 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -51,6 +51,11 @@ struct audio_pcm_info { typedef struct SWVoiceCap SWVoiceCap; +typedef struct STSampleBuffer { + size_t pos, size; + st_sample samples[]; +} STSampleBuffer; + typedef struct HWVoiceOut { AudioState *s; int enabled; @@ -59,11 +64,9 @@ typedef struct HWVoiceOut { struct audio_pcm_info info; f_sample *clip; - - size_t rpos; uint64_t ts_helper; - struct st_sample *mix_buf; + STSampleBuffer *mix_buf; void *buf_emul; size_t pos_emul, pending_emul, size_emul; @@ -83,11 +86,10 @@ typedef struct HWVoiceIn { t_sample *conv; - size_t wpos; size_t total_samples_captured; uint64_t ts_helper; - struct st_sample *conv_buf; + STSampleBuffer *conv_buf; void *buf_emul; size_t pos_emul, pending_emul, size_emul; diff --git a/audio/audio_template.h b/audio/audio_template.h index fcab583cfc..83ffc62183 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -76,16 +76,15 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) HWBUF = NULL; } -static bool glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) +static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { - HWBUF = audio_calloc(__func__, hw->samples, sizeof(struct st_sample)); - if (!HWBUF) { - dolog("Could not allocate " NAME " buffer (%zu samples)\n", - hw->samples); - return false; + size_t samples = hw->samples; + if (audio_bug(__func__, samples == 0)) { + dolog("Attempted to allocate empty buffer\n"); } - return true; + HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples); + HWBUF->size = samples; } static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) @@ -104,7 +103,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) { int samples; - samples = ((int64_t) sw->hw->samples << 32) / sw->ratio; + samples = ((int64_t) sw->HWBUF->size << 32) / sw->ratio; sw->buf = audio_calloc(__func__, samples, sizeof(struct st_sample)); if (!sw->buf) { @@ -280,9 +279,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, [hw->info.swap_endianness] [audio_bits_to_index (hw->info.bits)]; - if (!glue(audio_pcm_hw_alloc_resources_, TYPE)(hw)) { - goto err1; - } + glue(audio_pcm_hw_alloc_resources_, TYPE)(hw); QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries); glue (s->nb_hw_voices_, TYPE) -= 1; diff --git a/audio/audio.c b/audio/audio.c index 8bfc122e60..b5dbf5228b 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -545,8 +545,8 @@ static size_t audio_pcm_hw_find_min_in (HWVoiceIn *hw) static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) { size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); - if (audio_bug(__func__, live > hw->samples)) { - dolog("live=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(__func__, live > hw->conv_buf->size)) { + dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size); return 0; } return live; @@ -555,17 +555,17 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) { size_t clipped = 0; - size_t pos = hw->rpos; + size_t pos = hw->mix_buf->pos; while (len) { - st_sample *src = hw->mix_buf + pos; + st_sample *src = hw->mix_buf->samples + pos; uint8_t *dst = advance (pcm_buf, clipped << hw->info.shift); - size_t samples_till_end_of_buf = hw->samples - pos; + size_t samples_till_end_of_buf = hw->mix_buf->size - pos; size_t samples_to_clip = MIN(len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip); - pos = (pos + samples_to_clip) % hw->samples; + pos = (pos + samples_to_clip) % hw->mix_buf->size; len -= samples_to_clip; clipped += samples_to_clip; } @@ -580,17 +580,17 @@ static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw) ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired; ssize_t rpos; - if (audio_bug(__func__, live < 0 || live > hw->samples)) { - dolog("live=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(__func__, live < 0 || live > hw->conv_buf->size)) { + dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size); return 0; } - rpos = hw->wpos - live; + rpos = hw->conv_buf->pos - live; if (rpos >= 0) { return rpos; } else { - return hw->samples + rpos; + return hw->conv_buf->size + rpos; } } @@ -600,11 +600,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; struct st_sample *src, *dst = sw->buf; - rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; + rpos = audio_pcm_sw_get_rpos_in(sw) % hw->conv_buf->size; live = hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(__func__, live > hw->samples)) { - dolog("live_in=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(__func__, live > hw->conv_buf->size)) { + dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size); return 0; } @@ -617,11 +617,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) swlim = MIN (swlim, samples); while (swlim) { - src = hw->conv_buf + rpos; - if (hw->wpos > rpos) { - isamp = hw->wpos - rpos; + src = hw->conv_buf->samples + rpos; + if (hw->conv_buf->pos > rpos) { + isamp = hw->conv_buf->pos - rpos; } else { - isamp = hw->samples - rpos; + isamp = hw->conv_buf->size - rpos; } if (!isamp) { @@ -631,7 +631,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) st_rate_flow (sw->rate, src, dst, &isamp, &osamp); swlim -= osamp; - rpos = (rpos + isamp) % hw->samples; + rpos = (rpos + isamp) % hw->conv_buf->size; dst += osamp; ret += osamp; total += isamp; @@ -679,8 +679,8 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live) if (nb_live1) { size_t live = smin; - if (audio_bug(__func__, live > hw->samples)) { - dolog("live=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(__func__, live > hw->mix_buf->size)) { + dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size); return 0; } return live; @@ -700,11 +700,11 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return size; } - hwsamples = sw->hw->samples; + hwsamples = sw->hw->mix_buf->size; live = sw->total_hw_samples_mixed; if (audio_bug(__func__, live > hwsamples)) { - dolog("live=%zu hw->samples=%zu\n", live, hwsamples); + dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples); return 0; } @@ -715,7 +715,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return 0; } - wpos = (sw->hw->rpos + live) % hwsamples; + wpos = (sw->hw->mix_buf->pos + live) % hwsamples; samples = size >> sw->info.shift; dead = hwsamples - live; @@ -741,7 +741,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) st_rate_flow_mix ( sw->rate, sw->buf + pos, - sw->hw->mix_buf + wpos, + sw->hw->mix_buf->samples + wpos, &isamp, &osamp ); @@ -869,7 +869,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) int AUD_get_buffer_size_out (SWVoiceOut *sw) { - return sw->hw->samples << sw->hw->info.shift; + return sw->hw->mix_buf->size << sw->hw->info.shift; } void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -970,8 +970,9 @@ static size_t audio_get_avail (SWVoiceIn *sw) } live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(__func__, live > sw->hw->samples)) { - dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); + if (audio_bug(__func__, live > sw->hw->conv_buf->size)) { + dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live, + sw->hw->conv_buf->size); return 0; } @@ -994,12 +995,13 @@ static size_t audio_get_free(SWVoiceOut *sw) live = sw->total_hw_samples_mixed; - if (audio_bug(__func__, live > sw->hw->samples)) { - dolog("live=%zu sw->hw->samples=%zu\n", live, sw->hw->samples); + if (audio_bug(__func__, live > sw->hw->mix_buf->size)) { + dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live, + sw->hw->mix_buf->size); return 0; } - dead = sw->hw->samples - live; + dead = sw->hw->mix_buf->size - live; #ifdef DEBUG_OUT dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n", @@ -1024,12 +1026,12 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, n = samples; while (n) { - size_t till_end_of_hw = hw->samples - rpos2; + size_t till_end_of_hw = hw->mix_buf->size - rpos2; size_t to_write = MIN(till_end_of_hw, n); size_t bytes = to_write << hw->info.shift; size_t written; - sw->buf = hw->mix_buf + rpos2; + sw->buf = hw->mix_buf->samples + rpos2; written = audio_pcm_sw_write (sw, NULL, bytes); if (written - bytes) { dolog("Could not mix %zu bytes into a capture " @@ -1038,14 +1040,14 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, break; } n -= to_write; - rpos2 = (rpos2 + to_write) % hw->samples; + rpos2 = (rpos2 + to_write) % hw->mix_buf->size; } } } - n = MIN(samples, hw->samples - rpos); - mixeng_clear(hw->mix_buf + rpos, n); - mixeng_clear(hw->mix_buf, samples - n); + n = MIN(samples, hw->mix_buf->size - rpos); + mixeng_clear(hw->mix_buf->samples + rpos, n); + mixeng_clear(hw->mix_buf->samples, samples - n); } static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) @@ -1063,7 +1065,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) live -= proc; clipped += proc; - hw->rpos = (hw->rpos + proc) % hw->samples; + hw->mix_buf->pos = (hw->mix_buf->pos + proc) % hw->mix_buf->size; if (proc == 0 || proc < decr) { break; @@ -1087,8 +1089,8 @@ static void audio_run_out (AudioState *s) live = 0; } - if (audio_bug(__func__, live > hw->samples)) { - dolog ("live=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(__func__, live > hw->mix_buf->size)) { + dolog ("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size); continue; } @@ -1119,13 +1121,13 @@ static void audio_run_out (AudioState *s) continue; } - prev_rpos = hw->rpos; + prev_rpos = hw->mix_buf->pos; played = audio_pcm_hw_run_out(hw, live); replay_audio_out(&played); - if (audio_bug(__func__, hw->rpos >= hw->samples)) { - dolog("hw->rpos=%zu hw->samples=%zu played=%zu\n", - hw->rpos, hw->samples, played); - hw->rpos = 0; + if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) { + dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n", + hw->mix_buf->pos, hw->mix_buf->size, played); + hw->mix_buf->pos = 0; } #ifdef DEBUG_OUT @@ -1182,6 +1184,7 @@ static void audio_run_out (AudioState *s) static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) { size_t conv = 0; + STSampleBuffer *conv_buf = hw->conv_buf; while (samples) { size_t proc; @@ -1195,10 +1198,10 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) } proc = MIN(size >> hw->info.shift, - hw->samples - hw->wpos); + conv_buf->size - conv_buf->pos); - hw->conv(hw->conv_buf + hw->wpos, buf, proc); - hw->wpos = (hw->wpos + proc) % hw->samples; + hw->conv(conv_buf->samples + conv_buf->pos, buf, proc); + conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size; samples -= proc; conv += proc; @@ -1218,9 +1221,10 @@ static void audio_run_in (AudioState *s) if (replay_mode != REPLAY_MODE_PLAY) { captured = audio_pcm_hw_run_in( - hw, hw->samples - audio_pcm_hw_get_live_in(hw)); + hw, hw->conv_buf->size - audio_pcm_hw_get_live_in(hw)); } - replay_audio_in(&captured, hw->conv_buf, &hw->wpos, hw->samples); + replay_audio_in(&captured, hw->conv_buf->samples, &hw->conv_buf->pos, + hw->conv_buf->size); min = audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min; @@ -1251,14 +1255,14 @@ static void audio_run_capture (AudioState *s) SWVoiceOut *sw; captured = live = audio_pcm_hw_get_live_out (hw, NULL); - rpos = hw->rpos; + rpos = hw->mix_buf->pos; while (live) { - size_t left = hw->samples - rpos; + size_t left = hw->mix_buf->size - rpos; size_t to_capture = MIN(live, left); struct st_sample *src; struct capture_callback *cb; - src = hw->mix_buf + rpos; + src = hw->mix_buf->samples + rpos; hw->clip (cap->buf, src, to_capture); mixeng_clear (src, to_capture); @@ -1266,10 +1270,10 @@ static void audio_run_capture (AudioState *s) cb->ops.capture (cb->opaque, cap->buf, to_capture << hw->info.shift); } - rpos = (rpos + to_capture) % hw->samples; + rpos = (rpos + to_capture) % hw->mix_buf->size; live -= to_capture; } - hw->rpos = rpos; + hw->mix_buf->pos = rpos; for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (!sw->active && sw->empty) { @@ -1317,7 +1321,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) ssize_t start; if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->samples << hw->info.shift; + size_t calc_size = hw->conv_buf->size << hw->info.shift; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; hw->pos_emul = hw->pending_emul = 0; @@ -1353,7 +1357,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 = hw->samples << hw->info.shift; + size_t calc_size = hw->mix_buf->size << hw->info.shift; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; @@ -1761,21 +1765,16 @@ CaptureVoiceOut *AUD_add_capture( /* XXX find a more elegant way */ hw->samples = 4096 * 4; - hw->mix_buf = audio_calloc(__func__, hw->samples, - sizeof(struct st_sample)); - if (!hw->mix_buf) { - dolog("Could not allocate capture mix buffer (%zu samples)\n", - hw->samples); - goto err2; - } + audio_pcm_hw_alloc_resources_out(hw); audio_pcm_init_info (&hw->info, as); - cap->buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift); + cap->buf = audio_calloc(__func__, hw->mix_buf->size, + 1 << hw->info.shift); if (!cap->buf) { dolog ("Could not allocate capture buffer " "(%zu samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); + hw->mix_buf->size, 1 << hw->info.shift); goto err3; } @@ -1795,7 +1794,6 @@ CaptureVoiceOut *AUD_add_capture( err3: g_free (cap->hw.mix_buf); - err2: g_free (cap); err1: g_free (cb); diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 774a41fbf9..957d14eb8e 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -584,7 +584,7 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } - audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->samples); + audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->mix_buf->size); trig = PCM_ENABLE_OUTPUT; if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { oss_logerr ( From patchwork Wed Jan 16 23:37:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767207 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 12F6413A4 for ; Thu, 17 Jan 2019 00:16:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0338D2E4ED for ; Thu, 17 Jan 2019 00:16:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EAE242FC9F; Thu, 17 Jan 2019 00:16:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A62252E4ED for ; Thu, 17 Jan 2019 00:16:55 +0000 (UTC) Received: from localhost ([127.0.0.1]:40818 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvMZ-0001XD-Sv for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:16:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58531) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulC-0004Uw-Pf for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003TB-Ss for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:34223) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003Gf-D0 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wm1-x343.google.com with SMTP id y185so2237631wmd.1 for ; Wed, 16 Jan 2019 15:38:00 -0800 (PST) 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=gb3gtq3AuwqtG99gGovRiMdFDeVs8xqZdvLOvde21Wk=; b=WiJMwxleBWwb8C6FwX3Qu7j9w5BTfPhGCqSA5Zzlp1PHRunU7th5wqUyF0z15n2IKm 1Je3DOJn3Up91eer3xO4WulhNOJCAIdnBjw6iWJzjlp+NbFob24kHvhnm16YbTCQelAw rh2u2qzdRbnIhRc6lHMSjhkh2rBwNxlU3RolH1QhSwCTy0SRnR9Hgi56JcKiBxQBdIku 6FUdBF9qR0677LIK7SVr/YWRMcj/NHaF5MtdkbhXmCxkW4oeSDytEcDUM8EG+EZ1WP/R +/R11gYS/mrOFNKCn3A/7x4PspE21ZYvKnnY0c9dyFLTPDl4PnotMdIXCIs1lR2dsiaI e46g== 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=gb3gtq3AuwqtG99gGovRiMdFDeVs8xqZdvLOvde21Wk=; b=KQZa8gz5hKXvgY39gs+iwbTEJeJndo9sjaZzW8/zXeD6ulixpfv1eLS4b6b0AWDJWA 79eL3pSRD3f68G+HmHpo+PEHmTF/u01JmDpxIBBuc/WdSryNXaOs5+nMBFo6mVwl+Hbd l6GYzBVcuuQovu4DjfjCv/oYjhoI/nzpLr6Cs9n1Uy490XXtdk8ooe1Z7xC9ojwpnB9d C8e29G2o98NJFXiRSKPSowb/jT5Gp7WT4AFSpxby4HgM9aA5iubkjMZCp3QnW2uwaDV+ S9H6v7gzDdWojcSEBHi4QKwlZ4kc/8rD+s/vzscaF4isGc3KJIlJZ46g2cPniKuAp7Ul IzZQ== X-Gm-Message-State: AJcUukeTNrgvVFHTVE3pgidFFq45pyGx5HH/CiFwrNrTYFwpHpocsM+g ZMUHNv9gqaYQrKEUUAYbogJLDxH9pXA= X-Google-Smtp-Source: ALg8bN6c6NgBpO33zUouppuPqMOF+hBPH6tuvUC05V6pGJ2DrFYMdrK6W4s6dEdCY6QyRk2vOGCtJw== X-Received: by 2002:a1c:e242:: with SMTP id z63mr9140759wmg.2.1547681879493; Wed, 16 Jan 2019 15:37:59 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:58 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:11 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 38/50] audio: remove hw->samples, buffer_size_in/out pcm_ops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch removes the samples member from HWVoiceIn and HWVoiceOut. Backends can specify buffer size via the newly added buffer_size_in and buffer_size_out functions in audio_pcm_ops. They are optional, if not defined qemu will fall back to some built-in constant. Signed-off-by: Kővágó, Zoltán --- Notes: Not sure if this is necessary. At first it seemed like a good idea to have a function so that backends can compute the size on demand when needed and things like that, but currently it's just a burden. The only good feature is that it allows a backend to not define a function and let the audio subsystem choose a default value, but the same could be achieved by specifying that hw->samples = 0 means use a default value. So if you guys agree, I'll remove this patch. Maybe add an -audiodev parameter to change it, overriding whatever the backends supplies. audio/audio_int.h | 5 +++-- audio/audio_template.h | 24 +++++++++++++++--------- audio/dsound_template.h | 8 +++++++- audio/alsaaudio.c | 20 ++++++++++++++++++-- audio/audio.c | 2 -- audio/coreaudio.c | 10 +++++++++- audio/dsoundaudio.c | 4 ++++ audio/noaudio.c | 2 -- audio/ossaudio.c | 22 +++++++++++++++++++--- audio/paaudio.c | 21 +++++++++++++++++---- audio/sdlaudio.c | 10 +++++++++- audio/spiceaudio.c | 14 ++++++++++++-- audio/wavaudio.c | 1 - 13 files changed, 113 insertions(+), 30 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 97d159f28e..a5263966a8 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -70,7 +70,6 @@ typedef struct HWVoiceOut { void *buf_emul; size_t pos_emul, pending_emul, size_emul; - size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head; int ctl_caps; @@ -93,7 +92,6 @@ typedef struct HWVoiceIn { void *buf_emul; size_t pos_emul, pending_emul, size_emul; - size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; int ctl_caps; struct audio_pcm_ops *pcm_ops; @@ -155,6 +153,8 @@ struct audio_pcm_ops { int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque); void (*fini_out)(HWVoiceOut *hw); size_t (*write) (HWVoiceOut *hw, void *buf, size_t size); + /* get the optimal buffer size in samples; optional */ + size_t (*buffer_size_out)(HWVoiceOut *hw); /* * get a buffer that after later can be passed to put_buffer_out; optional * returns the buffer, and writes it's size to size (in bytes) @@ -172,6 +172,7 @@ struct audio_pcm_ops { int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); size_t (*read) (HWVoiceIn *hw, void *buf, size_t size); + size_t (*buffer_size_in)(HWVoiceIn *hw); void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); diff --git a/audio/audio_template.h b/audio/audio_template.h index 83ffc62183..07ce9ce51f 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -78,7 +78,20 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { - size_t samples = hw->samples; + size_t samples; + if (!hw->pcm_ops) { + /* + * We should only end up here when using wavcapture hmp command (and not + * the wavcapture audio backend). + * It needs a lot of samples, otherwise you'll end up with "Could not + * mix X bytes into a capture buffer" warnings and a garbled capture. + */ + samples = 4096 * 4; + } else if (hw->pcm_ops->glue(buffer_size_, TYPE)) { + samples = hw->pcm_ops->glue(buffer_size_, TYPE)(hw); + } else { + samples = 1024; /* todo better default */ + } if (audio_bug(__func__, samples == 0)) { dolog("Attempted to allocate empty buffer\n"); } @@ -264,11 +277,6 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, goto err0; } - if (audio_bug(__func__, hw->samples <= 0)) { - dolog("hw->samples=%zd\n", hw->samples); - goto err1; - } - #ifdef DAC hw->clip = mixeng_clip #else @@ -288,9 +296,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, #endif return hw; - err1: - glue (hw->pcm_ops->fini_, TYPE) (hw); - err0: +err0: g_free (hw); return NULL; } diff --git a/audio/dsound_template.h b/audio/dsound_template.h index ff5a1f85fd..6a10b6751b 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -254,7 +254,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, ); } hw->size_emul = bc.dwBufferBytes; - hw->samples = bc.dwBufferBytes >> hw->info.shift; + ds->samples = bc.dwBufferBytes >> hw->info.shift; ds->s = s; #ifdef DEBUG_DSOUND @@ -268,6 +268,12 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, return -1; } +static size_t glue(dsound_buffer_size_, TYPE)(HWVOICE *hw) +{ + DSOUNDVOICE *ds = (DSOUNDVOICE *) hw; + return ds->samples; +} + #undef NAME #undef NAME2 #undef TYPE diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index c23dedd4bf..1489f50dfd 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -44,6 +44,7 @@ struct pollhlp { typedef struct ALSAVoiceOut { HWVoiceOut hw; snd_pcm_t *handle; + size_t samples; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceOut; @@ -51,6 +52,7 @@ typedef struct ALSAVoiceOut { typedef struct ALSAVoiceIn { HWVoiceIn hw; snd_pcm_t *handle; + size_t samples; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceIn; @@ -695,7 +697,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.endianness = obt.endianness; audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + alsa->samples = obt.samples; alsa->pollhlp.s = hw->s; alsa->handle = handle; @@ -703,6 +705,12 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as, return 0; } +static size_t alsa_buffer_size_out(HWVoiceOut *hw) +{ + ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; + return alsa->samples; +} + #define VOICE_CTL_PAUSE 0 #define VOICE_CTL_PREPARE 1 #define VOICE_CTL_START 2 @@ -789,7 +797,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt_as.endianness = obt.endianness; audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + alsa->samples = obt.samples; alsa->pollhlp.s = hw->s; alsa->handle = handle; @@ -797,6 +805,12 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) return 0; } +static size_t alsa_buffer_size_in(HWVoiceIn *hw) +{ + ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; + return alsa->samples; +} + static void alsa_fini_in (HWVoiceIn *hw) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; @@ -933,11 +947,13 @@ static void alsa_audio_fini (void *opaque) static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, + .buffer_size_out = alsa_buffer_size_out, .write = alsa_write, .ctl_out = alsa_ctl_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, + .buffer_size_in = alsa_buffer_size_in, .read = alsa_read, .ctl_in = alsa_ctl_in, }; diff --git a/audio/audio.c b/audio/audio.c index b5dbf5228b..4b5c1712e3 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1763,8 +1763,6 @@ CaptureVoiceOut *AUD_add_capture( QLIST_INIT (&hw->sw_head); QLIST_INIT (&cap->cb_head); - /* XXX find a more elegant way */ - hw->samples = 4096 * 4; audio_pcm_hw_alloc_resources_out(hw); audio_pcm_init_info (&hw->info, as); diff --git a/audio/coreaudio.c b/audio/coreaudio.c index e32c5b62fd..693f6f11d7 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -43,6 +43,7 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; + size_t samples; } coreaudioVoiceOut; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 @@ -557,7 +558,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, "Could not get device buffer frame size\n"); return -1; } - hw->samples = (pdo->has_buffer_count ? pdo->buffer_count : 4) * + core->samples = (pdo->has_buffer_count ? pdo->buffer_count : 4) * core->audioDevicePropertyBufferFrameSize; /* get StreamFormat */ @@ -617,6 +618,12 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, return 0; } +static size_t coreaudio_buffer_size_out(HWVoiceOut *hw) +{ + coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; + return core->samples; +} + static void coreaudio_fini_out (HWVoiceOut *hw) { OSStatus status; @@ -693,6 +700,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .write = coreaudio_write, + .buffer_size_out = coreaudio_buffer_size_out, .get_buffer_out = coreaudio_get_buffer_out, .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index 951152ecea..e030bb29b5 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -54,12 +54,14 @@ typedef struct { HWVoiceOut hw; LPDIRECTSOUNDBUFFER dsound_buffer; dsound *s; + size_t samples; } DSoundVoiceOut; typedef struct { HWVoiceIn hw; LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer; dsound *s; + size_t samples; } DSoundVoiceIn; static void dsound_log_hresult (HRESULT hr) @@ -672,6 +674,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_out = dsound_init_out, .fini_out = dsound_fini_out, .write = audio_generic_write, + .buffer_size_out = dsound_buffer_size_out, .get_buffer_out = dsound_get_buffer_out, .put_buffer_out = dsound_put_buffer_out, .ctl_out = dsound_ctl_out, @@ -679,6 +682,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .init_in = dsound_init_in, .fini_in = dsound_fini_in, .read = audio_generic_read, + .buffer_size_in = dsound_buffer_size_in, .get_buffer_in = dsound_get_buffer_in, .put_buffer_in = dsound_put_buffer_in, .ctl_in = dsound_ctl_in diff --git a/audio/noaudio.c b/audio/noaudio.c index 647558f54c..dc77d1aff5 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -58,7 +58,6 @@ static size_t no_write(HWVoiceOut *hw, void *buf, size_t len) static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { audio_pcm_init_info (&hw->info, as); - hw->samples = 1024; return 0; } @@ -77,7 +76,6 @@ static int no_ctl_out (HWVoiceOut *hw, int cmd, ...) static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) { audio_pcm_init_info (&hw->info, as); - hw->samples = 1024; return 0; } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 957d14eb8e..a93f97aa63 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -43,6 +43,7 @@ typedef struct OSSVoiceOut { int nfrags; int fragsize; int mmapped; + size_t samples; Audiodev *dev; } OSSVoiceOut; @@ -51,6 +52,7 @@ typedef struct OSSVoiceIn { int fd; int nfrags; int fragsize; + size_t samples; Audiodev *dev; } OSSVoiceIn; @@ -510,11 +512,11 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, obt.nfrags * obt.fragsize, hw->info.align + 1); } - hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->mmapped = 0; if (oopts->has_try_mmap && oopts->try_mmap) { - hw->size_emul = hw->samples << hw->info.shift; + hw->size_emul = oss->samples << hw->info.shift; hw->buf_emul = mmap ( NULL, hw->size_emul, @@ -562,6 +564,12 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, return 0; } +static size_t oss_buffer_size_out(HWVoiceOut *hw) +{ + OSSVoiceOut *oss = (OSSVoiceOut *) hw; + return oss->samples; +} + static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) { int trig; @@ -657,13 +665,19 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) obt.nfrags * obt.fragsize, hw->info.align + 1); } - hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; oss->fd = fd; oss->dev = dev; return 0; } +static size_t oss_buffer_size_in(HWVoiceIn *hw) +{ + OSSVoiceIn *oss = (OSSVoiceIn *) hw; + return oss->samples; +} + static void oss_fini_in (HWVoiceIn *hw) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; @@ -769,6 +783,7 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_out = oss_init_out, .fini_out = oss_fini_out, .write = oss_write, + .buffer_size_out = oss_buffer_size_out, .get_buffer_out = oss_get_buffer_out, .put_buffer_out = oss_put_buffer_out, .ctl_out = oss_ctl_out, @@ -776,6 +791,7 @@ static struct audio_pcm_ops oss_pcm_ops = { .init_in = oss_init_in, .fini_in = oss_fini_in, .read = oss_read, + .buffer_size_in = oss_buffer_size_in, .ctl_in = oss_ctl_in }; diff --git a/audio/paaudio.c b/audio/paaudio.c index bb1367fbae..cfa4e895c7 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -355,8 +355,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, } audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = pa->samples = audio_buffer_samples(g->dev->out, &obt_as, - 46440); + pa->samples = audio_buffer_samples(g->dev->out, &obt_as, 46440); return 0; @@ -364,6 +363,13 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, return -1; } +static size_t qpa_buffer_size_out(HWVoiceOut *hw) +{ + PAVoiceOut *pa = (PAVoiceOut *) hw; + return pa->samples; +} + + static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) { int error; @@ -397,8 +403,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) } audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = pa->samples = audio_buffer_samples(g->dev->in, &obt_as, - 46440); + pa->samples = audio_buffer_samples(g->dev->in, &obt_as, 46440); return 0; @@ -406,6 +411,12 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) return -1; } +static size_t qpa_buffer_size_in(HWVoiceIn *hw) +{ + PAVoiceIn *pa = (PAVoiceIn *) hw; + return pa->samples; +} + static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream) { int err; @@ -696,11 +707,13 @@ static struct audio_pcm_ops qpa_pcm_ops = { .init_out = qpa_init_out, .fini_out = qpa_fini_out, .write = qpa_write, + .buffer_size_out = qpa_buffer_size_out, .ctl_out = qpa_ctl_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .read = qpa_read, + .buffer_size_in = qpa_buffer_size_in, .ctl_in = qpa_ctl_in }; diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index 685cbc83b8..4df35ce31a 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -42,6 +42,7 @@ typedef struct SDLVoiceOut { HWVoiceOut hw; + size_t samples; } SDLVoiceOut; static struct SDLAudioState { @@ -363,7 +364,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.endianness = endianness; audio_pcm_init_info (&hw->info, &obt_as); - hw->samples = obt.samples; + sdl->samples = obt.samples; s->initialized = 1; s->exit = 0; @@ -371,6 +372,12 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as, return 0; } +static size_t sdl_buffer_size_out(HWVoiceOut *hw) +{ + SDLVoiceOut *sdl = (SDLVoiceOut *) hw; + return sdl->samples; +} + static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...) { (void) hw; @@ -439,6 +446,7 @@ static struct audio_pcm_ops sdl_pcm_ops = { .init_out = sdl_init_out, .fini_out = sdl_fini_out, .write = sdl_write, + .buffer_size_out = sdl_buffer_size_out, .get_buffer_out = sdl_get_buffer_out, .put_buffer_out = sdl_put_buffer_out_nowrite, .ctl_out = sdl_ctl_out, diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index d1605d3939..709245e453 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -133,7 +133,6 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, settings.endianness = AUDIO_HOST_ENDIANNESS; audio_pcm_init_info (&hw->info, &settings); - hw->samples = LINE_OUT_SAMPLES; out->active = 0; out->sin.base.sif = &playback_sif.base; @@ -144,6 +143,11 @@ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, return 0; } +static size_t line_out_buffer_size(HWVoiceOut *hw) +{ + return LINE_OUT_SAMPLES; +} + static void line_out_fini (HWVoiceOut *hw) { SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); @@ -248,7 +252,6 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) settings.endianness = AUDIO_HOST_ENDIANNESS; audio_pcm_init_info (&hw->info, &settings); - hw->samples = LINE_IN_SAMPLES; in->active = 0; in->sin.base.sif = &record_sif.base; @@ -259,6 +262,11 @@ static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) return 0; } +static size_t line_in_buffer_size(HWVoiceIn *hw) +{ + return LINE_IN_SAMPLES; +} + static void line_in_fini (HWVoiceIn *hw) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); @@ -329,6 +337,7 @@ static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, .fini_out = line_out_fini, .write = audio_generic_write, + .buffer_size_out = line_out_buffer_size, .get_buffer_out = line_out_get_buffer, .put_buffer_out = line_out_put_buffer, .ctl_out = line_out_ctl, @@ -336,6 +345,7 @@ static struct audio_pcm_ops audio_callbacks = { .init_in = line_in_init, .fini_in = line_in_fini, .read = line_in_read, + .buffer_size_in = line_in_buffer_size, .ctl_in = line_in_ctl, }; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 31db03aadb..0a0e76d2d9 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -110,7 +110,6 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, wav_as.endianness = 0; audio_pcm_init_info (&hw->info, &wav_as); - hw->samples = 1024; le_store (hdr + 22, hw->info.nchannels, 2); le_store (hdr + 24, hw->info.freq, 4); le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4); From patchwork Wed Jan 16 23:37:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767217 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C9076746 for ; Thu, 17 Jan 2019 00:25:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B81662F6B3 for ; Thu, 17 Jan 2019 00:25:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AC5902F71D; Thu, 17 Jan 2019 00:25:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EB9922F6B3 for ; Thu, 17 Jan 2019 00:25:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:43213 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvVN-0008FF-AM for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:25:57 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58396) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004R7-It for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Rm-Gj for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:43010) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003H3-2R for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x441.google.com with SMTP id r10so8917397wrs.10 for ; Wed, 16 Jan 2019 15:38:01 -0800 (PST) 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=lyszR7KJMR8mmgSavkPwk4sCvoCwM4cV8SrMD15fejE=; b=PFOOqXF59Kn68rfHukGmRKsuFeX6yuDXFZO/9goCga7O3Ht9XtRQ2NvrI2MztcxxIV AUoWMv2SdycDsVrNMJwzwcTtozvKjmjB/j+v7bsJjU90xiZ1zqgfvUo7EnxFjTQsYvNi RtpbLPzTmjd09rr2KDzm1ktmme+SLP1XTEwumOAgBJqQAdlSNDQkDdWS/lHtCatNC+U7 m+eKq+/5ubxGdXX+9bqtHI1da8Lp7frvOkf88vl1cgwbuKEcjWB5d+Qa9vlHSlp8Qxyl LzVpSo4JyFGVwpLO2RmbG2nDLuYn1vkFqgjJYAkrrXSWa7Do8HrNajhJOO++MEaUsFlE QXTQ== 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=lyszR7KJMR8mmgSavkPwk4sCvoCwM4cV8SrMD15fejE=; b=BSLmDpldg3aIwq+4IrMdKMrX8b7KcBUau210EKKIx6ngQMdDjDm90sUhsHH8COUmv6 ka8dQTim090ReJ7LNfg9LdpZU4lBjfSL4Fv3wsgCJ76+OI1320wveD95Yr9qygLcmf6R eJMNls6j78pne7VF/8ZJEqdx7vGLoSOPogemH/WtYgMbNjwmSnHcpVu9rGrg3jSNellX fsFJ5sWF3xwpFv8GSzP0hvka2+f69rUR3vtByriYgBOlWleN1tllju5Ho+oOj3YZIqUX rXCsYnv1iuheY0NKp/u10djiPSKSq1XNkPFbtu9YdcQxNlL9FyLcgbSNE3afj6J2CG+x CWSg== X-Gm-Message-State: AJcUuke3n3Y01TjBrvgAL4gG94RQ8iBSR3x5LC3CNF+65ni9F0fdpzQs D0lOZPGrICpVj8dHf6LqNLsvtBuZSh8= X-Google-Smtp-Source: ALg8bN4NquAhopY7vSWqi+1rWjy94ISazaO0Ad5JhWcwocp/vdt4Uhw9cKr0NtB7sy2B85d55pMDYA== X-Received: by 2002:adf:8484:: with SMTP id 4mr9393798wrg.249.1547681880292; Wed, 16 Jan 2019 15:38:00 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.37.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:37:59 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:12 +0100 Message-Id: <36a8ffaf72fe3574ce3336de91482390b3c04e3f.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 39/50] audio: common rate control code for timer based outputs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This commit removes the ad-hoc rate-limiting code from noaudio and wavaudio, and replaces them with a (slightly modified) code from spiceaudio. This way multiple write calls (for example when the circular buffer wraps around) do not cause problems. Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 9 +++++++++ audio/audio.c | 30 ++++++++++++++++++++++++++++ audio/noaudio.c | 49 +++++++++++++++++++++------------------------- audio/spiceaudio.c | 49 +++++++--------------------------------------- audio/wavaudio.c | 21 ++++++++++---------- 5 files changed, 78 insertions(+), 80 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index a5263966a8..236b523286 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -242,6 +242,15 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size); void audio_run(AudioState *s, const char *msg); +typedef struct RateCtl { + int64_t start_ticks; + int64_t bytes_sent; +} RateCtl; + +void audio_rate_start(RateCtl *rate); +size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, + size_t bytes_avail); + #define VOICE_ENABLE 1 #define VOICE_DISABLE 2 #define VOICE_VOLUME 3 diff --git a/audio/audio.c b/audio/audio.c index 4b5c1712e3..798541638e 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -2032,3 +2032,33 @@ const char *audio_get_id(QEMUSoundCard *card) return ""; } } + +void audio_rate_start(RateCtl *rate) +{ + memset(rate, 0, sizeof(RateCtl)); + rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +} + +size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, + size_t bytes_avail) +{ + int64_t now; + int64_t ticks; + int64_t bytes; + int64_t samples; + size_t ret; + + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + ticks = now - rate->start_ticks; + bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND); + samples = (bytes - rate->bytes_sent) >> info->shift; + if (samples < 0 || samples > 65536) { + AUD_log(NULL, "Resetting rate control (%" PRId64 " samples)", samples); + audio_rate_start(rate); + samples = 0; + } + + ret = MIN(samples << info->shift, bytes_avail); + rate->bytes_sent += ret; + return ret; +} diff --git a/audio/noaudio.c b/audio/noaudio.c index dc77d1aff5..b29929dac4 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -32,32 +32,26 @@ typedef struct NoVoiceOut { HWVoiceOut hw; - int64_t old_ticks; + RateCtl rate; } NoVoiceOut; typedef struct NoVoiceIn { HWVoiceIn hw; - int64_t old_ticks; + RateCtl rate; } NoVoiceIn; static size_t no_write(HWVoiceOut *hw, void *buf, size_t len) { NoVoiceOut *no = (NoVoiceOut *) hw; - int64_t now; - int64_t ticks; - int64_t bytes; - - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - ticks = now - no->old_ticks; - bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - - no->old_ticks = now; - return MIN(len, bytes); + return audio_rate_get_bytes(&hw->info, &no->rate, len); } static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { + NoVoiceOut *no = (NoVoiceOut *) hw; + audio_pcm_init_info (&hw->info, as); + audio_rate_start(&no->rate); return 0; } @@ -68,14 +62,20 @@ static void no_fini_out (HWVoiceOut *hw) static int no_ctl_out (HWVoiceOut *hw, int cmd, ...) { - (void) hw; - (void) cmd; + NoVoiceOut *no = (NoVoiceOut *) hw; + + if (cmd == VOICE_ENABLE) { + audio_rate_start(&no->rate); + } return 0; } static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) { + NoVoiceIn *no = (NoVoiceIn *) hw; + audio_pcm_init_info (&hw->info, as); + audio_rate_start(&no->rate); return 0; } @@ -86,25 +86,20 @@ static void no_fini_in (HWVoiceIn *hw) static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) { - size_t to_clear; NoVoiceIn *no = (NoVoiceIn *) hw; + int64_t bytes = audio_rate_get_bytes(&hw->info, &no->rate, size); - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - int64_t ticks = now - no->old_ticks; - int64_t bytes = - muldiv64 (ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - - no->old_ticks = now; - to_clear = MIN(bytes, size); - - audio_pcm_info_clear_buf(&hw->info, buf, to_clear >> hw->info.shift); - return to_clear; + audio_pcm_info_clear_buf(&hw->info, buf, bytes >> hw->info.shift); + return bytes; } static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) { - (void) hw; - (void) cmd; + NoVoiceIn *no = (NoVoiceIn *) hw; + + if (cmd == VOICE_ENABLE) { + audio_rate_start(&no->rate); + } return 0; } diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 709245e453..2495866c82 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -40,15 +40,10 @@ #define LINE_IN_SAMPLES (256 * 4) #endif -typedef struct SpiceRateCtl { - int64_t start_ticks; - int64_t bytes_sent; -} SpiceRateCtl; - typedef struct SpiceVoiceOut { HWVoiceOut hw; SpicePlaybackInstance sin; - SpiceRateCtl rate; + RateCtl rate; int active; uint32_t *frame; uint32_t fpos; @@ -58,7 +53,7 @@ typedef struct SpiceVoiceOut { typedef struct SpiceVoiceIn { HWVoiceIn hw; SpiceRecordInstance sin; - SpiceRateCtl rate; + RateCtl rate; int active; } SpiceVoiceIn; @@ -89,32 +84,6 @@ static void spice_audio_fini (void *opaque) /* nothing */ } -static void rate_start (SpiceRateCtl *rate) -{ - memset (rate, 0, sizeof (*rate)); - rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -} - -static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate) -{ - int64_t now; - int64_t ticks; - int64_t bytes; - int64_t samples; - - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - ticks = now - rate->start_ticks; - bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND); - samples = (bytes - rate->bytes_sent) >> info->shift; - if (samples < 0 || samples > 65536) { - error_report("Resetting rate control (%" PRId64 " samples)", samples); - rate_start(rate); - samples = 0; - } - rate->bytes_sent += samples << info->shift; - return samples; -} - /* playback */ static int line_out_init(HWVoiceOut *hw, struct audsettings *as, @@ -158,17 +127,14 @@ static void line_out_fini (HWVoiceOut *hw) static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) { SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); - size_t decr; if (!out->frame) { spice_server_playback_get_buffer(&out->sin, &out->frame, &out->fsize); out->fpos = 0; } - decr = rate_get_samples(&hw->info, &out->rate); - decr = MIN(out->fsize - out->fpos, decr); - - *size = decr << hw->info.shift; + *size = audio_rate_get_bytes(&hw->info, &out->rate, + (out->fsize - out->fpos) << hw->info.shift); return out->frame + out->fpos; } @@ -197,7 +163,7 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) break; } out->active = 1; - rate_start (&out->rate); + audio_rate_start(&out->rate); spice_server_playback_start (&out->sin); break; case VOICE_DISABLE: @@ -277,8 +243,7 @@ static void line_in_fini (HWVoiceIn *hw) static size_t line_in_read(HWVoiceIn *hw, void *buf, size_t len) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); - uint64_t delta_samp = rate_get_samples(&hw->info, &in->rate); - uint64_t to_read = MIN(len >> 2, delta_samp); + uint64_t to_read = audio_rate_get_bytes(&hw->info, &in->rate, len) >> 2; size_t ready = spice_server_record_get_samples(&in->sin, buf, to_read); /* XXX: do we need this? */ @@ -300,7 +265,7 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) break; } in->active = 1; - rate_start (&in->rate); + audio_rate_start(&in->rate); spice_server_record_start (&in->sin); break; case VOICE_DISABLE: diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 0a0e76d2d9..f977d96b9c 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -33,21 +33,15 @@ typedef struct WAVVoiceOut { HWVoiceOut hw; FILE *f; - int64_t old_ticks; + RateCtl rate; int total_samples; } WAVVoiceOut; static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - int64_t ticks = now - wav->old_ticks; - int64_t bytes = - muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND); - - bytes = MIN(bytes, len); - bytes = bytes >> hw->info.shift << hw->info.shift; - wav->old_ticks = now; + int64_t bytes = audio_rate_get_bytes(&hw->info, &wav->rate, len); + assert(bytes >> hw->info.shift << hw->info.shift == bytes); if (bytes && fwrite(buf, bytes, 1, wav->f) != 1) { dolog("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n", @@ -127,6 +121,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as, strerror(errno)); return -1; } + + audio_rate_start(&wav->rate); return 0; } @@ -176,8 +172,11 @@ static void wav_fini_out (HWVoiceOut *hw) static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...) { - (void) hw; - (void) cmd; + WAVVoiceOut *wav = (WAVVoiceOut *) hw; + + if (cmd == VOICE_ENABLE) { + audio_rate_start(&wav->rate); + } return 0; } From patchwork Wed Jan 16 23:37:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767225 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 74CB91390 for ; Thu, 17 Jan 2019 00:27:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6015A2F899 for ; Thu, 17 Jan 2019 00:27:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 53BED2F91F; Thu, 17 Jan 2019 00:27:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 80EFE2F899 for ; Thu, 17 Jan 2019 00:27:54 +0000 (UTC) Received: from localhost ([127.0.0.1]:43752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvXF-00014D-Pu for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:27:53 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58557) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulD-0004VZ-6c for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003RR-Do for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:15 -0500 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]:43753) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-0003JW-RB for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x42c.google.com with SMTP id r10so8917449wrs.10 for ; Wed, 16 Jan 2019 15:38:02 -0800 (PST) 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=icUd3rTtEPT6f4SL9hqPXiuKLq/clJ7idLWEaUxDsQQ=; b=eYn+5/5keFZLC1iP8cSXcadQskI4e0JAdvzY+KVaMyyMY+Rvdr/XraIQp/iLwDKAjN HPVQ0FmZ2Jbz4UzJ48c72WSSQLBzEmtKWInFwn6JJ8pQPg/aorQ3O34e++g76s7O9UFL TkSfdxqYxZeamrEFRMS0gOiCabzFWM6gDyTwRZKPvs0ckssqG3vc+gv2reDIIsgakSTS W98IyAEVyizePg2yEYEyBe8tH84uwGoquKo/obbMK1N5DRrUhe0aVoahPSQ0/hkAvx6b zllv9N/cjamhcGNG1UByk4qavi6rr7/MteNd1FlWd+5Ec2iraElsSHDyfus2TJY62S1Z rCdQ== 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=icUd3rTtEPT6f4SL9hqPXiuKLq/clJ7idLWEaUxDsQQ=; b=il9cfyLoTyEENPEHqRsJFN+wc5mpEAHO5aNl7Bj3hKi5k6E3AMK7uzutA1nBlSL9Qa Y5zvusZ5ehYJTCLtElbjp+I6cwpvJUG1FhkIwKO2WJjeXMyVxlsHO+bXpF1MSSpWwEvq TTwedBCWumiHQQx0/Her02cL4maXCDsSr4KXtWcIyJghRJHE2JqpT7xRN1pLm6zk2/Lj 9R0ZTZ2h4UiikKLw7v/9YUIv1zj4U1xHlAn2KQbSjM4iCbISctTAqDQgoIDuVqcGTDjS 7fB3fugYneQbwD3s58iNsnVYngx00OWopdZeqWtjeOo+iELz8Xqp8FBCfzTclqGbvfTM om7Q== X-Gm-Message-State: AJcUukeyMXgHXg6Qu4MsXm6UoqWlIdCucIboX04ljoYzxoohuce2o4EW h6fuqDKulBW3XRdpL2vJeIK7VFv6NGw= X-Google-Smtp-Source: ALg8bN4tPqM6cH7aKYvu3rWgPB/GF7Pt6b3xwGgSPrVOdfAtq333zwQ1+cVk/y84gbVhsCMYok5e4g== X-Received: by 2002:adf:f550:: with SMTP id j16mr9382100wrp.258.1547681881300; Wed, 16 Jan 2019 15:38:01 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:00 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:13 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42c Subject: [Qemu-devel] [PATCH v3 40/50] audio: split ctl_* functions into enable_* and volume_* X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This way we no longer need vararg functions, improving compile time error detection. Also now it's possible to check actually what commands are supported, without needing to manually update ctl_caps. Signed-off-by: Kővágó, Zoltán --- audio/audio_int.h | 15 ++--- audio/audio_template.h | 1 - audio/alsaaudio.c | 56 +++++++----------- audio/audio.c | 45 +++++++++------ audio/coreaudio.c | 13 ++--- audio/dsoundaudio.c | 50 +++++++--------- audio/noaudio.c | 14 ++--- audio/ossaudio.c | 78 ++++++++++--------------- audio/paaudio.c | 126 ++++++++++++++++------------------------- audio/sdlaudio.c | 17 +----- audio/spiceaudio.c | 101 ++++++++++++++------------------- audio/wavaudio.c | 7 +-- 12 files changed, 213 insertions(+), 310 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index 236b523286..6fec4f159c 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -72,7 +72,6 @@ typedef struct HWVoiceOut { QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head; - int ctl_caps; struct audio_pcm_ops *pcm_ops; QLIST_ENTRY (HWVoiceOut) entries; } HWVoiceOut; @@ -93,7 +92,6 @@ typedef struct HWVoiceIn { size_t pos_emul, pending_emul, size_emul; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; - int ctl_caps; struct audio_pcm_ops *pcm_ops; QLIST_ENTRY (HWVoiceIn) entries; } HWVoiceIn; @@ -145,7 +143,6 @@ struct audio_driver { int max_voices_in; int voice_size_out; int voice_size_in; - int ctl_caps; QLIST_ENTRY(audio_driver) next; }; @@ -167,7 +164,8 @@ struct audio_pcm_ops { * size may be smaller */ size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size); - int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); + void (*enable_out)(HWVoiceOut *hw, bool enable); + void (*volume_out)(HWVoiceOut *hw, struct mixeng_volume *vol); int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); void (*fini_in) (HWVoiceIn *hw); @@ -175,7 +173,8 @@ struct audio_pcm_ops { size_t (*buffer_size_in)(HWVoiceIn *hw); void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); - int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); + void (*enable_in)(HWVoiceIn *hw, bool enable); + void (*volume_in)(HWVoiceIn *hw, struct mixeng_volume *vol); }; void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size); @@ -251,12 +250,6 @@ void audio_rate_start(RateCtl *rate); size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, size_t bytes_avail); -#define VOICE_ENABLE 1 -#define VOICE_DISABLE 2 -#define VOICE_VOLUME 3 - -#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME) - static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len) { return (dst >= src) ? (dst - src) : (len - src + dst); diff --git a/audio/audio_template.h b/audio/audio_template.h index 07ce9ce51f..9ec565fc48 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -267,7 +267,6 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, hw->s = s; hw->pcm_ops = drv->pcm_ops; - hw->ctl_caps = drv->ctl_caps; QLIST_INIT (&hw->sw_head); #ifdef DAC diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 1489f50dfd..446bb90ceb 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -744,34 +744,28 @@ static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl) return 0; } -static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void alsa_enable_out(HWVoiceOut *hw, bool enable) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.alsa_out; - switch (cmd) { - case VOICE_ENABLE: - { - bool poll_mode = apdo->try_poll; + if (enable) { + bool poll_mode = apdo->try_poll; - ldebug ("enabling voice\n"); - if (poll_mode && alsa_poll_out (hw)) { - poll_mode = 0; - } - hw->poll_mode = poll_mode; - return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE); + ldebug ("enabling voice\n"); + if (poll_mode && alsa_poll_out (hw)) { + poll_mode = 0; } - - case VOICE_DISABLE: + hw->poll_mode = poll_mode; + alsa_voice_ctl(alsa->handle, "playback", VOICE_CTL_PREPARE); + } else { ldebug ("disabling voice\n"); if (hw->poll_mode) { hw->poll_mode = 0; alsa_fini_poll (&alsa->pollhlp); } - return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE); + alsa_voice_ctl(alsa->handle, "playback", VOICE_CTL_PAUSE); } - - return -1; } static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) @@ -860,35 +854,29 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) return pos; } -static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) +static void alsa_enable_in(HWVoiceIn *hw, bool enable) { ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.alsa_in; - switch (cmd) { - case VOICE_ENABLE: - { - bool poll_mode = apdo->try_poll; + if (enable) { + bool poll_mode = apdo->try_poll; - ldebug ("enabling voice\n"); - if (poll_mode && alsa_poll_in (hw)) { - poll_mode = 0; - } - hw->poll_mode = poll_mode; - - return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START); + ldebug ("enabling voice\n"); + if (poll_mode && alsa_poll_in (hw)) { + poll_mode = 0; } + hw->poll_mode = poll_mode; - case VOICE_DISABLE: + alsa_voice_ctl(alsa->handle, "capture", VOICE_CTL_START); + } else { ldebug ("disabling voice\n"); if (hw->poll_mode) { hw->poll_mode = 0; alsa_fini_poll (&alsa->pollhlp); } - return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE); + alsa_voice_ctl(alsa->handle, "capture", VOICE_CTL_PAUSE); } - - return -1; } static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions **apdo, @@ -949,13 +937,13 @@ static struct audio_pcm_ops alsa_pcm_ops = { .fini_out = alsa_fini_out, .buffer_size_out = alsa_buffer_size_out, .write = alsa_write, - .ctl_out = alsa_ctl_out, + .enable_out = alsa_enable_out, .init_in = alsa_init_in, .fini_in = alsa_fini_in, .buffer_size_in = alsa_buffer_size_in, .read = alsa_read, - .ctl_in = alsa_ctl_in, + .enable_in = alsa_enable_in, }; static struct audio_driver alsa_audio_driver = { diff --git a/audio/audio.c b/audio/audio.c index 798541638e..6bbbcd3e03 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -637,7 +637,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) total += isamp; } - if (!(hw->ctl_caps & VOICE_VOLUME_CAP)) { + if (!hw->pcm_ops->volume_in) { mixeng_volume (sw->buf, ret, &sw->vol); } @@ -724,7 +724,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) if (swlim) { sw->conv (sw->buf, buf, swlim); - if (!(sw->hw->ctl_caps & VOICE_VOLUME_CAP)) { + if (!sw->hw->pcm_ops->volume_out) { mixeng_volume (sw->buf, swlim, &sw->vol); } } @@ -891,7 +891,9 @@ void AUD_set_active_out (SWVoiceOut *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_out(hw, VOICE_ENABLE); + if (hw->pcm_ops->enable_out) { + hw->pcm_ops->enable_out(hw, true); + } audio_reset_timer (s); } } @@ -936,7 +938,9 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) if (!hw->enabled) { hw->enabled = 1; if (s->vm_running) { - hw->pcm_ops->ctl_in(hw, VOICE_ENABLE); + if (hw->pcm_ops->enable_in) { + hw->pcm_ops->enable_in(hw, true); + } audio_reset_timer (s); } } @@ -953,7 +957,9 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) if (nb_active == 1) { hw->enabled = 0; - hw->pcm_ops->ctl_in (hw, VOICE_DISABLE); + if (hw->pcm_ops->enable_in) { + hw->pcm_ops->enable_in(hw, false); + } } } } @@ -1101,7 +1107,9 @@ static void audio_run_out (AudioState *s) #endif hw->enabled = 0; hw->pending_disable = 0; - hw->pcm_ops->ctl_out (hw, VOICE_DISABLE); + if (hw->pcm_ops->enable_out) { + hw->pcm_ops->enable_out(hw, false); + } for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) { sc->sw.active = 0; audio_recalc_and_notify_capture (sc->cap); @@ -1464,15 +1472,18 @@ static void audio_vm_change_state_handler (void *opaque, int running, AudioState *s = opaque; HWVoiceOut *hwo = NULL; HWVoiceIn *hwi = NULL; - int op = running ? VOICE_ENABLE : VOICE_DISABLE; s->vm_running = running; while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) { - hwo->pcm_ops->ctl_out(hwo, op); + if (hwo->pcm_ops->enable_out) { + hwo->pcm_ops->enable_out(hwo, running); + } } while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) { - hwi->pcm_ops->ctl_in(hwi, op); + if (hwi->pcm_ops->enable_in) { + hwi->pcm_ops->enable_in(hwi, running); + } } audio_reset_timer (s); } @@ -1492,8 +1503,8 @@ static void free_audio_state(AudioState *s) QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) { SWVoiceCap *sc; - if (hwo->enabled) { - hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE); + if (hwo->enabled && hwo->pcm_ops->enable_out) { + hwo->pcm_ops->enable_out(hwo, false); } hwo->pcm_ops->fini_out (hwo); @@ -1509,8 +1520,8 @@ static void free_audio_state(AudioState *s) } QLIST_FOREACH_SAFE(hwi, &s->hw_head_in, entries, hwin) { - if (hwi->enabled) { - hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE); + if (hwi->enabled && hwi->pcm_ops->enable_in) { + hwi->pcm_ops->enable_in(hwi, false); } hwi->pcm_ops->fini_in (hwi); QLIST_REMOVE(hwi, entries); @@ -1848,8 +1859,8 @@ void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol) sw->vol.l = nominal_volume.l * lvol / 255; sw->vol.r = nominal_volume.r * rvol / 255; - if (hw->pcm_ops->ctl_out) { - hw->pcm_ops->ctl_out (hw, VOICE_VOLUME, sw); + if (hw->pcm_ops->volume_out) { + hw->pcm_ops->volume_out(hw, &sw->vol); } } } @@ -1863,8 +1874,8 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) sw->vol.l = nominal_volume.l * lvol / 255; sw->vol.r = nominal_volume.r * rvol / 255; - if (hw->pcm_ops->ctl_in) { - hw->pcm_ops->ctl_in (hw, VOICE_VOLUME, sw); + if (hw->pcm_ops->volume_in) { + hw->pcm_ops->volume_in(hw, &sw->vol); } } } diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 693f6f11d7..508bee19d4 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -655,13 +655,12 @@ static void coreaudio_fini_out (HWVoiceOut *hw) } } -static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void coreaudio_enable_out (HWVoiceOut *hw, bool enable) { OSStatus status; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; - switch (cmd) { - case VOICE_ENABLE: + if (enable) { /* start playback */ if (!isPlaying(core->outputDeviceID)) { status = AudioDeviceStart(core->outputDeviceID, core->ioprocid); @@ -669,9 +668,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) coreaudio_logerr (status, "Could not resume playback\n"); } } - break; - - case VOICE_DISABLE: + } else { /* stop playback */ if (!audio_is_cleaning_up()) { if (isPlaying(core->outputDeviceID)) { @@ -682,9 +679,7 @@ static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...) } } } - break; } - return 0; } static void *coreaudio_audio_init(Audiodev *dev) @@ -703,7 +698,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .buffer_size_out = coreaudio_buffer_size_out, .get_buffer_out = coreaudio_get_buffer_out, .put_buffer_out = coreaudio_put_buffer_out_nowrite, - .ctl_out = coreaudio_ctl_out + .enable_out = coreaudio_enable_out }; static struct audio_driver coreaudio_audio_driver = { diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index e030bb29b5..da9276c268 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -363,7 +363,7 @@ static int dsound_open (dsound *s) return 0; } -static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void dsound_enable_out(HWVoiceOut *hw, bool enable) { HRESULT hr; DWORD status; @@ -373,18 +373,17 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) if (!dsb) { dolog ("Attempt to control voice without a buffer\n"); - return 0; + return; } - switch (cmd) { - case VOICE_ENABLE: + if (enable) { if (dsound_get_status_out (dsb, &status, s)) { - return -1; + return; } if (status & DSBSTATUS_PLAYING) { dolog ("warning: Voice is already playing\n"); - return 0; + return; } dsound_clear_sample (hw, dsb, s); @@ -392,28 +391,24 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING); if (FAILED (hr)) { dsound_logerr (hr, "Could not start playing buffer\n"); - return -1; + return; } - break; - - case VOICE_DISABLE: + } else { if (dsound_get_status_out (dsb, &status, s)) { - return -1; + return; } if (status & DSBSTATUS_PLAYING) { hr = IDirectSoundBuffer_Stop (dsb); if (FAILED (hr)) { dsound_logerr (hr, "Could not stop playing buffer\n"); - return -1; + return; } } else { dolog ("warning: Voice is not playing\n"); } - break; } - return 0; } static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size) @@ -463,7 +458,7 @@ static size_t dsound_put_buffer_out(HWVoiceOut *hw, void *buf, size_t len) return len; } -static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) +static void dsound_enable_in(HWVoiceIn *hw, bool enable) { HRESULT hr; DWORD status; @@ -472,18 +467,17 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) if (!dscb) { dolog ("Attempt to control capture voice without a buffer\n"); - return -1; + return; } - switch (cmd) { - case VOICE_ENABLE: + if (enable) { if (dsound_get_status_in (dscb, &status)) { - return -1; + return; } if (status & DSCBSTATUS_CAPTURING) { dolog ("warning: Voice is already capturing\n"); - return 0; + return; } /* clear ?? */ @@ -491,28 +485,24 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING); if (FAILED (hr)) { dsound_logerr (hr, "Could not start capturing\n"); - return -1; + return; } - break; - - case VOICE_DISABLE: + } else { if (dsound_get_status_in (dscb, &status)) { - return -1; + return; } if (status & DSCBSTATUS_CAPTURING) { hr = IDirectSoundCaptureBuffer_Stop (dscb); if (FAILED (hr)) { dsound_logerr (hr, "Could not stop capturing\n"); - return -1; + return; } } else { dolog ("warning: Voice is not capturing\n"); } - break; } - return 0; } static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) @@ -677,7 +667,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .buffer_size_out = dsound_buffer_size_out, .get_buffer_out = dsound_get_buffer_out, .put_buffer_out = dsound_put_buffer_out, - .ctl_out = dsound_ctl_out, + .enable_out = dsound_enable_out, .init_in = dsound_init_in, .fini_in = dsound_fini_in, @@ -685,7 +675,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .buffer_size_in = dsound_buffer_size_in, .get_buffer_in = dsound_get_buffer_in, .put_buffer_in = dsound_put_buffer_in, - .ctl_in = dsound_ctl_in + .enable_in = dsound_enable_in, }; static struct audio_driver dsound_audio_driver = { diff --git a/audio/noaudio.c b/audio/noaudio.c index b29929dac4..c8bcfa9bca 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -60,14 +60,13 @@ static void no_fini_out (HWVoiceOut *hw) (void) hw; } -static int no_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void no_enable_out(HWVoiceOut *hw, bool enable) { NoVoiceOut *no = (NoVoiceOut *) hw; - if (cmd == VOICE_ENABLE) { + if (enable) { audio_rate_start(&no->rate); } - return 0; } static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) @@ -93,14 +92,13 @@ static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) return bytes; } -static int no_ctl_in (HWVoiceIn *hw, int cmd, ...) +static void no_enable_in(HWVoiceIn *hw, bool enable) { NoVoiceIn *no = (NoVoiceIn *) hw; - if (cmd == VOICE_ENABLE) { + if (enable) { audio_rate_start(&no->rate); } - return 0; } static void *no_audio_init(Audiodev *dev) @@ -117,12 +115,12 @@ static struct audio_pcm_ops no_pcm_ops = { .init_out = no_init_out, .fini_out = no_fini_out, .write = no_write, - .ctl_out = no_ctl_out, + .enable_out = no_enable_out, .init_in = no_init_in, .fini_in = no_fini_in, .read = no_read, - .ctl_in = no_ctl_in + .enable_in = no_enable_in }; static struct audio_driver no_audio_driver = { diff --git a/audio/ossaudio.c b/audio/ossaudio.c index a93f97aa63..f12d8a95bd 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -570,59 +570,50 @@ static size_t oss_buffer_size_out(HWVoiceOut *hw) return oss->samples; } -static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void oss_enable_out(HWVoiceOut *hw, bool enable) { int trig; OSSVoiceOut *oss = (OSSVoiceOut *) hw; AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out; - switch (cmd) { - case VOICE_ENABLE: - { - bool poll_mode = opdo->try_poll; + if (enable) { + bool poll_mode = opdo->try_poll; - ldebug ("enabling voice\n"); - if (poll_mode) { - oss_poll_out (hw); - poll_mode = 0; - } - hw->poll_mode = poll_mode; - - if (!oss->mmapped) { - return 0; - } + ldebug ("enabling voice\n"); + if (poll_mode) { + oss_poll_out (hw); + poll_mode = 0; + } + hw->poll_mode = poll_mode; - audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->mix_buf->size); - trig = PCM_ENABLE_OUTPUT; - if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { - oss_logerr ( - errno, - "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n" - ); - return -1; - } + if (!oss->mmapped) { + return; } - break; - case VOICE_DISABLE: + audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->mix_buf->size); + trig = PCM_ENABLE_OUTPUT; + if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { + oss_logerr(errno, + "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"); + return; + } + } else { if (hw->poll_mode) { qemu_set_fd_handler (oss->fd, NULL, NULL, NULL); hw->poll_mode = 0; } if (!oss->mmapped) { - return 0; + return; } ldebug ("disabling voice\n"); trig = 0; if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n"); - return -1; + return; } - break; } - return 0; } static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) @@ -715,32 +706,25 @@ static size_t oss_read(HWVoiceIn *hw, void *buf, size_t len) return pos; } -static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) +static void oss_enable_in(HWVoiceIn *hw, bool enable) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.oss_out; - switch (cmd) { - case VOICE_ENABLE: - { - bool poll_mode = opdo->try_poll; + if (enable) { + bool poll_mode = opdo->try_poll; - if (poll_mode) { - oss_poll_in (hw); - poll_mode = 0; - } - hw->poll_mode = poll_mode; + if (poll_mode) { + oss_poll_in (hw); + poll_mode = 0; } - break; - - case VOICE_DISABLE: + hw->poll_mode = poll_mode; + } else { if (hw->poll_mode) { hw->poll_mode = 0; qemu_set_fd_handler (oss->fd, NULL, NULL, NULL); } - break; } - return 0; } static void oss_init_per_direction(AudiodevOssPerDirectionOptions **opdo, @@ -786,13 +770,13 @@ static struct audio_pcm_ops oss_pcm_ops = { .buffer_size_out = oss_buffer_size_out, .get_buffer_out = oss_get_buffer_out, .put_buffer_out = oss_put_buffer_out, - .ctl_out = oss_ctl_out, + .enable_out = oss_enable_out, .init_in = oss_init_in, .fini_in = oss_fini_in, .read = oss_read, .buffer_size_in = oss_buffer_size_in, - .ctl_in = oss_ctl_in + .enable_in = oss_enable_in }; static struct audio_driver oss_audio_driver = { diff --git a/audio/paaudio.c b/audio/paaudio.c index cfa4e895c7..a45469066b 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -458,7 +458,7 @@ static void qpa_fini_in (HWVoiceIn *hw) } } -static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol) { PAVoiceOut *pa = (PAVoiceOut *) hw; pa_operation *op; @@ -469,48 +469,36 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...) pa_cvolume_init (&v); /* function is present in 0.9.13+ */ #endif - switch (cmd) { - case VOICE_VOLUME: - { - SWVoiceOut *sw; - va_list ap; + v.channels = 2; + v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX; + v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX; - va_start (ap, cmd); - sw = va_arg (ap, SWVoiceOut *); - va_end (ap); + pa_threaded_mainloop_lock(c->mainloop); - v.channels = 2; - v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; - v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; - - pa_threaded_mainloop_lock(c->mainloop); - - op = pa_context_set_sink_input_volume(c->context, - pa_stream_get_index (pa->stream), - &v, NULL, NULL); - if (!op) - qpa_logerr (pa_context_errno(c->context), - "set_sink_input_volume() failed\n"); - else - pa_operation_unref (op); - - op = pa_context_set_sink_input_mute(c->context, - pa_stream_get_index (pa->stream), - sw->vol.mute, NULL, NULL); - if (!op) { - qpa_logerr (pa_context_errno(c->context), - "set_sink_input_mute() failed\n"); - } else { - pa_operation_unref (op); - } + op = pa_context_set_sink_input_volume(c->context, + pa_stream_get_index(pa->stream), + &v, NULL, NULL); + if (!op) { + qpa_logerr(pa_context_errno(c->context), + "set_sink_input_volume() failed\n"); + } else { + pa_operation_unref (op); + } - pa_threaded_mainloop_unlock(c->mainloop); - } + op = pa_context_set_sink_input_mute(c->context, + pa_stream_get_index(pa->stream), + vol->mute, NULL, NULL); + if (!op) { + qpa_logerr(pa_context_errno(c->context), + "set_sink_input_mute() failed\n"); + } else { + pa_operation_unref(op); } - return 0; + + pa_threaded_mainloop_unlock(c->mainloop); } -static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) +static void qpa_volume_in(HWVoiceIn *hw, struct mixeng_volume *vol) { PAVoiceIn *pa = (PAVoiceIn *) hw; pa_operation *op; @@ -521,46 +509,33 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) pa_cvolume_init (&v); #endif - switch (cmd) { - case VOICE_VOLUME: - { - SWVoiceIn *sw; - va_list ap; + v.channels = 2; + v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX; + v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX; - va_start (ap, cmd); - sw = va_arg (ap, SWVoiceIn *); - va_end (ap); + pa_threaded_mainloop_lock(c->mainloop); - v.channels = 2; - v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.l) / UINT32_MAX; - v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw->vol.r) / UINT32_MAX; - - pa_threaded_mainloop_lock(c->mainloop); - - op = pa_context_set_source_output_volume(c->context, - pa_stream_get_index(pa->stream), - &v, NULL, NULL); - if (!op) { - qpa_logerr(pa_context_errno(c->context), - "set_source_output_volume() failed\n"); - } else { - pa_operation_unref(op); - } - - op = pa_context_set_source_output_mute(c->context, - pa_stream_get_index (pa->stream), - sw->vol.mute, NULL, NULL); - if (!op) { - qpa_logerr(pa_context_errno(c->context), - "set_source_output_mute() failed\n"); - } else { - pa_operation_unref (op); - } + op = pa_context_set_source_output_volume(c->context, + pa_stream_get_index(pa->stream), + &v, NULL, NULL); + if (!op) { + qpa_logerr(pa_context_errno(c->context), + "set_source_output_volume() failed\n"); + } else { + pa_operation_unref(op); + } - pa_threaded_mainloop_unlock(c->mainloop); - } + op = pa_context_set_source_output_mute(c->context, + pa_stream_get_index(pa->stream), + vol->mute, NULL, NULL); + if (!op) { + qpa_logerr(pa_context_errno(c->context), + "set_source_output_mute() failed\n"); + } else { + pa_operation_unref (op); } - return 0; + + pa_threaded_mainloop_unlock(c->mainloop); } /* common */ @@ -708,13 +683,13 @@ static struct audio_pcm_ops qpa_pcm_ops = { .fini_out = qpa_fini_out, .write = qpa_write, .buffer_size_out = qpa_buffer_size_out, - .ctl_out = qpa_ctl_out, + .volume_out = qpa_volume_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .read = qpa_read, .buffer_size_in = qpa_buffer_size_in, - .ctl_in = qpa_ctl_in + .volume_in = qpa_volume_in }; static struct audio_driver pa_audio_driver = { @@ -728,7 +703,6 @@ static struct audio_driver pa_audio_driver = { .max_voices_in = INT_MAX, .voice_size_out = sizeof (PAVoiceOut), .voice_size_in = sizeof (PAVoiceIn), - .ctl_caps = VOICE_VOLUME_CAP }; static void register_audio_pa(void) diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index 4df35ce31a..93554df119 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -378,20 +378,9 @@ static size_t sdl_buffer_size_out(HWVoiceOut *hw) return sdl->samples; } -static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void sdl_enable_out(HWVoiceOut *hw, bool enable) { - (void) hw; - - switch (cmd) { - case VOICE_ENABLE: - SDL_PauseAudio (0); - break; - - case VOICE_DISABLE: - SDL_PauseAudio (1); - break; - } - return 0; + SDL_PauseAudio(!enable); } static void *sdl_audio_init(Audiodev *dev) @@ -449,7 +438,7 @@ static struct audio_pcm_ops sdl_pcm_ops = { .buffer_size_out = sdl_buffer_size_out, .get_buffer_out = sdl_get_buffer_out, .put_buffer_out = sdl_put_buffer_out_nowrite, - .ctl_out = sdl_ctl_out, + .enable_out = sdl_enable_out, }; static struct audio_driver sdl_audio_driver = { diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 2495866c82..771ecacf27 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -153,22 +153,20 @@ static size_t line_out_put_buffer(HWVoiceOut *hw, void *buf, size_t size) return size; } -static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) +static void line_out_enable(HWVoiceOut *hw, bool enable) { SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); - switch (cmd) { - case VOICE_ENABLE: + if (enable) { if (out->active) { - break; + return; } out->active = 1; audio_rate_start(&out->rate); spice_server_playback_start (&out->sin); - break; - case VOICE_DISABLE: + } else { if (!out->active) { - break; + return; } out->active = 0; if (out->frame) { @@ -177,29 +175,21 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...) out->frame = NULL; } spice_server_playback_stop (&out->sin); - break; - case VOICE_VOLUME: - { + } +} + #if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)) - SWVoiceOut *sw; - va_list ap; - uint16_t vol[2]; +static void line_out_volume(HWVoiceOut *hw, struct mixeng_volume *vol) +{ + SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); + uint16_t svol[2]; - va_start (ap, cmd); - sw = va_arg (ap, SWVoiceOut *); - va_end (ap); - - vol[0] = sw->vol.l / ((1ULL << 16) + 1); - vol[1] = sw->vol.r / ((1ULL << 16) + 1); - spice_server_playback_set_volume (&out->sin, 2, vol); - spice_server_playback_set_mute (&out->sin, sw->vol.mute); + svol[0] = vol->l / ((1ULL << 16) + 1); + svol[1] = vol->r / ((1ULL << 16) + 1); + spice_server_playback_set_volume(&out->sin, 2, svol); + spice_server_playback_set_mute(&out->sin, vol->mute); +} #endif - break; - } - } - - return 0; -} /* record */ @@ -255,48 +245,38 @@ static size_t line_in_read(HWVoiceIn *hw, void *buf, size_t len) return ready << 2; } -static int line_in_ctl (HWVoiceIn *hw, int cmd, ...) +static void line_in_enable(HWVoiceIn *hw, bool enable) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); - switch (cmd) { - case VOICE_ENABLE: + if (enable) { if (in->active) { - break; + return; } in->active = 1; audio_rate_start(&in->rate); spice_server_record_start (&in->sin); - break; - case VOICE_DISABLE: + } else { if (!in->active) { - break; + return; } in->active = 0; spice_server_record_stop (&in->sin); - break; - case VOICE_VOLUME: - { + } +} + #if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2)) - SWVoiceIn *sw; - va_list ap; - uint16_t vol[2]; +static void line_in_volume(HWVoiceIn *hw, struct mixeng_volume *vol) +{ + SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); + uint16_t svol[2]; - va_start (ap, cmd); - sw = va_arg (ap, SWVoiceIn *); - va_end (ap); - - vol[0] = sw->vol.l / ((1ULL << 16) + 1); - vol[1] = sw->vol.r / ((1ULL << 16) + 1); - spice_server_record_set_volume (&in->sin, 2, vol); - spice_server_record_set_mute (&in->sin, sw->vol.mute); + svol[0] = vol->l / ((1ULL << 16) + 1); + svol[1] = vol->r / ((1ULL << 16) + 1); + spice_server_record_set_volume(&in->sin, 2, svol); + spice_server_record_set_mute(&in->sin, vol->mute); +} #endif - break; - } - } - - return 0; -} static struct audio_pcm_ops audio_callbacks = { .init_out = line_out_init, @@ -305,13 +285,19 @@ static struct audio_pcm_ops audio_callbacks = { .buffer_size_out = line_out_buffer_size, .get_buffer_out = line_out_get_buffer, .put_buffer_out = line_out_put_buffer, - .ctl_out = line_out_ctl, + .enable_out = line_out_enable, +#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)) + .volume_out = line_out_volume, +#endif .init_in = line_in_init, .fini_in = line_in_fini, .read = line_in_read, .buffer_size_in = line_in_buffer_size, - .ctl_in = line_in_ctl, + .enable_in = line_in_enable, +#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2)) + .volume_in = line_in_volume, +#endif }; static struct audio_driver spice_audio_driver = { @@ -324,9 +310,6 @@ static struct audio_driver spice_audio_driver = { .max_voices_in = 1, .voice_size_out = sizeof (SpiceVoiceOut), .voice_size_in = sizeof (SpiceVoiceIn), -#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)) - .ctl_caps = VOICE_VOLUME_CAP -#endif }; void qemu_spice_audio_init (void) diff --git a/audio/wavaudio.c b/audio/wavaudio.c index f977d96b9c..672d5fc337 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -170,14 +170,13 @@ static void wav_fini_out (HWVoiceOut *hw) wav->f = NULL; } -static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...) +static void wav_enable_out(HWVoiceOut *hw, bool enable) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; - if (cmd == VOICE_ENABLE) { + if (enable) { audio_rate_start(&wav->rate); } - return 0; } static void *wav_audio_init(Audiodev *dev) @@ -195,7 +194,7 @@ static struct audio_pcm_ops wav_pcm_ops = { .init_out = wav_init_out, .fini_out = wav_fini_out, .write = wav_write_out, - .ctl_out = wav_ctl_out, + .enable_out = wav_enable_out, }; static struct audio_driver wav_audio_driver = { From patchwork Wed Jan 16 23:37:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767165 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 40ABB13A4 for ; Wed, 16 Jan 2019 23:58:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30C802FC42 for ; Wed, 16 Jan 2019 23:58:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 238032FC1C; Wed, 16 Jan 2019 23:58:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AD15C2FC1C for ; Wed, 16 Jan 2019 23:58:22 +0000 (UTC) Received: from localhost ([127.0.0.1]:36296 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjv4f-0003ZN-WF for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 18:58:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58323) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul8-0004P3-2z for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003Rn-II for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:10 -0500 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]:36186) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003Jl-4P for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x42b.google.com with SMTP id u4so8967971wrp.3 for ; Wed, 16 Jan 2019 15:38:03 -0800 (PST) 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=CCmmtkTX5UQWh5lGDkfWpkyZkld9l3muJnFm8hymQpM=; b=V575rm4bzYa7x7HqzIlvG90YuG/pzGeUuSVi5kC7t3uzrYxs4tPBB02CtQK487rSuO FLXOfWwpSxsmT85RAWhcSsz6pfVyktR+heYXKPGaWs291Fc9vUMZCajbKP04g6Nk6HwT /KeAVOvSaoUjCfEc+PLQMOCE+FYJK6WLtJDqW9ZSIjK0kgoG+zBKbk6fmlbvoq26N3sx +XBOtRbep/oLs12ZUSaOktyijIuajpaYByxaiZ8meTDi3vR/BWH0NZHrlPjYa6v5tIu2 0OAsTd15CmJqgmmOkuU45gkBskk/cADUSeqTA5LAhS+0NvJ7tkdvVi+wYV/XP9uD8YyZ 4qig== 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=CCmmtkTX5UQWh5lGDkfWpkyZkld9l3muJnFm8hymQpM=; b=ohz/AgfflILnCFsps/hsg5b0Fg2gr4k/heC9giIOUUEgSPB+tiZXvn1lGiOg5UGWGu MSpDaxhS0w9uZhu7M/pYux1T19HFaw5EWKzjainu2vZ81dYePJg6c43TtQdbcTO0qSLY FW9hOjAvEpxpX+cL43hjf4sOIy0W5b9HkGlwkUDSIhVbUPXLc4KyBuD2sV0iHQZkF2ws QbC0JYLFMVtltyK4MAuGJ+tEa3Vuv7g2K/WacfY8IMxlhnESfSuplthfK+azsGvKiype er6enaNT/mehEBc/7NT3LjegUjQ8HEEPwtrdcWJ/e2V5KCQMTzuxMHGw3ViX+O/KVWdP VoTw== X-Gm-Message-State: AJcUukfvMPlaVeGxwkspZ+2IcFpTLNnlWKeb/9E2fOp1G2J+kMBfWAvq dgSE+l6htVeYJEcFZj61F8YW7QaRWcI= X-Google-Smtp-Source: ALg8bN5EomIzaYLVSR5S+zTspD7zv2A1OoxMfer6XSk8O0XXLpfS4JFOXIEzgegx1QnP7Q6Dsrr/Sw== X-Received: by 2002:a05:6000:51:: with SMTP id k17mr8958109wrx.259.1547681882080; Wed, 16 Jan 2019 15:38:02 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:01 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:14 +0100 Message-Id: <48943170cf1619d5d2aadfaebf450a017316d8d2.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42b Subject: [Qemu-devel] [PATCH v3 41/50] audio: add mixeng option (documentation) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann , Markus Armbruster Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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. However mixeng is not removed, only made optional, so this shouldn't be a big concern. Signed-off-by: Kővágó, Zoltán --- Notes: Changes from v2: * removed #optional qapi/audio.json | 5 +++++ qemu-options.hx | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/qapi/audio.json b/qapi/audio.json index bd6e2494bd..7bcea6240f 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -172,6 +172,10 @@ # # General audio backend options that are used for both playback and recording. # +# @mixeng: use QEMU's mixing engine to mix all streams inside QEMU. When set to +# off, fixed-settings must be also off. Not every backend compatible +# with the off setting (default on) +# # @fixed-settings: use fixed settings for host input/output. When off, # frequency, channels and format must not be specified # (default on) @@ -192,6 +196,7 @@ ## { 'struct': 'AudiodevPerDirectionOptions', 'data': { + '*mixeng': 'bool', '*fixed-settings': 'bool', '*frequency': 'uint32', '*channels': 'uint32', diff --git a/qemu-options.hx b/qemu-options.hx index 098508ce09..53fc5ef453 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -432,6 +432,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, " specifies the audio backend to use\n" " id= identifier of the backend\n" " timer-period= timer period in microseconds\n" + " in|out.mixeng= use mixeng to mix streams inside QEMU\n" " in|out.fixed-settings= use fixed settings for host audio\n" " in|out.frequency= frequency to use with fixed settings\n" " in|out.channels= number of channels to use with fixed settings\n" @@ -500,6 +501,11 @@ Identifies the audio backend. Sets the timer @var{period} used by the audio subsystem in microseconds. Default is 10000 (10 ms). +@item in|out.mixeng=on|off +Use QEMU's mixing engine to mix all streams inside QEMU. When off, +@var{fixed-settings} must be off too. Not every backend is fully +compatible with the off setting. Default is on. + @item in|out.fixed-settings=on|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 From patchwork Wed Jan 16 23:37:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767183 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 915791390 for ; Thu, 17 Jan 2019 00:07:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80F452E9BD for ; Thu, 17 Jan 2019 00:07:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 730872F353; Thu, 17 Jan 2019 00:07:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D47B12E9BD for ; Thu, 17 Jan 2019 00:07:40 +0000 (UTC) Received: from localhost ([127.0.0.1]:38415 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvDg-00028t-4g for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:07:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58380) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004Qi-6q for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003S6-Ke for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:46786) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003Kf-69 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x442.google.com with SMTP id l9so8888921wrt.13 for ; Wed, 16 Jan 2019 15:38:03 -0800 (PST) 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=+GJrV0c5zzNT39TwSPxNd5uWTZp42OGxJwGSrdyqRJw=; b=RLyzQe952zw0PoyTjO6eYGpJpd4PMU4ruHmv7eubsIjkXWXmCrOtsyAfTaFud9tOLw qwGQZYENhRjIPttWpJ+d/N5QJPfxZsYnjZQoerD5y15+3Kz0Pd1Z1r0bBvn6BI1BRgja PoTo8xGtFiwChm1eCTbOZF7gqhD9ZBCZfqMrFUMUL5sbzYOR+rX1jZIufgn1VMWByNdC HLc7jnbLRXTrpwk/dgyRyvPlZext+3HIxkyH7c10KglZ44uzt5kts419A4JOxZxfnvCj fIgKamj696EVw/Dvobv2vKDvXxAn7r0UF/mU5/V4e/qmBcVEVOLIPoswtfbjy7RLve/U X6Ng== 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=+GJrV0c5zzNT39TwSPxNd5uWTZp42OGxJwGSrdyqRJw=; b=uF84/vjRpx6+lEXtEk3jYKhEXk21sD/D52lcxYZRfiSaKJ3FOggwy6rkW94lh81Lqq 7LpwlVAFG9MmAtRXcK8iEQ9i3+27keIzKvz4pJek92K2yFihfqlQKmb9OEFYfs8iX1HY C1N1+IIPHoU8usoiWK6xo8ZCTlO+67fN3GSNQHhzojk3TonUuoDx3kgfPlVTTK7KnI5j gMkxduvF3RYXB/tmm7FP3UPAbfuYp+N829uULwql26UHfSItD6aU6aK4qb1Cxh2WIq0p 4Eydui4B2YltnocYHjRVxOAzjZt5zTfrB2Z41pqcbVMyMgle97ZA1a6nKMenSgdgL7lF s5NA== X-Gm-Message-State: AJcUukdH1fUlJMcHImvcJdHoZ/f6dOs9UQskMFw+88mxx5bYWHhG9Ig4 +5oaF7VXI6Zjg9YN/a/9TgXMygGB0cg= X-Google-Smtp-Source: ALg8bN4JRfBBv+Pp2dab6ZPrR6B1hzZ4j/mSo5HINLyDeJO+/1GCf8EzvLQj74AaZVYY+Md4n7k7AA== X-Received: by 2002:adf:a58a:: with SMTP id g10mr9366125wrc.3.1547681882807; Wed, 16 Jan 2019 15:38:02 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:02 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:15 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v3 42/50] audio: make mixeng optional X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implementation of the previously added mixeng option. Signed-off-by: Kővágó, Zoltán --- audio/audio_template.h | 46 ++++++++++++++++----------- audio/audio.c | 70 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 24 deletions(-) diff --git a/audio/audio_template.h b/audio/audio_template.h index 9ec565fc48..e5a4d6fa40 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -78,26 +78,32 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { - size_t samples; - if (!hw->pcm_ops) { - /* - * We should only end up here when using wavcapture hmp command (and not - * the wavcapture audio backend). - * It needs a lot of samples, otherwise you'll end up with "Could not - * mix X bytes into a capture buffer" warnings and a garbled capture. - */ - samples = 4096 * 4; - } else if (hw->pcm_ops->glue(buffer_size_, TYPE)) { - samples = hw->pcm_ops->glue(buffer_size_, TYPE)(hw); + if (hw->s->dev->TYPE->mixeng) { + size_t samples; + if (!hw->pcm_ops) { + /* + * We should only end up here when using wavcapture hmp command (and + * not the wavcapture audio backend). + * It needs a lot of samples, otherwise you'll end up with "Could + * not mix X bytes into a capture buffer" warnings and a garbled + * capture. + */ + samples = 4096 * 4; + } else if (hw->pcm_ops->glue(buffer_size_, TYPE)) { + samples = hw->pcm_ops->glue(buffer_size_, TYPE)(hw); + } else { + samples = 1024; /* todo better default */ + } + + if (audio_bug(__func__, samples == 0)) { + dolog("Attempted to allocate empty buffer\n"); + } + + HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples); + HWBUF->size = samples; } else { - samples = 1024; /* todo better default */ + HWBUF = NULL; } - if (audio_bug(__func__, samples == 0)) { - dolog("Attempted to allocate empty buffer\n"); - } - - HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples); - HWBUF->size = samples; } static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) @@ -116,6 +122,10 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) { int samples; + if (!sw->s->dev->TYPE->mixeng) { + return 0; + } + samples = ((int64_t) sw->HWBUF->size << 32) / sw->ratio; sw->buf = audio_calloc(__func__, samples, sizeof(struct st_sample)); diff --git a/audio/audio.c b/audio/audio.c index 6bbbcd3e03..db42d89dc3 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -839,32 +839,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 = sw->hw; - if (!sw->hw->enabled) { + if (!hw->enabled) { dolog ("Writing to disabled voice %s\n", SW_NAME (sw)); return 0; } - return audio_pcm_sw_write(sw, buf, size); + if (hw->s->dev->out->mixeng) { + return audio_pcm_sw_write(sw, buf, size); + } else { + return hw->pcm_ops->write(hw, buf, size); + } } size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) { + HWVoiceIn *hw; + if (!sw) { /* XXX: Consider options */ return size; } + hw = sw->hw; - if (!sw->hw->enabled) { + if (!hw->enabled) { dolog ("Reading from disabled voice %s\n", SW_NAME (sw)); return 0; } - return audio_pcm_sw_read(sw, buf, size); + if (hw->s->dev->in->mixeng) { + return audio_pcm_sw_read(sw, buf, size); + } else { + return hw->pcm_ops->read(hw, buf, size); + } } int AUD_get_buffer_size_out (SWVoiceOut *sw) @@ -1086,6 +1100,26 @@ static void audio_run_out (AudioState *s) HWVoiceOut *hw = NULL; SWVoiceOut *sw; + if (!s->dev->out->mixeng) { + while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) { + /* there is exactly 1 sw for each hw with no mixeng */ + sw = hw->sw_head.lh_first; + + if (hw->pending_disable) { + hw->enabled = 0; + hw->pending_disable = 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 = audio_pcm_hw_find_any_enabled_out(s, hw))) { size_t played, live, prev_rpos, free; int nb_live, cleanup_required; @@ -1223,6 +1257,17 @@ static void audio_run_in (AudioState *s) { HWVoiceIn *hw = NULL; + if (!s->dev->in->mixeng) { + while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) { + /* there is exactly 1 sw for each hw with no mixeng */ + SWVoiceIn *sw = hw->sw_head.lh_first; + if (sw->active) { + sw->callback.fn(sw->callback.opaque, INT_MAX); + } + } + return; + } + while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) { SWVoiceIn *sw; size_t captured = 0, min; @@ -1738,6 +1783,11 @@ CaptureVoiceOut *AUD_add_capture( s = audio_init(NULL, NULL); } + if (!s->dev->out->mixeng) { + dolog("Can't capture with mixeng disabled\n"); + goto err0; + } + if (audio_validate_settings (as)) { dolog ("Invalid settings were passed when trying to add capture\n"); audio_print_settings (as); @@ -1888,9 +1938,13 @@ static void audio_validate_per_direction_opts( *has_pdo = true; } + if (!(*pdo)->has_mixeng) { + (*pdo)->has_mixeng = true; + (*pdo)->mixeng = true; + } if (!(*pdo)->has_fixed_settings) { (*pdo)->has_fixed_settings = true; - (*pdo)->fixed_settings = true; + (*pdo)->fixed_settings = (*pdo)->mixeng; } if (!(*pdo)->fixed_settings && ((*pdo)->has_frequency || (*pdo)->has_channels || (*pdo)->has_format)) { @@ -1898,6 +1952,10 @@ static void audio_validate_per_direction_opts( "You can't use frequency, channels or format with fixed-settings=off"); return; } + if (!(*pdo)->mixeng && (*pdo)->fixed_settings) { + error_setg(errp, "You can't use fixed-settings without mixeng"); + return; + } if (!(*pdo)->has_frequency) { (*pdo)->has_frequency = true; @@ -1909,7 +1967,7 @@ static void audio_validate_per_direction_opts( } if (!(*pdo)->has_voices) { (*pdo)->has_voices = true; - (*pdo)->voices = 1; + (*pdo)->voices = (*pdo)->mixeng ? 1 : INT_MAX; } if (!(*pdo)->has_format) { (*pdo)->has_format = true; From patchwork Wed Jan 16 23:37:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767179 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E2E8F14E5 for ; Thu, 17 Jan 2019 00:05:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D1E052E9BD for ; Thu, 17 Jan 2019 00:05:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C34BF2F144; Thu, 17 Jan 2019 00:05:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 632FA2E9BD for ; Thu, 17 Jan 2019 00:05:26 +0000 (UTC) Received: from localhost ([127.0.0.1]:37884 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvBV-0000TI-KZ for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:05:25 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul5-0004MH-Qs for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003QC-1t for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:07 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:38059) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul3-0003ML-Nx for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:05 -0500 Received: by mail-wr1-x441.google.com with SMTP id v13so8966308wrw.5 for ; Wed, 16 Jan 2019 15:38:04 -0800 (PST) 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=tTY1W5I1BvSohdMC0L9ttbPe41jJ2IOf/RIdE7ybc6E=; b=ac1rgwKMqrHzL94YHpWj/cfx3asbyh9qBHi8+JmoFp464Pboex3m3F3L446T3YyPEY ZhqDhFivPSZzF54tpQ6H7I4UvIX0KxHjJgspieUhrIl0wjdz8AhS+6oKOLQffIBb8tu8 vMKzUh+dUwy3qCWxZ0+xFp6Udk/80SnzSikqtx7nsC7a4eJrpLJ7t73ovs8dJrFKKU5f 16teOYDaXLunM7PeSqP5HeEx4GPr1fJaWpcPKG/irSBhHzPoRsirHn8Iafhh4YpykY2X TovU8ZEXeOXCRhqPB68HJaB24paY/0q/XRBgHvd+eSjRYEH3adRicdMaNyxr5hXrwJtO uuMg== 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=tTY1W5I1BvSohdMC0L9ttbPe41jJ2IOf/RIdE7ybc6E=; b=YEZlxbBt/kr3OgT9IbnReWWKktF4BPiw0XgoGm4Dm5SBUQrrOepqCOfafxNEHSPxQN o/UxdIAB3nax20LrymctcVUIrg/n9RfR808MW9YUN21AarWqfkx+PmQ6rPx72EieDb3k WjTmof08HV2QO1hwJ8AEcsRs4YH+t66NaOmsAnhlUwt8SGug7+NuaksAvAudfpEkGmD2 bSfbHNIwZlX73bPjXju7bz9XtgMfKyZV5/0qt+M7H9oUHeJhCmVT6Wg/VamwIlHIhp0l QjpRho6CdBMF+UyTzh2Z3rkXnEy26Nz2nfPIKDMs04v+tfG2kFKVVRosBA0kZsrosTAI 79FA== X-Gm-Message-State: AJcUukdt+Fec6+INn1k6enxGcZkKgCkHQcW8zYhwtgxRh/G6WsYwuLq4 nCfb/O1KQxHuhDWlfO5Zg2K7GTJwhlM= X-Google-Smtp-Source: ALg8bN4HaopbDyDv7hnR8iCb+dM+Vd1xZlHI2U08LnsWce8Q5VptFo7xPRq8Hct+PnqNYlOZj+ml4Q== X-Received: by 2002:adf:ca13:: with SMTP id o19mr9419110wrh.148.1547681883559; Wed, 16 Jan 2019 15:38:03 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:03 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:16 +0100 Message-Id: <8afbe9918cd5da8e6d70749efd4cab3739e068a5.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 43/50] paaudio: get/put_buffer functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This lets us avoid some buffer copying when using mixeng. Signed-off-by: Kővágó, Zoltán --- audio/paaudio.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/audio/paaudio.c b/audio/paaudio.c index a45469066b..01c5df278b 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -97,6 +97,59 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) } \ } while (0) +static void *qpa_get_buffer_in(HWVoiceIn *hw, size_t *size) +{ + PAVoiceIn *p = (PAVoiceIn *) hw; + PAConnection *c = 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 = pa_stream_peek(p->stream, &p->read_data, &p->read_length); + CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail, + "pa_stream_peek failed\n"); + } + + *size = 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 = 0; + return NULL; +} + +static void qpa_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size) +{ + PAVoiceIn *p = (PAVoiceIn *) hw; + PAConnection *c = 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 == p->read_data && size <= p->read_length); + + p->read_data += size; + p->read_length -= size; + + if (size && !p->read_length) { + r = pa_stream_drop(p->stream); + CHECK_SUCCESS_GOTO(c, r == 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 = (PAVoiceIn *) hw; @@ -135,6 +188,32 @@ unlock_and_fail: return 0; } +static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + PAVoiceOut *p = (PAVoiceOut *) hw; + PAConnection *c = 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 = -1; + r = pa_stream_begin_write(p->stream, &ret, size); + CHECK_SUCCESS_GOTO(c, r >= 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 = 0; + return NULL; +} + static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length) { PAVoiceOut *p = (PAVoiceOut *) hw; @@ -683,12 +762,16 @@ static struct audio_pcm_ops qpa_pcm_ops = { .fini_out = qpa_fini_out, .write = qpa_write, .buffer_size_out = qpa_buffer_size_out, + .get_buffer_out = qpa_get_buffer_out, + .put_buffer_out = qpa_write, /* pa handles it */ .volume_out = qpa_volume_out, .init_in = qpa_init_in, .fini_in = qpa_fini_in, .read = qpa_read, .buffer_size_in = qpa_buffer_size_in, + .get_buffer_in = qpa_get_buffer_in, + .put_buffer_in = qpa_put_buffer_in, .volume_in = qpa_volume_in }; From patchwork Wed Jan 16 23:37:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767203 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79FAB17FB for ; Thu, 17 Jan 2019 00:15:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B8982E116 for ; Thu, 17 Jan 2019 00:15:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 69CB32FC42; Thu, 17 Jan 2019 00:15:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B60222FB2A for ; Thu, 17 Jan 2019 00:15:52 +0000 (UTC) Received: from localhost ([127.0.0.1]:40588 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvLc-0000rB-26 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:15:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58319) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul8-0004P0-1L for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul4-0003SR-KV for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:09 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:39039) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003ND-7Y for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:06 -0500 Received: by mail-wr1-x441.google.com with SMTP id t27so8961186wra.6 for ; Wed, 16 Jan 2019 15:38:05 -0800 (PST) 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=nRdmBexwGVk7768hNeTlwsRI1xYFXkTuW9TXHvffV1I=; b=cIamHcYKyjBTT9hAXozCXjkuik3PwfnWspGpCpAK5qMFD3bl84QwGGwswPPvUN6UTz DTaK9/z/ZsB48hVlF/jrnNP6AeSq4MCv0GNvs1DCJgNYV6OdGxWBFgfmJvd6pqSJKJh0 KmHT6wipno1/NeG+LjHtGsYWMTz7XUZcr2/LnE0Y/52ykJn+utOJeoSCkIyKtCF5W2DM 2p06sNgHDC7HDefRUNZUuArotDZMdU8FdNRaEwmd+Z2mxJYiN1KJDbp+JUSRsqPZn2a0 Ba+i4tOeOE/dChoQeoKdaltQVVMZfPvG3gevtENsKjVm2DqkY0016Uprfz4mpiFD81VN M+Cw== 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=nRdmBexwGVk7768hNeTlwsRI1xYFXkTuW9TXHvffV1I=; b=r9J56IRZHgyT2PrFDyDFCppTRUG7AvUdDafDaStZ1KIribgvFlrR8JRsNbrd5bGxWQ zmBki2+aVt8NlO4ft6k1Axa6oQCFHzOtqG3boXuOFyd9Jhke6VASIy5KvrtjSNhL/P3m t5Itxplnz9z3VhST7F2O19oIz332tE0SbVII8NegLrlOwwQ59bDkERoexh1TrpVwy0iH mKOmJOciIOX7qdnDtNR+bZ1SjX7YAGBbc+cYWLsmzFmD8dlQnyS0w+aFeCSgg3eEMUPT 8FjTKCZRToC5MI43vcF59MD9bXvfhAhjzYGWiGnZxC/3fJmtE1Wt4qfKGAvAsEQhsRhV uFuw== X-Gm-Message-State: AJcUukfQNjXxDpNqCZY4Vc/fvGANHhiPNEMoTpWIIuD2fQB11uX/4sFs 2XNp0fVOSnmtNYdlY13iBQK4eVYM19M= X-Google-Smtp-Source: ALg8bN4yvGfhmcOjXFZ7wex5dFecR2bSjkkXFancGchdyaDYbxZRhc9VWVtEGqiDGc9GwbW0mT7LkQ== X-Received: by 2002:adf:a50c:: with SMTP id i12mr9106887wrb.220.1547681884371; Wed, 16 Jan 2019 15:38:04 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:03 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:17 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::441 Subject: [Qemu-devel] [PATCH v3 44/50] audio: support more than two channels in volume setting X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Kővágó, Zoltán --- audio/audio.h | 10 ++++++++++ audio/audio_int.h | 4 ++-- audio/audio.c | 28 ++++++++++++++++++++-------- audio/paaudio.c | 20 ++++++++++++-------- audio/spiceaudio.c | 14 ++++++++------ 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/audio/audio.h b/audio/audio.h index 2db27bba7b..bfb7ab2197 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -123,6 +123,16 @@ uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts); void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol); void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol); +#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 6fec4f159c..cef749d647 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -165,7 +165,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); 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); }; void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size); diff --git a/audio/audio.c b/audio/audio.c index db42d89dc3..a5ee0c4324 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1901,31 +1901,43 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) } void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol) +{ + Volume vol = { .mute = mute, .channels = 2, .vol = { lvol, rvol } }; + audio_set_volume_out(sw, &vol); +} + +void audio_set_volume_out(SWVoiceOut *sw, Volume *vol) { if (sw) { HWVoiceOut *hw = sw->hw; - sw->vol.mute = mute; - sw->vol.l = nominal_volume.l * lvol / 255; - sw->vol.r = nominal_volume.r * rvol / 255; + sw->vol.mute = vol->mute; + sw->vol.l = nominal_volume.l * vol->vol[0] / 255; + sw->vol.r = nominal_volume.l * vol->vol[vol->channels > 1 ? 1 : 0] / 255; if (hw->pcm_ops->volume_out) { - hw->pcm_ops->volume_out(hw, &sw->vol); + hw->pcm_ops->volume_out(hw, vol); } } } void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) +{ + Volume vol = { .mute = mute, .channels = 2, .vol = { lvol, rvol } }; + audio_set_volume_in(sw, &vol); +} + +void audio_set_volume_in(SWVoiceIn *sw, Volume *vol) { if (sw) { HWVoiceIn *hw = sw->hw; - sw->vol.mute = mute; - sw->vol.l = nominal_volume.l * lvol / 255; - sw->vol.r = nominal_volume.r * rvol / 255; + sw->vol.mute = vol->mute; + sw->vol.l = nominal_volume.l * vol->vol[0] / 255; + sw->vol.r = nominal_volume.r * vol->vol[vol->channels > 1 ? 1 : 0] / 255; 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/paaudio.c b/audio/paaudio.c index 01c5df278b..0d67c03b4c 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -537,20 +537,22 @@ static void qpa_fini_in (HWVoiceIn *hw) } } -static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol) +static void qpa_volume_out(HWVoiceOut *hw, Volume *vol) { PAVoiceOut *pa = (PAVoiceOut *) hw; pa_operation *op; pa_cvolume v; PAConnection *c = pa->g->conn; + int i; #ifdef PA_CHECK_VERSION /* macro is present in 0.9.16+ */ pa_cvolume_init (&v); /* function is present in 0.9.13+ */ #endif - v.channels = 2; - v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX; - v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX; + v.channels = vol->channels; + for (i = 0; i < vol->channels; ++i) { + v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255; + } pa_threaded_mainloop_lock(c->mainloop); @@ -577,20 +579,22 @@ static void qpa_volume_out(HWVoiceOut *hw, struct mixeng_volume *vol) pa_threaded_mainloop_unlock(c->mainloop); } -static void qpa_volume_in(HWVoiceIn *hw, struct mixeng_volume *vol) +static void qpa_volume_in(HWVoiceIn *hw, Volume *vol) { PAVoiceIn *pa = (PAVoiceIn *) hw; pa_operation *op; pa_cvolume v; PAConnection *c = pa->g->conn; + int i; #ifdef PA_CHECK_VERSION pa_cvolume_init (&v); #endif - v.channels = 2; - v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->l) / UINT32_MAX; - v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->r) / UINT32_MAX; + v.channels = vol->channels; + for (i = 0; i < vol->channels; ++i) { + v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255; + } pa_threaded_mainloop_lock(c->mainloop); diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 771ecacf27..b26d10434b 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -179,13 +179,14 @@ static void line_out_enable(HWVoiceOut *hw, bool enable) } #if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2)) -static void line_out_volume(HWVoiceOut *hw, struct mixeng_volume *vol) +static void line_out_volume(HWVoiceOut *hw, Volume *vol) { SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw); uint16_t svol[2]; - svol[0] = vol->l / ((1ULL << 16) + 1); - svol[1] = vol->r / ((1ULL << 16) + 1); + assert(vol->channels == 2); + svol[0] = vol->vol[0] * 257; + svol[1] = vol->vol[1] * 257; spice_server_playback_set_volume(&out->sin, 2, svol); spice_server_playback_set_mute(&out->sin, vol->mute); } @@ -266,13 +267,14 @@ static void line_in_enable(HWVoiceIn *hw, bool enable) } #if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2)) -static void line_in_volume(HWVoiceIn *hw, struct mixeng_volume *vol) +static void line_in_volume(HWVoiceIn *hw, Volume *vol) { SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw); uint16_t svol[2]; - svol[0] = vol->l / ((1ULL << 16) + 1); - svol[1] = vol->r / ((1ULL << 16) + 1); + assert(vol->channels == 2); + svol[0] = vol->vol[0] * 257; + svol[1] = vol->vol[1] * 257; spice_server_record_set_volume(&in->sin, 2, svol); spice_server_record_set_mute(&in->sin, vol->mute); } From patchwork Wed Jan 16 23:37:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767205 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30E0113A4 for ; Thu, 17 Jan 2019 00:16:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 209C62FB2F for ; Thu, 17 Jan 2019 00:16:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1EE502FC92; Thu, 17 Jan 2019 00:16:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D0D162FB2F for ; Thu, 17 Jan 2019 00:16:38 +0000 (UTC) Received: from localhost ([127.0.0.1]:40755 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvMM-0001Ln-1l for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:16:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58499) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulC-0004U6-2f for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul5-0003UR-90 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:39040) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul4-0003Qh-RA for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:07 -0500 Received: by mail-wr1-x442.google.com with SMTP id t27so8961213wra.6 for ; Wed, 16 Jan 2019 15:38:06 -0800 (PST) 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=6Y7zcCw1JOakhGt46M5w7kH289gKDuWYeYjNaxP+8iM=; b=aYJyKdGwBQaHX69IisHEE081ei7Jsu98dAoZnwzZBN1zcYEzPDuhqVOEkxz7yrKfix zU/5yakG17l2jk0PaWqwzUJgt6SMP51A3JAZyul9GMnDw6N7/1NPUU03DQeVXQsSJczo KrMlrJ0Q4l/G5jhdXUCkfyOrs/Tgf68ktA8BtkxGILQHOCVOyqqS6/4uivFk6GRRLyE+ GujeGqSW/9hSmIhvZdU4V+oTn7cYOT3iOD2tcCCVzs3NVtHkOfu/BAT5ebCUYSnA6XlL 0SxsdwwnJlT7ekQQODfQEQKTBM9YdlvOGkjXhme35e0e7EhniVzoGm1bAiO6KDehRXia siAQ== 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=6Y7zcCw1JOakhGt46M5w7kH289gKDuWYeYjNaxP+8iM=; b=g/IkGMH4WS1/s+ls0VD9z9u5ywn5tN37GTZQQZZK/k2wuH/8rdOP9jYNo//4rhmg9l QQA6Bs7oXezleJe0KoyYXhOttYXRjhQdGbRd1IoRUVZBa4K/Z51NY4q9OSmwnoYMqzT9 YtNrdt8KbZJ0gG0AtfhsuTWFnEFUVI+Ftzl6fp4J2ISASSskHoaYXAy1bIUndiHYR88+ NGzpCVOO/6vLNzMBs53A2pfHk5bfinH6FoXuGxio70taS7tvyJr5sPh8EwkuPMsSvBnq UndHRSErycnsCNBYvOrQ6sB/+QeWb1aH/9s5FHoaJnC5XC9xyfgC7cTNSMPz0VpCG8LB 5Ajw== X-Gm-Message-State: AJcUukeVwiWwHj76rLEnT27IbomwlLsUbC7k6z7YgZpFrlViwwl26o2W ONC6A6TwJQbw548FvHHB/L8sp6B9Tqs= X-Google-Smtp-Source: ALg8bN4alypn6L84x2xRo+I22tXVkZPBjJotE3ZummkkyFlEA47VeHGc1/MP2u682WMR5nn+FiH9iA== X-Received: by 2002:adf:e1c3:: with SMTP id l3mr9670400wri.36.1547681885262; Wed, 16 Jan 2019 15:38:05 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:04 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:18 +0100 Message-Id: <95a888ccd61f53a1ac88e8f33454b2f7677d9d3d.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v3 45/50] audio: replace shift in audio_pcm_info with bytes_per_frame X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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ővágó, Zoltán --- audio/audio_int.h | 3 +- audio/dsound_template.h | 10 +++--- audio/alsaaudio.c | 10 +++--- audio/audio.c | 76 ++++++++++++++++++++--------------------- audio/coreaudio.c | 4 +-- audio/dsoundaudio.c | 4 +-- audio/noaudio.c | 2 +- audio/ossaudio.c | 14 ++++---- audio/spiceaudio.c | 5 +-- audio/wavaudio.c | 6 ++-- 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/audio/audio_int.h b/audio/audio_int.h index cef749d647..925552a2f7 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/dsound_template.h b/audio/dsound_template.h index 6a10b6751b..31d356d084 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -98,8 +98,8 @@ static int glue (dsound_lock_, TYPE) ( goto fail; } - 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 audsettings *as, obt_as.endianness = 0; audio_pcm_init_info (&hw->info, &obt_as); - 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 = bc.dwBufferBytes; - ds->samples = bc.dwBufferBytes >> hw->info.shift; + ds->samples = bc.dwBufferBytes / hw->info.bytes_per_frame; ds->s = s; #ifdef DEBUG_DSOUND diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 446bb90ceb..3e5c800d38 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -611,7 +611,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; size_t pos = 0; - size_t len_frames = len >> hw->info.shift; + size_t len_frames = len / hw->info.bytes_per_frame; while (len_frames) { char *src = advance(buf, pos); @@ -655,7 +655,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) } } - pos += written << hw->info.shift; + pos += written * hw->info.bytes_per_frame; if (written < len_frames) { break; } @@ -821,7 +821,7 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) void *dst = advance(buf, pos); snd_pcm_sframes_t nread; - nread = snd_pcm_readi(alsa->handle, dst, len >> hw->info.shift); + nread = snd_pcm_readi(alsa->handle, dst, len / hw->info.bytes_per_frame); if (nread <= 0) { switch (nread) { @@ -847,8 +847,8 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) } } - pos += nread << hw->info.shift; - len -= nread << hw->info.shift; + pos += nread * hw->info.bytes_per_frame; + len -= nread * hw->info.bytes_per_frame; } return pos; diff --git a/audio/audio.c b/audio/audio.c index a5ee0c4324..c89e82443d 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -297,26 +297,27 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *a void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) { - int bits = 8, sign = 0, shift = 0; + int bits = 8, sign = 0, mul; switch (as->fmt) { case AUDIO_FORMAT_S8: sign = 1; case AUDIO_FORMAT_U8: + mul = 1; break; case AUDIO_FORMAT_S16: sign = 1; case AUDIO_FORMAT_U16: bits = 16; - shift = 1; + mul = 2; break; case AUDIO_FORMAT_S32: sign = 1; case AUDIO_FORMAT_U32: bits = 32; - shift = 2; + mul = 4; break; default: @@ -327,9 +328,8 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) info->bits = bits; info->sign = sign; info->nchannels = as->nchannels; - info->shift = (as->nchannels == 2) + shift; - info->align = (1 << info->shift) - 1; - info->bytes_per_second = info->freq << info->shift; + info->bytes_per_frame = as->nchannels * mul; + info->bytes_per_second = info->freq * info->bytes_per_frame; info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS); } @@ -340,26 +340,25 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) } 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; case 16: { int i; uint16_t *p = buf; - int shift = info->nchannels - 1; short s = INT16_MAX; if (info->swap_endianness) { s = bswap16 (s); } - for (i = 0; i < len << shift; i++) { + for (i = 0; i < len * info->nchannels; i++) { p[i] = s; } } @@ -369,14 +368,13 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) { int i; uint32_t *p = buf; - int shift = info->nchannels - 1; int32_t s = INT32_MAX; if (info->swap_endianness) { s = bswap32 (s); } - for (i = 0; i < len << shift; i++) { + for (i = 0; i < len * info->nchannels; i++) { p[i] = s; } } @@ -559,7 +557,7 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) while (len) { st_sample *src = hw->mix_buf->samples + pos; - uint8_t *dst = advance (pcm_buf, clipped << hw->info.shift); + uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame); size_t samples_till_end_of_buf = hw->mix_buf->size - pos; size_t samples_to_clip = MIN(len, samples_till_end_of_buf); @@ -608,7 +606,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) return 0; } - samples = size >> sw->info.shift; + samples = size / sw->info.bytes_per_frame; if (!live) { return 0; } @@ -643,7 +641,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) sw->clip (buf, sw->buf, ret); sw->total_hw_samples_acquired += total; - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } /* @@ -716,7 +714,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) } wpos = (sw->hw->mix_buf->pos + live) % hwsamples; - samples = size >> sw->info.shift; + samples = size / sw->info.bytes_per_frame; dead = hwsamples - live; swlim = ((int64_t) dead << 32) / sw->ratio; @@ -760,13 +758,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 - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } #ifdef DEBUG_AUDIO @@ -883,7 +881,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) 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; } void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -999,10 +997,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_frame ); - return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_frame; } static size_t audio_get_free(SWVoiceOut *sw) @@ -1026,10 +1024,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.shift); + live, dead, (((int64_t) dead << 32) / sw->ratio) * + sw->info.bytes_per_frame); #endif - return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) dead << 32) / sw->ratio) * sw->info.bytes_per_frame; } static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, @@ -1048,7 +1047,7 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, while (n) { size_t till_end_of_hw = hw->mix_buf->size - rpos2; size_t to_write = MIN(till_end_of_hw, n); - size_t bytes = to_write << hw->info.shift; + size_t bytes = to_write * hw->info.bytes_per_frame; size_t written; sw->buf = hw->mix_buf->samples + rpos2; @@ -1078,10 +1077,11 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) size_t size, decr, proc; void *buf = hw->pcm_ops->get_buffer_out(hw, &size); - decr = MIN(size >> hw->info.shift, live); + decr = MIN(size / hw->info.bytes_per_frame, live); audio_pcm_hw_clip_out(hw, buf, decr); - proc = hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shift) >> - hw->info.shift; + proc = hw->pcm_ops->put_buffer_out(hw, buf, + decr * hw->info.bytes_per_frame) / + hw->info.bytes_per_frame; live -= proc; clipped += proc; @@ -1230,16 +1230,16 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) while (samples) { size_t proc; - size_t size = samples << hw->info.shift; + size_t size = samples * hw->info.bytes_per_frame; void *buf = hw->pcm_ops->get_buffer_in(hw, &size); - assert((size & hw->info.align) == 0); + assert(size % hw->info.bytes_per_frame == 0); if (size == 0) { hw->pcm_ops->put_buffer_in(hw, buf, size); break; } - proc = MIN(size >> hw->info.shift, + proc = MIN(size / hw->info.bytes_per_frame, conv_buf->size - conv_buf->pos); hw->conv(conv_buf->samples + conv_buf->pos, buf, proc); @@ -1247,7 +1247,7 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) samples -= proc; conv += 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_frame); } return conv; @@ -1321,7 +1321,7 @@ static void audio_run_capture (AudioState *s) for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) { cb->ops.capture (cb->opaque, cap->buf, - to_capture << hw->info.shift); + to_capture * hw->info.bytes_per_frame); } rpos = (rpos + to_capture) % hw->mix_buf->size; live -= to_capture; @@ -1374,7 +1374,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) ssize_t start; if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->conv_buf->size << hw->info.shift; + size_t calc_size = hw->conv_buf->size * hw->info.bytes_per_frame; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; hw->pos_emul = hw->pending_emul = 0; @@ -1410,7 +1410,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 = hw->mix_buf->size << hw->info.shift; + size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; @@ -1829,11 +1829,11 @@ CaptureVoiceOut *AUD_add_capture( audio_pcm_init_info (&hw->info, as); cap->buf = audio_calloc(__func__, hw->mix_buf->size, - 1 << hw->info.shift); + hw->info.bytes_per_frame); if (!cap->buf) { dolog ("Could not allocate capture buffer " "(%zu samples, each %d bytes)\n", - hw->mix_buf->size, 1 << hw->info.shift); + hw->mix_buf->size, hw->info.bytes_per_frame); goto err3; } @@ -2132,14 +2132,14 @@ size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - rate->start_ticks; bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND); - samples = (bytes - rate->bytes_sent) >> info->shift; + samples = (bytes - rate->bytes_sent) / info->bytes_per_frame; if (samples < 0 || samples > 65536) { AUD_log(NULL, "Resetting rate control (%" PRId64 " samples)", samples); audio_rate_start(rate); samples = 0; } - ret = MIN(samples << info->shift, bytes_avail); + ret = MIN(samples * info->bytes_per_frame, bytes_avail); rate->bytes_sent += ret; return ret; } diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 508bee19d4..f011f4db59 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -441,7 +441,7 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; - pending_frames = hw->pending_emul >> hw->info.shift; + pending_frames = hw->pending_emul / hw->info.bytes_per_frame; /* if there are not enough samples, set signal and return */ if (pending_frames < frameCount) { @@ -450,7 +450,7 @@ static OSStatus audioDeviceIOProc( return 0; } - len = frameCount << hw->info.shift; + len = frameCount * hw->info.bytes_per_frame; while (len) { size_t write_len; ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index da9276c268..4bf2be74c1 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -322,8 +322,8 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb, return; } - len1 = blen1 >> hw->info.shift; - len2 = blen2 >> hw->info.shift; + len1 = blen1 / hw->info.bytes_per_frame; + len2 = blen2 / hw->info.bytes_per_frame; #ifdef DEBUG_DSOUND dolog ("clear %p,%ld,%ld %p,%ld,%ld\n", diff --git a/audio/noaudio.c b/audio/noaudio.c index c8bcfa9bca..65ef953104 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -88,7 +88,7 @@ static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) NoVoiceIn *no = (NoVoiceIn *) hw; int64_t bytes = audio_rate_get_bytes(&hw->info, &no->rate, size); - 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_frame); return bytes; } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index f12d8a95bd..2afa7fbfa1 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -507,16 +507,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - 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); } - oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; oss->mmapped = 0; if (oopts->has_try_mmap && oopts->try_mmap) { - hw->size_emul = oss->samples << hw->info.shift; + hw->size_emul = oss->samples * hw->info.bytes_per_frame; hw->buf_emul = mmap ( NULL, hw->size_emul, @@ -651,12 +651,12 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - 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); } - oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; oss->fd = fd; oss->dev = dev; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index b26d10434b..a1c80ff92a 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -133,8 +133,9 @@ static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) out->fpos = 0; } - *size = audio_rate_get_bytes(&hw->info, &out->rate, - (out->fsize - out->fpos) << hw->info.shift); + *size = audio_rate_get_bytes( + &hw->info, &out->rate, + (out->fsize - out->fpos) * hw->info.bytes_per_frame); return out->frame + out->fpos; } diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 672d5fc337..a23f6e710b 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -41,14 +41,14 @@ static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; int64_t bytes = audio_rate_get_bytes(&hw->info, &wav->rate, len); - assert(bytes >> hw->info.shift << hw->info.shift == bytes); + assert(bytes % hw->info.bytes_per_frame == 0); if (bytes && fwrite(buf, bytes, 1, wav->f) != 1) { dolog("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n", bytes, strerror(errno)); } - wav->total_samples += bytes >> hw->info.shift; + wav->total_samples += bytes / hw->info.bytes_per_frame; return bytes; } @@ -131,7 +131,7 @@ static void wav_fini_out (HWVoiceOut *hw) WAVVoiceOut *wav = (WAVVoiceOut *) hw; uint8_t rlen[4]; uint8_t dlen[4]; - uint32_t datalen = wav->total_samples << hw->info.shift; + uint32_t datalen = wav->total_samples * hw->info.bytes_per_frame; uint32_t rifflen = datalen + 36; if (!wav->f) { From patchwork Wed Jan 16 23:37:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767197 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69E241390 for ; Thu, 17 Jan 2019 00:12:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C72D2FC17 for ; Thu, 17 Jan 2019 00:12:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5078E2FC35; Thu, 17 Jan 2019 00:12:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 034FF2FC17 for ; Thu, 17 Jan 2019 00:12:53 +0000 (UTC) Received: from localhost ([127.0.0.1]:39810 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvIj-0006d2-0k for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:12:53 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58374) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004Qf-5M for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul5-0003Uz-Es for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:33800) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul5-0003S5-7B for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:07 -0500 Received: by mail-wr1-x442.google.com with SMTP id j2so9013335wrw.1 for ; Wed, 16 Jan 2019 15:38:07 -0800 (PST) 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=sa/1JDOEKtcmm5AdOCqgp/QNq8H0ymve3K1gS2hF/qM=; b=XbkbPi/5IoQJ/Ozs8s0WzBUCxzkhZgX76NS9gH3Ck51n12Mfw9Qdx38GnKihwY2q4+ 0IYPkWV46zlgotY8/JjrqyCDQ+knZdvzbZ2AnWd7FhiQIvWXZrxGYCSMbR6difNbOi9B bsqq91tUirwrJPe460AL4tPrQS+iRk44IvOaAmRQE7n9d3+P646O3jQBuAZuDFNhgEbg Mbo+PDeY5i8K4Z0ePxC7DPXrkMuspKpoGHK8x0AfY6rF7SqSHo11ih0OSEZgTASe1eMp sOax7meerg7XAQROINffLwvvhepW2quv71sqb1grO2TY+2Ybv0fO/94r0Zfb4P0Zaeyx ZV7Q== 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=sa/1JDOEKtcmm5AdOCqgp/QNq8H0ymve3K1gS2hF/qM=; b=gNlmNLanvh79756Z5b3JwgtjTyA62P/H6fnRahbD8q4U8Zq3dTcfRha57lZufkZo8o ccu0Bc99+Fuu8z700oDaVEgbGWREXI+Ygq3gb+agsGT7CNMxUdcXZTl3dyu//hdGcBgG YdTYZzm+dssSo44UvDehw20lJVm89w6qIUzqVCItVt8YwBquAN/i9WiMn12osMQovbsd M+EBqA4TBhHl4F0VQ4HgiyD7YeqvPtWEp4a5mhlH4F1Uq6QmyVPVUHkB0SI4v4RVw2SR OivNhfEU0Vc2kswq13znBQvK71j1y1CJYUyyd21Yuw/G0uV0TfzD1cw/cqryJKI81bfM vOWg== X-Gm-Message-State: AJcUukfIfShBNK8RzFshEPSVI52X4qivW1vwLQ6bP9lYh6Dui5RxJVX0 Zw3ZFoIaHALLO5bF1EvJUzu77Vwy0aY= X-Google-Smtp-Source: ALg8bN4qvytRjnIeLLzZk8etd33+aVd2dO0tdMluXJAMHjtRy/HvcupMy+lh0BTQdoIwalDNpnEUMg== X-Received: by 2002:adf:9205:: with SMTP id 5mr9438429wrj.189.1547681885973; Wed, 16 Jan 2019 15:38:05 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:05 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:19 +0100 Message-Id: <8b7b4e3fa7d5f06d4dd05be668dd4c65fdadba90.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v3 46/50] audio: basic support for multichannel audio X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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ővágó, Zoltán --- 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 3e5c800d38..f6fe95b557 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -497,13 +497,6 @@ static int alsa_open(bool in, struct alsa_params_req *req, goto err; } - if (nchannels != 1 && nchannels != 2) { - alsa_logerr2 (err, typ, - "Can not handle obtained number of channels %d\n", - nchannels); - goto err; - } - if (pdo->buffer_count) { if (pdo->buffer_len) { int64_t req = pdo->buffer_len * pdo->buffer_count; diff --git a/audio/audio.c b/audio/audio.c index c89e82443d..f59dd0100f 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -240,7 +240,7 @@ static int audio_validate_settings (struct audsettings *as) { int invalid; - invalid = as->nchannels != 1 && as->nchannels != 2; + invalid = as->nchannels < 1; invalid |= as->endianness != 0 && as->endianness != 1; switch (as->fmt) { From patchwork Wed Jan 16 23:37:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767213 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E861746 for ; Thu, 17 Jan 2019 00:21:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AEBC2F144 for ; Thu, 17 Jan 2019 00:21:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2BA132FAF5; Thu, 17 Jan 2019 00:21:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A525F2F144 for ; Thu, 17 Jan 2019 00:21:26 +0000 (UTC) Received: from localhost ([127.0.0.1]:41907 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvQw-0004mH-2K for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:21:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58404) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004RM-QT for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul6-0003YW-JA for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:54054) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul6-0003VH-6O for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:08 -0500 Received: by mail-wm1-x344.google.com with SMTP id d15so3886090wmb.3 for ; Wed, 16 Jan 2019 15:38:08 -0800 (PST) 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=wFxcgM/q5BlX8DcgUOK+D68Xqs58OTOhAm8rzeXNdZk=; b=hXltc+hjUnYSSdzbyfhpUmtg9+DxgPdeIPp6lFfPkWpLuK4Bk76bCPIzvHdDhu8N10 88FCS/3nj8hlCUsLWcgo9g2it8s6VTXrIWlhklGSOGvidYTzEAJ+BkjJO1xJUk6KUaqO 8q/5al1Az8Lxl14nyn0Mo6nIK2dUehalltxrvtTL4Jyt7I95nS0SQG69YCklRmFM7JVr pQLoU/UdfZwxNvaUeKzN+18e9Ze/9NR84dg8ffmbAV9VGT7TqJDXk7tyrZzhGEtfoW0o m8OJ/iqh4NSvqc8jRFlWY1vMj870DtyQYEsSp7rGMAcBp22R3WI12eeVcyktZz5BnNcN lf+Q== 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=wFxcgM/q5BlX8DcgUOK+D68Xqs58OTOhAm8rzeXNdZk=; b=InjqNt6hFXRLunuocWA0hFWmiXOCmGg8X6J1LoDEEH5Y0cMoMNbrfaUHXoHnpIVAge dL9YNdC2bg4DN/XnL/kAcc9LgvFNvCowPUeIAdiFm4Xr9sgKWs9dcnCwr77FrCAvSxUq 1a/b7rFE/Y9sjmSSzpcyqj0CjlK13vMO0NCIEMTUqw3Bw7wePJ41a26MNRNghfTUwzJ4 6LCPgN5oTz5QO+rnL+04aUM3hih2nDpoyvF+wHdtPFPeXa6osTDfyaIxqNW/0gNmmAjB ZwcJMNCKb/ZVjA8OZKuOH8//Nun3ib/MdBwlnfE20SYuZwtbE3iQhkEfopgSte1mQseQ AEsA== X-Gm-Message-State: AJcUukfUE2HinTZ6H+x/rCNt29xwApMQZ7MyT/7PwvZJAwlu71GzPpdq danJpT/TcVU8+ORyjvisAvkan/gHvCo= X-Google-Smtp-Source: ALg8bN5qcunwJXxEWiIYon9M/M2sVxMrfhe48eFBvndFY9lRW/EnCEoC7VRSRw8p+rdG/g4TyJBPGA== X-Received: by 2002:a1c:bc82:: with SMTP id m124mr9197733wmf.77.1547681886789; Wed, 16 Jan 2019 15:38:06 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:06 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:20 +0100 Message-Id: <82a755097c6aaa16363348599110f9af3bb07583.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v3 47/50] paaudio: channel-map option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann , Markus Armbruster Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add an option to change the channel map used by pulseaudio. If not specified, falls back to an OSS compatible channel map. Signed-off-by: Kővágó, Zoltán --- qapi/audio.json | 5 ++++- audio/paaudio.c | 18 ++++++++++++++---- qemu-options.hx | 9 +++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/qapi/audio.json b/qapi/audio.json index 7bcea6240f..86078039dc 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -107,11 +107,14 @@ # # @name: name of the sink/source to use # +# @channel-map: channel map to use (default: OSS compatible map) +# # Since: 4.0 ## { 'struct': 'AudiodevPaPerDirectionOptions', 'data': { - '*name': 'str' } } + '*name': 'str', + '*channel-map': 'str' } } ## # @AudiodevPaOptions: diff --git a/audio/paaudio.c b/audio/paaudio.c index 0d67c03b4c..b0e311584a 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -337,17 +337,27 @@ 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 char *map, const pa_buffer_attr *attr, int *rerror) { int r; pa_stream *stream; pa_stream_flags_t flags; + pa_channel_map pa_map; pa_threaded_mainloop_lock(c->mainloop); - stream = pa_stream_new(c->context, name, ss, map); + if (map && !pa_channel_map_parse(&pa_map, map)) { + dolog("Invalid channel map specified: '%s'\n", map); + map = NULL; + } + if (!map) { + pa_channel_map_init_extend(&pa_map, ss->channels, + PA_CHANNEL_MAP_OSS); + } + + stream = pa_stream_new(c->context, name, ss, &pa_map); if (!stream) { goto fail; } @@ -424,7 +434,7 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as, PA_STREAM_PLAYBACK, ppdo->has_name ? ppdo->name : NULL, &ss, - NULL, /* channel map */ + ppdo->has_channel_map ? ppdo->channel_map : NULL, &ba, /* buffering attributes */ &error ); @@ -472,7 +482,7 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) PA_STREAM_RECORD, ppdo->has_name ? ppdo->name : NULL, &ss, - NULL, /* channel map */ + ppdo->has_channel_map ? ppdo->channel_map : NULL, NULL, /* buffering attributes */ &error ); diff --git a/qemu-options.hx b/qemu-options.hx index 53fc5ef453..c4835f77c3 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -468,6 +468,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, "-audiodev pa,id=id[,prop[=value][,...]]\n" " server= PulseAudio server address\n" " sink|source.name= sink/source device name\n" + " sink|source.channel-map= channel map to use\n" #endif #ifdef CONFIG_SDL "-audiodev sdl,id=id[,prop[=value][,...]]\n" @@ -621,6 +622,14 @@ Sets the PulseAudio @var{server} to connect to. @item sink|source.name=@var{sink} Use the specified sink/source for playback/recording. +@item sink|source.channel-map=@var{map} +Use the specified channel map. The default is an OSS compatible +channel map. Do not forget to escape commas inside the map: + +@example +-audiodev pa,id=example,sink.channel-map=front-left,,front-right +@end example + @end table @item -audiodev sdl,id=@var{id}[,@var{prop}[=@var{value}][,...]] From patchwork Wed Jan 16 23:37:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767189 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76BF61390 for ; Thu, 17 Jan 2019 00:10:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 685C42FB1C for ; Thu, 17 Jan 2019 00:10:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5CF822FBCE; Thu, 17 Jan 2019 00:10:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0239C2FB2F for ; Thu, 17 Jan 2019 00:10:30 +0000 (UTC) Received: from localhost ([127.0.0.1]:39214 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvGP-0004iS-0I for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:10:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58373) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjul9-0004Qc-5M for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul6-0003ZX-TK for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:11 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:55755) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul6-0003Wh-L6 for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:08 -0500 Received: by mail-wm1-x342.google.com with SMTP id y139so3851834wmc.5 for ; Wed, 16 Jan 2019 15:38:08 -0800 (PST) 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=AyJ30updK3hnIixXSYEwUA0xI8Q1m4nxDMv/ypz28XA=; b=SjgcSjXs5NgBI83R7fr82+vLT724Erku/MeQ6z3F7KABWaCOGZplXxu5+JA8KQOvPE rqf7lhOjIoTQIUAoVH22m7rYqCrWvhuoNigdMt4fQZUuz1qz7+Qf3HFeg/dcsuehnFIK i5fzlG5FYHbM86iskAA1AySRqYkl71w6oDG6RkAd7aMhany5Zaxfd1dORRshTuC6Zw4G K3oZJpsANt7jqQ5mncuX5YVFpHo8O/cxSaZXwB0Vb/SgPrrNEtKmrm27G16tlQanJpqs Oe4PRIQqfM2rE6ZL00mAcNGJdpUSwukynqDAiPlw4DUM4KQvKbr55TyyYPU/HxXHD6/5 v2Uw== 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=AyJ30updK3hnIixXSYEwUA0xI8Q1m4nxDMv/ypz28XA=; b=E/ChpWDOmFGqnyEt6Zi4SnsfHl07y3qaFV1SwZ0GY7LfkcuZWujPxn5r8DT61tso1K +LsKM2qYhV9RHqhOYeSKiA6mKZ5UQEBivyT16q/6sElN0L9xU/LzolY5ta5HIR2GUqQe n5pTQ/Fn8ns733T0K/2v9skaG3v2wwN8wEJQQYMire1W107+3GQHuMHhSV6fmCarEHqH ieZhVhI/K93P0oXLVzOfKJ4jRZ1jTG8jk7WA+ZLE2XEkDoW0XbDci+/lAXoTqF8vYLyp u77CCMEIIYK4cIrWNyIOJLaQtW4IArqlQy/mDMcxKpxDh1a65Jq8qRsXeQ3/3+q4Xcbf 3I/w== X-Gm-Message-State: AJcUuke1kk9GQ6M6aqQf72WV+H3/5rlkKyALViPHeGiGQ9YdlnxIoqNe VgX5hZBcAXYqgLYg3EQj+2DZPw6rQzU= X-Google-Smtp-Source: ALg8bN7ZWo238/W6eWpIoD0ufCcSkHmjcUhT9yQ/6obXfmFTtu9KvM1O6isL6zpxRT2dj7bR5esWRw== X-Received: by 2002:a1c:3282:: with SMTP id y124mr9720064wmy.134.1547681887515; Wed, 16 Jan 2019 15:38:07 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:07 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:21 +0100 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::342 Subject: [Qemu-devel] [PATCH v3 48/50] usb-audio: do not count on avail bytes actually available X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This assumption is no longer true when mixeng is turned off. Signed-off-by: Kővágó, Zoltán --- hw/usb/dev-audio.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 84e737808c..0bfdd52423 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -318,30 +318,31 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p) { uint32_t free = buf->size - (buf->prod - buf->cons); - if (!free) { + if (free < USBAUDIO_PACKET_SIZE) { return 0; } if (p->iov.size != USBAUDIO_PACKET_SIZE) { return 0; } - assert(free >= USBAUDIO_PACKET_SIZE); + usb_packet_copy(p, buf->data + (buf->prod % buf->size), USBAUDIO_PACKET_SIZE); buf->prod += USBAUDIO_PACKET_SIZE; return USBAUDIO_PACKET_SIZE; } -static uint8_t *streambuf_get(struct streambuf *buf) +static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) { uint32_t used = buf->prod - buf->cons; uint8_t *data; if (!used) { + *len = 0; return NULL; } - assert(used >= USBAUDIO_PACKET_SIZE); data = buf->data + (buf->cons % buf->size); - buf->cons += USBAUDIO_PACKET_SIZE; + *len = MIN(buf->prod - buf->cons, + buf->size - (buf->cons % buf->size)); return data; } @@ -373,16 +374,21 @@ static void output_callback(void *opaque, int avail) USBAudioState *s = opaque; uint8_t *data; - for (;;) { - if (avail < USBAUDIO_PACKET_SIZE) { - return; - } - data = streambuf_get(&s->out.buf); + while (avail) { + size_t written, len; + + data = streambuf_get(&s->out.buf, &len); if (!data) { return; } - AUD_write(s->out.voice, data, USBAUDIO_PACKET_SIZE); - avail -= USBAUDIO_PACKET_SIZE; + + written = AUD_write(s->out.voice, data, len); + avail -= written; + s->out.buf.cons += written; + + if (written < len) { + return; + } } } From patchwork Wed Jan 16 23:37:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10767199 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9E5014E5 for ; Thu, 17 Jan 2019 00:13:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC7012FC3B for ; Thu, 17 Jan 2019 00:13:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AAED62FC41; Thu, 17 Jan 2019 00:13:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 580FA2FC6F for ; Thu, 17 Jan 2019 00:13:34 +0000 (UTC) Received: from localhost ([127.0.0.1]:39993 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjvJN-0007Gb-J8 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Jan 2019 19:13:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58444) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjulA-0004Sk-Vt for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjul8-0003dU-NG for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:12 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:55756) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjul8-0003bb-Fw for qemu-devel@nongnu.org; Wed, 16 Jan 2019 18:38:10 -0500 Received: by mail-wm1-x343.google.com with SMTP id y139so3851887wmc.5 for ; Wed, 16 Jan 2019 15:38:10 -0800 (PST) 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=wEDj/G7ABwVSP60sak8/OqY1zNt0dE9Nkcw+RIT1qMY=; b=ELaqkhcvpylYIKRAZo1HRUhBzxymfQyb1hEdo0dc1cHh93zVsTyFL2NxwBRWrz3dK6 EXU/77YRJuBBS7BYzWK/RxqhnmibYGYsk7c9rAtQnGV2i2FT3nQS0Ny0wBMnv45P2YLh 1gRkDivfQ/OQgZmXesRR53rvCYk+Vx8H59pgPqaj89Clqi8aDeLQ/fRv7H9C9kqWLSlg Vdu5Ej47FC4+KptcOWc5chZtmi+JNqTLCBsTY6L/65x38BRLV/adWaGl/i9Yjwx/Sk/i IW18TwF16q3Ai297rHoqdMbW/b+bdU7iALkTVOpUdC8BmiP4PP3rOYDp5y5+I1i+I+NG jQfQ== 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=wEDj/G7ABwVSP60sak8/OqY1zNt0dE9Nkcw+RIT1qMY=; b=EQ8Pv4ao5TzsHO6sbteTKlUHBKd5qJUcQzAxNlrr18dqFZMeqDgi6vTc0N+SdPAyTc nYXQGVntnWSRtGTpGpiGU/UP/jCXYngzvkLnDKejsxIH2u6Tp/UvLzt1wu8n3h7gSynV 05kBrzsEb6cFovxvb4zeFHVm1WylNyXtFrUGbE2n4irXRqnAoaZL4Ti+urdEXzv2osMO B9JPQb8/0fqb8gkZuk0rYK8inpvG59EBhpSf9zj1cbO4vx3TkEv7TJfu8kpjaxACCw/B wHdYLGQhnksFH9g2sBgGG+kdBJK+gir0H1azi/a5kqQiRPSMTkZtHC8/7JJOA4P1TyKr u76g== X-Gm-Message-State: AJcUukcukwJwpgVMzXvQIAR9jQubjmkn89cEdQqL38616yrGLlKY8+CM OYKwdxH3Df0bw7DnlkVH1lEj2171gxQ= X-Google-Smtp-Source: ALg8bN4HbPMpedZCopc+qGtQeDU/I44s3ooOQygNaEu4gcuHbV626uW1iVNZ6kl+ezq1S6yRKSfLoQ== X-Received: by 2002:a1c:5dd1:: with SMTP id r200mr9728338wmb.93.1547681889252; Wed, 16 Jan 2019 15:38:09 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-e4b0-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:e4b0::5]) by smtp.gmail.com with ESMTPSA id s66sm30760437wmf.34.2019.01.16.15.38.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Jan 2019 15:38:08 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Thu, 17 Jan 2019 00:37:23 +0100 Message-Id: <161ea7f0cc7aaf032116cf9f137898deafa59ffb.1547681517.git.DirtY.iCE.hu@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [PATCH v3 50/50] usbaudio: change playback counters to 64 bit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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ővágó, Zoltán --- 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 f7406da5a4..82bc6eb88f 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -577,9 +577,9 @@ static const USBDesc desc_audio_multi = { struct streambuf { uint8_t *data; - uint32_t size; - uint32_t prod; - uint32_t cons; + size_t size; + uint64_t prod; + uint64_t cons; }; static void streambuf_init(struct streambuf *buf, uint32_t size, @@ -600,7 +600,7 @@ static void streambuf_fini(struct streambuf *buf) static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels) { - uint32_t free = buf->size - (buf->prod - buf->cons); + int64_t free = buf->size - (buf->prod - buf->cons); if (free < USBAUDIO_PACKET_SIZE(channels)) { return 0; @@ -609,6 +609,8 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels) return 0; } + /* can happen if prod overflows */ + assert(buf->prod % USBAUDIO_PACKET_SIZE(channels) == 0); usb_packet_copy(p, buf->data + (buf->prod % buf->size), USBAUDIO_PACKET_SIZE(channels)); buf->prod += USBAUDIO_PACKET_SIZE(channels); @@ -617,10 +619,10 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels) static uint8_t *streambuf_get(struct streambuf *buf, size_t *len) { - uint32_t used = buf->prod - buf->cons; + int64_t used = buf->prod - buf->cons; uint8_t *data; - if (!used) { + if (used <= 0) { *len = 0; return NULL; }