[+] Speed control

This commit is contained in:
2025-11-23 13:50:48 +08:00
parent 53a4d6428e
commit 656c81b82e
3 changed files with 21 additions and 2 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ Practice Japanese Karaoke lyrics reading and typing at the same time with KaraDa
* [x] 跟随音乐滚动歌词
* [ ] 升降调
* [ ] 播放/暂停音乐控制
* [ ] 变速
* [x] 变速
* [ ] 音域分析(自动推荐升降调幅度)
* [ ] 电视模式
* [ ] 和手机配对、用手机点歌
+11
View File
@@ -4,6 +4,7 @@ import type { LyricLine } from '$lib/types'
export class MusicControl {
player: Tone.Player
vocalsPlayer?: Tone.Player
speed: number = 1
lyrics: LyricLine[] = []
currentLineIndex: number = 0
checkInterval: any
@@ -13,6 +14,8 @@ export class MusicControl {
vocalsUrl?: string
constructor(audioUrl: string, vocalsUrl?: string) {
this.audioUrl = audioUrl
this.vocalsUrl = vocalsUrl
this.audioUrl = audioUrl
this.vocalsUrl = vocalsUrl
this.player = new Tone.Player(audioUrl).toDestination()
@@ -72,6 +75,14 @@ export class MusicControl {
this.startCheckLoop()
}
setSpeed(speed: number) {
this.speed = speed
this.player.playbackRate = this.speed
if (this.vocalsPlayer) {
this.vocalsPlayer.playbackRate = this.speed
}
}
setVocalsVolume(db: number) {
if (this.vocalsPlayer) this.vocalsPlayer.volume.value = db
}
+9 -1
View File
@@ -22,6 +22,7 @@
$effect(() => { API.saveUserData({ loc }) })
let vocalsVolume = $state(100) // 0-100
let speed = $state(1)
// Process lyrics
const isHideRepeated = $derived(settings.hideRepeated)
@@ -31,13 +32,14 @@
let musicControl = $state<MusicControl>()
$effect(() => { li; musicControl?.updateLine(li) })
// Volume control
// Volume, Speed control
$effect(() => {
if (musicControl) {
// Tone.js volume is in decibels. 0 is full, -Infinity is silent.
// Simple mapping: 100 -> 0, 0 -> -60 (or mute)
const db = vocalsVolume === 0 ? -Infinity : 20 * Math.log10(vocalsVolume / 100)
musicControl.setVocalsVolume(db)
musicControl.setSpeed(speed)
}
})
@@ -96,6 +98,12 @@
{t.noVocals}
</div>
{/if}
<div class="hbox gap-4 items-center">
<div class="i-material-symbols:speed-rounded text-2xl" title="Speed"></div>
<input type="range" min="0.5" max="1.5" step="0.05" bind:value={speed} class="flex-1" />
<div class="w-12 text-right">{speed.toFixed(2)}x</div>
</div>
</div>
<Lyrics lines={processedLrc} currentLineIndex={li} {settings} {states} />