Saya mencoba untuk mensimulasikan efek doppler dalam permainan (permainan balap mobil). Saya tidak menggunakan pustaka suara tertentu yang mensimulasikan efek, saya hanya memiliki fungsi panggilan balik di mana saya mencampur data.
Saya sudah menemukan cara mengubah frekuensi sampel dalam fungsi mixer.
Apa yang saya tidak tahu adalah berapa frekuensi harus berubah tergantung posisi pemain dan emitor dan kecepatan.
Inilah yang saya miliki dalam permainan:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) Menurut wikipedia , hubungan antara frekuensi yang dipancarkan dan frekuensi yang diamati diberikan oleh:
float f = (c + vr) / (c + vs) * fo
di mana c adalah konstanta, kecepatan dalam medium (biasanya dalam jumlah besar) vs dan vr adalah kecepatan sumber dan penerima relatif terhadap medium.
jadi saya kira:
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
tetapi saya pikir itu salah, itu tidak akan menghasilkan perubahan dalam frekuensi, misalnya: jika vr = 0
(pemain tidak bergerak) dan emitor memiliki kecepatan konstan, maka vr
dan vs
tidak akan berubah (sementara mereka harus).
mungkin saya harus menghitung kecepatan pemain relatif terhadap kecepatan emitor?
seperti ini :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
lalu bagaimana vr
dan vs
harus diberi makan?
2) wikipedia juga memberikan formula lain untuk mensimulasikan efek kendaraan yang dilewati oleh pengamat:
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); ?
Namun, rumus ini menganggap penerima tidak bergerak, yang tidak terjadi di sini. jika pemain dan emitor bergerak dengan kecepatan yang sama (atau perbedaan kecil), seharusnya tidak ada efek doppler. fungsi ini juga spesifik untuk satu kasus, saya kira rumus terakhir harus sama tanpa situasi.
EDIT: Saya mencoba mencari formula yang benar, menggunakan pos 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:
Bagi yang berminat, berikut adalah rumus terakhir:
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
CATATAN: ini menggunakan proyeksi vektor, dijelaskan di sini :
lalu vr,s
dan vs,r
harus disuntikkan dalam rumus wikipedia pertama:
Saya mengujinya dan berhasil, memberikan hasil yang bagus.
Jawaban:
1) Diasumsikan bahwa kedua objek bergerak pada baris yang sama - (ini dijelaskan di halaman wikipedia yang Anda tautkan) kesimpulan Anda benar, dalam situasi ini, dengan kecepatan konstan, pergeseran frekuensi konstan. Untuk perubahan frekuensi untuk berubah, kecepatan relatif perlu diubah, maka rumus 2), untuk situasi di mana
Vs
konstan tetapi tidak colinear dengan sumbu SR.Formula 2) menyesatkan:
Vr
harus dibaca sebagaiVs,r
komponen radial / relatif dari kecepatan sumber.Harap dicatat bahwa efek Doppler hanya bergantung pada kecepatan, Anda hanya perlu posisi untuk menemukan sumbu SR.
Sunting : ini akan membantu Anda mengetahui kecepatan, Anda perlu menggunakan
Vs,r
danVr,r
jumlah dengan rumus 1:sumber
Untuk XACT, ada variabel skalar pitch doppler yang harus ditentukan, yaitu kecepatan relatif, di mana 1,0 adalah kecepatan yang sama, tetapi <1,0 lebih lambat dan> 1,0 lebih cepat
Terima kasih kawan atas kodenya, yang telah saya transfer ke bagian C # ini, di mana suara dihitung antara posisi layar dan isyarat. Bekerja dengan tepat
Btw.
sumber