Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
571ec3d6
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
571ec3d6
编写于
11月 20, 2005
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
audio merge (malc)
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@1636
c046a42c-6fe2-441c-8c8c-71466251a162
上级
5e941d4b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
396 addition
and
448 deletion
+396
-448
audio/alsaaudio.c
audio/alsaaudio.c
+129
-89
audio/audio.c
audio/audio.c
+61
-287
audio/audio.h
audio/audio.h
+4
-2
audio/audio_int.h
audio/audio_int.h
+1
-1
audio/audio_template.h
audio/audio_template.h
+195
-67
audio/ossaudio.c
audio/ossaudio.c
+6
-2
未找到文件。
audio/alsaaudio.c
浏览文件 @
571ec3d6
...
...
@@ -31,15 +31,12 @@ typedef struct ALSAVoiceOut {
HWVoiceOut
hw
;
void
*
pcm_buf
;
snd_pcm_t
*
handle
;
int
can_pause
;
int
was_enabled
;
}
ALSAVoiceOut
;
typedef
struct
ALSAVoiceIn
{
HWVoiceIn
hw
;
snd_pcm_t
*
handle
;
void
*
pcm_buf
;
int
can_pause
;
}
ALSAVoiceIn
;
static
struct
{
...
...
@@ -58,6 +55,7 @@ static struct {
int
buffer_size_out_overriden
;
int
period_size_out_overriden
;
int
verbose
;
}
conf
=
{
#ifdef HIGH_LATENCY
.
size_in_usec_in
=
1
,
...
...
@@ -73,8 +71,8 @@ static struct {
#else
#define DEFAULT_BUFFER_SIZE 1024
#define DEFAULT_PERIOD_SIZE 256
.
buffer_size_in
=
DEFAULT_BUFFER_SIZE
,
.
period_size_in
=
DEFAULT_PERIOD_SIZE
,
.
buffer_size_in
=
DEFAULT_BUFFER_SIZE
*
4
,
.
period_size_in
=
DEFAULT_PERIOD_SIZE
*
4
,
.
buffer_size_out
=
DEFAULT_BUFFER_SIZE
,
.
period_size_out
=
DEFAULT_PERIOD_SIZE
,
.
buffer_size_in_overriden
=
0
,
...
...
@@ -82,7 +80,8 @@ static struct {
.
period_size_in_overriden
=
0
,
.
period_size_out_overriden
=
0
,
#endif
.
threshold
=
0
.
threshold
=
0
,
.
verbose
=
0
};
struct
alsa_params_req
{
...
...
@@ -97,7 +96,6 @@ struct alsa_params_obt {
int
freq
;
audfmt_e
fmt
;
int
nchannels
;
int
can_pause
;
snd_pcm_uframes_t
samples
;
};
...
...
@@ -474,12 +472,6 @@ static int alsa_open (int in, struct alsa_params_req *req,
goto
err
;
}
obt
->
can_pause
=
snd_pcm_hw_params_can_pause
(
hw_params
);
if
(
obt
->
can_pause
<
0
)
{
alsa_logerr
(
err
,
"Could not get pause capability for %s
\n
"
,
typ
);
obt
->
can_pause
=
0
;
}
if
(
!
in
&&
conf
.
threshold
)
{
snd_pcm_uframes_t
threshold
;
int
bytes_per_sec
;
...
...
@@ -527,6 +519,28 @@ static int alsa_recover (snd_pcm_t *handle)
return
0
;
}
static
snd_pcm_sframes_t
alsa_get_avail
(
snd_pcm_t
*
handle
)
{
snd_pcm_sframes_t
avail
;
avail
=
snd_pcm_avail_update
(
handle
);
if
(
avail
<
0
)
{
if
(
avail
==
-
EPIPE
)
{
if
(
!
alsa_recover
(
handle
))
{
avail
=
snd_pcm_avail_update
(
handle
);
}
}
if
(
avail
<
0
)
{
alsa_logerr
(
avail
,
"Could not obtain number of available frames
\n
"
);
return
-
1
;
}
}
return
avail
;
}
static
int
alsa_run_out
(
HWVoiceOut
*
hw
)
{
ALSAVoiceOut
*
alsa
=
(
ALSAVoiceOut
*
)
hw
;
...
...
@@ -541,57 +555,53 @@ static int alsa_run_out (HWVoiceOut *hw)
return
0
;
}
avail
=
snd_pcm_avail_update
(
alsa
->
handle
);
avail
=
alsa_get_avail
(
alsa
->
handle
);
if
(
avail
<
0
)
{
if
(
avail
==
-
EPIPE
)
{
if
(
!
alsa_recover
(
alsa
->
handle
))
{
avail
=
snd_pcm_avail_update
(
alsa
->
handle
);
if
(
avail
>=
0
)
{
goto
ok
;
}
}
}
alsa_logerr
(
avail
,
"Could not get amount free space
\n
"
);
dolog
(
"Could not get number of available playback frames
\n
"
);
return
0
;
}
ok:
decr
=
audio_MIN
(
live
,
avail
);
samples
=
decr
;
rpos
=
hw
->
rpos
;
while
(
samples
)
{
int
left_till_end_samples
=
hw
->
samples
-
rpos
;
int
convert_samples
=
audio_MIN
(
samples
,
left_till_end_samples
);
int
len
=
audio_MIN
(
samples
,
left_till_end_samples
);
snd_pcm_sframes_t
written
;
src
=
hw
->
mix_buf
+
rpos
;
dst
=
advance
(
alsa
->
pcm_buf
,
rpos
<<
hw
->
info
.
shift
);
hw
->
clip
(
dst
,
src
,
convert_samples
);
hw
->
clip
(
dst
,
src
,
len
);
while
(
convert_samples
)
{
written
=
snd_pcm_writei
(
alsa
->
handle
,
dst
,
convert_samples
);
while
(
len
)
{
written
=
snd_pcm_writei
(
alsa
->
handle
,
dst
,
len
);
if
(
written
<
0
)
{
if
(
written
<
=
0
)
{
switch
(
written
)
{
case
-
EPIPE
:
if
(
!
alsa_recover
(
alsa
->
handle
)
)
{
continue
;
case
0
:
if
(
conf
.
verbose
)
{
dolog
(
"Failed to write %d frames (wrote zero)
\n
"
,
len
)
;
}
dolog
(
"Failed to write %d frames to %p, "
"handle %p not prepared
\n
"
,
convert_samples
,
dst
,
alsa
->
handle
);
goto
exit
;
case
-
EAGAIN
:
case
-
EPIPE
:
if
(
alsa_recover
(
alsa
->
handle
))
{
alsa_logerr
(
written
,
"Failed to write %d frames
\n
"
,
len
);
goto
exit
;
}
if
(
conf
.
verbose
)
{
dolog
(
"Recovering from playback xrun
\n
"
);
}
continue
;
case
-
EAGAIN
:
goto
exit
;
default:
alsa_logerr
(
written
,
"Failed to write %d frames to %p
\n
"
,
convert_samples
,
dst
);
len
,
dst
);
goto
exit
;
}
}
...
...
@@ -599,7 +609,7 @@ static int alsa_run_out (HWVoiceOut *hw)
mixeng_clear
(
src
,
written
);
rpos
=
(
rpos
+
written
)
%
hw
->
samples
;
samples
-=
written
;
convert_samples
-=
written
;
len
-=
written
;
dst
=
advance
(
dst
,
written
<<
hw
->
info
.
shift
);
src
+=
written
;
}
...
...
@@ -659,7 +669,6 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
&
obt_as
,
audio_need_to_swap_endian
(
endianness
)
);
alsa
->
can_pause
=
obt
.
can_pause
;
hw
->
samples
=
obt
.
samples
;
alsa
->
pcm_buf
=
audio_calloc
(
AUDIO_FUNC
,
obt
.
samples
,
1
<<
hw
->
info
.
shift
);
...
...
@@ -671,46 +680,46 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
}
alsa
->
handle
=
handle
;
alsa
->
was_enabled
=
0
;
return
0
;
}
static
int
alsa_
ctl_out
(
HWVoiceOut
*
hw
,
int
cmd
,
...
)
static
int
alsa_
voice_ctl
(
snd_pcm_t
*
handle
,
const
char
*
typ
,
int
pause
)
{
int
err
;
if
(
pause
)
{
err
=
snd_pcm_drop
(
handle
);
if
(
err
<
0
)
{
alsa_logerr
(
err
,
"Could not stop %s"
,
typ
);
return
-
1
;
}
}
else
{
err
=
snd_pcm_prepare
(
handle
);
if
(
err
<
0
)
{
alsa_logerr
(
err
,
"Could not prepare handle for %s"
,
typ
);
return
-
1
;
}
}
return
0
;
}
static
int
alsa_ctl_out
(
HWVoiceOut
*
hw
,
int
cmd
,
...)
{
ALSAVoiceOut
*
alsa
=
(
ALSAVoiceOut
*
)
hw
;
switch
(
cmd
)
{
case
VOICE_ENABLE
:
ldebug
(
"enabling voice
\n
"
);
audio_pcm_info_clear_buf
(
&
hw
->
info
,
alsa
->
pcm_buf
,
hw
->
samples
);
if
(
alsa
->
can_pause
)
{
/* Why this was_enabled madness is needed at all?? */
if
(
alsa
->
was_enabled
)
{
err
=
snd_pcm_pause
(
alsa
->
handle
,
0
);
if
(
err
<
0
)
{
alsa_logerr
(
err
,
"Failed to resume playing
\n
"
);
/* not fatal really */
}
}
else
{
alsa
->
was_enabled
=
1
;
}
}
break
;
return
alsa_voice_ctl
(
alsa
->
handle
,
"playback"
,
0
);
case
VOICE_DISABLE
:
ldebug
(
"disabling voice
\n
"
);
if
(
alsa
->
can_pause
)
{
err
=
snd_pcm_pause
(
alsa
->
handle
,
1
);
if
(
err
<
0
)
{
alsa_logerr
(
err
,
"Failed to stop playing
\n
"
);
/* not fatal really */
}
}
break
;
return
alsa_voice_ctl
(
alsa
->
handle
,
"playback"
,
1
);
}
return
0
;
return
-
1
;
}
static
int
alsa_init_in
(
HWVoiceIn
*
hw
,
audsettings_t
*
as
)
...
...
@@ -749,7 +758,6 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
&
obt_as
,
audio_need_to_swap_endian
(
endianness
)
);
alsa
->
can_pause
=
obt
.
can_pause
;
hw
->
samples
=
obt
.
samples
;
alsa
->
pcm_buf
=
audio_calloc
(
AUDIO_FUNC
,
hw
->
samples
,
1
<<
hw
->
info
.
shift
);
...
...
@@ -783,6 +791,7 @@ static int alsa_run_in (HWVoiceIn *hw)
int
i
;
int
live
=
audio_pcm_hw_get_live_in
(
hw
);
int
dead
=
hw
->
samples
-
live
;
int
decr
;
struct
{
int
add
;
int
len
;
...
...
@@ -790,22 +799,36 @@ static int alsa_run_in (HWVoiceIn *hw)
{
hw
->
wpos
,
0
},
{
0
,
0
}
};
snd_pcm_sframes_t
avail
;
snd_pcm_uframes_t
read_samples
=
0
;
if
(
!
dead
)
{
return
0
;
}
if
(
hw
->
wpos
+
dead
>
hw
->
samples
)
{
avail
=
alsa_get_avail
(
alsa
->
handle
);
if
(
avail
<
0
)
{
dolog
(
"Could not get number of captured frames
\n
"
);
return
0
;
}
if
(
!
avail
&&
(
snd_pcm_state
(
alsa
->
handle
)
==
SND_PCM_STATE_PREPARED
))
{
avail
=
hw
->
samples
;
}
decr
=
audio_MIN
(
dead
,
avail
);
if
(
!
decr
)
{
return
0
;
}
if
(
hw
->
wpos
+
decr
>
hw
->
samples
)
{
bufs
[
0
].
len
=
(
hw
->
samples
-
hw
->
wpos
);
bufs
[
1
].
len
=
(
de
ad
-
(
hw
->
samples
-
hw
->
wpos
));
bufs
[
1
].
len
=
(
de
cr
-
(
hw
->
samples
-
hw
->
wpos
));
}
else
{
bufs
[
0
].
len
=
de
ad
;
bufs
[
0
].
len
=
de
cr
;
}
for
(
i
=
0
;
i
<
2
;
++
i
)
{
void
*
src
;
st_sample_t
*
dst
;
...
...
@@ -820,24 +843,27 @@ static int alsa_run_in (HWVoiceIn *hw)
while
(
len
)
{
nread
=
snd_pcm_readi
(
alsa
->
handle
,
src
,
len
);
if
(
nread
<
0
)
{
if
(
nread
<
=
0
)
{
switch
(
nread
)
{
case
-
EPIPE
:
if
(
!
alsa_recover
(
alsa
->
handle
)
)
{
continue
;
case
0
:
if
(
conf
.
verbose
)
{
dolog
(
"Failed to read %ld frames (read zero)
\n
"
,
len
)
;
}
dolog
(
"Failed to read %ld frames from %p, "
"handle %p not prepared
\n
"
,
len
,
src
,
alsa
->
handle
);
goto
exit
;
case
-
EAGAIN
:
case
-
EPIPE
:
if
(
alsa_recover
(
alsa
->
handle
))
{
alsa_logerr
(
nread
,
"Failed to read %ld frames
\n
"
,
len
);
goto
exit
;
}
if
(
conf
.
verbose
)
{
dolog
(
"Recovering from capture xrun
\n
"
);
}
continue
;
case
-
EAGAIN
:
goto
exit
;
default:
alsa_logerr
(
nread
,
...
...
@@ -871,9 +897,19 @@ static int alsa_read (SWVoiceIn *sw, void *buf, int size)
static
int
alsa_ctl_in
(
HWVoiceIn
*
hw
,
int
cmd
,
...)
{
(
void
)
hw
;
(
void
)
cmd
;
return
0
;
ALSAVoiceIn
*
alsa
=
(
ALSAVoiceIn
*
)
hw
;
switch
(
cmd
)
{
case
VOICE_ENABLE
:
ldebug
(
"enabling voice
\n
"
);
return
alsa_voice_ctl
(
alsa
->
handle
,
"capture"
,
0
);
case
VOICE_DISABLE
:
ldebug
(
"disabling voice
\n
"
);
return
alsa_voice_ctl
(
alsa
->
handle
,
"capture"
,
1
);
}
return
-
1
;
}
static
void
*
alsa_audio_init
(
void
)
...
...
@@ -909,6 +945,10 @@ static struct audio_option alsa_options[] = {
{
"ADC_DEV"
,
AUD_OPT_STR
,
&
conf
.
pcm_name_in
,
"ADC device name"
,
NULL
,
0
},
{
"VERBOSE"
,
AUD_OPT_BOOL
,
&
conf
.
verbose
,
"Behave in a more verbose way"
,
NULL
,
0
},
{
NULL
,
0
,
NULL
,
NULL
,
NULL
,
0
}
};
...
...
audio/audio.c
浏览文件 @
571ec3d6
...
...
@@ -96,7 +96,7 @@ static struct {
{
0
},
/* period */
0
,
/* plive */
0
0
/* log_to_monitor */
};
static
AudioState
glob_audio_state
;
...
...
@@ -623,25 +623,6 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
/*
* Hard voice (capture)
*/
static
void
audio_pcm_hw_free_resources_in
(
HWVoiceIn
*
hw
)
{
if
(
hw
->
conv_buf
)
{
qemu_free
(
hw
->
conv_buf
);
}
hw
->
conv_buf
=
NULL
;
}
static
int
audio_pcm_hw_alloc_resources_in
(
HWVoiceIn
*
hw
)
{
hw
->
conv_buf
=
audio_calloc
(
AUDIO_FUNC
,
hw
->
samples
,
sizeof
(
st_sample_t
));
if
(
!
hw
->
conv_buf
)
{
dolog
(
"Could not allocate ADC conversion buffer (%d samples)
\n
"
,
hw
->
samples
);
return
-
1
;
}
return
0
;
}
static
int
audio_pcm_hw_find_min_in
(
HWVoiceIn
*
hw
)
{
SWVoiceIn
*
sw
;
...
...
@@ -668,64 +649,6 @@ int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
/*
* Soft voice (capture)
*/
static
void
audio_pcm_sw_free_resources_in
(
SWVoiceIn
*
sw
)
{
if
(
sw
->
conv_buf
)
{
qemu_free
(
sw
->
conv_buf
);
}
if
(
sw
->
rate
)
{
st_rate_stop
(
sw
->
rate
);
}
sw
->
conv_buf
=
NULL
;
sw
->
rate
=
NULL
;
}
static
int
audio_pcm_sw_alloc_resources_in
(
SWVoiceIn
*
sw
)
{
int
samples
=
((
int64_t
)
sw
->
hw
->
samples
<<
32
)
/
sw
->
ratio
;
sw
->
conv_buf
=
audio_calloc
(
AUDIO_FUNC
,
samples
,
sizeof
(
st_sample_t
));
if
(
!
sw
->
conv_buf
)
{
dolog
(
"Could not allocate buffer for `%s' (%d samples)
\n
"
,
SW_NAME
(
sw
),
samples
);
return
-
1
;
}
sw
->
rate
=
st_rate_start
(
sw
->
hw
->
info
.
freq
,
sw
->
info
.
freq
);
if
(
!
sw
->
rate
)
{
qemu_free
(
sw
->
conv_buf
);
sw
->
conv_buf
=
NULL
;
return
-
1
;
}
return
0
;
}
static
int
audio_pcm_sw_init_in
(
SWVoiceIn
*
sw
,
HWVoiceIn
*
hw
,
const
char
*
name
,
audsettings_t
*
as
)
{
/* None of the cards emulated by QEMU are big-endian
hence following shortcut */
audio_pcm_init_info
(
&
sw
->
info
,
as
,
audio_need_to_swap_endian
(
0
));
sw
->
hw
=
hw
;
sw
->
ratio
=
((
int64_t
)
sw
->
info
.
freq
<<
32
)
/
sw
->
hw
->
info
.
freq
;
sw
->
clip
=
mixeng_clip
[
sw
->
info
.
nchannels
==
2
]
[
sw
->
info
.
sign
]
[
sw
->
info
.
swap_endian
]
[
sw
->
info
.
bits
==
16
];
sw
->
name
=
qemu_strdup
(
name
);
audio_pcm_sw_free_resources_in
(
sw
);
return
audio_pcm_sw_alloc_resources_in
(
sw
);
}
static
int
audio_pcm_sw_get_rpos_in
(
SWVoiceIn
*
sw
)
{
HWVoiceIn
*
hw
=
sw
->
hw
;
...
...
@@ -750,7 +673,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
{
HWVoiceIn
*
hw
=
sw
->
hw
;
int
samples
,
live
,
ret
=
0
,
swlim
,
isamp
,
osamp
,
rpos
,
total
=
0
;
st_sample_t
*
src
,
*
dst
=
sw
->
conv_
buf
;
st_sample_t
*
src
,
*
dst
=
sw
->
buf
;
rpos
=
audio_pcm_sw_get_rpos_in
(
sw
)
%
hw
->
samples
;
...
...
@@ -794,7 +717,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
total
+=
isamp
;
}
sw
->
clip
(
buf
,
sw
->
conv_
buf
,
ret
);
sw
->
clip
(
buf
,
sw
->
buf
,
ret
);
sw
->
total_hw_samples_acquired
+=
total
;
return
ret
<<
sw
->
info
.
shift
;
}
...
...
@@ -802,27 +725,6 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
/*
* Hard voice (playback)
*/
static
void
audio_pcm_hw_free_resources_out
(
HWVoiceOut
*
hw
)
{
if
(
hw
->
mix_buf
)
{
qemu_free
(
hw
->
mix_buf
);
}
hw
->
mix_buf
=
NULL
;
}
static
int
audio_pcm_hw_alloc_resources_out
(
HWVoiceOut
*
hw
)
{
hw
->
mix_buf
=
audio_calloc
(
AUDIO_FUNC
,
hw
->
samples
,
sizeof
(
st_sample_t
));
if
(
!
hw
->
mix_buf
)
{
dolog
(
"Could not allocate DAC mixing buffer (%d samples)
\n
"
,
hw
->
samples
);
return
-
1
;
}
return
0
;
}
static
int
audio_pcm_hw_find_min_out
(
HWVoiceOut
*
hw
,
int
*
nb_livep
)
{
SWVoiceOut
*
sw
;
...
...
@@ -876,66 +778,6 @@ int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
/*
* Soft voice (playback)
*/
static
void
audio_pcm_sw_free_resources_out
(
SWVoiceOut
*
sw
)
{
if
(
sw
->
buf
)
{
qemu_free
(
sw
->
buf
);
}
if
(
sw
->
rate
)
{
st_rate_stop
(
sw
->
rate
);
}
sw
->
buf
=
NULL
;
sw
->
rate
=
NULL
;
}
static
int
audio_pcm_sw_alloc_resources_out
(
SWVoiceOut
*
sw
)
{
sw
->
buf
=
audio_calloc
(
AUDIO_FUNC
,
sw
->
hw
->
samples
,
sizeof
(
st_sample_t
));
if
(
!
sw
->
buf
)
{
dolog
(
"Could not allocate buffer for `%s' (%d samples)
\n
"
,
SW_NAME
(
sw
),
sw
->
hw
->
samples
);
return
-
1
;
}
sw
->
rate
=
st_rate_start
(
sw
->
info
.
freq
,
sw
->
hw
->
info
.
freq
);
if
(
!
sw
->
rate
)
{
qemu_free
(
sw
->
buf
);
sw
->
buf
=
NULL
;
return
-
1
;
}
return
0
;
}
static
int
audio_pcm_sw_init_out
(
SWVoiceOut
*
sw
,
HWVoiceOut
*
hw
,
const
char
*
name
,
audsettings_t
*
as
)
{
/* None of the cards emulated by QEMU are big-endian
hence following shortcut */
audio_pcm_init_info
(
&
sw
->
info
,
as
,
audio_need_to_swap_endian
(
0
));
sw
->
hw
=
hw
;
sw
->
empty
=
1
;
sw
->
active
=
0
;
sw
->
ratio
=
((
int64_t
)
sw
->
hw
->
info
.
freq
<<
32
)
/
sw
->
info
.
freq
;
sw
->
total_hw_samples_mixed
=
0
;
sw
->
conv
=
mixeng_conv
[
sw
->
info
.
nchannels
==
2
]
[
sw
->
info
.
sign
]
[
sw
->
info
.
swap_endian
]
[
sw
->
info
.
bits
==
16
];
sw
->
name
=
qemu_strdup
(
name
);
audio_pcm_sw_free_resources_out
(
sw
);
return
audio_pcm_sw_alloc_resources_out
(
sw
);
}
int
audio_pcm_sw_write
(
SWVoiceOut
*
sw
,
void
*
buf
,
int
size
)
{
int
hwsamples
,
samples
,
isamp
,
osamp
,
wpos
,
live
,
dead
,
left
,
swlim
,
blck
;
...
...
@@ -1316,6 +1158,16 @@ static void audio_run_in (AudioState *s)
}
}
static
void
audio_timer
(
void
*
opaque
)
{
AudioState
*
s
=
opaque
;
audio_run_out
(
s
);
audio_run_in
(
s
);
qemu_mod_timer
(
s
->
ts
,
qemu_get_clock
(
vm_clock
)
+
conf
.
period
.
ticks
);
}
static
struct
audio_option
audio_options
[]
=
{
/* DAC */
{
"DAC_FIXED_SETTINGS"
,
AUD_OPT_BOOL
,
&
conf
.
fixed_out
.
enabled
,
...
...
@@ -1356,13 +1208,31 @@ static struct audio_option audio_options[] = {
{
"PLIVE"
,
AUD_OPT_BOOL
,
&
conf
.
plive
,
"(undocumented)"
,
NULL
,
0
},
{
"LOG_TO_MONITOR"
,
AUD_OPT_BOOL
,
&
conf
.
log_to_monitor
,
"print logging messages to montior instead of stderr"
,
NULL
,
0
},
{
NULL
,
0
,
NULL
,
NULL
,
NULL
,
0
}
};
static
void
audio_pp_nb_voices
(
const
char
*
typ
,
int
nb
)
{
switch
(
nb
)
{
case
0
:
printf
(
"Does not support %s
\n
"
,
typ
);
break
;
case
1
:
printf
(
"One %s voice
\n
"
,
typ
);
break
;
case
INT_MAX
:
printf
(
"Theoretically supports many %s voices
\n
"
,
typ
);
break
;
default:
printf
(
"Theoretically supports upto %d %s voices
\n
"
,
nb
,
typ
);
break
;
}
}
void
AUD_help
(
void
)
{
size_t
i
;
...
...
@@ -1387,37 +1257,8 @@ void AUD_help (void)
printf
(
"Name: %s
\n
"
,
d
->
name
);
printf
(
"Description: %s
\n
"
,
d
->
descr
);
switch
(
d
->
max_voices_out
)
{
case
0
:
printf
(
"Does not support DAC
\n
"
);
break
;
case
1
:
printf
(
"One DAC voice
\n
"
);
break
;
case
INT_MAX
:
printf
(
"Theoretically supports many DAC voices
\n
"
);
break
;
default:
printf
(
"Theoretically supports upto %d DAC voices
\n
"
,
d
->
max_voices_out
);
break
;
}
switch
(
d
->
max_voices_in
)
{
case
0
:
printf
(
"Does not support ADC
\n
"
);
break
;
case
1
:
printf
(
"One ADC voice
\n
"
);
break
;
case
INT_MAX
:
printf
(
"Theoretically supports many ADC voices
\n
"
);
break
;
default:
printf
(
"Theoretically supports upto %d ADC voices
\n
"
,
d
->
max_voices_in
);
break
;
}
audio_pp_nb_voices
(
"playback"
,
d
->
max_voices_out
);
audio_pp_nb_voices
(
"capture"
,
d
->
max_voices_in
);
if
(
d
->
options
)
{
printf
(
"Options:
\n
"
);
...
...
@@ -1434,7 +1275,7 @@ void AUD_help (void)
"Example:
\n
"
#ifdef _WIN32
" set QEMU_AUDIO_DRV=wav
\n
"
" set QEMU_WAV_PATH=c:
/
tune.wav
\n
"
" set QEMU_WAV_PATH=c:
\\
tune.wav
\n
"
#else
" export QEMU_AUDIO_DRV=wav
\n
"
" export QEMU_WAV_PATH=$HOME/tune.wav
\n
"
...
...
@@ -1444,16 +1285,6 @@ void AUD_help (void)
);
}
void
audio_timer
(
void
*
opaque
)
{
AudioState
*
s
=
opaque
;
audio_run_out
(
s
);
audio_run_in
(
s
);
qemu_mod_timer
(
s
->
ts
,
qemu_get_clock
(
vm_clock
)
+
conf
.
period
.
ticks
);
}
static
int
audio_driver_init
(
AudioState
*
s
,
struct
audio_driver
*
drv
)
{
if
(
drv
->
options
)
{
...
...
@@ -1462,62 +1293,8 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
s
->
drv_opaque
=
drv
->
init
();
if
(
s
->
drv_opaque
)
{
if
(
s
->
nb_hw_voices_out
>
drv
->
max_voices_out
)
{
if
(
!
drv
->
max_voices_out
)
{
dolog
(
"`%s' does not support DAC
\n
"
,
drv
->
name
);
}
else
{
dolog
(
"`%s' does not support %d multiple DAC voicess
\n
"
"Resetting to %d
\n
"
,
drv
->
name
,
s
->
nb_hw_voices_out
,
drv
->
max_voices_out
);
}
s
->
nb_hw_voices_out
=
drv
->
max_voices_out
;
}
if
(
!
drv
->
voice_size_in
&&
drv
->
max_voices_in
)
{
ldebug
(
"warning: No ADC voice size defined for `%s'
\n
"
,
drv
->
name
);
drv
->
max_voices_in
=
0
;
}
if
(
!
drv
->
voice_size_out
&&
drv
->
max_voices_out
)
{
ldebug
(
"warning: No DAC voice size defined for `%s'
\n
"
,
drv
->
name
);
}
if
(
drv
->
voice_size_in
&&
!
drv
->
max_voices_in
)
{
ldebug
(
"warning: `%s' ADC voice size %d, zero voices
\n
"
,
drv
->
name
,
drv
->
voice_size_out
);
}
if
(
drv
->
voice_size_out
&&
!
drv
->
max_voices_out
)
{
ldebug
(
"warning: `%s' DAC voice size %d, zero voices
\n
"
,
drv
->
name
,
drv
->
voice_size_in
);
}
if
(
s
->
nb_hw_voices_in
>
drv
->
max_voices_in
)
{
if
(
!
drv
->
max_voices_in
)
{
ldebug
(
"`%s' does not support ADC
\n
"
,
drv
->
name
);
}
else
{
dolog
(
"`%s' does not support %d multiple ADC voices
\n
"
"Resetting to %d
\n
"
,
drv
->
name
,
s
->
nb_hw_voices_in
,
drv
->
max_voices_in
);
}
s
->
nb_hw_voices_in
=
drv
->
max_voices_in
;
}
LIST_INIT
(
&
s
->
hw_head_out
);
LIST_INIT
(
&
s
->
hw_head_in
);
audio_init_nb_voices_out
(
s
,
drv
);
audio_init_nb_voices_in
(
s
,
drv
);
s
->
drv
=
drv
;
return
0
;
}
...
...
@@ -1549,25 +1326,13 @@ static void audio_atexit (void)
HWVoiceOut
*
hwo
=
NULL
;
HWVoiceIn
*
hwi
=
NULL
;
while
((
hwo
=
audio_pcm_hw_find_any_out
(
s
,
hwo
)))
{
if
(
!
hwo
->
pcm_ops
)
{
continue
;
}
if
(
hwo
->
enabled
)
{
hwo
->
pcm_ops
->
ctl_out
(
hwo
,
VOICE_DISABLE
);
}
while
((
hwo
=
audio_pcm_hw_find_any_enabled_out
(
s
,
hwo
)))
{
hwo
->
pcm_ops
->
ctl_out
(
hwo
,
VOICE_DISABLE
);
hwo
->
pcm_ops
->
fini_out
(
hwo
);
}
while
((
hwi
=
audio_pcm_hw_find_any_in
(
s
,
hwi
)))
{
if
(
!
hwi
->
pcm_ops
)
{
continue
;
}
if
(
hwi
->
enabled
)
{
hwi
->
pcm_ops
->
ctl_in
(
hwi
,
VOICE_DISABLE
);
}
while
((
hwi
=
audio_pcm_hw_find_any_enabled_in
(
s
,
hwi
)))
{
hwi
->
pcm_ops
->
ctl_in
(
hwi
,
VOICE_DISABLE
);
hwi
->
pcm_ops
->
fini_in
(
hwi
);
}
...
...
@@ -1616,21 +1381,31 @@ AudioState *AUD_init (void)
const
char
*
drvname
;
AudioState
*
s
=
&
glob_audio_state
;
LIST_INIT
(
&
s
->
hw_head_out
);
LIST_INIT
(
&
s
->
hw_head_in
);
atexit
(
audio_atexit
);
s
->
ts
=
qemu_new_timer
(
vm_clock
,
audio_timer
,
s
);
if
(
!
s
->
ts
)
{
dolog
(
"Could not create audio timer
\n
"
);
return
NULL
;
}
audio_process_options
(
"AUDIO"
,
audio_options
);
s
->
nb_hw_voices_out
=
conf
.
fixed_out
.
nb_voices
;
s
->
nb_hw_voices_in
=
conf
.
fixed_in
.
nb_voices
;
if
(
s
->
nb_hw_voices_out
<=
0
)
{
dolog
(
"Bogus number of
DAC voices %d
\n
"
,
dolog
(
"Bogus number of
playback voices %d, setting to 1
\n
"
,
s
->
nb_hw_voices_out
);
s
->
nb_hw_voices_out
=
1
;
}
if
(
s
->
nb_hw_voices_in
<=
0
)
{
dolog
(
"Bogus number of
ADC voices %d
\n
"
,
dolog
(
"Bogus number of
capture voices %d, setting to 0
\n
"
,
s
->
nb_hw_voices_in
);
s
->
nb_hw_voices_in
=
1
;
s
->
nb_hw_voices_in
=
0
;
}
{
...
...
@@ -1638,12 +1413,6 @@ AudioState *AUD_init (void)
drvname
=
audio_get_conf_str
(
"QEMU_AUDIO_DRV"
,
NULL
,
&
def
);
}
s
->
ts
=
qemu_new_timer
(
vm_clock
,
audio_timer
,
s
);
if
(
!
s
->
ts
)
{
dolog
(
"Could not create audio timer
\n
"
);
return
NULL
;
}
if
(
drvname
)
{
int
found
=
0
;
...
...
@@ -1680,6 +1449,8 @@ AudioState *AUD_init (void)
}
if
(
done
)
{
VMChangeStateEntry
*
e
;
if
(
conf
.
period
.
hz
<=
0
)
{
if
(
conf
.
period
.
hz
<
0
)
{
dolog
(
"warning: Timer period is negative - %d "
...
...
@@ -1692,7 +1463,11 @@ AudioState *AUD_init (void)
conf
.
period
.
ticks
=
ticks_per_sec
/
conf
.
period
.
hz
;
}
qemu_add_vm_change_state_handler
(
audio_vm_change_state_handler
,
s
);
e
=
qemu_add_vm_change_state_handler
(
audio_vm_change_state_handler
,
s
);
if
(
!
e
)
{
dolog
(
"warning: Could not register change state handler
\n
"
"(Audio can continue looping even after stopping the VM)
\n
"
);
}
}
else
{
qemu_del_timer
(
s
->
ts
);
...
...
@@ -1701,7 +1476,6 @@ AudioState *AUD_init (void)
LIST_INIT
(
&
s
->
card_head
);
register_savevm
(
"audio"
,
0
,
1
,
audio_save
,
audio_load
,
s
);
atexit
(
audio_atexit
);
qemu_mod_timer
(
s
->
ts
,
qemu_get_clock
(
vm_clock
)
+
conf
.
period
.
ticks
);
return
s
;
}
audio/audio.h
浏览文件 @
571ec3d6
...
...
@@ -73,7 +73,8 @@ SWVoiceOut *AUD_open_out (
const
char
*
name
,
void
*
callback_opaque
,
audio_callback_fn_t
callback_fn
,
audsettings_t
*
settings
audsettings_t
*
settings
,
int
sw_endian
);
void
AUD_close_out
(
QEMUSoundCard
*
card
,
SWVoiceOut
*
sw
);
...
...
@@ -91,7 +92,8 @@ SWVoiceIn *AUD_open_in (
const
char
*
name
,
void
*
callback_opaque
,
audio_callback_fn_t
callback_fn
,
audsettings_t
*
settings
audsettings_t
*
settings
,
int
sw_endian
);
void
AUD_close_in
(
QEMUSoundCard
*
card
,
SWVoiceIn
*
sw
);
...
...
audio/audio_int.h
浏览文件 @
571ec3d6
...
...
@@ -123,7 +123,7 @@ struct SWVoiceIn {
int64_t
ratio
;
void
*
rate
;
int
total_hw_samples_acquired
;
st_sample_t
*
conv_
buf
;
st_sample_t
*
buf
;
f_sample
*
clip
;
HWVoiceIn
*
hw
;
char
*
name
;
...
...
audio/audio_template.h
浏览文件 @
571ec3d6
...
...
@@ -23,52 +23,159 @@
*/
#ifdef DAC
#define NAME "playback"
#define HWBUF hw->mix_buf
#define TYPE out
#define HW
glue (HWVoice, Out)
#define SW
glue (SWVoice, Out)
#define HW
HWVoiceOut
#define SW
SWVoiceOut
#else
#define NAME "capture"
#define TYPE in
#define HW glue (HWVoice, In)
#define SW glue (SWVoice, In)
#define HW HWVoiceIn
#define SW SWVoiceIn
#define HWBUF hw->conv_buf
#endif
static
int
glue
(
audio_pcm_hw_init
_
,
TYPE
)
(
HW
*
hw
,
audsettings_t
*
as
static
void
glue
(
audio_init_nb_voices
_
,
TYPE
)
(
AudioState
*
s
,
struct
audio_driver
*
drv
)
{
glue
(
audio_pcm_hw_free_resources_
,
TYPE
)
(
hw
);
int
max_voices
=
glue
(
drv
->
max_voices_
,
TYPE
);
int
voice_size
=
glue
(
drv
->
voice_size_
,
TYPE
);
if
(
glue
(
hw
->
pcm_ops
->
init_
,
TYPE
)
(
hw
,
as
))
{
return
-
1
;
if
(
glue
(
s
->
nb_hw_voices_
,
TYPE
)
>
max_voices
)
{
if
(
!
max_voices
)
{
#ifdef DAC
dolog
(
"Driver `%s' does not support "
NAME
"
\n
"
,
drv
->
name
);
#endif
}
else
{
dolog
(
"Driver `%s' does not support %d "
NAME
" voices, max %d
\n
"
,
drv
->
name
,
glue
(
s
->
nb_hw_voices_
,
TYPE
),
max_voices
);
}
glue
(
s
->
nb_hw_voices_
,
TYPE
)
=
max_voices
;
}
if
(
audio_bug
(
AUDIO_FUNC
,
hw
->
samples
<=
0
))
{
dolog
(
"hw->samples=%d
\n
"
,
hw
->
samples
);
if
(
audio_bug
(
AUDIO_FUNC
,
!
voice_size
&&
max_voices
))
{
dolog
(
"drv=`%s' voice_size=0 max_voices=%d
\n
"
,
drv
->
name
,
max_voices
);
glue
(
s
->
nb_hw_voices_
,
TYPE
)
=
0
;
}
if
(
audio_bug
(
AUDIO_FUNC
,
voice_size
&&
!
max_voices
))
{
dolog
(
"drv=`%s' voice_size=%d max_voices=0
\n
"
,
drv
->
name
,
voice_size
);
}
}
static
void
glue
(
audio_pcm_hw_free_resources_
,
TYPE
)
(
HW
*
hw
)
{
if
(
HWBUF
)
{
qemu_free
(
HWBUF
);
}
HWBUF
=
NULL
;
}
static
int
glue
(
audio_pcm_hw_alloc_resources_
,
TYPE
)
(
HW
*
hw
)
{
HWBUF
=
audio_calloc
(
AUDIO_FUNC
,
hw
->
samples
,
sizeof
(
st_sample_t
));
if
(
!
HWBUF
)
{
dolog
(
"Could not allocate "
NAME
" buffer (%d samples)
\n
"
,
hw
->
samples
);
return
-
1
;
}
LIST_INIT
(
&
hw
->
sw_head
);
return
0
;
}
static
void
glue
(
audio_pcm_sw_free_resources_
,
TYPE
)
(
SW
*
sw
)
{
if
(
sw
->
buf
)
{
qemu_free
(
sw
->
buf
);
}
if
(
sw
->
rate
)
{
st_rate_stop
(
sw
->
rate
);
}
sw
->
buf
=
NULL
;
sw
->
rate
=
NULL
;
}
static
int
glue
(
audio_pcm_sw_alloc_resources_
,
TYPE
)
(
SW
*
sw
)
{
int
samples
;
#ifdef DAC
hw
->
clip
=
mixeng_clip
samples
=
sw
->
hw
->
samples
;
#else
hw
->
conv
=
mixeng_conv
samples
=
((
int64_t
)
sw
->
hw
->
samples
<<
32
)
/
sw
->
ratio
;
#endif
[
hw
->
info
.
nchannels
==
2
]
[
hw
->
info
.
sign
]
[
hw
->
info
.
swap_endian
]
[
hw
->
info
.
bits
==
16
];
if
(
glue
(
audio_pcm_hw_alloc_resources_
,
TYPE
)
(
hw
))
{
glue
(
hw
->
pcm_ops
->
fini_
,
TYPE
)
(
hw
);
sw
->
buf
=
audio_calloc
(
AUDIO_FUNC
,
samples
,
sizeof
(
st_sample_t
));
if
(
!
sw
->
buf
)
{
dolog
(
"Could not allocate buffer for `%s' (%d samples)
\n
"
,
SW_NAME
(
sw
),
samples
);
return
-
1
;
}
#ifdef DAC
sw
->
rate
=
st_rate_start
(
sw
->
info
.
freq
,
sw
->
hw
->
info
.
freq
);
#else
sw
->
rate
=
st_rate_start
(
sw
->
hw
->
info
.
freq
,
sw
->
info
.
freq
);
#endif
if
(
!
sw
->
rate
)
{
qemu_free
(
sw
->
buf
);
sw
->
buf
=
NULL
;
return
-
1
;
}
return
0
;
}
static
int
glue
(
audio_pcm_sw_init_
,
TYPE
)
(
SW
*
sw
,
HW
*
hw
,
const
char
*
name
,
audsettings_t
*
as
,
int
endian
)
{
int
err
;
audio_pcm_init_info
(
&
sw
->
info
,
as
,
audio_need_to_swap_endian
(
endian
));
sw
->
hw
=
hw
;
sw
->
active
=
0
;
#ifdef DAC
sw
->
ratio
=
((
int64_t
)
sw
->
hw
->
info
.
freq
<<
32
)
/
sw
->
info
.
freq
;
sw
->
total_hw_samples_mixed
=
0
;
sw
->
empty
=
1
;
#else
sw
->
ratio
=
((
int64_t
)
sw
->
info
.
freq
<<
32
)
/
sw
->
hw
->
info
.
freq
;
#endif
#ifdef DAC
sw
->
conv
=
mixeng_conv
#else
sw
->
clip
=
mixeng_clip
#endif
[
sw
->
info
.
nchannels
==
2
]
[
sw
->
info
.
sign
]
[
sw
->
info
.
swap_endian
]
[
sw
->
info
.
bits
==
16
];
sw
->
name
=
qemu_strdup
(
name
);
err
=
glue
(
audio_pcm_sw_alloc_resources_
,
TYPE
)
(
sw
);
if
(
err
)
{
qemu_free
(
sw
->
name
);
sw
->
name
=
NULL
;
}
return
err
;
}
static
void
glue
(
audio_pcm_sw_fini_
,
TYPE
)
(
SW
*
sw
)
{
glue
(
audio_pcm_sw_free_resources_
,
TYPE
)
(
sw
);
...
...
@@ -117,31 +224,6 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
return
NULL
;
}
static
HW
*
glue
(
audio_pcm_hw_find_any_passive_
,
TYPE
)
(
AudioState
*
s
)
{
if
(
glue
(
s
->
nb_hw_voices_
,
TYPE
))
{
struct
audio_driver
*
drv
=
s
->
drv
;
if
(
audio_bug
(
AUDIO_FUNC
,
!
drv
))
{
dolog
(
"No host audio driver
\n
"
);
return
NULL
;
}
HW
*
hw
=
audio_calloc
(
AUDIO_FUNC
,
1
,
glue
(
drv
->
voice_size_
,
TYPE
));
if
(
!
hw
)
{
dolog
(
"Can not allocate voice `%s' size %d
\n
"
,
drv
->
name
,
glue
(
drv
->
voice_size_
,
TYPE
));
return
NULL
;
}
LIST_INSERT_HEAD
(
&
s
->
glue
(
hw_head_
,
TYPE
),
hw
,
entries
);
glue
(
s
->
nb_hw_voices_
,
TYPE
)
-=
1
;
return
hw
;
}
return
NULL
;
}
static
HW
*
glue
(
audio_pcm_hw_find_specific_
,
TYPE
)
(
AudioState
*
s
,
HW
*
hw
,
...
...
@@ -159,23 +241,63 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
static
HW
*
glue
(
audio_pcm_hw_add_new_
,
TYPE
)
(
AudioState
*
s
,
audsettings_t
*
as
)
{
HW
*
hw
;
struct
audio_driver
*
drv
=
s
->
drv
;
hw
=
glue
(
audio_pcm_hw_find_any_passive_
,
TYPE
)
(
s
);
if
(
hw
)
{
hw
->
pcm_ops
=
s
->
drv
->
pcm_ops
;
if
(
!
hw
->
pcm_ops
)
{
return
NULL
;
}
if
(
!
glue
(
s
->
nb_hw_voices_
,
TYPE
))
{
return
NULL
;
}
if
(
glue
(
audio_pcm_hw_init_
,
TYPE
)
(
hw
,
as
))
{
glue
(
audio_pcm_hw_gc_
,
TYPE
)
(
s
,
&
hw
);
return
NULL
;
}
else
{
return
hw
;
}
if
(
audio_bug
(
AUDIO_FUNC
,
!
drv
))
{
dolog
(
"No host audio driver
\n
"
);
return
NULL
;
}
if
(
audio_bug
(
AUDIO_FUNC
,
!
drv
->
pcm_ops
))
{
dolog
(
"Host audio driver without pcm_ops
\n
"
);
return
NULL
;
}
hw
=
audio_calloc
(
AUDIO_FUNC
,
1
,
glue
(
drv
->
voice_size_
,
TYPE
));
if
(
!
hw
)
{
dolog
(
"Can not allocate voice `%s' size %d
\n
"
,
drv
->
name
,
glue
(
drv
->
voice_size_
,
TYPE
));
return
NULL
;
}
hw
->
pcm_ops
=
drv
->
pcm_ops
;
LIST_INIT
(
&
hw
->
sw_head
);
if
(
glue
(
hw
->
pcm_ops
->
init_
,
TYPE
)
(
hw
,
as
))
{
goto
err0
;
}
if
(
audio_bug
(
AUDIO_FUNC
,
hw
->
samples
<=
0
))
{
dolog
(
"hw->samples=%d
\n
"
,
hw
->
samples
);
goto
err1
;
}
#ifdef DAC
hw
->
clip
=
mixeng_clip
#else
hw
->
conv
=
mixeng_conv
#endif
[
hw
->
info
.
nchannels
==
2
]
[
hw
->
info
.
sign
]
[
hw
->
info
.
swap_endian
]
[
hw
->
info
.
bits
==
16
];
if
(
glue
(
audio_pcm_hw_alloc_resources_
,
TYPE
)
(
hw
))
{
goto
err1
;
}
LIST_INSERT_HEAD
(
&
s
->
glue
(
hw_head_
,
TYPE
),
hw
,
entries
);
glue
(
s
->
nb_hw_voices_
,
TYPE
)
-=
1
;
return
hw
;
err1:
glue
(
hw
->
pcm_ops
->
fini_
,
TYPE
)
(
hw
);
err0:
qemu_free
(
hw
);
return
NULL
;
}
...
...
@@ -206,7 +328,8 @@ static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
static
SW
*
glue
(
audio_pcm_create_voice_pair_
,
TYPE
)
(
AudioState
*
s
,
const
char
*
sw_name
,
audsettings_t
*
as
audsettings_t
*
as
,
int
sw_endian
)
{
SW
*
sw
;
...
...
@@ -234,7 +357,7 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
glue
(
audio_pcm_hw_add_sw_
,
TYPE
)
(
hw
,
sw
);
if
(
glue
(
audio_pcm_sw_init_
,
TYPE
)
(
sw
,
hw
,
sw_name
,
as
))
{
if
(
glue
(
audio_pcm_sw_init_
,
TYPE
)
(
sw
,
hw
,
sw_name
,
as
,
sw_endian
))
{
goto
err3
;
}
...
...
@@ -256,6 +379,7 @@ static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
glue
(
audio_pcm_hw_gc_
,
TYPE
)
(
s
,
&
sw
->
hw
);
qemu_free
(
sw
);
}
void
glue
(
AUD_close_
,
TYPE
)
(
QEMUSoundCard
*
card
,
SW
*
sw
)
{
if
(
sw
)
{
...
...
@@ -275,7 +399,8 @@ SW *glue (AUD_open_, TYPE) (
const
char
*
name
,
void
*
callback_opaque
,
audio_callback_fn_t
callback_fn
,
audsettings_t
*
as
audsettings_t
*
as
,
int
sw_endian
)
{
AudioState
*
s
;
...
...
@@ -347,15 +472,16 @@ SW *glue (AUD_open_, TYPE) (
goto
fail
;
}
if
(
glue
(
audio_pcm_sw_init_
,
TYPE
)
(
sw
,
hw
,
name
,
as
))
{
glue
(
audio_pcm_sw_fini_
,
TYPE
)
(
sw
);
if
(
glue
(
audio_pcm_sw_init_
,
TYPE
)
(
sw
,
hw
,
name
,
as
,
sw_endian
))
{
goto
fail
;
}
}
else
{
sw
=
glue
(
audio_pcm_create_voice_pair_
,
TYPE
)
(
s
,
name
,
as
);
sw
=
glue
(
audio_pcm_create_voice_pair_
,
TYPE
)
(
s
,
name
,
as
,
sw_endian
);
if
(
!
sw
)
{
dolog
(
"Failed to create voice `%s'
\n
"
,
name
);
goto
fail
;
return
NULL
;
}
}
...
...
@@ -435,3 +561,5 @@ uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
#undef TYPE
#undef HW
#undef SW
#undef HWBUF
#undef NAME
audio/ossaudio.c
浏览文件 @
571ec3d6
...
...
@@ -75,11 +75,11 @@ static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
AUD_vlog
(
AUDIO_CAP
,
fmt
,
ap
);
va_end
(
ap
);
va_start
(
ap
,
fmt
);
AUD_log
(
AUDIO_CAP
,
"Reason: %s
\n
"
,
strerror
(
err
));
va_end
(
ap
);
}
static
void
GCC_FMT_ATTR
(
3
,
4
)
oss_logerr2
(
...
...
@@ -422,6 +422,8 @@ static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
audfmt_e
effective_fmt
;
audsettings_t
obt_as
;
oss
->
fd
=
-
1
;
req
.
fmt
=
aud_to_ossfmt
(
as
->
fmt
);
req
.
freq
=
as
->
freq
;
req
.
nchannels
=
as
->
nchannels
;
...
...
@@ -565,6 +567,8 @@ static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
audfmt_e
effective_fmt
;
audsettings_t
obt_as
;
oss
->
fd
=
-
1
;
req
.
fmt
=
aud_to_ossfmt
(
as
->
fmt
);
req
.
freq
=
as
->
freq
;
req
.
nchannels
=
as
->
nchannels
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录