> ## 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 FFT/IFFT à flux unique à l'aide de l'API XDSP

> Vue d'ensemble d'une FFT/IFFT à flux unique à l'aide de l'API XDSP

Dans cette rubrique, nous passerons en revue le déroulement prévu du code pour utiliser le matériel afin d'effectuer des FFT/IFFT sur les appareils XBOX Series X, à l'aide de l'un des exemples inclus avec 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 au moyen de [XDspConnect](/fr-CA/reference/audio/xdspaudio/functions/xdspconnect). 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 et/ou de multiplicateur de bloc qui seront transmises au matériel. Cette mémoire doit être allouée au moyen de 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 le montre l'exemple ci-dessous. Cette mémoire ne doit pas être libérée tant que l'appel à [XDspDisconnect](/fr-CA/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.

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

4. handle : pointeur vers le [XDspClientHandle](/fr-CA/reference/audio/xdspaudio/handles/xdspclienthandle) qui contiendra le handle retourné par cet appel.

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

```cpp theme={null}
class TransformOneBufferManager 
{ 
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 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* à 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 le [XDspProcessType](/fr-CA/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 la réponse impulsionnelle dans le domaine fréquentiel dans [XDspActivationParameters](/fr-CA/reference/audio/xdspaudio/structs/xdspactivationparameters). Seuls les flux mono ou stéréo sont autorisés. Pour [XDspProcessType::ForwardFourierTransform](/fr-CA/reference/audio/xdspaudio/enums/xdspprocesstype) et [XDspProcessType::inverseFourierTransform](/fr-CA/reference/audio/xdspaudio/enums/xdspprocesstype), [XDspActivationParameters::impulseResponse](/fr-CA/reference/audio/xdspaudio/structs/xdspactivationparameters) doit être nullptr et [XDspActivationParameters::impulseResponseLengthInFloats](/fr-CA/reference/audio/xdspaudio/structs/xdspactivationparameters) = 0. [XDspActivationOptions](/fr-CA/reference/audio/xdspaudio/enums/xdspactivationoptions) doit être défini de façon appropriée.

Voici le code permettant d'activer un flux pour la transformée de Fourier directe; le code est semblable pour la transformée de Fourier inverse.

```cpp theme={null}
XDspActivationParameters params; 
XDspStatus* status; 
XDspStreamHandle* streamHandle; 
params.type = isForward ? XDspProcessType::ForwardFourierTransform : XDspProcessType::InverseFourierTransform;  // choose FFT vs IFFT
params.blockFrameCount = maxBufferFrameCount; 
params.channelCount = 1; // only mono is supported 
params.impulseResponseLengthInFloats = 0; // should be 0 for FFT/IFFT
params.impulseResponse = nullptr;  // should be nullptr for FFT/IFFT
params.options |= isPolar ? XDspActivationOptions::EnablePolarFormat : XDspActivationOptions::None;  // specifies whether the output should be in Polar format or Cartesian format and for IFFT this specifies whether the input is in Polar or Cartesian format.
 
hr = XDspActivate(clientHandle, &params, &status, &streamHandle);
```

[XDspActivate](/fr-CA/reference/audio/xdspaudio/functions/xdspactivate) retourne une mémoire tampon [XDspStatus](/fr-CA/reference/audio/xdspaudio/structs/xdspstatus) dans l'un de ses paramètres. Cette mémoire tampon [XDspStatus](/fr-CA/reference/audio/xdspaudio/structs/xdspstatus) doit servir à 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, la FFT ou l'IFFT. Cela doit se faire à l'aide de l'API [XDspSubmitCommand](/fr-CA/reference/audio/xdspaudio/functions/xdspsubmitcommand). Pour chaque appel à [XDspSubmitCommand](/fr-CA/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* données.
2. Remplir [XDspCommand](/fr-CA/reference/audio/xdspaudio/structs/xdspcommand) avec les valeurs appropriées ainsi que des mémoires tampons d'entrée et de sortie alignées sur 16 octets.
3. Appeler [XDspSubmitCommand](/fr-CA/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 servir à suivre le nombre de commandes envoyées au matériel.

```cpp theme={null}
XDspCommand command;  
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-CA/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-CA/reference/audio/xdspaudio/structs/xdspstatus), [XDspDeactivate](/fr-CA/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-CA/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-CA/reference/audio/xdspaudio/functions/xdspdeactivate) a réussi, l'appelant doit appeler [XDspDisconnect](/fr-CA/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-CA/reference/audio/xdspaudio/functions/xdspdisconnect) retourne l'erreur *XDSP\_E\_NOT\_ALL\_HANDLES\_DEACTIVATED*.

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


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