6 points par GN⁺ 2025-02-17 | 1 commentaires | Partager sur WhatsApp
  • En remontant à la source du bruit blanc sur un ordinateur portable Linux, on découvre qu’un onglet Firefox maintient le sink audio de PulseAudio éveillé en permanence, même sans aucun son réel
  • module-suspend-on-idle était configuré pour arrêter le périphérique audio après 10 secondes, mais lorsqu’un site web crée un AudioContext, le sink ne redescend plus vers IDLE/SUSPENDED
  • Le même phénomène a été observé avec les notifications web d’Outlook, un clic sur x.com, la lecture vocale de Google Translate et l’application web Discord, et new AudioContext() seul suffit à déclencher le bruit
  • D’après les mesures, sans bruit, l’utilisation CPU de pulseaudio était de 0,0 %, mais avec le bruit elle montait à 4,7 %, et la consommation du système augmentait d’environ 1,5 W
  • AudioContext.suspend() peut interrompre l’accès au matériel audio pour réduire l’usage CPU/batterie, mais Firefox n’arrête pas automatiquement ce gaspillage après un certain temps comme le fait Chrome

Le problème du sink audio qui ne s’endort pas

  • Sur un nouvel ordinateur portable, un bruit blanc faible mais agaçant sortait des haut-parleurs même lorsqu’aucune musique ni aucun audio n’était en lecture
  • Pour vérifier l’état de PulseAudio sous Linux, la commande pactl list sinks short a été utilisée
    • L’état d’un sink audio apparaît comme IDLE, SUSPENDED ou RUNNING
    • Quand le sink était en SUSPENDED, les haut-parleurs restaient silencieux
    • En IDLE ou RUNNING, un bruit blanc pouvait apparaître même sans lecture réelle
  • Dans /etc/pulse/default.pa et /etc/pulse/system.pa, module-suspend-on-idle était chargé
    • En théorie, après 10 secondes d’inactivité, le sink audio devait s’arrêter automatiquement
    • Mais dans certaines situations, le sink ne passait même pas en IDLE et n’atteignait donc jamais SUSPENDED

Pourquoi un audio inactif consomme de l’énergie

  • module-suspend-on-idle déconnecte côté backend les sinks et sources qui ne sont reliés à aucun flux pendant un certain temps
  • Son effet principal est l’économie d’énergie
    • Si PulseAudio continue d’envoyer des données vides à la carte son même au repos, ALSA consomme davantage de cycles CPU
    • Sauf si l’on prévoit de maintenir en permanence un flux actif, régler un timer court est préférable pour économiser l’énergie

La cause se resserre sur des onglets Firefox et des sites web

  • Chaque fois que le bruit blanc apparaissait, pactl list sink-inputs servait à identifier quel programme utilisait le sink audio
  • Le responsable était toujours Firefox
    • Aucun onglet ouvert n’était censé lire un son réel
    • Il n’y avait pas non plus de vidéo en sourdine
  • Un petit script a été ajouté à la barre d’état i3 pour afficher un indicateur rouge lorsque le sink audio passait en RUNNING
  • Au départ, cela semblait venir du son de notification de outlook.office.com, laissé ouvert en onglet épinglé
    • À la réception d’un e-mail, le bruit blanc commençait
    • Il ne s’arrêtait qu’après rechargement de l’onglet ou redémarrage de Firefox
  • Le même comportement a ensuite été confirmé sur d’autres sites

Résultats des mesures CPU et consommation

  • Sans bruit blanc, l’utilisation CPU de pulseaudio s’affichait à 0,0 %
  • Dans les mêmes conditions, la consommation mesurée se situait en général entre 4,2 et 5,1 W
  • Avec le bruit blanc, l’utilisation CPU de pulseaudio montait à 4,7 %
  • La consommation mesurée se situait alors plutôt entre 5,8 et 6,7 W
  • La différence est loin d’être négligeable et se résume à une hausse d’environ 1,5 W

