Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
a58c16dc
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看板
提交
a58c16dc
编写于
10月 15, 2009
作者:
M
malc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
winwave: ADC support
Signed-off-by:
N
malc
<
av1474@comtv.ru
>
上级
cb4f03e8
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
336 addition
and
24 deletion
+336
-24
audio/winwaveaudio.c
audio/winwaveaudio.c
+336
-24
未找到文件。
audio/winwaveaudio.c
浏览文件 @
a58c16dc
...
...
@@ -15,9 +15,13 @@
static
struct
{
int
dac_headers
;
int
dac_samples
;
int
adc_headers
;
int
adc_samples
;
}
conf
=
{
.
dac_headers
=
4
,
.
dac_samples
=
1024
.
dac_samples
=
1024
,
.
adc_headers
=
4
,
.
adc_samples
=
1024
};
typedef
struct
{
...
...
@@ -33,6 +37,19 @@ typedef struct {
CRITICAL_SECTION
crit_sect
;
}
WaveVoiceOut
;
typedef
struct
{
HWVoiceIn
hw
;
HWAVEIN
hwi
;
WAVEHDR
*
hdrs
;
HANDLE
event
;
void
*
pcm_buf
;
int
curhdr
;
int
paused
;
int
rpos
;
int
avail
;
CRITICAL_SECTION
crit_sect
;
}
WaveVoiceIn
;
static
void
winwave_log_mmresult
(
MMRESULT
mr
)
{
const
char
*
str
=
"BUG"
;
...
...
@@ -73,11 +90,11 @@ static void winwave_log_mmresult (MMRESULT mr)
break
;
default:
AUD_log
(
AUDIO_CAP
,
"Reason: Unknown (MMRESULT %#x)
\n
"
,
mr
);
dolog
(
"Reason: Unknown (MMRESULT %#x)
\n
"
,
mr
);
return
;
}
AUD_log
(
AUDIO_CAP
,
"Reason: %s
\n
"
,
str
);
dolog
(
"Reason: %s
\n
"
,
str
);
}
static
void
GCC_FMT_ATTR
(
2
,
3
)
winwave_logerr
(
...
...
@@ -107,7 +124,7 @@ static void winwave_anal_close_out (WaveVoiceOut *wave)
wave
->
hwo
=
NULL
;
}
static
void
CALLBACK
winwave_callback
(
static
void
CALLBACK
winwave_callback
_out
(
HWAVEOUT
hwo
,
UINT
msg
,
DWORD_PTR
dwInstance
,
...
...
@@ -130,8 +147,7 @@ static void CALLBACK winwave_callback (
LeaveCriticalSection
(
&
wave
->
crit_sect
);
if
(
wave
->
hw
.
poll_mode
)
{
if
(
!
SetEvent
(
wave
->
event
))
{
AUD_log
(
AUDIO_CAP
,
"SetEvent failed %lx
\n
"
,
GetLastError
());
dolog
(
"DAC SetEvent failed %lx
\n
"
,
GetLastError
());
}
}
}
...
...
@@ -143,7 +159,7 @@ static void CALLBACK winwave_callback (
break
;
default:
AUD_log
(
AUDIO_CAP
,
"unknown wave
callback msg %x
\n
"
,
msg
);
dolog
(
"unknown wave out
callback msg %x
\n
"
,
msg
);
}
}
...
...
@@ -159,13 +175,13 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
InitializeCriticalSection
(
&
wave
->
crit_sect
);
err
=
waveformat_from_audio_settings
(
&
wfx
,
as
);
err
=
waveformat_from_audio_settings
(
&
wfx
,
as
);
if
(
err
)
{
goto
err0
;
}
mr
=
waveOutOpen
(
&
wave
->
hwo
,
WAVE_MAPPER
,
&
wfx
,
(
DWORD_PTR
)
winwave_callback
,
(
DWORD_PTR
)
winwave_callback
_out
,
(
DWORD_PTR
)
wave
,
CALLBACK_FUNCTION
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveOutOpen"
);
...
...
@@ -198,7 +214,7 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
mr
=
waveOutPrepareHeader
(
wave
->
hwo
,
h
,
sizeof
(
*
h
));
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveOutPrepareHeader(%d)"
,
wave
->
curhdr
);
winwave_logerr
(
mr
,
"waveOutPrepareHeader(%d)"
,
i
);
goto
err4
;
}
}
...
...
@@ -238,7 +254,7 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
doreset
=
hw
->
poll_mode
&&
(
wave
->
pending
>=
conf
.
dac_samples
);
if
(
doreset
&&
!
ResetEvent
(
wave
->
event
))
{
AUD_log
(
AUDIO_CAP
,
"
ResetEvent failed %lx
\n
"
,
GetLastError
());
dolog
(
"DAC
ResetEvent failed %lx
\n
"
,
GetLastError
());
}
while
(
wave
->
pending
>=
conf
.
dac_samples
)
{
...
...
@@ -259,10 +275,10 @@ static int winwave_run_out (HWVoiceOut *hw, int live)
return
decr
;
}
static
void
winwave_poll
_out
(
void
*
opaque
)
static
void
winwave_poll
(
void
*
opaque
)
{
(
void
)
opaque
;
audio_run
(
"winwave_poll
_out
"
);
audio_run
(
"winwave_poll"
);
}
static
void
winwave_fini_out
(
HWVoiceOut
*
hw
)
...
...
@@ -287,9 +303,9 @@ static void winwave_fini_out (HWVoiceOut *hw)
winwave_anal_close_out
(
wave
);
if
(
wave
->
event
)
{
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
_out
,
wave
);
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
if
(
!
CloseHandle
(
wave
->
event
))
{
AUD_log
(
AUDIO_CAP
,
"
CloseHandle failed %lx
\n
"
,
GetLastError
());
dolog
(
"DAC
CloseHandle failed %lx
\n
"
,
GetLastError
());
}
wave
->
event
=
NULL
;
}
...
...
@@ -319,17 +335,15 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
if
(
poll_mode
&&
!
wave
->
event
)
{
wave
->
event
=
CreateEvent
(
NULL
,
TRUE
,
TRUE
,
NULL
);
if
(
!
wave
->
event
)
{
AUD_log
(
AUDIO_CAP
,
"CreateEvent: %lx, poll mode will be disabled
\n
"
,
GetLastError
());
dolog
(
"DAC CreateEvent: %lx, poll mode will be disabled
\n
"
,
GetLastError
());
}
}
if
(
wave
->
event
)
{
int
ret
;
ret
=
qemu_add_wait_object
(
wave
->
event
,
winwave_poll_out
,
wave
);
ret
=
qemu_add_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
hw
->
poll_mode
=
(
ret
==
0
);
}
else
{
...
...
@@ -356,13 +370,294 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
}
}
if
(
wave
->
event
)
{
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
_out
,
wave
);
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
}
return
0
;
}
return
-
1
;
}
static
void
winwave_anal_close_in
(
WaveVoiceIn
*
wave
)
{
MMRESULT
mr
;
mr
=
waveInClose
(
wave
->
hwi
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInClose"
);
}
wave
->
hwi
=
NULL
;
}
static
void
CALLBACK
winwave_callback_in
(
HWAVEIN
*
hwi
,
UINT
msg
,
DWORD_PTR
dwInstance
,
DWORD_PTR
dwParam1
,
DWORD_PTR
dwParam2
)
{
WaveVoiceIn
*
wave
=
(
WaveVoiceIn
*
)
dwInstance
;
switch
(
msg
)
{
case
WIM_DATA
:
{
WAVEHDR
*
h
=
(
WAVEHDR
*
)
dwParam1
;
if
(
!
h
->
dwUser
)
{
h
->
dwUser
=
1
;
EnterCriticalSection
(
&
wave
->
crit_sect
);
{
wave
->
avail
+=
conf
.
adc_samples
;
}
LeaveCriticalSection
(
&
wave
->
crit_sect
);
if
(
wave
->
hw
.
poll_mode
)
{
if
(
!
SetEvent
(
wave
->
event
))
{
dolog
(
"ADC SetEvent failed %lx
\n
"
,
GetLastError
());
}
}
}
}
break
;
case
WIM_CLOSE
:
case
WIM_OPEN
:
break
;
default:
dolog
(
"unknown wave in callback msg %x
\n
"
,
msg
);
}
}
static
void
winwave_add_buffers
(
WaveVoiceIn
*
wave
,
int
samples
)
{
int
doreset
;
doreset
=
wave
->
hw
.
poll_mode
&&
(
samples
>=
conf
.
adc_samples
);
if
(
doreset
&&
!
ResetEvent
(
wave
->
event
))
{
dolog
(
"ADC ResetEvent failed %lx
\n
"
,
GetLastError
());
}
while
(
samples
>=
conf
.
adc_samples
)
{
MMRESULT
mr
;
WAVEHDR
*
h
=
&
wave
->
hdrs
[
wave
->
curhdr
];
h
->
dwUser
=
0
;
mr
=
waveInAddBuffer
(
wave
->
hwi
,
h
,
sizeof
(
*
h
));
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInAddBuffer(%d)"
,
wave
->
curhdr
);
}
wave
->
curhdr
=
(
wave
->
curhdr
+
1
)
%
conf
.
adc_headers
;
samples
-=
conf
.
adc_samples
;
}
}
static
int
winwave_init_in
(
HWVoiceIn
*
hw
,
struct
audsettings
*
as
)
{
int
i
;
int
err
;
MMRESULT
mr
;
WAVEFORMATEX
wfx
;
WaveVoiceIn
*
wave
;
wave
=
(
WaveVoiceIn
*
)
hw
;
InitializeCriticalSection
(
&
wave
->
crit_sect
);
err
=
waveformat_from_audio_settings
(
&
wfx
,
as
);
if
(
err
)
{
goto
err0
;
}
mr
=
waveInOpen
(
&
wave
->
hwi
,
WAVE_MAPPER
,
&
wfx
,
(
DWORD_PTR
)
winwave_callback_in
,
(
DWORD_PTR
)
wave
,
CALLBACK_FUNCTION
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInOpen"
);
goto
err1
;
}
wave
->
hdrs
=
audio_calloc
(
AUDIO_FUNC
,
conf
.
dac_headers
,
sizeof
(
*
wave
->
hdrs
));
if
(
!
wave
->
hdrs
)
{
goto
err2
;
}
audio_pcm_init_info
(
&
hw
->
info
,
as
);
hw
->
samples
=
conf
.
adc_samples
*
conf
.
adc_headers
;
wave
->
avail
=
0
;
wave
->
pcm_buf
=
audio_calloc
(
AUDIO_FUNC
,
conf
.
adc_samples
,
conf
.
adc_headers
<<
hw
->
info
.
shift
);
if
(
!
wave
->
pcm_buf
)
{
goto
err3
;
}
for
(
i
=
0
;
i
<
conf
.
adc_headers
;
++
i
)
{
WAVEHDR
*
h
=
&
wave
->
hdrs
[
i
];
h
->
dwUser
=
0
;
h
->
dwBufferLength
=
conf
.
adc_samples
<<
hw
->
info
.
shift
;
h
->
lpData
=
advance
(
wave
->
pcm_buf
,
i
*
h
->
dwBufferLength
);
h
->
dwFlags
=
0
;
mr
=
waveInPrepareHeader
(
wave
->
hwi
,
h
,
sizeof
(
*
h
));
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInPrepareHeader(%d)"
,
i
);
goto
err4
;
}
}
wave
->
paused
=
1
;
winwave_add_buffers
(
wave
,
hw
->
samples
);
return
0
;
err4:
qemu_free
(
wave
->
pcm_buf
);
err3:
qemu_free
(
wave
->
hdrs
);
err2:
winwave_anal_close_in
(
wave
);
err1:
err0:
return
-
1
;
}
static
void
winwave_fini_in
(
HWVoiceIn
*
hw
)
{
int
i
;
MMRESULT
mr
;
WaveVoiceIn
*
wave
=
(
WaveVoiceIn
*
)
hw
;
mr
=
waveInReset
(
wave
->
hwi
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInReset"
);
}
for
(
i
=
0
;
i
<
conf
.
adc_headers
;
++
i
)
{
mr
=
waveInUnprepareHeader
(
wave
->
hwi
,
&
wave
->
hdrs
[
i
],
sizeof
(
wave
->
hdrs
[
i
]));
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInUnprepareHeader(%d)"
,
i
);
}
}
winwave_anal_close_in
(
wave
);
if
(
wave
->
event
)
{
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
if
(
!
CloseHandle
(
wave
->
event
))
{
dolog
(
"ADC CloseHandle failed %lx
\n
"
,
GetLastError
());
}
wave
->
event
=
NULL
;
}
qemu_free
(
wave
->
pcm_buf
);
wave
->
pcm_buf
=
NULL
;
qemu_free
(
wave
->
hdrs
);
wave
->
hdrs
=
NULL
;
}
static
int
winwave_run_in
(
HWVoiceIn
*
hw
)
{
WaveVoiceIn
*
wave
=
(
WaveVoiceIn
*
)
hw
;
int
live
=
audio_pcm_hw_get_live_in
(
hw
);
int
dead
=
hw
->
samples
-
live
;
int
decr
,
ret
;
if
(
!
dead
)
{
return
0
;
}
EnterCriticalSection
(
&
wave
->
crit_sect
);
{
decr
=
audio_MIN
(
dead
,
wave
->
avail
);
wave
->
avail
-=
decr
;
}
LeaveCriticalSection
(
&
wave
->
crit_sect
);
ret
=
decr
;
while
(
decr
)
{
int
left
=
hw
->
samples
-
hw
->
wpos
;
int
conv
=
audio_MIN
(
left
,
decr
);
hw
->
conv
(
hw
->
conv_buf
+
hw
->
wpos
,
advance
(
wave
->
pcm_buf
,
wave
->
rpos
<<
hw
->
info
.
shift
),
conv
,
&
nominal_volume
);
wave
->
rpos
=
(
wave
->
rpos
+
conv
)
%
hw
->
samples
;
hw
->
wpos
=
(
hw
->
wpos
+
conv
)
%
hw
->
samples
;
decr
-=
conv
;
}
winwave_add_buffers
(
wave
,
ret
);
return
ret
;
}
static
int
winwave_read
(
SWVoiceIn
*
sw
,
void
*
buf
,
int
size
)
{
return
audio_pcm_sw_read
(
sw
,
buf
,
size
);
}
static
int
winwave_ctl_in
(
HWVoiceIn
*
hw
,
int
cmd
,
...)
{
MMRESULT
mr
;
WaveVoiceIn
*
wave
=
(
WaveVoiceIn
*
)
hw
;
switch
(
cmd
)
{
case
VOICE_ENABLE
:
{
va_list
ap
;
int
poll_mode
;
va_start
(
ap
,
cmd
);
poll_mode
=
va_arg
(
ap
,
int
);
va_end
(
ap
);
if
(
poll_mode
&&
!
wave
->
event
)
{
wave
->
event
=
CreateEvent
(
NULL
,
TRUE
,
TRUE
,
NULL
);
if
(
!
wave
->
event
)
{
dolog
(
"ADC CreateEvent: %lx, poll mode will be disabled
\n
"
,
GetLastError
());
}
}
if
(
wave
->
event
)
{
int
ret
;
ret
=
qemu_add_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
hw
->
poll_mode
=
(
ret
==
0
);
}
else
{
hw
->
poll_mode
=
0
;
}
if
(
wave
->
paused
)
{
mr
=
waveInStart
(
wave
->
hwi
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInStart"
);
}
wave
->
paused
=
0
;
}
}
return
0
;
case
VOICE_DISABLE
:
if
(
!
wave
->
paused
)
{
mr
=
waveInStop
(
wave
->
hwi
);
if
(
mr
!=
MMSYSERR_NOERROR
)
{
winwave_logerr
(
mr
,
"waveInStop"
);
}
else
{
wave
->
paused
=
1
;
}
}
if
(
wave
->
event
)
{
qemu_del_wait_object
(
wave
->
event
,
winwave_poll
,
wave
);
}
return
0
;
}
return
0
;
}
static
void
*
winwave_audio_init
(
void
)
{
return
&
conf
;
...
...
@@ -386,6 +681,18 @@ static struct audio_option winwave_options[] = {
.
valp
=
&
conf
.
dac_samples
,
.
descr
=
"DAC number of samples per header"
,
},
{
.
name
=
"ADC_HEADERS"
,
.
tag
=
AUD_OPT_INT
,
.
valp
=
&
conf
.
adc_headers
,
.
descr
=
"ADC number of headers"
,
},
{
.
name
=
"ADC_SAMPLES"
,
.
tag
=
AUD_OPT_INT
,
.
valp
=
&
conf
.
adc_samples
,
.
descr
=
"ADC number of samples per header"
,
},
{
/* End of list */
}
};
...
...
@@ -394,7 +701,12 @@ static struct audio_pcm_ops winwave_pcm_ops = {
.
fini_out
=
winwave_fini_out
,
.
run_out
=
winwave_run_out
,
.
write
=
winwave_write
,
.
ctl_out
=
winwave_ctl_out
.
ctl_out
=
winwave_ctl_out
,
.
init_in
=
winwave_init_in
,
.
fini_in
=
winwave_fini_in
,
.
run_in
=
winwave_run_in
,
.
read
=
winwave_read
,
.
ctl_in
=
winwave_ctl_in
};
struct
audio_driver
winwave_audio_driver
=
{
...
...
@@ -406,7 +718,7 @@ struct audio_driver winwave_audio_driver = {
.
pcm_ops
=
&
winwave_pcm_ops
,
.
can_be_default
=
1
,
.
max_voices_out
=
INT_MAX
,
.
max_voices_in
=
0
,
.
max_voices_in
=
INT_MAX
,
.
voice_size_out
=
sizeof
(
WaveVoiceOut
),
.
voice_size_in
=
0
.
voice_size_in
=
sizeof
(
WaveVoiceIn
)
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录