Compare commits

...

21 commits

Author SHA1 Message Date
Alper Nebi Yasak
76566cd5e4 Merge branch 'support-old-webrtc' into 'master'
echo-cancel: Support old webrtc-audio-processing library

See merge request pulseaudio/pulseaudio!836
2025-10-16 11:25:08 +03:00
Fco. Javier F. Serrador
eee0e8f22f Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/es/
2025-10-01 05:20:04 +02:00
Fco. Javier F. Serrador
b50c28af2c Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/es/
2025-10-01 05:20:04 +02:00
Martin Srebotnjak
210f4742e7 Translated using Weblate (Slovenian)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/sl/
2025-10-01 05:20:04 +02:00
Temuri Doghonadze
53532e63bf Translated using Weblate (Georgian)
Currently translated at 79.3% (454 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ka/
2025-10-01 05:20:04 +02:00
Jim Spentzos
6834e0041c Translated using Weblate (Greek)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/el/
2025-10-01 05:20:04 +02:00
김인수
329c05b04f Translated using Weblate (Korean)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ko/
2025-10-01 05:20:04 +02:00
Jim Spentzos
76320675d8 Translated using Weblate (Greek)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/el/
2025-10-01 05:20:04 +02:00
Salvatore Cocuzza
d5b58d29ea Translated using Weblate (Italian)
Currently translated at 99.6% (570 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/it/
2025-10-01 05:20:04 +02:00
Salvatore Cocuzza
511926ab4b Translated using Weblate (Italian)
Currently translated at 99.3% (568 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/it/
2025-10-01 05:20:04 +02:00
Fco. Javier F. Serrador
f6e1124942 Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/es/
2025-10-01 05:20:04 +02:00
Fco. Javier F. Serrador
c7db9d60a6 Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/es/
2025-10-01 05:20:04 +02:00
Fco. Javier F. Serrador
7493990c84 Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/es/
2025-10-01 05:20:04 +02:00
김인수
79455f69f7 Translated using Weblate (Korean)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ko/
2025-10-01 05:20:04 +02:00
Remus-Gabriel Chelu
a1fef186d0 Translated using Weblate (Romanian)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ro/
2025-10-01 05:20:04 +02:00
Sergey A
4fa2e83ac3 Translated using Weblate (Russian)
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ru/
2025-10-01 05:20:04 +02:00
Temuri Doghonadze
f081327511 Translated using Weblate (Georgian)
Currently translated at 78.8% (451 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ka/
2025-10-01 05:20:04 +02:00
Rafael Fontenelle
d3f1e217e7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (572 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/pt_BR/
2025-10-01 05:20:04 +02:00
Zayed Al-Saidi
5a3b45cda1 Translated using Weblate (Arabic)
Currently translated at 34.4% (197 of 572 strings)

Translation: pulseaudio/pulseaudio
Translate-URL: https://translate.fedoraproject.org/projects/pulseaudio/pulseaudio/ar/
2025-10-01 05:20:04 +02:00
Rômulo Borges
b4b3889f3c pactl: add JSON output format
Previously, using the -f json or --format=json flags did not return JSON for the following commands:
- get-sink-volume
- get-source-volume
- get-sink-mute
- get-source-mute

This change adds proper JSON output for these commands.
2025-09-28 12:25:49 -03:00
Alper Nebi Yasak
681ab57f17 echo-cancel: Support old webrtc-audio-processing library
PulseAudio requires webrtc-audio-processing-1 >= 1.0 since v17.0, but
Debian hasn't managed to package that version yet. The dependency is
only used for the echo-cancel module, and the API exposed by the webrtc
component doesn't appear to be changed.

It looks like we can revert the changes to allow building with an older
version, but it would be better to have the code support both versions
to make it easier to transition from early library versions to later
versions. As a step towards that, check in an older copy of the webrtc
component from commit b16b107171, and build with that when we have the
old library version.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2024-10-25 17:14:44 +03:00
14 changed files with 820 additions and 170 deletions

View file

@ -726,9 +726,15 @@ if get_option('daemon')
cdata.set('HAVE_SOXR', 1) cdata.set('HAVE_SOXR', 1)
endif endif
webrtc_dep = dependency('webrtc-audio-processing-1', version : '>= 1.0', required : get_option('webrtc-aec')) webrtc_dep = dependency('webrtc-audio-processing-1', version : '>= 1.0', required : false)
if webrtc_dep.found() if webrtc_dep.found()
cdata.set('HAVE_WEBRTC', 1) cdata.set('HAVE_WEBRTC', 1)
cdata.set('HAVE_WEBRTC1', 1)
else
webrtc_dep = dependency('webrtc-audio-processing', version : ['>= 0.2', '< 1.0'], required : get_option('webrtc-aec'))
if webrtc_dep.found()
cdata.set('HAVE_WEBRTC', 1)
endif
endif endif
systemd_dep = dependency('systemd', required : get_option('systemd')) systemd_dep = dependency('systemd', required : get_option('systemd'))

View file

@ -9,9 +9,8 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2025-04-27 12:48+0000\n" "PO-Revision-Date: 2025-05-08 08:25+0000\n"
"Last-Translator: Weblate Translation Memory <noreply-mt-weblate-translation-" "Last-Translator: Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n"
"memory@weblate.org>\n"
"Language-Team: Arabic <https://translate.fedoraproject.org/projects/" "Language-Team: Arabic <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/ar/>\n" "pulseaudio/pulseaudio/ar/>\n"
"Language: ar\n" "Language: ar\n"
@ -20,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 5.11\n" "X-Generator: Weblate 5.11.3\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -462,7 +461,7 @@ msgstr "نظام صوت بلس أوديو"
#: src/daemon/pulseaudio.desktop.in:5 #: src/daemon/pulseaudio.desktop.in:5
msgid "Start the PulseAudio Sound System" msgid "Start the PulseAudio Sound System"
msgstr "" msgstr "ابدأ نظام صوت بلس أوديو"
#: src/modules/alsa/alsa-mixer.c:2708 #: src/modules/alsa/alsa-mixer.c:2708
msgid "Input" msgid "Input"
@ -525,27 +524,27 @@ msgstr "لا يوجد التحكم في الرفع الصوت آلي"
#: src/modules/alsa/alsa-mixer.c:2722 #: src/modules/alsa/alsa-mixer.c:2722
msgid "Boost" msgid "Boost"
msgstr "" msgstr "تعزيز"
#: src/modules/alsa/alsa-mixer.c:2723 #: src/modules/alsa/alsa-mixer.c:2723
msgid "No Boost" msgid "No Boost"
msgstr "" msgstr "دون تعزيز"
#: src/modules/alsa/alsa-mixer.c:2724 #: src/modules/alsa/alsa-mixer.c:2724
msgid "Amplifier" msgid "Amplifier"
msgstr "" msgstr "مُضَخِّم"
#: src/modules/alsa/alsa-mixer.c:2725 #: src/modules/alsa/alsa-mixer.c:2725
msgid "No Amplifier" msgid "No Amplifier"
msgstr "" msgstr "دون مُضَخِّم"
#: src/modules/alsa/alsa-mixer.c:2726 #: src/modules/alsa/alsa-mixer.c:2726
msgid "Bass Boost" msgid "Bass Boost"
msgstr "" msgstr "تعزيز القرار"
#: src/modules/alsa/alsa-mixer.c:2727 #: src/modules/alsa/alsa-mixer.c:2727
msgid "No Bass Boost" msgid "No Bass Boost"
msgstr "" msgstr "دون تعزيز القرار"
#: src/modules/alsa/alsa-mixer.c:2728 src/modules/bluetooth/module-bluez5-device.c:1964 #: src/modules/alsa/alsa-mixer.c:2728 src/modules/bluetooth/module-bluez5-device.c:1964
#: src/utils/pactl.c:333 #: src/utils/pactl.c:333
@ -1046,7 +1045,7 @@ msgstr ""
#: src/modules/reserve-wrap.c:149 #: src/modules/reserve-wrap.c:149
msgid "PulseAudio Sound Server" msgid "PulseAudio Sound Server"
msgstr "" msgstr "خادم صوت بلس أوديو"
#: src/pulse/channelmap.c:105 #: src/pulse/channelmap.c:105
msgid "Front Center" msgid "Front Center"
@ -1074,7 +1073,7 @@ msgstr "خلف يمين"
#: src/pulse/channelmap.c:113 #: src/pulse/channelmap.c:113
msgid "Subwoofer" msgid "Subwoofer"
msgstr "مضخم صوت" msgstr "مضخم الترددات المنخفضة"
#: src/pulse/channelmap.c:115 #: src/pulse/channelmap.c:115
msgid "Front Left-of-center" msgid "Front Left-of-center"
@ -1332,7 +1331,7 @@ msgstr "نعم"
#: src/pulsecore/core-util.h:97 #: src/pulsecore/core-util.h:97
msgid "no" msgid "no"
msgstr "" msgstr "لا"
#: src/pulsecore/lock-autospawn.c:141 src/pulsecore/lock-autospawn.c:227 #: src/pulsecore/lock-autospawn.c:141 src/pulsecore/lock-autospawn.c:227
msgid "Cannot access autospawn lock." msgid "Cannot access autospawn lock."
@ -1370,7 +1369,7 @@ msgstr "ممنوع الوصول"
#: src/pulse/error.c:40 #: src/pulse/error.c:40
msgid "Unknown command" msgid "Unknown command"
msgstr "" msgstr "أمر مجهول"
#: src/pulse/error.c:41 #: src/pulse/error.c:41
msgid "Invalid argument" msgid "Invalid argument"
@ -1402,7 +1401,7 @@ msgstr ""
#: src/pulse/error.c:48 #: src/pulse/error.c:48
msgid "Internal error" msgid "Internal error"
msgstr "خطأ داخلي." msgstr "خطأ داخلي"
#: src/pulse/error.c:49 #: src/pulse/error.c:49
msgid "Connection terminated" msgid "Connection terminated"
@ -1438,7 +1437,7 @@ msgstr ""
#: src/pulse/error.c:57 #: src/pulse/error.c:57
msgid "Not supported" msgid "Not supported"
msgstr "غير معتمد" msgstr "غير مدعوم"
#: src/pulse/error.c:58 #: src/pulse/error.c:58
msgid "Unknown error code" msgid "Unknown error code"
@ -1466,7 +1465,7 @@ msgstr "خطأ في الإدخال/الإخراج"
#: src/pulse/error.c:64 #: src/pulse/error.c:64
msgid "Device or resource busy" msgid "Device or resource busy"
msgstr "" msgstr "الجهاز أو المورد مشغول"
#: src/pulse/sample.c:179 #: src/pulse/sample.c:179
#, c-format #, c-format

View file

@ -9,8 +9,8 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2024-09-04 16:38+0000\n" "PO-Revision-Date: 2025-06-22 10:49+0000\n"
"Last-Translator: Giannis Antypas <gianni.antypas@gmail.com>\n" "Last-Translator: Jim Spentzos <jimspentzos2000@gmail.com>\n"
"Language-Team: Greek <https://translate.fedoraproject.org/projects/" "Language-Team: Greek <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/el/>\n" "pulseaudio/pulseaudio/el/>\n"
"Language: el\n" "Language: el\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.7.1\n" "X-Generator: Weblate 5.12.2\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -359,7 +359,7 @@ msgstr "Περιγραφή: %s\n"
#: src/daemon/dumpmodules.c:67 #: src/daemon/dumpmodules.c:67
#, c-format #, c-format
msgid "Author: %s\n" msgid "Author: %s\n"
msgstr "Συγγραφέας: %s\n" msgstr "Δημιουργός: %s\n"
#: src/daemon/dumpmodules.c:69 #: src/daemon/dumpmodules.c:69
#, c-format #, c-format
@ -2298,9 +2298,7 @@ msgstr "ΠΛΑΙΣΙΑ"
#: src/utils/pacmd.c:80 src/utils/pactl.c:2659 #: src/utils/pacmd.c:80 src/utils/pactl.c:2659
msgid "RECIPIENT MESSAGE [MESSAGE_PARAMETERS]" msgid "RECIPIENT MESSAGE [MESSAGE_PARAMETERS]"
msgstr "" msgstr "ΜΗΝΥΜΑ ΠΑΡΑΛΗΠΤΗ [MESSAGE_PARAMETERS]"
"ΜΗΝΥΜΑ ΠΑΡΑΛΗΠΤΗ\n"
"[ΠΑΡΑΜΕΤΡΟΙ_ΜΗΝΥΜΑΤΟΣ]"
#: src/utils/pacmd.c:82 #: src/utils/pacmd.c:82
#, c-format #, c-format

View file

@ -14,8 +14,8 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2022-12-18 11:19+0000\n" "PO-Revision-Date: 2025-07-29 09:34+0000\n"
"Last-Translator: Toni Estevez <toni.estevez@gmail.com>\n" "Last-Translator: \"Fco. Javier F. Serrador\" <fserrador@gmail.com>\n"
"Language-Team: Spanish <https://translate.fedoraproject.org/projects/" "Language-Team: Spanish <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/es/>\n" "pulseaudio/pulseaudio/es/>\n"
"Language: es\n" "Language: es\n"
@ -23,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.15\n" "X-Generator: Weblate 5.12.2\n"
"X-Poedit-Language: Spanish\n" "X-Poedit-Language: Spanish\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
@ -97,7 +97,7 @@ msgid ""
"\n" "\n"
" -n Don't load default script file\n" " -n Don't load default script file\n"
msgstr "" msgstr ""
"%s [opciones]\n" "--dl-search-path%s [opciones]\n"
"\n" "\n"
"ÓRDENES:\n" "ÓRDENES:\n"
" -h, --help Mostrar esta ayuda\n" " -h, --help Mostrar esta ayuda\n"
@ -123,8 +123,8 @@ msgstr ""
"inicio\n" "inicio\n"
" --fail[=BOOL] Salir cuando falla el inicio\n" " --fail[=BOOL] Salir cuando falla el inicio\n"
" --high-priority[=BOOL] Intentar asignar una prioridad alta\n" " --high-priority[=BOOL] Intentar asignar una prioridad alta\n"
" (solo disponible como superusuario, " " (solo disponible como admin, con "
"con SUID\n" "SUID\n"
" o con un valor RLIMIT_NICE elevado)\n" " o con un valor RLIMIT_NICE elevado)\n"
" --realtime[=BOOL] Intentar activar la programación en " " --realtime[=BOOL] Intentar activar la programación en "
"tiempo real\n" "tiempo real\n"
@ -136,19 +136,19 @@ msgstr ""
" del usuario tras el inicio\n" " del usuario tras el inicio\n"
" --disallow-exit[=BOOL] Denegar la salida a petición del " " --disallow-exit[=BOOL] Denegar la salida a petición del "
"usuario\n" "usuario\n"
" --exit-idle-time=SEGUNDOS Finalizar el servicio cuando esté " " --exit-idle-time=SEGS Finalizar el servicio cuando esté "
"inactivo y\n" "inactivo y\n"
" haya pasado este tiempo\n" " haya pasado este tiempo\n"
" --scache-idle-time=SEGUNDOS Descargar las muestras cargadas " " --scache-idle-time=SEGS Descargar las muestras cargadas "
"automáticamente\n" "automáticamente\n"
" cuando esté inactivo y haya pasado " " cuando esté inactivo y haya pasado "
"este tiempo\n" "este tiempo\n"
" --log-level[=NIVEL] Aumentar o configurar el nivel de " " --log-level[=NIVEL] Aumentar o configurar el nivel de "
"registro\n" "registro\n"
" -v --verbose Aumentar el nivel de registro\n" " -v --verbose Aumentar el nivel de registro\n"
" --log-target={auto,syslog,stderr,file:RUTA,newfile:RUTA}\n" " --log-target={auto,syslog,stderr,file:RUTA,newfile:RUTA}\n"
" Especificar el destino del registro\n" " Especificar el destino del registro\n"
" --log-meta[=BOOL] Incluir ubicaciones del código en el " " --log-meta[=BOOL] Incluir lugares del código en el "
"registro\n" "registro\n"
" --log-time[=BOOL] Incluir marcas de tiempo en el " " --log-time[=BOOL] Incluir marcas de tiempo en el "
"registro\n" "registro\n"
@ -156,16 +156,19 @@ msgstr ""
"registro\n" "registro\n"
" -p, --dl-search-path=RUTA Configurar la ruta de búsqueda de " " -p, --dl-search-path=RUTA Configurar la ruta de búsqueda de "
"objetos\n" "objetos\n"
" dinámicos compartidos (complementos)" " "
"\n" "dinámicos compartidos (complementos)\n"
" --resample-method=MÉTODO Usar el método de remuestreo " " --resample-method=MÉTODO Usar el método de remuestreo "
"especificado\n" "especificado\n"
" (Consulte los valores posibles con\n" " "
" --dump-resample-methods)\n" "(Consulte los valores posibles con\n"
" "
"--dump-resample-methods)\n"
" --use-pid-file[=BOOL] Crear un archivo PID\n" " --use-pid-file[=BOOL] Crear un archivo PID\n"
" --no-cpu-limit[=BOOL] No instalar el limitador de carga de " " --no-cpu-limit[=BOOL] No instalar el limitador de carga de "
"la CPU\n" "la CPU\n"
" en las plataformas compatibles.\n" " en las "
"plataformas compatibles.\n"
" --disable-shm[=BOOL] Desactivar el uso de memoria " " --disable-shm[=BOOL] Desactivar el uso de memoria "
"compartida\n" "compartida\n"
" --enable-memfd[=BOOL] Activar el uso de memoria compartida " " --enable-memfd[=BOOL] Activar el uso de memoria compartida "
@ -174,10 +177,12 @@ msgstr ""
"GUION DE INICIO:\n" "GUION DE INICIO:\n"
" -L, --load=\"ARGUMENTO DEL MÓDULO\" Cargar el módulo del complemento " " -L, --load=\"ARGUMENTO DEL MÓDULO\" Cargar el módulo del complemento "
"especificado\n" "especificado\n"
" con el argumento especificado\n" " "
" -F, --file=ARCHIVO Ejecutar el guion especificado\n" "con el argumento especificado\n"
" -C Abrir una línea de órdenes en el TTY " " -F, --file=ARCHIVO Ejecutar el guion "
"en\n" "especificado\n"
" -C Abrir una línea de "
"órdenes en el TTY en\n"
" ejecución tras el inicio\n" " ejecución tras el inicio\n"
" -n No cargar el archivo de órdenes " " -n No cargar el archivo de órdenes "
"predeterminado\n" "predeterminado\n"
@ -195,9 +200,9 @@ msgid ""
"--log-level expects log level argument (either numeric in range 0..4 or one " "--log-level expects log level argument (either numeric in range 0..4 or one "
"of error, warn, notice, info, debug)." "of error, warn, notice, info, debug)."
msgstr "" msgstr ""
"--log-level espera un argumento para el nivel de registro (un valor numérico " "--log-level espera un argumento para el nivel de bitácora (un valor numérico "
"en el rango de 0-4 o bien uno de estos valores: error, warn, notice, info, " "en el intervalo de 0..4 o bien uno de estos valores: error, warn, notice, "
"debug)." "info, debug)."
#: src/daemon/cmdline.c:277 #: src/daemon/cmdline.c:277
msgid "--high-priority expects boolean argument" msgid "--high-priority expects boolean argument"
@ -217,7 +222,7 @@ msgstr "--disallow-exit espera un argumento booleano"
#: src/daemon/cmdline.c:309 #: src/daemon/cmdline.c:309
msgid "--use-pid-file expects boolean argument" msgid "--use-pid-file expects boolean argument"
msgstr "--use pid-file espera un argumento booleano" msgstr "--use-pid-file espera un argumento booleano"
#: src/daemon/cmdline.c:328 #: src/daemon/cmdline.c:328
msgid "" msgid ""
@ -750,11 +755,11 @@ msgstr "Salida de juego"
#: src/modules/alsa/alsa-mixer.c:2819 src/modules/alsa/alsa-mixer.c:2820 #: src/modules/alsa/alsa-mixer.c:2819 src/modules/alsa/alsa-mixer.c:2820
msgid "Chat Output" msgid "Chat Output"
msgstr "Salida de chat" msgstr "Salida de charla"
#: src/modules/alsa/alsa-mixer.c:2821 #: src/modules/alsa/alsa-mixer.c:2821
msgid "Chat Input" msgid "Chat Input"
msgstr "Entrada de chat" msgstr "Entrada de charla"
#: src/modules/alsa/alsa-mixer.c:2822 #: src/modules/alsa/alsa-mixer.c:2822
msgid "Virtual Surround 7.1" msgid "Virtual Surround 7.1"
@ -1546,10 +1551,10 @@ msgid ""
"e.g. happen if you try to connect to a non-root PulseAudio as a root user, " "e.g. happen if you try to connect to a non-root PulseAudio as a root user, "
"over the native protocol. Don't do that.)" "over the native protocol. Don't do that.)"
msgstr "" msgstr ""
"XDG_RUNTIME_DIR (%s) no es de nuestra propiedad (usuario %d), sino del " "XDG_RUNTIME_DIR (%s) no es de nuestra propiedad (uid %d), sino del usuario "
"usuario %d. (Esto puede pasar, por ejemplo, al intentar conectarse como " "%d. (Esto puede pasar, por ejemplo, al intentar conectarse como superusuario "
"superusuario a un servidor PulseAudio que se ejecuta sin privilegios de " "a un servidor PulseAudio que se ejecuta sin privilegios de administrador "
"administrador mediante el protocolo nativo. No lo haga.)" "mediante el protocolo nativo. No lo haga.)"
#: src/pulsecore/core-util.h:97 #: src/pulsecore/core-util.h:97
msgid "yes" msgid "yes"
@ -1742,7 +1747,7 @@ msgstr "pa_stream_drain(): %s"
#: src/utils/pacat.c:194 src/utils/pacat.c:543 #: src/utils/pacat.c:194 src/utils/pacat.c:543
#, c-format #, c-format
msgid "pa_stream_begin_write() failed: %s" msgid "pa_stream_begin_write() failed: %s"
msgstr "Ha fallado pa_stream_write(): %s" msgstr "Ha fallado pa_stream_begin_write(): %s"
#: src/utils/pacat.c:244 src/utils/pacat.c:274 #: src/utils/pacat.c:244 src/utils/pacat.c:274
#, c-format #, c-format
@ -2285,7 +2290,7 @@ msgstr "NOMBRE|NÚMERO PUERTO"
#: src/utils/pacmd.c:74 src/utils/pactl.c:2658 #: src/utils/pacmd.c:74 src/utils/pactl.c:2658
msgid "CARD-NAME|CARD-#N PORT OFFSET" msgid "CARD-NAME|CARD-#N PORT OFFSET"
msgstr "NOMBRE-TARJETA|NÚMERO-TARJETA PUERTO COMPENSACIÓN" msgstr "NOMBRE-TARJETA|Nº-TARJETA PUERTO COMPENSACIÓN"
#: src/utils/pacmd.c:75 #: src/utils/pacmd.c:75
msgid "TARGET" msgid "TARGET"

View file

@ -12,7 +12,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2025-04-18 18:51+0000\n" "PO-Revision-Date: 2025-06-08 14:42+0000\n"
"Last-Translator: Salvatore Cocuzza <info@salvatorecocuzza.it>\n" "Last-Translator: Salvatore Cocuzza <info@salvatorecocuzza.it>\n"
"Language-Team: Italian <https://translate.fedoraproject.org/projects/" "Language-Team: Italian <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/it/>\n" "pulseaudio/pulseaudio/it/>\n"
@ -21,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.11\n" "X-Generator: Weblate 5.11.4\n"
# mamma mia che impressione # mamma mia che impressione
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
@ -1245,7 +1245,6 @@ msgid "Virtual surround sink"
msgstr "Sink surround virtuale" msgstr "Sink surround virtuale"
#: src/modules/module-virtual-surround-sink.c:54 #: src/modules/module-virtual-surround-sink.c:54
#, fuzzy
msgid "" msgid ""
"sink_name=<name for the sink> sink_properties=<properties for the sink> " "sink_name=<name for the sink> sink_properties=<properties for the sink> "
"master=<name of sink to filter> sink_master=<name of sink to filter> " "master=<name of sink to filter> sink_master=<name of sink to filter> "
@ -2418,7 +2417,7 @@ msgstr "Recupero delle informazioni del server non riuscito: %s"
#: src/utils/pactl.c:224 src/utils/pactl.c:236 #: src/utils/pactl.c:224 src/utils/pactl.c:236
#, c-format #, c-format
msgid "%s\n" msgid "%s\n"
msgstr "" msgstr "%s\n"
#: src/utils/pactl.c:281 #: src/utils/pactl.c:281
#, c-format #, c-format
@ -2489,7 +2488,6 @@ msgid "Mic"
msgstr "Mic" msgstr "Mic"
#: src/utils/pactl.c:338 #: src/utils/pactl.c:338
#, fuzzy
msgid "Handset" msgid "Handset"
msgstr "Cuffie con microfono" msgstr "Cuffie con microfono"
@ -2584,7 +2582,6 @@ msgid "\t\t%s: %s (type: %s, priority: %u%s%s, %s)\n"
msgstr "\t\t%s: %s (tipo: %s, priorità: %u%s%s, %s)\n" msgstr "\t\t%s: %s (tipo: %s, priorità: %u%s%s, %s)\n"
#: src/utils/pactl.c:710 src/utils/pactl.c:894 src/utils/pactl.c:1256 #: src/utils/pactl.c:710 src/utils/pactl.c:894 src/utils/pactl.c:1256
#, fuzzy
msgid ", availability group: " msgid ", availability group: "
msgstr ", gruppo disponibilità: " msgstr ", gruppo disponibilità: "

View file

@ -9,7 +9,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2025-04-13 20:52+0000\n" "PO-Revision-Date: 2025-07-21 10:49+0000\n"
"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n" "Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
"Language-Team: Georgian <https://translate.fedoraproject.org/projects/" "Language-Team: Georgian <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/ka/>\n" "pulseaudio/pulseaudio/ka/>\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n" "X-Generator: Weblate 5.12.2\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -328,7 +328,7 @@ msgstr ""
#: src/daemon/main.c:287 src/daemon/main.c:292 #: src/daemon/main.c:287 src/daemon/main.c:292
#, c-format #, c-format
msgid "Failed to create '%s': %s" msgid "Failed to create '%s': %s"
msgstr "შეცდომა %s-ის გახსნისას: %s" msgstr "'%s'-ის შექმნა ჩავარდა: %s"
#: src/daemon/main.c:299 #: src/daemon/main.c:299
#, c-format #, c-format
@ -554,11 +554,11 @@ msgstr "გამაძლიერებლის გარეშე"
#: src/modules/alsa/alsa-mixer.c:2726 #: src/modules/alsa/alsa-mixer.c:2726
msgid "Bass Boost" msgid "Bass Boost"
msgstr "Bass-ის გაძლიერება" msgstr "ბასის გაძლიერება"
#: src/modules/alsa/alsa-mixer.c:2727 #: src/modules/alsa/alsa-mixer.c:2727
msgid "No Bass Boost" msgid "No Bass Boost"
msgstr "Bass-ის გაძლიერების გარეშე" msgstr "ბასის გაძლიერების გარეშე"
#: src/modules/alsa/alsa-mixer.c:2728 #: src/modules/alsa/alsa-mixer.c:2728
#: src/modules/bluetooth/module-bluez5-device.c:1964 src/utils/pactl.c:333 #: src/modules/bluetooth/module-bluez5-device.c:1964 src/utils/pactl.c:333
@ -1338,7 +1338,7 @@ msgstr "xcb_connect() ჩავარდა"
#: src/pulse/client-conf-x11.c:66 src/utils/pax11publish.c:102 #: src/pulse/client-conf-x11.c:66 src/utils/pax11publish.c:102
msgid "xcb_connection_has_error() returned true" msgid "xcb_connection_has_error() returned true"
msgstr "xcb_connection_has_error()-მა 1 დააბრუნა" msgstr "xcb_connection_has_error()-მა დააბრუნა ჭეშმარიტი მნისვნელობა"
#: src/pulse/client-conf-x11.c:102 #: src/pulse/client-conf-x11.c:102
msgid "Failed to parse cookie data" msgid "Failed to parse cookie data"
@ -2112,8 +2112,8 @@ msgstr "სტატისტიკის მიღების შეცდო
#, c-format #, c-format
msgid "Currently in use: %u block containing %s bytes total.\n" msgid "Currently in use: %u block containing %s bytes total.\n"
msgid_plural "Currently in use: %u blocks containing %s bytes total.\n" msgid_plural "Currently in use: %u blocks containing %s bytes total.\n"
msgstr[0] "" msgstr[0] "ამჟამად გამოიყენება: %u ბლოკი, რომელიც შეიცავს სულ %s ბაიტს.\n"
msgstr[1] "" msgstr[1] "ამჟამად გამოიყენება: %u ბლოკი, რომელიც შეიცავს სულ %s ბაიტს.\n"
#: src/utils/pactl.c:205 #: src/utils/pactl.c:205
#, c-format #, c-format
@ -2121,7 +2121,11 @@ msgid "Allocated during whole lifetime: %u block containing %s bytes total.\n"
msgid_plural "" msgid_plural ""
"Allocated during whole lifetime: %u blocks containing %s bytes total.\n" "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
msgstr[0] "" msgstr[0] ""
"გამოყოფილია მთელი სიცოცხლის განმავლობაში: %u ბლოკი, რომელიც სულ %s ბაიტს "
"შეიცავს.\n"
msgstr[1] "" msgstr[1] ""
"გამოყოფილია მთელი სიცოცხლის განმავლობაში: %u ბლოკი, რომელიც სულ %s ბაიტს "
"შეიცავს.\n"
#: src/utils/pactl.c:211 #: src/utils/pactl.c:211
#, c-format #, c-format
@ -2560,7 +2564,11 @@ msgid_plural ""
"Failed to set volume: You tried to set volumes for %d channels, whereas " "Failed to set volume: You tried to set volumes for %d channels, whereas "
"channel(s) supported = %d\n" "channel(s) supported = %d\n"
msgstr[0] "" msgstr[0] ""
"ხმის დაყენაბა ჩავარდა: სცადეთ, დაგეყენებინათ ხმა %d არხზე მაშინ, როცა "
"მხარდაჭერილი არხები = %d\n"
msgstr[1] "" msgstr[1] ""
"ხმის დაყენაბა ჩავარდა: სცადეთ, დაგეყენებინათ ხმა %d არხზე მაშინ, როცა "
"მხარდაჭერილი არხები = %d\n"
#: src/utils/pactl.c:2107 #: src/utils/pactl.c:2107
#, c-format #, c-format

View file

@ -7,7 +7,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2024-08-04 19:41+0000\n" "PO-Revision-Date: 2025-06-14 13:17+0000\n"
"Last-Translator: 김인수 <simmon@nplob.com>\n" "Last-Translator: 김인수 <simmon@nplob.com>\n"
"Language-Team: Korean <https://translate.fedoraproject.org/projects/" "Language-Team: Korean <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/ko/>\n" "pulseaudio/pulseaudio/ko/>\n"
@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.6.2\n" "X-Generator: Weblate 5.11.4\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -230,7 +230,7 @@ msgstr "--disable-shm 에는 부울 인자 값이 필요합니다"
#: src/daemon/cmdline.c:397 #: src/daemon/cmdline.c:397
msgid "--enable-memfd expects boolean argument" msgid "--enable-memfd expects boolean argument"
msgstr "--enable-memfd는 부울 인수가 필요합니다" msgstr "--enable-memfd 는 부울 인수가 예상됩니다"
#: src/daemon/daemon-conf.c:270 #: src/daemon/daemon-conf.c:270
#, c-format #, c-format
@ -423,9 +423,8 @@ msgstr "명령어 행 분석 실패."
msgid "" msgid ""
"System mode refused for non-root user. Only starting the D-Bus server lookup " "System mode refused for non-root user. Only starting the D-Bus server lookup "
"service." "service."
msgstr "" msgstr "non-root 사용자에게 시스템 방식이 거부되었습니다. D-Bus 서버 검색 서비스만 "
"비 루트 사용자의 시스템 모드 전환을 거부했습니다. D-Bus 서버 검색 서비스만 시" "시작합니다."
"작합니다."
#: src/daemon/main.c:788 #: src/daemon/main.c:788
#, c-format #, c-format
@ -436,9 +435,8 @@ msgstr "데몬 종료 실패: %s"
msgid "" msgid ""
"This program is not intended to be run as root (unless --system is " "This program is not intended to be run as root (unless --system is "
"specified)." "specified)."
msgstr "" msgstr "이와 같은 프로그램은 root로 동작하도록 의도되지 않았습니다 (--system 이 "
"이 프로그램은 루트 계정으로 실행하도록 만들지 않았습니다. (실행하려면 --" "지정되지 않은 경우)."
"system을 명기하십시오)."
#: src/daemon/main.c:820 #: src/daemon/main.c:820
msgid "Root privileges required." msgid "Root privileges required."
@ -451,24 +449,22 @@ msgstr "--start는 시스템 인스턴스에 대해 지원되지 않습니다."
#: src/daemon/main.c:867 #: src/daemon/main.c:867
#, c-format #, c-format
msgid "User-configured server at %s, refusing to start/autospawn." msgid "User-configured server at %s, refusing to start/autospawn."
msgstr "%s에서 사용자 설정한 서버, start/autospawn을 거부하고 있습니다." msgstr "%s에 User-configured 서버, start/autospawn을 거부하고 있습니다."
#: src/daemon/main.c:873 #: src/daemon/main.c:873
#, c-format #, c-format
msgid "" msgid ""
"User-configured server at %s, which appears to be local. Probing deeper." "User-configured server at %s, which appears to be local. Probing deeper."
msgstr "%s에 사용자가 설정한 서버, 이는 로컬에 있습니다. 상세히 조사합니다." msgstr "%s에 User-configured 서버, 이는 로컬에 있습니다. 상세히 조사합니다."
#: src/daemon/main.c:878 #: src/daemon/main.c:878
msgid "Running in system mode, but --disallow-exit not set." msgid "Running in system mode, but --disallow-exit not set."
msgstr "" msgstr "시스템 방식에서 실행 중이지만, --disallow-exit 를 설정하지 않았습니다."
"시스템 모드에서 실행 중입니다. 하지만 --disallow-exit을 설정하지 않았습니다."
#: src/daemon/main.c:881 #: src/daemon/main.c:881
msgid "Running in system mode, but --disallow-module-loading not set." msgid "Running in system mode, but --disallow-module-loading not set."
msgstr "" msgstr "시스템 방식에서 실행 중이지만, --disallow-module-loading 를 설정하지 "
"시스템 모드에서 실행 중입니다. 하지만 --disallow-module-loading을 설정하지 않" "않았습니다."
"았습니다."
#: src/daemon/main.c:884 #: src/daemon/main.c:884
msgid "Running in system mode, forcibly disabling SHM mode." msgid "Running in system mode, forcibly disabling SHM mode."
@ -1014,11 +1010,11 @@ msgstr "전화기"
#: src/modules/bluetooth/module-bluez5-device.c:2042 #: src/modules/bluetooth/module-bluez5-device.c:2042
msgid "High Fidelity Playback (A2DP Sink)" msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Hi-Fi 재생 (A2DP Sink)" msgstr "고음질 재생 (A2DP Sink)"
#: src/modules/bluetooth/module-bluez5-device.c:2054 #: src/modules/bluetooth/module-bluez5-device.c:2054
msgid "High Fidelity Capture (A2DP Source)" msgid "High Fidelity Capture (A2DP Source)"
msgstr "Hi-Fi 캡쳐 (A2DP Source)" msgstr "고음질 캡쳐 (A2DP Source)"
#: src/modules/bluetooth/module-bluez5-device.c:2066 #: src/modules/bluetooth/module-bluez5-device.c:2066
msgid "Headset Head Unit (HSP)" msgid "Headset Head Unit (HSP)"
@ -1479,9 +1475,9 @@ msgid ""
"e.g. happen if you try to connect to a non-root PulseAudio as a root user, " "e.g. happen if you try to connect to a non-root PulseAudio as a root user, "
"over the native protocol. Don't do that.)" "over the native protocol. Don't do that.)"
msgstr "" msgstr ""
"XDG_RUNTIME_DIR (%s) 우리(uid %d)가 아니라 uid %d가 소유합니다! (자체 프로" "XDG_RUNTIME_DIR (%s) 우리(uid %d)가 아니라 uid %d가 소유합니다! (자체 "
"토콜로 비 루트 펄스오디오 사용자가 루트 사용자 권한으로 연결할 때 이 문제가 " "통신규약을 통해 root 사용자로 root가 아닌 PluseAudio에 연결을 시도 할 때에 "
"일어납니다. 그렇게 하지 마십시오.)" "예시로 발생 할 수 있습니다. 그렇게 하지 않습니다.)"
#: src/pulsecore/core-util.h:97 #: src/pulsecore/core-util.h:97
msgid "yes" msgid "yes"

View file

@ -11,7 +11,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2024-10-11 16:01+0000\n" "PO-Revision-Date: 2025-05-10 22:55+0000\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n" "Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Portuguese (Brazil) <https://translate.fedoraproject.org/" "Language-Team: Portuguese (Brazil) <https://translate.fedoraproject.org/"
"projects/pulseaudio/pulseaudio/pt_BR/>\n" "projects/pulseaudio/pulseaudio/pt_BR/>\n"
@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7.2\n" "X-Generator: Weblate 5.11.3\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -1908,7 +1908,7 @@ msgid "pa_stream_update_timing_info() failed: %s"
msgstr "pa_stream_update_timing_info() falhou: %s" msgstr "pa_stream_update_timing_info() falhou: %s"
#: src/utils/pacat.c:676 #: src/utils/pacat.c:676
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"%s [options]\n" "%s [options]\n"
"%s\n" "%s\n"
@ -1987,62 +1987,58 @@ msgstr ""
" -v, --verbose Habilita operações no modo " " -v, --verbose Habilita operações no modo "
"detalhado\n" "detalhado\n"
"\n" "\n"
" -s, --server=SERVIDOR O nome do servidor a conectar-se\n" " -s, --server=SERVIDOR O nome do servidor para se conectar\n"
" -d, --device=DISPOSITIVO O nome do destino/fonte a conectar-" " -d, --device=DISPOSITIVO O nome do destino/fonte para se "
"se\n" "conectar\n"
" -n, --client-name=NOME Como chamar este cliente no " " -n, --client-name=NOME Como chamar este cliente no "
"servidor\n" "servidor\n"
" --stream-name=NOME Como chamar este fluxo no servidor\n" " --stream-name=NOME Como chamar este fluxo no servidor\n"
" --volume=VOLUME Especifica a faixa (linear) inicial\n" " --volume=VOLUME Especifica o volume (linear) inicial "
" de volume no intervalo 0...65536\n" "no intervalo 0...65536\n"
" --rate=TAXA_DE_AMOSTRAGEM Taxa de amostragem, Hz (padrão " " --rate=TAXA_DE_AMOSTRAGEM Taxa de amostragem em Hz (padrão: "
"44100)\n" "44100)\n"
" --format=FORMATO_DE_AMOSTRAGEM Tipo de amostragem, veja\n" " --format=FORMATO_DE_AMOSTRAGEM Formato da amostragem, veja\n"
" https://www.freedesktop.org/wiki/" " https://www.freedesktop.org/wiki/"
"Software/PulseAudio/Documentation/User/SupportedAudioFormats/\n" "Software/PulseAudio/Documentation/User/SupportedAudioFormats/\n"
" para valores possíveis (padrão: " " para valores possíveis (padrão: "
"s16ne)\n" "s16ne)\n"
" --channels=CANAIS O número de canais, 1 para mono,\n" " --channels=CANAIS O número de canais, 1 para mono, 2 "
" 2 para estéreo (padrão: 2)\n" "para estéreo\n"
" --channel-map=MAPA_DE_CANAIS Mapeamento de canais a ser usado no\n" " (padrão: 2)\n"
" lugar do padrão\n" " --channel-map=MAPA_DE_CANAIS Mapeamento de canais para usar em "
" --fix-format Obtém o formato da amostragem do\n" "vez do padrão\n"
" destino/fonte onde o fluxo está\n" " --fix-format Obtém o formato da amostragem do "
" sendo conectado.\n" "destino/fonte onde\n"
" --fix-rate Obtém a taxa de amostragem do\n" " o fluxo está sendo conectado.\n"
" destino/fonte onde o fluxo está\n" " --fix-rate Obtém a taxa de amostragem do "
" sendo conectado.\n" "destino/fonte onde\n"
" --fix-channels Obtém o número de canais e o mapa " " o fluxo está sendo conectado.\n"
"de\n" " --fix-channels Obtém o número de canais e o mapa de "
" canais do destino onde o fluxo está\n" "canais do destino\n"
" sendo conectado.\n" " onde o fluxo está sendo conectado.\n"
" --no-remix Não faz upmix nem downmix dos " " --no-remix Não faz upmix nem downmix dos canais."
"canais.\n" "\n"
" --no-remap Mapeia os canais por índice em vez\n" " --no-remap Mapeia os canais por índice em vez "
" de nome\n" "de nome.\n"
" --latency=BYTES Requisita a latência especificada " " --latency=BYTES Requisita a latência especificada em "
"em\n"
" bytes.\n"
" --process-time=BYTES Requisita o tempo de processo\n"
" especificado por requisições em "
"bytes.\n" "bytes.\n"
" --latency-msec=MSEGUNDOS Requisita a latência especificada " " --process-time=BYTES Requisita o tempo de processo por "
"em\n" "requisições em bytes.\n"
" milissegundos.\n" " --latency-msec=MSEGUNDOS Requisita a latência especificada em "
" --process-time-msec=MSEGUNDOS Requisita a o tempo do processo por\n" "milissegundos.\n"
" requisição em milissegundos.\n" " --process-time-msec=MSEGUNDOS Requisita o tempo de processo por "
"requisições em milissegundos.\n"
" --property=PROPRIEDADE=VALOR Define a propriedade especificada " " --property=PROPRIEDADE=VALOR Define a propriedade especificada "
"para\n" "para o valor especificado.\n"
" o valor especificado.\n"
" --raw Grava/reproduz dados PCM não " " --raw Grava/reproduz dados PCM não "
"tratados.\n" "tratados.\n"
" --passthrough Dados para conversão.\n" " --passthrough Dados para conversão.\n"
" --file-format[=FORMATO_ARQUIVO] Grava/reproduz dados PCM " " --file-format[=FORMATO_ARQUIVO] Grava/reproduz dados PCM formatados."
"formatados.\n" "\n"
" --list-file-formats Lista formatos de arquivo " " --list-file-formats Lista formatos de arquivo "
"disponíveis.\n" "disponíveis.\n"
" --monitor-stream=ÍNDICE Grava da entrada do destino com " " --monitor-stream=ÍNDICE Grava da entrada do destino com "
"índice.\n" "índice ÍNDICE.\n"
#: src/utils/pacat.c:793 #: src/utils/pacat.c:793
msgid "Play back encoded audio files on a PulseAudio sound server." msgid "Play back encoded audio files on a PulseAudio sound server."
@ -2875,11 +2871,12 @@ msgstr "mensagem list-handlers falhou: %s"
#: src/utils/pactl.c:1711 src/utils/pactl.c:1760 #: src/utils/pactl.c:1711 src/utils/pactl.c:1760
msgid "list-handlers message response could not be parsed correctly" msgid "list-handlers message response could not be parsed correctly"
msgstr "a resposta da mensagem list-handlers não pôde ser tratada corretamente" msgstr ""
"a resposta da mensagem de list-handlers não pôde ser tratada corretamente"
#: src/utils/pactl.c:1718 #: src/utils/pactl.c:1718
msgid "list-handlers message response is not a JSON array" msgid "list-handlers message response is not a JSON array"
msgstr "a resposta da mensagem list-handlers não é um array JSON" msgstr "a resposta da mensagem de list-handlers não é um array JSON"
#: src/utils/pactl.c:1729 #: src/utils/pactl.c:1729
#, c-format #, c-format
@ -3051,7 +3048,7 @@ msgstr ""
"padrão.\n" "padrão.\n"
#: src/utils/pactl.c:2664 #: src/utils/pactl.c:2664
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"\n" "\n"
" -h, --help Show this help\n" " -h, --help Show this help\n"
@ -3068,7 +3065,9 @@ msgstr ""
" -h, --help Mostra esta ajuda\n" " -h, --help Mostra esta ajuda\n"
" --version Mostra a versão\n" " --version Mostra a versão\n"
"\n" "\n"
" -s, --server=SERVIDOR Nome do servidor a ser conectado\n" " -f, --format=FORMATO O formato da saída. \"normal\" ou "
"\"json\"\n"
" -s, --server=SERVIDOR Nome do servidor para se conectar\n"
" -n, --client-name=NOME Como chamar este cliente no " " -n, --client-name=NOME Como chamar este cliente no "
"servidor\n" "servidor\n"
@ -3084,9 +3083,9 @@ msgstr ""
"Vinculado com libpulse %s\n" "Vinculado com libpulse %s\n"
#: src/utils/pactl.c:2751 #: src/utils/pactl.c:2751
#, fuzzy, c-format #, c-format
msgid "Invalid format value '%s'" msgid "Invalid format value '%s'"
msgstr "Nome do fluxo “%s” inválido" msgstr "Valor de formato “%s” inválido"
#: src/utils/pactl.c:2778 #: src/utils/pactl.c:2778
#, c-format #, c-format

View file

@ -9,7 +9,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2025-02-23 20:53+0000\n" "PO-Revision-Date: 2025-05-11 11:49+0000\n"
"Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n" "Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n"
"Language-Team: Romanian <https://translate.fedoraproject.org/projects/" "Language-Team: Romanian <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/ro/>\n" "pulseaudio/pulseaudio/ro/>\n"
@ -19,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
"20)) ? 1 : 2;\n" "20)) ? 1 : 2;\n"
"X-Generator: Weblate 5.10\n" "X-Generator: Weblate 5.11.3\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -502,7 +502,7 @@ msgstr ""
#: src/daemon/main.c:922 #: src/daemon/main.c:922
msgid "Failed to acquire stdio." msgid "Failed to acquire stdio."
msgstr "Nu s-a reușit să se achizționeze stdio." msgstr "Nu s-a reușit să se achiziționeze stdio."
#: src/daemon/main.c:928 src/daemon/main.c:999 #: src/daemon/main.c:928 src/daemon/main.c:999
#, c-format #, c-format
@ -2135,7 +2135,7 @@ msgstr "Nu s-a putut determina specificația eșantionului din fișier."
#: src/utils/pacat.c:1100 #: src/utils/pacat.c:1100
msgid "Warning: Failed to determine channel map from file." msgid "Warning: Failed to determine channel map from file."
msgstr "Avertisment: Nu s-a reușit determinarea schemei canalelor din fișier." msgstr "Avertisment: Nu s-a reușit să se determine schema canalelor din fișier."
#: src/utils/pacat.c:1111 #: src/utils/pacat.c:1111
msgid "Channel map doesn't match sample specification" msgid "Channel map doesn't match sample specification"

View file

@ -10,8 +10,8 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2023-09-12 13:35+0000\n" "PO-Revision-Date: 2025-05-11 00:38+0000\n"
"Last-Translator: \"Sergey A.\" <sw@atrus.ru>\n" "Last-Translator: \"Sergey A.\" <Ser82-png@yandex.ru>\n"
"Language-Team: Russian <https://translate.fedoraproject.org/projects/" "Language-Team: Russian <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/ru/>\n" "pulseaudio/pulseaudio/ru/>\n"
"Language: ru\n" "Language: ru\n"
@ -20,7 +20,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.0.1\n" "X-Generator: Weblate 5.11.3\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -397,7 +397,7 @@ msgstr ""
#: src/daemon/ltdl-bind-now.c:144 #: src/daemon/ltdl-bind-now.c:144
msgid "Failed to add bind-now-loader." msgid "Failed to add bind-now-loader."
msgstr "Не удалось добавить новый загрузчик bind-now." msgstr "Не удалось добавить bind-now-loader."
#: src/daemon/main.c:265 #: src/daemon/main.c:265
#, c-format #, c-format

View file

@ -9,7 +9,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues/new\n" "issues/new\n"
"POT-Creation-Date: 2022-06-18 09:49+0300\n" "POT-Creation-Date: 2022-06-18 09:49+0300\n"
"PO-Revision-Date: 2024-08-17 18:38+0000\n" "PO-Revision-Date: 2025-07-25 04:53+0000\n"
"Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n" "Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n"
"Language-Team: Slovenian <https://translate.fedoraproject.org/projects/" "Language-Team: Slovenian <https://translate.fedoraproject.org/projects/"
"pulseaudio/pulseaudio/sl/>\n" "pulseaudio/pulseaudio/sl/>\n"
@ -19,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
"n%100==4 ? 2 : 3;\n" "n%100==4 ? 2 : 3;\n"
"X-Generator: Weblate 5.6.2\n" "X-Generator: Weblate 5.12.2\n"
#: src/daemon/cmdline.c:113 #: src/daemon/cmdline.c:113
#, c-format #, c-format
@ -447,7 +447,7 @@ msgstr "Ni uspelo ubiti zalednega procesa: %s"
#: src/daemon/main.c:817 #: src/daemon/main.c:817
msgid "This program is not intended to be run as root (unless --system is specified)." msgid "This program is not intended to be run as root (unless --system is specified)."
msgstr "Ta program ni namenjen zagonu kot root (razen če je določeno --sistem)." msgstr "Ta program ni namenjen zagonu kot root (razen če je določeno --system)."
#: src/daemon/main.c:820 #: src/daemon/main.c:820
msgid "Root privileges required." msgid "Root privileges required."
@ -1526,7 +1526,7 @@ msgid ""
"happen if you try to connect to a non-root PulseAudio as a root user, over the native " "happen if you try to connect to a non-root PulseAudio as a root user, over the native "
"protocol. Don't do that.)" "protocol. Don't do that.)"
msgstr "" msgstr ""
"XDG_RUNTIME_DIR (%s) ni v naši lasti (uiid %d), ampak v lasti uid %d (to se " "XDG_RUNTIME_DIR (%s) ni v naši lasti (uid %d), ampak v lasti uid %d (to se "
"lahko npr. zgodi, če se poskušate povezati z nekorenskim PulseAudio kot " "lahko npr. zgodi, če se poskušate povezati z nekorenskim PulseAudio kot "
"korenski uporabnik prek izvornega protokola; ne počnite tega)!" "korenski uporabnik prek izvornega protokola; ne počnite tega)!"
@ -1966,7 +1966,7 @@ msgstr ""
"uporabiti namesto privzete\n" "uporabiti namesto privzete\n"
" --fix-format Vzemite obliko vzorca iz ponora/" " --fix-format Vzemite obliko vzorca iz ponora/"
"vira, s katerim je tok povezan.\n" "vira, s katerim je tok povezan.\n"
" fix-rate Hitrost vzorčenja vzemite iz ponora/" " --fix-rate Hitrost vzorčenja vzemite iz ponora/"
"vira, s katerim je tok povezan.\n" "vira, s katerim je tok povezan.\n"
" --fix-channels Vzame število kanalov in preslikavo " " --fix-channels Vzame število kanalov in preslikavo "
"kanalov\n" "kanalov\n"

View file

@ -9,9 +9,15 @@
add_languages('cpp') add_languages('cpp')
libwebrtc_util_sources = [ if cdata.has('HAVE_WEBRTC1')
'webrtc.cc' libwebrtc_util_sources = [
] 'webrtc.cc'
]
else
libwebrtc_util_sources = [
'webrtc-old.cc'
]
endif
if host_machine.system() == 'darwin' if host_machine.system() == 'darwin'
ignore_unresolved_symbols_link_args = ['-Wl,-undefined,dynamic_lookup'] ignore_unresolved_symbols_link_args = ['-Wl,-undefined,dynamic_lookup']

View file

@ -0,0 +1,594 @@
/***
This file is part of PulseAudio.
Copyright 2011 Collabora Ltd.
2015 Aldebaran SoftBank Group
Contributor: Arun Raghavan <mail@arunraghavan.net>
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulse/cdecl.h>
PA_C_DECL_BEGIN
#include <pulsecore/core-util.h>
#include <pulsecore/modargs.h>
#include <pulse/timeval.h>
#include "echo-cancel.h"
PA_C_DECL_END
#include <webrtc/modules/audio_processing/include/audio_processing.h>
#include <webrtc/modules/interface/module_common_types.h>
#include <webrtc/system_wrappers/include/trace.h>
#define BLOCK_SIZE_US 10000
#define DEFAULT_HIGH_PASS_FILTER true
#define DEFAULT_NOISE_SUPPRESSION true
#define DEFAULT_ANALOG_GAIN_CONTROL true
#define DEFAULT_DIGITAL_GAIN_CONTROL false
#define DEFAULT_MOBILE false
#define DEFAULT_ROUTING_MODE "speakerphone"
#define DEFAULT_COMFORT_NOISE true
#define DEFAULT_DRIFT_COMPENSATION false
#define DEFAULT_VAD true
#define DEFAULT_EXTENDED_FILTER false
#define DEFAULT_INTELLIGIBILITY_ENHANCER false
#define DEFAULT_EXPERIMENTAL_AGC false
#define DEFAULT_AGC_START_VOLUME 85
#define DEFAULT_BEAMFORMING false
#define DEFAULT_TRACE false
#define WEBRTC_AGC_MAX_VOLUME 255
static const char* const valid_modargs[] = {
"high_pass_filter",
"noise_suppression",
"analog_gain_control",
"digital_gain_control",
"mobile",
"routing_mode",
"comfort_noise",
"drift_compensation",
"voice_detection",
"extended_filter",
"intelligibility_enhancer",
"experimental_agc",
"agc_start_volume",
"beamforming",
"mic_geometry", /* documented in parse_mic_geometry() */
"target_direction", /* documented in parse_mic_geometry() */
"trace",
NULL
};
static int routing_mode_from_string(const char *rmode) {
if (pa_streq(rmode, "quiet-earpiece-or-headset"))
return webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
else if (pa_streq(rmode, "earpiece"))
return webrtc::EchoControlMobile::kEarpiece;
else if (pa_streq(rmode, "loud-earpiece"))
return webrtc::EchoControlMobile::kLoudEarpiece;
else if (pa_streq(rmode, "speakerphone"))
return webrtc::EchoControlMobile::kSpeakerphone;
else if (pa_streq(rmode, "loud-speakerphone"))
return webrtc::EchoControlMobile::kLoudSpeakerphone;
else
return -1;
}
class PaWebrtcTraceCallback : public webrtc::TraceCallback {
void Print(webrtc::TraceLevel level, const char *message, int length)
{
if (level & webrtc::kTraceError || level & webrtc::kTraceCritical)
pa_log("%s", message);
else if (level & webrtc::kTraceWarning)
pa_log_warn("%s", message);
else if (level & webrtc::kTraceInfo)
pa_log_info("%s", message);
else
pa_log_debug("%s", message);
}
};
static int webrtc_volume_from_pa(pa_volume_t v)
{
return (v * WEBRTC_AGC_MAX_VOLUME) / PA_VOLUME_NORM;
}
static pa_volume_t webrtc_volume_to_pa(int v)
{
return (v * PA_VOLUME_NORM) / WEBRTC_AGC_MAX_VOLUME;
}
static void webrtc_ec_fixate_spec(pa_sample_spec *rec_ss, pa_channel_map *rec_map,
pa_sample_spec *play_ss, pa_channel_map *play_map,
pa_sample_spec *out_ss, pa_channel_map *out_map,
bool beamforming)
{
rec_ss->format = PA_SAMPLE_FLOAT32NE;
play_ss->format = PA_SAMPLE_FLOAT32NE;
/* AudioProcessing expects one of the following rates */
if (rec_ss->rate >= 48000)
rec_ss->rate = 48000;
else if (rec_ss->rate >= 32000)
rec_ss->rate = 32000;
else if (rec_ss->rate >= 16000)
rec_ss->rate = 16000;
else
rec_ss->rate = 8000;
*out_ss = *rec_ss;
*out_map = *rec_map;
if (beamforming) {
/* The beamformer gives us a single channel */
out_ss->channels = 1;
pa_channel_map_init_mono(out_map);
}
/* Playback stream rate needs to be the same as capture */
play_ss->rate = rec_ss->rate;
}
static bool parse_point(const char **point, float (&f)[3]) {
int ret, length;
ret = sscanf(*point, "%g,%g,%g%n", &f[0], &f[1], &f[2], &length);
if (ret != 3)
return false;
/* Consume the bytes we've read so far */
*point += length;
return true;
}
static bool parse_mic_geometry(const char **mic_geometry, std::vector<webrtc::Point>& geometry) {
/* The microphone geometry is expressed as cartesian point form:
* x1,y1,z1,x2,y2,z2,...
*
* Where x1,y1,z1 is the position of the first microphone with regards to
* the array's "center", x2,y2,z2 the position of the second, and so on.
*
* 'x' is the horizontal coordinate, with positive values being to the
* right from the mic array's perspective.
*
* 'y' is the depth coordinate, with positive values being in front of the
* array.
*
* 'z' is the vertical coordinate, with positive values being above the
* array.
*
* All distances are in meters.
*/
/* The target direction is expected to be in spherical point form:
* a,e,r
*
* Where 'a' is the azimuth of the target point relative to the center of
* the array, 'e' its elevation, and 'r' the radius.
*
* 0 radians azimuth is to the right of the array, and positive angles
* move in a counter-clockwise direction.
*
* 0 radians elevation is horizontal w.r.t. the array, and positive
* angles go upwards.
*
* radius is distance from the array center in meters.
*/
long unsigned int i;
float f[3];
for (i = 0; i < geometry.size(); i++) {
if (!parse_point(mic_geometry, f)) {
pa_log("Failed to parse channel %lu in mic_geometry", i);
return false;
}
/* Except for the last point, we should have a trailing comma */
if (i != geometry.size() - 1) {
if (**mic_geometry != ',') {
pa_log("Failed to parse channel %lu in mic_geometry", i);
return false;
}
(*mic_geometry)++;
}
pa_log_debug("Got mic #%lu position: (%g, %g, %g)", i, f[0], f[1], f[2]);
geometry[i].c[0] = f[0];
geometry[i].c[1] = f[1];
geometry[i].c[2] = f[2];
}
if (**mic_geometry != '\0') {
pa_log("Failed to parse mic_geometry value: more parameters than expected");
return false;
}
return true;
}
bool pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
pa_sample_spec *rec_ss, pa_channel_map *rec_map,
pa_sample_spec *play_ss, pa_channel_map *play_map,
pa_sample_spec *out_ss, pa_channel_map *out_map,
uint32_t *nframes, const char *args) {
webrtc::AudioProcessing *apm = NULL;
webrtc::ProcessingConfig pconfig;
webrtc::Config config;
bool hpf, ns, agc, dgc, mobile, cn, vad, ext_filter, intelligibility, experimental_agc, beamforming;
int rm = -1, i;
uint32_t agc_start_volume;
pa_modargs *ma;
bool trace = false;
if (!(ma = pa_modargs_new(args, valid_modargs))) {
pa_log("Failed to parse submodule arguments.");
goto fail;
}
hpf = DEFAULT_HIGH_PASS_FILTER;
if (pa_modargs_get_value_boolean(ma, "high_pass_filter", &hpf) < 0) {
pa_log("Failed to parse high_pass_filter value");
goto fail;
}
ns = DEFAULT_NOISE_SUPPRESSION;
if (pa_modargs_get_value_boolean(ma, "noise_suppression", &ns) < 0) {
pa_log("Failed to parse noise_suppression value");
goto fail;
}
agc = DEFAULT_ANALOG_GAIN_CONTROL;
if (pa_modargs_get_value_boolean(ma, "analog_gain_control", &agc) < 0) {
pa_log("Failed to parse analog_gain_control value");
goto fail;
}
dgc = agc ? false : DEFAULT_DIGITAL_GAIN_CONTROL;
if (pa_modargs_get_value_boolean(ma, "digital_gain_control", &dgc) < 0) {
pa_log("Failed to parse digital_gain_control value");
goto fail;
}
if (agc && dgc) {
pa_log("You must pick only one between analog and digital gain control");
goto fail;
}
mobile = DEFAULT_MOBILE;
if (pa_modargs_get_value_boolean(ma, "mobile", &mobile) < 0) {
pa_log("Failed to parse mobile value");
goto fail;
}
ec->params.drift_compensation = DEFAULT_DRIFT_COMPENSATION;
if (pa_modargs_get_value_boolean(ma, "drift_compensation", &ec->params.drift_compensation) < 0) {
pa_log("Failed to parse drift_compensation value");
goto fail;
}
if (mobile) {
if (ec->params.drift_compensation) {
pa_log("Can't use drift_compensation in mobile mode");
goto fail;
}
if ((rm = routing_mode_from_string(pa_modargs_get_value(ma, "routing_mode", DEFAULT_ROUTING_MODE))) < 0) {
pa_log("Failed to parse routing_mode value");
goto fail;
}
cn = DEFAULT_COMFORT_NOISE;
if (pa_modargs_get_value_boolean(ma, "comfort_noise", &cn) < 0) {
pa_log("Failed to parse cn value");
goto fail;
}
} else {
if (pa_modargs_get_value(ma, "comfort_noise", NULL) || pa_modargs_get_value(ma, "routing_mode", NULL)) {
pa_log("The routing_mode and comfort_noise options are only valid with mobile=true");
goto fail;
}
}
vad = DEFAULT_VAD;
if (pa_modargs_get_value_boolean(ma, "voice_detection", &vad) < 0) {
pa_log("Failed to parse voice_detection value");
goto fail;
}
ext_filter = DEFAULT_EXTENDED_FILTER;
if (pa_modargs_get_value_boolean(ma, "extended_filter", &ext_filter) < 0) {
pa_log("Failed to parse extended_filter value");
goto fail;
}
intelligibility = DEFAULT_INTELLIGIBILITY_ENHANCER;
if (pa_modargs_get_value_boolean(ma, "intelligibility_enhancer", &intelligibility) < 0) {
pa_log("Failed to parse intelligibility_enhancer value");
goto fail;
}
experimental_agc = DEFAULT_EXPERIMENTAL_AGC;
if (pa_modargs_get_value_boolean(ma, "experimental_agc", &experimental_agc) < 0) {
pa_log("Failed to parse experimental_agc value");
goto fail;
}
agc_start_volume = DEFAULT_AGC_START_VOLUME;
if (pa_modargs_get_value_u32(ma, "agc_start_volume", &agc_start_volume) < 0) {
pa_log("Failed to parse agc_start_volume value");
goto fail;
}
if (agc_start_volume > WEBRTC_AGC_MAX_VOLUME) {
pa_log("AGC start volume must not exceed %u", WEBRTC_AGC_MAX_VOLUME);
goto fail;
}
ec->params.webrtc.agc_start_volume = agc_start_volume;
beamforming = DEFAULT_BEAMFORMING;
if (pa_modargs_get_value_boolean(ma, "beamforming", &beamforming) < 0) {
pa_log("Failed to parse beamforming value");
goto fail;
}
if (ext_filter)
config.Set<webrtc::ExtendedFilter>(new webrtc::ExtendedFilter(true));
if (intelligibility)
pa_log_warn("The intelligibility enhancer is not currently supported");
if (experimental_agc)
config.Set<webrtc::ExperimentalAgc>(new webrtc::ExperimentalAgc(true, ec->params.webrtc.agc_start_volume));
trace = DEFAULT_TRACE;
if (pa_modargs_get_value_boolean(ma, "trace", &trace) < 0) {
pa_log("Failed to parse trace value");
goto fail;
}
if (trace) {
webrtc::Trace::CreateTrace();
webrtc::Trace::set_level_filter(webrtc::kTraceAll);
ec->params.webrtc.trace_callback = new PaWebrtcTraceCallback();
webrtc::Trace::SetTraceCallback((PaWebrtcTraceCallback *) ec->params.webrtc.trace_callback);
}
webrtc_ec_fixate_spec(rec_ss, rec_map, play_ss, play_map, out_ss, out_map, beamforming);
/* We do this after fixate because we need the capture channel count */
if (beamforming) {
std::vector<webrtc::Point> geometry(rec_ss->channels);
webrtc::SphericalPointf direction(0.0f, 0.0f, 0.0f);
const char *mic_geometry, *target_direction;
if (!(mic_geometry = pa_modargs_get_value(ma, "mic_geometry", NULL))) {
pa_log("mic_geometry must be set if beamforming is enabled");
goto fail;
}
if (!parse_mic_geometry(&mic_geometry, geometry)) {
pa_log("Failed to parse mic_geometry value");
goto fail;
}
if ((target_direction = pa_modargs_get_value(ma, "target_direction", NULL))) {
float f[3];
if (!parse_point(&target_direction, f)) {
pa_log("Failed to parse target_direction value");
goto fail;
}
if (*target_direction != '\0') {
pa_log("Failed to parse target_direction value: more parameters than expected");
goto fail;
}
#define IS_ZERO(f) ((f) < 0.000001 && (f) > -0.000001)
if (!IS_ZERO(f[1]) || !IS_ZERO(f[2])) {
pa_log("The beamformer currently only supports targeting along the azimuth");
goto fail;
}
direction.s[0] = f[0];
direction.s[1] = f[1];
direction.s[2] = f[2];
}
if (!target_direction)
config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
else
config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry, direction));
}
apm = webrtc::AudioProcessing::Create(config);
pconfig = {
webrtc::StreamConfig(rec_ss->rate, rec_ss->channels, false), /* input stream */
webrtc::StreamConfig(out_ss->rate, out_ss->channels, false), /* output stream */
webrtc::StreamConfig(play_ss->rate, play_ss->channels, false), /* reverse input stream */
webrtc::StreamConfig(play_ss->rate, play_ss->channels, false), /* reverse output stream */
};
if (apm->Initialize(pconfig) != webrtc::AudioProcessing::kNoError) {
pa_log("Error initialising audio processing module");
goto fail;
}
if (hpf)
apm->high_pass_filter()->Enable(true);
if (!mobile) {
apm->echo_cancellation()->enable_drift_compensation(ec->params.drift_compensation);
apm->echo_cancellation()->Enable(true);
} else {
apm->echo_control_mobile()->set_routing_mode(static_cast<webrtc::EchoControlMobile::RoutingMode>(rm));
apm->echo_control_mobile()->enable_comfort_noise(cn);
apm->echo_control_mobile()->Enable(true);
}
if (ns) {
apm->noise_suppression()->set_level(webrtc::NoiseSuppression::kHigh);
apm->noise_suppression()->Enable(true);
}
if (agc || dgc) {
if (mobile && rm <= webrtc::EchoControlMobile::kEarpiece) {
/* Maybe this should be a knob, but we've got a lot of knobs already */
apm->gain_control()->set_mode(webrtc::GainControl::kFixedDigital);
ec->params.webrtc.agc = false;
} else if (dgc) {
apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveDigital);
ec->params.webrtc.agc = false;
} else {
apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveAnalog);
if (apm->gain_control()->set_analog_level_limits(0, WEBRTC_AGC_MAX_VOLUME) !=
webrtc::AudioProcessing::kNoError) {
pa_log("Failed to initialise AGC");
goto fail;
}
ec->params.webrtc.agc = true;
}
apm->gain_control()->Enable(true);
}
if (vad)
apm->voice_detection()->Enable(true);
ec->params.webrtc.apm = apm;
ec->params.webrtc.rec_ss = *rec_ss;
ec->params.webrtc.play_ss = *play_ss;
ec->params.webrtc.out_ss = *out_ss;
ec->params.webrtc.blocksize = (uint64_t) out_ss->rate * BLOCK_SIZE_US / PA_USEC_PER_SEC;
*nframes = ec->params.webrtc.blocksize;
ec->params.webrtc.first = true;
for (i = 0; i < rec_ss->channels; i++)
ec->params.webrtc.rec_buffer[i] = pa_xnew(float, *nframes);
for (i = 0; i < play_ss->channels; i++)
ec->params.webrtc.play_buffer[i] = pa_xnew(float, *nframes);
pa_modargs_free(ma);
return true;
fail:
if (ma)
pa_modargs_free(ma);
if (ec->params.webrtc.trace_callback) {
webrtc::Trace::ReturnTrace();
delete ((PaWebrtcTraceCallback *) ec->params.webrtc.trace_callback);
} if (apm)
delete apm;
return false;
}
void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play) {
webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
const pa_sample_spec *ss = &ec->params.webrtc.play_ss;
int n = ec->params.webrtc.blocksize;
float **buf = ec->params.webrtc.play_buffer;
webrtc::StreamConfig config(ss->rate, ss->channels, false);
pa_deinterleave(play, (void **) buf, ss->channels, pa_sample_size(ss), n);
pa_assert_se(apm->ProcessReverseStream(buf, config, config, buf) == webrtc::AudioProcessing::kNoError);
/* FIXME: If ProcessReverseStream() makes any changes to the audio, such as
* applying intelligibility enhancement, those changes don't have any
* effect. This function is called at the source side, but the processing
* would have to be done in the sink to be able to feed the processed audio
* to speakers. */
}
void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out) {
webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
const pa_sample_spec *rec_ss = &ec->params.webrtc.rec_ss;
const pa_sample_spec *out_ss = &ec->params.webrtc.out_ss;
float **buf = ec->params.webrtc.rec_buffer;
int n = ec->params.webrtc.blocksize;
int old_volume, new_volume;
webrtc::StreamConfig rec_config(rec_ss->rate, rec_ss->channels, false);
webrtc::StreamConfig out_config(out_ss->rate, out_ss->channels, false);
pa_deinterleave(rec, (void **) buf, rec_ss->channels, pa_sample_size(rec_ss), n);
if (ec->params.webrtc.agc) {
pa_volume_t v = pa_echo_canceller_get_capture_volume(ec);
old_volume = webrtc_volume_from_pa(v);
apm->gain_control()->set_stream_analog_level(old_volume);
}
apm->set_stream_delay_ms(0);
pa_assert_se(apm->ProcessStream(buf, rec_config, out_config, buf) == webrtc::AudioProcessing::kNoError);
if (ec->params.webrtc.agc) {
if (PA_UNLIKELY(ec->params.webrtc.first)) {
/* We start at a sane default volume (taken from the Chromium
* condition on the experimental AGC in audio_processing.h). This is
* needed to make sure that there's enough energy in the capture
* signal for the AGC to work */
ec->params.webrtc.first = false;
new_volume = ec->params.webrtc.agc_start_volume;
} else {
new_volume = apm->gain_control()->stream_analog_level();
}
if (old_volume != new_volume)
pa_echo_canceller_set_capture_volume(ec, webrtc_volume_to_pa(new_volume));
}
pa_interleave((const void **) buf, out_ss->channels, out, pa_sample_size(out_ss), n);
}
void pa_webrtc_ec_set_drift(pa_echo_canceller *ec, float drift) {
webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.webrtc.apm;
apm->echo_cancellation()->set_stream_drift_samples(drift * ec->params.webrtc.blocksize);
}
void pa_webrtc_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
pa_webrtc_ec_play(ec, play);
pa_webrtc_ec_record(ec, rec, out);
}
void pa_webrtc_ec_done(pa_echo_canceller *ec) {
int i;
if (ec->params.webrtc.trace_callback) {
webrtc::Trace::ReturnTrace();
delete ((PaWebrtcTraceCallback *) ec->params.webrtc.trace_callback);
}
if (ec->params.webrtc.apm) {
delete (webrtc::AudioProcessing*)ec->params.webrtc.apm;
ec->params.webrtc.apm = NULL;
}
for (i = 0; i < ec->params.webrtc.rec_ss.channels; i++)
pa_xfree(ec->params.webrtc.rec_buffer[i]);
for (i = 0; i < ec->params.webrtc.play_ss.channels; i++)
pa_xfree(ec->params.webrtc.play_buffer[i]);
}

