J'essaie de simuler l'effet doppler dans un jeu (un jeu de course automobile). Je n'utilise pas de bibliothèque de sons spécifique qui simule l'effet, je n'ai qu'une fonction de rappel où je mixe les données.
J'ai déjà compris comment changer la fréquence d'un échantillon dans la fonction de mixage.
Ce que je ne sais pas, c'est à quel point la fréquence doit changer en fonction de la position et de la vitesse du joueur et de l'émetteur.
Voici ce que j'ai dans le jeu:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) Selon wikipedia , la relation entre la fréquence émise et la fréquence observée est donnée par:
float f = (c + vr) / (c + vs) * fo
où c est une constante, la vitesse dans le milieu (généralement un grand nombre) vs et vr sont les vitesses source et réceptrice par rapport au milieu.
donc je suppose :
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
mais je pense que c'est faux, cela ne produira aucun changement de fréquence, par exemple: si vr = 0
(le joueur ne bouge pas) et l'émetteur ont une vitesse constante, alors vr
et vs
ne changera pas (alors qu'ils le devraient).
peut-être devrais-je calculer la vitesse du joueur par rapport à la vitesse de l'émetteur?
comme ça :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
alors comment vr
et vs
devrait être nourrir?
2) wikipedia donne également une autre formule pour simuler l'effet d'un véhicule que ce véhicule passe par l'observateur:
vr = vs * cos(theta);
//theta is angle between observer and emitter
//theta = atan2(e.pos.y-p.pos.y, e.pos.x-p.pos.x); ?
cependant, cette formule suppose que le récepteur ne bouge pas, ce qui n'est pas le cas ici. si le joueur et l'émetteur se déplacent à la même vitesse (ou à une petite différence), il ne devrait pas y avoir d'effet doppler. cette fonction est également spécifique à un cas, je suppose que la formule finale devrait être la même quelle que soit la situation.
EDIT: j'essaie de trouver la bonne formule, en utilisant le post SkimFlux:
vr,r = vr.vel * cos(shortest_angle_between ( vr.vel , vs.pos - vr.pos));
vs,r = vs.vel * cos(shortest_angle_between ( vs.vel , vr.pos - vs.pos));
//is there a easier/faster way to find them out ?
//note: vr.vel and vs.vel are vectors, the green and red arrows on SkimFlux picture.
EDIT2:
Pour les intéressés, voici la formule finale:
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
REMARQUE: il utilise une projection vectorielle, décrite ici :
puis vr,s
et vs,r
devrait être injecté dans la première formule wikipedia:
Je l'ai testé et cela fonctionne avec succès, fournissant de grands résultats.
Réponses:
1) Suppose que les deux objets se déplacent sur la même ligne - (cela est expliqué dans la page wikipedia que vous avez liée) votre conclusion est correcte, dans cette situation, avec des vitesses constantes, le décalage de fréquence est constant. Pour que le décalage de fréquence change, les vitesses relatives doivent changer, d'où la formule 2), pour la situation où
Vs
est constante mais non colinéaire avec l'axe SR.La formule 2) est cependant trompeuse:
Vr
doit être lue commeVs,r
, c'est-à-dire la composante radiale / relative de la vitesse de la source.Veuillez noter que l'effet Doppler dépend uniquement des vitesses, vous n'avez besoin que des positions pour trouver l'axe SR.
Edit : cela devrait vous aider à comprendre les vitesses, vous devez utiliser les quantités
Vs,r
etVr,r
avec la formule 1:la source
Pour XACT, il y a la variable scalaire de hauteur Doppler à spécifier, c'est-à-dire la vitesse relative, où 1.0 est la même vitesse, mais <1.0 est plus lent et> 1.0 est plus rapide
Merci les gars pour le code que j'ai transféré sur ce morceau de C #, où un son est calculé entre la position de l'écran et un signal. Fonctionne avec précision
Btw.
la source