« Wwise est un gros tableur ». C'est une phrase que nous entendons souvent en tant que membres de l'Équipe Expérience Utilisateur. La vérité est que, bien que Wwise soit un outil de conception sonore, sous le capot, un projet Wwise, ça reste des données. Beaucoup de données. La réalité d'aujourd'hui est que les jeux sont énormes et qu'il vaut mieux avoir le contrôle de ses données si l'on veut éviter les problèmes.
Heureusement, Wwise offre des outils pour manipuler facilement de grandes quantités de données, comme la List View, le Multi Editor, le Batch Rename et le Query Editor.
Il existe également de nombreuses techniques et bonnes pratiques à avoir pour améliorer l'organisation à l'intérieur d'un projet Wwise, et ainsi faciliter la manipulation de grandes quantités de données. Par exemple, la création de Work Units, l'utilisation d'une nomenclature fiable, l'importation en groupe de fichiers audio depuis des tableurs, l'utilisation de propriétés personnalisées, l'utilisation du Batch Renamer, l'attribution de couleurs, etc.
Vous disposez également de la fonction Search et du Query Editor pour vous aider à vous y retrouver dans vos données. Mais ces outils ont leurs limites. Que faire si vous voulez savoir quels Random Containers de votre projet contiennent un son en boucle ? Quelles sont les sources audio auxquelles un Event fait référence ?
Il y a quelques années, nous avons développé WAAPI, une API de programmation qui donne la possibilité aux programmeurs d'automatiser, de manipuler et d'interroger le projet Wwise. Mais WAAPI nécessite l'utilisation d'un langage de programmation. Cette option reste principalement dans les mains des programmeurs, et elle est difficilement accessible au reste des utilisateurs de Wwise. De plus, la mise en place d'un script WAAPI nécessite un certain temps d'installation.
Voici un exemple de WAAPI, écrit en Python, qui imprime tous les fichiers convertis auxquels un Event fait référence. Ce n'est pas particulièrement facile à lire.
from waapi import WaapiClient
import pprint
# Connect (default URL)
client = WaapiClient()
# Return all targets
args = {
"from": {"path": ['\\Events\\Default Work Unit\\Play']},
"transform": [
{"select": ['children']}
]
}
options = {
"return": ['@Target']
}
result = client.call("ak.wwise.core.object.get", args, options=options)
pprint.pprint(result)
# Return all wem files from targets
args = {
"from": {"id": list(map(lambda x: x['@Target']['id'], result['return']))},
"transform": [
{"select": ['descendants']},
{"where": ['type:isIn', ['AudioFileSource']]}
]
}
options = {
"return": ['name', 'id','sound:convertedWemFilePath']
}
result = client.call("ak.wwise.core.object.get", args, options=options)
pprint.pprint(result)
# Disconnect
client.disconnect()
Introduction à WAQL
Wwise 2021.1 inclut la nouvelle fonctionnalité WAQL. Il s'agit du Wwise Authoring Query Language et se prononce wa-keul. Si vous êtes un utilisateur de JIRA, vous connaissez peut-être le langage JIRA Query Language (JQL) qui permet d'interroger la base de données JIRA. Les programmeurs parmi vous connaissent peut-être C# LINQ ou SQL. Le langage WAQL est un peu semblable. Il permet d'interroger le projet Wwise à travers son système de gestion de données. En réalité, il interroge les objets Wwise et leurs propriétés.
WAQL est la prochaine étape pour vous offrir plus de contrôle sur les données de votre projet. Il s'agit toujours d'un nouveau langage à apprendre, mais sa difficulté est bien moindre face à l'apprentissage d'un langage de programmation complet comme Python, Javascript ou C#. Et, ce qui est plus important encore, il est immédiatement accessible après l'installation du logiciel Wwise Authoring. Le but de cet article est de vous aider à comprendre les bases de WAQL. Nous vous recommandons en fait de l'essayer par vous-même dans votre projet Wwise pendant que vous lisez cet article. Celui-ci se présente comme un tutoriel et une introduction à WAQL.
OK, commençons par quelque chose de simple. Trouvons tous les objets de votre projet dont le volume est inférieur à zéro. Pour cela, commencez par ouvrir la List View, et écrivez : $ where volume < 0.
Un instant ! Essayons de comprendre ce qui se passe. Tout d'abord, lorsque vous écrivez quelque chose dans la barre de recherche de la List View, celle-ci exécute normalement une recherche textuelle sur l'ensemble du projet ; mais maintenant, puisque nous avons commencé par taper un $, cela indique à Wwise que nous sommes sur le point de lancer une requête WAQL au lieu d'une simple recherche.
Ensuite, le mot-clé where indique que nous sommes sur le point d'écrire une instruction conditionnelle. Par défaut, lorsqu'on lance une requête avec un where, la condition sera exécutée sur tous les objets du projet. Enfin, nous écrivons l'instruction conditionnelle. Dans ce cas, nous demandons de comparer le volume, soit une propriété d'un objet Wwise, avec un nombre : zéro. La condition va filtrer les objets pour lesquels le volume n'est pas inférieur à zéro.
Objets et propriétés de Wwise
Ceci nous amène à un autre sujet : Les objets et les propriétés de Wwise. Les objets Wwise sont essentiellement tous les éléments que l'on retrouve dans le Project Explorer, en plus de quelques autres objets qui sont cachés ou visibles dans différents systèmes. Les propriétés sont définies à l'intérieur des objets et elles stockent des valeurs.
Il existe de nombreuses propriétés dans Wwise. Par exemple, voici les propriétés que l'on trouve dans l'onglet General Settings du Property Editor lorsqu'un objet Sound est sélectionné :
Les propriétés peuvent stocker l'un des éléments suivants :
- Une valeur (nombre entier, nombre réel, booléen, chaîne de caractères). Ex : Volume
- Une référence à un autre objet du projet. Ex : OutputBus. Effect0
- Un objet local, connu sous le nom de « Custom ». Ex : Effect0
Une liste exhaustive de toutes les propriétés pour tous les objets Wwise est disponible ici.
De plus, il existe des propriétés de base que l'on retrouve sur la plupart des objets. Par exemple, les propriétés « name », « notes », « path » et « id » sont des propriétés de base accessibles sur n'importe quel objet Wwise, tandis que les propriétés « volume » et « outputbus » se trouvent seulement sur certains types d'objets. Les propriétés de base sont parfois calculées, parfois stockées avec l'objet. Dans tous les cas, les noms de propriétés dans WAQL ne sont pas sensibles à la casse.
Plus d'informations sur les propriétés de base disponibles ici.
Commencer avec des conditions
Comme nous l'avons vu plus haut, l'instruction where permet de définir une condition. La condition sera évaluée sur chaque objet inclus dans l'instruction where . Les conditions sont définies par une expression booléenne, c'est-à-dire une déclaration qui peut être soit vraie, soit fausse.
Voici quelques exemples :
- $ where pitch = 1200
- $ where volume > -10 and volume < 0
- $ where IsLoopingEnabled or IsStreamingEnabled
- $ where (volume >= 0 and (lowpass > 0 or highpass > 0))
Essayez maintenant d'expérimenter d'autres scénarios en utilisant les conditions where.
Nous pouvons également rechercher et comparer du texte avec WAQL en utilisant l'un des trois opérateurs de comparaison de chaînes de caractères :
- $ where name = "Hello"
Le symbole égal est utilisé pour effectuer une comparaison insensible à la casse de la chaîne de caractères entière avec une autre chaîne de caractères, et retourne la valeur True lorsque les chaînes de caractères sont exactement les mêmes. - $ where notes : "hell"
Les deux points sont utilisés pour trouver le début d'un mot dans une chaîne de caractères. Il n'est pas sensible à la casse. Il retourne la valeur True si le mot a été trouvé dans une chaîne de caractères. - $ where outputbus = /^Music\d+$/
L'opérateur égal peut aussi être utilisé avec une expression standardisée (style ECMAScript).
Combiner les objets et les propriétés
Il existe deux types de propriétés sur les objets Wwise :
Les propriétés retournant une valeur :
- volume, pitch, lowpass, etc : Communément associées à un slider dans Wwise, elles stockent une valeur numérique. Elles peuvent varier selon le type d'objet. Par exemple, les Random Containers et les objets Sound n'ont pas tout à fait les mêmes propriétés.
- name, notes, id, path : Éléments fondamentaux du système d'objets de Wwise, ils stockent souvent une valeur de chaîne de caractères. On les trouve sur tous les types d'objet Wwise.
Les propriétés retournant un autre objet Wwise (également appelées références) :
- outputbus, target, userauxsend0, effect0 : Ces propriétés pointent vers un autre objet et varient en fonction du type d'objet. Par exemple, les Event et les objets Sound n'ont pas les mêmes propriétés.
- parent : Pointe vers l'objet parent.
Il est possible de combiner des objets et des valeurs en utilisant le caractère point. Par exemple :
- $ where parent.name = "Music"
Le nom du parent est « Musique ». - $ where parent.parent.name = "Music"
Le nom du grand-parent est « Music ». - $ where parent.volume < 0
Le volume du parent est inférieur à zéro. - $ where outputbus.parent.name = "Master Audio Bus"
Le nom du parent du bus de sortie est « Master Audio Bus ». - $ where effect0.pluginname = "Wwise Compressor"
Le nom du plug-in de l'effet situé dans l'emplacement 0 est « Wwise Compressor ».
Partir d'une source différente
Jusqu'à présent, nous avons filtré les objets de l'ensemble du projet. Cependant, dans certains cas, nous pouvons souhaiter concentrer notre recherche sur un groupe d'objets plus restreint. WAQL vous permet également de définir la source de la requête telle que :
- Tous les objets des types spécifiés
- Un ou plusieurs objets spécifiques du projet
- Le résultat d'un objet de requête hérité (Query Editor)
- Le résultat d'une requête de recherche textuelle
Voici quelques exemples à essayer :
- $ from type sound
- $ from type audiofilesource
- $ from type randomsequencecontainer, switchcontainer, blendcontainer
Spécifier le type en utilisant directement l'instruction from est un moyen très efficace de restreindre une recherche. WAQL limitera l'itération de recherche à la source spécifiée. La dernière requête pourrait également contenir un filtre de recherche utilisant le mot-clé where. Cependant, le processus de filtrage devra passer par tous les objets du projet, y compris les événements, les bus, les sons, etc. Le temps d'exécution sera donc plus long :
- $ where type = "randomsequencecontainer" or type = "switchcontainer" or type = "blendcontainer"
Vous pouvez essayer avec d'autres types d'objets. Pour plus d'informations sur les types d'objets, consultez cette page.
Il peut aussi être très pratique de partir d'un seul objet :
- $ from object "\Actor-Mixer Hierarchy\Default Work Unit"
- $ from object "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
- $ from object "Event:Play_Footstep_01"7
La requête précédente peut également être écrite sous une forme plus courte, en omettant l'instruction from object :
- $ "\Actor-Mixer Hierarchy\Default Work Unit"
- $ "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
- $ "Event:Play_Footstep_01"
Et nous pouvons également spécifier plusieurs objets :
- $ "\Actor-Mixer Hierarchy", "\Interactive Music Hierarchy"
- $ "{DE2B0843-131F-4E52-BC71-23C43A5324AB}", "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
- $ "Event:Play_Footstep_01", "Event:Play_Footstep_02", "Event:Play_Footstep_03"
Voici d'autres exemples de requêtes avec différentes sources comme point de départ :
- $ from search "foot walk"
- $ from search "hello" where type = "sound"
- $ from query "\Queries\Factory Queries\Audio Source\Audio Source - Format = Vorbis"
Sélectionner des objets
Jusqu'à présent, nous avons appris à spécifier la source d'une requête WAQL avec le mot-clé from, et nous avons appris à filtrer une requête WAQL avec le mot-clé where. Voyons maintenant comment modifier davantage les résultats obtenus avec le mot-clé select.
Sélectionner des objets vous permet d'obtenir d'autres objets à partir de la séquence initiale d'objets. Gardez toujours à l'esprit que chaque partie d'une requête WAQL alimente la suivante.
Tapez la requête suivante dans la List View :
- $ from object "\Actor-Mixer Hierarchy\Default Work Unit" select children
Cette requête prend la Default Work Unit et retourne tous les enfants directs de celle-ci. Cette requête comporte deux parties : l'instruction from et l'instruction select. L'instruction from définit le début de la requête, ou la source. L'instruction select est exécutée sur chaque objet provenant de la source.
Voici d'autres requêtes sélectionnant différents éléments dans la hiérarchie d'objets :
- $ "\Actor-Mixer Hierarchy\Default Work Unit" select descendants
Retourne tous les enfants de manière récursive. - $ "\Actor-Mixer Hierarchy\Default Work Unit" select parent
Retourne le parent direct.
$ "\Actor-Mixer Hierarchy\Default Work Unit" select parent.parent
Retourne le grand-parent direct. - $ "\Actor-Mixer Hierarchy\Default Work Unit" select ancestors
Retourne tous les parents de manière récursive. - $ "\Actor-Mixer Hierarchy\Default Work Unit" select parent, children
Retourne le parent combiné aux enfants. - $ "\Actor-Mixer Hierarchy\Default Work Unit" select this, parent, children
Retourne la Default Work Unit elle-même, son parent combiné à ses enfants. - $ from type sound select parent
Retourne tous les parents de tous les sons.
Non seulement vous pouvez naviguer dans les enfants et les parents de la hiérarchie avec le mot-clé select, mais vous pouvez également sélectionner des objets à partir des propriétés :
- $ from type sound select effect0
Retourne tous les effets à l'index 0 trouvés pour tous les objets son. - $ from type sound select effect0, effect1, effect2, effect3
Retourne tous les effets trouvés pour tous les objets son. - $ from type sound select outputbus
Retourne tous les bus trouvés sur l'Output Bus pour tous les objets son. - $ from type sound select outputbus.parent
Retourne les parents des bus trouvés au niveau de l'Output Bus pour tous les objets sonores.
Exercices supplémentaires :
- Essayez d'ajouter une instruction where après une instruction select
- Essayez d'insérer une instruction where avant une instruction select
- Essayez l'instruction select referencesto
Analyse d'une requête complexe
Prenons la requête suivante, qui énumère tous les objets Sound référencés par un Event. La requête comporte cinq instructions enchaînées les unes aux autres :
- $ from type event select children select target select this, descendants where type = "sound"
Voici chaque partie de la requête :
- $ from type event
Cette instruction commence par énumérer tous les Event du projet - $ from type event select children
Ensuite, celle-ci permet d'obtenir les actions des Event (enfants directs) à partir des objets Event. - $ from type event select children select target
Ensutie, celle-ci permet d'obtenir les cibles (référence nommée « target ») pour chaque action. - $ from type event select children select target select this, descendants
Ensuite, celle-ci sélectionne les cibles elles-mêmes (en utilisant le mot clé « this ») et leurs descendants. - $ from type event select children select target select this, descendants where type = "sound"
Pour finir, cette dernière instruction permet de ne garder que les objets sonores.
Et ensuite ?
Ceci n'est que la partie émergée de l'iceberg. Nous n'en sommes qu'à la version 1 du langage WAQL, et vous pouvez vous attendre à ce qu'il y en ait encore plus à l'avenir. Il y a déjà plus de 450 propriétés différentes auxquelles vous pouvez accéder et que vous pouvez interroger à travers plus de 60 types d'objets différents. Vous pouvez combiner autant d'instructions que vous le souhaitez, dans n'importe quel ordre — les possibilités sont aujourd'hui déjà infinies. Il existe également d'autres mots-clés que nous n'avons pas mentionnés dans cet article.
La List View est un bon endroit pour s'entraîner à utiliser le langage WAQL. Vous pouvez également utiliser le Query Editor pour sauvegarder vos requêtes WAQL dans votre projet.
Pour en savoir plus sur le langage WAQL et tout ce qu'il supporte, vous pouvez consulter la documentation.
Si vous êtes un utilisateur de WAAPI, vous pouvez également utiliser le WAQL directement dans la fonction ak.wwise.core.object.get. Cela vous rendra la vie bien plus facile.
Dites-nous ce que vous avez réussi à faire avec le langage WAQL !
Commentaires