diff --git a/audios/musicplayer.go b/audios/musicplayer.go index e7db0959..429b19fa 100644 --- a/audios/musicplayer.go +++ b/audios/musicplayer.go @@ -23,7 +23,7 @@ const defaultSampleRate beep.SampleRate = 44100 const quality = 4 func init() { - speaker.Init(defaultSampleRate, defaultSampleRate.N(time.Second/30)) + speaker.Init(defaultSampleRate, defaultSampleRate.N(time.Second/20)) } func NewMusicPlayer(f beep.StreamSeekCloser, format beep.Format, ratio float64) MusicPlayer { @@ -61,6 +61,9 @@ func NewMusicPlayerFromFile(fsys fs.FS, name string, ratio float64) (MusicPlayer } func (mp *MusicPlayer) Play() { + if mp.IsEmpty() { + return + } if mp.played { return } @@ -78,24 +81,46 @@ func (mp *MusicPlayer) Rewind() { func (mp MusicPlayer) IsEmpty() bool { return mp.streamer == nil } -func (mp MusicPlayer) IsPlayed() bool { return mp.played } +func (mp MusicPlayer) IsPlayed() bool { + if mp.IsEmpty() { + return false + } + return mp.played +} func (mp MusicPlayer) Time() time.Duration { + if mp.IsEmpty() { + return 0 + } return defaultSampleRate.D(mp.streamer.Position()) } func (mp MusicPlayer) Duration() time.Duration { + if mp.IsEmpty() { + return 0 + } return defaultSampleRate.D(mp.streamer.Len()) } -func (mp MusicPlayer) PlaybackRate() float64 { return mp.resampler.Ratio() } +func (mp MusicPlayer) PlaybackRate() float64 { + if mp.IsEmpty() { + return 1 + } + return mp.resampler.Ratio() +} func (mp *MusicPlayer) SetPlaybackRate(ratio float64) { + if mp.IsEmpty() { + return + } speaker.Lock() mp.resampler.SetRatio(ratio) speaker.Unlock() } func (mp *MusicPlayer) SetVolume(vol float64) { + if mp.IsEmpty() { + return + } speaker.Lock() mp.volume.Volume = beepVolume(vol) if vol <= 0.001 { // 0.1% @@ -106,23 +131,35 @@ func (mp *MusicPlayer) SetVolume(vol float64) { speaker.Unlock() } -func (mp MusicPlayer) IsPaused() bool { return mp.ctrl.Paused } +func (mp MusicPlayer) IsPaused() bool { + if mp.IsEmpty() { + return false + } + return mp.ctrl.Paused +} func (mp *MusicPlayer) Pause() { + if mp.IsEmpty() { + return + } speaker.Lock() mp.ctrl.Paused = true speaker.Unlock() } func (mp *MusicPlayer) Resume() { + if mp.IsEmpty() { + return + } speaker.Lock() mp.ctrl.Paused = false speaker.Unlock() } func (mp *MusicPlayer) Close() { - speaker.Clear() - if mp != nil && mp.streamer != nil { - mp.streamer.Close() + if mp.IsEmpty() { + return } + speaker.Clear() + mp.streamer.Close() } diff --git a/mode/piano/sceneplay.go b/mode/piano/sceneplay.go index d76fe3d9..96c895ba 100644 --- a/mode/piano/sceneplay.go +++ b/mode/piano/sceneplay.go @@ -88,10 +88,7 @@ func NewScenePlay(cfg *Config, assets map[int]*Asset, fsys fs.FS, name string, r } const ratio = 1 - s.musicPlayer, err = audios.NewMusicPlayerFromFile(fsys, s.MusicFilename, ratio) - if err != nil { - return - } + s.musicPlayer, _ = audios.NewMusicPlayerFromFile(fsys, s.MusicFilename, ratio) s.SetMusicVolume(*s.MusicVolume) s.SoundMap = audios.NewSoundMap(fsys, s.DefaultHitSoundFormat, s.SoundVolume) @@ -189,6 +186,12 @@ func (s *ScenePlay) Update() any { var worstJudgment mode.Judgment kas := s.readInput() for _, ka := range kas { + // Todo: solve this + if len(ka.KeyActions) != s.KeyCount { + fmt.Println("len(ka.KeyActions) != s.KeyCount") + continue + } + missed := s.Scorer.flushStagedNotes(ka.Time) if missed { worstJudgment = s.miss() @@ -270,11 +273,6 @@ func (s *ScenePlay) tryPlayMusic() { // Todo: set all sample volumes in advance? func (s ScenePlay) playSounds(ka input.KeyboardAction) { - if len(ka.KeyActions) != s.KeyCount { - fmt.Println("len(ka.KeyActions) != s.KeyCount") - return - } - for k, n := range s.stagedNotes { if n == nil { continue @@ -364,7 +362,7 @@ func (s *ScenePlay) Resume() { } func (s ScenePlay) Finish() any { - s.musicPlayer.Close() + // s.musicPlayer.Close() if s.Keyboard != nil { s.Keyboard.Close() } diff --git a/scene/choose/musicplayer.go b/scene/choose/musicplayer.go index d46b43ce..2bed1472 100644 --- a/scene/choose/musicplayer.go +++ b/scene/choose/musicplayer.go @@ -24,13 +24,16 @@ type PreviewMusicPlayer struct { func (s *Scene) updatePreviewMusic() { // It is fine to call Close at blank MusicPlayer. - s.MusicPlayer.Close() + if s.MusicPlayer != nil { + s.MusicPlayer.Close() + } c := s.chart() fsys := c.MusicFS name := c.MusicFilename mp, _ := audios.NewMusicPlayerFromFile(fsys, name, 1) mp.SetVolume(s.MusicVolume) + // MusicPlayer should be pointer so that it plays only once. s.PreviewMusicPlayer = PreviewMusicPlayer{ MusicPlayer: &mp, StartTime: time.Now(), diff --git a/scene/config.go b/scene/config.go index c0756f56..4cdce4ba 100644 --- a/scene/config.go +++ b/scene/config.go @@ -52,7 +52,7 @@ func NewConfig() *Config { MusicVolume: 0.60, SoundVolume: 0.60, - MusicOffset: 0, + MusicOffset: -20, BackgroundBrightness: 0.6, DebugPrint: true, Replay: false,