View file

@ -1841,8 +1841,18 @@ static void get_sink_mute_callback(pa_context *c, const pa_sink_info *i, int is_
pa_assert(i); pa_assert(i);
printf(("Mute: %s\n"), if (format == JSON) {
pa_yes_no_localised(i->mute)); pa_json_encoder *encoder = pa_json_encoder_new();
pa_json_encoder_begin_element_object(encoder);
pa_json_encoder_add_member_bool(encoder, "mute", i->mute);
pa_json_encoder_end_object(encoder);
char* json_str = pa_json_encoder_to_string_free(encoder);
printf("%s\n", json_str);
pa_xfree(json_str);
} else {
printf(("Mute: %s\n"),
pa_yes_no_localised(i->mute));
}
complete_action(); complete_action();
} }
@ -1860,10 +1870,21 @@ static void get_sink_volume_callback(pa_context *c, const pa_sink_info *i, int i
pa_assert(i); pa_assert(i);
char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
printf(("Volume: %s\n" if (format == JSON) {
" balance %0.2f\n"), pa_json_encoder *encoder = pa_json_encoder_new();
pa_cvolume_snprint_verbose(cv, sizeof(cv), &i->volume, &i->channel_map, true), pa_json_encoder_begin_element_object(encoder);
pa_cvolume_get_balance(&i->volume, &i->channel_map)); pa_json_encoder_add_member_raw_json(encoder, "volume", pa_cvolume_to_json_object(&i->volume, &i->channel_map, i->flags & PA_SINK_DECIBEL_VOLUME));
pa_json_encoder_add_member_double(encoder, "balance", pa_cvolume_get_balance(&i->volume, &i->channel_map), 2);
pa_json_encoder_end_object(encoder);
char* json_str = pa_json_encoder_to_string_free(encoder);
printf("%s\n", json_str);
pa_xfree(json_str);
} else {
printf(("Volume: %s\n"
" balance %0.2f\n"),
pa_cvolume_snprint_verbose(cv, sizeof(cv), &i->volume, &i->channel_map, true),
pa_cvolume_get_balance(&i->volume, &i->channel_map));
}
complete_action(); complete_action();
} }
@ -1907,8 +1928,18 @@ static void get_source_mute_callback(pa_context *c, const pa_source_info *i, int
pa_assert(i); pa_assert(i);
printf(("Mute: %s\n"), if (format == JSON) {
pa_yes_no_localised(i->mute)); pa_json_encoder *encoder = pa_json_encoder_new();
pa_json_encoder_begin_element_object(encoder);
pa_json_encoder_add_member_bool(encoder, "mute", i->mute);
pa_json_encoder_end_object(encoder);
char* json_str = pa_json_encoder_to_string_free(encoder);
printf("%s\n", json_str);
pa_xfree(json_str);
} else {
printf(("Mute: %s\n"),
pa_yes_no_localised(i->mute));
}
complete_action(); complete_action();
} }
@ -1926,10 +1957,21 @@ static void get_source_volume_callback(pa_context *c, const pa_source_info *i, i
pa_assert(i); pa_assert(i);
char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
printf(("Volume: %s\n" if (format == JSON) {
" balance %0.2f\n"), pa_json_encoder *encoder = pa_json_encoder_new();
pa_cvolume_snprint_verbose(cv, sizeof(cv), &i->volume, &i->channel_map, true), pa_json_encoder_begin_element_object(encoder);
pa_cvolume_get_balance(&i->volume, &i->channel_map)); pa_json_encoder_add_member_raw_json(encoder, "volume", pa_cvolume_to_json_object(&i->volume, &i->channel_map, i->flags & PA_SINK_DECIBEL_VOLUME));
pa_json_encoder_add_member_double(encoder, "balance", pa_cvolume_get_balance(&i->volume, &i->channel_map), 2);
pa_json_encoder_end_object(encoder);
char* json_str = pa_json_encoder_to_string_free(encoder);
printf("%s\n", json_str);
pa_xfree(json_str);
} else {
printf(("Volume: %s\n"
" balance %0.2f\n"),
pa_cvolume_snprint_verbose(cv, sizeof(cv), &i->volume, &i->channel_map, true),
pa_cvolume_get_balance(&i->volume, &i->channel_map));
}
complete_action(); complete_action();
} }