> ## 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.

# Vue d'ensemble d'une convolution à flux unique à l'aide de l'API XDSP

> Vue d'ensemble d'une convolution à flux unique à l'aide de l'API XDSP

Dans cette rubrique, nous allons examiner le flux de code attendu pour utiliser la réverbération par convolution matérielle sur les appareils XBOX Series X, à l'aide de l'un des exemples inclus dans le Microsoft Game Development Kit (GDK).

## Connexion au matériel et démarrage

Une connexion doit être établie avec l'unité d'accélération matérielle via [XDspConnect](/fr/reference/audio/xdspaudio/functions/xdspconnect) ou [XDspConnectWithMaximumStreamLimit](/fr/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit). L'appelant définit les exigences de la connexion à l'aide des paramètres suivants :

1. *baseBuffer* : pointeur vers la mémoire allouée par l'utilisateur, suffisante pour contenir les mémoires tampons d'entrée, de sortie, d'enveloppe et/ou de multiplicateur de bloc qui seront passées au matériel. Cette mémoire doit être allouée via XMemAlloc avec les attributs suivants : *XALLOC\_MEMTYPE\_PHYSICAL\_CACHEABLE*, *XALLOC\_PAGESIZE\_64KB*, *XALLOC\_ALIGNMENT\_64K*. Ces attributs doivent être définis à l'aide de `MAKE_XALLOC_ATTRIBUTES()`, comme illustré dans l'exemple ci-dessous. Cette mémoire ne doit pas être libérée tant que l'appel à [XDspDisconnect](/fr/reference/audio/xdspaudio/functions/xdspdisconnect) n'a pas réussi. Cette mémoire tampon doit avoir une taille d'au moins 64 Ko.

2. *baseBufferLength* : longueur de *baseBuffer* en octets. Cette mémoire tampon doit avoir une taille d'au moins 64 Ko et d'au plus 500 Mo.

3. *aggregateImpulseResponseInSeconds* : représente la durée totale de toutes les réponses impulsionnelles individuelles qui seront activées simultanément à l'aide de [XDspActivate](/fr/reference/audio/xdspaudio/functions/xdspactivate) avec [XDspProcessType::Convolution](/fr/reference/audio/xdspaudio/enums/xdspprocesstype). Si cette valeur est 0, aucun flux avec [XDspProcessType::Convolution](/fr/reference/audio/xdspaudio/enums/xdspprocesstype) ne peut être activé.

4. handle : pointeur vers le [XDspClientHandle](/fr/reference/audio/xdspaudio/handles/xdspclienthandle) destiné à contenir le handle retourné par cet appel.

Si l'appel réussit, l'appelant peut utiliser *baseBuffer* pour passer les données d'entrée et récupérer les données de sortie des flux via les paramètres de [XDspCommand](/fr/reference/audio/xdspaudio/structs/xdspcommand). Toute mémoire tampon passée dans [XDspCommand](/fr/reference/audio/xdspaudio/structs/xdspcommand) doit être alignée sur 16 octets. L'exemple suivant de gestionnaire de mémoire tampon simple peut être utilisé pour gérer les mémoires tampons d'entrée et de sortie.

```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));
    }

};
```

Voici l'exemple de code de la première étape, qui consiste à allouer de la mémoire et à établir une connexion.

```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);
```

Où XMemAllocAttributes représente les attributs mentionnés ci-dessus. Le code suivant définit *aggregateImpulseResponse* sur 32 secondes.

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

## Activation et désactivation des flux

Une fois la connexion établie avec l'appareil, l'appelant doit envoyer une commande d'activation de flux pour lancer une convolution, une FFT ou une IFFT. L'appelant doit spécifier dans [XDspActivationParameters](/fr/reference/audio/xdspaudio/structs/xdspactivationparameters) le [XDspProcessType](/fr/reference/audio/xdspaudio/enums/xdspprocesstype), le nombre de trames par bloc, le nombre de canaux, la longueur de la réponse impulsionnelle en valeurs float et un pointeur vers les données de réponse impulsionnelle dans le domaine fréquentiel. Seuls les flux mono ou stéréo sont autorisés. Pour [XDspProcessType::ForwardFourierTransform](/fr/reference/audio/xdspaudio/enums/xdspprocesstype) et [XDspProcessType::inverseFourierTransform](/fr/reference/audio/xdspaudio/enums/xdspprocesstype), [XDspActivationParameters::impulseResponse](/fr/reference/audio/xdspaudio/structs/xdspactivationparameters) doit être nullptr et [XDspActivationParameters::impulseResponseLengthInFloats](/fr/reference/audio/xdspaudio/structs/xdspactivationparameters) = 0. [XDspActivationOptions](/fr/reference/audio/xdspaudio/enums/xdspactivationoptions) doit être défini de manière appropriée.

Voici le code permettant d'activer un flux pour la convolution.

