diff options
author | Kővágó, Zoltán <dirty.ice.hu@gmail.com> | 2019-10-13 21:58:02 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-10-18 08:14:05 +0200 |
commit | 2b9cce8c8c37b95290c48c037e51e001985124d1 (patch) | |
tree | 82fbbf3fff30c561215cada4c3f2a97f8cda1dbb /audio/audio.c | |
parent | cecc1e79bf9ad9a0e2d3ce513d4f71792a0985f6 (diff) | |
download | qemu-2b9cce8c8c37b95290c48c037e51e001985124d1.zip qemu-2b9cce8c8c37b95290c48c037e51e001985124d1.tar.gz qemu-2b9cce8c8c37b95290c48c037e51e001985124d1.tar.bz2 |
audio: replace shift in audio_pcm_info with bytes_per_frame
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 <DirtY.iCE.hu@gmail.com>
Message-id: 1351fd9bcce0ff20d81850c5292722194329de02.1570996490.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'audio/audio.c')
-rw-r--r-- | audio/audio.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/audio/audio.c b/audio/audio.c index f1c145d..c00f4de 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -299,12 +299,13 @@ 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: @@ -312,7 +313,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) /* fall through */ case AUDIO_FORMAT_U16: bits = 16; - shift = 1; + mul = 2; break; case AUDIO_FORMAT_S32: @@ -320,7 +321,7 @@ void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as) /* fall through */ case AUDIO_FORMAT_U32: bits = 32; - shift = 2; + mul = 4; break; default: @@ -331,9 +332,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); } @@ -344,26 +344,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; } } @@ -373,14 +372,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; } } @@ -558,7 +556,7 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len) while (len) { st_sample *src = hw->mix_buf->samples + pos; - uint8_t *dst = advance(pcm_buf, clipped << hw->info.shift); + uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame); size_t samples_till_end_of_buf = hw->mix_buf->size - pos; size_t samples_to_clip = MIN(len, samples_till_end_of_buf); @@ -607,7 +605,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; } @@ -642,7 +640,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; } /* @@ -715,7 +713,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; @@ -759,13 +757,13 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size) dolog ( "%s: write size %zu ret %zu total sw %zu\n", SW_NAME (sw), - size >> sw->info.shift, + size / sw->info.bytes_per_frame, ret, sw->total_hw_samples_mixed ); #endif - return ret << sw->info.shift; + return ret * sw->info.bytes_per_frame; } #ifdef DEBUG_AUDIO @@ -882,7 +880,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) @@ -998,10 +996,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) @@ -1025,10 +1023,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, @@ -1047,7 +1046,7 @@ static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos, while (n) { size_t till_end_of_hw = hw->mix_buf->size - rpos2; size_t to_write = MIN(till_end_of_hw, n); - size_t bytes = to_write << hw->info.shift; + size_t bytes = to_write * hw->info.bytes_per_frame; size_t written; sw->buf = hw->mix_buf->samples + rpos2; @@ -1082,10 +1081,11 @@ static size_t audio_pcm_hw_run_out(HWVoiceOut *hw, size_t live) return clipped + live; } - decr = MIN(size >> hw->info.shift, live); + decr = MIN(size / hw->info.bytes_per_frame, live); audio_pcm_hw_clip_out(hw, buf, decr); - proc = hw->pcm_ops->put_buffer_out(hw, buf, decr << hw->info.shift) >> - hw->info.shift; + proc = hw->pcm_ops->put_buffer_out(hw, buf, + decr * hw->info.bytes_per_frame) / + hw->info.bytes_per_frame; live -= proc; clipped += proc; @@ -1234,16 +1234,16 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) while (samples) { size_t proc; - size_t size = samples << hw->info.shift; + size_t size = samples * hw->info.bytes_per_frame; void *buf = hw->pcm_ops->get_buffer_in(hw, &size); - assert((size & hw->info.align) == 0); + assert(size % hw->info.bytes_per_frame == 0); if (size == 0) { hw->pcm_ops->put_buffer_in(hw, buf, size); break; } - proc = MIN(size >> hw->info.shift, + proc = MIN(size / hw->info.bytes_per_frame, conv_buf->size - conv_buf->pos); hw->conv(conv_buf->samples + conv_buf->pos, buf, proc); @@ -1251,7 +1251,7 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples) samples -= proc; conv += proc; - hw->pcm_ops->put_buffer_in(hw, buf, proc << hw->info.shift); + hw->pcm_ops->put_buffer_in(hw, buf, proc * hw->info.bytes_per_frame); } return conv; @@ -1325,7 +1325,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; @@ -1378,7 +1378,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; @@ -1414,7 +1414,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; @@ -1833,7 +1833,7 @@ CaptureVoiceOut *AUD_add_capture( audio_pcm_init_info (&hw->info, as); - cap->buf = g_malloc0_n(hw->mix_buf->size, 1 << hw->info.shift); + cap->buf = g_malloc0_n(hw->mix_buf->size, hw->info.bytes_per_frame); hw->clip = mixeng_clip [hw->info.nchannels == 2] @@ -2153,14 +2153,14 @@ size_t audio_rate_get_bytes(struct audio_pcm_info *info, RateCtl *rate, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ticks = now - rate->start_ticks; bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND); - samples = (bytes - rate->bytes_sent) >> info->shift; + samples = (bytes - rate->bytes_sent) / info->bytes_per_frame; if (samples < 0 || samples > 65536) { AUD_log(NULL, "Resetting rate control (%" PRId64 " samples)\n", samples); audio_rate_start(rate); samples = 0; } - ret = MIN(samples << info->shift, bytes_avail); + ret = MIN(samples * info->bytes_per_frame, bytes_avail); rate->bytes_sent += ret; return ret; } |