New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sound: Various issues under Windows #65
Comments
Hi! You locking mutex for 5 seconds and mixer thread just does not have enough time to mix everything and send data to sound device. Here is your loop: loop {
println!("Looping");
let mut context = context.lock().unwrap();
let source = context.source_mut(source_handle);
source.play();
// This introduces audio artifacts after a while.
// Use `from_secs(5)` and these go away for me.
thread::sleep(Duration::from_millis(5000));
} and here is correct version: loop {
println!("Looping");
// This scope ensures that mutex will be released before calling thread::sleep.
// Alternatively you can std::mem::drop(context) after source.play(); which will
// also release the lock.
{
let mut context = context.lock().unwrap();
let source = context.source_mut(source_handle);
source.play();
}
// This introduces audio artifacts after a while.
// Use `from_secs(5)` and these go away for me.
thread::sleep(Duration::from_millis(5000));
} So, general rule is to lock mutex as short time as possible, otherwise mixer thread will just wait and sound will be incorrect. |
Oh, duh. Sorry for the silly mistake. Now, with this code, I'm able to trigger the odd delays. I would expect this footstep sound to play rhythmically. But, on my system, it doesn't. There are odd delays every few footsteps, and the pattern doesn't repeat. To be clear, I don't expect it to cleanly loop. I just expect it to sound rhythmic, but instead it is more staggered. Not sure if Am I doing something wrong here as well? Thanks.
|
Here is the picture that should clarify what is going on under the hood: So there are two threads - one is user thread, and second is mixer thread. Mixer thread mix samples into audio buffer and sends data to output device, the time that send procedure could take is undefined, it depends on the driver, OS, and other stuff. So perfect looping could be achived only by setting |
Sorry, I'm blind and can't see the picture.
But to be clear, I'm not interested in looping a sound. If someone is
running, for instance, there would be less time between their individual
footsteps, and you wouldn't want a previous footstep overlapping the
next one, nor would you want the previous one playing where they were.
What is the correct way to handle that with your engine? Should I be
creating a new footstep sound and stopping the previous one? I'd hoped
to just reuse the source, move it and restart it.
Thanks.
|
Oh, sorry. What I'm doing in my shooter is that I'm creating new source per footstep. Also the engine can automatically handle lifetime of a source for such temporary sound sources. So you need to create a source with Other way of implementing this is to use multiple sources with different buffers - each buffer should have slightly different version of footstep to sound more naturally. In this case you should stop currently playing source, and then play a random one. I'm not a sound designer and don't know all the tricks that will result in natural sound, just relying on what I hear. |
Got it, so seems this is working as designed. Any chance you might eventually support more responsive stopping/restarting of sources? Or should this be closed? Having to create new sources vs. controlling an existing one would seem to make some types of problems more difficult. It's also a bit more verbose, since instead of just reusing this footstep source, I'd have to create a new one each time. Thanks for your help. |
I can't imagine a situation in game where such precision is needed, in case of footsteps small variation is good actually, in other cases such small delay is ok too for me 🤔 . |
I think you're technically right in that the footstep delay isn't bad
from an aesthetic perspective, as it makes them sound more natural. But
I think those should be designed in, rather than done that way by necessity.
Anyhow, thanks for your work on this project. I respect that it meets
your needs, so I'll let you decide whether or not to close this. I also
appreciate the quick help!
|
Not sure how to title this issue, and I'm not sure if my use of Windows is relevant. I've been trying to use rg3d-sound in Bevy, and have hit an odd issue where my footstep sound is slightly delayed every few seconds. I also, very occasionally, get an issue where sound glitches and can be heard panned slightly differently in the stereo field, as if the source parameters aren't quite synced.
I thought I'd try creating a reproduction, which I have here. But while I can't reproduce the delay, I've found a few issues that may be related.
Essentially, I took your play_sound example, subbed in my footstep sound, and added a
loop { ... }
block. I need to start/stop my footstep sound more or less quickly based on step length, so I need to control the looping. Here's what I discovered:println!
at the beginning. The print is called correctly, but the sound still seems to loop quickly despite me explicitly setting it not to.from_millis(5000)
for the sleep, the behavior changes. After 20-30 seconds, I start getting audio artifacts similar to the ones I occasionally experience, where the source sounds slightly out of sync.It's quite possible that I'm misusing the library here, but it seems like it's misbehaving in ways that don't make sense. I don't understand why the source doesn't play once per 5 seconds, nor do I understand the odd audio artifacts here. I might expect performance degradation at higher speeds as the mutex deadlocks, but not at 1/5 seconds.
Am I doing something obviously wrong? Full disclosure: haven't had my coffee yet. :)
Thanks!
The text was updated successfully, but these errors were encountered: