From patchwork Fri Aug 21 15:37:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?UTF-8?B?Wm9sdMOhbiBLxZF2w6Fnw7M=?= X-Patchwork-Id: 509562 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9F8611402C8 for ; Sat, 22 Aug 2015 01:59:47 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=atYTGQcX; dkim-atps=neutral Received: from localhost ([::1]:42316 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSojJ-0001Ja-Ja for incoming@patchwork.ozlabs.org; Fri, 21 Aug 2015 11:59:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51137) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSoOY-00030x-JV for qemu-devel@nongnu.org; Fri, 21 Aug 2015 11:38:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZSoOW-0002F6-I9 for qemu-devel@nongnu.org; Fri, 21 Aug 2015 11:38:18 -0400 Received: from mail-wi0-x231.google.com ([2a00:1450:400c:c05::231]:34900) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZSoOW-0002Eu-7c for qemu-devel@nongnu.org; Fri, 21 Aug 2015 11:38:16 -0400 Received: by wicne3 with SMTP id ne3so19128653wic.0 for ; Fri, 21 Aug 2015 08:38:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=CLSLCpsEtAhQkx1aCGVRYHp0QqMKXdG+GLnVSrdJVUU=; b=atYTGQcX6LLGTw9XHEfeDYMmmA3f/ITd26Juh5i8sgVYBFfDu06c3Oc0jMBuL8xyBn +nxlBnOt7J+Zc773yDU1zL5lznT4zcXLO3u0nsgQmDAGLbt9KNRcZTIX7kmBjtXEKSgh VlzD0tDGj7umIY4HpfYQYp4uGZW7qN0ziQR3fqW5kbpr5/US3yzdgsG/HizSOEkn3UvL QgkVQz68llzCP3lXSg0ak3R3omzZccFK+sA5uhC4B8fCeZdLyaDArkHPvIQSKwT4Low7 pFKdgKZZcatR3c4cXIg6bC/HoKgJQaZFFeyagd/cfuNf5O6adQYlsFRGflPtpQELC9LO nI+Q== X-Received: by 10.180.87.71 with SMTP id v7mr7254258wiz.74.1440171495675; Fri, 21 Aug 2015 08:38:15 -0700 (PDT) Received: from nullptr.home.dirty-ice.org (178-164-172-216.pool.digikabel.hu. [178.164.172.216]) by smtp.gmail.com with ESMTPSA id v8sm10479895wjr.15.2015.08.21.08.38.15 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 21 Aug 2015 08:38:15 -0700 (PDT) From: "=?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?=" X-Google-Original-From: =?UTF-8?q?K=C5=91v=C3=A1g=C3=B3=2C=20Zolt=C3=A1n?= To: qemu-devel@nongnu.org Date: Fri, 21 Aug 2015 17:37:42 +0200 Message-Id: X-Mailer: git-send-email 2.5.0 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::231 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 46/49] audio: unify input and output mixeng buffer management X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 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 Signed-off-by: Kővágó, Zoltán --- audio/audio.c | 123 +++++++++++++++++++++++-------------------------- audio/audio_int.h | 12 +++-- audio/audio_template.h | 18 +++----- 3 files changed, 71 insertions(+), 82 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 584400c..4ae91e4 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -515,8 +515,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(AUDIO_FUNC, live > hw->samples)) { - dolog("live=%zu samples=%zu\n", live, hw->samples); + if (audio_bug(AUDIO_FUNC, live > hw->conv_buf->size)) { + dolog("live=%zu samples=%zu\n", live, hw->conv_buf->size); return 0; } return live; @@ -525,17 +525,17 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw) static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) { size_t clipped = 0; - size_t pos = hw->rpos; + size_t pos = hw->mix_buf->pos; while (len) { - st_sample *src = hw->mix_buf + pos; + st_sample *src = hw->mix_buf->samples + pos; uint8_t *dst = advance (pcm_buf, clipped << hw->info.shift); - size_t samples_till_end_of_buf = hw->samples - pos; + size_t samples_till_end_of_buf = hw->mix_buf->size - pos; size_t samples_to_clip = MIN(len, samples_till_end_of_buf); hw->clip (dst, src, samples_to_clip); - pos = (pos + samples_to_clip) % hw->samples; + pos = (pos + samples_to_clip) % hw->mix_buf->size; len -= samples_to_clip; clipped += samples_to_clip; } @@ -550,17 +550,17 @@ static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw) ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired; ssize_t rpos; - if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { - dolog("live=%zd samples=%zu\n", live, hw->samples); + if (audio_bug(AUDIO_FUNC, live < 0 || live > hw->conv_buf->size)) { + dolog("live=%zd samples=%zu\n", live, hw->conv_buf->size); return 0; } - rpos = hw->wpos - live; + rpos = hw->conv_buf->pos - live; if (rpos >= 0) { return rpos; } else { - return hw->samples + rpos; + return hw->conv_buf->size + rpos; } } @@ -570,11 +570,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; struct st_sample *src, *dst = sw->buf; - rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; + rpos = audio_pcm_sw_get_rpos_in(sw) % hw->conv_buf->size; live = hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(AUDIO_FUNC, live > hw->samples)) { - dolog("live_in=%zu samples=%zu\n", live, hw->samples); + if (audio_bug(AUDIO_FUNC, live > hw->conv_buf->size)) { + dolog("live_in=%zu samples=%zu\n", live, hw->conv_buf->size); return 0; } @@ -587,11 +587,11 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) swlim = MIN (swlim, samples); while (swlim) { - src = hw->conv_buf + rpos; - if (hw->wpos > rpos) { - isamp = hw->wpos - rpos; + src = hw->conv_buf->samples + rpos; + if (hw->conv_buf->pos > rpos) { + isamp = hw->conv_buf->pos - rpos; } else { - isamp = hw->samples - rpos; + isamp = hw->conv_buf->size - rpos; } if (!isamp) { @@ -601,7 +601,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) st_rate_flow (sw->rate, src, dst, &isamp, &osamp); swlim -= osamp; - rpos = (rpos + isamp) % hw->samples; + rpos = (rpos + isamp) % hw->conv_buf->size; dst += osamp; ret += osamp; total += isamp; @@ -649,8 +649,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(AUDIO_FUNC, live > hw->samples)) { - dolog("live=%zu hw->samples=%zu\n", live, hw->samples); + if (audio_bug(AUDIO_FUNC, live > hw->mix_buf->size)) { + dolog("live=%zu hw->samples=%zu\n", live, hw->mix_buf->size); return 0; } return live; @@ -671,7 +671,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return size; } - hwsamples = sw->hw->samples; + hwsamples = sw->hw->mix_buf->size; live = sw->total_hw_samples_mixed; if (audio_bug(AUDIO_FUNC, live > hwsamples)){ @@ -686,7 +686,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) return 0; } - wpos = (sw->hw->rpos + live) % hwsamples; + wpos = (sw->hw->mix_buf->pos + live) % hwsamples; samples = size >> sw->info.shift; dead = hwsamples - live; @@ -712,7 +712,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) st_rate_flow_mix ( sw->rate, sw->buf + pos, - sw->hw->mix_buf + wpos, + sw->hw->mix_buf->samples + wpos, &isamp, &osamp ); @@ -823,7 +823,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) int AUD_get_buffer_size_out (SWVoiceOut *sw) { - return sw->hw->samples << sw->hw->info.shift; + return sw->hw->mix_buf->size << sw->hw->info.shift; } void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -924,8 +924,8 @@ static size_t audio_get_avail (SWVoiceIn *sw) } live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; - if (audio_bug(AUDIO_FUNC, live > sw->hw->samples)) { - dolog("live=%zu samples=%zu\n", live, sw->hw->samples); + if (audio_bug(AUDIO_FUNC, live > sw->hw->conv_buf->size)) { + dolog("live=%zu samples=%zu\n", live, sw->hw->conv_buf->size); return 0; } @@ -948,12 +948,12 @@ static size_t audio_get_free(SWVoiceOut *sw) live = sw->total_hw_samples_mixed; - if (audio_bug(AUDIO_FUNC, live > sw->hw->samples)) { - dolog("live=%zu samples=%zu\n", live, sw->hw->samples); + if (audio_bug(AUDIO_FUNC, live > sw->hw->mix_buf->size)) { + dolog("live=%zu samples=%zu\n", live, sw->hw->mix_buf->size); return 0; } - dead = sw->hw->samples - live; + dead = sw->hw->mix_buf->size - live; #ifdef DEBUG_OUT dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n", @@ -978,12 +978,12 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, n = samples; while (n) { - size_t till_end_of_hw = hw->samples - rpos2; + size_t till_end_of_hw = hw->mix_buf->size - rpos2; size_t to_write = MIN(till_end_of_hw, n); size_t bytes = to_write << hw->info.shift; size_t written; - sw->buf = hw->mix_buf + rpos2; + sw->buf = hw->mix_buf->samples + rpos2; written = audio_pcm_sw_write (sw, NULL, bytes); if (written - bytes) { dolog("Could not mix %zu bytes into a capture " @@ -992,14 +992,14 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, break; } n -= to_write; - rpos2 = (rpos2 + to_write) % hw->samples; + rpos2 = (rpos2 + to_write) % hw->mix_buf->size; } } } - n = MIN(samples, hw->samples - rpos); - mixeng_clear(hw->mix_buf + rpos, n); - mixeng_clear(hw->mix_buf, samples - n); + n = MIN(samples, hw->mix_buf->size - rpos); + mixeng_clear(hw->mix_buf->samples + rpos, n); + mixeng_clear(hw->mix_buf->samples, samples - n); } static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) @@ -1017,7 +1017,7 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) live -= proc; clipped += proc; - hw->rpos = (hw->rpos + proc) % hw->samples; + hw->mix_buf->pos = (hw->mix_buf->pos + proc) % hw->mix_buf->size; if (proc == 0 || proc < decr) { break; @@ -1041,8 +1041,8 @@ static void audio_run_out (AudioState *s) live = 0; } - if (audio_bug(AUDIO_FUNC, live > hw->samples)) { - dolog("live=%zu samples=%zu\n", live, hw->samples); + if (audio_bug(AUDIO_FUNC, live > hw->mix_buf->size)) { + dolog("live=%zu samples=%zu\n", live, hw->mix_buf->size); continue; } @@ -1073,12 +1073,12 @@ static void audio_run_out (AudioState *s) continue; } - prev_rpos = hw->rpos; + prev_rpos = hw->mix_buf->pos; played = audio_pcm_hw_run_out(hw, live); - if (audio_bug(AUDIO_FUNC, hw->rpos >= hw->samples)) { + if (audio_bug(AUDIO_FUNC, hw->mix_buf->pos >= hw->mix_buf->size)) { dolog("rpos=%zu samples=%zu played=%zu\n", - hw->rpos, hw->samples, played); - hw->rpos = 0; + hw->mix_buf->pos, hw->mix_buf->size, played); + hw->mix_buf->pos = 0; } #ifdef DEBUG_OUT @@ -1135,6 +1135,7 @@ static void audio_run_out (AudioState *s) static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) { size_t conv = 0; + STSampleBuffer *conv_buf = hw->conv_buf; while (samples) { size_t proc; @@ -1148,10 +1149,10 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) } proc = MIN(size >> hw->info.shift, - hw->samples - hw->wpos); + conv_buf->size - conv_buf->pos); - hw->conv(hw->conv_buf + hw->wpos, buf, proc); - hw->wpos = (hw->wpos + proc) % hw->samples; + hw->conv(conv_buf->samples + conv_buf->pos, buf, proc); + conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size; samples -= proc; conv += proc; @@ -1170,7 +1171,7 @@ static void audio_run_in (AudioState *s) size_t captured, min; captured = audio_pcm_hw_run_in( - hw, hw->samples - audio_pcm_hw_get_live_in(hw)); + hw, hw->conv_buf->size - audio_pcm_hw_get_live_in(hw)); min = audio_pcm_hw_find_min_in (hw); hw->total_samples_captured += captured - min; @@ -1201,14 +1202,14 @@ static void audio_run_capture (AudioState *s) SWVoiceOut *sw; captured = live = audio_pcm_hw_get_live_out (hw, NULL); - rpos = hw->rpos; + rpos = hw->mix_buf->pos; while (live) { - size_t left = hw->samples - rpos; + size_t left = hw->mix_buf->size - rpos; size_t to_capture = MIN(live, left); struct st_sample *src; struct capture_callback *cb; - src = hw->mix_buf + rpos; + src = hw->mix_buf->samples + rpos; hw->clip (cap->buf, src, to_capture); mixeng_clear (src, to_capture); @@ -1216,10 +1217,10 @@ static void audio_run_capture (AudioState *s) cb->ops.capture (cb->opaque, cap->buf, to_capture << hw->info.shift); } - rpos = (rpos + to_capture) % hw->samples; + rpos = (rpos + to_capture) % hw->mix_buf->size; live -= to_capture; } - hw->rpos = rpos; + hw->mix_buf->pos = rpos; for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { if (!sw->active && sw->empty) { @@ -1267,7 +1268,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) ssize_t start; if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->samples << hw->info.shift; + size_t calc_size = hw->conv_buf->size << hw->info.shift; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; hw->pos_emul = hw->pending_emul = 0; @@ -1303,7 +1304,7 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size) void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size) { if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->samples << hw->info.shift; + size_t calc_size = hw->mix_buf->size << hw->info.shift; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; @@ -1678,23 +1679,16 @@ CaptureVoiceOut *AUD_add_capture( QLIST_INIT (&hw->sw_head); QLIST_INIT (&cap->cb_head); - /* XXX find a more elegant way */ - hw->samples = 4096 * 4; - hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples, - sizeof (struct st_sample)); - if (!hw->mix_buf) { - dolog("Could not allocate capture mix buffer (%zu samples)\n", - hw->samples); - goto err2; - } + audio_pcm_hw_alloc_resources_out(hw); audio_pcm_init_info (&hw->info, as); - cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); + cap->buf = audio_calloc(AUDIO_FUNC, hw->mix_buf->size, + 1 << hw->info.shift); if (!cap->buf) { dolog ("Could not allocate capture buffer " "(%zu samples, each %d bytes)\n", - hw->samples, 1 << hw->info.shift); + hw->mix_buf->size, 1 << hw->info.shift); goto err3; } @@ -1715,7 +1709,6 @@ CaptureVoiceOut *AUD_add_capture( err3: g_free (cap->hw.mix_buf); - err2: g_free (cap); err1: g_free (cb); diff --git a/audio/audio_int.h b/audio/audio_int.h index 487867c..031f699 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -50,6 +50,11 @@ struct audio_pcm_info { typedef struct SWVoiceCap SWVoiceCap; +typedef struct STSampleBuffer { + size_t pos, size; + st_sample samples[]; +} STSampleBuffer; + typedef struct HWVoiceOut { AudioState *s; int enabled; @@ -58,11 +63,9 @@ typedef struct HWVoiceOut { struct audio_pcm_info info; f_sample *clip; - - size_t rpos; uint64_t ts_helper; - struct st_sample *mix_buf; + STSampleBuffer *mix_buf; void *buf_emul; size_t pos_emul, pending_emul, size_emul; @@ -82,11 +85,10 @@ typedef struct HWVoiceIn { t_sample *conv; - size_t wpos; size_t total_samples_captured; uint64_t ts_helper; - struct st_sample *conv_buf; + STSampleBuffer *conv_buf; void *buf_emul; size_t pos_emul, pending_emul, size_emul; diff --git a/audio/audio_template.h b/audio/audio_template.h index f157695..a37aea3 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -76,16 +76,12 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) HWBUF = NULL; } -static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) +static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw) { - HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample)); - if (!HWBUF) { - dolog("Could not allocate " NAME " buffer (%zu samples)\n", - hw->samples); - return -1; - } + size_t samples = hw->samples; - return 0; + HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample)*samples); + HWBUF->size = samples; } static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) @@ -104,7 +100,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) { int samples; - samples = ((int64_t) sw->hw->samples << 32) / sw->ratio; + samples = ((int64_t) sw->HWBUF->size << 32) / sw->ratio; sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample)); if (!sw->buf) { @@ -280,9 +276,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s, [hw->info.swap_endianness] [audio_bits_to_index (hw->info.bits)]; - if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { - goto err1; - } + glue(audio_pcm_hw_alloc_resources_, TYPE)(hw); QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries); glue (s->nb_hw_voices_, TYPE) -= 1;