Hi, I am trying to learn Godot, so I decided to attempt to play my own sound waves. However, the resources Godot has for this aren't very well documented on how exactly this is supposed to be done. There's a demo on Godot, including a script that generates a pure tone.
However, I am really confused by how this all works. It seems like this script just generates a portion of the sine wave every frame or something through the Process function, but there's also a buffer size that seems like it would be limited. I tried to change this fill_buffer function to play a triangle wave instead, but I got these weird frequencies that didn't match up with the pulse_hz value. And what is meant by "frames" here? The function is called "get_frames_available", but it also kind of seems like "frame" from Godot's perspective might just mean audio samples. So which is it?
All I am trying to do is to play my own array of values. So I tried a million different modifications to this script, in attempt to set the data of a new AudioStreamSample, and feed that sample to the Player, before finally calling play() on that. Here is the modified code:
extends Node2D
export var sample_hz = 22050 # Keep the number of samples to mix low, GDScript is not super fast.
export var pulse_hz = 440
export var phase = 0.0
export var curve : Curve
var c := AudioStreamSample.new()
var playback:= AudioStreamPlayback.new() # Actual playback stream, assigned in _ready().
func _process(_delta):
pass
func _fill_buffer():
var s : float = sample_hz
var p : float = pulse_hz
var increment = p / s
var r = (1/p) * s
var i = 0
var array := PoolByteArray()
while i < r:
array.append(pong(i/r))
i += 1
print(i)
c.data = array
print(array)
c.loop_mode = AudioStreamSample.LOOP_FORWARD
c.mix_rate = sample_hz
$Player.get
$Player.stream = c
func pong (var d):
var r = d
if (d > 0.25):
r = 0.5 - d
if (d > 0.75):
r = -1 + d
return (r * 512 - 128)
func _ready():
$Player.stream.mix_rate = sample_hz # Setting mix rate is only possible before play().
playback = $Player.get_stream_playback()
_fill_buffer() # Prefill, do before play() to avoid delay.
$Player.play()
Clearly there is something I am not understanding about this. I just want to execute this once and have it continue to loop a triangle waveform on its own.