Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
c484694f
Commit
c484694f
authored
May 28, 2010
by
Alexandre Savard
Browse files
[#1966] Make echo canceller and noise suppressor optional
parent
34dd2ffe
Changes
17
Hide whitespace changes
Inline
Side-by-side
sflphone-client-gnome/src/config/audioconf.c
View file @
c484694f
...
...
@@ -47,6 +47,7 @@ GtkWidget *codecTreeView; // View used instead of store to get access to select
GtkWidget
*
pulse
;
GtkWidget
*
alsabox
;
GtkWidget
*
alsa_conf
;
GtkWidget
*
noisebox
;
GtkWidget
*
noise_conf
;
// Codec properties ID
...
...
@@ -776,6 +777,48 @@ select_audio_manager( void )
}
void
active_echo_cancel
(
void
)
{
gchar
*
state
;
gchar
*
newstate
;
DEBUG
(
"Audio: Active echo cancel clicked"
);
state
=
dbus_get_echo_cancel_state
();
DEBUG
(
"Audio: Get echo cancel state %s"
,
state
);
if
(
strcmp
(
state
,
"enabled"
)
==
0
)
newstate
=
"disabled"
;
else
newstate
=
"enabled"
;
dbus_set_echo_cancel_state
(
newstate
);
}
void
active_noise_suppress
(
void
)
{
gchar
*
state
;
gchar
*
newstate
;
DEBUG
(
"Audio: Active noise suppress clicked"
);
state
=
dbus_get_noise_suppress_state
();
DEBUG
(
"Audio: Get echo cancel state %s"
,
state
);
if
(
strcmp
(
state
,
"enabled"
)
==
0
)
newstate
=
"disabled"
;
else
newstate
=
"enabled"
;
dbus_set_noise_suppress_state
(
newstate
);
}
GtkWidget
*
alsa_box
()
{
GtkWidget
*
ret
;
...
...
@@ -886,30 +929,37 @@ GtkWidget* alsa_box()
GtkWidget
*
noise_box
()
{
GtkWidget
*
ret
;
GtkWidget
*
enable
VoiceActivity
;
GtkWidget
*
enable
EchoCancel
;
GtkWidget
*
enableNoiseReduction
;
gboolean
echocancelActive
,
noisesuppressActive
;
gchar
*
state
;
// check button to enable ringtones
ret
=
gtk_hbox_new
(
TRUE
,
1
);
enableEchoCancel
=
gtk_check_button_new_with_mnemonic
(
_
(
"_Echo Suppression"
));
state
=
dbus_get_echo_cancel_state
();
echocancelActive
=
FALSE
;
if
(
strcmp
(
state
,
"enabled"
)
==
0
)
echocancelActive
=
TRUE
;
else
echocancelActive
=
FALSE
;
gtk_toggle_button_set_active
(
GTK_TOGGLE_BUTTON
(
enableEchoCancel
),
echocancelActive
);
g_signal_connect
(
G_OBJECT
(
enableEchoCancel
),
"clicked"
,
active_echo_cancel
,
NULL
);
enableVoiceActivity
=
gtk_check_button_new_with_mnemonic
(
_
(
"_Voice Activity Detection"
));
//TODO Use the value from D-BUS
gtk_toggle_button_set_active
(
GTK_TOGGLE_BUTTON
(
enableVoiceActivity
),
FALSE
);
gtk_box_pack_start
(
GTK_BOX
(
ret
)
,
enableVoiceActivity
,
TRUE
,
TRUE
,
1
);
//TODO Enable it
//gtk_widget_set_sensitive(GTK_WIDGET(noise_conf), FALSE);
//TODO Add a callback function
//g_signal_connect(G_OBJECT( enableNoiseReduction) , "clicked" , NULL , NULL);
gtk_box_pack_start
(
GTK_BOX
(
ret
),
enableEchoCancel
,
TRUE
,
TRUE
,
1
);
enableNoiseReduction
=
gtk_check_button_new_with_mnemonic
(
_
(
"_Noise Reduction (Narrow-Band Companding)"
));
//TODO Use the value from D-BUS
gtk_toggle_button_set_active
(
GTK_TOGGLE_BUTTON
(
enableNoiseReduction
),
FALSE
);
enableNoiseReduction
=
gtk_check_button_new_with_mnemonic
(
_
(
"_Noise Reduction"
));
state
=
dbus_get_noise_suppress_state
();
noisesuppressActive
=
FALSE
;
if
(
strcmp
(
state
,
"enabled"
)
==
0
)
noisesuppressActive
=
TRUE
;
else
noisesuppressActive
=
FALSE
;
gtk_toggle_button_set_active
(
GTK_TOGGLE_BUTTON
(
enableNoiseReduction
),
noisesuppressActive
);
gtk_box_pack_start
(
GTK_BOX
(
ret
)
,
enableNoiseReduction
,
TRUE
,
TRUE
,
1
);
//TODO Enable it
// gtk_widget_set_sensitive(GTK_WIDGET(noise_conf), FALSE);
//TODO Add a callback function
//g_signal_connect(G_OBJECT( enableNoiseReduction) , "clicked" , NULL , NULL);
g_signal_connect
(
G_OBJECT
(
enableNoiseReduction
),
"clicked"
,
active_noise_suppress
,
NULL
);
return
ret
;
}
...
...
@@ -1017,6 +1067,15 @@ GtkWidget* create_audio_configuration()
gtk_file_chooser_add_filter
(
GTK_FILE_CHOOSER
(
fileChooser
)
,
filter
);
gtk_table_attach
(
GTK_TABLE
(
table
),
fileChooser
,
1
,
2
,
0
,
1
,
GTK_EXPAND
|
GTK_FILL
,
GTK_EXPAND
|
GTK_FILL
,
0
,
0
);
gnome_main_section_new
(
_
(
"Voice enhancement settings"
),
&
noise_conf
);
gtk_box_pack_start
(
GTK_BOX
(
ret
),
noise_conf
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
noise_conf
);
// Box for the voice enhancement configuration
noisebox
=
noise_box
();
gtk_container_add
(
GTK_CONTAINER
(
noise_conf
)
,
noisebox
);
gtk_widget_show_all
(
ret
);
if
(
!
pulse_audio
)
{
...
...
sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
View file @
c484694f
...
...
@@ -574,6 +574,36 @@
</arg>
</method>
<method
name=
"getEchoCancelState"
tp:name-for-bindings=
"getEchoCancelState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method
name=
"setEchoCancelState"
tp:name-for-bindings=
"setEchoCancelState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"in"
>
</arg>
</method>
<method
name=
"getNoiseSuppressState"
tp:name-for-bindings=
"getNoiseSuppressState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method
name=
"setNoiseSuppressState"
tp:name-for-binding=
"setNoiseSuppressState"
>
<arg
type=
"s"
name=
"state"
direction=
"in"
>
</arg>
</method>
<!-- General Settings Panel -->
<method
name=
"isMd5CredentialHashing"
tp:name-for-bindings=
"isMd5CredentialHashing"
>
...
...
sflphone-client-gnome/src/dbus/dbus.c
View file @
c484694f
...
...
@@ -1503,6 +1503,72 @@ dbus_get_current_audio_output_plugin()
return
plugin
;
}
/**
* Get echo canceller state
*/
gchar
*
dbus_get_echo_cancel_state
()
{
gchar
*
state
=
""
;
GError
*
error
=
NULL
;
org_sflphone_SFLphone_ConfigurationManager_get_echo_cancel_state
(
configurationManagerProxy
,
&
state
,
&
error
);
if
(
error
)
{
ERROR
(
"DBus: Failed to call get_echo_cancel_state() on ConfigurationManager: %s"
,
error
->
message
);
g_error_free
(
error
);
}
return
state
;
}
/**
* Set echo canceller state
*/
void
dbus_set_echo_cancel_state
(
gchar
*
state
)
{
GError
*
error
=
NULL
;
org_sflphone_SFLphone_ConfigurationManager_set_echo_cancel_state
(
configurationManagerProxy
,
state
,
&
error
);
if
(
error
)
{
ERROR
(
"Failed to call set_echo_cancel_state() on ConfigurationManager: %s"
,
error
->
message
);
g_error_free
(
error
);
}
}
/**
* Get noise reduction state
*/
gchar
*
dbus_get_noise_suppress_state
()
{
gchar
*
state
=
""
;
GError
*
error
=
NULL
;
org_sflphone_SFLphone_ConfigurationManager_get_noise_suppress_state
(
configurationManagerProxy
,
&
state
,
&
error
);
if
(
error
)
{
ERROR
(
"DBus: Failed to call get_noise_suppress_state() on ConfigurationManager: %s"
,
error
->
message
);
g_error_free
(
error
);
}
return
state
;
}
/**
* Set echo canceller state
*/
void
dbus_set_noise_suppress_state
(
gchar
*
state
)
{
GError
*
error
=
NULL
;
org_sflphone_SFLphone_ConfigurationManager_set_noise_suppress_state
(
configurationManagerProxy
,
state
,
&
error
);
if
(
error
)
{
ERROR
(
"Failed to call set_noise_suppress_state() on ConfigurationManager: %s"
,
error
->
message
);
g_error_free
(
error
);
}
}
gchar
*
dbus_get_ringtone_choice
()
{
...
...
sflphone-client-gnome/src/dbus/dbus.h
View file @
c484694f
...
...
@@ -315,6 +315,32 @@ int dbus_get_audio_device_index(const gchar* name);
*/
gchar
*
dbus_get_current_audio_output_plugin
();
/**
* ConfigurationManager - Get the current state of echo canceller
* @return gchar* The state (enabled/disabled)
*/
gchar
*
dbus_get_echo_cancel_state
(
void
);
/**
* ConfigurationManager - Set the crrent state of echo canceller
* @param gchar* The state (enabled/disabled)
*/
void
dbus_set_echo_cancel_state
(
gchar
*
state
);
/**
* ConfigurationManager - Get the current noise suppressor state
* @return gchar* The state (enabled/disabled)
*/
gchar
*
dbus_get_noise_suppress_state
(
void
);
/**
* ConfigurationManager - Set the current noise suppressor state
* @param gchar* The state (enabled/disabled)
*/
void
dbus_set_noise_suppress_state
(
gchar
*
state
);
/**
* ConfigurationManager - Query to server to
* know if MD5 credential hashing is enabled.
...
...
sflphone-common/src/audio/alsa/alsalayer.cpp
View file @
c484694f
...
...
@@ -59,6 +59,9 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager)
// _audioThread = new AudioThread (this);
// _audioThread = NULL;
_urgentRingBuffer
.
createReadPointer
();
AudioLayer
::
_echocancelstate
=
true
;
AudioLayer
::
_noisesuppressstate
=
true
;
}
// Destructor
...
...
@@ -71,12 +74,6 @@ AlsaLayer::~AlsaLayer (void)
delete
_converter
;
_converter
=
NULL
;
}
delete
AudioLayer
::
_echoCancel
;
AudioLayer
::
_echoCancel
=
NULL
;
delete
AudioLayer
::
_echoCanceller
;
AudioLayer
::
_echoCanceller
=
NULL
;
}
bool
...
...
@@ -141,6 +138,9 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int indexRing, int sampleRate,
AudioLayer
::
_echoCancel
=
new
EchoCancel
();
AudioLayer
::
_echoCanceller
=
new
AudioProcessing
(
static_cast
<
Algorithm
*>
(
_echoCancel
));
AudioLayer
::
_echoCancel
->
setEchoCancelState
(
AudioLayer
::
_echocancelstate
);
AudioLayer
::
_echoCancel
->
setNoiseSuppressState
(
AudioLayer
::
_noisesuppressstate
);
AudioLayer
::
_dcblocker
=
new
DcBlocker
();
AudioLayer
::
_audiofilter
=
new
AudioProcessing
(
static_cast
<
Algorithm
*>
(
_dcblocker
));
...
...
@@ -254,6 +254,27 @@ bool AlsaLayer::isCaptureActive (void)
return
false
;
}
void
AlsaLayer
::
setEchoCancelState
(
bool
state
)
{
// if a stream already running
if
(
AudioLayer
::
_echoCancel
)
_echoCancel
->
setEchoCancelState
(
state
);
AudioLayer
::
_echocancelstate
=
state
;
}
void
AlsaLayer
::
setNoiseSuppressState
(
bool
state
)
{
// if a stream already opened
if
(
AudioLayer
::
_echoCancel
)
_echoCancel
->
setNoiseSuppressState
(
state
);
AudioLayer
::
_noisesuppressstate
=
state
;
}
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////// ALSA PRIVATE FUNCTIONS ////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
...
...
sflphone-common/src/audio/alsa/alsalayer.h
View file @
c484694f
...
...
@@ -154,6 +154,30 @@ class AlsaLayer : public AudioLayer {
bool
isCaptureActive
(
void
);
/**
* Get the echo canceller state
* @return true if echo cancel activated
*/
virtual
bool
getEchoCancelState
(
void
)
{
return
AudioLayer
::
_echocancelstate
;
}
/**
* Set the echo canceller state
* @param state true if echocancel active, false elsewhere
*/
virtual
void
setEchoCancelState
(
bool
state
);
/**
* Get the noise suppressor state
* @return true if noise suppressor activated
*/
virtual
bool
getNoiseSuppressState
(
void
)
{
return
AudioLayer
::
_noisesuppressstate
;
}
/**
* Set the noise suppressor state
* @param state true if noise suppressor active, false elsewhere
*/
virtual
void
setNoiseSuppressState
(
bool
state
);
private:
// Copy Constructor
...
...
sflphone-common/src/audio/audiolayer.h
View file @
c484694f
...
...
@@ -232,6 +232,30 @@ class AudioLayer {
*/
inline
Recordable
*
getRecorderInstance
(
void
)
{
return
_recorder
;}
/**
* Get the echo canceller state
* @return true if echo cancel activated
*/
virtual
bool
getEchoCancelState
(
void
)
=
0
;
/**
* Set the echo canceller state
* @param state true if echocancel active, false elsewhere
*/
virtual
void
setEchoCancelState
(
bool
state
)
=
0
;
/**
* Get the noise suppressor state
* @return true if noise suppressor activated
*/
virtual
bool
getNoiseSuppressState
(
void
)
=
0
;
/**
* Set the noise suppressor state
* @param state true if noise suppressor active, false elsewhere
*/
virtual
void
setNoiseSuppressState
(
bool
state
)
=
0
;
/**
* Get the mutex lock for the entire audio layer
*/
...
...
@@ -325,6 +349,10 @@ class AudioLayer {
DcBlocker
*
_dcblocker
;
AudioProcessing
*
_audiofilter
;
bool
_echocancelstate
;
bool
_noisesuppressstate
;
};
#endif // _AUDIO_LAYER_H_
sflphone-common/src/audio/echocancel.cpp
View file @
c484694f
...
...
@@ -55,7 +55,9 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
_spkrAdaptSize
(
SPKR_ADAPT_SIZE
),
_micAdaptSize
(
MIC_ADAPT_SIZE
),
_correlationSize
(
0
),
_processedByte
(
0
)
_processedByte
(
0
),
_echoActive
(
true
),
_noiseActive
(
true
)
{
_debug
(
"EchoCancel: Instantiate echo canceller"
);
...
...
@@ -265,7 +267,8 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
// spkrFile->write((const char *)_tmpSpkr, byteSize);
// Remove noise
speex_preprocess_run
(
_noiseState
,
_tmpMic
);
if
(
_noiseActive
)
speex_preprocess_run
(
_noiseState
,
_tmpMic
);
// Processed echo cancellation
performEchoCancel
(
_tmpMic
,
_tmpSpkr
,
_tmpOut
);
...
...
@@ -284,8 +287,6 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
++
nbFrame
;
}
// _event.reset();
return
nbFrame
*
_smplPerFrame
;
}
...
...
@@ -337,10 +338,11 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
// lowpass filtering
float
amplify
=
(
_lastAmplFactor
+
_amplFactor
)
/
2
;
_lastAmplFactor
=
_amplFactor
;
amplifySignal
(
micData
+
(
k
*
_smplPerSeg
),
outputData
+
(
k
*
_smplPerSeg
),
amplify
);
if
(
!
_echoActive
)
amplify
=
1.0
;
//
amplifySignal(micData+(k*_smplPerSeg), outputData+(k*_smplPerSeg),
1.0
);
amplifySignal
(
micData
+
(
k
*
_smplPerSeg
),
outputData
+
(
k
*
_smplPerSeg
),
amplify
);
}
...
...
@@ -353,7 +355,7 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
void
EchoCancel
::
updateEchoCancel
(
SFLDataFormat
*
micData
,
SFLDataFormat
*
spkrData
)
{
// TODO: we should find a way to normalize signal at this point
int
micLvl
=
computeAmplitudeLevel
(
micData
,
_smplPerSeg
)
/
10
;
int
micLvl
=
computeAmplitudeLevel
(
micData
,
_smplPerSeg
)
/
6
;
int
spkrLvl
=
computeAmplitudeLevel
(
spkrData
,
_smplPerSeg
);
// Add 1 to make sure we are not dividing by 0
...
...
sflphone-common/src/audio/echocancel.h
View file @
c484694f
...
...
@@ -116,6 +116,14 @@ class EchoCancel : public Algorithm {
*/
void
setSamplingRate
(
int
smplRate
);
void
setEchoCancelState
(
bool
state
)
{
_echoActive
=
state
;
}
bool
getEchoCancelState
(
void
)
{
return
_echoActive
;
}
void
setNoiseSuppressState
(
bool
state
)
{
_noiseActive
=
state
;
}
bool
getNoiseSuppressState
(
void
)
{
return
_noiseActive
;
}
private:
/**
...
...
@@ -311,7 +319,15 @@ class EchoCancel : public Algorithm {
*/
SpeexPreprocessState
*
_noiseState
;
ost
::
Event
_event
;
/**
* true if noise suppressor is active, false elsewhere
*/
bool
_echoActive
;
/**
* true if noise suppressor is active, false elsewhere
*/
bool
_noiseActive
;
};
...
...
sflphone-common/src/audio/mainbuffer.cpp
View file @
c484694f
...
...
@@ -244,7 +244,7 @@ void MainBuffer::unBindCallID (CallID call_id1, CallID call_id2)
void
MainBuffer
::
unBindAll
(
CallID
call_id
)
{
// ost::MutexLock guard (_mutex);
// ost::MutexLock guard (_mutex);
CallIDSet
*
callid_set
=
getCallIDSet
(
call_id
);
...
...
@@ -271,7 +271,7 @@ void MainBuffer::unBindAll (CallID call_id)
int
MainBuffer
::
putData
(
void
*
buffer
,
int
toCopy
,
unsigned
short
volume
,
CallID
call_id
)
{
// ost::MutexLock guard (_mutex);
// ost::MutexLock guard (_mutex);
RingBuffer
*
ring_buffer
=
getRingBuffer
(
call_id
);
...
...
@@ -298,7 +298,7 @@ int MainBuffer::putData (void *buffer, int toCopy, unsigned short volume, CallID
int
MainBuffer
::
availForPut
(
CallID
call_id
)
{
// ost::MutexLock guard (_mutex);
// ost::MutexLock guard (_mutex);
RingBuffer
*
ringbuffer
=
getRingBuffer
(
call_id
);
...
...
sflphone-common/src/audio/pulseaudio/pulselayer.cpp
View file @
c484694f
...
...
@@ -257,6 +257,9 @@ PulseLayer::PulseLayer (ManagerImpl* manager)
is_started
=
false
;
AudioLayer
::
_echocancelstate
=
true
;
AudioLayer
::
_noisesuppressstate
=
true
;
/*
captureFile = new ofstream("captureFile", ofstream::binary);
captureRsmplFile = new ofstream("captureRsmplFile", ofstream::binary);
...
...
@@ -760,6 +763,25 @@ void PulseLayer::processData (void)
}
void
PulseLayer
::
setEchoCancelState
(
bool
state
)
{
// if a stream already running
if
(
AudioLayer
::
_echoCancel
)
_echoCancel
->
setEchoCancelState
(
state
);
AudioLayer
::
_echocancelstate
=
state
;
}
void
PulseLayer
::
setNoiseSuppressState
(
bool
state
)
{
// if a stream already opened
if
(
AudioLayer
::
_echoCancel
)
_echoCancel
->
setNoiseSuppressState
(
state
);
AudioLayer
::
_noisesuppressstate
=
state
;
}
void
PulseLayer
::
writeToSpeaker
(
void
)
{
...
...
sflphone-common/src/audio/pulseaudio/pulselayer.h
View file @
c484694f
...
...
@@ -177,6 +177,30 @@ class PulseLayer : public AudioLayer {
void
processRingtoneData
(
void
);
void
processData
(
void
);
/**
* Get the echo canceller state
* @return true if echo cancel activated
*/
bool
getEchoCancelState
(
void
)
{
return
AudioLayer
::
_echocancelstate
;
}
/**
* Set the echo canceller state
* @param state true if echocancel active, false elsewhere
*/
void
setEchoCancelState
(
bool
state
);
/**
* Get the noise suppressor state
* @return true if noise suppressor activated
*/
bool
getNoiseSuppressState
(
void
)
{
return
AudioLayer
::
_noisesuppressstate
;
}
/**
* Set the noise suppressor state
* @param state true if noise suppressor active, false elsewhere
*/
void
setNoiseSuppressState
(
bool
state
);
private:
// Copy Constructor
...
...
sflphone-common/src/dbus/configurationmanager-introspec.xml
View file @
c484694f
...
...
@@ -574,6 +574,36 @@
</arg>
</method>
<method
name=
"getEchoCancelState"
tp:name-for-bindings=
"getEchoCancelState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method
name=
"setEchoCancelState"
tp:name-for-bindings=
"setEchoCancelState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"in"
>
</arg>
</method>
<method
name=
"getNoiseSuppressState"
tp:name-for-bindings=
"getNoiseSuppressState"
>
<tp:docstring>
</tp:docstring>
<arg
type=
"s"
name=
"state"
direction=
"out"
>
<tp:docstring>
</tp:docstring>
</arg>