From patchwork Mon Aug 17 18:12:01 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: 508046 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 BB90414012C for ; Tue, 18 Aug 2015 04:12:59 +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=JnqCMLAr; dkim-atps=neutral Received: from localhost ([::1]:56257 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZROtz-0001c2-W0 for incoming@patchwork.ozlabs.org; Mon, 17 Aug 2015 14:12:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58464) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZROtC-00014j-AN for qemu-devel@nongnu.org; Mon, 17 Aug 2015 14:12:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZROtA-0008FL-0P for qemu-devel@nongnu.org; Mon, 17 Aug 2015 14:12:06 -0400 Received: from mail-wi0-x233.google.com ([2a00:1450:400c:c05::233]:34831) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZROt9-0008Ew-Eq for qemu-devel@nongnu.org; Mon, 17 Aug 2015 14:12:03 -0400 Received: by wicne3 with SMTP id ne3so76944236wic.0 for ; Mon, 17 Aug 2015 11:12:02 -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=oxwRwg7RhUGr+6Rg0Rrj9H6AN7g2QKxskpPMQ5dgI0g=; b=JnqCMLArFqRRTx+cz5X9aHHrvqjkSgIa25KGgah9ZhMoJwrjk14eVn/qefCyKDBCF5 RnKKjpLFTPvfBf8ZkqJm38J40L2RI9kO92mxcDrhMQxhhSOlsEX4tV0UzWMKDt/6Ubby 31v+WG7pKVEKAjXe37UwqXUxqlD2E6A704/hFAUeuFkvdW+rkL0HRxzqGBtZH46ww5r4 8bHLtnfXUtq1d063AHzB/sVhu1wRsBUD8LnJEPWbAe+5HLyO81vqxlx1AiMhDag2hWvh psu9lP4hMiWjT/KoFVHxQ68yblyR5tQpI6nOXW9I/Pfuv5jms5UvfcTpWAB+jUeNQjtB Hu0Q== X-Received: by 10.194.78.84 with SMTP id z20mr5074119wjw.141.1439835122902; Mon, 17 Aug 2015 11:12:02 -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 ny7sm17774432wic.11.2015.08.17.11.12.02 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 17 Aug 2015 11:12:02 -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: Mon, 17 Aug 2015 20:12:01 +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::233 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 1/5] audio: replace shift in audio_pcm_info with bytes_per_frame 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 The bit shifting trick worked because the number of bytes per frame was always a power-of-two (since QEMU only supports mono, stereo and 8, 16 and 32 bit samples). But if we want to add support for surround sound, this no longer holds true. Signed-off-by: Kővágó, Zoltán --- audio/alsaaudio.c | 10 ++++---- audio/audio.c | 68 ++++++++++++++++++++++++------------------------- audio/audio_int.h | 3 +-- audio/coreaudio.c | 4 +-- audio/dsound_template.h | 10 ++++---- audio/dsoundaudio.c | 4 +-- audio/noaudio.c | 2 +- audio/ossaudio.c | 14 +++++----- audio/wavaudio.c | 6 ++--- 9 files changed, 60 insertions(+), 61 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 7834633..148df13 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -613,7 +613,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; size_t pos = 0; - size_t len_frames = len >> hw->info.shift; + size_t len_frames = len / hw->info.bytes_per_frame; while (len_frames) { char *src = advance(buf, pos); @@ -657,7 +657,7 @@ static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) } } - pos += written << hw->info.shift; + pos += written * hw->info.bytes_per_frame; if (written < len_frames) { break; } @@ -823,7 +823,7 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) void *dst = advance(buf, pos); snd_pcm_sframes_t nread; - nread = snd_pcm_readi(alsa->handle, dst, len >> hw->info.shift); + nread = snd_pcm_readi(alsa->handle, dst, len / hw->info.bytes_per_frame); if (nread <= 0) { switch (nread) { @@ -849,8 +849,8 @@ static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len) } } - pos += nread << hw->info.shift; - len -= nread << hw->info.shift; + pos += nread * hw->info.bytes_per_frame; + len -= nread * hw->info.bytes_per_frame; } return pos; diff --git a/audio/audio.c b/audio/audio.c index ebe241d..bc32312 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -267,26 +267,27 @@ static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *a void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) { - int bits = 8, sign = 0, shift = 0; + int bits = 8, sign = 0, mul; switch (as->fmt) { case AUDIO_FORMAT_S8: sign = 1; case AUDIO_FORMAT_U8: + mul = 1; break; case AUDIO_FORMAT_S16: sign = 1; case AUDIO_FORMAT_U16: bits = 16; - shift = 1; + mul = 2; break; case AUDIO_FORMAT_S32: sign = 1; case AUDIO_FORMAT_U32: bits = 32; - shift = 2; + mul = 4; break; default: @@ -297,9 +298,8 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) info->bits = bits; info->sign = sign; info->nchannels = as->nchannels; - info->shift = (as->nchannels == 2) + shift; - info->align = (1 << info->shift) - 1; - info->bytes_per_second = info->freq << info->shift; + info->bytes_per_frame = as->nchannels * mul; + info->bytes_per_second = info->freq * info->bytes_per_frame; info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS); } @@ -310,26 +310,25 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) } if (info->sign) { - memset (buf, 0x00, len << info->shift); + memset (buf, 0x00, len * info->bytes_per_frame); } else { switch (info->bits) { case 8: - memset (buf, 0x80, len << info->shift); + memset (buf, 0x80, len * info->bytes_per_frame); break; case 16: { int i; uint16_t *p = buf; - int shift = info->nchannels - 1; short s = INT16_MAX; if (info->swap_endianness) { s = bswap16 (s); } - for (i = 0; i < len << shift; i++) { + for (i = 0; i < len * info->nchannels; i++) { p[i] = s; } } @@ -339,14 +338,13 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len) { int i; uint32_t *p = buf; - int shift = info->nchannels - 1; int32_t s = INT32_MAX; if (info->swap_endianness) { s = bswap32 (s); } - for (i = 0; i < len << shift; i++) { + for (i = 0; i < len * info->nchannels; i++) { p[i] = s; } } @@ -530,7 +528,7 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, while (len) { st_sample *src = hw->mix_buf->samples + pos; - uint8_t *dst = advance (pcm_buf, clipped << hw->info.shift); + uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame); size_t samples_till_end_of_buf = hw->mix_buf->size - pos; size_t samples_to_clip = audio_MIN(len, samples_till_end_of_buf); @@ -579,7 +577,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) return 0; } - samples = size >> sw->info.shift; + samples = size / sw->info.bytes_per_frame; if (!live) { return 0; } @@ -614,7 +612,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size) sw->clip (buf, sw->buf, ret); sw->total_hw_samples_acquired += total; - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } /* @@ -688,7 +686,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) } wpos = (sw->hw->mix_buf->pos + live) % hwsamples; - samples = size >> sw->info.shift; + samples = size / sw->info.bytes_per_frame; dead = hwsamples - live; swlim = ((int64_t) dead << 32) / sw->ratio; @@ -732,13 +730,13 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) dolog ( "%s: write size %d ret %d total sw %d\n", SW_NAME (sw), - size >> sw->info.shift, + size / sw->info.bytes_per_frame, ret, sw->total_hw_samples_mixed ); #endif - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } #ifdef DEBUG_AUDIO @@ -838,7 +836,7 @@ size_t AUD_read(SWVoiceIn *sw, void *buf, size_t size) int AUD_get_buffer_size_out (SWVoiceOut *sw) { - return sw->hw->mix_buf->size << sw->hw->info.shift; + return sw->hw->mix_buf->size * sw->hw->info.bytes_per_frame; } void AUD_set_active_out (SWVoiceOut *sw, int on) @@ -953,10 +951,10 @@ static size_t audio_get_avail (SWVoiceIn *sw) ldebug ( "%s: get_avail live %d ret %" PRId64 "\n", SW_NAME (sw), - live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift + live, (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_frame ); - return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_frame; } static size_t audio_get_free(SWVoiceOut *sw) @@ -979,10 +977,11 @@ static size_t audio_get_free(SWVoiceOut *sw) #ifdef DEBUG_OUT dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n", SW_NAME (sw), - live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift); + live, dead, (((int64_t) dead << 32) / sw->ratio) * + sw->info.bytes_per_frame); #endif - return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; + return (((int64_t) dead << 32) / sw->ratio) * sw->info.bytes_per_frame; } static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, @@ -1001,7 +1000,7 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, while (n) { size_t till_end_of_hw = hw->mix_buf->size - rpos2; size_t to_write = audio_MIN (till_end_of_hw, n); - size_t bytes = to_write << hw->info.shift; + size_t bytes = to_write * hw->info.bytes_per_frame; size_t written; sw->buf = hw->mix_buf->samples + rpos2; @@ -1031,10 +1030,11 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) size_t size, decr, proc; void *buf = hw->pcm_ops->get_buffer_out(hw, &size); - decr = audio_MIN(size >> hw->info.shift, live); + decr = audio_MIN(size / hw->info.bytes_per_frame, live); audio_pcm_hw_clip_out(hw, buf, decr); - proc = hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shift) >> - hw->info.shift; + proc = hw->pcm_ops->put_buffer_out(hw, buf, + decr * hw->info.bytes_per_frame) / + hw->info.bytes_per_frame; live -= proc; clipped += proc; @@ -1269,7 +1269,7 @@ static void audio_run_capture (AudioState *s) for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) { cb->ops.capture (cb->opaque, cap->buf, - to_capture << hw->info.shift); + to_capture * hw->info.bytes_per_frame); } rpos = (rpos + to_capture) % hw->mix_buf->size; live -= to_capture; @@ -1322,7 +1322,7 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size) ssize_t start; if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->conv_buf->size << hw->info.shift; + size_t calc_size = hw->conv_buf->size * hw->info.bytes_per_frame; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; hw->pos_emul = hw->pending_emul = 0; @@ -1358,7 +1358,7 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size) void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size) { if (unlikely(!hw->buf_emul)) { - size_t calc_size = hw->mix_buf->size << hw->info.shift; + size_t calc_size = hw->mix_buf->size * hw->info.bytes_per_frame; hw->buf_emul = g_malloc(calc_size); hw->size_emul = calc_size; @@ -1745,11 +1745,11 @@ CaptureVoiceOut *AUD_add_capture( audio_pcm_init_info (&hw->info, as); cap->buf = audio_calloc(AUDIO_FUNC, hw->mix_buf->size, - 1 << hw->info.shift); + hw->info.bytes_per_frame); if (!cap->buf) { dolog ("Could not allocate capture buffer " "(%zu samples, each %d bytes)\n", - hw->mix_buf->size, 1 << hw->info.shift); + hw->mix_buf->size, hw->info.bytes_per_frame); goto err3; } @@ -2058,14 +2058,14 @@ size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - rate->start_ticks; bytes = muldiv64(ticks, info->bytes_per_second, get_ticks_per_sec()); - samples = (bytes - rate->bytes_sent) >> info->shift; + samples = (bytes - rate->bytes_sent) / info->bytes_per_frame; if (samples < 0 || samples > 65536) { AUD_log(NULL, "Resetting rate control (%" PRId64 " samples)", samples); audio_rate_start(rate); samples = 0; } - ret = audio_MIN(samples << info->shift, bytes_avail); + ret = audio_MIN(samples * info->bytes_per_frame, bytes_avail); rate->bytes_sent += ret; return ret; } diff --git a/audio/audio_int.h b/audio/audio_int.h index 8b53c52..0c0289d 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -42,8 +42,7 @@ struct audio_pcm_info { int sign; int freq; int nchannels; - int align; - int shift; + int bytes_per_frame; int bytes_per_second; int swap_endianness; }; diff --git a/audio/coreaudio.c b/audio/coreaudio.c index bf35b0b..deb2d99 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -225,7 +225,7 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; - pending_frames = hw->pending_emul >> hw->info.shift; + pending_frames = hw->pending_emul / hw->info.bytes_per_frame; /* if there are not enough samples, set signal and return */ if (pending_frames < frameCount) { @@ -234,7 +234,7 @@ static OSStatus audioDeviceIOProc( return 0; } - len = frameCount << hw->info.shift; + len = frameCount * hw->info.bytes_per_frame; while (len) { size_t write_len; ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; diff --git a/audio/dsound_template.h b/audio/dsound_template.h index 6a10b67..d262c1e 100644 --- a/audio/dsound_template.h +++ b/audio/dsound_template.h @@ -98,8 +98,8 @@ static int glue (dsound_lock_, TYPE) ( goto fail; } - if ((p1p && *p1p && (*blen1p & info->align)) || - (p2p && *p2p && (*blen2p & info->align))) { + if ((p1 && (blen1 % info->bytes_per_frame)) || + (p2 && (blen2 % info->bytes_per_frame))) { dolog ("DirectSound returned misaligned buffer %ld %ld\n", *blen1p, *blen2p); glue (dsound_unlock_, TYPE) (buf, *p1p, p2p ? *p2p : NULL, *blen1p, @@ -247,14 +247,14 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as, obt_as.endianness = 0; audio_pcm_init_info (&hw->info, &obt_as); - if (bc.dwBufferBytes & hw->info.align) { + if (bc.dwBufferBytes % hw->info.bytes_per_frame) { dolog ( "GetCaps returned misaligned buffer size %ld, alignment %d\n", - bc.dwBufferBytes, hw->info.align + 1 + bc.dwBufferBytes, hw->info.bytes_per_frame ); } hw->size_emul = bc.dwBufferBytes; - ds->samples = bc.dwBufferBytes >> hw->info.shift; + ds->samples = bc.dwBufferBytes / hw->info.bytes_per_frame; ds->s = s; #ifdef DEBUG_DSOUND diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index e55dd46..3efe218 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -320,8 +320,8 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb, return; } - len1 = blen1 >> hw->info.shift; - len2 = blen2 >> hw->info.shift; + len1 = blen1 / hw->info.bytes_per_frame; + len2 = blen2 / hw->info.bytes_per_frame; #ifdef DEBUG_DSOUND dolog ("clear %p,%ld,%ld %p,%ld,%ld\n", diff --git a/audio/noaudio.c b/audio/noaudio.c index 0618b60..32fbf64 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -86,7 +86,7 @@ static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) NoVoiceIn *no = (NoVoiceIn *) hw; int64_t bytes = audio_rate_get_bytes(&hw->info, &no->rate, size); - audio_pcm_info_clear_buf(&hw->info, buf, bytes >> hw->info.shift); + audio_pcm_info_clear_buf(&hw->info, buf, bytes / hw->info.bytes_per_frame); return bytes; } diff --git a/audio/ossaudio.c b/audio/ossaudio.c index a854d5a..b5efbbf 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -511,16 +511,16 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as, oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - if (obt.nfrags * obt.fragsize & hw->info.align) { + if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) { dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n", - obt.nfrags * obt.fragsize, hw->info.align + 1); + obt.nfrags * obt.fragsize, hw->info.bytes_per_frame); } - oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; oss->mmapped = 0; if (oopts->has_try_mmap && oopts->try_mmap) { - hw->size_emul = oss->samples << hw->info.shift; + hw->size_emul = oss->samples * hw->info.bytes_per_frame; hw->buf_emul = mmap ( NULL, hw->size_emul, @@ -655,12 +655,12 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) oss->nfrags = obt.nfrags; oss->fragsize = obt.fragsize; - if (obt.nfrags * obt.fragsize & hw->info.align) { + if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) { dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n", - obt.nfrags * obt.fragsize, hw->info.align + 1); + obt.nfrags * obt.fragsize, hw->info.bytes_per_frame); } - oss->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; + oss->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame; oss->fd = fd; oss->dev = dev; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 5b35173..487a1bb 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -40,14 +40,14 @@ static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len) { WAVVoiceOut *wav = (WAVVoiceOut *) hw; int64_t bytes = audio_rate_get_bytes(&hw->info, &wav->rate, len); - assert(bytes >> hw->info.shift << hw->info.shift == bytes); + assert(bytes % hw->info.bytes_per_frame == 0); if (bytes && fwrite(buf, bytes, 1, wav->f) != 1) { dolog("wav_write_out: fwrite of %zu bytes failed\nReaons: %s\n", bytes, strerror(errno)); } - wav->total_samples += bytes >> hw->info.shift; + wav->total_samples += bytes / hw->info.bytes_per_frame; return bytes; } @@ -130,7 +130,7 @@ static void wav_fini_out (HWVoiceOut *hw) WAVVoiceOut *wav = (WAVVoiceOut *) hw; uint8_t rlen[4]; uint8_t dlen[4]; - uint32_t datalen = wav->total_samples << hw->info.shift; + uint32_t datalen = wav->total_samples * hw->info.bytes_per_frame; uint32_t rifflen = datalen + 36; if (!wav->f) {