Kitai Délégué de la tasse bleue
Nombre de messages : 2907
Date d'inscription : 01/08/2006
| Sujet: SpatializedSpeech : spatialisation du doublage Sam 15 Juin 2013 - 15:46 | |
| Valoulef avait un problème de spatialisation du doublage et nous l'avons (plus ou moins) solutionné. Sur cette base, j'ai fait un modeste module pour automatiser tout ça. En-tête : SpaSpeech.ash- Spoiler:
- Code:
-
enum SpaSpeech_HearerType { eSpaSpeech_Player, eSpaSpeech_Character, eSpaSpeech_Object, eSpaSpeech_Point, eSpaSpeech_ScreenPoint }; struct SpaSpeech { /// Sets the hearer (the player by default). Pass -1 as MAX_DISTANCE to only play on panning. If you specify a character or an object, pass its id as X and leave y blank import static void SetHearer(int max_distance, SpaSpeech_HearerType type = eSpaSpeech_Player, int x = -1, int y = 0); import static attribute bool Enabled; import static bool get_Enabled(); // $AUTOCOMPLETEIGNORE$ import static void set_Enabled(bool enabled); // $AUTOCOMPLETEIGNORE$ }; Corps : SpaSpeech.asc- Spoiler:
- Code:
-
AudioChannel* Channel; // The channel instance on which the speech is played (0) int MaxDistance, DistX, DistY; // Distances to calculates the volumes int HearerX, HearerY; // If the hearer is a point, its coordinates Character* SpeakingChar; // The currently speaking character bool Spatialized = true; // Enables/Disables adjusting volume and panning bool NewChar; // If a new character starts to speak SpaSpeech_HearerType Hearer; // The type of the hearer (character, object or point) Character* HearerCharacter; // The hearer character Object* HearerObject; // The hearer object // Sets a new hearer (character, object or point) // // The closer the distance between the hearer and the source gets to MAX_DISTANCE, // the more the volume decreases (down to 0 when distance>=MAX_DISTANCE). // // If you only specify MAX_DISTANCE, the player character will stand as the hearer. // // If you pass eSpaSpeech_Player as TYPE, just leave X and Y blank. // If you pass eSpaSpeech_Character as TYPE, just pass the character's id as X and leave Y blank. // If you pass eSpaSpeech_Object as TYPE, pass the object's id as X and leave Y blank. // If you pass eSpaSpeech_Point as TYPE, pass the fixed room coordinates as X and Y. // If you pass eSpaSpeech_ScreenPoint as TYPE, pass the screen coordinates as X and Y. // static void SpaSpeech::SetHearer(int max_distance, SpaSpeech_HearerType type, int x, int y) { HearerObject = null; HearerCharacter = null; MaxDistance = max_distance; Hearer = type; if (type == eSpaSpeech_Player) HearerCharacter = player; else if (type == eSpaSpeech_Character) { if (x < 0 || x >= Game.CharacterCount) HearerCharacter = player; else HearerCharacter = character[x]; } else if (type == eSpaSpeech_Object) { if (x < 0 || x >= Room.ObjectCount) return; HearerObject = object[x]; } else { HearerX = x; HearerY = y; } } static bool SpaSpeech::get_Enabled() { return Spatialized; } static void SpaSpeech::set_Enabled(bool enabled) { Spatialized = enabled; } /// Returns X's absolute value float Abs(float x) { if (x < 0.0) return -1.0 * x; return x; } /// Gets the X coordinate of the hearer int GetHearerX() { if ((Hearer == eSpaSpeech_Character || Hearer = eSpaSpeech_Player) && HearerCharacter != null) return HearerCharacter.x; else if (Hearer == eSpaSpeech_Object && HearerObject != null) return HearerObject.X; else if (Hearer == eSpaSpeech_Point) return HearerX; else if (Hearer == eSpaSpeech_ScreenPoint) return HearerX+GetViewportX(); else return player.x; } /// Gets the Y coordinate of the hearer int GetHearerY() { if ((Hearer == eSpaSpeech_Character || Hearer = eSpaSpeech_Player) && HearerCharacter != null) return HearerCharacter.y; else if (Hearer == eSpaSpeech_Object && HearerObject != null) return HearerObject.Y; else if (Hearer == eSpaSpeech_Point) return HearerY; else if (Hearer == eSpaSpeech_ScreenPoint) return HearerY+GetViewportY(); else return player.y; } /// Gets the character that is currently speaking or NULL if there is no Character* GetSpeakingCharacter() { int i = 0; while (i < Game.CharacterCount) { if (character[i].Speaking) { NewChar = true; return character[i]; } i++; } return null; } /// Calculates the panning int CalculatePanning() { if (SpeakingChar == null || SpeakingChar.Room != player.Room) return 0; int dx = SpeakingChar.x-GetHearerX(), dy = SpeakingChar.y-GetHearerY(); if (dx == 0) return 0; // We make the panning in [0,100] proporitional to the ratio dY/dX float pan = 100.0/Maths.RaiseToPower(2.0, Abs(IntToFloat(dy)/IntToFloat(dx))); if (dx < 0) return -1*FloatToInt(pan); else return FloatToInt(pan); } /// Calculates the volume int CalculateVolume() { if (SpeakingChar == null || MaxDistance <= 0 || SpeakingChar.Room != player.Room) return 100; int dx = SpeakingChar.x-GetHearerX(), dy = SpeakingChar.y-GetHearerY(), // We make the volume in [0,100] proportional to MaxDistance-distance volume = 100-100*FloatToInt(Maths.Sqrt(IntToFloat(dx*dx+dy*dy)))/MaxDistance; if (volume < 0) volume = 0; return volume; } /// Instanciates the channel with the channel 0, on which the system plays speech function game_start() { Channel = System.AudioChannels[0]; } function repeatedly_execute_always() { if (Spatialized) { // If the player character has changed while eSpaSpeech_Player, update the hearer character if (Hearer == eSpaSpeech_Player && player != HearerCharacter) HearerCharacter = player; // If some speech is being played if (Channel.IsPlaying) { int panning = Channel.Panning, volume = Channel.Volume; // If we have a new speaker if (SpeakingChar == null || !SpeakingChar.Speaking) SpeakingChar = GetSpeakingCharacter(); else if (NewChar) NewChar = false; if (SpeakingChar != null) { // Calculates X and Y distances between the hearer and the source int dx = GetHearerX()-SpeakingChar.x, dy = GetHearerY()-SpeakingChar.y; // If the distance has changed, fix the volume and the panning if (NewChar || dx != DistX || dy != DistY) { panning = CalculatePanning(); volume = CalculateVolume(); DistX = dx; // Remember the DistY = dy; // new distances } Channel.Panning = panning; Channel.Volume = volume; } } // If no speech is currently playing else SpeakingChar = null; } }
function on_event(EventType event, int data) { // If the player leaves a room where an object is the hearer, make it null if (event == eEventLeaveRoom && Hearer == eSpaSpeech_Object) HearerObject = null; } Utilisation :Une fois importé, le module fonctionne automatiquement pour l'équilibrage gauche/droite. En revanche il n'ajuste pas automatiquement le volume car il ne sait pas de combien vous voulez réduire le volume selon la distance. Par défaut, c'est le personnage joueur qui est l'entendeur (l'ajustement est donc calculé selon lui). Pour définir la distance jusqu'à laquelle le personnage joueur peut se trouver de la source (donc la distance jusqu'à laquelle on entendra encore le doublage), utilisez la commande suivante (passez -1 si vous voulez uniquement jouer sur l'équilibrage) : - Code:
-
SpaSpeech.SetHearer(DISTANCE); // Remplacez DISTANCE par une valeur numérique Vous pouvez définir un nouvel entendeur : - Le joueur (automatiquement mis à jour en cas de changement de joueur) :
- Code:
-
SpaSpeech.SetHearer(-1, eSpaSpeech_Player); // Définira le joueur (quel qu'il soit) comme l'entendeur et se contentera d'équilibrer le discours - Un personnage :
- Code:
-
SpaSpeech.SetHearer(500, eSpaSpeech_Character, cRoger.ID); // Définira Roger comme l'entendeur qui entendra jusqu'à une distance de 500 - Un objet :
- Code:
-
SpaSpeech.SetHearer(300, eSpaSpeech_Object, oPotDeFleurs.ID); // Définira le pot de fleurs comme l'entendeur qui entendra jusqu'à une distance de 300 - Un point fixe dans la pièce :
- Code:
-
SpaSpeech.SetHearer(800, eSpaSpeech_Point, Room.Width/2, Room.Height/2); // "Placera le microphone" au centre de la pièce avec une portée de 800 - Un point ancré à l'écran :
- Code:
-
SpaSpeech.SetHearer(System.ScreenWidth/2, eSpaSpeech_ScreenPoint, System.ScreenWidth/2, System.ScreenHeight/2); // "Placera le microphone" au centre de l'écran en permanence avec une portée de la moitié de la largeur de l'écran (on n'entendra donc pas les doublages des personnages en dehors de l'écran horizontalement) Avertissements :- Ce module ne détecte que les personnages qui ont une vue de dialogue (Speech View)
- Rappel : la commande SayBackground ne prend pas en charge le doublage
_________________ Ga is Ga Vous pouvez consulter l' aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !
Dernière édition par Kitai le Lun 23 Déc 2013 - 1:07, édité 9 fois (Raison : mise à jour module) |
|
Billbis Disciple de la Grande Tasse Bleue
Nombre de messages : 1346
Date d'inscription : 10/05/2012
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Dim 16 Juin 2013 - 8:02 | |
| Beau boulot, Kitai. Je pense que c'est plus logique de spatialiser le son par rapport au centre de l'écran, mais comme c'est customisable, c'est nickel ! Remarque, moi comme je n'ai pas de doublage, le problème est réglé. Les noms de variables et commentaires sont en anglais. Bientôt sur le forum officiel ?
Dernière édition par Billbis le Dim 16 Juin 2013 - 10:10, édité 1 fois |
|
Kitai Délégué de la tasse bleue
Nombre de messages : 2907
Date d'inscription : 01/08/2006
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Dim 16 Juin 2013 - 8:29 | |
| - Billbis a écrit:
- Les noms de variables et commentaires sont en anglais. Bientôt sur le forum officiel ?
Pourquoi un tel smiley ? En fait j'ai toujours la flemme de poster sur le forum officiel, mais oui, en théorie je voudrais poster mes modules dessus. Mais je le fais pas C'est aussi que je donne les explications en français ici, donc si jamais je dois donner le module à quelqu'un qui parle pas français au moins il aura les instructions dans une langue qu'il comprendra peut-être. _________________ Ga is Ga Vous pouvez consulter l' aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit ! |
|
Billbis Disciple de la Grande Tasse Bleue
Nombre de messages : 1346
Date d'inscription : 10/05/2012
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Dim 16 Juin 2013 - 10:13 | |
| - Kitai a écrit:
- Pourquoi un tel smiley ?
Oups, je voulais mettre Clin d'Oeil. Me suis trompé. C'est que les smiley sont devenus tout petit depuis que tu as passé la rédaction des billets en WYSIWYG. (Enfin, c'est pas un problème, c'est juste une excuse pour faire preuve de mauvaise fois et accuser le forum plutôt que le rédacteur) |
|
Kitai Délégué de la tasse bleue
Nombre de messages : 2907
Date d'inscription : 01/08/2006
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Dim 16 Juin 2013 - 12:41 | |
| - Billbis a écrit:
- Je pense que c'est plus logique de spatialiser le son par rapport au centre de l'écran, mais comme c'est customisable, c'est nickel !
En fait tu viens de me faire remarquer que ça c'est pas directement proposé : on peut passer des coordonnées relatives à la pièce, mais pas à l'écran. Je vais ajouter cette option sous peu du coup EDIT : c'est fait, merci pour le conseil ! _________________ Ga is Ga Vous pouvez consulter l' aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit ! |
|
valoulef Délégué de la tasse bleue
Nombre de messages : 1791
Age : 35
Localisation : Condate
Date d'inscription : 01/08/2011
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Jeu 20 Juin 2013 - 11:02 | |
| Et deux modules "rien que pour moi", deux ! Dites donc vous allez bien mériter votre place (certainement en double au moins) dans les crédits de L'Affaire Aspirox ! Vu que laisser des questions non résolues semble être inenvisageable pour vous, je vais commencer par sentir une grosse responsabilité avant d'en poser une En tout cas ça m'a l'air très bien, je n'ai pas trop le temps de tester en ce moment, mais je le ferai dès que possible ! _________________ Vous êtes déjà allés à Condate ? Ils ont un petit vin qui à un goût de pierre à catapulte. C'est Toutatis en culotte de velours si j'ose m'exprimer ainsi.
|
|
Kitai Délégué de la tasse bleue
Nombre de messages : 2907
Date d'inscription : 01/08/2006
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Jeu 20 Juin 2013 - 11:13 | |
| - valoulef a écrit:
- Vu que laisser des questions non résolues semble être inenvisageable pour vous, je vais commencer par sentir une grosse responsabilité avant d'en poser une
Que veux-tu, on aime les défis _________________ Ga is Ga Vous pouvez consulter l' aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit ! |
|
Kitai Délégué de la tasse bleue
Nombre de messages : 2907
Date d'inscription : 01/08/2006
| Sujet: Re: SpatializedSpeech : spatialisation du doublage Mer 11 Déc 2013 - 13:54 | |
| Juste un nouveau message pour signaler que je suppute (eh oui) quelques problèmes avec ce module. Je n'ai pas fait les tests pour le moment, mais je pense que si on définit un objet comme entendeur puis qu'on change de pièce, on aura un problème de pointeur. Si on définit un personnage (non joueur) comme entendeur puis qu'on change de pièce, on continuera de se baser sur le personnage de l'autre pièce pour le calcul de la distance EDIT : j'ajouterai une option eSpaSpeech_Player de façon à rationaliser le comportement. Enfin, je pense que le "+1000" pour les objets est une relique que je devrais enlever. Je testerai mes dires et ajusterai le code en conséquence plus tard, mais je tenais à prévenir et voilà qui est fait.
Re-EDIT : Mise à jour effectuée. Si vous avez défini un certain personnage comme entendeur et que vous quittez la pièce où il se trouve, il n'y aura pas d'ajustement. _________________ Ga is Ga Vous pouvez consulter l' aide d'AGS 3.2 en français et contribuer à la traduction et à l'amélioration si le cœur vous en dit !
Dernière édition par Kitai le Lun 23 Déc 2013 - 1:02, édité 1 fois (Raison : Mise à jour effectuée) |
|
Contenu sponsorisé
| Sujet: Re: SpatializedSpeech : spatialisation du doublage | |
| |
|