Historique: SoundFont specification SF2
Aperçu de cette version: 15
note
Cette page présentera soundfont specification SF2.
attention
Page en cours d'écriture
ardoisebleue - 12 11 2013
ardoisebleue - 12 11 2013
Table des matières
Préambule :
Ce tutoriel a été crée à partir de tests et de la traduction de la spécification soundfont SF2.(ici trouver le nouveau lien pour afficher la norme SF2 connect.creativelabs n'est plus disponible)
La norme SoundFont2 est destinée à fournir un format d'échange universel, portable et extensible pour synthétiseur à échantillon et leurs données d'articulations; Elle est portable et universelle grace à l'utilisation d'une définition précise des paramètres indépendants du matériel, ainsi que par des pratiques spécifiques conçues pour être supportées par un large éventail de technologies.
Dans ce mémo, c'est le langage de programmation C++ ( QT4 ) qui est utilisé pour illustrer les exemples.
Le fichier soundfont SF2 que j'utilise a été créé avec Swami sur un seul échantillon stéréo (un signal LA de 1 seconde), un seul intrument, et un seul preset.
Le format du fichier SF2 :
Un fichier SF2 est stocké en format RIFF (Resource Interchange File Format) qui est une structure de fichier balisé, développée pour les fichiers de ressources multimédia, il est décrit en détail dans les Référence Microsoft Windows SDK multimédia programmer.
La structure fichier balisé est intéressante car elle permet d'éviter les problèmes de compatibilité qui peuvent se produire dans les changements de définition de fichier au fil du temps, du fait que chaque élément de données dans ce fichier est identifié par une tête standard, une application qui ne reconnaît pas un de ces éléments de données peut éluder cette information inconnue.
Un fichier RIFF est construit à partir de blocs et sous-blocs stratifiés en niveaux, la lecture doit se faire séquentiellement, bloc par bloc, afin de récupérer la taille de ces blocs et de pouvoir lire les données "en paquet" d'octets ou par une structure de donnée (struct).
Principe des blocs :
Les blocs sont "balisés" par des chaines de 4 octets ( ex: snbk, INAM, ifil, LIST ... ), la spécification n'impose pas si ces caractères doivent être majuscules, minuscules ou le deux.
La valeur "taille" du bloc est écrite sur 4 octets le premier est celui de poids faible, le quatrième de poids fort, ce qui implique que le calcul de cette valeur s'effectuera après la lecture des octets de la façon suivante :
octet1 + octet2*256 + octet3*(256²) + octet4*(256³) etc...
ex : 44 F1 02 00 => 192836
Les informations concernant d'autres données techniques sont en annexe A.
Le premier bloc :
Dans ce bloc, nous récupérons le type de structure et la taille du bloc de données. Il a une taille invariable de 8 octets
Copy to clipboard
struct entete{ DWORD typestructure;// RIFF = #52494646 DWORD taillefichier; DWORD typefichier;//sfbk = #7366626b };
Ce premier bloc est commun à tous les fichier RIFF, il fournit les informations sur le fichier traiter, dans notre cas, nous avons à faire avec un fichier RIFF de type banque son. Quant à la donnée taillefichier, elle renseigne sur la taille du bloc de donnée, c'est à dire que sa valeur = (taille réelle du fichier) - 8 octets (RIFF et taillefichier).
les blocs suivants :
Ces blocs peuvent être organisés dans le RIFF dans n'importe quel ordre, puisqu'il commence toujours par des balises pour les décrire. De plus, ces blocs ne sont pas obligatoirement prèsents, ainsi que certaines de leurs données peuvent être absentes. Il est aussi possible que des blocs écrits dans le fichier ou des données ne soient pas utilisable dans le logiciel. C'est ce qui fait la souplesse et fiabilité dans le temps des fichier RIFF (sous réserve que le logiciel qui les utilise soit dotés des contrôles nécessaires).
Mais, il est plus judicieux de se conformer à une organisation "standard" lors de la création d'un fichier RIFF. Pour description qui suit, j'utilise un fichier SF2 créé avec Swami avec un seul échantillon stéréo (un signal LA de 1 seconde), un seul intrument, et un seul preset.
Le bloc de description commence toujours par la balise LIST suivie de la taille du bloc et son type ce qui permet (si le type n'est pas utilisé par le logiciel) d'aller immédiatement au bloc suivant par l'utilisation de la valeur taille_du_bloc_qui_suit.
Copy to clipboard
struct baliseLIST{ DWORD balise;// LIST DWORD taille_du_bloc_qui_suit; DWORD balise_bloc;//INFO };
Chaque donnée contenue dans une balise_bloc à une structure simple elle est composée d'un nom, d'une taille et de la valeur de la donnée.
Copy to clipboard
struct balise_donnee{ DWORD nom_de_balise;// ex: ifil -> N° de version de la norme SF2 utilisée DWORD taille_de_la_donnee;// ex: 04 00 00 00 };
ensuite la valeur de la donnée suit ces valeurs. Pour récupérer la valeur de la donnée il suffit d'utiliser "taille_de_la_donnee".
On procéde de cette façon jusqu'à la limite finale du bloc donnée par "taille_du_bloc_qui_suit". Après quoi, un nouveau bloc, commençant par une balise LIST commence.
Description des blocs et de leurs données
Les données de type chaines de caractères ASCII finissent par un ou deux octets à 0, de manière à obtenir éventuellement, la longueur de la chaine ; Donc la taille concernant ces chaines (taille_de_la_donnee) comprend les valeurs 0 finales. Les carcatères ASCII doivent être considérés comme sensible à la casse, en d'autres termes "abc" n'est pas la même chose que "ABC". Les chaines acceptées sont de 256 octets ou moins, sauf indication contraires.
Le bloc LIST : INFO
Il contient les données générales de la soundfont 11 balises de données sont actuellement définies :
| balise | type | présence | description |
|---|---|---|---|
| ifil | numérique | obligatoire | identificateur de la version de la spécification de la SoundFont. Sa taille est toujours de 4 octets et contient des données en fonction de la structure: Copy to clipboard
69 66 69 6c balise : ifil 04 00 00 00 taille du bloc ifil ( 4 ) 02 00 01 00 donnée de la version SF2 (ici 2.1) Ces valeurs doivent être utilisées par les applications qui lisent des fichiers compatibles SoundFont pour déterminer si le format du fichier est utilisable l'application. En général, elle doit accepter le fichier soit, comme utilisable (éventuellement avec une transposition appropriée), soit elle le rejetera ou avertira l'utilisateur qu'il peut y avoir des données non-traitables dans le fichier. Si cette valeur est manquante : le fichier doit être rejeté. |
| isng | chaine | obligatoire | C'est une valeur identifiant le moteur sonore pour lequel le fichier a été optimisé. Par défaut la valeur est de huit octets représentant "EMU8000" suivi par un octet nul. Cette valeur peut être utilisée par les pilotes de puce pour modifier leurs algorithmes de synthèse afin d'émuler le moteur sonore. Si cette valeur est manquante ou déficiente : le champ doit être ignoré et EMU8000 supposé. |
| INAM | chaine | obligatoire | Indique le nom de la banque de son, elle est généralement utilisé pour l'identification de la banque pour la dissocier du nom de fichier qui lui peut être modifié. Si cette valeur est manquante : le champ doit être ignoré et remplacé avec un nom par défaut valide. (l'absence du nom de banque n'empêche pas la soundfont de fonctionner). |
| IROM | chaine | option | Elle identifie une ROM de table de son particulière à laquelle les échantillons se référent.. Une donnée typique de IROM serait "1MGM" de deux octets nuls. Cette valeur est utilisée par les pilotes pour vérifier que les données en ROM et référencées par le fichier SF2 sont disponibles pour le moteur de son. Si cette valeur est manquante ou déficient : le champ doit être ignoré. Si IROM est prèsent, IVER doit être prèsent et valide. |
| VER | numérique | option | C'est une valeur de même type que ifil. Elle est utilisée par les pilotes pour vérifier que les données de la ROM référencés par le fichier sont dans la bonne version. Si cette valeur est manquante ou déficient : le champ doit être ignoré. Si IVER est prèsent, IROM doit être prèsent et valide. |
| ICRD | chaine | option | C'est une chaine optionnelle. Elle indique la date de création de la banque et sa taille possible de 256 octets, ne devrait jamais dépasser 32. Cette chaine est fournie à des fins de gestion de bibliothèque. Si cette valeur est manquante ou déficient : le champ doit être ignoré. Si le fichier est réécrit et cette valeur manquante, la date courante devrait être indiquée. |
| IENG | chaine | option | Conteient le ou les noms des sound designers ou ingénieurs responsables de la banque.Elle est fournie à des fins de gestion de bibliothèque. Si cette valeur est manquante ou déficient : le champ doit être ignoré. |
| IPRD | chaine | option | Identificateur d'un produit spécifique auquel la banque serait destinée. Ex : un champ de 8 octets représentant "SBAWE32" + un octet nul. Cette valeur est fournie à des fins de gestion de bibliothèque. Si cette valeur est manquante ou déficient : le champ doit être ignoré. |
| ICOP | chaine | option | Indique le type de licence qui règit la banque. Si cette valeur est manquante ou déficient : le champ doit être ignoré, mais la banque ne peut être considèrée comme libre de droit. |
| ICMT | chaine | option | Contient les commentaires associés à la banque. Sa taille peut être de 65.536 octets ou moins. Si cette valeur est manquante ou déficient : le champ doit être ignoré. |
| ISFT | chaine | option | Elle indique l'outil compatible SoundFont le plus récemment utilisé pour créer et modifier la banque. ex "libInstPatch v1.0.0:libInstPatch 1.0.0" : par convention, le nom de l'outil et le numéro de révision sont inclus, la première partie est l'outil de création et la deuxième celui de la modification la plus récente. Les deux chaînes sont séparées par un : . Cette chaine doit être construite par le programme de création (par exemple "libInstPatch v1.0.0:), et chaque fois qu'un outil modifie la banque, il devrait remplacer la deuxième partie par son propre nom et son numéro de révision. Cette chaine est principalement fournie à des fins de traçage d'erreur. Si cette valeur est manquante ou déficient : le champ doit être ignoré. Si le fichier est réécrit et cette valeur absente, le champs doit être créée par l'utilitaire utilisé. |
Le bloc des presets et instruments : pdta
Les données de l'articulation au sein d'un fichier compatible SF2 sont décrites dans neuf sous-blocs obligatoires. La structure a été conçue à des fins d'échange et n'est pas optimisé que ce soit pour une synthèse d'exécution ou une édition on-the-fly. Il est recommandé pour les programmes clients SF2 d'interprèter et écrire cette structure comme elle est décrite dans la spécification.
- phdr
- un enregistrement pour chaque Preset.
- un enregistrement final pour être conforme à la structure.
Copy to clipboard
struct sfPresetHeader { CHAR achPresetName[20]; // contient le nom du preset en ASCII WORD wPreset; // numéro de présélection MIDI WORD wBank; // numéro de banque MIDI qui s appliquent à cette présélection WORD wPresetBagNdx; // indice de la liste de zone du préréglage dans le sous-bloc pbag /*Les trois valeurs suivantes sont reservées pour la mise en œuvre future d une fonction de gestion de la bibliothèque de presets ellse doivent exister et être = 0 */ DWORD dwLibrary; DWORD dwGenre; DWORD dwMorphology; };
| nom | description |
|---|---|
| achPresetName | Les caractères du champ ASCII inutilisés doivent être mis à 0. Les noms prédéfinis sont sensibles à la casse. Un nom unique doit toujours être attribué à chaque préréglage dans la banque compatible SoundFont pour permettre l'identification. Toutefois, si une banque en lecture contient des presets avec noms identiques, les presets ne doivent pas être rejetés. Ils doivent être soit conservés comme lisible ou de préférence renommés avec un nom unique. Notez que les préréglages ne sont pas ordonnées au sein de la banque compatible SoundFont. Les Presets doivent disposer d'un ensemble unique de chiffres wPreset et wBank. Toutefois, si deux presets ont des valeurs identiques de wPreset et wBank, la première présélection se produisant dans le bloc PHDR est le preset actif, mais tous les autres avec des valeurs identiques wPreset et wBank seront maintenus afin qu'ils puissent être renumérotés et utilisés ultérieurement. Le cas particulier de banque General MIDI de percussion est traitée de manière classique par une valeur wBank=128. Si la valeur dans un des champs n'est pas une valeur valide de 0 à 127, ou 128 pour wBank, le préréglage ne doit pas être joué mais il doit être maintenu. |
| WpresetBagNdx | Comme la liste de la zone preset est dans le même ordre que la liste d'entête-presets, les Preset bag seront réguliers et croissants suivant l'incrémentation des entête-presets. La taille du bloc pbag en octets sera égal à 4 fois wPresetBagNdx du Preset final + 4. Si les indices de Preset bag sont irréguliers ou si le wPresetBagNdx du Preset final ne correspond pas à la taille du bloc pbag, le fichier est structurellement défectueux et doit être rejeté au moment du chargement. Tous les presets, excepté le Preset final doivent avoir au moins une zone; tout Preset sans zones doit être ignoré. |
Le dernier enregistrement sfPresetHeader ne doit jamais être accessible (ou être lu), et n'existe que pour fournir un wPresetBagNdx final permettant de terminer le nombre de zones du dernier Preset. Toutes les autres valeurs de cet enregistrement final sont mises à 0, à l'exception de achPresetName, qui peut éventuellement être "EOP" indiquant la fin des Presets.
Si le sous-bloc phdr est manquant ou contient moins de deux enregistrements, ou sa taille n'est pas un multiple de 38 octets, le fichier sera rejeté comme structurellement défectueux.
- pbag
Copy to clipboard
struct sfPresetBag { WORD wGenNdx; // indice dans la liste de zone presets des générateurs dans le sous-bloc pgen WORD wModNdx; // indice dans la liste des modulateurs dans le sous-bloc pmod. };
La première zone de donnée pour un Preset est située à l'indice wPresetBagNdx du Preset dans la zone de données pbag. Le nombre de zones de ce Preset est déterminé par la différence entre le wPresetBagNdx du Preset en cours et le wPresetBagNdx du Preset suivant.
Comme les listes de génerateurs et modulateurs sont dans le même ordre que les entête-Presets et des listes de zone, les indices wGenNdx et wModNdx seront incrémenter de façon régulière avec l'augmentation des Preset zones. La taille en octets du sous-bloc pmod = 10 fois le wModNdx du Preset final + 10, et la taille du sous-bloc pgen = 4 fois le wGenNdx du Preset final + 4.
Si les indices de Generateur ou modulateur sont irréguliers ou ne correspondent pas à la taille des sous-blocs pgne ou pmod, le fichier est structurellement défectueux et sera rejeté au moment du chargement.
Si un Preset possède plus d'une zone, la première zone peut être une zone globale. Une zone globale est déterminée par le fait que le dernier Generateur dans la liste n'est pas un instrument Generateur.
Toutes les listes de Generateurs doivent contenir au moins un Generateur à une exception près - si une zone globale existe pour lesquelles il n'y a pas de Generateurs, mais seulement des modulateurs.
Les listes modulateur peuvent contenir zéro ou plusieurs modulateurs.
Si une zone autre que la première zone ne possède pas d'instrument Generateur comme dernier Generateur, cette zone doit être ignorée.
Une zone globale sans modulateurs et aucun Generators doit être ignorée.
Si le sous-bloc pbag est manquant ou sa taille n'est pas un multiple de 4 octets, le fichier doit être rejeté comme structurellement défectueux.
- pmod
Copy to clipboard
struct sfModList { SFModulator SfModSrcOper; // valeur de l une des énumérations SFModulator SFGenerator sfModDestOper; // indique la destination du modulateur. SHORT modAmount; // valeur signée indiquant le degré auquel la source module la destination. SFModulator sfModAmtSrcOper; // valeur de l une des énumérations SFModulator SFTransform sfModTransOper; // valeur de l une des énumérations SFTransform } ;
Le Preset zone WModNdx pointe vers le premier modulateur pour cette Preset zone, et le nombre de modulateurs présents pour une Preset zone est déterminé par la différence entre la wModNdx de la Preset zone suivante et le wModNdx de la Preset zone en cours. Une différence égale à 0 indique qu'il n'y a pas de modulateurs dans cette Preset zone. Toutes les valeurs des éléments de cette structure sont de 2 octets.
- SfModSrcOper : Cette valeur indique la source de données pour le modulateur. Les valeurs inconnues ou indéfinies seront ignorées. Les Modulateurs avec sfModAmtSrcOper fixés par un «lien» qui n'aboutit pas sont ignorés.
- sfModDestOper : la destination est soit une valeur du type d'énumération SFGenerator , soit un lien vers le sfModSrcOper d'un autre bloc modulateur. Celle-ci est indiquée par le bit haut du champ sfModDestOper, les 15 autres bits désigne la valeur de l'indice du modulateur dont la source doit être la sortie du modulateur en cours par rapport au premier modulateur dans la zone instrument. Les valeurs inconnues ou indéfinies sont ignorées. Des modulateurs avec des liens qui pointent vers un indice modulateur qui dépasse le nombre total de modulateurs pour une zone donnée sont ignorées. Des modulateurs liés qui font partie de liens circulaires sont ignorés.
- modAmount : Une valeur de zéro indique qu'il n'y a pas de modulation fixée.
- sfModAmtSrcOper : Cette valeur qui indique le degré auquel la source module la destination doit être commandé par la source de modulation spécifié. les valeurs inconnues ou indéfinies sont ignorées. Des modulateurs avec sfModAmtSrcOper fixé à un «lien» sont ignorés.
- sfModTransOper : Cette valeur indique qu'une transformée du type spécifié est appliqué à la source de modulation avant l'application sur le modulateur. Les valeurs inconnues ou indéfinies sont ignorées.
Un modulateur est défini par son sfModSrcOper, son sfModDestOper, et son sfModSrcAmtOper. Tous les modulateurs dans une zone doivent disposer d'un ensemble unique de ces trois énumérateurs. Si un second modulateur est rencontré avec les trois mêmes énumérateurs comme un modulateur précédent avec la même zone, le premier modulateur sera ignoré.
Des modulateurs du sous-bloc pmod peuvent être utilisés comme modulateurs additionnels en respectant ceux du sous-bloc imod. En d'autres termes, un modulateur pmod peut augmenter ou diminuer l'action d'un modulateur de imod.
En SoundFont 2.00, aucun modulateurs n'a encore été défini, et le sous-bloc pmod sera toujours composé de 10 octets de valeur 0.
Si le sous-bloc pmod est manquant ou sa taille n'est pas multiple de 10, le fichier doit être rejeté comme structurellement défectueux.
- pgen
Copy to clipboard
typedef struct { BYTE byLo, byHi; } rangesType; typedef union { rangesType ranges; SHORT shAmount; WORD wAmount; } genAmountType; struct sfGenList { SFGenerator sfGenOper; // une des valeurs de type énumération SFGenerator genAmountType genAmount; // valeur à attribuer au Generator spécifié };
- sfGenOper
- genAmount
- Certains Générateurs spécifient une plage de numéros de clé MIDI de vélocité MIDI, avec une valeur minimum et maximum.
- D'autres Générateurs spécifient une valeur de mot non signé.
- Mais la plupart des Générateurs, spécifient une valeur WORD 16 bits signé.
Sauf si la zone est une zone globale : le dernier Générateurs de la liste est un « Instrument » Générateurs, dont la valeur est un pointeur vers l'appareil associé à cette zone.
- Si un Générateur de key range existe pour la Preset zone, il est toujours le premier générateur dans la liste pour cette Preset zone.
- Si un Générateur velocity range existe pour la Preset zone, il devra n'être précédé que par un Générateur de « key range ».
- Si des Générateurs suivent un Générateur « instrument », ils seront ignorés.
Les générateurs dans le sous-bloc pgen sont appliqués par rapport aux générateurs dans le sous-bloc igen d'une manière additionnelle. En d'autres termes : les générateurs pgen augmentent ou diminuent la valeur d'un générateur igen.
Si pgen est manquant ou sa taille n'est pas multiple de 4, le fichier doit être rejeté comme structurellement défectueux.
Si un générateur key range est présent mais pas en première position des générateurs, il doit être ignoré.
Si un générateur velocity range est présent, et, est précédé par un générateur autre que key range, il doit être ignoré.
Si une liste non globale ne s'arrête pas par un générateur « instrument », la zone doit être ignorée.
Si la valeur du générateur « instrument » est plus grande ou égale à l'instrument de cloture, le fichier doit être rejeté comme structurellement défectueux.
- inst
Copy to clipboard
struct sfInst { CHAR achInstName[20]; // contient le nom de l instrument exprimé en ASCII WORD wInstBagNdx; // indice de la liste de la zone de l instrument dans ibag };
| nom | description |
|---|---|
| achInstName | Les caractères inutilisés sont mis à 0. Les noms d'instruments sont sensibles à la casse. Un nom unique doit toujours être attribué à chaque instrument dans la banque compatible SoundFont pour permettre l'identification. Toutefois, si à la lecture d'une banque plusieurs noms identiques sont trouvés, les instruments ne doivent pas être rejetés, mais ils doivent être soit conservés comme accessible ou de préférence renommés avec un nom unique. |
| wInstBagNdx | Comme la liste des zones instrument est dans le même ordre que la liste des instruments, les indices wInstBagNdx de instrument bag sera incrémentée régulièrement avec l'accroissement de la liste des instruments. La taille du sous-bloc ibag sera de 4 octets supérieure à 4 fois la valeur du wInstBagNdx de l'enregistrement de cloture (EOI). Si les indices d'instrument sont irréguliers ou si le wInstBagNdx de l'intrument de cloture ne correspond pas à la taille du sous-bloc ibag, le fichier est structurellement défectueux et doit être rejeté au moment du chargement. Tous les instruments, excepté celui de cloture, doivent avoir au moins une zone; Chaque Preset sans zone doit être ignoré. |
L'enregistrement sfInst de cloture ne doit jamais être accessible, et n'existe que pour fournir un wInstBagNdx de fin permettant de déterminer le nombre de zones dans le dernier instrument. Toutes les autres valeurs sont par convention à 0, à l'exception de achInstName, qui devrait être "EOI" indiquant la fin des instruments.
Si le sous-bloc inst est manquant, contient moins de deux enregistrements, ou sa taille n'est pas un multiple de 22 octets, le fichier doit être rejeté comme structurellement défectueux.
Tous les appareils présents dans le sous-bloc inst sont généralement référencés par un Preset zone. Toutefois, un fichier ne contenant que des instruments «orphelins» ne doit pas être rejetée. Des applications compatibles SoundFont pouvant éventuellement ignorer ou de filtrer ces instruments orphelins en fonction des préférences de l'utilisateur.
- ibag
Copy to clipboard
struct sfInstBag { WORD wInstGenNdx; // indice de la liste de la zone instrument des générateurs de igen WORD wInstModNdx; // indice de la liste des modulateurs de imod };
La première zone, dans un instrument donné est placée à l'indice wInstBagNdx de cet instrument. Le nombre de zones de l'instrument est déterminée par la différence entre la wInstBagNdx de l'instrument suivant et le wInstBagNdx courant.
Comme les listes de générateurs et les listes de modulateurs sont dans le même ordre que les listes d'instrument et de zone, ces indices wInstBagNdx et wInstModNdx seront de incrémentiel et régulier avec l'accroissement des zones.
La taille du sous-bloc imod = 10 fois le "wModNdx" de l'instrument de cloture + 10 ; Et la taille du sous-bloc igen = 4 fois la valeur du "wGenNdx" de l'instrument de cloture + 4.
Si les indices de générateur ou modulateur sont irréguliers ou ne correspondent pas à la taille de leur igen ou imod respectifs, le fichier est structurellement défectueux et doit être rejeté au moment du chargement.
Si un instrument a plus d'une zone, la première zone peut être une zone globale. Une zone globale est déterminée par le fait que le dernier générateur de la liste n'est pas un générateur sampleID. Toutes les listes de générateurs doivent contenir au moins un générateur à une exception près - si une zone globale existe pour lesquelles il n'y a pas de générateur, mais seulement des modulateurs. Les listes modulateur peut contenir zéro ou plusieurs modulateurs.
Si dans une zone autre que la première zone manque un générateur sampleID comme dernier générateur, cette zone doit être ignorée. Une zone globale sans modulateurs et aucun générateur devrait aussi être ignorée.
Si ibag est manquant ou sa taille n'est pas multiple de 4, le fichier doit être rejeté comme structurellement défectueux.
- imod
Copy to clipboard
struct sfModList { SFModulator sfModSrcOper; // valeur du type d énumérateur SFModulator SFGenerator sfModDestOper; // indique la destination du modulateur. SHORT modAmount; // valeur signée indiquant le degré avec lequel la source module la destination SFModulator sfModAmtSrcOper; // valeur du type d énumérateur SFModulator SFTransform sfModTransOper; // valeur du type d énumérateur SFTransform };
Le WInstModNdx pointe sur le premier modulateur pour cette zone, et le nombre de modulateurs présents pour une zone est déterminée par la différence entre la wInstModNdx de la zone suivante et la wModNdx de la zone courante. Une différence de zéro indique qu'il n'y a pas de modulateurs dans cette zone. Notez que ces énumérations sont de 2 octets
| nom | description |
|---|---|
| sfModSrcOper | Cette valeur indique la source de données pour le modulateur. . Les valeurs inconnues ou indéfinies sont ignorées. Des Modulateurs avec sfModAmtSrcOper fixé à un «lien» qui n'aboutit pas sont ignorés. |
| sfModDestOper | Cette valeur est soit une valeur du type énumérateur SFGenerator, soit un «lien» vers la sfModSrcOper d'un autre bloc modulateur. Cette destination est indiquée par le bit haut du champ de sfModDestOper, les 15 autres bits désignent la valeur de l'indice du modulateur dont la source doit être la sortie du modulateur courant par rapport au premier modulateur dans la zone instrument. Les valeurs inconnues ou indéfinies sont ignorés. Des Modulateurs avec des liens qui pointent vers un indice modulateur qui dépasse le nombre total de modulateurs pour une zone donnée sont ignorées. Des Modulateurs liés par des liens circulaires sont ignorés. |
| modAmount | Une valeur de zéro indique qu'il n'y a pas de valeur fixée. |
| sfModAmtSrcOper | Cette valeur indique avec quel degré de modulation la destination doit être commandée par la source de modulation spécifiée. Les valeurs inconnues ou indéfinies sont ignorées. Des Modulateurs avec sfModAmtSrcOper fixés à un «lien» sont ignorés. |
| sfModTransOper | Cette valeur indique qu'une transformée du type spécifié est appliquée à la source de modulation avant l'application sur le modulateur. Les valeurs inconnues ou indéfinies sont ignorés. |
L'enregistrement de cloture contient par convention 0 dans tous les champs, et est toujours ignoré.
Un modulateur est défini par ses sfModSrcOper, sfModDestOper, et sfModSrcAmtOper. Tous les modulateurs dans une zone doivent disposer d'un ensemble unique de ces trois énumérateurs. Si un second modulateur est rencontré avec les trois mêmes énumérateurs comme modulateur précédent dans cette même zone, le premier modulateur sera ignoré.
Des modulateurs du sous-bloc imod sont absolus, cela signifie qu'un modulateur de imod remplace, plutôt que s'y ajouter, un modulateur par défaut. Toutefois, l'effet d'un modulateur sur un générateur est additif, à savoir la sortie d'un modulateur s'ajoute à une valeur de générateur.
En SoundFont 2.00, aucun modulateurs n'a encore été défini, et le sous-bloc imod sera toujours composé de 10 octets de valeur 0.
Si le sous-bloc imod est manquant ou sa taille n'est pas multiple de 10, le fichier doit être rejeté comme structurellement défectueux.
- igen
Copy to clipboard
structure où les types sont définis comme dans la zone pgen ci-dessus. struct sfInstGenList { SFGenerator sfGenOper; // genAmountType genAmount; // valeur à attribuer au Generator spécifiée };
Notez que genAmount peut être de trois formats. Certains Generators spécifier une plage de numéros de clé MIDI de vélocité MIDI, avec une valeur minimum et maximum. D'autres Generators spécifient une valeur de mot non signé. La plupart des Generators, cependant, spécifie une valeur 16 bits signé.
les points de zone WInstGenNdx au premier Generator de cette zone. Sauf si la zone est une zone globale, le dernier Generator de la liste est un Generator sampleID, dont la valeur est un pointeur vers le sample associé à cette zone. Si un Generator "key range" existe pour la zone, il est toujours le premier Generator dans la liste de cette zone. Si un Generator "velocity range" existe pour la zone, il ne sera précédée par un Generator de « key range ». Si des Generators suivent un Generator sampleID, ils seront ignorés.
Un Generator est défini par sa sfGenOper. Tous les Generators dans une zone doivent avoir un énumérateur de sfGenOper unique. Si un second Generator est rencontré avec le même agent énumérateur de sfGenOper comme un Generator précédent dans la même zone, le premier Generator sera ignoré.
Des Generators de la sous-chunk IGEN sont de nature absolue. Cela signifie qu'un Generator IGEN remplace, plutôt que s'ajoute à la valeur par défaut pour le Generator.
Si le sous-chunk IGEN est manquant ou sa taille n'est pas un multiple de 4 octets, le fichier doit être rejeté comme structurellement défectueux. Si un Generator de « key range » est présent et n'est pas le premier Generator, il doit être ignoré. Si un Generator de « velocity key » est présent, et est précédé par un Generator autre qu'un Generator « key range », il doit être ignorée. Si une liste non globale ne s'arrête pas à un Generator sampleID, la zone doit être ignorée. Si la valeur du Generator sampleID est supérieure ou égal à l'enregistrement de cloture sampleID, le fichier doit être rejeté comme structurellement défectueux.
- shdr
Le bloc des articulations
Le bloc LIST des échantillons : sdta
Les échantillons stockés dans la SF2 peuvent être du format 16 bits OU 24 bits, c'est le créateur de la banque qui définit le format de stockage des échantillons suivant le format des fichiers échantillonés à stocker.
Le bloc sdta contient un seul sous-bloc optionnel : SMPL. Celui-ci contient toutes les données de sons 16 bits qui seront placées dans la RAM et reliées à la banque. Sa taille est variable, et contient obligatoirement un nombre paire d'octets. Quant au sous-bloc SM24, si les données stockées sont au format 24 bits, il fait exactement la moitié de la taille du SMPL, plus 1 octet, si nécessaire pour satisfaire l'alignement sur 16 bits (bombre pair d'octets).
Si le bloc sdta est absent, soit il n'y aura pas de sons qui joués, soit la banque fera référence aux échantillons d'une ROM.
Copy to clipboard
struct bloc_sdta{ SMPL;// bloc d échantillon 16 bits SM24;// bloc d échantillons 24 bits };
Le bloc smpl :
S'il est présent, il contient un ou plusieurs «échantillons» de l'information audio numérique sous la forme d'un code linéaire seize bits, signés, little endian (octet le moins significatif en premier). Chaque échantillon est suivie d'un minimum de 46 data_points échantillons égal à 0 qui sont nécessaires pour garantir que vous pourrez faire une boucle sur des données 0 à la fin du son avec toute élévation raisonnable de tonalité en utilisant n'importe quelle interpolation raisonnable.
Le bloc sm24
S'il est présent, il contient les octets les moins significatifs homologues à chacun des data_points contenu dans le bloc SMPL. Notez que cela signifie pour chaque paire d'octets dans le SMPL il y a un complèment de 1 octet dans le SM24.
Ces points de forme d'onde de l'échantillon doivent être combinées avec les points de forme d'onde des échantillons correspondants SMPL, pour créer ensemble un seul pool de données de l'échantillon avec une résolution de 24 bits.
- Si SMPL est absent, et SM24 prèsent il doit être ignoré.
- Si la version ifil du format est inférieur à la version 2.04 la SM24 doit être ignorée.
- Si la taille du SM24 n'est pas exactement égale à la moitié de la taille du chunk SMPL (+ 1 octet dans le cas où 1/2 la taille de chunk SMPL est une valeur impaire), les deux bloc SM24 et SMPL devraient être ignorés.
- Dans tous les cas où le SM24 est ignoré, mais le SMPL accepté, le synthétiseur devrait utiliser uniquement les échantillons contenus dans le SMPL.
L'utilisation des boucles dans les échantillons :
Au sein de chaque échantillon, une ou plusieurs paires de points de boucles peuvent exister. Les emplacements de ces points sont définis dans le bloc pdta, mais dans les échantillons, les data_points doivent se conformer à certaines pratiques pour que la boucle soit compatible sur de multiples plateformes.
Les boucles sont définies par des «points équivalents» dans l'échantillon. Cela signifie qu'il y a deux data_points qui sont logiquement équivalents, et une boucle se produit lorsque ces points sont raccordées au sommet d'un autre. En théorie, le point de fin de boucle n'est jamais joué au cours du bouclage ; A la place, le point de départ de la boucle suit le point juste avant le point de fin de boucle. En raison de la nature de bande limitée de l'échantillonnage audio numérique, une boucle sans articulations montrera des données pratiquement identiques autour des points équivalents.
En réalité, à cause des divers algorithmes d'interpolation utilisés par des synthétiseurs d'échantillons, les données entourant à la fois le début de la boucle et les points d'extrémité peuvent affecter le son de la boucle. Ainsi les points à la fois le début et la fin de la boucle doivent être entourés par des données audio en continu. Par exemple : même si le son est programmé pour continuer à boucler pendant le decay, les sample data_points doivent être fournis au-delà du point de fin de boucle. Ces données seront généralement identiques aux données au début de la boucle. Un minimum de 8 points de données valides doivent être présents avant le début de la boucle et après la fin de la boucle.
Ces huit points de données (quatre de chaque côté) entourant les deux points de la boucle équivalentes doivent également être obligatoirement identiques.
En forçant les données à être identiques, tous les algorithmes d'interpolation garantissent la reproduction correcte d'une boucle sans articulations. Voir notions de boucle dans Banque SF2 avec swami pour plus de détails.
Annexe A :
Dans les exemples de codes qui suivent, tous les contrôles de validité ont été éludés pour faciliter la lecture.
Types de données utilisés dans ces exemples :
Copy to clipboard
typedef unsigned char BYTE; // 1 oct 0 à 255 typedef char CHAR; // 1 oct -128 à +127 typedef unsigned int DWORD; // 4 oct 0 à 4.294.967.295 typedef short SHORT; // 2 oct -32.768 à +32.767. typedef unsigned short WORD;// 2 oct 0 à 65.535
exemple 1 : lecture d'un bloc de fichier RIFF.
Copy to clipboard
struct enrg_de_bloc{ DWORD A,B,C;};// taille enrg : 12 octets enteteRIFF donnee; QFile fichierRIFF( "banqueson.sf2" ); fichierRIFF.open( QIODevice::ReadOnly )) int nb_octet_retourne = fichierRIFF.read( (char *) &donnee, 12 ); fichierRIFF.close();
Annexe B :
Décriptage d'un fichier SF2
| contenu (hex) | valeur | description |
|---|---|---|
| 52 49 46 46 | RIFF | valide un fichier de bloc |
| 44 f1 02 00 | taille du bloc fichier (ici 192836 ) = ( taille réelle du fichier (192844) ) - ces 8 premiers octets | |
| 73 66 62 6b | sfbk | balise : type de fichier RIFF : soundfontbank |
| 4c 49 53 54 | LIST | balise : démarre un bloc de donnée |
| da 00 00 00 | taille du bloc INFO ( ici 218 ) | |
| 49 4e 46 4f | INFO | balise : designe le bloc information de la banque |
| 69 66 69 6c | ifil | balise : N° de version de la soundfont SF2 |
| 04 00 00 00 | taille du bloc ifil ( 4 ) | |
| 02 00 01 00 | valeur | donnée de la version SF2 (ici 2.1) |
| 69 73 6e 67 | isng | balise : puce synthétiseur ciblée |
| 08 00 00 00 | taille de la chaine de caractère | |
| 45 4d 55 38 30 30 30 00 | valeur | EMU8000 ( 7 + le 0 terminal = 8) |
| 49 4e 41 4d | INAM | balise : nom de la banque son |
| 12 00 00 00 | taille de la chaine (inclu le 0 terminal s'il existe) | |
| 62 ... 32 00 00 | valeur | banque-essai-sf2 |
| 49 43 52 44 | ICRD | balise : date de création de la banque |
| 0c 00 00 00 | taille de la chaine | |
| 32 ...39 00 00 | valeur | 2013-11-09 |
| 49 45 4e 47 | IENG | |
| 0e 00 00 00 | taille de la chaine | |
| 44 ... 6e 00 | valeur | |
| 49 50 52 44 | IPRD | |
| 0e 00 00 00 | taille de la chaine | |
| 7a ... 74 00 00 | valeur | |
| 49 43 4f 50 | ICOP | |
| 0c 00 00 00 | taille de la chaine | |
| 43 ... 65 00 00 | valeur | |
| 49 43 4d 54 | ICMT | |
| 14 00 00 00 | taille de la chaine | |
| 7a ... 65 00 | valeur | |
| 49 53 46 54 | ISFT | |
| 28 00 00 00 | taille de la chaine | |
| 6c .. 30 00 00 | valeur | |
| 4c 49 53 54 | LIST | |
| c4 ee 02 00 | taille du bloc de l'échantillon | |
| 73 64 74 61 | stda | balise pour les données des échantillons |
| 73 6d 70 6c | smpl | balise pour les échantillons basés sur 16 bits |
| b8 ee 02 00 | taille de l'échantillon | |
| 4c 49 53 54 | LIST | |
| 8a 01 00 00 | taille des instruments | |
| 70 64 74 61 | pdta | |
| 70 68 64 72 | phdr | |
| 4c 00 00 00 | ||
| 50 ... 41 00 | valeur | Preset-inst-note-LA |
| 01 00 | ||
| 16 octets NUL | ||
| 45 4f 50 | EOP | end of preset |
| 20 octets NUL | ||
| 00 01 | ||
| 13 octets NUL | ||
| 70 62 61 67 | pbag | balise : |
| 08 00 00 00 | taille | |
| 00 00 00 00 01 00 00 00 | valeur | |
| 70 6d 6f 64 | pmod | balise : |
| 0a 00 00 00 | taille | |
| 00 00 00 00 00 00 00 00 00 00 |
valeur | |
| 70 67 65 6e | pgen | balise : |
| 08 00 00 00 | taille | |
| 29 00 00 00 00 00 00 00 | valeur | |
| 69 6e 73 74 | inst | balise : |
| 2c 00 00 00 | taille | |
| 49 6e 73 74 2d 6e 6f 74 |
||
| 65 2d 4c 41 00 00 00 00 |
||
| 00 00 00 00 00 00 |
valeur | |
| 45 4f 49 | end of instrument | |
| 17 octets à NUL | ||
| 02 00 | ||
| 69 62 61 67 | ibag | balise : |
| 0c 00 00 00 | taille | |
| 00 00 00 00 01 00 00 00 02 00 00 00 |
valeur | |
| 69 6d 6f 64 | imod | balise : |
| 0a 00 00 00 | taille | |
| 00 00 00 00 00 00 00 00 00 00 |
valeur | |
| 69 67 65 6e | igen | balise : |
| 0c 00 00 00 | taille | |
| 35 00 00 00 35 00 01 00 00 00 00 00 |
valeur | |
| 73 68 64 72 | shdr | balise : |
| 8a 00 00 00 | taille | |
| 4c 41 34 34 30 5f 4c | valeur | LA440_L |
| 4c 41 34 34 30 5f 52 | valeur | LA440_R |
| 45 4f 53 | end of sample |