WebAudio API et AudioContext

  • En HTML/JavaScript, il existe deux façons de lire de l’audio : la balise <audio> et la WebAudio API
  • Pour des sons joués de manière dynamique, comme dans Outlook, on utilise la WebAudio API, et il faut d’abord créer un AudioContext
  • Le problème est que le simple fait d’exécuter const audioCtx = new AudioContext(); suffit à provoquer du bruit blanc dans les haut-parleurs
  • Une page de test est fournie : https://editor.43z.one/sqare/i
  • AudioContext.suspend() arrête la progression temporelle du contexte audio et suspend l’accès au matériel audio afin de réduire l’usage CPU/batterie
  • AudioContext.resume() relance la progression temporelle d’un contexte audio suspendu

Différence entre Firefox et Chrome

  • De nombreux sites créent un AudioContext même lorsqu’ils n’ont pas besoin d’émettre un son immédiatement, puis ne le suspendent pas
  • Chrome met automatiquement fin à ce gaspillage de CPU/batterie après un certain temps
  • Firefox, lui, ne l’arrête pas automatiquement et continue à maintenir l’état qui produit le bruit blanc
  • Le site web est la cause directe, mais le reproche demeure que Firefox ne protège pas l’utilisateur contre ce type de gaspillage de ressources
  • Il existe aussi un soupçon qu’avec un casque Bluetooth connecté, un clic sur x.com déclenche également l’envoi de ce bruit blanc, gaspillant potentiellement la batterie du casque

Réponse temporaire : AudioContext Suspender

