Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
21e2557b
Commit
21e2557b
authored
Feb 04, 2013
by
Denis Charmet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove aout_Packet from directsound audio output
parent
8cbd52ac
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
236 deletions
+178
-236
modules/audio_output/directx.c
modules/audio_output/directx.c
+178
-236
No files found.
modules/audio_output/directx.c
View file @
21e2557b
...
@@ -35,25 +35,10 @@
...
@@ -35,25 +35,10 @@
#include <vlc_plugin.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
#include <vlc_aout.h>
#include <vlc_charset.h>
#include <vlc_charset.h>
#include <vlc_atomic.h>
#include "windows_audio_common.h"
#include "windows_audio_common.h"
/*****************************************************************************
#define DS_BUF_SIZE (1024*1024)
* notification_thread_t: DirectX event thread
*****************************************************************************/
typedef
struct
notification_thread_t
{
int
i_frame_size
;
/* size in bytes of one frame */
int
i_write_slot
;
/* current write position in our circular buffer */
mtime_t
start_date
;
HANDLE
event
;
vlc_thread_t
thread
;
vlc_atomic_t
abort
;
}
notification_thread_t
;
/*****************************************************************************
/*****************************************************************************
* aout_sys_t: directx audio output method descriptor
* aout_sys_t: directx audio output method descriptor
...
@@ -63,23 +48,24 @@ typedef struct notification_thread_t
...
@@ -63,23 +48,24 @@ typedef struct notification_thread_t
*****************************************************************************/
*****************************************************************************/
struct
aout_sys_t
struct
aout_sys_t
{
{
aout_packet_t
packet
;
HINSTANCE
hdsound_dll
;
/* handle of the opened dsound dll */
HINSTANCE
hdsound_dll
;
/* handle of the opened dsound dll */
LPDIRECTSOUND
p_dsobject
;
/* main Direct Sound object */
LPDIRECTSOUND
p_dsobject
;
/* main Direct Sound object */
LPDIRECTSOUNDBUFFER
p_dsbuffer
;
/* the sound buffer we use (direct sound
LPDIRECTSOUNDBUFFER
p_dsbuffer
;
/* the sound buffer we use (direct sound
* takes care of mixing all the
* takes care of mixing all the
* secondary buffers into the primary) */
* secondary buffers into the primary) */
LPDIRECTSOUNDNOTIFY
p_notify
;
HANDLE
hnotify_evt
;
struct
struct
{
{
LONG
volume
;
float
volume
;
LONG
mb
;
LONG
mb
;
bool
mute
;
bool
mute
;
}
volume
;
}
volume
;
notification_thread_t
notif
;
/* DirectSoundThread id */
int
i_bytes_per_sample
;
/* Size in bytes of one frame */
int
i_rate
;
/* Sample rate */
int
i_frame_size
;
/* Size in bytes of one frame */
int
i_speaker_setup
;
/* Speaker setup override */
int
i_speaker_setup
;
/* Speaker setup override */
...
@@ -87,6 +73,8 @@ struct aout_sys_t
...
@@ -87,6 +73,8 @@ struct aout_sys_t
uint8_t
chan_table
[
AOUT_CHAN_MAX
];
uint8_t
chan_table
[
AOUT_CHAN_MAX
];
uint32_t
i_channel_mask
;
uint32_t
i_channel_mask
;
vlc_fourcc_t
format
;
vlc_fourcc_t
format
;
size_t
i_write
;
};
};
/*****************************************************************************
/*****************************************************************************
...
@@ -95,18 +83,20 @@ struct aout_sys_t
...
@@ -95,18 +83,20 @@ struct aout_sys_t
static
int
Open
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Stop
(
audio_output_t
*
);
static
void
Stop
(
audio_output_t
*
);
static
void
Play
(
audio_output_t
*
,
block_t
*
);
static
void
Play
(
audio_output_t
*
,
block_t
*
);
static
int
VolumeSet
(
audio_output_t
*
,
float
);
static
int
VolumeSet
(
audio_output_t
*
,
float
);
static
int
MuteSet
(
audio_output_t
*
,
bool
);
static
int
MuteSet
(
audio_output_t
*
,
bool
);
static
void
Flush
(
audio_output_t
*
,
bool
);
static
void
Pause
(
audio_output_t
*
,
bool
,
mtime_t
);
static
int
TimeGet
(
audio_output_t
*
,
mtime_t
*
);
/* local functions */
/* local functions */
static
void
Probe
(
audio_output_t
*
,
const
audio_sample_format_t
*
);
static
void
Probe
(
audio_output_t
*
,
const
audio_sample_format_t
*
);
static
int
InitDirectSound
(
audio_output_t
*
);
static
int
InitDirectSound
(
audio_output_t
*
);
static
int
CreateDSBuffer
(
audio_output_t
*
,
int
,
int
,
int
,
int
,
int
,
bool
);
static
int
CreateDSBuffer
(
audio_output_t
*
,
int
,
int
,
int
,
int
,
bool
);
static
int
CreateDSBufferPCM
(
audio_output_t
*
,
vlc_fourcc_t
*
,
int
,
int
,
bool
);
static
int
CreateDSBufferPCM
(
audio_output_t
*
,
vlc_fourcc_t
*
,
int
,
int
,
bool
);
static
void
DestroyDSBuffer
(
audio_output_t
*
);
static
void
DestroyDSBuffer
(
audio_output_t
*
);
static
void
*
DirectSoundThread
(
void
*
);
static
int
FillBuffer
(
audio_output_t
*
,
block_t
*
);
static
int
FillBuffer
(
audio_output_t
*
,
int
,
block_t
*
);
static
int
ReloadDirectXDevices
(
vlc_object_t
*
,
const
char
*
,
static
int
ReloadDirectXDevices
(
vlc_object_t
*
,
const
char
*
,
char
***
,
char
***
);
char
***
,
char
***
);
...
@@ -145,7 +135,7 @@ vlc_module_begin ()
...
@@ -145,7 +135,7 @@ vlc_module_begin ()
add_string
(
"directx-audio-speaker"
,
"Windows default"
,
add_string
(
"directx-audio-speaker"
,
"Windows default"
,
SPEAKER_TEXT
,
SPEAKER_LONGTEXT
,
true
)
SPEAKER_TEXT
,
SPEAKER_LONGTEXT
,
true
)
change_string_list
(
speaker_list
,
speaker_list
)
change_string_list
(
speaker_list
,
speaker_list
)
add_
integer
(
"directx-volume"
,
DSBVOLUME_MAX
,
add_
float
(
"directx-volume"
,
1
.
0
f
,
VOLUME_TEXT
,
VOLUME_LONGTEXT
,
true
)
VOLUME_TEXT
,
VOLUME_LONGTEXT
,
true
)
change_integer_range
(
DSBVOLUME_MIN
,
DSBVOLUME_MAX
)
change_integer_range
(
DSBVOLUME_MIN
,
DSBVOLUME_MAX
)
...
@@ -216,19 +206,15 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
...
@@ -216,19 +206,15 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
/* Calculate the frame size in bytes */
/* Calculate the frame size in bytes */
fmt
->
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
fmt
->
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
fmt
->
i_frame_length
=
A52_FRAME_NB
;
fmt
->
i_frame_length
=
A52_FRAME_NB
;
p_aout
->
sys
->
i_frame_size
=
fmt
->
i_bytes_per_frame
;
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_SPDIFL
,
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_SPDIFL
,
fmt
->
i_physical_channels
,
fmt
->
i_physical_channels
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
false
)
p_aout
->
sys
->
i_frame_size
,
false
)
!=
VLC_SUCCESS
)
!=
VLC_SUCCESS
)
{
{
msg_Err
(
p_aout
,
"cannot open directx audio device"
);
msg_Err
(
p_aout
,
"cannot open directx audio device"
);
goto
error
;
goto
error
;
}
}
aout_PacketInit
(
p_aout
,
&
p_aout
->
sys
->
packet
,
A52_FRAME_NB
,
fmt
);
}
}
else
else
{
{
...
@@ -254,37 +240,19 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
...
@@ -254,37 +240,19 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
msg_Err
(
p_aout
,
"cannot open directx audio device"
);
msg_Err
(
p_aout
,
"cannot open directx audio device"
);
goto
error
;
goto
error
;
}
}
/* Calculate the frame size in bytes */
aout_PacketInit
(
p_aout
,
&
p_aout
->
sys
->
packet
,
fmt
->
i_rate
/
20
,
fmt
);
}
}
p_aout
->
sys
->
i_write
=
0
;
/* Force volume update in thread. TODO: use session volume on Vista+ */
/* Force volume update */
p_aout
->
sys
->
volume
.
volume
=
p_aout
->
sys
->
volume
.
mb
;
VolumeSet
(
p_aout
,
p_aout
->
sys
->
volume
.
volume
);
MuteSet
(
p_aout
,
p_aout
->
sys
->
volume
.
mute
);
/* Now we need to setup our DirectSound play notification structure */
vlc_atomic_set
(
&
p_aout
->
sys
->
notif
.
abort
,
0
);
p_aout
->
sys
->
notif
.
event
=
CreateEvent
(
0
,
FALSE
,
FALSE
,
0
);
if
(
unlikely
(
p_aout
->
sys
->
notif
.
event
==
NULL
)
)
abort
();
p_aout
->
sys
->
notif
.
i_frame_size
=
p_aout
->
sys
->
i_frame_size
;
/* then launch the notification thread */
/* then launch the notification thread */
msg_Dbg
(
p_aout
,
"creating DirectSoundThread"
);
p_aout
->
time_get
=
TimeGet
;
if
(
vlc_clone
(
&
p_aout
->
sys
->
notif
.
thread
,
DirectSoundThread
,
p_aout
,
VLC_THREAD_PRIORITY_HIGHEST
)
)
{
msg_Err
(
p_aout
,
"cannot create DirectSoundThread"
);
CloseHandle
(
p_aout
->
sys
->
notif
.
event
);
p_aout
->
sys
->
notif
.
event
=
NULL
;
aout_PacketDestroy
(
p_aout
);
goto
error
;
}
p_aout
->
time_get
=
aout_PacketTimeGet
;
p_aout
->
play
=
Play
;
p_aout
->
play
=
Play
;
p_aout
->
pause
=
NULL
;
p_aout
->
pause
=
Pause
;
p_aout
->
flush
=
aout_PacketFlush
;
p_aout
->
flush
=
Flush
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
error:
error:
...
@@ -479,8 +447,7 @@ static void Probe( audio_output_t * p_aout, const audio_sample_format_t *fmt )
...
@@ -479,8 +447,7 @@ static void Probe( audio_output_t * p_aout, const audio_sample_format_t *fmt )
{
{
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_SPDIFL
,
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_SPDIFL
,
fmt
->
i_physical_channels
,
fmt
->
i_physical_channels
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
true
)
AOUT_SPDIF_SIZE
,
true
)
==
VLC_SUCCESS
)
==
VLC_SUCCESS
)
{
{
msg_Dbg
(
p_aout
,
"device supports A/52 over S/PDIF"
);
msg_Dbg
(
p_aout
,
"device supports A/52 over S/PDIF"
);
...
@@ -511,26 +478,29 @@ static void Probe( audio_output_t * p_aout, const audio_sample_format_t *fmt )
...
@@ -511,26 +478,29 @@ static void Probe( audio_output_t * p_aout, const audio_sample_format_t *fmt )
*****************************************************************************/
*****************************************************************************/
static
void
Play
(
audio_output_t
*
p_aout
,
block_t
*
p_buffer
)
static
void
Play
(
audio_output_t
*
p_aout
,
block_t
*
p_buffer
)
{
{
/* get the playing date of the first aout buffer */
if
(
FillBuffer
(
p_aout
,
p_buffer
)
==
VLC_SUCCESS
)
p_aout
->
sys
->
notif
.
start_date
=
p_buffer
->
i_pts
;
{
/* start playing the buffer */
/* fill in the first samples (zeroes) */
HRESULT
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
FillBuffer
(
p_aout
,
0
,
NULL
);
0
,
0
,
DSBPLAY_LOOPING
);
if
(
dsresult
==
DSERR_BUFFERLOST
)
/* wake up the audio output thread */
{
SetEvent
(
p_aout
->
sys
->
notif
.
event
);
IDirectSoundBuffer_Restore
(
p_aout
->
sys
->
p_dsbuffer
);
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
aout_PacketPlay
(
p_aout
,
p_buffer
);
0
,
0
,
DSBPLAY_LOOPING
);
p_aout
->
play
=
aout_PacketPlay
;
}
if
(
dsresult
!=
DS_OK
)
msg_Err
(
p_aout
,
"cannot start playing buffer"
);
}
}
}
static
int
VolumeSet
(
audio_output_t
*
p_aout
,
float
vol
)
static
int
VolumeSet
(
audio_output_t
*
p_aout
,
float
vol
ume
)
{
{
aout_sys_t
*
sys
=
p_aout
->
sys
;
aout_sys_t
*
sys
=
p_aout
->
sys
;
int
ret
=
0
;
int
ret
=
0
;
/* Convert UI volume to linear factor (cube) */
/* Convert UI volume to linear factor (cube) */
vol
=
vol
*
vol
*
vol
;
float
vol
=
volume
*
volume
*
volume
;
/* millibels from linear amplification */
/* millibels from linear amplification */
LONG
mb
=
lroundf
(
2000
.
f
*
log10f
(
vol
));
LONG
mb
=
lroundf
(
2000
.
f
*
log10f
(
vol
));
...
@@ -546,28 +516,31 @@ static int VolumeSet( audio_output_t *p_aout, float vol )
...
@@ -546,28 +516,31 @@ static int VolumeSet( audio_output_t *p_aout, float vol )
mb
=
DSBVOLUME_MIN
;
mb
=
DSBVOLUME_MIN
;
sys
->
volume
.
mb
=
mb
;
sys
->
volume
.
mb
=
mb
;
if
(
!
sys
->
volume
.
mute
)
sys
->
volume
.
volume
=
volume
;
InterlockedExchange
(
&
sys
->
volume
.
volume
,
mb
);
if
(
!
sys
->
volume
.
mute
&&
sys
->
p_dsbuffer
&&
IDirectSoundBuffer_SetVolume
(
sys
->
p_dsbuffer
,
mb
)
!=
DS_OK
)
return
-
1
;
/* Convert back to UI volume */
/* Convert back to UI volume */
vol
=
cbrtf
(
powf
(
10
.
f
,
((
float
)
mb
)
/
2000
.
f
));
aout_VolumeReport
(
p_aout
,
volume
);
aout_VolumeReport
(
p_aout
,
vol
);
if
(
var_InheritBool
(
p_aout
,
"volume-save"
)
)
if
(
var_InheritBool
(
p_aout
,
"volume-save"
)
)
config_Put
Int
(
p_aout
,
"directx-volume"
,
mb
);
config_Put
Float
(
p_aout
,
"directx-volume"
,
volume
);
return
ret
;
return
ret
;
}
}
static
int
MuteSet
(
audio_output_t
*
p_aout
,
bool
mute
)
static
int
MuteSet
(
audio_output_t
*
p_aout
,
bool
mute
)
{
{
HRESULT
res
=
DS_OK
;
aout_sys_t
*
sys
=
p_aout
->
sys
;
aout_sys_t
*
sys
=
p_aout
->
sys
;
sys
->
volume
.
mute
=
mute
;
sys
->
volume
.
mute
=
mute
;
InterlockedExchange
(
&
sys
->
volume
.
volume
,
mute
?
DSBVOLUME_MIN
:
sys
->
volume
.
mb
);
if
(
sys
->
p_dsbuffer
)
res
=
IDirectSoundBuffer_SetVolume
(
sys
->
p_dsbuffer
,
mute
?
DSBVOLUME_MIN
:
sys
->
volume
.
mb
);
aout_MuteReport
(
p_aout
,
mute
);
aout_MuteReport
(
p_aout
,
mute
);
return
0
;
return
(
res
!=
DS_OK
)
;
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -576,27 +549,19 @@ static int MuteSet( audio_output_t *p_aout, bool mute )
...
@@ -576,27 +549,19 @@ static int MuteSet( audio_output_t *p_aout, bool mute )
static
void
Stop
(
audio_output_t
*
p_aout
)
static
void
Stop
(
audio_output_t
*
p_aout
)
{
{
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
msg_Dbg
(
p_aout
,
"closing audio device"
);
msg_Dbg
(
p_aout
,
"closing audio device"
);
/* kill the position notification thread, if any */
if
(
p_sys
->
p_notify
)
if
(
p_sys
->
notif
.
event
!=
NULL
)
IDirectSoundNotify_Release
(
p_sys
->
p_notify
);
{
p_sys
->
p_notify
=
NULL
;
vlc_atomic_set
(
&
p_aout
->
sys
->
notif
.
abort
,
1
);
/* wake up the audio thread if needed */
if
(
p_aout
->
play
==
Play
)
SetEvent
(
p_sys
->
notif
.
event
);
vlc_join
(
p_sys
->
notif
.
thread
,
NULL
);
CloseHandle
(
p_sys
->
notif
.
event
);
aout_PacketDestroy
(
p_aout
);
}
IDirectSoundBuffer_Stop
(
p_sys
->
p_dsbuffer
);
/* release the secondary buffer */
/* release the secondary buffer */
DestroyDSBuffer
(
p_aout
);
DestroyDSBuffer
(
p_aout
);
/* finally release the DirectSound object */
/* finally release the DirectSound object */
if
(
p_sys
->
p_dsobject
)
IDirectSound_Release
(
p_sys
->
p_dsobject
);
if
(
p_sys
->
p_dsobject
)
IDirectSound_Release
(
p_sys
->
p_dsobject
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -675,7 +640,7 @@ static int InitDirectSound( audio_output_t *p_aout )
...
@@ -675,7 +640,7 @@ static int InitDirectSound( audio_output_t *p_aout )
*****************************************************************************/
*****************************************************************************/
static
int
CreateDSBuffer
(
audio_output_t
*
p_aout
,
int
i_format
,
static
int
CreateDSBuffer
(
audio_output_t
*
p_aout
,
int
i_format
,
int
i_channels
,
int
i_nb_channels
,
int
i_rate
,
int
i_channels
,
int
i_nb_channels
,
int
i_rate
,
int
i_bytes_per_frame
,
bool
b_probe
)
bool
b_probe
)
{
{
WAVEFORMATEXTENSIBLE
waveformat
;
WAVEFORMATEXTENSIBLE
waveformat
;
DSBUFFERDESC
dsbdesc
;
DSBUFFERDESC
dsbdesc
;
...
@@ -723,14 +688,16 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
...
@@ -723,14 +688,16 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
waveformat
.
Format
.
nAvgBytesPerSec
=
waveformat
.
Format
.
nAvgBytesPerSec
=
waveformat
.
Format
.
nSamplesPerSec
*
waveformat
.
Format
.
nBlockAlign
;
waveformat
.
Format
.
nSamplesPerSec
*
waveformat
.
Format
.
nBlockAlign
;
p_aout
->
sys
->
i_bytes_per_sample
=
waveformat
.
Format
.
nBlockAlign
;
p_aout
->
sys
->
format
=
i_format
;
p_aout
->
sys
->
format
=
i_format
;
/* Then fill in the direct sound descriptor */
/* Then fill in the direct sound descriptor */
memset
(
&
dsbdesc
,
0
,
sizeof
(
DSBUFFERDESC
));
memset
(
&
dsbdesc
,
0
,
sizeof
(
DSBUFFERDESC
));
dsbdesc
.
dwSize
=
sizeof
(
DSBUFFERDESC
);
dsbdesc
.
dwSize
=
sizeof
(
DSBUFFERDESC
);
dsbdesc
.
dwFlags
=
DSBCAPS_GETCURRENTPOSITION2
/* Better position accuracy */
dsbdesc
.
dwFlags
=
DSBCAPS_GETCURRENTPOSITION2
/* Better position accuracy */
|
DSBCAPS_GLOBALFOCUS
/* Allows background playing */
|
DSBCAPS_GLOBALFOCUS
/* Allows background playing */
|
DSBCAPS_CTRLVOLUME
;
/* Allows volume control */
|
DSBCAPS_CTRLVOLUME
/* Allows volume control */
|
DSBCAPS_CTRLPOSITIONNOTIFY
;
/* Allow position notifications */
/* Only use the new WAVE_FORMAT_EXTENSIBLE format for multichannel audio */
/* Only use the new WAVE_FORMAT_EXTENSIBLE format for multichannel audio */
if
(
i_nb_channels
<=
2
)
if
(
i_nb_channels
<=
2
)
...
@@ -747,7 +714,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
...
@@ -747,7 +714,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
dsbdesc
.
dwFlags
|=
DSBCAPS_LOCHARDWARE
;
dsbdesc
.
dwFlags
|=
DSBCAPS_LOCHARDWARE
;
}
}
dsbdesc
.
dwBufferBytes
=
FRAMES_NUM
*
i_bytes_per_frame
;
/* buffer size */
dsbdesc
.
dwBufferBytes
=
DS_BUF_SIZE
;
/* buffer size */
dsbdesc
.
lpwfxFormat
=
(
WAVEFORMATEX
*
)
&
waveformat
;
dsbdesc
.
lpwfxFormat
=
(
WAVEFORMATEX
*
)
&
waveformat
;
if
FAILED
(
IDirectSound_CreateSoundBuffer
(
if
FAILED
(
IDirectSound_CreateSoundBuffer
(
...
@@ -781,7 +748,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
...
@@ -781,7 +748,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
p_aout
->
sys
->
i_
frame_size
=
i_bytes_per_fram
e
;
p_aout
->
sys
->
i_
rate
=
i_rat
e
;
p_aout
->
sys
->
i_channel_mask
=
waveformat
.
dwChannelMask
;
p_aout
->
sys
->
i_channel_mask
=
waveformat
.
dwChannelMask
;
p_aout
->
sys
->
chans_to_reorder
=
p_aout
->
sys
->
chans_to_reorder
=
aout_CheckChannelReorder
(
pi_channels_in
,
pi_channels_out
,
aout_CheckChannelReorder
(
pi_channels_in
,
pi_channels_out
,
...
@@ -792,6 +759,18 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
...
@@ -792,6 +759,18 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
msg_Dbg
(
p_aout
,
"channel reordering needed"
);
msg_Dbg
(
p_aout
,
"channel reordering needed"
);
}
}
if
(
IDirectSoundBuffer_QueryInterface
(
p_aout
->
sys
->
p_dsbuffer
,
&
IID_IDirectSoundNotify
,
(
void
**
)
&
p_aout
->
sys
->
p_notify
)
!=
DS_OK
)
{
msg_Err
(
p_aout
,
"Couldn't query IDirectSoundNotify"
);
p_aout
->
sys
->
p_notify
=
NULL
;
}
FillBuffer
(
p_aout
,
NULL
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -810,13 +789,11 @@ static int CreateDSBufferPCM( audio_output_t *p_aout, vlc_fourcc_t *i_format,
...
@@ -810,13 +789,11 @@ static int CreateDSBufferPCM( audio_output_t *p_aout, vlc_fourcc_t *i_format,
if
(
!
var_GetBool
(
p_aout
,
"directx-audio-float32"
)
||
if
(
!
var_GetBool
(
p_aout
,
"directx-audio-float32"
)
||
i_nb_channels
>
2
||
i_nb_channels
>
2
||
CreateDSBuffer
(
p_aout
,
VLC_CODEC_FL32
,
CreateDSBuffer
(
p_aout
,
VLC_CODEC_FL32
,
i_channels
,
i_nb_channels
,
i_rate
,
i_channels
,
i_nb_channels
,
i_rate
,
b_probe
)
(
i_rate
/
20
)
*
4
*
i_nb_channels
,
b_probe
)
!=
VLC_SUCCESS
)
!=
VLC_SUCCESS
)
{
{
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_S16N
,
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_S16N
,
i_channels
,
i_nb_channels
,
i_rate
,
i_channels
,
i_nb_channels
,
i_rate
,
b_probe
)
(
i_rate
/
20
)
*
2
*
i_nb_channels
,
b_probe
)
!=
VLC_SUCCESS
)
!=
VLC_SUCCESS
)
{
{
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -853,10 +830,11 @@ static void DestroyDSBuffer( audio_output_t *p_aout )
...
@@ -853,10 +830,11 @@ static void DestroyDSBuffer( audio_output_t *p_aout )
*****************************************************************************
*****************************************************************************
* Returns VLC_SUCCESS on success.
* Returns VLC_SUCCESS on success.
*****************************************************************************/
*****************************************************************************/
static
int
FillBuffer
(
audio_output_t
*
p_aout
,
int
i_frame
,
block_t
*
p_buffer
)
static
int
FillBuffer
(
audio_output_t
*
p_aout
,
block_t
*
p_buffer
)
{
{
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
notification_thread_t
*
p_notif
=
&
p_sys
->
notif
;
size_t
towrite
=
(
p_buffer
)
?
p_buffer
->
i_buffer
:
DS_BUF_SIZE
;
void
*
p_write_position
,
*
p_wrap_around
;
void
*
p_write_position
,
*
p_wrap_around
;
unsigned
long
l_bytes1
,
l_bytes2
;
unsigned
long
l_bytes1
,
l_bytes2
;
HRESULT
dsresult
;
HRESULT
dsresult
;
...
@@ -864,20 +842,20 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
...
@@ -864,20 +842,20 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
/* Before copying anything, we have to lock the buffer */
/* Before copying anything, we have to lock the buffer */
dsresult
=
IDirectSoundBuffer_Lock
(
dsresult
=
IDirectSoundBuffer_Lock
(
p_sys
->
p_dsbuffer
,
/* DS buffer */
p_sys
->
p_dsbuffer
,
/* DS buffer */
i_frame
*
p_notif
->
i_frame_size
,
/* Start offset */
p_aout
->
sys
->
i_write
,
/* Start offset */
p_notif
->
i_frame_size
,
/* Number of bytes */
towrite
,
/* Number of bytes */
&
p_write_position
,
/* Address of lock start */
&
p_write_position
,
/* Address of lock start */
&
l_bytes1
,
/* Count of bytes locked before wrap around */
&
l_bytes1
,
/* Count of bytes locked before wrap around */
&
p_wrap_around
,
/* Buffer address (if wrap around) */
&
p_wrap_around
,
/* Buffer address (if wrap around) */
&
l_bytes2
,
/* Count of bytes after wrap around */
&
l_bytes2
,
/* Count of bytes after wrap around */
0
);
/* Flags
*/
0
);
/* Flags: DSBLOCK_FROMWRITECURSOR is buggy
*/
if
(
dsresult
==
DSERR_BUFFERLOST
)
if
(
dsresult
==
DSERR_BUFFERLOST
)
{
{
IDirectSoundBuffer_Restore
(
p_sys
->
p_dsbuffer
);
IDirectSoundBuffer_Restore
(
p_sys
->
p_dsbuffer
);
dsresult
=
IDirectSoundBuffer_Lock
(
dsresult
=
IDirectSoundBuffer_Lock
(
p_sys
->
p_dsbuffer
,
p_sys
->
p_dsbuffer
,
i_frame
*
p_notif
->
i_frame_siz
e
,
p_aout
->
sys
->
i_writ
e
,
p_notif
->
i_frame_siz
e
,
towrit
e
,
&
p_write_position
,
&
p_write_position
,
&
l_bytes1
,
&
l_bytes1
,
&
p_wrap_around
,
&
p_wrap_around
,
...
@@ -904,6 +882,8 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
...
@@ -904,6 +882,8 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
p_sys
->
format
);
p_sys
->
format
);
memcpy
(
p_write_position
,
p_buffer
->
p_buffer
,
l_bytes1
);
memcpy
(
p_write_position
,
p_buffer
->
p_buffer
,
l_bytes1
);
if
(
l_bytes1
<
p_buffer
->
i_buffer
)
memcpy
(
p_wrap_around
,
p_buffer
->
p_buffer
+
l_bytes1
,
l_bytes2
);
block_Release
(
p_buffer
);
block_Release
(
p_buffer
);
}
}
...
@@ -911,117 +891,10 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
...
@@ -911,117 +891,10 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
IDirectSoundBuffer_Unlock
(
p_sys
->
p_dsbuffer
,
p_write_position
,
l_bytes1
,
IDirectSoundBuffer_Unlock
(
p_sys
->
p_dsbuffer
,
p_write_position
,
l_bytes1
,
p_wrap_around
,
l_bytes2
);
p_wrap_around
,
l_bytes2
);
p_notif
->
i_write_slot
=
(
i_frame
+
1
)
%
FRAMES_NUM
;
p_sys
->
i_write
+=
towrite
;
return
VLC_SUCCESS
;
p_sys
->
i_write
%=
DS_BUF_SIZE
;
}
/*****************************************************************************
* DirectSoundThread: this thread will capture play notification events.
*****************************************************************************
* We use this thread to emulate a callback mechanism. The thread probes for
* event notification and fills up the DS secondary buffer when needed.
*****************************************************************************/
static
void
*
DirectSoundThread
(
void
*
data
)
{
audio_output_t
*
p_aout
=
(
audio_output_t
*
)
data
;
notification_thread_t
*
p_notif
=
&
p_aout
->
sys
->
notif
;
mtime_t
last_time
;
msg_Dbg
(
p_aout
,
"DirectSoundThread ready"
);
/* Wait here until Play() is called */
WaitForSingleObject
(
p_notif
->
event
,
INFINITE
);
if
(
!
vlc_atomic_get
(
&
p_notif
->
abort
)
)
{
HRESULT
dsresult
;
mwait
(
p_notif
->
start_date
-
AOUT_MAX_PTS_ADVANCE
/
2
);
/* start playing the buffer */
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
0
,
/* Unused */
0
,
/* Unused */
DSBPLAY_LOOPING
);
/* Flags */
if
(
dsresult
==
DSERR_BUFFERLOST
)
{
IDirectSoundBuffer_Restore
(
p_aout
->
sys
->
p_dsbuffer
);
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
0
,
/* Unused */
0
,
/* Unused */
DSBPLAY_LOOPING
);
/* Flags */
}
if
(
dsresult
!=
DS_OK
)
{
msg_Err
(
p_aout
,
"cannot start playing buffer"
);
}
}
last_time
=
mdate
();
while
(
!
vlc_atomic_get
(
&
p_notif
->
abort
)
)
{
DWORD
l_read
;
int
l_queued
=
0
,
l_free_slots
;
unsigned
i_frame_siz
=
p_aout
->
sys
->
packet
.
samples
;
mtime_t
mtime
=
mdate
();
int
i
;
/* Update volume if required */
LONG
volume
=
InterlockedExchange
(
&
p_aout
->
sys
->
volume
.
volume
,
-
1
);
if
(
unlikely
(
volume
!=
-
1
)
)
IDirectSoundBuffer_SetVolume
(
p_aout
->
sys
->
p_dsbuffer
,
volume
);
/*
* Fill in as much audio data as we can in our circular buffer
*/
/* Find out current play position */
if
FAILED
(
IDirectSoundBuffer_GetCurrentPosition
(
p_aout
->
sys
->
p_dsbuffer
,
&
l_read
,
NULL
)
)
{
msg_Err
(
p_aout
,
"GetCurrentPosition() failed!"
);
l_read
=
0
;
}
/* Detect underruns */
if
(
l_queued
&&
mtime
-
last_time
>
INT64_C
(
1000000
)
*
l_queued
/
p_aout
->
sys
->
packet
.
format
.
i_rate
)
{
msg_Dbg
(
p_aout
,
"detected underrun!"
);
}
last_time
=
mtime
;
/* Try to fill in as many frame buffers as possible */
return
VLC_SUCCESS
;
l_read
/=
(
p_aout
->
sys
->
packet
.
format
.
i_bytes_per_frame
/
p_aout
->
sys
->
packet
.
format
.
i_frame_length
);
l_queued
=
p_notif
->
i_write_slot
*
i_frame_siz
-
l_read
;
if
(
l_queued
<
0
)
l_queued
+=
(
i_frame_siz
*
FRAMES_NUM
);
l_free_slots
=
(
FRAMES_NUM
*
i_frame_siz
-
l_queued
)
/
i_frame_siz
;
for
(
i
=
0
;
i
<
l_free_slots
;
i
++
)
{
block_t
*
p_buffer
=
aout_PacketNext
(
p_aout
,
mtime
+
INT64_C
(
1000000
)
*
(
i
*
i_frame_siz
+
l_queued
)
/
p_aout
->
sys
->
packet
.
format
.
i_rate
);
/* If there is no audio data available and we have some buffered
* already, then just wait for the next time */
if
(
!
p_buffer
&&
(
i
||
l_queued
/
i_frame_siz
)
)
break
;
if
(
FillBuffer
(
p_aout
,
p_notif
->
i_write_slot
%
FRAMES_NUM
,
p_buffer
)
!=
VLC_SUCCESS
)
break
;
}
/* Sleep a reasonable amount of time */
l_queued
+=
(
i
*
i_frame_siz
);
msleep
(
INT64_C
(
1000000
)
*
l_queued
/
p_aout
->
sys
->
packet
.
format
.
i_rate
/
2
);
}
/* make sure the buffer isn't playing */
IDirectSoundBuffer_Stop
(
p_aout
->
sys
->
p_dsbuffer
);
msg_Dbg
(
p_aout
,
"DirectSoundThread exiting"
);
return
NULL
;
}
}
typedef
struct
typedef
struct
...
@@ -1106,11 +979,19 @@ static int Open(vlc_object_t *obj)
...
@@ -1106,11 +979,19 @@ static int Open(vlc_object_t *obj)
aout
->
mute_set
=
MuteSet
;
aout
->
mute_set
=
MuteSet
;
/* Volume */
/* Volume */
LONG
mb
=
var_InheritInteger
(
aout
,
"directx-volume"
);
sys
->
volume
.
volume
=
var_InheritFloat
(
aout
,
"directx-volume"
);
sys
->
volume
.
mb
=
mb
;
aout_VolumeReport
(
aout
,
sys
->
volume
.
volume
);
aout_VolumeReport
(
aout
,
cbrtf
(
powf
(
10
.
f
,
((
float
)
mb
)
/
2000
.
f
)));
MuteSet
(
aout
,
var_InheritBool
(
aout
,
"mute"
));
MuteSet
(
aout
,
var_InheritBool
(
aout
,
"mute"
));
sys
->
hnotify_evt
=
CreateEvent
(
NULL
,
FALSE
,
TRUE
,
NULL
);
if
(
!
sys
->
hnotify_evt
)
{
msg_Err
(
aout
,
"cannot create Event"
);
FreeLibrary
(
sys
->
hdsound_dll
);
free
(
sys
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -1119,6 +1000,67 @@ static void Close(vlc_object_t *obj)
...
@@ -1119,6 +1000,67 @@ static void Close(vlc_object_t *obj)
audio_output_t
*
aout
=
(
audio_output_t
*
)
obj
;
audio_output_t
*
aout
=
(
audio_output_t
*
)
obj
;
aout_sys_t
*
sys
=
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
CloseHandle
(
sys
->
hnotify_evt
);
FreeLibrary
(
sys
->
hdsound_dll
);
/* free DSOUND.DLL */
FreeLibrary
(
sys
->
hdsound_dll
);
/* free DSOUND.DLL */
free
(
sys
);
free
(
sys
);
}
}
static
void
Flush
(
audio_output_t
*
aout
,
bool
drain
)
{
aout_sys_t
*
sys
=
aout
->
sys
;
size_t
read
;
if
(
drain
)
{
if
(
sys
->
p_notify
)
{
DSBPOSITIONNOTIFY
notif
=
{.
dwOffset
=
aout
->
sys
->
i_write
,
.
hEventNotify
=
sys
->
hnotify_evt
}
;
if
(
IDirectSoundNotify_SetNotificationPositions
(
sys
->
p_notify
,
1
,
&
notif
)
==
DS_OK
)
{
WaitForSingleObject
(
sys
->
hnotify_evt
,
INFINITE
);
IDirectSoundBuffer_Stop
(
aout
->
sys
->
p_dsbuffer
);
}
}
else
while
(
IDirectSoundBuffer_GetCurrentPosition
(
aout
->
sys
->
p_dsbuffer
,(
LPDWORD
)
&
read
,
NULL
)
==
DS_OK
)
{
read
%=
DS_BUF_SIZE
;
if
(
read
==
aout
->
sys
->
i_write
)
break
;
msleep
(
10000
);
}
}
else
{
IDirectSoundBuffer_Stop
(
aout
->
sys
->
p_dsbuffer
);
IDirectSoundBuffer_SetCurrentPosition
(
aout
->
sys
->
p_dsbuffer
,
aout
->
sys
->
i_write
);
}
}
static
void
Pause
(
audio_output_t
*
aout
,
bool
pause
,
mtime_t
date
)
{
(
void
)
date
;
if
(
pause
)
IDirectSoundBuffer_Stop
(
aout
->
sys
->
p_dsbuffer
);
else
IDirectSoundBuffer_Play
(
aout
->
sys
->
p_dsbuffer
,
0
,
0
,
DSBPLAY_LOOPING
);
}
static
int
TimeGet
(
audio_output_t
*
aout
,
mtime_t
*
delay
)
{
uint32_t
read
;
mtime_t
size
;
if
(
IDirectSoundBuffer_GetCurrentPosition
(
aout
->
sys
->
p_dsbuffer
,
(
LPDWORD
)
&
read
,
NULL
)
!=
DS_OK
)
return
1
;
read
%=
DS_BUF_SIZE
;
size
=
(
mtime_t
)
aout
->
sys
->
i_write
-
(
mtime_t
)
read
;
if
(
size
<
0
)
size
+=
DS_BUF_SIZE
;
*
delay
=
(
size
/
aout
->
sys
->
i_bytes_per_sample
)
*
CLOCK_FREQ
/
aout
->
sys
->
i_rate
;
return
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