aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/audio_template.h7
-rw-r--r--audio/coreaudio.c32
-rw-r--r--audio/mixeng.c48
-rw-r--r--audio/mixeng.h5
4 files changed, 69 insertions, 23 deletions
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 3287d7075e..0336d2670c 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -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
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index c7a7196c2d..e3620b274b 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -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);
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 2f5ba71381..16b646d48c 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -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)
diff --git a/audio/mixeng.h b/audio/mixeng.h
index 18e62c7c49..7ef61763e8 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -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);