Gestion du son

 

 

   

Voici un petit travail que j'ai effectué et que nous allons décortiquer ensemble.

L'objectif, ici, sera de créer les éléments de bases qui permettent de faire un lecteur audio avec toutes les fonctionnalités que l'on rencontre généralement sur une platine.

---------------------------------------------------------
Ce que l'on va aborder : Les listes, la manipulation du son sous Director

---------------------------------------------------------

Avant tout, que doit on avoir sur notre platine pour qu'elle réponde aux exigences de l'utilisateur ?

On doit pouvoir mettre en lecture, metre en pause, régler le volume, passer au morceau suivant, retourner sur le morceau précédent, choisir le morceau que l'on désire écouter dans une tracklist.

---------------------------------------------------------

Pour cela, il est important de connaitre les notions de bases en lingo pour manipuler le son.

Les pistes sons :

De même que les autres média, Pour pouvoir lire un son, il est important de l'utiliser sur une piste. Ces pistes peuvent être visualisées dans la fenêtre de scénario, juste au dessus de la ligne de script.
Lorsque vous glissez un son de votre distribution jusqu'à la scène, votre média son se posera automatiquement sur l'une des deux pistes du scénario.

L'avantage des pistes :

L'avantage du principe des pistes, c'est que, de même, que pour les autres média sur votre scène, vous pouvez très bien superposer des sons pour enrichir votre ambiance sonore. Par exemple, une piste pourrait servir d'ambiance générale avec une musique en fond, et les autres pistes, elles, serviront de pistes d'effets (voix, bruitages divers...).

On a dit deux pistes... On en a pas plus ?

J'ai dis vos autres pistes alors que vous pouvez constater, sur votre scénario qu'il n'y a que deux pistes son. En effet, avec l'utilisation du scénario, vous avez accès à deux pistes seulement. Par contre, si vous gérez votre son par le biais du langage Lingo, vous pouvez manipuler jusqu'à 8 pistes simultanément. Vous en conviendrez, ca devient tout de suite plus intéressant, et les perspectives offertes deviennent bien plus avantageuses ;-) .

Comment utiliser une piste en Lingo ?

Pour l'utilisation des pistes en lingo, c'est très simple.
De même que pour les autres média, où on marquait le bout d'instruction suivante :

sprite(numSprite)


le code, pour les pistes audios sera :

sound(NumPiste)

sound correspond à la commande siginifiant la piste, et ensuite vous choisissez votre piste en 1 et 8. Celle que vous choisirez sera affiliée pour l'instruction qui suivra. Par exemple la mise en lecture...

Mais quelles sont les commandes pour la manipulation du son ?

Elles sont nombreuses et pour ce tut, nous allons nous pencher sur les 4 principales.

Play() : Cette commande permet de lancer la lecture du son sur une piste son choisie. Cette commande peut être utilisée avec différentes propriétés qui offrent des possibilités de manipulations très interessantes. Mais je ne m'étendrais pas dessus dans ce tutorial. J'y reviendrais plus profondément une prochaine fois ;-)
sound(5).play(member("Son1"))
sound (5) --> la piste 5 est utilisée pour l'instruction qui suit
play (member("son1")) --> lecture de l'acteur qui s'appelle "son1" dans votre distribution

IMPORTANT : J'en arrive à une toute petite subtilité qui ne devrez pas poser de problème si l'on comprend bien la distinction des termes :

On appelle la piste 5. Mais l'acteur, lui, comme les autres média, est un acteur. Pour l'appeler, il est important d'utiliser le mot clé member afin que Director puisse faire le tri dans tout ça. Cela signifie quoi ? Que dans la plupart des cas, la syntaxe restera semblable : piste(numpiste).action(acteur"Quel acteur"))

stop() : cette commande permet de couper la lecture d'un son sur une piste choisie
sound(5).stop()

pause() : Cette commande interrompt la lecture du son courant dans la piste audio choisie. Une prochaine commande play() entraînera la reprise de la lecture.
sound(5).pause()


Démarrons le code...

A présent, nous connaissons les bases pour lancer un son, le couper et le remettre en route. Mais un lecteur ne se borne pas à un seul morceau génaralement. Il est important de pouvoir passer à une autre track, voire de choisir dans une liste.
Pour cela, nous allons mettre en place deux variables globales. Une nous servira de liste dans laquelle nous iront puiser les sons. L'autre, quant à elle, permettra de naviguer dans notre liste grâce à une numérotation... Hummm... C'est pas très clair là ??? Passons au code alors ;-)

