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
352b5f93
Commit
352b5f93
authored
Aug 20, 2006
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make headphone also an audio_filter2
parent
663716c0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
258 additions
and
79 deletions
+258
-79
modules/audio_filter/channel_mixer/headphone.c
modules/audio_filter/channel_mixer/headphone.c
+258
-79
No files found.
modules/audio_filter/channel_mixer/headphone.c
View file @
352b5f93
...
...
@@ -30,8 +30,10 @@
#include <math.h>
/* sqrt */
#include <vlc/vlc.h>
#include "audio_output.h"
#include "aout_internal.h"
#include <audio_output.h>
#include <aout_internal.h>
#include <vlc_filter.h>
#include <vlc_block.h>
/*****************************************************************************
* Local prototypes
...
...
@@ -42,6 +44,11 @@ static void Destroy ( vlc_object_t * );
static
void
DoWork
(
aout_instance_t
*
,
aout_filter_t
*
,
aout_buffer_t
*
,
aout_buffer_t
*
);
/* Audio filter2 */
static
int
OpenFilter
(
vlc_object_t
*
);
static
void
CloseFilter
(
vlc_object_t
*
);
static
block_t
*
Convert
(
filter_t
*
,
block_t
*
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
...
...
@@ -85,6 +92,12 @@ vlc_module_begin();
set_capability
(
"audio filter"
,
0
);
set_callbacks
(
Create
,
Destroy
);
add_shortcut
(
"headphone"
);
/* Audio filter 2 */
add_submodule
();
set_description
(
_
(
"Headphone virtual spatialization effect"
)
);
set_capability
(
"audio filter2"
,
100
);
set_callbacks
(
OpenFilter
,
CloseFilter
);
vlc_module_end
();
...
...
@@ -107,6 +120,14 @@ struct aout_filter_sys_t
struct
atomic_operation_t
*
p_atomic_operations
;
};
struct
filter_sys_t
{
size_t
i_overflow_buffer_size
;
/* in bytes */
byte_t
*
p_overflow_buffer
;
unsigned
int
i_nb_atomic_operations
;
struct
atomic_operation_t
*
p_atomic_operations
;
};
/*****************************************************************************
* Init: initialize internal data structures
* and computes the needed atomic operations
...
...
@@ -125,10 +146,10 @@ struct aout_filter_sys_t
*
* x-axis
* */
static
void
ComputeChannelOperations
(
struct
aout_filter_sys_t
*
p_data
,
unsigned
int
i_rate
,
unsigned
int
i_next_atomic_operation
,
int
i_source_channel_offset
,
double
d_x
,
double
d_z
,
double
d_compensation_length
,
double
d_channel_amplitude_factor
)
static
void
ComputeChannelOperations
(
struct
aout_filter_sys_t
*
p_data
,
unsigned
int
i_rate
,
unsigned
int
i_next_atomic_operation
,
int
i_source_channel_offset
,
double
d_x
,
double
d_z
,
double
d_compensation_length
,
double
d_channel_amplitude_factor
)
{
double
d_c
=
340
;
/*sound celerity (unit: m/s)*/
double
d_compensation_delay
=
(
d_compensation_length
-
0
.
1
)
/
d_c
*
i_rate
;
...
...
@@ -141,12 +162,12 @@ static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
p_data
->
p_atomic_operations
[
i_next_atomic_operation
]
.
i_delay
=
(
int
)(
sqrt
(
(
-
0
.
1
-
d_x
)
*
(
-
0
.
1
-
d_x
)
+
(
0
-
d_z
)
*
(
0
-
d_z
)
)
/
d_c
*
i_rate
-
d_compensation_delay
);
if
(
d_x
<
0
)
if
(
d_x
<
0
)
{
p_data
->
p_atomic_operations
[
i_next_atomic_operation
]
.
d_amplitude_factor
=
d_channel_amplitude_factor
*
1
.
1
/
2
;
}
else
if
(
d_x
>
0
)
else
if
(
d_x
>
0
)
{
p_data
->
p_atomic_operations
[
i_next_atomic_operation
]
.
d_amplitude_factor
=
d_channel_amplitude_factor
*
0
.
9
/
2
;
...
...
@@ -165,12 +186,12 @@ static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
p_data
->
p_atomic_operations
[
i_next_atomic_operation
+
1
]
.
i_delay
=
(
int
)(
sqrt
(
(
0
.
1
-
d_x
)
*
(
0
.
1
-
d_x
)
+
(
0
-
d_z
)
*
(
0
-
d_z
)
)
/
d_c
*
i_rate
-
d_compensation_delay
);
if
(
d_x
<
0
)
if
(
d_x
<
0
)
{
p_data
->
p_atomic_operations
[
i_next_atomic_operation
+
1
]
.
d_amplitude_factor
=
d_channel_amplitude_factor
*
0
.
9
/
2
;
}
else
if
(
d_x
>
0
)
else
if
(
d_x
>
0
)
{
p_data
->
p_atomic_operations
[
i_next_atomic_operation
+
1
]
.
d_amplitude_factor
=
d_channel_amplitude_factor
*
1
.
1
/
2
;
...
...
@@ -182,11 +203,11 @@ static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
}
}
static
int
Init
(
aout_filter_t
*
p_filter
,
struct
aout_filter_sys_t
*
p_data
,
unsigned
int
i_nb_channels
,
uint32_t
i_physical_channels
static
int
Init
(
vlc_object_t
*
p_this
,
struct
aout_filter_sys_t
*
p_data
,
unsigned
int
i_nb_channels
,
uint32_t
i_physical_channels
,
unsigned
int
i_rate
)
{
double
d_x
=
config_GetInt
(
p_filter
,
"headphone-dim"
);
double
d_x
=
config_GetInt
(
p_this
,
"headphone-dim"
);
double
d_z
=
d_x
;
double
d_z_rear
=
-
d_x
/
3
;
double
d_min
=
0
;
...
...
@@ -194,16 +215,16 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
int
i_source_channel_offset
;
unsigned
int
i
;
if
(
p_data
==
NULL
)
if
(
p_data
==
NULL
)
{
msg_Dbg
(
p_filter
,
"passing a null pointer as argument"
);
msg_Dbg
(
p_this
,
"passing a null pointer as argument"
);
return
0
;
}
if
(
config_GetInt
(
p_filter
,
"headphone-compensate"
)
)
if
(
config_GetInt
(
p_this
,
"headphone-compensate"
)
)
{
/* minimal distance to any speaker */
if
(
i_physical_channels
&
AOUT_CHAN_REARCENTER
)
if
(
i_physical_channels
&
AOUT_CHAN_REARCENTER
)
{
d_min
=
d_z_rear
;
}
...
...
@@ -215,15 +236,15 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
/* Number of elementary operations */
p_data
->
i_nb_atomic_operations
=
i_nb_channels
*
2
;
if
(
i_physical_channels
&
AOUT_CHAN_CENTER
)
if
(
i_physical_channels
&
AOUT_CHAN_CENTER
)
{
p_data
->
i_nb_atomic_operations
+=
2
;
}
p_data
->
p_atomic_operations
=
malloc
(
sizeof
(
struct
atomic_operation_t
)
p_data
->
p_atomic_operations
=
malloc
(
sizeof
(
struct
atomic_operation_t
)
*
p_data
->
i_nb_atomic_operations
);
if
(
p_data
->
p_atomic_operations
==
NULL
)
if
(
p_data
->
p_atomic_operations
==
NULL
)
{
msg_Err
(
p_
filter
,
"out of memory"
);
msg_Err
(
p_
this
,
"out of memory"
);
return
-
1
;
}
...
...
@@ -231,78 +252,78 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
* to each ear */
i_next_atomic_operation
=
0
;
i_source_channel_offset
=
0
;
if
(
i_physical_channels
&
AOUT_CHAN_LEFT
)
if
(
i_physical_channels
&
AOUT_CHAN_LEFT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
-
d_x
,
d_z
,
d_min
,
2
.
0
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_RIGHT
)
if
(
i_physical_channels
&
AOUT_CHAN_RIGHT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
d_x
,
d_z
,
d_min
,
2
.
0
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_MIDDLELEFT
)
if
(
i_physical_channels
&
AOUT_CHAN_MIDDLELEFT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
-
d_x
,
0
,
d_min
,
1
.
5
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_MIDDLERIGHT
)
if
(
i_physical_channels
&
AOUT_CHAN_MIDDLERIGHT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
d_x
,
0
,
d_min
,
1
.
5
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_REARLEFT
)
if
(
i_physical_channels
&
AOUT_CHAN_REARLEFT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
-
d_x
,
d_z_rear
,
d_min
,
1
.
5
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_REARRIGHT
)
if
(
i_physical_channels
&
AOUT_CHAN_REARRIGHT
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
d_x
,
d_z_rear
,
d_min
,
1
.
5
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_REARCENTER
)
if
(
i_physical_channels
&
AOUT_CHAN_REARCENTER
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
0
,
-
d_z
,
d_min
,
1
.
5
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_CENTER
)
if
(
i_physical_channels
&
AOUT_CHAN_CENTER
)
{
/* having two center channels increases the spatialization effect */
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
d_x
/
5
.
0
,
d_z
,
d_min
,
0
.
75
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
-
d_x
/
5
.
0
,
d_z
,
d_min
,
0
.
75
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
i_source_channel_offset
++
;
}
if
(
i_physical_channels
&
AOUT_CHAN_LFE
)
if
(
i_physical_channels
&
AOUT_CHAN_LFE
)
{
ComputeChannelOperations
(
p_data
,
i_rate
ComputeChannelOperations
(
p_data
,
i_rate
,
i_next_atomic_operation
,
i_source_channel_offset
,
0
,
d_z_rear
,
d_min
,
5
.
0
/
i_nb_channels
);
i_next_atomic_operation
+=
2
;
...
...
@@ -312,22 +333,22 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
/* Initialize the overflow buffer
* we need it because the process induce a delay in the samples */
p_data
->
i_overflow_buffer_size
=
0
;
for
(
i
=
0
;
i
<
p_data
->
i_nb_atomic_operations
;
i
++
)
for
(
i
=
0
;
i
<
p_data
->
i_nb_atomic_operations
;
i
++
)
{
if
(
p_data
->
i_overflow_buffer_size
if
(
p_data
->
i_overflow_buffer_size
<
p_data
->
p_atomic_operations
[
i
].
i_delay
*
2
*
sizeof
(
float
)
)
{
p_data
->
i_overflow_buffer_size
=
p_data
->
p_atomic_operations
[
i
].
i_delay
*
2
*
sizeof
(
float
);
}
}
p_data
->
p_overflow_buffer
=
malloc
(
p_data
->
i_overflow_buffer_size
);
if
(
p_data
->
p_atomic_operations
==
NULL
)
p_data
->
p_overflow_buffer
=
malloc
(
p_data
->
i_overflow_buffer_size
);
if
(
p_data
->
p_atomic_operations
==
NULL
)
{
msg_Err
(
p_
filter
,
"out of memory"
);
msg_Err
(
p_
this
,
"out of memory"
);
return
-
1
;
}
memset
(
p_data
->
p_overflow_buffer
,
0
,
p_data
->
i_overflow_buffer_size
);
memset
(
p_data
->
p_overflow_buffer
,
0
,
p_data
->
i_overflow_buffer_size
);
/* end */
return
0
;
...
...
@@ -342,7 +363,7 @@ static int Create( vlc_object_t *p_this )
vlc_bool_t
b_fit
=
VLC_TRUE
;
/* Activate this filter only with stereo devices */
if
(
p_filter
->
output
.
i_physical_channels
if
(
p_filter
->
output
.
i_physical_channels
!=
(
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
)
)
{
msg_Dbg
(
p_filter
,
"filter discarded (incompatible format)"
);
...
...
@@ -350,26 +371,26 @@ static int Create( vlc_object_t *p_this )
}
/* Request a specific format if not already compatible */
if
(
p_filter
->
input
.
i_original_channels
if
(
p_filter
->
input
.
i_original_channels
!=
p_filter
->
output
.
i_original_channels
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
input
.
i_original_channels
=
p_filter
->
output
.
i_original_channels
;
}
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
if
(
p_filter
->
input
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
||
p_filter
->
output
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
input
.
i_format
=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
);
p_filter
->
output
.
i_format
=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
);
}
if
(
p_filter
->
input
.
i_rate
!=
p_filter
->
output
.
i_rate
)
if
(
p_filter
->
input
.
i_rate
!=
p_filter
->
output
.
i_rate
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
input
.
i_rate
=
p_filter
->
output
.
i_rate
;
}
if
(
p_filter
->
input
.
i_physical_channels
==
(
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
)
if
(
p_filter
->
input
.
i_physical_channels
==
(
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
)
&&
(
p_filter
->
input
.
i_original_channels
&
AOUT_CHAN_DOLBYSTEREO
)
&&
!
config_GetInt
(
p_filter
,
"headphone-dolby"
)
)
{
...
...
@@ -379,7 +400,7 @@ static int Create( vlc_object_t *p_this )
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
;
}
if
(
!
b_fit
)
if
(
!
b_fit
)
{
msg_Dbg
(
p_filter
,
"requesting specific format"
);
return
VLC_EGENERIC
;
...
...
@@ -387,7 +408,7 @@ static int Create( vlc_object_t *p_this )
/* Allocate the memory needed to store the module's structure */
p_filter
->
p_sys
=
malloc
(
sizeof
(
struct
aout_filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory"
);
return
VLC_EGENERIC
;
...
...
@@ -397,7 +418,7 @@ static int Create( vlc_object_t *p_this )
p_filter
->
p_sys
->
i_nb_atomic_operations
=
0
;
p_filter
->
p_sys
->
p_atomic_operations
=
NULL
;
if
(
Init
(
p_filter
,
p_filter
->
p_sys
if
(
Init
(
VLC_OBJECT
(
p_filter
)
,
p_filter
->
p_sys
,
aout_FormatNbChannels
(
&
p_filter
->
input
)
,
p_filter
->
input
.
i_physical_channels
,
p_filter
->
input
.
i_rate
)
<
0
)
...
...
@@ -418,17 +439,17 @@ static void Destroy( vlc_object_t *p_this )
{
aout_filter_t
*
p_filter
=
(
aout_filter_t
*
)
p_this
;
if
(
p_filter
->
p_sys
!=
NULL
)
if
(
p_filter
->
p_sys
!=
NULL
)
{
if
(
p_filter
->
p_sys
->
p_overflow_buffer
!=
NULL
)
if
(
p_filter
->
p_sys
->
p_overflow_buffer
!=
NULL
)
{
free
(
p_filter
->
p_sys
->
p_overflow_buffer
);
free
(
p_filter
->
p_sys
->
p_overflow_buffer
);
}
if
(
p_filter
->
p_sys
->
p_atomic_operations
!=
NULL
)
if
(
p_filter
->
p_sys
->
p_atomic_operations
!=
NULL
)
{
free
(
p_filter
->
p_sys
->
p_atomic_operations
);
free
(
p_filter
->
p_sys
->
p_atomic_operations
);
}
free
(
p_filter
->
p_sys
);
free
(
p_filter
->
p_sys
);
p_filter
->
p_sys
=
NULL
;
}
}
...
...
@@ -457,46 +478,45 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
unsigned
int
i_delay
;
double
d_amplitude_factor
;
/* out buffer characterisitcs */
p_out_buf
->
i_nb_samples
=
p_in_buf
->
i_nb_samples
;
p_out_buf
->
i_nb_bytes
=
p_in_buf
->
i_nb_bytes
*
i_output_nb
/
i_input_nb
;
p_out
=
p_out_buf
->
p_buffer
;
i_out_size
=
p_out_buf
->
i_nb_bytes
;
if
(
p_filter
->
p_sys
!=
NULL
)
if
(
p_filter
->
p_sys
!=
NULL
)
{
/* Slide the overflow buffer */
p_overflow
=
p_filter
->
p_sys
->
p_overflow_buffer
;
i_overflow_size
=
p_filter
->
p_sys
->
i_overflow_buffer_size
;
memset
(
p_out
,
0
,
i_out_size
);
memset
(
p_out
,
0
,
i_out_size
);
if
(
i_out_size
>
i_overflow_size
)
memcpy
(
p_out
,
p_overflow
,
i_overflow_size
);
memcpy
(
p_out
,
p_overflow
,
i_overflow_size
);
else
memcpy
(
p_out
,
p_overflow
,
i_out_size
);
memcpy
(
p_out
,
p_overflow
,
i_out_size
);
p_slide
=
p_filter
->
p_sys
->
p_overflow_buffer
;
while
(
p_slide
<
p_overflow
+
i_overflow_size
)
while
(
p_slide
<
p_overflow
+
i_overflow_size
)
{
if
(
p_slide
+
i_out_size
<
p_overflow
+
i_overflow_size
)
if
(
p_slide
+
i_out_size
<
p_overflow
+
i_overflow_size
)
{
memset
(
p_slide
,
0
,
i_out_size
);
if
(
p_slide
+
2
*
i_out_size
<
p_overflow
+
i_overflow_size
)
memcpy
(
p_slide
,
p_slide
+
i_out_size
,
i_out_size
);
memset
(
p_slide
,
0
,
i_out_size
);
if
(
p_slide
+
2
*
i_out_size
<
p_overflow
+
i_overflow_size
)
memcpy
(
p_slide
,
p_slide
+
i_out_size
,
i_out_size
);
else
memcpy
(
p_slide
,
p_slide
+
i_out_size
,
p_overflow
+
i_overflow_size
-
(
p_slide
+
i_out_size
)
);
memcpy
(
p_slide
,
p_slide
+
i_out_size
,
p_overflow
+
i_overflow_size
-
(
p_slide
+
i_out_size
)
);
}
else
{
memset
(
p_slide
,
0
,
p_overflow
+
i_overflow_size
-
p_slide
);
memset
(
p_slide
,
0
,
p_overflow
+
i_overflow_size
-
p_slide
);
}
p_slide
+=
i_out_size
;
}
/* apply the atomic operations */
for
(
i
=
0
;
i
<
p_filter
->
p_sys
->
i_nb_atomic_operations
;
i
++
)
for
(
i
=
0
;
i
<
p_filter
->
p_sys
->
i_nb_atomic_operations
;
i
++
)
{
/* shorter variable names */
i_source_channel_offset
...
...
@@ -507,10 +527,10 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
d_amplitude_factor
=
p_filter
->
p_sys
->
p_atomic_operations
[
i
].
d_amplitude_factor
;
if
(
p_out_buf
->
i_nb_samples
>
i_delay
)
if
(
p_out_buf
->
i_nb_samples
>
i_delay
)
{
/* current buffer coefficients */
for
(
j
=
0
;
j
<
p_out_buf
->
i_nb_samples
-
i_delay
;
j
++
)
for
(
j
=
0
;
j
<
p_out_buf
->
i_nb_samples
-
i_delay
;
j
++
)
{
((
float
*
)
p_out
)[
(
i_delay
+
j
)
*
i_output_nb
+
i_dest_channel_offset
]
+=
p_in
[
j
*
i_input_nb
+
i_source_channel_offset
]
...
...
@@ -518,7 +538,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
}
/* overflow buffer coefficients */
for
(
j
=
0
;
j
<
i_delay
;
j
++
)
for
(
j
=
0
;
j
<
i_delay
;
j
++
)
{
((
float
*
)
p_overflow
)[
j
*
i_output_nb
+
i_dest_channel_offset
]
+=
p_in
[
(
p_out_buf
->
i_nb_samples
-
i_delay
+
j
)
...
...
@@ -529,7 +549,7 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
else
{
/* overflow buffer coefficients only */
for
(
j
=
0
;
j
<
p_out_buf
->
i_nb_samples
;
j
++
)
for
(
j
=
0
;
j
<
p_out_buf
->
i_nb_samples
;
j
++
)
{
((
float
*
)
p_overflow
)[
(
i_delay
-
p_out_buf
->
i_nb_samples
+
j
)
*
i_output_nb
+
i_dest_channel_offset
]
...
...
@@ -541,6 +561,165 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
}
else
{
memset
(
p_out
,
0
,
i_out_size
);
memset
(
p_out
,
0
,
i_out_size
);
}
}
/*
* Audio filter 2
*/
/*****************************************************************************
* OpenFilter:
*****************************************************************************/
static
int
OpenFilter
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
vlc_bool_t
b_fit
=
VLC_TRUE
;
/* Activate this filter only with stereo devices */
if
(
p_filter
->
fmt_out
.
audio
.
i_physical_channels
!=
(
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
)
)
{
msg_Dbg
(
p_filter
,
"filter discarded (incompatible format)"
);
return
VLC_EGENERIC
;
}
/* Request a specific format if not already compatible */
if
(
p_filter
->
fmt_in
.
audio
.
i_original_channels
!=
p_filter
->
fmt_out
.
audio
.
i_original_channels
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
fmt_in
.
audio
.
i_original_channels
=
p_filter
->
fmt_out
.
audio
.
i_original_channels
;
}
if
(
p_filter
->
fmt_in
.
audio
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
||
p_filter
->
fmt_out
.
audio
.
i_format
!=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
)
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
fmt_in
.
audio
.
i_format
=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
);
p_filter
->
fmt_out
.
audio
.
i_format
=
VLC_FOURCC
(
'f'
,
'l'
,
'3'
,
'2'
);
}
if
(
p_filter
->
fmt_in
.
audio
.
i_rate
!=
p_filter
->
fmt_out
.
audio
.
i_rate
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
fmt_in
.
audio
.
i_rate
=
p_filter
->
fmt_out
.
audio
.
i_rate
;
}
if
(
p_filter
->
fmt_in
.
audio
.
i_physical_channels
==
(
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
)
&&
(
p_filter
->
fmt_in
.
audio
.
i_original_channels
&
AOUT_CHAN_DOLBYSTEREO
)
&&
!
config_GetInt
(
p_filter
,
"headphone-dolby"
)
)
{
b_fit
=
VLC_FALSE
;
p_filter
->
fmt_in
.
audio
.
i_physical_channels
=
AOUT_CHAN_LEFT
|
AOUT_CHAN_RIGHT
|
AOUT_CHAN_CENTER
|
AOUT_CHAN_REARLEFT
|
AOUT_CHAN_REARRIGHT
;
}
if
(
!
b_fit
)
{
msg_Dbg
(
p_filter
,
"requesting specific format"
);
return
VLC_EGENERIC
;
}
/* Allocate the memory needed to store the module's structure */
p_filter
->
p_sys
=
malloc
(
sizeof
(
struct
filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory"
);
return
VLC_EGENERIC
;
}
p_filter
->
p_sys
->
i_overflow_buffer_size
=
0
;
p_filter
->
p_sys
->
p_overflow_buffer
=
NULL
;
p_filter
->
p_sys
->
i_nb_atomic_operations
=
0
;
p_filter
->
p_sys
->
p_atomic_operations
=
NULL
;
if
(
Init
(
VLC_OBJECT
(
p_filter
),
(
struct
aout_filter_sys_t
*
)
p_filter
->
p_sys
,
aout_FormatNbChannels
(
&
(
p_filter
->
fmt_in
.
audio
)
)
,
p_filter
->
fmt_in
.
audio
.
i_physical_channels
,
p_filter
->
fmt_in
.
audio
.
i_rate
)
<
0
)
{
return
VLC_EGENERIC
;
}
p_filter
->
pf_audio_filter
=
Convert
;
p_filter
->
fmt_out
.
audio
.
i_rate
=
p_filter
->
fmt_in
.
audio
.
i_rate
;
msg_Dbg
(
p_this
,
">> HEADPHONE filter loaded"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* CloseFilter : deallocate data structures
*****************************************************************************/
static
void
CloseFilter
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_filter
->
p_sys
!=
NULL
)
{
if
(
p_filter
->
p_sys
->
p_overflow_buffer
!=
NULL
)
{
free
(
p_filter
->
p_sys
->
p_overflow_buffer
);
}
if
(
p_filter
->
p_sys
->
p_atomic_operations
!=
NULL
)
{
free
(
p_filter
->
p_sys
->
p_atomic_operations
);
}
free
(
p_filter
->
p_sys
);
p_filter
->
p_sys
=
NULL
;
}
if
(
p_sys
)
free
(
p_sys
);
}
static
block_t
*
Convert
(
filter_t
*
p_filter
,
block_t
*
p_block
)
{
aout_filter_t
aout_filter
;
aout_buffer_t
in_buf
,
out_buf
;
block_t
*
p_out
;
int
i_out_size
;
if
(
!
p_block
||
!
p_block
->
i_samples
)
{
if
(
p_block
)
p_block
->
pf_release
(
p_block
);
return
NULL
;
}
i_out_size
=
p_block
->
i_samples
*
p_filter
->
fmt_out
.
audio
.
i_bitspersample
*
p_filter
->
fmt_out
.
audio
.
i_channels
/
8
;
p_out
=
p_filter
->
pf_audio_buffer_new
(
p_filter
,
i_out_size
);
if
(
!
p_out
)
{
msg_Warn
(
p_filter
,
"can't get output buffer"
);
if
(
p_block
)
p_block
->
pf_release
(
p_block
);
return
NULL
;
}
p_out
->
i_samples
=
p_block
->
i_samples
;
p_out
->
i_dts
=
p_block
->
i_dts
;
p_out
->
i_pts
=
p_block
->
i_pts
;
p_out
->
i_length
=
p_block
->
i_length
;
aout_filter
.
p_sys
=
(
struct
aout_filter_sys_t
*
)
p_filter
->
p_sys
;
aout_filter
.
input
=
p_filter
->
fmt_in
.
audio
;
aout_filter
.
input
.
i_format
=
p_filter
->
fmt_in
.
i_codec
;
aout_filter
.
output
=
p_filter
->
fmt_out
.
audio
;
aout_filter
.
output
.
i_format
=
p_filter
->
fmt_out
.
i_codec
;
aout_filter
.
b_in_place
=
0
;
in_buf
.
p_buffer
=
p_block
->
p_buffer
;
in_buf
.
i_nb_bytes
=
p_block
->
i_buffer
;
in_buf
.
i_nb_samples
=
p_block
->
i_samples
;
out_buf
.
p_buffer
=
p_out
->
p_buffer
;
out_buf
.
i_nb_bytes
=
p_out
->
i_buffer
;
out_buf
.
i_nb_samples
=
p_out
->
i_samples
;
DoWork
(
(
aout_instance_t
*
)
p_filter
,
&
aout_filter
,
&
in_buf
,
&
out_buf
);
p_out
->
i_buffer
=
out_buf
.
i_nb_bytes
;
p_out
->
i_samples
=
out_buf
.
i_nb_samples
;
if
(
p_block
)
p_block
->
pf_release
(
p_block
);
return
p_out
;
}
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