From patchwork Sun Jan 15 13:12:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726709 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwYm3yjFz23g1 for ; Mon, 16 Jan 2023 00:12:44 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oK-0003xq-Fh; Sun, 15 Jan 2023 08:12:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oI-0003xi-CV for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:30 -0500 Received: from mailout04.t-online.de ([194.25.134.18]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oF-000585-Rr for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:30 -0500 Received: from fwd76.dcpf.telekom.de (fwd76.aul.t-online.de [10.223.144.102]) by mailout04.t-online.de (Postfix) with SMTP id EC1A0230F2; Sun, 15 Jan 2023 14:12:24 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd76.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oC-3NPIA50; Sun, 15 Jan 2023 14:12:24 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 536AE200623; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 01/17] audio: change type of mix_buf and conv_buf Date: Sun, 15 Jan 2023 14:12:08 +0100 Message-Id: <20230115131224.30751-1-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 6dee40a4-d82d-4115-921c-bd42e6864451 Received-SPF: none client-ip=194.25.134.18; envelope-from=volker.ruemelin@t-online.de; helo=mailout04.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Change the type of mix_buf in struct HWVoiceOut and conv_buf in struct HWVoiceIn from STSampleBuffer * to STSampleBuffer. However, a buffer pointer is still needed. For this reason in struct STSampleBuffer samples[] is changed to *buffer. This is a preparation for the next patch. The next patch will add this line, which is not possible with the current struct STSampleBuffer definition. + sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2; There are no functional changes. Signed-off-by: Volker Rümelin --- audio/audio.c | 106 ++++++++++++++++++++--------------------- audio/audio_int.h | 6 +-- audio/audio_template.h | 19 ++++---- 3 files changed, 67 insertions(+), 64 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index fb0d4a2cac..6a17b3bb2f 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -521,8 +521,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->conv_buf->size)) { - dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size); + 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; @@ -531,13 +531,13 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void *pcm_buf, size_t samples) { size_t conv = 0; - STSampleBuffer *conv_buf = hw->conv_buf; + STSampleBuffer *conv_buf = &hw->conv_buf; while (samples) { uint8_t *src = advance(pcm_buf, conv * hw->info.bytes_per_frame); size_t proc = MIN(samples, conv_buf->size - conv_buf->pos); - hw->conv(conv_buf->samples + conv_buf->pos, src, proc); + hw->conv(conv_buf->buffer + conv_buf->pos, src, proc); conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size; samples -= proc; conv += proc; @@ -559,12 +559,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) if (!live) { return 0; } - if (audio_bug(__func__, live > hw->conv_buf->size)) { - dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size); + 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; } - rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size); + rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size); samples = size / sw->info.bytes_per_frame; @@ -572,11 +572,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->samples + rpos; - if (hw->conv_buf->pos > rpos) { - isamp = hw->conv_buf->pos - rpos; + src = hw->conv_buf.buffer + rpos; + if (hw->conv_buf.pos > rpos) { + isamp = hw->conv_buf.pos - rpos; } else { - isamp = hw->conv_buf->size - rpos; + isamp = hw->conv_buf.size - rpos; } if (!isamp) { @@ -586,7 +586,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->conv_buf->size; + rpos = (rpos + isamp) % hw->conv_buf.size; dst += osamp; ret += osamp; total += isamp; @@ -634,8 +634,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->mix_buf->size)) { - dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size); + 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; @@ -652,17 +652,17 @@ static size_t audio_pcm_hw_get_free(HWVoiceOut *hw) static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) { size_t clipped = 0; - size_t pos = hw->mix_buf->pos; + size_t pos = hw->mix_buf.pos; while (len) { - st_sample *src = hw->mix_buf->samples + pos; + st_sample *src = hw->mix_buf.buffer + pos; 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_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->mix_buf->size; + pos = (pos + samples_to_clip) % hw->mix_buf.size; len -= samples_to_clip; clipped += samples_to_clip; } @@ -681,11 +681,11 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return size; } - hwsamples = sw->hw->mix_buf->size; + hwsamples = sw->hw->mix_buf.size; live = sw->total_hw_samples_mixed; if (audio_bug(__func__, live > hwsamples)) { - dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples); + dolog("live=%zu hw->mix_buf.size=%zu\n", live, hwsamples); return 0; } @@ -696,7 +696,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return 0; } - wpos = (sw->hw->mix_buf->pos + live) % hwsamples; + wpos = (sw->hw->mix_buf.pos + live) % hwsamples; dead = hwsamples - live; hw_free = audio_pcm_hw_get_free(sw->hw); @@ -723,7 +723,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->samples + wpos, + sw->hw->mix_buf.buffer + wpos, &isamp, &osamp ); @@ -987,9 +987,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->conv_buf->size)) { - dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live, - sw->hw->conv_buf->size); + 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; } @@ -1024,13 +1024,13 @@ static size_t audio_get_free(SWVoiceOut *sw) live = sw->total_hw_samples_mixed; - 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); + 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->mix_buf->size - live; + dead = sw->hw->mix_buf.size - live; #ifdef DEBUG_OUT dolog("%s: get_free live %zu dead %zu frontend frames %zu\n", @@ -1054,12 +1054,12 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, n = samples; while (n) { - size_t till_end_of_hw = hw->mix_buf->size - 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.bytes_per_frame; size_t written; - sw->buf = hw->mix_buf->samples + rpos2; + sw->buf = hw->mix_buf.buffer + rpos2; written = audio_pcm_sw_write (sw, NULL, bytes); if (written - bytes) { dolog("Could not mix %zu bytes into a capture " @@ -1068,14 +1068,14 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, break; } n -= to_write; - rpos2 = (rpos2 + to_write) % hw->mix_buf->size; + rpos2 = (rpos2 + to_write) % hw->mix_buf.size; } } } - n = MIN(samples, hw->mix_buf->size - rpos); - mixeng_clear(hw->mix_buf->samples + rpos, n); - mixeng_clear(hw->mix_buf->samples, samples - n); + n = MIN(samples, hw->mix_buf.size - rpos); + mixeng_clear(hw->mix_buf.buffer + rpos, n); + mixeng_clear(hw->mix_buf.buffer, samples - n); } static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) @@ -1101,7 +1101,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) live -= proc; clipped += proc; - hw->mix_buf->pos = (hw->mix_buf->pos + proc) % hw->mix_buf->size; + hw->mix_buf.pos = (hw->mix_buf.pos + proc) % hw->mix_buf.size; if (proc == 0 || proc < decr) { break; @@ -1172,8 +1172,8 @@ static void audio_run_out (AudioState *s) live = 0; } - if (audio_bug(__func__, live > hw->mix_buf->size)) { - dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size); + if (audio_bug(__func__, live > hw->mix_buf.size)) { + dolog("live=%zu hw->mix_buf.size=%zu\n", live, hw->mix_buf.size); continue; } @@ -1201,13 +1201,13 @@ static void audio_run_out (AudioState *s) continue; } - prev_rpos = hw->mix_buf->pos; + prev_rpos = hw->mix_buf.pos; played = audio_pcm_hw_run_out(hw, live); replay_audio_out(&played); - 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; + 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 @@ -1288,10 +1288,10 @@ static void audio_run_in (AudioState *s) if (replay_mode != REPLAY_MODE_PLAY) { captured = audio_pcm_hw_run_in( - hw, hw->conv_buf->size - 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->samples, &hw->conv_buf->pos, - hw->conv_buf->size); + replay_audio_in(&captured, hw->conv_buf.buffer, &hw->conv_buf.pos, + hw->conv_buf.size); min = audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min; @@ -1324,14 +1324,14 @@ static void audio_run_capture (AudioState *s) SWVoiceOut *sw; captured = live = audio_pcm_hw_get_live_out (hw, NULL); - rpos = hw->mix_buf->pos; + rpos = hw->mix_buf.pos; while (live) { - size_t left = hw->mix_buf->size - 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->samples + rpos; + src = hw->mix_buf.buffer + rpos; hw->clip (cap->buf, src, to_capture); mixeng_clear (src, to_capture); @@ -1339,10 +1339,10 @@ static void audio_run_capture (AudioState *s) cb->ops.capture (cb->opaque, cap->buf, to_capture * hw->info.bytes_per_frame); } - rpos = (rpos + to_capture) % hw->mix_buf->size; + rpos = (rpos + to_capture) % hw->mix_buf.size; live -= to_capture; } - hw->mix_buf->pos = rpos; + hw->mix_buf.pos = rpos; for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (!sw->active && sw->empty) { @@ -1901,7 +1901,7 @@ CaptureVoiceOut *AUD_add_capture( audio_pcm_init_info (&hw->info, as); - cap->buf = g_malloc0_n(hw->mix_buf->size, hw->info.bytes_per_frame); + cap->buf = g_malloc0_n(hw->mix_buf.size, hw->info.bytes_per_frame); if (hw->info.is_float) { hw->clip = mixeng_clip_float[hw->info.nchannels == 2]; @@ -1953,7 +1953,7 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) sw = sw1; } QLIST_REMOVE (cap, entries); - g_free (cap->hw.mix_buf); + g_free(cap->hw.mix_buf.buffer); g_free (cap->buf); g_free (cap); } diff --git a/audio/audio_int.h b/audio/audio_int.h index 9d04be9128..900b0a6255 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -58,7 +58,7 @@ typedef struct SWVoiceCap SWVoiceCap; typedef struct STSampleBuffer { size_t pos, size; - st_sample samples[]; + st_sample *buffer; } STSampleBuffer; typedef struct HWVoiceOut { @@ -71,7 +71,7 @@ typedef struct HWVoiceOut { f_sample *clip; uint64_t ts_helper; - STSampleBuffer *mix_buf; + STSampleBuffer mix_buf; void *buf_emul; size_t pos_emul, pending_emul, size_emul; @@ -93,7 +93,7 @@ typedef struct HWVoiceIn { size_t total_samples_captured; uint64_t ts_helper; - STSampleBuffer *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 9c600448fb..9283f00e9e 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -71,8 +71,9 @@ 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; + g_free(HWBUF.buffer); + HWBUF.buffer = NULL; + HWBUF.size = 0; } static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) @@ -83,10 +84,12 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) dolog("Attempted to allocate empty buffer\n"); } - HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples); - HWBUF->size = samples; + HWBUF.buffer = g_new0(st_sample, samples); + HWBUF.size = samples; + HWBUF.pos = 0; } else { - HWBUF = NULL; + HWBUF.buffer = NULL; + HWBUF.size = 0; } } @@ -111,16 +114,16 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) } #ifdef DAC - samples = ((int64_t) sw->HWBUF->size << 32) / sw->ratio; + samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio; #else - samples = (int64_t)sw->HWBUF->size * sw->ratio >> 32; + samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32; #endif if (samples == 0) { HW *hw = sw->hw; size_t f_fe_min; /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */ - f_fe_min = (hw->info.freq + HWBUF->size - 1) / HWBUF->size; + f_fe_min = (hw->info.freq + HWBUF.size - 1) / HWBUF.size; qemu_log_mask(LOG_UNIMP, AUDIO_CAP ": The guest selected a " NAME " sample rate" " of %d Hz for %s. Only sample rates >= %zu Hz are" From patchwork Sun Jan 15 13:12:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726720 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Nvwbq2zmwz23g1 for ; Mon, 16 Jan 2023 00:14:31 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oQ-0003z7-Nn; Sun, 15 Jan 2023 08:12:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oN-0003yR-SW for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:36 -0500 Received: from mailout06.t-online.de ([194.25.134.19]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oL-00058l-Rd for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:35 -0500 Received: from fwd89.dcpf.telekom.de (fwd89.aul.t-online.de [10.223.144.115]) by mailout06.t-online.de (Postfix) with SMTP id 16C71CB9F; Sun, 15 Jan 2023 14:12:32 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd89.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oE-1wRQ810; Sun, 15 Jan 2023 14:12:27 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 55913200624; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 02/17] audio: change type and name of the resample buffer Date: Sun, 15 Jan 2023 14:12:09 +0100 Message-Id: <20230115131224.30751-2-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 6ec5ab77-e123-4d9f-a299-965e08d05aad Received-SPF: none client-ip=194.25.134.19; envelope-from=volker.ruemelin@t-online.de; helo=mailout06.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Change the type of the resample buffer from struct st_sample * to STSampleBuffer. Also change the name from buf to resample_buf for better readability. The new variables resample_buf.size and resample_buf.pos will be used after the next patches. There is no functional change. Signed-off-by: Volker Rümelin --- audio/audio.c | 15 ++++++++------- audio/audio_int.h | 4 ++-- audio/audio_template.h | 10 ++++++---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 6a17b3bb2f..22ec7d3093 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -553,7 +553,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) { HWVoiceIn *hw = sw->hw; size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; - struct st_sample *src, *dst = sw->buf; + struct st_sample *src, *dst = sw->resample_buf.buffer; live = hw->total_samples_captured - sw->total_hw_samples_acquired; if (!live) { @@ -593,10 +593,10 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) } if (!hw->pcm_ops->volume_in) { - mixeng_volume (sw->buf, ret, &sw->vol); + mixeng_volume(sw->resample_buf.buffer, ret, &sw->vol); } - sw->clip (buf, sw->buf, ret); + sw->clip(buf, sw->resample_buf.buffer, ret); sw->total_hw_samples_acquired += total; return ret * sw->info.bytes_per_frame; } @@ -704,10 +704,10 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) samples = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio; samples = MIN(samples, size / sw->info.bytes_per_frame); if (samples) { - sw->conv(sw->buf, buf, samples); + sw->conv(sw->resample_buf.buffer, buf, samples); if (!sw->hw->pcm_ops->volume_out) { - mixeng_volume(sw->buf, samples, &sw->vol); + mixeng_volume(sw->resample_buf.buffer, samples, &sw->vol); } } @@ -722,7 +722,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) osamp = blck; st_rate_flow_mix ( sw->rate, - sw->buf + pos, + sw->resample_buf.buffer + pos, sw->hw->mix_buf.buffer + wpos, &isamp, &osamp @@ -1059,7 +1059,8 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, size_t bytes = to_write * hw->info.bytes_per_frame; size_t written; - sw->buf = hw->mix_buf.buffer + rpos2; + sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2; + sw->resample_buf.size = to_write; written = audio_pcm_sw_write (sw, NULL, bytes); if (written - bytes) { dolog("Could not mix %zu bytes into a capture " diff --git a/audio/audio_int.h b/audio/audio_int.h index 900b0a6255..f4ec5dcf11 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -109,7 +109,7 @@ struct SWVoiceOut { struct audio_pcm_info info; t_sample *conv; int64_t ratio; - struct st_sample *buf; + STSampleBuffer resample_buf; void *rate; size_t total_hw_samples_mixed; int active; @@ -129,7 +129,7 @@ struct SWVoiceIn { int64_t ratio; void *rate; size_t total_hw_samples_acquired; - struct st_sample *buf; + STSampleBuffer resample_buf; f_sample *clip; HWVoiceIn *hw; char *name; diff --git a/audio/audio_template.h b/audio/audio_template.h index 9283f00e9e..07c14e7821 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -95,13 +95,13 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) { - g_free (sw->buf); + g_free(sw->resample_buf.buffer); + sw->resample_buf.buffer = NULL; + sw->resample_buf.size = 0; if (sw->rate) { st_rate_stop (sw->rate); } - - sw->buf = NULL; sw->rate = NULL; } @@ -132,7 +132,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) return -1; } - sw->buf = g_new0(st_sample, samples); + sw->resample_buf.buffer = g_new0(st_sample, samples); + sw->resample_buf.size = samples; + sw->resample_buf.pos = 0; #ifdef DAC sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq); From patchwork Sun Jan 15 13:12:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726710 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZ81hT9z23g1 for ; Mon, 16 Jan 2023 00:13:04 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oP-0003yp-N2; Sun, 15 Jan 2023 08:12:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oN-0003yH-33 for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:35 -0500 Received: from mailout02.t-online.de ([194.25.134.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oL-00058h-6I for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:34 -0500 Received: from fwd79.dcpf.telekom.de (fwd79.aul.t-online.de [10.223.144.105]) by mailout02.t-online.de (Postfix) with SMTP id 2812D13B16; Sun, 15 Jan 2023 14:12:31 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd79.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oH-3NGUb30; Sun, 15 Jan 2023 14:12:29 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 576D520062B; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 03/17] audio: make the resampling code greedy Date: Sun, 15 Jan 2023 14:12:10 +0100 Message-Id: <20230115131224.30751-3-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: bc3def23-dace-4837-a75c-6e6f6e4ca583 Received-SPF: none client-ip=194.25.134.17; envelope-from=volker.ruemelin@t-online.de; helo=mailout02.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Read the maximum possible number of audio frames instead of the minimum necessary number of frames when the audio stream is downsampled and the output buffer is limited. This makes the function symmetrical to upsampling when the input buffer is limited. The maximum possible number of frames is written here. With this change it's easier to calculate the exact number of audio frames the resample function will read or write. These two functions will be introduced later. Signed-off-by: Volker Rümelin --- audio/rate_template.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/audio/rate_template.h b/audio/rate_template.h index b432719ebb..6648f0d2e5 100644 --- a/audio/rate_template.h +++ b/audio/rate_template.h @@ -40,8 +40,6 @@ void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, int64_t t; #endif - ilast = rate->ilast; - istart = ibuf; iend = ibuf + *isamp; @@ -59,15 +57,17 @@ void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, return; } - while (obuf < oend) { + /* without input samples, there's nothing to do */ + if (ibuf >= iend) { + *osamp = 0; + return; + } - /* Safety catch to make sure we have input samples. */ - if (ibuf >= iend) { - break; - } + ilast = rate->ilast; - /* read as many input samples so that ipos > opos */ + while (true) { + /* read as many input samples so that ipos > opos */ while (rate->ipos <= (rate->opos >> 32)) { ilast = *ibuf++; rate->ipos++; @@ -78,6 +78,11 @@ void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, } } + /* make sure that the next output sample can be written */ + if (obuf >= oend) { + break; + } + icur = *ibuf; /* wrap ipos and opos around long before they overflow */ From patchwork Sun Jan 15 13:12:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726711 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZB66M1z23g1 for ; Mon, 16 Jan 2023 00:13:06 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oT-0003zc-DK; Sun, 15 Jan 2023 08:12:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oP-0003ys-J0 for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:37 -0500 Received: from mailout08.t-online.de ([194.25.134.20]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oN-00058w-Ma for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:37 -0500 Received: from fwd78.dcpf.telekom.de (fwd78.aul.t-online.de [10.223.144.104]) by mailout08.t-online.de (Postfix) with SMTP id A619C29F8A; Sun, 15 Jan 2023 14:12:33 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd78.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oJ-0XixtJ0; Sun, 15 Jan 2023 14:12:31 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 5A2C620062C; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 04/17] audio: replace the resampling loop in audio_pcm_sw_write() Date: Sun, 15 Jan 2023 14:12:11 +0100 Message-Id: <20230115131224.30751-4-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 32774ffe-89d7-483a-ad47-1d813119a757 Received-SPF: none client-ip=194.25.134.20; envelope-from=volker.ruemelin@t-online.de; helo=mailout08.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Replace the resampling loop in audio_pcm_sw_write() with the new function audio_pcm_sw_resample_out(). Unlike the old resample loop the new function will try to consume input frames even if the output buffer is full. This is necessary when downsampling to avoid reading less audio frames than calculated in advance. The loop was unrolled to avoid complicated loop control conditions in this case. Signed-off-by: Volker Rümelin --- audio/audio.c | 63 +++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 22ec7d3093..b0a270ba85 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -671,11 +671,44 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) /* * Soft voice (playback) */ +static void audio_pcm_sw_resample_out(SWVoiceOut *sw, + size_t frames_in_max, size_t frames_out_max, + size_t *total_in, size_t *total_out) +{ + HWVoiceOut *hw = sw->hw; + struct st_sample *src, *dst; + size_t live, wpos, frames_in, frames_out; + + live = sw->total_hw_samples_mixed; + wpos = (hw->mix_buf.pos + live) % hw->mix_buf.size; + + /* write to mix_buf from wpos to end of buffer */ + src = sw->resample_buf.buffer; + frames_in = frames_in_max; + dst = hw->mix_buf.buffer + wpos; + frames_out = MIN(frames_out_max, hw->mix_buf.size - wpos); + st_rate_flow_mix(sw->rate, src, dst, &frames_in, &frames_out); + wpos += frames_out; + *total_in = frames_in; + *total_out = frames_out; + + /* write to mix_buf from start of buffer if there are input frames left */ + if (frames_in_max - frames_in > 0 && wpos == hw->mix_buf.size) { + src += frames_in; + frames_in = frames_in_max - frames_in; + dst = hw->mix_buf.buffer; + frames_out = frames_out_max - frames_out; + st_rate_flow_mix(sw->rate, src, dst, &frames_in, &frames_out); + *total_in += frames_in; + *total_out += frames_out; + } +} + static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) { - size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, blck; + size_t hwsamples, samples, live, dead; size_t hw_free; - size_t ret = 0, pos = 0, total = 0; + size_t ret, total; if (!sw) { return size; @@ -696,8 +729,6 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return 0; } - wpos = (sw->hw->mix_buf.pos + live) % hwsamples; - dead = hwsamples - live; hw_free = audio_pcm_hw_get_free(sw->hw); hw_free = hw_free > live ? hw_free - live : 0; @@ -711,29 +742,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) } } - while (samples) { - dead = hwsamples - live; - left = hwsamples - wpos; - blck = MIN (dead, left); - if (!blck) { - break; - } - isamp = samples; - osamp = blck; - st_rate_flow_mix ( - sw->rate, - sw->resample_buf.buffer + pos, - sw->hw->mix_buf.buffer + wpos, - &isamp, - &osamp - ); - ret += isamp; - samples -= isamp; - pos += isamp; - live += osamp; - wpos = (wpos + osamp) % hwsamples; - total += osamp; - } + audio_pcm_sw_resample_out(sw, samples, MIN(dead, hw_free), &ret, &total); sw->total_hw_samples_mixed += total; sw->empty = sw->total_hw_samples_mixed == 0; From patchwork Sun Jan 15 13:12:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726716 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZz3f67z23g1 for ; Mon, 16 Jan 2023 00:13:47 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oU-000403-2q; Sun, 15 Jan 2023 08:12:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oP-0003yu-PJ for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:37 -0500 Received: from mailout03.t-online.de ([194.25.134.81]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oO-000591-6s for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:37 -0500 Received: from fwd87.dcpf.telekom.de (fwd87.aul.t-online.de [10.223.144.113]) by mailout03.t-online.de (Postfix) with SMTP id 6E57A20719; Sun, 15 Jan 2023 14:12:34 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd87.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oL-12V4G90; Sun, 15 Jan 2023 14:12:34 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 5CB26200631; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 05/17] audio: remove sw == NULL check Date: Sun, 15 Jan 2023 14:12:12 +0100 Message-Id: <20230115131224.30751-5-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 1ca0a024-e826-4d25-9d92-01e553e7ade8 Received-SPF: none client-ip=194.25.134.81; envelope-from=volker.ruemelin@t-online.de; helo=mailout03.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin All call sites of audio_pcm_sw_write() guarantee that sw is not NULL. Remove the unnecessary NULL check. Signed-off-by: Volker Rümelin --- audio/audio.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index b0a270ba85..9d6ffa500a 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -710,10 +710,6 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) size_t hw_free; size_t ret, total; - if (!sw) { - return size; - } - hwsamples = sw->hw->mix_buf.size; live = sw->total_hw_samples_mixed; From patchwork Sun Jan 15 13:12:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726715 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZs43qlz23g1 for ; Mon, 16 Jan 2023 00:13:41 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oX-00043j-3T; Sun, 15 Jan 2023 08:12:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oU-000407-IU for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:42 -0500 Received: from mailout08.t-online.de ([194.25.134.20]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oS-00059w-Uy for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:42 -0500 Received: from fwd85.dcpf.telekom.de (fwd85.aul.t-online.de [10.223.144.111]) by mailout08.t-online.de (Postfix) with SMTP id 39D1D29F8A; Sun, 15 Jan 2023 14:12:39 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd85.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oO-239C4n0; Sun, 15 Jan 2023 14:12:36 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 5F409200635; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 06/17] audio: rename variables in audio_pcm_sw_write() Date: Sun, 15 Jan 2023 14:12:13 +0100 Message-Id: <20230115131224.30751-6-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: db8a8fd3-60c7-4624-80d1-3557b8a4ca4f Received-SPF: none client-ip=194.25.134.20; envelope-from=volker.ruemelin@t-online.de; helo=mailout08.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin The audio_pcm_sw_write() function uses a lot of very unspecific variable names. Rename them for better readability. ret => total_in total => total_out size => buf_len hwsamples => hw->mix_buf.size samples => frames_in_max Signed-off-by: Volker Rümelin --- audio/audio.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 9d6ffa500a..a8571100ff 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -704,56 +704,55 @@ static void audio_pcm_sw_resample_out(SWVoiceOut *sw, } } -static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) +static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len) { - size_t hwsamples, samples, live, dead; - size_t hw_free; - size_t ret, total; - - hwsamples = sw->hw->mix_buf.size; + HWVoiceOut *hw = sw->hw; + size_t live, dead, hw_free; + size_t frames_in_max, total_in, total_out; live = sw->total_hw_samples_mixed; - if (audio_bug(__func__, live > hwsamples)) { - dolog("live=%zu hw->mix_buf.size=%zu\n", live, hwsamples); + 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; } - if (live == hwsamples) { + if (live == hw->mix_buf.size) { #ifdef DEBUG_OUT dolog ("%s is full %zu\n", sw->name, live); #endif return 0; } - dead = hwsamples - live; - hw_free = audio_pcm_hw_get_free(sw->hw); + dead = hw->mix_buf.size - live; + hw_free = audio_pcm_hw_get_free(hw); hw_free = hw_free > live ? hw_free - live : 0; - samples = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio; - samples = MIN(samples, size / sw->info.bytes_per_frame); - if (samples) { - sw->conv(sw->resample_buf.buffer, buf, samples); + frames_in_max = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio; + frames_in_max = MIN(frames_in_max, buf_len / sw->info.bytes_per_frame); + if (frames_in_max) { + sw->conv(sw->resample_buf.buffer, buf, frames_in_max); if (!sw->hw->pcm_ops->volume_out) { - mixeng_volume(sw->resample_buf.buffer, samples, &sw->vol); + mixeng_volume(sw->resample_buf.buffer, frames_in_max, &sw->vol); } } - audio_pcm_sw_resample_out(sw, samples, MIN(dead, hw_free), &ret, &total); + audio_pcm_sw_resample_out(sw, frames_in_max, MIN(dead, hw_free), + &total_in, &total_out); - sw->total_hw_samples_mixed += total; + sw->total_hw_samples_mixed += total_out; sw->empty = sw->total_hw_samples_mixed == 0; #ifdef DEBUG_OUT dolog ( - "%s: write size %zu ret %zu total sw %zu\n", - SW_NAME (sw), - size / sw->info.bytes_per_frame, - ret, + "%s: write size %zu written %zu total mixed %zu\n", + SW_NAME(sw), + buf_len / sw->info.bytes_per_frame, + total_in, sw->total_hw_samples_mixed ); #endif - return ret * sw->info.bytes_per_frame; + return total_in * sw->info.bytes_per_frame; } #ifdef DEBUG_AUDIO From patchwork Sun Jan 15 13:12:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwcC5pjXz23g1 for ; Mon, 16 Jan 2023 00:14:51 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oX-00043p-Jm; Sun, 15 Jan 2023 08:12:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oW-00042t-2i for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:44 -0500 Received: from mailout03.t-online.de ([194.25.134.81]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oU-0005A2-FV for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:43 -0500 Received: from fwd87.dcpf.telekom.de (fwd87.aul.t-online.de [10.223.144.113]) by mailout03.t-online.de (Postfix) with SMTP id 4D22D1281B; Sun, 15 Jan 2023 14:12:40 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd87.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oQ-1T1Bg10; Sun, 15 Jan 2023 14:12:38 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 61E0E200638; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 07/17] audio: don't misuse audio_pcm_sw_write() Date: Sun, 15 Jan 2023 14:12:14 +0100 Message-Id: <20230115131224.30751-7-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: a3a622b3-c675-4cb7-bd84-d1a17f678256 Received-SPF: none client-ip=194.25.134.81; envelope-from=volker.ruemelin@t-online.de; helo=mailout03.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin The audio_pcm_sw_write() function is intended to convert a PCM audio stream to the internal representation, adjust the volume, and then mix it with the other audio streams with a possibly changed sample rate in mix_buf. In order for the audio_capture_mix_and_clear() function to use audio_pcm_sw_write(), it must bypass the first two tasks of audio_pcm_sw_write(). Since patch "audio: split out the resampling loop in audio_pcm_sw_write()" this is no longer necessary, because now the audio_pcm_sw_resample_out() function can be used instead of audio_pcm_sw_write(). Signed-off-by: Volker Rümelin --- audio/audio.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index a8571100ff..0cfd56850f 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -1054,26 +1054,33 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) { SWVoiceOut *sw = &sc->sw; - int rpos2 = rpos; + size_t rpos2 = rpos; n = samples; 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.bytes_per_frame; - size_t written; + size_t to_read = MIN(till_end_of_hw, n); + size_t live, frames_in, frames_out; sw->resample_buf.buffer = hw->mix_buf.buffer + rpos2; - sw->resample_buf.size = to_write; - written = audio_pcm_sw_write (sw, NULL, bytes); - if (written - bytes) { - dolog("Could not mix %zu bytes into a capture " + sw->resample_buf.size = to_read; + live = sw->total_hw_samples_mixed; + + audio_pcm_sw_resample_out(sw, + to_read, sw->hw->mix_buf.size - live, + &frames_in, &frames_out); + + sw->total_hw_samples_mixed += frames_out; + sw->empty = sw->total_hw_samples_mixed == 0; + + if (to_read - frames_in) { + dolog("Could not mix %zu frames into a capture " "buffer, mixed %zu\n", - bytes, written); + to_read, frames_in); break; } - n -= to_write; - rpos2 = (rpos2 + to_write) % hw->mix_buf.size; + n -= to_read; + rpos2 = (rpos2 + to_read) % hw->mix_buf.size; } } } From patchwork Sun Jan 15 13:12:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726718 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwbS0f35z23g1 for ; Mon, 16 Jan 2023 00:14:12 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oZ-00044T-Qx; Sun, 15 Jan 2023 08:12:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oX-00043y-Qz for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:45 -0500 Received: from mailout01.t-online.de ([194.25.134.80]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oW-0005AI-3U for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:45 -0500 Received: from fwd89.dcpf.telekom.de (fwd89.aul.t-online.de [10.223.144.115]) by mailout01.t-online.de (Postfix) with SMTP id 3AFC016B22; Sun, 15 Jan 2023 14:12:41 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd89.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oS-0qBzXd0; Sun, 15 Jan 2023 14:12:40 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 6479220063B; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 08/17] audio: remove unused noop_conv() function Date: Sun, 15 Jan 2023 14:12:15 +0100 Message-Id: <20230115131224.30751-8-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 584776b2-93ce-4234-9dc9-cc1bd1586f36 Received-SPF: none client-ip=194.25.134.80; envelope-from=volker.ruemelin@t-online.de; helo=mailout01.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin The function audio_capture_mix_and_clear() no longer uses audio_pcm_sw_write() to resample audio frames from one internal buffer to another. For this reason, the noop_conv() function is now unused. Remove it. Signed-off-by: Volker Rümelin --- audio/audio.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 0cfd56850f..9c0855fb13 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -379,13 +379,6 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) /* * Capture */ -static void noop_conv (struct st_sample *dst, const void *src, int samples) -{ - (void) src; - (void) dst; - (void) samples; -} - static CaptureVoiceOut *audio_pcm_capture_find_specific(AudioState *s, struct audsettings *as) { @@ -483,7 +476,6 @@ static int audio_attach_capture (HWVoiceOut *hw) sw->info = hw->info; sw->empty = 1; sw->active = hw->enabled; - sw->conv = noop_conv; sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq; sw->vol = nominal_volume; sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq); From patchwork Sun Jan 15 13:12:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726725 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Nvwcl2wPtz23fk for ; Mon, 16 Jan 2023 00:15:17 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oa-00044k-AO; Sun, 15 Jan 2023 08:12:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oZ-00044K-4x for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:47 -0500 Received: from mailout02.t-online.de ([194.25.134.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oX-0005Ak-Gw for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:46 -0500 Received: from fwd79.dcpf.telekom.de (fwd79.aul.t-online.de [10.223.144.105]) by mailout02.t-online.de (Postfix) with SMTP id 4BC1313B18; Sun, 15 Jan 2023 14:12:44 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd79.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oV-01srmj0; Sun, 15 Jan 2023 14:12:43 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 66EDC20063C; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 09/17] audio/mixeng: calculate number of input frames Date: Sun, 15 Jan 2023 14:12:16 +0100 Message-Id: <20230115131224.30751-9-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 96d41563-2a40-434e-8c7e-37f66554e933 Received-SPF: none client-ip=194.25.134.17; envelope-from=volker.ruemelin@t-online.de; helo=mailout02.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Calculate the exact number of audio input frames needed to get a given number of audio output frames. The exact number of frames depends only on the difference of opos - ipos and the number of output frames. When downsampling, this function returns the maximum number of input frames needed. This function will later replace the audio_frontend_frames_out() function, which calculates the average number of input frames rounded down to the nearest integer. Signed-off-by: Volker Rümelin --- audio/mixeng.c | 36 ++++++++++++++++++++++++++++++++++++ audio/mixeng.h | 1 + 2 files changed, 37 insertions(+) diff --git a/audio/mixeng.c b/audio/mixeng.c index fe454e0725..6bb3d54f77 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -440,6 +440,42 @@ void st_rate_stop (void *opaque) g_free (opaque); } +/** + * st_rate_frames_in() - returns the number of frames needed to + * get frames_out frames after resampling + * + * @opaque: pointer to struct rate + * @frames_out: number of frames + */ +uint32_t st_rate_frames_in(void *opaque, uint32_t frames_out) +{ + struct rate *rate = opaque; + uint64_t opos_start, opos_end; + uint32_t ipos_start, ipos_end; + + if (rate->opos_inc == 1ULL << 32) { + return frames_out; + } + + if (frames_out) { + opos_start = rate->opos; + ipos_start = rate->ipos; + } else { + uint64_t offset; + + /* add offset = ceil(opos_inc) to opos and ipos to avoid an underflow */ + offset = (rate->opos_inc + (1ULL << 32) - 1) & ~((1ULL << 32) - 1); + opos_start = rate->opos + offset; + ipos_start = rate->ipos + (offset >> 32); + } + /* last frame written was at opos_start - rate->opos_inc */ + opos_end = opos_start - rate->opos_inc + rate->opos_inc * frames_out; + ipos_end = (opos_end >> 32) + 1; + + /* last frame read was at ipos_start - 1 */ + return ipos_end + 1 > ipos_start ? ipos_end + 1 - ipos_start : 0; +} + void mixeng_clear (struct st_sample *buf, int len) { memset (buf, 0, len * sizeof (struct st_sample)); diff --git a/audio/mixeng.h b/audio/mixeng.h index 2dcd6df245..64c1e231cc 100644 --- a/audio/mixeng.h +++ b/audio/mixeng.h @@ -52,6 +52,7 @@ void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf, 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); +uint32_t st_rate_frames_in(void *opaque, uint32_t frames_out); void mixeng_clear (struct st_sample *buf, int len); void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol); From patchwork Sun Jan 15 13:12:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726714 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZm26Sgz23gX for ; Mon, 16 Jan 2023 00:13:36 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2ob-000450-Gf; Sun, 15 Jan 2023 08:12:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oa-00044m-JJ for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:48 -0500 Received: from mailout04.t-online.de ([194.25.134.18]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oY-0005Az-TJ for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:48 -0500 Received: from fwd76.dcpf.telekom.de (fwd76.aul.t-online.de [10.223.144.102]) by mailout04.t-online.de (Postfix) with SMTP id 8639EFD46; Sun, 15 Jan 2023 14:12:45 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd76.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oX-0pLTCT0; Sun, 15 Jan 2023 14:12:45 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 69A0020063D; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 10/17] audio: wire up st_rate_frames_in() Date: Sun, 15 Jan 2023 14:12:17 +0100 Message-Id: <20230115131224.30751-10-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: c3004046-2014-4013-8ddd-4673521944f3 Received-SPF: none client-ip=194.25.134.18; envelope-from=volker.ruemelin@t-online.de; helo=mailout04.t-online.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Wire up the st_rate_frames_in() function and replace audio_frontend_frames_out() to make audio packet length calculation exact. When upsampling, it's still possible that the audio frontends can't write the last audio frame. This will be fixed later. Signed-off-by: Volker Rümelin --- audio/audio.c | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 9c0855fb13..3d3b5e5b91 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -699,8 +699,8 @@ static void audio_pcm_sw_resample_out(SWVoiceOut *sw, static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len) { HWVoiceOut *hw = sw->hw; - size_t live, dead, hw_free; - size_t frames_in_max, total_in, total_out; + size_t live, dead, hw_free, sw_max, fe_max; + size_t frames_in_max, frames_out_max, total_in, total_out; live = sw->total_hw_samples_mixed; if (audio_bug(__func__, live > hw->mix_buf.size)) { @@ -718,17 +718,21 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len) dead = hw->mix_buf.size - live; hw_free = audio_pcm_hw_get_free(hw); hw_free = hw_free > live ? hw_free - live : 0; - frames_in_max = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio; - frames_in_max = MIN(frames_in_max, buf_len / sw->info.bytes_per_frame); - if (frames_in_max) { - sw->conv(sw->resample_buf.buffer, buf, frames_in_max); + frames_out_max = MIN(dead, hw_free); + sw_max = st_rate_frames_in(sw->rate, frames_out_max); + fe_max = MIN(buf_len / sw->info.bytes_per_frame, sw->resample_buf.size); + frames_in_max = MIN(sw_max, fe_max); - if (!sw->hw->pcm_ops->volume_out) { - mixeng_volume(sw->resample_buf.buffer, frames_in_max, &sw->vol); - } + if (!frames_in_max) { + return 0; } - audio_pcm_sw_resample_out(sw, frames_in_max, MIN(dead, hw_free), + sw->conv(sw->resample_buf.buffer, buf, frames_in_max); + if (!sw->hw->pcm_ops->volume_out) { + mixeng_volume(sw->resample_buf.buffer, frames_in_max, &sw->vol); + } + + audio_pcm_sw_resample_out(sw, frames_in_max, frames_out_max, &total_in, &total_out); sw->total_hw_samples_mixed += total_out; @@ -998,18 +1002,6 @@ static size_t audio_get_avail (SWVoiceIn *sw) return live; } -/** - * audio_frontend_frames_out() - returns the number of frames needed to - * get frames_out frames after resampling - * - * @sw: audio playback frontend - * @frames_out: number of frames - */ -static size_t audio_frontend_frames_out(SWVoiceOut *sw, size_t frames_out) -{ - return ((int64_t)frames_out << 32) / sw->ratio; -} - static size_t audio_get_free(SWVoiceOut *sw) { size_t live, dead; @@ -1029,8 +1021,8 @@ static size_t audio_get_free(SWVoiceOut *sw) dead = sw->hw->mix_buf.size - live; #ifdef DEBUG_OUT - dolog("%s: get_free live %zu dead %zu frontend frames %zu\n", - SW_NAME(sw), live, dead, audio_frontend_frames_out(sw, dead)); + dolog("%s: get_free live %zu dead %zu frontend frames %u\n", + SW_NAME(sw), live, dead, st_rate_frames_in(sw->rate, dead)); #endif return dead; @@ -1159,12 +1151,13 @@ static void audio_run_out (AudioState *s) size_t free; if (hw_free > sw->total_hw_samples_mixed) { - free = audio_frontend_frames_out(sw, + free = st_rate_frames_in(sw->rate, MIN(sw_free, hw_free - sw->total_hw_samples_mixed)); } else { free = 0; } if (free > 0) { + free = MIN(free, sw->resample_buf.size); sw->callback.fn(sw->callback.opaque, free * sw->info.bytes_per_frame); } From patchwork Sun Jan 15 13:12:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726719 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwbY13lGz23g1 for ; Mon, 16 Jan 2023 00:14:17 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2of-00049G-Jq; Sun, 15 Jan 2023 08:12:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2od-00045u-Pw for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:51 -0500 Received: from mailout01.t-online.de ([194.25.134.80]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oc-0005BX-4W for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:51 -0500 Received: from fwd77.dcpf.telekom.de (fwd77.aul.t-online.de [10.223.144.103]) by mailout01.t-online.de (Postfix) with SMTP id 85F8A16B21; Sun, 15 Jan 2023 14:12:48 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd77.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oZ-1TIEi10; Sun, 15 Jan 2023 14:12:47 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 6C3BC2006C1; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 11/17] audio: replace the resampling loop in audio_pcm_sw_read() Date: Sun, 15 Jan 2023 14:12:18 +0100 Message-Id: <20230115131224.30751-11-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 6e23ab49-bdc3-4820-acf2-2d1c3cca5264 Received-SPF: none client-ip=194.25.134.80; envelope-from=volker.ruemelin@t-online.de; helo=mailout01.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Replace the resampling loop in audio_pcm_sw_read() with the new function audio_pcm_sw_resample_in(). Unlike the old resample loop the new function will try to consume input frames even if the output buffer is full. This is necessary when downsampling to avoid reading less audio frames than calculated in advance. The loop was unrolled to avoid complicated loop control conditions in this case. Signed-off-by: Volker Rümelin --- audio/audio.c | 59 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 3d3b5e5b91..83bac97fa4 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -541,11 +541,43 @@ static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void *pcm_buf, size_t samples) /* * Soft voice (capture) */ +static void audio_pcm_sw_resample_in(SWVoiceIn *sw, + size_t frames_in_max, size_t frames_out_max, + size_t *total_in, size_t *total_out) +{ + HWVoiceIn *hw = sw->hw; + struct st_sample *src, *dst; + size_t live, rpos, frames_in, frames_out; + + live = hw->total_samples_captured - sw->total_hw_samples_acquired; + rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size); + + /* resample conv_buf from rpos to end of buffer */ + src = hw->conv_buf.buffer + rpos; + frames_in = MIN(live, hw->conv_buf.size - rpos); + dst = sw->resample_buf.buffer; + frames_out = frames_out_max; + st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out); + rpos += frames_in; + *total_in = frames_in; + *total_out = frames_out; + + /* resample conv_buf from start of buffer if there are input frames left */ + if (live - frames_in && rpos == hw->conv_buf.size) { + src = hw->conv_buf.buffer; + frames_in = live - frames_in; + dst += frames_out; + frames_out = frames_out_max - frames_out; + st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out); + *total_in += frames_in; + *total_out += frames_out; + } +} + static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) { HWVoiceIn *hw = sw->hw; - size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; - struct st_sample *src, *dst = sw->resample_buf.buffer; + size_t samples, live, ret, swlim, total; live = hw->total_samples_captured - sw->total_hw_samples_acquired; if (!live) { @@ -556,33 +588,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) return 0; } - rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size); - samples = size / sw->info.bytes_per_frame; swlim = (live * sw->ratio) >> 32; swlim = MIN (swlim, samples); - while (swlim) { - src = hw->conv_buf.buffer + rpos; - if (hw->conv_buf.pos > rpos) { - isamp = hw->conv_buf.pos - rpos; - } else { - isamp = hw->conv_buf.size - rpos; - } - - if (!isamp) { - break; - } - osamp = swlim; - - st_rate_flow (sw->rate, src, dst, &isamp, &osamp); - swlim -= osamp; - rpos = (rpos + isamp) % hw->conv_buf.size; - dst += osamp; - ret += osamp; - total += isamp; - } + audio_pcm_sw_resample_in(sw, live, swlim, &total, &ret); if (!hw->pcm_ops->volume_in) { mixeng_volume(sw->resample_buf.buffer, ret, &sw->vol); From patchwork Sun Jan 15 13:12:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726721 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Nvwby2LBtz23g1 for ; Mon, 16 Jan 2023 00:14:38 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2oh-0004DW-2b; Sun, 15 Jan 2023 08:12:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2of-00049L-I8 for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:53 -0500 Received: from mailout11.t-online.de ([194.25.134.85]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oe-0005Bh-00 for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:53 -0500 Received: from fwd75.dcpf.telekom.de (fwd75.aul.t-online.de [10.223.144.101]) by mailout11.t-online.de (Postfix) with SMTP id 96F9913D07; Sun, 15 Jan 2023 14:12:50 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd75.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oc-1oOKMT0; Sun, 15 Jan 2023 14:12:50 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 6EC132006C4; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 12/17] audio: rename variables in audio_pcm_sw_read() Date: Sun, 15 Jan 2023 14:12:19 +0100 Message-Id: <20230115131224.30751-12-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 1eef7ca8-81bd-47da-b985-a02e5cddb20b Received-SPF: none client-ip=194.25.134.85; envelope-from=volker.ruemelin@t-online.de; helo=mailout11.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin The audio_pcm_sw_read() function uses a few very unspecific variable names. Rename them for better readability. ret => total_out total => total_in size => buf_len samples => frames_out_max Signed-off-by: Volker Rümelin --- audio/audio.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 83bac97fa4..b660569928 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -574,10 +574,10 @@ static void audio_pcm_sw_resample_in(SWVoiceIn *sw, } } -static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) +static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len) { HWVoiceIn *hw = sw->hw; - size_t samples, live, ret, swlim, total; + size_t live, frames_out_max, swlim, total_in, total_out; live = hw->total_samples_captured - sw->total_hw_samples_acquired; if (!live) { @@ -588,20 +588,20 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) return 0; } - samples = size / sw->info.bytes_per_frame; + frames_out_max = buf_len / sw->info.bytes_per_frame; swlim = (live * sw->ratio) >> 32; - swlim = MIN (swlim, samples); + swlim = MIN(swlim, frames_out_max); - audio_pcm_sw_resample_in(sw, live, swlim, &total, &ret); + audio_pcm_sw_resample_in(sw, live, swlim, &total_in, &total_out); if (!hw->pcm_ops->volume_in) { - mixeng_volume(sw->resample_buf.buffer, ret, &sw->vol); + mixeng_volume(sw->resample_buf.buffer, total_out, &sw->vol); } + sw->clip(buf, sw->resample_buf.buffer, total_out); - sw->clip(buf, sw->resample_buf.buffer, ret); - sw->total_hw_samples_acquired += total; - return ret * sw->info.bytes_per_frame; + sw->total_hw_samples_acquired += total_in; + return total_out * sw->info.bytes_per_frame; } /* From patchwork Sun Jan 15 13:12:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726712 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZh48z7z23g1 for ; Mon, 16 Jan 2023 00:13:32 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2os-0004Uy-Km; Sun, 15 Jan 2023 08:13:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oo-0004Jj-KY for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:02 -0500 Received: from mailout12.t-online.de ([194.25.134.22]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2om-0005Cn-PB for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:02 -0500 Received: from fwd84.dcpf.telekom.de (fwd84.aul.t-online.de [10.223.144.110]) by mailout12.t-online.de (Postfix) with SMTP id 5C12A7E50; Sun, 15 Jan 2023 14:12:57 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd84.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oe-3l2fmz0; Sun, 15 Jan 2023 14:12:52 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 7168A2006C5; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 13/17] audio/mixeng: calculate number of output frames Date: Sun, 15 Jan 2023 14:12:20 +0100 Message-Id: <20230115131224.30751-13-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 1c13819f-08e0-4db1-80bf-5d980f602ba3 Received-SPF: none client-ip=194.25.134.22; envelope-from=volker.ruemelin@t-online.de; helo=mailout12.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Calculate the exact number of audio output frames the resampling code can generate from a given number of audio input frames. When upsampling, this function returns the maximum number of output frames. This function will later replace the audio_frontend_frames_in() function, which calculates the average number of output frames rounded down to the nearest integer. Signed-off-by: Volker Rümelin --- audio/mixeng.c | 37 +++++++++++++++++++++++++++++++++++++ audio/mixeng.h | 1 + 2 files changed, 38 insertions(+) diff --git a/audio/mixeng.c b/audio/mixeng.c index 6bb3d54f77..92a3a1ac58 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -440,6 +440,43 @@ void st_rate_stop (void *opaque) g_free (opaque); } +/** + * st_rate_frames_out() - returns the number of frames the resampling code + * generates from frames_in frames + * + * @opaque: pointer to struct rate + * @frames_in: number of frames + */ +uint32_t st_rate_frames_out(void *opaque, uint32_t frames_in) +{ + struct rate *rate = opaque; + uint64_t opos_end, opos_delta; + uint32_t ipos_end; + uint32_t frames_out; + + if (rate->opos_inc == 1ULL << 32) { + return frames_in; + } + + /* no output frame without at least one input frame */ + if (!frames_in) { + return 0; + } + + /* last frame read was at rate->ipos - 1 */ + ipos_end = rate->ipos - 1 + frames_in; + opos_end = (uint64_t)ipos_end << 32; + + /* last frame written was at rate->opos - rate->opos_inc */ + if (opos_end + rate->opos_inc <= rate->opos) { + return 0; + } + opos_delta = opos_end - rate->opos + rate->opos_inc; + frames_out = opos_delta / rate->opos_inc; + + return opos_delta % rate->opos_inc ? frames_out : frames_out - 1; +} + /** * st_rate_frames_in() - returns the number of frames needed to * get frames_out frames after resampling diff --git a/audio/mixeng.h b/audio/mixeng.h index 64c1e231cc..f9de7cffeb 100644 --- a/audio/mixeng.h +++ b/audio/mixeng.h @@ -52,6 +52,7 @@ void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf, 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); +uint32_t st_rate_frames_out(void *opaque, uint32_t frames_in); uint32_t st_rate_frames_in(void *opaque, uint32_t frames_out); void mixeng_clear (struct st_sample *buf, int len); void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol); From patchwork Sun Jan 15 13:12:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726713 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwZl6HD3z23g1 for ; Mon, 16 Jan 2023 00:13:35 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2on-0004He-IL; Sun, 15 Jan 2023 08:13:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2om-0004HM-9o for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:00 -0500 Received: from mailout05.t-online.de ([194.25.134.82]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2ok-0005CN-Ff for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:12:59 -0500 Received: from fwd80.dcpf.telekom.de (fwd80.aul.t-online.de [10.223.144.106]) by mailout05.t-online.de (Postfix) with SMTP id 732611D39D; Sun, 15 Jan 2023 14:12:56 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd80.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2og-1SDxvF0; Sun, 15 Jan 2023 14:12:54 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 740E32006C6; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 14/17] audio: wire up st_rate_frames_out() Date: Sun, 15 Jan 2023 14:12:21 +0100 Message-Id: <20230115131224.30751-14-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 6bac1636-ee8b-4667-90e4-cafab4c05c36 Received-SPF: none client-ip=194.25.134.82; envelope-from=volker.ruemelin@t-online.de; helo=mailout05.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Wire up the st_rate_frames_out() function and replace audio_frontend_frames_in() to make audio packet length calculation exact. Signed-off-by: Volker Rümelin --- audio/audio.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index b660569928..ecd5d31260 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -577,7 +577,7 @@ static void audio_pcm_sw_resample_in(SWVoiceIn *sw, static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len) { HWVoiceIn *hw = sw->hw; - size_t live, frames_out_max, swlim, total_in, total_out; + size_t live, frames_out_max, total_in, total_out; live = hw->total_samples_captured - sw->total_hw_samples_acquired; if (!live) { @@ -588,12 +588,10 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len) return 0; } - frames_out_max = buf_len / sw->info.bytes_per_frame; + frames_out_max = MIN(buf_len / sw->info.bytes_per_frame, + sw->resample_buf.size); - swlim = (live * sw->ratio) >> 32; - swlim = MIN(swlim, frames_out_max); - - audio_pcm_sw_resample_in(sw, live, swlim, &total_in, &total_out); + audio_pcm_sw_resample_in(sw, live, frames_out_max, &total_in, &total_out); if (!hw->pcm_ops->volume_in) { mixeng_volume(sw->resample_buf.buffer, total_out, &sw->vol); @@ -977,18 +975,6 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) } } -/** - * audio_frontend_frames_in() - returns the number of frames the resampling - * code generates from frames_in frames - * - * @sw: audio recording frontend - * @frames_in: number of frames - */ -static size_t audio_frontend_frames_in(SWVoiceIn *sw, size_t frames_in) -{ - return (int64_t)frames_in * sw->ratio >> 32; -} - static size_t audio_get_avail (SWVoiceIn *sw) { size_t live; @@ -1005,9 +991,9 @@ static size_t audio_get_avail (SWVoiceIn *sw) } ldebug ( - "%s: get_avail live %zu frontend frames %zu\n", + "%s: get_avail live %zu frontend frames %u\n", SW_NAME (sw), - live, audio_frontend_frames_in(sw, live) + live, st_rate_frames_out(sw->rate, live) ); return live; @@ -1312,8 +1298,9 @@ static void audio_run_in (AudioState *s) size_t sw_avail = audio_get_avail(sw); size_t avail; - avail = audio_frontend_frames_in(sw, sw_avail); + avail = st_rate_frames_out(sw->rate, sw_avail); if (avail > 0) { + avail = MIN(avail, sw->resample_buf.size); sw->callback.fn(sw->callback.opaque, avail * sw->info.bytes_per_frame); } From patchwork Sun Jan 15 13:12:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726723 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwcF1hw9z23g1 for ; Mon, 16 Jan 2023 00:14:53 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2ot-0004aL-K9; Sun, 15 Jan 2023 08:13:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2or-0004Se-IU for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:05 -0500 Received: from mailout02.t-online.de ([194.25.134.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2op-0005Dj-GY for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:05 -0500 Received: from fwd72.dcpf.telekom.de (fwd72.aul.t-online.de [10.223.144.98]) by mailout02.t-online.de (Postfix) with SMTP id 45FF11AA32; Sun, 15 Jan 2023 14:13:02 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd72.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2oi-3CNxcv0; Sun, 15 Jan 2023 14:12:57 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 76B102006C7; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 15/17] audio: handle leftover audio frame from upsampling Date: Sun, 15 Jan 2023 14:12:22 +0100 Message-Id: <20230115131224.30751-15-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 8c006ce9-0454-4073-a2e2-8799cdae2b28 Received-SPF: none client-ip=194.25.134.17; envelope-from=volker.ruemelin@t-online.de; helo=mailout02.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Upsampling may leave one remaining audio frame in the input buffer. The emulated audio playback devices are currently resposible to write this audio frame again in the next write cycle. Push that task down to audio_pcm_sw_write. This is another step towards an audio callback interface that guarantees that when audio frontends are told they can write n audio frames, they can actually do so. Signed-off-by: Volker Rümelin --- audio/audio.c | 34 ++++++++++++++++++++++++++++------ audio/audio_template.h | 5 +++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index ecd5d31260..b846b89a27 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -729,16 +729,21 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len) hw_free = hw_free > live ? hw_free - live : 0; frames_out_max = MIN(dead, hw_free); sw_max = st_rate_frames_in(sw->rate, frames_out_max); - fe_max = MIN(buf_len / sw->info.bytes_per_frame, sw->resample_buf.size); + fe_max = MIN(buf_len / sw->info.bytes_per_frame + sw->resample_buf.pos, + sw->resample_buf.size); frames_in_max = MIN(sw_max, fe_max); if (!frames_in_max) { return 0; } - sw->conv(sw->resample_buf.buffer, buf, frames_in_max); - if (!sw->hw->pcm_ops->volume_out) { - mixeng_volume(sw->resample_buf.buffer, frames_in_max, &sw->vol); + if (frames_in_max > sw->resample_buf.pos) { + sw->conv(sw->resample_buf.buffer + sw->resample_buf.pos, + buf, frames_in_max - sw->resample_buf.pos); + if (!sw->hw->pcm_ops->volume_out) { + mixeng_volume(sw->resample_buf.buffer + sw->resample_buf.pos, + frames_in_max - sw->resample_buf.pos, &sw->vol); + } } audio_pcm_sw_resample_out(sw, frames_in_max, frames_out_max, @@ -747,6 +752,22 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t buf_len) sw->total_hw_samples_mixed += total_out; sw->empty = sw->total_hw_samples_mixed == 0; + /* + * Upsampling may leave one audio frame in the resample buffer. Decrement + * total_in by one if there was a leftover frame from the previous resample + * pass in the resample buffer. Increment total_in by one if the current + * resample pass left one frame in the resample buffer. + */ + if (frames_in_max - total_in == 1) { + /* copy one leftover audio frame to the beginning of the buffer */ + *sw->resample_buf.buffer = *(sw->resample_buf.buffer + total_in); + total_in += 1 - sw->resample_buf.pos; + sw->resample_buf.pos = 1; + } else if (total_in >= sw->resample_buf.pos) { + total_in -= sw->resample_buf.pos; + sw->resample_buf.pos = 0; + } + #ifdef DEBUG_OUT dolog ( "%s: write size %zu written %zu total mixed %zu\n", @@ -1153,8 +1174,9 @@ static void audio_run_out (AudioState *s) } else { free = 0; } - if (free > 0) { - free = MIN(free, sw->resample_buf.size); + if (free > sw->resample_buf.pos) { + free = MIN(free, sw->resample_buf.size) + - sw->resample_buf.pos; sw->callback.fn(sw->callback.opaque, free * sw->info.bytes_per_frame); } diff --git a/audio/audio_template.h b/audio/audio_template.h index 07c14e7821..a9a550a3b7 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -132,8 +132,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) return -1; } - sw->resample_buf.buffer = g_new0(st_sample, samples); - sw->resample_buf.size = samples; + /* allocate one additional audio frame that is needed for upsampling */ + sw->resample_buf.buffer = g_new0(st_sample, samples + 1); + sw->resample_buf.size = samples + 1; sw->resample_buf.pos = 0; #ifdef DAC From patchwork Sun Jan 15 13:12:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726717 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Nvwb80vRBz23g1 for ; Mon, 16 Jan 2023 00:13:56 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2or-0004SS-MA; Sun, 15 Jan 2023 08:13:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2op-0004K9-2Z for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:03 -0500 Received: from mailout11.t-online.de ([194.25.134.85]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2on-0005D0-G2 for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:02 -0500 Received: from fwd71.dcpf.telekom.de (fwd71.aul.t-online.de [10.223.144.97]) by mailout11.t-online.de (Postfix) with SMTP id 6CACA13D10; Sun, 15 Jan 2023 14:12:59 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd71.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2ol-1rbPlp0; Sun, 15 Jan 2023 14:12:59 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 795172006C8; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 16/17] audio/audio_template: substitute sw->hw with hw Date: Sun, 15 Jan 2023 14:12:23 +0100 Message-Id: <20230115131224.30751-16-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 49c2125d-4c9b-4ebc-aa71-337abc4bd80c Received-SPF: none client-ip=194.25.134.85; envelope-from=volker.ruemelin@t-online.de; helo=mailout11.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Substitute sw->hw with hw in the audio_pcm_sw_alloc_resources_* functions. Signed-off-by: Volker Rümelin --- audio/audio_template.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/audio/audio_template.h b/audio/audio_template.h index a9a550a3b7..0cdf57760e 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -107,6 +107,7 @@ static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) { + HW *hw = sw->hw; int samples; if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) { @@ -119,7 +120,6 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32; #endif if (samples == 0) { - HW *hw = sw->hw; size_t f_fe_min; /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */ @@ -138,9 +138,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) sw->resample_buf.pos = 0; #ifdef DAC - sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq); + sw->rate = st_rate_start(sw->info.freq, hw->info.freq); #else - sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq); + sw->rate = st_rate_start(hw->info.freq, sw->info.freq); #endif return 0; From patchwork Sun Jan 15 13:12:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Volker_R=C3=BCmelin?= X-Patchwork-Id: 1726724 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NvwcF1x5Lz23gX for ; Mon, 16 Jan 2023 00:14:53 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pH2ov-0004iL-3P; Sun, 15 Jan 2023 08:13:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2os-0004Ux-IZ for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:06 -0500 Received: from mailout10.t-online.de ([194.25.134.21]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pH2oq-0005Dz-LG for qemu-devel@nongnu.org; Sun, 15 Jan 2023 08:13:06 -0500 Received: from fwd77.dcpf.telekom.de (fwd77.aul.t-online.de [10.223.144.103]) by mailout10.t-online.de (Postfix) with SMTP id 154C524B34; Sun, 15 Jan 2023 14:13:02 +0100 (CET) Received: from linpower.localnet ([79.208.25.151]) by fwd77.t-online.de with (TLSv1.3:TLS_AES_256_GCM_SHA384 encrypted) esmtp id 1pH2on-0gcIwz0; Sun, 15 Jan 2023 14:13:01 +0100 Received: by linpower.localnet (Postfix, from userid 1000) id 7BEC72006C9; Sun, 15 Jan 2023 14:12:24 +0100 (CET) From: =?utf-8?q?Volker_R=C3=BCmelin?= To: Gerd Hoffmann Cc: qemu-devel@nongnu.org Subject: [PATCH 17/17] audio: remove sw->ratio Date: Sun, 15 Jan 2023 14:12:24 +0100 Message-Id: <20230115131224.30751-17-volker.ruemelin@t-online.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> References: <61bd351f-0683-7f58-b746-66c9578a7cdc@t-online.de> MIME-Version: 1.0 X-TOI-MSGID: 9eaa5b86-7b91-45d1-828e-0936903caca1 Received-SPF: none client-ip=194.25.134.21; envelope-from=volker.ruemelin@t-online.de; helo=mailout10.t-online.de X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Volker Rümelin Simplify the resample buffer size calculation. For audio playback we have sw->ratio = ((int64_t)sw->hw->info.freq << 32) / sw->info.freq; samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio; This can be simplified to samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq); For audio recording we have sw->ratio = ((int64_t)sw->info.freq << 32) / sw->hw->info.freq; samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32; This can be simplified to samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq); With hw = sw->hw this becomes in both cases samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq); Now that sw->ratio is no longer needed, remove sw->ratio. Signed-off-by: Volker Rümelin --- audio/audio.c | 1 - audio/audio_int.h | 2 -- audio/audio_template.h | 9 +-------- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index b846b89a27..b68ed4eb68 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -476,7 +476,6 @@ static int audio_attach_capture (HWVoiceOut *hw) sw->info = hw->info; sw->empty = 1; sw->active = hw->enabled; - sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq; sw->vol = nominal_volume; sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq); QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries); diff --git a/audio/audio_int.h b/audio/audio_int.h index f4ec5dcf11..3cd3539bd4 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -108,7 +108,6 @@ struct SWVoiceOut { AudioState *s; struct audio_pcm_info info; t_sample *conv; - int64_t ratio; STSampleBuffer resample_buf; void *rate; size_t total_hw_samples_mixed; @@ -126,7 +125,6 @@ struct SWVoiceIn { AudioState *s; int active; struct audio_pcm_info info; - int64_t ratio; void *rate; size_t total_hw_samples_acquired; STSampleBuffer resample_buf; diff --git a/audio/audio_template.h b/audio/audio_template.h index 0cdf57760e..c053792da3 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -114,11 +114,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) return 0; } -#ifdef DAC - samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio; -#else - samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32; -#endif + samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq); if (samples == 0) { size_t f_fe_min; @@ -159,11 +155,8 @@ static int glue (audio_pcm_sw_init_, TYPE) ( sw->hw = hw; sw->active = 0; #ifdef DAC - sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq; sw->total_hw_samples_mixed = 0; sw->empty = 1; -#else - sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq; #endif if (sw->info.is_float) {