[+] Speed control
This commit is contained in:
@@ -21,7 +21,7 @@ Practice Japanese Karaoke lyrics reading and typing at the same time with KaraDa
|
|||||||
* [x] 跟随音乐滚动歌词
|
* [x] 跟随音乐滚动歌词
|
||||||
* [ ] 升降调
|
* [ ] 升降调
|
||||||
* [ ] 播放/暂停音乐控制
|
* [ ] 播放/暂停音乐控制
|
||||||
* [ ] 变速
|
* [x] 变速
|
||||||
* [ ] 音域分析(自动推荐升降调幅度)
|
* [ ] 音域分析(自动推荐升降调幅度)
|
||||||
* [ ] 电视模式
|
* [ ] 电视模式
|
||||||
* [ ] 和手机配对、用手机点歌
|
* [ ] 和手机配对、用手机点歌
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { LyricLine } from '$lib/types'
|
|||||||
export class MusicControl {
|
export class MusicControl {
|
||||||
player: Tone.Player
|
player: Tone.Player
|
||||||
vocalsPlayer?: Tone.Player
|
vocalsPlayer?: Tone.Player
|
||||||
|
speed: number = 1
|
||||||
lyrics: LyricLine[] = []
|
lyrics: LyricLine[] = []
|
||||||
currentLineIndex: number = 0
|
currentLineIndex: number = 0
|
||||||
checkInterval: any
|
checkInterval: any
|
||||||
@@ -13,6 +14,8 @@ export class MusicControl {
|
|||||||
vocalsUrl?: string
|
vocalsUrl?: string
|
||||||
|
|
||||||
constructor(audioUrl: string, vocalsUrl?: string) {
|
constructor(audioUrl: string, vocalsUrl?: string) {
|
||||||
|
this.audioUrl = audioUrl
|
||||||
|
this.vocalsUrl = vocalsUrl
|
||||||
this.audioUrl = audioUrl
|
this.audioUrl = audioUrl
|
||||||
this.vocalsUrl = vocalsUrl
|
this.vocalsUrl = vocalsUrl
|
||||||
this.player = new Tone.Player(audioUrl).toDestination()
|
this.player = new Tone.Player(audioUrl).toDestination()
|
||||||
@@ -72,6 +75,14 @@ export class MusicControl {
|
|||||||
this.startCheckLoop()
|
this.startCheckLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSpeed(speed: number) {
|
||||||
|
this.speed = speed
|
||||||
|
this.player.playbackRate = this.speed
|
||||||
|
if (this.vocalsPlayer) {
|
||||||
|
this.vocalsPlayer.playbackRate = this.speed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setVocalsVolume(db: number) {
|
setVocalsVolume(db: number) {
|
||||||
if (this.vocalsPlayer) this.vocalsPlayer.volume.value = db
|
if (this.vocalsPlayer) this.vocalsPlayer.volume.value = db
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
$effect(() => { API.saveUserData({ loc }) })
|
$effect(() => { API.saveUserData({ loc }) })
|
||||||
|
|
||||||
let vocalsVolume = $state(100) // 0-100
|
let vocalsVolume = $state(100) // 0-100
|
||||||
|
let speed = $state(1)
|
||||||
|
|
||||||
// Process lyrics
|
// Process lyrics
|
||||||
const isHideRepeated = $derived(settings.hideRepeated)
|
const isHideRepeated = $derived(settings.hideRepeated)
|
||||||
@@ -31,13 +32,14 @@
|
|||||||
let musicControl = $state<MusicControl>()
|
let musicControl = $state<MusicControl>()
|
||||||
$effect(() => { li; musicControl?.updateLine(li) })
|
$effect(() => { li; musicControl?.updateLine(li) })
|
||||||
|
|
||||||
// Volume control
|
// Volume, Speed control
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (musicControl) {
|
if (musicControl) {
|
||||||
// Tone.js volume is in decibels. 0 is full, -Infinity is silent.
|
// Tone.js volume is in decibels. 0 is full, -Infinity is silent.
|
||||||
// Simple mapping: 100 -> 0, 0 -> -60 (or mute)
|
// Simple mapping: 100 -> 0, 0 -> -60 (or mute)
|
||||||
const db = vocalsVolume === 0 ? -Infinity : 20 * Math.log10(vocalsVolume / 100)
|
const db = vocalsVolume === 0 ? -Infinity : 20 * Math.log10(vocalsVolume / 100)
|
||||||
musicControl.setVocalsVolume(db)
|
musicControl.setVocalsVolume(db)
|
||||||
|
musicControl.setSpeed(speed)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -96,6 +98,12 @@
|
|||||||
{t.noVocals}
|
{t.noVocals}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/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>
|
</div>
|
||||||
|
|
||||||
<Lyrics lines={processedLrc} currentLineIndex={li} {settings} {states} />
|
<Lyrics lines={processedLrc} currentLineIndex={li} {settings} {states} />
|
||||||
|
|||||||
Reference in New Issue
Block a user