```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](/fr/reference/audio/xdspaudio/functions/xdspactivate) retourne une mémoire tampon [XDspStatus](/fr/reference/audio/xdspaudio/structs/xdspstatus) dans l'un de ses paramètres. Cette mémoire tampon [XDspStatus](/fr/reference/audio/xdspaudio/structs/xdspstatus) doit être utilisée pour connaître l'état des commandes traitées par le matériel pour ce flux. Une fois le résultat de l'activation reçu, l'appelant peut commencer à soumettre des données pour la convolution/FFT/IFFT. Cela doit se faire à l'aide de l'API [XDspSubmitCommand](/fr/reference/audio/xdspaudio/functions/xdspsubmitcommand). Pour chaque [XDspSubmitCommand](/fr/reference/audio/xdspaudio/functions/xdspsubmitcommand), l'appelant doit effectuer les opérations suivantes :

1. Remplir la mémoire tampon d'entrée avec exactement *blockFrameCount* de données.
2. Renseigner [XDspCommand](/fr/reference/audio/xdspaudio/structs/xdspcommand) avec les valeurs appropriées et des mémoires tampons d'entrée et de sortie alignées sur 16 octets.
3. Appeler [XDspSubmitCommand](/fr/reference/audio/xdspaudio/functions/xdspsubmitcommand) pour soumettre la commande au matériel. Cette fonction retourne un numéro de séquence de commande qui peut être utilisé pour suivre le nombre de commandes envoyées au matériel.

```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++;
}
```

Ensuite, vous pouvez vérifier [XDspStatus](/fr/reference/audio/xdspaudio/structs/xdspstatus) pour connaître l'état des commandes soumises au matériel, comme suit :

```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();
}
```

Lorsque les paquets du flux ont été traités ou que le matériel retourne une erreur dans le résultat de [XDspStatus](/fr/reference/audio/xdspaudio/structs/xdspstatus), [XDspDeactivate](/fr/reference/audio/xdspaudio/functions/xdspdeactivate) doit être appelé.

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

[XDspDeactivate](/fr/reference/audio/xdspaudio/functions/xdspdeactivate) retourne *XDSP\_E\_PENDING\_RESULTS* si le matériel n'a pas fini de traiter toutes les commandes soumises pour ce flux.

## Arrêt

Une fois que [XDspDeactivate](/fr/reference/audio/xdspaudio/functions/xdspdeactivate) a réussi, l'appelant doit appeler [XDspDisconnect](/fr/reference/audio/xdspaudio/functions/xdspdisconnect) pour se déconnecter de l'unité d'accélération matérielle audio et libérer toutes les ressources allouées. Si tous les flux ne sont pas désactivés, [XDspDisconnect](/fr/reference/audio/xdspaudio/functions/xdspdisconnect) retourne l'erreur *XDSP\_E\_NOT\_ALL\_HANDLES\_DEACTIVATED*.

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

## Documentation de référence de l'API

* [XDspAudio (contenu de l'API)](/fr/reference/audio/xdspaudio/xdspaudio_members)
  * Fonctions
    * [XDspConnect](/fr/reference/audio/xdspaudio/functions/xdspconnect)
    * [XDspConnectWithMaximumStreamLimit](/fr/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit)
    * [XDspDisconnect](/fr/reference/audio/xdspaudio/functions/xdspdisconnect)
    * [XDspActivate](/fr/reference/audio/xdspaudio/functions/xdspactivate)
    * [XDspSubmitCommand](/fr/reference/audio/xdspaudio/functions/xdspsubmitcommand)
    * [XDspDeactivate](/fr/reference/audio/xdspaudio/functions/xdspdeactivate)
  * Structures
    * [XDspCommand](/fr/reference/audio/xdspaudio/structs/xdspcommand)
    * [XDspActivationParameters](/fr/reference/audio/xdspaudio/structs/xdspactivationparameters)
    * [XDspStatus](/fr/reference/audio/xdspaudio/structs/xdspstatus)

## Voir aussi

[Vue d'ensemble de XDSP](/fr/build/console-features/audio/overviews/xdsp-overview)


## Related topics

- [Vue d'ensemble de l'API C Services - PFLeaderboardsTypes.h](/fr/services/playfab/api-references/c/pfleaderboardstypes/pfleaderboardstypes_members.md)
- [Vue d'ensemble de l'API C Services - PFLeaderboards.h](/fr/services/playfab/api-references/c/pfleaderboards/pfleaderboards_members.md)
- [Vue d'ensemble d'Unity](/fr/paths/unity/overview.md)
- [Vue d'ensemble de l'API C Services - PFStatistics.h](/fr/services/playfab/api-references/c/pfstatistics/pfstatistics_members.md)
- [Vue d'ensemble de Windows & ROG XBOX Ally](/fr/paths/windows/overview.md)
