# SDIF

# Le format de fichier

Analyse/Synthèse

Dominique Virolle

- Principe de SDIF

- Des Matrices
- Des Frames
- Notion Temporelle
- Des Chunks
- BigEndian

- Le Format

- File Header
- Informations Table Chunk

- Informations Table Header
- Informations Table Data
- Padding

- Types Declarations Chunk

- Types Declarations Header
- Types Declarations Data

- Type de Matrice
- Type de Frame
- Types Declarations Grammaire

- Stream IDs Table Chunk

- Stream IDs Table Header
- Stream IDs Table Data

- Frames Chunks

- Frame

- Frame Header
- Frame Data

- Matrix

- Matrix Header
- Matrix Data

- Exemple de Frame en texte

- Mots Reservés SDIF

- Mots Information Table
- Predefined Types

- Predefined Matrix Types
- Predefined Frame Types

- StreamID TreeWay pour Chant

- Description de chaque élément du TreeWay
- Exemple TreeWay Chant

# Principe de SDIF

- Des Matrices
- Des Frames
- Notion Temporelle
- Des Chunks
- BigEndian

L'idée générale de SDIF est de stocker les informations liées au traitement du signal et plus particuliairement du son, dans des fichiers, suivant un format commun à tous les types de données. Ainsi, il est possible de stocker des résultats ou des paramètres d'analyses, de synthèses...

## Des Matrices

Le format a comme première spécification le stockage des données sous forme de matrices ou chaque colonne représente un champ de structure, et chaque ligne un élément de cette structure. Une structure que l'on peut représenter sous forme de matrice est dite dans ce document "simple".

Ainsi, pour une structure Filtre composée de trois champs "fréquence", "amplitude", et "largeur de bande", des éléments de Filtre sont stockés comme une matrice de trois colonnes et de autant de lignes qu'il y a d'éléments.

Filtre | fréquence | amplitude | largeur de bande
--- | --- | --- | ---
Filtre1 | - | - | -
Filtre2 | - | - | -
FiltreN | - | - | -

## Des Frames

La seconde spécification de SDIF est que les matrices sont regroupées dans des frames. Il y a plusieurs types de frames : les bancs de filtres, les bancs de fofs... Un frame s'adresse à un objet contenant plusieurs sous-objets de structure(s) simple(s). Ainsi, un frame BancDeFiltre permet de représenter un ensemble de Filtres. Une structure associée à un frame est dite "composée".

## Notion Temporelle

A chaque modification dans le temps d'un paramètre d'un objet est associé un bloc frame SDIF pour le type de l'objet. Le fichier SDIF est globalement une succession de frames ordonnés dans le temps.

## Des Chunks

Un fichier SDIF se compose de plusieurs chunks dans l'ordre :

- Zéro, une ou plusieurs table d'informations "Informations Table",
- Un Chunk optionnel de déclarations ou de complétions de types de matrices ou frames "Types Declarations",
- Une table optionnelle d'index SDIF "Stream IDs Table",
- Une suite de chunks de type "Frame".

Il devrait y avoir une Time Table mais son format et sa position n'ont pas encore été décidés.

## BigEndian

Quelque soient les données d'un fichier SDIF ou le type de matériel informatique qui écrit ou lit des fichiers SDIF, toutes les données sont écrites en BigEndian IEEE et alignées sur 8 bytes.

# Le Format

- File Header
- Informations Table Chunk

- Informations Table Header
- Informations Table Data
- Padding

- Types Declarations Chunk

- Types Declarations Header
- Types Declarations Data

- Type de Matrice
- Type de Frame
- Types Declarations Grammaire

- Stream IDs Table Chunk

- Stream IDs Table Header
- Stream IDs Table Data

- Frames Chunks

- Frame

- Frame Header
- Frame Data

- Matrix

- Matrix Header
- Matrix Data

- Exemple de Frame en texte

## File Header

L'entête d'un fichier SDIF se compose de 2 champs :

"SDIF" | 4 bytes | Signature SDIF
<champ vide> | 4 bytes | non encore défini (== 00000000 hexa)

## Informations Table Chunk

### Informations Table Header

L'entête d'un chunk d'une table d'informations est codée sur 8 bytes :

"1NVT" | 4 bytes | Signature Informations Table
<Chunk Size> | 4 bytes | Taille du Chunk sans compter l'entête. (Padding inclus et par défault ffffffff hexa)

