Initial commit. Implement music sync features.

This commit is contained in:
2026-01-19 22:48:17 +08:00
commit f16cf0fb96
37 changed files with 757 additions and 0 deletions

4
resource_type/chart.gd Normal file
View File

@@ -0,0 +1,4 @@
## Contains all the notes and events that make up a chart.
class_name Chart extends Resource
var notes: Array[Note]

View File

@@ -0,0 +1 @@
uid://oih6cupm4xnu

10
resource_type/music.gd Normal file
View File

@@ -0,0 +1,10 @@
class_name Music extends Resource
## Music AudioStream.
@export var stream: AudioStream = null
## Music offset in seconds.
@export var offset: float = 0.0
## BPM data to sync to the music.
@export var tempo: Tempo = Tempo.new()

View File

@@ -0,0 +1 @@
uid://rg6orh6kutai

13
resource_type/song.gd Normal file
View File

@@ -0,0 +1,13 @@
## Represents a level for a music audio that may contain multiple charts.
class_name Song extends Resource
var music: Music
var charts: Dictionary[StringName, Chart] = {}
func has_music() -> bool:
return music != null and music.stream != null
func has_chart() -> bool:
return not charts.is_empty()

View File

@@ -0,0 +1 @@
uid://jcm4r2avbciq

75
resource_type/tempo.gd Normal file
View File

@@ -0,0 +1,75 @@
## Resource for storing BPM data and loading into a SyncTrack.
class_name Tempo extends Resource
## Defines how the BPM changes throughout its length.
enum BPM_TYPE {
HOLD = 0, ## BPM stays constant through the whole length.
LINEAR = 1 ## BPM linearly interpolates to the next BPM.
}
# The data for each BPM is stored in the same index
# across the different arrays.
@export var bpms: Array[float] = []
@export var lengths: Array[float] = []
@export var types: Array[BPM_TYPE] = []
## Get the number of valid BPM changes.
func size() -> int:
return min(bpms.size(), lengths.size() + 1)
## Ensure the arrays obey the following properties:
## all arrays are the same size (every BPM has a length and type),
## last element of BPM Length Beats is -1 (since the
## corresponding BPM is assumed to last the rest of the chart).
## Extra BPM or BPM Length values are truncated.
## If BPM Types must be resized greater, assume every BPM after is
## BPM_TYPE.HOLD.
func normalize() -> void:
var target_size := size()
bpms.resize(target_size)
lengths.resize(target_size)
types.resize(target_size)
if target_size > 0:
_make_bpm_positive()
_make_lengths_positive()
lengths[-1] = -1
types[-1] = BPM_TYPE.HOLD
#----- Static Constructors -----#
static func create_from_arrays(
p_bpms: Array[float],
p_lengths: Array[float],
p_types: Array[BPM_TYPE]
) -> Tempo:
var result: Tempo = Tempo.new()
result.bpms = p_bpms
result.lengths = p_lengths
result.types = p_types
result.normalize()
return result
static func create_from_nodes(_p_nodes: Array[Variant]) -> Tempo:
var result: Tempo = Tempo.new()
# Parse array and add data to result...
# Might not be used?
return result
#----- ------------- -----#
## Makes sure every BPM entry is positive.
## Negative BPMs are inverted.
func _make_bpm_positive() -> void:
for i: int in range(bpms.size()):
bpms[i] = abs(bpms[i])
## Makes sure every length entry is positive.
## Negative lengths are inverted.
func _make_lengths_positive() -> void:
for i: int in range(lengths.size()):
lengths[i] = abs(lengths[i])

View File

@@ -0,0 +1 @@
uid://c3vwmf1f1woo3