Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
934a64cb
Commit
934a64cb
authored
May 24, 2011
by
Andrew Eikum
Committed by
Alexandre Julliard
May 25, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winealsa.drv: Implement device enumeration.
parent
32d7f32c
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
162 additions
and
15 deletions
+162
-15
mmdevdrv.c
dlls/winealsa.drv/mmdevdrv.c
+162
-15
No files found.
dlls/winealsa.drv/mmdevdrv.c
View file @
934a64cb
...
...
@@ -134,6 +134,7 @@ static CRITICAL_SECTION g_sessions_lock;
static
struct
list
g_sessions
=
LIST_INIT
(
g_sessions
);
static
const
WCHAR
defaultW
[]
=
{
'd'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
0
};
static
const
char
defname
[]
=
"default"
;
static
const
IAudioClientVtbl
AudioClient_Vtbl
;
static
const
IAudioRenderClientVtbl
AudioRenderClient_Vtbl
;
...
...
@@ -206,40 +207,186 @@ BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved)
return
TRUE
;
}
HRESULT
WINAPI
AUDDRV_GetEndpointIDs
(
EDataFlow
flow
,
WCHAR
***
ids
,
void
***
keys
,
static
HRESULT
alsa_get_card_devices
(
EDataFlow
flow
,
WCHAR
**
ids
,
char
**
keys
,
UINT
*
num
,
snd_ctl_t
*
ctl
,
int
card
,
const
WCHAR
*
cardnameW
)
{
static
const
WCHAR
dashW
[]
=
{
' '
,
'-'
,
' '
,
0
};
int
err
,
device
;
snd_pcm_info_t
*
info
;
info
=
HeapAlloc
(
GetProcessHeap
(),
0
,
snd_pcm_info_sizeof
());
if
(
!
info
)
return
E_OUTOFMEMORY
;
snd_pcm_info_set_subdevice
(
info
,
0
);
snd_pcm_info_set_stream
(
info
,
flow
==
eRender
?
SND_PCM_STREAM_PLAYBACK
:
SND_PCM_STREAM_CAPTURE
);
device
=
-
1
;
for
(
err
=
snd_ctl_pcm_next_device
(
ctl
,
&
device
);
device
!=
-
1
&&
err
>=
0
;
err
=
snd_ctl_pcm_next_device
(
ctl
,
&
device
)){
const
char
*
devname
;
snd_pcm_info_set_device
(
info
,
device
);
if
((
err
=
snd_ctl_pcm_info
(
ctl
,
info
))
<
0
){
if
(
err
==
-
ENOENT
)
/* This device doesn't have the right stream direction */
continue
;
WARN
(
"Failed to get info for card %d, device %d: %d (%s)
\n
"
,
card
,
device
,
err
,
snd_strerror
(
err
));
continue
;
}
if
(
ids
&&
keys
){
DWORD
len
,
cardlen
;
devname
=
snd_pcm_info_get_name
(
info
);
if
(
!
devname
){
WARN
(
"Unable to get device name for card %d, device %d
\n
"
,
card
,
device
);
continue
;
}
cardlen
=
lstrlenW
(
cardnameW
);
len
=
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
devname
,
-
1
,
NULL
,
0
);
len
+=
lstrlenW
(
dashW
);
len
+=
cardlen
;
ids
[
*
num
]
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
));
if
(
!
ids
[
*
num
]){
HeapFree
(
GetProcessHeap
(),
0
,
info
);
return
E_OUTOFMEMORY
;
}
memcpy
(
ids
[
*
num
],
cardnameW
,
cardlen
*
sizeof
(
WCHAR
));
memcpy
(
ids
[
*
num
]
+
cardlen
,
dashW
,
lstrlenW
(
dashW
)
*
sizeof
(
WCHAR
));
cardlen
+=
lstrlenW
(
dashW
);
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
devname
,
-
1
,
ids
[
*
num
]
+
cardlen
,
len
-
cardlen
);
keys
[
*
num
]
=
HeapAlloc
(
GetProcessHeap
(),
0
,
32
);
if
(
!
keys
[
*
num
]){
HeapFree
(
GetProcessHeap
(),
0
,
info
);
HeapFree
(
GetProcessHeap
(),
0
,
ids
[
*
num
]);
return
E_OUTOFMEMORY
;
}
sprintf
(
keys
[
*
num
],
"hw:%d,%d"
,
card
,
device
);
}
++
(
*
num
);
}
HeapFree
(
GetProcessHeap
(),
0
,
info
);
if
(
err
!=
0
)
WARN
(
"Got a failure during device enumeration on card %d: %d (%s)
\n
"
,
card
,
err
,
snd_strerror
(
err
));
return
S_OK
;
}
static
HRESULT
alsa_enum_devices
(
EDataFlow
flow
,
WCHAR
**
ids
,
char
**
keys
,
UINT
*
num
)
{
int
err
,
card
;
card
=
-
1
;
*
num
=
0
;
for
(
err
=
snd_card_next
(
&
card
);
card
!=
-
1
&&
err
>=
0
;
err
=
snd_card_next
(
&
card
)){
char
cardpath
[
64
];
const
char
*
cardname
;
WCHAR
*
cardnameW
;
snd_ctl_t
*
ctl
;
DWORD
len
;
sprintf
(
cardpath
,
"hw:%u"
,
card
);
if
((
err
=
snd_ctl_open
(
&
ctl
,
cardpath
,
0
))
<
0
){
WARN
(
"Unable to open ctl for ALSA device %s: %d (%s)
\n
"
,
cardpath
,
err
,
snd_strerror
(
err
));
continue
;
}
if
((
err
=
snd_card_get_name
(
card
,
(
char
**
)
&
cardname
))
<
0
){
WARN
(
"Unable to get card name for ALSA device %s: %d (%s)
\n
"
,
cardpath
,
err
,
snd_strerror
(
err
));
/* FIXME: Should be localized */
cardname
=
"Unknown soundcard"
;
}
len
=
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
cardname
,
-
1
,
NULL
,
0
);
cardnameW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
));
if
(
!
cardnameW
){
snd_ctl_close
(
ctl
);
return
E_OUTOFMEMORY
;
}
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
cardname
,
-
1
,
cardnameW
,
len
);
alsa_get_card_devices
(
flow
,
ids
,
keys
,
num
,
ctl
,
card
,
cardnameW
);
HeapFree
(
GetProcessHeap
(),
0
,
cardnameW
);
snd_ctl_close
(
ctl
);
}
if
(
err
!=
0
)
WARN
(
"Got a failure during card enumeration: %d (%s)
\n
"
,
err
,
snd_strerror
(
err
));
return
S_OK
;
}
HRESULT
WINAPI
AUDDRV_GetEndpointIDs
(
EDataFlow
flow
,
WCHAR
***
ids
,
char
***
keys
,
UINT
*
num
,
UINT
*
def_index
)
{
TRACE
(
"%d %p %p %p
\n
"
,
flow
,
ids
,
num
,
def_index
)
;
HRESULT
hr
;
*
num
=
1
;
*
def_index
=
0
;
TRACE
(
"%d %p %p %p %p
\n
"
,
flow
,
ids
,
keys
,
num
,
def_index
);
hr
=
alsa_enum_devices
(
flow
,
NULL
,
NULL
,
num
);
if
(
FAILED
(
hr
))
return
hr
;
*
ids
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
*
));
if
(
!*
ids
)
*
ids
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
num
+
1
)
*
sizeof
(
WCHAR
*
));
*
keys
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
num
+
1
)
*
sizeof
(
char
*
));
if
(
!*
ids
||
!*
keys
){
HeapFree
(
GetProcessHeap
(),
0
,
*
ids
);
HeapFree
(
GetProcessHeap
(),
0
,
*
keys
);
return
E_OUTOFMEMORY
;
}
(
*
ids
)[
0
]
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
defaultW
));
if
(
!
(
*
ids
)[
0
]){
memcpy
((
*
ids
)[
0
],
defaultW
,
sizeof
(
defaultW
));
(
*
keys
)[
0
]
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
defname
));
memcpy
((
*
keys
)[
0
],
defname
,
sizeof
(
defname
));
*
def_index
=
0
;
hr
=
alsa_enum_devices
(
flow
,
(
*
ids
)
+
1
,
(
*
keys
)
+
1
,
num
);
if
(
FAILED
(
hr
)){
int
i
;
for
(
i
=
0
;
i
<
*
num
;
++
i
){
HeapFree
(
GetProcessHeap
(),
0
,
(
*
ids
)[
i
]);
HeapFree
(
GetProcessHeap
(),
0
,
(
*
keys
)[
i
]);
}
HeapFree
(
GetProcessHeap
(),
0
,
*
ids
);
HeapFree
(
GetProcessHeap
(),
0
,
*
keys
);
return
E_OUTOFMEMORY
;
}
lstrcpyW
((
*
ids
)[
0
],
defaultW
);
*
keys
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
void
*
));
(
*
keys
)[
0
]
=
NULL
;
++
(
*
num
);
/* for default device */
return
S_OK
;
}
HRESULT
WINAPI
AUDDRV_GetAudioEndpoint
(
void
*
key
,
IMMDevice
*
dev
,
HRESULT
WINAPI
AUDDRV_GetAudioEndpoint
(
const
char
*
key
,
IMMDevice
*
dev
,
EDataFlow
dataflow
,
IAudioClient
**
out
)
{
ACImpl
*
This
;
int
err
;
snd_pcm_stream_t
stream
;
TRACE
(
"
%p
%p %d %p
\n
"
,
key
,
dev
,
dataflow
,
out
);
TRACE
(
"
\"
%s
\"
%p %d %p
\n
"
,
key
,
dev
,
dataflow
,
out
);
This
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
ACImpl
));
if
(
!
This
)
...
...
@@ -262,10 +409,10 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(void *key, IMMDevice *dev,
}
This
->
dataflow
=
dataflow
;
if
((
err
=
snd_pcm_open
(
&
This
->
pcm_handle
,
"default"
,
stream
,
if
((
err
=
snd_pcm_open
(
&
This
->
pcm_handle
,
key
,
stream
,
SND_PCM_NONBLOCK
))
<
0
){
HeapFree
(
GetProcessHeap
(),
0
,
This
);
WARN
(
"Unable to open PCM
\"
default
\"
: %d (%s)
\n
"
,
err
,
WARN
(
"Unable to open PCM
\"
%s
\"
: %d (%s)
\n
"
,
key
,
err
,
snd_strerror
(
err
));
return
E_FAIL
;
}
...
...
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