### Informations Table Data

La table d'informations permet d'avoir des informations générales comme l'auteur du fichier, la version de SDIF, le nombre de cannaux... Les données de ce chunk sont en ASCII.

Les données commencent par '{' et finissent par '}'. Chaque information est sous la forme `<Nom> <Valeur> ';'` . Il est nécessaire d'avoir au moins un caractère d'espacement entre le nom et la valeur (et non des caractères nuls '\0' car c'est une partie ASCII).

Exemple de Informations Table Data:

    {
      numChannels   6   ;
      SDIFVersion   1.0.0.alpha;
      MonProgrammeParametreSpecial  integer4  ;
    }

La grammaire associée est :

    <Info Table Data>    := '{' <Info declaration> | ... '}'
      <Info declaration> := [<space chars>] <Name>
                                     <space chars> <Value> [<space chars>]';'
        <space chars>    := <space> | ...
          <space>        :=  ' ' | '\t' | '\n' | '\f' | '\r' | '\v'
        <Name>           := ASCII string
        <Value>          := ASCII string

### Padding

L'aspect ASCII de la table d'informations commence au '{' et fini au '}'. Mais après le '}', il y a un Padding qui peut varier de 0 à 7 bytes. Chaque bytes du Padding est mis à '\0'. Le Padding permet d'aligner le fichier sur 64 bits. Ainsi le chunk suivant débute aligné.

## Types Declarations Chunk

Il est possible dans SDIF de compléter les types de matrices ou de frames existant (cf : Predefined Types) ou d'en créer de nouveaux. Si un types existe déjà, on considère qu'une déclaration sur ce type est une complétion. S'il n'existe pas, alors c'est une création.

Cependant, pour un type donné, il ne peut y avoir qu'une seule déclaration dans un fichier SDIF. C'est à dire que l'on ne peut pas compléter un type une deuxième fois et on ne peut pas créer un nouveau type puis le compléter.

Comme pour les tables d'informations, les données de déclarations de types sont en ASCII. Par contre, il ne peut y en avoir qu'un.

Important : Les créations sont vivement déconseillées puiqu'il s'agit d'un mode exclusif par rapport à une application. De plus, les noms de types créés doivent avoir 'E' comme premier caractère. Ainsi, un type exclusif peut être ajouter à la base des types prédéfinis en remplaçant le 'E' par un digit. Les fichiers utilisant le type exclusif est ainsi toujours lisible (pas de conflits de déclaration de type).

### Types Declarations Header

L'entête d'un chunk de déclaration de types est codée sur 8 bytes :

"1TYP" | 4 bytes | Signature Types Declarations
<Chunk Size> | 4 bytes | Taille du Chunk sans compter l'entête (Padding inclus et par défault ffffffff hexa)

### Types Declarations Data

La partie donnée du chunk Types Declarations est en ASCII. Elle commence donc par '{' et fini par '}'. Une donnée est soit une déclaration de type de matrice, soit une déclaration de type de frame. Comme un type de frame est un ensemble de matrices, sa déclaration dépend des déclarations des types de matrices contenues. Deux mots clés permettent de savoir s'il s'agit d'une déclaration d'un type de matrice ou d'un frame. "1MTD" pour matrice, "1FTD" pour frame.

#### Type de Matrice

La déclaration d'un type de matrice commence donc par "1MTD". On a ensuite le nom du type de matrice sur 4 caractères ASCII dont le premier est un chiffre indiquant la version du type si c'est une complétion ou 'E' si c'est une création. Ensuite, on définie comme un tableau en C les noms des champs de la structure représentée. Les champs indiques les entêtes de colonnes.

Exemples :

       1MTD EFIL {frequence, amplitude, largeurdebande}
       1MTD  1TYP { Champ1, Champ2, Champ3 }
       1MTD2TYP{Champ21,Champ22,Champ23}

    EFIL est une création, 1TYP et 2TYP sont des complétions.

Comme les tailles de "1MTD" et du nom du type sont fixes, il n'est pas nécessaire d'avoir des espacements (toutefois, c'est préférable).

Les noms de champs définissent l'ordre des colonnes dans les matrices. Celui-ci ne peut pas être modifier sans créer un nouveau type. Contrairement aux structures C, les champs ne sont pas typés. Ceci vient du fait que les données sont toujours des floattants sur 4 bytes ou sur 8 bytes (cf. Matrice Data).

La Complétion de Matrice :

Lorsque le type de matrice est prédéfini (il existe comme format dans SDIF), une déclaration sur ce type entraine le mode complétion. Celle-ci consiste seulement à ajouter de nouvelles colonnes (champs) aux matrices (aux structures simples). Ainsi si 1FIL est prédéfini dans SDIF avec "fréquence", "amplitude", et "largeur de bande", `1MTD 1FIL {saliance, correction}` ajoute deux nouvelles colonnes aux matrices (la 4 et la 5). Mais aucune modification des colonnes prédéfinies n'est possible.

#### Type de Frame

La déclaration d'un type de frame commence par "1FTD". Ensuite on a le nom du type de frame (ne doit pas exister comme type de matrice) sur 4 caractères ASCII dont le premier digit indique la version du type si c'est une complétion ou 'E' si c'est une création. Le bloc de définition commence par '{' et fini par '}'. Chaque donnée du type de frame est : un nom de type de matrice existant, un nom de champ de structure frame. A la fin d'une donnée de type de frame, on a un ';'.

Exemple (supposant 1FIL et 1TYP existant) :

    Création : mode exclusif
        1FTD EFIB
         {
           1FIL  filtres;
           1TYP  exemple1types;
         }

    Complétion
        1FTD 1FIB
         {
           2TYP exemple2types
         }

    EFIB et 1FIB ne représentent pas le même type de frame même s'ils ont les
    mêmes 2 premières matrices, et que les 3 lettres significatives sont 'FIB'.

Ainsi, on défini EFIB comme un frame de 2 matrices. Comme pour les matrices, si le type de frames est prédéfini, alors on complète le type de frame par des matrices supplémentaires. Ainsi, si 1FIB est prédéfini comme dans l'exemple précédent, si on déclare 1FTD 1FIB {2TYP exemple2types}, alors on ajoute une nouvelle matrice à 1FIB (exemple1types de type 1TYP est toujours là).

#### Types Declarations Grammaire

    <Types Declaration Data> := '{' <Matrix or Frame Declaration> | ... '}'
      <Matrix or Frame Declaration> :=  <Matrix Declaration>
                                           | <Frame Declaration>
        <Matrix Declaration> := 1MTD [space chars] <Matrix Name> [space chars]
                                       '{' <Col Names > <One Col Name> '}'
          <Matrix Name> := 4 chars (32bits)
          <Col Names> := [<(N-1) Col Names>]
            <(N-1) Col Names> := <One Col Name Not Last> | ...
              <One Col Name Not Last> := <One Col Name> ','
          <One Col Name> := [space chars]<string>[space chars]
             <string> := ASCII chars
        <Frame Declaration> := 1FTD [space chars] <Frame Name> [space chars]
                                       '{' <Frame Component> | ... '}'
          <Frame Name>  :=  4 chars (32bits)
          <Frame Component> := [spaces] <Matrix Name>
                                     [spaces] <Frame Component Name>[spaces] ';'
             <Frame Component Name> := <string>

Exemple de déclaration de types (ici ils sont complétés):

    1TYP <ChunkSize>
    {
      1MTD 1FIL {frequency, amplitude, banwidth}
      1MTD 1CHA {channel1, channel2}

      1FTD FIB
        {
          1FIL filtersparameters;
          1CHA filterschannels;
        }

      1MTD 1FOF {frequence, amplitude, banwidth, tex, debatt, atten, phase}
      1MTD 1FQ0 {fondamentalfq}

      1FTD 1FOB
        {
          1FQ0 pitch;
          1FOF fofsparameters;
          1CHA fofschannels;
        }
    }

Le chunk de déclarations de types est optionnel.

Comme pour le chunk d'informations, le bloc données du chunk de type est suivi d'un Padding.

## Stream IDs Table Chunk

### Stream IDs Table Header

L'entête d'un chunk de la table de d'ID est aussi codée sur 8 bytes :

"1IDS" | 4 bytes | Signature Stream IDs Table
<Chunk Size> | 4 bytes | Taille du Chunk sans compter l'entête (Padding inclus et par défault ffffffff hexa)

### Stream IDs Table Data

La table d'ID permet d'avoir des informations sur les objets sur lesquels les frames vont s'appliquer. Un ID est un entier représentant un objet particulier. Deux objets ont toujours deux ID différents, même s'ils se différencient déjà par leurs types. Ainsi un ID est une clé absolue pour un objet par rapport à un fichier SDIF.

Les données commencent par '{' et finissent par '}'. Chaque information est sous la forme `<ID> <Source ou Destination>: <TreeWay> ';'` . Les données sont en ASCII.

Exemple de Stream IDs Table Data:

    {
      1   MonProg:Groupe1/1/FIB/0/12/500./3./80.;
      2   MonProg:Groupe1/1/FIB/1/5/500./3./80.;
      3   MonProg:Groupe1/1/FIB/2/8/500./3./80.;
      4   TonProg:FOB/"Fofbank"/4/4/2;
    }

La signification et la construction de TreeWay dépendent de la Source, mais rien n'est prédéfini. La Source doit être un nom de programme, ou un nom de méthode de calcul, d'analyse, de synthèse... Elle est utile pour le programme qui va lire les données et non par celui qui les écrit. C'est la raison pour laquelle on parle de Source ou de Destination. TreeWay peut donner des informations sur des liens entre objet. Une composante dans les TreeWay semble obligatoire : il doit y avoir le nom du type de l'objet dans le TreeWay (sans le numéro de version pour qu'un lecteur SDIF puisse faire une tentative de lecture sur un type de frame de version inconnue). La table des ID est en quelque sorte le moyen de déclarer des objets qui seront modifiés dans le temps via les frames.

La grammaire associée est :

    <ID Table Data>            := '{' <ID declaration> | ... '}'
      <ID declaration>         := [<space chars>] <ID>
                                         <space chars> <Souce ou Destination> ':'
    			             [<space chars>] <TreeWay> ';'
        <space chars>          := <space> | ...
          <space>              :=  ' ' | '\t' | '\n' | '\f' | '\r' | '\v'
        <ID>                   := ASCII digits
        <Source ou Destination>:= ASCII string
        <TreeWay>              := ASCII string (définition variable)
             Les composants de TreeWay sont séparés par le symbol '/'.

Comme pour les précédents chunk, le Stream IDs Chunk est aligné sur 8 bytes par Padding.

## Frames Chunks

### Frame

#### Frame Header

Il faut pour l'entête du frame, avoir le nom du type, la taille du frame (Somme des matrices), le nombre de matrices, l'ID de l'objet de la structure composée du frame et le temps qui designe l'instant de la mise en place des données codé en double précision (8 bytes).

Le nombre de matrices d'un frame peut être inférieur au nombre de matrices du type de frame. Le frame peut contenir seulement les N premières matrices du type : 0 < N <= NbMatriceFrameType. si on considère le type de frame 1FOB (cf. Types Declarations Grammaire), on peut avoir un frame portant uniquement sur le "pitch" et sur les "fofsparameters". Les "fofschannels" ne sont alors pas défini : N == 2. Mais, il n'est pas possible d'avoir un frame 1FOB avec les matrices "pitch" et "fofschannels" car l'ordre des matrices doit suivre l'ordre donnée dans la déclaration de type (ou du type prédéfini).

Remarque : Il ne doit pas y avoir d'"états". C'est à dire qu'a chaque frame, toutes les connaissances sur l'objet indexé doivent apparaitre pour le temps donné. On doit pouvoir ainsi donner toutes les informations d'un objet à la lecture d'un seul frame pour un temps donné; inutile de lire les frames de temps inférieurs.

<Nom du type de Frame> | 4 bytes | char[4]
<Frame Size> (entête incluse) | 4 bytes | int 4
<Nombre de Matrices N> | 4 bytes | int 4
<ID de l'objet concerné> | 4 bytes | int 4
<Temps> | 8 bytes | float 8

#### Frame Data

Les données d'un frame sont simplement une succession de N matrices. Il n'y a pas de Padding pour les frames car ils sont obligatoirement alignés par le fait que l'entête est sur 24 bytes donc alignée sur 8 bytes et que chaque matrice sera alignée.

Matrice 1 | Alignée sur 8 bytes
... | Alignée sur 8 bytes
Matrice N | Alignée sur 8 bytes

### Matrix

#### Matrix Header

L'entête d'une matrice commence par sa signature. Elle doit correspondre avec la signature déclarée dans le type de frame en fonction de la position de la matrice dans le frame.

Après le nom du type de matrice, il doit y avoir le code du format de donnée :

- 32 si les données sont en float sur 4 bytes.
- 64 si les données sont en float sur 8 bytes.

Ensuite, on a le nombre de lignes L qui dépend du nombre d'éléments de la structure simple contenus dans l'objet (ID) de la structure composée. Les éléments de la structure simple sont indexés uniquement par le numéro de la ligne dans la matrice.

Après L, le nombre de colonnes C. Celui-ci a la même propriété que N du niveau frame. C'est à dire que la matrice contient les C premières colonnes du type de matrice.

Les 3 données "type de données (32 ou 64), L et C sont écrites dans un fichier SDIF en float (4 bytes).

Nom du type de Matrice | 4 bytes | char
Largeur des données (bits) | 4 bytes | float 4
Nombre de lignes L | 4 bytes | float 4
Nombre de colonnes C | 4 bytes | float 4

#### Matrix Data

La matrice est écrite ligne après ligne. Elle est suivit d'un Padding pour l'alignement sur 8 bytes.

Ligne1 | (4 ou 8 bytes)*C | float 4 ou 8
... | (4 ou 8 bytes)*C | float 4 ou 8
LigneL | (4 ou 8 bytes)*C | float 4 ou 8
Padding | 0 ou 4 bytes | '\0'

### Exemple de Frame en texte

    ( ) : commentaire pour l'exemple.

    '1FOB'  <FrameSize>  (N=)3   (ID=)0    (Time=)1.45

      (matrice 1 : pitch)
      '1FQ0'    (TypeDonnées=)32    (L=)1    (C=)1

           (frequency)
              164.

      (matrice 2 : fofsparameters)
      '1FOF'    (TypeDonnées=)32    (L=)5    (C=)7
            (frequency amplitude bandwidth    tex  atten   debatt phase)
    	   609.       80.       78.     0.002   0.05    0.004   0.   (fof1)
    	   1000.      53.9	88.     0.002   0.05    0.004   0.   (fof2)
    	   2450.      18.	123.	0.002   0.05    0.004   0.   (fof3)
    	   2700.      19.	128.    0.002   0.05    0.004   0.   (fof4)
    	   3200.      6.1	138.    0.002   0.05    0.004   0.   (fof5)

      (matrice 3 : fofschannels)
      '1CHA'    (TypeDonnées=)32    (L=)5    (C=)1
            (channel1 channel2)
    	   1.5       1.    (fof1)
    	   1.5	     1.    (fof2)
    	   1.5	     2.2   (fof3)
    	   1.5	     0.5   (fof4)
    	   1.5	     1.5   (fof5)

     A part les signatures, la taille du frame, le nombre de matrices N et ID,
     toutes les données sont des floats. Time est toujours en double précision.

# Mots Reservés SDIF

- Mots Information Table
- Predefined Types

- Predefined Matrix Types

- Fréquence fondamentale 1FQ0
- Forme d'onde formantique 1FOF
- Cannaux, mixage 1CHA
- Filtre Resonnant 1RES
- Distribution d'un processus aléatoire 1DIS

- Predefined Frame Types

- Bank de Formants 1FOB
- Bank de Filtres résonnants 1REB
- Bruit 1NOI

## Mots Information Table

SDIFAuthor | auteur du fichier
SDIFLibraryVersion | version de la librairie SDIF
SDIFTypesVersion | version du format des types

## Predefined Types

1 décembre 1997

### Predefined Matrix Types

Nom | Signification
--- | ---
1FQ0 | Fréquence fondamentale ou excitation d'un banc de fofs
1FOF | Forme d'Onde Formantique
1CHA | Channels
1RES | Filtre Resonnant
1DIS | Distribution d'un processus aléatoire

    1FQ0    {Frequency, Mode, Hit}
      Frequency : Fréquence fondamentale d'un banc de fofs >0. (Hz).
      Mode      : Mode d'excitation (0: Frequency, 1:Hit, 2:Both).
      Hit       : Excitation (Dirac) sur un temps précis
                  (0:pas d'excitation, 1: excitation).

    1FOF	{Frequency, Amplitude, BandWidth, Tex, DebAtt, Atten, Phase}
      Frequency : Fréquence du fof  >0. (Hz).
      Amplitude : Amplitude de l'enveloppe du fof linèaire.
      BandWidth : Largeur de bande du Fof >0. (Hz).
      Tex       : Temps d'exitation >0.  (secondes).
      DebAtt    : Instant de début de l'atténuation de l'enveloppe >0. (secondes).
      Atten     : Durée de l'atténuation >0.  (secondes).
      Phase     : Phase de la sinusoïde du fof 0. à 2pi rad.

    1CHA	{Channel1, Channel2, Channel3, Channel4}
      channelX : Amplitude linéaire sur le channel X   >0..
      Si il y a plus de 4 cannaux, il suffit d'avoir un chunk de déclaration de types
      et de faire une complétion de 1CHA :
         1MTD 1CHA {Channel5, Channel6}
      On peut ainsi ajouter autant de cannaux que l'on le souhaite.

    1RES	{Frequency, Amplitude, BandWidth, Saliance, Correction}
      Frequency  : Fréquence du filtre résonnant.
      Amplitude  : Gain du Filtre.
      BandWidth  : Largeur de bande du Filtre >0. (Hz).
      Saliance   : pourcentage d'erreur des paramètres 0.à 100.
      Correction : paramètre de correction automatique du gain par rapport
            aux autres paramètres  0. à 1.

    1DIS	{Distribution, Amplitude}
      Distribution : type de distribution
         (pas encore défini mais 0 signifie équi-répartie)
      Amplitude : variance du processus aléatoire (amplitude).
         Ce type peut-être compléter pour faire apparaître des moments
         d'ordre supérieur.

### Predefined Frame Types

Nom | Signification
--- | ---
1FOB | Bank de fofs
1REB | Bank de filtres résonnants
1NOI | Bruit

    1FOB
      {
        1FQ0  PitchModeHit;
        1FOF  Formants;
        1CHA  FormantsChannels;
      }
    PitchModeHit : excitation du fofbank. 1 seule ligne par frame 1FOB.
    Formants : paramètres des enveloppes de fof.
    FormantsChannels : amplitude de sortie des fofs sur chaque canal.
      On pourrait avoir les cannaux dans 1FOF mais la complétion du
      type ne permetterait que d'augmenter le nombre de cannaux
      et non d'ajouter des paramètres liés à l'enveloppe.

    1REB
      {
        1RES  Filters;
        1CHA  FiltersChannels;
      }
    Filters : paramamètres des filtres.
    Filterschannels :  amplitude de sortie des filtres sur chaque canal.
       Même remarque que pour fofschannels de 1FOB.

    1NOI
      {
        1DIS  NoiseInfo;
      }
    NoiseInfo : paramètres du bruit.

}

## StreamID TreeWay pour Chant

Rappel: Le champ TreeWay d'un StreamID n'a pas de définition absolue. Son interprétation dépend du champ Source qui représente le type de TreeWay qui le suit. La seule mise en forme prévue est que le TreeWay doit avoir l'allure d'une URL. <

La librairie Chant sait interpréter des StreamID dont le champ Source est 'Chant' et où le champ TreeWay suit ce formalisme:
`<PatchType>/<NumPatch>/<ObjType>/<NumObj> /<NbSubObjt>/<StartTime>/<EndTime>[/"<SoundFileName>"]`
([] signifie ici "éventuellement, Obj: Objet, Num: Numéro, Nb: Nombre").

### Description de chaque élément du TreeWay

- PatchType: C'est le type de patch prédéfini dans Chant auquel appartient l'object indexé. Les valeurs possibles sont Patch0, Patch1, Patch2, Patch3 (Janvier98).
- NumPatch: Numéro qui référence le patch parmis tous les patchs de même type. On peut ainsi contrôler plusieurs patch de type Patch0. Le premier aura NumPatch=1 et un second NumPatch=2...
- ObjType: Un patch Chant est un assemblage d'objets de types différents. ObjType représente le type de l'objet indexé. Les types reconnus sont: 'FOB', 'REB', 'NOI' et 'SND'. Les trois premiers sont aussi des signatures de types de frames prédéfinis sans version. Ainsi, il y a correspondance entre le type de l'objet déclaré dans le TreeWay et le type de frame qui permet de faire évoluer cet objet (reférencé dans l'index de l'entête de frame).
- NumObj: Dans le cas où un patch contient plusieurs objets de même type, Il est nécessaire de pouvoir référencé chacun d'eux. Ainsi, NumObj détermine à quel objet de type ObjType on s'adresse. Attention, le numéro a une signification très précise au niveau des connections. Aussi, les patchs prédéfinis sont figés, on ne peut pas avoir NumObj=3 si le patch ne contient que deux objets du type ObjType (cf. Exemple ci-dessous). Actuellement (Janvier 1998) aucun patch prédéfini de Chant ne contient plus d'1 objet de même type, donc NumObj est toujours 1.
- NbSubObj: Nombre de sous objets maximum de l'objet indexé par le StreamID. Pour un banc de FOFs, c'est typiquement le nombre de FOFs maximum du banc (de même pour les bancs de filtres). Les objets typés par 'NOI' ou 'SND' sont les bruit et les fichiers sons. Ils ne possèdent pas de sous objets. Dans ce cas NbSubObj=0.
- StartTime et EndTime: Ce sont les temps de début et de fin de l'objet.
- SoundFileName: Cet élément du TreeWay doit être dans le TreeWay uniquement pour un objet typé par 'SND'. Il contient le nom du fichier son référencé par cet objet. La seule contrainte du contenu du nom placé entre '"', est qu'il ne doit pas y avoir de caractères ';'.

### Exemple

Prenons un exemple de type de patch très général.
Chaque type d'objet de Chant y est représenté. Ce type de patch n'est qu'un exemple et n'existe pas comme type de patch prédéfini.

On remarque qu'il y a 2 bancs de filtres. Ceci va faire intervenir le numéro de l'objet (à droite des noms sur le schéma). En effet, le banc de filtre dont le numéro est 1 correspond au banc qui ne filtre que le banc de FOFs. Le banc 2 correspond à celui qui filtre tous les objets. On pourra avoir par exemple les Stream ID suivant pour remplir le patch.

    1IDS
    {
      145   Chant:PatchTypeExemple/1/FOB/1/23/0./5.;
      7     Chant:PatchTypeExemple/1/REB/1/45/0./5.;
      32    Chant:PatchTypeExemple/1/NOI/1/0/0./6.;
      12    Chant:PatchTypeExemple/1/SND/1/0/0./6./"./snd/file.sf.rs";
      122   Chant:PatchTypeExemple/1/REB/2/85/0./6.;
    }

Les NumID sont idépendants des TreeWay. Ils doivent seulement être unique. Le nombre de sous-objet, les temps de fins et de début sont aussi indépendant pour chaque objet. L'objet de NumID 7 est le banc de filtres 1 du patch. C'est donc ce lui qui ne filtre que le banc de FOFs. L'objet de NumID 122 est le banc de filtres 2 qui filtre le banc de FOFs, le bruit et le fichier son.
Avoir un TreamID supplémentaire :
`123 Chant:PatchTypeExemple/1/REB/3/85/0./6.;`
ne permet pas d'avoir un troisième banc de filtres, car un type de patch est figé.
De plus, s'il manque l'un des composants du patch, alors ce patch n'apparaitra pas à la synthèse. Un patch doit être complet pour être pris en compte dans la synthèse.

Actuellement, ces types de patch sont disponibles :

Le Stream ID SND de Patch2 contient le nom d'un fichier son à filtrer. Cependant, il n'y a ni matrice, ni frame associé à cet objet.

     Exemple de Stream ID pour un Patch1 :
      0	Chant:Patch1/1/FOB/1/4/0./1.;
      1	Chant:Patch1/1/REB/1/5/0./1.;
      2	Chant:Patch1/1/NOI/1/0/0./1.;   // un bruit n'a pas de sous objets.

    si on a un autre Patch1:
      3	Chant:Patch1/2/FOB/1/3/2./5.;
      4	Chant:Patch1/2/REB/1/8/2./5.;
      5	Chant:Patch1/2/NOI/1/0/2./5.;

    Patch2:
      6	Chant:Patch2/1/NOI/1/0/0./4.;
      7	Chant:Patch2/1/REB/1/5/0./5.;
      8	Chant:Patch2/1/SND/1/0/0./4./"filename";