> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/media/audio-analysis.md).

# Análisis de audio

Lee datos de amplitud y frecuencia en tiempo real del audio que se reproduce en tu scene para impulsar visuales reactivos.

El `AudioAnalysis` componente lee datos en tiempo real desde una fuente de audio que se reproduce en tu escena, para que puedas impulsar las visuales a partir de la música. En cada frame, informa un valor general de **amplitud** valor y **8 bandas de frecuencia** (de menor a mayor) que puedes usar para escalar, colorear o animar entities.

Usos comunes:

* Cubes que rebotan al ritmo del bajo.
* Luces que pulsan con el ritmo.
* Visualizadores de barras al estilo ecualizador.
* Materiales reactivos o props escalados que acompañan la música.

`AudioAnalysis` es una fuente de solo lectura — tu escena solo consume los valores, y el runtime los completa. Funciona en entities que reproducen audio a través de un [AudioSource](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-del-contenido-3d/sounds.md), un [AudioStream](/creator/content-creator-es/scenes-sdk7/media/audio-streaming.md), o el audio de un [VideoPlayer](/creator/content-creator-es/scenes-sdk7/media/video-playing.md).

{% hint style="warning" %}
**📔 Nota**: `AudioAnalysis` Actualmente solo es compatible con la aplicación de escritorio oficial de Decentraland. En otros clientes los valores del componente nunca se completan, así que asegúrate de que tu escena siga funcionando aunque los datos nunca lleguen.
{% endhint %}

## Ejemplo mínimo

La siguiente escena reproduce un sonido, adjunta `AudioAnalysis` al mismo Entity, y escala un cubo en cada frame usando la amplitud del audio.

```ts
import {
  engine,
  Transform,
  MeshRenderer,
  AudioSource,
  AudioAnalysis,
  AudioAnalysisView,
} from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";

export function main() {
  // Reproducir un sonido en un Entity
  const audioEntity = engine.addEntity();
  Transform.create(audioEntity);
  AudioSource.create(audioEntity, {
    audioClipUrl: "sounds/music.mp3",
    playing: true,
    loop: true,
  });

  // Adjuntar AudioAnalysis al mismo Entity para comenzar a recibir datos de análisis
  AudioAnalysis.createAudioAnalysis(audioEntity);

  // Un objeto de vista reutilizable en el que el componente escribirá en cada frame
  const analysis: AudioAnalysisView = {
    amplitude: 0,
    bands: new Array<number>(8),
  };

  // Un cubo que pulsa con la amplitud del audio
  const cube = engine.addEntity();
  MeshRenderer.setBox(cube);
  Transform.create(cube, { position: Vector3.create(8, 1, 8) });

  // En cada frame, lee los últimos valores de análisis y escala el cubo
  engine.addSystem(() => {
    AudioAnalysis.readIntoView(audioEntity, analysis);
    const s = 1 + analysis.amplitude * 10;
    Transform.getMutable(cube).scale = Vector3.create(s, s, s);
  });
}
```

Las llamadas clave son:

