// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package sound import ( "math" "strconv" "strings" "time" ) const positionCuePrefix = "generated-position-tone:" // PositionCueName encodes relative position: zero is first, one is last. func PositionCueName(position float64) string { return positionCuePrefix + strconv.FormatFloat(position, 'g', -1, 64) } func set_position(cue string) (float64, bool) { if !strings.HasPrefix(cue, positionCuePrefix) { return 0, false } position, err := strconv.ParseFloat(strings.TrimPrefix(cue, positionCuePrefix), 64) return position, err == nil && !math.IsNaN(position) && !math.IsInf(position, 0) && position >= 0 && position <= 1 } func position_tone_wav(position float64) []byte { // Two octaves distinguish the ends of a set. Smooth the edges of this // short cue; the service supplies the user's volume and stereo position. return tone_wav(220*math.Pow(4, position), 60*time.Millisecond, 0.5, 5*time.Millisecond) }