# HG changeset patch # User milek7 # Date 2021-05-20 22:22:28 # Node ID 3e3ba4ccb6695cf895ba4cf9b7f973fe61ebef24 # Parent fb7980bf2415098479aef10189173ab150558f25 Fix: Workarounds for BeMidi driver to work properly on Haiku diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.cpp @@ -13,14 +13,8 @@ #include "../base_media_base.h" #include "midifile.hpp" -/* BeOS System Includes */ -#include - #include "../safeguards.h" -/** The file we're playing. */ -static BMidiSynthFile midiSynthFile; - /** Factory for BeOS' midi player. */ static FMusicDriver_BeMidi iFMusicDriver_BeMidi; @@ -31,7 +25,7 @@ const char *MusicDriver_BeMidi::Start(co void MusicDriver_BeMidi::Stop() { - midiSynthFile.UnloadFile(); + this->StopSong(); } void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) @@ -39,25 +33,44 @@ void MusicDriver_BeMidi::PlaySong(const std::string filename = MidiFile::GetSMFFile(song); this->Stop(); + this->midi_synth_file = new BMidiSynthFile(); if (!filename.empty()) { entry_ref midiRef; get_ref_for_path(filename.c_str(), &midiRef); - midiSynthFile.LoadFile(&midiRef); - midiSynthFile.Start(); + if (this->midi_synth_file->LoadFile(&midiRef) == B_OK) { + this->midi_synth_file->SetVolume(this->current_volume); + this->midi_synth_file->Start(); + this->just_started = true; + } else { + this->Stop(); + } } } void MusicDriver_BeMidi::StopSong() { - midiSynthFile.UnloadFile(); + /* Reusing BMidiSynthFile can cause stuck notes when switching + * tracks, just delete whole object entirely. */ + delete this->midi_synth_file; + this->midi_synth_file = nullptr; } bool MusicDriver_BeMidi::IsSongPlaying() { - return !midiSynthFile.IsFinished(); + if (this->midi_synth_file == nullptr) return false; + + /* IsFinished() returns true for a moment after Start() + * but before it really starts playing, use just_started flag + * to prevent accidental track skipping. */ + if (this->just_started) { + if (!this->midi_synth_file->IsFinished()) this->just_started = false; + return true; + } + return !this->midi_synth_file->IsFinished(); } void MusicDriver_BeMidi::SetVolume(byte vol) { - fprintf(stderr, "BeMidi: Set volume not implemented\n"); + this->current_volume = vol / 128.0; + if (this->midi_synth_file != nullptr) this->midi_synth_file->SetVolume(this->current_volume); } diff --git a/src/music/bemidi.h b/src/music/bemidi.h --- a/src/music/bemidi.h +++ b/src/music/bemidi.h @@ -12,6 +12,9 @@ #include "music_driver.hpp" +/* For BMidiSynthFile */ +#include + /** The midi player for BeOS. */ class MusicDriver_BeMidi : public MusicDriver { public: @@ -27,6 +30,11 @@ public: void SetVolume(byte vol) override; const char *GetName() const override { return "bemidi"; } + +private: + BMidiSynthFile *midi_synth_file = nullptr; + double current_volume = 1.0; + bool just_started = false; }; /** Factory for the BeOS midi player. */