1. `AudioAnalysis.createAudioAnalysis(entity)` — adjunta el componente al Entity que posee el `AudioSource`, `AudioStream`, o `VideoPlayer`. Usa el modo logarítmico por defecto (consulta [Modos](#modes)).
2. `AudioAnalysis.readIntoView(entity, analysis)` — copia los últimos `amplitud` y 8 `bandas` valores en un objeto de vista que proporcionas.

{% hint style="warning" %}
**📔 Nota**: Preasigna siempre el `bandas` array con **8 elementos** antes de llamar a `readIntoView`. El componente no cambia el tamaño del array por ti.
{% endhint %}

## Leer los datos en cada frame

`AudioAnalysis` está diseñado para leerse una vez por frame desde un system. El patrón recomendado es:

1. Asigna un único `AudioAnalysisView` objeto una sola vez.
2. En un system, llama a `readIntoView` para actualizarlo.
3. Usa los valores directamente o comparte la vista entre varios systems.

```ts
const analysis: AudioAnalysisView = {
  amplitude: 0,
  bands: new Array<number>(8),
};

engine.addSystem(() => {
  AudioAnalysis.readIntoView(audioEntity, analysis);
  // analysis.amplitude y analysis.bands[0..7] ahora contienen los valores más recientes
});
```

Si el Entity analizado todavía no tiene un `AudioAnalysis` componente (por ejemplo, se crea más tarde o se elimina dinámicamente), usa `tryReadIntoView` en su lugar. Devuelve `false` cuando el componente falta, y `true` cuando se escribieron valores.

```ts
engine.addSystem(() => {
  if (!AudioAnalysis.tryReadIntoView(audioEntity, analysis)) return;
  // es seguro usar analysis aquí
});
```

{% hint style="info" %}
**💡 Consejo**: Es más barato llamar a `readIntoView` una vez y permitir que varios systems compartan el mismo objeto de vista que leer el componente repetidamente.
{% endhint %}

## Reacciona a bandas de frecuencia específicas

Las 8 bandas cubren el espectro audible de menor a mayor. `bands[0]` es la más baja (graves) y `bands[7]` es la más alta (agudos). Puedes controlar diferentes entities con diferentes bands para construir un ecualizador clásico.

```ts
import {
  engine,
  Transform,
  MeshRenderer,
  Material,
  AudioSource,
  AudioAnalysis,
  AudioAnalysisView,
  Schemas,
} from "@dcl/sdk/ecs";
import { Color4, Vector3 } from "@dcl/sdk/math";

// Componente personalizado para marcar cada barra y recordar qué banda sigue
const VisualBar = engine.defineComponent("visual-bar", {
  index: Schemas.Number,
});

const BARS_HEIGHT = 12;

export function main() {
  const audioEntity = engine.addEntity();
  Transform.create(audioEntity);
  AudioSource.create(audioEntity, {
    audioClipUrl: "sounds/music.mp3",
    playing: true,
    loop: true,
  });
  AudioAnalysis.createAudioAnalysis(audioEntity);

  const analysis: AudioAnalysisView = {
    amplitude: 0,
    bands: new Array<number>(8),
  };

  // Crea 8 barras, una por banda
  for (let i = 0; i < 8; i++) {
    const bar = engine.addEntity();
    VisualBar.create(bar, { index: i });
    Transform.create(bar, { position: Vector3.create(4 + i, 0, 8) });
    MeshRenderer.setBox(bar);
    Material.setPbrMaterial(bar, { albedoColor: Color4.Yellow() });
  }

  // Leer una vez por frame
  engine.addSystem(() => {
    AudioAnalysis.readIntoView(audioEntity, analysis);
  });

  // Escala cada barra con su banda
  engine.addSystem(() => {
    for (const [entity] of engine.getEntitiesWith(VisualBar, Transform)) {
      const index = VisualBar.get(entity).index;
      const transform = Transform.getMutable(entity);
      transform.scale = Vector3.create(
        1,
        analysis.bands[index] * BARS_HEIGHT,
        1
      );
    }
  });
}
```

Este es el mismo patrón usado en el [ejemplo de escena de visualización de audio](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/88,-10-audio-visualization), reducido a lo esencial.

## Modos

`AudioAnalysis` admite dos modos de análisis, que se establecen al crear el componente:

* `PBAudioAnalysisMode.MODE_LOGARITHMIC` (predeterminado): los valores se escalan con una curva logarítmica, lo que se acerca más a cómo el oído humano percibe los cambios de volumen. Ideal para la reactividad visual.
* `PBAudioAnalysisMode.MODE_RAW`: la amplitud sin procesar y los valores de banda FFT. Usa esto si quieres aplicar tu propia escala.

```ts
import { AudioAnalysis, PBAudioAnalysisMode } from "@dcl/sdk/ecs";

// Usa valores sin procesar
AudioAnalysis.createAudioAnalysis(audioEntity, PBAudioAnalysisMode.MODE_RAW);
```

### Ajustar el modo logarítmico

En el modo logarítmico puedes pasar dos multiplicadores de ganancia opcionales:

* `amplitudeGain` — multiplicador aplicado a la amplitud general. Valor predeterminado `5`.
* `bandsGain` — multiplicador aplicado a las 8 bandas. Valor predeterminado `0.05`.

Ganancias más altas hacen que los valores sean más reactivos; ganancias más bajas los hacen más sutiles.

```ts
// Reacción de amplitud más fuerte, reacción de bandas más suave
AudioAnalysis.createAudioAnalysis(
  audioEntity,
  PBAudioAnalysisMode.MODE_LOGARITHMIC,
  10, // amplitudeGain
  0.03 // bandsGain
);
```

{% hint style="warning" %}
**📔 Nota**: `amplitudeGain` y `bandsGain` solo se aplican en el modo logarítmico. En el modo raw se ignoran.
{% endhint %}

## Reemplazar un componente existente

`createAudioAnalysis` falla si el Entity ya tiene un `AudioAnalysis` componente. Para cambiar modos o ganancias en runtime, usa `createOrReplaceAudioAnalysis`, que tiene la misma firma.

```ts
// Cambiar al modo raw a mitad de la escena
AudioAnalysis.createOrReplaceAudioAnalysis(
  audioEntity,
  PBAudioAnalysisMode.MODE_RAW
);
```

## Referencia del componente

### `AudioAnalysis.createAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)`

Adjunta un `AudioAnalysis` componente a `Entity`. Falla si ya hay un componente presente.

* `Entity` (`Entity`): el Entity que posee el `AudioSource`, `AudioStream`, o `VideoPlayer` que quieres analizar.
* `mode` (`PBAudioAnalysisMode`, opcional): `MODE_LOGARITHMIC` (predeterminado) o `MODE_RAW`.
* `amplitudeGain` (`number`, opcional): multiplicador de amplitud del modo logarítmico. Predeterminado `5`.
* `bandsGain` (`number`, opcional): multiplicador de bandas del modo logarítmico. Predeterminado `0.05`.

### `AudioAnalysis.createOrReplaceAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)`

Igual que arriba, pero reemplaza un `AudioAnalysis` componente en el Entity en lugar de fallar.

### `AudioAnalysis.readIntoView(entity, out)`

Lee los últimos valores en `out`. Lanza un error si `Entity` no tiene un `AudioAnalysis` componente.

* `Entity` (`Entity`): el Entity con el componente.
* `out` (`AudioAnalysisView`): un objeto de vista que proporcionas. Debe tener `bandas` preasignado con 8 números.

### `AudioAnalysis.tryReadIntoView(entity, out): boolean`

Igual que `readIntoView`, pero devuelve `false` si el Entity no tiene un `AudioAnalysis` componente en lugar de lanzar un error. Devuelve `true` cuando se escriben valores.

### `AudioAnalysisView`

Un objeto simple que asignas para recibir los datos de análisis:

```ts
type AudioAnalysisView = {
  amplitude: number; // fuerza general de la señal
  bands: number[]; // 8 bandas de frecuencia, de bajas (0) a altas (7)
};
```

## Notas y limitaciones

* **8 bandas, fijas.** El número de bandas de frecuencia es fijo en 8. No hay una API para solicitar más o menos bandas.
* **Una fuente de audio por análisis.** Cada `AudioAnalysis` componente analiza el audio del Entity al que está adjunto. Para analizar varias fuentes, adjunta `AudioAnalysis` a cada una.
* **Los live video streams no se analizan.** Hay un problema conocido en el que `AudioAnalysis` no recibe datos cuando el `VideoPlayer` source es un stream no progresivo, como un `.m3u8` URL HLS: el audio del stream se reproduce, pero los valores de análisis permanecen en cero. Los archivos de video (como `.mp4`) se analizan correctamente.
* **El audio en pausa no informa actualizaciones.** Cuando el audio subyacente se detiene o se pausa, los valores del componente dejan de cambiar. Tus últimos valores leídos permanecen en tu objeto de vista hasta que el audio se reproduzca de nuevo.
* **Barato, pero no gratis.** El análisis por frame está diseñado para ser económico (menos de un milisegundo por fuente en escritorio). Evita adjuntar `AudioAnalysis` a muchas fuentes a la vez si no necesitas los datos. Elimina el componente cuando un visualizador no sea visible.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/media/audio-analysis.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
