Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
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
Hide 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 @@
#include <vlc_plugin.h>
#include <vlc_aout.h>
#include <vlc_charset.h>
#include <vlc_atomic.h>
#include "windows_audio_common.h"
/*****************************************************************************
* 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
;
#define DS_BUF_SIZE (1024*1024)
/*****************************************************************************
* aout_sys_t: directx audio output method descriptor
...
...
@@ -63,30 +48,33 @@ typedef struct notification_thread_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
* takes care of mixing all the
* secondary buffers into the primary) */
LPDIRECTSOUNDNOTIFY
p_notify
;
HANDLE
hnotify_evt
;
struct
{
LONG
volume
;
float
volume
;
LONG
mb
;
bool
mute
;
}
volume
;
notification_thread_t
notif
;
/* DirectSoundThread id */
int
i_frame_size
;
/* Size in bytes of one frame */
int
i_bytes_per_sample
;
/* Size in bytes of one frame */
int
i_rate
;
/* Sample rate */
int
i_speaker_setup
;
/* Speaker setup override */
int
i_speaker_setup
;
/* Speaker setup override */
uint8_t
chans_to_reorder
;
/* do we need channel reordering */
uint8_t
chans_to_reorder
;
/* do we need channel reordering */
uint8_t
chan_table
[
AOUT_CHAN_MAX
];
uint32_t
i_channel_mask
;
vlc_fourcc_t
format
;
size_t
i_write
;
};
/*****************************************************************************
...
...
@@ -95,18 +83,20 @@ struct aout_sys_t
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
void
Stop
(
audio_output_t
*
);
static
void
Play
(
audio_output_t
*
,
block_t
*
);
static
int
VolumeSet
(
audio_output_t
*
,
float
);
static
int
MuteSet
(
audio_output_t
*
,
bool
);
static
void
Play
(
audio_output_t
*
,
block_t
*
);
static
int
VolumeSet
(
audio_output_t
*
,
float
);
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 */
static
void
Probe
(
audio_output_t
*
,
const
audio_sample_format_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
void
DestroyDSBuffer
(
audio_output_t
*
);
static
void
*
DirectSoundThread
(
void
*
);
static
int
FillBuffer
(
audio_output_t
*
,
int
,
block_t
*
);
static
int
FillBuffer
(
audio_output_t
*
,
block_t
*
);
static
int
ReloadDirectXDevices
(
vlc_object_t
*
,
const
char
*
,
char
***
,
char
***
);
...
...
@@ -145,7 +135,7 @@ vlc_module_begin ()
add_string
(
"directx-audio-speaker"
,
"Windows default"
,
SPEAKER_TEXT
,
SPEAKER_LONGTEXT
,
true
)
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
)
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 )
/* Calculate the frame size in bytes */
fmt
->
i_bytes_per_frame
=
AOUT_SPDIF_SIZE
;
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
,
fmt
->
i_physical_channels
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
p_aout
->
sys
->
i_frame_size
,
false
)
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
false
)
!=
VLC_SUCCESS
)
{
msg_Err
(
p_aout
,
"cannot open directx audio device"
);
goto
error
;
}
aout_PacketInit
(
p_aout
,
&
p_aout
->
sys
->
packet
,
A52_FRAME_NB
,
fmt
);
}
else
{
...
...
@@ -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"
);
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+ */
p_aout
->
sys
->
volume
.
volume
=
p_aout
->
sys
->
volume
.
mb
;
/* 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
;
/* Force volume update */
VolumeSet
(
p_aout
,
p_aout
->
sys
->
volume
.
volume
);
MuteSet
(
p_aout
,
p_aout
->
sys
->
volume
.
mute
);
/* then launch the notification thread */
msg_Dbg
(
p_aout
,
"creating DirectSoundThread"
);
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
->
time_get
=
TimeGet
;
p_aout
->
play
=
Play
;
p_aout
->
pause
=
NULL
;
p_aout
->
flush
=
aout_PacketFlush
;
p_aout
->
pause
=
Pause
;
p_aout
->
flush
=
Flush
;
return
VLC_SUCCESS
;
error:
...
...
@@ -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
,
fmt
->
i_physical_channels
,
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
AOUT_SPDIF_SIZE
,
true
)
aout_FormatNbChannels
(
fmt
),
fmt
->
i_rate
,
true
)
==
VLC_SUCCESS
)
{
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 )
*****************************************************************************/
static
void
Play
(
audio_output_t
*
p_aout
,
block_t
*
p_buffer
)
{
/* get the playing date of the first aout buffer */
p_aout
->
sys
->
notif
.
start_date
=
p_buffer
->
i_pts
;
/* fill in the first samples (zeroes) */
FillBuffer
(
p_aout
,
0
,
NULL
);
/* wake up the audio output thread */
SetEvent
(
p_aout
->
sys
->
notif
.
event
);
aout_PacketPlay
(
p_aout
,
p_buffer
);
p_aout
->
play
=
aout_PacketPlay
;
if
(
FillBuffer
(
p_aout
,
p_buffer
)
==
VLC_SUCCESS
)
{
/* start playing the buffer */
HRESULT
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
0
,
0
,
DSBPLAY_LOOPING
);
if
(
dsresult
==
DSERR_BUFFERLOST
)
{
IDirectSoundBuffer_Restore
(
p_aout
->
sys
->
p_dsbuffer
);
dsresult
=
IDirectSoundBuffer_Play
(
p_aout
->
sys
->
p_dsbuffer
,
0
,
0
,
DSBPLAY_LOOPING
);
}
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
;
int
ret
=
0
;
/* Convert UI volume to linear factor (cube) */
vol
=
vol
*
vol
*
vol
;
float
vol
=
volume
*
volume
*
volume
;
/* millibels from linear amplification */
LONG
mb
=
lroundf
(
2000
.
f
*
log10f
(
vol
));
...
...
@@ -546,28 +516,31 @@ static int VolumeSet( audio_output_t *p_aout, float vol )
mb
=
DSBVOLUME_MIN
;
sys
->
volume
.
mb
=
mb
;
if
(
!
sys
->
volume
.
mute
)
InterlockedExchange
(
&
sys
->
volume
.
volume
,
mb
);
sys
->
volume
.
volume
=
volume
;
if
(
!
sys
->
volume
.
mute
&&
sys
->
p_dsbuffer
&&
IDirectSoundBuffer_SetVolume
(
sys
->
p_dsbuffer
,
mb
)
!=
DS_OK
)
return
-
1
;
/* Convert back to UI volume */
vol
=
cbrtf
(
powf
(
10
.
f
,
((
float
)
mb
)
/
2000
.
f
));
aout_VolumeReport
(
p_aout
,
vol
);
aout_VolumeReport
(
p_aout
,
volume
);
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
;
}
static
int
MuteSet
(
audio_output_t
*
p_aout
,
bool
mute
)
{
HRESULT
res
=
DS_OK
;
aout_sys_t
*
sys
=
p_aout
->
sys
;
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
);
return
0
;
return
(
res
!=
DS_OK
)
;
}
/*****************************************************************************
...
...
@@ -576,27 +549,19 @@ static int MuteSet( audio_output_t *p_aout, bool mute )
static
void
Stop
(
audio_output_t
*
p_aout
)
{
aout_sys_t
*
p_sys
=
p_aout
->
sys
;
msg_Dbg
(
p_aout
,
"closing audio device"
);
/* kill the position notification thread, if any */
if
(
p_sys
->
notif
.
event
!=
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
);
}
if
(
p_sys
->
p_notify
)
IDirectSoundNotify_Release
(
p_sys
->
p_notify
);
p_sys
->
p_notify
=
NULL
;
IDirectSoundBuffer_Stop
(
p_sys
->
p_dsbuffer
);
/* release the secondary buffer */
DestroyDSBuffer
(
p_aout
);
/* 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 )
*****************************************************************************/
static
int
CreateDSBuffer
(
audio_output_t
*
p_aout
,
int
i_format
,
int
i_channels
,
int
i_nb_channels
,
int
i_rate
,
int
i_bytes_per_frame
,
bool
b_probe
)
bool
b_probe
)
{
WAVEFORMATEXTENSIBLE
waveformat
;
DSBUFFERDESC
dsbdesc
;
...
...
@@ -723,14 +688,16 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
waveformat
.
Format
.
nAvgBytesPerSec
=
waveformat
.
Format
.
nSamplesPerSec
*
waveformat
.
Format
.
nBlockAlign
;
p_aout
->
sys
->
i_bytes_per_sample
=
waveformat
.
Format
.
nBlockAlign
;
p_aout
->
sys
->
format
=
i_format
;
/* Then fill in the direct sound descriptor */
memset
(
&
dsbdesc
,
0
,
sizeof
(
DSBUFFERDESC
));
dsbdesc
.
dwSize
=
sizeof
(
DSBUFFERDESC
);
dsbdesc
.
dwFlags
=
DSBCAPS_GETCURRENTPOSITION2
/* Better position accuracy */
|
DSBCAPS_GLOBALFOCUS
/* Allows background playing */
|
DSBCAPS_CTRLVOLUME
;
/* Allows volume control */
dsbdesc
.
dwFlags
=
DSBCAPS_GETCURRENTPOSITION2
/* Better position accuracy */
|
DSBCAPS_GLOBALFOCUS
/* Allows background playing */
|
DSBCAPS_CTRLVOLUME
/* Allows volume control */
|
DSBCAPS_CTRLPOSITIONNOTIFY
;
/* Allow position notifications */
/* Only use the new WAVE_FORMAT_EXTENSIBLE format for multichannel audio */
if
(
i_nb_channels
<=
2
)
...
...
@@ -747,7 +714,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
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
;
if
FAILED
(
IDirectSound_CreateSoundBuffer
(
...
...
@@ -781,7 +748,7 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
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
->
chans_to_reorder
=
aout_CheckChannelReorder
(
pi_channels_in
,
pi_channels_out
,
...
...
@@ -792,6 +759,18 @@ static int CreateDSBuffer( audio_output_t *p_aout, int i_format,
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
;
}
...
...
@@ -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"
)
||
i_nb_channels
>
2
||
CreateDSBuffer
(
p_aout
,
VLC_CODEC_FL32
,
i_channels
,
i_nb_channels
,
i_rate
,
(
i_rate
/
20
)
*
4
*
i_nb_channels
,
b_probe
)
i_channels
,
i_nb_channels
,
i_rate
,
b_probe
)
!=
VLC_SUCCESS
)
{
if
(
CreateDSBuffer
(
p_aout
,
VLC_CODEC_S16N
,
i_channels
,
i_nb_channels
,
i_rate
,
(
i_rate
/
20
)
*
2
*
i_nb_channels
,
b_probe
)
i_channels
,
i_nb_channels
,
i_rate
,
b_probe
)
!=
VLC_SUCCESS
)
{
return
VLC_EGENERIC
;
...
...
@@ -853,31 +830,32 @@ static void DestroyDSBuffer( audio_output_t *p_aout )
*****************************************************************************
* 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
;
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
;
unsigned
long
l_bytes1
,
l_bytes2
;
HRESULT
dsresult
;
/* Before copying anything, we have to lock the buffer */
dsresult
=
IDirectSoundBuffer_Lock
(
p_sys
->
p_dsbuffer
,
/* DS buffer */
i_frame
*
p_notif
->
i_frame_size
,
/* Start offset */
p_notif
->
i_frame_size
,
/* Number of bytes */
&
p_write_position
,
/* Address of lock start */
&
l_bytes1
,
/* Count of bytes locked before wrap around */
&
p_wrap_around
,
/* Buffer address (if wrap around) */
&
l_bytes2
,
/* Count of bytes after wrap around */
0
);
/* Flags
*/
p_sys
->
p_dsbuffer
,
/* DS buffer */
p_aout
->
sys
->
i_write
,
/* Start offset */
towrite
,
/* Number of bytes */
&
p_write_position
,
/* Address of lock start */
&
l_bytes1
,
/* Count of bytes locked before wrap around */
&
p_wrap_around
,
/* Buffer address (if wrap around) */
&
l_bytes2
,
/* Count of bytes after wrap around */
0
);
/* Flags: DSBLOCK_FROMWRITECURSOR is buggy
*/
if
(
dsresult
==
DSERR_BUFFERLOST
)
{
IDirectSoundBuffer_Restore
(
p_sys
->
p_dsbuffer
);
dsresult
=
IDirectSoundBuffer_Lock
(
p_sys
->
p_dsbuffer
,
i_frame
*
p_notif
->
i_frame_siz
e
,
p_notif
->
i_frame_siz
e
,
p_aout
->
sys
->
i_writ
e
,
towrit
e
,
&
p_write_position
,
&
l_bytes1
,
&
p_wrap_around
,
...
...
@@ -904,6 +882,8 @@ static int FillBuffer( audio_output_t *p_aout, int i_frame, block_t *p_buffer )
p_sys
->
format
);
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
);
}
...
...
@@ -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
,
p_wrap_around
,
l_bytes2
);
p_notif
->
i_write_slot
=
(
i_frame
+
1
)
%
FRAMES_NUM
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* 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
;
}
p_sys
->
i_write
+=
towrite
;
p_sys
->
i_write
%=
DS_BUF_SIZE
;
/* 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 */
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
;
return
VLC_SUCCESS
;
}
typedef
struct
...
...
@@ -1106,11 +979,19 @@ static int Open(vlc_object_t *obj)
aout
->
mute_set
=
MuteSet
;
/* Volume */
LONG
mb
=
var_InheritInteger
(
aout
,
"directx-volume"
);
sys
->
volume
.
mb
=
mb
;
aout_VolumeReport
(
aout
,
cbrtf
(
powf
(
10
.
f
,
((
float
)
mb
)
/
2000
.
f
)));
sys
->
volume
.
volume
=
var_InheritFloat
(
aout
,
"directx-volume"
);
aout_VolumeReport
(
aout
,
sys
->
volume
.
volume
);
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
;
}
...
...
@@ -1119,6 +1000,67 @@ static void Close(vlc_object_t *obj)
audio_output_t
*
aout
=
(
audio_output_t
*
)
obj
;
aout_sys_t
*
sys
=
aout
->
sys
;
CloseHandle
(
sys
->
hnotify_evt
);
FreeLibrary
(
sys
->
hdsound_dll
);
/* free DSOUND.DLL */
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