Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
9ad60d1d
Commit
9ad60d1d
authored
Aug 05, 2011
by
Andrew Eikum
Committed by
Alexandre Julliard
Aug 05, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winealsa.drv: Inject handle_underrun=1 setting for pulse-backed devices.
parent
8c109aee
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
104 additions
and
6 deletions
+104
-6
mmdevdrv.c
dlls/winealsa.drv/mmdevdrv.c
+104
-6
No files found.
dlls/winealsa.drv/mmdevdrv.c
View file @
9ad60d1d
...
...
@@ -407,12 +407,96 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, char ***keys,
return
S_OK
;
}
/* Using the pulse PCM device from alsa-plugins 1.0.24 triggers a bug
* which causes audio to cease playing after a few minutes of playback.
* Setting handle_underrun=1 on pulse-backed ALSA devices seems to work
* around this issue. */
static
snd_config_t
*
make_handle_underrun_config
(
const
char
*
name
)
{
snd_config_t
*
lconf
,
*
dev_node
,
*
hu_node
,
*
type_node
;
char
dev_node_name
[
64
];
const
char
*
type_str
;
int
err
;
snd_config_update
();
if
((
err
=
snd_config_copy
(
&
lconf
,
snd_config
))
<
0
){
WARN
(
"snd_config_copy failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
sprintf
(
dev_node_name
,
"pcm.%s"
,
name
);
err
=
snd_config_search
(
lconf
,
dev_node_name
,
&
dev_node
);
if
(
err
==
-
ENOENT
){
snd_config_delete
(
lconf
);
return
NULL
;
}
if
(
err
<
0
){
snd_config_delete
(
lconf
);
WARN
(
"snd_config_search failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
/* ALSA is extremely fragile. If it runs into a config setting it doesn't
* recognize, it tends to fail or assert. So we only want to inject
* handle_underrun=1 on devices that we know will recognize it. */
err
=
snd_config_search
(
dev_node
,
"type"
,
&
type_node
);
if
(
err
==
-
ENOENT
){
snd_config_delete
(
lconf
);
return
NULL
;
}
if
(
err
<
0
){
snd_config_delete
(
lconf
);
WARN
(
"snd_config_search failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
if
((
err
=
snd_config_get_string
(
type_node
,
&
type_str
))
<
0
){
snd_config_delete
(
lconf
);
return
NULL
;
}
if
(
strcmp
(
type_str
,
"pulse"
)
!=
0
){
snd_config_delete
(
lconf
);
return
NULL
;
}
err
=
snd_config_search
(
dev_node
,
"handle_underrun"
,
&
hu_node
);
if
(
err
>=
0
){
/* user already has an explicit handle_underrun setting, so don't
* use a local config */
snd_config_delete
(
lconf
);
return
NULL
;
}
if
(
err
!=
-
ENOENT
){
snd_config_delete
(
lconf
);
WARN
(
"snd_config_search failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
if
((
err
=
snd_config_imake_integer
(
&
hu_node
,
"handle_underrun"
,
1
))
<
0
){
snd_config_delete
(
lconf
);
WARN
(
"snd_config_imake_integer failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
if
((
err
=
snd_config_add
(
dev_node
,
hu_node
))
<
0
){
snd_config_delete
(
lconf
);
WARN
(
"snd_config_add failed: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
NULL
;
}
return
lconf
;
}
HRESULT
WINAPI
AUDDRV_GetAudioEndpoint
(
const
char
*
key
,
IMMDevice
*
dev
,
EDataFlow
dataflow
,
IAudioClient
**
out
)
{
ACImpl
*
This
;
int
err
;
snd_pcm_stream_t
stream
;
snd_config_t
*
lconf
;
TRACE
(
"
\"
%s
\"
%p %d %p
\n
"
,
key
,
dev
,
dataflow
,
out
);
...
...
@@ -436,13 +520,27 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(const char *key, IMMDevice *dev,
return
E_UNEXPECTED
;
}
lconf
=
make_handle_underrun_config
(
key
);
This
->
dataflow
=
dataflow
;
if
((
err
=
snd_pcm_open
(
&
This
->
pcm_handle
,
key
,
stream
,
SND_PCM_NONBLOCK
))
<
0
){
HeapFree
(
GetProcessHeap
(),
0
,
This
);
WARN
(
"Unable to open PCM
\"
%s
\"
: %d (%s)
\n
"
,
key
,
err
,
snd_strerror
(
err
));
return
E_FAIL
;
if
(
lconf
){
if
((
err
=
snd_pcm_open_lconf
(
&
This
->
pcm_handle
,
key
,
stream
,
SND_PCM_NONBLOCK
,
lconf
))
<
0
){
snd_config_delete
(
lconf
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
WARN
(
"Unable to open PCM
\"
%s
\"
: %d (%s)
\n
"
,
key
,
err
,
snd_strerror
(
err
));
return
E_FAIL
;
}
snd_config_delete
(
lconf
);
}
else
{
if
((
err
=
snd_pcm_open
(
&
This
->
pcm_handle
,
key
,
stream
,
SND_PCM_NONBLOCK
))
<
0
){
HeapFree
(
GetProcessHeap
(),
0
,
This
);
WARN
(
"Unable to open PCM
\"
%s
\"
: %d (%s)
\n
"
,
key
,
err
,
snd_strerror
(
err
));
return
E_FAIL
;
}
}
This
->
hw_params
=
HeapAlloc
(
GetProcessHeap
(),
0
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment