extends Node


#var sample_hz = 44100.0 # Keep the number of samples to mix low, GDScript is not super fast.
var sample_hz = 44100.0/4 # Keep the number of samples to mix low, GDScript is not super fast.
@onready var noise = FastNoiseLite.new()

var phase_rotation = 0.0

var vol_master=20.0
var vol_overtones=0.0
var vol_overtones_sample=0
var vol_basefrequency=0.0
var vol_basefrequency_sample=0 

var playback: AudioStreamPlayback = null # Actual playback stream, assigned in _ready().

var carspeed=0 #m/s
var caraccel:float=0 #0 to 1
var increment_motorrotation=1.0/2
var offset_rotation=0



func setCarSpeed(s):
	carspeed=s
func setCarAcceleration(a,delta):
	a=min(1.0,max(a,0.0))
	var maxchange=2.0*delta
	caraccel+=min(maxchange,max(a-caraccel,-maxchange))
	
	

func _fill_buffer():
	var increment_motorrotation = carspeed*increment_motorrotation / sample_hz


	var to_fill = playback.get_frames_available()
	while to_fill > 0:
		var sample=0
		
		var maxsamplevolumechange=100/sample_hz
		vol_basefrequency_sample+=clamp(vol_basefrequency-vol_basefrequency_sample,-maxsamplevolumechange,maxsamplevolumechange)
		vol_overtones_sample+=clamp(vol_overtones-vol_overtones_sample,-maxsamplevolumechange,maxsamplevolumechange)
		
		sample+=noise.get_noise_2d(cos(phase_rotation*TAU)*0.2,sin(phase_rotation*TAU)*0.2)*vol_basefrequency_sample
		sample+=noise.get_noise_2d(cos((phase_rotation+0.1)*3*TAU)*0.5,sin(phase_rotation*1*TAU)*0.5)*vol_overtones_sample/2
		sample+=noise.get_noise_2d(cos(phase_rotation*3*TAU)*1,sin(phase_rotation*2*TAU)*1)*vol_overtones_sample
		
		
		
		playback.push_frame(Vector2.ONE * sample*vol_master) # Audio frames are stereo.
		
		
		phase_rotation = fmod(phase_rotation + increment_motorrotation, 1.0)
		
		to_fill -= 1


func _process(_delta):
	vol_basefrequency=clamp(remap(carspeed,20.0,100.0,0.0,1.0),0,1)*clamp(remap(carspeed,200.0,500.0,1.0,0.5),0,1)
	vol_basefrequency*=caraccel
	vol_overtones=clamp(remap(carspeed,20.0,100.0,0.0,1.0),0,1)*clamp(remap(carspeed,200.0,500.0,1.0,0.5),0,1)
	vol_overtones*=(0.5+caraccel*0.5)
	
	
	_fill_buffer()


func _ready():
	# Setting mix rate is only possible before play().
	$Player.stream.mix_rate = sample_hz
	$Player.play()
	playback = $Player.get_stream_playback()
	# `_fill_buffer` must be called *after* setting `playback`,
	# as `fill_buffer` uses the `playback` member variable.
	_fill_buffer()