module-echo-cancel: aec_method='webrtc', parsing mic_geometry value is locale dependent
Submitted by Antonio Ospite
Assigned to pul..@..op.org
Description
Hi,
I was trying setting mic_geometry for the PS3Eye (http://m.eet.com/media/1111734/101016_move_teardown_5_700.jpg), but it didn't work at first:
Set the first PS3Eye as the input device, it is important to do so before
loading module-echo-cancel because the mic_geometry parameter is expected to
contain exactly as many points as are the channels of the source device
master format.
PS3EYE_SOURCE=$(pactl list short sources | grep "OmniVision_Technologies__Inc._USB_Camera" | head -1 | cut -f 2) pactl set-default-source $PS3EYE_SOURCE
Load the mic geometry.
pactl load-module module-echo-cancel use_master_format=1 aec_method='webrtc' aec_args='"beamforming=1 mic_geometry=-0.03,0,0,-0.01,0,0,0.01,0,0,0.03,0,0"'
Loading the module failed:
pulseaudio[3640]: Failed to parse channel 0 in mic_geometry pulseaudio[3640]: Failed to parse mic_geometry value pulseaudio[3640]: [pulseaudio] module-echo-cancel.c: Failed to init AEC engine pulseaudio[3640]: [pulseaudio] module.c: Failed to load module "module-echo-cancel" (argument: "use_master_format=1 aec_method=webrtc aec_args="beamforming=1 mic_geometry=-0.03,0,0,-0.01,0,0,0.01,0,0,0.03,0,0""): initialization failed.
I figured out that was happening if pulseaudio was started in an environment with a locale with a decimal point character different than a period, this was the case for me because I use the "it_IT.utf8" locale and pulseaudio inherit it by calling:
setlocale(LC_ALL, "")
The locale affects decimal number representation (floats values) and the issue does not occur in other modules because echo-cancel/webrtc.cc is the only place where a float is parsed with sscanf(), the other modules only have integer parameters.
Launching pulseaudio with LC_NUMERIC=C works around the issue:
pulseaudio -k && LC_NUMERIC=C pulseaudio
Not sure what the best fix in the code is: setting LC_NUMERIC to "C", using pa_atod (which can use strtod_l) or adding a locale independent sscanf wrapper.
Thanks, Antonio