Ce code doit être placé dans un script d'animation (movie script) afin de fonctionner à tout moment de l'animation.

__________________________________________________
global gListe, gListe_position

on startmovie
gListe= [member ("son1"), member ("son2"), member ("son3"), member("son4"), member("son5"),\ member("son6"), member("son6"), member("son7"), member("son8"), member("son9"), member("son10")]\
gListe_position = 1
end

__________________________________________________
global gListe, gListe_position : ici nous déclarons nos deux variables globales

gListe sera notre liste dans laquelle nous déterminons nos divers sons présents dans notre distribution. Avec l'instruction suivante :
gListe= [member ("son1"), member ("son2"), member ("son3"), member("son4"), member("son5"), member("son6"), member("son6"), member("son7"), member("son8"), member("son9"), member("son10")]
nos acteurs son sont mis à la queue leu leu. Director retient cette liste, ce qui nous permettra de naviguer aisément entre les morceaux.
gListe_position va nous servir à déterminer la position du morceau choisi. Ainsi, par exemple, gListe_position correspondra à une numérotation claire pour le classement de nos sons.
gListe_position = 1 se réferrera par exemple à l'acteur "son1" dans la liste gListe.

Oui mais euuuuuuuuuh... Si j'ai 200 sons je dois tous les mettre dans ma liste ? C'est pas un peu long tout de même ???

Hum... Oui... C'est un peu long en effet. C'est pour cela qu'il est intéressant dans ce cas là, d'utiliser une petite routine qui va rescencer les acteurs sons qui se trouvent dans votre distribution et les placer automatiquement (autrement dit, comme un grand ;-) ) dans la liste gListe.

Pour ce faire, un petit code dans le même script d'animation va vous épargner bien des peines. Je supposerais, au préalable, que vous avez créé une distribution particulière, où vous avez rangé tous vos sons. :-) (on va dire que la distribution s'appelle "son". Comment ca je ne fais pas dans l'originalité ???)

__________________________________________________
global gListe, gListe_position
on startmovie
clearglobals()
sprite(5).member.text = ""
gListe = []

repeat with i = 1 to the number of members of castLib("son")

if voidP(member(i, "son")) then next repeat
if (member(i, "son").type <> #sound) then next repeat

gListe.append(member(i,("son")))
end repeat
gListe_position = 1
end

__________________________________________________

clearglobals() : à l'entrée de notre animation, toutes nos globales sont purgées pour éviter des bugs dûs aux fait que nos variables contiendraient des valeurs précédemment mises en mémoire

gListe= [ ] : On déclare notre liste qui pour l'instant, grâce à "[]" est vide
repeat with i = 1 to the number of members of castLib("son") : Ceci est une boucle qui signifie que la variable "i" va prendre succesivement les valeurs de 1 jusqu'au dernier numéro d'acteur de votre cast (comprendre que "i" correspond à une itération par morceau de musique. C'est à dire que s'il y a 200 sons, la valeur de "i" va donc de 1 à 200 par exemple). Dans le cas présent, si la position esdt vide on demande à Director de passer à l'itération suivante.

if (member(i, "son").type <> #sound) then next repeat : De même, il se pourrait très bien que l'acteur à la position "i" ne soit pas un acteur son. Sur le coup cela ne poserait pas de bug, mais par contre, lorsque l'acteur sera activé, Director va essayer de le lire comme un son. Un bug va alors se produire...

if voidP(member(i, "son")) then next repeat : Il se peut tout à fait que dans votre distribution, une des position, dans la castlib soit vide. Sans cette ligne de code, Director essaierait don d'ajouter un acteur qui n'existe pas dans la liste et provoquerait donc une erreur.

gListe.append(member(i, "son")) : On ajoute à la fin de notre liste gListe les acteurs se trouvant en position "i" dans la distribution "son". cela signifie que successivement, chacun des sons de notre distribution, en commençant par celui qui se trouve en première position, vont se faufiler dans notre liste ;-)


end repeat : On termine notre boucle


Maintenant, nous avons nos morceaux en mémoire et marqués. Il s'agit à présent d'utiliser cette liste afin de pouvoir donner son rôle à notre lecteur.


Mais comment je fais maintenant pour mettre en lecture ?

Pour cela, nous allons créer un petit script pour notre bouton lecture. Comme nous avons pu le constater, il suffit de mettre une simple ligne du type : sound(1).play(member("son1")). Mais cette simple inscription va poser un probleme. On ne pourra pas passer à la chanson suivante lorsque "son1" sera terminé. Qui plus est nous perdrons l'intérêt de notre liste. Donc il faut procéder autrement.
Nous pouvons par exemple, lancer une variable qui nous servira de lancement. Cette variable va permettre de lancer tout un processus pour générer une fonction qui controlera si le son est activé, et si la chanson se termine, passera à la suivante dans la liste gListe.

Dans le script qui sera affilié au bouton de lecture :

____________________________________________________
global gListe, gListe_position, gLance
on mouseup me
gLance = 1
sound(1).play(gListe[gListe_position])
end

____________________________________________________

Ici, nous déclarons une nouvelle variable, la variable gLance. On l'incrémente à la valeur 1. Cette valeur va prendre toute sa signifiaction dans le code suivant, celui de notre exitframe.

sound(1).play(gListe[gListe_position]) : On lance la lecture du morceau se trouvant à la position gListe_position de notre liste gListe. Concrètement, lors de la première utilisation, on lance le morceau numéro 1 de la liste

Dans notre exitframe
____________________________________________________

global gListe, gListe_position,glance

on exitFrame me
if gLance = 1 then
if sound(1).isBusy() then
nothing
else
if gListe_position< gListe.count() then
gListe_position = gListe_position + 1

sound(1).play(gListe[gListe_position])
end if
end if
end if

go to the frame

end
_____________________________________________________
if gLance = 1 then : Nous lançons une condition . Si gLance = 1 alors...
if sound(1).isBusy() then : Ici, on imbrique une deuxième condition. la commande isBusy() permet de déterminer si un son est activé sur la piste choisie (dans ce cas présent, notre piste(1)). Ainsi, lorqu'un son est activé, rien ne se passe (d'où le nothing qui suit). Par contre, la chanson terminée, nous passons à la suite de notre condition, c'est à dire le "else"

if gListe_position< gListe.count() then
gListe_position = gListe_position + 1
sound(1).play(gListe[gListe_position])
: Cette condition, elle, va déterminer si la valeur de gListe_position n'est pas supérieure aux nombres d'éléments dans notre liste. En effet, si l'on ne mettait pas cette condition en place, lorsque votre gListe_position dépasserait le nombre d'éléments de votre liste, votre variable,elle, continuerait à appeler un member... Qui n'existerait alors pas... Imaginez le calvaire pour Director ;-). Ensuite, si la condition se vérifie, gListe_position s'incrémente de 1 et lance le morceau correspondant à sa nouvelle valeur. Par là, il faut comprendre : supposons que notre variable gListe_position a la valeur 1 et s'incrémente de 1. Sa valeur devient donc 2. Ensuite, grâce à sound(numPiste).play(). La piste audio 1 lance l'acteur son qui se trouve en position 2 dans la liste.

Maintenant, votre son sera lancé lors du clic sur le bouton lecture, mais en plus de cela, les chansons vont se succéder jusqu'à ce que la liste soit épuisée.

Mais si je veux passer à la chanson suivante ?

Très simple, les bases du code sont déjà mises en place :-). Il va suffire de placer le script suivant sur le bouton correspondant :

_____________________________________________________

global gListe, gListe_position, glance
on mouseup me
if gLance = 1 then
if gListe_position<gListe.count() then
gListe_position = gListe_position +1
sound(1).play(gListe[gListe_position])
end if
end if
end

_____________________________________________________

Dans ce script on vérifie que la lecture est en route avec notre variable gLance
Ensuite on procède comme précédemment en affectant manuellement une incrémentation de + 1 à gListe_position.
Et pour faire un retour en arrière dans la liste, c'est exactement pareil si ce n'est que l'on marquera

_____________________________________________________
if gListe_position> 1 then
...
gListe_position = gListe_position -1

_____________________________________________________

Maintenant, vous pouvez zapper les morceaux qui ne vous conviennent pas. :-)

Super ! J'ai tout compris. Mais bon... Si je suis à la chanson 10 et que je veux la 89 ème...

Bien évidemment, on ne peut pas se permettre de laisser l'utilisateur perdre l'usage de son doigt à force de cliquer sur sa souris frénétiquement.Il faut donc trouver le moyen de faire une saisie dans notre liste.

Pour cela, on va commencer par déterminer les caractères autorisés, ou plutot ceux qui ne doivent pas être utisisés.

Créez un script de comportement que vous poserez sur un acteur "texte" vide.
_____________________________________________________
global gListe, gListe_position, glance,gvar
property pcaracteresAutorises


