Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mediastreamer2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
External Wiki
External Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
BC
public
mediastreamer2
Commits
39a3f4dd
Commit
39a3f4dd
authored
Apr 01, 2011
by
jehan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of git.linphone.org:mediastreamer2
parents
ecb4a41f
66ca1775
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
107 additions
and
28 deletions
+107
-28
mediastream.h
include/mediastreamer2/mediastream.h
+0
-3
msinterfaces.h
include/mediastreamer2/msinterfaces.h
+8
-0
audiostream.c
src/audiostream.c
+22
-24
speexec.c
src/speexec.c
+77
-1
No files found.
include/mediastreamer2/mediastream.h
View file @
39a3f4dd
...
...
@@ -58,9 +58,6 @@ struct _AudioStream
uint64_t
last_packet_count
;
time_t
last_packet_time
;
EchoLimiterType
el_type
;
/*use echo limiter: two MSVolume, measured input level controlling local output level*/
int
ec_tail_len
;
/*milliseconds*/
int
ec_delay
;
/*milliseconds*/
int
ec_framesize
;
/* number of fft points */
OrtpEvQueue
*
evq
;
bool_t
play_dtmfs
;
bool_t
use_gc
;
...
...
include/mediastreamer2/msinterfaces.h
View file @
39a3f4dd
...
...
@@ -107,6 +107,14 @@ typedef enum _MSPlayerState MSPlayerState;
#define MS_ECHO_CANCELLER_GET_BYPASS_MODE \
MS_FILTER_METHOD(MSFilterEchoCancellerInterface,4,bool_t)
/** retrieve echo canceller internal state, as a base64 encoded string */
#define MS_ECHO_CANCELLER_GET_STATE_STRING \
MS_FILTER_METHOD(MSFilterEchoCancellerInterface,5,char **)
/** restore a previous state suppling the echo canceller config as base64 encoded string */
#define MS_ECHO_CANCELLER_SET_STATE_STRING \
MS_FILTER_METHOD(MSFilterEchoCancellerInterface,6, const char *)
/** Interface definitions for video decoders */
...
...
src/audiostream.c
View file @
39a3f4dd
...
...
@@ -298,27 +298,12 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_filter_call_method
(
stream
->
soundwrite
,
MS_FILTER_SET_NCHANNELS
,
&
tmp
);
/*configure the echo canceller if required */
if
(
use_ec
)
{
MSFilterDesc
*
ec_desc
=
ms_filter_lookup_by_name
(
"MSOslec"
);
if
(
ec_desc
!=
NULL
)
stream
->
ec
=
ms_filter_new_from_desc
(
ec_desc
);
else
stream
->
ec
=
ms_filter_new
(
MS_SPEEX_EC_ID
);
if
(
!
use_ec
)
{
ms_filter_destroy
(
stream
->
ec
);
stream
->
ec
=
NULL
;
}
if
(
stream
->
ec
){
ms_filter_call_method
(
stream
->
ec
,
MS_FILTER_SET_SAMPLE_RATE
,
&
sample_rate
);
if
(
stream
->
ec_tail_len
!=
0
)
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_TAIL_LENGTH
,
&
stream
->
ec_tail_len
);
if
(
stream
->
ec_delay
!=
0
){
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_DELAY
,
&
stream
->
ec_delay
);
}
else
{
/*configure from latency of sound card in case it is availlable */
int
latency
=
0
;
ms_filter_call_method
(
stream
->
soundread
,
MS_FILTER_GET_LATENCY
,
&
latency
);
latency
-=
20
;
/*keep 30 milliseconds security margin*/
if
(
latency
<
0
)
latency
=
0
;
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_DELAY
,
&
latency
);
}
if
(
stream
->
ec_framesize
!=
0
)
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_FRAMESIZE
,
&
stream
->
ec_framesize
);
}
/* give the encoder/decoder some parameters*/
...
...
@@ -459,8 +444,17 @@ void audio_stream_record(AudioStream *st, const char *name){
AudioStream
*
audio_stream_new
(
int
locport
,
bool_t
ipv6
){
AudioStream
*
stream
=
(
AudioStream
*
)
ms_new0
(
AudioStream
,
1
);
MSFilterDesc
*
ec_desc
=
ms_filter_lookup_by_name
(
"MSOslec"
);
stream
->
session
=
create_duplex_rtpsession
(
locport
,
ipv6
);
/*some filters are created right now to allow configuration by the application before start() */
stream
->
rtpsend
=
ms_filter_new
(
MS_RTP_SEND_ID
);
if
(
ec_desc
!=
NULL
)
stream
->
ec
=
ms_filter_new_from_desc
(
ec_desc
);
else
stream
->
ec
=
ms_filter_new
(
MS_SPEEX_EC_ID
);
stream
->
evq
=
ortp_ev_queue_new
();
rtp_session_register_event_queue
(
stream
->
session
,
stream
->
evq
);
stream
->
play_dtmfs
=
TRUE
;
...
...
@@ -485,10 +479,14 @@ void audio_stream_set_relay_session_id(AudioStream *stream, const char *id){
ms_filter_call_method
(
stream
->
rtpsend
,
MS_RTP_SEND_SET_RELAY_SESSION_ID
,(
void
*
)
id
);
}
void
audio_stream_set_echo_canceller_params
(
AudioStream
*
st
,
int
tail_len_ms
,
int
delay_ms
,
int
framesize
){
st
->
ec_tail_len
=
tail_len_ms
;
st
->
ec_delay
=
delay_ms
;
st
->
ec_framesize
=
framesize
;
void
audio_stream_set_echo_canceller_params
(
AudioStream
*
stream
,
int
tail_len_ms
,
int
delay_ms
,
int
framesize
){
if
(
tail_len_ms
!=
0
)
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_TAIL_LENGTH
,
&
tail_len_ms
);
if
(
delay_ms
!=
0
){
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_DELAY
,
&
delay_ms
);
}
if
(
framesize
!=
0
)
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_FRAMESIZE
,
&
framesize
);
}
void
audio_stream_enable_echo_limiter
(
AudioStream
*
stream
,
EchoLimiterType
type
){
...
...
src/speexec.c
View file @
39a3f4dd
...
...
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msticker.h"
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
#include "ortp/b64.h"
#ifdef HAVE_CONFIG_H
#include "mediastreamer-config.h"
...
...
@@ -138,6 +139,7 @@ typedef struct SpeexECState{
int
nominal_ref_samples
;
int
min_ref_samples
;
AudioFlowController
afc
;
char
*
state_str
;
#ifdef EC_DUMP
FILE
*
echofile
;
FILE
*
reffile
;
...
...
@@ -159,6 +161,7 @@ static void speex_ec_init(MSFilter *f){
s
->
ecstate
=
NULL
;
s
->
framesize
=
framesize
;
s
->
den
=
NULL
;
s
->
state_str
=
NULL
;
s
->
using_zeroes
=
FALSE
;
s
->
echostarted
=
FALSE
;
s
->
bypass_mode
=
FALSE
;
...
...
@@ -182,6 +185,7 @@ static void speex_ec_init(MSFilter *f){
static
void
speex_ec_uninit
(
MSFilter
*
f
){
SpeexECState
*
s
=
(
SpeexECState
*
)
f
->
data
;
if
(
s
->
state_str
)
ms_free
(
s
->
state_str
);
ms_bufferizer_uninit
(
&
s
->
delayed_ref
);
#ifdef EC_DUMP
if
(
s
->
echofile
)
...
...
@@ -192,6 +196,55 @@ static void speex_ec_uninit(MSFilter *f){
ms_free
(
s
);
}
#ifdef SPEEX_ECHO_GET_BLOB
static
void
apply_config
(
SpeexECState
*
s
){
if
(
s
->
state_str
!=
NULL
){
size_t
buflen
=
strlen
(
s
->
state_str
);
uint8_t
*
buffer
=
alloca
(
buflen
);
SpeexEchoStateBlob
*
blob
;
if
((
buflen
=
b64_decode
(
s
->
state_str
,
strlen
(
s
->
state_str
),
buffer
,
buflen
))
<=
0
){
ms_error
(
"Could not decode base64 %s"
,
s
->
state_str
);
return
;
}
blob
=
speex_echo_state_blob_new_from_memory
(
buffer
,
buflen
);
if
(
blob
==
NULL
){
ms_error
(
"Could not create blob from config string"
);
return
;
}
if
(
speex_echo_ctl
(
s
->
ecstate
,
SPEEX_ECHO_SET_BLOB
,
blob
)
!=
0
){
ms_error
(
"Could not apply speex echo blob !"
);
}
speex_echo_state_blob_free
(
blob
);
ms_message
(
"speex echo state restored."
);
}
}
static
void
fetch_config
(
SpeexECState
*
s
){
SpeexEchoStateBlob
*
blob
=
NULL
;
char
*
txt
;
size_t
txt_len
;
if
(
s
->
ecstate
==
NULL
)
return
;
if
(
speex_echo_ctl
(
s
->
ecstate
,
SPEEX_ECHO_GET_BLOB
,
&
blob
)
!=
0
){
ms_error
(
"Could not retrieve speex echo blob !"
);
return
;
}
txt_len
=
(
speex_echo_state_blob_get_size
(
blob
)
*
4
)
+
1
;
txt
=
ms_malloc0
(
txt_len
);
if
(
b64_encode
(
speex_echo_state_blob_get_data
(
blob
),
speex_echo_state_blob_get_size
(
blob
),
txt
,
txt_len
)
==
0
){
ms_error
(
"Base64 encoding failed."
);
ms_free
(
txt
);
return
;
}
speex_echo_state_blob_free
(
blob
);
if
(
s
->
state_str
)
ms_free
(
s
->
state_str
);
s
->
state_str
=
txt
;
}
#endif
static
void
speex_ec_preprocess
(
MSFilter
*
f
){
SpeexECState
*
s
=
(
SpeexECState
*
)
f
->
data
;
...
...
@@ -215,6 +268,11 @@ static void speex_ec_preprocess(MSFilter *f){
s
->
min_ref_samples
=-
1
;
s
->
nominal_ref_samples
=
delay_samples
;
audio_flow_controller_init
(
&
s
->
afc
);
#ifdef SPEEX_ECHO_GET_BLOB
apply_config
(
s
);
#else
if
(
s
->
state_str
)
ms_warning
(
"This version of speex doesn't support echo canceller restoration state. Rebuild speex and mediatreamer2 if you want to use this feature."
);
#endif
}
/* inputs[0]= reference signal from far end (sent to soundcard)
...
...
@@ -309,6 +367,7 @@ static void speex_ec_process(MSFilter *f){
static
void
speex_ec_postprocess
(
MSFilter
*
f
){
SpeexECState
*
s
=
(
SpeexECState
*
)
f
->
data
;
ms_bufferizer_flush
(
&
s
->
delayed_ref
);
ms_bufferizer_flush
(
&
s
->
echo
);
if
(
s
->
ecstate
!=
NULL
){
...
...
@@ -356,13 +415,30 @@ static int speex_ec_get_bypass_mode(MSFilter *f, void *arg) {
return
0
;
}
static
int
speex_ec_set_state
(
MSFilter
*
f
,
void
*
arg
){
SpeexECState
*
s
=
(
SpeexECState
*
)
f
->
data
;
s
->
state_str
=
ms_strdup
((
const
char
*
)
arg
);
return
0
;
}
static
int
speex_ec_get_state
(
MSFilter
*
f
,
void
*
arg
){
SpeexECState
*
s
=
(
SpeexECState
*
)
f
->
data
;
#ifdef SPEEX_ECHO_GET_BLOB
fetch_config
(
s
);
#endif
*
(
char
**
)
arg
=
s
->
state_str
;
return
0
;
}
static
MSFilterMethod
speex_ec_methods
[]
=
{
{
MS_FILTER_SET_SAMPLE_RATE
,
speex_ec_set_sr
},
{
MS_ECHO_CANCELLER_SET_TAIL_LENGTH
,
speex_ec_set_tail_length
},
{
MS_ECHO_CANCELLER_SET_DELAY
,
speex_ec_set_delay
},
{
MS_ECHO_CANCELLER_SET_FRAMESIZE
,
speex_ec_set_framesize
},
{
MS_ECHO_CANCELLER_SET_BYPASS_MODE
,
speex_ec_set_bypass_mode
},
{
MS_ECHO_CANCELLER_GET_BYPASS_MODE
,
speex_ec_get_bypass_mode
}
{
MS_ECHO_CANCELLER_GET_BYPASS_MODE
,
speex_ec_get_bypass_mode
},
{
MS_ECHO_CANCELLER_GET_STATE_STRING
,
speex_ec_get_state
},
{
MS_ECHO_CANCELLER_SET_STATE_STRING
,
speex_ec_set_state
}
};
#ifdef _MSC_VER
...
...
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