Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
d329a6fb
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看板
提交
d329a6fb
编写于
6月 07, 2004
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
audip fixes (malc)
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@911
c046a42c-6fe2-441c-8c8c-71466251a162
上级
7ebb5e41
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
275 addition
and
198 deletion
+275
-198
hw/sb16.c
hw/sb16.c
+42
-8
oss.c
oss.c
+233
-190
未找到文件。
hw/sb16.c
浏览文件 @
d329a6fb
...
@@ -26,7 +26,10 @@
...
@@ -26,7 +26,10 @@
#define MIN(a, b) ((a)>(b)?(b):(a))
#define MIN(a, b) ((a)>(b)?(b):(a))
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
#define log(...) fprintf (stderr, "sb16: " __VA_ARGS__)
#define log(...) do { \
fprintf (stderr, "sb16: " __VA_ARGS__); \
fputc ('\n', stderr); \
} while (0)
/* #define DEBUG_SB16 */
/* #define DEBUG_SB16 */
#ifdef DEBUG_SB16
#ifdef DEBUG_SB16
...
@@ -44,6 +47,8 @@
...
@@ -44,6 +47,8 @@
#define IO_WRITE_PROTO(name) \
#define IO_WRITE_PROTO(name) \
void name (void *opaque, uint32_t nport, uint32_t val)
void name (void *opaque, uint32_t nport, uint32_t val)
static
const
char
e3
[]
=
"COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."
;
static
struct
{
static
struct
{
int
ver_lo
;
int
ver_lo
;
int
ver_hi
;
int
ver_hi
;
...
@@ -76,7 +81,7 @@ typedef struct SB16State {
...
@@ -76,7 +81,7 @@ typedef struct SB16State {
int
v2x6
;
int
v2x6
;
uint8_t
in_data
[
10
];
uint8_t
in_data
[
10
];
uint8_t
out_data
[
1
0
];
uint8_t
out_data
[
5
0
];
int
left_till_irq
;
int
left_till_irq
;
...
@@ -223,6 +228,20 @@ static void command (SB16State *dsp, uint8_t cmd)
...
@@ -223,6 +228,20 @@ static void command (SB16State *dsp, uint8_t cmd)
/* IMS uses those when probing for sound devices */
/* IMS uses those when probing for sound devices */
return
;
return
;
case
0x04
:
dsp
->
needed_bytes
=
1
;
break
;
case
0x05
:
case
0x0e
:
dsp
->
needed_bytes
=
2
;
break
;
case
0x0f
:
dsp
->
needed_bytes
=
1
;
dsp_out_data
(
dsp
,
0
);
break
;
case
0x10
:
case
0x10
:
dsp
->
needed_bytes
=
1
;
dsp
->
needed_bytes
=
1
;
break
;
break
;
...
@@ -274,8 +293,8 @@ static void command (SB16State *dsp, uint8_t cmd)
...
@@ -274,8 +293,8 @@ static void command (SB16State *dsp, uint8_t cmd)
uint8_t
d0
;
uint8_t
d0
;
d0
=
4
;
d0
=
4
;
if
(
dsp
->
fmt_signed
)
d0
|=
16
;
/* if (dsp->fmt_signed) d0 |= 16; */
if
(
dsp
->
fmt_stereo
)
d0
|=
32
;
/* if (dsp->fmt_stereo) d0 |= 32; */
dma_cmd
(
cmd
==
0x90
?
0xc4
:
0xc0
,
d0
,
-
1
);
dma_cmd
(
cmd
==
0x90
?
0xc4
:
0xc0
,
d0
,
-
1
);
cmd
=
-
1
;
cmd
=
-
1
;
break
;
break
;
...
@@ -324,6 +343,14 @@ static void command (SB16State *dsp, uint8_t cmd)
...
@@ -324,6 +343,14 @@ static void command (SB16State *dsp, uint8_t cmd)
dsp_out_data
(
dsp
,
sb
.
ver_hi
);
dsp_out_data
(
dsp
,
sb
.
ver_hi
);
return
;
return
;
case
0xe3
:
{
int
i
;
for
(
i
=
sizeof
(
e3
)
-
1
;
i
>=
0
;
--
i
)
dsp_out_data
(
dsp
,
e3
[
i
]);
return
;
}
case
0xf2
:
case
0xf2
:
dsp_out_data
(
dsp
,
0xaa
);
dsp_out_data
(
dsp
,
0xaa
);
dsp
->
mixer_regs
[
0x82
]
|=
dsp
->
mixer_regs
[
0x80
];
dsp
->
mixer_regs
[
0x82
]
|=
dsp
->
mixer_regs
[
0x80
];
...
@@ -360,6 +387,11 @@ static void complete (SB16State *dsp)
...
@@ -360,6 +387,11 @@ static void complete (SB16State *dsp)
}
}
else
{
else
{
switch
(
dsp
->
cmd
)
{
switch
(
dsp
->
cmd
)
{
case
0x05
:
case
0x04
:
case
0x0e
:
case
0x0f
:
break
;
case
0x10
:
case
0x10
:
break
;
break
;
...
@@ -425,8 +457,10 @@ static IO_WRITE_PROTO (dsp_write)
...
@@ -425,8 +457,10 @@ static IO_WRITE_PROTO (dsp_write)
iport
=
nport
-
sb
.
port
;
iport
=
nport
-
sb
.
port
;
ldebug
(
"write %#x %#x
\n
"
,
nport
,
iport
);
switch
(
iport
)
{
switch
(
iport
)
{
case
0x6
:
case
0x6
:
control
(
0
);
if
(
0
==
val
)
if
(
0
==
val
)
dsp
->
v2x6
=
0
;
dsp
->
v2x6
=
0
;
else
if
((
1
==
val
)
&&
(
0
==
dsp
->
v2x6
))
{
else
if
((
1
==
val
)
&&
(
0
==
dsp
->
v2x6
))
{
...
@@ -477,7 +511,7 @@ static IO_READ_PROTO (dsp_read)
...
@@ -477,7 +511,7 @@ static IO_READ_PROTO (dsp_read)
if
(
dsp
->
out_data_len
)
{
if
(
dsp
->
out_data_len
)
{
retval
=
dsp
->
out_data
[
--
dsp
->
out_data_len
];
retval
=
dsp
->
out_data
[
--
dsp
->
out_data_len
];
}
else
{
}
else
{
log
(
"empty output buffer
\n
"
);
log
(
"empty output buffer"
);
goto
error
;
goto
error
;
}
}
break
;
break
;
...
@@ -487,7 +521,7 @@ static IO_READ_PROTO (dsp_read)
...
@@ -487,7 +521,7 @@ static IO_READ_PROTO (dsp_read)
break
;
break
;
case
0xd
:
/* timer interrupt clear */
case
0xd
:
/* timer interrupt clear */
log
(
"timer interrupt clear
\n
"
);
log
(
"timer interrupt clear"
);
goto
error
;
goto
error
;
case
0xe
:
/* data available status | irq 8 ack */
case
0xe
:
/* data available status | irq 8 ack */
...
@@ -669,7 +703,7 @@ static int magic_of_irq (int irq)
...
@@ -669,7 +703,7 @@ static int magic_of_irq (int irq)
case
10
:
case
10
:
return
8
;
return
8
;
default:
default:
log
(
"bad irq %d
\n
"
,
irq
);
log
(
"bad irq %d"
,
irq
);
return
2
;
return
2
;
}
}
}
}
...
@@ -687,7 +721,7 @@ static int irq_of_magic (int magic)
...
@@ -687,7 +721,7 @@ static int irq_of_magic (int magic)
case 8:
case 8:
return 10;
return 10;
default:
default:
log ("bad irq magic %d
\n
", magic);
log ("bad irq magic %d", magic);
return 2;
return 2;
}
}
}
}
...
...
oss.c
浏览文件 @
d329a6fb
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include "vl.h"
#include "vl.h"
#ifndef _WIN32
#ifndef _WIN32
#include <ctype.h>
#include <fcntl.h>
#include <fcntl.h>
#include <errno.h>
#include <errno.h>
#include <stdio.h>
#include <stdio.h>
...
@@ -32,6 +33,7 @@
...
@@ -32,6 +33,7 @@
#include <stdlib.h>
#include <stdlib.h>
#include <limits.h>
#include <limits.h>
#include <inttypes.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <sys/soundcard.h>
...
@@ -90,25 +92,38 @@ static inline uint32_t lsbindex (uint32_t u)
...
@@ -90,25 +92,38 @@ static inline uint32_t lsbindex (uint32_t u)
ldebug ("ioctl " #args " = %d\n", ret); \
ldebug ("ioctl " #args " = %d\n", ret); \
} while (0)
} while (0)
static
int
audio_fd
=
-
1
;
static
struct
{
static
int
freq
;
int
fd
;
static
int
conf_nfrags
=
4
;
int
freq
;
static
int
conf_fragsize
;
int
bits16
;
static
int
nfrags
;
int
nchannels
;
static
int
fragsize
;
int
rpos
;
static
int
bufsize
;
int
wpos
;
static
int
nchannels
;
int
live
;
static
int
fmt
;
int
oss_fmt
;
static
int
rpos
;
int
bytes_per_second
;
static
int
wpos
;
int
is_mapped
;
static
int
atom
;
void
*
buf
;
static
int
live
;
int
bufsize
;
static
int
leftover
;
int
nfrags
;
static
int
bytes_per_second
;
int
fragsize
;
static
void
*
buf
;
int
old_optr
;
static
enum
{
DONT
,
DSP
,
TID
}
estimate
=
TID
;
int
leftover
;
uint64_t
old_ticks
;
static
void
(
*
copy_fn
)(
void
*
,
void
*
,
int
);
void
(
*
copy_fn
)(
void
*
,
void
*
,
int
);
}
oss
=
{
.
fd
=
-
1
};
static
struct
{
int
try_mmap
;
int
nfrags
;
int
fragsize
;
}
conf
=
{
.
try_mmap
=
0
,
.
nfrags
=
4
,
.
fragsize
=
4096
};
static
enum
{
DONT
,
DSP
,
TID
}
est
=
DONT
;
static
void
copy_no_conversion
(
void
*
dst
,
void
*
src
,
int
size
)
static
void
copy_no_conversion
(
void
*
dst
,
void
*
src
,
int
size
)
{
{
...
@@ -141,70 +156,124 @@ static void pab (struct audio_buf_info *abinfo)
...
@@ -141,70 +156,124 @@ static void pab (struct audio_buf_info *abinfo)
rpos
,
wpos
,
live
);
rpos
,
wpos
,
live
);
}
}
void
AUD_reset
(
int
rfreq
,
int
rnchannels
,
audfmt_e
rfmt
)
static
void
do_open
(
)
{
{
int
fmt_
;
int
mmmmssss
;
int
bits16
;
audio_buf_info
abinfo
;
int
fmt
,
freq
,
nchannels
;
if
(
-
1
==
audio_fd
)
{
if
(
oss
.
buf
)
{
AUD_open
(
rfreq
,
rnchannels
,
rfmt
);
if
(
-
1
==
munmap
(
oss
.
buf
,
oss
.
bufsize
))
{
return
;
ERRFail
(
"failed to unmap audio buffer %p %d"
,
oss
.
buf
,
oss
.
bufsize
);
}
oss
.
buf
=
NULL
;
}
}
switch
(
rfmt
)
{
if
(
-
1
!=
oss
.
fd
)
case
AUD_FMT_U8
:
close
(
oss
.
fd
);
bits16
=
0
;
fmt_
=
AFMT_U8
;
copy_fn
=
copy_no_conversion
;
atom
=
1
;
break
;
case
AUD_FMT_S8
:
oss
.
fd
=
open
(
"/dev/dsp"
,
O_RDWR
|
O_NONBLOCK
);
Fail
(
"can not play 8bit signed"
);
if
(
-
1
==
oss
.
fd
)
{
ERRFail
(
"can not open /dev/dsp"
);
}
case
AUD_FMT_S16
:
fmt
=
oss
.
oss_fmt
;
bits16
=
1
;
freq
=
oss
.
freq
;
fmt_
=
AFMT_S16_LE
;
nchannels
=
oss
.
nchannels
;
copy_fn
=
copy_no_conversion
;
atom
=
2
;
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_RESET
,
1
));
break
;
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_SAMPLESIZE
,
&
fmt
));
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_CHANNELS
,
&
nchannels
));
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_SPEED
,
&
freq
));
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_NONBLOCK
));
mmmmssss
=
(
conf
.
nfrags
<<
16
)
|
conf
.
fragsize
;
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_SETFRAGMENT
,
&
mmmmssss
));
if
((
oss
.
oss_fmt
!=
fmt
)
||
(
oss
.
nchannels
!=
nchannels
)
||
(
oss
.
freq
!=
freq
))
{
Fail
(
"failed to set audio parameters
\n
"
"parameter | requested value | obtained value
\n
"
"format | %10d | %10d
\n
"
"channels | %10d | %10d
\n
"
"frequency | %10d | %10d
\n
"
,
oss
.
oss_fmt
,
fmt
,
oss
.
nchannels
,
nchannels
,
oss
.
freq
,
freq
);
}
case
AUD_FMT_U16
:
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_GETOSPACE
,
&
abinfo
));
bits16
=
1
;
fmt_
=
AFMT_S16_LE
;
copy_fn
=
copy_u16_to_s16
;
atom
=
2
;
break
;
default:
oss
.
nfrags
=
abinfo
.
fragstotal
;
abort
();
oss
.
fragsize
=
abinfo
.
fragsize
;
}
oss
.
bufsize
=
oss
.
nfrags
*
oss
.
fragsize
;
oss
.
old_optr
=
0
;
if
((
fmt_
==
fmt
)
&&
(
bits16
+
1
==
nchannels
)
&&
(
rfreq
==
freq
))
oss
.
bytes_per_second
=
(
freq
<<
(
nchannels
>>
1
))
<<
oss
.
bits16
;
return
;
linfo
(
"bytes per second %d
\n
"
,
oss
.
bytes_per_second
);
linfo
(
"fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d
\n
"
,
abinfo
.
fragments
,
abinfo
.
fragstotal
,
abinfo
.
fragsize
,
abinfo
.
bytes
,
oss
.
bufsize
);
oss
.
buf
=
MAP_FAILED
;
oss
.
is_mapped
=
0
;
if
(
conf
.
try_mmap
)
{
oss
.
buf
=
mmap
(
NULL
,
oss
.
bufsize
,
PROT_WRITE
,
MAP_SHARED
,
oss
.
fd
,
0
);
if
(
MAP_FAILED
==
oss
.
buf
)
{
int
err
;
err
=
errno
;
log
(
"failed to mmap audio, size %d, fd %d
\n
"
"syserr: %s
\n
"
,
oss
.
bufsize
,
oss
.
fd
,
strerror
(
err
));
}
else
{
else
{
AUD_open
(
rfreq
,
rnchannels
,
rfmt
);
est
=
TID
;
oss
.
is_mapped
=
1
;
}
}
if
(
MAP_FAILED
==
oss
.
buf
)
{
est
=
TID
;
oss
.
buf
=
mmap
(
NULL
,
oss
.
bufsize
,
PROT_READ
|
PROT_WRITE
,
MAP_ANONYMOUS
|
MAP_PRIVATE
,
-
1
,
0
);
if
(
MAP_FAILED
==
oss
.
buf
)
{
ERRFail
(
"mmap audio buf, size %d"
,
oss
.
bufsize
);
}
}
oss
.
rpos
=
0
;
oss
.
wpos
=
0
;
oss
.
live
=
0
;
if
(
oss
.
is_mapped
)
{
int
trig
;
trig
=
0
;
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_SETTRIGGER
,
&
trig
));
trig
=
PCM_ENABLE_OUTPUT
;
IOCTL
((
oss
.
fd
,
SNDCTL_DSP_SETTRIGGER
,
&
trig
));
}
}
}
}
void
AUD_open
(
int
rfreq
,
int
rnchannels
,
audfmt_e
rfmt
)
static
void
maybe_open
(
int
req_freq
,
int
req_nchannels
,
audfmt_e
req_fmt
,
int
force_open
)
{
{
int
fmt_
;
int
oss_fmt
,
bits16
;
int
mmmmssss
;
struct
audio_buf_info
abinfo
;
int
_fmt
;
int
_freq
;
int
_nchannels
;
int
bits16
;
bits16
=
0
;
switch
(
req_fmt
)
{
switch
(
rfmt
)
{
case
AUD_FMT_U8
:
case
AUD_FMT_U8
:
bits16
=
0
;
bits16
=
0
;
fmt_
=
AFMT_U8
;
oss_fmt
=
AFMT_U8
;
copy_fn
=
copy_no_conversion
;
oss
.
copy_fn
=
copy_no_conversion
;
atom
=
1
;
break
;
break
;
case
AUD_FMT_S8
:
case
AUD_FMT_S8
:
...
@@ -212,111 +281,42 @@ void AUD_open (int rfreq, int rnchannels, audfmt_e rfmt)
...
@@ -212,111 +281,42 @@ void AUD_open (int rfreq, int rnchannels, audfmt_e rfmt)
case
AUD_FMT_S16
:
case
AUD_FMT_S16
:
bits16
=
1
;
bits16
=
1
;
fmt_
=
AFMT_S16_LE
;
oss_fmt
=
AFMT_S16_LE
;
copy_fn
=
copy_no_conversion
;
oss
.
copy_fn
=
copy_no_conversion
;
atom
=
2
;
break
;
break
;
case
AUD_FMT_U16
:
case
AUD_FMT_U16
:
bits16
=
1
;
bits16
=
1
;
fmt_
=
AFMT_S16_LE
;
oss_fmt
=
AFMT_S16_LE
;
copy_fn
=
copy_u16_to_s16
;
oss
.
copy_fn
=
copy_u16_to_s16
;
atom
=
2
;
break
;
break
;
default:
default:
abort
();
abort
();
}
}
if
(
buf
)
{
if
(
force_open
free
(
buf
);
||
(
-
1
==
oss
.
fd
)
buf
=
0
;
||
(
oss_fmt
!=
oss
.
oss_fmt
)
}
||
(
req_nchannels
!=
oss
.
nchannels
)
||
(
req_freq
!=
oss
.
freq
)
if
(
-
1
!=
audio_fd
)
||
(
bits16
!=
oss
.
bits16
))
{
close
(
audio_fd
);
oss
.
oss_fmt
=
oss_fmt
;
oss
.
nchannels
=
req_nchannels
;
audio_fd
=
open
(
"/dev/dsp"
,
O_WRONLY
|
O_NONBLOCK
);
oss
.
freq
=
req_freq
;
if
(
-
1
==
audio_fd
)
{
oss
.
bits16
=
bits16
;
ERRFail
(
"can not open /dev/dsp"
);
do_open
();
}
_fmt
=
fmt_
;
_freq
=
rfreq
;
_nchannels
=
rnchannels
;
IOCTL
((
audio_fd
,
SNDCTL_DSP_RESET
,
1
));
IOCTL
((
audio_fd
,
SNDCTL_DSP_SAMPLESIZE
,
&
_fmt
));
IOCTL
((
audio_fd
,
SNDCTL_DSP_CHANNELS
,
&
_nchannels
));
IOCTL
((
audio_fd
,
SNDCTL_DSP_SPEED
,
&
_freq
));
IOCTL
((
audio_fd
,
SNDCTL_DSP_NONBLOCK
));
/* from oss.pdf:
The argument to this call is an integer encoded as 0xMMMMSSSS (in
hex). The 16 least significant bits determine the fragment
size. The size is 2^SSSS. For examp le SSSS=0008 gives fragment
size of 256 bytes (2^8). The minimum is 16 bytes (SSSS=4) and the
maximum is total_buffer_size/2. Some devices or processor
architectures may require larger fragments - in this case the
requested fragment size is automatically increased.
So ahem... 4096 = 2^12, and grand total 0x0004000c
*/
mmmmssss
=
(
conf_nfrags
<<
16
)
|
conf_fragsize
;
IOCTL
((
audio_fd
,
SNDCTL_DSP_SETFRAGMENT
,
&
mmmmssss
));
linfo
(
"_fmt = %d, fmt = %d
\n
"
"_channels = %d, rnchannels = %d
\n
"
"_freq = %d, freq = %d
\n
"
,
_fmt
,
fmt_
,
_nchannels
,
rnchannels
,
_freq
,
rfreq
);
if
(
_fmt
!=
fmt_
)
{
Fail
(
"format %d != %d"
,
_fmt
,
fmt_
);
}
if
(
_nchannels
!=
rnchannels
)
{
Fail
(
"channels %d != %d"
,
_nchannels
,
rnchannels
);
}
}
}
if
(
_freq
!=
rfreq
)
{
void
AUD_reset
(
int
req_freq
,
int
req_nchannels
,
audfmt_e
req_fmt
)
Fail
(
"freq %d != %d"
,
_freq
,
rfreq
);
{
}
maybe_open
(
req_freq
,
req_nchannels
,
req_fmt
,
0
);
}
IOCTL
((
audio_fd
,
SNDCTL_DSP_GETOSPACE
,
&
abinfo
));
nfrags
=
abinfo
.
fragstotal
;
fragsize
=
abinfo
.
fragsize
;
freq
=
_freq
;
fmt
=
_fmt
;
nchannels
=
rnchannels
;
atom
<<=
nchannels
>>
1
;
bufsize
=
nfrags
*
fragsize
;
bytes_per_second
=
(
freq
<<
(
nchannels
>>
1
))
<<
bits16
;
linfo
(
"bytes per second %d
\n
"
,
bytes_per_second
);
linfo
(
"fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d
\n
"
,
abinfo
.
fragments
,
abinfo
.
fragstotal
,
abinfo
.
fragsize
,
abinfo
.
bytes
,
bufsize
);
if
(
NULL
==
buf
)
{
buf
=
malloc
(
bufsize
);
if
(
NULL
==
buf
)
{
abort
();
}
}
rpos
=
0
;
void
AUD_open
(
int
req_freq
,
int
req_nchannels
,
audfmt_e
req_fmt
)
wpos
=
0
;
{
live
=
0
;
maybe_open
(
req_freq
,
req_nchannels
,
req_fmt
,
1
)
;
}
}
int
AUD_write
(
void
*
in_buf
,
int
size
)
int
AUD_write
(
void
*
in_buf
,
int
size
)
...
@@ -324,27 +324,27 @@ int AUD_write (void *in_buf, int size)
...
@@ -324,27 +324,27 @@ int AUD_write (void *in_buf, int size)
int
to_copy
,
temp
;
int
to_copy
,
temp
;
uint8_t
*
in
,
*
out
;
uint8_t
*
in
,
*
out
;
to_copy
=
MIN
(
bufsize
-
live
,
size
);
to_copy
=
MIN
(
oss
.
bufsize
-
oss
.
live
,
size
);
temp
=
to_copy
;
temp
=
to_copy
;
in
=
in_buf
;
in
=
in_buf
;
out
=
buf
;
out
=
oss
.
buf
;
while
(
temp
)
{
while
(
temp
)
{
int
copy
;
int
copy
;
copy
=
MIN
(
temp
,
bufsize
-
wpos
);
copy
=
MIN
(
temp
,
oss
.
bufsize
-
oss
.
wpos
);
copy_fn
(
out
+
wpos
,
in
,
copy
);
oss
.
copy_fn
(
out
+
oss
.
wpos
,
in
,
copy
);
wpos
+=
copy
;
oss
.
wpos
+=
copy
;
if
(
wpos
==
bufsize
)
{
if
(
oss
.
wpos
==
oss
.
bufsize
)
{
wpos
=
0
;
oss
.
wpos
=
0
;
}
}
temp
-=
copy
;
temp
-=
copy
;
in
+=
copy
;
in
+=
copy
;
live
+=
copy
;
oss
.
live
+=
copy
;
}
}
return
to_copy
;
return
to_copy
;
...
@@ -356,10 +356,34 @@ void AUD_run (void)
...
@@ -356,10 +356,34 @@ void AUD_run (void)
int
bytes
;
int
bytes
;
struct
audio_buf_info
abinfo
;
struct
audio_buf_info
abinfo
;
if
(
0
==
live
)
if
(
0
==
oss
.
live
)
return
;
return
;
res
=
ioctl
(
audio_fd
,
SNDCTL_DSP_GETOSPACE
,
&
abinfo
);
if
(
oss
.
is_mapped
)
{
count_info
info
;
res
=
ioctl
(
oss
.
fd
,
SNDCTL_DSP_GETOPTR
,
&
info
);
if
(
-
1
==
res
)
{
int
err
;
err
=
errno
;
lwarn
(
"SNDCTL_DSP_GETOPTR failed with %s
\n
"
,
strerror
(
err
));
return
;
}
if
(
info
.
ptr
>
oss
.
old_optr
)
{
bytes
=
info
.
ptr
-
oss
.
old_optr
;
}
else
{
bytes
=
oss
.
bufsize
+
info
.
ptr
-
oss
.
old_optr
;
}
oss
.
old_optr
=
info
.
ptr
;
oss
.
live
-=
bytes
;
return
;
}
res
=
ioctl
(
oss
.
fd
,
SNDCTL_DSP_GETOSPACE
,
&
abinfo
);
if
(
-
1
==
res
)
{
if
(
-
1
==
res
)
{
int
err
;
int
err
;
...
@@ -369,7 +393,7 @@ void AUD_run (void)
...
@@ -369,7 +393,7 @@ void AUD_run (void)
}
}
bytes
=
abinfo
.
bytes
;
bytes
=
abinfo
.
bytes
;
bytes
=
MIN
(
live
,
bytes
);
bytes
=
MIN
(
oss
.
live
,
bytes
);
#if 0
#if 0
bytes = (bytes / fragsize) * fragsize;
bytes = (bytes / fragsize) * fragsize;
#endif
#endif
...
@@ -377,9 +401,9 @@ void AUD_run (void)
...
@@ -377,9 +401,9 @@ void AUD_run (void)
while
(
bytes
)
{
while
(
bytes
)
{
int
left
,
play
,
written
;
int
left
,
play
,
written
;
left
=
bufsize
-
rpos
;
left
=
oss
.
bufsize
-
oss
.
rpos
;
play
=
MIN
(
left
,
bytes
);
play
=
MIN
(
left
,
bytes
);
written
=
write
(
audio_fd
,
(
void
*
)
((
uint32_t
)
buf
+
rpos
),
play
);
written
=
write
(
oss
.
fd
,
(
void
*
)
((
uint32_t
)
oss
.
buf
+
oss
.
rpos
),
play
);
if
(
-
1
==
written
)
{
if
(
-
1
==
written
)
{
if
(
EAGAIN
==
errno
||
EINTR
==
errno
)
{
if
(
EAGAIN
==
errno
||
EINTR
==
errno
)
{
...
@@ -391,12 +415,12 @@ void AUD_run (void)
...
@@ -391,12 +415,12 @@ void AUD_run (void)
}
}
play
=
written
;
play
=
written
;
live
-=
play
;
oss
.
live
-=
play
;
rpos
+=
play
;
oss
.
rpos
+=
play
;
bytes
-=
play
;
bytes
-=
play
;
if
(
rpos
==
bufsize
)
{
if
(
oss
.
rpos
==
oss
.
bufsize
)
{
rpos
=
0
;
oss
.
rpos
=
0
;
}
}
}
}
}
}
...
@@ -406,7 +430,7 @@ static int get_dsp_bytes (void)
...
@@ -406,7 +430,7 @@ static int get_dsp_bytes (void)
int
res
;
int
res
;
struct
count_info
info
;
struct
count_info
info
;
res
=
ioctl
(
audio_
fd
,
SNDCTL_DSP_GETOPTR
,
&
info
);
res
=
ioctl
(
oss
.
fd
,
SNDCTL_DSP_GETOPTR
,
&
info
);
if
(
-
1
==
res
)
{
if
(
-
1
==
res
)
{
int
err
;
int
err
;
...
@@ -420,22 +444,22 @@ static int get_dsp_bytes (void)
...
@@ -420,22 +444,22 @@ static int get_dsp_bytes (void)
}
}
}
}
void
AUD_adjust_estimate
(
int
_
leftover
)
void
AUD_adjust_estimate
(
int
leftover
)
{
{
leftover
=
_
leftover
;
oss
.
leftover
=
leftover
;
}
}
int
AUD_get_free
(
void
)
int
AUD_get_free
(
void
)
{
{
int
free
,
elapsed
;
int
free
,
elapsed
;
free
=
bufsize
-
live
;
free
=
oss
.
bufsize
-
oss
.
live
;
if
(
0
==
free
)
if
(
0
==
free
)
return
0
;
return
0
;
elapsed
=
free
;
elapsed
=
free
;
switch
(
est
imate
)
{
switch
(
est
)
{
case
DONT
:
case
DONT
:
break
;
break
;
...
@@ -456,16 +480,15 @@ int AUD_get_free (void)
...
@@ -456,16 +480,15 @@ int AUD_get_free (void)
case
TID
:
case
TID
:
{
{
static
uint64_t
old_ticks
;
uint64_t
ticks
,
delta
;
uint64_t
ticks
,
delta
;
uint64_t
ua_elapsed
;
uint64_t
ua_elapsed
;
uint64_t
al_elapsed
;
uint64_t
al_elapsed
;
ticks
=
qemu_get_clock
(
rt_clock
);
ticks
=
qemu_get_clock
(
rt_clock
);
delta
=
ticks
-
old_ticks
;
delta
=
ticks
-
o
ss
.
o
ld_ticks
;
old_ticks
=
ticks
;
o
ss
.
o
ld_ticks
=
ticks
;
ua_elapsed
=
(
delta
*
bytes_per_second
)
/
1000
;
ua_elapsed
=
(
delta
*
oss
.
bytes_per_second
)
/
1000
;
al_elapsed
=
ua_elapsed
&
~
3ULL
;
al_elapsed
=
ua_elapsed
&
~
3ULL
;
ldebug
(
"tid elapsed %llu bytes
\n
"
,
ua_elapsed
);
ldebug
(
"tid elapsed %llu bytes
\n
"
,
ua_elapsed
);
...
@@ -475,7 +498,7 @@ int AUD_get_free (void)
...
@@ -475,7 +498,7 @@ int AUD_get_free (void)
else
else
elapsed
=
al_elapsed
;
elapsed
=
al_elapsed
;
elapsed
+=
leftover
;
elapsed
+=
oss
.
leftover
;
}
}
}
}
...
@@ -490,27 +513,47 @@ int AUD_get_free (void)
...
@@ -490,27 +513,47 @@ int AUD_get_free (void)
int
AUD_get_live
(
void
)
int
AUD_get_live
(
void
)
{
{
return
live
;
return
oss
.
live
;
}
}
int
AUD_get_buffer_size
(
void
)
int
AUD_get_buffer_size
(
void
)
{
{
return
bufsize
;
return
oss
.
bufsize
;
}
#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
#define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
#define QC_OSS_MMAP "QEMU_OSS_MMAP"
static
int
get_conf_val
(
const
char
*
key
,
int
defval
)
{
int
val
=
defval
;
char
*
strval
;
strval
=
getenv
(
key
);
if
(
strval
)
{
val
=
atoi
(
strval
);
}
return
val
;
}
}
void
AUD_init
(
void
)
void
AUD_init
(
void
)
{
{
int
fsp
;
int
fsp
;
int
_fragsize
=
4096
;
DEREF
(
pab
);
DEREF
(
pab
);
fsp
=
_fragsize
;
conf
.
fragsize
=
get_conf_val
(
QC_OSS_FRAGSIZE
,
conf
.
fragsize
);
conf
.
nfrags
=
get_conf_val
(
QC_OSS_NFRAGS
,
conf
.
nfrags
);
conf
.
try_mmap
=
get_conf_val
(
QC_OSS_MMAP
,
conf
.
try_mmap
);
fsp
=
conf
.
fragsize
;
if
(
0
!=
(
fsp
&
(
fsp
-
1
)))
{
if
(
0
!=
(
fsp
&
(
fsp
-
1
)))
{
Fail
(
"fragment size %d is not power of 2"
,
fsp
);
Fail
(
"fragment size %d is not power of 2"
,
fsp
);
}
}
conf
_
fragsize
=
lsbindex
(
fsp
);
conf
.
fragsize
=
lsbindex
(
fsp
);
}
}
#else
#else
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录