on beginsprite me
sprite (me.spritenum).editable = true
end


on keyDown me
c= the key
sprite(me.spritenum).member.text = sprite(me.spritenum).member.text & string(c)
gvar = gvar + 1

valeurTemporaire = sprite(me.spriteNum).member.text
pcaracteresAutorises = "1234567890"
if pcaracteresAutorises contains valeurTemporaire then
nothing
else

alert("Vous ne pouvez mettre que des chiffres dans ce champ!")
valeurtemporaire = void
sprite(5).member.text = ""
sound(1).stop()
glance = 0
end if
end

____________________________________________________

sprite (me.spritenum).editable = true : On rend le sprite editable par l'utilisateur
on keyDown me : lorsque une touche est enfoncée
sprite(me.spritenum).member.text = sprite(me.spritenum).member.text & string(c) : On affecte la valeur de the key dans l'acteur

On crée ensuite une variable locale "valeurTemporaire" dans laquelle nous allons mémoriser la saisie de l'utilisateur. Elle va servir de comparatif, en fait, avec ce qui ne doit pas être saisi (caracères facteurs de buggs donc... et oui, si l'on demande le morceau numero "3c" au lieu de 30 par exemple, Director va essayer pourtant de le trouver. La code va alors déraillé...)

pcaracteresAutorises = "1234567890" : Nous créons une property qui rescence les seuls caractères qui peuvent être saisis. Maintenant nous avons nos deux éléments de comparaisons...

if pcaracteresAutorises contains valeurTemporaire then
nothing
else

alert("Vous ne pouvez mettre que des chiffres dans ce champ!")
valeurtemporaire = void
sprite(5).member.text = ""
sound(1).stop()
glance = 0
end if
end

Si dans notre acteur texte, certains caractères ne sont pas présents dans la liste de "pcaractèresAutorises", un message d'avertissement apparait alors et coupe le son après avoir réinitialiser le tout.


Nous allons créer un bouton de validation à présent, celui ci va permettre de déterminer si l'utilisateur n'a pas choisi un morceau de musique qui n'est pas présent. Par exemple : s'il y a que 30 chansons, il ne pourra pas sélectionner la 32 ème...

____________________________________________________

global gListe, gListe_position, glance
property pcaracteresInterdits

on mouseup me
valeurTemporaire = sprite(5).member.text

if valeurTemporaire > gListe.count() then
sprite(5).member.text = ""
alert("La piste n'existe pas. Votre discothèque n'est pas aussi fourni")
sound(1).stop()
glance = 0

end if

if valeurTemporaire <= gListe.count() and valeurTemporaire > 0 then
gListe_position= valeurTemporaire.value
sound(1).play(gListe[gListe_position])
glance = 1
sprite(5).member.text = ""

end if
end if
end

____________________________________________________

Dans la première condition if, nous réutilisons la variable "valeurTemporaire" pour prendre la valeur numérique de saisie de l'utilisateur.

if valeurTemporaire > gListe.count() then : Si la valeur choisie est plus importante que le nombre de morceaux dans la liste, alors un message apparait et le son est coupé.

if valeurTemporaire <= gListe.count() and valeurTemporaire > 0 then : si valeurTemporaire est inférieure au nombre de la liste et est supérieure à 0 alors gListe-position va prendre la valeur de notre variable temporaire(par exemple 25) et déclenché la musique en position ayant la valeur de notre variable valeurTemporaire(le morceau 25 se déclenche alors...)

A présent, nous pouvons choisir le morceau que l'on veux dans une saisie...

 

Nous en resterons là pour l'instant avec ce tutorial. Il serait aisé de créer un bouton de volume par exemple grâce au comportement très efficace proposé par Macromédia dans la bibliothèque de script.

De même pour l'affichage du titre de la chanson, il suffit de poser un acteur texte qui prend dynamiquement le nom de notre acteur son.

Il serait possible aussi de faire en sorte que l'utilisateur puisse naviguer sur son ordinateur et choisir lui même les morceaux qu'il désire. Pour cela des Xtras comme FileXtra4 ou Buddy API seront nécessaires...

Vous l'aurez compris, cet exercice offre maintenant des perspectives de plus en plus nombreuses. Nous avons ici la structure de base.
Je poursuivrais ce tutorial dans une seconde partie ultérieurement.

Bonne journée,

Ecrit par Steve Louis

 

  Contact : Steve Louis