I'm trying to build a programmable sound generator in GD Script--Sine, Square, and Triangle Waves, that kind of thing. My goal is basically to impliment something like BFXR in Godot. I've worked on making ADSR envelopes, tremolo, vibrato, slides, random volume shimmer, and random pitch jitter. They're all "working," but they're producing unexpected noise.

Pure sine waves are okay, for instance, but the ADSR envelop produces a scraping noise when my volumes over 50%. I'm not an expert on DSP stuff, so it's hard to diagnose whether these issues or me, or Godot, which I understand still has issues with Windows drivers. Here's my basic code:

func _ready():
	$Player.stream.mix_rate = sample_rate
	playback = $Player.get_stream_playback()
	generate_wave(0.0)
	$Player.play()

func _process(delta):
var increment = pitch / sample_rate
var to_fill = min(playback.get_frames_available(), sample_rate * delta)
while to_fill > 0:
	var sample = Vector2.ONE * sin(phase * TAU)
	phase += increment
	if phase >= 1.0:
		volume_update(1 / pitch) #Update's Volume Adjustment according to master volume * ADSR envelope
		phase = fmod(phase, 1.0)
	sample *= volume_adjustment
	playback.push_frame(sample)
	to_fill -= 1

I could also provide the volume_update function for the ADSR stuff, but this is the gist of it. Any obvious ideas why this would cause noise?

Sometimes for the work I'm doing we have scratchy audio if there is too many audio streams playing that cover the same spectrum (generally happens when the audio is very similar to something already playing). I've found that reducing the volume_db in the AudioStreamPlayer can sometimes fix the issue, but I'm not sure if it would work here.

For testing, you might be able to try exporting to an audio file and seeing if it has the noise. I have not tried it myself, but this post has a code snippet that shows how to save small .wav files.

a year later