Skip to content
Snippets Groups Projects
Commit 180b044f authored by Volker Rümelin's avatar Volker Rümelin Committed by Gerd Hoffmann
Browse files

coreaudio: fix coreaudio playback

There are reports that since commit 2ceb8240 "coreaudio: port
to the new audio backend api" audio playback with CoreAudio is
broken. This patch reverts some parts the commit.

Because of changes in the audio subsystem the audio clip
function in v4.1.0 of coreaudio.c had to be moved to mixeng.c
and the generic buffer management code needed a hint about the
size of the float type.

This patch is based on a patch from Zoltán Kővágó found at
https://lists.nongnu.org/archive/html/qemu-devel/2020-01/msg02142.html

.

Fixes: 2ceb8240 "coreaudio: port to the new audio backend api"

Signed-off-by: default avatarVolker Rümelin <vr_qemu@t-online.de>
Message-id: 20200202140641.4737-1-vr_qemu@t-online.de
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent fb35c2ce
No related branches found
No related tags found
No related merge requests found
......@@ -276,6 +276,13 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
goto err1;
}
if (s->dev->driver == AUDIODEV_DRIVER_COREAUDIO) {
#ifdef DAC
hw->clip = clip_natural_float_from_stereo;
#else
hw->conv = conv_natural_float_to_stereo;
#endif
} else
#ifdef DAC
hw->clip = mixeng_clip
#else
......
......@@ -471,20 +471,6 @@ static OSStatus audioDeviceIOProc(
return 0;
}
static UInt32 coreaudio_get_flags(struct audio_pcm_info *info,
struct audsettings *as)
{
UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0;
if (as->endianness) { /* 0 = little, 1 = big */
flags |= kAudioFormatFlagIsBigEndian;
}
if (flags == 0) { /* must not be 0 */
flags = kAudioFormatFlagsAreAllClear;
}
return flags;
}
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
void *drv_opaque)
{
......@@ -496,6 +482,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
Audiodev *dev = drv_opaque;
AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
int frames;
struct audsettings fake_as;
/* create mutex */
err = pthread_mutex_init(&core->mutex, NULL);
......@@ -504,6 +491,14 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
return -1;
}
/*
* The canonical audio format for CoreAudio on macOS is float. Currently
* there is no generic code for AUDIO_FORMAT_F32 in qemu. Here we select
* AUDIO_FORMAT_S32 instead because only the sample size has to match.
*/
fake_as = *as;
as = &fake_as;
as->fmt = AUDIO_FORMAT_S32;
audio_pcm_init_info (&hw->info, as);
status = coreaudio_get_voice(&core->outputDeviceID);
......@@ -572,15 +567,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
/* set Samplerate */
core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM;
core->outputStreamBasicDescription.mFormatFlags =
coreaudio_get_flags(&hw->info, as);
core->outputStreamBasicDescription.mBytesPerPacket =
core->outputStreamBasicDescription.mBytesPerFrame =
hw->info.nchannels * hw->info.bits / 8;
core->outputStreamBasicDescription.mFramesPerPacket = 1;
core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels;
core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits;
status = coreaudio_set_streamformat(core->outputDeviceID,
&core->outputStreamBasicDescription);
......
......@@ -267,6 +267,54 @@ f_sample *mixeng_clip[2][2][2][3] = {
}
};
void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
int samples)
{
float *in = (float *)src;
#ifndef FLOAT_MIXENG
const float scale = UINT_MAX;
#endif
while (samples--) {
#ifdef FLOAT_MIXENG
dst->l = *in++;
dst->r = *in++;
#else
dst->l = *in++ * scale;
dst->r = *in++ * scale;
#endif
dst++;
}
}
void clip_natural_float_from_stereo(void *dst, const struct st_sample *src,
int samples)
{
float *out = (float *)dst;
#ifndef FLOAT_MIXENG
#ifdef RECIPROCAL
const float scale = 1.f / UINT_MAX;
#else
const float scale = UINT_MAX;
#endif
#endif
while (samples--) {
#ifdef FLOAT_MIXENG
*out++ = src->l;
*out++ = src->r;
#else
#ifdef RECIPROCAL
*out++ = src->l * scale;
*out++ = src->r * scale;
#else
*out++ = src->l / scale;
*out++ = src->r / scale;
#endif
#endif
src++;
}
}
void audio_sample_to_uint64(void *samples, int pos,
uint64_t *left, uint64_t *right)
......
......@@ -41,6 +41,11 @@ typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
extern t_sample *mixeng_conv[2][2][2][3];
extern f_sample *mixeng_clip[2][2][2][3];
void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
int samples);
void clip_natural_float_from_stereo(void *dst, const struct st_sample *src,
int samples);
void *st_rate_start (int inrate, int outrate);
void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf,
size_t *isamp, size_t *osamp);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment