> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Información general de una convolución de secuencia única mediante la API XDSP

> Información general de una convolución de secuencia única mediante la API XDSP

En este tema, se explica el flujo de código previsto sobre cómo usar la reverberación por convolución de hardware en dispositivos XBOX Series X mediante uno de los ejemplos incluidos con el Microsoft Game Development Kit (GDK).

## Conexión con el hardware e inicio

Se debe establecer una conexión con la unidad de aceleración de hardware mediante [XDspConnect](/reference/audio/xdspaudio/functions/xdspconnect) o [XDspConnectWithMaximumStreamLimit](/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit). El llamador establece los requisitos de la conexión mediante los parámetros siguientes:

1. *baseBuffer*: un puntero a la memoria asignada por el usuario suficiente para contener los búferes de entrada, salida, envolvente o multiplicadores de bloque que se pasarán al hardware. Esta memoria se debe asignar mediante XMemAlloc con estos atributos: *XALLOC\_MEMTYPE\_PHYSICAL\_CACHEABLE*, *XALLOC\_PAGESIZE\_64KB*, *XALLOC\_ALIGNMENT\_64K*. Estos atributos se deben establecer mediante `MAKE_XALLOC_ATTRIBUTES()`, como se muestra en el ejemplo siguiente. Esta memoria no se debe liberar hasta que la llamada a [XDspDisconnect](/reference/audio/xdspaudio/functions/xdspdisconnect) se realice correctamente. Este búfer debe tener un tamaño mínimo de 64 KB.

2. *baseBufferLength*: la longitud del *baseBuffer* en bytes. Este búfer debe tener al menos 64 KB y no más de 500 MB.

3. *aggregateImpulseResponseInSeconds*: representa la duración total de todas las respuestas al impulso individuales que se activarán simultáneamente mediante [XDspActivate](/reference/audio/xdspaudio/functions/xdspactivate) con [XDspProcessType::Convolution](/reference/audio/xdspaudio/enums/xdspprocesstype). Si este valor es 0, no se puede activar ninguna secuencia con [XDspProcessType::Convolution](/reference/audio/xdspaudio/enums/xdspprocesstype).

4. handle: un puntero al [XDspClientHandle](/reference/audio/xdspaudio/handles/xdspclienthandle) que contendrá el identificador devuelto por esta llamada.

Si la llamada se realiza correctamente, el llamador puede usar el *baseBuffer* para pasar los datos de entrada y recuperar los datos de salida de las secuencias mediante los parámetros de [XDspCommand](/reference/audio/xdspaudio/structs/xdspcommand). Cualquier búfer que se pase en [XDspCommand](/reference/audio/xdspaudio/structs/xdspcommand) debe estar alineado a 16 bytes. El siguiente ejemplo de un administrador de búferes sencillo se puede usar para administrar los búferes de entrada y salida.

```cpp theme={null}
class ConvolveOneBufferManager
{
private:
    float const* _outputBuffer = nullptr;
    uint32_t _maxBufferFrameCount = 0;
    uint32_t _bufferStride = 0;
    uint32_t _maxBufferCount = 0;
    uint32_t _acquiredBufferCount = 0;
    uint32_t _channelCount = 1;

public:
    void Reset(float const* outputBuffer, uint32_t maxBufferCount, uint32_t maxBufferFrameCount, uint32_t channelCount) {
        _outputBuffer = outputBuffer;
        _maxBufferCount = maxBufferCount;
        _maxBufferFrameCount = maxBufferFrameCount;
        _channelCount = channelCount;
    }

    uint32_t GetMaxBufferFrameCount() const {
        return _maxBufferFrameCount;
    }

    bool IsFull() const {
        return _acquiredBufferCount >= _maxBufferCount;
    }

    void Acquire() {
        if (_acquiredBufferCount < _maxBufferCount) {
            _acquiredBufferCount++;
        }
    }

    void Release() {
        if (_acquiredBufferCount > 0) {
            _acquiredBufferCount--;
        }
    }

    float* GetOutputBuffer(uint32_t index) {
        return const_cast<float*>(_outputBuffer) + (((index % _maxBufferCount) * _maxBufferFrameCount * _channelCount));
    }

};
```

A continuación se muestra el ejemplo de código del primer paso para asignar memoria y establecer una conexión.

```cpp theme={null}
static const ULONGLONG XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES(allocatorId,
                      0,
                      XALLOC_MEMTYPE_PHYSICAL_CACHEABLE,
                      XALLOC_PAGESIZE_64KB,
                      XALLOC_ALIGNMENT_64K,
                      FALSE);

float* baseBuffer = (float *)XMemAlloc(baseBufferLength, XMemAllocAttributes);
```

Donde XMemAllocAttributes representa los atributos mencionados anteriormente. El código siguiente establece *aggregateImpulseResponse* en 32 segundos.

```cpp theme={null}
hr = XDspConnect(baseBuffer, baseBufferLength, 32 /*aggregateImpulseResponseInSeconds*/, &clientHandle);
```

## Activación y desactivación de secuencias

Una vez establecida la conexión con el dispositivo, el llamador debe enviar un comando de activación de secuencia para iniciar una convolución, FFT o IFFT. El llamador debe especificar el [XDspProcessType](/reference/audio/xdspaudio/enums/xdspprocesstype), el número de tramas por bloque, el número de canales, la longitud de la respuesta al impulso en floats y un puntero a los datos de la respuesta al impulso en el dominio de la frecuencia en [XDspActivationParameters](/reference/audio/xdspaudio/structs/xdspactivationparameters). Solo se permiten secuencias mono o estéreo. Para [XDspProcessType::ForwardFourierTransform](/reference/audio/xdspaudio/enums/xdspprocesstype) y [XDspProcessType::inverseFourierTransform](/reference/audio/xdspaudio/enums/xdspprocesstype), [XDspActivationParameters::impulseResponse](/reference/audio/xdspaudio/structs/xdspactivationparameters) debe ser nullptr y [XDspActivationParameters::impulseResponseLengthInFloats](/reference/audio/xdspaudio/structs/xdspactivationparameters) = 0. [XDspActivationOptions](/reference/audio/xdspaudio/enums/xdspactivationoptions) se debe establecer adecuadamente.

A continuación se muestra el código para activar una secuencia para convolución.

```cpp theme={null}
XDspActivationParameters params;
XDspStatus* status;
XDspStreamHandle* streamHandle;
params.type = XDspProcessType::Convolution;
params.blockFrameCount = maxBufferFrameCount;
params.channelCount = channelCount; // mono or stereo
params.impulseResponseLengthInFloats = filterFrameCount;
params.impulseResponse = filterBuffer;

if (channelCount == 2 && deinterleaved)
{
    params.options |= XDspActivationOptions::Deinterleaved;
}
if (stereoImpulseResponse)
{
    params.options |= XDspActivationOptions::StereoImpulseResponse;
}
hr = XDspActivate(clientHandle, &params, &status, &streamHandle); 
```

[XDspActivate](/reference/audio/xdspaudio/functions/xdspactivate) devuelve un búfer [XDspStatus](/reference/audio/xdspaudio/structs/xdspstatus) como uno de sus parámetros. Este búfer [XDspStatus](/reference/audio/xdspaudio/structs/xdspstatus) se debe usar para conocer el estado de los comandos procesados por el hardware para esta secuencia. Una vez recibido el resultado de la activación, el llamador puede empezar a enviar datos para la convolución, la FFT o la IFFT. Esto se debe hacer mediante la API [XDspSubmitCommand](/reference/audio/xdspaudio/functions/xdspsubmitcommand). Para cada [XDspSubmitCommand](/reference/audio/xdspaudio/functions/xdspsubmitcommand), el llamador debe hacer lo siguiente:

1. Rellenar el búfer de entrada con exactamente *blockFrameCount* de datos.
2. Rellenar el [XDspCommand](/reference/audio/xdspaudio/structs/xdspcommand) con los valores adecuados y con búferes de entrada y salida alineados a 16 bytes.
3. Llamar a [XDspSubmitCommand](/reference/audio/xdspaudio/functions/xdspsubmitcommand) para enviar el comando al hardware. Esta función devuelve un número de secuencia de comando que se puede usar para hacer un seguimiento del número de comandos enviados al hardware.

```cpp theme={null}
XDspCommand command;

command.beginScale = 1.0f;
command.endScale = 1.0f;
command.inputBlockBuffer = inputDataBuffer;
command.outputBlockBuffer =  bufferManager.GetOutputBuffer(_totalCommandsSubmitted + 1);
command.blockBufferMultiplier = nullptr;

uint32_t sequence = 0;
hr = XDspSubmitCommand(streamHandle, &command, &sequence);

if (SUCCEEDED(hr))
{
    totalCommandsSubmitted++;
}
```

A continuación, se puede comprobar [XDspStatus](/reference/audio/xdspaudio/structs/xdspstatus) para conocer el estado de los comandos enviados al hardware de la siguiente manera:

```cpp theme={null}
while (status->lastProcessedCommandSequence > totalResponsesReceived)
{
    totalResponsesReceived++;
 
    // Hardware status is only updated when there is a hardware fault and the
    // error is going to persist for the duration of the stream. But, all the
    // commands that have already been submitted will still be processed by
    // the hardware and we have to wait for these commands to be processed 
    // before calling XDspDeactivate.
    hr = status->result; 
     
    float* outBuffer = bufferManager.GetOutputBuffer(totalResponsesReceived);
    // The output will be in the outBuffer
    // Do something with the outBuffer
    bufferManager.Release();
}
```

Cuando se procesan los paquetes de la secuencia o el hardware devuelve un error en el resultado de [XDspStatus](/reference/audio/xdspaudio/structs/xdspstatus), se debe llamar a [XDspDeactivate](/reference/audio/xdspaudio/functions/xdspdeactivate).

```cpp theme={null}
while (totalResponsesReceived < totalCommandsSubmitted)
{
    // run the above code in the while loop to obtain all the responses
}
hr = XDspDeactivate(streamHandle);
```

[XDspDeactivate](/reference/audio/xdspaudio/functions/xdspdeactivate) devuelve *XDSP\_E\_PENDING\_RESULTS* si el hardware no ha terminado de procesar todos los comandos enviados para esta secuencia.

## Finalización

Después de que [XDspDeactivate](/reference/audio/xdspaudio/functions/xdspdeactivate) se realice correctamente, el llamador debe llamar a [XDspDisconnect](/reference/audio/xdspaudio/functions/xdspdisconnect) para desconectarse de la unidad de aceleración de hardware de audio y liberar todos los recursos asignados. Si no se han desactivado todas las secuencias, [XDspDisconnect](/reference/audio/xdspaudio/functions/xdspdisconnect) devolverá el error *XDSP\_E\_NOT\_ALL\_HANDLES\_DEACTIVATED*.

```cpp theme={null}
hr = XDspDisconnect(clientHandle);
XMemFree(baseBuffer, XMemAllocAttributes);
```

## Documentación de referencia de la API

* [XDspAudio (contenido de la API)](/reference/audio/xdspaudio/xdspaudio_members)
  * Funciones
    * [XDspConnect](/reference/audio/xdspaudio/functions/xdspconnect)
    * [XDspConnectWithMaximumStreamLimit](/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit)
    * [XDspDisconnect](/reference/audio/xdspaudio/functions/xdspdisconnect)
    * [XDspActivate](/reference/audio/xdspaudio/functions/xdspactivate)
    * [XDspSubmitCommand](/reference/audio/xdspaudio/functions/xdspsubmitcommand)
    * [XDspDeactivate](/reference/audio/xdspaudio/functions/xdspdeactivate)
  * Estructuras
    * [XDspCommand](/reference/audio/xdspaudio/structs/xdspcommand)
    * [XDspActivationParameters](/reference/audio/xdspaudio/structs/xdspactivationparameters)
    * [XDspStatus](/reference/audio/xdspaudio/structs/xdspstatus)

## Consulte también

[Información general de XDSP](/build/console-features/audio/overviews/xdsp-overview)


## Related topics

- [Convolución de secuencia única con envolvente mediante la API XDSP](/es/build/console-features/audio/overviews/xdsp-overview-single-stream-convolution-with-envelope.md)
- [Información general de una FFT/IFFT de secuencia única mediante la API XDSP](/es/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [XDspActivate](/es/reference/audio/xdspaudio/functions/xdspactivate.md)
- [XDspDeactivate](/es/reference/audio/xdspaudio/functions/xdspdeactivate.md)
- [XDspDisconnect](/es/reference/audio/xdspaudio/functions/xdspdisconnect.md)
