Commit 1d14ffa9 authored by bellard's avatar bellard

merged 15a_aqemu.patch audio patch (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1584 c046a42c-6fe2-441c-8c8c-71466251a162
parent 3b0d4f61
version 0.7.3:
- Mac OS X cocoa improvements (Mike Kronenberg)
- DirectSound driver (malc)
- new audio options: '-soundhw' and 'audio-help' (malc)
- ES1370 PCI audio device (malc)
version 0.7.2: version 0.7.2:
- x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit) - x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit)
......
...@@ -262,7 +262,7 @@ endif ...@@ -262,7 +262,7 @@ endif
VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o
VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
SOUND_HW = sb16.o SOUND_HW = sb16.o es1370.o
AUDIODRV = audio.o noaudio.o wavaudio.o AUDIODRV = audio.o noaudio.o wavaudio.o
ifdef CONFIG_SDL ifdef CONFIG_SDL
AUDIODRV += sdlaudio.o AUDIODRV += sdlaudio.o
...@@ -270,29 +270,38 @@ endif ...@@ -270,29 +270,38 @@ endif
ifdef CONFIG_OSS ifdef CONFIG_OSS
AUDIODRV += ossaudio.o AUDIODRV += ossaudio.o
endif endif
ifdef CONFIG_COREAUDIO
pc.o: DEFINES := -DUSE_SB16 $(DEFINES) AUDIODRV += coreaudio.o
endif
ifdef CONFIG_ADLIB ifdef CONFIG_ALSA
SOUND_HW += fmopl.o adlib.o AUDIODRV += alsaaudio.o
LIBS += -lasound
endif
ifdef CONFIG_DSOUND
AUDIODRV += dsoundaudio.o
LIBS += -lole32 -ldxguid
endif endif
ifdef CONFIG_FMOD ifdef CONFIG_FMOD
AUDIODRV += fmodaudio.o AUDIODRV += fmodaudio.o
audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES) audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES)
LIBS += $(CONFIG_FMOD_LIB) LIBS += $(CONFIG_FMOD_LIB)
endif endif
ifdef CONFIG_ADLIB
SOUND_HW += fmopl.o adlib.o
endif
ifeq ($(TARGET_BASE_ARCH), i386) ifeq ($(TARGET_BASE_ARCH), i386)
# Hardware support # Hardware support
VL_OBJS+= ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) VL_OBJS+= ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o
DEFINES += -DHAS_AUDIO
endif endif
ifeq ($(TARGET_BASE_ARCH), ppc) ifeq ($(TARGET_BASE_ARCH), ppc)
VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
DEFINES += -DHAS_AUDIO
endif endif
ifeq ($(TARGET_ARCH), mips) ifeq ($(TARGET_ARCH), mips)
VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8254.o i8259.o VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8254.o i8259.o
...@@ -317,7 +326,10 @@ VL_OBJS+=sdl.o ...@@ -317,7 +326,10 @@ VL_OBJS+=sdl.o
endif endif
ifdef CONFIG_COCOA ifdef CONFIG_COCOA
VL_OBJS+=cocoa.o VL_OBJS+=cocoa.o
COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
ifdef CONFIG_COREAUDIO
COCOA_LIBS+=-framework CoreAudio
endif
endif endif
ifdef CONFIG_SLIRP ifdef CONFIG_SLIRP
DEFINES+=-I$(SRC_PATH)/slirp DEFINES+=-I$(SRC_PATH)/slirp
...@@ -349,6 +361,10 @@ ifeq ($(ARCH),ia64) ...@@ -349,6 +361,10 @@ ifeq ($(ARCH),ia64)
VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
endif endif
ifdef CONFIG_WIN32
SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
endif
$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
...@@ -364,6 +380,9 @@ sdlaudio.o: sdlaudio.c ...@@ -364,6 +380,9 @@ sdlaudio.o: sdlaudio.c
depend: $(SRCS) depend: $(SRCS)
$(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend $(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
vldepend: $(VL_OBJS:.o=.c)
$(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
# libqemu # libqemu
libqemu.a: $(LIBOBJS) libqemu.a: $(LIBOBJS)
...@@ -415,8 +434,6 @@ op.o: op.c op_template.c op_mem.c ...@@ -415,8 +434,6 @@ op.o: op.c op_template.c op_mem.c
op_helper.o: op_helper_mem.c op_helper.o: op_helper_mem.c
endif endif
mixeng.o: mixeng.c mixeng.h mixeng_template.h
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
...@@ -434,3 +451,9 @@ endif ...@@ -434,3 +451,9 @@ endif
ifneq ($(wildcard .depend),) ifneq ($(wildcard .depend),)
include .depend include .depend
endif endif
ifeq (0, 1)
audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \
fmodaudio.o alsaaudio.o mixeng.o: \
CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
endif
This diff is collapsed.
This diff is collapsed.
/* /*
* QEMU Audio subsystem header * QEMU Audio subsystem header
* *
* Copyright (c) 2003-2004 Vassili Karpov (malc) * Copyright (c) 2003-2005 Vassili Karpov (malc)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#ifndef QEMU_AUDIO_H #ifndef QEMU_AUDIO_H
#define QEMU_AUDIO_H #define QEMU_AUDIO_H
#include "mixeng.h" typedef void (*audio_callback_fn_t) (void *opaque, int avail);
typedef enum { typedef enum {
AUD_FMT_U8, AUD_FMT_U8,
...@@ -33,22 +33,60 @@ typedef enum { ...@@ -33,22 +33,60 @@ typedef enum {
AUD_FMT_S16 AUD_FMT_S16
} audfmt_e; } audfmt_e;
typedef struct SWVoice SWVoice; typedef struct SWVoiceOut SWVoiceOut;
typedef struct SWVoiceIn SWVoiceIn;
typedef struct QEMUAudioTimeStamp {
uint64_t old_ts;
} QEMUAudioTimeStamp;
void AUD_vlog (const char *cap, const char *fmt, va_list ap);
void AUD_log (const char *cap, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((__format__ (__printf__, 2, 3)))
#endif
;
SWVoice * AUD_open (SWVoice *sw, const char *name, int freq, void AUD_init (void);
int nchannels, audfmt_e fmt); void AUD_help (void);
void AUD_init (void);
void AUD_log (const char *cap, const char *fmt, ...) SWVoiceOut *AUD_open_out (
__attribute__ ((__format__ (__printf__, 2, 3)));; SWVoiceOut *sw,
void AUD_close (SWVoice *sw); const char *name,
int AUD_write (SWVoice *sw, void *pcm_buf, int size); void *callback_opaque,
void AUD_adjust (SWVoice *sw, int leftover); audio_callback_fn_t callback_fn,
void AUD_reset (SWVoice *sw); int freq,
int AUD_get_free (SWVoice *sw); int nchannels,
int AUD_get_buffer_size (SWVoice *sw); audfmt_e fmt
void AUD_run (void); );
void AUD_enable (SWVoice *sw, int on); void AUD_close_out (SWVoiceOut *sw);
int AUD_calc_elapsed (SWVoice *sw); int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
int AUD_get_buffer_size_out (SWVoiceOut *sw);
void AUD_set_active_out (SWVoiceOut *sw, int on);
int AUD_is_active_out (SWVoiceOut *sw);
void AUD_init_time_stamp_out (SWVoiceOut *sw,
QEMUAudioTimeStamp *ts);
uint64_t AUD_time_stamp_get_elapsed_usec_out (SWVoiceOut *sw,
QEMUAudioTimeStamp *ts);
SWVoiceIn *AUD_open_in (
SWVoiceIn *sw,
const char *name,
void *callback_opaque,
audio_callback_fn_t callback_fn,
int freq,
int nchannels,
audfmt_e fmt
);
void AUD_close_in (SWVoiceIn *sw);
int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
void AUD_adjust_in (SWVoiceIn *sw, int leftover);
void AUD_set_active_in (SWVoiceIn *sw, int on);
int AUD_is_active_in (SWVoiceIn *sw);
void AUD_init_time_stamp_in (SWVoiceIn *sw,
QEMUAudioTimeStamp *ts);
uint64_t AUD_time_stamp_get_elapsed_usec_in (SWVoiceIn *sw,
QEMUAudioTimeStamp *ts);
static inline void *advance (void *p, int incr) static inline void *advance (void *p, int incr)
{ {
...@@ -59,7 +97,21 @@ static inline void *advance (void *p, int incr) ...@@ -59,7 +97,21 @@ static inline void *advance (void *p, int incr)
uint32_t popcount (uint32_t u); uint32_t popcount (uint32_t u);
inline uint32_t lsbindex (uint32_t u); inline uint32_t lsbindex (uint32_t u);
#ifdef __GNUC__
#define audio_MIN(a, b) ( __extension__ ({ \
__typeof (a) ta = a; \
__typeof (b) tb = b; \
((ta)>(tb)?(tb):(ta)); \
}))
#define audio_MAX(a, b) ( __extension__ ({ \
__typeof (a) ta = a; \
__typeof (b) tb = b; \
((ta)<(tb)?(tb):(ta)); \
}))
#else
#define audio_MIN(a, b) ((a)>(b)?(b):(a)) #define audio_MIN(a, b) ((a)>(b)?(b):(a))
#define audio_MAX(a, b) ((a)<(b)?(b):(a)) #define audio_MAX(a, b) ((a)<(b)?(b):(a))
#endif
#endif /* audio.h */ #endif /* audio.h */
/* /*
* QEMU Audio subsystem header * QEMU Audio subsystem header
* *
* Copyright (c) 2003-2004 Vassili Karpov (malc) * Copyright (c) 2003-2005 Vassili Karpov (malc)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
...@@ -24,140 +24,266 @@ ...@@ -24,140 +24,266 @@
#ifndef QEMU_AUDIO_INT_H #ifndef QEMU_AUDIO_INT_H
#define QEMU_AUDIO_INT_H #define QEMU_AUDIO_INT_H
#include "vl.h" #include "sys-queue.h"
#ifdef CONFIG_COREAUDIO
#define FLOAT_MIXENG
/* #define RECIPROCAL */
#endif
#include "mixeng.h"
int audio_bug (const char *funcname, int cond);
struct audio_pcm_ops;
typedef enum {
AUD_OPT_INT,
AUD_OPT_FMT,
AUD_OPT_STR,
AUD_OPT_BOOL
} audio_option_tag_e;
struct audio_option {
const char *name;
audio_option_tag_e tag;
void *valp;
const char *descr;
int *overridenp;
int overriden;
};
struct audio_callback {
void *opaque;
audio_callback_fn_t fn;
};
struct pcm_ops; struct audio_pcm_info {
int bits;
int sign;
int freq;
int nchannels;
int align;
int shift;
int bytes_per_second;
int swap_endian;
};
typedef struct HWVoice { typedef struct HWVoiceOut {
int active; int active;
int enabled; int enabled;
int pending_disable; int pending_disable;
int valid; int valid;
int freq; struct audio_pcm_info info;
f_sample *clip; f_sample *clip;
audfmt_e fmt;
int nchannels;
int align;
int shift;
int rpos; int rpos;
int bufsize; int bufsize;
uint64_t ts_helper;
int bytes_per_second;
st_sample_t *mix_buf; st_sample_t *mix_buf;
int samples; int samples;
int64_t old_ticks; LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
int nb_voices; struct audio_pcm_ops *pcm_ops;
struct SWVoice **pvoice; LIST_ENTRY (HWVoiceOut) entries;
struct pcm_ops *pcm_ops; } HWVoiceOut;
} HWVoice;
extern struct pcm_ops no_pcm_ops; typedef struct HWVoiceIn {
extern struct audio_output_driver no_output_driver; int enabled;
int active;
struct audio_pcm_info info;
t_sample *conv;
extern struct pcm_ops oss_pcm_ops; int wpos;
extern struct audio_output_driver oss_output_driver; int bufsize;
int total_samples_captured;
uint64_t ts_helper;
extern struct pcm_ops sdl_pcm_ops; st_sample_t *conv_buf;
extern struct audio_output_driver sdl_output_driver;
extern struct pcm_ops wav_pcm_ops; int samples;
extern struct audio_output_driver wav_output_driver; LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
struct audio_pcm_ops *pcm_ops;
LIST_ENTRY (HWVoiceIn) entries;
} HWVoiceIn;
extern struct pcm_ops fmod_pcm_ops; extern struct audio_driver no_audio_driver;
extern struct audio_output_driver fmod_output_driver; extern struct audio_driver oss_audio_driver;
extern struct audio_driver sdl_audio_driver;
extern struct audio_driver wav_audio_driver;
extern struct audio_driver fmod_audio_driver;
extern struct audio_driver alsa_audio_driver;
extern struct audio_driver coreaudio_audio_driver;
extern struct audio_driver dsound_audio_driver;
extern volume_t nominal_volume;
struct audio_output_driver { struct audio_driver {
const char *name; const char *name;
const char *descr;
struct audio_option *options;
void *(*init) (void); void *(*init) (void);
void (*fini) (void *); void (*fini) (void *);
struct pcm_ops *pcm_ops; struct audio_pcm_ops *pcm_ops;
int can_be_default; int can_be_default;
int max_voices; int max_voices_out;
int voice_size; int max_voices_in;
int voice_size_out;
int voice_size_in;
}; };
typedef struct AudioState { typedef struct AudioState {
int fixed_format; int fixed_settings_out;
int fixed_freq; int fixed_freq_out;
int fixed_channels; int fixed_channels_out;
int fixed_fmt; int fixed_fmt_out;
int nb_hw_voices; int nb_hw_voices_out;
int64_t ticks_threshold; int greedy_out;
int freq_threshold;
int fixed_settings_in;
int fixed_freq_in;
int fixed_channels_in;
int fixed_fmt_in;
int nb_hw_voices_in;
int greedy_in;
void *opaque; void *opaque;
struct audio_output_driver *drv; struct audio_driver *drv;
} AudioState;
extern AudioState audio_state;
struct SWVoice { QEMUTimer *ts;
int freq; union {
audfmt_e fmt; int usec;
int nchannels; int64_t ticks;
} period;
int shift; int plive;
int align; } AudioState;
extern AudioState audio_state;
struct SWVoiceOut {
struct audio_pcm_info info;
t_sample *conv; t_sample *conv;
int left;
int pos;
int bytes_per_second;
int64_t ratio; int64_t ratio;
st_sample_t *buf; st_sample_t *buf;
void *rate; void *rate;
int total_hw_samples_mixed;
int active;
int empty;
HWVoiceOut *hw;
char *name;
volume_t vol;
struct audio_callback callback;
LIST_ENTRY (SWVoiceOut) entries;
};
int wpos; struct SWVoiceIn {
int live;
int active; int active;
int64_t old_ticks; struct audio_pcm_info info;
HWVoice *hw; int64_t ratio;
void *rate;
int total_hw_samples_acquired;
st_sample_t *conv_buf;
f_sample *clip;
HWVoiceIn *hw;
char *name; char *name;
volume_t vol;
struct audio_callback callback;
LIST_ENTRY (SWVoiceIn) entries;
}; };
struct pcm_ops { struct audio_pcm_ops {
int (*init) (HWVoice *hw, int freq, int nchannels, audfmt_e fmt); int (*init_out)(HWVoiceOut *hw, int freq, int nchannels, audfmt_e fmt);
void (*fini) (HWVoice *hw); void (*fini_out)(HWVoiceOut *hw);
void (*run) (HWVoice *hw); int (*run_out) (HWVoiceOut *hw);
int (*write) (SWVoice *sw, void *buf, int size); int (*write) (SWVoiceOut *sw, void *buf, int size);
int (*ctl) (HWVoice *hw, int cmd, ...); int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
int (*init_in) (HWVoiceIn *hw, int freq, int nchannels, audfmt_e fmt);
void (*fini_in) (HWVoiceIn *hw);
int (*run_in) (HWVoiceIn *hw);
int (*read) (SWVoiceIn *sw, void *buf, int size);
int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
}; };
void pcm_sw_free_resources (SWVoice *sw); void audio_pcm_init_info (struct audio_pcm_info *info, int freq,
int pcm_sw_alloc_resources (SWVoice *sw); int nchannels, audfmt_e fmt, int swap_endian);
void pcm_sw_fini (SWVoice *sw); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
int nchannels, audfmt_e fmt); int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
void pcm_hw_clear (HWVoice *hw, void *buf, int len);
HWVoice * pcm_hw_find_any (HWVoice *hw); int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
HWVoice * pcm_hw_find_any_active (HWVoice *hw); int audio_pcm_hw_get_live_out (HWVoiceOut *hw);
HWVoice * pcm_hw_find_any_passive (HWVoice *hw); int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live);
HWVoice * pcm_hw_find_specific (HWVoice *hw, int freq,
int nchannels, audfmt_e fmt);
HWVoice * pcm_hw_add (int freq, int nchannels, audfmt_e fmt);
int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw);
int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw);
SWVoice * pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt);
void pcm_hw_free_resources (HWVoice *hw);
int pcm_hw_alloc_resources (HWVoice *hw);
void pcm_hw_fini (HWVoice *hw);
void pcm_hw_gc (HWVoice *hw);
int pcm_hw_get_live (HWVoice *hw);
int pcm_hw_get_live2 (HWVoice *hw, int *nb_active);
void pcm_hw_dec_live (HWVoice *hw, int decr);
int pcm_hw_write (SWVoice *sw, void *buf, int len);
int audio_get_conf_int (const char *key, int defval);
const char *audio_get_conf_str (const char *key, const char *defval);
struct audio_output_driver;
#define VOICE_ENABLE 1 #define VOICE_ENABLE 1
#define VOICE_DISABLE 2 #define VOICE_DISABLE 2
static inline int audio_ring_dist (int dst, int src, int len)
{
return (dst >= src) ? (dst - src) : (len - src + dst);
}
static inline int audio_need_to_swap_endian (int endianness)
{
#ifdef WORDS_BIGENDIAN
return endianness != 1;
#else
return endianness != 0;
#endif
}
#if defined __GNUC__
#define GCC_ATTR __attribute__ ((__unused__, __format__ (__printf__, 1, 2)))
#define INIT_FIELD(f) . f
#define GCC_FMT_ATTR(n, m) __attribute__ ((__format__ (printf, n, m)))
#else
#define GCC_ATTR /**/
#define INIT_FIELD(f) /**/
#define GCC_FMT_ATTR(n, m)
#endif
static void GCC_ATTR dolog (const char *fmt, ...)
{
va_list ap;