🔊

Godot上でサイン波を生成する。

2024/11/13に公開

何年も前に一度調べて書いたのにすっかり忘れてたのでまとめ直す。

AudioStreamGenerator — Godotエンジン (安定版) ドキュメント (英語)

このサンプルで注意なのが、関連してるノードから書かないとダメ。
つまり、ノードを作って、そこから子ノードでAudioStreamPlayerを作って、
最初に作ったノードにスクリプトをアタッチさせる、という感じ。

あとこのサンプルをさらに改造して、サイン波がずっと鳴るようにした。

extends Node

## 1秒あたりのバッファ数を取得する
@onready var sample_hz = $AudioStreamPlayer.stream.mix_rate

## サイン波の周波数(基準周波数)
var pulse_hz = 440.0 # The frequency of the sound wave.

## ここに書き込み可能なバッファがたまる。
var playback # Will hold the AudioStreamGeneratorPlayback.

## 位相。サイン波を生成した際に途切れないように波の生成タイミングを保存しておく
var phase =0.0

## 準備関数
func _ready():
    ## AudioStreamPlayerとしては常に鳴らしておく
    $AudioStreamPlayer.play()
    ## バッファを取得する。
    playback = $AudioStreamPlayer.get_stream_playback()
    # fill_buffer()

## ループ処理関数
func _process(delta):
    fill_buffer()

## バッファを埋める関数
func fill_buffer():
    ## 位相の変化差分を求める
    var increment = pulse_hz / sample_hz
    
    ## 書き込み可能なストリームのバッファサイズを取得する
    var frames_available = playback.get_frames_available()

    ## バッファに対しサイン波の書き込みを行う処理
    for i in range(frames_available):
        ## 1バイトずつサイン波を書き込みする
        playback.push_frame(Vector2.ONE * sin(phase * TAU))        
        ## 位相を変化させる
        phase = fmod(phase + increment, 1.0)

Discussion