Commit 42061a1435 ("audio/mixeng: replace redundant pcm_info fields
with AudioFormat") accidentally changed the conv/clip function selection
in audio_pcm_sw_init_ to use hw->info.af (the hardware voice format)
instead of sw->info.af (the software voice format). This causes audio
distortion when the software and hardware voices use different formats,
as the wrong conversion functions are applied to the audio data.
Fix by using sw->info.af, restoring the original behavior.
Fixes: 42061a1435 ("audio/mixeng: replace redundant pcm_info fields with AudioFormat")
Reported-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
init_out_device may only commit some part of the result and leave the
state inconsistent when it encounters a fatal error or the device gets
unplugged during the operation, which is expressed by
kAudioHardwareBadObjectError or kAudioHardwareBadDeviceError. Commit the
result in the end of the function so that it commits the result iff it
sees no fatal error and the device remains plugged.
With this change, handle_voice_change can rely on core->outputDeviceID
to know whether the output device is initialized after calling
init_out_device.
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20260304-coreaudio-v8-4-bf1d40731e73@rsg.ci.i.u-tokyo.ac.jp>
coreaudio had names that are not conforming to QEMU codding style.
coreaudioVoiceOut also had some members that are prefixed with redundant
words like "output" or "audio".
Global names included "out" to tell they are specific to output devices,
but this rule was not completely enforced.
The frame size had three different names "frameSize", "bufferFrameSize",
and "frameCount".
Replace identifiers to fix these problems.
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20260304-coreaudio-v8-3-bf1d40731e73@rsg.ci.i.u-tokyo.ac.jp>
The NULL checks for be, name, callback_fn, and as in
audio_mixeng_backend_open_{in,out} are redundant: the callers
audio_be_open_{in,out} already assert that name, callback_fn, and as
are non-NULL, and dereference be unconditionally via
AUDIO_BACKEND_GET_CLASS(be) before the call.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20260224163229.2918858-1-marcandre.lureau@redhat.com>
Since commit 8f68a33ad4 we get on macOS:
Audio backends
CoreAudio support : YES
PipeWire support : NO
JACK support : YES 1.9.22
../audio/jackaudio.c:654:12: error: unused function 'qjack_thread_creator' [-Werror,-Wunused-function]
654 | static int qjack_thread_creator(jack_native_thread_t *thread,
| ^~~~~~~~~~~~~~~~~~~~
This is simply due to a missing #ifdef'ry change. Update
so we can use the new qemu_thread_set_name() exposed by
commit 46255cc2be.
Fixes: 8f68a33ad4 ("audio: make jackaudio use qemu_thread_set_name")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <20260307114923.75394-1-philmd@linaro.org>
This has greater portability than directly call pthread_setname_np,
which is only 1 out of 3 possible functions for pthreads that can
set the name.
The new API requires a trampoline function, since it can only set
the name of the current thread.
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
audio_bug() is a bit unconventional, it is meant to be used as a
condition expression, passing the actual condition as second argument
(and __func__ as first argument).
If the condition is true, it uses AUD_log() to print to stderr, and has
some dubious recommendations printed only once.
This change:
- clears the control flow, and make the condition directly visible in
the 'if' statement.
- uses standard QEMU error_report()
- audio_bug() now captures __func__
- remove the "Save all your work and restart..." once hint
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Currently, when given invalid settings, QEMU will print to stderr:
A bug was just triggered in audio_mixeng_backend_open_out
Save all your work and restart without audio
I am sorry
Context:
audio: frequency=44100 nchannels=0 fmt=S16 endianness=little
Now it will use error_report() and simply report:
audio: Invalid audio settings: frequency=44100 nchannels=0 fmt=s16 endian=little
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the ldebug macro calls with proper trace events:
- audio_get_avail: traces available samples in capture stream
- audio_open_out/audio_open_in: traces stream open parameters
This provides structured tracing that can be enabled at runtime
without requiring debug builds.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The endianness field used an int to represent a boolean concept, with
0 meaning little-endian and 1 meaning big-endian. This required runtime
validation to reject invalid values and made the code less readable.
Replace with a bool big_endian field that is self-documenting and
type-safe. The compiler now enforces valid values, eliminating the
need for the validation check in audio_validate_settings().
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The audio_pcm_info structure stored three fields (bits, is_signed,
is_float) that were always derived from the AudioFormat enum. This
redundancy meant the same information was represented twice, with no
type-level guarantee that they stayed in sync.
Replace these fields with a single AudioFormat field, and add helper
functions to extract the derived properties when needed:
- audio_format_bits()
- audio_format_is_signed()
- audio_format_is_float()
This improves type safety by making AudioFormat the single source of
truth, eliminating the possibility of inconsistent state between the
format enum and its derived boolean/integer representations.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Replace the custom audio logging infrastructure (dolog macro and
AUD_log/AUD_vlog) with standard QEMU error reporting (error_report,
error_printf, error_vprintf).
Note that we also dropped the abort() call in DEBUG_AUDIO, as it is not
usually compiled with, doesn't help much, and can easily be added back
when doing development as needed.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the custom audio logging infrastructure with standard QEMU
error reporting and tracing.
qpa_conn_init() is called during audio_pa_realize() and already reports
an error through Error *.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the custom audio logging infrastructure with standard QEMU
error reporting and tracing.
Note the patch drops DEBUG_MISMATCH condition, and now always trace
actual audio parameters.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the custom audio logging infrastructure with standard QEMU
error reporting and tracing.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The DirectSound audio backend uses its own logging infrastructure
(AUD_log, AUD_vlog, dolog) and the AUDIO_CAP macro. This approach is
inconsistent with the rest of QEMU and makes the output harder to
filter and configure.
Replace the custom logging with standard QEMU error reporting.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The DBus audio backend already uses error_report() for error logging.
Remove the unused AUDIO_CAP macro which was left over from the old
logging infrastructure.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The CoreAudio backend uses its own logging infrastructure (AUD_log,
AUD_vlog, dolog) and the AUDIO_CAP macro. This approach is inconsistent
with the rest of QEMU and makes the output harder to filter and
configure.
Replace the custom logging with standard QEMU error reporting:
- Use error_report() / error_printf() for errors
- Use warn_report() for non-fatal warnings (buffer frame size
adjustments)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
The ALSA audio backend uses its own logging infrastructure (AUD_log,
AUD_vlog, dolog, ldebug) and a custom alsa_dump_info() debug helper.
This approach is inconsistent with the rest of QEMU and makes the
output harder to filter and configure.
Replace the custom logging with standard QEMU error reporting:
- Use error_report() / error_printf() for errors
- Use warn_report() for non-fatal warnings (invalid formats,
rejected parameters, unexpected states)
- Convert ldebug() calls and alsa_dump_info() to trace events
Remove DEBUG_ALSA and AUDIO_CAP macros which are no longer needed.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Remove the separate audio_pcm_ops structure and move its function
pointers directly into AudioMixengBackendClass. This is a cleaner
QOM-style design where the PCM operations are part of the class
vtable rather than a separate indirection through hw->pcm_ops.
The HWVoiceOut and HWVoiceIn structures no longer need to store
a pcm_ops pointer, as the operations are now accessed through
the class with AUDIO_MIXENG_BACKEND_GET_CLASS().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Move all fields from audio_driver directly into AudioMixengBackendClass,
eliminating an unnecessary extra struct. Drivers now set class
fields directly in class_init instead of creating a static audio_driver
instance.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
They are no longer used after conversion to QOM.
Also removing the drv_opaque from a few of the pcm_ops methods.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Migrate the DirectSound audio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.
The dsound struct fields are now embedded directly in the AudioDsound
QOM object instead of being allocated separately as drv_opaque. This
allows accessing the backend state through proper QOM type casting
with AUDIO_DSOUND() rather than casting drv_opaque pointers.
The DirectSound and DirectSoundCapture COM objects are now managed
through the QOM lifecycle, with initialization in realize and cleanup
in finalize.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Remove the legacy driver init/fini callbacks from the CoreAudio backend.
Both coreaudio_audio_init() and coreaudio_audio_fini() were no-ops that
performed no real initialization or cleanup work. Access to the
Audiodev is now through hw->s->dev instead of the drv_opaque pointer.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Remove the legacy driver init/fini callbacks from the sndio audio backend.
Both sndio_audio_init() and sndio_audio_fini() were no-ops that
performed no real initialization or cleanup work. Access to the
Audiodev is now through hw->s->dev instead of the drv_opaque pointer.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Remove the legacy driver init/fini callbacks from the JACK audio backend.
Both qjack_init() and qjack_fini() were no-ops that performed no real
initialization or cleanup work. Access to the Audiodev is now through
hw->s->dev instead of the drv_opaque pointer.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Migrate the PipeWire audio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.
The pwaudio struct fields are now embedded directly in the AudioPw
QOM object instead of being allocated separately as drv_opaque. This
allows accessing the backend state through proper QOM type casting
with AUDIO_PW() rather than casting drv_opaque pointers.
The PipeWire thread loop and context are now managed through the QOM
lifecycle, with initialization in realize and cleanup in finalize.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Migrate the SDL audio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.
The sdl_audio_init() function is replaced with audio_sdl_realize(),
which initializes the SDL audio subsystem before delegating to the
parent class realize method. The sdl_audio_fini() is replaced with
audio_sdl_finalize() to properly clean up the SDL audio subsystem.
Access to the Audiodev is now through hw->s->dev instead of the
drv_opaque pointer.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Migrate the PulseAudio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.
The paaudio struct fields are now embedded directly in the AudioPa
QOM object instead of being allocated separately as drv_opaque. This
allows accessing the backend state through proper QOM type casting
with AUDIO_PA() rather than casting drv_opaque pointers.
The PulseAudio connection is now managed through the QOM lifecycle,
with the connection reference acquired in realize and released in
finalize.
Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>