Remplacer l'envoi FFT brut (spectrum.data) par une représentation compacte, stable et directement exploitable par une IA dans une boucle:
- modifier le DSP / les paramètres
- mesurer
- comparer
- décider
- Compact : limiter fortement le volume de données transmis.
- Actionnable : fournir des signaux faciles à interpréter (équilibre tonal, pics, métriques globales).
- Stable : garder un schéma JSON déterministe et versionné.
- Comparatif : inclure des deltas pour guider l'itération.
Type MCP/HTTP recommandé: spectrum_summary_v1
{
"type": "spectrum_summary_v1",
"capturedAt": 1738900000000,
"frame": {
"sampleRate": 44100,
"fftSize": 2048,
"fmin": 20,
"fmax": 20000,
"floorDb": -110,
"bandsCount": 32
},
"bandsDbQ": [-72, -68, -63, -59, -55, -50, -48, -45, -42, -39, -37, -36, -34, -33, -31, -30, -29, -30, -32, -35, -38, -41, -44, -47, -50, -53, -56, -59, -62, -66, -70, -74],
"peaks": [
{ "hz": 110.0, "dbQ": -18, "q": 12.4 },
{ "hz": 220.0, "dbQ": -24, "q": 10.8 },
{ "hz": 330.0, "dbQ": -29, "q": 9.1 }
],
"features": {
"rmsDbQ": -14,
"centroidHz": 1850,
"rolloff95Hz": 6200,
"flatnessQ": 12,
"crestDbQ": 11
},
"audioQuality": {
"peakDbFSQ": -1,
"clipSampleCount": 24,
"clipRatioQ": 3,
"dcOffsetQ": 2,
"clickCount": 5,
"clickScoreQ": 18
},
"delta": {
"rmsDbQ": -2,
"centroidHz": 210,
"rolloff95Hz": 480,
"flatnessQ": -3,
"crestDbQ": 1
}
}- Retourne le dernier
spectrum_summary_v1disponible. - Source:
state.spectrumSummary(prioritaire). - Fallback de transition:
state.spectrum(legacy) sispectrumSummaryabsent.
Exemple de payload:
{
"mime": "application/json",
"content": {
"type": "spectrum_summary_v1",
"capturedAt": 1738900000000,
"frame": { "sampleRate": 44100, "fftSize": 2048, "fmin": 20, "fmax": 20000, "floorDb": -110, "bandsCount": 32 },
"bandsDbQ": [-72, -68, -63],
"peaks": [{ "hz": 110, "dbQ": -18, "q": 12.4 }],
"features": { "rmsDbQ": -14, "centroidHz": 1850, "rolloff95Hz": 6200, "flatnessQ": 12, "crestDbQ": 11 },
"audioQuality": { "peakDbFSQ": -1, "clipSampleCount": 24, "clipRatioQ": 3, "dcOffsetQ": 2, "clickCount": 5, "clickScoreQ": 18 },
"delta": { "rmsDbQ": -2, "centroidHz": 210, "rolloff95Hz": 480, "flatnessQ": -3, "crestDbQ": 1 }
}
}- Outil de compatibilité pour certains clients IA.
- Retourne le même contenu spectral que
get_spectrum. - L’export audio brut (
wav/pcm) n’est pas implémenté dans cette version. - Les arguments éventuels (
duration_ms,format) sont acceptés mais informatifs.
Objectif: déclencher un bouton Faust puis retourner une série temporelle compacte pour analyse IA de l'évolution.
Entrée:
{
"path": "/instrument/excite",
"holdMs": 80,
"captureMs": 600,
"sampleEveryMs": 80,
"maxFrames": 10
}path: chemin du bouton (obligatoire).holdMs: durée de pression (défaut:80, plage1..5000).captureMs: fenêtre totale d'observation (défaut:300, plage50..10000).sampleEveryMs: période d'échantillonnage des résumés (défaut:80, min40, max500).maxFrames: limite de frames retournées (défaut:10, max20).
Sortie:
{
"path": "/instrument/excite",
"holdMs": 80,
"captureMs": 600,
"sampleEveryMs": 80,
"series": [
{
"tMs": 0,
"summary": { "type": "spectrum_summary_v1", "capturedAt": 1738900000000 }
},
{
"tMs": 80,
"summary": { "type": "spectrum_summary_v1", "capturedAt": 1738900000080 }
}
],
"aggregate": {
"mode": "max_hold",
"summary": { "type": "spectrum_summary_v1", "capturedAt": 1738900000600 }
}
}Règles:
seriescontient des snapshots ordonnés partMscroissant.tMs=0correspond au moment du trigger.aggregate.mode="max_hold"est calculé sur toute la fenêtrecaptureMs.- Si aucune frame n'est capturée: erreur explicite (
Run view active + audio running). - Les snapshots de la série suivent le même schéma
spectrum_summary_v1.
Objectif: modifier un paramètre continu puis mesurer l'impact spectral avec une capture atomique.
Entrée:
{
"path": "/instrument/cutoff",
"value": 2400,
"settleMs": 120,
"captureMs": 500,
"sampleEveryMs": 80,
"maxFrames": 10
}path: chemin du paramètre continu (obligatoire).value: nouvelle valeur du paramètre (obligatoire).settleMs: délai après écriture avant capture (défaut:120, plage0..5000).captureMs: fenêtre totale d'observation (défaut:300, plage50..10000).sampleEveryMs: période d'échantillonnage des résumés (défaut:80, min40, max500).maxFrames: limite de frames retournées (défaut:10, max20).
Sortie:
{
"path": "/instrument/cutoff",
"value": 2400,
"settleMs": 120,
"captureMs": 500,
"sampleEveryMs": 80,
"series": [
{
"tMs": 0,
"summary": { "type": "spectrum_summary_v1", "capturedAt": 1738900000000 }
}
],
"aggregate": {
"mode": "max_hold",
"summary": { "type": "spectrum_summary_v1", "capturedAt": 1738900000500 }
}
}Règles:
- force la vue
runet démarre l'audio si nécessaire. - applique d'abord
set_run_param(path, value). - attend
settleMs, puis lance la capture. seriescontient des snapshots ordonnés partMscroissant.aggregate.mode="max_hold"est calculé sur toute la fenêtrecaptureMs.
type: version de format (spectrum_summary_v1).capturedAt: timestamp Unix en millisecondes.frame: métadonnées de capture.bandsDbQ: énergie par bande log-spacée, quantifiée en dB (entiers).peaks:Kpics dominants (fréquence, niveau quantifié, facteur de qualité).features: descripteurs globaux robustes.audioQuality(optionnel): indicateurs temporels de qualité audio (saturation/clicks).delta: variation vs dernier snapshot publié.
Le bloc audioQuality est optionnel dans spectrum_summary_v1 (extension backward-compatible).
{
"audioQuality": {
"peakDbFSQ": -1,
"clipSampleCount": 24,
"clipRatioQ": 3,
"dcOffsetQ": 2,
"clickCount": 5,
"clickScoreQ": 18
}
}Définitions:
peakDbFSQ:- pic temporel de la fenêtre en dBFS quantifié (pas 1 dB,
0= plein échelle).
- pic temporel de la fenêtre en dBFS quantifié (pas 1 dB,
clipSampleCount:- nombre d’échantillons au-dessus d’un seuil d’écrêtage (
abs(x) >= 0.999recommandé).
- nombre d’échantillons au-dessus d’un seuil d’écrêtage (
clipRatioQ:- proportion de samples écrêtés en pour-mille (
round(1000 * clipSampleCount / N)).
- proportion de samples écrêtés en pour-mille (
dcOffsetQ:- offset DC absolu quantifié (
round(abs(mean(x)) * 1000)).
- offset DC absolu quantifié (
clickCount:- nombre d’événements impulsionnels détectés sur la fenêtre.
clickScoreQ:- score global de risque de click (0..100 recommandé).
- Calculer la dérivée absolue
d[n] = abs(x[n] - x[n-1]). - Définir un seuil élevé (ex:
d[n] > 0.35) + condition d’isolement local. - Compter les impulsions courtes comme
clickCount. - Dériver
clickScoreQ(normalisation sur la taille de fenêtre, bornée à[0..100]).
But:
- permettre à l’IA de détecter objectivement des défauts temporels audibles même quand le spectre moyen semble acceptable.
- dB: quantification entière (
dbQ) avec pas 1 dB. flatnessQ:round(flatness * 100), plage[0..100].- fréquences: Hz en entier (ou float 0.1 Hz si besoin).
bandsCount: recommandé24ou32(défaut:32).peaks: recommandéK=8(défaut), max16.
- Découper
[fmin, fmax]enNbandes logarithmiques. - Pour chaque bande: prendre l'énergie max ou moyenne en dB.
- Recommandation:
max-holdsur fenêtre courte pour robustesse perçue.
- Détection de maxima locaux sur spectre lissé.
- Trier par amplitude décroissante.
- Garder top-
K. qapproximatif =f0 / bandwidth(-3 dB).
rmsDb: niveau global.centroidHz: centre de masse spectral.rolloff95Hz: fréquence contenant 95% de l'énergie.flatness: rapport géométrique/arithmetic mean.crestDb:peak - rms.
Pour limiter le trafic:
- cadence max recommandée:
5 Hz(200 ms). - émettre seulement si changement significatif:
|delta.rmsDbQ| >= 1ou|delta.centroidHz| >= 80ou- distance L1 normalisée des bandes > seuil (ex:
0.06). - sinon, ignorer la frame.
Pour trigger_button_and_get_spectrum (capture forcée):
- la capture force l'échantillonnage de la série pendant
captureMs, - mais garde la limite
maxFrames, - et publie
aggregate.max_holdmême si certaines frames intermédiaires sont manquantes.
- Conserver temporairement le format historique (
spectrum.data) derrière un flag. - Nouveau champ recommandé dans l'état partagé:
spectrumSummary(nouveau, snapshot courant)spectrumSeries(optionnel, buffer court pour capture tool)spectrum(legacy, optionnel de transition)- MCP
get_spectrumdoit retournerspectrumSummaryen priorité.
bands=32,peaks=8, features+delta:- taille JSON typique: ~0.7 à 1.5 KB/frame (au lieu de plusieurs dizaines de KB).
L'IA doit pouvoir:
- comparer deux snapshots sans FFT brut,
- détecter les déplacements tonaux (
centroid,rolloff, bandes), - détecter évolution harmonique (
peaks), - prendre des décisions paramétriques directement exploitables.
- Incrémenter
typepour toute rupture de schéma (spectrum_summary_v2, etc.). - Garder les champs existants stables entre versions mineures.