godot
godot copied to clipboard
Godot 4 - Audio clips have their beginning cut off
Godot version
v4.0.beta1.official [20d667284]
System information
Windows 10, Vulkan, NVidia RTX 2070 Super
Issue description
In Godot 4, some audio clips sound incorrect in engine for me; it sounds like the start is being cut off. I've tried both .ogg and .wav files and it happens with both, I've tried tweaking the import settings on the sound to no effect, and I've tried an identical setup in Godot 3.4.2 and the issue does not occur.
Here's a video comparing the original sound file, the sound in Godot 4, and the sound in Godot 3. You can hear that in Godot 4 the sound file sounds less "sharp" at the beginning as it does in the original file and Godot 3. Both these projects were created with no changes made to any settings.
https://user-images.githubusercontent.com/3895119/192319165-d8c13f8f-4ce7-4a0c-a10f-9e494e10ac65.mp4
Steps to reproduce
- Create a new project in Godot 4
- Import a short sound like the one I used (It's most noticeable on very short 8-bit style sounds)
- Play through the preview or through an AudioStreamPlayer and compare with the original sound file
Minimal reproduction project
Godot 4.0 beta project: Soundtest.zip
Godot 3.4.2 project: Soundtest3.zip
Update: This is still happening in Beta 8.
This may be an intentional measure to prevent audible clicks when looping sounds rapidly (which was a common issue throughout Godot 3.x).
cc @ellenhp
@Calinou Do you know where this was implemented? I looked through recent-ish audio commits and @ellenhp's recent commits but couldn't find anything that looked related.
The fade in/out logic is all in servers/audio_server.cpp
. The main mixing loop is pretty well documented but I will say that due to the way atomics are used, the structure of it is pretty fragile so large changes could have serious and unexpected stability implications. You can try tweaking some of the parameters in there though, and possibly in the associated header file. Constants should be totally fine to tweak. Please do update this bug if you find some values that work better for a wide variety of audio files. The ones that are going to be the most likely to have issues are low frequency tones, especially if they don't start at a zero-crossing.
edit: Also test play(x)
for random x
to make sure that the shorter fade-ins don't cause pops when they happen at random points in the waveform.
@ellenhp I've been playing around with some constants in audio_server.cpp
, but I'm not sure I've been looking at the correct ones (This is starting on line 357):
if (mixed_frames != buffer_size) {
// We know we have at least the size of our lookahead buffer for fade-out purposes.
float fadeout_base = 0.94;
float fadeout_coefficient = 1;
static_assert(LOOKAHEAD_BUFFER_SIZE == 64, "Update fadeout_base and comment here if you change LOOKAHEAD_BUFFER_SIZE.");
// 0.94 ^ 64 = 0.01906. There might still be a pop but it'll be way better than if we didn't do this.
for (unsigned int idx = mixed_frames; idx < buffer_size; idx++) {
fadeout_coefficient *= fadeout_base;
buf[idx] *= fadeout_coefficient;
}
AudioStreamPlaybackListNode::PlaybackState new_state;
new_state = AudioStreamPlaybackListNode::AWAITING_DELETION;
playback->state.store(new_state);
} else {
// Move the last little bit of what we just mixed into our lookahead buffer.
for (int i = 0; i < LOOKAHEAD_BUFFER_SIZE; i++) {
playback->lookahead[i] = buf[buffer_size + i];
}
}
I tried messing with fadeout_base
and fadeout_constant
, and setting them high enough does bring back an extreme pop at the end of the sample, but it doesn't get rid of the beginning of the clip being cut off. Commenting out the entirety of the multiplying the buffer by the constants also seems to do nothing.
Is there a different section of this code that handles the start of the audio clip? I tried changing LOOKAHEAD_BUFFER_SIZE
but that didn't do anything audible.
Oh weird, it looks like I never implemented proper fade-in, so the volume ramp code is what is preventing pops on fade-in. Does changing buffer size to something shorter like 128 or 64 make a difference? https://github.com/godotengine/godot/blob/master/servers/audio_server.cpp#LL1346C2-L1346C2
This is not a good workaround because it will increase CPU requirements, maybe dramatically. But it will work for diagnosing the issue.
@ellenhp It looks like reducing the buffer size does indeed fix the beginning being cut off. I tried a few different values and 160 seemed to be around the highest I could go with it sounding correct. The next highest I tried was 192 and there I noticed it being cut off.
Could you test #71780?
Looks like #71780 fixed the issue on my end!
I think i'm having this issue. Strangely it was working fine until it didn't. I now have a cut-off after each few shots on my guns. Sounds like OP's problem.
Ok i've found my issue. My game is made to work at 10 physics ticks per second to save on computing power because i can have a lot of enemies and physic stuff happening at the same time and everything works fine so far like this (The project is almost done) except now, sound. If i bring back the physics ticks to 60 the cut-off goes away. Starts getting better around 30 ticks.
Not sure how and why the audio is tied to the physics update ticks. My audio calls are made in _process function so it's not on my end.
Having this issue with Godot 4.0.2, where short audio files (mp3, wav) won't play at runtime with AudioStreamPlayer. This might be related to the beginning being cut off?
Having this issue with Godot 4.0.2, where short audio files (mp3, wav) won't play at runtime with AudioStreamPlayer. This might be related to the beginning being cut off?
Does it work with longer audio files?
Having this issue with Godot 4.0.2, where short audio files (mp3, wav) won't play at runtime with AudioStreamPlayer. This might be related to the beginning being cut off?
Does it work with longer audio files?
Good idea! :) I have tried it out and, no a longer audio file doesn't work either.
I've just tried to exchange the short audio file with a longer audio file, which works fine in different AudioStreamPlayer in another Node, and it doesn't play either. That's very strange, since I can't find any difference between the two AudioStreamPlayer instances!
I'm still experiencing this issue in 4.1.3 stable. This is a video comparing a WAV sound effect played outside of Godot with how it sounds played in-engine. The start of the sound in-engine is noticeably quieter, making it less 'punchy'.
https://github.com/godotengine/godot/assets/149937817/19be4c63-2a27-453d-9110-2c0384a6e9e7
If anyone is interested in fixing this, I suggest reading this comment first: https://github.com/godotengine/godot/pull/71780#issuecomment-1427131768
https://godotforums.org/d/37831-fix-sound-plugin-on-godot-352-when-exporting-html-5 Its what you need
Hello :) I just tested the above pull request (#87064) and it resolves the issue on my project. Here's a before and after comparison, which sounds correct to me: https://github.com/kdreese/gmtk-2022/issues/72#issuecomment-2076109920 It's worth trying out that branch for anyone else experiencing the issue, since it fixes it for me and I'd love to see it get merged :) Thanks!
Glad to hear it worked! I don't have bandwidth to contribute right now but if someone wants to pick up those changes and get them merged I would love that. This is one of those bugs that I wrote a long time ago and feel really bad about, and I'd like to see it get fixed. :)
Chiming in as someone who just realized how pervasive this issue can be. No idea truly what the ramifications of changing the single line that mitigates this issue actually are, but is the current every sound that is played fades in affecting the sound design in your game subtly but universally
behaviour more acceptable than the potential changing the audio bus of a stream while it's playing might cause a pop
behaviour? Is that an oversimplification? Would a PR with that single line change be accepted?
Attached is a video (sound on) comparing a sound with a delay long enough to avoid the fade-in (512 samples, the current best workaround I assume) to one cut precisely.
https://github.com/godotengine/godot/assets/3820082/8efb16f9-b05e-47d0-9ca5-8e250bafa32e
chiming in as well, i love godot as a engine but this has been a major roadblock for a project ive been wanting to do for a long time now i 100% agree with goki here, having every sound have a forced fade in makes dealing with sound really really difficult (or impossible) if theres something specific you are trying to achieve
this is a project ive been working on, a recreation of Undertale's text system, on the left is how it sounds now and on the right is how it is supposed to sound (using #87064)
https://github.com/godotengine/godot/assets/96512249/67f1d7c8-ca5b-4f36-89dc-b282b5a730fb