earshot : des oreilles pour un agent
Vous ne pouvez pas entendre. Ne dites jamais comment un son sonne, ni qu'un son "convient", sans une lecture earshot derrière, et citez
le nombre lorsque vous rapportez ("correspondance forte, z +3.9 ; p_real 0.96 ; -14.2 LUFS"). earshot s'exécute localement sur CPU (l'audio
ne quitte jamais la machine, sauf avec la commande optionnelle llm) et met en cache chaque plongement et résultat sur disque.
Coût : chaque appel CLI est un nouveau processus qui charge d'abord les modèles (~20-40 s sur un ordinateur portable chargé, même pour un fichier en cache) ;
dans le serveur MCP ou un script Python unique, les modèles se chargent une fois et les appels répétés prennent quelques secondes. Pour plus d'une
poignée d'appels, utilisez MCP ou un court script (from earshot import api; api.find(...); api.realness(...)).
Configuration (une fois)
pip install -e "/chemin/vers/earshot[mcp,llm]" # ou le venv du dépôt : /chemin/vers/earshot/.venv/bin/python -m earshot ...
earshot doctor # packages, ffmpeg, modèles (révision épinglée, état du cache) ; --load les chronomètre
Deux façons d'entrer, mêmes fonctions :
- CLI :
earshot <commande> ... [--json] [--out resultat.json]. La sortie texte commence par un résumé simple ; les temps sont en m:ss.ss dans le texte et en secondes dans le JSON. - MCP (les modèles restent chargés entre les appels) :
claude mcp add earshot --scope user -e EARSHOT_THREADS=3 -- /chemin/vers/earshot/.venv/bin/python -m earshot mcp, ou dans le.mcp.jsonde tout client :{"mcpServers": {"earshot": {"command": "/chemin/vers/earshot/.venv/bin/python", "args": ["-m", "earshot", "mcp"], "env": {"EARSHOT_THREADS": "3", "GEMINI_API_KEY": "${GEMINI_API_KEY:-}"}}}}(la ligne de clé seulement pour l'outil llm optionnel ; Claude Code la remplit à partir de l'environnement de l'utilisateur, d'autres clients peuvent avoir besoin que la clé soit définie dans l'environnement qui les lance : n'écrivez jamais une clé littérale dans un fichier de projet). Outils : measure, describe, match, rank, find, compare, ab, realness, timeline, sheet, critique, doctor, llm_critique ; la banque sonore (pas de modèles) : sfx_list, sfx_render, kit_render (Boucle 5). Passez des chemins absolus ;full=trueretourne tout le JSON. Le serveur répond en quelques secondes, plus longtemps sur une machine froide ou chargée ; si Claude Code ne montre aucun outil earshot, lancez-le avecMCP_TIMEOUT=60000(PowerShell :$env:MCP_TIMEOUT=60000; claude).earshot mcp --warmprécharge les modèles au démarrage. Si la machine est partagée, définissezEARSHOT_THREADS=2-3(ou--threads 2sur n'importe quelle commande). Le premier appel de modèle d'un processus charge CLAP + AST (~20-60 s) ; les appels ultérieurs dans le même processus sont rapides. Tout fichier lisible par ffmpeg fonctionne, y compris l'audio d'un mp4 (une vidéo sans piste audio le signale). Les erreurs sont une ligne sur stderr :earshot <commande>: error: ..., exit 1.
Boucle 1 : choisir un actif
earshot rank "un coup de maillet en feutre doux sur un bloc de bois" telechargements/sfx/ --top 5- présélectionnez à partir d'un dossier.earshot find gagnant.ogg "un seul coup de maillet propre" --top 3- les meilleurs moments comme extraits d'échantillon (début / fin en secondes). Chaque segment a un type :stroke(une attaque jusqu'à ce qu'elle décroît) etevent(des strokes qui vont ensemble, par exemple l'enfoncement + le relâchement d'une touche) commencent 5 ms avant l'attaque et se terminent après la décroissance ;windowest un étirement dont les bords se sont accrochés au son pour les requêtes ponctuelles (un étirement simple, à fondre enchaîné, pour les nappes).head/tail= le volume des premières 5 ms / dernières 10 ms par rapport au pic de l'extrait (-30 dB ou moins = propre) ; un extrait marqué 'head cut' ou 'tail cut' commence ou se termine à l'intérieur d'un son : ne l'utilisez pas tel quel.--kind eventretourne uniquement les extraits basés sur l'attaque (impacts, clics, pas),--kind textureuniquement les fenêtres simples (nappes) ; la valeur par défaut lit la requête.earshot describe gagnant.ogg --start 1.12 --end 1.48- à quoi cela ressemble réellement ; vérifiez que les meilleures étiquettes correspondent à ce dont vous avez besoin et que la forme (attaque / décroissance) correspond à l'image. Les étiquettes AudioSet sont faibles sur les sons ponctuels de moins de ~0,5 s : 'tagger unsure' ou une classe proche (Zipper pour un swish, Finger snapping pour un clic) est neutre ; seule une classe carrément différente (Speech, Music, Engine, Vehicle) est un drapeau rouge.earshot realness gagnant.ogg --start 1.12 --end 1.48(ou un dossier entier) - jugez l'extrait que vous utiliserez : un fichier multi-prise a un p_real qui est la moyenne de chaque prise et du silence entre elles. Lorsque l'utilisateur veut un son réel ou produit professionnellement, n'utilisez pas un extrait 'probablement synthétisé par code', et lisez les preuves d'un extrait 'incertain' avant de l'utiliser (écrivez pourquoi vous l'avez conservé). Lorsque le son synthétisé est le but (musique procédurale, tonalités d'interface, sons créés avec earshot forge), le réalisme est une information, pas une barrière. Les seuils de verdict dépendent de la durée (chaque résumé les nomme) : un son jusqu'à 6 s utilise les seuils de clip (bas 0,17 / haut 0,77), un fichier plus long la moyenne de ses fenêtres de 4 s avec des seuils de fichier faiblement calibrés (bas 0,40 / haut 0,77), comparez donc les verdicts, pas le p_real brut, entre des fichiers de différentes longueurs. Les enregistrements réels et la musique et le design sonore produits professionnellement sont généralement lus comme réels, mais le réalisme entend comment un son sonne, pas d'où il vient : les tonalités synthétisées professionnellement propres (sons d'interface, carillons, stab de synthé) sont également lues comme synthétisées par code. Si le réalisme est indisponible (modèle manquant), dites clairement que réel-vs-synthétique n'a pas été vérifié ; les classes AudioSet de describe (Sine wave, Beep, Synthesizer) sont des preuves plus faibles. Les zéros numériques exacts seuls ne prouvent rien (59 % des enregistrements réels sous licence du projet ont une modification ou un fondu de remplissage).- Pour choisir entre deux candidats :
earshot ab a.ogg b.ogg --query "un whoosh d'air rapide et net", avec--a-start/--a-end/--b-start/--b-endpour les extraits de find (A et B peuvent être le même fichier multi-prise). Optionnel :earshot match gagnant.ogg "une pression de touche profonde et sourde" --alts "un contacteur bleu cliquable" "une touche de machine à écrire"pour tester une affirmation, ouearshot compare gagnant.ogg --refs approuve/ [--start --end]pour vérifier qu'il s'intègre à la palette.
Boucle 2 : réviser un mixage ou un film
earshot timeline film.mp4 --cues repères.json(oubande-son.wav --video film.mp4) - la transcription d'écoute : événements avec temps, niveau et étiquettes, sections, courbe de volume, coupes image, synchronisation par coupe / repère.--detail lowest rapide,highétiquette jusqu'à 96 événements (les plus importants en premier ; le résumé dit combien ont été étiquetés, donc un événement non étiqueté n'est pas un son manquant). Lisez les statistiques de synchronisation : offset_ms = son moins image (négatif = en avance), et la fraction 'chance' dit ce que des points de montage aléatoires obtiendraient ; seule une synchronisation meilleure que le hasard signifie quelque chose. Une coupe listée sans impact peut quand même porter un whoosh doux : vérifiez-la sur la fiche avant d'ajouter un son.earshot sheet film.mp4 -o feuille.png --cues repères.json(--from 10 --to 25zoome,--detail lowest plus rapide) - un PNG annoté : trames, sections, événements étiquetés, spectrogramme, volume, beats, marqueurs de repère colorés par synchronisation (vert = dans une trame, ambre = dans 100 ms, rouge = pas de son). OUVRIR LE PNG avec votre lecteur d'image : les lacunes, les accumulations, le masquage et les retards sont évidents en un coup d'œil.earshot critique film.mp4(--fastsaute les passes AudioSet / realness) - tableau de bord par rapport à la plage mesurée des films de lancement professionnels : chaque métrique ok / faible / élevé avec son poids et des actions avec horodatages, et un verdict (prêt pour le lancement / proche / nécessite du travail / pas prêt pour le lancement). Corrigez d'abord les lignes critiques, relancez 1-3 sur le nouveau rendu. Sa part "attaque sur événements visuels" compte les nouvelles attaques dans +-100 ms seulement (la définition des références) ; ses corrections et conseils nomment les coupes sans aucun son, par le même matcher que timeline. Si le fichier est l'un des propres films de référence du profil, critique le dit et le note par rapport aux autres.- Mesures exactes à tout moment (LUFS, pic vrai dBTP, LRA, plancher de bruit, attaque / décroissance, luminosité, bandes) :
earshot measure mix.wav [--music]ou l'outil MCPmeasure.
Boucle 3 : A/B d'un changement
earshot ab avant.wav après.wav --query "kick chaud puissant"ou--refs pro_refs/- lequel est le plus proche, et en quoi B diffère de A en termes mesurés (plus fort, plus lumineux, décroissance plus longue). Pour les sons dans des fichiers plus longs, passez les extraits (--a-start 1.217 --a-end 1.615 --b-start 7.881 --b-end 8.285) : un A/B de fichiers entiers multi-prise compare chaque prise plus le silence entre elles. Lancez ensuiteearshot timeline après.wavet comparez les lignes d'événements et les statistiques de synchronisation avec l'ancienne exécution. Changez une chose à la fois.
Boucle 4 : faire un son en code (earshot forge)
Utilisez ceci quand l'utilisateur veut un son fait, non choisi : une IA qui entend peut écrire du code de synthèse, écouter et l'améliorer. Chaque échantillon doit être calculé (pas de son enregistré à l'intérieur, même pas une réponse impulsionnelle) ; les enregistrements réels ne sont que les références que le critique compare.
-
Écrivez ou choisissez une recette dans
earshot/forge/recipes/<nom>.py:SPACE(plages de paramètres),DEFAULTS,TARGET,ALTS(confusions réalistes) etrender(params, r) -> tableau 48 kHz, construit à partir deearshot.forge.dsp(résonateurs modaux, excitations de contact, couleurs de bruit, un SVF variant dans le temps, une pièce calculée, un micro avec un plancher de bruit). Modélisez la physique de la chose réelle, mesurée sur les références : ce qui frappe quoi, ce qui sonne, combien de temps, dans quelle pièce. -
Lancez un tour :
earshot forge <recette> --refs <réfs réelles> --budget 144 --reps 2 --tone 1.5 --keep 4 --robust 8 --dir <dossier du tour>, ou dans un script Python par tour qui charge les modèles une fois :forge(recette, critique=Critic(target, alts, refs, tone=1.5), reps=2, espace={...}).--tonemet l'équilibre tonal sans modèle et la queue dans l'objectif.--reps 2classe chaque candidat par 2 rendus, contre les rendus chanceux.- Cela prend environ 3-5 minutes pour 160 rendus sur un CPU d'ordinateur portable chargé, y compris un échauffement du modèle de 30-60 s.
-
Lisez ce qu'il a entendu. Le résumé de chaque choix dit, par exemple, "ressemble à : un pop de bouchon, un tintement de verre", "décroissance +2,4 en dehors des refs" ou "tone 11,2 dB de la médiane des refs : +16 dB à 500-630 Hz (au-dessus de toutes les refs)". Vérifiez ensuite les choix de quatre façons :
- les mots
tonesans modèle : quelles bandes tombent en dehors de chaque référence, les parts d'énergie, la queue, la longueur (le signal le plus fiable une fois que les scores du modèle sont élevés) robust: la moyenne sur de nouvelles graines, pas le meilleur rendu chanceuxalt_zs: quelle confusion est la plus proche- les spectrogrammes à côté des références :
ffmpeg -i x.wav -lavfi showspectrumpic=s=900x360:scale=log:legend=0 x.png
Les étiquettes AudioSet dans report.json sont mises de côté seulement pendant que vous ne choisissez pas ou ne dirigez pas par elles. Fixez une règle de sélection (par exemple, la moyenne robuste) avant de regarder, et rapportez les étiquettes ensuite.
- les mots
-
Changez la structure de la recette, pas seulement ses plages, pour ce qui ne va pas (un tic de relâchement manquant, un son métallique, une queue trop longue). Puis répétez. Gardez un LOG de chaque changement de tour et de ses chiffres.
-
Rapportez honnêtement, à côté des références réelles notées par le même critique (
report.jsonref_scores, leave-one-out).
Goodhart, dites-le clairement :
- L'optimisation optimise les propres modèles d'earshot. Les sons fabriqués surpassent systématiquement les enregistrements réels sur eux, ce qui signifie que le critique est satisfait, pas que le son est meilleur.
- p_real est facile à tromper : les résonateurs modaux plus une pièce et un plancher de bruit de micro sont lus comme "réels".
- La typicalité récompense le fait d'être une moyenne des références.
- Les vérifications du modèle saturent : après une recherche, chaque vérification du modèle, les formulations mises de côté et les ensembles réels indépendants inclus, place le son fabriqué à l'intérieur des vrais. Seules les mesures et les oreilles peuvent encore les distinguer.
- Jugez par la proximité mesurée avec les références : équilibre tonal, bandes en dehors de chaque référence, queues, longueurs. Utilisez également les re-rendus robustes et les spectrogrammes.
- Demandez un test à l'aveugle humain (ordre aléatoire, volume assorti, clé cachée) avant d'appeler un son fabriqué "aussi bon que réel".
Dans le premier test (demo/forge-test), un juge indépendant a trouvé la pression de touche 8-13 dB décalée par rapport à l'équilibre tonal réel et les pops à bande illimitée avec de longues queues sifflantes, tandis que toutes les vérifications du modèle les appelaient réelles. Refait en dirigeant avec la vérification sans modèle, ils se situent maintenant à l'intérieur de la dispersion mesurée des enregistrements réels. Le whoosh a été refait comme un vraiment rapide. L'impact (plus sombre, mené par un gonflement) et le clic (queues courtes) n'ont pas été refaits. Aucun humain n'a encore écouté.
Boucle 5 : faire un kit sonore de film (earshot sfx / earshot kit)
Utilisez ceci quand un film fait en code (un film cinétique, n'importe quelle feuille de repère) a besoin de ses effets : rendez-les à partir de la banque intégrée d'earshot au lieu d'écrire des voix de synthèse. Aucun modèle ne se charge ; un kit entier se rend en environ une minute et se re-rend en quelques secondes.
- Partez d'un préréglage :
earshot kit init --preset calm -o audio/kit.json(calme pour les films menés par le texte, net pour les films produits énergétiques, minimal pour les films à effets conçus uniquement, lancement pour les films montés sur la musique). Lanotede chaque rôle dit pourquoi son son a été choisi. calm / crisp / minimal gardent riser, swell et suck off : une révélation se résout sur un élément, et le verrouillage est un seul impact propre. launch sonne un riser ou un swell inversé à un changement de section et utilise les sons 0.4 faits pour les films menés par la musique (ci-dessous). - Adaptez-le au film :
earshot sfx list --kind hit(ou--category) montre les candidats avec les longueurs, les temps de pic et les boutons. Changez lesoundd'un rôle, définissezedits(pitchà la racine du film pour l'impact ou la chute,dur/apexpour un mouvement fixe),takes(12 ou plus pour la frappe, 2-4 ailleurs),level_db. Auditionnez un candidat avecearshot sfx render ID -o x.wav [--pitch E5] [--dur 0.8 --apex 0.32]et lisez son onset / pic / fin mesurés. - Rendez :
earshot kit render audio/kit.json --out audio/kit. Les prises etkit.lock.json(onset mesuré, pic, fin, volume par prise) sont ce que le mixeur place sur les trames de repère : onset sur la trame pour les impacts et les touches, le pic sur un apex de whoosh, la fin sur un hit de riser (son pic quand le rôle s'aligne surpeak, comme le riser et le swell de launch le font : ces membres tombent après leur climax ;kit checknote un aligné sur la fin). - Vérifiez :
earshot kit check audio/kit.json --out audio/kit. Il refuse ce qu'un rendu ne peut pas utiliser (un bouton ou une hauteur que le son ne peut pas prendre, un niveau supérieur à 0 d