1 commentaires

 
GN⁺ 2025-02-17
Avis sur Hacker News
  • C’est prévu et important, et nous comptons le corriger bientôt si possible. Cela a déjà beaucoup trop tardé, et je suis désolé que ce ne soit pas encore traité. C’est toujours une question de priorités, donc il est difficile de satisfaire tout le monde à temps, mais c’est assez haut dans ma liste de priorités personnelle.
    Comme on peut l’imaginer, c’est beaucoup plus complexe que de mettre en pause un AudioContext après un certain temps de silence, mais je pense que c’est corrigeable malgré tout. D’autres navigateurs l’ont déjà fait, et il existe des compromis acceptables.
    Source : j’ai implémenté beaucoup de fonctionnalités autour de cela dans Firefox et je suis aussi éditeur du standard Web Audio API.
    • J’espère que tu ne prendras pas ce genre de critique personnellement. Récemment, un mainteneur open source a pris ce type de critique comme une frustration dirigée contre lui, et ça a vraiment explosé.
      La plupart des gens comprennent la situation décrite ici. Il y a beaucoup à faire et le temps est limité.
      J’ai vu directement les développeurs de Firefox aller au-delà de ce qui était attendu pour que des sites très utilisés fonctionnent correctement pour les utilisateurs. Je sais jusqu’où vous allez quand un problème affecte les utilisateurs, donc courage et continuez.
    • J’aimerais devenir un meilleur utilisateur de Firefox et essayer de déboguer les problèmes que je constate en local. J’aurais besoin d’indications sur par où commencer.
  • Le fait qu’un site ouvre un contexte audio sans rien lire réellement est probablement lié à la détection de bots.
    Comme le traitement audio est implémenté différemment selon les moteurs de navigateur et les systèmes d’exploitation, si l’on lit un son totalement inaudible puis qu’on le réenregistre via l’API, on obtient une signature.
    Cette signature permet de vérifier si le navigateur falsifie son user-agent, s’il tourne en mode headless, ou s’il s’agit de toutes sortes de cas atypiques qui ne correspondent pas à un vrai utilisateur en train d’acheter un produit.
    https://github.com/fingerprintjs/fingerprintjs/blob/3201a7d6...
    • Le monde des navigateurs et des standards web a vraiment multiplié les API sans retenue, et n’a manifestement pas assez réfléchi à la manière dont elles seraient détournées.
    • Il existe déjà, parmi les plugins pour bots en circulation, des outils qui simulent l’Audio Context pour tromper la détection de bots. C’est délirant.
    • J’ai déjà hâte que Cloudflare adopte ça pour entraver encore davantage la liberté de navigation et gaspiller des cycles CPU.
  • Ce bruit blanc me rendait fou depuis longtemps, et je n’arrivais absolument pas à en trouver la cause.
    L’icône de lecture n’apparaît pas sur l’onglet, et couper le son de l’onglet n’arrête pas le bruit.
    Même en coupant Firefox dans le mélangeur de volume de Windows, le son ne s’arrête pas.
    Modification : pour les utilisateurs desktop, cette extension est en fait plutôt mauvaise. Le bruit blanc qui s’active et se coupe sans arrêt est encore bien plus agaçant.
    • Si couper Firefox dans le mélangeur de volume de Windows ne l’arrête pas, j’ai l’impression que c’est un bug à un niveau plus profond que Firefox.
    • J’utilise cette extension sur desktop sans problème. Ça semble dépendre des sites visités. Sur les sites qui lisent et interrompent souvent du son, il suffit probablement de désactiver l’extension.
  • Quand la sortie devient inactive, le signal numérique SPDIF perd la synchronisation. La resynchronisation au début de la lecture n’est pas instantanée, et on perd environ la première seconde de l’audio.
    J’ai donc créé mon propre programme qui ne fait pas passer de données sur la ligne, mais garde la sortie ouverte afin qu’elle ne passe pas en état inactif.
    Cela dit, dans le contexte d’un ordinateur portable, ça n’a pas vraiment de sens, donc l’économie d’énergie y est justifiée.
    • Avec un DAC FiiO K3 sur MacBook, c’était vraiment interminablement agaçant. Les sons système comme les notifications n’étaient quasiment pas joués à cause de la latence.
      Le pilote Windows dispose d’une option pour régler le flux sur Always On. J’aimerais vraiment que macOS ait la même chose.
    • J’avais fait la même chose autrefois avec un DAC USB. J’avais simplement configuré play -qn & pour se lancer à la connexion.
  • Cela semble expliquer le problème que j’avais parfois avec Firefox Android, où mon téléphone consommait aléatoirement 10 Go de données en une journée. La facture mobile était absurde.
    Un site d’actualité lisait de l’audio tout en rechargeant sans cesse de nouvelles publicités, et à cause de l’audio, l’onglet ne passait apparemment pas en veille. Les frais de données imprévus se répétaient, et j’ai fini par devoir passer à Chrome.
  • J’ai déjà vu le même phénomène, ou quelque chose de très similaire, sur macOS. Je ne sais pas si le site gardait réellement un contexte audio ouvert ou si c’était un problème interne à Firefox, car cela se produisait aussi sur des sites comme Youtube qui n’utilisent pas la Web Audio API.
    Autrement dit, il n’y avait pas de bruit blanc, mais il y avait une consommation d’énergie due à l’audio : https://bugzilla.mozilla.org/show_bug.cgi?id=1821102
    Même maintenant, sur Mac, alors que rien n’est en cours de lecture, coreaudiod utilise 20 % du CPU. Cela ruine vraiment l’autonomie, au point que j’envisage de passer à un autre navigateur jusqu’à ce que ce soit corrigé, même si je n’ai pas envie d’abandonner Firefox pour quelque chose qui semble aussi mineur.
    Mise à jour : cela semble lié, mais être un bug différent.
  • Le code qui gère cette mise en pause dans Chromium est ici :
    https://source.chromium.org/chromium/chromium/src/+/main:med...
    En gros, après avoir détecté environ 30 secondes de silence, il passe du sink adossé au périphérique audio du système d’exploitation à un sink nul.
    À noter que cette approche utilise une horloge différente de celle du périphérique audio, et il y a eu quelques signalements de distorsion sur certaines tonalités lorsque le contexte est réellement utilisé plus tard. Le contournement consiste pour le site à utiliser l’API suspend/resume mentionnée dans l’article.
  • Je ne sais pas en détail comment audioContext est implémenté en interne, mais il semble y avoir beaucoup d’éléments assez malins et dynamiques. Lire un son de notification me fait un peu penser à dessiner du SVG avec D3 au lieu d’utiliser img href *.svg.
    Je me demande s’il existe quelque chose comme un hook de Service Worker permettant d’enregistrer des éléments simples et répétables, comme un gestionnaire de notifications, auprès d’une API de plus bas niveau et plus efficace.
  • Est-ce qu’on est censé entendre quelque chose, en fait ?
    Sur Firefox 134.0.1 sous macOS, je n’entends rien.
    • De mon côté non plus je n’entends rien, mais quand j’appuie sur le bouton de lecture du son sur la page de démo de l’auteur, la consommation électrique augmente d’environ 1 W.
    • Sur Firefox Android, on entend un léger bruit blanc.
  • Ça a corrigé le problème de la page d’accueil de https://www.dr.dk/.