generator_demo.gd 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. extends Node
  2. # Keep the number of samples per second to mix low, as GDScript is not super fast.
  3. var sample_hz := 22050.0
  4. var pulse_hz := 440.0
  5. var phase := 0.0
  6. # Actual playback stream, assigned in _ready().
  7. var playback: AudioStreamPlayback
  8. func _fill_buffer() -> void:
  9. var increment := pulse_hz / sample_hz
  10. var to_fill: int = playback.get_frames_available()
  11. while to_fill > 0:
  12. playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo.
  13. phase = fmod(phase + increment, 1.0)
  14. to_fill -= 1
  15. func _process(_delta: float) -> void:
  16. _fill_buffer()
  17. func _ready() -> void:
  18. # Setting mix rate is only possible before play().
  19. $Player.stream.mix_rate = sample_hz
  20. $Player.play()
  21. playback = $Player.get_stream_playback()
  22. # `_fill_buffer` must be called *after* setting `playback`,
  23. # as `fill_buffer` uses the `playback` member variable.
  24. _fill_buffer()
  25. func _on_frequency_h_slider_value_changed(value: float) -> void:
  26. %FrequencyLabel.text = "%d Hz" % value
  27. pulse_hz = value
  28. func _on_volume_h_slider_value_changed(value: float) -> void:
  29. # Use `linear_to_db()` to get a volume slider that matches perceptual human hearing.
  30. %VolumeLabel.text = "%.2f dB" % linear_to_db(value)
  31. $Player.volume_db = linear_to_db(value)