From patchwork Sun Dec 23 20:51:37 2018 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: 10741857 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 E4E8F1399 for ; Sun, 23 Dec 2018 21:18:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4D4B2877F for ; Sun, 23 Dec 2018 21:18:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C7BE32878E; Sun, 23 Dec 2018 21:18: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6D78D2877F for ; Sun, 23 Dec 2018 21:18:30 +0000 (UTC) Received: from localhost ([127.0.0.1]:42148 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAlt-0003T1-4o for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:54:49 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52014) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjh-0007Jg-Hm for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjg-0001PV-Nb for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:33 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:33256) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjg-0001Jv-Hn for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:32 -0500 Received: by mail-wm1-x341.google.com with SMTP id r24so18059286wmh.0 for ; Sun, 23 Dec 2018 12:52: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=vQbAxA17LBqG3YNdc2WxogxuczEivFcvaHHUcCjdIPs=; b=uMgx7IevqX/mnftLxPx5nZy3TYuFe1tMvhF7ro18go8ezDcx6Z0+14PNQOnoDRVCNz LSnwRiBJVKh/Sdzpg+GTzMAryM0uvw1qZFio4HSV+LBu+VxdLVjoQruW0VSUzTl4Vyn5 6yG4NoKORcdRCitrLt8Wcqlxd9CiI0AIYYqvui7qSRk2PIP2/s/Tv+Xc8RG/5FVScQkO r118iz2/ufNOtamXOvrfcYnfkiXZalWHQ17ObBfTEiQHbBPq7EAgn9GcymTYZR0OAMK1 iEKu/C8TGl1ctZ2qRzk4SnGKGwuzwMyZgWV7y+fafS+9Mnsm8vS3UXEI/mAysP3WMLAh uQxQ== 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=vQbAxA17LBqG3YNdc2WxogxuczEivFcvaHHUcCjdIPs=; b=XnNCRJgf0ICxShjm3B8qr6nTxptHG71qe+HYxZ8PzZAjCV3tbwvTlxYiVr7vuWlojw BD3yOqlSDVrCsQt1OdDyb/06c4wcZQ/MwxVZmYXPoSsNaOqijW3DaYolDVa3bal3+gXS K9iEfUTsfHSqcZxmGRc29U8oW8IYfM/+GafLJMf1f4bzvDkAMNpyGBcd2Oz/n9qU+ehK luHk2rwD/jncna1cSgJXr+W4FeJ7K5pVE2fKYFnmxamqMwtrciDzADQYxxgdYvQ9G4vK Ao7KcEsvonpoKiUFWEbT+v5Y7eD9BgYSdyxcMp2cYH1CPGlyDC4+czcchGkNVOtkv6Su qesg== X-Gm-Message-State: AA+aEWbeOUn7AaBjLdsPlVwoyx+KDm89IMax0BaRtZacFHygX5bkJy79 tOgB4E8KchXQLyHPQEfgqm3Oe/LU X-Google-Smtp-Source: AFSGD/Xtt6FdkCdL3MrgqpAKCMxxrf8QKiXWsZYgbFL3as7QS5x3KdVn4AzB4PzwcJztpZYf9b5YSA== X-Received: by 2002:a1c:864f:: with SMTP id i76mr9909558wmd.83.1545598351091; Sun, 23 Dec 2018 12:52:31 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:30 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:37 +0100 Message-Id: <5ffd8b7b6fefbc3c2c4fb074f3083ffbdc946d20.1545598229.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 v2 01/52] qapi: support alternates in OptsVisitor 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 Roth , 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 They are required for flat unions (you still have to allocate the structs). Signed-off-by: Kővágó, Zoltán --- include/qapi/opts-visitor.h | 7 +++---- qapi/opts-visitor.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h index 9b989e7e08..ca044e3b33 100644 --- a/include/qapi/opts-visitor.h +++ b/include/qapi/opts-visitor.h @@ -29,10 +29,9 @@ typedef struct OptsVisitor OptsVisitor; * - values below INT64_MIN or LLONG_MIN are rejected, * - values above INT64_MAX or LLONG_MAX are rejected. * - * The Opts input visitor does not implement support for visiting QAPI - * alternates, numbers (other than integers), null, or arbitrary - * QTypes. It also requires a non-null list argument to - * visit_start_list(). + * The Opts input visitor does not implement support for visiting numbers + * (other than integers), null, or arbitrary QTypes. It also requires a + * non-null list argument to visit_start_list(). */ Visitor *opts_visitor_new(const QemuOpts *opts); diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 324b197495..4af6043b75 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -156,6 +156,13 @@ opts_start_struct(Visitor *v, const char *name, void **obj, } } +static void +opts_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, + size_t size, Error **errp) +{ + opts_start_struct(v, name, (void **)obj, size, errp); +} + static void opts_check_struct(Visitor *v, Error **errp) @@ -198,6 +205,12 @@ opts_end_struct(Visitor *v, void **obj) ov->fake_id_opt = NULL; } +static void +opts_end_alternate(Visitor *v, void **obj) +{ + opts_end_struct(v, obj); +} + static GQueue * lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp) @@ -547,6 +560,9 @@ opts_visitor_new(const QemuOpts *opts) ov->visitor.check_struct = &opts_check_struct; ov->visitor.end_struct = &opts_end_struct; + ov->visitor.start_alternate = &opts_start_alternate; + ov->visitor.end_alternate = &opts_end_alternate; + ov->visitor.start_list = &opts_start_list; ov->visitor.next_list = &opts_next_list; ov->visitor.check_list = &opts_check_list; From patchwork Sun Dec 23 20:51:38 2018 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: 10741815 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 621846C2 for ; Sun, 23 Dec 2018 21:01:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E06228783 for ; Sun, 23 Dec 2018 21:01:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3F7B82878E; Sun, 23 Dec 2018 21: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 07E4528783 for ; Sun, 23 Dec 2018 21:01:48 +0000 (UTC) Received: from localhost ([127.0.0.1]:42214 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAse-00052M-6f for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:01:48 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52041) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjk-0007MA-C3 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAji-0001Vn-45 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:36 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:38255) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjh-0001R3-Pj for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:34 -0500 Received: by mail-wr1-x444.google.com with SMTP id v13so10103041wrw.5 for ; Sun, 23 Dec 2018 12:52: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=m94Go48ZwqUBlRLMY8hU2u+ONGMXkfsC28xGxzVnpO8=; b=bA3riAv7TsIbgGry0MYu0GCNjUXgk1HkR3dnGvBTrEqyE6q4ZSwpHh8MXP2z5IdgH9 +rOhS/T3T5ncyGINrJ5SAl//Pl2ak4EayVT4TKDC5QLpjGD3G8XbsF5W24SLrB2arSPw JeovXQoshm+jhBVugp9HgiSt8EcE3yY3DI6rSGKDiv7K9eBTQrpwsWWkd5AH+6YwmvLM jehcQV653kzXmtEC78x1mOwc8AFdh0AG+kF7FmLhqfesVBFWFfelH+zLRgT/13bARfLp MALVGitkNq0C2s9UT9FatHVeQSEJJGh2Zal7G/KGODX1MZIKeKZx1RRsWcs1VRMI602J 5aoQ== 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=m94Go48ZwqUBlRLMY8hU2u+ONGMXkfsC28xGxzVnpO8=; b=PdJBR9jRx6QsbY2qUaYpGTDkpD0bHj+BmfD24l5wAm1/+UZtmosOCxyYET05j+RHtj fjXi4f5d4ay3zgRDtdOQA1yB2IzOh8wEXsIj7rjpswbum8pwM+3DJWLa5lk2lGy8gQT/ OYjhkRLdd26dS4EtEwJybdpZmhH8JQDmE/OcQVx0ukAX59JlxzQoFBE3QIX5IibT2XZv r2VlEYL86p3O8MdCFWSvbMqFR6GBnKEnc1mS2Z0EEomKzbWEgVNgszQmJgGZT1q36vBJ RwezYncs2HukIn6J0sskuplRRFNJa05rxOCGkoukvLFtAg1ACLd9QOPvSQ8qpgnrLl7C 0WYw== X-Gm-Message-State: AJcUukegHD2ZOraOSyav1Pu/mDDcYFT5drV54Xnbb/ZyCaESDK0wUp80 agRdbj7GeoYa6ie2E5jn68XVRLmzUb8= X-Google-Smtp-Source: ALg8bN785B6f+VyM3AeAhtPSf+sf21KcrEXIlDM7RxllrJuWNRW/SHIbjKTJit3/TKLy2JNb+bmdIw== X-Received: by 2002:a5d:4b01:: with SMTP id v1mr9205935wrq.5.1545598352368; Sun, 23 Dec 2018 12:52:32 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:31 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:38 +0100 Message-Id: <8b272e5a75fa89e5acaa7ae9aa3a8260de6744db.1545598229.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 v2 02/52] qapi: support nested structs in OptsVisitor 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: Eduardo Habkost , "Michael S. Tsirkin" , Jason Wang , Michael Roth , Markus Armbruster , Gerd Hoffmann , =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= , Igor Mammedov , =?utf-8?q?Andreas_F=C3=A4rber?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Kővágó, Zoltán The current OptsVisitor flattens the whole structure, if there are same named fields under different paths (like `in' and `out' in `Audiodev'), the current visitor can't cope with them (for example setting `frequency=44100' will set the in's frequency to 44100 and leave out's frequency unspecified). This patch fixes it, by always requiring a complete path in case of nested structs. Fields in the path are separated by dots, similar to C structs (without pointers), like `in.frequency' or `out.frequency'. You must provide a full path even in non-ambiguous cases. To keep backward compatibility, this new feature can be disabled when creating a new OptsVisitor, in that case it will work identical to previous versions. Signed-off-by: Kővágó, Zoltán --- hw/acpi/core.c | 2 +- include/qapi/opts-visitor.h | 2 +- net/net.c | 2 +- numa.c | 2 +- qapi/opts-visitor.c | 129 ++++++++++++++++++++---- qom/object_interfaces.c | 2 +- tests/qapi-schema/qapi-schema-test.json | 9 +- tests/qapi-schema/qapi-schema-test.out | 4 + tests/test-opts-visitor.c | 43 +++++++- 9 files changed, 163 insertions(+), 32 deletions(-) diff --git a/hw/acpi/core.c b/hw/acpi/core.c index d6f0709691..654508ac13 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -243,7 +243,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp) { Visitor *v; - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, false); visit_type_AcpiTableOptions(v, NULL, &hdrs, &err); visit_free(v); } diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h index ca044e3b33..84edb49f7a 100644 --- a/include/qapi/opts-visitor.h +++ b/include/qapi/opts-visitor.h @@ -33,6 +33,6 @@ typedef struct OptsVisitor OptsVisitor; * (other than integers), null, or arbitrary QTypes. It also requires a * non-null list argument to visit_start_list(). */ -Visitor *opts_visitor_new(const QemuOpts *opts); +Visitor *opts_visitor_new(const QemuOpts *opts, bool nested); #endif diff --git a/net/net.c b/net/net.c index 1f7d626197..f5e7d8a6ef 100644 --- a/net/net.c +++ b/net/net.c @@ -1106,7 +1106,7 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) void *object = NULL; Error *err = NULL; int ret = -1; - Visitor *v = opts_visitor_new(opts); + Visitor *v = opts_visitor_new(opts, false); const char *type = qemu_opt_get(opts, "type"); diff --git a/numa.c b/numa.c index 50ec016013..31a24f750f 100644 --- a/numa.c +++ b/numa.c @@ -220,7 +220,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) NumaOptions *object = NULL; MachineState *ms = MACHINE(opaque); Error *err = NULL; - Visitor *v = opts_visitor_new(opts); + Visitor *v = opts_visitor_new(opts, false); visit_type_NumaOptions(v, NULL, &object, &err); visit_free(v); diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 4af6043b75..d8af51b16c 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -72,6 +72,7 @@ struct OptsVisitor * schema, with a single mandatory scalar member. */ ListMode list_mode; GQueue *repeated_opts; + char *repeated_name; /* When parsing a list of repeating options as integers, values of the form * "a-b", representing a closed interval, are allowed. Elements in the @@ -87,6 +88,9 @@ struct OptsVisitor * not survive or escape the OptsVisitor object. */ QemuOpt *fake_id_opt; + + /* List of field names leading to the current structure. */ + GQueue *nested_names; }; @@ -107,6 +111,7 @@ static void opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt) { GQueue *list; + assert(opt); list = g_hash_table_lookup(unprocessed_opts, opt->name); if (list == NULL) { @@ -134,6 +139,11 @@ opts_start_struct(Visitor *v, const char *name, void **obj, if (obj) { *obj = g_malloc0(size); } + + if (ov->nested_names != NULL) { + g_queue_push_tail(ov->nested_names, (gpointer) name); + } + if (ov->depth++ > 0) { return; } @@ -171,6 +181,10 @@ opts_check_struct(Visitor *v, Error **errp) GHashTableIter iter; GQueue *any; + if (ov->nested_names != NULL) { + g_queue_pop_tail(ov->nested_names); + } + if (ov->depth > 1) { return; } @@ -212,15 +226,59 @@ opts_end_alternate(Visitor *v, void **obj) } +static void +sum_strlen(gpointer data, gpointer user_data) +{ + const char *str = data; + size_t *sum_len = user_data; + + if (str) { /* skip NULLs */ + *sum_len += strlen(str) + 1; + } +} + +static void +append_str(gpointer data, gpointer user_data) +{ + const char *str = data; + char *concat_str = user_data; + + if (str) { + strcat(concat_str, str); + strcat(concat_str, "."); + } +} + +/* lookup a name, using a fully qualified version */ static GQueue * -lookup_distinct(const OptsVisitor *ov, const char *name, Error **errp) +lookup_distinct(const OptsVisitor *ov, const char *name, char **out_key, + Error **errp) { - GQueue *list; + GQueue *list = NULL; + char *key; + + if (ov->nested_names != NULL) { + size_t sum_len = strlen(name); + g_queue_foreach(ov->nested_names, sum_strlen, &sum_len); + key = g_malloc(sum_len + 1); + key[0] = 0; + g_queue_foreach(ov->nested_names, append_str, key); + strcat(key, name); + } else { + key = g_strdup(name); + } + + list = g_hash_table_lookup(ov->unprocessed_opts, key); + if (list && out_key) { + *out_key = key; + key = NULL; + } - list = g_hash_table_lookup(ov->unprocessed_opts, name); if (!list) { error_setg(errp, QERR_MISSING_PARAMETER, name); } + + g_free(key); return list; } @@ -235,7 +293,8 @@ opts_start_list(Visitor *v, const char *name, GenericList **list, size_t size, assert(ov->list_mode == LM_NONE); /* we don't support visits without a list */ assert(list); - ov->repeated_opts = lookup_distinct(ov, name, errp); + assert(ov->repeated_opts == NULL && ov->repeated_name == NULL); + ov->repeated_opts = lookup_distinct(ov, name, &ov->repeated_name, errp); if (ov->repeated_opts) { ov->list_mode = LM_IN_PROGRESS; *list = g_malloc0(size); @@ -266,11 +325,9 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size) /* range has been completed, fall through in order to pop option */ case LM_IN_PROGRESS: { - const QemuOpt *opt; - - opt = g_queue_pop_head(ov->repeated_opts); + g_queue_pop_head(ov->repeated_opts); if (g_queue_is_empty(ov->repeated_opts)) { - g_hash_table_remove(ov->unprocessed_opts, opt->name); + g_hash_table_remove(ov->unprocessed_opts, ov->repeated_name); return NULL; } break; @@ -304,22 +361,28 @@ opts_end_list(Visitor *v, void **obj) ov->list_mode == LM_SIGNED_INTERVAL || ov->list_mode == LM_UNSIGNED_INTERVAL); ov->repeated_opts = NULL; + + g_free(ov->repeated_name); + ov->repeated_name = NULL; + ov->list_mode = LM_NONE; } static const QemuOpt * -lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp) +lookup_scalar(const OptsVisitor *ov, const char *name, char** out_key, + Error **errp) { if (ov->list_mode == LM_NONE) { GQueue *list; /* the last occurrence of any QemuOpt takes effect when queried by name */ - list = lookup_distinct(ov, name, errp); + list = lookup_distinct(ov, name, out_key, errp); return list ? g_queue_peek_tail(list) : NULL; } assert(ov->list_mode == LM_IN_PROGRESS); + assert(out_key == NULL || *out_key == NULL); return g_queue_peek_head(ov->repeated_opts); } @@ -341,8 +404,9 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp) { OptsVisitor *ov = to_ov(v); const QemuOpt *opt; + char *key = NULL; - opt = lookup_scalar(ov, name, errp); + opt = lookup_scalar(ov, name, &key, errp); if (!opt) { *obj = NULL; return; @@ -353,7 +417,8 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp) * valid enum value; this is harmless because tracking what gets * consumed only matters to visit_end_struct() as the final error * check if there were no other failures during the visit. */ - processed(ov, name); + processed(ov, key); + g_free(key); } @@ -363,8 +428,9 @@ opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { OptsVisitor *ov = to_ov(v); const QemuOpt *opt; + char *key = NULL; - opt = lookup_scalar(ov, name, errp); + opt = lookup_scalar(ov, name, &key, errp); if (!opt) { return; } @@ -381,13 +447,15 @@ opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) } else { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, "on|yes|y|off|no|n"); + g_free(key); return; } } else { *obj = true; } - processed(ov, name); + processed(ov, key); + g_free(key); } @@ -399,13 +467,14 @@ opts_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) const char *str; long long val; char *endptr; + char *key = NULL; if (ov->list_mode == LM_SIGNED_INTERVAL) { *obj = ov->range_next.s; return; } - opt = lookup_scalar(ov, name, errp); + opt = lookup_scalar(ov, name, &key, errp); if (!opt) { return; } @@ -419,11 +488,13 @@ opts_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) if (errno == 0 && endptr > str && INT64_MIN <= val && val <= INT64_MAX) { if (*endptr == '\0') { *obj = val; - processed(ov, name); + processed(ov, key); + g_free(key); return; } if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) { long long val2; + assert(key == NULL); str = endptr + 1; val2 = strtoll(str, &endptr, 0); @@ -444,6 +515,7 @@ opts_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, (ov->list_mode == LM_NONE) ? "an int64 value" : "an int64 value or range"); + g_free(key); } @@ -455,13 +527,14 @@ opts_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) const char *str; unsigned long long val; char *endptr; + char *key = NULL; if (ov->list_mode == LM_UNSIGNED_INTERVAL) { *obj = ov->range_next.u; return; } - opt = lookup_scalar(ov, name, errp); + opt = lookup_scalar(ov, name, &key, errp); if (!opt) { return; } @@ -473,11 +546,13 @@ opts_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) if (parse_uint(str, &val, &endptr, 0) == 0 && val <= UINT64_MAX) { if (*endptr == '\0') { *obj = val; - processed(ov, name); + processed(ov, key); + g_free(key); return; } if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) { unsigned long long val2; + assert(key == NULL); str = endptr + 1; if (parse_uint_full(str, &val2, 0) == 0 && @@ -496,6 +571,7 @@ opts_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, (ov->list_mode == LM_NONE) ? "a uint64 value" : "a uint64 value or range"); + g_free(key); } @@ -505,8 +581,9 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) OptsVisitor *ov = to_ov(v); const QemuOpt *opt; int err; + char *key = NULL; - opt = lookup_scalar(ov, name, errp); + opt = lookup_scalar(ov, name, &key, errp); if (!opt) { return; } @@ -515,10 +592,12 @@ opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) if (err < 0) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, "a size value"); + g_free(key); return; } - processed(ov, name); + processed(ov, key); + g_free(key); } @@ -529,7 +608,7 @@ opts_optional(Visitor *v, const char *name, bool *present) /* we only support a single mandatory scalar field in a list node */ assert(ov->list_mode == LM_NONE); - *present = (lookup_distinct(ov, name, NULL) != NULL); + *present = (lookup_distinct(ov, name, NULL, NULL) != NULL); } @@ -547,7 +626,7 @@ opts_free(Visitor *v) Visitor * -opts_visitor_new(const QemuOpts *opts) +opts_visitor_new(const QemuOpts *opts, bool nested) { OptsVisitor *ov; @@ -556,6 +635,12 @@ opts_visitor_new(const QemuOpts *opts) ov->visitor.type = VISITOR_INPUT; + if (nested) { + ov->nested_names = g_queue_new(); + } else { + ov->nested_names = NULL; + } + ov->visitor.start_struct = &opts_start_struct; ov->visitor.check_struct = &opts_check_struct; ov->visitor.end_struct = &opts_end_struct; diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index db85d1eb75..17f995ee31 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -119,7 +119,7 @@ Object *user_creatable_add_opts(QemuOpts *opts, Error **errp) qemu_opts_set_id(opts, NULL); pdict = qemu_opts_to_qdict(opts, NULL); - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, false); obj = user_creatable_add_type(type, id, pdict, v, errp); visit_free(v); diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index cb0857df52..324b9eb40c 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -149,6 +149,11 @@ # Smoke test on out-of-band and allow-preconfig-test { 'command': 'test-flags-command', 'allow-oob': true, 'allow-preconfig': true } +# For testing hierarchy support in opts-visitor +{ 'struct': 'UserDefOptionsSub', + 'data': { + '*nint': 'int' } } + # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: # @@ -162,7 +167,9 @@ '*u64' : [ 'uint64' ], '*u16' : [ 'uint16' ], '*i64x': 'int' , - '*u64x': 'uint64' } } + '*u64x': 'uint64' , + 'sub0': 'UserDefOptionsSub', + 'sub1': 'UserDefOptionsSub' } } # testing event { 'struct': 'EventStructOne', diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 9464101d26..3c1b47c7cd 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -200,12 +200,16 @@ command boxed-union UserDefNativeListUnion -> None gen=True success_response=True boxed=True oob=False preconfig=False command test-flags-command None -> None gen=True success_response=True boxed=False oob=True preconfig=True +object UserDefOptionsSub + member nint: int optional=True object UserDefOptions member i64: intList optional=True member u64: uint64List optional=True member u16: uint16List optional=True member i64x: int optional=True member u64x: uint64 optional=True + member sub0: UserDefOptionsSub optional=False + member sub1: UserDefOptionsSub optional=False object EventStructOne member struct1: UserDefOne optional=False member string: str optional=False diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c index 23e897061c..52950dfc4a 100644 --- a/tests/test-opts-visitor.c +++ b/tests/test-opts-visitor.c @@ -43,7 +43,7 @@ setup_fixture(OptsVisitorFixture *f, gconstpointer test_data) NULL); g_assert(opts != NULL); - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, true); visit_type_UserDefOptions(v, NULL, &f->userdef, &f->err); visit_free(v); qemu_opts_del(opts); @@ -170,6 +170,34 @@ expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data) g_assert(f->userdef->u64->value == UINT64_MAX); } +static void +expect_both(OptsVisitorFixture *f, gconstpointer test_data) +{ + expect_ok(f, test_data); + g_assert(f->userdef->sub0->has_nint); + g_assert(f->userdef->sub0->nint == 13); + g_assert(f->userdef->sub1->has_nint); + g_assert(f->userdef->sub1->nint == 17); +} + +static void +expect_sub0(OptsVisitorFixture *f, gconstpointer test_data) +{ + expect_ok(f, test_data); + g_assert(f->userdef->sub0->has_nint); + g_assert(f->userdef->sub0->nint == 13); + g_assert(!f->userdef->sub1->has_nint); +} + +static void +expect_sub1(OptsVisitorFixture *f, gconstpointer test_data) +{ + expect_ok(f, test_data); + g_assert(!f->userdef->sub0->has_nint); + g_assert(f->userdef->sub1->has_nint); + g_assert(f->userdef->sub1->nint == 13); +} + /* test cases */ static void @@ -184,7 +212,7 @@ test_opts_range_unvisited(void) opts = qemu_opts_parse(qemu_find_opts("userdef"), "ilist=0-2", false, &error_abort); - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, false); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -225,7 +253,7 @@ test_opts_range_beyond(void) opts = qemu_opts_parse(qemu_find_opts("userdef"), "ilist=0", false, &error_abort); - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, false); visit_start_struct(v, NULL, NULL, 0, &error_abort); @@ -260,7 +288,7 @@ test_opts_dict_unvisited(void) opts = qemu_opts_parse(qemu_find_opts("userdef"), "i64x=0,bogus=1", false, &error_abort); - v = opts_visitor_new(opts); + v = opts_visitor_new(opts, false); visit_type_UserDefOptions(v, NULL, &userdef, &err); error_free_or_abort(&err); visit_free(v); @@ -366,6 +394,13 @@ main(int argc, char **argv) g_test_add_func("/visitor/opts/dict/unvisited", test_opts_dict_unvisited); + /* Test nested structs support */ + add_test("/visitor/opts/nested/unqualified", &expect_fail, "nint=13"); + add_test("/visitor/opts/nested/both", &expect_both, + "sub0.nint=13,sub1.nint=17"); + add_test("/visitor/opts/nested/sub0", &expect_sub0, "sub0.nint=13"); + add_test("/visitor/opts/nested/sub1", &expect_sub1, "sub1.nint=13"); + g_test_run(); return 0; } From patchwork Sun Dec 23 20:51:39 2018 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: 10741907 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 1DC6D6C2 for ; Sun, 23 Dec 2018 21:48:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 098B0219AC for ; Sun, 23 Dec 2018 21:48:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC82C22376; Sun, 23 Dec 2018 21:48:55 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2DD40219AC for ; Sun, 23 Dec 2018 21:48:55 +0000 (UTC) Received: from localhost ([127.0.0.1]:42176 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbApF-000835-Cy for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:58:17 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52043) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjk-0007MS-EI for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAji-0001Z4-V9 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:36 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:42851) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAji-0001Vb-MT for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:34 -0500 Received: by mail-wr1-x443.google.com with SMTP id q18so10089842wrx.9 for ; Sun, 23 Dec 2018 12:52:34 -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=BXtiWb/9JaAsoRkYo6+/UTmp9osbnclizxbjAv57xkw=; b=vMxomW03q067SxVcCBL1Gf3aDONlhYm2Vq/9cdL8um5YDLk+RtzqMgUijv/FELTBgV RNbmugHVt/vYrl3GkPwHtazmyd3ae/+QezR+m11h+KL062+Pielvn0evMN4gJHwm9m7/ xFy66flZp7kVJeIhaFBVVMRQ4/pmzH4Gof19lMFs7ir1LTo13zj/YMNTFZ5K+k6xp2NL Ajui3ChxtrwjXEHPAphhRy/4jrlXg+Nrn748+ILCLCKFpQofY+lmlq8phImmdwvl6a/u ipz/jLUITWOSSbFi2uQczr+m7J0c/8YlgAIJjY8296Xqcg7LnBZ2jfb1aVuPtytYtZCm qxYQ== 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=BXtiWb/9JaAsoRkYo6+/UTmp9osbnclizxbjAv57xkw=; b=W5Ia9UJVTc5RWPEY1qEoKqkG92wBgP/PV3FUd40AaOCGlfBdL+JKK3gSIU0AAPArUL CUNzO4bcdjRrCWHoRaMlcthTVKTQ6hpLd+FH4LTC4VQjwWKZNnmHr4o3IuUj7Kq8ps+K 4AO/XI+l3BYPieXsmwCwQUC7dLGSuN6rU99A2roYTUXPFK6t8TRHy0go+6HeI44QgaVj jOxnE8S/AY/lmFpq2KweEmludkZllKnI2NdPoP3cTydSt+ydJMDkmhLdrDM0x/0Ye9HR OnHFAoHwmAGf9wwUZwxGr0uMkWGGrbTQh8c2I0ber8idmykB2NcHY9iSzEQcbvN6AjED WBqw== X-Gm-Message-State: AJcUukfigpWfXJ7h7QsVXsXC44hv4jvC2wpY3rIosxukXkQBJCqhlZK9 GGOoHn8vsowUePt1oopIuFPVVJVf7Jw= X-Google-Smtp-Source: ALg8bN426hjK+nirOME2hnZVaSMraYwkmQSC49XGwCvhMD97A7x3/2AIfvXK9eRC3oIww2hQ49amEw== X-Received: by 2002:a5d:6b81:: with SMTP id n1mr10352906wrx.149.1545598353301; Sun, 23 Dec 2018 12:52:33 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:32 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51: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::443 Subject: [Qemu-devel] [PATCH v2 03/52] 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 --- Makefile.objs | 6 +- qapi/audio.json | 253 ++++++++++++++++++++++++++++++++++++++++++ qapi/qapi-schema.json | 1 + 3 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 qapi/audio.json diff --git a/Makefile.objs b/Makefile.objs index bc5b8a8442..3f833a70c0 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..56d8ce439f --- /dev/null +++ b/qapi/audio.json @@ -0,0 +1,253 @@ +# -*- mode: python -*- +# +# Copyright (C) 2015 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. + +## +# @AudiodevNoOptions: +# +# The none, coreaudio, sdl and spice audio backend have no options. +# +# Since: 3.2 +## +{ 'struct': 'AudiodevNoOptions', + 'data': { } } + +## +# @AudiodevAlsaPerDirectionOptions: +# +# Options of the alsa backend that are used for both playback and recording. +# +# @dev: #optional the name of the alsa device to use (default 'default') +# +# @try-poll: #optional attempt to use poll mode, falling back to non polling +# access on failure (default on) +# +# Since: 3.2 +## +{ '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: #optional set the threshold (in microseconds) when playback starts +# +# Since: 3.2 +## +{ 'struct': 'AudiodevAlsaOptions', + 'data': { + 'alsa-in': 'AudiodevAlsaPerDirectionOptions', + 'alsa-out': 'AudiodevAlsaPerDirectionOptions', + '*threshold': 'int' } } + +## +# @AudiodevDsoundOptions: +# +# Options of the dsound audio backend. +# +# @latency: #optional add extra latency to playback in microseconds (default +# 10000) +# +# Since: 3.2 +## +{ 'struct': 'AudiodevDsoundOptions', + 'data': { + '*latency': 'int' } } + +## +# @AudiodevOssPerDirectionOptions: +# +# Options of the oss backend that are used for both playback and recording. +# +# @dev: #optional file name of the oss device (default '/dev/dsp') +# +# @try-poll: #optional attempt to use poll mode, falling back to non polling +# access on failure (default on) +# +# Since: 3.2 +## +{ '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: #optional try using memory mapped access, falling back to non +# memory mapped access on failure (default off) +# +# @exclusive: #optional open device in exclusive mode (vmix won't work) +# (default off) +# +# @dsp-policy: #optional 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: 3.2 +## +{ 'struct': 'AudiodevOssOptions', + 'data': { + 'oss-in': 'AudiodevOssPerDirectionOptions', + 'oss-out': 'AudiodevOssPerDirectionOptions', + '*try-mmap': 'bool', + '*exclusive': 'bool', + '*dsp-policy': 'int' } } + +## +# @AudiodevPaPerDirectionOptions: +# +# Options of the pa backend that are used for both playback and recording. +# +# @name: #optional name of the sink/source to use +# +# Since: 3.2 +## +{ 'struct': 'AudiodevPaPerDirectionOptions', + 'data': { + '*name': 'str' } } + +## +# @AudiodevPaOptions: +# +# Options of the pa (PulseAudio) audio backend. +# +# @server: #optional PulseAudio server address (default: let PulseAudio choose) +# +# @sink: sink specific options +# +# @source: source specific options +# +# Since: 3.2 +## +{ 'struct': 'AudiodevPaOptions', + 'data': { + '*server': 'str', + 'sink': 'AudiodevPaPerDirectionOptions', + 'source': 'AudiodevPaPerDirectionOptions' } } + +## +# @AudiodevWavOptions: +# +# Options of the wav audio backend. +# +# @path: #optional name of the wav file to record (default 'qemu.wav') +# +# Since: 3.2 +## +{ 'struct': 'AudiodevWavOptions', + 'data': { + '*path': 'str' } } + + +## +# @AudioFormat: +# +# An enumeration of possible audio formats. +# +# Since: 3.2 +## +{ 'enum': 'AudioFormat', + 'data': [ 'u8', 's8', 'u16', 's16', 'u32', 's32' ] } + +## +# @AudiodevDriver: +# +# An enumeration of possible audio backend drivers. +# +# Since: 3.2 +## +{ '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: #optional use fixed settings for host input/output. When +# off, frequency, channels and format must not be specified +# (default on) +# +# @frequency: #optional frequency to use when using fixed settings +# (default 44100) +# +# @channels: #optional number of channels when using fixed settings +# (default 2) +# +# @voices: #optional number of voices to use (default 1) +# +# @format: #optional sample format to use when using fixed settings +# (default s16) +# +# @buffer-len: #optional the buffer size in microseconds +# +# @buffer-count: #optional number of buffers +# +# Since: 3.2 +## +{ 'struct': 'AudiodevPerDirectionOptions', + 'data': { + '*fixed-settings': 'bool', + '*frequency': 'int', + '*channels': 'int', + '*voices': 'int', + '*format': 'AudioFormat', + '*buffer-len': 'int', + '*buffer-count': 'int' } } + +## +# @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: #optional timer period (in microseconds, 0: use lowest +# possible) +# +# Since: 3.2 +## +{ 'union': 'Audiodev', + 'base': { + 'id': 'str', + 'driver': 'AudiodevDriver', + 'in': 'AudiodevPerDirectionOptions', + 'out': 'AudiodevPerDirectionOptions', + '*timer-period': 'int' }, + 'discriminator': 'driver', + 'data': { + 'none': 'AudiodevNoOptions', + 'alsa': 'AudiodevAlsaOptions', + 'coreaudio': 'AudiodevNoOptions', + 'dsound': 'AudiodevDsoundOptions', + 'oss': 'AudiodevOssOptions', + 'pa': 'AudiodevPaOptions', + 'sdl': 'AudiodevNoOptions', + 'spice': 'AudiodevNoOptions', + '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 Sun Dec 23 20:51:40 2018 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: 10741803 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 CBAD491E for ; Sun, 23 Dec 2018 20:55:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B46F92870B for ; Sun, 23 Dec 2018 20:55:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A6A492875E; Sun, 23 Dec 2018 20:55: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8E2842870B for ; Sun, 23 Dec 2018 20:55:01 +0000 (UTC) Received: from localhost ([127.0.0.1]:42152 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAm3-0003qu-Ov for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:54:59 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52084) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjn-0007Ro-Ra for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjk-0001gH-HY for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:39 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:54756) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjk-0001bN-6L; Sun, 23 Dec 2018 15:52:36 -0500 Received: by mail-wm1-x343.google.com with SMTP id a62so9861352wmh.4; Sun, 23 Dec 2018 12:52: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=GZHfE/KQolbyHZSZzfj5RIQCz4TsmSs/M4GmpQq5TN0=; b=su+mwEMTYJIgwmQ0asmHPusugEaxrDmLZidMsMdrwNYzcH7aL7lVFKKD2Qlp41JdEh wU9W4+ch5bgVdY4vGqgWIwrHrJrhHnQNsaflQbTMY9Uw1tt4p44d3g1Z1Ci7VGgxVuv4 pHst1IfZU4XT9ZDqEmaRCic1m+CRuZZNNRTu9iR8PNd3hfMqB3FVPNT7nzQiVmoljIBr eLonN2jszYzHqPyw4MP7udpehy53k/8sJnReBlL92frqTFbnbM82gijI7qcQai8GUi/U 8oYAKNlyk188hm3nIcirAbiMuMz5iefO6qfick62gftB+0Vhk9JmDGExhp2peZ0qhR1I WNXg== 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=GZHfE/KQolbyHZSZzfj5RIQCz4TsmSs/M4GmpQq5TN0=; b=ccuADRIVBCLoveT2+c4fQTXj6yrI6oFMDVJ7a6FgIMUnM1yE6bFKPpArSFyWL8oA2o Kmumy4SomL7rfo+BUe3PZ10EWCvJDk2U9PnjoNoswYwOUWhpUvR88x6Wa8rm79Fw5Ys2 yuF5/7CaUYoQvCOeqLgfJ4G5CYZtFOOhRLJCovXeQZ8SkFWpIoCjDbXhbTqMRvW9Ofw0 AqTOsek+HrPyz5cTt4aI2kHDVBOdMzjzwCqJdpNXpx3PAZKH321oP8CcRemawzMStqBU 1nA4hNUj/ll6AswlXUykWdwTQePednhUeYNRqO1l+XQhcKOFgwXoZtWj0dy1qL0PTLgQ bdCA== X-Gm-Message-State: AA+aEWZqqmHlO5MiWnkl01jnJ+EuWQKMPlJtv4JxsvroBc50klXhGwco 4piDQMRGDLqVhgCKxZvR3jJ+jgvDfv8= X-Google-Smtp-Source: AFSGD/UkVrPjfuJw9ZJ6Z3D4NpyE+FBxR/R3UmFnCZLKf37vQwh4tvajfqwWzj55Wf/AATwjea53EA== X-Received: by 2002:a7b:c24c:: with SMTP id b12mr9214856wmj.29.1545598354439; Sun, 23 Dec 2018 12:52:34 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:34 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:40 +0100 Message-Id: <81d553b07006e0991873d4ac8b8f028a3515571c.1545598229.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 v2 04/52] 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/alsaaudio.c | 53 +++++++++++---------- audio/audio.c | 97 +++++++++++++++++++++------------------ audio/audio.h | 12 +---- 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 | 4 +- hw/display/xlnx_dp.c | 2 +- hw/input/tsc210x.c | 2 +- hw/usb/dev-audio.c | 2 +- ui/vnc.c | 26 +++++------ 26 files changed, 195 insertions(+), 188 deletions(-) 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.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/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..5d614c0d8b 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); 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 1cad57f644..7b826e0e22 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 ee43e4914d..b1b9736a19 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -647,7 +647,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 0c1b477425..0e9e9fb63a 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 Sun Dec 23 20:51:41 2018 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: 10741801 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 68F8691E for ; Sun, 23 Dec 2018 20:54:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DF1D2870B for ; Sun, 23 Dec 2018 20:54:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3CAA72875E; Sun, 23 Dec 2018 20:54:57 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6AA7C2870B for ; Sun, 23 Dec 2018 20:54:56 +0000 (UTC) Received: from localhost ([127.0.0.1]:42150 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAlz-0003hd-3C for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:54:55 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52074) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjm-0007R5-Mc for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjk-0001ho-Ti for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:38 -0500 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:39295) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjk-0001dR-Ju for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:36 -0500 Received: by mail-wr1-x42e.google.com with SMTP id t27so10103792wra.6 for ; Sun, 23 Dec 2018 12:52: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=HEQQLr/pCWYvGLDMUNz4EA6GqIdK8nzIMZRig4JRJ2o=; b=hRzG3hDVSwxCGFaPZEjV4OB8JQa0PSe3ZNNHwUdqvp/ZiygI6uEmUga416XbEDToNU Vuzl+1i4ZcdtrA610quwjHyY8pYOGyjGgCHmwByo63f0jEDJaJQq1BXv18IX7m6r8l2Y lFCBc8UX1Uh4pNM+5gyisbOu6R3qxnUFBgZylMDqIYAU/sWGdUrly2K0pJ4JBW4BaPyj p+Mu23gjhs6T9vVJtu4CKxmtlHDmtrfpESxV0pk6ttdZOmWKRMW9ubymmJjq6wmnlDjW fC5Pd7MRBklWxpq+vCH45c2HQXOGzSXlnJHiLsBX2pi04RuTIYqMOPIlr37ZJvV+CeJU GBmQ== 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=HEQQLr/pCWYvGLDMUNz4EA6GqIdK8nzIMZRig4JRJ2o=; b=fRdJu5hosMas6SFo6p7koYhLu5zQhNJjzgixtQ7n0fItv8QYLS5EMocsu2+TXfkDn8 y/U5V+JoDV6HjVw3/8YcYaa5nlc9haudjrU5td5vJzsOo+Gs6Hk6vpJ/Cd89iHmsJ43a IUEWtY7kCIL3rppDyMAbl6CyCmp26B46oSEnwRk6IMQizWqigPfDkUi+fRuSJ+cFAJXC X0A6iYEzpERsi+A0hpswbQgUuuS23Enm3aHjQto6b9k5Xaqm6KOTKMscXvnsPEwIitYC KooCnj0S63vU68VyvOw+UYVZa7Ya1V0MeDfI0dd5olBzHFebeDqFNoyEnAnZg8zWowuw ha8g== X-Gm-Message-State: AJcUukfEZ/ZpBt4GimFnnx+yvoBxMMiIaybusVZdEFlWvdosHiJ5LHR3 9hPAqLX+GXBUBeqQ4kbyLDIzqvYCdCE= X-Google-Smtp-Source: ALg8bN5yS4V2WhTI7f7cmVixbWFU7ZHKBV6z3Gi6AM0R4p92EsZjhFy96ZxLaxEcgXNh786CYo2CGg== X-Received: by 2002:a5d:56d2:: with SMTP id m18mr10227015wrw.113.1545598355167; Sun, 23 Dec 2018 12:52:35 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:34 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:41 +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::42e Subject: [Qemu-devel] [PATCH v2 05/52] 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 df42116ecc..3ede6a591d 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 Sun Dec 23 20:51:42 2018 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: 10741851 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 AA56013A4 for ; Sun, 23 Dec 2018 21:16:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 972E02877F for ; Sun, 23 Dec 2018 21:16:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A4662878E; Sun, 23 Dec 2018 21:16:57 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 73AEF2877F for ; Sun, 23 Dec 2018 21:16:55 +0000 (UTC) Received: from localhost ([127.0.0.1]:59842 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB7F-00034s-KP for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:16:53 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52132) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjq-0007SF-0V for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjm-0001ma-9q for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:41 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:38253) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjl-0001k2-TG for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:38 -0500 Received: by mail-wr1-x441.google.com with SMTP id v13so10103114wrw.5 for ; Sun, 23 Dec 2018 12:52: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=gxzbrdb3i3QrbJe0ZUOMFwI9ErESnZkXb+YI+ZQKKnI=; b=eKB6qrbq6i6bLq7mwPvPQkEVMqSQiK1b9TiH6HLW80X79KYznAdXfAwj7ujG5QtVVg h8TB0+plpWXznomh4JAufMPVQi1VeMJZCMjO7QglDi5wtG/i0Ne5xPMhfcnIbr2IHclg 2l4nVAnjGoXBkvUfs2N5xU3A4Oe8P2P7aj/eLJKW9UbebvvKeuNysdfdp0US504dvDnf 8FtGSnuBobunGMP0e9GvIZFv9OSpAAqW7q8HWn+px0KPtAeg0oIoIk3C5FJKF2EvzZ3I 2/V3lxA3iQQAGocvSfRnqyBrAGbzKYf5nmEag/X5OJMAi5gP2YNbblRQF7zHORJkffi+ d1kg== 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=gxzbrdb3i3QrbJe0ZUOMFwI9ErESnZkXb+YI+ZQKKnI=; b=A0U9dqz8ib0Kkvg+kDs0WjhH5n7r8uprF3cYisRe4FDt9ofmy5SOk0hujM64XjassF 4xXzfbvxEF7VNA6VXJ6LC63mIC+lPBHX4oEbfQYkG/XdGoWNvQPk6sD5xZ9474qVlxDN EssOyjBSKJ8pz8V60JIrBGvkaZvt51HJQT1uwopJPSlBMRg0c3W/q2X6vFEst9i7c4Qq GmudzucfnKcdd21R6Jvug2NMmTT6NwmnTKWC0UQOW9+PFKYe5mPUux2iyhO9jFokaaEH nYzrUT2mbYaABTqAFoqQ9Zys1/r0BpBn4UqtV3VUkXIwj4okXOvwyo0LNxLqAD+XC0A1 HNXQ== X-Gm-Message-State: AJcUukcLfZ9hNxlx3CKXwEIlOoIRGcczftoEgsFmxpobtjPAERSQlYRo MN3uIRKnjpiroLtdoV2vgQXtta7FmNQ= X-Google-Smtp-Source: ALg8bN7ljENq43s75OHDw5oScPSwXDrkPt+1OVwnC2u+tIgfnKbaTKyQXeStg9ibi+B0RqD+xlt+lA== X-Received: by 2002:adf:fd87:: with SMTP id d7mr9283979wrr.74.1545598356096; Sun, 23 Dec 2018 12:52:36 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:35 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:42 +0100 Message-Id: <26b300d6c17e6ac015f1519d50151744cf806c03.1545598229.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 v2 06/52] 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 --- audio/Makefile.objs | 2 +- audio/alsaaudio.c | 2 +- audio/audio.c | 589 ++++++++++++++++------------------------- audio/audio.h | 20 +- audio/audio_int.h | 6 +- audio/audio_legacy.c | 211 +++++++++++++++ audio/audio_template.h | 13 +- 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 | 11 +- 16 files changed, 491 insertions(+), 379 deletions(-) create mode 100644 audio/audio_legacy.c 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 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..e7f25ea84b 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -25,7 +25,12 @@ #include "hw/hw.h" #include "audio.h" #include "monitor/monitor.h" +#include "qapi/opts-visitor.h" #include "qemu/timer.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "qapi/error.h" +#include "qapi/qapi-visit-audio.h" #include "sysemu/sysemu.h" #include "qemu/cutils.h" #include "sysemu/replay.h" @@ -46,11 +51,12 @@ 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; @@ -80,61 +86,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 +102,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 +109,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 +173,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 +298,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 +1005,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 +1023,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 +1093,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 +1138,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 +1459,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 +1489,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 +1543,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 +1559,40 @@ static const VMStateDescription vmstate_audio = { } }; -static void audio_init (void) +static Audiodev *parse_option(QemuOpts *opts, Error **errp); +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 */ + QemuOptsList *list = NULL; 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 */ + audio_handle_legacy_opts(); + list = qemu_find_opts("audiodev"); + dev = parse_option(QTAILQ_FIRST(&list->head), &error_abort); + if (!dev) { + exit(1); + } + } + s->dev = dev; + QLIST_INIT (&s->hw_head_out); QLIST_INIT (&s->hw_head_in); QLIST_INIT (&s->cap_head); @@ -1885,10 +1600,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 +1615,46 @@ 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; !done && audio_prio_list[i]; i++) { + QemuOpts *opts = qemu_opts_find(list, 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 (driver && opts) { + qapi_free_Audiodev(dev); + dev = parse_option(opts, &error_abort); + if (!dev) { + exit(1); + } + s->dev = dev; + done = !audio_driver_init(s, driver, dev); } } } 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); + if (dev->timer_period <= 0) { + if (dev->timer_period < 0) { + dolog ("warning: Timer period is negative - %" PRId64 + " treating as zero\n", + dev->timer_period); } - conf.period.ticks = 1; + 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 +1665,12 @@ static void audio_init (void) QLIST_INIT (&s->card_head); vmstate_register (NULL, 0, &vmstate_audio, s); + return 0; } 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 +1841,158 @@ void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol) } } } + +QemuOptsList qemu_audiodev_opts = { + .name = "audiodev", + .head = QTAILQ_HEAD_INITIALIZER(qemu_audiodev_opts.head), + .implied_opt_name = "driver", + .desc = { + /* + * no elements => accept any params + * sanity checking will happen later + */ + { /* end of list */ } + }, +}; + +static void validate_per_direction_opts(AudiodevPerDirectionOptions *pdo, + Error **errp) +{ + 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 Audiodev *parse_option(QemuOpts *opts, Error **errp) +{ + Error *local_err = NULL; + Visitor *v = opts_visitor_new(opts, true); + Audiodev *dev = NULL; + visit_type_Audiodev(v, NULL, &dev, &local_err); + visit_free(v); + + if (local_err) { + goto err2; + } + + validate_per_direction_opts(dev->in, &local_err); + if (local_err) { + goto err; + } + validate_per_direction_opts(dev->out, &local_err); + if (local_err) { + goto err; + } + + if (!dev->has_timer_period) { + dev->has_timer_period = true; + dev->timer_period = 10000; /* 100Hz -> 10ms */ + } + + return dev; + +err: + qapi_free_Audiodev(dev); +err2: + error_propagate(errp, local_err); + return NULL; +} + +static int each_option(void *opaque, QemuOpts *opts, Error **errp) +{ + Audiodev *dev = parse_option(opts, errp); + if (!dev) { + return -1; + } + return audio_init(dev); +} + +void audio_set_options(void) +{ + if (qemu_opts_foreach(qemu_find_opts("audiodev"), each_option, NULL, + &error_abort)) { + exit(1); + } +} + +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.h b/audio/audio.h index 02f29a3b3e..7df1b8b249 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, @@ -78,10 +87,11 @@ typedef struct QEMUAudioTimeStamp { uint64_t old_ts; } QEMUAudioTimeStamp; +extern QemuOptsList qemu_audiodev_opts; + 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 +173,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_set_options(void); +void audio_handle_legacy_opts(void); +void audio_legacy_help(void); + #endif /* QEMU_AUDIO_H */ diff --git a/audio/audio_int.h b/audio/audio_int.h index 244b454012..24b8793496 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); diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c new file mode 100644 index 0000000000..2242f06a5e --- /dev/null +++ b/audio/audio_legacy.c @@ -0,0 +1,211 @@ +#include "qemu/osdep.h" +#include "audio.h" +#include "audio_int.h" +#include "qemu-common.h" +#include "qemu/config-file.h" +#include "qemu/cutils.h" +#include "qemu/option.h" +#include "qapi/error.h" + +#define AUDIO_CAP "audio-legacy" +#include "audio_int.h" + +typedef enum EnvTransform { + ENV_TRANSFORM_NONE, + ENV_TRANSFORM_BOOL, + ENV_TRANSFORM_FMT, + ENV_TRANSFORM_FRAMES_TO_USECS_IN, + ENV_TRANSFORM_FRAMES_TO_USECS_OUT, + ENV_TRANSFORM_SAMPLES_TO_USECS_IN, + ENV_TRANSFORM_SAMPLES_TO_USECS_OUT, + ENV_TRANSFORM_BYTES_TO_USECS_IN, + ENV_TRANSFORM_BYTES_TO_USECS_OUT, + ENV_TRANSFORM_MILLIS_TO_USECS, + ENV_TRANSFORM_HZ_TO_USECS, +} EnvTransform; + +typedef struct SimpleEnvMap { + const char *name; + const char *option; + EnvTransform transform; +} SimpleEnvMap; + +SimpleEnvMap global_map[] = { + /* DAC/out settings */ + { "QEMU_AUDIO_DAC_FIXED_SETTINGS", "out.fixed-settings", + ENV_TRANSFORM_BOOL }, + { "QEMU_AUDIO_DAC_FIXED_FREQ", "out.frequency" }, + { "QEMU_AUDIO_DAC_FIXED_FMT", "out.format", ENV_TRANSFORM_FMT }, + { "QEMU_AUDIO_DAC_FIXED_CHANNELS", "out.channels" }, + { "QEMU_AUDIO_DAC_VOICES", "out.voices" }, + + /* ADC/in settings */ + { "QEMU_AUDIO_ADC_FIXED_SETTINGS", "in.fixed-settings", + ENV_TRANSFORM_BOOL }, + { "QEMU_AUDIO_ADC_FIXED_FREQ", "in.frequency" }, + { "QEMU_AUDIO_ADC_FIXED_FMT", "in.format", ENV_TRANSFORM_FMT }, + { "QEMU_AUDIO_ADC_FIXED_CHANNELS", "in.channels" }, + { "QEMU_AUDIO_ADC_VOICES", "in.voices" }, + + /* general */ + { "QEMU_AUDIO_TIMER_PERIOD", "timer-period", ENV_TRANSFORM_HZ_TO_USECS }, + { /* End of list */ } +}; + +static unsigned long long toull(const char *str) +{ + unsigned long long ret; + if (parse_uint_full(str, &ret, 10)) { + dolog("Invalid integer value `%s'\n", str); + exit(1); + } + return ret; +} + +/* non reentrant typesafe or anything, but enough in this small c file */ +static const char *tostr(unsigned long long val) +{ + /* max length in decimal possible for an unsigned long long number */ + #define LEN ((CHAR_BIT * sizeof(unsigned long long) - 1) / 3 + 2) + static char ret[LEN]; + snprintf(ret, LEN, "%llu", val); + return ret; +} + +static uint64_t frames_to_usecs(QemuOpts *opts, uint64_t frames, bool in) +{ + const char *opt = in ? "in.frequency" : "out.frequency"; + uint64_t freq = qemu_opt_get_number(opts, opt, 44100); + return (frames * 1000000 + freq / 2) / freq; +} + +static uint64_t samples_to_usecs(QemuOpts *opts, uint64_t samples, bool in) +{ + const char *opt = in ? "in.channels" : "out.channels"; + uint64_t channels = qemu_opt_get_number(opts, opt, 2); + return frames_to_usecs(opts, samples / channels, in); +} + +static uint64_t bytes_to_usecs(QemuOpts *opts, uint64_t bytes, bool in) +{ + const char *opt = in ? "in.format" : "out.format"; + const char *val = qemu_opt_get(opts, opt); + uint64_t bytes_per_sample = (val ? toull(val) : 16) / 8; + return samples_to_usecs(opts, bytes * bytes_per_sample, in); +} + +static const char *transform_val(QemuOpts *opts, const char *val, + EnvTransform transform) +{ + switch (transform) { + case ENV_TRANSFORM_NONE: + return val; + + case ENV_TRANSFORM_BOOL: + return toull(val) ? "on" : "off"; + + case ENV_TRANSFORM_FMT: + if (strcasecmp(val, "u8") == 0) { + return "u8"; + } else if (strcasecmp(val, "u16") == 0) { + return "u16"; + } else if (strcasecmp(val, "u32") == 0) { + return "u32"; + } else if (strcasecmp(val, "s8") == 0) { + return "s8"; + } else if (strcasecmp(val, "s16") == 0) { + return "s16"; + } else if (strcasecmp(val, "s32") == 0) { + return "s32"; + } else { + dolog("Invalid audio format `%s'\n", val); + exit(1); + } + + case ENV_TRANSFORM_FRAMES_TO_USECS_IN: + return tostr(frames_to_usecs(opts, toull(val), true)); + case ENV_TRANSFORM_FRAMES_TO_USECS_OUT: + return tostr(frames_to_usecs(opts, toull(val), false)); + + case ENV_TRANSFORM_SAMPLES_TO_USECS_IN: + return tostr(samples_to_usecs(opts, toull(val), true)); + case ENV_TRANSFORM_SAMPLES_TO_USECS_OUT: + return tostr(samples_to_usecs(opts, toull(val), false)); + + case ENV_TRANSFORM_BYTES_TO_USECS_IN: + return tostr(bytes_to_usecs(opts, toull(val), true)); + case ENV_TRANSFORM_BYTES_TO_USECS_OUT: + return tostr(bytes_to_usecs(opts, toull(val), false)); + + case ENV_TRANSFORM_MILLIS_TO_USECS: + return tostr(toull(val) * 1000); + + case ENV_TRANSFORM_HZ_TO_USECS: + return tostr(1000000 / toull(val)); + } + + abort(); /* it's unreachable, gcc */ +} + +static void handle_env_opts(QemuOpts *opts, SimpleEnvMap *map) +{ + while (map->name) { + const char *val = getenv(map->name); + + if (val) { + qemu_opt_set(opts, map->option, + transform_val(opts, val, map->transform), + &error_abort); + } + + ++map; + } +} + +static void legacy_opt(const char *drv) +{ + QemuOpts *opts; + opts = qemu_opts_create(qemu_find_opts("audiodev"), drv, true, + &error_abort); + qemu_opt_set(opts, "driver", drv, &error_abort); + + handle_env_opts(opts, global_map); +} + +void audio_handle_legacy_opts(void) +{ + const char *drvname = getenv("QEMU_AUDIO_DRV"); + + if (drvname) { + audio_driver *driver = audio_driver_lookup(drvname); + if (!driver) { + dolog("Unknown audio driver `%s'\n", drvname); + } + legacy_opt(drvname); + } 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) { + legacy_opt(driver->name); + } + } + } +} + +static int legacy_help_each(void *opaque, QemuOpts *opts, Error **errp) +{ + printf("-audiodev "); + qemu_opts_print(opts, ","); + printf("\n"); + return 0; +} + +void audio_legacy_help(void) +{ + printf("Environment variable based configuration deprecated.\n"); + printf("Please use the new -audiodev option.\n"); + + audio_handle_legacy_opts(); + printf("\nEquivalent -audiodev to your current environment variables:\n"); + qemu_opts_foreach(qemu_find_opts("audiodev"), legacy_help_each, NULL, NULL); +} 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/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..2cc274c5e5 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 8353d3c718..b5364ffe46 100644 --- a/vl.c +++ b/vl.c @@ -3074,6 +3074,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_option_rom_opts); qemu_add_opts(&qemu_machine_opts); qemu_add_opts(&qemu_accel_opts); + qemu_add_opts(&qemu_audiodev_opts); qemu_add_opts(&qemu_mem_opts); qemu_add_opts(&qemu_smp_opts); qemu_add_opts(&qemu_boot_opts); @@ -3307,9 +3308,15 @@ 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: + if (!qemu_opts_parse_noisily(qemu_find_opts("audiodev"), + optarg, true)) { + exit(1); + } + break; case QEMU_OPTION_soundhw: select_soundhw (optarg); break; @@ -4545,6 +4552,8 @@ int main(int argc, char **argv, char **envp) /* do monitor/qmp handling at preconfig state if requested */ main_loop(); + audio_set_options(); + /* from here on runstate is RUN_STATE_PRELAUNCH */ machine_run_board_init(current_machine); From patchwork Sun Dec 23 20:51:43 2018 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: 10741893 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 BC79691E for ; Sun, 23 Dec 2018 21:33:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AAA712878E for ; Sun, 23 Dec 2018 21:33:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E1D828793; Sun, 23 Dec 2018 21:33:09 +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 listsout.gnu.org (listsout.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 80EF82878E for ; Sun, 23 Dec 2018 21:33:08 +0000 (UTC) Received: from localhost ([127.0.0.1]:42180 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbApR-0008HH-CA for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:58:29 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52101) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjp-0007Rr-0O for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjm-0001oM-Lh for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:40 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:35867) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjm-0001kk-AV for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:38 -0500 Received: by mail-wr1-x442.google.com with SMTP id u4so10091652wrp.3 for ; Sun, 23 Dec 2018 12:52: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=Y3icb4jpF6MQbt4owFVdSTjplHJtm83/PBbVt/5t8w4=; b=MocmvEHAYqB3Y/iKz4rjBHdWKaAAps3tBZZe+mtTRgqZcQySTgCx9+7ygwWQnGv2cX 9VrmVhV6kvBSxtlvSCf68jNpjGpvtI6B9hdkjEPSO7U4CK7qYMPaZhVxmYkoTO02aFZ6 vYJp1BZSRj82rkvxKWIP14ng9kkoK1py601qm4vAeBVLeqRvjlmmoCgmxdymgdw235NS 5bQZCM0MZVjXDaRasmn1D8fHKh+uTDc/CxdGK7635rCfv8OMnhuJ24SBcjbqLcwDUTrp E2wbuBwTmdx5SAW8p+6d1Tp/E6qFxUX+jdk9qX10dxMtFMCmuCESmg1ABeYfCX7V+Xs8 WH6Q== 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=Y3icb4jpF6MQbt4owFVdSTjplHJtm83/PBbVt/5t8w4=; b=IsOj5kOtqQQn/gdsJOjazDNoVCPIAos+eug+wnv/AfVmry7eT74eqXFva37rjpol0X bQYiLdWQMQgqdP8+pJ35R6M8fWEKvDOZf2j2HtDL7zyA952HyknL1BaCh1XJ6T/vm4Ip 8xkoFHOWB60C89yIU/T3iPakq6NjuMGnC8VG8EcW3coBjR9B4UtEBlcykglI0GIvnu0E PR36RUdbUAEqud3K99fuY2SO9Qw04V4qk6jse4lu+uNIoHatVOmVnxBUhRu4gcHll3aI 0eu/qPP1WOu3kQlPmurH41KJCvIGXebmTMZkQ9WsXu7hzhxSGUjwclN6FWRLopMJGLZO NDjA== X-Gm-Message-State: AJcUukduIC1iwpy+/+3UC0m/9pt+q3cNEllTfJjv7l7ioQH1UGKslD25 J1cuzr1Njcksa4guNyI9sUVazJiabGk= X-Google-Smtp-Source: ALg8bN6gneuFZJ7L+EYekuqBi8wzuIc/RZdJWj6sm4NJ0LHv1fzOC4Z0N+9lwRTbC4m2dw2RfrVdBA== X-Received: by 2002:adf:efd1:: with SMTP id i17mr9387418wrp.200.1545598356912; Sun, 23 Dec 2018 12:52:36 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:36 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:43 +0100 Message-Id: <07f5a54a86ae8083a91111e06387c8dc892aaf4b.1545598229.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 v2 07/52] 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 | 314 ++++++++++++------------------------------- audio/audio_legacy.c | 64 +++++++++ 2 files changed, 152 insertions(+), 226 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 8302f3e882..6f75644538 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" #include +#include "qapi/opts-visitor.h" #include "qemu-common.h" #include "qemu/main-loop.h" #include "audio.h" @@ -33,28 +34,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 +48,7 @@ typedef struct ALSAVoiceOut { void *pcm_buf; snd_pcm_t *handle; struct pollhlp pollhlp; + Audiodev *dev; } ALSAVoiceOut; typedef struct ALSAVoiceIn { @@ -73,16 +56,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 +388,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 +397,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 %" PRId64 " buffer count %" PRId64 "\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 +433,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 +511,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 %" PRId64 "\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 %" PRId64 " was rejected, using %d\n", + pdo->buffer_len, ptime); + } } err = snd_pcm_hw_params (handle, hw_params); @@ -631,33 +585,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 +601,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 +731,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 +758,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 +798,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->has_try_poll || apdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode && alsa_poll_out (hw)) { @@ -911,19 +832,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 +859,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 +1001,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->has_try_poll || apdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode && alsa_poll_in (hw)) { @@ -1118,88 +1029,40 @@ 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_audio_init(Audiodev *dev) { - ALSAConf *conf = g_malloc(sizeof(ALSAConf)); - *conf = glob_conf; - return conf; + assert(dev->driver == AUDIODEV_DRIVER_ALSA); + + /* + * 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 +1080,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 2242f06a5e..f91ce0c3e2 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -52,6 +52,17 @@ SimpleEnvMap global_map[] = { { /* End of list */ } }; +SimpleEnvMap alsa_map[] = { + { "QEMU_AUDIO_DAC_TRY_POLL", "alsa-out.try-poll", ENV_TRANSFORM_BOOL }, + { "QEMU_AUDIO_ADC_TRY_POLL", "alsa-in.try-poll", ENV_TRANSFORM_BOOL }, + + { "QEMU_ALSA_THRESHOLD", "threshold", ENV_TRANSFORM_MILLIS_TO_USECS }, + { "QEMU_ALSA_DAC_DEV", "alsa-out.dev" }, + { "QEMU_ALSA_ADC_DEV", "alsa-in.dev" }, + + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -162,6 +173,54 @@ static void handle_env_opts(QemuOpts *opts, SimpleEnvMap *map) } } +static void handle_alsa_side(QemuOpts *opts, int period, int buffer, + const char *usec_env, const char *period_env, + const char *buffer_env, const char *usec_opt, + const char *count_opt, bool in) +{ + char *usec_s, *period_s, *buffer_s; + bool usec = false; + + usec_s = getenv(usec_env); + if (usec_s) { + usec = toull(usec_s); + } + + period_s = getenv(period_env); + if (period_s) { + period = toull(period_s); + } + if (!usec) { + period = frames_to_usecs(opts, period, in); + } + if (period_s) { + qemu_opt_set(opts, usec_opt, tostr(period), &error_abort); + } + + buffer_s = getenv(buffer_env); + if (buffer_s) { + buffer = toull(buffer_s); + if (!usec) { + buffer = frames_to_usecs(opts, buffer, in); + } + printf("buffer %d period %d\n", buffer, period); + qemu_opt_set(opts, count_opt, tostr((buffer + period / 2) / period), + &error_abort); + } +} + +static void handle_alsa(QemuOpts *opts) +{ + handle_alsa_side(opts, 1024, 4096, + "QEMU_ALSA_DAC_SIZE_IN_USEC", "QEMU_ALSA_DAC_PERIOD_SIZE", + "QEMU_ALSA_DAC_BUFFER_SIZE", + "out.buffer-len", "out.buffer-count", false); + handle_alsa_side(opts, 0, 0, + "QEMU_ALSA_ADC_SIZE_IN_USEC", "QEMU_ALSA_ADC_PERIOD_SIZE", + "QEMU_ALSA_ADC_BUFFER_SIZE", + "in.buffer-len", "in.buffer-count", true); +} + static void legacy_opt(const char *drv) { QemuOpts *opts; @@ -170,6 +229,11 @@ static void legacy_opt(const char *drv) qemu_opt_set(opts, "driver", drv, &error_abort); handle_env_opts(opts, global_map); + + if (strcmp(drv, "alsa") == 0) { + handle_env_opts(opts, alsa_map); + handle_alsa(opts); + } } void audio_handle_legacy_opts(void) From patchwork Sun Dec 23 20:51:44 2018 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: 10741813 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 E83D991E for ; Sun, 23 Dec 2018 21:01:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2F7428783 for ; Sun, 23 Dec 2018 21:01:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C14852878E; Sun, 23 Dec 2018 21:01: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 35F2B28783 for ; Sun, 23 Dec 2018 21:01:40 +0000 (UTC) Received: from localhost ([127.0.0.1]:42212 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAsV-0004Sc-4K for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:01:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52130) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjp-0007SE-Vs for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjo-0001tg-E3 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:41 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:33891) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjo-0001n7-7P for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:40 -0500 Received: by mail-wr1-x444.google.com with SMTP id j2so10134010wrw.1 for ; Sun, 23 Dec 2018 12:52: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=wAHDeK1AOwR0vXP1Q2B9ENZRD49lzQs0kBC9KBs6zNk=; b=g0N9klN64bxalaHUWGsOnR0IUER9T6NxzSFBDrl/avsm+7d/8AVJPz/nSDMPpEPgr/ 4klBl1Kf7bq1ilmUQ1Um1JlPkWlOyCH+zqObpToUrIqkUBSIHsdJskuQo2kjIDuGrwDA tGy3QyAghKsLizJqZytiHAjZM/vt8o/dw3Z9IDmn0f2+aSjJZip5m/FyWOGodmQk02Wv GfuDn6q8C/WYadKR258PxIXcS9/hns+pBJ5E1WASJC/kjuOP/f862P+EgBq6Ju7E/q83 hk7tr70i+N8JZLqxRi3B2AL9yHCLSBnGwjQQ+vqsBOtsyPxJRzATPw3h+4ypYC3nLK/B 2ZQQ== 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=wAHDeK1AOwR0vXP1Q2B9ENZRD49lzQs0kBC9KBs6zNk=; b=i0syIcxq9V9EfNROwwwXxe1chFJFOP0GTBu5+fPOUCaiqY2cI0iBcs49lDIMaLy4n+ 23qE7GxQpaMND1ce1Wgk3BL+Mrdbn+xIS79ex5h/+8jqG39vasoVtGS/fwHmK1oBzY7D FJUjoLitQE+7G8K4gB0D3KXlW3XqiyjjetW7Dgy5jXc3m0U2zV1T9o9nssaN0g3S6N0J T4nQvMHiFlT5AdHAtwfLRFvr+p7v/1mVVO/xltZpO/hB6lwgWoZuIEePzCxoHwjALhFC irGcQhGZ0n5rO8D89gtXKpOS1S+2TiXjFqrK0UY68YEmqqCuebcCHjXBCZpsYG6hnDl3 9i3A== X-Gm-Message-State: AJcUukdBWIe1naPHFxl6EtaYvsQsFl40ZqD0jEcCmK/BWmumRmzN7mbu 9k7SqaAD5mchg/eDXBmGAVp0RwA+TZg= X-Google-Smtp-Source: ALg8bN4JtlTJLcF4WjVtNzomq3JKButZ5z78Qpj+Z5OWp7zLAl9EA8zQ4HNIzFxXZ7r2lPVPi1S5Nw== X-Received: by 2002:a5d:65ce:: with SMTP id e14mr9315913wrw.150.1545598357852; Sun, 23 Dec 2018 12:52:37 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:37 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:44 +0100 Message-Id: <017477fdfa5850f2fe1ebfd99fc6e2cca58ce004.1545598229.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 v2 08/52] 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 | 10 ++++++++++ audio/coreaudio.c | 47 ++++++++++---------------------------------- 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index f91ce0c3e2..42b55035e3 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -63,6 +63,14 @@ SimpleEnvMap alsa_map[] = { { /* End of list */ } }; +SimpleEnvMap coreaudio_map[] = { + { "QEMU_COREAUDIO_BUFFER_SIZE", "buffer-len", + ENV_TRANSFORM_FRAMES_TO_USECS_OUT }, + { "QEMU_COREAUDIO_BUFFER_COUNT", "buffer-count" }, + + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -233,6 +241,8 @@ static void legacy_opt(const char *drv) if (strcmp(drv, "alsa") == 0) { handle_env_opts(opts, alsa_map); handle_alsa(opts); + } else if (strcmp(drv, "coreaudio") == 0) { + handle_env_opts(opts, coreaudio_map); } } 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 Sun Dec 23 20:51:45 2018 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: 10741837 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 C3BF01399 for ; Sun, 23 Dec 2018 21:12:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF83A2877F for ; Sun, 23 Dec 2018 21:12:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F0722878E; Sun, 23 Dec 2018 21:12:37 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E77B22877F for ; Sun, 23 Dec 2018 21:12:36 +0000 (UTC) Received: from localhost ([127.0.0.1]:59798 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB36-0006J5-2l for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:12:36 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52124) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjp-0007Rw-K1 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjo-0001sq-45 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:41 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:33889) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjn-0001pa-RC for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:40 -0500 Received: by mail-wr1-x441.google.com with SMTP id j2so10134020wrw.1 for ; Sun, 23 Dec 2018 12:52: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=z1VYgEcSQEeFzDDUAYv8CHY326OnGpT09OgWbI2IuX4=; b=Jg2RzvgKp1asYwS3a9BIbn0ddgiMbBNA79JqARd7q+b1vV/rddkfHrgXShiruwDLTd dg7NWbUxABMWOZL0TWmDtP8iWesucwFI0b6G81Awm26s3R3xr5NWzydu9x+lbpqOrVgT 6lp0GkuwNtgosmJOdy0mKYXALH+oDsmPu9vxaakot42a9Sv7BJtQEiiSDfxf9d5U82nb Boo+gpHIoFQ7Fas2FoNB3FrM4BYT6EwDwSOessJ847wvPfA0CrbDpuM+z3JhZOOcrYYP buWIJydtALVV89y6Rrh1VhHaG0RDOh/wtGn/2pyh8wKus3s7zsgVmP8mYwPH7GAl/rPH Tr6g== 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=z1VYgEcSQEeFzDDUAYv8CHY326OnGpT09OgWbI2IuX4=; b=gkCvzlfoaLtxqbpUl1o70DMXiOBloRTVgVTb5WTJAoiyR2SzW+3Usb5YFI13rlyBs7 rQiSyEH1bSP4r62x+K02ZG/8clJ7gXwA8+pvBWR0qdOZfwjueaUktAqMMEoqnYaRX4GP xP/4zoTYAkhw+TNYcBBLE9Ig36jGY1SyNCDQQFs05j737JEqyweRf/ONs7DKv8Maq124 XT5OEJPoCgyvC5KRl3+D8SwozoqJ+xj6rwIvaikdmC3mRWzWeP1r2A6/RAGnped9JSft 5WKwvTHL1lNrRjVozfgmROHxtK7GfxpCRnpsG1ER41usJ7xE9dt84BdQ4RqxHtpYLFsd dTcw== X-Gm-Message-State: AJcUukcOvnd2agAgQw+sPgmo+tXVVxouMc+ZIkPadRi4Zta0foWaKtFr Gz80YIYdjUtQ72DmwbXRyxAnyuOj20Q= X-Google-Smtp-Source: ALg8bN5g0kHBjGAEAc3FopAT7QE04s5K3s9KHrP37AJIZRHDFHVvTMA6cuA07LEcuV5NXg8R0LZlGA== X-Received: by 2002:adf:eec9:: with SMTP id a9mr9363411wrp.242.1545598358611; Sun, 23 Dec 2018 12:52:38 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:38 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:45 +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 v2 09/52] 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/audio_legacy.c | 12 +++++++++ audio/dsound_template.h | 6 ++--- audio/dsoundaudio.c | 59 ++++++++++++----------------------------- 3 files changed, 32 insertions(+), 45 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 42b55035e3..48a22c390a 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -71,6 +71,16 @@ SimpleEnvMap coreaudio_map[] = { { /* End of list */ } }; +SimpleEnvMap dsound_map[] = { + { "QEMU_DSOUND_LATENCY_MILLIS", "latency", ENV_TRANSFORM_MILLIS_TO_USECS }, + { "QEMU_DSOUND_BUFSIZE_OUT", "out.buffer-len", + ENV_TRANSFORM_BYTES_TO_USECS_OUT }, + { "QEMU_DSOUND_BUFSIZE_IN", "in.buffer-len", + ENV_TRANSFORM_BYTES_TO_USECS_IN }, + + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -243,6 +253,8 @@ static void legacy_opt(const char *drv) handle_alsa(opts); } else if (strcmp(drv, "coreaudio") == 0) { handle_env_opts(opts, coreaudio_map); + } else if (strcmp(drv, "dsound") == 0) { + handle_env_opts(opts, dsound_map); } } 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/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 Sun Dec 23 20:51:46 2018 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: 10741877 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 1EF86924 for ; Sun, 23 Dec 2018 21:25:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10DE228787 for ; Sun, 23 Dec 2018 21:25:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 03AB828790; Sun, 23 Dec 2018 21:25:35 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A3F8D28787 for ; Sun, 23 Dec 2018 21:25:34 +0000 (UTC) Received: from localhost ([127.0.0.1]:42178 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbApG-00083t-4k for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:58:18 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52117) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjp-0007Rs-EF for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjo-0001u4-Lm for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:41 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:39954) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjo-0001rt-Fg for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:40 -0500 Received: by mail-wm1-x341.google.com with SMTP id f188so10406915wmf.5 for ; Sun, 23 Dec 2018 12:52: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=6dzWAz4o/r53OdD96erWt+rVtVFClcHBAdsRmyedBBs=; b=T3TnLHLeQNw6qQJAovU48kEe6aGD8PmmQlUGcdTNFehK+zl7PZJkJwRi25iHW26Egk PPtCYmA3tbIY4tzbd+9dCu/i5ZkBFWxfYGakSG6D2IUajlMCOdn7VBtn8yaAsKhOitTT Qw3rAwfEAVOfBFRSQDypn4S+Yyo4PwIpAOQky4raXgMmI+Q9uuwlTN/ros/WuFfTr1sf ruX86BQ/Y/1ityHzc5v44i9eQFyfWf5NR7olw17j7dywdLj28ttzhVn4jGtQXM7PXhEu hJfV/VoHKiJHiddiDtoShycFOhPUwRVggbMI7ERAvpMaObINOsoZzlIBOWtuIlD2/A7z o4Lw== 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=6dzWAz4o/r53OdD96erWt+rVtVFClcHBAdsRmyedBBs=; b=SY4z48RnSLxAdphb9mRHN5ycBQWuVv5HVHzwFwcWLHXb3o87win2VXm2i2bnqM9VzW patrVanbZHO/K1mDQI8fOfp3TQPYO/GUqod/dhGJdI4NWxmuHQMdasOvVo74s6uEOFNY aSgQV+An8cUsfFdMOvrt7cUXrhVuHf3SPD4XHF/C/srm1XmEkxHlqQahgM+Blwkl81gh s9MelG2/v6UGrISuc9ZX24fHBTitGn9/FL+jkis//YDaLF5HZcjx/zCaLRRLl7A7NFZ6 TKgjZo5LSCKmbqp9SjOxSJavKUWsrBmOb4QkZVSZb+IbvGwYU/PM/fffSnSS4kzgX4eT 4//A== X-Gm-Message-State: AJcUukcrgR6rHj6BMdagCckCxHxGrPg26h1OPMCi8Zyk9ONEMOAofP41 73RbxEMmwspkdqv1ZPfcFzRW+dh108Q= X-Google-Smtp-Source: ALg8bN7unvHnr8VeTsCm9zBceb9ob69hZkNQ75NOQKLlPMXqbgptjCsYEs9Q2hgOr8MH53PxO8e44Q== X-Received: by 2002:a1c:4d12:: with SMTP id o18mr10433868wmh.92.1545598359393; Sun, 23 Dec 2018 12:52:39 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:38 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:46 +0100 Message-Id: <41f3a0498fae350f8362023292606cfffea122e9.1545598229.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 v2 10/52] 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 2cc274c5e5..f1eb048d80 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 Sun Dec 23 20:51:47 2018 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: 10741841 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 215EE91E for ; Sun, 23 Dec 2018 21:14:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D14D281E1 for ; Sun, 23 Dec 2018 21:14:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EDBD127FB1; Sun, 23 Dec 2018 21:14:00 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1A8FF27FB1 for ; Sun, 23 Dec 2018 21:14:00 +0000 (UTC) Received: from localhost ([127.0.0.1]:59814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB4Q-00081C-T6 for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:13:58 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52180) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjr-0007WT-Vx for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjp-0001yy-Tf for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:43 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:39956) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjp-0001va-Hf for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:41 -0500 Received: by mail-wm1-x343.google.com with SMTP id f188so10406929wmf.5 for ; Sun, 23 Dec 2018 12:52: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=nrXQsUZtGs3cN6Zxy1oriXZA+DwG5rkLKgE6Qe8K8P4=; b=cxlNw753oSk6BWLlYDqwApcGAM9+Fu5nHQnaNdu/hO518aFDpG/g2GdBcii7gzfje9 LUeyKUXYDE6q6KsAwvoC80Oyde3CZ3IxTdsqGIU3SxkbMTDEBuFsgJwxOQ8Xo0RND6mI SA5Sywl11a7ewONz5brl3c3y/kFoKNyhvHoMq9z6Q3fY7Y8gi6UI2UIXeDNEG+L4qrO0 QNXtu1BzMLGm2uLg5Tdazq9vjakpizW6isYygiHLY791Xb8/2X10RW5jhsDqmLnAj5qG 6TY8lKSRGp7XW1usIhOejo25fCtv5sYTLffwSC4xr2iIskSy/1hUuXUs7Y/XWxd/7lm6 YMkg== 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=nrXQsUZtGs3cN6Zxy1oriXZA+DwG5rkLKgE6Qe8K8P4=; b=e7FCfkUeL3kX54Xwe9pY9u+BiH0MDP/qigYjt1MGwEInf1e5p6En94hN+AyOVtlMo4 8SjqPw9oxZBBlKH2VhNmbAGcsVa6/jS8ELsAv278QHHyp5AfuZebNDo40DNUuxdgWmHq XUislbejNhMe4TPcHZBN0uO//RU6r3j16zG9XIz6wx8jkY67qrSXQM3sookzsyqcEWmd fEyKyhYP2gDpXq+6U9K6u3yGIgg08gIzQk5skqkuzCFAIZO3VA/ezKTNy8S4sCE7LLXq /aTMyB2qrhAhUuCq2ce1EVLWC03BiyhNbUwrIJ+NPMtDe9vVaCwXnlMYJtfGIcpsfJNM VNpw== X-Gm-Message-State: AJcUukcQeQT/IN0rTF0weBPkwIDLoVilPOH2lV/eh/vUsAgsVo3s7m6h g9TcUv8NfmnYtGLgZ7SrBTJrwsAhaJc= X-Google-Smtp-Source: ALg8bN4t2viuBYFzWS6PCcxLG7ZtbOr0sPdPPGn1+SFl2JPWrjRwvB4dO7pxKGJTlxyrXK9vFaIy7g== X-Received: by 2002:a1c:888d:: with SMTP id k135mr10472164wmd.137.1545598360090; Sun, 23 Dec 2018 12:52:40 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:39 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:47 +0100 Message-Id: <26249b5186151dd3be871730b41b87959037540f.1545598229.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 v2 11/52] 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 | 17 +++++ audio/ossaudio.c | 153 ++++++++++++------------------------------- 2 files changed, 59 insertions(+), 111 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 48a22c390a..f37407586b 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -81,6 +81,21 @@ SimpleEnvMap dsound_map[] = { { /* End of list */ } }; +SimpleEnvMap oss_map[] = { + { "QEMU_AUDIO_DAC_TRY_POLL", "oss-out.try-poll", ENV_TRANSFORM_BOOL }, + { "QEMU_AUDIO_ADC_TRY_POLL", "oss-in.try-poll", ENV_TRANSFORM_BOOL }, + + { "QEMU_OSS_FRAGSIZE", "buffer-len", ENV_TRANSFORM_BYTES_TO_USECS_OUT }, + { "QEMU_OSS_NFRAGS", "buffer-count" }, + { "QEMU_OSS_MMAP", "try-mmap", ENV_TRANSFORM_BOOL }, + { "QEMU_OSS_DAC_DEV", "oss-out.dev" }, + { "QEMU_OSS_ADC_DEV", "oss-in.dev" }, + { "QEMU_OSS_EXCLUSIVE", "exclusive", ENV_TRANSFORM_BOOL }, + { "QEMU_OSS_POLICY", "dsp-policy" }, + + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -255,6 +270,8 @@ static void legacy_opt(const char *drv) handle_env_opts(opts, coreaudio_map); } else if (strcmp(drv, "dsound") == 0) { handle_env_opts(opts, dsound_map); + } else if (strcmp(drv, "oss") == 0) { + handle_env_opts(opts, oss_map); } } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index e0cadbef29..83ff1d2ebd 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -27,6 +27,7 @@ #include "qemu-common.h" #include "qemu/main-loop.h" #include "qemu/host-utils.h" +#include "qapi/opts-visitor.h" #include "audio.h" #include "trace.h" @@ -37,16 +38,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 +47,7 @@ typedef struct OSSVoiceOut { int fragsize; int mmapped; int pending; - OSSConf *conf; + Audiodev *dev; } OSSVoiceOut; typedef struct OSSVoiceIn { @@ -65,12 +56,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 +253,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 +283,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 +308,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 +502,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 +538,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 +596,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, } oss->fd = fd; - oss->conf = conf; + oss->dev = dev; return 0; } @@ -605,16 +604,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->has_try_poll || opdo->try_poll; ldebug ("enabling voice\n"); if (poll_mode) { @@ -669,16 +664,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 +705,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 +796,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->has_try_poll || opdo->try_poll; if (poll_mode) { oss_poll_in (hw); @@ -832,82 +821,25 @@ 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_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; + 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 +857,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 Sun Dec 23 20:51:48 2018 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: 10741817 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 442BE91E for ; Sun, 23 Dec 2018 21:01:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3247928783 for ; Sun, 23 Dec 2018 21:01:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 23EE728790; Sun, 23 Dec 2018 21:01:59 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9A41328783 for ; Sun, 23 Dec 2018 21:01:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:42216 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAsm-0005DF-RD for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:01:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAju-0007aP-Gf for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjq-00021E-GP for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:45 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:37497) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjq-0001y5-5M for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:42 -0500 Received: by mail-wm1-x336.google.com with SMTP id g67so10420651wmd.2 for ; Sun, 23 Dec 2018 12:52: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=vcB7bxTnfRfgqQXaotat+XXmhaSKEHoQVPmLY3YbJ7E=; b=pxWjfR1CLpm7a1rnjRA4Nw/cjseNQNMFmwL2nBumeq68Yevu1uhyjtEUgo1TOluZ24 PAfMwK8NEhx+u9rFMPBQCPy4AjKxhhJ+zb9t/xShTGKUH5RWrht3ig5/B+TreRsHVY7L rz4hp9bBQaRJMvV06fZ+W/0mvuiOGpEj/YWzlu4y9EtOlTMXEb4o8GowRHI3o+w/hgGX h2wRg1JeTXrSX6PoK1n9ZFQaX5MQ8F6nPk3p7QV5PU5YvvU7J9GdmdmIq0qxxVFswuOw 4EueUFqyoLAsrhhziVLwCtqRbSlEttB+HnTLBXAkb41CtrPrHXB3UXTSBU02e+cA6kNs A8Hw== 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=vcB7bxTnfRfgqQXaotat+XXmhaSKEHoQVPmLY3YbJ7E=; b=SvLiAFwGclIRpUiZuHsdrlleMCQ1axv5UDLNXH7nDZ2m3omKcCqEL+luNR32guEpt+ 8ZeiITfEzvSGh/g0tmJPisAJ7NSQWxdlEHVuRJtxguSda023nBIdFvfL8QccEvej/o85 ShL8QZEkq6+eVuL+mEgzCtV4qBdRnY1K0JNySL8e7aRUNDKtJZQiBRvWSlLjZ3ymfVaf m/J4rIWX31x2pyMc92pKVYQvQAiPyJIiUlK4JTtlZgmjh87ymeGoU5Nf9E1bghW95r5y NxmLot9RE1ooZACHHVJzo27GSz2rF+6020Xr+91LXJJ+BXHM9M7Lph8nt2yvrX3bDonT cZ2g== X-Gm-Message-State: AA+aEWZNiBT2hwvwP5z442FQC6PWtmbzRII7MZ2ky7zWaquRsimLLD0Z R9KclLrrAIZCCQIGvY6iAKYqWFqwenc= X-Google-Smtp-Source: AFSGD/VVCS2AvzNQP8GLZNnX2daBOvHHocs/VGAUmD5CaMfXFDWjsbCP8QcHEYP2Nr2gjoIiURhJ/Q== X-Received: by 2002:a1c:e1d5:: with SMTP id y204mr9942241wmg.65.1545598360800; Sun, 23 Dec 2018 12:52:40 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:40 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51: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::336 Subject: [Qemu-devel] [PATCH v2 12/52] 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 | 11 ++++++ audio/paaudio.c | 80 ++++++++++++++++---------------------------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index f37407586b..1f99d21803 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -96,6 +96,15 @@ SimpleEnvMap oss_map[] = { { /* End of list */ } }; +SimpleEnvMap pa_map[] = { + { "QEMU_PA_SAMPLES", "buffer", ENV_TRANSFORM_SAMPLES_TO_USECS_OUT }, + { "QEMU_PA_SERVER", "server" }, + { "QEMU_PA_SINK", "sink.name" }, + { "QEMU_PA_SOURCE", "source.name" }, + + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -272,6 +281,8 @@ static void legacy_opt(const char *drv) handle_env_opts(opts, dsound_map); } else if (strcmp(drv, "oss") == 0) { handle_env_opts(opts, oss_map); + } else if (strcmp(drv, "pa") == 0) { + handle_env_opts(opts, pa_map); } } diff --git a/audio/paaudio.c b/audio/paaudio.c index 0981f010c9..6de6ed97fc 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,19 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...) } /* common */ -static PAConf glob_conf = { - .samples = 4096, -}; - 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); + + 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 +832,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 +902,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 +919,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 Sun Dec 23 20:51:49 2018 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: 10741897 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 D4A3491E for ; Sun, 23 Dec 2018 21:35:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C54C22877F for ; Sun, 23 Dec 2018 21:35:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9BB828793; Sun, 23 Dec 2018 21:35:55 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CD4C72877F for ; Sun, 23 Dec 2018 21:35:53 +0000 (UTC) Received: from localhost ([127.0.0.1]:60066 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBPc-0000Nn-NX for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:35:52 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52183) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjs-0007XS-8q for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjr-000233-2K for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:44 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:36981) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjq-00020G-PL for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:42 -0500 Received: by mail-wr1-x442.google.com with SMTP id s12so10090931wrt.4 for ; Sun, 23 Dec 2018 12:52: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=8GUx8AhdRd4T/lz27VOZ17VoHctMlkxhmlrzIsMKO3o=; b=pRDvuj/zksaDZ0dqjKH4VqsgizZZnnRUQpqRv1CUlhhHN2O6BMGkksIGei4PGGmXj+ YoJqfOrgrmyz7EfPD65sCL6bSIFvkN+2s63G+qDXyf3/doowIdBWre7ViMcFcJKDdnuo /qhlKiHU6JdcSZDNFulEYSRgkwk08OSpJNXhFKoeN+DKhbohmkZEHuwa1/Wrq9rG3FLy Pp2wfVKc4haBD1iwwmoRHsp51goOCuZkkM9S4lBEYzmbzXUvan5vVxeZH+E0tiAwHedt B2ivIg8Wu8Ronj5gGLmxX+ulE3ATJZnHx9xeSBjIF2DZIICHwXphI7Jc87CTqExKvMrL Fc+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=8GUx8AhdRd4T/lz27VOZ17VoHctMlkxhmlrzIsMKO3o=; b=IcePsFnxpjwc/RQno+JnyfCuedXExM/6Ki4Y6pr9dMc+UaIJ3PrxGLHrWVEzW82JxK /+aXMW8Qxb304UwKd1L0M6m9AU10+W/XuiUgQfMtAuZrRwBm1EU6m+d4Y70rFHoz6zz0 9LmBhUGtbXDmSGI3WuwzUO3GDkHSsAD+rNifMHqxYp+RjIgAmgMDX5wGEtHUAi9I5Q8w ZtFJ8pUmkx/lJqinfLegGHt7GFT4eiVkwch8t7jtc/hDFJfjS71FAL52/pPfwzFrVvHQ QZVGcBQPL0LyG3090zDvvMto3V2n0K5LGyNGRwu5fSO5Y23Wua8pRx05h4I16ejAwodi c2vw== X-Gm-Message-State: AJcUukcrRKHT4KbppwKtEEWQDGtWgXgHbNTKUpO3bhrhB0vjnzLxauv3 eL/HrhGoG9DS41QQ4TlOYxNZkFoaHSY= X-Google-Smtp-Source: ALg8bN6yGPJ18SEdV+wMqW3PA4WKRZ1E8/rdJeQMOgeIFZDTCP8MfmhJvUBpEAMe2P6V/G7Ukgda9A== X-Received: by 2002:adf:9542:: with SMTP id 60mr9357984wrs.60.1545598361573; Sun, 23 Dec 2018 12:52:41 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:41 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:49 +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 v2 13/52] 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 | 7 +++++++ audio/sdlaudio.c | 22 ++++------------------ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 1f99d21803..6d95b761b8 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -105,6 +105,11 @@ SimpleEnvMap pa_map[] = { { /* End of list */ } }; +SimpleEnvMap sdl_map[] = { + { "QEMU_SDL_SAMPLES", "buffer-len", ENV_TRANSFORM_SAMPLES_TO_USECS_OUT }, + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -283,6 +288,8 @@ static void legacy_opt(const char *drv) handle_env_opts(opts, oss_map); } else if (strcmp(drv, "pa") == 0) { handle_env_opts(opts, pa_map); + } else if (strcmp(drv, "sdl") == 0) { + handle_env_opts(opts, sdl_map); } } 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 Sun Dec 23 20:51:50 2018 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: 10741909 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 6087A13A4 for ; Sun, 23 Dec 2018 21:55:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C2B828759 for ; Sun, 23 Dec 2018 21:55:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 403A02877F; Sun, 23 Dec 2018 21:55: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C1EA228759 for ; Sun, 23 Dec 2018 21:55:50 +0000 (UTC) Received: from localhost ([127.0.0.1]:42182 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbApU-0008LB-5x for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 15:58:32 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52215) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAju-0007bi-2U for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjs-00029p-Qb for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:45 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:50272) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjs-00022U-Ic for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:44 -0500 Received: by mail-wm1-x344.google.com with SMTP id n190so9881434wmd.0 for ; Sun, 23 Dec 2018 12:52: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=gFlI6J52EuSN1uBwYtC2z1Nd0p5GKE1yjn2uKwH4Jm0=; b=WnAz9/xYRVzVSuCF6fIT9g/AeRmNjUzUPRKvFTf3fvyIZFXfQoKYhPVtoX6Ja/u1mP jE/iLYA7VLLHGmn8XISm/WimEGI49vb9DU+t4dCfKwbYCZ24p8+2r7voBkH1X9RTQs+u E0Okpbk98CSYxXQx/sEz/6fgP6Zy/7fwwKbA0N8HMaO2VVb6hKRsK4SuAXm+XtpJVm55 ehDdiQxj9oYi8ob8SvsWP/giOCvwKUbJj4qstF/a5NvcYUc66Sq6teDK5VH6vzlAhcoo 1L3VlHsReruS5JL/M/9Z5pFO5oRudDqdxqPu10a8gvNDp+n1MXrWeYHVeFq1WWxpSFf+ Hqrg== 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=ntPV0VGSqD9Sd0q5l/uEUxQOBrHLUcLqtavjHL/XrHDvha5sbWaSdeje+g73U949t1 C0FvtgUT6bfQuTll8Fw3V262VqmT5yx+uegI394oIbjdqeEGWOlKpHoQcAUR7S6qYOqK ymDE3M79UogDKvRyvU8aNkh9LdnSiDkawhj8j0EF87ninjCp7BqgSxTlScod87acYvPU sc2uh3Y+bE2J0q9Kx7bb3z/lA8kCJpRY6IWrBUTYf3orsZJEwfSMX1YbF3micuSj229L LWqcphgJU9GVu7B6bZ5NyZshMJ6hWwy+dLCT8jJWosdq3lhaa/rRGRAwLGHcLNcFbQDC hjfQ== X-Gm-Message-State: AJcUukfoDqadha299Q4pWfV2TAWY37n0OM3L3AaBrd8HNp7nIogcrZjb x8aLb55KvVJL1FUHdb4vh1Fnmz5jrM0= X-Google-Smtp-Source: ALg8bN7AWjnYmYWVq+ZWHKfnSovdzOwQTD/d3mAZ0SosI+D9DNxIdv4Dy+EthUtevWfR5J+K77uoKQ== X-Received: by 2002:a1c:8c05:: with SMTP id o5mr9574329wmd.29.1545598362266; Sun, 23 Dec 2018 12:52:42 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:41 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:50 +0100 Message-Id: <7d984c53e0cce55748abf07e85b0caf5bb48952e.1545598229.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 v2 14/52] 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 Sun Dec 23 20:51:51 2018 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: 10741899 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 C88B96C2 for ; Sun, 23 Dec 2018 21:37:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5B732877F for ; Sun, 23 Dec 2018 21:37:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A788628793; Sun, 23 Dec 2018 21:37: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1BAA22877F for ; Sun, 23 Dec 2018 21:37:06 +0000 (UTC) Received: from localhost ([127.0.0.1]:60078 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBQn-0001Po-Cn for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:37:05 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52220) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAju-0007ch-A8 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjs-00028M-DX for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:43039) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjs-00025J-5I for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:44 -0500 Received: by mail-wr1-x444.google.com with SMTP id r10so10087896wrs.10 for ; Sun, 23 Dec 2018 12:52: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=M7msQeFIeK8RPDjcHTtd5tP//OSPSScp7Hf0dkBVVdg=; b=KzLdZA/3G3zEAZQNhrNmyApB6U2fBzvZMMigoArEB/ysisYAzfB+oq6uZrkchByEL/ LI4yauIEliqezN/rbTM5qk8+j58EIufpS02fo/OYsALgwGUMW05t0/pivML0z2YcgTh9 rS3EB4wqz7Zw9ubZmUYPiyCA+68fqR8Qlbgun8NxXBqfZ3GHruuTacVWzeDKjYYh1BcT 3UPbkxA2rz9EymFbhWJtAtMTGhCjS8JUJnn9DY1CVanwZaQIBoTU+NKtWKCLFXy8ylS8 KLY/abezlxrh9sUw/vk7FbLbHjY/vDZayqgS09EM7UNjso0wsnArWExKLSk9siIvyKe8 scSA== 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=M7msQeFIeK8RPDjcHTtd5tP//OSPSScp7Hf0dkBVVdg=; b=lcTOV3nt7c0OzIVL0AWfuSKttaB5bE07KB0IW1sPXdQINWoYGNaMj+rNO7I4lP7wUR 8i4o9x+mUHAi3GI/kFYy9FOMQcWD5JLrYqs/bYwqYUsmCBTqzNjn0kUdObICLho205mK +aDJDiWeb/E5q9VL0LG0R5pUfzOpWpgceheW9dkJ6Vhqu0NeamrHts+wD0Sb8forUcRS QxF9wNnCKMpvvNE/FsZyIlItOh0T4L6nrGULlh8jHfu8UQqYK98g6aki7an6LUBbk/xN r4uj0yHn0t9B5FmfYWNgJVzP3mxUqZzN+x6vD1i3Hrf6BRyjdPhsWSACJDFenK3jopn/ Karw== X-Gm-Message-State: AJcUukdykQHQ3JKecaahBZOlWYTBu7l4ZQJOwFb8OIwBfj0jyozlxC7I OgYuPAv0ZK+21ejqY1aQ4BbCj7rwzqM= X-Google-Smtp-Source: ALg8bN5eUVS2SDnE8Q78oIGSqaNWx++5uIc64R4nyaWsau/T5kpY7vfhV7HrlqaLpWvIJhGYkt98Ig== X-Received: by 2002:a5d:454f:: with SMTP id p15mr10183387wrr.39.1545598362913; Sun, 23 Dec 2018 12:52:42 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:42 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:51 +0100 Message-Id: <801e931cea3505400b3262dc2d170e2ce6dde2fc.1545598229.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 v2 15/52] 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 | 10 ++++++++ audio/wavaudio.c | 58 +++++++------------------------------------- 2 files changed, 19 insertions(+), 49 deletions(-) diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c index 6d95b761b8..71bbda04e2 100644 --- a/audio/audio_legacy.c +++ b/audio/audio_legacy.c @@ -110,6 +110,14 @@ SimpleEnvMap sdl_map[] = { { /* End of list */ } }; +SimpleEnvMap wav_map[] = { + { "QEMU_WAV_FREQUENCY", "out.frequency" }, + { "QEMU_WAV_FORMAT", "out.format", ENV_TRANSFORM_FMT }, + { "QEMU_WAV_DAC_FIXED_CHANNELS", "out.channels" }, + { "QEMU_WAV_PATH", "path" }, + { /* End of list */ } +}; + static unsigned long long toull(const char *str) { unsigned long long ret; @@ -290,6 +298,8 @@ static void legacy_opt(const char *drv) handle_env_opts(opts, pa_map); } else if (strcmp(drv, "sdl") == 0) { handle_env_opts(opts, sdl_map); + } else if (strcmp(drv, "wav") == 0) { + handle_env_opts(opts, wav_map); } } 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 Sun Dec 23 20:51:52 2018 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: 10741819 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 BFCFA14DE for ; Sun, 23 Dec 2018 21:01:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFC7828783 for ; Sun, 23 Dec 2018 21:01:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3FB32878E; Sun, 23 Dec 2018 21:01:59 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 06A9B28787 for ; Sun, 23 Dec 2018 21:01:59 +0000 (UTC) Received: from localhost ([127.0.0.1]:42218 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAso-0005F6-7s for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:01:58 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52238) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAju-0007eA-VK for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjt-0002C1-A7 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:50271) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjt-00028S-0n for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:45 -0500 Received: by mail-wm1-x342.google.com with SMTP id n190so9881461wmd.0 for ; Sun, 23 Dec 2018 12:52: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=+cUsRleoO4YUEA7trsmly6GGSR7W4F/uhGZGMcrGvso=; b=unTrerOdRuyEoCuFM/3Ag8KuhyClHvlouEg4L3RljhxyZF6syamR0CNZkDM8dBHn0g VJOxC2N3lG5NAZr19PlD+vcWFov8YsINz9O+KRQzC790fSNhDvkRwB5fwHJl5j0jdKE6 FKHBC5SjVs7AWnTrTqx/EmE436ehdP8E4XvtM7YmNiE4dpLl2lJ9gsQK0jeBz/tmZp2h Er2fuadON8cJySIa1MRHSRHwtQ5HFOvKEsZL7LE/WV+sBfETdfo6O5WoZOct+2JcSa+j OQcXaFS791Ac4E4aNweCbarthoLFcdJzeRBLdVJa9cdGpX7E+Wvng/w3GEGcP5+Dapsq KMSw== 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=+cUsRleoO4YUEA7trsmly6GGSR7W4F/uhGZGMcrGvso=; b=LqiNGcsBUCZTs61IzOcFJuaEYBYmSK61KLrdZrz2wFmLJv4kS4RU8V/CSx84dRR52m vhmE8QNTVhciYQjLsryxFNLb/l8ymLXcm7pOaGP0UpxPGM/taoclREeyPf+pldrnw8Vr 9X/XiykQuKR8rIqXLkF/PDMpUJm8d2iP7pmsLZ2R4oNMeAwrtbfGs9AFKUYwxOPb+G3o pHFh3y2BF59IDvo/dIy34nAWz01Plg2YCH07klvB+EXGqaSn8VxFQr+qD25fC+gv8OHL 3P9fzWa9BnGlFVv76V9WbT9on0p7tNzyrDLgc0H2kDg2LD3AuvQ5G3S10vEGZQPoOqfD dtSg== X-Gm-Message-State: AA+aEWbbMt86qv2FKvC7LYnTb+woZzyiZERv/d7vPsl9iSH2ib/DZ9AJ /Smva0/ArnSDqWjk9NTJQUasa5KUHGM= X-Google-Smtp-Source: AFSGD/Wja3IoSUQv0O9scAK4mYhfxuVQk9mpNKVZ50E8dnfawx0toAy7jv6aerAUHz1AO8jXhJaY9w== X-Received: by 2002:a1c:27c6:: with SMTP id n189mr9939766wmn.108.1545598363666; Sun, 23 Dec 2018 12:52:43 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:43 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:52 +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 v2 16/52] 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.c | 201 +--------------------------------------------- audio/audio_int.h | 17 ---- 2 files changed, 4 insertions(+), 214 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index e7f25ea84b..0c3f0efd46 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -173,113 +173,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) { @@ -298,89 +191,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); @@ -1093,7 +903,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); } } @@ -1138,7 +948,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); } } @@ -1462,9 +1272,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) { @@ -1489,11 +1296,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); } diff --git a/audio/audio_int.h b/audio/audio_int.h index 24b8793496..83fb517b2a 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; From patchwork Sun Dec 23 20:51:53 2018 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: 10741863 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 EBD3614DE for ; Sun, 23 Dec 2018 21:20:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D6A4828783 for ; Sun, 23 Dec 2018 21:20:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C44072878E; Sun, 23 Dec 2018 21:20: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CC1A328783 for ; Sun, 23 Dec 2018 21:20:15 +0000 (UTC) Received: from localhost ([127.0.0.1]:59883 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBAT-0007rY-Td for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:20:14 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52271) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjw-0007hl-Es for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAju-0002HS-CM for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:48 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:34912) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAju-0002Ci-0u for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:46 -0500 Received: by mail-wr1-x442.google.com with SMTP id 96so10114917wrb.2 for ; Sun, 23 Dec 2018 12:52:45 -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=orG4GWeMiA5jSPueiS3zQ/VjA8TfIztY36paMY+adRw=; b=jrpb2p2Iu4S1Ijw5JKrbJ+nZbJRvpKgjYvuux7osDUPTjISNcgGtGAhGfISwTv3F60 uaRDd/M+n+NrfNkFpNr9R/kw7H07TJAvlgKcjfFyD3KwGkI/qurUMVlY+J2PddlPyTdD Vp+jjor6S5zE5XDmCI+SUe/Qn2CBPeuMTikxnaFhaOW5u1ZJvvc2eyW3ESdsoEY8zTfz zyC6DqWxnSLEoZHLqsZtyQSRvsv1YhgbdGLxE8g2oIoS3DZ12+TT28ED5HHv6V0Bcu8m uZE3HReRLb4q+VI8xYbIZCJqiexkYQmL1buSYAbOZdD7ZMJgQ01CpJYKVWl9gTA31Lt2 95hg== 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=orG4GWeMiA5jSPueiS3zQ/VjA8TfIztY36paMY+adRw=; b=JfKG70r7l4+ocpAuFmslIlCNv3VUoGf9+zXfOPw6LK+9VAQX5XN+ardMfbFKTDVTNg 0eFNEYPquqbDOOFjgyb3z7lUuB/JWsecntV+qq/ufK+UveMZ4P58BE35Bcce7WBenwU1 3+AiXgruCpl353OTWYRMIeywX9qgUzmK46mrNpl8t/Mja5bFablqnfBVXajuOP8i3oPT bFFzlGhhLr65Ldkj9vVuBX0aKoxdGq98TXfnNNUFy9jx+kPeS1SDN5k6wocwA9HAuRUN zJbpCQMZaph+eQK6wZa7XD+HFzoupJid0BYL9o7HTrQTtM3roATnhZ+7TsQd+DA534VA oo2w== X-Gm-Message-State: AJcUukeKXEQAayd7d7ScQYV/BAECaD3rZZFc4BX4s5r4Ff2nO7Vo9dZI fylzGkWxpgSQVEpjDhL3oFCzLVuAFNQ= X-Google-Smtp-Source: ALg8bN6USkjhmmU4kbqrmcw9UdupFxVFIwVyUMiAZR8521Kt+X9Z8tD48cQ5Dwg2m5q37t8BLYqfqQ== X-Received: by 2002:adf:cd0e:: with SMTP id w14mr9993374wrm.218.1545598364599; Sun, 23 Dec 2018 12:52:44 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:44 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:53 +0100 Message-Id: <18f35cc23aa31d945416bf185c84dc15d81df6ad.1545598229.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 v2 17/52] 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.c | 59 +++++++++++++++++++----------------------- audio/audio_int.h | 7 +++++ audio/audio_template.h | 46 ++++++++++++++++---------------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 0c3f0efd46..461aea7a01 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -398,12 +398,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)) { @@ -480,7 +478,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); @@ -793,19 +791,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; @@ -813,18 +807,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(); } } @@ -836,11 +830,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); @@ -894,7 +888,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; @@ -941,7 +935,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) { @@ -1064,7 +1058,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; @@ -1169,7 +1163,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; @@ -1275,8 +1269,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; } @@ -1295,11 +1289,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); @@ -1319,7 +1313,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) { @@ -1338,7 +1332,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); } @@ -1515,7 +1509,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; @@ -1532,6 +1526,7 @@ CaptureVoiceOut *AUD_add_capture ( } hw = &cap->hw; + hw->s = s; QLIST_INIT (&hw->sw_head); QLIST_INIT (&cap->cb_head); @@ -1564,7 +1559,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; diff --git a/audio/audio_int.h b/audio/audio_int.h index 83fb517b2a..792ec3152a 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; From patchwork Sun Dec 23 20:51:54 2018 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: 10741869 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 5FA70924 for ; Sun, 23 Dec 2018 21:23:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4CEAD28783 for ; Sun, 23 Dec 2018 21:23:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3FA6B2878E; Sun, 23 Dec 2018 21:23: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3FF2328783 for ; Sun, 23 Dec 2018 21:23:42 +0000 (UTC) Received: from localhost ([127.0.0.1]:59919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBDp-0003N7-CQ for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:23:41 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjx-0007lQ-RE for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjv-0002Lr-Iq for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:49 -0500 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]:35604) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjv-0002IU-72 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:47 -0500 Received: by mail-wm1-x32e.google.com with SMTP id c126so10408927wmh.0 for ; Sun, 23 Dec 2018 12:52: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=tTVe+jJk0EaKByELjmC3oiKcANxWjg8moyqqWN0/9Xs=; b=bbzqfGqHS1KpdvWXwffB5DBKLoI2ZZlqwicfuP46GCqYlgivPhVXyR5WH9CFJb5a+E oczFDC9msSX1N2KzJccDalXaldMdp0kAxAZwtdSDiTTw8vT2LmST79/1KLrvjIYt9K2a ztWMgTUhlryp0Y/Yvs+Inhv4xCvzL49EjggfYDqeVR5fljgTHN1FjeY1NwCkv+/J8o4O Fi3c5h/9Gn3vhSsMEHjq2iTGvDvvkUR1FHR4EYEYnTNTCahxfP1GFmtoM6vKZ+nF56tB oaQU6QJTYt4BP4xzNpgjTFWk6og40e8sUVbTTUt6NKYBfHuKbCzXmGqm1Muehl5sTnJP VSjA== 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=tTVe+jJk0EaKByELjmC3oiKcANxWjg8moyqqWN0/9Xs=; b=SgHEpI7viR2Ed1yVaHrzlQegPpWUwjw5rvIUmyUl0ekHecSysQV1vISI1BMXHBQ3bS GLh2mvSSx+m9xtziu+XwY/1Or9q0ytrd7tiJ49aZqS4txS0MXmMsqOXkMKh8B976TP8w 8s/M1YoZ+FMMm1Xpsn2Td0fyhFUm/2tfgLyHSc/isVeBUuX19bTrNh4GpniZifs7L/WH QRrMEcKvoZhLREGCkODSDmkfB4Yw3YC4ObDqEDib4Cl/b15nT1QyANySSYjRzknFcKit oWhyymsWV/Nn3iaK53NwdfDRtY09b6lPqH49hYSDMPRMjnUe2p81cSq/F5jOGnewPAk1 0oeg== X-Gm-Message-State: AJcUukdy99qBlq+dQG53Rwaa1iTQpw7j5+vLZza4r68CoLFhpGYH80LP eISChDL6PWxqRH1uQYTrr167ED9FpOY= X-Google-Smtp-Source: ALg8bN4dAZ/woD6STFmsJaKsJoibbtcQ64MEs6L+yOP76xklRZwhQMSJffB6fFkzadWVForUd/QipQ== X-Received: by 2002:a1c:b189:: with SMTP id a131mr10420545wmf.38.1545598365553; Sun, 23 Dec 2018 12:52:45 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:45 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:54 +0100 Message-Id: <899034ec66d2d4b9a2302d874482b727d7eb92e4.1545598229.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::32e Subject: [Qemu-devel] [PATCH v2 18/52] 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.c | 105 +++++++++++++++++++++++++++++++---------- audio/audio.h | 12 +++-- audio/audio_int.h | 2 + audio/audio_template.h | 2 +- audio/wavcapture.c | 6 +-- hmp-commands.hx | 11 +++-- monitor.c | 12 ++++- qemu-options.hx | 5 ++ ui/vnc.c | 15 +++++- ui/vnc.h | 2 + 10 files changed, 133 insertions(+), 39 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 461aea7a01..92fa170b46 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -86,7 +86,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, @@ -1240,11 +1241,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; @@ -1306,13 +1310,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; @@ -1349,6 +1351,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 = { @@ -1361,28 +1374,34 @@ static const VMStateDescription vmstate_audio = { }; static Audiodev *parse_option(QemuOpts *opts, Error **errp); -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 */ QemuOptsList *list = NULL; - 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 */ audio_handle_legacy_opts(); @@ -1392,12 +1411,18 @@ static int audio_init(Audiodev *dev) exit(1); } } + + 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); @@ -1466,15 +1491,18 @@ static int audio_init(Audiodev *dev) QLIST_INIT (&s->card_head); vmstate_register (NULL, 0, &vmstate_audio, s); - return 0; + return s; } 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) @@ -1484,16 +1512,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); @@ -1730,7 +1763,7 @@ static int each_option(void *opaque, QemuOpts *opts, Error **errp) if (!dev) { return -1; } - return audio_init(dev); + return audio_init(dev) ? 0 : -1; } void audio_set_options(void) @@ -1798,3 +1831,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/audio.h b/audio/audio.h index 7df1b8b249..5e0dcdb93e 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; @@ -94,7 +96,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 @@ -162,8 +165,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); @@ -177,4 +180,7 @@ void audio_set_options(void); void audio_handle_legacy_opts(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 792ec3152a..9d9db8c270 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/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/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/monitor.c b/monitor.c index 0ad54d8b11..14e130308f 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/qemu-options.hx b/qemu-options.hx index 3ede6a591d..687dd23bf2 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 diff --git a/ui/vnc.c b/ui/vnc.c index 0e9e9fb63a..c64ca10de9 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/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 { From patchwork Sun Dec 23 20:51:55 2018 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: 10741873 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 DF64813A4 for ; Sun, 23 Dec 2018 21:24:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CEC8528787 for ; Sun, 23 Dec 2018 21:24:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C084528790; Sun, 23 Dec 2018 21:24:55 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 637E928787 for ; Sun, 23 Dec 2018 21:24:54 +0000 (UTC) Received: from localhost ([127.0.0.1]:59940 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBEy-000565-72 for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:24:52 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52342) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk0-0007sI-84 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjy-0002WC-5w for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:52 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:36945) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjx-0002KM-Qp for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:50 -0500 Received: by mail-wm1-x342.google.com with SMTP id g67so10420765wmd.2 for ; Sun, 23 Dec 2018 12:52: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=wK4iprOhVykhGE6GzQERX2/swGr9VNPKc2tipOaIFTE=; b=qg3Mt4vI6Sm2zkLUvKtoLTviFehJVt1uMfC3gluBYfu6w0BzhMjITEgOSJpwQ4j8+D iLcwqyLODNUm6r5vzrhBTveVAOiFhDmWPSp4iKPZLp1blp/HMdKiE6egJo9XF7ewjXmD xu9/LnQxfNVi1hlyTUUgu/9a+XdQXspbUfnkF8/xJor73VPJK65anicDAQfGxwHQzQ7c /i1OAL66wpbP1v8mJTFXejGLGwElZuYmfi6v58CHJlga4J/C3QFtfGu5KIGGKnqZRNhf hYPVhAk0zhxh52WujNDHoVj5nGkzjTG6AamDcZBCWhK7NOim806AdRQU07O2NzUVHq4O Yy/A== 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=wK4iprOhVykhGE6GzQERX2/swGr9VNPKc2tipOaIFTE=; b=ksOQG/2OD0QuZgl8Ac//cKTb/DXszegzY0qTbEr96qoEKFnnfcQ1W0CDIigwNQvQ8M wFBh24VMF++asSGWimEyrHvVX7YFL6Kw5qTBLrNrYfvDktFu1Vu9/eagOKNaVg7z6iUl ndDSvVlwgMVsHmQhv7KIDcy1Q+mVNUZd5UfloLXidKTNmGknHSkfk/eD2C0vBTmjA1nl j3vnfML9tycoXt8clShTF/LaIAbA1G0RpxKgvEsq4/GDEPjDxmiOrkhPcBjA7mLfoSf4 z5oBzioKoBr+Jh5FNPPOPw2iVRmIJ9uBMNGepluB2873cyHPYrVxm5rnfuzzjMK5AzDF wEYg== X-Gm-Message-State: AA+aEWZf8/4KMYgkweaIJdt6TnUr4t4Ug03bfSDn/MvL5Ys/sJluKNPh MQHee6B++vWihQw/XK13BfXmYtmL7Mc= X-Google-Smtp-Source: ALg8bN7OJHjJzumdtYm8w/h5UpVnwdxQ1heAn5lcdgqMhOKwXfKK3uylBhkv9NQ5lL9mTWr6oV6emA== X-Received: by 2002:a7b:cb86:: with SMTP id m6mr10105791wmi.61.1545598366320; Sun, 23 Dec 2018 12:52:46 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:46 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:55 +0100 Message-Id: <10517b96e87d45063ef7d6a2d0bce66fd06620ae.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 19/52] 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 ++ 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 + include/hw/qdev-properties.h | 3 ++ 15 files changed, 90 insertions(+), 1 deletion(-) diff --git a/audio/audio.h b/audio/audio.h index 5e0dcdb93e..ccfef9e10a 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -183,4 +183,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/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 5d614c0d8b..c86fd91f98 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 b1b9736a19..589977d96c 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -663,6 +663,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), 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() \ {} From patchwork Sun Dec 23 20:51:56 2018 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: 10741903 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 164A091E for ; Sun, 23 Dec 2018 21:38:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9E4123B32 for ; Sun, 23 Dec 2018 21:38:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D9EF5252D5; Sun, 23 Dec 2018 21:38: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AA9E523B32 for ; Sun, 23 Dec 2018 21:38:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:60090 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBSa-0002uK-15 for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:38:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52356) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk0-0007tJ-Ma for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjy-0002Vb-2E for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:52 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:45126) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjx-0002Nt-Lw for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:49 -0500 Received: by mail-wr1-x441.google.com with SMTP id t6so10090838wrr.12 for ; Sun, 23 Dec 2018 12:52: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=mpFI0pWpKGS2O5X/JOf1VN9iV30kQWaTVUXR6lMMvu8=; b=Ag30ew5mmtiEUcYpRKGSkFVGQojOJjLz6ULI9LKoWfTJhNJ9ATqseTnOUG7SZR+f/g sDf69u8icU6R7kSIihhhY/SvEHpkOAiMiLBNMWBvkxlp2qyu/f2Q9MCL1zyN9j6+F+1i KYt3SDIArzLe3RkIFhwlUcHumyJVENOEYjS8SrhztJ8Gkos1uG00NPPQV62zxmH2y4Go U3R3+S0QaQ834psvMDveFcldzn+c9WXcUXaNvNXKkRIYkR1pmyMo0+WkVwyt14naTP9O uMI4OiwcLWColtPuvcmHd1CC/2kS9K36UuixmKHO5Mw2Bnb2oh97ImoCIhUlhZoNBtLW umnQ== 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=mpFI0pWpKGS2O5X/JOf1VN9iV30kQWaTVUXR6lMMvu8=; b=N5Wi+CjlEDLBq1rHzIhExxZevEIPELH2Q82FaqvgS+k6JVV5FHcDmLiyosWA4/Uayy +sA6XMx0lTwAwhXau0CmBHoao1fXx0ZAy96xCoD6IW+XpF0M/nEcG10eThakoc3/qEno tARRukPl39LLIunSYwsM3NmeMi7QjGXqkBHjtkMUC5VtVWVz+G7hVHCyTTYBESVsXsfZ DbBtafNlEz1w0mKHmOII4hnab3hHc0+hOQZsvfeLBXx4QL9YcM9/s6PSe9dxNiM7vJ/w CyekrRP1wOH2eHPTS5j/iN9n5QgrUJPDIGLfdWJ/8n3l4S0cHu3yL9FGMlpLxJqy8eGn a1xA== X-Gm-Message-State: AJcUukcpUrtyrUhIkjQsgt3Fh5VD7c3BEyBGez20NNGi2X0DNRbcOiox Ag1FoY9n9Fu8FRWdKRAE5nNK+C7xwgw= X-Google-Smtp-Source: ALg8bN4spB/i3/opPZ3dSMvXjie+NZ7R6DvMUbR2C/URBCtuukeSi6HtQNrNgJIA3xXQRx+vQ3PrIQ== X-Received: by 2002:adf:891a:: with SMTP id s26mr9542732wrs.44.1545598367141; Sun, 23 Dec 2018 12:52:47 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:46 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:56 +0100 Message-Id: <5262d91b3c72117da7cdc3c45c8685ae8b19c211.1545598229.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 v2 20/52] 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 --- audio/audio.c | 24 ++-- audio/paaudio.c | 303 +++++++++++++++++++++++++++--------------------- 2 files changed, 189 insertions(+), 138 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 92fa170b46..a7f79f3929 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -100,6 +100,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 @@ -1381,7 +1383,7 @@ static Audiodev *parse_option(QemuOpts *opts, Error **errp); * 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; @@ -1395,12 +1397,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 */ @@ -1497,7 +1500,7 @@ static AudioState *audio_init(Audiodev *dev) 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); @@ -1523,8 +1526,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)) { @@ -1763,7 +1769,7 @@ static int each_option(void *opaque, QemuOpts *opts, Error **errp) if (!dev) { return -1; } - return audio_init(dev) ? 0 : -1; + return audio_init(dev, NULL) ? 0 : -1; } void audio_set_options(void) diff --git a/audio/paaudio.c b/audio/paaudio.c index 6de6ed97fc..24b75ca503 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,122 +792,156 @@ 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_audio_init(Audiodev *dev) { paaudio *g; AudiodevPaOptions *popts; const char *server; + PAConnection *c; assert(dev->driver == AUDIODEV_DRIVER_PA); - 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 Sun Dec 23 20:51:57 2018 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: 10741849 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 EFAF61399 for ; Sun, 23 Dec 2018 21:16:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD25628787 for ; Sun, 23 Dec 2018 21:16:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CC86128790; Sun, 23 Dec 2018 21:16:55 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7DC9728787 for ; Sun, 23 Dec 2018 21:16:55 +0000 (UTC) Received: from localhost ([127.0.0.1]:59854 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB7G-0003CL-Kz for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:16:54 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52297) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAjy-0007lm-2i for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjx-0002SI-8g for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:49 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:53887) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjw-0002PN-UV for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:49 -0500 Received: by mail-wm1-x341.google.com with SMTP id d15so9848809wmb.3 for ; Sun, 23 Dec 2018 12:52: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=U+TkwZPvsdP+BtiX7XwI/XyHTCguiF8VKQhrroY0L8c=; b=fAHFrZc3Dh+BoXNy40hFDWlZddY8jUXjKdPJfyhZKO9kCAVgzXfGQ1oJiz369PHLFc EGZW9eWuzjn5ZFX2LWHY0Py4xOt3nxGn86/uyI9jVAT1mQce2c/2r9Xz5WoucfKOUlMm q5LIuZptoM6sONo6TO19QK6sitOPaO99alYw2TwdPlXqdYS4B5BAcmJNkv+al9H0qj6v UV9aDvQCINyE0KLZT9BuVh1LH0OEeo4pJ/WMrQQNo/4E9hRICq5szsqKLZ6/3xjfUnTc xpuZrEJh4FKSavn9vhtc9VUtYtlQaAiLQSsxkPBTMp9f1kcwVc+r0opW7cmeHu8gcJFI WkIA== 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=U+TkwZPvsdP+BtiX7XwI/XyHTCguiF8VKQhrroY0L8c=; b=IB7dxNW6JP1GF+AQx2yF0zZyKrkrThIXfnkXcGjmp3zoOumSMYXcy43muWzXvJ78ZY +2OgbK6Q8f9rShulExMuFbogY5ulXDVZgkAJ86LULVLNrJKhohIt5TM5nqfIz01ju2H0 FfTAoSyQcwZEJXFNpbepTSX/56ynalx9UpDZE6mCSeArx2ZVPHPThJbFcF/2g/VEas1Q tQDazyD9bieKU3NEz3RC29lsoILq+u8j2qrrWgKt1o51j8mAaz1u3Fm/4ekiSPQ4GkDm 1ztD6YusrCEYFDnWVhvFQS9qP6JqCuZ7tMTHyzmBXNTJEkFwGXoHIdsgaDrYf1efvDbi EN/A== X-Gm-Message-State: AA+aEWb0MgHLsFkXYwH2H89dBT+/AZIYNeWo9A80FMXNOJEkbF95gvqb ieU8eg0aRM6uGbEt+evzjBwS9NFCXag= X-Google-Smtp-Source: AFSGD/XrrYM6GX7hUYNASg10VqNh+7AZBxghXFw3LALMAUBcrFqMmDQOB2bsUDGTY7Fab2jUIG7p/A== X-Received: by 2002:a1c:864f:: with SMTP id i76mr9909943wmd.83.1545598367825; Sun, 23 Dec 2018 12:52:47 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:47 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:57 +0100 Message-Id: <4fbca2b5d360379e9a0134c585d1f72e512d4199.1545598229.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 v2 21/52] 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 24b75ca503..21ffbf7f6e 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 Sun Dec 23 20:51:58 2018 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: 10741825 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 261FE1399 for ; Sun, 23 Dec 2018 21:06:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 127F128717 for ; Sun, 23 Dec 2018 21:06:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 044862878E; Sun, 23 Dec 2018 21:06:33 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A4DE528717 for ; Sun, 23 Dec 2018 21:06:32 +0000 (UTC) Received: from localhost ([127.0.0.1]:59746 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAxC-0000dJ-Pj for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:06:30 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52335) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk0-0007s5-1E for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjy-0002Yl-VX for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:51 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:34914) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjy-0002Rc-NL for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:50 -0500 Received: by mail-wr1-x444.google.com with SMTP id 96so10114969wrb.2 for ; Sun, 23 Dec 2018 12:52:49 -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=S9Z96Jun/qXlVlruSUttW+xrZVG697H3Ng16fR66cQY=; b=laVMAF6uFQfojHaSDJtMzG/4lBOceN3WC7rVTS0KTQUn+57dUNTkxuGZM7kjcJ3E3U BI/ws336GNDVSVaZQWx9+dkyS5KZREHbYfEIcET2t2sEyvl+/QlRwjyev/Ru/BjyTJ+2 xUDTYUE2tA22t3C4m6Vo19qLcExUOWx22fhTWYkZGFHrh8+GHUAld4B0m6X1cyLALflU tlks/TQ2GECBOAosBAPoah0ufCqAeV10ywlBr1pNgjFtG3YAkI15xDfDUEFq5+5atiDx VSun3o994gC+P2pe/vIK5IZZXtLD7JdCQC8bxpy0CQm8moH4k32RwuUdT6NEPwn3xpcL vOfA== 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=S9Z96Jun/qXlVlruSUttW+xrZVG697H3Ng16fR66cQY=; b=abeaJ0/rprcK4ZKDeXQl80jVT3amnou/i0Y1H4rE6bIXCY1K4Y/p2loEM4LWyC7wK5 1YUScQSO1Esbh5g4gVKF7t0Aq79O0e0q98eNMNIbYnENohk67k1YnRzW9/OmZ/xI4zxx t3fyXccqQcsF/Sd1V7sbD/M0Pm0egjfpnSblk2RJFtoztJhtLzfXJM3MuCvqR3PgHQxf mE6J/hZADuTLiqF6gvogmK/GIuogRWR5qWpVLcqy2hblUwfG06g1WSyWCkris0ufQ6+2 GJHvY6deYWnTCExNuz3ul9ONWE0smez26k3G56CiMFysLWNLJoBa7kvEZZ09OrR4ykDj EF6g== X-Gm-Message-State: AJcUukfunDe00OMTS1FujC5C+ugD/j/V0ChbXoSWSirbd7+aXjHFS7SQ GcPBcITjRO5qjTsH4/O1xBZ84VAhCik= X-Google-Smtp-Source: ALg8bN7OIK/KhLlHbped3fItPJIBVKsmHkHCWV/7x+cPyQnTta64ErXUTHu7WdKGFXJV3b8VGdC+Eg== X-Received: by 2002:adf:9382:: with SMTP id 2mr9449376wrp.269.1545598368490; Sun, 23 Dec 2018 12:52:48 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:48 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:58 +0100 Message-Id: <97534e3bc9bd0df88c76193de6cf0530c8210c5f.1545598229.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 v2 22/52] 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 21ffbf7f6e..fa867a8065 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 Sun Dec 23 20:51:59 2018 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: 10741881 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 EC52F924 for ; Sun, 23 Dec 2018 21:27:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D817A28787 for ; Sun, 23 Dec 2018 21:27:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CC00128790; Sun, 23 Dec 2018 21:27:09 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 39F7528787 for ; Sun, 23 Dec 2018 21:27:08 +0000 (UTC) Received: from localhost ([127.0.0.1]:59964 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBH9-0007xZ-Ds for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:27:07 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52407) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk3-00080V-Ch for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjz-0002cJ-Vd for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:55 -0500 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]:42044) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjz-0002YF-IV for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:51 -0500 Received: by mail-wr1-x429.google.com with SMTP id q18so10090137wrx.9 for ; Sun, 23 Dec 2018 12:52: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=p9NiquY01cLMU9G1IsJj/cvIfw9GLMYq+Qxn35fvl+U=; b=YShX1rm3FttV5YZnFbgsELQvyXAhw88OVAWO6hKmZYaDoH1ejKrcKyYCjffONETw7O Sg8p3QGkFKhrr8zG0BerZRw/03Uw3n1D38s2gTBulZMSgj26OkJAIJ50N9FZJ79HmaiS ycPjpE0w+DME9ZXyzs595is3y78/bbCMUvIB+QpP/spN0QRj5ZbwxXq7M4TfbW7YiT21 93UK3eREmNz4InjcxWcnjKsnH7bz2jl/59chdteqUqYVIOyvh+bhm+A8ByodYZpSlSGI NifjMLjjGwZUfRjnyu9lPoB05i1XY+RLJOWHGf/zFMhq6o2hihCC0V0BrsL74MlSGWWp U9XA== 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=p9NiquY01cLMU9G1IsJj/cvIfw9GLMYq+Qxn35fvl+U=; b=ZQ/c2+RFaYor7d/+A5ntCr4EhyST3F7FhA7JWfFYwAEHrCXrYynB6e+XgpzBZr4ui6 VfLlQg7YU3cNotWpVIfWUJYHvnQ9MJyRsqc1fHiv7LehBhR6WAzPoTiGMWtJ3cyyk326 quwKBMJ6nU6BiVJ5YDatVCsfJO8PAA4B91SdL+hBXv9aP8GIK/LOnqSNIpHJV5gkGV+S wBqNWrEDiPH9/JERz0CV58x1K6kpDFb3CAWfoqKk2gT2ItkGNCLZ+XKXP8e4S6lIEWhe 4SmDqmGSbhCAMTskHX3OH7IdnR+XgVmhfRZjHkC7gsJ+d4koDfIBxOfgODWAZboWPKqi PrUA== X-Gm-Message-State: AJcUukfkuo9gBYHLe1j3BkvgG/D2ozKOI0qx8RT8qKCdbBK9Qq3hES4/ SA61qIpTsdTGkEpiLcgHx9jPEbFP77A= X-Google-Smtp-Source: ALg8bN63e2r8yKsCNVxzWo5ER0A1GQGb1RAOX9cAJR3o6IN1kKfHwf+ZB29Y/31qmu+PRLGfrLpvpA== X-Received: by 2002:adf:c846:: with SMTP id e6mr9282608wrh.243.1545598369395; Sun, 23 Dec 2018 12:52:49 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:49 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:51:59 +0100 Message-Id: <11a6562f583531e5a5473716bea44ee3ae7be120.1545598229.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::429 Subject: [Qemu-devel] [PATCH v2 23/52] 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 --- Changes from v1: * removed audio_MIN, audio_MAX macros --- audio/alsaaudio.c | 6 +++--- audio/audio.c | 20 ++++++++++---------- audio/audio.h | 17 ----------------- 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/alsaaudio.c b/audio/alsaaudio.c index 6f75644538..d4bb540cb9 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -642,7 +642,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) { @@ -705,7 +705,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); @@ -923,7 +923,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 a7f79f3929..a32b86a813 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -537,7 +537,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; @@ -557,14 +557,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); @@ -618,7 +618,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; @@ -666,7 +666,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; } } @@ -729,7 +729,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); @@ -741,7 +741,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; } @@ -1033,7 +1033,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; @@ -1051,7 +1051,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); } @@ -1207,7 +1207,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/audio.h b/audio/audio.h index ccfef9e10a..bcbe56d639 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -148,23 +148,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/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 f1eb048d80..299ba3d09c 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 83ff1d2ebd..ae06e58d13 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -388,7 +388,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); @@ -437,7 +437,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); @@ -456,7 +456,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 fa867a8065..6ed12851c0 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 c86fd91f98..13337b9b08 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 Sun Dec 23 20:52:00 2018 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: 10741859 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 79E236C5 for ; Sun, 23 Dec 2018 21:19:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6785D286E6 for ; Sun, 23 Dec 2018 21:19:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5798928783; Sun, 23 Dec 2018 21:19: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9ACC5286E6 for ; Sun, 23 Dec 2018 21:19:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:59873 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB9v-0006Zf-8A for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:19:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52359) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk0-0007tg-QP for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAjz-0002bb-Oy for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:52 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:45127) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAjz-0002Ya-Gy for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:51 -0500 Received: by mail-wr1-x442.google.com with SMTP id t6so10090887wrr.12 for ; Sun, 23 Dec 2018 12:52: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=YPuNGIRKm2jxLFFPWotlUp4dlUU0csmb5qDX1UMMr1I=; b=SrUHEwVJ8efc6/fVH62qEE8UD0O9OSwS1bXcfNgsYX82Ea+3RfZhdEInQB0qH35Rqi MJI+yGMmAIjdX0ej0WzuUWGZogP7MrDAnSZofEg24yZ0ko5Ees9/M9pwfmIc/im4JEBq 6IT+EXECvRE0+r+PJHxPVNPU0I/cgSwZ5Bz2AalZRU5h5ezGBKtrTrULPjdi3WPiaHs1 XB8vwG4dR0Np0fSYVwUB24fwRJd5au1XLdOWFhrlrboHiULywfVAWlJkTe7RK/V7FII7 6CqWcfy6au+nCnS7NRav0ecFj1G/dYy1KFhnOLfLXMM9Vi8+qePVmhCWvLBZvPiew4i9 7RBA== 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=YPuNGIRKm2jxLFFPWotlUp4dlUU0csmb5qDX1UMMr1I=; b=idSL3Rn7E+KUMv7F/ob/TGq/jczMeDUS/lHu8tDr36QQ/LSJM7cgLDgjjN9R2y1AEO F2TJnPWqArmTu5R0uzHthQA9Ul0hvb7hRAoKPKWPO1s6gEUtoHpluvmZvNNz9vNjWhWh 5ojSRddZTg3ebZtlN2qNJMlu27Em3oUp2o8cX7cOY1a/krKhcEEIe/me5Qrhzj+jFBz6 kU9GCq+kCYh36aFBdrHbnwVT0bAOfW5hKAe6fU+XWi5ihY7oQIkkBgntLP6gpcfLg/O0 RhPBF3NM1l0ujC5Jgh7mPcLKGAFpk00yzp7iJ3JRDVd87ieApgYVdq+Sg1r8+iWplJUo Ibgg== X-Gm-Message-State: AJcUukfMkyglFn9yhpIb5Fi8XAVx/pYru/MLHWACIm4CABvRTzaOkH5R cBeir39/9G63hpVEd1r7XdUSGgSZgyI= X-Google-Smtp-Source: ALg8bN4CzSSXGCzZmc0O76C/KkpUdRGTRCXR7J4/KHTM4haO0ozlommwgHoLjrKKwqnaqEF5Ffaalg== X-Received: by 2002:adf:93e2:: with SMTP id 89mr10073781wrp.129.1545598370033; Sun, 23 Dec 2018 12:52:50 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:49 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52: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::442 Subject: [Qemu-devel] [PATCH v2 24/52] 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/alsaaudio.c | 7 +++++-- audio/audio.c | 14 +++++--------- audio/audio_int.h | 2 +- audio/ossaudio.c | 12 ++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index d4bb540cb9..ffc6220d7a 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -39,6 +39,7 @@ struct pollhlp { struct pollfd *pfds; int count; int mask; + AudioState *s; }; typedef struct ALSAVoiceOut { @@ -199,11 +200,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: @@ -757,6 +758,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; @@ -858,6 +860,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 a32b86a813..4779061859 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -839,7 +839,7 @@ static void audio_timer (void *opaque) } s->timer_last = now; - audio_run("timer"); + audio_run(s, "timer"); audio_reset_timer(s); } @@ -1241,15 +1241,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/audio_int.h b/audio/audio_int.h index 9d9db8c270..9950cea869 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/ossaudio.c b/audio/ossaudio.c index ae06e58d13..fde62c8ce2 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -110,28 +110,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 Sun Dec 23 20:52:01 2018 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: 10741901 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 152BD6C2 for ; Sun, 23 Dec 2018 21:38:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 046272877F for ; Sun, 23 Dec 2018 21:38:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC21128793; Sun, 23 Dec 2018 21:38:19 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9D34B2877F for ; Sun, 23 Dec 2018 21:38:19 +0000 (UTC) Received: from localhost ([127.0.0.1]:60086 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBRy-0002Nd-UA for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:38:18 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52368) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk1-0007v7-As for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk0-0002e9-C4 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:53 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:55631) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk0-0002b5-4I for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:52 -0500 Received: by mail-wm1-x341.google.com with SMTP id y139so9809490wmc.5 for ; Sun, 23 Dec 2018 12:52: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=DhsP1IZYKezBoWf9kL+ulOkH8CQ0XIepreTWbDHpa6k=; b=JYz907P8/OBdq4p0Eu2l9yKC8yYazS+zxLMFBLbW/33cu5U3QnvtdJAqRrGYu2VM/6 1bWwQVBba/HpWI6gQ97WdSMKHarj80/yIk47c9QZWM2TiCYqTgtp3WpU9FR3y9qw2s0Y NvMlpZVQJwVXBLnVhzcBdR4ULcaN3F05DOVY2NhhvjNowid2SLtTYV63sK7ix4GNRBRm QxrGTL7wWiXhf48uCTFvtiwq21EIY4Zaq5mYgLq4vqMEDtK62Lqb31kJOjPnWFmdCZ8v WVhf4LhG+ctjzdrXL5AwjHuGmX7ueAON+jLGw2diEPJuqf1TA/hv+p8EVhji5fmoeR8l 9TQg== 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=DhsP1IZYKezBoWf9kL+ulOkH8CQ0XIepreTWbDHpa6k=; b=kAvdyBO5uRKyZaMyKmQsJiHC+1jqHrwpqeh4JHZvz6UjaNoVxUHfoln/nnXumzUpwm e82XJIcHgjLTa9yVJiXt8e7fxe/3bVDDbsquTF4om14IoM78aVXkhTpLfrvaDJmS4cS3 dm9XGGMNa5kU+Fse+tF2ie/NmvUtFCbDXT84k5gku7+nN2YDXcs6PO7xxYsddacxImxm HVa89OCfHyogQoIipp0JolKEmUDg7lm4F/046ww4y2lfMgzfHC5SvTCh8H598cdu9SwA Fo52dKysoKitxhvk4i8aXIHp1TLtFbkBcIp+zxi9xbK2EvjrJ1eSjs3AFpI+WjEOWuka poAA== X-Gm-Message-State: AA+aEWaA30E/kScQTGOuTJk9x4dibzFjaYMXoHdH/J87LIa3YCeCUrN5 OSrLflAANnBa4sznuB45DcpAC+atOUQ= X-Google-Smtp-Source: ALg8bN5XVabu9Nix+tE/Kmv6OykYErE+3qnEY0TQXsmhteh62mcqZNMXxV/KfexjLV2Wt166KZ7+lw== X-Received: by 2002:a1c:3d44:: with SMTP id k65mr9831278wma.76.1545598370968; Sun, 23 Dec 2018 12:52:50 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:50 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:01 +0100 Message-Id: <69db519bda51135da1fe3e379586c98756be3a1c.1545598229.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 v2 25/52] 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 6ed12851c0..9331e630d1 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 Sun Dec 23 20:52:02 2018 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: 10741831 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 5527D91E for ; Sun, 23 Dec 2018 21:09:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 441E226CFF for ; Sun, 23 Dec 2018 21:09:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3614F2847A; Sun, 23 Dec 2018 21:09: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 97EAD26CFF for ; Sun, 23 Dec 2018 21:09:07 +0000 (UTC) Received: from localhost ([127.0.0.1]:59775 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAzi-0003vd-QU for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:09:06 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52404) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk3-000802-7l for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk1-0002hj-9s for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:55 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:39162) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk0-0002eK-UG for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:53 -0500 Received: by mail-wr1-x443.google.com with SMTP id t27so10104042wra.6 for ; Sun, 23 Dec 2018 12:52: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=SjH7HR9+yRzPtD3exZCY7X78mVj8MVzYWYna83NV+ng=; b=ZjV3hThSsnkWG28t3kjr5281xQB6yV6xRsFLqoC48YjrvJOaQ/AqfB0Wtc85K9fz7H dp2/bYgIwPmMm+TsIL/qzOzSMZVxct+W53UqMpQwhXjJwomKxJdfqTke88X3gCaZNbbh +KxnG9DseUDcGcayQG2Wg402DU+55VFyPZP8bELnPUz7DG9Lhk6mk2/S4+VCocBK3MYa iP5e1FTy9i7/K1eFmwAcCE7Prkl8ZcEqpQMQkISjbfDCVP4msoy4iLulHkg7qx9rX9wl ND5B297Hy1qVs5qg5KgKbw2HeqcAfDbp3Fw0PM2k9vpmXpGacM/XMdbjHNkLSzzcPgYG UOkQ== 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=SjH7HR9+yRzPtD3exZCY7X78mVj8MVzYWYna83NV+ng=; b=M/C8jY6nuvA00Vj1Cv2Te/ZgOPJRMZ/Vnub/q1KN+Sf1OaNicklUU3mdUPVtxl3+12 gadODQzcQbuyqUad1PTYm2ztpC4KCfn+KRjKV8rF9mVx3wi+0qeUyK1TB0nxsk3qzC9r RANlNocPfKw6ky4K/xWu63zIJdSaXZXetnBakbJzcxQ5RLfwxIOfmGYKOXPZJG/fqMCc a/GyhZuBjHmTiy2PjElJe7Zym2fCwkTVpHZKQKx0wDds7jEJeBDTNrvbgOwNR0OkFb6q 989mW0OUfRjGVxBck1DOCWNXwbjAGY9xQgDRZs6eVgwhtvBCMHGhTA8TS7hpGfpi5Csj Ws5w== X-Gm-Message-State: AJcUukdV94Xqr6hUOIzNyqfq6qpxA8oUTo5oM3DZEgH21+CEic9ELDTb R1Luv2O7aXQ6RBSnDZQNsTNNzIiDCps= X-Google-Smtp-Source: ALg8bN4G3HxyyJGJgffpFn4ri9RP/XHGXPp8+ajX6SSV8SxP4W8+1Z0IY+CQqZaBBJKKTJr3FXCoGQ== X-Received: by 2002:a5d:56d2:: with SMTP id m18mr10227465wrw.113.1545598371735; Sun, 23 Dec 2018 12:52:51 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:51 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:02 +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 v2 26/52] 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/alsaaudio.c | 12 ------------ audio/audio.c | 8 ++++---- audio/audio_int.h | 5 ----- 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/alsaaudio.c b/audio/alsaaudio.c index ffc6220d7a..19de7d01cb 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -270,11 +270,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) { @@ -996,11 +991,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; @@ -1070,13 +1060,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 4779061859..1ea80ba6a7 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -598,7 +598,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; @@ -700,7 +700,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; @@ -858,7 +858,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) @@ -873,7 +873,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/audio_int.h b/audio/audio_int.h index 9950cea869..d269c38465 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/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 299ba3d09c..c49f2df4b3 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 fde62c8ce2..70909e5696 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -134,11 +134,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) { @@ -788,11 +783,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; @@ -844,13 +834,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 9331e630d1..6a1919e93b 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; @@ -975,13 +965,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 Sun Dec 23 20:52:03 2018 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: 10741847 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 66C4B13A4 for ; Sun, 23 Dec 2018 21:15:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FCA428787 for ; Sun, 23 Dec 2018 21:15:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D9002877F; Sun, 23 Dec 2018 21:15: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7FF2B2877F for ; Sun, 23 Dec 2018 21:15:36 +0000 (UTC) Received: from localhost ([127.0.0.1]:59838 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB5x-00032v-LX for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:15:33 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52444) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk6-00086s-2C for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk2-0002oF-Ne for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:57 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:51806) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk2-0002k9-D3 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:54 -0500 Received: by mail-wm1-x343.google.com with SMTP id b11so9877281wmj.1 for ; Sun, 23 Dec 2018 12:52: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=VWVc0dBC+d+cr2gfhMfyWcpXiNEMsPSh3kWaTs5Eqp8=; b=OeDgWJmMHDK6y4adA44XBf+iZy2kfjw/rfBgTZC1SCV/juPCz+r2d4igmbKfSuGyvn mJPkmxsoC+2M9boVx9LkRjV4JRe5p/iQzViexjJ4F/yBmWTNRuIi3edK/kzNGzk8uodj 0cp4leAMZBtA9hFa7zLg9rDa8a5/oi6V6LZ0M/YiQdxTAcIUGhYPq9a5z5jL1edUmKMk pkU+ErZnagyR8shn0G72OY2TMPJXzJkWnsgFJmMWFkJ1cBpO3zH5wA0nAI9v4PfhMlKi +zzuQ3Az6OWnpJK6FyLgPXRdgQXw1lV7BkGLtRbXCvh0aThZGjeKgX/1bxkVqMNmDcJZ Euww== 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=VWVc0dBC+d+cr2gfhMfyWcpXiNEMsPSh3kWaTs5Eqp8=; b=Yb4DUmLCKDnhtnAdIRlkuy8NN2I4Khsn/TFrWk8VOFIlvgRLVnSKS6YjRacgKe00bO djf+fnpOz4ZNphyb/BDUG0QUEecPGEe6ysHsabsAEKIG7gmL61u5cc/YV8GQyNnVrFQF 98b1cMhezWiVfJ6MC5OlAx7Ntwt5rBPInZ49EziJqf3RU5ZKumUSrS9w3PEoAUoiRkXH KLJcutzH0PUu8rcIJ6+jnHOzoGsuEN/JnYGgCAlJ2oA9+g6EdJfYS8uzAmj2gI6wLH7i pgUWLQkS5JJz3cQgfzgv+OVorYeixHcMO5/Szf40gfNCRO95FhmByB4MXpCe/FJiEMvD vitQ== X-Gm-Message-State: AA+aEWZZeJpIllY0rZMqoiG1c0VP2PxLnncaJfT147/vBWjf4BlTiT7r O6x+5hpvhbKaVZlVctyaZsDU5EaKfj8= X-Google-Smtp-Source: AFSGD/XgVLGJNXoemlSvDhge2kWmGQVfOEK5m2auozfBONGXIn0bCPSVQ5F6gogp/XKMJPSkghs5OQ== X-Received: by 2002:a1c:282:: with SMTP id 124mr9815043wmc.113.1545598372556; Sun, 23 Dec 2018 12:52:52 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:52 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:03 +0100 Message-Id: <5f0cba98be3d59c4f1d6118b0554429f9e7b3ceb.1545598229.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 v2 27/52] 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 --- audio/alsaaudio.c | 8 +- audio/audio.c | 162 ++++++++++++++++++++-------------------- audio/audio.h | 4 +- audio/audio_int.h | 22 +++--- audio/audio_template.h | 6 +- audio/mixeng.h | 11 ++- audio/ossaudio.c | 18 ++--- audio/paaudio.c | 8 +- audio/rate_template.h | 2 +- audio/sdlaudio.c | 3 +- audio/wavaudio.c | 4 +- include/sysemu/replay.h | 4 +- replay/replay-audio.c | 16 ++-- 13 files changed, 133 insertions(+), 135 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 19de7d01cb..69e7a3868c 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -747,8 +747,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; } @@ -849,8 +849,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; } diff --git a/audio/audio.c b/audio/audio.c index 1ea80ba6a7..27a8a31a64 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -530,10 +530,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) { @@ -543,28 +543,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); @@ -578,14 +578,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; } @@ -598,17 +598,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; } @@ -622,9 +622,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; } @@ -633,11 +633,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; @@ -658,10 +653,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) { @@ -675,9 +670,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); @@ -686,10 +681,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; @@ -700,10 +695,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; @@ -712,8 +707,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; } @@ -767,7 +762,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, @@ -846,7 +841,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 */ @@ -861,7 +856,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 */ @@ -970,17 +965,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; } @@ -993,9 +988,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; @@ -1003,8 +998,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; } @@ -1019,9 +1014,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; @@ -1032,17 +1028,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; @@ -1051,9 +1047,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) @@ -1062,16 +1058,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; } @@ -1106,13 +1102,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) { @@ -1127,8 +1123,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; } @@ -1168,7 +1164,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); @@ -1183,7 +1179,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) { @@ -1199,15 +1195,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; @@ -1230,8 +1226,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; } @@ -1570,8 +1566,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; } @@ -1580,7 +1576,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/audio.h b/audio/audio.h index bcbe56d639..bfb12e7531 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -114,7 +114,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); @@ -135,7 +135,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 d269c38465..330c465d0b 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; @@ -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..fecbf1a046 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -79,8 +79,8 @@ static int 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); + dolog("Could not allocate " NAME " buffer (%zu samples)\n", + hw->samples); return -1; } @@ -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; } diff --git a/audio/mixeng.h b/audio/mixeng.h index b53a5ef99a..2c09ed41e7 100644 --- a/audio/mixeng.h +++ b/audio/mixeng.h @@ -25,6 +25,8 @@ #ifndef QEMU_MIXENG_H #define QEMU_MIXENG_H +#include + #ifdef FLOAT_MIXENG typedef float mixeng_real; struct mixeng_volume { int mute; mixeng_real r; mixeng_real l; }; @@ -33,6 +35,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 +44,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/ossaudio.c b/audio/ossaudio.c index 70909e5696..05c7d6f85c 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -476,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 { @@ -543,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; @@ -568,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); } } } @@ -581,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 ); @@ -693,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; } diff --git a/audio/paaudio.c b/audio/paaudio.c index 6a1919e93b..251b087a74 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -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/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/audio/sdlaudio.c b/audio/sdlaudio.c index ab9166d054..92da4804c6 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -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; } diff --git a/audio/wavaudio.c b/audio/wavaudio.c index dda6993fb9..58300663ff 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -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/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/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(); From patchwork Sun Dec 23 20:52:04 2018 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: 10741861 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 E54141822 for ; Sun, 23 Dec 2018 21:19:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D33B3286E6 for ; Sun, 23 Dec 2018 21:19:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C767C28783; Sun, 23 Dec 2018 21:19: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 022D7286E6 for ; Sun, 23 Dec 2018 21:19:52 +0000 (UTC) Received: from localhost ([127.0.0.1]:59877 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBA6-0006ks-5j for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:19:50 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52423) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk4-00083O-Oo for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk2-0002p4-UB for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:56 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:36147) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk2-0002l4-Kp for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:54 -0500 Received: by mail-wm1-x342.google.com with SMTP id p6so10418101wmc.1 for ; Sun, 23 Dec 2018 12:52: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=Xx8jsSimDtCrlyE22EoFoyLHbKim9wAP8S82IzGMhm0=; b=GxpxeYAqRjukJkin9yYx6jB/cLQHSbGspFKgHVTLVu3IzJhZ8M4S9GLNtPlAWMIezP 8UKApOfEjNfSM7kQxtqgP2MwZHhMLeer4qzeVZa76jbclQtc2wM1xllmrzvYcYjz7GxK X/B34Td4sc0f20cgWtXY8MlMBP1ziioO+iE4y1S9Osz63whm7PnQu6tsGSw4zGvv1awF W4yKYpxH2TscY6EEUh6qvAOiwT8WBhei1aT8NiJ0urG+4hPqmMaGPLgj+YPPY97LMStE cCPXqimFUhZd9YgDGzj8OXhgABIBG9xZihV6lyHxsdYHDdy4qRHgwK9yaBSmqtD4sAhl bkKw== 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=Xx8jsSimDtCrlyE22EoFoyLHbKim9wAP8S82IzGMhm0=; b=VWF9CKEnzT2fe0CFRSykwS83UEWJCWxDzIzkGxzw+qyC1ERMnJi0nD7eMiPAGl+NCh 93S0iM+7IOrXdZcgEtXvfTu1YS5X1ss6BG9Y3XYs0Bk9HC18jE+7TLEy/KLJcHj/RMtT d7BnTSpRJfRWn23VoJtIQbQH8EfpVg9uDM/7oSznVQ7cNXCoQESPzx1hRIeGvKmNmA4Q fx+Kx3BxdFqw+fvvtuRxQJSKVlX8U8qX63lXrvvbvSRvcptdiXX+JzFC7q3DYJjA44Fu Mo/z73DRZI4RmqXVVctwAw9ifv35afltzgxZejcwZ3JCNfveaT5GmwT2fTj5riih9qKv NYWw== X-Gm-Message-State: AJcUukf4vIL91zHQbzEhbp/KPMbFt/DKAFpHgXl/yEcmHTfR1k1I9SFA l3/D1h8eMGDxVItvqKcx6GQEbCdLn2M= X-Google-Smtp-Source: ALg8bN6KO4bvW23iPcW3LYKle/rebSFK7I6dmoeg2MyYdQOuRXK+2PePadkCxnZZgs6yhha3Mp8Avg== X-Received: by 2002:a1c:8d49:: with SMTP id p70mr10749336wmd.68.1545598373273; Sun, 23 Dec 2018 12:52:53 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:52 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:04 +0100 Message-Id: <59bee9fad02c04c6600eba20dafb0c4cd1b31007.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 28/52] 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.c | 211 ++++++++++++++++++++++++++++++++++++++++- audio/audio_int.h | 45 +++++++-- audio/audio_template.h | 1 + 3 files changed, 247 insertions(+), 10 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 27a8a31a64..1897e22444 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -575,6 +575,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) */ @@ -1052,6 +1071,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; @@ -1099,7 +1143,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", @@ -1158,6 +1206,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; @@ -1167,7 +1244,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); @@ -1261,12 +1343,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; diff --git a/audio/audio_int.h b/audio/audio_int.h index 330c465d0b..5c361d9451 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 (*run_out) (HWVoiceOut *hw, int live); - int (*ctl_out) (HWVoiceOut *hw, int cmd, ...); + int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque); + void (*fini_out)(HWVoiceOut *hw); + int (*run_out) (HWVoiceOut *hw, int 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 + * 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 (*run_in) (HWVoiceIn *hw); - int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); + int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); + void (*fini_in) (HWVoiceIn *hw); + int (*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); + 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 fecbf1a046..33cdb66d7f 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; } From patchwork Sun Dec 23 20:52:05 2018 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: 10741867 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 BAD40924 for ; Sun, 23 Dec 2018 21:23:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FF2E28783 for ; Sun, 23 Dec 2018 21:23:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 90D382878E; Sun, 23 Dec 2018 21:23: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CD24D28783 for ; Sun, 23 Dec 2018 21:23:09 +0000 (UTC) Received: from localhost ([127.0.0.1]:59913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBDG-0002et-Pm for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:23:06 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52455) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk6-00086z-Di for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk4-0002wP-Or for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:58 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]:55062) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk3-0002oe-E1 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:56 -0500 Received: by mail-wm1-x334.google.com with SMTP id a62so9861769wmh.4 for ; Sun, 23 Dec 2018 12:52: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=YnnRM/vSQEh9oj5PD+2/CVZbUzS4tMKZkk15FArm3Co=; b=jKs9xNcehpsrXpkztv1Jsw1+Igxl7grexThc3TBE5GXrjfdht2NjdMAxH8x9KIQ/yO zxieLrFESYABw8f5s/09x3SSZh/ZNIc5U4LVW7k0tIbqtjhkV/o/ozm3Rj10wus7oLxu o/DjvFY4NcC3funwsBXiozQc/9XKMysLh9gU+LLjRtiutdS1JRaKEf6Y0kzZt7hDEOYs IJDby9QRx2mdlhS7bPinYtExQFKp2mkgtDTU9ucsoRznAFfBh9hLYjmuhZ762vJNa0LF pLv/kFOujpjnt89oAX2HSejidd/U1xI7MY6zUFnJZQmR9k0KLjo+oyWCa8+KYudxMX2c gn3Q== 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=YnnRM/vSQEh9oj5PD+2/CVZbUzS4tMKZkk15FArm3Co=; b=Qo+TwlrXhj5KyDs5+4/C6p5+TsuIkluS6lryawzD3dYyoMQzces262FW4+a3SBwbk8 RvA06Ij6F13i2PcVgBJc2wZWdjMVmdkns96XAqhSaj25EHbZpfCAEW03A31tWpIELUgB u289GniDgXuZcT/tNEasipXf+ultVldTQ4k0Q0IaX5qFYJZQCX8KSciL4AyHUJTo93o6 LvEQcXhwjbtz4SuQXES6Df/V+2HOFOyQ734cmlwLZXEOmT/yhBIYNbH0aJCUvklq+I7O wSZkuJh9IbwplqoOSVA9dsc2GEKWIsZ/SWK/XXnvVayorR1JL8N3uCN6diLPg1PwYyyM yk2w== X-Gm-Message-State: AJcUukdne9Ts5uXhHUNLg6sNKRC/CJkxliXGf+CKl0m6KvWHhmC/onCg XYi6FHJcdOYUB1xbvWiX7qWWp46lha4= X-Google-Smtp-Source: ALg8bN5A4yrXqHc3y8VFtjfDuotrJiYsBBTBch6itCYYekYAB/y3/ivN3lxGAvEMRX0EPPnS0Urw2A== X-Received: by 2002:a1c:4d12:: with SMTP id o18mr10434226wmh.92.1545598374130; Sun, 23 Dec 2018 12:52:54 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:53 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:05 +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::334 Subject: [Qemu-devel] [PATCH v2 29/52] 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 69e7a3868c..56271b1174 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -44,9 +44,6 @@ struct pollhlp { typedef struct ALSAVoiceOut { HWVoiceOut hw; - int wpos; - int pending; - void *pcm_buf; snd_pcm_t *handle; struct pollhlp pollhlp; Audiodev *dev; @@ -55,7 +52,6 @@ typedef struct ALSAVoiceOut { typedef struct ALSAVoiceIn { HWVoiceIn hw; snd_pcm_t *handle; - void *pcm_buf; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceIn; @@ -610,102 +606,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 int alsa_run_out (HWVoiceOut *hw, int live) +static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; - int 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) @@ -714,9 +670,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, @@ -745,14 +698,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; @@ -847,14 +792,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; @@ -866,129 +803,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 int 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; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; - int decr; - struct { - int add; - int 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, ...) @@ -1059,12 +915,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 Sun Dec 23 20:52:06 2018 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: 10741823 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 CF7AC1399 for ; Sun, 23 Dec 2018 21:06:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEBF328717 for ; Sun, 23 Dec 2018 21:06:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AFBBF2878E; Sun, 23 Dec 2018 21:06:24 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1852F28717 for ; Sun, 23 Dec 2018 21:06:24 +0000 (UTC) Received: from localhost ([127.0.0.1]:59748 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAx5-0000dK-AS for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:06:23 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52463) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk7-00087C-1E for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk4-0002vC-Fw for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:58 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:53888) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk4-0002sC-8r for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:56 -0500 Received: by mail-wm1-x342.google.com with SMTP id d15so9848907wmb.3 for ; Sun, 23 Dec 2018 12:52: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=W2dAba28TjIae0d/Hlsf5eMIrMDV7595+AUWgCdiIDI=; b=HLW1bSlXECowxThxFKI1uzMPIt4oTLuqdpvpb0PR67TJyYTZdf9MlbcInWkK1EFjMD kGRDd3Y7hnmD3FqoDBDAinNmNoTIpQPkgf1aY9eofknSDnisjyQy4ezIqj/8rMydQHTT EJf/70fcZlOhFqJ84wJSQjYIlpWhjHNWxMmS6oXixTlHqLemJCBi1FXFeslH3YgV1lqF 9i9rpAZO4JgtY4bvXBNpCrc/EoPSAxGLYVzs0RT+ZYWl1VU8WXrljqF9k2EufsbDc6MJ hGiSv1xdqSF6dbqDTealE9RkqLkprYp55TKDnG9KsyPSuRSn55RzG49Gx21nmBsOdWF1 m77A== 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=W2dAba28TjIae0d/Hlsf5eMIrMDV7595+AUWgCdiIDI=; b=LzX3Jf8zbmCYv9AIUl5DiNypyQUHTuTFhqwg5qpF8oZhP3bay30N7TUh10Q55f1Nqt M2TEtykrgr4//6TjmgX7g3US7vKXnFcPF4d6BbYCQjSDY3VQdRHEoXtVhQRk47mpUgNM LzxlR93iegAGaPp/f2yHKuEhxPUGm2jzvFWfzWmLiCi9DZT+eH91jiBCg9QQuhVLc4XN aHT4tZcq03yaOlEnTLHREh+lG7qjlwfvjgFvkdUDScKBrqtdErlsykfCDifiZWN7duI7 2CBysV/bAZYhB64VNImH75CKF7cZfIk67c43N/jpscaZaOdQFSlrsJeZ9+PgfTdT5+T0 vK5w== X-Gm-Message-State: AJcUukdk12pdQmUt8GaKKkSmiD0L3mWy2R7sU4g3C98xN+gg8i8NWekq nldtWd/nkvfEfDevEHDi70J7Vv5EX7k= X-Google-Smtp-Source: AFSGD/Viu0SKpj7bb4IRcTBJH+qzBUXP98xGISDS2nHM6cLI539JNMbLD8Cm2zq308az1HpenD56qw== X-Received: by 2002:a1c:7306:: with SMTP id d6mr9761206wmb.98.1545598375049; Sun, 23 Dec 2018 12:52:55 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:54 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:06 +0100 Message-Id: <913694ede1eaa88edbe2be55ed0969f3f14f105d.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 30/52] 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 abbbb45d69..a532e862dd 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -43,9 +43,6 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; - int live; - int decr; - int 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 int coreaudio_run_out (HWVoiceOut *hw, int live) -{ - int 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 *, (HWVocieOut *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 Sun Dec 23 20:52:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 10741829 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 2F69491E for ; Sun, 23 Dec 2018 21:08:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A66026CFF for ; Sun, 23 Dec 2018 21:08:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 07ADC26E98; Sun, 23 Dec 2018 21:08: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 07AC326CFF for ; Sun, 23 Dec 2018 21:08:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:59773 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAzX-0003mC-7Y for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:08:55 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52472) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk7-00087E-KW for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk5-00030O-Nk for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:59 -0500 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:39791) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk5-0002wX-DJ for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:57 -0500 Received: by mail-wm1-x333.google.com with SMTP id f81so10393861wmd.4 for ; Sun, 23 Dec 2018 12:52: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=Ux877SubpN+vMU4fAvA4kT9xqiWB2UQdru4VXjEMgko=; b=ABqABR/Wh7hwdqEE7SK4uLVAiBNoY+Pj3fXqoAv8uRvc+XjjVj3VKKNST+JNl2wo+g aWOHqfSx+ic6BHxq8cDD7zIXU0q8WjbOcPJS7fd3QrestZwv9LI4WeAn79YRzuTC2vKj KJcUy8nN1XWaMwvc+gVEn97wWPNqtDkHB2yOOIGeyhiMMIeZEE/aMYvFqoZFZPytGmVp nIfDg9BdFJcK3MLQ5TYXk6HBDU8juB33Rb2FFJiLeZu1eJCJXSIU4GvkNbG4xVegfuhF jCPeaB/uPRIrV8XnOR8tmlNsNvrH4KigSYKDjbn1clssDj3qcNbkROOenTufvEhADDA9 z4MQ== 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=Ux877SubpN+vMU4fAvA4kT9xqiWB2UQdru4VXjEMgko=; b=c1vkIqVVx7ySSjLQbnktcTg4fjYjyv3ylFMQ2DJYRX3bedCOevrryxR+E1EXJyn8nx H5AbARlglePHTZ7GkPesz09HjvrmgbkI/Qzieo61rGKUItW05YohXNr05Pyv14Wss5mV +oqJeB/hZyFIfMSP7AStGsZEuTyUYu2PoeTL0d52BDcdVCXZ4pbg6Zsn33rIKL7BABcJ wF9hOEagh25H86+hw0Mq1thW7XSOdJwmh8DWD7bdJE689eHStYAoCG6nenZnvrsARS9/ KWLOO1ITnI9jm1uA5I8GzMoJvDnmCrio8B07fpmWdfflv3jV9cgy3VsSCngjQFwoN+AC dQ0w== X-Gm-Message-State: AJcUukeiO4OM24ONrTBpppU2BUTXoG69sHc6bdHwXxy29sGuWEHrg2LS XJi4FSm/BVZzY8gOOSJ9AuPl2p9qCyk= X-Google-Smtp-Source: ALg8bN7NirmIy4jd/Vs15ry4Ejcg1XFDc1r8zAB3v67+ym785g1BmP5RlbTElv9w6VpGVMb0Mw6kqw== X-Received: by 2002:a1c:8c05:: with SMTP id o5mr9574644wmd.29.1545598375909; Sun, 23 Dec 2018 12:52:55 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:55 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:07 +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::333 Subject: [Qemu-devel] [PATCH v2 31/52] 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 --- audio/dsound_template.h | 45 +++--- audio/dsoundaudio.c | 328 ++++++++++------------------------------ 2 files changed, 102 insertions(+), 271 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 dfcb70c81a..7b3266aaf3 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,138 +414,51 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...) return 0; } -static int dsound_run_out (HWVoiceOut *hw, int 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; - int len, hwshift; - DWORD blen1, blen2; - DWORD len1, len2; - DWORD decr; - DWORD wpos, ppos, old_pos; - LPVOID p1, p2; - int 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, ...) @@ -640,96 +513,49 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...) return 0; } -static int 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; + + 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; - int 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) @@ -845,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 Sun Dec 23 20:52:08 2018 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: 10741839 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 04EEF1399 for ; Sun, 23 Dec 2018 21:12:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E86712877F for ; Sun, 23 Dec 2018 21:12:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB3B02878E; Sun, 23 Dec 2018 21:12: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7C8D42877F for ; Sun, 23 Dec 2018 21:12:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:59808 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB39-0007v0-KA for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:12:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk7-00087R-T3 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk5-00031m-Tl for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:58 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:39694) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk5-0002xp-N4 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:57 -0500 Received: by mail-wm1-x341.google.com with SMTP id f81so10393873wmd.4 for ; Sun, 23 Dec 2018 12:52: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=WipQek9x1u13Ko1/oMje1fHohsxHrq2H6frltFwooJw=; b=ahF5pr1tl0T15S13REj6NoTNda/Y/PpAn67m+1hGvmDJnY2PfxNEBzcQ42Ds5qKebu n3IKG3wjckiIiJp58h970v94k8pYsak5X1X21AsCpW+voXxZF4xx0+HrOGoblkQHuv79 N90QcbfevFrY78j+CfsJLqKG5DlrS6AmaVyCuUYeJrmw+TDaiD0jRynzXS0s3s6sTweE GKQONKurXdpg+phzEz1+vNxPHX4H13eNa4PyBYP01wKKyQ6s3SKAEm7EQhV5nKHt1dEv hSRxxQt7nkZX8YPAOltub/oeFmg0C8cij3Qsf3HbteMetQnRVB1TOH4iqq57BEHqm4lU ua/A== 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=WipQek9x1u13Ko1/oMje1fHohsxHrq2H6frltFwooJw=; b=Csf8MXzxzoKjdWFBtzZQ7clJLC1aUDr7ovSsEpiM7R7+Pi8SzkAyrHICQk4iGZahsu K2JWbUt+HA/t2uirwyFgv2FXTZHcE0t0sjaOaDgfaiVGRXgBc4Y7uOhYMcLseZQK+OBa 7i5NDLh43qqLq6MUxPf6+zyRVtQQNFMTKF7j9jLTCeZghbf1hhsmM03uLbkU3T98XnoI e0jGy+fLYM/W08UTpHSCkrslmFF9AeCVTe44uFIwVzaJmwqeluu9+4oSjrXHEdTk00KT RoPTh40SwK3M5zzIbiE5ju9TqtV4V6WMx2dpjV0W7cIr0bgEuNMdUBE0/Ax2ZL9+Tupk MQ8A== X-Gm-Message-State: AJcUukcsSNH/1EVdvot2lgiSmSmBIDcKMmJ7M5wPLWsFlFK2PtDE4osR fn1aM8SiIBv/Mnn6XEVdQyo0pP92lcU= X-Google-Smtp-Source: ALg8bN6NqKYR0lzgMGhbp0vnBgWSq6XGd6g1l8JhsOfBr+bKAIIv5GWbYBSaj8gKGeZZFvfhjCFo3g== X-Received: by 2002:a1c:9dc4:: with SMTP id g187mr93193wme.152.1545598376538; Sun, 23 Dec 2018 12:52:56 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:56 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:08 +0100 Message-Id: <3cdadfc819548ae32d9c90877de7382c391d0371.1545598229.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 v2 32/52] 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 c49f2df4b3..6a3a1c418b 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -40,10 +40,9 @@ typedef struct NoVoiceIn { int64_t old_ticks; } NoVoiceIn; -static int no_run_out (HWVoiceOut *hw, int live) +static size_t no_write(HWVoiceOut *hw, void *buf, size_t len) { NoVoiceOut *no = (NoVoiceOut *) hw; - int decr, samples; int64_t now; int64_t ticks; int64_t bytes; @@ -51,13 +50,9 @@ 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); - 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 int 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; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; - int 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, INT_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 Sun Dec 23 20:52:09 2018 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: 10741855 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 650581399 for ; Sun, 23 Dec 2018 21:18:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 519872877F for ; Sun, 23 Dec 2018 21:18:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 42E782878E; Sun, 23 Dec 2018 21:18: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 60FC52877F for ; Sun, 23 Dec 2018 21:18:22 +0000 (UTC) Received: from localhost ([127.0.0.1]:59871 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB8f-0006Yj-Hs for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:18:21 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52492) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAk8-00087S-GY for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk6-00035P-Sg for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:00 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:51807) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk6-00032o-Lz for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:52:58 -0500 Received: by mail-wm1-x344.google.com with SMTP id b11so9877348wmj.1 for ; Sun, 23 Dec 2018 12:52: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=tpU0Bm4FTnsmP2mJ8E5z3uValeKltimc+tzsriL09v4=; b=IAuWCA9J8ybNL4hkxBurfA1ssdfr7XNEUqYP8N3fOVGC9kCeNuvm9uyxX9ttMxU0Jn L0HkNXSHR3kjeCHrOuO6q9aImMW9CxqI66Y3RGdkrYOQbpBlEK9zCwVjhEycTX3mt+Ba vqMC0LqjtfV533q6FOq08UCmAmRxXeUrxtfm3yfLTsavXhdnRQMUc1WVqhprmbvksCV+ WGx8aO42PJJBgFw8keqKcsaq/pS8xyvrxlSX2gxtmekrQO0e+cNF8sYz/mWAYrV+YVyl zrZzfKhRrLEIN4Isr3n7F0c9VBuknjRsxzn4XBkzn/lSZymknOgCtLjhcQpcUIEStOq7 Cu8Q== 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=tpU0Bm4FTnsmP2mJ8E5z3uValeKltimc+tzsriL09v4=; b=Yrz/4QHUjzxsyy2jmAfEVitRBGmuDvxw98Vu5uM9tQt299s89vlhZxYcS9IFwRFz+b Rmv9m2Do6OIkXCAVt7EYtig1ypMsT3UWNxCS/+l9C5TgZVgCXU5mypQNX/unx4MhtkLg ZYSrgYIS+S5NKhO6yY6l6ef17pH7QzCwQRF5MP/0xGvMjtn/JG4MSLRRRMDTuTd/ZiUR t/G0QwiHUsoby7kRc9Lya8JapFUWMPkyoFQlOXNnHfoWUidfbrCjJZcdFzzOjVrQXv+/ 09F2PTG2tHW510GX6RF/A5hm4JpVC19vrtcWqRvl6rfl8m0ogPIene9ze2d0mdzVF7TR OdHw== X-Gm-Message-State: AJcUukeVNDMShpAloA7qwDOa+Qcmqd2LiDaEkCT16jKK+0N6QNr8VV3u Z0c9ykiwZdAMTkl1pMLDoCnQnup2NYY= X-Google-Smtp-Source: AFSGD/Vs8wXdWYrOQKuejMTk5u5HakcBv0tEp6iC7I3icNB9DV+ZtOfcmwn/aT9T/zE5lbpuaqVq9w== X-Received: by 2002:a1c:81ca:: with SMTP id c193mr10677239wmd.66.1545598377231; Sun, 23 Dec 2018 12:52:57 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:56 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:09 +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::344 Subject: [Qemu-devel] [PATCH v2 33/52] 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 | 287 +++++++++++++++++------------------------------ 1 file changed, 104 insertions(+), 183 deletions(-) diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 05c7d6f85c..f1b57c87b4 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -40,19 +40,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; @@ -371,97 +367,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 int oss_run_out (HWVoiceOut *hw, int live) -{ - OSSVoiceOut *oss = (OSSVoiceOut *) hw; - int err, decr; - struct audio_buf_info abinfo; - struct count_info cntinfo; - int 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 +458,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 +515,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 +548,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 +585,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 +659,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 +670,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 int 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; - int live = audio_pcm_hw_get_live_in (hw); - int dead = hw->samples - live; - size_t read_samples = 0; - struct { - int add; - int 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 %d), " - "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 %d 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, ...) @@ -833,12 +752,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 Sun Dec 23 20:52:10 2018 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: 10741827 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 9EEBB91E for ; Sun, 23 Dec 2018 21:08:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 75B3428717 for ; Sun, 23 Dec 2018 21:08:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4F7092878E; Sun, 23 Dec 2018 21:08: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0898C28717 for ; Sun, 23 Dec 2018 21:08:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:59771 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAzI-0003UB-OO for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:08:40 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkB-0008Da-Ae for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk8-0003E0-UE for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:03 -0500 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:55510) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk8-00035c-Jh for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:00 -0500 Received: by mail-wm1-x32d.google.com with SMTP id y139so9809607wmc.5 for ; Sun, 23 Dec 2018 12:52: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=c/Coow8G0mqpkiOlGU70gKsvP+kyigQWe3fXpD82mw0=; b=fXf34VUC8UbYfoXYUUfIbOAO8Km3VPEKoemHjYF6I0oKFvz1i6lc4OYdnTgMpRT6Lc 623NuXRMqald0WP/F4nBdK3jvCHRIpPztxxSkddYBNoNuePFyCQA+FBPkzluO06ccyXz SRU12ErxBEeDi/coXPFkhVazTxYgTR2Ko76ICIDg5L8EqbSpdNDXRtGnC8qU7fXQqWns EQr7Tf8x8CqFKPa2zLQVnQ4HAOhf75Ns6cb/WZ6XwcJhrIpotEixa75m+/cXlJQnOwNT n6FOlQEv/Zucl3l/LVrja1sS2Iy/aCtEQ/yO8Q28cr5csLEIEaJUNSuHLLDsYs4hey/h q97A== 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=c/Coow8G0mqpkiOlGU70gKsvP+kyigQWe3fXpD82mw0=; b=K3Rh+XpNbKnx41d2asdoq+IYHcylXDCQcAdjeXnjXOa/YuaaELoqRQVL7j7Tzxf4wX qHsGbQkdzRt7nqvM674ULZxRb8gbJtFFc0uuVBmVS0aFjwQ8N5xF97FFFa6i5YSGFzXt HbU3EICZylq7ngTBE+Fw9oQ5DlktpXTz6Nn2F1EA3Lm/ye6zkVcFTw1R/fNV4AMx0UV4 zfa0kTPYHasY7Mv88uFeSYCT0NQfJBv0ve+2rNoY9CYCEH2TcGgZ7l8A0b0gafaeBBxG Xlifr+fsbVER+dy4vkXO7N10Lvv/SLEDAFFDbHciR9/YvQs3i8+IOdln/12HipXkjTjZ Bh3w== X-Gm-Message-State: AJcUukcYBYQdjbl82eDRU/7B4/Ly7SNMEv63gvNyMBmy9kS9uHA2+FUT qLvKKdUwmFXwGQr5kpwlSwXvVEjknF4= X-Google-Smtp-Source: AFSGD/U+LRC1Gzp2U25FiJZ2tm4q5+0zAsWAbUgcWgEuxDQUbh+F0tfcse2Vj49KwHrjDOdjhXstOg== X-Received: by 2002:a1c:5656:: with SMTP id k83mr10180590wmb.125.1545598377944; Sun, 23 Dec 2018 12:52:57 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:57 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:10 +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::32d Subject: [Qemu-devel] [PATCH v2 34/52] 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 --- audio/Makefile.objs | 1 - audio/audio_pt_int.c | 174 -------------------- audio/audio_pt_int.h | 22 --- audio/paaudio.c | 372 ++++++------------------------------------- configure | 5 - 5 files changed, 45 insertions(+), 529 deletions(-) delete mode 100644 audio/audio_pt_int.c delete mode 100644 audio/audio_pt_int.h 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 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/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/paaudio.c b/audio/paaudio.c index 251b087a74..392225c875 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; - int done; - int live; - int decr; - int rpos; pa_stream *stream; - void *pcm_buf; - struct audio_pt pt; paaudio *g; int samples; } PAVoiceOut; typedef struct { HWVoiceIn hw; - int done; - int dead; - int incr; - int 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; int 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 (;;) { - int 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; - int 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 int qpa_run_out (HWVoiceOut *hw, int live) -{ - int 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 (;;) { - int 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; - int 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 int qpa_run_in (HWVoiceIn *hw) -{ - int 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, ...) @@ -964,12 +682,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/configure b/configure index 224d3071ac..872a5efb3b 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" @@ -3339,7 +3338,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) @@ -6304,9 +6302,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 From patchwork Sun Dec 23 20:52:11 2018 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: 10741821 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 CD08A91E for ; Sun, 23 Dec 2018 21:06:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B55D228717 for ; Sun, 23 Dec 2018 21:06:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A657E2878E; Sun, 23 Dec 2018 21:06: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1B0EC28717 for ; Sun, 23 Dec 2018 21:06:06 +0000 (UTC) Received: from localhost ([127.0.0.1]:59744 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAwk-0000dH-79 for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:06:02 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52523) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkA-0008B0-8K for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk9-0003Ei-3M for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:02 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:54758) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk8-000376-Sz for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: by mail-wm1-x342.google.com with SMTP id a62so9861848wmh.4 for ; Sun, 23 Dec 2018 12:52: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=ft3EHNJylWfz7qh/YSL81ihyTJc8DQwGj3ZZ2/uBCGQ=; b=eU1uiGAvj0igtY0s9qqPRHnigD87DafQ5y3i19ioZa4YNgNrzIJKecVgOo4eMs9Nwt w6/d1Mm9dXCffmA+xtBo54wAB8pTVZowrjAgoliy8NXL9ircFu4wphmLj46wb9aCsVXN /wQvab490VKUzGQ0YFRlBnHteMTRodzZq3OBQyzQ644aptfBpEu10x4i2sX0Jc0zCJ5H eQ/n/a4o7tlYTjRPJOG56dhT0NV/799zk6L1vKzLVxYXxGZ36QrKfa+so5tWDo+dqtLU ViM0lCEtq4w4ZOdKB07/XEdbFU2Mn6Ifd96fNDnCpOjNqGZt+4XqD2FiCe7GTt+lMzgx t8dw== 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=ft3EHNJylWfz7qh/YSL81ihyTJc8DQwGj3ZZ2/uBCGQ=; b=GQhJeI5ae2eChNGRGqzohAO3gg07C8GyjAQAM4L5+3yqKtBGgAdp2ZSEzW0t9SmM0E D/9S7prvYYg/Cl3p6uH3KXEXTTLiepTQh9p43iKqhYSy6ZIJc1GgJkYmA43W2REyOVrA F1ftfHB0LYFxNbz0G7CGvoAlxXxjLHQ74f2Oc+sPkxmoj/6pcaXcPvbHVafrXck2gtPH j4Orm3NAVuW7LS4SbSyDrm0Q2G6ANBuAyoWaxVxDfKwnf/TmXdMh6LQjQUGZTEnDs8qr V/C3WXuUJeRVbUGC3sySxitI4wbIZPSq/7B1V0+21pdhgsLFwDG0GxV40ITCwXLIcVUs T0Tw== X-Gm-Message-State: AA+aEWYy9v3GIASrFeGlw8F912GF7XNIZFNaVi+9ehywylWO1CzpATJk 2Fk+HTDvuJmtIPNCYkGOz1iOKiy1ekc= X-Google-Smtp-Source: ALg8bN7fcNZj+tRyzPXpFBpwWSmsXrb55YzgA+GzsMkHeVhsdTrRZSYIFLpijF+yLkVADwr6eTi30g== X-Received: by 2002:a1c:b456:: with SMTP id d83mr10563643wmf.115.1545598378631; Sun, 23 Dec 2018 12:52:58 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:58 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:11 +0100 Message-Id: <8b28b74150934d42fef0b2e4b9d19b60700a686e.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 35/52] 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 92da4804c6..685cbc83b8 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -42,11 +42,6 @@ typedef struct SDLVoiceOut { HWVoiceOut hw; - int live; -#if USE_SEMAPHORE - int rpos; -#endif - int 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; - int samples = len >> hw->info.shift; if (s->exit) { return; } - while (samples) { - int 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) { - int 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 int sdl_run_out (HWVoiceOut *hw, int live) -{ - int 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 Sun Dec 23 20:52:12 2018 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: 10741865 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 9F06A924 for ; Sun, 23 Dec 2018 21:21:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8B32928787 for ; Sun, 23 Dec 2018 21:21:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7AE0528783; Sun, 23 Dec 2018 21:21: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E045028783 for ; Sun, 23 Dec 2018 21:21:12 +0000 (UTC) Received: from localhost ([127.0.0.1]:59905 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBBQ-0001oa-3G for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:21:12 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkA-0008Ai-1E for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk8-0003DG-O3 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:55633) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk8-0003Ai-Ho for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:00 -0500 Received: by mail-wm1-x343.google.com with SMTP id y139so9809625wmc.5 for ; Sun, 23 Dec 2018 12:53: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=pmc46JkspRIEo+BrQodF3XHgvv8dZ93fB9tiE2Sk9rk=; b=AxbxneCdfAlX+4YtWm+DzbDQViKlaRQl3Cc3bEnN0zLmfXBAa/H/yAAJ8UACFn2+a9 Cp9HlRjWiB/dxh7Jn4e5vxA15wbI9abALX0lvxKO8M9et2A94zPEYT6zEBWuISGkdGdu tO6Rl5VjYwPCH3b/Gw3LYUiVsC3+AC4P3XF8U7UcL2vxBjg409xWqFCL4K/6t7omRjYS kMtvtPE9MDEAIA/hmcAdK/FOf9f2Y4ILzc8hGhSRBWxkGaHU7V7SWEv4egLszcQhVdVk sXEsCOAOUpyvLDrMFWqg6NAB/i0Qpd3XhQ6h0BT6MBcVEtpzbRfd38BfaKkKdjxRcdYW o3cg== 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=pmc46JkspRIEo+BrQodF3XHgvv8dZ93fB9tiE2Sk9rk=; b=VznT5B+11X2EFYMyg3bzZ9rGzp8WYfZdrX3ixVllq6825HXTuNAv0xFVrIq0HM/Iov 8IjGePZKTQrQPOffwxls3M6qwA0M/L2IpcxYepdLPR4Tgc9FUcLkqBxRmYxkpGaMcZ/x T3mQQ+F3K60zCCZP/WBWJgyiRvdn/FHX2sUaZCibq3H6Ciee2IkjkxrpS1h8qrhhh3ZP lF0U6yRPMYV5heNuszDx0naTd7dctrxudDOkpPkhOhXdGx0OBLFaSK7fyYj7fAsKbeQX YYnGk/Vvoyy1V1sePLbhUk7zX0bQjpLt+BXM/Ym4XLI54grdbh6uWIlYJZO4k0LZjuhZ kWCA== X-Gm-Message-State: AA+aEWYokCwVst8iTt1+LPSynBGBlKpkDkOYI0jEw6g3llCRgXLTfFt1 6Ju9j9lRvxncktkzJvVNNZdw03+tDVI= X-Google-Smtp-Source: ALg8bN4lzdPP4As5v2SdF4u0DhcGdbKUnJt/GOF+HwzAnWAMqmrEQIdUP2yQ3uyeeBDmYWxXM/db3w== X-Received: by 2002:a1c:3d44:: with SMTP id k65mr9831454wma.76.1545598379346; Sun, 23 Dec 2018 12:52:59 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:58 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:12 +0100 Message-Id: <645cc4345f9dd8f133fed0c40a91fbfb75944dfb.1545598229.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 v2 36/52] 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 f963853ed8..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 int line_out_run (HWVoiceOut *hw, int live) +static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size) { - SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw); - int rpos, decr; - int 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 int 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); - int num_samples; - int ready; - int 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 Sun Dec 23 20:52:13 2018 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: 10741871 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 56659924 for ; Sun, 23 Dec 2018 21:23:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CAD228249 for ; Sun, 23 Dec 2018 21:23:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2C9AE2839C; Sun, 23 Dec 2018 21:23: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A852628249 for ; Sun, 23 Dec 2018 21:23:55 +0000 (UTC) Received: from localhost ([127.0.0.1]:59943 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBE1-0005F7-UH for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:23:53 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52536) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkA-0008CS-QB for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAk9-0003G0-H4 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:02 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:50633) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAk9-0003DS-A4 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:01 -0500 Received: by mail-wm1-x336.google.com with SMTP id n190so9881731wmd.0 for ; Sun, 23 Dec 2018 12:53: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=toa5Yj8KNOnf+7+Nol6wtf7GLlK5GhyUi/dB0JzrOnM=; b=g1nA6pcWpuNiJGCJa2Mjp2oromVfwe60SMq3zRUhqzjJx/mvWTQgxONY0aF/cxKGEw /gw8xD5hQxdcvKsR95Yhpyaf3jeCuixc92BOmfWyNebHlRl4FNCb/FbRgljkh4AXNJHV PoYjD1q18s6eWc82K02XvcGCYMXkH6x8WNiXs+1FDYM3bYgCEr8ARhG28W8sg+HwrYhV CT0j893+m2LZgVIf9nO2m9XT3j8b1rtQcFHN4yWBA3RcRaSFzrd+BUECs4Uc8ttMp5qu xJvzKJYiBaDy0XtZk23f40bPSwE5bf0089RrYvcHdEZcxwysTxGIvrVVeJr7gKB/g3Z4 4gkQ== 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=toa5Yj8KNOnf+7+Nol6wtf7GLlK5GhyUi/dB0JzrOnM=; b=DOagKrNx7W0sfG5KcafAsaPEXOxiut9Q+aaULAoxX+ARVXtc4d7fA0Lu4EplhrmTA9 TOVoybTV+wpcheCvZsDdNPd1nkorDPec8JbMO4WyHxVXBwcXh5ZhLu2DVHGfLdYoAIhU u2W+eHltY+gBiisyCvEjo050I+wgXGdvHq94yBd41xqNCILPpQxUmDFfxyZxm9FZAb9i Yy472rl4pSDWEdo0P/Wa6BWkFI0z/Z3bEMjKZ/ivrHMN3DVD8ikbdRcoduyR7eDCx6hO MUtZzsy9CuSfAi3E5mu9r0zDmmeXZ2hkgC2IBSlJ4YNrB3kMe3zP+bnAMooSTkDQkJDl 9Cww== X-Gm-Message-State: AA+aEWZZt9OcCtMQIsRrEEggErXGsqLSUQ6yn7/VHMME0DxeVCLUEAJQ 0MpyyA02+lPBkFEv4uINllbedBgyAbg= X-Google-Smtp-Source: AFSGD/WuubybkomXxZBOSHoBa0b4DiQkZNufCylhmJUsT3flPoiiZ58mj3ROHcHw7QHApjCpdZSuaA== X-Received: by 2002:a1c:282:: with SMTP id 124mr9815208wmc.113.1545598380134; Sun, 23 Dec 2018 12:53:00 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.52.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:52:59 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:13 +0100 Message-Id: <4a336338eda1c3f6b8d27003d840373ada76a099.1545598229.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::336 Subject: [Qemu-devel] [PATCH v2 37/52] 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 58300663ff..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 int wav_run_out (HWVoiceOut *hw, int live) +static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; - int 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 Sun Dec 23 20:52:14 2018 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: 10741879 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 40F84924 for ; Sun, 23 Dec 2018 21:26:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D97828787 for ; Sun, 23 Dec 2018 21:26:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F6F628790; Sun, 23 Dec 2018 21:26:11 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 91F1628787 for ; Sun, 23 Dec 2018 21:26:10 +0000 (UTC) Received: from localhost ([127.0.0.1]:59966 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBGC-00082i-DM for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:26:08 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52559) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkB-0008E9-Ff for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkA-0003Iy-BF for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:03 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:34457) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkA-0003Fp-3M for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:02 -0500 Received: by mail-wm1-x344.google.com with SMTP id y185so18070806wmd.1 for ; Sun, 23 Dec 2018 12:53: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=zc+1alpNaFuLeQPioqsoXZwrEtMCV4iO7xr0H+qg9g0=; b=nMaGGlrzdCTiC3LI9ysUZ9uV1QuIFbFatH6WSEbdOnEKouIx1f8fgt8JsWm8+YiB5s quA0rDMEo3lOzkWScOcx5YWifqW+9Vu4IZ40njbS+288YcsTdsNO89xbchBZYJo4wOIV 5vxJVtvW8/6i853zmwQkTQRVewTb0FoC4Qd2Is0XnT73qgxAbtmBgt8zLmqdVtJUBi6/ WHaK3RlWqY0fMA5lE3tRfxOq7S1WvKQfdkG0swPqByh5RTNTmRNANPG+dXkdo4itmFvP D20F7iMArLmIvzfqJSg6EnMRg2A0x+kX0DkzmIGDFU1rELHKaibdgT9ZDNcpKw5a6EIa B4lw== 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=zc+1alpNaFuLeQPioqsoXZwrEtMCV4iO7xr0H+qg9g0=; b=DegoQ/4HXc7Ib9T7At1r0HAPNRa3zUnDU+/ku5SOR7L9UPW8LE64z77GSOsX04cQZH Jj6memA8Q+sNKJrRiTRMe5Ddax1wQTJv9pWFkcYQODfROkUFD9z5sI3gK+VSAaYKexCK LaQW9E0WUaVQkxTAtl/IyFY3cbnrpaGRrHt0mYyV5chjrviOea1in/he5NwIbeqayIi/ iW9eKFoLULxztjll1Eh9yjz8oRHi/MptNbc3YQGM3oK9RySWo3fVk99++2Zr5F7k2/0l V5KWF5LXh/Nx9iAyUvKiEBcd5VKKIJ/e+ZHMZZc2BUHxUJiqdFEEuFCQKN/N4ANOlwj8 ORxQ== X-Gm-Message-State: AJcUukc4cv+E+QXDK8vtvnSYcrCgmHSCXd+nAyFsxqoxsEZ/ToE0L2HN 2DWNdpYE4fY0b/76mglcLl6HLxyZkvQ= X-Google-Smtp-Source: ALg8bN72Z6jjc0ZJ8fgJ1fxNcVbnYeVk4LUKd0l7e2vtc6AlaJ/tkAinX9yXARc2RSnC4WgAQ+JSdw== X-Received: by 2002:a1c:8d49:: with SMTP id p70mr10749503wmd.68.1545598380839; Sun, 23 Dec 2018 12:53:00 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:00 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:14 +0100 Message-Id: <8627649dea93ec22ccc713ce7f8ba1ea72d14098.1545598229.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 v2 38/52] 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.c | 42 ++++++------------------------------------ audio/audio_int.h | 7 ------- 2 files changed, 6 insertions(+), 43 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 1897e22444..4c33e057d7 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -543,7 +543,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)) { @@ -553,29 +553,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; @@ -1080,7 +1058,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; @@ -1143,11 +1121,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", @@ -1244,12 +1218,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); diff --git a/audio/audio_int.h b/audio/audio_int.h index 5c361d9451..cca7efaa05 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); - int (*run_out) (HWVoiceOut *hw, int 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); - int (*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); From patchwork Sun Dec 23 20:52:15 2018 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: 10741887 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 D6253924 for ; Sun, 23 Dec 2018 21:29:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5315286BD for ; Sun, 23 Dec 2018 21:29:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B878B2878E; Sun, 23 Dec 2018 21:29: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 93A2E286BD for ; Sun, 23 Dec 2018 21:29:57 +0000 (UTC) Received: from localhost ([127.0.0.1]:60017 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBJs-00041S-Dm for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:29:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52587) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkD-0008Jw-LV for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkB-0003Ms-Df for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:05 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:33258) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkB-0003Je-3i for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:03 -0500 Received: by mail-wm1-x342.google.com with SMTP id r24so18059780wmh.0 for ; Sun, 23 Dec 2018 12:53: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=GlRNrc5ncc7ponDHKuLtYruYPFsPm+T1bfbtS537cmg=; b=gDvg3ulpYQ28lj9c68tlv71Q+Lskl01St0LIX035lu+6A+Nv2XgdKBWh9sVFA+IIZX Cr3BnT9q4b3A/tLkRgpX1w4B5qDNRtrklwhE3FV773JZcQDbbC9Or/kqDoV6nbkLD5lC JKQTry8yKF4Y8AmsY5NH6TmM4NJxCzqzz6pfIPFmx9fxcaPQDkDDOTxcYwobGOM3sibM pvkvu6O13OS1Uy+pCoj1+s/6uwRs3s2Ff7Ng49R2KrZcb8mDxB9QLNNZGHql/JgdrLQm zfeh+hlZ7s55NfjQm+eOUvCxglClcrP52mpgIkslX+Pqv5kNlw3RIXY90B7QUNUsetbA tnAQ== 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=GlRNrc5ncc7ponDHKuLtYruYPFsPm+T1bfbtS537cmg=; b=jfZ7bET05S+PNY2t35kRxfUrC52v18OiRrZyRfwx9uNv3olZMlELA0Gmj7zzCV8fcO bhbDws4X21NDwa+L0thQqQDp6MrTQhETdkIV749DGdq1tM7UIEoH5FwDVlapYazsHWFK zG4YawVQFne5oak+vxup6RG5AapqSachMyCpMlEdajSVRkEoMa1pQDEqlhnQlLQdACjo luKd/2vUY9jBKvIfjgkpYZeYUN2bz+MzZsKuLU50qZASaHGCSzPoL4C63+3ed5Q9zFbg BMCuLafDmUTcgziGcabNRq4vx8BldGpwNQJq45hH+acAj0VJp/ktr9jtSpBNPtpBOexA LCxg== X-Gm-Message-State: AA+aEWZOnXoeGMJvPjcVXjPmpJzfr1XplTuBhCUOmRinxTraBpBOYmqa DrU2NuhSKtoABmm0hc9X7eiN2XbkpA8= X-Google-Smtp-Source: AFSGD/V4vNXjRkFsoP85q9XLA50dfzJPuCGOj3l/2J8hsMdYKckv5RD0KnjPXzpQo1+ft3Nu735+Kw== X-Received: by 2002:a1c:6607:: with SMTP id a7mr9673656wmc.129.1545598381514; Sun, 23 Dec 2018 12:53:01 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:01 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:15 +0100 Message-Id: <43f81a1d655afec17dc6602ea0ce60ab29e3dd97.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 39/52] 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.c | 130 ++++++++++++++++++++--------------------- audio/audio_int.h | 12 ++-- audio/audio_template.h | 19 +++--- audio/ossaudio.c | 2 +- 4 files changed, 80 insertions(+), 83 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 4c33e057d7..f195d8eb95 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -546,8 +546,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; @@ -556,17 +556,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; } @@ -581,17 +581,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; } } @@ -601,11 +601,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; } @@ -618,11 +618,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) { @@ -632,7 +632,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; @@ -680,8 +680,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; @@ -701,11 +701,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; } @@ -716,7 +716,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; @@ -742,7 +742,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 ); @@ -870,7 +870,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) @@ -971,8 +971,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; } @@ -995,12 +996,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", @@ -1025,12 +1027,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 " @@ -1039,14 +1041,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) @@ -1064,7 +1066,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; @@ -1088,8 +1090,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; } @@ -1120,13 +1122,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 @@ -1183,6 +1185,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; @@ -1196,10 +1199,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; @@ -1219,9 +1222,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; @@ -1252,14 +1256,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); @@ -1267,10 +1271,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) { @@ -1318,7 +1322,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; @@ -1354,7 +1358,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; @@ -1740,21 +1744,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; } @@ -1774,7 +1773,6 @@ CaptureVoiceOut *AUD_add_capture( err3: g_free (cap->hw.mix_buf); - err2: g_free (cap); err1: g_free (cb); diff --git a/audio/audio_int.h b/audio/audio_int.h index cca7efaa05..a5add3c2b8 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 33cdb66d7f..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 int 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 -1; + size_t samples = hw->samples; + if (audio_bug(__func__, samples == 0)) { + dolog("Attempted to allocate empty buffer\n"); } - return 0; + 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/ossaudio.c b/audio/ossaudio.c index f1b57c87b4..08fe047f91 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -585,7 +585,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 Sun Dec 23 20:52:16 2018 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: 10741833 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 75FAA91E for ; Sun, 23 Dec 2018 21:11:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5EC352877F for ; Sun, 23 Dec 2018 21:11:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39EDC2878E; Sun, 23 Dec 2018 21:11: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E668C2877F for ; Sun, 23 Dec 2018 21:11:06 +0000 (UTC) Received: from localhost ([127.0.0.1]:59796 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB1d-00069A-V8 for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:11:06 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52603) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkE-0008MG-Ex for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkC-0003PU-63 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:06 -0500 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:33259) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkB-0003M8-Rs for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:04 -0500 Received: by mail-wm1-x343.google.com with SMTP id r24so18059798wmh.0 for ; Sun, 23 Dec 2018 12:53: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=eyLEnplvO2/pftGdi2Ftp47TkqsnFw2IOMQgeNX63ps=; b=VkbD/2D9PPDALHiZk/5KQBPTiT7ONqCybCQvKKWOSCb0dj3TMVEhq+g16Rei7lxi57 0hQSNHTNM+RkA3av8m86uccV2TOa248SFgPiQNviYnTLx3TF1z6u2A2uWGYesu1YIaok 9rR+OcQ6jk0xDDALEtTRYokoNmVr6+VWfslwrgnpE7ESv3iJpuqLsKNDCoKuXLa6geU0 qpMzn4VJzlQuxoZqxIXM9WtAARVFYfNZWADzWxH/MGT6UGQPf2/mQwS9DuiF7ZGa59/c ssvQI1NsSz6ii5SQ8DjQSnnOUMeCyEfu/wrFjrkqL1nnjIfsmeT2LKD8BqvUQSWmORnD YTrQ== 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=eyLEnplvO2/pftGdi2Ftp47TkqsnFw2IOMQgeNX63ps=; b=KBq/Vj138f+XQpCaJK3YQWRV41dz0M6hy8Oe6rFtQXsFMY6HPHwZ6Z2zfxGbDvne9O W77cfQbxOaV0TJP/6QQ0HPMbq/nMFAiElhZbNGsshdXQpyf/C+bG5h2AmEQ3CM8lfUTc Gvsq/Abbtf84E1ahc9BA9NAiYvyBCMTldhs4ygEcwyBAEGqdb/BAZsG216hR25LJdjfd XZ7OmXC6g56Dal83PkwydHkkXgYEZaFQ1jc0x+hUFOUZ3rrQpWiXtAQorwCGXrztsZbb OBi3EC90GL0KorG5iU6Svx31VVxf4Hto9iV3Ys0rVoQIYnMZt0upwl3jPtH48f3v73iP 4+6w== X-Gm-Message-State: AA+aEWaRc5hZ+uyTKhc3SeIXlADYTSxgKEyw7lXYnKthhHZ1tNaWoCch GyLaIkWnDzx09yE/h7uOxGVMyXrHmvg= X-Google-Smtp-Source: AFSGD/U1KXoByPandIb6QnwwhgXuD8wbbFuVr3uYmB6EP/M2D6eipIVwTxXyuOLExeDKWWgiRdZ+Ig== X-Received: by 2002:a1c:e1d5:: with SMTP id y204mr9942715wmg.65.1545598382256; Sun, 23 Dec 2018 12:53:02 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:01 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:16 +0100 Message-Id: <3fa7d671ea0bf769c6c7c1d30bb7031f6031eb2f.1545598229.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 v2 40/52] 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 --- 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/alsaaudio.c | 20 ++++++++++++++++++-- audio/audio.c | 2 -- audio/audio_int.h | 5 +++-- audio/audio_template.h | 24 +++++++++++++++--------- audio/coreaudio.c | 10 +++++++++- audio/dsound_template.h | 8 +++++++- 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/alsaaudio.c b/audio/alsaaudio.c index 56271b1174..672803e5c2 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -45,6 +45,7 @@ struct pollhlp { typedef struct ALSAVoiceOut { HWVoiceOut hw; snd_pcm_t *handle; + size_t samples; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceOut; @@ -52,6 +53,7 @@ typedef struct ALSAVoiceOut { typedef struct ALSAVoiceIn { HWVoiceIn hw; snd_pcm_t *handle; + size_t samples; struct pollhlp pollhlp; Audiodev *dev; } ALSAVoiceIn; @@ -696,7 +698,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; @@ -704,6 +706,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 @@ -790,7 +798,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; @@ -798,6 +806,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; @@ -915,11 +929,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 f195d8eb95..7db183b357 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1742,8 +1742,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/audio_int.h b/audio/audio_int.h index a5add3c2b8..598038d999 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/coreaudio.c b/audio/coreaudio.c index a532e862dd..f4210d5784 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/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/dsoundaudio.c b/audio/dsoundaudio.c index 7b3266aaf3..be6b8d8889 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 6a3a1c418b..9b1dfb551d 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 08fe047f91..bc34e12de4 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -44,6 +44,7 @@ typedef struct OSSVoiceOut { int nfrags; int fragsize; int mmapped; + size_t samples; Audiodev *dev; } OSSVoiceOut; @@ -52,6 +53,7 @@ typedef struct OSSVoiceIn { int fd; int nfrags; int fragsize; + size_t samples; Audiodev *dev; } OSSVoiceIn; @@ -511,11 +513,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, @@ -563,6 +565,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; @@ -658,13 +666,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; @@ -753,6 +767,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, @@ -760,6 +775,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 392225c875..7cab3cff97 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; @@ -683,11 +694,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 Sun Dec 23 20:52:17 2018 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: 10741835 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 29F1C91E for ; Sun, 23 Dec 2018 21:11:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A5992877F for ; Sun, 23 Dec 2018 21:11:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E40F2878E; Sun, 23 Dec 2018 21:11: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 48FAA2877F for ; Sun, 23 Dec 2018 21:11:21 +0000 (UTC) Received: from localhost ([127.0.0.1]:59788 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB1s-00059h-Eg for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:11:20 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52593) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkE-0008Ks-1Q for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkC-0003Qn-G6 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:05 -0500 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:51806) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkC-0003O3-9H for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:04 -0500 Received: by mail-wm1-x342.google.com with SMTP id b11so9877447wmj.1 for ; Sun, 23 Dec 2018 12:53: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=SUbvM79h+6p8o6Q3uE4iViwBWiRzQ8vMimUk8hH1Yag=; b=OayLXffHFpox50yMVJdrC7mdqYQtWP/2K8eMPnafe8n4GzqaUNoiFHQ4Q8E49fa6YL 9qZaq4Xbz7W4QKSw/JuP+tFV9HGgURqLvES+TrS0GFc6hPAdSloQqyRKFEhiPqoWIyCy PhwM70M8VsBj9m9di2Ph5MKVd3SI4DUKww1hCSzvywnnzjefTLmW4Jb4u+BDOzr2HuI0 b9X9BuaD+mGsEhGPkD4Qw45ZedabnggO/caSMC5cHbjEGF1ms/RgTmQScPruX1sj5/lR Cfy4r6hMQ6YtJil2f6hMBrr/VKiY4vcUf7b8Q/np6Dbb8U5hLZTPKVpYoEJKz34UomV6 Sn8w== 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=SUbvM79h+6p8o6Q3uE4iViwBWiRzQ8vMimUk8hH1Yag=; b=IG/+H2eV2pjUSTYnrDOFl5CCesJ0eZPkaLVdKDRxCkBYw7ImL0c8gzbsHfyFS38uGO XaJb2Kg6OdZWAswgMDt18umDzQ2S9wabVZBI1cSRL5PwZVZN4512Eae/iF91whCITjZA Ga22pSMKcOmsie8D1VIyx2x99t7hZBlgmHOtqv44/8zsss3AqxZKsFo7oAJuCu+DBxSC 5xNw69Efidt3mwYbaub+FPO+aSbsvb4MrASJ05EsiIZibu8LA3aa/BZ84NIWflPqm3Se E2YEV1A1T4awOFsVip9uJHViCob6+zXaPEONY4ne7RlkO03tESG5HdWNtAUzUSC9VKxV UbpQ== X-Gm-Message-State: AJcUukdL6tNTkbIzl74EwGm1XTAt3WJmANPmbYw5aLttydm78Treegjo zIS6TjF/P8cQtrSB0CsBXf4EY3KqufE= X-Google-Smtp-Source: ALg8bN4hbERXq/FRLSb6aUCN14614ZYwuG9FQtHfR+qed2klnR3KrWcakb/lATWYqC+4JjKUbXeSaQ== X-Received: by 2002:a1c:8d12:: with SMTP id p18mr10945661wmd.31.1545598383021; Sun, 23 Dec 2018 12:53:03 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:02 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:17 +0100 Message-Id: <0c83ec1eca3a43206de8f0c664691219038b818e.1545598229.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::342 Subject: [Qemu-devel] [PATCH v2 41/52] 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.c | 30 ++++++++++++++++++++++++++++ audio/audio_int.h | 9 +++++++++ audio/noaudio.c | 49 +++++++++++++++++++++------------------------- audio/spiceaudio.c | 49 +++++++--------------------------------------- audio/wavaudio.c | 21 ++++++++++---------- 5 files changed, 78 insertions(+), 80 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 7db183b357..f89bce3a34 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -2024,3 +2024,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/audio_int.h b/audio/audio_int.h index 598038d999..0f0ea3e040 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/noaudio.c b/audio/noaudio.c index 9b1dfb551d..85241612cf 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 Sun Dec 23 20:52:18 2018 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: 10741843 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 D6C9F91E for ; Sun, 23 Dec 2018 21:14:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C339727FB1 for ; Sun, 23 Dec 2018 21:14:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B726B283F9; Sun, 23 Dec 2018 21:14:02 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C9138283B0 for ; Sun, 23 Dec 2018 21:14:00 +0000 (UTC) Received: from localhost ([127.0.0.1]:59818 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB4R-0001CQ-Uo for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:13:59 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52659) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkI-0008P3-1W for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkE-0003Wc-5d for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:33806) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkD-0003Sz-Os for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:06 -0500 Received: by mail-wm1-x336.google.com with SMTP id y185so18070866wmd.1 for ; Sun, 23 Dec 2018 12:53: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=qJMeTz37t7lisWe7NXZm6A93RxqpWrQT4Px/oZ+HqxQ=; b=g5mjSaABIHYfm5yJgRLRGuDflax7x9FKsV77p6g8CkBnfC42Tk1Xk3O/0quTXIYe9m QDezJ5ZG2L0MHoY4CH2ctlFQ4/RtlR/qK7VytM8XeMjI2M/MQ6m8TliK4iNPLgAwgyoI km31txgWYx1eksezzrZbPVdQkQuSEMbX4qtkippxeNC1i4jfRQiyGMRMWXkqSnwmzN3K TZ5HEiFNc9NirmwDI2Zf39HmxqHODHfqaQMM28SQSEuPCGsgcD2TtYTyEetXk2IrT1Yz AetdMKhzdTgQPjJoih+i5CvotMiwUAAbRQi7fSDfkdlNtOcQmLpJmYZBgIRKBRMZ/xP/ pBeg== 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=qJMeTz37t7lisWe7NXZm6A93RxqpWrQT4Px/oZ+HqxQ=; b=chU8zAmSCVvF7mTeQZuC/nVLl17pOTcZpdGpgHNgpyA7THZRfNHULODuha6hdEJ6D7 ZvmPfXHsPwRya+fx5pKxjhCivFAqFrjhY7R7FuIdTAqlFfEjSynl9MzS86+wEffuIdmx OoZcf7TPa2o4P5svBIO8eLx9+O8GBem24Vq1iD/Ct8Sg5FFOlHLqliddJ98xFiZcBosv fChTkBqkTNLtMZFA9HtxofBnlpM4o0smr9ScDmhA12GMIPiINk5eoIR2/B2eqDBMu5wk e+A3c55QSVL3qp82dZK47rSFUOxwV1CAH91UndKNjTMY/3QUlopPY88HMAH/HyXLZ6pl Ke8w== X-Gm-Message-State: AJcUukdR+DhBi5SyflsU4s//uGuTL1tcZpAMCNOgaFfHC50RN5OvVHRS GTyuC6/NFgMOnuAYNlzgXwdylw8tt+A= X-Google-Smtp-Source: ALg8bN4nloW2ucP9o2UBoZTYnyGHi1kEez4bktzidf4p62nmmqJ5FaSqI1Y/uUMSRpAERDnStaBdSw== X-Received: by 2002:a1c:9dc4:: with SMTP id g187mr93370wme.152.1545598383795; Sun, 23 Dec 2018 12:53:03 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:03 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:18 +0100 Message-Id: <43c41cadb8334e39ab419fe1c8447c794481ef5d.1545598229.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::336 Subject: [Qemu-devel] [PATCH v2 42/52] 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/alsaaudio.c | 56 +++++++----------- audio/audio.c | 45 +++++++++------ audio/audio_int.h | 15 ++--- audio/audio_template.h | 1 - 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/alsaaudio.c b/audio/alsaaudio.c index 672803e5c2..bc097b1f31 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -745,34 +745,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->has_try_poll || apdo->try_poll; + if (enable) { + bool poll_mode = !apdo->has_try_poll || 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) @@ -861,35 +855,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->has_try_poll || apdo->try_poll; + if (enable) { + bool poll_mode = !apdo->has_try_poll || 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_audio_init(Audiodev *dev) @@ -931,13 +919,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 f89bce3a34..7ba939560a 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -638,7 +638,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); } @@ -725,7 +725,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); } } @@ -892,7 +892,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); } } @@ -937,7 +939,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); } } @@ -954,7 +958,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); + } } } } @@ -1102,7 +1108,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); @@ -1465,15 +1473,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); } @@ -1493,8 +1504,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); @@ -1510,8 +1521,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); @@ -1827,8 +1838,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); } } } @@ -1842,8 +1853,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/audio_int.h b/audio/audio_int.h index 0f0ea3e040..a5ead07998 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/coreaudio.c b/audio/coreaudio.c index f4210d5784..a3cdbd87ce 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 be6b8d8889..6c10d271fe 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 85241612cf..f2938aff66 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 bc34e12de4..cefc90fe58 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -571,59 +571,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->has_try_poll || opdo->try_poll; + if (enable) { + bool poll_mode = !opdo->has_try_poll || 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) @@ -716,32 +707,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->has_try_poll || opdo->try_poll; + if (enable) { + bool poll_mode = !opdo->has_try_poll || 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_audio_init(Audiodev *dev) @@ -770,13 +754,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 7cab3cff97..6565048ac7 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 */ @@ -695,13 +670,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 = { @@ -715,7 +690,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 Sun Dec 23 20:52:19 2018 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: 10741883 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 A602413A4 for ; Sun, 23 Dec 2018 21:28:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 95CEA28787 for ; Sun, 23 Dec 2018 21:28:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8657428790; Sun, 23 Dec 2018 21:28: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0DBA928787 for ; Sun, 23 Dec 2018 21:28:10 +0000 (UTC) Received: from localhost ([127.0.0.1]:59995 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBI9-00026G-Ag for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:28:09 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkF-0008Nf-7h for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkE-0003WJ-33 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:07 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]:51214) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkD-0003TW-S9 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:06 -0500 Received: by mail-wm1-x332.google.com with SMTP id b11so9877472wmj.1 for ; Sun, 23 Dec 2018 12:53: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=YPkI6O+yO0+PWs9SLcVDMljymIpnHMJomM9nRkZBkws=; b=b18povVGbzci8Ix1XUUlkk/X/hIdnX4HhFjQg8DG9r7l/uYU91LypgEeXhDWXpBcmh wmHzZTx5nCQVG8WvZSVvqRDT9rZq6t9QvLqewt0NKV7V2ANVYKSdU/Ix/9gnESdsX2id 7jNxEdgz4AdIr+twwPSdvgr1NESSVvidsOIqYjSgeL6S/vVO4KphoNnLjgDYf7iU+02F 55P+yMawKHDK3h/mX5Rkk42rxDBe2TLtBGuxe1KZa5OjyvOuZgEuUCoiQbQgde5GB659 vHm1ruBmfivvlVtba9ZSiiC/CYiGMgZl2Gc9orpDGHZXHhVwDcM5jzR/F009CtJQKLXd J9nw== 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=YPkI6O+yO0+PWs9SLcVDMljymIpnHMJomM9nRkZBkws=; b=WPPvRfLEbijb+Ef+B91nsiZN0qJ2hgoabgHSV5Ly+xo+mx7Kfdy22xL22bZnODha1J m0IlW/on2lmmB7TFMWnlM+dPcUl/s6rsxmoRGijYqwMCU9/UfNmxVMgGAxAMXDebv2eS Iqk51LYLaSRgx1zSd2xcaOtKEwMVeBCIubZwrgzYasvAC8qKipZv4WIzdneEo9EJ9HRK cP9ajbrqmeYnWtAKWNE/RkL6TJ38C2pijPQKiQhimTeVr/4mhggybyOCEvN2y3czg1xK 6+Ir/ddeUwEO0162AtW8NpgLFZ/fbw6gIUCRtuP+aIJWyuv7Eexi0tp9OCgFQvmUfHwh 5Cig== X-Gm-Message-State: AA+aEWYK676a75Pk0Gl2AQh1mzLKj6dLhELh8hLje25Son7cKNUjl8VO u7Q/fGy5qtgz+II0bJE2iCTrEU0Yr8E= X-Google-Smtp-Source: ALg8bN6KnXNGJzHTeYAcjo70uP5AEsYmstyqmB6h4Ar754kFv2q0xvQ5Rq4YlXnNR6E4/VKkr8gLpQ== X-Received: by 2002:a7b:cb86:: with SMTP id m6mr10106232wmi.61.1545598384607; Sun, 23 Dec 2018 12:53:04 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:04 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:19 +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::332 Subject: [Qemu-devel] [PATCH v2 43/52] 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 --- qapi/audio.json | 5 +++++ qemu-options.hx | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/qapi/audio.json b/qapi/audio.json index 56d8ce439f..180bf207a8 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -184,6 +184,10 @@ # # General audio backend options that are used for both playback and recording. # +# @mixeng: #optional 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: #optional use fixed settings for host input/output. When # off, frequency, channels and format must not be specified # (default on) @@ -207,6 +211,7 @@ ## { 'struct': 'AudiodevPerDirectionOptions', 'data': { + '*mixeng': 'bool', '*fixed-settings': 'bool', '*frequency': 'int', '*channels': 'int', diff --git a/qemu-options.hx b/qemu-options.hx index 687dd23bf2..eb65b511fa 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 Sun Dec 23 20:52:20 2018 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: 10741889 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 137FA924 for ; Sun, 23 Dec 2018 21:31:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 015B12878E for ; Sun, 23 Dec 2018 21:31:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7AC528793; Sun, 23 Dec 2018 21:31: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4DC5D2878E for ; Sun, 23 Dec 2018 21:31:42 +0000 (UTC) Received: from localhost ([127.0.0.1]:60034 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBLY-0005rO-IJ for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:31:40 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkH-0008O3-Dx for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkG-0003df-27 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:45127) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkF-0003WH-OC for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:07 -0500 Received: by mail-wr1-x441.google.com with SMTP id t6so10091170wrr.12 for ; Sun, 23 Dec 2018 12:53: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=sHasOL13Sm4lJqugf3XEUgVeA6clMRH1eNhcHgdVAJw=; b=pWHJZatrWpkqjkvdsrDDYEW8oYKm25EwxCbDuvDs0Jc61h0rSwBcbcYVnDQIMdQoml uYCCj6fv7GWGfac3nkB0/U/8fw4wMSvyaxkv1zSup/IphBwFqHhyjrcADmnA+/mKR2ST oBlS4vn4KkB/lsQ59jSQOT4rRXEhDh/7GrkTQyLXW/oVjE/IDrULMq0eW19fs0zm6wd3 4L/FiKHq3iBLG6YBpdSnFm7Hhz48P0NvpJ69e2TaWYreHcWI+DJqZz7dGAFsky6603Uo Opf/HqsiQnD1vlNN24UwnaRxxiLuSIyvzuGplnHT2lpMkY6tvxc6qMHHm2eRpO31BFbZ pBhA== 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=sHasOL13Sm4lJqugf3XEUgVeA6clMRH1eNhcHgdVAJw=; b=OAgq4CcPhqYvoe8JK/2GP/yrY0F8mc8lsTCJ6EijvnlppX6CyYYBhvExJUuNznrmOl DWE0inFrnm4ttvXHzOWnUcGWnNlGrI0HX15zpA88BaQqeXwEM5gk61YyCzF5ewlZGFh0 vYAGx/oGuXDlDA65MSuxLrZTiJ05BNE61CoEYzn71pnfIfrukRcYsqg60PmXl0JA1Yv2 SjgXEvKEfeiHiaUsEE9j/c9J8aeafkF1hugqGQxaFV59nZhx5a07J5HNWC5LMwhH3L68 CLsgdNGsQPxJA7yQy5N1TdSKKoj3ArqYRJRtxQSo59mlrV6gMJ34YLYJhvFxhX9IciRA fVLg== X-Gm-Message-State: AJcUukcfgIeBE53fSLXQz0J7XAYzYfWJmvecwjfxagfcWsVWWDJMRX32 Y649yF/Aqz9CWZgelv/1t66w3zy7VBU= X-Google-Smtp-Source: ALg8bN7R+zlBOiKtf4GhRCImIWqcr7PtNjhDTHPhvmC0m6ifYDIAEGzKAXUxbkac+mA8ER/typV3Pw== X-Received: by 2002:adf:ae41:: with SMTP id u1mr9136811wrd.20.1545598385358; Sun, 23 Dec 2018 12:53:05 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:04 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:20 +0100 Message-Id: <03189c11f5216339f472d06925582a8e20e7b21b.1545598229.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 v2 44/52] 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.c | 70 ++++++++++++++++++++++++++++++++++++++---- audio/audio_template.h | 46 ++++++++++++++++----------- 2 files changed, 92 insertions(+), 24 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 7ba939560a..26ce25989f 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -840,32 +840,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) @@ -1087,6 +1101,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; @@ -1224,6 +1258,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; @@ -1717,6 +1762,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); @@ -1875,9 +1925,13 @@ QemuOptsList qemu_audiodev_opts = { static void validate_per_direction_opts(AudiodevPerDirectionOptions *pdo, Error **errp) { + 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)) { @@ -1885,6 +1939,10 @@ static void validate_per_direction_opts(AudiodevPerDirectionOptions *pdo, "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; @@ -1896,7 +1954,7 @@ static void validate_per_direction_opts(AudiodevPerDirectionOptions *pdo, } 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; 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)); From patchwork Sun Dec 23 20:52:22 2018 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: 10741891 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 380F891E for ; Sun, 23 Dec 2018 21:32:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25CA12878E for ; Sun, 23 Dec 2018 21:32:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1732128793; Sun, 23 Dec 2018 21:32:59 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6B3A92878E for ; Sun, 23 Dec 2018 21:32:58 +0000 (UTC) Received: from localhost ([127.0.0.1]:60042 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBMn-0006vN-LR for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:32:57 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52657) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkI-0008P0-0i for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkG-0003ew-C8 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:34912) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkG-0003bb-2s for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:08 -0500 Received: by mail-wr1-x441.google.com with SMTP id 96so10115297wrb.2 for ; Sun, 23 Dec 2018 12:53: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=4nR+35Q31zYxKBL7I9lE6ZcGEgVRMDAQoSJBFeGj2bA=; b=vEoFSE0/rAN0PeqpdoMjNYGfZFJ1Ykoo8/NVOJruxYfrHp70PRLww29zleD8ZNnLoS ZU+iiDC+I0+O0CPIO+36vCDS4BPvn4TfyvLhUPUIX51DWiHKWOZIydt7RITI55HPUJhg TWrc8DErCQwvKHII0VrVgyxGAxDFGSlDH944Pp7XTxNC7wrnYWebVflvvq0rrplhGHqF lCY/x2IlW3NAK6STNA3fi8bEuL1MfZu8EqC96iU9e+tl10a4lzVIBPVmt4PW2Zm+LYYs 3L6W1JkAnMNBhhF/PqwlfgBX7fdarKrMTYLoBEC6vckpz5F64egcb3K+MzN1UYh1CfsT yM1Q== 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=4nR+35Q31zYxKBL7I9lE6ZcGEgVRMDAQoSJBFeGj2bA=; b=KnTKb5LSSU4nmTrD6z0RAvnsIWTFVz5/IyAwiVvY+eMBlvc9Qj+WawwB9QI6NcplpX /YK2HOciugPrsibRbuQS1B7bfoWq4qQC5YzJo2ZDkoBein1hZDvzrPPCNFNlqWJ/hnZ+ yIve9ZOmQ0EvDksQN+sH0GVMIodcrtPgEjQ6xnIL110pOysW/GQ0016Sin5DcTn/ht1p 1QXeq1vN/tCU07BKIT2q0NOl6Bxkp/Maf5RneTLBe2g+s//kBFzvjUff1R7+ihQ/YDaM s0LByDEZXfO8G6BMpnPfOI2LhHOzYc2E0rbSs8b9oI1uvY6Wi7oPxlFUf8uXfr19uNTG UAQQ== X-Gm-Message-State: AJcUukde+Zafw9N9/5MQMGTCxmijv9qwid94KYmZ82oLFID3MU1j9H8c FhxKEJkOTR6iscxoQr02pCGQMq+19js= X-Google-Smtp-Source: ALg8bN7a+7o6IjQXLwO7pEAxnwtNPVqogE78+AObycFRpRfplzQA9I5ivjMc1Xi4yZAGf6l7hzPeFw== X-Received: by 2002:adf:f4c2:: with SMTP id h2mr9350241wrp.21.1545598386837; Sun, 23 Dec 2018 12:53:06 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:06 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:22 +0100 Message-Id: <6f033fb593404b7c292cf626242e34559c3e7905.1545598229.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 v2 46/52] 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.c | 28 ++++++++++++++++++++-------- audio/audio.h | 10 ++++++++++ audio/audio_int.h | 4 ++-- audio/paaudio.c | 20 ++++++++++++-------- audio/spiceaudio.c | 14 ++++++++------ 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 26ce25989f..71744fa2c8 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1880,31 +1880,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/audio.h b/audio/audio.h index bfb12e7531..911365cebd 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -125,6 +125,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 a5ead07998..c2f6da5cc2 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/paaudio.c b/audio/paaudio.c index e8556e7a9d..3b4b29b38f 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 Sun Dec 23 20:52:23 2018 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: 10741895 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 DF697924 for ; Sun, 23 Dec 2018 21:34:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD55128614 for ; Sun, 23 Dec 2018 21:34:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BE9DD28793; Sun, 23 Dec 2018 21:34:14 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 848FA28614 for ; Sun, 23 Dec 2018 21:34:13 +0000 (UTC) Received: from localhost ([127.0.0.1]:60048 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBO0-0007vx-Pw for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:34:12 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52686) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkJ-0008SZ-TE for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkH-0003j9-Hu for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:11 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:39163) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkH-0003fY-1X for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:09 -0500 Received: by mail-wr1-x444.google.com with SMTP id t27so10104307wra.6 for ; Sun, 23 Dec 2018 12:53: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=PrqnfBbc2q7kO0WvF/nvebkUGu/d5fqL2pdzGUs2SAA=; b=t0NP209bfXVAZxEg1YbVSkHC/TFU2LA+PuRhw47c+mjXoW9CQ6xLDkGRmtypvqDccQ OaslzBecYDLIgIVbT7KeiaNKUheFZeHBUb0t+5bynj++0Kizpfe8LiYszsfodJEIk1tt 8m/N1D87g1DtAEUeVIVCFX3X4kTv2/pcLhl+ApQiShDvFM4vfbV0r3NrdfYTEI9LjRvM WqBeV+AcsbH+xxYyyK7iKO+66vCgcc3sWjFlLhnU6k63rd8Im3b9+AWZk/4hm804uNUC urYu6miT9I/Qed45NXuR+2TJj5LQP4DVcOIk2+VYu5qxWyIQBziA47ht4zXytjlMBJAK WVwQ== 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=PrqnfBbc2q7kO0WvF/nvebkUGu/d5fqL2pdzGUs2SAA=; b=IT292o01nzsIde5W5oqT2HKeXUjsouahcaExdYwEk3P4DmM23w7++3lPHRUr2mtlqB 7RgkSJ9c5dA5sszHxoRJzYO185Nj4pWFWCMeRmK8r5wCfrGFa9rME0nvNsNgYhbLCLeA osIr2yX9hZCC8K+qrhewgSO5osCNtNtkBTEpoodYd/ykkSqIz9raWptequOF4OUlHS0R nXO3faeHRS4rqQ7LbVpNaR47AeFf8grIe7DpVGXoIrdGT6yI8NgPsh7s8WNP+x64ujyJ vkVMf2mI1eH33qK4xkeazsKknsb+wFYBp7MdZZchYD9n3TflatmYIjwmkOCzfj9h7JAI tGFw== X-Gm-Message-State: AJcUuke81oKQ9vktNNumNFkP3z2wIFD1VaemkmTmGxtT3GIZps3NtCZz dPcBlBhujbv/MH04kQmtEPXRxJ8HY8c= X-Google-Smtp-Source: ALg8bN76gGv4B6gK+INNlnqkpV+uSV1AuVXN4hivbgtE1Kzi4NpPOmh5kg6Zwt6Kt9yMho5s50d1Tg== X-Received: by 2002:adf:cd0e:: with SMTP id w14mr9993934wrm.218.1545598387566; Sun, 23 Dec 2018 12:53:07 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:07 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:23 +0100 Message-Id: <5e8f665e98f07cd5ab4fb5786052e80992b0b947.1545598229.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 v2 47/52] 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/alsaaudio.c | 10 +++--- audio/audio.c | 76 ++++++++++++++++++++--------------------- audio/audio_int.h | 3 +- audio/coreaudio.c | 4 +-- audio/dsound_template.h | 10 +++--- audio/dsoundaudio.c | 4 +-- audio/noaudio.c | 2 +- audio/ossaudio.c | 14 ++++---- audio/spiceaudio.c | 5 +-- audio/wavaudio.c | 6 ++-- 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index bc097b1f31..418b888a57 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -612,7 +612,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); @@ -656,7 +656,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; } @@ -822,7 +822,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) { @@ -848,8 +848,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 71744fa2c8..ee508c1f15 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -298,26 +298,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: @@ -328,9 +329,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); } @@ -341,26 +341,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; } } @@ -370,14 +369,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; } } @@ -560,7 +558,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); @@ -609,7 +607,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; } @@ -644,7 +642,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; } /* @@ -717,7 +715,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; @@ -761,13 +759,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 @@ -884,7 +882,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) @@ -1000,10 +998,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) @@ -1027,10 +1025,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, @@ -1049,7 +1048,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; @@ -1079,10 +1078,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; @@ -1231,16 +1231,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); @@ -1248,7 +1248,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; @@ -1322,7 +1322,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; @@ -1375,7 +1375,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; @@ -1411,7 +1411,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; @@ -1808,11 +1808,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; } @@ -2124,14 +2124,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/audio_int.h b/audio/audio_int.h index c2f6da5cc2..cdd37908e0 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -43,8 +43,7 @@ struct audio_pcm_info { int sign; int freq; int nchannels; - int align; - int shift; + int bytes_per_frame; int bytes_per_second; int swap_endianness; }; diff --git a/audio/coreaudio.c b/audio/coreaudio.c index a3cdbd87ce..1a835da29d 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/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/dsoundaudio.c b/audio/dsoundaudio.c index 6c10d271fe..81c2092a04 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 f2938aff66..dfeb61c56c 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 cefc90fe58..f456732b5f 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -508,16 +508,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, @@ -652,12 +652,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 Sun Dec 23 20:52:24 2018 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: 10741875 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 AB5B2924 for ; Sun, 23 Dec 2018 21:25:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A90A28787 for ; Sun, 23 Dec 2018 21:25:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8EB0028790; Sun, 23 Dec 2018 21:25: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3F94A28787 for ; Sun, 23 Dec 2018 21:25:31 +0000 (UTC) Received: from localhost ([127.0.0.1]:59947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBFa-0005xM-5H for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:25:30 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52688) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkJ-0008Sg-U1 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkJ-0003qO-5H for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:11 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:36985) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkI-0003gk-Ll for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:10 -0500 Received: by mail-wr1-x444.google.com with SMTP id s12so10091412wrt.4 for ; Sun, 23 Dec 2018 12:53:09 -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=fhP6WBpbt0PxGvYor8BExz8ZfJELNLXzFqwl9L31VbU=; b=q3E+6a00W3y2AjiNfZjurcifLoAdkjLerzj7e63MGxvhBG6KziM3GTEnpB/em3zVB3 Uhh8cN3bhzoRk1key1xYRaLYQIaZ84gklQD367Ou8LqifNUyLq9yJrYqLp9jdVecXMoS 82sH3OMxzn61dJr+zw07rpb0WhI24AsUg75A/a+4Dl8sZBrImsTVbE00jEj2yf0wSMx2 mOtuXIA3Koo++MzSeT4hhpvPPcc9vv9AaAf4aeeEqIv7qEdv+eagM7D0flCYzkhywYH8 aFU3PsUWubfnDBtlfD8HR8ptda/BusMIlE9HiS7grB1/V4ACvvF9SQiEz9apIHxS6RfI 5LNg== 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=fhP6WBpbt0PxGvYor8BExz8ZfJELNLXzFqwl9L31VbU=; b=alPKKQ437KXRmw5T4/S0HS/SJaedDaIPvl0RqpzNKGDsFCGK9n9IIrfek0uUHudqBw M3j1Q9xe/15elcViWHquuoGPeq2JmCsdsKbDfRHaa9YPvENwrXTSFvX37K16QXwumtUg 5lHRuCrMF4dQmOc3SDra3F+mqpX12yX36ge1Fipn7obs6ULYkrqS3LLboHQaLHdI769z E146Wa1ht/wqJ27YGudVzi7D9d9n8ENZybl5O9vqD169xohs16dhtswtOBA37M7xxKia mRoajNSpsnyTCvB2RN+J+cq9sQ6TqwtRgFyvrP2L+ZFGS/2h/kcZfZEWne/gsUsUsB8A XRLg== X-Gm-Message-State: AJcUukfQtxKbre5cf0rhCqFVmASaMCAZqJBWSFWREQVSOiSaeus+9eXu GHm5AhxxSiGcjeu0azSPqzBHL4Nbsf0= X-Google-Smtp-Source: ALg8bN59ximJ7vID61RHals7AsgbymH9V7xb/IBPQlTLVb+G7oWafKyrMe0CAFFrC2XasqNCHLDkrA== X-Received: by 2002:a5d:6b81:: with SMTP id n1mr10353841wrx.149.1545598388305; Sun, 23 Dec 2018 12:53:08 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:07 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:24 +0100 Message-Id: <62b2383050d51d0901322a10ea70eda298d60a5a.1545598229.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 v2 48/52] 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 418b888a57..063531b743 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -498,13 +498,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 ee508c1f15..782e4ed1c7 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -241,7 +241,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 Sun Dec 23 20:52:25 2018 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: 10741885 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 1393813A4 for ; Sun, 23 Dec 2018 21:28:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01F5B26247 for ; Sun, 23 Dec 2018 21:28:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E39E726255; Sun, 23 Dec 2018 21:28: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6500F26247 for ; Sun, 23 Dec 2018 21:28:58 +0000 (UTC) Received: from localhost ([127.0.0.1]:59993 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbBIv-00025Z-LQ for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:28:57 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52717) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkV-0000QN-9R for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkJ-0003t8-RK for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:15 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:55632) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkJ-0003k1-CG for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:11 -0500 Received: by mail-wm1-x341.google.com with SMTP id y139so9809824wmc.5 for ; Sun, 23 Dec 2018 12:53: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=pKXND/VSeufO0cB6Q6G59MV/QtejKT3urPyHZ0tVI1k=; b=s1TQdnZSxHefYt9W+9+Iv1uZl+kHt+83eYFwRcIObHPWjy0ctKcXa59P8LGleidxuI nQbo/d2jHr3BUFGWpBajEF/Jqs6uaXO5Rf2HOHXOVfgnphuIh6a2xlI8E5edf87SM9ky bkySaH1r05QU/CIpcch2yRzoFasG6VXhJ17j1njIAIw7GDuYGsgXXUGHSHv//7Hu95tp 0pSBr3P9Xd87GfjefL1SBa6Bko3l/pk2RTrsov14hel+W40inL4K+I0HcIseex4FytBg 1HFD9v4WpAdoDc1PlRtGnGWpHocDPZD+c9BMD97k3AjB05eZfi49G+frp5AEkkZW2jUq dygw== 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=pKXND/VSeufO0cB6Q6G59MV/QtejKT3urPyHZ0tVI1k=; b=kxr3i2QbZgERdl61JP08oA0zpELQ3jPINKCO3+MHtS1q8rqFStpN20+sP8C4pGDPiN Lb49cUChC/pYuEllrHg4QPOHtoyNf/06Z4aZdPUUcjdG4iUg3j9R2HNKCcFCUjEJ1nVR 2am1SEsj5mmMF6q6gQobqyNEvNzFn6srHBmG/XtIMBtzNlskrm+/Hmy6dHsb23Dlc5OR AwshCO149hbSRj5n71bHJxrWRxoiOOrK/3L+CfW8MVG+hAkMzSNtPAjQCty7AaVhq9/G Pnh9D0A6pmuUeX99flhaczLAk7qLiGLVvjTeSb3OlCHtfNNkXTGQQInFjClTyI4V2SEe xYHA== X-Gm-Message-State: AA+aEWbHA8KRquwG+Q6DEL+neap1AWVa7HfSPI6S1MwGFGtb+blB5amx 2DZSupnovQcN9kR1XviNlw7Ya5SF3OY= X-Google-Smtp-Source: ALg8bN7gnTjLfgWqyIFeAxcImN8+e1lBXFEQsPlrnncRKKo6kquMfLwF5RaGrd9/uKCG/pp3UuG/qQ== X-Received: by 2002:a1c:2686:: with SMTP id m128mr9598917wmm.52.1545598389021; Sun, 23 Dec 2018 12:53:09 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:08 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:25 +0100 Message-Id: <23860c05408d965c70746307bb52a809fc62e3b5.1545598229.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 v2 49/52] 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 --- audio/paaudio.c | 18 ++++++++++++++---- qapi/audio.json | 5 ++++- qemu-options.hx | 9 +++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/audio/paaudio.c b/audio/paaudio.c index 3b4b29b38f..f472f25e8f 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/qapi/audio.json b/qapi/audio.json index 180bf207a8..f3efa4620b 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -119,11 +119,14 @@ # # @name: #optional name of the sink/source to use # +# @channel-map: #optional channel map to use (default: OSS compatible map) +# # Since: 3.2 ## { 'struct': 'AudiodevPaPerDirectionOptions', 'data': { - '*name': 'str' } } + '*name': 'str', + '*channel-map': 'str' } } ## # @AudiodevPaOptions: diff --git a/qemu-options.hx b/qemu-options.hx index eb65b511fa..d051c52bbb 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 Sun Dec 23 20:52:26 2018 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: 10741853 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 34F941399 for ; Sun, 23 Dec 2018 21:18:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 246F32877F for ; Sun, 23 Dec 2018 21:18:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 15C542878E; Sun, 23 Dec 2018 21:18: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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B4D072877F for ; Sun, 23 Dec 2018 21:18:02 +0000 (UTC) Received: from localhost ([127.0.0.1]:59867 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB8J-00066p-VX for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:18:00 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52718) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAkV-0000QO-9Y for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkJ-0003rd-Hh for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:15 -0500 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:43040) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkI-0003mI-Vz for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:11 -0500 Received: by mail-wr1-x443.google.com with SMTP id r10so10088349wrs.10 for ; Sun, 23 Dec 2018 12:53: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=A1supMrKTSYMET4aKJaItJj2/zuxVrJZ8lTFZOxceuo=; b=or2gHcZtDUULs8at7S6KATW+PnaBFj0/RHiCkR78o3uet0zOloNdOTjUw3lNtOkA3I u7EoFLiOjkQD06zRkgXk4c0AbbN/0FOtnUIIHydlFRfjNmXWuKegNIivOUlY84+tDVhq 5qeREK2tClBGg3zMDqdMGI9IICdZhNFiQXzrtjdnIBvtZc7Zzr4Csu9UljKYicVN8U31 ti5eBg5JLVfO+QgCTi9W6cBnHUp3vbT4lk8QRZYHtyF3tWldifpc13cM1rcjYE/HkuPW POKGAg7kWTbm0z6gSqBPVMsI9Rx5Nbro6DBBPS1eLGMjjeQ7P6FbjVs2Luc9Xj3Em/kV FhZw== 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=A1supMrKTSYMET4aKJaItJj2/zuxVrJZ8lTFZOxceuo=; b=AaPD0vAJsE/f3yOzVHPLX7rnTBBPAnykYmJcrahiVUYH7Mk03IqMAmvk3k0mL3q0FN 6wgcEV7GB4YX5Z1k7KpzzIa5eZAodbLagHIVeGPyn6ebbxB1QkpwUGNC3VDETkr4LrQ2 jXs+AaWj74zhSGCpNAv0Hv94VzBzk1PQISBjRK39e8u0jaZLD2J8LstoJWrrG8kn75ZW mOCfXEGil8PTqXeyX1iC7ktd1tSpNihwUZu+aNrmLK5ZIWaZyV4kZleytK08nNZcwOxa xH/6z80NmQGQ7Y7L7j1r4NSSOstxfZL1P+tZ19R7p5+hy2ES6pJttZtqbV1txHyPwAR4 sMUA== X-Gm-Message-State: AJcUukcPHJ+0WyEbcIMRH7XJ1jSkC55IGnE0dhBUnDF9DAhzNfiMm21z 8fwqXXXLRUe8KmJhdGIcneQoPO2uXko= X-Google-Smtp-Source: ALg8bN6XjHy3/GGqOhNJoocRlebDTtEPyYDjgZxepCkeETFuNXv3P7psBFm/65pESheLVPJYVzrwPA== X-Received: by 2002:a5d:56d2:: with SMTP id m18mr10227934wrw.113.1545598389735; Sun, 23 Dec 2018 12:53:09 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:09 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:26 +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 v2 50/52] 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 589977d96c..510585ad7a 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -318,27 +318,28 @@ 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; } - 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; } @@ -370,16 +371,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 Sun Dec 23 20:52:28 2018 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: 10741845 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 107481399 for ; Sun, 23 Dec 2018 21:14:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01A4427FB1 for ; Sun, 23 Dec 2018 21:14:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EA374283F9; Sun, 23 Dec 2018 21:14:12 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9476F27FB1 for ; Sun, 23 Dec 2018 21:14:12 +0000 (UTC) Received: from localhost ([127.0.0.1]:59826 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbB4b-0001MP-Fu for patchwork-qemu-devel@patchwork.kernel.org; Sun, 23 Dec 2018 16:14:09 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52748) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gbAka-0000ZI-Gu for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gbAkY-0004ni-K4 for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:27 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:38256) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gbAkV-0003t7-8E for qemu-devel@nongnu.org; Sun, 23 Dec 2018 15:53:25 -0500 Received: by mail-wr1-x442.google.com with SMTP id v13so10103762wrw.5 for ; Sun, 23 Dec 2018 12:53:12 -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=blZ1oxTVQaiyXqreEZgc0soR/DvDn0TwgxsS14dCMLI=; b=SiMQk8oyykRcdZgCsvAV2Kw3Vo5+diaCvwy4ZXDIFBxBj3cYlq2vonb9vjQ5faxllU 8zxsKleZuW8PLG+utmLKb2mfgwJJ0i5wLa8IyqDIYeFyV8sccj66Oh1PjME9lXoNg26h zavjyyKN9SBUQaiUunb2HSxMV1EOcx5Ip23JK+C7TZvMC4t+VgmXLR2tveIZxUOn3Khu l0qpXW4883m+VMFN1PcqwVzuc9vq6D6WxPgBQDWK0mEmmp4nHnBRwlG/b3GI1NMPzbXE tcg+8UVSQ++LQZm2VC8e++2trMpOyU2+qG5sG9CtUbE2qYaHniXiSCO8Pdt2tqtMSAs4 pvAg== 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=blZ1oxTVQaiyXqreEZgc0soR/DvDn0TwgxsS14dCMLI=; b=Vh94dR70nnypgTLkA+0qx5rDKwL9FxxFQgNcuvyRsqn+TPypMKfYNjPDQ6TMlZqdTo WRvTMP94dxOsD2BhypoJdM1r2t9Cp0gzNdvF/2iwNPbChfMch2XzJ9jwwz9dfKFcT+EJ sl0oykAU+K+VMUtprCq8RZvNmBbfQ5+cpcxZiMJaimg9kcDdK/A6iE86FyAwoMCexxVB YmoFxFjExFml7KjVF32F4scSbV7J1W9I4qghaUB+AgtXBSHS609m8PFrKJsYQchPjYKk 3glkXu8mbri/3GI8eEmf+0HYSI7rJcYg7ejoB44Z3tZqQun/aYRzCfWJGodxtqWTALkC 5YQw== X-Gm-Message-State: AJcUukcaA3r7YEdqCGRkC8WpNtU22exnkOW1h8B/iYBlxFCr/bQPB+pH QRTRYkXdj3ZIkoDx14vHNhMQrQgTOxs= X-Google-Smtp-Source: ALg8bN6FWFHwD2SMe7iooklPyHDxvkvl7oVxh1iF9c3LVJYgvOSr7s9fvGhyy6+kPYoQUNeJltiHjQ== X-Received: by 2002:a5d:5182:: with SMTP id k2mr9571358wrv.121.1545598391225; Sun, 23 Dec 2018 12:53:11 -0800 (PST) Received: from nullptr.home.dirty-ice.org (2a01-036c-0113-24a3-0000-0000-0000-0005.pool6.digikabel.hu. [2a01:36c:113:24a3::5]) by smtp.gmail.com with ESMTPSA id g198sm25456920wmd.23.2018.12.23.12.53.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Dec 2018 12:53:10 -0800 (PST) From: " =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= " X-Google-Original-From: =?utf-8?b?S8WRdsOhZ8OzLCBab2x0w6Fu?= To: qemu-devel@nongnu.org Date: Sun, 23 Dec 2018 21:52:28 +0100 Message-Id: <1415d73f73787a48532cc6cdd3c2a5a0c2e02e2f.1545598229.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 v2 52/52] 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 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 29475a2b70..45ffc3ebb3 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,12 +600,14 @@ 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); + uint64_t free = buf->size - (buf->prod - buf->cons); if (free < USBAUDIO_PACKET_SIZE(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); @@ -614,7 +616,7 @@ 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; + uint64_t used = buf->prod - buf->cons; uint8_t *data; if (!used) {