diff options
73 files changed, 3890 insertions, 1689 deletions
diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..0b99ec63 --- /dev/null +++ b/.mailmap @@ -0,0 +1,7 @@ +Diego Elio Pettenò <flameeyes@gmail.com> +Lennart Poettering <mzfuryy@0pointer.net> +Lennart Poettering <lennart@poettering.net> +Russ Dill <Russ.Dill@asu.edu> +Russ Dill <russ.dill@gmail.com> +Sjoerd Simons <sjoerd@luon.net> +Sjoerd Simons <sjoerd@debian.org> diff --git a/configure.ac b/configure.ac index 18d7cd91..48520496 100644 --- a/configure.ac +++ b/configure.ac @@ -26,11 +26,11 @@ m4_define(pa_major, [0]) m4_define(pa_minor, [9]) m4_define(pa_micro, [15]) -AC_INIT([pulseaudio],[pa_major.pa_minor.pa_micro],[mzchyfrnhqvb (at) 0pointer (dot) net]) +AC_INIT([pulseaudio],[pa_major.pa_minor.pa_micro-test1],[mzchyfrnhqvb (at) 0pointer (dot) net]) AC_CONFIG_SRCDIR([src/daemon/main.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) -AM_INIT_AUTOMAKE([foreign 1.10 -Wall]) +AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Wno-portability]) AC_SUBST(PA_MAJOR, pa_major) AC_SUBST(PA_MINOR, pa_minor) @@ -44,7 +44,7 @@ AC_SUBST(PA_PROTOCOL_VERSION, 15) # The stable ABI for client applications, for the version info x:y:z # always will hold y=z -AC_SUBST(LIBPULSE_VERSION_INFO, [7:1:7]) +AC_SUBST(LIBPULSE_VERSION_INFO, [8:0:8]) # A simplified, synchronous, ABI-stable interface for client # applications, for the version info x:y:z always will hold y=z @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-08 01:48+0000\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2009-01-31 06:12+0100\n" "Last-Translator: Agustí Grau <fletxa@gmail.com>\n" "Language-Team: Catalan <fedora@softcatala.net>\n" @@ -27,15 +27,20 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/daemon/ltdl-bind-now.c:177 -#: ../src/daemon/ltdl-bind-now.c:197 -msgid "Failed to add bind-now-loader." -msgstr "S'ha produït un error en afegir bind-now-loader." +#: ../src/daemon/ltdl-bind-now.c:124 +#, fuzzy +msgid "Failed to find original lt_dlopen loader." +msgstr "No s'ha trobat el carregador dlopen original." -#: ../src/daemon/ltdl-bind-now.c:184 -msgid "Failed to find original dlopen loader." +#: ../src/daemon/ltdl-bind-now.c:129 +#, fuzzy +msgid "Failed to allocate new dl loader." msgstr "No s'ha trobat el carregador dlopen original." +#: ../src/daemon/ltdl-bind-now.c:142 +msgid "Failed to add bind-now-loader." +msgstr "S'ha produït un error en afegir bind-now-loader." + #: ../src/daemon/polkit.c:55 #, c-format msgid "Cannot connect to system bus: %s" @@ -79,7 +84,8 @@ msgstr "No s'ha pogut inicialitzar PolKitContext: %s" #: ../src/daemon/polkit.c:119 #, c-format msgid "Could not determine whether caller is authorized: %s" -msgstr "S'ha produït un error en determinar si el cridador està autoritzada: %s" +msgstr "" +"S'ha produït un error en determinar si el cridador està autoritzada: %s" #: ../src/daemon/polkit.c:139 #, c-format @@ -125,8 +131,7 @@ msgstr "El GID de l'usuari '%s' i del grup '%s' no coincideixen" msgid "Home directory of user '%s' is not '%s', ignoring." msgstr "El directori d'inici de l'usuari '%s' no és '%s', s'ignorarà." -#: ../src/daemon/main.c:201 -#: ../src/daemon/main.c:206 +#: ../src/daemon/main.c:201 ../src/daemon/main.c:206 #, c-format msgid "Failed to create '%s': %s" msgstr "S'ha produït un error durant la creació de '%s': %s" @@ -159,258 +164,275 @@ msgstr "El mode de sistema no està disponible en aquesta plataforma." msgid "setrlimit(%s, (%u, %u)) failed: %s" msgstr "S'ha produït un error en setrlimit(%s, (%u, %u)): %s" -#: ../src/daemon/main.c:425 +#: ../src/daemon/main.c:429 msgid "Failed to parse command line." msgstr "S'ha produït un error en interpretar la línia d'ordres." -#: ../src/daemon/main.c:441 +#: ../src/daemon/main.c:451 #, c-format msgid "We're in the group '%s', allowing high-priority scheduling." -msgstr "Aquesta aplicació està en el grup '%s', s'està establint la planificació amb prioritat alta." +msgstr "" +"Aquesta aplicació està en el grup '%s', s'està establint la planificació amb " +"prioritat alta." -#: ../src/daemon/main.c:448 +#: ../src/daemon/main.c:458 #, c-format msgid "We're in the group '%s', allowing real-time scheduling." -msgstr "Aquesta aplicació està en el grup '%s', s'està establint la planificació amb prioritat en temps real." +msgstr "" +"Aquesta aplicació està en el grup '%s', s'està establint la planificació amb " +"prioritat en temps real." -#: ../src/daemon/main.c:456 +#: ../src/daemon/main.c:466 msgid "PolicyKit grants us acquire-high-priority privilege." msgstr "PolicyKit ha permés el permís acquire-high-priority." -#: ../src/daemon/main.c:459 +#: ../src/daemon/main.c:469 msgid "PolicyKit refuses acquire-high-priority privilege." msgstr "PolicyKit ha rebutjat el permís acquire-high-priority." -#: ../src/daemon/main.c:464 +#: ../src/daemon/main.c:474 msgid "PolicyKit grants us acquire-real-time privilege." msgstr "PolicyKit ha permés el permís acquire-real-time." -#: ../src/daemon/main.c:467 +#: ../src/daemon/main.c:477 msgid "PolicyKit refuses acquire-real-time privilege." msgstr "PolicyKit ha rebutjat el permís acquire-real-time." -#: ../src/daemon/main.c:479 +#: ../src/daemon/main.c:506 +#, fuzzy msgid "" -"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n" +"Called SUID root and real-time and/or high-priority scheduling was requested " +"in the configuration. However, we lack the necessary privileges:\n" "We are not in group '" msgstr "" -"S'han especificat la crida SUID root i la planificació amb prioritat alta/temps real en la configuració, però no té els permissos necessaris:\n" +"S'han especificat la crida SUID root i la planificació amb prioritat alta/" +"temps real en la configuració, però no té els permissos necessaris:\n" "No es pertany al grup '" -#: ../src/daemon/main.c:480 +#: ../src/daemon/main.c:530 msgid "" -"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" -"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '" +"High-priority scheduling enabled in configuration but not allowed by policy." msgstr "" -"' i PolicyKit ha denegat els permissos. S'està lliberant SUID. \n" -"Per habilitar la prioritat en temps real, s'ha d'adquirir els permissos de PolicyKit, o pertanyer a '" - -#: ../src/daemon/main.c:481 -msgid "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user." -msgstr "', o incrementar els límits de recursos RLIMIT_NICE/RLIMIT_RTPRIO per a aquest usuari." - -#: ../src/daemon/main.c:497 -msgid "High-priority scheduling enabled in configuration but not allowed by policy." -msgstr "La prioritat alta està habilitada en la configuració però no està permesa per la política." +"La prioritat alta està habilitada en la configuració però no està permesa " +"per la política." -#: ../src/daemon/main.c:522 +#: ../src/daemon/main.c:559 msgid "Successfully increased RLIMIT_RTPRIO" msgstr "S'ha incrementat el valor de RLIMIT_RTPRIO amb éxit." -#: ../src/daemon/main.c:525 +#: ../src/daemon/main.c:562 #, c-format msgid "RLIMIT_RTPRIO failed: %s" msgstr "S'ha produït un error amb RLIMIT_RTPRIO: %s" -#: ../src/daemon/main.c:532 +#: ../src/daemon/main.c:569 msgid "Giving up CAP_NICE" msgstr "No es continuarà amb CAP_NICE" -#: ../src/daemon/main.c:539 -msgid "Real-time scheduling enabled in configuration but not allowed by policy." -msgstr "La prioritat de planificació de temps real està habilitada en la configuració però no està permesa per la política." +#: ../src/daemon/main.c:576 +msgid "" +"Real-time scheduling enabled in configuration but not allowed by policy." +msgstr "" +"La prioritat de planificació de temps real està habilitada en la " +"configuració però no està permesa per la política." -#: ../src/daemon/main.c:597 +#: ../src/daemon/main.c:637 msgid "Daemon not running" msgstr "El dimoni no s'està executant." -#: ../src/daemon/main.c:599 +#: ../src/daemon/main.c:639 #, c-format msgid "Daemon running as PID %u" msgstr "El dimoni s'està executant amb PID %u" -#: ../src/daemon/main.c:609 +#: ../src/daemon/main.c:649 #, c-format msgid "Failed to kill daemon: %s" msgstr "S'ha produït un error en matar el dimoni: %s" -#: ../src/daemon/main.c:627 -msgid "This program is not intended to be run as root (unless --system is specified)." -msgstr "No és necessari executar aquesta aplicació com a root (excepte si s'especifica --system)" +#: ../src/daemon/main.c:667 +msgid "" +"This program is not intended to be run as root (unless --system is " +"specified)." +msgstr "" +"No és necessari executar aquesta aplicació com a root (excepte si " +"s'especifica --system)" -#: ../src/daemon/main.c:629 -msgid "Root priviliges required." +#: ../src/daemon/main.c:669 +#, fuzzy +msgid "Root privileges required." msgstr "Es requereixen permisos de root." -#: ../src/daemon/main.c:634 +#: ../src/daemon/main.c:674 msgid "--start not supported for system instances." msgstr "L'opció --start no està disponible per a instàncies de sistema." -#: ../src/daemon/main.c:639 +#: ../src/daemon/main.c:679 msgid "Running in system mode, but --disallow-exit not set!" -msgstr "S'està executant en mode sistema, però no s'ha especificat l'opció --disallow-exit." +msgstr "" +"S'està executant en mode sistema, però no s'ha especificat l'opció --" +"disallow-exit." -#: ../src/daemon/main.c:642 +#: ../src/daemon/main.c:682 msgid "Running in system mode, but --disallow-module-loading not set!" -msgstr "S'està executant en mode sistema, però no s'ha especificat l'opció --disallow-module-loading." +msgstr "" +"S'està executant en mode sistema, però no s'ha especificat l'opció --" +"disallow-module-loading." -#: ../src/daemon/main.c:645 +#: ../src/daemon/main.c:685 msgid "Running in system mode, forcibly disabling SHM mode!" -msgstr "S'està executant en mode sistema, es forçarà la inhabilitació del mode SHM" +msgstr "" +"S'està executant en mode sistema, es forçarà la inhabilitació del mode SHM" -#: ../src/daemon/main.c:650 +#: ../src/daemon/main.c:690 msgid "Running in system mode, forcibly disabling exit idle time!" -msgstr "S'està executant en mode sistema, la sortida per temps d'inactivitat es deshabilita." +msgstr "" +"S'està executant en mode sistema, la sortida per temps d'inactivitat es " +"deshabilita." -#: ../src/daemon/main.c:677 +#: ../src/daemon/main.c:717 msgid "Failed to acquire stdio." msgstr "S'ha produït un error en adquirir stdio." -#: ../src/daemon/main.c:683 +#: ../src/daemon/main.c:723 #, c-format msgid "pipe failed: %s" msgstr "Ha fallat la canonada: %s" -#: ../src/daemon/main.c:688 +#: ../src/daemon/main.c:728 #, c-format msgid "fork() failed: %s" msgstr "Ha fallat fork(): %s" -#: ../src/daemon/main.c:702 +#: ../src/daemon/main.c:742 #, c-format msgid "read() failed: %s" msgstr "Ha fallat read(): %s" -#: ../src/daemon/main.c:708 +#: ../src/daemon/main.c:748 msgid "Daemon startup failed." msgstr "S'ha produït un error en iniciar el dimoni." -#: ../src/daemon/main.c:710 +#: ../src/daemon/main.c:750 msgid "Daemon startup successful." msgstr "S'ha iniciat el dimoni." -#: ../src/daemon/main.c:780 +#: ../src/daemon/main.c:820 #, c-format msgid "This is PulseAudio %s" msgstr "Aquest és el PulseAudio %s" -#: ../src/daemon/main.c:781 +#: ../src/daemon/main.c:821 #, c-format msgid "Compilation host: %s" msgstr "Host de compilació: %s" -#: ../src/daemon/main.c:782 +#: ../src/daemon/main.c:822 #, c-format msgid "Compilation CFLAGS: %s" msgstr "CFLAGS de compilació: %s" -#: ../src/daemon/main.c:785 +#: ../src/daemon/main.c:825 #, c-format msgid "Running on host: %s" msgstr "S'està executant en el host: %s" -#: ../src/daemon/main.c:788 +#: ../src/daemon/main.c:828 +#, c-format +msgid "Found %u CPUs." +msgstr "" + +#: ../src/daemon/main.c:830 #, c-format msgid "Page size is %lu bytes" msgstr "La mida de pàgina és de %lu bytes." -#: ../src/daemon/main.c:791 +#: ../src/daemon/main.c:833 msgid "Compiled with Valgrind support: yes" msgstr "Compilat amb suport per a Valgrind: sí" -#: ../src/daemon/main.c:793 +#: ../src/daemon/main.c:835 msgid "Compiled with Valgrind support: no" msgstr "Compilat amb suport per a Valgrind: no" -#: ../src/daemon/main.c:796 +#: ../src/daemon/main.c:838 #, c-format msgid "Running in valgrind mode: %s" msgstr "S'està executant amb el mode valgrind: %s" -#: ../src/daemon/main.c:799 +#: ../src/daemon/main.c:841 msgid "Optimized build: yes" msgstr "Construcció optimitzada: sí" -#: ../src/daemon/main.c:801 +#: ../src/daemon/main.c:843 msgid "Optimized build: no" msgstr "Construcció optmitzada: no" -#: ../src/daemon/main.c:805 +#: ../src/daemon/main.c:847 msgid "Failed to get machine ID" msgstr "S'ha produït un error en obtenir l'ID de la màquina" -#: ../src/daemon/main.c:808 +#: ../src/daemon/main.c:850 #, c-format msgid "Machine ID is %s." msgstr "La ID de la màquina és %s." -#: ../src/daemon/main.c:813 +#: ../src/daemon/main.c:855 #, c-format msgid "Using runtime directory %s." msgstr "S'esta utilitzant el directori d'execució %s." -#: ../src/daemon/main.c:818 +#: ../src/daemon/main.c:860 #, c-format msgid "Using state directory %s." msgstr "S'està utilitzant el directori d'estat %s." -#: ../src/daemon/main.c:821 +#: ../src/daemon/main.c:863 #, c-format msgid "Running in system mode: %s" msgstr "S'està executant en mode sistema: %s" -#: ../src/daemon/main.c:836 +#: ../src/daemon/main.c:878 msgid "pa_pid_file_create() failed." msgstr "S'ha produït un error en pa_pid_file_create()." -#: ../src/daemon/main.c:848 +#: ../src/daemon/main.c:890 msgid "Fresh high-resolution timers available! Bon appetit!" msgstr "Estan disponibles els temporitzadors d'alta resolució." -#: ../src/daemon/main.c:850 -msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!" -msgstr "Es recomana la utilització d'un nucli amb els temporitzadors d'alta resolució habilitats." +#: ../src/daemon/main.c:892 +msgid "" +"Dude, your kernel stinks! The chef's recommendation today is Linux with high-" +"resolution timers enabled!" +msgstr "" +"Es recomana la utilització d'un nucli amb els temporitzadors d'alta " +"resolució habilitats." -#: ../src/daemon/main.c:860 +#: ../src/daemon/main.c:904 msgid "pa_core_new() failed." msgstr "S'ha produït un error en pa_core_new()." -#: ../src/daemon/main.c:921 +#: ../src/daemon/main.c:965 msgid "Failed to initialize daemon." msgstr "S'ha produït un error en inicialitzar el dimoni." -#: ../src/daemon/main.c:926 +#: ../src/daemon/main.c:970 msgid "Daemon startup without any loaded modules, refusing to work." msgstr "El dimoni s'ha iniciat sense cap mòdul carregat, no funcionarà." -#: ../src/daemon/main.c:931 -#, c-format -msgid "Default sink name (%s) does not exist in name register." -msgstr "El nom per omissió del conducte (%s) no existeix en el registre de noms." - -#: ../src/daemon/main.c:944 +#: ../src/daemon/main.c:983 msgid "Daemon startup complete." msgstr "S'ha completat la inicialització del dimoni." -#: ../src/daemon/main.c:950 +#: ../src/daemon/main.c:989 msgid "Daemon shutdown initiated." msgstr "S'ha iniciat l'aturada del dimoni." -#: ../src/daemon/main.c:971 +#: ../src/daemon/main.c:1010 msgid "Daemon terminated." msgstr "S'ha aturat el dimoni." -#: ../src/daemon/cmdline.c:117 +#: ../src/daemon/cmdline.c:121 #, fuzzy, c-format msgid "" "%s [options]\n" @@ -421,34 +443,48 @@ msgid "" " --dump-conf Dump default configuration\n" " --dump-modules Dump list of available modules\n" " --dump-resample-methods Dump available resample methods\n" -" --cleanup-shm Cleanup stale shared memory segments\n" -" --start Start the daemon if it is not running\n" +" --cleanup-shm Cleanup stale shared memory " +"segments\n" +" --start Start the daemon if it is not " +"running\n" " -k --kill Kill a running daemon\n" -" --check Check for a running daemon\n" +" --check Check for a running daemon (only " +"returns exit code)\n" "\n" "OPTIONS:\n" " --system[=BOOL] Run as system-wide instance\n" " -D, --daemonize[=BOOL] Daemonize after startup\n" " --fail[=BOOL] Quit when startup fails\n" " --high-priority[=BOOL] Try to set high nice level\n" -" (only available as root, when SUID or\n" +" (only available as root, when SUID " +"or\n" " with elevated RLIMIT_NICE)\n" " --realtime[=BOOL] Try to enable realtime scheduling\n" -" (only available as root, when SUID or\n" +" (only available as root, when SUID " +"or\n" " with elevated RLIMIT_RTPRIO)\n" -" --disallow-module-loading[=BOOL] Disallow module user requested module\n" +" --disallow-module-loading[=BOOL] Disallow module user requested " +"module\n" " loading/unloading after startup\n" " --disallow-exit[=BOOL] Disallow user requested exit\n" -" --exit-idle-time=SECS Terminate the daemon when idle and this\n" +" --exit-idle-time=SECS Terminate the daemon when idle and " +"this\n" " time passed\n" -" --module-idle-time=SECS Unload autoloaded modules when idle and\n" +" --module-idle-time=SECS Unload autoloaded modules when idle " +"and\n" " this time passed\n" -" --scache-idle-time=SECS Unload autoloaded samples when idle and\n" +" --scache-idle-time=SECS Unload autoloaded samples when idle " +"and\n" " this time passed\n" " --log-level[=LEVEL] Increase or set verbosity level\n" " -v Increase the verbosity level\n" " --log-target={auto,syslog,stderr} Specify the log target\n" -" -p, --dl-search-path=PATH Set the search path for dynamic shared\n" +" --log-meta[=BOOL] Include code location in log " +"messages\n" +" --log-time[=BOOL] Include timestamps in log messages\n" +" --log-backtrace=FRAMES Include a backtrace in log messages\n" +" -p, --dl-search-path=PATH Set the search path for dynamic " +"shared\n" " objects (plugins)\n" " --resample-method=METHOD Use the specified resampling method\n" " (See --dump-resample-methods for\n" @@ -459,10 +495,12 @@ msgid "" " --disable-shm[=BOOL] Disable shared memory support.\n" "\n" "STARTUP SCRIPT:\n" -" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module with\n" +" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module " +"with\n" " the specified argument\n" " -F, --file=FILENAME Run the specified script\n" -" -C Open a command line on the running TTY\n" +" -C Open a command line on the running " +"TTY\n" " after startup\n" "\n" " -n Don't load default script file\n" @@ -474,35 +512,46 @@ msgstr "" " --version Mostra la versió\n" " --dump-conf Volca la configuració per omissió\n" " --dump-modules Volca la llista de mòduls\n" -" --dump-resample-methods Volca els mètodes disponibles de remostratge\n" -" --cleanup-shm Neteja els segments de memòria compartida no emprats\n" +" --dump-resample-methods Volca els mètodes disponibles de " +"remostratge\n" +" --cleanup-shm Neteja els segments de memòria " +"compartida no emprats\n" " --start Inicia el dimoni si no està corrent\n" " -k --kill Mata el dimoni en execució\n" " --check Comprova l'execució del dimoni\n" "\n" "OPCIONS:\n" " --system[=BOOL] Executa com a instància de sistema\n" -" -D, --daemonize[=BOOL] Converteix en dimoni després de la inicialització\n" +" -D, --daemonize[=BOOL] Converteix en dimoni després de la " +"inicialització\n" " --fail[=BOOL] Surt quan falli la inicialització\n" " --high-priority[=BOOL] Prova d'establir un nivell\n" -" de prioritat alt (només disponible com a root,\n" -" amb SUID o amb un elevat RLIMIT_NICE)\n" +" de prioritat alt (només disponible " +"com a root,\n" +" amb SUID o amb un elevat " +"RLIMIT_NICE)\n" " --realtime[=BOOL] Try to enable realtime scheduling\n" -" (only available as root, when SUID or\n" +" (only available as root, when SUID " +"or\n" " with elevated RLIMIT_RTPRIO)\n" -" --disallow-module-loading[=BOOL] Disallow module user requested module\n" +" --disallow-module-loading[=BOOL] Disallow module user requested " +"module\n" " loading/unloading after startup\n" " --disallow-exit[=BOOL] Disallow user requested exit\n" -" --exit-idle-time=SECS Terminate the daemon when idle and this\n" +" --exit-idle-time=SECS Terminate the daemon when idle and " +"this\n" " time passed\n" -" --module-idle-time=SECS Unload autoloaded modules when idle and\n" +" --module-idle-time=SECS Unload autoloaded modules when idle " +"and\n" " this time passed\n" -" --scache-idle-time=SECS Unload autoloaded samples when idle and\n" +" --scache-idle-time=SECS Unload autoloaded samples when idle " +"and\n" " this time passed\n" " --log-level[=LEVEL] Increase or set verbosity level\n" " -v Increase the verbosity level\n" " --log-target={auto,syslog,stderr} Specify the log target\n" -" -p, --dl-search-path=PATH Set the search path for dynamic shared\n" +" -p, --dl-search-path=PATH Set the search path for dynamic " +"shared\n" " objects (plugins)\n" " --resample-method=METHOD Use the specified resampling method\n" " (See --dump-resample-methods for\n" @@ -513,64 +562,80 @@ msgstr "" " --disable-shm[=BOOL] Disable shared memory support.\n" "\n" "STARTUP SCRIPT:\n" -" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module with\n" +" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module " +"with\n" " the specified argument\n" " -F, --file=FILENAME Run the specified script\n" -" -C Open a command line on the running TTY\n" +" -C Open a command line on the running " +"TTY\n" " after startup\n" "\n" " -n Don't load default script file\n" -#: ../src/daemon/cmdline.c:245 +#: ../src/daemon/cmdline.c:252 msgid "--daemonize expects boolean argument" msgstr "--daemonize necessita un argument booleà" -#: ../src/daemon/cmdline.c:252 +#: ../src/daemon/cmdline.c:259 msgid "--fail expects boolean argument" msgstr "--fail necessita un argument booleà" -#: ../src/daemon/cmdline.c:262 -msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)." -msgstr "--log-level necessita un argument de nivell de log (valor númeric 0..4 o 'debug', 'info', 'notice', 'warn', 'error')." +#: ../src/daemon/cmdline.c:269 +msgid "" +"--log-level expects log level argument (either numeric in range 0..4 or one " +"of debug, info, notice, warn, error)." +msgstr "" +"--log-level necessita un argument de nivell de log (valor númeric 0..4 o " +"'debug', 'info', 'notice', 'warn', 'error')." -#: ../src/daemon/cmdline.c:274 +#: ../src/daemon/cmdline.c:281 msgid "--high-priority expects boolean argument" msgstr "--high-priority necessita un argument booleà" -#: ../src/daemon/cmdline.c:281 +#: ../src/daemon/cmdline.c:288 msgid "--realtime expects boolean argument" msgstr "--realtime necessita un argument booleà" -#: ../src/daemon/cmdline.c:288 +#: ../src/daemon/cmdline.c:295 msgid "--disallow-module-loading expects boolean argument" msgstr "--disallow-module-loading necessita un argument booleà" -#: ../src/daemon/cmdline.c:295 +#: ../src/daemon/cmdline.c:302 msgid "--disallow-exit boolean argument" msgstr "--disallow-exit necessita un argument booleà" -#: ../src/daemon/cmdline.c:302 +#: ../src/daemon/cmdline.c:309 msgid "--use-pid-file expects boolean argument" msgstr "--use-pid-file necessita un argument booleà" -#: ../src/daemon/cmdline.c:319 +#: ../src/daemon/cmdline.c:326 msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'." msgstr "Objectiu de registre invàlid: utilitzeu 'syslog', 'stderr' o 'auto'." -#: ../src/daemon/cmdline.c:338 +#: ../src/daemon/cmdline.c:333 +#, fuzzy +msgid "--log-time boolean argument" +msgstr "--disallow-exit necessita un argument booleà" + +#: ../src/daemon/cmdline.c:340 +#, fuzzy +msgid "--log-meta boolean argument" +msgstr "--disallow-exit necessita un argument booleà" + +#: ../src/daemon/cmdline.c:359 #, c-format msgid "Invalid resample method '%s'." msgstr "Mètode de remostratge invàlid '%s'." -#: ../src/daemon/cmdline.c:345 +#: ../src/daemon/cmdline.c:366 msgid "--system expects boolean argument" msgstr "--system necessita un argument booleà" -#: ../src/daemon/cmdline.c:352 +#: ../src/daemon/cmdline.c:373 msgid "--no-cpu-limit expects boolean argument" msgstr "--no-cpu-limit necessita un argument booleà" -#: ../src/daemon/cmdline.c:359 +#: ../src/daemon/cmdline.c:380 msgid "--disable-shm expects boolean argument" msgstr "--disable-shm necessita un argument booleà" @@ -614,290 +679,314 @@ msgstr "" msgid "Path: %s\n" msgstr "" -#: ../src/daemon/daemon-conf.c:205 +#: ../src/daemon/daemon-conf.c:212 #, c-format msgid "[%s:%u] Invalid log target '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:221 +#: ../src/daemon/daemon-conf.c:228 #, c-format msgid "[%s:%u] Invalid log level '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:237 +#: ../src/daemon/daemon-conf.c:244 #, c-format msgid "[%s:%u] Invalid resample method '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:260 +#: ../src/daemon/daemon-conf.c:267 #, c-format msgid "[%s:%u] Invalid rlimit '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:267 +#: ../src/daemon/daemon-conf.c:274 #, c-format msgid "[%s:%u] rlimit not supported on this platform." msgstr "" -#: ../src/daemon/daemon-conf.c:283 +#: ../src/daemon/daemon-conf.c:290 #, c-format msgid "[%s:%u] Invalid sample format '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:301 +#: ../src/daemon/daemon-conf.c:308 #, c-format msgid "[%s:%u] Invalid sample rate '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:319 +#: ../src/daemon/daemon-conf.c:326 #, c-format msgid "[%s:%u] Invalid sample channels '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:337 +#: ../src/daemon/daemon-conf.c:344 #, c-format msgid "[%s:%u] Invalid number of fragments '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:355 +#: ../src/daemon/daemon-conf.c:362 #, c-format msgid "[%s:%u] Invalid fragment size '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:373 +#: ../src/daemon/daemon-conf.c:380 #, c-format msgid "[%s:%u] Invalid nice level '%s'." msgstr "" -#: ../src/daemon/daemon-conf.c:570 +#: ../src/daemon/daemon-conf.c:566 #, c-format msgid "Failed to open configuration file: %s" msgstr "" -#: ../src/daemon/daemon-conf.c:644 +#: ../src/daemon/daemon-conf.c:640 #, c-format msgid "### Read from configuration file: %s ###\n" msgstr "" #: ../src/daemon/caps.c:63 -msgid "Dropping root priviliges." -msgstr "" +#, fuzzy +msgid "Dropping root privileges." +msgstr "S'han lliberat els permissos de root amb éxit." #: ../src/daemon/caps.c:103 msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "" -#: ../src/pulse/channelmap.c:102 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "" -#: ../src/pulse/channelmap.c:104 +#: ../src/pulse/channelmap.c:105 msgid "Front Center" msgstr "" -#: ../src/pulse/channelmap.c:105 +#: ../src/pulse/channelmap.c:106 msgid "Front Left" msgstr "" -#: ../src/pulse/channelmap.c:106 +#: ../src/pulse/channelmap.c:107 msgid "Front Right" msgstr "" -#: ../src/pulse/channelmap.c:108 +#: ../src/pulse/channelmap.c:109 msgid "Rear Center" msgstr "" -#: ../src/pulse/channelmap.c:109 +#: ../src/pulse/channelmap.c:110 msgid "Rear Left" msgstr "" -#: ../src/pulse/channelmap.c:110 +#: ../src/pulse/channelmap.c:111 msgid "Rear Right" msgstr "" -#: ../src/pulse/channelmap.c:112 +#: ../src/pulse/channelmap.c:113 msgid "Low Frequency Emmiter" msgstr "" -#: ../src/pulse/channelmap.c:114 +#: ../src/pulse/channelmap.c:115 msgid "Front Left-of-center" msgstr "" -#: ../src/pulse/channelmap.c:115 +#: ../src/pulse/channelmap.c:116 msgid "Front Right-of-center" msgstr "" -#: ../src/pulse/channelmap.c:117 +#: ../src/pulse/channelmap.c:118 msgid "Side Left" msgstr "" -#: ../src/pulse/channelmap.c:118 +#: ../src/pulse/channelmap.c:119 msgid "Side Right" msgstr "" -#: ../src/pulse/channelmap.c:120 +#: ../src/pulse/channelmap.c:121 msgid "Auxiliary 0" msgstr "" -#: ../src/pulse/channelmap.c:121 +#: ../src/pulse/channelmap.c:122 msgid "Auxiliary 1" msgstr "" -#: ../src/pulse/channelmap.c:122 +#: ../src/pulse/channelmap.c:123 msgid "Auxiliary 2" msgstr "" -#: ../src/pulse/channelmap.c:123 +#: ../src/pulse/channelmap.c:124 msgid "Auxiliary 3" msgstr "" -#: ../src/pulse/channelmap.c:124 +#: ../src/pulse/channelmap.c:125 msgid "Auxiliary 4" msgstr "" -#: ../src/pulse/channelmap.c:125 +#: ../src/pulse/channelmap.c:126 msgid "Auxiliary 5" msgstr "" -#: ../src/pulse/channelmap.c:126 +#: ../src/pulse/channelmap.c:127 msgid "Auxiliary 6" msgstr "" -#: ../src/pulse/channelmap.c:127 +#: ../src/pulse/channelmap.c:128 msgid "Auxiliary 7" msgstr "" -#: ../src/pulse/channelmap.c:128 +#: ../src/pulse/channelmap.c:129 msgid "Auxiliary 8" msgstr "" -#: ../src/pulse/channelmap.c:129 +#: ../src/pulse/channelmap.c:130 msgid "Auxiliary 9" msgstr "" -#: ../src/pulse/channelmap.c:130 +#: ../src/pulse/channelmap.c:131 msgid "Auxiliary 10" msgstr "" -#: ../src/pulse/channelmap.c:131 +#: ../src/pulse/channelmap.c:132 msgid "Auxiliary 11" msgstr "" -#: ../src/pulse/channelmap.c:132 +#: ../src/pulse/channelmap.c:133 msgid "Auxiliary 12" msgstr "" -#: ../src/pulse/channelmap.c:133 +#: ../src/pulse/channelmap.c:134 msgid "Auxiliary 13" msgstr "" -#: ../src/pulse/channelmap.c:134 +#: ../src/pulse/channelmap.c:135 msgid "Auxiliary 14" msgstr "" -#: ../src/pulse/channelmap.c:135 +#: ../src/pulse/channelmap.c:136 msgid "Auxiliary 15" msgstr "" -#: ../src/pulse/channelmap.c:136 +#: ../src/pulse/channelmap.c:137 msgid "Auxiliary 16" msgstr "" -#: ../src/pulse/channelmap.c:137 +#: ../src/pulse/channelmap.c:138 msgid "Auxiliary 17" msgstr "" -#: ../src/pulse/channelmap.c:138 +#: ../src/pulse/channelmap.c:139 msgid "Auxiliary 18" msgstr "" -#: ../src/pulse/channelmap.c:139 +#: ../src/pulse/channelmap.c:140 msgid "Auxiliary 19" msgstr "" -#: ../src/pulse/channelmap.c:140 +#: ../src/pulse/channelmap.c:141 msgid "Auxiliary 20" msgstr "" -#: ../src/pulse/channelmap.c:141 +#: ../src/pulse/channelmap.c:142 msgid "Auxiliary 21" msgstr "" -#: ../src/pulse/channelmap.c:142 +#: ../src/pulse/channelmap.c:143 msgid "Auxiliary 22" msgstr "" -#: ../src/pulse/channelmap.c:143 +#: ../src/pulse/channelmap.c:144 msgid "Auxiliary 23" msgstr "" -#: ../src/pulse/channelmap.c:144 +#: ../src/pulse/channelmap.c:145 msgid "Auxiliary 24" msgstr "" -#: ../src/pulse/channelmap.c:145 +#: ../src/pulse/channelmap.c:146 msgid "Auxiliary 25" msgstr "" -#: ../src/pulse/channelmap.c:146 +#: ../src/pulse/channelmap.c:147 msgid "Auxiliary 26" msgstr "" -#: ../src/pulse/channelmap.c:147 +#: ../src/pulse/channelmap.c:148 msgid "Auxiliary 27" msgstr "" -#: ../src/pulse/channelmap.c:148 +#: ../src/pulse/channelmap.c:149 msgid "Auxiliary 28" msgstr "" -#: ../src/pulse/channelmap.c:149 +#: ../src/pulse/channelmap.c:150 msgid "Auxiliary 29" msgstr "" -#: ../src/pulse/channelmap.c:150 +#: ../src/pulse/channelmap.c:151 msgid "Auxiliary 30" msgstr "" -#: ../src/pulse/channelmap.c:151 +#: ../src/pulse/channelmap.c:152 msgid "Auxiliary 31" msgstr "" -#: ../src/pulse/channelmap.c:153 +#: ../src/pulse/channelmap.c:154 msgid "Top Center" msgstr "" -#: ../src/pulse/channelmap.c:155 +#: ../src/pulse/channelmap.c:156 msgid "Top Front Center" msgstr "" -#: ../src/pulse/channelmap.c:156 +#: ../src/pulse/channelmap.c:157 msgid "Top Front Left" msgstr "" -#: ../src/pulse/channelmap.c:157 +#: ../src/pulse/channelmap.c:158 msgid "Top Front Right" msgstr "" -#: ../src/pulse/channelmap.c:159 +#: ../src/pulse/channelmap.c:160 msgid "Top Rear Center" msgstr "" -#: ../src/pulse/channelmap.c:160 +#: ../src/pulse/channelmap.c:161 msgid "Top Rear Left" msgstr "" -#: ../src/pulse/channelmap.c:161 +#: ../src/pulse/channelmap.c:162 msgid "Top Rear Right" msgstr "" -#: ../src/pulse/channelmap.c:472 -#: ../src/pulse/sample.c:144 -#: ../src/pulse/volume.c:163 -#: ../src/pulse/volume.c:194 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "" +#: ../src/pulse/channelmap.c:808 +msgid "Stereo" +msgstr "" + +#: ../src/pulse/channelmap.c:813 +msgid "Surround 4.0" +msgstr "" + +#: ../src/pulse/channelmap.c:819 +msgid "Surround 4.1" +msgstr "" + +#: ../src/pulse/channelmap.c:825 +msgid "Surround 5.0" +msgstr "" + +#: ../src/pulse/channelmap.c:831 +msgid "Surround 5.1" +msgstr "" + +#: ../src/pulse/channelmap.c:838 +msgid "Surround 7.1" +msgstr "" + #: ../src/pulse/error.c:43 msgid "OK" msgstr "" @@ -986,8 +1075,40 @@ msgstr "" msgid "No such extension" msgstr "" -#: ../src/pulse/client-conf-x11.c:55 -#: ../src/utils/pax11publish.c:100 +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + +#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "" @@ -1000,45 +1121,35 @@ msgstr "" msgid "Failed to open configuration file '%s': %s" msgstr "" -#: ../src/pulse/context.c:516 +#: ../src/pulse/context.c:517 msgid "No cookie loaded. Attempting to connect without." msgstr "" -#: ../src/pulse/context.c:642 +#: ../src/pulse/context.c:643 #, c-format msgid "fork(): %s" msgstr "" -#: ../src/pulse/context.c:695 +#: ../src/pulse/context.c:696 #, c-format msgid "waitpid(): %s" msgstr "" -#: ../src/pulse/context.c:1256 +#: ../src/pulse/context.c:1257 #, c-format msgid "Received message for unknown extension '%s'" msgstr "" -#: ../src/utils/pacat.c:93 +#: ../src/utils/pacat.c:94 #, c-format msgid "pa_stream_write() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:132 +#: ../src/utils/pacat.c:133 #, c-format msgid "pa_stream_peek() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:141 -#, c-format -msgid "Buffer overrun, dropping incoming data\n" -msgstr "" - -#: ../src/utils/pacat.c:143 -#, c-format -msgid "pa_stream_drop() failed: %s\n" -msgstr "" - #: ../src/utils/pacat.c:169 #, c-format msgid "Stream successfully created.\n" @@ -1118,83 +1229,78 @@ msgstr "" msgid "pa_stream_new() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:287 +#: ../src/utils/pacat.c:288 #, c-format msgid "pa_stream_connect_playback() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:293 +#: ../src/utils/pacat.c:294 #, c-format msgid "pa_stream_connect_record() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:307 -#: ../src/utils/pasuspender.c:159 -#: ../src/utils/pactl.c:666 -#: ../src/utils/paplay.c:183 +#: ../src/utils/pacat.c:308 ../src/utils/pasuspender.c:159 +#: ../src/utils/pactl.c:758 ../src/utils/paplay.c:183 #, c-format msgid "Connection failure: %s\n" msgstr "" -#: ../src/utils/pacat.c:328 -#: ../src/utils/paplay.c:75 +#: ../src/utils/pacat.c:329 ../src/utils/paplay.c:75 #, c-format msgid "Failed to drain stream: %s\n" msgstr "" -#: ../src/utils/pacat.c:333 -#: ../src/utils/paplay.c:80 +#: ../src/utils/pacat.c:334 ../src/utils/paplay.c:80 #, c-format msgid "Playback stream drained.\n" msgstr "" -#: ../src/utils/pacat.c:343 -#: ../src/utils/paplay.c:92 +#: ../src/utils/pacat.c:344 ../src/utils/paplay.c:92 #, c-format msgid "Draining connection to server.\n" msgstr "" -#: ../src/utils/pacat.c:369 +#: ../src/utils/pacat.c:370 #, c-format msgid "Got EOF.\n" msgstr "" -#: ../src/utils/pacat.c:375 +#: ../src/utils/pacat.c:376 #, c-format msgid "pa_stream_drain(): %s\n" msgstr "" -#: ../src/utils/pacat.c:385 +#: ../src/utils/pacat.c:386 #, c-format msgid "read() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:417 +#: ../src/utils/pacat.c:418 #, c-format msgid "write() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:438 +#: ../src/utils/pacat.c:439 #, c-format msgid "Got signal, exiting.\n" msgstr "" -#: ../src/utils/pacat.c:452 +#: ../src/utils/pacat.c:453 #, c-format msgid "Failed to get latency: %s\n" msgstr "" -#: ../src/utils/pacat.c:457 +#: ../src/utils/pacat.c:458 #, c-format msgid "Time: %0.3f sec; Latency: %0.0f usec. \r" msgstr "" -#: ../src/utils/pacat.c:477 +#: ../src/utils/pacat.c:478 #, c-format msgid "pa_stream_update_timing_info() failed: %s\n" msgstr "" -#: ../src/utils/pacat.c:490 +#: ../src/utils/pacat.c:491 #, c-format msgid "" "%s [options]\n" @@ -1207,30 +1313,47 @@ msgid "" "\n" " -v, --verbose Enable verbose operations\n" "\n" -" -s, --server=SERVER The name of the server to connect to\n" -" -d, --device=DEVICE The name of the sink/source to connect to\n" -" -n, --client-name=NAME How to call this client on the server\n" -" --stream-name=NAME How to call this stream on the server\n" -" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n" -" --rate=SAMPLERATE The sample rate in Hz (defaults to 44100)\n" -" --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le,\n" -" float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n" -" --channels=CHANNELS The number of channels, 1 for mono, 2 for stereo\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" +" -d, --device=DEVICE The name of the sink/source to " +"connect to\n" +" -n, --client-name=NAME How to call this client on the " +"server\n" +" --stream-name=NAME How to call this stream on the " +"server\n" +" --volume=VOLUME Specify the initial (linear) volume " +"in range 0...65536\n" +" --rate=SAMPLERATE The sample rate in Hz (defaults to " +"44100)\n" +" --format=SAMPLEFORMAT The sample type, one of s16le, " +"s16be, u8, float32le,\n" +" float32be, ulaw, alaw, s32le, s32be " +"(defaults to s16ne)\n" +" --channels=CHANNELS The number of channels, 1 for mono, " +"2 for stereo\n" " (defaults to 2)\n" -" --channel-map=CHANNELMAP Channel map to use instead of the default\n" -" --fix-format Take the sample format from the sink the stream is\n" +" --channel-map=CHANNELMAP Channel map to use instead of the " +"default\n" +" --fix-format Take the sample format from the sink " +"the stream is\n" " being connected to.\n" -" --fix-rate Take the sampling rate from the sink the stream is\n" +" --fix-rate Take the sampling rate from the sink " +"the stream is\n" " being connected to.\n" -" --fix-channels Take the number of channels and the channel map\n" -" from the sink the stream is being connected to.\n" +" --fix-channels Take the number of channels and the " +"channel map\n" +" from the sink the stream is being " +"connected to.\n" " --no-remix Don't upmix or downmix channels.\n" -" --no-remap Map channels by index instead of name.\n" -" --latency=BYTES Request the specified latency in bytes.\n" -" --process-time=BYTES Request the specified process time per request in bytes.\n" +" --no-remap Map channels by index instead of " +"name.\n" +" --latency=BYTES Request the specified latency in " +"bytes.\n" +" --process-time=BYTES Request the specified process time " +"per request in bytes.\n" msgstr "" -#: ../src/utils/pacat.c:591 +#: ../src/utils/pacat.c:592 #, c-format msgid "" "pacat %s\n" @@ -1238,94 +1361,88 @@ msgid "" "Linked with libpulse %s\n" msgstr "" -#: ../src/utils/pacat.c:647 +#: ../src/utils/pacat.c:649 #, c-format msgid "Invalid channel map '%s'\n" msgstr "" -#: ../src/utils/pacat.c:676 +#: ../src/utils/pacat.c:678 #, c-format msgid "Invalid latency specification '%s'\n" msgstr "" -#: ../src/utils/pacat.c:683 +#: ../src/utils/pacat.c:685 #, c-format msgid "Invalid process time specification '%s'\n" msgstr "" -#: ../src/utils/pacat.c:694 +#: ../src/utils/pacat.c:696 #, c-format msgid "Invalid sample specification\n" msgstr "" -#: ../src/utils/pacat.c:699 +#: ../src/utils/pacat.c:701 #, c-format msgid "Channel map doesn't match sample specification\n" msgstr "" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 #, c-format msgid "Opening a %s stream with sample specification '%s'.\n" msgstr "" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 msgid "recording" msgstr "" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 msgid "playback" msgstr "" -#: ../src/utils/pacat.c:714 +#: ../src/utils/pacat.c:716 #, c-format msgid "open(): %s\n" msgstr "" -#: ../src/utils/pacat.c:719 +#: ../src/utils/pacat.c:721 #, c-format msgid "dup2(): %s\n" msgstr "" -#: ../src/utils/pacat.c:729 +#: ../src/utils/pacat.c:731 #, c-format msgid "Too many arguments.\n" msgstr "" -#: ../src/utils/pacat.c:742 -#: ../src/utils/pasuspender.c:280 -#: ../src/utils/pactl.c:909 -#: ../src/utils/paplay.c:381 +#: ../src/utils/pacat.c:744 ../src/utils/pasuspender.c:280 +#: ../src/utils/pactl.c:1013 ../src/utils/paplay.c:381 #, c-format msgid "pa_mainloop_new() failed.\n" msgstr "" -#: ../src/utils/pacat.c:763 +#: ../src/utils/pacat.c:765 #, c-format msgid "io_new() failed.\n" msgstr "" -#: ../src/utils/pacat.c:769 -#: ../src/utils/pasuspender.c:293 -#: ../src/utils/pactl.c:923 -#: ../src/utils/paplay.c:396 +#: ../src/utils/pacat.c:771 ../src/utils/pasuspender.c:293 +#: ../src/utils/pactl.c:1027 ../src/utils/paplay.c:396 #, c-format msgid "pa_context_new() failed.\n" msgstr "" -#: ../src/utils/pacat.c:777 +#: ../src/utils/pacat.c:779 #, c-format msgid "pa_context_connect() failed: %s" msgstr "" -#: ../src/utils/pacat.c:788 +#: ../src/utils/pacat.c:790 #, c-format msgid "time_new() failed.\n" msgstr "" -#: ../src/utils/pacat.c:795 -#: ../src/utils/pasuspender.c:301 -#: ../src/utils/pactl.c:931 -#: ../src/utils/paplay.c:407 +#: ../src/utils/pacat.c:797 ../src/utils/pasuspender.c:301 +#: ../src/utils/pactl.c:1035 ../src/utils/paplay.c:407 #, c-format msgid "pa_mainloop_run() failed.\n" msgstr "" @@ -1355,8 +1472,7 @@ msgstr "" msgid "WARNING: Sound server is not local, not suspending.\n" msgstr "" -#: ../src/utils/pasuspender.c:176 -#: ../src/utils/pactl.c:672 +#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:764 #: ../src/utils/paplay.c:191 #, c-format msgid "Got SIGINT, exiting.\n" @@ -1374,7 +1490,8 @@ msgid "" "\n" " -h, --help Show this help\n" " --version Show version\n" -" -s, --server=SERVER The name of the server to connect to\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" "\n" msgstr "" @@ -1386,32 +1503,32 @@ msgid "" "Linked with libpulse %s\n" msgstr "" -#: ../src/utils/pactl.c:107 +#: ../src/utils/pactl.c:108 #, c-format msgid "Failed to get statistics: %s\n" msgstr "" -#: ../src/utils/pactl.c:113 +#: ../src/utils/pactl.c:114 #, c-format msgid "Currently in use: %u blocks containing %s bytes total.\n" msgstr "" -#: ../src/utils/pactl.c:116 +#: ../src/utils/pactl.c:117 #, c-format msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n" msgstr "" -#: ../src/utils/pactl.c:119 +#: ../src/utils/pactl.c:120 #, c-format msgid "Sample cache size: %s\n" msgstr "" -#: ../src/utils/pactl.c:128 +#: ../src/utils/pactl.c:129 #, c-format msgid "Failed to get server information: %s\n" msgstr "" -#: ../src/utils/pactl.c:135 +#: ../src/utils/pactl.c:136 #, c-format msgid "" "User name: %s\n" @@ -1424,206 +1541,212 @@ msgid "" "Cookie: %08x\n" msgstr "" -#: ../src/utils/pactl.c:160 +#: ../src/utils/pactl.c:175 #, c-format msgid "Failed to get sink information: %s\n" msgstr "" -#: ../src/utils/pactl.c:176 +#: ../src/utils/pactl.c:191 #, c-format msgid "" -"*** Sink #%u ***\n" -"Name: %s\n" -"Driver: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Owner Module: %u\n" -"Volume: %s\n" -"Monitor Source: %s\n" -"Latency: %0.0f usec, configured %0.0f usec\n" -"Flags: %s%s%s%s%s%s\n" -"Properties:\n" -"%s" -msgstr "" - -#: ../src/utils/pactl.c:193 -#: ../src/utils/pactl.c:371 -msgid "muted" -msgstr "" - -#: ../src/utils/pactl.c:212 +"Sink #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s%s%s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s%s%s\n" +"\tMonitor Source: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:255 #, c-format msgid "Failed to get source information: %s\n" msgstr "" -#: ../src/utils/pactl.c:228 +#: ../src/utils/pactl.c:271 #, c-format msgid "" -"*** Source #%u ***\n" -"Name: %s\n" -"Driver: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Owner Module: %u\n" -"Volume: %s\n" -"Monitor of Sink: %s\n" -"Latency: %0.0f usec, configured %0.0f usec\n" -"Flags: %s%s%s%s%s%s\n" -"Properties:\n" -"%s" -msgstr "" - -#: ../src/utils/pactl.c:246 -#: ../src/utils/pactl.c:289 -#: ../src/utils/pactl.c:322 -#: ../src/utils/pactl.c:366 -#: ../src/utils/pactl.c:367 -#: ../src/utils/pactl.c:374 -#: ../src/utils/pactl.c:418 -#: ../src/utils/pactl.c:419 -#: ../src/utils/pactl.c:425 -#: ../src/utils/pactl.c:468 -#: ../src/utils/pactl.c:469 -#: ../src/utils/pactl.c:473 +"Source #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s%s%s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s%s%s\n" +"\tMonitor of Sink: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:303 ../src/utils/pactl.c:347 ../src/utils/pactl.c:382 +#: ../src/utils/pactl.c:419 ../src/utils/pactl.c:478 ../src/utils/pactl.c:479 +#: ../src/utils/pactl.c:489 ../src/utils/pactl.c:533 ../src/utils/pactl.c:534 +#: ../src/utils/pactl.c:540 ../src/utils/pactl.c:583 ../src/utils/pactl.c:584 +#: ../src/utils/pactl.c:591 msgid "n/a" msgstr "" -#: ../src/utils/pactl.c:263 +#: ../src/utils/pactl.c:321 #, c-format msgid "Failed to get module information: %s\n" msgstr "" -#: ../src/utils/pactl.c:281 +#: ../src/utils/pactl.c:339 #, c-format msgid "" -"*** Module #%u ***\n" -"Name: %s\n" -"Argument: %s\n" -"Usage counter: %s\n" -"Auto unload: %s\n" +"Module #%u\n" +"\tName: %s\n" +"\tArgument: %s\n" +"\tUsage counter: %s\n" +"\tProperties:\n" +"\t\t%s\n" msgstr "" -#: ../src/utils/pactl.c:298 +#: ../src/utils/pactl.c:358 #, c-format msgid "Failed to get client information: %s\n" msgstr "" -#: ../src/utils/pactl.c:316 +#: ../src/utils/pactl.c:376 #, c-format msgid "" -"*** Client #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Properties:\n" -"%s" +"Client #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" msgstr "" -#: ../src/utils/pactl.c:333 +#: ../src/utils/pactl.c:393 +#, fuzzy, c-format +msgid "Failed to get card information: %s\n" +msgstr "S'ha produït un error en obtenir l'ID de la màquina" + +#: ../src/utils/pactl.c:411 #, c-format -msgid "Failed to get sink input information: %s\n" +msgid "" +"Card #%u\n" +"\tName: %s\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" msgstr "" -#: ../src/utils/pactl.c:352 +#: ../src/utils/pactl.c:425 #, c-format -msgid "" -"*** Sink Input #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Client: %s\n" -"Sink: %u\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Volume: %s\n" -"Buffer Latency: %0.0f usec\n" -"Sink Latency: %0.0f usec\n" -"Resample method: %s\n" -"Properties:\n" -"%s" -msgstr "" - -#: ../src/utils/pactl.c:385 +msgid "\tProfiles:\n" +msgstr "" + +#: ../src/utils/pactl.c:431 +#, fuzzy, c-format +msgid "\tActive Profile: %s\n" +msgstr "Ha fallat la canonada: %s" + +#: ../src/utils/pactl.c:442 #, c-format -msgid "Failed to get source output information: %s\n" +msgid "Failed to get sink input information: %s\n" msgstr "" -#: ../src/utils/pactl.c:405 +#: ../src/utils/pactl.c:461 #, c-format msgid "" -"*** Source Output #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Client: %s\n" -"Source: %u\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Buffer Latency: %0.0f usec\n" -"Source Latency: %0.0f usec\n" -"Resample method: %s\n" -"Properties:\n" -"%s" -msgstr "" - -#: ../src/utils/pactl.c:436 +"Sink Input #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSink: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t %s\n" +"\t balance %0.2f\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSink Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:500 #, c-format -msgid "Failed to get sample information: %s\n" +msgid "Failed to get source output information: %s\n" msgstr "" -#: ../src/utils/pactl.c:455 +#: ../src/utils/pactl.c:520 #, c-format msgid "" -"*** Sample #%u ***\n" -"Name: %s\n" -"Volume: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Duration: %0.1fs\n" -"Size: %s\n" -"Lazy: %s\n" -"Filename: %s\n" -"Properties:\n" -"%s" -msgstr "" - -#: ../src/utils/pactl.c:481 +"Source Output #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSource: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSource Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:551 #, c-format -msgid "Failed to get autoload information: %s\n" +msgid "Failed to get sample information: %s\n" msgstr "" -#: ../src/utils/pactl.c:497 +#: ../src/utils/pactl.c:569 #, c-format msgid "" -"*** Autoload Entry #%u ***\n" -"Name: %s\n" -"Type: %s\n" -"Module: %s\n" -"Argument: %s\n" -msgstr "" - -#: ../src/utils/pactl.c:504 -msgid "sink" -msgstr "" - -#: ../src/utils/pactl.c:504 -msgid "source" -msgstr "" - -#: ../src/utils/pactl.c:511 -#: ../src/utils/pactl.c:521 +"Sample #%u\n" +"\tName: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tVolume: %s\n" +"\t %s\n" +"\t balance %0.2f\n" +"\tDuration: %0.1fs\n" +"\tSize: %s\n" +"\tLazy: %s\n" +"\tFilename: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:599 ../src/utils/pactl.c:609 #, c-format msgid "Failure: %s\n" msgstr "" -#: ../src/utils/pactl.c:545 +#: ../src/utils/pactl.c:633 #, c-format msgid "Failed to upload sample: %s\n" msgstr "" -#: ../src/utils/pactl.c:562 +#: ../src/utils/pactl.c:650 #, c-format msgid "Premature end of file\n" msgstr "" -#: ../src/utils/pactl.c:678 +#: ../src/utils/pactl.c:770 #, c-format msgid "" "%s [options] stat\n" @@ -1638,15 +1761,18 @@ msgid "" "%s [options] unload-module ID\n" "%s [options] suspend-sink [SINK] 1|0\n" "%s [options] suspend-source [SOURCE] 1|0\n" +"%s [options] set-card-profile [CARD] [PROFILE] \n" "\n" " -h, --help Show this help\n" " --version Show version\n" "\n" -" -s, --server=SERVER The name of the server to connect to\n" -" -n, --client-name=NAME How to call this client on the server\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" +" -n, --client-name=NAME How to call this client on the " +"server\n" msgstr "" -#: ../src/utils/pactl.c:729 +#: ../src/utils/pactl.c:822 #, c-format msgid "" "pactl %s\n" @@ -1654,57 +1780,66 @@ msgid "" "Linked with libpulse %s\n" msgstr "" -#: ../src/utils/pactl.c:768 +#: ../src/utils/pactl.c:861 #, c-format msgid "Please specify a sample file to load\n" msgstr "" -#: ../src/utils/pactl.c:790 +#: ../src/utils/pactl.c:883 #, c-format msgid "Failed to open sound file.\n" msgstr "" -#: ../src/utils/pactl.c:802 +#: ../src/utils/pactl.c:895 #, c-format msgid "You have to specify a sample name to play\n" msgstr "" -#: ../src/utils/pactl.c:814 +#: ../src/utils/pactl.c:907 #, c-format msgid "You have to specify a sample name to remove\n" msgstr "" -#: ../src/utils/pactl.c:822 +#: ../src/utils/pactl.c:915 #, c-format msgid "You have to specify a sink input index and a sink\n" msgstr "" -#: ../src/utils/pactl.c:831 +#: ../src/utils/pactl.c:924 #, c-format msgid "You have to specify a source output index and a source\n" msgstr "" -#: ../src/utils/pactl.c:845 +#: ../src/utils/pactl.c:938 #, c-format msgid "You have to specify a module name and arguments.\n" msgstr "" -#: ../src/utils/pactl.c:865 +#: ../src/utils/pactl.c:958 #, c-format msgid "You have to specify a module index\n" msgstr "" -#: ../src/utils/pactl.c:875 +#: ../src/utils/pactl.c:968 +#, c-format +msgid "" +"You may not specify more than one sink. You have to specify a boolean " +"value.\n" +msgstr "" + +#: ../src/utils/pactl.c:981 #, c-format -msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n" +msgid "" +"You may not specify more than one source. You have to specify a boolean " +"value.\n" msgstr "" -#: ../src/utils/pactl.c:888 +#: ../src/utils/pactl.c:993 #, c-format -msgid "You may not specify more than one source. You have to specify at least one boolean value.\n" +msgid "You have to specify a card name/index and a profile name\n" msgstr "" -#: ../src/utils/pactl.c:904 +#: ../src/utils/pactl.c:1008 #, c-format msgid "No valid command specified.\n" msgstr "" @@ -1716,7 +1851,8 @@ msgid "" "\n" " -d Show current PulseAudio data attached to X11 display (default)\n" " -e Export local PulseAudio data to X11 display\n" -" -i Import PulseAudio data from X11 display to local environment variables and cookie file.\n" +" -i Import PulseAudio data from X11 display to local environment " +"variables and cookie file.\n" " -r Remove PulseAudio data from X11 display\n" msgstr "" @@ -1798,19 +1934,17 @@ msgstr "" msgid "Daemon not responding." msgstr "" -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 -#: ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 -#: ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -1840,11 +1974,15 @@ msgid "" "\n" " -v, --verbose Enable verbose operation\n" "\n" -" -s, --server=SERVER The name of the server to connect to\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" " -d, --device=DEVICE The name of the sink to connect to\n" -" -n, --client-name=NAME How to call this client on the server\n" -" --stream-name=NAME How to call this stream on the server\n" -" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n" +" -n, --client-name=NAME How to call this client on the " +"server\n" +" --stream-name=NAME How to call this stream on the " +"server\n" +" --volume=VOLUME Specify the initial (linear) volume " +"in range 0...65536\n" " --channel-map=CHANNELMAP Set the channel map to the use\n" msgstr "" @@ -1876,8 +2014,26 @@ msgstr "" msgid "Using sample spec '%s'\n" msgstr "" -#: ../src/pulsecore/lock-autospawn.c:126 -#: ../src/pulsecore/lock-autospawn.c:207 +#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207 msgid "Cannot access autospawn lock." msgstr "" +#~ msgid "" +#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" +#~ "For enabling real-time scheduling please acquire the appropriate " +#~ "PolicyKit priviliges, or become a member of '" +#~ msgstr "" +#~ "' i PolicyKit ha denegat els permissos. S'està lliberant SUID. \n" +#~ "Per habilitar la prioritat en temps real, s'ha d'adquirir els permissos " +#~ "de PolicyKit, o pertanyer a '" + +#~ msgid "" +#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this " +#~ "user." +#~ msgstr "" +#~ "', o incrementar els límits de recursos RLIMIT_NICE/RLIMIT_RTPRIO per a " +#~ "aquest usuari." + +#~ msgid "Default sink name (%s) does not exist in name register." +#~ msgstr "" +#~ "El nom per omissió del conducte (%s) no existeix en el registre de noms." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-10-19 22:31+0200\n" "Last-Translator: Petr Kovar <pknbe@volny.cz>\n" "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n" @@ -711,7 +711,7 @@ msgstr "Rušení superuživatelských oprávnění." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "Schopnosti úspěšně omezeny na CAP_SYS_NICE." -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -915,34 +915,34 @@ msgstr "Horní zadní levý" msgid "Top Rear Right" msgstr "Horní zadní pravý" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 #, fuzzy msgid "(invalid)" msgstr "Neplatné" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -1034,6 +1034,39 @@ msgstr "Neznámý chybový kód" msgid "No such extension" msgstr "Takové rozšíření neexistuje" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() selhalo" @@ -1960,17 +1993,17 @@ msgstr "Nezdařilo se zabít démona PulseAudio." msgid "Daemon not responding." msgstr "Démon neodpovídá." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-10-22 00:58+0100\n" "Last-Translator: Fabian Affolter <fab@fedoraproject.org>\n" "Language-Team: German <fedora-trans-de@redhat.com>\n" @@ -727,7 +727,7 @@ msgstr "Gebe Root-Privilegien auf." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "Fähigkeiten erfolgreich auf CAP_SYS_NICE reduziert." -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -931,33 +931,33 @@ msgstr "Oben Hinten Links" msgid "Top Rear Right" msgstr "Oben Hinten Rechts" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(ungültig)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -1049,6 +1049,39 @@ msgstr "Unbekannter Fehlercode" msgid "No such extension" msgstr "Erweiterung nicht vorhanden" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() fehlgeschlagen" @@ -2042,17 +2075,17 @@ msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen." msgid "Daemon not responding." msgstr "Daemon antwortet nicht." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: el\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-08-22 19:40+0300\n" "Last-Translator: Dimitris Glezos <dimitris@glezos.com>\n" "Language-Team: Greek <fedora-trans-el@redhat.com>\n" @@ -645,7 +645,7 @@ msgstr "" msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "" -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "" @@ -849,33 +849,33 @@ msgstr "" msgid "Top Rear Right" msgstr "" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -967,6 +967,39 @@ msgstr "" msgid "No such extension" msgstr "" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "" @@ -1793,17 +1826,17 @@ msgstr "" msgid "Daemon not responding." msgstr "" -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PulseAudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2009-01-16 09:25-0300\n" "Last-Translator: daniel cabrera <h.daniel.cabrera@gmail.com>\n" "Language-Team: Spanish <fedora-trans-es@redhat.com>\n" @@ -755,7 +755,7 @@ msgstr "Abandonando privilegios de root." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "Capacidades limitadas con éxito para CAP_SYS_NICE-" -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -959,33 +959,33 @@ msgstr "Posterior izquierdo superior" msgid "Top Rear Right" msgstr "Posterior derecho superior" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(inválido)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -1077,6 +1077,39 @@ msgstr "Código de error desconocido" msgid "No such extension" msgstr "No existe tal extensión" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() falló" @@ -2089,17 +2122,17 @@ msgstr "Error al intentar detener el demonio de PulseAudio." msgid "Daemon not responding." msgstr "El demonio no responde." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: git trunk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-12-01 18:40+0200\n" "Last-Translator: Timo Jyrinki <timo.jyrinki@iki.fi>\n" "Language-Team: Finnish <laatu@lokalisointi.org>\n" @@ -652,7 +652,7 @@ msgstr "Pudotetaan pääkäyttäjän oikeudet." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "" -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -856,33 +856,33 @@ msgstr "Vasen ylä taka" msgid "Top Rear Right" msgstr "Oikea ylä taka" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(virheellinen)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -974,6 +974,39 @@ msgstr "Tuntematon virhekoodi" msgid "No such extension" msgstr "Ei kyseisenlaista laajennusta" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() epäonnistui" @@ -1883,17 +1916,17 @@ msgstr "PulseAudio-taustaprosessin lopettaminen epäonnistui." msgid "Daemon not responding." msgstr "Taustaprosessi ei vastaa." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "" @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio trunk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-10-18 20:34+0200\n" "Last-Translator: Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>\n" "Language-Team: Français <fedora-trans-fr@redhat.com>\n" @@ -759,7 +759,7 @@ msgstr "Abandon des permissions root." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "Limitation des capacités à CAP_SYS_NICE réussie." -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -963,33 +963,33 @@ msgstr "Arrière gauche haut" msgid "Top Rear Right" msgstr "Arrière droit haut" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(invalide)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -1081,6 +1081,39 @@ msgstr "Code d'erreur inconnu" msgid "No such extension" msgstr "Aucune extension de ce type" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "Échec de XOpenDisplay()" @@ -2112,17 +2145,17 @@ msgstr "Impossible de tuer le démon PulseAudio." msgid "Daemon not responding." msgstr "Le démon ne répond pas." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select() : %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read() : %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write() : %s" @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: pl\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" -"PO-Revision-Date: 2009-01-09 22:17+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" +"PO-Revision-Date: 2009-02-05 22:09+0100\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <pl@li.org>\n" "MIME-Version: 1.0\n" @@ -318,7 +318,7 @@ msgstr "Uruchamianie na komputerze: %s" #: ../src/daemon/main.c:828 #, c-format msgid "Found %u CPUs." -msgstr "" +msgstr "Znaleziono %u procesorów." #: ../src/daemon/main.c:830 #, c-format @@ -740,7 +740,7 @@ msgstr "Porzucanie uprawnień roota." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "Pomyślnie ograniczono możliwości do CAP_SYS_NICE." -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -944,35 +944,35 @@ msgstr "Górny tylny lewy" msgid "Top Rear Right" msgstr "Górny tylny prawy" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(nieprawidłowe)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" -msgstr "" +msgstr "Stereo" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" -msgstr "" +msgstr "Surround 4.0" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" -msgstr "" +msgstr "Surround 4.1" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" -msgstr "" +msgstr "Surround 5.0" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" -msgstr "" +msgstr "Surround 5.1" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" -msgstr "" +msgstr "Surround 7.1" #: ../src/pulse/error.c:43 msgid "OK" @@ -1062,6 +1062,39 @@ msgstr "Nieznany kod błędu" msgid "No such extension" msgstr "Nie ma takiego rozszerzenia" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "Przestarzała funkcjonalność" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "Brak implementacji" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "%s %uch %uHz" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "%0.1f GiB" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "%0.1f MiB" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "%0.1f KiB" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "%u B" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() nie powiodło się" @@ -1317,7 +1350,7 @@ msgstr "" " -v, --verbose Wyświetla więcej informacji o " "działaniu\n" "\n" -" -s, --server=SERWER Nazwa serwera do połączenia się z\n" +" -s, --server=SERWER Nazwa serwera do połączenia się\n" " -d, --device=URZĄDZENIE Nazwa odpływu/źródła do połączenia " "się z\n" " -n, --client-name=NAZWA Jak nazywać tego klienta na " @@ -1503,7 +1536,7 @@ msgstr "" "\n" " -h, --help Wyświetla tę pomoc\n" " --version Wyświetla wersję\n" -" -s, --server=SERWER Nazwa serwera do połączenia się z\n" +" -s, --server=SERWER Nazwa serwera do połączenia się\n" "\n" #: ../src/utils/pasuspender.c:251 @@ -1571,7 +1604,7 @@ msgid "Failed to get sink information: %s\n" msgstr "Uzyskanie informacji o odpływie nie powiodło się: %s\n" #: ../src/utils/pactl.c:191 -#, fuzzy, c-format +#, c-format msgid "" "Sink #%u\n" "\tState: %s\n" @@ -1591,18 +1624,23 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Odpływ #%u ***\n" -"Nazwa: %s\n" -"Sterownik: %s\n" -"Określenie próbki: %s\n" -"Mapa kanałów: %s\n" -"Właściciel modułu: %u\n" -"Poziom głośności: %s\n" -"Źródło monitora: %s\n" -"Opóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n" -"Flagi: %s%s%s%s%s%s\n" -"Właściwości:\n" -"%s" +"Odpływ #%u\n" +"\tStan: %s\n" +"\tNazwa: %s\n" +"\tOpis: %s\n" +"\tSterownik: %s\n" +"\tOkreślenie próbki: %s\n" +"\tMapa kanałów: %s\n" +"\tWłaściciel modułu: %u\n" +"\tWyciszenie: %s\n" +"\tPoziom głośności: %s%s%s\n" +"\t balans %0.2f\n" +"\tGłośność podstawowa: %s%s%s\n" +"\tŹródło monitora: %s\n" +"\tOpóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n" +"\tFlagi: %s%s%s%s%s%s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:255 #, c-format @@ -1610,7 +1648,7 @@ msgid "Failed to get source information: %s\n" msgstr "Uzyskanie informacji o źródle nie powiodło się: %s\n" #: ../src/utils/pactl.c:271 -#, fuzzy, c-format +#, c-format msgid "" "Source #%u\n" "\tState: %s\n" @@ -1630,18 +1668,23 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Źródło #%u ***\n" -"Nazwa: %s\n" -"Sterownik: %s\n" -"Określenie próbki: %s\n" -"Mapa kanałów: %s\n" -"Właściciel modułu: %u\n" -"Poziom głośności: %s\n" -"Monitor odpływu: %s\n" -"Opóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n" -"Flagi: %s%s%s%s%s%s\n" -"Właściwości:\n" -"%s" +"Źródło #%u\n" +"\tStan: %s\n" +"\tNazwa: %s\n" +"\tOpis: %s\n" +"\tSterownik: %s\n" +"\tOkreślenie próbki: %s\n" +"\tMapa kanałów: %s\n" +"\tWłaściciel modułu: %u\n" +"\tWyciszenie: %s\n" +"\tPoziom głośności: %s%s%s\n" +"\t balans %0.2f\n" +"\tGłośność podstawowa: %s%s%s\n" +"\tMonitor odpływu: %s\n" +"\tOpóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n" +"\tFlagi: %s%s%s%s%s%s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:303 ../src/utils/pactl.c:347 ../src/utils/pactl.c:382 #: ../src/utils/pactl.c:419 ../src/utils/pactl.c:478 ../src/utils/pactl.c:479 @@ -1657,7 +1700,7 @@ msgid "Failed to get module information: %s\n" msgstr "Uzyskanie informacji o module nie powiodło się: %s\n" #: ../src/utils/pactl.c:339 -#, fuzzy, c-format +#, c-format msgid "" "Module #%u\n" "\tName: %s\n" @@ -1666,11 +1709,12 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Moduł #%u ***\n" -"Nazwa: %s\n" -"Parametr: %s\n" -"Liczniki użycia: %s\n" -"Automatyczne usuwanie: %s\n" +"Moduł #%u\n" +"\tNazwa: %s\n" +"\tParametr: %s\n" +"\tLicznik użycia: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:358 #, c-format @@ -1678,7 +1722,7 @@ msgid "Failed to get client information: %s\n" msgstr "Uzyskanie informacji o kliencie nie powiodło się: %s\n" #: ../src/utils/pactl.c:376 -#, fuzzy, c-format +#, c-format msgid "" "Client #%u\n" "\tDriver: %s\n" @@ -1686,20 +1730,19 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Klient #%u ***\n" -"Sterownik: %s\n" -"Właściciel modułu: %s\n" -"Właściwości:\n" -"%s" +"Klient #%u\n" +"\tSterownik: %s\n" +"\tWłaściciel modułu: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:393 -#, fuzzy, c-format +#, c-format msgid "Failed to get card information: %s\n" -msgstr "" -"Uzyskanie informacji o automatycznym wczytywaniu nie powiodło się: %s\n" +msgstr "Uzyskanie informacji o karcie nie powiodło się: %s\n" #: ../src/utils/pactl.c:411 -#, fuzzy, c-format +#, c-format msgid "" "Card #%u\n" "\tName: %s\n" @@ -1708,21 +1751,22 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Klient #%u ***\n" -"Sterownik: %s\n" -"Właściciel modułu: %s\n" -"Właściwości:\n" -"%s" +"Karta #%u\n" +"\tNazwa: %s\n" +"\tSterownik: %s\n" +"\tWłaściciel modułu: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:425 #, c-format msgid "\tProfiles:\n" -msgstr "" +msgstr "\tProfile:\n" #: ../src/utils/pactl.c:431 -#, fuzzy, c-format +#, c-format msgid "\tActive Profile: %s\n" -msgstr "potok nie powiódł się: %s" +msgstr "\tAktywny profil: %s\n" #: ../src/utils/pactl.c:442 #, c-format @@ -1730,7 +1774,7 @@ msgid "Failed to get sink input information: %s\n" msgstr "Uzyskanie informacji o wejściu odpływu nie powiodło się: %s\n" #: ../src/utils/pactl.c:461 -#, fuzzy, c-format +#, c-format msgid "" "Sink Input #%u\n" "\tDriver: %s\n" @@ -1749,19 +1793,22 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Odpływ wejścia #%u ***\n" -"Sterownik: %s\n" -"Właściciel modułu: %s\n" -"Klient: %s\n" -"Odpływ: %u\n" -"Określenie próbki: %s\n" -"Mapa kanałów: %s\n" -"Poziom głośności: %s\n" -"Opóźnienie bufora: %0.0f usekundy\n" -"Opóźnienie odpływu: %0.0f usekundy\n" -"Metoda resamplingu: %s\n" -"Właściwości:\n" -"%s" +"Odpływ wejścia #%u\n" +"\tSterownik: %s\n" +"\tWłaściciel modułu: %s\n" +"\tKlient: %s\n" +"\tOdpływ: %u\n" +"\tOkreślenie próbki: %s\n" +"\tMapa kanałów: %s\n" +"\tWyciszenie: %s\n" +"\tPoziom głośności: %s\n" +"\t %s\n" +"\t balans %0.2f\n" +"\tOpóźnienie bufora: %0.0f usekundy\n" +"\tOpóźnienie odpływu: %0.0f usekundy\n" +"\tMetoda resamplingu: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:500 #, c-format @@ -1769,7 +1816,7 @@ msgid "Failed to get source output information: %s\n" msgstr "Uzyskanie informacji o wyjściu źródła nie powiodło się: %s\n" #: ../src/utils/pactl.c:520 -#, fuzzy, c-format +#, c-format msgid "" "Source Output #%u\n" "\tDriver: %s\n" @@ -1784,18 +1831,18 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Źródło wyjścia #%u ***\n" -"Sterownik: %s\n" -"Właściciel modułu: %s\n" -"Klient: %s\n" -"Źródło: %u\n" -"Określenie próbki: %s\n" -"Mapa kanałów: %s\n" -"Opóźnienie bufora: %0.0f usekundy\n" -"Opóźnienie źródła: %0.0f usekundy\n" -"Metoda resamplingu: %s\n" -"Właściwości:\n" -"%s" +"Źródło wyjścia #%u\n" +"\tSterownik: %s\n" +"\tWłaściciel modułu: %s\n" +"\tKlient: %s\n" +"\tŹródło: %u\n" +"\tOkreślenie próbki: %s\n" +"\tMapa kanałów: %s\n" +"\tOpóźnienie bufora: %0.0f usekundy\n" +"\tOpóźnienie źródła: %0.0f usekundy\n" +"\tMetoda resamplingu: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:551 #, c-format @@ -1803,7 +1850,7 @@ msgid "Failed to get sample information: %s\n" msgstr "Uzyskanie informacji o przykładzie nie powiodło się: %s\n" #: ../src/utils/pactl.c:569 -#, fuzzy, c-format +#, c-format msgid "" "Sample #%u\n" "\tName: %s\n" @@ -1819,17 +1866,19 @@ msgid "" "\tProperties:\n" "\t\t%s\n" msgstr "" -"*** Próbka #%u ***\n" -"Nazwa: %s\n" -"Poziom głośności: %s\n" -"Określenie próbki: %s\n" -"Mapa kanałów: %s\n" -"Czas trwania: %0.1fs\n" -"Rozmiar: %s\n" -"Lazy: %s\n" -"Nazwa pliku: %s\n" -"Właściwości:\n" -"%s" +"Próbka #%u\n" +"\tNazwa: %s\n" +"\tOkreślenie próbki: %s\n" +"\tMapa kanałów: %s\n" +"\tPoziom głośności: %s\n" +"\t %s\n" +"\t balans %0.2f\n" +"\tCzas trwania: %0.1fs\n" +"\tRozmiar: %s\n" +"\tLazy: %s\n" +"\tNazwa pliku: %s\n" +"\tWłaściwości:\n" +"\t\t%s\n" #: ../src/utils/pactl.c:599 ../src/utils/pactl.c:609 #, c-format @@ -1847,7 +1896,7 @@ msgid "Premature end of file\n" msgstr "Przedwczesny koniec pliku\n" #: ../src/utils/pactl.c:770 -#, fuzzy, c-format +#, c-format msgid "" "%s [options] stat\n" "%s [options] list\n" @@ -1883,11 +1932,12 @@ msgstr "" "%s [opcje] unload-module IDENTYFIKATOR\n" "%s [opcje] suspend-sink [ODPŁYW] 1|0\n" "%s [opcje] suspend-source [ŹRÓDŁO] 1|0\n" +"%s [opcje] set-card-profile [KARTA] [PROFIL] \n" "\n" " -h, --help Wyświetla tę pomoc\n" " --version Wyświetla wersję\n" "\n" -" -s, --server=SERWER Nazwa serwera do połączenia się z\n" +" -s, --server=SERWER Nazwa serwera do połączenia się\n" " -n, --client-name=NAZWA Jak nazwać tego klienta na serwerze\n" #: ../src/utils/pactl.c:822 @@ -1942,27 +1992,25 @@ msgid "You have to specify a module index\n" msgstr "Należy podać indeks modułu\n" #: ../src/utils/pactl.c:968 -#, fuzzy, c-format +#, c-format msgid "" "You may not specify more than one sink. You have to specify a boolean " "value.\n" msgstr "" -"Nie można podać więcej niż jednego odpływu. Należy podać co najmniej jedną " -"wartość logiczną.\n" +"Nie można podać więcej niż jednego odpływu. Należy podać wartość logiczną.\n" #: ../src/utils/pactl.c:981 -#, fuzzy, c-format +#, c-format msgid "" "You may not specify more than one source. You have to specify a boolean " "value.\n" msgstr "" -"Nie można podać więcej niż jednego źródła. Należy podać co najmniej jedną " -"wartość logiczną.\n" +"Nie można podać więcej niż jednego źródła. Należy podać wartość logiczną.\n" #: ../src/utils/pactl.c:993 -#, fuzzy, c-format +#, c-format msgid "You have to specify a card name/index and a profile name\n" -msgstr "Należy podać indeks odpływu wejścia i odpływ\n" +msgstr "Należy podać nazwę karty/indeks i nazwę profilu\n" #: ../src/utils/pactl.c:1008 #, c-format @@ -2066,17 +2114,17 @@ msgstr "Zniszczenie demona PulseAudio nie powiodło się." msgid "Daemon not responding." msgstr "Demon nie odpowiada." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -2125,8 +2173,8 @@ msgstr "" " -v, --verbose Wyświetla więcej informacji o " "działaniach\n" "\n" -" -s, --server=SERWER Nazwa serwera do połączenia się z\n" -" -d, --device=URZĄDZENIE Nazwa odpływu do połączenia się z\n" +" -s, --server=SERWER Nazwa serwera do połączenia się\n" +" -d, --device=URZĄDZENIE Nazwa odpływu do połączenia się\n" " -n, --client-name=NAZWA Jak nazwać tego klienta na serwerze\n" " --stream-name=NAZWA Jak nazwać ten strumień na serwerze\n" " --volume=POZIOMGŁOŚNOŚCI Określa początkowy (liniowy) poziom " @@ -2167,34 +2215,3 @@ msgstr "Używanie przykładowej specyfikacji \"%s\"\n" #: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207 msgid "Cannot access autospawn lock." msgstr "Nie można uzyskać dostępu do blokady automatycznego wznawiania." - -#~ msgid "Default sink name (%s) does not exist in name register." -#~ msgstr "Domyślna nazwa odpływu (%s) nie istnieje w rejestrze nazw." - -#~ msgid "Buffer overrun, dropping incoming data\n" -#~ msgstr "Przepełniono bufor, porzucanie danych przychodzących\n" - -#~ msgid "pa_stream_drop() failed: %s\n" -#~ msgstr "pa_stream_drop() nie powiodło się: %s\n" - -#~ msgid "muted" -#~ msgstr "wyciszone" - -#~ msgid "" -#~ "*** Autoload Entry #%u ***\n" -#~ "Name: %s\n" -#~ "Type: %s\n" -#~ "Module: %s\n" -#~ "Argument: %s\n" -#~ msgstr "" -#~ "*** Wpis automatycznego wczytywania #%u ***\n" -#~ "Nazwa: %s\n" -#~ "Typ: %s\n" -#~ "Moduł: %s\n" -#~ "Parametr: %s\n" - -#~ msgid "sink" -#~ msgstr "odpływ" - -#~ msgid "source" -#~ msgstr "źródło" diff --git a/po/pt_BR.po b/po/pt_BR.po index 31016254..b285288d 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-11-21 01:21-0300\n" "Last-Translator: Henrique (LonelySpooky) Junior <lspooky@fedoraproject.org>\n" "Language-Team: Brazilian-Portuguese <fedora-trans-pt_br@redhat.com>\n" @@ -743,7 +743,7 @@ msgstr "Descartando os privilégios de root." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "As capacidades foram limitadas com sucesso para CAP_SYS_NICE." -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -947,33 +947,33 @@ msgstr "Posterior Superior Esquerdo" msgid "Top Rear Right" msgstr "Posterior Superior Direito" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(Inválido)" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -1065,6 +1065,39 @@ msgstr "Código de erro desconhecido" msgid "No such extension" msgstr "Não existe tal extensão" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() falhou" @@ -2068,17 +2101,17 @@ msgstr "Falha em cancelar o daemon do PulseAudio." msgid "Daemon not responding." msgstr "Daemon não responde." -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: pulseaudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-01-28 04:30+0100\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2008-09-05 18:24+0100\n" "Last-Translator: Daniel Nylander <po@danielnylander.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" @@ -649,7 +649,7 @@ msgstr "Släpper root-behörighet." msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "" -#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:742 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "Mono" @@ -853,34 +853,34 @@ msgstr "" msgid "Top Rear Right" msgstr "" -#: ../src/pulse/channelmap.c:473 ../src/pulse/sample.c:152 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:189 -#: ../src/pulse/volume.c:209 ../src/pulse/volume.c:239 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 #, fuzzy msgid "(invalid)" msgstr "Ogiltig" -#: ../src/pulse/channelmap.c:746 +#: ../src/pulse/channelmap.c:808 msgid "Stereo" msgstr "" -#: ../src/pulse/channelmap.c:751 +#: ../src/pulse/channelmap.c:813 msgid "Surround 4.0" msgstr "" -#: ../src/pulse/channelmap.c:757 +#: ../src/pulse/channelmap.c:819 msgid "Surround 4.1" msgstr "" -#: ../src/pulse/channelmap.c:763 +#: ../src/pulse/channelmap.c:825 msgid "Surround 5.0" msgstr "" -#: ../src/pulse/channelmap.c:769 +#: ../src/pulse/channelmap.c:831 msgid "Surround 5.1" msgstr "" -#: ../src/pulse/channelmap.c:776 +#: ../src/pulse/channelmap.c:838 msgid "Surround 7.1" msgstr "" @@ -972,6 +972,39 @@ msgstr "Okänd felkod" msgid "No such extension" msgstr "" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay() misslyckades" @@ -1804,17 +1837,17 @@ msgstr "" msgid "Daemon not responding." msgstr "" -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select(): %s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read(): %s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write(): %s" diff --git a/po/zh_CN.po b/po/zh_CN.po index 1045b607..0ec230a8 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -3,28 +3,34 @@ # This file is distributed under the same license as the package. # 闫丰刚 (sainry)<sainry@gmail.com> 2008 # 闫丰刚 <sainry@gmail.com>, 2009. -# -# +# +# msgid "" msgstr "" "Project-Id-Version: PulseAudio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-26 01:41+0000\n" +"POT-Creation-Date: 2009-02-04 21:48+0100\n" "PO-Revision-Date: 2009-01-24 12:47+0800\n" "Last-Translator: 王泽国 <zak.zeguo.wang@gmail.com>\n" "Language-Team: Chinese/Simplified\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit" +"Content-Transfer-Encoding: 8bit\n" -#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197 -msgid "Failed to add bind-now-loader." -msgstr "添加bind-now-loader失败。" +#: ../src/daemon/ltdl-bind-now.c:124 +#, fuzzy +msgid "Failed to find original lt_dlopen loader." +msgstr "查找原始dlopen加载器失败。" -#: ../src/daemon/ltdl-bind-now.c:184 -msgid "Failed to find original dlopen loader." +#: ../src/daemon/ltdl-bind-now.c:129 +#, fuzzy +msgid "Failed to allocate new dl loader." msgstr "查找原始dlopen加载器失败。" +#: ../src/daemon/ltdl-bind-now.c:142 +msgid "Failed to add bind-now-loader." +msgstr "添加bind-now-loader失败。" + #: ../src/daemon/polkit.c:55 #, c-format msgid "Cannot connect to system bus: %s" @@ -146,267 +152,256 @@ msgstr "此平台不支持system-wide模式。" msgid "setrlimit(%s, (%u, %u)) failed: %s" msgstr "setrlimit(%s, (%u, %u)) 失败:%s" -#: ../src/daemon/main.c:425 +#: ../src/daemon/main.c:429 msgid "Failed to parse command line." msgstr "分析命令行失败。" -#: ../src/daemon/main.c:441 +#: ../src/daemon/main.c:451 #, c-format msgid "We're in the group '%s', allowing high-priority scheduling." msgstr "我们在'%s'组中,允许高优先级调度。" -#: ../src/daemon/main.c:448 +#: ../src/daemon/main.c:458 #, c-format msgid "We're in the group '%s', allowing real-time scheduling." msgstr "我们在'%s'组中,允许实时调度。" -#: ../src/daemon/main.c:456 +#: ../src/daemon/main.c:466 msgid "PolicyKit grants us acquire-high-priority privilege." msgstr "PolicyKit授予我们“获取高优先级”权限。" -#: ../src/daemon/main.c:459 +#: ../src/daemon/main.c:469 msgid "PolicyKit refuses acquire-high-priority privilege." msgstr "PolicyKit拒绝“获取高优先级”权限。" -#: ../src/daemon/main.c:464 +#: ../src/daemon/main.c:474 msgid "PolicyKit grants us acquire-real-time privilege." msgstr "PolicyKit授予我们“获取实时”权限。" -#: ../src/daemon/main.c:467 +#: ../src/daemon/main.c:477 msgid "PolicyKit refuses acquire-real-time privilege." msgstr "PolicyKit拒绝我们“获取实时”权限。" -#: ../src/daemon/main.c:479 +#: ../src/daemon/main.c:506 +#, fuzzy msgid "" -"Called SUID root and real-time/high-priority scheduling was requested in the " -"configuration. However, we lack the necessary priviliges:\n" +"Called SUID root and real-time and/or high-priority scheduling was requested " +"in the configuration. However, we lack the necessary privileges:\n" "We are not in group '" -msgstr "此配置需要调用SUID root和实时/高优先级调度。但是我们没有所需的权限:\n" +msgstr "" +"此配置需要调用SUID root和实时/高优先级调度。但是我们没有所需的权限:\n" "我们不属该组" -#: ../src/daemon/main.c:480 -msgid "" -"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" -"For enabling real-time scheduling please acquire the appropriate PolicyKit " -"priviliges, or become a member of '" -msgstr "而且PolicyKit拒绝授予我们权限。再次取消SUID。\n" -"要启用实时调度,请取得适应的PolicyKit权限,或者成为组成员'" - -#: ../src/daemon/main.c:481 -msgid "" -"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user." -msgstr "',或者提高本用户的RLIMIT_NICE/RLIMIT_RTPRIO资源上限。" - -#: ../src/daemon/main.c:497 +#: ../src/daemon/main.c:530 msgid "" "High-priority scheduling enabled in configuration but not allowed by policy." msgstr "配置中已启用高优先级调度,但策略未允许。" -#: ../src/daemon/main.c:522 +#: ../src/daemon/main.c:559 msgid "Successfully increased RLIMIT_RTPRIO" msgstr "提高RLIMIT_RTPRIO成功。" -#: ../src/daemon/main.c:525 +#: ../src/daemon/main.c:562 #, c-format msgid "RLIMIT_RTPRIO failed: %s" msgstr "RLIMIT_RTPRIO失败:%s" -#: ../src/daemon/main.c:532 +#: ../src/daemon/main.c:569 msgid "Giving up CAP_NICE" msgstr "正在放弃CAP_NICE" -#: ../src/daemon/main.c:539 +#: ../src/daemon/main.c:576 msgid "" "Real-time scheduling enabled in configuration but not allowed by policy." msgstr "配置中已启用实时调度,但策略未允许。" -#: ../src/daemon/main.c:597 +#: ../src/daemon/main.c:637 msgid "Daemon not running" msgstr "后台程序没有运行" -#: ../src/daemon/main.c:599 +#: ../src/daemon/main.c:639 #, c-format msgid "Daemon running as PID %u" msgstr "后台程序正在运行,PID %u" -#: ../src/daemon/main.c:609 +#: ../src/daemon/main.c:649 #, c-format msgid "Failed to kill daemon: %s" msgstr "杀死后台程序失败:%s" -#: ../src/daemon/main.c:627 +#: ../src/daemon/main.c:667 msgid "" "This program is not intended to be run as root (unless --system is " "specified)." msgstr "不应以root身份运行本程序(除非指定 --system)。" -#: ../src/daemon/main.c:629 -msgid "Root priviliges required." +#: ../src/daemon/main.c:669 +#, fuzzy +msgid "Root privileges required." msgstr "需要root权限。" -#: ../src/daemon/main.c:634 +#: ../src/daemon/main.c:674 msgid "--start not supported for system instances." msgstr "系统实例不支持 --start。" -#: ../src/daemon/main.c:639 +#: ../src/daemon/main.c:679 msgid "Running in system mode, but --disallow-exit not set!" msgstr "正在以系统模式运行,但是 --disallow-exit 未设定!" -#: ../src/daemon/main.c:642 +#: ../src/daemon/main.c:682 msgid "Running in system mode, but --disallow-module-loading not set!" msgstr "正在以系统模式运行,但是 --disallow-module-loading 未设定!" -#: ../src/daemon/main.c:645 +#: ../src/daemon/main.c:685 msgid "Running in system mode, forcibly disabling SHM mode!" msgstr "正在以系统模式运行,强制禁用SHM模式!" -#: ../src/daemon/main.c:650 +#: ../src/daemon/main.c:690 msgid "Running in system mode, forcibly disabling exit idle time!" msgstr "正在以系统模式运行,强制禁用退出空闲时间!" -#: ../src/daemon/main.c:677 +#: ../src/daemon/main.c:717 msgid "Failed to acquire stdio." msgstr "获取stdio失败。" -#: ../src/daemon/main.c:683 +#: ../src/daemon/main.c:723 #, c-format msgid "pipe failed: %s" msgstr "管道失败:%s" -#: ../src/daemon/main.c:688 +#: ../src/daemon/main.c:728 #, c-format msgid "fork() failed: %s" msgstr "fork()失败:%s" -#: ../src/daemon/main.c:702 +#: ../src/daemon/main.c:742 #, c-format msgid "read() failed: %s" msgstr "read()失败:%s" -#: ../src/daemon/main.c:708 +#: ../src/daemon/main.c:748 msgid "Daemon startup failed." msgstr "后台程序启动失败。" -#: ../src/daemon/main.c:710 +#: ../src/daemon/main.c:750 msgid "Daemon startup successful." msgstr "后台程序启动成功。" -#: ../src/daemon/main.c:780 +#: ../src/daemon/main.c:820 #, c-format msgid "This is PulseAudio %s" msgstr "这是 PulseAudio %s" -#: ../src/daemon/main.c:781 +#: ../src/daemon/main.c:821 #, c-format msgid "Compilation host: %s" msgstr "编译主机:%s" -#: ../src/daemon/main.c:782 +#: ../src/daemon/main.c:822 #, c-format msgid "Compilation CFLAGS: %s" msgstr "编译CFLAGS:%s" -#: ../src/daemon/main.c:785 +#: ../src/daemon/main.c:825 #, c-format msgid "Running on host: %s" msgstr "正在主机上运行:%s" -#: ../src/daemon/main.c:788 +#: ../src/daemon/main.c:828 +#, c-format +msgid "Found %u CPUs." +msgstr "" + +#: ../src/daemon/main.c:830 #, c-format msgid "Page size is %lu bytes" msgstr "页面大小为%lu字节" -#: ../src/daemon/main.c:791 +#: ../src/daemon/main.c:833 msgid "Compiled with Valgrind support: yes" msgstr "编译启用Valgrind支持:是" -#: ../src/daemon/main.c:793 +#: ../src/daemon/main.c:835 msgid "Compiled with Valgrind support: no" msgstr "编译启用Valgrind支持:否" -#: ../src/daemon/main.c:796 +#: ../src/daemon/main.c:838 #, c-format msgid "Running in valgrind mode: %s" msgstr "正在以valgrind模式运行:%s" -#: ../src/daemon/main.c:799 +#: ../src/daemon/main.c:841 msgid "Optimized build: yes" msgstr "优化生成:是" -#: ../src/daemon/main.c:801 +#: ../src/daemon/main.c:843 msgid "Optimized build: no" msgstr "优化生成:否" -#: ../src/daemon/main.c:805 +#: ../src/daemon/main.c:847 msgid "Failed to get machine ID" msgstr "获取machine ID失败" -#: ../src/daemon/main.c:808 +#: ../src/daemon/main.c:850 #, c-format msgid "Machine ID is %s." msgstr "machine ID是%s。" -#: ../src/daemon/main.c:813 +#: ../src/daemon/main.c:855 #, c-format msgid "Using runtime directory %s." msgstr "正在使用运行时文件夹%s。" -#: ../src/daemon/main.c:818 +#: ../src/daemon/main.c:860 #, c-format msgid "Using state directory %s." msgstr "正在使用状态文件夹%s。" -#: ../src/daemon/main.c:821 +#: ../src/daemon/main.c:863 #, c-format msgid "Running in system mode: %s" msgstr "正在以系统模式运行:%s" -#: ../src/daemon/main.c:836 +#: ../src/daemon/main.c:878 msgid "pa_pid_file_create() failed." msgstr "pa_pid_file_create()失败。" -#: ../src/daemon/main.c:848 +#: ../src/daemon/main.c:890 msgid "Fresh high-resolution timers available! Bon appetit!" msgstr "新鲜的高分辨率计时器开锅了!吃个饱!" -#: ../src/daemon/main.c:850 +#: ../src/daemon/main.c:892 msgid "" "Dude, your kernel stinks! The chef's recommendation today is Linux with high-" "resolution timers enabled!" -msgstr "" -"老兄,你的内核真臭!现在流行的是启用了高分辩率计分器的Linux!" +msgstr "老兄,你的内核真臭!现在流行的是启用了高分辩率计分器的Linux!" -#: ../src/daemon/main.c:860 +#: ../src/daemon/main.c:904 msgid "pa_core_new() failed." msgstr "pa_core_new()失败。" -#: ../src/daemon/main.c:921 +#: ../src/daemon/main.c:965 msgid "Failed to initialize daemon." msgstr "后台程序初始化失败。" -#: ../src/daemon/main.c:926 +#: ../src/daemon/main.c:970 msgid "Daemon startup without any loaded modules, refusing to work." msgstr "后台程序启动未加载任何模块,拒绝工作。" -#: ../src/daemon/main.c:931 -#, c-format -msgid "Default sink name (%s) does not exist in name register." -msgstr "名称登记表中不存在默认的音频出口名(%s)。" - -#: ../src/daemon/main.c:944 +#: ../src/daemon/main.c:983 msgid "Daemon startup complete." msgstr "后台程序启动完成。" -#: ../src/daemon/main.c:950 +#: ../src/daemon/main.c:989 msgid "Daemon shutdown initiated." msgstr "开始关闭后台程序。" -#: ../src/daemon/main.c:971 +#: ../src/daemon/main.c:1010 msgid "Daemon terminated." msgstr "后台程序已终止。" -#: ../src/daemon/cmdline.c:117 -#, c-format +#: ../src/daemon/cmdline.c:121 +#, fuzzy, c-format msgid "" "%s [options]\n" "\n" @@ -421,7 +416,8 @@ msgid "" " --start Start the daemon if it is not " "running\n" " -k --kill Kill a running daemon\n" -" --check Check for a running daemon\n" +" --check Check for a running daemon (only " +"returns exit code)\n" "\n" "OPTIONS:\n" " --system[=BOOL] Run as system-wide instance\n" @@ -451,6 +447,10 @@ msgid "" " --log-level[=LEVEL] Increase or set verbosity level\n" " -v Increase the verbosity level\n" " --log-target={auto,syslog,stderr} Specify the log target\n" +" --log-meta[=BOOL] Include code location in log " +"messages\n" +" --log-time[=BOOL] Include timestamps in log messages\n" +" --log-backtrace=FRAMES Include a backtrace in log messages\n" " -p, --dl-search-path=PATH Set the search path for dynamic " "shared\n" " objects (plugins)\n" @@ -526,58 +526,70 @@ msgstr "" "\n" " -n 不加载默认的脚本文件\n" -#: ../src/daemon/cmdline.c:245 +#: ../src/daemon/cmdline.c:252 msgid "--daemonize expects boolean argument" msgstr "--daemonize 期待布尔参数" -#: ../src/daemon/cmdline.c:252 +#: ../src/daemon/cmdline.c:259 msgid "--fail expects boolean argument" msgstr "--fail 期待布尔参数" -#: ../src/daemon/cmdline.c:262 +#: ../src/daemon/cmdline.c:269 msgid "" "--log-level expects log level argument (either numeric in range 0..4 or one " "of debug, info, notice, warn, error)." -msgstr "--log-level 期待日志级别参数(可以是数字0~4或者debug,info,notice,warn,error中的一个)" +msgstr "" +"--log-level 期待日志级别参数(可以是数字0~4或者debug,info,notice,warn," +"error中的一个)" -#: ../src/daemon/cmdline.c:274 +#: ../src/daemon/cmdline.c:281 msgid "--high-priority expects boolean argument" msgstr "--high-priority 期待布尔参数" -#: ../src/daemon/cmdline.c:281 +#: ../src/daemon/cmdline.c:288 msgid "--realtime expects boolean argument" msgstr "--realtime 期待布尔参数" -#: ../src/daemon/cmdline.c:288 +#: ../src/daemon/cmdline.c:295 msgid "--disallow-module-loading expects boolean argument" msgstr "--disallow-module-loading 期待布尔参数" -#: ../src/daemon/cmdline.c:295 +#: ../src/daemon/cmdline.c:302 msgid "--disallow-exit boolean argument" msgstr "--disallow-exit 布尔参数" -#: ../src/daemon/cmdline.c:302 +#: ../src/daemon/cmdline.c:309 msgid "--use-pid-file expects boolean argument" msgstr "--use-pid-file 期待布尔参数" -#: ../src/daemon/cmdline.c:319 +#: ../src/daemon/cmdline.c:326 msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'." msgstr "无效的日志目标:从syslog,stderr和auto中选取一个" -#: ../src/daemon/cmdline.c:338 +#: ../src/daemon/cmdline.c:333 +#, fuzzy +msgid "--log-time boolean argument" +msgstr "--disallow-exit 布尔参数" + +#: ../src/daemon/cmdline.c:340 +#, fuzzy +msgid "--log-meta boolean argument" +msgstr "--disallow-exit 布尔参数" + +#: ../src/daemon/cmdline.c:359 #, c-format msgid "Invalid resample method '%s'." msgstr "无效的重采样方法'%s'。" -#: ../src/daemon/cmdline.c:345 +#: ../src/daemon/cmdline.c:366 msgid "--system expects boolean argument" msgstr "--system 期待布尔参数" -#: ../src/daemon/cmdline.c:352 +#: ../src/daemon/cmdline.c:373 msgid "--no-cpu-limit expects boolean argument" msgstr "--no-cpu-limit 期待布尔参数" -#: ../src/daemon/cmdline.c:359 +#: ../src/daemon/cmdline.c:380 msgid "--disable-shm expects boolean argument" msgstr "--disable-shm 期待布尔参数" @@ -621,288 +633,314 @@ msgstr "加载一次:%s\n" msgid "Path: %s\n" msgstr "路径:%s\n" -#: ../src/daemon/daemon-conf.c:205 +#: ../src/daemon/daemon-conf.c:212 #, c-format msgid "[%s:%u] Invalid log target '%s'." msgstr "[%s:%u] 无效的日志目标'%s'。" -#: ../src/daemon/daemon-conf.c:221 +#: ../src/daemon/daemon-conf.c:228 #, c-format msgid "[%s:%u] Invalid log level '%s'." msgstr "[%s:%u] 无效的日志级别'%s'。" -#: ../src/daemon/daemon-conf.c:237 +#: ../src/daemon/daemon-conf.c:244 #, c-format msgid "[%s:%u] Invalid resample method '%s'." msgstr "[%s:%u] 无效的重采样方法'%s'。" -#: ../src/daemon/daemon-conf.c:260 +#: ../src/daemon/daemon-conf.c:267 #, c-format msgid "[%s:%u] Invalid rlimit '%s'." msgstr "[%s:%u] 无效的rlimit '%s'。" -#: ../src/daemon/daemon-conf.c:267 +#: ../src/daemon/daemon-conf.c:274 #, c-format msgid "[%s:%u] rlimit not supported on this platform." msgstr "[%s:%u] 此平台不支持rlimit。" -#: ../src/daemon/daemon-conf.c:283 +#: ../src/daemon/daemon-conf.c:290 #, c-format msgid "[%s:%u] Invalid sample format '%s'." msgstr "[%s:%u] 无效的样品格式'%s'。" -#: ../src/daemon/daemon-conf.c:301 +#: ../src/daemon/daemon-conf.c:308 #, c-format msgid "[%s:%u] Invalid sample rate '%s'." msgstr "[%s:%u] 无效的样品率'%s'。" -#: ../src/daemon/daemon-conf.c:319 +#: ../src/daemon/daemon-conf.c:326 #, c-format msgid "[%s:%u] Invalid sample channels '%s'." msgstr "[%s:%u] 无效的样品通道'%s'。" -#: ../src/daemon/daemon-conf.c:337 +#: ../src/daemon/daemon-conf.c:344 #, c-format msgid "[%s:%u] Invalid number of fragments '%s'." msgstr "[%s:%u] 无效的分段数'%s'。" -#: ../src/daemon/daemon-conf.c:355 +#: ../src/daemon/daemon-conf.c:362 #, c-format msgid "[%s:%u] Invalid fragment size '%s'." msgstr "[%s:%u] 无效的分段大小'%s'。" -#: ../src/daemon/daemon-conf.c:373 +#: ../src/daemon/daemon-conf.c:380 #, c-format msgid "[%s:%u] Invalid nice level '%s'." msgstr "[%s:%u] 无效的nice level '%s'。" -#: ../src/daemon/daemon-conf.c:570 +#: ../src/daemon/daemon-conf.c:566 #, c-format msgid "Failed to open configuration file: %s" msgstr "打开配置文件失败:%s" -#: ../src/daemon/daemon-conf.c:644 +#: ../src/daemon/daemon-conf.c:640 #, c-format msgid "### Read from configuration file: %s ###\n" msgstr "### 从配置文件读取:%s ###\n" #: ../src/daemon/caps.c:63 -msgid "Dropping root priviliges." +#, fuzzy +msgid "Dropping root privileges." msgstr "正在取消root权限。" #: ../src/daemon/caps.c:103 msgid "Limited capabilities successfully to CAP_SYS_NICE." msgstr "性能成功限制到CAP_SYS_NICE。" -#: ../src/pulse/channelmap.c:102 +#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:804 msgid "Mono" msgstr "单声道" -#: ../src/pulse/channelmap.c:104 +#: ../src/pulse/channelmap.c:105 msgid "Front Center" msgstr "中前" -#: ../src/pulse/channelmap.c:105 +#: ../src/pulse/channelmap.c:106 msgid "Front Left" msgstr "左前" -#: ../src/pulse/channelmap.c:106 +#: ../src/pulse/channelmap.c:107 msgid "Front Right" msgstr "右前" -#: ../src/pulse/channelmap.c:108 +#: ../src/pulse/channelmap.c:109 msgid "Rear Center" msgstr "中后" -#: ../src/pulse/channelmap.c:109 +#: ../src/pulse/channelmap.c:110 msgid "Rear Left" msgstr "左后" -#: ../src/pulse/channelmap.c:110 +#: ../src/pulse/channelmap.c:111 msgid "Rear Right" msgstr "右后" -#: ../src/pulse/channelmap.c:112 +#: ../src/pulse/channelmap.c:113 msgid "Low Frequency Emmiter" msgstr "低频脉冲" -#: ../src/pulse/channelmap.c:114 +#: ../src/pulse/channelmap.c:115 msgid "Front Left-of-center" msgstr "前左中央" -#: ../src/pulse/channelmap.c:115 +#: ../src/pulse/channelmap.c:116 msgid "Front Right-of-center" msgstr "前右中央" -#: ../src/pulse/channelmap.c:117 +#: ../src/pulse/channelmap.c:118 msgid "Side Left" msgstr "左侧" -#: ../src/pulse/channelmap.c:118 +#: ../src/pulse/channelmap.c:119 msgid "Side Right" msgstr "右侧" -#: ../src/pulse/channelmap.c:120 +#: ../src/pulse/channelmap.c:121 msgid "Auxiliary 0" msgstr "辅助 0" -#: ../src/pulse/channelmap.c:121 +#: ../src/pulse/channelmap.c:122 msgid "Auxiliary 1" msgstr "辅助 1" -#: ../src/pulse/channelmap.c:122 +#: ../src/pulse/channelmap.c:123 msgid "Auxiliary 2" msgstr "辅助 2" -#: ../src/pulse/channelmap.c:123 +#: ../src/pulse/channelmap.c:124 msgid "Auxiliary 3" msgstr "辅助 3" -#: ../src/pulse/channelmap.c:124 +#: ../src/pulse/channelmap.c:125 msgid "Auxiliary 4" msgstr "辅助 4" -#: ../src/pulse/channelmap.c:125 +#: ../src/pulse/channelmap.c:126 msgid "Auxiliary 5" msgstr "辅助 5" -#: ../src/pulse/channelmap.c:126 +#: ../src/pulse/channelmap.c:127 msgid "Auxiliary 6" msgstr "辅助 6" -#: ../src/pulse/channelmap.c:127 +#: ../src/pulse/channelmap.c:128 msgid "Auxiliary 7" msgstr "辅助 7" -#: ../src/pulse/channelmap.c:128 +#: ../src/pulse/channelmap.c:129 msgid "Auxiliary 8" msgstr "辅助 7" -#: ../src/pulse/channelmap.c:129 +#: ../src/pulse/channelmap.c:130 msgid "Auxiliary 9" msgstr "辅助 9" -#: ../src/pulse/channelmap.c:130 +#: ../src/pulse/channelmap.c:131 msgid "Auxiliary 10" msgstr "辅助 10" -#: ../src/pulse/channelmap.c:131 +#: ../src/pulse/channelmap.c:132 msgid "Auxiliary 11" msgstr "辅助 11" -#: ../src/pulse/channelmap.c:132 +#: ../src/pulse/channelmap.c:133 msgid "Auxiliary 12" msgstr "辅助 12" -#: ../src/pulse/channelmap.c:133 +#: ../src/pulse/channelmap.c:134 msgid "Auxiliary 13" msgstr "辅助 13" -#: ../src/pulse/channelmap.c:134 +#: ../src/pulse/channelmap.c:135 msgid "Auxiliary 14" msgstr "辅助 14" -#: ../src/pulse/channelmap.c:135 +#: ../src/pulse/channelmap.c:136 msgid "Auxiliary 15" msgstr "辅助 15" -#: ../src/pulse/channelmap.c:136 +#: ../src/pulse/channelmap.c:137 msgid "Auxiliary 16" msgstr "辅助 16" -#: ../src/pulse/channelmap.c:137 +#: ../src/pulse/channelmap.c:138 msgid "Auxiliary 17" msgstr "辅助 17" -#: ../src/pulse/channelmap.c:138 +#: ../src/pulse/channelmap.c:139 msgid "Auxiliary 18" msgstr "辅助 18" -#: ../src/pulse/channelmap.c:139 +#: ../src/pulse/channelmap.c:140 msgid "Auxiliary 19" msgstr "辅助 19" -#: ../src/pulse/channelmap.c:140 +#: ../src/pulse/channelmap.c:141 msgid "Auxiliary 20" msgstr "辅助 20" -#: ../src/pulse/channelmap.c:141 +#: ../src/pulse/channelmap.c:142 msgid "Auxiliary 21" msgstr "辅助 21" -#: ../src/pulse/channelmap.c:142 +#: ../src/pulse/channelmap.c:143 msgid "Auxiliary 22" msgstr "辅助 22" -#: ../src/pulse/channelmap.c:143 +#: ../src/pulse/channelmap.c:144 msgid "Auxiliary 23" msgstr "辅助 23" -#: ../src/pulse/channelmap.c:144 +#: ../src/pulse/channelmap.c:145 msgid "Auxiliary 24" msgstr "辅助 24" -#: ../src/pulse/channelmap.c:145 +#: ../src/pulse/channelmap.c:146 msgid "Auxiliary 25" msgstr "辅助 25" -#: ../src/pulse/channelmap.c:146 +#: ../src/pulse/channelmap.c:147 msgid "Auxiliary 26" msgstr "辅助 26" -#: ../src/pulse/channelmap.c:147 +#: ../src/pulse/channelmap.c:148 msgid "Auxiliary 27" msgstr "辅助 27" -#: ../src/pulse/channelmap.c:148 +#: ../src/pulse/channelmap.c:149 msgid "Auxiliary 28" msgstr "辅助 28" -#: ../src/pulse/channelmap.c:149 +#: ../src/pulse/channelmap.c:150 msgid "Auxiliary 29" msgstr "辅助 29" -#: ../src/pulse/channelmap.c:150 +#: ../src/pulse/channelmap.c:151 msgid "Auxiliary 30" msgstr "辅助 30" -#: ../src/pulse/channelmap.c:151 +#: ../src/pulse/channelmap.c:152 msgid "Auxiliary 31" msgstr "辅助 31" -#: ../src/pulse/channelmap.c:153 +#: ../src/pulse/channelmap.c:154 msgid "Top Center" msgstr "上中" -#: ../src/pulse/channelmap.c:155 +#: ../src/pulse/channelmap.c:156 msgid "Top Front Center" msgstr "上中前" -#: ../src/pulse/channelmap.c:156 +#: ../src/pulse/channelmap.c:157 msgid "Top Front Left" msgstr "上左前" -#: ../src/pulse/channelmap.c:157 +#: ../src/pulse/channelmap.c:158 msgid "Top Front Right" msgstr "上右前" -#: ../src/pulse/channelmap.c:159 +#: ../src/pulse/channelmap.c:160 msgid "Top Rear Center" msgstr "上中后" -#: ../src/pulse/channelmap.c:160 +#: ../src/pulse/channelmap.c:161 msgid "Top Rear Left" msgstr "上左后" -#: ../src/pulse/channelmap.c:161 +#: ../src/pulse/channelmap.c:162 msgid "Top Rear Right" msgstr "上右后" -#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144 -#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194 +#: ../src/pulse/channelmap.c:476 ../src/pulse/sample.c:167 +#: ../src/pulse/volume.c:170 ../src/pulse/volume.c:196 +#: ../src/pulse/volume.c:216 ../src/pulse/volume.c:246 msgid "(invalid)" msgstr "(无效)" +#: ../src/pulse/channelmap.c:808 +msgid "Stereo" +msgstr "" + +#: ../src/pulse/channelmap.c:813 +msgid "Surround 4.0" +msgstr "" + +#: ../src/pulse/channelmap.c:819 +msgid "Surround 4.1" +msgstr "" + +#: ../src/pulse/channelmap.c:825 +msgid "Surround 5.0" +msgstr "" + +#: ../src/pulse/channelmap.c:831 +msgid "Surround 5.1" +msgstr "" + +#: ../src/pulse/channelmap.c:838 +msgid "Surround 7.1" +msgstr "" + #: ../src/pulse/error.c:43 msgid "OK" msgstr "好" @@ -991,6 +1029,39 @@ msgstr "未知错误码" msgid "No such extension" msgstr "没有该扩展" +#: ../src/pulse/error.c:65 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:66 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/sample.c:169 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:181 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:183 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:185 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:187 +#, c-format +msgid "%u B" +msgstr "" + #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100 msgid "XOpenDisplay() failed" msgstr "XOpenDisplay()失败" @@ -1004,45 +1075,35 @@ msgstr "cookie数据分析失败" msgid "Failed to open configuration file '%s': %s" msgstr "打开配置文件'%s'失败:%s" -#: ../src/pulse/context.c:516 +#: ../src/pulse/context.c:517 msgid "No cookie loaded. Attempting to connect without." msgstr "没有加载cookie。尝试不加载cookie进行连接。" -#: ../src/pulse/context.c:642 +#: ../src/pulse/context.c:643 #, c-format msgid "fork(): %s" msgstr "fork():%s" -#: ../src/pulse/context.c:695 +#: ../src/pulse/context.c:696 #, c-format msgid "waitpid(): %s" msgstr "waitpid():%s" -#: ../src/pulse/context.c:1256 +#: ../src/pulse/context.c:1257 #, c-format msgid "Received message for unknown extension '%s'" msgstr "收到未知扩展'%s'的信息" -#: ../src/utils/pacat.c:93 +#: ../src/utils/pacat.c:94 #, c-format msgid "pa_stream_write() failed: %s\n" msgstr "pa_stream_write()失败:%s\n" -#: ../src/utils/pacat.c:132 +#: ../src/utils/pacat.c:133 #, c-format msgid "pa_stream_peek() failed: %s\n" msgstr "pa_stream_peek()失败:%s\n" -#: ../src/utils/pacat.c:141 -#, c-format -msgid "Buffer overrun, dropping incoming data\n" -msgstr "缓冲超限,丢弃正在读入的数据\n" - -#: ../src/utils/pacat.c:143 -#, c-format -msgid "pa_stream_drop() failed: %s\n" -msgstr "pa_stream_drop()失败:%s\n" - #: ../src/utils/pacat.c:169 #, c-format msgid "Stream successfully created.\n" @@ -1122,78 +1183,78 @@ msgstr "连接已建立。%s \n" msgid "pa_stream_new() failed: %s\n" msgstr "pa_stream_new()失败:%s\n" -#: ../src/utils/pacat.c:287 +#: ../src/utils/pacat.c:288 #, c-format msgid "pa_stream_connect_playback() failed: %s\n" msgstr "pa_stream_connect_playback()失败:%s\n" -#: ../src/utils/pacat.c:293 +#: ../src/utils/pacat.c:294 #, c-format msgid "pa_stream_connect_record() failed: %s\n" msgstr "pa_stream_connect_playback()失败:%s\n" -#: ../src/utils/pacat.c:307 ../src/utils/pasuspender.c:159 -#: ../src/utils/pactl.c:666 ../src/utils/paplay.c:183 +#: ../src/utils/pacat.c:308 ../src/utils/pasuspender.c:159 +#: ../src/utils/pactl.c:758 ../src/utils/paplay.c:183 #, c-format msgid "Connection failure: %s\n" msgstr "连接失败:%s\n" -#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75 +#: ../src/utils/pacat.c:329 ../src/utils/paplay.c:75 #, c-format msgid "Failed to drain stream: %s\n" msgstr "排出流失败:%s\n" -#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80 +#: ../src/utils/pacat.c:334 ../src/utils/paplay.c:80 #, c-format msgid "Playback stream drained.\n" msgstr "流播放完毕。\n" -#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92 +#: ../src/utils/pacat.c:344 ../src/utils/paplay.c:92 #, c-format msgid "Draining connection to server.\n" msgstr "" -#: ../src/utils/pacat.c:369 +#: ../src/utils/pacat.c:370 #, c-format msgid "Got EOF.\n" msgstr "收到EOF。\n" -#: ../src/utils/pacat.c:375 +#: ../src/utils/pacat.c:376 #, c-format msgid "pa_stream_drain(): %s\n" msgstr "pa_stream_drain():%s\n" -#: ../src/utils/pacat.c:385 +#: ../src/utils/pacat.c:386 #, c-format msgid "read() failed: %s\n" msgstr "read()失败:%s\n" -#: ../src/utils/pacat.c:417 +#: ../src/utils/pacat.c:418 #, c-format msgid "write() failed: %s\n" msgstr "write()失败:%s\n" -#: ../src/utils/pacat.c:438 +#: ../src/utils/pacat.c:439 #, c-format msgid "Got signal, exiting.\n" msgstr "收到信号,正在退出。\n" -#: ../src/utils/pacat.c:452 +#: ../src/utils/pacat.c:453 #, c-format msgid "Failed to get latency: %s\n" msgstr "获取传输延迟失败:%s\n" -#: ../src/utils/pacat.c:457 +#: ../src/utils/pacat.c:458 #, c-format msgid "Time: %0.3f sec; Latency: %0.0f usec. \r" msgstr "时间:%0.3f秒;延迟:%0.0f 微秒。 \r" -#: ../src/utils/pacat.c:477 +#: ../src/utils/pacat.c:478 #, c-format msgid "pa_stream_update_timing_info() failed: %s\n" msgstr "pa_stream_update_timing_info()失败:%s\n" -#: ../src/utils/pacat.c:490 +#: ../src/utils/pacat.c:491 #, c-format msgid "" "%s [options]\n" @@ -1244,7 +1305,8 @@ msgid "" "bytes.\n" " --process-time=BYTES Request the specified process time " "per request in bytes.\n" -msgstr "%s [options]\n" +msgstr "" +"%s [options]\n" "\n" " -h, --help 显示此帮助\n" " --version 显示版本号\n" @@ -1258,21 +1320,26 @@ msgstr "%s [options]\n" " -d, --device=DEVICE 要连接的sink/source名\n" " -n, --client-name=NAME 指定客户端在服务器上的名称\n" " --stream-name=NAME 指定流在服务器上的名称\n" -" --volume=VOLUME 指定初始(线性)音量,取值在0...65536之间\n" +" --volume=VOLUME 指定初始(线性)音量,取值在0...65536" +"之间\n" " --rate=SAMPLERATE 采样频率(单位Hz,默认为44100)\n" -" --format=SAMPLEFORMAT 采样类型,从s16le,s16be,u8,float32le,\n" -" float32be,ulaw,alaw,s32le,s32be中取(默认为s16ne)\n" -" --channels=CHANNELS 通道数,1为单声道,2为立体声(默认为2)\n" +" --format=SAMPLEFORMAT 采样类型,从s16le,s16be,u8," +"float32le,\n" +" float32be,ulaw,alaw,s32le,s32be中" +"取(默认为s16ne)\n" +" --channels=CHANNELS 通道数,1为单声道,2为立体声(默认为" +"2)\n" " --channel-map=CHANNELMAP 取代默认值的通道映射表\n" " --fix-format 从流连接的音频出口处取采样格式。\n" " --fix-rate 从流连接的音频出口处取采样率。\n" -" --fix-channels 从流连接的音频出口处取通道数和通道映射表。\n" +" --fix-channels 从流连接的音频出口处取通道数和通道映" +"射表。\n" " --no-remix Don't upmix or downmix channels.\n" " --no-remap 根据下标而非名称来映射通道。\n" " --latency=BYTES 请求指定字节数的延迟。\n" " --process-time=BYTES 每次请求指定字节数的处理时间。\n" -#: ../src/utils/pacat.c:591 +#: ../src/utils/pacat.c:592 #, c-format msgid "" "pacat %s\n" @@ -1283,88 +1350,88 @@ msgstr "" "Compiled with libpulse %s\n" "Linked with libpulse %s\n" -#: ../src/utils/pacat.c:647 +#: ../src/utils/pacat.c:649 #, c-format msgid "Invalid channel map '%s'\n" msgstr "无效的通道映射描述'%s'\n" -#: ../src/utils/pacat.c:676 +#: ../src/utils/pacat.c:678 #, c-format msgid "Invalid latency specification '%s'\n" msgstr "无效的延迟规格描述 %s'\n" -#: ../src/utils/pacat.c:683 +#: ../src/utils/pacat.c:685 #, c-format msgid "Invalid process time specification '%s'\n" msgstr "无效的处理时间描述 '%s'\n" -#: ../src/utils/pacat.c:694 +#: ../src/utils/pacat.c:696 #, c-format msgid "Invalid sample specification\n" msgstr "无效的采样描述\n" -#: ../src/utils/pacat.c:699 +#: ../src/utils/pacat.c:701 #, c-format msgid "Channel map doesn't match sample specification\n" msgstr "通道映射与采样描述不匹配\n" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 #, c-format msgid "Opening a %s stream with sample specification '%s'.\n" msgstr "以采样规格'%s'打开%s流。\n" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 msgid "recording" msgstr "正在录制" -#: ../src/utils/pacat.c:706 +#: ../src/utils/pacat.c:708 msgid "playback" msgstr "回放" -#: ../src/utils/pacat.c:714 +#: ../src/utils/pacat.c:716 #, c-format msgid "open(): %s\n" msgstr "open():%s\n" -#: ../src/utils/pacat.c:719 +#: ../src/utils/pacat.c:721 #, c-format msgid "dup2(): %s\n" msgstr "dup2():%s\n" -#: ../src/utils/pacat.c:729 +#: ../src/utils/pacat.c:731 #, c-format msgid "Too many arguments.\n" msgstr "参数过多。\n" -#: ../src/utils/pacat.c:742 ../src/utils/pasuspender.c:280 -#: ../src/utils/pactl.c:909 ../src/utils/paplay.c:381 +#: ../src/utils/pacat.c:744 ../src/utils/pasuspender.c:280 +#: ../src/utils/pactl.c:1013 ../src/utils/paplay.c:381 #, c-format msgid "pa_mainloop_new() failed.\n" msgstr "pa_mainloop_new()失败。\n" -#: ../src/utils/pacat.c:763 +#: ../src/utils/pacat.c:765 #, c-format msgid "io_new() failed.\n" msgstr "io_new()失败。\n" -#: ../src/utils/pacat.c:769 ../src/utils/pasuspender.c:293 -#: ../src/utils/pactl.c:923 ../src/utils/paplay.c:396 +#: ../src/utils/pacat.c:771 ../src/utils/pasuspender.c:293 +#: ../src/utils/pactl.c:1027 ../src/utils/paplay.c:396 #, c-format msgid "pa_context_new() failed.\n" msgstr "pa_context_new()失败。\n" -#: ../src/utils/pacat.c:777 +#: ../src/utils/pacat.c:779 #, c-format msgid "pa_context_connect() failed: %s" msgstr "pa_context_connect()失败:%s" -#: ../src/utils/pacat.c:788 +#: ../src/utils/pacat.c:790 #, c-format msgid "time_new() failed.\n" msgstr "time_new()失败。\n" -#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301 -#: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407 +#: ../src/utils/pacat.c:797 ../src/utils/pasuspender.c:301 +#: ../src/utils/pactl.c:1035 ../src/utils/paplay.c:407 #, c-format msgid "pa_mainloop_run() failed.\n" msgstr "pa_mainloop_run()失败。\n" @@ -1394,7 +1461,7 @@ msgstr "恢复失败:%s\n" msgid "WARNING: Sound server is not local, not suspending.\n" msgstr "警告:非本地声音服务器,不会挂起。\n" -#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672 +#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:764 #: ../src/utils/paplay.c:191 #, c-format msgid "Got SIGINT, exiting.\n" @@ -1415,7 +1482,8 @@ msgid "" " -s, --server=SERVER The name of the server to connect " "to\n" "\n" -msgstr "%s [options] ... \n" +msgstr "" +"%s [options] ... \n" "\n" " -h, --help 显示此帮助\n" " --version 显示版本\n" @@ -1433,32 +1501,32 @@ msgstr "" "Compiled with libpulse %s\n" "Linked with libpulse %s\n" -#: ../src/utils/pactl.c:107 +#: ../src/utils/pactl.c:108 #, c-format msgid "Failed to get statistics: %s\n" msgstr "获取统计数据失败:%s\n" -#: ../src/utils/pactl.c:113 +#: ../src/utils/pactl.c:114 #, c-format msgid "Currently in use: %u blocks containing %s bytes total.\n" msgstr "当前使用:%u块,总共%s字节。\n" -#: ../src/utils/pactl.c:116 +#: ../src/utils/pactl.c:117 #, c-format msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n" msgstr "整个生命周期所得分配:%u块,总共%s字节。\n" -#: ../src/utils/pactl.c:119 +#: ../src/utils/pactl.c:120 #, c-format msgid "Sample cache size: %s\n" msgstr "采样缓存大小:%s\n" -#: ../src/utils/pactl.c:128 +#: ../src/utils/pactl.c:129 #, c-format msgid "Failed to get server information: %s\n" msgstr "获取服务器信息失败:%s\n" -#: ../src/utils/pactl.c:135 +#: ../src/utils/pactl.c:136 #, c-format msgid "" "User name: %s\n" @@ -1469,7 +1537,8 @@ msgid "" "Default Sink: %s\n" "Default Source: %s\n" "Cookie: %08x\n" -msgstr "用户名:%s\n" +msgstr "" +"用户名:%s\n" "主机名:%s\n" "服务器名:%s\n" "服务器版本:%s\n" @@ -1478,27 +1547,33 @@ msgstr "用户名:%s\n" "默认音频入口:%s\n" "Cookie:%08x\n" -#: ../src/utils/pactl.c:160 +#: ../src/utils/pactl.c:175 #, c-format msgid "Failed to get sink information: %s\n" msgstr "获取音频出口信息失败:%s\n" -#: ../src/utils/pactl.c:176 -#, c-format +#: ../src/utils/pactl.c:191 +#, fuzzy, c-format msgid "" -"*** Sink #%u ***\n" -"Name: %s\n" -"Driver: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Owner Module: %u\n" -"Volume: %s\n" -"Monitor Source: %s\n" -"Latency: %0.0f usec, configured %0.0f usec\n" -"Flags: %s%s%s%s%s%s\n" -"Properties:\n" -"%s" -msgstr "*** 音频出口 #%u ***\n" +"Sink #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s%s%s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s%s%s\n" +"\tMonitor Source: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 音频出口 #%u ***\n" "名称:%s\n" "驱动:%s\n" "采样规格:%s\n" @@ -1511,31 +1586,33 @@ msgstr "*** 音频出口 #%u ***\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371 -msgid "muted" -msgstr "已静音" - -#: ../src/utils/pactl.c:212 +#: ../src/utils/pactl.c:255 #, c-format msgid "Failed to get source information: %s\n" msgstr "获取音频入口信息失败:%s\n" -#: ../src/utils/pactl.c:228 -#, c-format +#: ../src/utils/pactl.c:271 +#, fuzzy, c-format msgid "" -"*** Source #%u ***\n" -"Name: %s\n" -"Driver: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Owner Module: %u\n" -"Volume: %s\n" -"Monitor of Sink: %s\n" -"Latency: %0.0f usec, configured %0.0f usec\n" -"Flags: %s%s%s%s%s%s\n" -"Properties:\n" -"%s" -msgstr "*** 音频入口 #%u ***\n" +"Source #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s%s%s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s%s%s\n" +"\tMonitor of Sink: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 音频入口 #%u ***\n" "名称:%s\n" "驱动:%s\n" "采样规格:%s\n" @@ -1548,73 +1625,112 @@ msgstr "*** 音频入口 #%u ***\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:246 ../src/utils/pactl.c:289 ../src/utils/pactl.c:322 -#: ../src/utils/pactl.c:366 ../src/utils/pactl.c:367 ../src/utils/pactl.c:374 -#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:419 ../src/utils/pactl.c:425 -#: ../src/utils/pactl.c:468 ../src/utils/pactl.c:469 ../src/utils/pactl.c:473 +#: ../src/utils/pactl.c:303 ../src/utils/pactl.c:347 ../src/utils/pactl.c:382 +#: ../src/utils/pactl.c:419 ../src/utils/pactl.c:478 ../src/utils/pactl.c:479 +#: ../src/utils/pactl.c:489 ../src/utils/pactl.c:533 ../src/utils/pactl.c:534 +#: ../src/utils/pactl.c:540 ../src/utils/pactl.c:583 ../src/utils/pactl.c:584 +#: ../src/utils/pactl.c:591 msgid "n/a" msgstr "n/a" -#: ../src/utils/pactl.c:263 +#: ../src/utils/pactl.c:321 #, c-format msgid "Failed to get module information: %s\n" msgstr "获取模块信息失败:%s\n" -#: ../src/utils/pactl.c:281 -#, c-format +#: ../src/utils/pactl.c:339 +#, fuzzy, c-format msgid "" -"*** Module #%u ***\n" -"Name: %s\n" -"Argument: %s\n" -"Usage counter: %s\n" -"Auto unload: %s\n" -msgstr "*** 模块 #%u ***\n" +"Module #%u\n" +"\tName: %s\n" +"\tArgument: %s\n" +"\tUsage counter: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 模块 #%u ***\n" "名称:%s\n" "参数:%s\n" "使用计数器:%s\n" "自动卸载:%s\n" -#: ../src/utils/pactl.c:298 +#: ../src/utils/pactl.c:358 #, c-format msgid "Failed to get client information: %s\n" msgstr "获取客户端信息失败:%s\n" -#: ../src/utils/pactl.c:316 -#, c-format +#: ../src/utils/pactl.c:376 +#, fuzzy, c-format msgid "" -"*** Client #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Properties:\n" +"Client #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 客户端 #%u ***\n" +"驱动:%s\n" +"所有者模块:%s\n" +"属性:\n" "%s" -msgstr "*** 客户端 #%u ***\n" + +#: ../src/utils/pactl.c:393 +#, fuzzy, c-format +msgid "Failed to get card information: %s\n" +msgstr "获取自动加载信息失败:%s\n" + +#: ../src/utils/pactl.c:411 +#, fuzzy, c-format +msgid "" +"Card #%u\n" +"\tName: %s\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 客户端 #%u ***\n" "驱动:%s\n" "所有者模块:%s\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:333 +#: ../src/utils/pactl.c:425 +#, c-format +msgid "\tProfiles:\n" +msgstr "" + +#: ../src/utils/pactl.c:431 +#, fuzzy, c-format +msgid "\tActive Profile: %s\n" +msgstr "管道失败:%s" + +#: ../src/utils/pactl.c:442 #, c-format msgid "Failed to get sink input information: %s\n" msgstr "获取音频出口输入信息失败:%s\n" -#: ../src/utils/pactl.c:352 -#, c-format +#: ../src/utils/pactl.c:461 +#, fuzzy, c-format msgid "" -"*** Sink Input #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Client: %s\n" -"Sink: %u\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Volume: %s\n" -"Buffer Latency: %0.0f usec\n" -"Sink Latency: %0.0f usec\n" -"Resample method: %s\n" -"Properties:\n" -"%s" -msgstr "*** 音频出口输入 #%u ***\n" +"Sink Input #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSink: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t %s\n" +"\t balance %0.2f\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSink Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 音频出口输入 #%u ***\n" "驱动:%s\n" "所有者模块:%s\n" "客户端:%s\n" @@ -1628,27 +1744,28 @@ msgstr "*** 音频出口输入 #%u ***\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:385 +#: ../src/utils/pactl.c:500 #, c-format msgid "Failed to get source output information: %s\n" msgstr "获取音频入口输出信息失败:%s\n" -#: ../src/utils/pactl.c:405 -#, c-format +#: ../src/utils/pactl.c:520 +#, fuzzy, c-format msgid "" -"*** Source Output #%u ***\n" -"Driver: %s\n" -"Owner Module: %s\n" -"Client: %s\n" -"Source: %u\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Buffer Latency: %0.0f usec\n" -"Source Latency: %0.0f usec\n" -"Resample method: %s\n" -"Properties:\n" -"%s" -msgstr "*** 音频入口输出 #%u ***\n" +"Source Output #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSource: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSource Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 音频入口输出 #%u ***\n" "驱动:%s\n" "所有者模块:%s\n" "客户端:%s\n" @@ -1661,26 +1778,29 @@ msgstr "*** 音频入口输出 #%u ***\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:436 +#: ../src/utils/pactl.c:551 #, c-format msgid "Failed to get sample information: %s\n" msgstr "获取采样信息失败:%s\n" -#: ../src/utils/pactl.c:455 -#, c-format +#: ../src/utils/pactl.c:569 +#, fuzzy, c-format msgid "" -"*** Sample #%u ***\n" -"Name: %s\n" -"Volume: %s\n" -"Sample Specification: %s\n" -"Channel Map: %s\n" -"Duration: %0.1fs\n" -"Size: %s\n" -"Lazy: %s\n" -"Filename: %s\n" -"Properties:\n" -"%s" -msgstr "*** 采样 #%u ***\n" +"Sample #%u\n" +"\tName: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tVolume: %s\n" +"\t %s\n" +"\t balance %0.2f\n" +"\tDuration: %0.1fs\n" +"\tSize: %s\n" +"\tLazy: %s\n" +"\tFilename: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" +"*** 采样 #%u ***\n" "名称:%s\n" "音量:%s\n" "采样规格:%s\n" @@ -1692,50 +1812,23 @@ msgstr "*** 采样 #%u ***\n" "属性:\n" "%s" -#: ../src/utils/pactl.c:481 -#, c-format -msgid "Failed to get autoload information: %s\n" -msgstr "获取自动加载信息失败:%s\n" - -#: ../src/utils/pactl.c:497 -#, c-format -msgid "" -"*** Autoload Entry #%u ***\n" -"Name: %s\n" -"Type: %s\n" -"Module: %s\n" -"Argument: %s\n" -msgstr "*** 自动加载项 #%u ***\n" -"名称:%s\n" -"类型:%s\n" -"模块:%s\n" -"参数:%s\n" - -#: ../src/utils/pactl.c:504 -msgid "sink" -msgstr "音频出口" - -#: ../src/utils/pactl.c:504 -msgid "source" -msgstr "音频入口" - -#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521 +#: ../src/utils/pactl.c:599 ../src/utils/pactl.c:609 #, c-format msgid "Failure: %s\n" msgstr "失败:%s\n" -#: ../src/utils/pactl.c:545 +#: ../src/utils/pactl.c:633 #, c-format msgid "Failed to upload sample: %s\n" msgstr "上传采样失败:%s\n" -#: ../src/utils/pactl.c:562 +#: ../src/utils/pactl.c:650 #, c-format msgid "Premature end of file\n" msgstr "文件过早结束\n" -#: ../src/utils/pactl.c:678 -#, c-format +#: ../src/utils/pactl.c:770 +#, fuzzy, c-format msgid "" "%s [options] stat\n" "%s [options] list\n" @@ -1749,6 +1842,7 @@ msgid "" "%s [options] unload-module ID\n" "%s [options] suspend-sink [SINK] 1|0\n" "%s [options] suspend-source [SOURCE] 1|0\n" +"%s [options] set-card-profile [CARD] [PROFILE] \n" "\n" " -h, --help Show this help\n" " --version Show version\n" @@ -1757,7 +1851,8 @@ msgid "" "to\n" " -n, --client-name=NAME How to call this client on the " "server\n" -msgstr "%s [options] stat\n" +msgstr "" +"%s [options] stat\n" "%s [options] list\n" "%s [options] exit\n" "%s [options] upload-sample FILENAME [NAME]\n" @@ -1776,7 +1871,7 @@ msgstr "%s [options] stat\n" " -s, --server=SERVER 要连接的服务器名\n" " -n, --client-name=NAME 此客户端在服务器上的名称\n" -#: ../src/utils/pactl.c:729 +#: ../src/utils/pactl.c:822 #, c-format msgid "" "pactl %s\n" @@ -1787,61 +1882,66 @@ msgstr "" "Compiled with libpulse %s\n" "Linked with libpulse %s\n" -#: ../src/utils/pactl.c:768 +#: ../src/utils/pactl.c:861 #, c-format msgid "Please specify a sample file to load\n" msgstr "请指定要加载的采样文件\n" -#: ../src/utils/pactl.c:790 +#: ../src/utils/pactl.c:883 #, c-format msgid "Failed to open sound file.\n" msgstr "打开声音文件失败。\n" -#: ../src/utils/pactl.c:802 +#: ../src/utils/pactl.c:895 #, c-format msgid "You have to specify a sample name to play\n" msgstr "你必须指定要播放的采样名\n" -#: ../src/utils/pactl.c:814 +#: ../src/utils/pactl.c:907 #, c-format msgid "You have to specify a sample name to remove\n" msgstr "你必须指定要删除的采样名\n" -#: ../src/utils/pactl.c:822 +#: ../src/utils/pactl.c:915 #, c-format msgid "You have to specify a sink input index and a sink\n" msgstr "你必须指定音频出口索引和音频出口\n" -#: ../src/utils/pactl.c:831 +#: ../src/utils/pactl.c:924 #, c-format msgid "You have to specify a source output index and a source\n" msgstr "你必须指定音频入口输出索引和音频入口\n" -#: ../src/utils/pactl.c:845 +#: ../src/utils/pactl.c:938 #, c-format msgid "You have to specify a module name and arguments.\n" msgstr "必须指定模块名和参数。\n" -#: ../src/utils/pactl.c:865 +#: ../src/utils/pactl.c:958 #, c-format msgid "You have to specify a module index\n" msgstr "必须指定模块索引\n" -#: ../src/utils/pactl.c:875 -#, c-format +#: ../src/utils/pactl.c:968 +#, fuzzy, c-format msgid "" -"You may not specify more than one sink. You have to specify at least one " -"boolean value.\n" +"You may not specify more than one sink. You have to specify a boolean " +"value.\n" msgstr "不可指定多个音频出口。必须指定至少一个布尔值。\n" -#: ../src/utils/pactl.c:888 -#, c-format +#: ../src/utils/pactl.c:981 +#, fuzzy, c-format msgid "" -"You may not specify more than one source. You have to specify at least one " -"boolean value.\n" +"You may not specify more than one source. You have to specify a boolean " +"value.\n" msgstr "不可指定多个音频入口。必须指定至少一个布尔值。\n" -#: ../src/utils/pactl.c:904 +#: ../src/utils/pactl.c:993 +#, fuzzy, c-format +msgid "You have to specify a card name/index and a profile name\n" +msgstr "你必须指定音频出口索引和音频出口\n" + +#: ../src/utils/pactl.c:1008 #, c-format msgid "No valid command specified.\n" msgstr "未指定有效的命令。\n" @@ -1942,17 +2042,17 @@ msgstr "杀死PulseAudio后台程序失败。" msgid "Daemon not responding." msgstr "后台程序未响应。" -#: ../src/utils/pacmd.c:112 +#: ../src/utils/pacmd.c:144 #, c-format msgid "select(): %s" msgstr "select():%s" -#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140 +#: ../src/utils/pacmd.c:154 ../src/utils/pacmd.c:171 #, c-format msgid "read(): %s" msgstr "read():%s" -#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167 +#: ../src/utils/pacmd.c:187 ../src/utils/pacmd.c:201 #, c-format msgid "write(): %s" msgstr "write():%s" @@ -2004,7 +2104,8 @@ msgstr "" " -d, --device=DEVICE 要连接的音频出口名\n" " -n, --client-name=NAME 此客户端在服务器上的名称\n" " --stream-name=NAME 此流在服务器上的名称\n" -" --volume=VOLUME 指定初始(线性)音量,取值在0...65536之间\n" +" --volume=VOLUME 指定初始(线性)音量,取值在0...65536" +"之间\n" " --channel-map=CHANNELMAP 设定使用的通道映射表\n" #: ../src/utils/paplay.c:255 @@ -2042,3 +2143,46 @@ msgstr "正在使用采样规格'%s'\n" msgid "Cannot access autospawn lock." msgstr "不能访问autospawn锁。" +#~ msgid "" +#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n" +#~ "For enabling real-time scheduling please acquire the appropriate " +#~ "PolicyKit priviliges, or become a member of '" +#~ msgstr "" +#~ "而且PolicyKit拒绝授予我们权限。再次取消SUID。\n" +#~ "要启用实时调度,请取得适应的PolicyKit权限,或者成为组成员'" + +#~ msgid "" +#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this " +#~ "user." +#~ msgstr "',或者提高本用户的RLIMIT_NICE/RLIMIT_RTPRIO资源上限。" + +#~ msgid "Default sink name (%s) does not exist in name register." +#~ msgstr "名称登记表中不存在默认的音频出口名(%s)。" + +#~ msgid "Buffer overrun, dropping incoming data\n" +#~ msgstr "缓冲超限,丢弃正在读入的数据\n" + +#~ msgid "pa_stream_drop() failed: %s\n" +#~ msgstr "pa_stream_drop()失败:%s\n" + +#~ msgid "muted" +#~ msgstr "已静音" + +#~ msgid "" +#~ "*** Autoload Entry #%u ***\n" +#~ "Name: %s\n" +#~ "Type: %s\n" +#~ "Module: %s\n" +#~ "Argument: %s\n" +#~ msgstr "" +#~ "*** 自动加载项 #%u ***\n" +#~ "名称:%s\n" +#~ "类型:%s\n" +#~ "模块:%s\n" +#~ "参数:%s\n" + +#~ msgid "sink" +#~ msgstr "音频出口" + +#~ msgid "source" +#~ msgstr "音频入口" diff --git a/src/Makefile.am b/src/Makefile.am index d2917a0c..fc478037 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -862,6 +862,13 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN # Plug-in libraries # ################################### +if HAVE_DBUS +# Serveral module (e.g. libalsa-util.la) +modlibexec_LTLIBRARIES += \ + libdbus-util.la \ + module-console-kit.la +endif + modlibexec_LTLIBRARIES += \ module-cli.la \ module-cli-protocol-tcp.la \ @@ -888,7 +895,9 @@ modlibexec_LTLIBRARIES += \ module-esound-sink.la \ module-tunnel-sink.la \ module-tunnel-source.la \ - module-position-event-sounds.la + module-position-event-sounds.la \ + module-augment-properties.la \ + module-cork-music-on-phone.la # See comment at librtp.la above @@ -989,21 +998,14 @@ endif if HAVE_HAL modlibexec_LTLIBRARIES += \ - libdbus-util.la \ module-hal-detect.la endif -if HAVE_DBUS -modlibexec_LTLIBRARIES += \ - libdbus-util.la \ - module-console-kit.la -endif - if HAVE_BLUEZ modlibexec_LTLIBRARIES += \ + libbluetooth-util.la \ module-bluetooth-proximity.la \ module-bluetooth-discover.la \ - libbluetooth-util.la \ libbluetooth-ipc.la \ libbluetooth-sbc.la \ module-bluetooth-device.la @@ -1084,6 +1086,8 @@ SYMDEF_FILES = \ modules/module-raop-discover-symdef.h \ modules/gconf/module-gconf-symdef.h \ modules/module-position-event-sounds-symdef.h \ + modules/module-augment-properties-symdef.h \ + modules/module-cork-music-on-phone-symdef.h \ modules/module-console-kit-symdef.h EXTRA_DIST += $(SYMDEF_FILES) @@ -1336,7 +1340,20 @@ module_volume_restore_la_CFLAGS = $(AM_CFLAGS) module_position_event_sounds_la_SOURCES = modules/module-position-event-sounds.c module_position_event_sounds_la_LDFLAGS = $(MODULE_LDFLAGS) module_position_event_sounds_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la -module_position_event_sounds_CFLAGS = $(AM_CFLAGS) +module_position_event_sounds_la_CFLAGS = $(AM_CFLAGS) + +# Augment properties from XDG .desktop files +module_augment_properties_la_SOURCES = modules/module-augment-properties.c +module_augment_properties_la_LDFLAGS = $(MODULE_LDFLAGS) +module_augment_properties_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +#module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"$(datadir)/applications\" +module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"/usr/share/applications\" + +# Cork music streams while a phone stream is active +module_cork_music_on_phone_la_SOURCES = modules/module-cork-music-on-phone.c +module_cork_music_on_phone_la_LDFLAGS = $(MODULE_LDFLAGS) +module_cork_music_on_phone_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_cork_music_on_phone_la_CFLAGS = $(AM_CFLAGS) # Device volume/muted restore module module_device_restore_la_SOURCES = modules/module-device-restore.c diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 279fb7ba..7d3b89f0 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -200,7 +200,7 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) { return 0; } -static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_log_target(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -216,7 +216,7 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva return 0; } -static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_log_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -232,7 +232,7 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval return 0; } -static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_resample_method(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_assert(filename); @@ -248,7 +248,7 @@ static int parse_resample_method(const char *filename, unsigned line, const char return 0; } -static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_rlimit(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { #ifdef HAVE_SYS_RESOURCE_H struct pa_rlimit *r = data; @@ -277,7 +277,7 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, return 0; } -static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_sample_format(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; pa_sample_format_t f; @@ -295,7 +295,7 @@ static int parse_sample_format(const char *filename, unsigned line, const char * return 0; } -static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; uint32_t r; @@ -313,7 +313,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv return 0; } -static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_sample_channels(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -331,7 +331,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char return 0; } -static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_fragments(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -349,7 +349,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval return 0; } -static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_fragment_size_msec(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t n; @@ -367,7 +367,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c return 0; } -static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_nice_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t level; @@ -385,7 +385,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva return 0; } -static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +static int parse_rtprio(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { pa_daemon_conf *c = data; int32_t rtprio; @@ -409,77 +409,77 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { unsigned i = 0; pa_config_item table[] = { - { "daemonize", pa_config_parse_bool, NULL }, - { "fail", pa_config_parse_bool, NULL }, - { "high-priority", pa_config_parse_bool, NULL }, - { "realtime-scheduling", pa_config_parse_bool, NULL }, - { "disallow-module-loading", pa_config_parse_bool, NULL }, - { "disallow-exit", pa_config_parse_bool, NULL }, - { "use-pid-file", pa_config_parse_bool, NULL }, - { "system-instance", pa_config_parse_bool, NULL }, - { "no-cpu-limit", pa_config_parse_bool, NULL }, - { "disable-shm", pa_config_parse_bool, NULL }, - { "flat-volumes", pa_config_parse_bool, NULL }, - { "exit-idle-time", pa_config_parse_int, NULL }, - { "scache-idle-time", pa_config_parse_int, NULL }, - { "realtime-priority", parse_rtprio, NULL }, - { "dl-search-path", pa_config_parse_string, NULL }, - { "default-script-file", pa_config_parse_string, NULL }, - { "log-target", parse_log_target, NULL }, - { "log-level", parse_log_level, NULL }, - { "verbose", parse_log_level, NULL }, - { "resample-method", parse_resample_method, NULL }, - { "default-sample-format", parse_sample_format, NULL }, - { "default-sample-rate", parse_sample_rate, NULL }, - { "default-sample-channels", parse_sample_channels, NULL }, - { "default-fragments", parse_fragments, NULL }, - { "default-fragment-size-msec", parse_fragment_size_msec, NULL }, - { "nice-level", parse_nice_level, NULL }, - { "disable-remixing", pa_config_parse_bool, NULL }, - { "disable-lfe-remixing", pa_config_parse_bool, NULL }, - { "load-default-script-file", pa_config_parse_bool, NULL }, - { "shm-size-bytes", pa_config_parse_size, NULL }, - { "log-meta", pa_config_parse_bool, NULL }, - { "log-time", pa_config_parse_bool, NULL }, - { "log-backtrace", pa_config_parse_unsigned, NULL }, + { "daemonize", pa_config_parse_bool, NULL, NULL }, + { "fail", pa_config_parse_bool, NULL, NULL }, + { "high-priority", pa_config_parse_bool, NULL, NULL }, + { "realtime-scheduling", pa_config_parse_bool, NULL, NULL }, + { "disallow-module-loading", pa_config_parse_bool, NULL, NULL }, + { "disallow-exit", pa_config_parse_bool, NULL, NULL }, + { "use-pid-file", pa_config_parse_bool, NULL, NULL }, + { "system-instance", pa_config_parse_bool, NULL, NULL }, + { "no-cpu-limit", pa_config_parse_bool, NULL, NULL }, + { "disable-shm", pa_config_parse_bool, NULL, NULL }, + { "flat-volumes", pa_config_parse_bool, NULL, NULL }, + { "exit-idle-time", pa_config_parse_int, NULL, NULL }, + { "scache-idle-time", pa_config_parse_int, NULL, NULL }, + { "realtime-priority", parse_rtprio, NULL, NULL }, + { "dl-search-path", pa_config_parse_string, NULL, NULL }, + { "default-script-file", pa_config_parse_string, NULL, NULL }, + { "log-target", parse_log_target, NULL, NULL }, + { "log-level", parse_log_level, NULL, NULL }, + { "verbose", parse_log_level, NULL, NULL }, + { "resample-method", parse_resample_method, NULL, NULL }, + { "default-sample-format", parse_sample_format, NULL, NULL }, + { "default-sample-rate", parse_sample_rate, NULL, NULL }, + { "default-sample-channels", parse_sample_channels, NULL, NULL }, + { "default-fragments", parse_fragments, NULL, NULL }, + { "default-fragment-size-msec", parse_fragment_size_msec, NULL, NULL }, + { "nice-level", parse_nice_level, NULL, NULL }, + { "disable-remixing", pa_config_parse_bool, NULL, NULL }, + { "disable-lfe-remixing", pa_config_parse_bool, NULL, NULL }, + { "load-default-script-file", pa_config_parse_bool, NULL, NULL }, + { "shm-size-bytes", pa_config_parse_size, NULL, NULL }, + { "log-meta", pa_config_parse_bool, NULL, NULL }, + { "log-time", pa_config_parse_bool, NULL, NULL }, + { "log-backtrace", pa_config_parse_unsigned, NULL, NULL }, #ifdef HAVE_SYS_RESOURCE_H - { "rlimit-fsize", parse_rlimit, NULL }, - { "rlimit-data", parse_rlimit, NULL }, - { "rlimit-stack", parse_rlimit, NULL }, - { "rlimit-core", parse_rlimit, NULL }, - { "rlimit-rss", parse_rlimit, NULL }, + { "rlimit-fsize", parse_rlimit, NULL, NULL }, + { "rlimit-data", parse_rlimit, NULL, NULL }, + { "rlimit-stack", parse_rlimit, NULL, NULL }, + { "rlimit-core", parse_rlimit, NULL, NULL }, + { "rlimit-rss", parse_rlimit, NULL, NULL }, #ifdef RLIMIT_NOFILE - { "rlimit-nofile", parse_rlimit, NULL }, + { "rlimit-nofile", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_AS - { "rlimit-as", parse_rlimit, NULL }, + { "rlimit-as", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_NPROC - { "rlimit-nproc", parse_rlimit, NULL }, + { "rlimit-nproc", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_MEMLOCK - { "rlimit-memlock", parse_rlimit, NULL }, + { "rlimit-memlock", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_LOCKS - { "rlimit-locks", parse_rlimit, NULL }, + { "rlimit-locks", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_SIGPENDING - { "rlimit-sigpending", parse_rlimit, NULL }, + { "rlimit-sigpending", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_MSGQUEUE - { "rlimit-msgqueue", parse_rlimit, NULL }, + { "rlimit-msgqueue", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_NICE - { "rlimit-nice", parse_rlimit, NULL }, + { "rlimit-nice", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_RTPRIO - { "rlimit-rtprio", parse_rlimit, NULL }, + { "rlimit-rtprio", parse_rlimit, NULL, NULL }, #endif #ifdef RLIMIT_RTTIME - { "rlimit-rttime", parse_rlimit, NULL }, + { "rlimit-rttime", parse_rlimit, NULL, NULL }, #endif #endif - { NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL }, }; table[i++].data = &c->daemonize; diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 91a1c614..02ac8e57 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -34,6 +34,10 @@ load-module module-device-restore load-module module-stream-restore load-module module-card-restore +### Automatically augment property information from .desktop files +### stored in /usr/share/application +load-module module-augment-properties + ### Load audio drivers statically (it's probably better to not load ### these drivers manually, but instead use module-hal-detect -- ### see below -- for doing this automatically) @@ -106,6 +110,9 @@ load-module module-console-kit ### Enable positioned event sounds load-module module-position-event-sounds +### Cork music streams when a phone stream is active +load-module module-cork-music-on-phone + # X11 modules should not be started from default.pa so that one daemon # can be shared by multiple sessions. diff --git a/src/map-file b/src/map-file index 3aa1d7a8..d9496593 100644 --- a/src/map-file +++ b/src/map-file @@ -1,5 +1,7 @@ PULSE_0 { global: +pa_ascii_filter; +pa_ascii_valid; pa_browser_new; pa_browser_new_full; pa_browser_ref; @@ -85,6 +87,7 @@ pa_context_set_card_profile_by_index; pa_context_set_card_profile_by_name; pa_context_set_default_sink; pa_context_set_default_source; +pa_context_set_event_callback; pa_context_set_name; pa_context_set_sink_input_mute; pa_context_set_sink_input_volume; @@ -109,6 +112,7 @@ pa_context_unref; pa_cvolume_avg; pa_cvolume_channels_equal_to; pa_cvolume_compatible; +pa_cvolume_compatible_with_channel_map; pa_cvolume_equal; pa_cvolume_get_balance; pa_cvolume_get_fade; @@ -180,6 +184,7 @@ pa_proplist_unset_many; pa_proplist_update; pa_sample_format_to_string; pa_sample_size; +pa_sample_size_of_format; pa_sample_spec_equal; pa_sample_spec_init; pa_sample_spec_snprint; @@ -228,6 +233,7 @@ pa_stream_proplist_update; pa_stream_readable_size; pa_stream_ref; pa_stream_set_buffer_attr; +pa_stream_set_event_callback; pa_stream_set_latency_update_callback; pa_stream_set_monitor_stream; pa_stream_set_moved_callback; diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 22460bb0..c56614c8 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -190,7 +190,9 @@ static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) { if (left_to_play > 0) { /* pa_log_debug("%0.2f ms left to play", (double) pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) / PA_USEC_PER_MSEC); */ } else if (!u->first && !u->after_rewind) { - pa_log_info("Underrun!"); + + if (pa_log_ratelimit()) + pa_log_info("Underrun!"); if (u->use_tsched) { size_t old_watermark = u->tsched_watermark; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 0fd9838c..2b42d3f9 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -187,7 +187,8 @@ static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) { if (left_to_record > 0) { /* pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record, &u->source->sample_spec) / PA_USEC_PER_MSEC); */ } else { - pa_log_info("Overrun!"); + if (pa_log_ratelimit()) + pa_log_info("Overrun!"); if (u->use_tsched) { size_t old_watermark = u->tsched_watermark; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 666dc6a7..94195957 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1095,6 +1095,9 @@ finish: /* dbus_error_init(&err); */ +/* if (!dbus_message_has_path(msg, u->path)) */ +/* goto done; */ + /* if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged") || */ /* dbus_message_is_signal(msg, "org.bluez.AudioSink", "PropertyChanged")) { */ diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c new file mode 100644 index 00000000..90bfbe7d --- /dev/null +++ b/src/modules/module-augment-properties.c @@ -0,0 +1,286 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + 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 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/stat.h> + +#include <pulse/xmalloc.h> +#include <pulse/volume.h> +#include <pulse/channelmap.h> + +#include <pulsecore/core-error.h> +#include <pulsecore/module.h> +#include <pulsecore/core-util.h> +#include <pulsecore/modargs.h> +#include <pulsecore/log.h> +#include <pulsecore/client.h> +#include <pulsecore/conf-parser.h> + +#include "module-augment-properties-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering"); +PA_MODULE_DESCRIPTION("Augment the property sets of streams with additional static information"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(TRUE); + +#define STAT_INTERVAL 30 +#define MAX_CACHE_SIZE 50 + +static const char* const valid_modargs[] = { + NULL +}; + +struct rule { + time_t timestamp; + pa_bool_t good; + time_t mtime; + char *process_name; + char *application_name; + char *icon_name; + pa_proplist *proplist; +}; + +struct userdata { + pa_hashmap *cache; + pa_hook_slot *client_new_slot, *client_proplist_changed_slot; +}; + +static void rule_free(struct rule *r) { + pa_assert(r); + + pa_xfree(r->process_name); + pa_xfree(r->application_name); + pa_xfree(r->icon_name); + if (r->proplist) + pa_proplist_free(r->proplist); + pa_xfree(r); +} + +static int parse_properties(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { + struct rule *r = userdata; + pa_proplist *n; + + if (!(n = pa_proplist_from_string(rvalue))) + return -1; + + if (r->proplist) { + pa_proplist_update(r->proplist, PA_UPDATE_MERGE, n); + pa_proplist_free(n); + } else + r->proplist = n; + + return 0; +} + +static int check_type(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { + return pa_streq(rvalue, "Application") ? 0 : -1; +} + +static int catch_all(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { + return 0; +} + +static void update_rule(struct rule *r) { + char *fn; + struct stat st; + static pa_config_item table[] = { + { "Name", pa_config_parse_string, NULL, "Desktop Entry" }, + { "Icon", pa_config_parse_string, NULL, "Desktop Entry" }, + { "Type", check_type, NULL, "Desktop Entry" }, + { "X-PulseAudio-Properties", parse_properties, NULL, "Desktop Entry" }, + { NULL, catch_all, NULL, NULL }, + { NULL, NULL, NULL, NULL }, + }; + + pa_assert(r); + fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s.desktop", r->process_name); + + if (stat(fn, &st) < 0) { + r->good = FALSE; + pa_xfree(fn); + return; + } + + if (r->good && st.st_mtime == r->mtime) { + pa_xfree(fn); + return; + } + + r->good = TRUE; + r->mtime = st.st_mtime; + pa_xfree(r->application_name); + pa_xfree(r->icon_name); + r->application_name = r->icon_name = NULL; + if (r->proplist) + pa_proplist_clear(r->proplist); + + table[0].data = &r->application_name; + table[1].data = &r->icon_name; + + if (pa_config_parse(fn, NULL, table, r) < 0) + pa_log_warn("Failed to parse .desktop file %s.", fn); + + pa_xfree(fn); +} + +static void apply_rule(struct rule *r, pa_proplist *p) { + pa_assert(r); + pa_assert(p); + + if (!r->good) + return; + + if (r->icon_name) + if (!pa_proplist_contains(p, PA_PROP_APPLICATION_ICON_NAME)) + pa_proplist_sets(p, PA_PROP_APPLICATION_ICON_NAME, r->icon_name); + + if (r->application_name) { + const char *t; + + t = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME); + + if (!t || pa_streq(t, r->process_name)) + pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, r->application_name); + } + + if (r->proplist) + pa_proplist_update(p, PA_UPDATE_MERGE, r->proplist); +} + +static void make_room(pa_hashmap *cache) { + pa_assert(cache); + + while (pa_hashmap_size(cache) >= MAX_CACHE_SIZE) { + struct rule *r; + + pa_assert_se(r = pa_hashmap_steal_first(cache)); + rule_free(r); + } +} + +static pa_hook_result_t process(struct userdata *u, pa_proplist *p) { + struct rule *r; + time_t now; + const char *pn; + + pa_assert(u); + pa_assert(p); + + if (!(pn = pa_proplist_gets(p, PA_PROP_APPLICATION_PROCESS_BINARY))) + return PA_HOOK_OK; + + if (*pn == '.' || strchr(pn, '/')) + return PA_HOOK_OK; + + time(&now); + + if ((r = pa_hashmap_get(u->cache, pn))) { + if (now-r->timestamp > STAT_INTERVAL) { + r->timestamp = now; + update_rule(r); + } + } else { + make_room(u->cache); + + r = pa_xnew0(struct rule, 1); + r->process_name = pa_xstrdup(pn); + r->timestamp = now; + pa_hashmap_put(u->cache, r->process_name, r); + update_rule(r); + } + + apply_rule(r, p); + return PA_HOOK_OK; +} + +static pa_hook_result_t client_new_cb(pa_core *core, pa_client_new_data *data, struct userdata *u) { + pa_core_assert_ref(core); + pa_assert(data); + pa_assert(u); + + return process(u, data->proplist); +} + +static pa_hook_result_t client_proplist_changed_cb(pa_core *core, pa_client *client, struct userdata *u) { + pa_core_assert_ref(core); + pa_assert(client); + pa_assert(u); + + return process(u, client->proplist); +} + +int pa__init(pa_module *m) { + pa_modargs *ma = NULL; + struct userdata *u; + + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + goto fail; + } + + m->userdata = u = pa_xnew(struct userdata, 1); + + u->cache = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + u->client_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CLIENT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) client_new_cb, u); + u->client_proplist_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) client_proplist_changed_cb, u); + + pa_modargs_free(ma); + + return 0; + +fail: + pa__done(m); + + if (ma) + pa_modargs_free(ma); + + return -1; +} + +void pa__done(pa_module *m) { + struct userdata* u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->client_new_slot) + pa_hook_slot_free(u->client_new_slot); + if (u->client_proplist_changed_slot) + pa_hook_slot_free(u->client_proplist_changed_slot); + + if (u->cache) { + struct rule *r; + + while ((r = pa_hashmap_steal_first(u->cache))) + rule_free(r); + + pa_hashmap_free(u->cache, NULL, NULL); + } + + pa_xfree(u); +} diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c index 02e973c4..4dffd365 100644 --- a/src/modules/module-card-restore.c +++ b/src/modules/module-card-restore.c @@ -68,7 +68,10 @@ struct userdata { GDBM_FILE gdbm_file; }; -struct entry { +#define ENTRY_VERSION 1 + +struct entry PA_GCC_PACKED { + uint8_t version; char profile[PA_NAME_MAX]; }; @@ -104,12 +107,17 @@ static struct entry* read_entry(struct userdata *u, const char *name) { goto fail; if (data.dsize != sizeof(struct entry)) { - pa_log_warn("Database contains entry for card %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); + pa_log_debug("Database contains entry for card %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); goto fail; } e = (struct entry*) data.dptr; + if (e->version != ENTRY_VERSION) { + pa_log_debug("Version of database entry for card %s doesn't match our version. Probably due to upgrade, ignoring.", name); + goto fail; + } + if (!memchr(e->profile, 0, sizeof(e->profile))) { pa_log_warn("Database contains entry for card %s with missing NUL byte in profile name", name); goto fail; @@ -148,6 +156,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 return; memset(&entry, 0, sizeof(entry)); + entry.version = ENTRY_VERSION; if (!(card = pa_idxset_get_by_index(c->cards, idx))) return; diff --git a/src/modules/module-cork-music-on-phone.c b/src/modules/module-cork-music-on-phone.c new file mode 100644 index 00000000..fb90cf34 --- /dev/null +++ b/src/modules/module-cork-music-on-phone.c @@ -0,0 +1,224 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + 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 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulsecore/macro.h> +#include <pulsecore/hashmap.h> +#include <pulsecore/hook-list.h> +#include <pulsecore/core.h> +#include <pulsecore/core-util.h> +#include <pulsecore/sink-input.h> +#include <pulsecore/modargs.h> + +#include "module-cork-music-on-phone-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering"); +PA_MODULE_DESCRIPTION("Mute or cork music while a phone stream exists"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(TRUE); + +static const char* const valid_modargs[] = { + NULL +}; + +struct userdata { + pa_core *core; + pa_hashmap *cork_state; + pa_hook_slot + *sink_input_put_slot, + *sink_input_unlink_slot, + *sink_input_move_start_slot, + *sink_input_move_finish_slot; +}; + +static pa_bool_t shall_cork(pa_sink *s, pa_sink_input *ignore) { + pa_sink_input *j; + uint32_t idx; + pa_sink_assert_ref(s); + + for (j = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); j; j = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) { + const char *role; + + if (j == ignore) + continue; + + if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE))) + continue; + + if (pa_streq(role, "phone")) + return TRUE; + } + + return FALSE; +} + +static void apply_cork(struct userdata *u, pa_sink *s, pa_sink_input *ignore, pa_bool_t cork) { + pa_sink_input *j; + uint32_t idx; + + pa_assert(u); + pa_sink_assert_ref(s); + + for (j = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); j; j = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) { + pa_bool_t corked; + const char *role; + + if (j == ignore) + continue; + + if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE))) + continue; + + if (!pa_streq(role, "video") && + !pa_streq(role, "music")) + continue; + + corked = !!pa_hashmap_get(u->cork_state, j); + + if (cork && !corked) { + pa_hashmap_put(u->cork_state, j, PA_INT_TO_PTR(1)); + pa_sink_input_set_mute(j, TRUE, FALSE); + pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_CORK, NULL); + } else if (!cork) { + pa_hashmap_remove(u->cork_state, j); + + if (corked) { + pa_sink_input_set_mute(j, FALSE, FALSE); + pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_UNCORK, NULL); + } + } + } +} + +static pa_hook_result_t process(struct userdata *u, pa_sink_input *i, pa_bool_t create) { + pa_bool_t cork = FALSE; + const char *role; + + pa_assert(u); + pa_sink_input_assert_ref(i); + + if (!create) + pa_hashmap_remove(u->cork_state, i); + + if (!(role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE))) + return PA_HOOK_OK; + + if (!pa_streq(role, "phone") && + !pa_streq(role, "music") && + !pa_streq(role, "video")) + return PA_HOOK_OK; + + cork = shall_cork(i->sink, create ? NULL : i); + apply_cork(u, i->sink, create ? NULL : i, cork); + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_core_assert_ref(core); + pa_sink_input_assert_ref(i); + + return process(u, i, TRUE); +} + +static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_core_assert_ref(core); + pa_sink_input_assert_ref(i); + + return process(u, i, FALSE); +} + +static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_core_assert_ref(core); + pa_sink_input_assert_ref(i); + + return process(u, i, FALSE); +} + +static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_core_assert_ref(core); + pa_sink_input_assert_ref(i); + + return process(u, i, TRUE); +} + +int pa__init(pa_module *m) { + pa_modargs *ma = NULL; + struct userdata *u; + + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + goto fail; + } + + m->userdata = u = pa_xnew(struct userdata, 1); + + u->core = m->core; + u->cork_state = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_put_cb, u); + u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u); + u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u); + u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u); + + pa_modargs_free(ma); + + return 0; + +fail: + pa__done(m); + + if (ma) + pa_modargs_free(ma); + + return -1; + + +} + +void pa__done(pa_module *m) { + struct userdata* u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->sink_input_put_slot) + pa_hook_slot_free(u->sink_input_put_slot); + if (u->sink_input_unlink_slot) + pa_hook_slot_free(u->sink_input_unlink_slot); + if (u->sink_input_move_start_slot) + pa_hook_slot_free(u->sink_input_move_start_slot); + if (u->sink_input_move_finish_slot) + pa_hook_slot_free(u->sink_input_move_finish_slot); + + if (u->cork_state) + pa_hashmap_free(u->cork_state, NULL, NULL); + + pa_xfree(u); + +} diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c index 8e0cf92b..7c56c240 100644 --- a/src/modules/module-device-restore.c +++ b/src/modules/module-device-restore.c @@ -79,10 +79,13 @@ struct userdata { pa_bool_t restore_muted:1; }; -struct entry { +#define ENTRY_VERSION 1 + +struct entry PA_GCC_PACKED { + uint8_t version; + pa_bool_t muted:1; pa_channel_map channel_map; pa_cvolume volume; - pa_bool_t muted:1; }; static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { @@ -117,12 +120,17 @@ static struct entry* read_entry(struct userdata *u, const char *name) { goto fail; if (data.dsize != sizeof(struct entry)) { - pa_log_warn("Database contains entry for device %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); + pa_log_debug("Database contains entry for device %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); goto fail; } e = (struct entry*) data.dptr; + if (e->version != ENTRY_VERSION) { + pa_log_debug("Version of database entry for device %s doesn't match our version. Probably due to upgrade, ignoring.", name); + goto fail; + } + if (!(pa_cvolume_valid(&e->volume))) { pa_log_warn("Invalid volume stored in database for device %s", name); goto fail; @@ -173,6 +181,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 return; memset(&entry, 0, sizeof(entry)); + entry.version = ENTRY_VERSION; if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) { pa_sink *sink; diff --git a/src/modules/module-match.c b/src/modules/module-match.c index cbf62687..17936110 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -233,7 +233,6 @@ int pa__init(pa_module*m) { goto fail; } - u = pa_xnew(struct userdata, 1); u->rules = NULL; u->subscription = NULL; diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c index 8e4f4c32..6252ebab 100644 --- a/src/modules/module-position-event-sounds.c +++ b/src/modules/module-position-event-sounds.c @@ -54,7 +54,6 @@ static const char* const valid_modargs[] = { }; struct userdata { - pa_core *core; pa_hook_slot *sink_input_fixate_hook_slot; }; @@ -62,6 +61,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i const char *hpos; double f; char t[PA_CVOLUME_SNPRINT_MAX]; + pa_cvolume v; pa_assert(data); @@ -80,16 +80,12 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i pa_log_debug("Positioning event sound '%s' at %0.2f.", pa_strnull(pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID)), f); - if (!data->virtual_volume_is_set) { - pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels); - data->virtual_volume_is_set = TRUE; - data->virtual_volume_is_absolute = FALSE; - } + pa_cvolume_reset(&v, data->sample_spec.channels); + pa_cvolume_set_balance(&v, &data->channel_map, f*2.0-1.0); - pa_cvolume_set_balance(&data->virtual_volume, &data->channel_map, f*2.0-1.0); - data->save_volume = FALSE; + pa_log_debug("Final volume factor %s.", pa_cvolume_snprint(t, sizeof(t), &v)); - pa_log_debug("Final volume %s.", pa_cvolume_snprint(t, sizeof(t), &data->virtual_volume)); + pa_sink_input_new_data_apply_volume_factor(data, &v); return PA_HOOK_OK; } @@ -106,7 +102,6 @@ int pa__init(pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->core = m->core; u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u); pa_modargs_free(ma); diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index 74ee6122..1784b2cc 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -100,9 +100,6 @@ struct userdata { pa_usec_t latency; - pa_volume_t volume; - pa_bool_t muted; - /*esd_format_t format;*/ int32_t rate; @@ -133,6 +130,9 @@ enum { SINK_MESSAGE_RIP_SOCKET }; +/* Forward declaration */ +static void sink_set_volume_cb(pa_sink *); + static void on_connection(PA_GCC_UNUSED int fd, void*userdata) { struct userdata *u = userdata; pa_assert(u); @@ -141,7 +141,7 @@ static void on_connection(PA_GCC_UNUSED int fd, void*userdata) { u->fd = fd; /* Set the initial volume */ - pa_raop_client_set_volume(u->raop, u->volume); + sink_set_volume_cb(u->sink); pa_log_debug("Connection authenticated, handing fd to IO thread..."); @@ -255,43 +255,36 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse return pa_sink_process_msg(o, code, data, offset, chunk); } -static void sink_get_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; - int i; - - pa_assert(u); - - for (i = 0; i < s->sample_spec.channels; i++) - s->virtual_volume.values[i] = u->volume; -} - static void sink_set_volume_cb(pa_sink *s) { struct userdata *u = s->userdata; - int rv; + pa_cvolume hw; + pa_volume_t v; + char t[PA_CVOLUME_SNPRINT_MAX]; pa_assert(u); - /* If we're muted, we fake it */ - if (u->muted) + /* If we're muted we don't need to do anything */ + if (s->muted) return; - pa_assert(s->sample_spec.channels > 0); + /* Calculate the max volume of all channels. + We'll use this as our (single) volume on the APEX device and emulate + any variation in channel volumes in software */ + v = pa_cvolume_max(&s->virtual_volume); - /* Avoid pointless volume sets */ - if (u->volume == s->virtual_volume.values[0]) - return; + /* Create a pa_cvolume version of our single value */ + pa_cvolume_set(&hw, s->sample_spec.channels, v); - rv = pa_raop_client_set_volume(u->raop, s->virtual_volume.values[0]); - if (0 == rv) - u->volume = s->virtual_volume.values[0]; -} + /* Perform any software manipulation of the volume needed */ + pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &hw); -static void sink_get_mute_cb(pa_sink *s) { - struct userdata *u = s->userdata; + pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume)); + pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &hw)); + pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->soft_volume)); - pa_assert(u); - - s->muted = u->muted; + /* Any necessary software volume manipulateion is done so set + our hw volume (or v as a single value) on the device */ + pa_raop_client_set_volume(u->raop, v); } static void sink_set_mute_cb(pa_sink *s) { @@ -299,8 +292,11 @@ static void sink_set_mute_cb(pa_sink *s) { pa_assert(u); - pa_raop_client_set_volume(u->raop, (s->muted ? PA_VOLUME_MUTED : u->volume)); - u->muted = s->muted; + if (s->muted) { + pa_raop_client_set_volume(u->raop, PA_VOLUME_MUTED); + } else { + sink_set_volume_cb(s); + } } static void thread_func(void *userdata) { @@ -541,9 +537,6 @@ int pa__init(pa_module*m) { u->next_encoding_overhead = 0; u->encoding_ratio = 1.0; - u->volume = roundf(0.7 * PA_VOLUME_NORM); - u->muted = FALSE; - u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); u->rtpoll_item = NULL; @@ -583,9 +576,7 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - u->sink->get_volume = sink_get_volume_cb; u->sink->set_volume = sink_set_volume_cb; - u->sink->get_mute = sink_get_mute_cb; u->sink->set_mute = sink_set_mute_cb; u->sink->flags = PA_SINK_LATENCY|PA_SINK_NETWORK|PA_SINK_HW_VOLUME_CTRL; diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 0c9bd4f9..2dd2045e 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -62,6 +62,7 @@ PA_MODULE_USAGE( "restore_muted=<Save/restore muted states?>"); #define SAVE_INTERVAL 10 +#define IDENTIFICATION_PROPERTY "module-stream-restore.id" static const char* const valid_modargs[] = { "restore_device", @@ -90,16 +91,18 @@ struct userdata { pa_idxset *subscribed; }; -struct entry { +#define ENTRY_VERSION 1 + +struct entry PA_GCC_PACKED { + uint8_t version; + pa_bool_t muted_valid:1, relative_volume_valid:1, absolute_volume_valid:1, device_valid:1; + pa_bool_t muted:1; pa_channel_map channel_map; - char device[PA_NAME_MAX]; pa_cvolume relative_volume; pa_cvolume absolute_volume; - pa_bool_t muted:1; - pa_bool_t device_valid:1, relative_volume_valid:1, absolute_volume_valid:1, muted_valid:1; + char device[PA_NAME_MAX]; }; - enum { SUBCOMMAND_TEST, SUBCOMMAND_READ, @@ -127,20 +130,27 @@ static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct static char *get_name(pa_proplist *p, const char *prefix) { const char *r; + char *t; if (!p) return NULL; + if ((r = pa_proplist_gets(p, IDENTIFICATION_PROPERTY))) + return pa_xstrdup(r); + if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE))) - return pa_sprintf_malloc("%s-by-media-role:%s", prefix, r); + t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r); else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID))) - return pa_sprintf_malloc("%s-by-application-id:%s", prefix, r); + t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r); else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME))) - return pa_sprintf_malloc("%s-by-application-name:%s", prefix, r); + t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r); else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME))) - return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r); + t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r); + else + t = pa_sprintf_malloc("%s-fallback:%s", prefix, r); - return pa_sprintf_malloc("%s-fallback:%s", prefix, r); + pa_proplist_sets(p, IDENTIFICATION_PROPERTY, t); + return t; } static struct entry* read_entry(struct userdata *u, const char *name) { @@ -161,19 +171,19 @@ static struct entry* read_entry(struct userdata *u, const char *name) { if (data.dsize != sizeof(struct entry)) { /* This is probably just a database upgrade, hence let's not * consider this more than a debug message */ - pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); + pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu. Probably due to uprade, ignoring.", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry)); goto fail; } e = (struct entry*) data.dptr; - if (!memchr(e->device, 0, sizeof(e->device))) { - pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name); + if (e->version != ENTRY_VERSION) { + pa_log_debug("Version of database entry for stream %s doesn't match our version. Probably due to upgrade, ignoring.", name); goto fail; } - if (!(pa_channel_map_valid(&e->channel_map))) { - pa_log_warn("Invalid channel map stored in database for stream %s", name); + if (!memchr(e->device, 0, sizeof(e->device))) { + pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name); goto fail; } @@ -182,6 +192,11 @@ static struct entry* read_entry(struct userdata *u, const char *name) { goto fail; } + if ((e->relative_volume_valid || e->absolute_volume_valid) && !(pa_channel_map_valid(&e->channel_map))) { + pa_log_warn("Invalid channel map stored in database for stream %s", name); + goto fail; + } + if ((e->relative_volume_valid && (!pa_cvolume_valid(&e->relative_volume) || e->relative_volume.channels != e->channel_map.channels)) || (e->absolute_volume_valid && (!pa_cvolume_valid(&e->absolute_volume) || e->absolute_volume.channels != e->channel_map.channels))) { pa_log_warn("Invalid volume stored in database for stream %s", name); @@ -233,7 +248,7 @@ static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) { return FALSE; if (a->muted_valid != b->muted_valid || - (a->muted && (a->muted != b->muted))) + (a->muted_valid && (a->muted != b->muted))) return FALSE; t = b->relative_volume; @@ -265,6 +280,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 return; memset(&entry, 0, sizeof(entry)); + entry.version = ENTRY_VERSION; if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) { pa_sink_input *sink_input; @@ -388,32 +404,33 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu if (u->restore_volume) { - if (!new_data->virtual_volume_is_set) { + if (!new_data->volume_is_set) { pa_cvolume v; pa_cvolume_init(&v); if (new_data->sink->flags & PA_SINK_FLAT_VOLUME) { + /* We don't check for e->device_valid here because + that bit marks whether it is a good choice for + restoring, not just if the data is filled in. */ if (e->absolute_volume_valid && - e->device_valid && - pa_streq(new_data->sink->name, e->device)) { + (e->device[0] == 0 || pa_streq(new_data->sink->name, e->device))) { v = e->absolute_volume; - new_data->virtual_volume_is_absolute = TRUE; + new_data->volume_is_absolute = TRUE; } else if (e->relative_volume_valid) { - v = e->relative_volume; - new_data->virtual_volume_is_absolute = FALSE; + new_data->volume_is_absolute = FALSE; } } else if (e->relative_volume_valid) { v = e->relative_volume; - new_data->virtual_volume_is_absolute = FALSE; + new_data->volume_is_absolute = FALSE; } if (v.channels > 0) { pa_log_info("Restoring volume for sink input %s.", name); - pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map)); + pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map)); new_data->save_volume = TRUE; } } else @@ -523,11 +540,10 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) { if (si->sink->flags & PA_SINK_FLAT_VOLUME) { if (e->absolute_volume_valid && - e->device_valid && - pa_streq(e->device, si->sink->name)) + (e->device[0] == 0 || pa_streq(e->device, si->sink->name))) v = e->absolute_volume; else if (e->relative_volume_valid) { - pa_cvolume t = si->sink->virtual_volume; + pa_cvolume t = *pa_sink_get_volume(si->sink, FALSE); pa_sw_cvolume_multiply(&v, &e->relative_volume, pa_cvolume_remap(&t, &si->sink->channel_map, &e->channel_map)); } } else if (e->relative_volume_valid) @@ -655,10 +671,11 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio if ((e = read_entry(u, name))) { pa_cvolume r; + pa_channel_map cm; pa_tagstruct_puts(reply, name); - pa_tagstruct_put_channel_map(reply, &e->channel_map); - pa_tagstruct_put_cvolume(reply, e->relative_volume_valid ? &e->relative_volume : pa_cvolume_init(&r)); + pa_tagstruct_put_channel_map(reply, (e->relative_volume_valid || e->absolute_volume_valid) ? &e->channel_map : pa_channel_map_init(&cm)); + pa_tagstruct_put_cvolume(reply, e->absolute_volume_valid ? &e->absolute_volume : (e->relative_volume_valid ? &e->relative_volume : pa_cvolume_init(&r))); pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL); pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE); @@ -697,21 +714,25 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio int k; memset(&entry, 0, sizeof(entry)); + entry.version = ENTRY_VERSION; if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_get_channel_map(t, &entry.channel_map) || - pa_tagstruct_get_cvolume(t, &entry.relative_volume) < 0 || + pa_tagstruct_get_cvolume(t, &entry.absolute_volume) < 0 || pa_tagstruct_gets(t, &device) < 0 || pa_tagstruct_get_boolean(t, &muted) < 0) goto fail; - entry.absolute_volume_valid = FALSE; - entry.relative_volume_valid = entry.relative_volume.channels > 0; - - if (entry.relative_volume_valid && - entry.channel_map.channels != entry.relative_volume.channels) + if (!name || !*name) goto fail; + entry.relative_volume = entry.absolute_volume; + entry.absolute_volume_valid = entry.relative_volume_valid = entry.relative_volume.channels > 0; + + if (entry.relative_volume_valid) + if (!pa_cvolume_compatible_with_channel_map(&entry.relative_volume, &entry.channel_map)) + goto fail; + entry.muted = muted; entry.muted_valid = TRUE; diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 5c7a6e55..26da2575 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -662,7 +662,7 @@ fail: /* Called from main context */ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { struct userdata *u = userdata; - pa_usec_t sink_usec, source_usec, transport_usec; + pa_usec_t sink_usec, source_usec, transport_usec = 0; pa_bool_t playing; int64_t write_index, read_index; struct timeval local, remote, now; diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index baf3532f..c118b5c6 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -453,7 +453,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in data.module = u->module; pa_sink_input_new_data_set_sample_spec(&data, &sdp_info->sample_spec); - pa_sink_input_new(&s->sink_input, u->module->core, &data, 0); + pa_sink_input_new(&s->sink_input, u->module->core, &data, PA_SINK_INPUT_VARIABLE_RATE); pa_sink_input_new_data_done(&data); if (!s->sink_input) { diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index 6ff30c26..983b8977 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -434,11 +434,11 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) { const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) { - pa_init_i18n(); - if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX) return NULL; + pa_init_i18n(); + return _(pretty_table[pos]); } @@ -448,6 +448,9 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_channel_map_valid(a), 0); + pa_return_val_if_fail(pa_channel_map_valid(b), 0); + if (a->channels != b->channels) return 0; @@ -502,19 +505,19 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { * "mono" here explicitly, because that can be understood as * listing with one channel called "mono". */ - if (strcmp(s, "stereo") == 0) { + if (pa_streq(s, "stereo")) { map.channels = 2; map.map[0] = PA_CHANNEL_POSITION_LEFT; map.map[1] = PA_CHANNEL_POSITION_RIGHT; goto finish; - } else if (strcmp(s, "surround-40") == 0) { + } else if (pa_streq(s, "surround-40")) { map.channels = 4; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; goto finish; - } else if (strcmp(s, "surround-41") == 0) { + } else if (pa_streq(s, "surround-41")) { map.channels = 5; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; @@ -522,7 +525,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; map.map[4] = PA_CHANNEL_POSITION_LFE; goto finish; - } else if (strcmp(s, "surround-50") == 0) { + } else if (pa_streq(s, "surround-50")) { map.channels = 5; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; @@ -530,7 +533,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; goto finish; - } else if (strcmp(s, "surround-51") == 0) { + } else if (pa_streq(s, "surround-51")) { map.channels = 6; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; @@ -539,7 +542,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; map.map[5] = PA_CHANNEL_POSITION_LFE; goto finish; - } else if (strcmp(s, "surround-71") == 0) { + } else if (pa_streq(s, "surround-71")) { map.channels = 8; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; @@ -563,13 +566,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { } /* Some special aliases */ - if (strcmp(p, "left") == 0) + if (pa_streq(p, "left")) map.map[map.channels++] = PA_CHANNEL_POSITION_LEFT; - else if (strcmp(p, "right") == 0) + else if (pa_streq(p, "right")) map.map[map.channels++] = PA_CHANNEL_POSITION_RIGHT; - else if (strcmp(p, "center") == 0) + else if (pa_streq(p, "center")) map.map[map.channels++] = PA_CHANNEL_POSITION_CENTER; - else if (strcmp(p, "subwoofer") == 0) + else if (pa_streq(p, "subwoofer")) map.map[map.channels++] = PA_CHANNEL_POSITION_SUBWOOFER; else { pa_channel_position_t i; @@ -617,11 +620,8 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s pa_assert(map); pa_assert(ss); - if (!pa_channel_map_valid(map)) - return 0; - - if (!pa_sample_spec_valid(ss)) - return 0; + pa_return_val_if_fail(pa_channel_map_valid(map), 0); + pa_return_val_if_fail(pa_sample_spec_valid(ss), 0); return map->channels == ss->channels; } @@ -633,6 +633,9 @@ int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) { pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_channel_map_valid(a), 0); + pa_return_val_if_fail(pa_channel_map_valid(b), 0); + memset(in_a, 0, sizeof(in_a)); for (i = 0; i < a->channels; i++) @@ -651,6 +654,8 @@ int pa_channel_map_can_balance(const pa_channel_map *map) { pa_assert(map); + pa_return_val_if_fail(pa_channel_map_valid(map), 0); + for (c = 0; c < map->channels; c++) { switch (map->map[c]) { @@ -687,6 +692,10 @@ int pa_channel_map_can_fade(const pa_channel_map *map) { unsigned c; pa_bool_t front = FALSE, rear = FALSE; + pa_assert(map); + + pa_return_val_if_fail(pa_channel_map_valid(map), 0); + for (c = 0; c < map->channels; c++) { switch (map->map[c]) { @@ -727,6 +736,8 @@ const char* pa_channel_map_to_name(const pa_channel_map *map) { pa_assert(map); + pa_return_val_if_fail(pa_channel_map_valid(map), NULL); + memset(in_map, 0, sizeof(in_map)); for (c = 0; c < map->channels; c++) @@ -779,11 +790,15 @@ const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) { pa_assert(map); + pa_return_val_if_fail(pa_channel_map_valid(map), NULL); + memset(in_map, 0, sizeof(in_map)); for (c = 0; c < map->channels; c++) pa_bitset_set(in_map, map->map[c], TRUE); + pa_init_i18n(); + if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, PA_CHANNEL_POSITION_MONO, -1)) return _("Mono"); diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h index f9124b2e..a6d37d85 100644 --- a/src/pulse/channelmap.h +++ b/src/pulse/channelmap.h @@ -141,6 +141,66 @@ typedef enum pa_channel_position { PA_CHANNEL_POSITION_MAX } pa_channel_position_t; +/** \cond fulldocs */ +#define PA_CHANNEL_POSITION_INVALID PA_CHANNEL_POSITION_INVALID +#define PA_CHANNEL_POSITION_MONO PA_CHANNEL_POSITION_MONO +#define PA_CHANNEL_POSITION_LEFT PA_CHANNEL_POSITION_LEFT +#define PA_CHANNEL_POSITION_RIGHT PA_CHANNEL_POSITION_RIGHT +#define PA_CHANNEL_POSITION_CENTER PA_CHANNEL_POSITION_CENTER +#define PA_CHANNEL_POSITION_FRONT_LEFT PA_CHANNEL_POSITION_FRONT_LEFT +#define PA_CHANNEL_POSITION_FRONT_RIGHT PA_CHANNEL_POSITION_FRONT_RIGHT +#define PA_CHANNEL_POSITION_FRONT_CENTER PA_CHANNEL_POSITION_FRONT_CENTER +#define PA_CHANNEL_POSITION_REAR_CENTER PA_CHANNEL_POSITION_REAR_CENTER +#define PA_CHANNEL_POSITION_REAR_LEFT PA_CHANNEL_POSITION_REAR_LEFT +#define PA_CHANNEL_POSITION_REAR_RIGHT PA_CHANNEL_POSITION_REAR_RIGHT +#define PA_CHANNEL_POSITION_LFE PA_CHANNEL_POSITION_LFE +#define PA_CHANNEL_POSITION_SUBWOOFER PA_CHANNEL_POSITION_SUBWOOFER +#define PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER +#define PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER +#define PA_CHANNEL_POSITION_SIDE_LEFT PA_CHANNEL_POSITION_SIDE_LEFT +#define PA_CHANNEL_POSITION_SIDE_RIGHT PA_CHANNEL_POSITION_SIDE_RIGHT +#define PA_CHANNEL_POSITION_AUX0 PA_CHANNEL_POSITION_AUX0 +#define PA_CHANNEL_POSITION_AUX1 PA_CHANNEL_POSITION_AUX1 +#define PA_CHANNEL_POSITION_AUX2 PA_CHANNEL_POSITION_AUX2 +#define PA_CHANNEL_POSITION_AUX3 PA_CHANNEL_POSITION_AUX3 +#define PA_CHANNEL_POSITION_AUX4 PA_CHANNEL_POSITION_AUX4 +#define PA_CHANNEL_POSITION_AUX5 PA_CHANNEL_POSITION_AUX5 +#define PA_CHANNEL_POSITION_AUX6 PA_CHANNEL_POSITION_AUX6 +#define PA_CHANNEL_POSITION_AUX7 PA_CHANNEL_POSITION_AUX7 +#define PA_CHANNEL_POSITION_AUX8 PA_CHANNEL_POSITION_AUX8 +#define PA_CHANNEL_POSITION_AUX9 PA_CHANNEL_POSITION_AUX9 +#define PA_CHANNEL_POSITION_AUX10 PA_CHANNEL_POSITION_AUX10 +#define PA_CHANNEL_POSITION_AUX11 PA_CHANNEL_POSITION_AUX11 +#define PA_CHANNEL_POSITION_AUX12 PA_CHANNEL_POSITION_AUX12 +#define PA_CHANNEL_POSITION_AUX13 PA_CHANNEL_POSITION_AUX13 +#define PA_CHANNEL_POSITION_AUX14 PA_CHANNEL_POSITION_AUX14 +#define PA_CHANNEL_POSITION_AUX15 PA_CHANNEL_POSITION_AUX15 +#define PA_CHANNEL_POSITION_AUX16 PA_CHANNEL_POSITION_AUX16 +#define PA_CHANNEL_POSITION_AUX17 PA_CHANNEL_POSITION_AUX17 +#define PA_CHANNEL_POSITION_AUX18 PA_CHANNEL_POSITION_AUX18 +#define PA_CHANNEL_POSITION_AUX19 PA_CHANNEL_POSITION_AUX19 +#define PA_CHANNEL_POSITION_AUX20 PA_CHANNEL_POSITION_AUX20 +#define PA_CHANNEL_POSITION_AUX21 PA_CHANNEL_POSITION_AUX21 +#define PA_CHANNEL_POSITION_AUX22 PA_CHANNEL_POSITION_AUX22 +#define PA_CHANNEL_POSITION_AUX23 PA_CHANNEL_POSITION_AUX23 +#define PA_CHANNEL_POSITION_AUX24 PA_CHANNEL_POSITION_AUX24 +#define PA_CHANNEL_POSITION_AUX25 PA_CHANNEL_POSITION_AUX25 +#define PA_CHANNEL_POSITION_AUX26 PA_CHANNEL_POSITION_AUX26 +#define PA_CHANNEL_POSITION_AUX27 PA_CHANNEL_POSITION_AUX27 +#define PA_CHANNEL_POSITION_AUX28 PA_CHANNEL_POSITION_AUX28 +#define PA_CHANNEL_POSITION_AUX29 PA_CHANNEL_POSITION_AUX29 +#define PA_CHANNEL_POSITION_AUX30 PA_CHANNEL_POSITION_AUX30 +#define PA_CHANNEL_POSITION_AUX31 PA_CHANNEL_POSITION_AUX31 +#define PA_CHANNEL_POSITION_TOP_CENTER PA_CHANNEL_POSITION_TOP_CENTER +#define PA_CHANNEL_POSITION_TOP_FRONT_LEFT PA_CHANNEL_POSITION_TOP_FRONT_LEFT +#define PA_CHANNEL_POSITION_TOP_FRONT_RIGHT PA_CHANNEL_POSITION_TOP_FRONT_RIGHT +#define PA_CHANNEL_POSITION_TOP_FRONT_CENTER PA_CHANNEL_POSITION_TOP_FRONT_CENTER +#define PA_CHANNEL_POSITION_TOP_REAR_LEFT PA_CHANNEL_POSITION_TOP_REAR_LEFT +#define PA_CHANNEL_POSITION_TOP_REAR_RIGHT PA_CHANNEL_POSITION_TOP_REAR_RIGHT +#define PA_CHANNEL_POSITION_TOP_REAR_CENTER PA_CHANNEL_POSITION_TOP_REAR_CENTER +#define PA_CHANNEL_POSITION_MAX PA_CHANNEL_POSITION_MAX +/** \endcond */ + /** A list of channel mapping definitions for pa_channel_map_init_auto() */ typedef enum pa_channel_map_def { PA_CHANNEL_MAP_AIFF, @@ -165,6 +225,16 @@ typedef enum pa_channel_map_def { /**< The default channel map */ } pa_channel_map_def_t; +/** \cond fulldocs */ +#define PA_CHANNEL_MAP_AIFF PA_CHANNEL_MAP_AIFF +#define PA_CHANNEL_MAP_ALSA PA_CHANNEL_MAP_ALSA +#define PA_CHANNEL_MAP_AUX PA_CHANNEL_MAP_AUX +#define PA_CHANNEL_MAP_WAVEEX PA_CHANNEL_MAP_WAVEEX +#define PA_CHANNEL_MAP_OSS PA_CHANNEL_MAP_OSS +#define PA_CHANNEL_MAP_DEF_MAX PA_CHANNEL_MAP_DEF_MAX +#define PA_CHANNEL_MAP_DEFAULT PA_CHANNEL_MAP_DEFAULT +/** \endcond */ + /** A channel map which can be used to attach labels to specific * channels of a stream. These values are relevant for conversion and * mixing of streams */ diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 58d64642..71f8443d 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -92,16 +92,16 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { /* Prepare the configuration parse table */ pa_config_item table[] = { - { "daemon-binary", pa_config_parse_string, NULL }, - { "extra-arguments", pa_config_parse_string, NULL }, - { "default-sink", pa_config_parse_string, NULL }, - { "default-source", pa_config_parse_string, NULL }, - { "default-server", pa_config_parse_string, NULL }, - { "autospawn", pa_config_parse_bool, NULL }, - { "cookie-file", pa_config_parse_string, NULL }, - { "disable-shm", pa_config_parse_bool, NULL }, - { "shm-size-bytes", pa_config_parse_size, NULL }, - { NULL, NULL, NULL }, + { "daemon-binary", pa_config_parse_string, NULL, NULL }, + { "extra-arguments", pa_config_parse_string, NULL, NULL }, + { "default-sink", pa_config_parse_string, NULL, NULL }, + { "default-source", pa_config_parse_string, NULL, NULL }, + { "default-server", pa_config_parse_string, NULL, NULL }, + { "autospawn", pa_config_parse_bool, NULL, NULL }, + { "cookie-file", pa_config_parse_string, NULL, NULL }, + { "disable-shm", pa_config_parse_bool, NULL, NULL }, + { "shm-size-bytes", pa_config_parse_size, NULL, NULL }, + { NULL, NULL, NULL, NULL }, }; table[0].data = &c->daemon_binary; diff --git a/src/pulse/context.c b/src/pulse/context.c index d41e62e2..81050914 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -95,7 +95,10 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended, [PA_COMMAND_STARTED] = pa_command_stream_started, [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event, - [PA_COMMAND_EXTENSION] = pa_command_extension + [PA_COMMAND_EXTENSION] = pa_command_extension, + [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event, + [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event, + [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event }; static void context_free(pa_context *c); @@ -112,6 +115,9 @@ static void reset_callbacks(pa_context *c) { c->subscribe_callback = NULL; c->subscribe_userdata = NULL; + c->event_callback = NULL; + c->event_userdata = NULL; + c->ext_stream_restore.callback = NULL; c->ext_stream_restore.userdata = NULL; } @@ -917,6 +923,17 @@ void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, voi c->state_userdata = userdata; } +void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) { + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED) + return; + + c->event_callback = cb; + c->event_userdata = userdata; +} + int pa_context_is_pending(pa_context *c) { pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); @@ -1245,6 +1262,11 @@ void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t pa_context_ref(c); + if (c->version < 15) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_gets(t, &name) < 0) { pa_context_fail(c, PA_ERR_PROTOCOL); @@ -1259,3 +1281,41 @@ void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t finish: pa_context_unref(c); } + + +void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_context *c = userdata; + pa_proplist *pl = NULL; + const char *event; + + pa_assert(pd); + pa_assert(command == PA_COMMAND_CLIENT_EVENT); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + pa_context_ref(c); + + if (c->version < 15) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + + pl = pa_proplist_new(); + + if (pa_tagstruct_gets(t, &event) < 0 || + pa_tagstruct_get_proplist(t, pl) < 0 || + !pa_tagstruct_eof(t) || !event) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + + if (c->event_callback) + c->event_callback(c, event, pl, c->event_userdata); + +finish: + pa_context_unref(c); + + if (pl) + pa_proplist_free(pl); +} diff --git a/src/pulse/context.h b/src/pulse/context.h index dfb7e4a1..2ae4c013 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -164,6 +164,13 @@ typedef void (*pa_context_notify_cb_t)(pa_context *c, void *userdata); /** A generic callback for operation completion */ typedef void (*pa_context_success_cb_t) (pa_context *c, int success, void *userdata); +/** A callback for asynchronous meta/policy event messages. The set + * of defined events can be extended at any time. Also, server modules + * may introduce additional message types so make sure that your + * callback function ignores messages it doesn't know. \since + * 0.9.15 */ +typedef void (*pa_context_event_cb_t)(pa_context *c, const char *name, pa_proplist *p, void *userdata); + /** Instantiate a new connection context with an abstract mainloop API * and an application name. It is recommended to use pa_context_new_with_proplist() * instead and specify some initial properties.*/ @@ -183,6 +190,10 @@ pa_context* pa_context_ref(pa_context *c); /** Set a callback function that is called whenever the context status changes */ void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata); +/** Set a callback function that is called whenver a meta/policy + * control event is received. \since 0.9.15 */ +void pa_context_set_event_callback(pa_context *p, pa_context_event_cb_t cb, void *userdata); + /** Return the error number of the last failed operation */ int pa_context_errno(pa_context *c); diff --git a/src/pulse/def.h b/src/pulse/def.h index 61498883..7f3a0c5d 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -57,6 +57,12 @@ static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) { } /** \cond fulldocs */ +#define PA_CONTEXT_UNCONNECTED PA_CONTEXT_UNCONNECTED +#define PA_CONTEXT_CONNECTING PA_CONTEXT_CONNECTING +#define PA_CONTEXT_AUTHORIZING PA_CONTEXT_AUTHORIZING +#define PA_CONTEXT_SETTING_NAME PA_CONTEXT_SETTING_NAME +#define PA_CONTEXT_READY PA_CONTEXT_READY +#define PA_CONTEXT_FAILED PA_CONTEXT_FAILED #define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD /** \endcond */ @@ -77,6 +83,11 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) { } /** \cond fulldocs */ +#define PA_STREAM_UNCONNECTED PA_STREAM_UNCONNECTED +#define PA_STREAM_CREATING PA_STREAM_CREATING +#define PA_STREAM_READY PA_STREAM_READY +#define PA_STREAM_FAILED PA_STREAM_FAILED +#define PA_STREAM_TERMINATED PA_STREAM_TERMINATED #define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD /** \endcond */ @@ -87,6 +98,12 @@ typedef enum pa_operation_state { PA_OPERATION_CANCELED /**< The operation has been canceled */ } pa_operation_state_t; +/** \cond fulldocs */ +#define PA_OPERATION_RUNNING PA_OPERATION_RUNNING +#define PA_OPERATION_DONE PA_OPERATION_DONE +#define PA_OPERATION_CANCELED PA_OPERATION_CANCELED +/** \endcond */ + /** An invalid index */ #define PA_INVALID_INDEX ((uint32_t) -1) @@ -109,6 +126,13 @@ typedef enum pa_stream_direction { PA_STREAM_UPLOAD /**< Sample upload stream */ } pa_stream_direction_t; +/** \cond fulldocs */ +#define PA_STREAM_NODIRECTION PA_STREAM_NODIRECTION +#define PA_STREAM_PLAYBACK PA_STREAM_PLAYBACK +#define PA_STREAM_RECORD PA_STREAM_RECORD +#define PA_STREAM_UPLOAD PA_STREAM_UPLOAD +/** \endcond */ + /** Some special flags for stream connections. */ typedef enum pa_stream_flags { @@ -491,6 +515,36 @@ typedef enum pa_subscription_event_type { /** Return one if an event type t matches an event mask bitfield */ #define pa_subscription_match_flags(m, t) (!!((m) & (1 << ((t) & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)))) +/** \cond fulldocs */ +#define PA_SUBSCRIPTION_MASK_NULL PA_SUBSCRIPTION_MASK_NULL +#define PA_SUBSCRIPTION_MASK_SINK PA_SUBSCRIPTION_MASK_SINK +#define PA_SUBSCRIPTION_MASK_SOURCE PA_SUBSCRIPTION_MASK_SOURCE +#define PA_SUBSCRIPTION_MASK_SINK_INPUT PA_SUBSCRIPTION_MASK_SINK_INPUT +#define PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT +#define PA_SUBSCRIPTION_MASK_MODULE PA_SUBSCRIPTION_MASK_MODULE +#define PA_SUBSCRIPTION_MASK_CLIENT PA_SUBSCRIPTION_MASK_CLIENT +#define PA_SUBSCRIPTION_MASK_SAMPLE_CACHE PA_SUBSCRIPTION_MASK_SAMPLE_CACHE +#define PA_SUBSCRIPTION_MASK_SERVER PA_SUBSCRIPTION_MASK_SERVER +#define PA_SUBSCRIPTION_MASK_AUTOLOAD PA_SUBSCRIPTION_MASK_AUTOLOAD +#define PA_SUBSCRIPTION_MASK_CARD PA_SUBSCRIPTION_MASK_CARD +#define PA_SUBSCRIPTION_MASK_ALL PA_SUBSCRIPTION_MASK_ALL +#define PA_SUBSCRIPTION_EVENT_SINK PA_SUBSCRIPTION_EVENT_SINK +#define PA_SUBSCRIPTION_EVENT_SOURCE PA_SUBSCRIPTION_EVENT_SOURCE +#define PA_SUBSCRIPTION_EVENT_SINK_INPUT PA_SUBSCRIPTION_EVENT_SINK_INPUT +#define PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT +#define PA_SUBSCRIPTION_EVENT_MODULE PA_SUBSCRIPTION_EVENT_MODULE +#define PA_SUBSCRIPTION_EVENT_CLIENT PA_SUBSCRIPTION_EVENT_CLIENT +#define PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE +#define PA_SUBSCRIPTION_EVENT_SERVER PA_SUBSCRIPTION_EVENT_SERVER +#define PA_SUBSCRIPTION_EVENT_AUTOLOAD PA_SUBSCRIPTION_EVENT_AUTOLOAD +#define PA_SUBSCRIPTION_EVENT_CARD PA_SUBSCRIPTION_EVENT_CARD +#define PA_SUBSCRIPTION_EVENT_FACILITY_MASK PA_SUBSCRIPTION_EVENT_FACILITY_MASK +#define PA_SUBSCRIPTION_EVENT_NEW PA_SUBSCRIPTION_EVENT_NEW +#define PA_SUBSCRIPTION_EVENT_CHANGE PA_SUBSCRIPTION_EVENT_CHANGE +#define PA_SUBSCRIPTION_EVENT_REMOVE PA_SUBSCRIPTION_EVENT_REMOVE +#define PA_SUBSCRIPTION_EVENT_TYPE_MASK PA_SUBSCRIPTION_EVENT_TYPE_MASK +/** \endcond */ + /** A structure for all kinds of timing information of a stream. See * pa_stream_update_timing_info() and pa_stream_get_timing_info(). The * total output latency a sample that is written with @@ -617,6 +671,13 @@ typedef enum pa_seek_mode { /**< Seek relatively to the current end of the buffer queue. */ } pa_seek_mode_t; +/** \cond fulldocs */ +#define PA_SEEK_RELATIVE PA_SEEK_RELATIVE +#define PA_SEEK_ABSOLUTE PA_SEEK_ABSOLUTE +#define PA_SEEK_RELATIVE_ON_READ PA_SEEK_RELATIVE_ON_READ +#define PA_SEEK_RELATIVE_END PA_SEEK_RELATIVE_END +/** \endcond */ + /** Special sink flags. */ typedef enum pa_sink_flags { PA_SINK_HW_VOLUME_CTRL = 0x0001U, @@ -694,6 +755,8 @@ static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) { #define PA_SINK_RUNNING PA_SINK_RUNNING #define PA_SINK_IDLE PA_SINK_IDLE #define PA_SINK_SUSPENDED PA_SINK_SUSPENDED +#define PA_SINK_INIT PA_SINK_INIT +#define PA_SINK_UNLINKED PA_SINK_UNLINKED #define PA_SINK_IS_OPENED PA_SINK_IS_OPENED /** \endcond */ @@ -769,12 +832,24 @@ static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) { #define PA_SOURCE_RUNNING PA_SOURCE_RUNNING #define PA_SOURCE_IDLE PA_SOURCE_IDLE #define PA_SOURCE_SUSPENDED PA_SOURCE_SUSPENDED +#define PA_SOURCE_INIT PA_SOURCE_INIT +#define PA_SOURCE_UNLINKED PA_SOURCE_UNLINKED #define PA_SOURCE_IS_OPENED PA_SOURCE_IS_OPENED /** \endcond */ /** A generic free() like callback prototype */ typedef void (*pa_free_cb_t)(void *p); +/** A stream policy/meta event requesting that an application should + * cork a specific stream. See pa_stream_event_cb_t for more + * information, \since 0.9.15 */ +#define PA_STREAM_EVENT_REQUEST_CORK "request-cork" + +/** A stream policy/meta event requesting that an application should + * cork a specific stream. See pa_stream_event_cb_t for more + * information, \since 0.9.15 */ +#define PA_STREAM_EVENT_REQUEST_UNCORK "request-uncork" + PA_C_DECL_END #endif diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c index 703179c5..469c822a 100644 --- a/src/pulse/ext-stream-restore.c +++ b/src/pulse/ext-stream-restore.c @@ -30,6 +30,7 @@ #include <pulsecore/pstream-util.h> #include "internal.h" +#include "operation.h" #include "ext-stream-restore.h" @@ -191,8 +192,8 @@ pa_operation *pa_ext_stream_restore_write( void *userdata) { uint32_t tag; - pa_operation *o; - pa_tagstruct *t; + pa_operation *o = NULL; + pa_tagstruct *t = NULL; pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); @@ -213,7 +214,15 @@ pa_operation *pa_ext_stream_restore_write( pa_tagstruct_put_boolean(t, apply_immediately); for (; n > 0; n--, data++) { + if (!data->name || !*data->name) + goto fail; + pa_tagstruct_puts(t, data->name); + + if (data->volume.channels > 0 && + !pa_cvolume_compatible_with_channel_map(&data->volume, &data->channel_map)) + goto fail; + pa_tagstruct_put_channel_map(t, &data->channel_map); pa_tagstruct_put_cvolume(t, &data->volume); pa_tagstruct_puts(t, data->device); @@ -224,6 +233,18 @@ pa_operation *pa_ext_stream_restore_write( pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); return o; + +fail: + if (o) { + pa_operation_cancel(o); + pa_operation_unref(o); + } + + if (t) + pa_tagstruct_free(t); + + pa_context_set_error(c, PA_ERR_INVALID); + return NULL; } pa_operation *pa_ext_stream_restore_delete( @@ -233,8 +254,8 @@ pa_operation *pa_ext_stream_restore_delete( void *userdata) { uint32_t tag; - pa_operation *o; - pa_tagstruct *t; + pa_operation *o = NULL; + pa_tagstruct *t = NULL; const char *const *k; pa_assert(c); @@ -251,13 +272,29 @@ pa_operation *pa_ext_stream_restore_delete( pa_tagstruct_puts(t, "module-stream-restore"); pa_tagstruct_putu32(t, SUBCOMMAND_DELETE); - for (k = s; *k; k++) + for (k = s; *k; k++) { + if (!*k || !**k) + goto fail; + pa_tagstruct_puts(t, *k); + } pa_pstream_send_tagstruct(c->pstream, t); pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); return o; + +fail: + if (o) { + pa_operation_cancel(o); + pa_operation_unref(o); + } + + if (t) + pa_tagstruct_free(t); + + pa_context_set_error(c, PA_ERR_INVALID); + return NULL; } pa_operation *pa_ext_stream_restore_subscribe( @@ -322,5 +359,4 @@ void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t) if (c->ext_stream_restore.callback) c->ext_stream_restore.callback(c, c->ext_stream_restore.userdata); - } diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h index ac01d235..cf9f4ccc 100644 --- a/src/pulse/ext-stream-restore.h +++ b/src/pulse/ext-stream-restore.h @@ -36,10 +36,10 @@ PA_C_DECL_BEGIN * maintained by module-stream-restore. \since 0.9.12 */ typedef struct pa_ext_stream_restore_info { const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */ - pa_channel_map channel_map; /**< The channel map for the volume field */ - pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable */ - const char *device; /**< The sink/source of the stream when it was last seen */ - int mute; /**< The boolean mute state of the stream when it was last seen, if applicable */ + pa_channel_map channel_map; /**< The channel map for the volume field, if applicable */ + pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable and saved */ + const char *device; /**< The sink/source of the stream when it was last seen, if applicable and saved */ + int mute; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */ } pa_ext_stream_restore_info; /** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */ diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 9a2d6457..e533625d 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -71,6 +71,8 @@ struct pa_context { void *state_userdata; pa_context_subscribe_cb_t subscribe_callback; void *subscribe_userdata; + pa_context_event_cb_t event_callback; + void *event_userdata; pa_mempool *mempool; @@ -181,6 +183,8 @@ struct pa_stream { void *suspended_userdata; pa_stream_notify_cb_t started_callback; void *started_userdata; + pa_stream_event_cb_t event_callback; + void *event_userdata; }; typedef void (*pa_operation_cb_t)(void); @@ -207,6 +211,9 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32 void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); +void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); +void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); + pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata); void pa_operation_done(pa_operation *o); diff --git a/src/pulse/operation.c b/src/pulse/operation.c index 13b470a8..aa2bbc05 100644 --- a/src/pulse/operation.c +++ b/src/pulse/operation.c @@ -62,6 +62,7 @@ pa_operation *pa_operation_ref(pa_operation *o) { PA_REFCNT_INC(o); return o; } + void pa_operation_unref(pa_operation *o) { pa_assert(o); pa_assert(PA_REFCNT_VALUE(o) >= 1); diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c index 282fe5cc..db4c9344 100644 --- a/src/pulse/proplist.c +++ b/src/pulse/proplist.c @@ -24,6 +24,7 @@ #endif #include <string.h> +#include <ctype.h> #include <pulse/xmalloc.h> #include <pulse/utf8.h> @@ -46,7 +47,7 @@ struct property { static pa_bool_t property_name_valid(const char *key) { - if (!pa_utf8_valid(key)) + if (!pa_ascii_valid(key)) return FALSE; if (strlen(key) <= 0) @@ -64,8 +65,6 @@ static void property_free(struct property *prop) { } pa_proplist* pa_proplist_new(void) { - pa_init_i18n(); - return MAKE_PROPLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func)); } @@ -83,6 +82,7 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) { pa_assert(p); pa_assert(key); + pa_assert(value); if (!property_name_valid(key) || !pa_utf8_valid(value)) return -1; @@ -104,25 +104,130 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) { } /** Will accept only valid UTF-8 */ +static int proplist_setn(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) { + struct property *prop; + pa_bool_t add = FALSE; + char *k, *v; + + pa_assert(p); + pa_assert(key); + pa_assert(value); + + k = pa_xstrndup(key, key_length); + v = pa_xstrndup(value, value_length); + + if (!property_name_valid(k) || !pa_utf8_valid(v)) { + pa_xfree(k); + pa_xfree(v); + return -1; + } + + if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) { + prop = pa_xnew(struct property, 1); + prop->key = k; + add = TRUE; + } else { + pa_xfree(prop->value); + pa_xfree(k); + } + + prop->value = v; + prop->nbytes = strlen(v)+1; + + if (add) + pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop); + + return 0; +} + +static int proplist_sethex(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) { + struct property *prop; + pa_bool_t add = FALSE; + char *k, *v; + uint8_t *d; + size_t dn; + + pa_assert(p); + pa_assert(key); + pa_assert(value); + + k = pa_xstrndup(key, key_length); + + if (!property_name_valid(k)) { + pa_xfree(k); + return -1; + } + + v = pa_xstrndup(value, value_length); + d = pa_xmalloc(value_length*2+1); + + if ((dn = pa_parsehex(v, d, value_length*2)) == (size_t) -1) { + pa_xfree(k); + pa_xfree(v); + pa_xfree(d); + return -1; + } + + pa_xfree(v); + + if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) { + prop = pa_xnew(struct property, 1); + prop->key = k; + add = TRUE; + } else { + pa_xfree(prop->value); + pa_xfree(k); + } + + d[dn] = 0; + prop->value = d; + prop->nbytes = dn; + + if (add) + pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop); + + return 0; +} + +/** Will accept only valid UTF-8 */ int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) { + struct property *prop; + pa_bool_t add = FALSE; va_list ap; - int r; - char *t; + char *v; pa_assert(p); pa_assert(key); + pa_assert(format); if (!property_name_valid(key) || !pa_utf8_valid(format)) return -1; va_start(ap, format); - t = pa_vsprintf_malloc(format, ap); + v = pa_vsprintf_malloc(format, ap); va_end(ap); - r = pa_proplist_sets(p, key, t); + if (!pa_utf8_valid(v)) + goto fail; - pa_xfree(t); - return r; + if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) { + prop = pa_xnew(struct property, 1); + prop->key = pa_xstrdup(key); + add = TRUE; + } else + pa_xfree(prop->value); + + prop->value = v; + prop->nbytes = strlen(v)+1; + + if (add) + pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop); + + return 0; + +fail: + pa_xfree(v); + return -1; } int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nbytes) { @@ -131,6 +236,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb pa_assert(p); pa_assert(key); + pa_assert(data); if (!property_name_valid(key)) return -1; @@ -142,7 +248,9 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb } else pa_xfree(prop->value); - prop->value = pa_xmemdup(data, nbytes); + prop->value = pa_xmalloc(nbytes+1); + memcpy(prop->value, data, nbytes); + ((char*) prop->value)[nbytes] = 0; prop->nbytes = nbytes; if (add) @@ -183,6 +291,8 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t * pa_assert(p); pa_assert(key); + pa_assert(data); + pa_assert(nbytes); if (!property_name_valid(key)) return -1; @@ -275,9 +385,32 @@ char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep) { if (!pa_strbuf_isempty(buf)) pa_strbuf_puts(buf, sep); - if ((v = pa_proplist_gets(p, key))) - pa_strbuf_printf(buf, "%s = \"%s\"", key, v); - else { + if ((v = pa_proplist_gets(p, key))) { + const char *t; + + pa_strbuf_printf(buf, "%s = \"", key); + + for (t = v;;) { + size_t h; + + h = strcspn(t, "\""); + + if (h > 0) + pa_strbuf_putsn(buf, t, h); + + t += h; + + if (*t == 0) + break; + + pa_assert(*t == '"'); + pa_strbuf_puts(buf, "\\\""); + + t++; + } + + pa_strbuf_puts(buf, "\""); + } else { const void *value; size_t nbytes; char *c; @@ -304,88 +437,189 @@ char *pa_proplist_to_string(pa_proplist *p) { return t; } -/* Remove all whitepsapce from the beginning and the end of *s. *s may - * be modified. (from conf-parser.c) */ -#define WHITESPACE " \t\n" -#define in_string(c,s) (strchr(s,c) != NULL) - -static char *strip(char *s) { - char *b = s+strspn(s, WHITESPACE); - char *e, *l = NULL; - - for (e = b; *e; e++) - if (!in_string(*e, WHITESPACE)) - l = e; +pa_proplist *pa_proplist_from_string(const char *s) { + enum { + WHITESPACE, + KEY, + AFTER_KEY, + VALUE_START, + VALUE_SIMPLE, + VALUE_DOUBLE_QUOTES, + VALUE_DOUBLE_QUOTES_ESCAPE, + VALUE_TICKS, + VALUE_TICKS_ESCAPED, + VALUE_HEX + } state; + + pa_proplist *pl; + const char *p, *key = NULL, *value = NULL; + size_t key_len = 0, value_len = 0; + + pa_assert(s); + + pl = pa_proplist_new(); + + state = WHITESPACE; + + for (p = s;; p++) { + switch (state) { + + case WHITESPACE: + if (*p == 0) + goto success; + else if (*p == '=') + goto fail; + else if (!isspace(*p)) { + key = p; + state = KEY; + key_len = 1; + } + break; - if (l) - *(l+1) = 0; + case KEY: + if (*p == 0) + goto fail; + else if (*p == '=') + state = VALUE_START; + else if (isspace(*p)) + state = AFTER_KEY; + else + key_len++; + break; - return b; -} + case AFTER_KEY: + if (*p == 0) + goto fail; + else if (*p == '=') + state = VALUE_START; + else if (!isspace(*p)) + goto fail; + break; -pa_proplist *pa_proplist_from_string(const char *str) { - pa_proplist *p; - char *s, *v, *k, *e; + case VALUE_START: + if (*p == 0) + goto fail; + else if (strncmp(p, "hex:", 4) == 0) { + state = VALUE_HEX; + value = p+4; + value_len = 0; + p += 3; + } else if (*p == '\'') { + state = VALUE_TICKS; + value = p+1; + value_len = 0; + } else if (*p == '"') { + state = VALUE_DOUBLE_QUOTES; + value = p+1; + value_len = 0; + } else if (!isspace(*p)) { + state = VALUE_SIMPLE; + value = p; + value_len = 1; + } + break; - pa_assert(str); - pa_assert_se(p = pa_proplist_new()); - pa_assert_se(s = strdup(str)); + case VALUE_SIMPLE: + if (*p == 0 || isspace(*p)) { + if (proplist_setn(pl, key, key_len, value, value_len) < 0) + goto fail; - for (k = s; *k; k = e) { - k = k+strspn(k, WHITESPACE); + if (*p == 0) + goto success; - if (!*k) - break; + state = WHITESPACE; + } else + value_len++; + break; - if (!(v = strchr(k, '='))) { - pa_log("Missing '='."); - break; - } + case VALUE_DOUBLE_QUOTES: + if (*p == 0) + goto fail; + else if (*p == '"') { + char *v; + + v = pa_unescape(pa_xstrndup(value, value_len)); + + if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) { + pa_xfree(v); + goto fail; + } + + pa_xfree(v); + state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_DOUBLE_QUOTES_ESCAPE; + value_len++; + } else + value_len++; + break; - *v++ = '\0'; - k = strip(k); + case VALUE_DOUBLE_QUOTES_ESCAPE: + if (*p == 0) + goto fail; + else { + state = VALUE_DOUBLE_QUOTES; + value_len++; + } + break; - v = v+strspn(v, WHITESPACE); - if (*v == '"') { - v++; - if (!(e = strchr(v, '"'))) { /* FIXME: handle escape */ - pa_log("Missing '\"' at end of string value."); + case VALUE_TICKS: + if (*p == 0) + goto fail; + else if (*p == '\'') { + char *v; + + v = pa_unescape(pa_xstrndup(value, value_len)); + + if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) { + pa_xfree(v); + goto fail; + } + + pa_xfree(v); + state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_TICKS_ESCAPED; + value_len++; + } else + value_len++; break; - } - *e++ = '\0'; - pa_proplist_sets(p, k, v); - } else { - uint8_t *blob; - if (*v++ != 'h' || *v++ != 'e' || *v++ != 'x' || *v++ != ':') { - pa_log("Value must be a string or \"hex:\""); + case VALUE_TICKS_ESCAPED: + if (*p == 0) + goto fail; + else { + state = VALUE_TICKS; + value_len++; + } break; - } - e = v; - while (in_string(*e, "0123456789abcdefABCDEF")) - ++e; + case VALUE_HEX: + if ((*p >= '0' && *p <= '9') || + (*p >= 'A' && *p <= 'F') || + (*p >= 'a' && *p <= 'f')) { + value_len++; + } else if (*p == 0 || isspace(*p)) { - if ((e - v) % 2) { - pa_log("Invalid \"hex:\" value data"); - break; - } + if (proplist_sethex(pl, key, key_len, value, value_len) < 0) + goto fail; - blob = pa_xmalloc((size_t)(e-v)/2); - if (pa_parsehex(v, blob, (e-v)/2) != (size_t)((e-v)/2)) { - pa_log("Invalid \"hex:\" value data"); - pa_xfree(blob); - break; - } + if (*p == 0) + goto success; - pa_proplist_set(p, k, blob, (e-v)/2); - pa_xfree(blob); + state = WHITESPACE; + } else + goto fail; + break; } } - pa_xfree(s); +success: + return MAKE_PROPLIST(pl); - return p; +fail: + pa_proplist_free(pl); + return NULL; } int pa_proplist_contains(pa_proplist *p, const char *key) { diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index 990ffd19..57a23d9f 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -39,7 +39,7 @@ PA_C_DECL_BEGIN * media.filename * media.icon Binary blob containing PNG icon data * media.icon_name Name from XDG icon naming spec - * media.role video, music, game, event, phone, production, filter, abstract, stream + * media.role video, music, game, event, phone, animation, production, filter, abstract, stream * event.id Name from XDG sound naming spec * event.description "Button blabla clicked" for a11y * event.mouse.x @@ -136,7 +136,7 @@ PA_C_DECL_BEGIN #define PA_PROP_MODULE_USAGE "module.usage" #define PA_PROP_MODULE_VERSION "module.version" -/** A property list object. Basically a dictionary with UTF-8 strings +/** A property list object. Basically a dictionary with ASCII strings * as keys and arbitrary data as values. \since 0.9.11 */ typedef struct pa_proplist pa_proplist; @@ -194,6 +194,12 @@ typedef enum pa_update_mode { * list. */ } pa_update_mode_t; +/** \cond fulldocs */ +#define PA_UPDATE_SET PA_UPDATE_SET +#define PA_UPDATE_MERGE PA_UPDATE_MERGE +#define PA_UPDATE_REPLACE PA_UPDATE_REPLACE +/** \endcond */ + /** Merge property list "other" into "p", adhering the merge mode as * specified in "mode". \since 0.9.11 */ void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, pa_proplist *other); diff --git a/src/pulse/sample.c b/src/pulse/sample.c index a6c77345..4b13a337 100644 --- a/src/pulse/sample.c +++ b/src/pulse/sample.c @@ -36,7 +36,7 @@ #include "sample.h" -size_t pa_sample_size(const pa_sample_spec *spec) { +size_t pa_sample_size_of_format(pa_sample_format_t f) { static const size_t table[] = { [PA_SAMPLE_U8] = 1, @@ -54,32 +54,44 @@ size_t pa_sample_size(const pa_sample_spec *spec) { [PA_SAMPLE_S24_32BE] = 4 }; + pa_assert(f >= 0); + pa_assert(f < PA_SAMPLE_MAX); + + return table[f]; +} + +size_t pa_sample_size(const pa_sample_spec *spec) { + pa_assert(spec); - pa_assert(spec->format >= 0); - pa_assert(spec->format < PA_SAMPLE_MAX); + pa_return_val_if_fail(pa_sample_spec_valid(spec), 0); - return table[spec->format]; + return pa_sample_size_of_format(spec->format); } size_t pa_frame_size(const pa_sample_spec *spec) { pa_assert(spec); + pa_return_val_if_fail(pa_sample_spec_valid(spec), 0); return pa_sample_size(spec) * spec->channels; } size_t pa_bytes_per_second(const pa_sample_spec *spec) { pa_assert(spec); + pa_return_val_if_fail(pa_sample_spec_valid(spec), 0); + return spec->rate*pa_frame_size(spec); } pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) { pa_assert(spec); + pa_return_val_if_fail(pa_sample_spec_valid(spec), 0); return (((pa_usec_t) (length / pa_frame_size(spec)) * PA_USEC_PER_SEC) / spec->rate); } size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) { pa_assert(spec); + pa_return_val_if_fail(pa_sample_spec_valid(spec), 0); return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * pa_frame_size(spec); } @@ -112,6 +124,9 @@ int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) { pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_sample_spec_valid(a), 0); + pa_return_val_if_fail(pa_sample_spec_valid(b), 0); + return (a->format == b->format) && (a->rate == b->rate) && @@ -143,7 +158,7 @@ const char *pa_sample_format_to_string(pa_sample_format_t f) { char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { pa_assert(s); - pa_assert(l); + pa_assert(l > 0); pa_assert(spec); pa_init_i18n(); @@ -151,22 +166,25 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { if (!pa_sample_spec_valid(spec)) pa_snprintf(s, l, _("(invalid)")); else - pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate); + pa_snprintf(s, l, _("%s %uch %uHz"), pa_sample_format_to_string(spec->format), spec->channels, spec->rate); return s; } char* pa_bytes_snprint(char *s, size_t l, unsigned v) { pa_assert(s); + pa_assert(l > 0); + + pa_init_i18n(); if (v >= ((unsigned) 1024)*1024*1024) - pa_snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024); + pa_snprintf(s, l, _("%0.1f GiB"), ((double) v)/1024/1024/1024); else if (v >= ((unsigned) 1024)*1024) - pa_snprintf(s, l, "%0.1f MiB", ((double) v)/1024/1024); + pa_snprintf(s, l, _("%0.1f MiB"), ((double) v)/1024/1024); else if (v >= (unsigned) 1024) - pa_snprintf(s, l, "%0.1f KiB", ((double) v)/1024); + pa_snprintf(s, l, _("%0.1f KiB"), ((double) v)/1024); else - pa_snprintf(s, l, "%u B", (unsigned) v); + pa_snprintf(s, l, _("%u B"), (unsigned) v); return s; } diff --git a/src/pulse/sample.h b/src/pulse/sample.h index 45a481fe..3c05b54a 100644 --- a/src/pulse/sample.h +++ b/src/pulse/sample.h @@ -261,6 +261,10 @@ size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE; /** Return the size of a sample with the specific sample type */ size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE; +/** Similar to pa_sample_size() but take a sample format instead of a + * full sample spec. \since 0.9.15 */ +size_t pa_sample_size_of_format(pa_sample_format_t f) PA_GCC_PURE; + /** Calculate the time the specified bytes take to play with the * specified sample type. The return value will always be rounded * down for non-integral return values. */ diff --git a/src/pulse/stream.c b/src/pulse/stream.c index fe2514d9..b36bf9b1 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -69,6 +69,8 @@ static void reset_callbacks(pa_stream *s) { s->suspended_userdata = NULL; s->started_callback = NULL; s->started_userdata = NULL; + s->event_callback = NULL; + s->event_userdata = NULL; } pa_stream *pa_stream_new_with_proplist( @@ -565,6 +567,52 @@ finish: pa_context_unref(c); } +void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + pa_context *c = userdata; + pa_stream *s; + uint32_t channel; + pa_proplist *pl = NULL; + const char *event; + + pa_assert(pd); + pa_assert(command == PA_COMMAND_PLAYBACK_STREAM_EVENT || command == PA_COMMAND_RECORD_STREAM_EVENT); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + pa_context_ref(c); + + if (c->version < 15) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + + pl = pa_proplist_new(); + + if (pa_tagstruct_getu32(t, &channel) < 0 || + pa_tagstruct_gets(t, &event) < 0 || + pa_tagstruct_get_proplist(t, pl) < 0 || + !pa_tagstruct_eof(t) || !event) { + pa_context_fail(c, PA_ERR_PROTOCOL); + goto finish; + } + + if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_EVENT ? c->playback_streams : c->record_streams, channel))) + goto finish; + + if (s->state != PA_STREAM_READY) + goto finish; + + if (s->event_callback) + s->event_callback(s, event, pl, s->event_userdata); + +finish: + pa_context_unref(c); + + if (pl) + pa_proplist_free(pl); +} + void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s; pa_context *c = userdata; @@ -1696,6 +1744,17 @@ void pa_stream_set_started_callback(pa_stream *s, pa_stream_notify_cb_t cb, void s->started_userdata = userdata; } +void pa_stream_set_event_callback(pa_stream *s, pa_stream_event_cb_t cb, void *userdata) { + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + + if (s->state == PA_STREAM_TERMINATED || s->state == PA_STREAM_FAILED) + return; + + s->event_callback = cb; + s->event_userdata = userdata; +} + void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; diff --git a/src/pulse/stream.h b/src/pulse/stream.h index 1bec1ebf..3965e9a2 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -324,6 +324,14 @@ typedef void (*pa_stream_request_cb_t)(pa_stream *p, size_t bytes, void *userdat /** A generic notification callback */ typedef void (*pa_stream_notify_cb_t)(pa_stream *p, void *userdata); +/** A callback for asynchronous meta/policy event messages. Well known + * event names are PA_STREAM_EVENT_REQUEST_CORK and + * PA_STREAM_EVENT_REQUEST_UNCORK. The set of defined events can be + * extended at any time. Also, server modules may introduce additional + * message types so make sure that your callback function ignores messages + * it doesn't know. \since 0.9.15 */ +typedef void (*pa_stream_event_cb_t)(pa_stream *p, const char *name, pa_proplist *pl, void *userdata); + /** Create a new, unconnected stream with the specified name and * sample type. It is recommended to use pa_stream_new_with_proplist() * instead and specify some initial properties. */ @@ -500,6 +508,10 @@ void pa_stream_set_moved_callback(pa_stream *p, pa_stream_notify_cb_t cb, void * * 0.9.8. \since 0.9.8 */ void pa_stream_set_suspended_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); +/** Set the callback function that is called whenver a meta/policy + * control event is received.\since 0.9.15 */ +void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *userdata); + /** Pause (or resume) playback of this stream temporarily. Available on both playback and recording streams. */ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata); @@ -518,7 +530,7 @@ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *us * temporarily. Available for playback streams only. */ pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); -/** Rename the stream. */ +/** Rename the stream.*/ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata); /** Return the current playback/recording time. This is based on the diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 7671be46..6b58bde3 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -263,3 +263,29 @@ char* pa_locale_to_utf8 (const char *str) { } #endif + +char *pa_ascii_valid(const char *str) { + const char *p; + pa_assert(str); + + for (p = str; *p; p++) + if ((unsigned char) *p >= 128) + return NULL; + + return (char*) str; +} + +char *pa_ascii_filter(const char *str) { + char *r, *s, *d; + pa_assert(str); + + r = pa_xstrdup(str); + + for (s = r, d = r; *s; s++) + if ((unsigned char) *s < 128) + *(d++) = *s; + + *d = 0; + + return r; +} diff --git a/src/pulse/utf8.h b/src/pulse/utf8.h index 4d751953..b9f74952 100644 --- a/src/pulse/utf8.h +++ b/src/pulse/utf8.h @@ -36,9 +36,15 @@ PA_C_DECL_BEGIN /** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */ char *pa_utf8_valid(const char *str) PA_GCC_PURE; +/** Test if the specified strings qualifies as valid 7-bit ASCII. Return the string if so, otherwise NULL. \since 0.9.15 */ +char *pa_ascii_valid(const char *str) PA_GCC_PURE; + /** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */ char *pa_utf8_filter(const char *str); +/** Filter all invalid ASCII characters from the specified string, returning a new fully ASCII valid string. Don't forget to free the returned string with pa_xfree(). \since 0.9.15 */ +char *pa_ascii_filter(const char *str); + /** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */ char* pa_utf8_to_locale (const char *str); diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 01a28e83..54838e89 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -37,6 +37,9 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) { pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_cvolume_valid(a), 0); + pa_return_val_if_fail(pa_cvolume_valid(b), 0); + if (a->channels != b->channels) return 0; @@ -78,7 +81,9 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) { pa_volume_t pa_cvolume_avg(const pa_cvolume *a) { uint64_t sum = 0; int i; + pa_assert(a); + pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED); for (i = 0; i < a->channels; i++) sum += a->values[i]; @@ -91,7 +96,9 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) { pa_volume_t pa_cvolume_max(const pa_cvolume *a) { pa_volume_t m = 0; int i; + pa_assert(a); + pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED); for (i = 0; i < a->channels; i++) if (a->values[i] > m) @@ -247,11 +254,12 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) { return s; } -/** Return non-zero if the volume of all channels is equal to the specified value */ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) { unsigned c; pa_assert(a); + pa_return_val_if_fail(pa_cvolume_valid(a), 0); + for (c = 0; c < a->channels; c++) if (a->values[c] != v) return 0; @@ -266,6 +274,9 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_cvolume_valid(a), NULL); + pa_return_val_if_fail(pa_cvolume_valid(b), NULL); + for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++) dest->values[i] = pa_sw_volume_multiply(a->values[i], b->values[i]); @@ -281,6 +292,9 @@ pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa pa_assert(a); pa_assert(b); + pa_return_val_if_fail(pa_cvolume_valid(a), NULL); + pa_return_val_if_fail(pa_cvolume_valid(b), NULL); + for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++) dest->values[i] = pa_sw_volume_divide(a->values[i], b->values[i]); @@ -373,7 +387,11 @@ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa pa_assert(v); pa_assert(from); pa_assert(to); - pa_assert(v->channels == from->channels); + + pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(pa_channel_map_valid(from), NULL); + pa_return_val_if_fail(pa_channel_map_valid(to), NULL); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL); if (pa_channel_map_equal(from, to)) return v; @@ -419,15 +437,22 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) { pa_assert(v); pa_assert(ss); - if (!pa_cvolume_valid(v)) - return 0; - - if (!pa_sample_spec_valid(ss)) - return 0; + pa_return_val_if_fail(pa_cvolume_valid(v), 0); + pa_return_val_if_fail(pa_sample_spec_valid(ss), 0); return v->channels == ss->channels; } +int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) { + pa_assert(v); + pa_assert(cm); + + pa_return_val_if_fail(pa_cvolume_valid(v), 0); + pa_return_val_if_fail(pa_channel_map_valid(cm), 0); + + return v->channels == cm->channels; +} + static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *l, pa_volume_t *r) { int c; pa_volume_t left = 0, right = 0; @@ -465,7 +490,10 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) { pa_assert(v); pa_assert(map); - pa_assert(map->channels == v->channels); + + pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f); + pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f); if (!pa_channel_map_can_balance(map)) return 0.0f; @@ -494,12 +522,15 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo pa_volume_t left, nleft, right, nright, m; unsigned c; - pa_assert(map->channels == v->channels); pa_assert(map); pa_assert(v); pa_assert(new_balance >= -1.0f); pa_assert(new_balance <= 1.0f); + pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(pa_channel_map_valid(map), NULL); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL); + if (!pa_channel_map_can_balance(map)) return v; @@ -538,6 +569,9 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) { pa_assert(v); + pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(max != (pa_volume_t) -1, NULL); + for (c = 0; c < v->channels; c++) if (v->values[c] > t) t = v->values[c]; @@ -588,7 +622,10 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) { pa_assert(v); pa_assert(map); - pa_assert(map->channels == v->channels); + + pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f); + pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f); if (!pa_channel_map_can_fade(map)) return 0.0f; @@ -608,12 +645,15 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float pa_volume_t front, nfront, rear, nrear, m; unsigned c; - pa_assert(map->channels == v->channels); pa_assert(map); pa_assert(v); pa_assert(new_fade >= -1.0f); pa_assert(new_fade <= 1.0f); + pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(pa_channel_map_valid(map), NULL); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL); + if (!pa_channel_map_can_fade(map)) return v; diff --git a/src/pulse/volume.h b/src/pulse/volume.h index 9ad3e9bf..8bfd0687 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -230,10 +230,14 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST; /** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to); -/** Return non-zero if the specified volume is compatible with - * the specified sample spec. \since 0.9.13 */ +/** Return non-zero if the specified volume is compatible with the + * specified sample spec. \since 0.9.13 */ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE; +/** Return non-zero if the specified volume is compatible with the + * specified sample spec. \since 0.9.15 */ +int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) PA_GCC_PURE; + /** Calculate a 'balance' value for the specified volume with the * specified channel map. The return value will range from -1.0f * (left) to +1.0f (right). If no balance value is applicable to this diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c index 18004412..7ca7b97c 100644 --- a/src/pulsecore/client.c +++ b/src/pulsecore/client.c @@ -73,6 +73,7 @@ pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) { c->userdata = NULL; c->kill = NULL; + c->send_event = NULL; pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0); @@ -126,8 +127,49 @@ void pa_client_kill(pa_client *c) { void pa_client_set_name(pa_client *c, const char *name) { pa_assert(c); + pa_assert(name); pa_log_info("Client %u changed name from \"%s\" to \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)), name); pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); + + pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c); + pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index); +} + +void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p) { + pa_assert(c); + pa_assert(p); + + pa_proplist_update(c->proplist, mode, p); + + pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c); pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index); } + +void pa_client_send_event(pa_client *c, const char *event, pa_proplist *data) { + pa_proplist *pl = NULL; + pa_client_send_event_hook_data hook_data; + + pa_assert(c); + pa_assert(event); + + if (!c->send_event) + return; + + if (!data) + data = pl = pa_proplist_new(); + + hook_data.client = c; + hook_data.data = data; + hook_data.event = event; + + if (pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_SEND_EVENT], &hook_data) < 0) + goto finish; + + c->send_event(c, event, data); + +finish: + + if (pl) + pa_proplist_free(pl); +} diff --git a/src/pulsecore/client.h b/src/pulsecore/client.h index 48e9bc7a..845a8bab 100644 --- a/src/pulsecore/client.h +++ b/src/pulsecore/client.h @@ -48,6 +48,8 @@ struct pa_client { void *userdata; void (*kill)(pa_client *c); + + void (*send_event)(pa_client *c, const char *name, pa_proplist *data); }; typedef struct pa_client_new_data { @@ -71,4 +73,14 @@ void pa_client_kill(pa_client *c); /* Rename the client */ void pa_client_set_name(pa_client *c, const char *name); +void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p); + +void pa_client_send_event(pa_client *c, const char *event, pa_proplist *data); + +typedef struct pa_client_send_event_hook_data { + pa_client *client; + const char *event; + pa_proplist *data; +} pa_client_send_event_hook_data; + #endif diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index ef6d6bb6..b7ec2b3c 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -40,17 +40,19 @@ #define COMMENTS "#;\n" /* Run the user supplied parser for an assignment */ -static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) { +static int next_assignment(const char *filename, unsigned line, const char *section, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) { pa_assert(filename); pa_assert(t); pa_assert(lvalue); pa_assert(rvalue); for (; t->parse; t++) - if (!strcmp(lvalue, t->lvalue)) - return t->parse(filename, line, lvalue, rvalue, t->data, userdata); + if (!t->lvalue || + (pa_streq(lvalue, t->lvalue) && + ((!section && !t->section) || pa_streq(section, t->section)))) + return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata); - pa_log("[%s:%u] Unknown lvalue '%s'.", filename, line, lvalue); + pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", filename, line, lvalue, pa_strnull(section)); return -1; } @@ -83,8 +85,10 @@ static char *strip(char *s) { } /* Parse a variable assignment line */ -static int parse_line(const char *filename, unsigned line, const pa_config_item *t, char *l, void *userdata) { - char *e, *c, *b = l+strspn(l, WHITESPACE); +static int parse_line(const char *filename, unsigned line, char **section, const pa_config_item *t, char *l, void *userdata) { + char *e, *c, *b; + + b = l+strspn(l, WHITESPACE); if ((c = strpbrk(b, COMMENTS))) *c = 0; @@ -92,6 +96,22 @@ static int parse_line(const char *filename, unsigned line, const pa_config_item if (!*b) return 0; + if (*b == '[') { + size_t k; + + k = strlen(b); + pa_assert(k > 0); + + if (b[k-1] != ']') { + pa_log("[%s:%u] Invalid section header.", filename, line); + return -1; + } + + pa_xfree(*section); + *section = pa_xstrndup(b+1, k-2); + return 0; + } + if (!(e = strchr(b, '='))) { pa_log("[%s:%u] Missing '='.", filename, line); return -1; @@ -100,7 +120,7 @@ static int parse_line(const char *filename, unsigned line, const pa_config_item *e = 0; e++; - return next_assignment(filename, line, t, strip(b), strip(e), userdata); + return next_assignment(filename, line, *section, t, strip(b), strip(e), userdata); } /* Go through the file and parse each line */ @@ -108,6 +128,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void int r = -1; unsigned line = 0; int do_close = !f; + char *section = NULL; pa_assert(filename); pa_assert(t); @@ -118,29 +139,29 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void goto finish; } - pa_log_warn("Failed to open configuration file '%s': %s", - filename, pa_cstrerror(errno)); + pa_log_warn("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno)); goto finish; } while (!feof(f)) { char l[256]; + if (!fgets(l, sizeof(l), f)) { if (feof(f)) break; - pa_log_warn("Failed to read configuration file '%s': %s", - filename, pa_cstrerror(errno)); + pa_log_warn("Failed to read configuration file '%s': %s", filename, pa_cstrerror(errno)); goto finish; } - if (parse_line(filename, ++line, t, l, userdata) < 0) + if (parse_line(filename, ++line, §ion, t, l, userdata) < 0) goto finish; } r = 0; finish: + pa_xfree(section); if (do_close && f) fclose(f); @@ -148,7 +169,7 @@ finish: return r; } -int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { int *i = data; int32_t k; @@ -166,7 +187,7 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, return 0; } -int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { unsigned *u = data; uint32_t k; @@ -184,7 +205,7 @@ int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lv return 0; } -int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { size_t *i = data; uint32_t k; @@ -202,7 +223,7 @@ int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue return 0; } -int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { int k; pa_bool_t *b = data; @@ -221,7 +242,7 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue return 0; } -int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) { +int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) { char **s = data; pa_assert(filename); diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h index 48a0fd26..f8f059fe 100644 --- a/src/pulsecore/conf-parser.h +++ b/src/pulsecore/conf-parser.h @@ -27,11 +27,14 @@ /* An abstract parser for simple, line based, shallow configuration * files consisting of variable assignments only. */ +typedef int (*pa_config_parser_cb_t)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); + /* Wraps info for parsing a specific configuration variable */ typedef struct pa_config_item { const char *lvalue; /* name of the variable */ - int (*parse)(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); /* Function that is called to parse the variable's value */ + pa_config_parser_cb_t parse; /* Function that is called to parse the variable's value */ void *data; /* Where to store the variable's data */ + const char *section; } pa_config_item; /* The configuration file parsing routine. Expects a table of @@ -40,10 +43,10 @@ typedef struct pa_config_item { int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata); /* Generic parsers for integers, size_t, booleans and strings */ -int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); +int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); +int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata); #endif diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index e65b1796..ad6c6ca9 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -88,6 +88,10 @@ #include <samplerate.h> #endif +#ifdef __APPLE__ +#include <xlocale.h> +#endif + #include <pulse/xmalloc.h> #include <pulse/util.h> #include <pulse/utf8.h> @@ -97,6 +101,7 @@ #include <pulsecore/log.h> #include <pulsecore/macro.h> #include <pulsecore/thread.h> +#include <pulsecore/strbuf.h> #include "core-util.h" @@ -2553,3 +2558,49 @@ unsigned pa_ncpus(void) { return ncpus <= 0 ? 1 : (unsigned) ncpus; } + +char *pa_replace(const char*s, const char*a, const char *b) { + pa_strbuf *sb; + size_t an; + + pa_assert(s); + pa_assert(a); + pa_assert(b); + + an = strlen(a); + sb = pa_strbuf_new(); + + for (;;) { + const char *p; + + if (!(p = strstr(s, a))) + break; + + pa_strbuf_putsn(sb, s, p-s); + pa_strbuf_puts(sb, b); + s = p + an; + } + + pa_strbuf_puts(sb, s); + + return pa_strbuf_tostring_free(sb); +} + +char *pa_unescape(char *p) { + char *s, *d; + pa_bool_t escaped = FALSE; + + for (s = p, d = p; *s; s++) { + if (!escaped && *s == '\\') { + escaped = TRUE; + continue; + } + + *(d++) = *s; + escaped = FALSE; + } + + *d = 0; + + return p; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 18901f47..442815f1 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -215,4 +215,8 @@ void pa_reduce(unsigned *num, unsigned *den); unsigned pa_ncpus(void); +char *pa_replace(const char*s, const char*a, const char *b); + +char *pa_unescape(char *p); + #endif diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 8fa9761f..53e2d2c3 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -74,6 +74,7 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED, PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED, PA_CORE_HOOK_SINK_INPUT_SET_VOLUME, + PA_CORE_HOOK_SINK_INPUT_SEND_EVENT, PA_CORE_HOOK_SOURCE_OUTPUT_NEW, PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE, PA_CORE_HOOK_SOURCE_OUTPUT_PUT, @@ -84,9 +85,12 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL, PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED, PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED, + PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT, PA_CORE_HOOK_CLIENT_NEW, PA_CORE_HOOK_CLIENT_PUT, PA_CORE_HOOK_CLIENT_UNLINK, + PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED, + PA_CORE_HOOK_CLIENT_SEND_EVENT, PA_CORE_HOOK_CARD_NEW, PA_CORE_HOOK_CARD_PUT, PA_CORE_HOOK_CARD_UNLINK, diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c index b57b6435..fd6a9487 100644 --- a/src/pulsecore/envelope.c +++ b/src/pulsecore/envelope.c @@ -744,6 +744,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { break; } + case PA_SAMPLE_S24LE: + case PA_SAMPLE_S24BE: + case PA_SAMPLE_S24_32LE: + case PA_SAMPLE_S24_32BE: + /* FIXME */ + pa_assert_not_reached(); + case PA_SAMPLE_MAX: case PA_SAMPLE_INVALID: pa_assert_not_reached(); diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index 9e60125e..866e6e0c 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -79,106 +79,111 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co } pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { - pa_hashmap *map = NULL; + enum { + WHITESPACE, + KEY, + VALUE_START, + VALUE_SIMPLE, + VALUE_DOUBLE_QUOTES, + VALUE_TICKS + } state; + + const char *p, *key = NULL, *value = NULL; + size_t key_len = 0, value_len = 0; + pa_hashmap *map; map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (args) { - enum { - WHITESPACE, - KEY, - VALUE_START, - VALUE_SIMPLE, - VALUE_DOUBLE_QUOTES, - VALUE_TICKS - } state; - - const char *p, *key, *value; - size_t key_len = 0, value_len = 0; - - key = value = NULL; - state = WHITESPACE; - for (p = args; *p; p++) { - switch (state) { - case WHITESPACE: - if (*p == '=') + if (!args) + return (pa_modargs*) map; + + state = WHITESPACE; + + for (p = args; *p; p++) { + switch (state) { + + case WHITESPACE: + if (*p == '=') + goto fail; + else if (!isspace(*p)) { + key = p; + state = KEY; + key_len = 1; + } + break; + + case KEY: + if (*p == '=') + state = VALUE_START; + else if (isspace(*p)) + goto fail; + else + key_len++; + break; + + case VALUE_START: + if (*p == '\'') { + state = VALUE_TICKS; + value = p+1; + value_len = 0; + } else if (*p == '"') { + state = VALUE_DOUBLE_QUOTES; + value = p+1; + value_len = 0; + } else if (isspace(*p)) { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) goto fail; - else if (!isspace(*p)) { - key = p; - state = KEY; - key_len = 1; - } - break; - case KEY: - if (*p == '=') - state = VALUE_START; - else if (isspace(*p)) + state = WHITESPACE; + } else { + state = VALUE_SIMPLE; + value = p; + value_len = 1; + } + break; + + case VALUE_SIMPLE: + if (isspace(*p)) { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) goto fail; - else - key_len++; - break; - case VALUE_START: - if (*p == '\'') { - state = VALUE_TICKS; - value = p+1; - value_len = 0; - } else if (*p == '"') { - state = VALUE_DOUBLE_QUOTES; - value = p+1; - value_len = 0; - } else if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else { - state = VALUE_SIMPLE; - value = p; - value_len = 1; - } - break; - case VALUE_SIMPLE: - if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - case VALUE_DOUBLE_QUOTES: - if (*p == '"') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - case VALUE_TICKS: - if (*p == '\'') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - } + state = WHITESPACE; + } else + value_len++; + break; + + case VALUE_DOUBLE_QUOTES: + if (*p == '"') { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) + goto fail; + state = WHITESPACE; + } else + value_len++; + break; + + case VALUE_TICKS: + if (*p == '\'') { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) + goto fail; + state = WHITESPACE; + } else + value_len++; + break; } + } - if (state == VALUE_START) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) - goto fail; - } else if (state == VALUE_SIMPLE) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0) - goto fail; - } else if (state != WHITESPACE) + if (state == VALUE_START) { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) goto fail; - } + } else if (state == VALUE_SIMPLE) { + if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0) + goto fail; + } else if (state != WHITESPACE) + goto fail; return (pa_modargs*) map; fail: - if (map) - pa_modargs_free((pa_modargs*) map); + pa_modargs_free((pa_modargs*) map); return NULL; } diff --git a/src/pulsecore/native-common.h b/src/pulsecore/native-common.h index b31a5da1..6951e10a 100644 --- a/src/pulsecore/native-common.h +++ b/src/pulsecore/native-common.h @@ -157,6 +157,10 @@ enum { PA_COMMAND_GET_CARD_INFO_LIST, PA_COMMAND_SET_CARD_PROFILE, + PA_COMMAND_CLIENT_EVENT, + PA_COMMAND_PLAYBACK_STREAM_EVENT, + PA_COMMAND_RECORD_STREAM_EVENT, + PA_COMMAND_MAX }; diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index d1631264..44aa6bf0 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -197,7 +197,7 @@ pa_sink_input* pa_memblockq_sink_input_new( data.driver = __FILE__; pa_sink_input_new_data_set_sample_spec(&data, ss); pa_sink_input_new_data_set_channel_map(&data, map); - pa_sink_input_new_data_set_virtual_volume(&data, volume); + pa_sink_input_new_data_set_volume(&data, volume); pa_proplist_update(data.proplist, PA_UPDATE_REPLACE, p); pa_sink_input_new(&u->sink_input, sink->core, &data, 0); diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c index 4920c27e..8a447cf7 100644 --- a/src/pulsecore/proplist-util.c +++ b/src/pulsecore/proplist-util.c @@ -27,6 +27,13 @@ #include <locale.h> #include <dlfcn.h> +#ifdef __APPLE__ +#include <crt_externs.h> +#define environ (*_NSGetEnviron()) +#elif !HAVE_DECL_ENVIRON +extern char **environ; +#endif + #include <pulse/proplist.h> #include <pulse/utf8.h> #include <pulse/xmalloc.h> @@ -37,10 +44,8 @@ #include "proplist-util.h" void pa_init_proplist(pa_proplist *p) { -#if !HAVE_DECL_ENVIRON - extern char **environ; -#endif char **e; + const char *pp; pa_assert(p); @@ -64,17 +69,21 @@ void pa_init_proplist(pa_proplist *p) { k = pa_xstrndup(*e+11, kl); - if (pa_proplist_contains(p, k)) { - pa_xfree(k); - continue; - } - pa_proplist_sets(p, k, *e+11+kl+1); pa_xfree(k); } } } + if ((pp = getenv("PULSE_PROP"))) { + pa_proplist *t; + + if ((t = pa_proplist_from_string(pp))) { + pa_proplist_update(p, PA_UPDATE_REPLACE, t); + pa_proplist_free(t); + } + } + if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_ID)) { char t[32]; pa_snprintf(t, sizeof(t), "%lu", (unsigned long) getpid()); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 21a2cfbc..c3032618 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -207,6 +207,7 @@ static void sink_input_moved_cb(pa_sink_input *i); static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes); static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes); static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes); +static void sink_input_send_event_cb(pa_sink_input *i, const char *event, pa_proplist *pl); static void native_connection_send_memblock(pa_native_connection *c); static void playback_stream_request_bytes(struct playback_stream*s); @@ -216,6 +217,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) static void source_output_suspend_cb(pa_source_output *o, pa_bool_t suspend); static void source_output_moved_cb(pa_source_output *o); static pa_usec_t source_output_get_latency_cb(pa_source_output *o); +static void source_output_send_event_cb(pa_source_output *o, const char *event, pa_proplist *pl); static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); @@ -595,7 +597,7 @@ static record_stream* record_stream_new( int *ret) { record_stream *s; - pa_source_output *source_output; + pa_source_output *source_output = NULL; size_t base; pa_source_output_new_data data; @@ -618,7 +620,7 @@ static record_stream* record_stream_new( if (peak_detect) data.resample_method = PA_RESAMPLER_PEAKS; - *ret = pa_source_output_new(&source_output, c->protocol->core, &data, flags); + *ret = -pa_source_output_new(&source_output, c->protocol->core, &data, flags); pa_source_output_new_data_done(&data); @@ -636,6 +638,7 @@ static record_stream* record_stream_new( s->source_output->get_latency = source_output_get_latency_cb; s->source_output->moved = source_output_moved_cb; s->source_output->suspend = source_output_suspend_cb; + s->source_output->send_event = source_output_send_event_cb; s->source_output->userdata = s; fix_record_buffer_attr_pre(s, adjust_latency, early_requests, maxlength, fragsize); @@ -971,7 +974,7 @@ static playback_stream* playback_stream_new( int *ret) { playback_stream *s, *ssync; - pa_sink_input *sink_input; + pa_sink_input *sink_input = NULL; pa_memchunk silence; uint32_t idx; int64_t start_index; @@ -1018,12 +1021,12 @@ static playback_stream* playback_stream_new( pa_sink_input_new_data_set_sample_spec(&data, ss); pa_sink_input_new_data_set_channel_map(&data, map); if (volume) - pa_sink_input_new_data_set_virtual_volume(&data, volume); + pa_sink_input_new_data_set_volume(&data, volume); if (muted_set) pa_sink_input_new_data_set_muted(&data, muted); data.sync_base = ssync ? ssync->sink_input : NULL; - *ret = pa_sink_input_new(&sink_input, c->protocol->core, &data, flags); + *ret = -pa_sink_input_new(&sink_input, c->protocol->core, &data, flags); pa_sink_input_new_data_done(&data); @@ -1048,6 +1051,7 @@ static playback_stream* playback_stream_new( s->sink_input->kill = sink_input_kill_cb; s->sink_input->moved = sink_input_moved_cb; s->sink_input->suspend = sink_input_suspend_cb; + s->sink_input->send_event = sink_input_send_event_cb; s->sink_input->userdata = s; start_index = ssync ? pa_memblockq_get_read_index(ssync->memblockq) : 0; @@ -1494,6 +1498,27 @@ static void sink_input_kill_cb(pa_sink_input *i) { } /* Called from main context */ +static void sink_input_send_event_cb(pa_sink_input *i, const char *event, pa_proplist *pl) { + playback_stream *s; + pa_tagstruct *t; + + pa_sink_input_assert_ref(i); + s = PLAYBACK_STREAM(i->userdata); + playback_stream_assert_ref(s); + + if (s->connection->version < 15) + return; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_EVENT); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, s->index); + pa_tagstruct_puts(t, event); + pa_tagstruct_put_proplist(t, pl); + pa_pstream_send_tagstruct(s->connection->pstream, t); +} + +/* Called from main context */ static void sink_input_suspend_cb(pa_sink_input *i, pa_bool_t suspend) { playback_stream *s; pa_tagstruct *t; @@ -1595,6 +1620,27 @@ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { } /* Called from main context */ +static void source_output_send_event_cb(pa_source_output *o, const char *event, pa_proplist *pl) { + record_stream *s; + pa_tagstruct *t; + + pa_source_output_assert_ref(o); + s = RECORD_STREAM(o->userdata); + record_stream_assert_ref(s); + + if (s->connection->version < 15) + return; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_EVENT); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, s->index); + pa_tagstruct_puts(t, event); + pa_tagstruct_put_proplist(t, pl); + pa_pstream_send_tagstruct(s->connection->pstream, t); +} + +/* Called from main context */ static void source_output_suspend_cb(pa_source_output *o, pa_bool_t suspend) { record_stream *s; pa_tagstruct *t; @@ -2295,11 +2341,9 @@ static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t return; } - pa_proplist_update(c->client->proplist, PA_UPDATE_REPLACE, p); + pa_client_update_proplist(c->client, PA_UPDATE_REPLACE, p); pa_proplist_free(p); - pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->client->index); - reply = reply_new(tag); if (c->version >= 13) @@ -3551,8 +3595,7 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); - pa_proplist_update(s->sink_input->proplist, mode, p); - pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, s->sink_input->index); + pa_sink_input_update_proplist(s->sink_input, mode, p); } else if (command == PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST) { record_stream *s; @@ -3560,13 +3603,11 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t s = pa_idxset_get_by_index(c->record_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - pa_proplist_update(s->source_output->proplist, mode, p); - pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, s->source_output->index); + pa_source_output_update_proplist(s->source_output, mode, p); } else { pa_assert(command == PA_COMMAND_UPDATE_CLIENT_PROPLIST); - pa_proplist_update(c->client->proplist, mode, p); - pa_subscription_post(c->protocol->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->client->index); + pa_client_update_proplist(c->client, mode, p); } pa_pstream_send_simple_ack(c->pstream, tag); @@ -4193,6 +4234,25 @@ static void client_kill_cb(pa_client *c) { pa_log_info("Connection killed."); } +static void client_send_event_cb(pa_client *client, const char*event, pa_proplist *pl) { + pa_tagstruct *t; + pa_native_connection *c; + + pa_assert(client); + c = PA_NATIVE_CONNECTION(client->userdata); + pa_native_connection_assert_ref(c); + + if (c->version < 15) + return; + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_CLIENT_EVENT); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_puts(t, event); + pa_tagstruct_put_proplist(t, pl); + pa_pstream_send_tagstruct(c->pstream, t); +} + /*** module entry points ***/ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { @@ -4270,6 +4330,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati c->client = client; c->client->kill = client_kill_cb; + c->client->send_event = client_send_event_cb; c->client->userdata = c; c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index be390db7..78ad5530 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -156,16 +156,6 @@ static int (* const init_table[])(pa_resampler*r) = { [PA_RESAMPLER_PEAKS] = peaks_init, }; -static inline size_t sample_size(pa_sample_format_t f) { - pa_sample_spec ss = { - .format = f, - .rate = 0, - .channels = 1 - }; - - return pa_sample_size(&ss); -} - pa_resampler* pa_resampler_new( pa_mempool *pool, const pa_sample_spec *a, @@ -275,7 +265,7 @@ pa_resampler* pa_resampler_new( pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format)); - r->w_sz = sample_size(r->work_format); + r->w_sz = pa_sample_size_of_format(r->work_format); if (r->i_ss.format == r->work_format) r->to_work_format_func = NULL; diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index fc87d5d8..22419ee5 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -72,18 +72,23 @@ void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const data->channel_map = *map; } -void pa_sink_input_new_data_set_soft_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) { +void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) { pa_assert(data); - if ((data->soft_volume_is_set = !!volume)) - data->soft_volume = *volume; + if ((data->volume_is_set = !!volume)) + data->volume = *volume; } -void pa_sink_input_new_data_set_virtual_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) { +void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) { pa_assert(data); + pa_assert(volume_factor); - if ((data->virtual_volume_is_set = !!volume)) - data->virtual_volume = *volume; + if (data->volume_factor_is_set) + pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor); + else { + data->volume_factor_is_set = TRUE; + data->volume_factor = *volume_factor; + } } void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) { @@ -117,6 +122,7 @@ static void reset_callbacks(pa_sink_input *i) { i->get_latency = NULL; i->state_change = NULL; i->may_move_to = NULL; + i->send_event = NULL; } /* Called from main context */ @@ -136,6 +142,9 @@ int pa_sink_input_new( pa_assert(core); pa_assert(data); + if (data->client) + pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); + if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0) return r; @@ -166,35 +175,28 @@ int pa_sink_input_new( pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID); pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID); - if (!data->virtual_volume_is_set) { + if (!data->volume_is_set) { if (data->sink->flags & PA_SINK_FLAT_VOLUME) { - data->virtual_volume = data->sink->virtual_volume; - pa_cvolume_remap(&data->virtual_volume, &data->sink->channel_map, &data->channel_map); - } else - pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels); + data->volume = *pa_sink_get_volume(data->sink, FALSE); + pa_cvolume_remap(&data->volume, &data->sink->channel_map, &data->channel_map); + data->volume_is_absolute = TRUE; + } else { + pa_cvolume_reset(&data->volume, data->sample_spec.channels); + data->volume_is_absolute = FALSE; + } data->save_volume = FALSE; - - } else if (!data->virtual_volume_is_absolute) { - - /* When the 'absolute' bool is set then we'll treat the volume - * as relative to the sink volume even in flat volume mode */ - if (data->sink->flags & PA_SINK_FLAT_VOLUME) { - pa_cvolume t = data->sink->virtual_volume; - pa_cvolume_remap(&t, &data->sink->channel_map, &data->channel_map); - pa_sw_cvolume_multiply(&data->virtual_volume, &data->virtual_volume, &t); - } } - pa_return_val_if_fail(pa_cvolume_valid(&data->virtual_volume), -PA_ERR_INVALID); - pa_return_val_if_fail(pa_cvolume_compatible(&data->virtual_volume, &data->sample_spec), -PA_ERR_INVALID); + pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID); + pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID); - if (!data->soft_volume_is_set) - data->soft_volume = data->virtual_volume; + if (!data->volume_factor_is_set) + pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels); - pa_return_val_if_fail(pa_cvolume_valid(&data->soft_volume), -PA_ERR_INVALID); - pa_return_val_if_fail(pa_cvolume_compatible(&data->soft_volume, &data->sample_spec), -PA_ERR_INVALID); + pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID); + pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID); if (!data->muted_is_set) data->muted = FALSE; @@ -216,17 +218,13 @@ int pa_sink_input_new( pa_assert(pa_channel_map_valid(&data->channel_map)); /* Due to the fixing of the sample spec the volume might not match anymore */ - pa_cvolume_remap(&data->soft_volume, &original_cm, &data->channel_map); - pa_cvolume_remap(&data->virtual_volume, &original_cm, &data->channel_map); + pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map); if (data->resample_method == PA_RESAMPLER_INVALID) data->resample_method = core->resample_method; pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID); - if (data->client) - pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); - if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0) return r; @@ -271,8 +269,19 @@ int pa_sink_input_new( i->sample_spec = data->sample_spec; i->channel_map = data->channel_map; - i->virtual_volume = data->virtual_volume; - i->soft_volume = data->soft_volume; + if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) { + /* When the 'absolute' bool is not set then we'll treat the volume + * as relative to the sink volume even in flat volume mode */ + + pa_cvolume t = *pa_sink_get_volume(data->sink, FALSE); + pa_cvolume_remap(&t, &data->sink->channel_map, &data->channel_map); + + pa_sw_cvolume_multiply(&i->virtual_volume, &data->volume, &t); + } else + i->virtual_volume = data->volume; + + i->volume_factor = data->volume_factor; + pa_cvolume_init(&i->soft_volume); i->save_volume = data->save_volume; i->save_sink = data->save_sink; i->save_muted = data->save_muted; @@ -502,9 +511,6 @@ void pa_sink_input_put(pa_sink_input *i) { pa_assert(i->process_rewind); pa_assert(i->kill); - i->thread_info.soft_volume = i->soft_volume; - i->thread_info.muted = i->muted; - state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING; update_n_corked(i, state); @@ -515,7 +521,11 @@ void pa_sink_input_put(pa_sink_input *i) { pa_cvolume new_volume; pa_sink_update_flat_volume(i->sink, &new_volume); pa_sink_set_volume(i->sink, &new_volume, FALSE, FALSE); - } + } else + pa_sw_cvolume_multiply(&i->soft_volume, &i->virtual_volume, &i->volume_factor); + + i->thread_info.soft_volume = i->soft_volume; + i->thread_info.muted = i->muted; pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0); @@ -886,8 +896,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo /* OK, we are in normal volume mode. The volume only affects * ourselves */ - - i->soft_volume = *volume; + pa_sw_cvolume_multiply(&i->soft_volume, volume, &i->volume_factor); /* Hooks have the ability to play games with i->soft_volume */ pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i); @@ -932,18 +941,16 @@ pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) { } /* Called from main thread */ -pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) { - - pa_sink_input_assert_ref(i); - - pa_proplist_update(i->proplist, mode, p); +void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) { + pa_sink_input_assert_ref(i); + pa_assert(p); - if (PA_SINK_IS_LINKED(i->state)) { - pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i); - pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); - } + pa_proplist_update(i->proplist, mode, p); - return TRUE; + if (PA_SINK_IS_LINKED(i->state)) { + pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i); + pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + } } /* Called from main context */ @@ -1078,7 +1085,7 @@ int pa_sink_input_start_move(pa_sink_input *i) { /* Make the absolute volume relative */ i->virtual_volume = i->soft_volume; - pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels); + i->soft_volume = i->volume_factor; /* We might need to update the sink's volume if we are in flat * volume mode. */ @@ -1440,3 +1447,31 @@ pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) { return ret; } + +/* Called from main context */ +void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) { + pa_proplist *pl = NULL; + pa_sink_input_send_event_hook_data hook_data; + + pa_sink_input_assert_ref(i); + pa_assert(event); + + if (!i->send_event) + return; + + if (!data) + data = pl = pa_proplist_new(); + + hook_data.sink_input = i; + hook_data.data = data; + hook_data.event = event; + + if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0) + goto finish; + + i->send_event(i, event, data); + +finish: + if (pl) + pa_proplist_free(pl); +} diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index d82a3a62..b4f05319 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -91,7 +91,7 @@ struct pa_sink_input { pa_sink_input *sync_prev, *sync_next; - pa_cvolume virtual_volume, soft_volume; + pa_cvolume virtual_volume, soft_volume, volume_factor; pa_bool_t muted:1; /* if TRUE then the source we are connected to and/or the volume @@ -171,6 +171,10 @@ struct pa_sink_input { * be allowed */ pa_bool_t (*may_move_to) (pa_sink_input *i, pa_sink *s); /* may be NULL */ + /* If non-NULL this function is used to dispatch asynchronous + * control events. */ + void (*send_event)(pa_sink_input *i, const char *event, pa_proplist* data); + struct { pa_sink_input_state_t state; pa_atomic_t drained; @@ -217,6 +221,12 @@ enum { PA_SINK_INPUT_MESSAGE_MAX }; +typedef struct pa_sink_input_send_event_hook_data { + pa_sink_input *sink_input; + const char *event; + pa_proplist *data; +} pa_sink_input_send_event_hook_data; + typedef struct pa_sink_input_new_data { pa_proplist *proplist; @@ -233,16 +243,16 @@ typedef struct pa_sink_input_new_data { pa_sample_spec sample_spec; pa_channel_map channel_map; - pa_cvolume virtual_volume, soft_volume; + pa_cvolume volume, volume_factor; pa_bool_t muted:1; pa_bool_t sample_spec_is_set:1; pa_bool_t channel_map_is_set:1; - pa_bool_t virtual_volume_is_set:1, soft_volume_is_set:1; + pa_bool_t volume_is_set:1, volume_factor_is_set:1; pa_bool_t muted_is_set:1; - pa_bool_t virtual_volume_is_absolute:1; + pa_bool_t volume_is_absolute:1; pa_bool_t save_sink:1, save_volume:1, save_muted:1; } pa_sink_input_new_data; @@ -250,8 +260,8 @@ typedef struct pa_sink_input_new_data { pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data); void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec); void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map); -void pa_sink_input_new_data_set_soft_volume(pa_sink_input_new_data *data, const pa_cvolume *volume); -void pa_sink_input_new_data_set_virtual_volume(pa_sink_input_new_data *data, const pa_cvolume *volume); +void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume); +void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor); void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute); void pa_sink_input_new_data_done(pa_sink_input_new_data *data); @@ -294,10 +304,12 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i); void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save); pa_bool_t pa_sink_input_get_mute(pa_sink_input *i); -pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p); +void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p); pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i); +void pa_sink_input_send_event(pa_sink_input *i, const char *name, pa_proplist *data); + int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save); pa_bool_t pa_sink_input_may_move(pa_sink_input *i); /* may this sink input move at all? */ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest); /* may this sink input move to this sink? */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 558da8c6..eadef809 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -992,6 +992,7 @@ void pa_sink_update_flat_volume(pa_sink *s, pa_cvolume *new_volume) { remapped_new_volume = *new_volume; pa_cvolume_remap(&remapped_new_volume, &s->channel_map, &i->channel_map); pa_sw_cvolume_divide(&i->soft_volume, &i->virtual_volume, &remapped_new_volume); + pa_sw_cvolume_multiply(&i->soft_volume, &i->soft_volume, &i->volume_factor); /* Hooks have the ability to play games with i->soft_volume */ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], i); diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 67b072b6..c3de3067 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -322,7 +322,7 @@ int pa_play_file( data.sink = sink; data.driver = __FILE__; pa_sink_input_new_data_set_sample_spec(&data, &ss); - pa_sink_input_new_data_set_virtual_volume(&data, volume); + pa_sink_input_new_data_set_volume(&data, volume); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, pa_path_get_filename(fname)); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_FILENAME, fname); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index c5cb16d8..382fb88c 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -92,6 +92,7 @@ static void reset_callbacks(pa_source_output *o) { o->get_latency = NULL; o->state_change = NULL; o->may_move_to = NULL; + o->send_event = NULL; } /* Called from main context */ @@ -110,6 +111,9 @@ int pa_source_output_new( pa_assert(core); pa_assert(data); + if (data->client) + pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); + if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], data)) < 0) return r; @@ -159,9 +163,6 @@ int pa_source_output_new( pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID); - if (data->client) - pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); - if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], data)) < 0) return r; @@ -615,18 +616,16 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) { } /* Called from main thread */ -pa_bool_t pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) { - - pa_source_output_assert_ref(o); - - pa_proplist_update(o->proplist, mode, p); +void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) { + pa_source_output_assert_ref(o); + pa_assert(p); - if (PA_SINK_IS_LINKED(o->state)) { - pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o); - pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); - } + pa_proplist_update(o->proplist, mode, p); - return TRUE; + if (PA_SINK_IS_LINKED(o->state)) { + pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o); + pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); + } } /* Called from main context */ @@ -869,3 +868,30 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int return -PA_ERR_NOTIMPLEMENTED; } + +void pa_source_output_send_event(pa_source_output *o, const char *event, pa_proplist *data) { + pa_proplist *pl = NULL; + pa_source_output_send_event_hook_data hook_data; + + pa_source_output_assert_ref(o); + pa_assert(event); + + if (!o->send_event) + return; + + if (!data) + data = pl = pa_proplist_new(); + + hook_data.source_output = o; + hook_data.data = data; + hook_data.event = event; + + if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT], &hook_data) < 0) + goto finish; + + o->send_event(o, event, data); + +finish: + if (pl) + pa_proplist_free(pl); +} diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 91f28f94..9369568c 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -143,6 +143,10 @@ struct pa_source_output { * will not be allowed */ pa_bool_t (*may_move_to) (pa_source_output *o, pa_source *s); /* may be NULL */ + /* If non-NULL this function is used to dispatch asynchronous + * control events. */ + void (*send_event)(pa_source_output *o, const char *event, pa_proplist* data); + struct { pa_source_output_state_t state; @@ -177,6 +181,12 @@ enum { PA_SOURCE_OUTPUT_MESSAGE_MAX }; +typedef struct pa_source_output_send_event_hook_data { + pa_source_output *source_output; + const char *event; + pa_proplist *data; +} pa_source_output_send_event_hook_data; + typedef struct pa_source_output_new_data { pa_proplist *proplist; pa_sink_input *direct_on_input; @@ -229,10 +239,12 @@ void pa_source_output_kill(pa_source_output*o); pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency); -pa_bool_t pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p); +void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p); pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o); +void pa_source_output_send_event(pa_source_output *o, const char *name, pa_proplist *data); + pa_bool_t pa_source_output_may_move(pa_source_output *o); pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest); int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save); diff --git a/src/tests/proplist-test.c b/src/tests/proplist-test.c index f69fa686..5526bb7e 100644 --- a/src/tests/proplist-test.c +++ b/src/tests/proplist-test.c @@ -29,8 +29,9 @@ #include <pulsecore/core-util.h> int main(int argc, char*argv[]) { - pa_proplist *a, *b, *c; - char *s, *t, *u; + pa_proplist *a, *b, *c, *d; + char *s, *t, *u, *v; + const char *text; a = pa_proplist_new(); pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0); @@ -63,5 +64,19 @@ int main(int argc, char*argv[]) { pa_proplist_free(b); pa_proplist_free(c); + text = " eins = zwei drei = \"\\\"vier\\\"\" fuenf=sechs sieben ='\\a\\c\\h\\t\\'\\\"' neun= hex:0123456789abCDef "; + + printf("%s\n", text); + d = pa_proplist_from_string(text); + v = pa_proplist_to_string(d); + pa_proplist_free(d); + printf("%s\n", v); + d = pa_proplist_from_string(v); + pa_xfree(v); + v = pa_proplist_to_string(d); + pa_proplist_free(d); + printf("%s\n", v); + pa_xfree(v); + return 0; } diff --git a/src/utils/pacat.c b/src/utils/pacat.c index 2d88e7f9..10015ce4 100644 --- a/src/utils/pacat.c +++ b/src/utils/pacat.c @@ -238,6 +238,18 @@ static void stream_moved_callback(pa_stream *s, void *userdata) { fprintf(stderr, _("Stream moved to device %s (%u, %ssuspended).%s \n"), pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : _("not "), CLEAR_LINE); } +static void stream_event_callback(pa_stream *s, const char *name, pa_proplist *pl, void *userdata) { + char *t; + + assert(s); + assert(name); + assert(pl); + + t = pa_proplist_to_string_sep(pl, ", "); + fprintf(stderr, "Got event '%s', properties '%s'\n", name, t); + pa_xfree(t); +} + /* This is called whenever the context status changes */ static void context_state_callback(pa_context *c, void *userdata) { assert(c); @@ -271,6 +283,7 @@ static void context_state_callback(pa_context *c, void *userdata) { pa_stream_set_underflow_callback(stream, stream_underflow_callback, NULL); pa_stream_set_overflow_callback(stream, stream_overflow_callback, NULL); pa_stream_set_started_callback(stream, stream_started_callback, NULL); + pa_stream_set_event_callback(stream, stream_event_callback, NULL); if (latency > 0) { memset(&buffer_attr, 0, sizeof(buffer_attr)); diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c index 2c89c8d9..507e229f 100644 --- a/src/utils/pacmd.c +++ b/src/utils/pacmd.c @@ -47,16 +47,16 @@ int main(int argc, char*argv[]) { int fd = -1; int ret = 1, i; struct sockaddr_un sa; - char ibuf[256], obuf[256]; + char ibuf[PIPE_BUF], obuf[PIPE_BUF]; size_t ibuf_index, ibuf_length, obuf_index, obuf_length; - fd_set ifds, ofds; char *cli; + pa_bool_t ibuf_eof, obuf_eof, ibuf_closed, obuf_closed; setlocale(LC_ALL, ""); bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) { - pa_log("No PulseAudio daemon running"); + pa_log("No PulseAudio daemon running, or not running as session daemon."); goto fail; } @@ -99,15 +99,47 @@ int main(int argc, char*argv[]) { } ibuf_index = ibuf_length = obuf_index = obuf_length = 0; + ibuf_eof = obuf_eof = ibuf_closed = obuf_closed = FALSE; + if (argc > 1) { + for (i = 1; i < argc; i++) { + size_t k; - FD_ZERO(&ifds); - FD_SET(0, &ifds); - FD_SET(fd, &ifds); + k = PA_MIN(sizeof(ibuf) - ibuf_length, strlen(argv[i])); + memcpy(ibuf + ibuf_length, argv[1], k); + ibuf_length += k; - FD_ZERO(&ofds); + if (ibuf_length < sizeof(ibuf)) { + ibuf[ibuf_length] = i < argc-1 ? ' ' : '\n'; + ibuf_length++; + } + } + + ibuf_eof = TRUE; + } for (;;) { + fd_set ifds, ofds; + + if (ibuf_eof && + obuf_eof && + ibuf_length <= 0 && + obuf_length <= 0) + break; + + FD_ZERO(&ifds); + FD_ZERO(&ofds); + + if (obuf_length > 0) + FD_SET(1, &ofds); + else if (!obuf_eof) + FD_SET(fd, &ifds); + + if (ibuf_length > 0) + FD_SET(fd, &ofds); + else if (!ibuf_eof) + FD_SET(0, &ifds); + if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) { pa_log(_("select(): %s"), strerror(errno)); goto fail; @@ -118,15 +150,16 @@ int main(int argc, char*argv[]) { assert(!ibuf_length); if ((r = read(0, ibuf, sizeof(ibuf))) <= 0) { - if (r == 0) - break; - - pa_log(_("read(): %s"), strerror(errno)); - goto fail; + if (r < 0) { + pa_log(_("read(): %s"), strerror(errno)); + goto fail; + } + + ibuf_eof = TRUE; + } else { + ibuf_length = (size_t) r; + ibuf_index = 0; } - - ibuf_length = (size_t) r; - ibuf_index = 0; } if (FD_ISSET(fd, &ifds)) { @@ -134,15 +167,16 @@ int main(int argc, char*argv[]) { assert(!obuf_length); if ((r = read(fd, obuf, sizeof(obuf))) <= 0) { - if (r == 0) - break; - - pa_log(_("read(): %s"), strerror(errno)); - goto fail; + if (r < 0) { + pa_log(_("read(): %s"), strerror(errno)); + goto fail; + } + + obuf_eof = TRUE; + } else { + obuf_length = (size_t) r; + obuf_index = 0; } - - obuf_length = (size_t) r; - obuf_index = 0; } if (FD_ISSET(1, &ofds)) { @@ -170,28 +204,26 @@ int main(int argc, char*argv[]) { ibuf_length -= (size_t) r; ibuf_index += obuf_index; - } - FD_ZERO(&ifds); - FD_ZERO(&ofds); - - if (obuf_length <= 0) - FD_SET(fd, &ifds); - else - FD_SET(1, &ofds); + if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) { + close(0); + shutdown(fd, SHUT_WR); + ibuf_closed = TRUE; + } - if (ibuf_length <= 0) - FD_SET(0, &ifds); - else - FD_SET(fd, &ofds); + if (obuf_length <= 0 && obuf_eof && !obuf_closed) { + shutdown(fd, SHUT_RD); + close(1); + obuf_closed = TRUE; + } } ret = 0; fail: if (fd >= 0) - close(fd); + pa_close(fd); return ret; } |