aboutsummaryrefslogtreecommitdiff
path: root/hw/audio/hda-codec.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-12-04 08:02:37 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2023-12-04 08:02:37 -0500
commit173e8280643ad3b7221b12a8deafce826f5e7efb (patch)
treed8bb8b3ec5b4348743f5f0bdd62ac33a7e742ac4 /hw/audio/hda-codec.c
parent019f8c19df054fe14f18495bb95571c10cc0bf69 (diff)
parent95e1019a4a9b4b6e2caeb3fd392525e522a747db (diff)
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, cleanups, fixes misc fixes, cleanups Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmVrmhwPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRp/XsH/05hHtQqO+EnKSAW5SEwZnlLfzDcajVVPIkT # h6Yf6ahHNf4hG1qqa2CICqJtDAOQYamO128QjZdQxsnYejwBmZ/oG//neWh6qLPV # Hp4AaKV2MjKRQZPNblnrGUirxkSWSTqIONXp4FsVVpKOKW9IX5f9tH6nyFAqXWX7 # KzNY/3KD1CVSwAV1+hY2c6OzWVdTSJykPRocfB0jTYY1RygI0t57Hiq7v8AliGAx # 7ktSJFD9MBr+4Un7CQZWp24eyrL77j8U+YQRlPVYupkmQyuXHPdBr4RruHcGupIy # GeIvbkX1mTCEfOd/HFQ1X41hpf8AEyZjjq2SOEBncIRWY6EhSio= # =opjy # -----END PGP SIGNATURE----- # gpg: Signature made Sat 02 Dec 2023 15:57:00 EST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: vhost-user-scsi: free the inflight area when reset vhost-user: fix the reconnect error msix: unset PCIDevice::msix_vector_poll_notifier in rollback virtio-iommu: Remove useless !sdev check in virtio_iommu_probe() hw/i386: fix short-circuit logic with non-optimizing builds hw/acpi/erst: Do not ignore Error* in realize handler pcie_sriov: Remove g_new assertion virtio-sound: add realize() error cleanup path virtio-snd: check AUD_register_card return value hw/audio/hda-codec: reenable the audio mixer hw/audio/hda-codec: fix multiplication overflow hw/audio/virtio-snd-pci: fix the PCI class code tests/acpi/bios-tables-test: do not write new blobs unless there are changes netdev: set timeout depending on loadavg osdep: add getloadavg Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/audio/hda-codec.c')
-rw-r--r--hw/audio/hda-codec.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index b9ad1f4c39..0bc20d49f6 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -22,6 +22,7 @@
#include "hw/qdev-properties.h"
#include "intel-hda.h"
#include "migration/vmstate.h"
+#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "intel-hda-defs.h"
#include "audio/audio.h"
@@ -189,9 +190,9 @@ struct HDAAudioState {
bool use_timer;
};
-static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
+static inline uint32_t hda_bytes_per_second(HDAAudioStream *st)
{
- return 2LL * st->as.nchannels * st->as.freq;
+ return 2 * (uint32_t)st->as.nchannels * (uint32_t)st->as.freq;
}
static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
@@ -222,12 +223,18 @@ static void hda_audio_input_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t buft_start = st->buft_start;
+ int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
+ int64_t wanted_rpos;
- int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
- / NANOSECONDS_PER_SECOND;
+ if (uptime <= 0) {
+ /* wanted_rpos <= 0 */
+ goto out_timer;
+ }
+
+ wanted_rpos = muldiv64(uptime, hda_bytes_per_second(st),
+ NANOSECONDS_PER_SECOND);
wanted_rpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_rpos <= rpos) {
@@ -286,12 +293,18 @@ static void hda_audio_output_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t buft_start = st->buft_start;
+ int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
+ int64_t wanted_wpos;
+
+ if (uptime <= 0) {
+ /* wanted_wpos <= 0 */
+ goto out_timer;
+ }
- int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
- / NANOSECONDS_PER_SECOND;
+ wanted_wpos = muldiv64(uptime, hda_bytes_per_second(st),
+ NANOSECONDS_PER_SECOND);
wanted_wpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_wpos <= wpos) {
@@ -855,10 +868,10 @@ static Property hda_audio_properties[] = {
static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &output_nomixemu;
+ const struct desc_codec *desc = &output_mixemu;
if (!a->mixer) {
- desc = &output_mixemu;
+ desc = &output_nomixemu;
}
hda_audio_init(hda, desc, errp);
@@ -867,10 +880,10 @@ static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &duplex_nomixemu;
+ const struct desc_codec *desc = &duplex_mixemu;
if (!a->mixer) {
- desc = &duplex_mixemu;
+ desc = &duplex_nomixemu;
}
hda_audio_init(hda, desc, errp);
@@ -879,10 +892,10 @@ static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &micro_nomixemu;
+ const struct desc_codec *desc = &micro_mixemu;
if (!a->mixer) {
- desc = &micro_mixemu;
+ desc = &micro_nomixemu;
}
hda_audio_init(hda, desc, errp);