godot icon indicating copy to clipboard operation
godot copied to clipboard

Godot 4 - Audio clips have their beginning cut off

Open FractalDiane opened this issue 2 years ago • 19 comments

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

  1. Create a new project in Godot 4
  2. Import a short sound like the one I used (It's most noticeable on very short 8-bit style sounds)
  3. 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

FractalDiane avatar Sep 26 '22 15:09 FractalDiane

Update: This is still happening in Beta 8.

FractalDiane avatar Dec 18 '22 03:12 FractalDiane

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 avatar Dec 18 '22 14:12 Calinou

@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.

FractalDiane avatar Jan 20 '23 16:01 FractalDiane

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 avatar Jan 20 '23 16:01 ellenhp

@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.

FractalDiane avatar Jan 21 '23 01:01 FractalDiane

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 avatar Jan 21 '23 02:01 ellenhp

@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.

FractalDiane avatar Jan 21 '23 02:01 FractalDiane

Could you test #71780?

ellenhp avatar Jan 21 '23 03:01 ellenhp

Looks like #71780 fixed the issue on my end!

FractalDiane avatar Jan 21 '23 03:01 FractalDiane

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.

YouveBeen avatar Apr 26 '23 17:04 YouveBeen

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.

YouveBeen avatar Apr 26 '23 18:04 YouveBeen

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?

tivtag avatar May 01 '23 17:05 tivtag

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?

YouveBeen avatar May 01 '23 17:05 YouveBeen

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!

tivtag avatar May 01 '23 17:05 tivtag

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

p3tina avatar Nov 06 '23 08:11 p3tina

If anyone is interested in fixing this, I suggest reading this comment first: https://github.com/godotengine/godot/pull/71780#issuecomment-1427131768

Calinou avatar Nov 06 '23 09:11 Calinou

https://godotforums.org/d/37831-fix-sound-plugin-on-godot-352-when-exporting-html-5 Its what you need

Lompikzozh avatar Nov 30 '23 13:11 Lompikzozh

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!

thearst3rd avatar Apr 25 '24 00:04 thearst3rd

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. :)

ellenhp avatar Apr 25 '24 06:04 ellenhp

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

gokiburikin avatar May 29 '24 14:05 gokiburikin

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

TheStarWorld avatar Jun 27 '24 21:06 TheStarWorld