Player: Helen's Mysterious Castle inaccurate BGM playback

Created on 11 Dec 2018  Â·  10Comments  Â·  Source: EasyRPG/Player

Name of the game:

Helen's Mysterious Castle

Player platform:

Windows, Linux

Player version:

EasyRPG Player 0.5.4 (git~287@d1d6fc63, 2018-12-10)

Attach files (as a .zip archive or link them)

Describe the issue in detail and how to reproduce it:

Music sounds (on Linux, heavily) different compared to original.
In game SFX seem fine.
To reproduce: nothing special, just load the save file.

EasyRPG Windows
  • Music slightly different from original.
  • At aprox. 1:13, music stops before looping again,
    unlike the gapless playback on original.
EasyRPG Linux
  • Music sounds very differently compared to both.
  • At aprox. 1:16, music stops before looping, just like under EasyRPG Windows.
Audio MIDI

All 10 comments

Hello, thank you for the detailed report and sorry for the late reply.
Started organizing audio issues after a while. For the music, they are related to MIDI playback. After checking:

  • The looping issue is being handled at #834.
  • The music playing different is mainly a sound bank difference, this is normal due to the different MIDI synthesizer used. On Windows the slight difference could be due to issues in volume handling in native MIDI. This is tracked at #1434.

Keeping this issue opened for better tracking affected games, though this issue is actually affecting any game having midi with loop events.

Hello again @sat3ll,

Music sounds (on Linux, heavily) different compared to original.

The master branch now supports FluidSynth playback. To get the same midi samples than the original Windows sound, you need a GM.DLS conversion to SF2, which are (likely) direct conversions made with software such Awave Studio. The file GM.DLS is available on Windows directories and in some old DirectX redistributables (up to dx7 if I recall correctly). There are some conversions created by users out there with different names, e.g.: "scc1t2.sf2". Try downloading it and rename "scc1t2.sf2" to "easyrpg.soundfont" and place it in the game folder (if not placed properly, the console log will tell the sound font was not found). You need to install fluidsynth development package.

Beware the GM.DLS attached license (there's a txt file in the same directory) does not allow using this sound bank on non-Windows operating systems explicitly, so making this the default is legally not possible to be distributed, so it's up to users to place the custom converted soundfont if they want a similar playback experience on non-Windows operating systems. FluidSynth with scc1t2.sf2 is not exactly like the original synthesizer modulators (attack, decay, sustain, release, chorus, reverb, etc.) and it may play slightly different. Sound samples used for the instruments are the same at least.

At aprox. 1:13 / 1:16, music stops before looping

This has been fixed in the master version for FluidSynth. Pitch is also correct when the music speed is set with a value different than 100% in the Play Music event command. The fmmidi synthesizer already implemented this. Wildmidi does not support this feature.

There are still some issues when games use Play Music event command to play the same song: it should continue playing without restarting and should apply volume, pitch and pan changes in-place. This is being addressed in future pull requests.

If you can test the current master version with fluidsynth and the mentioned sf2 file with current Player master build and fits with your reported issues, feel free to close the issue. These details mentioned in the paragraph above are being addressed in other issues.

Hi @fdelapena ,

Building the latest EasyRPG-Player is failing due to several circumstances (Fedora 32):

  • liblcf and fluidsynth versions used by EasyRPG-Player (commit: f507a13) are outdated in repositories

    • directory structure and filenames from Fedora liblcf (0.6.2) and upstream liblcf are different



      • solved by building liblcf master (https://github.com/EasyRPG/liblcf/commit/5e54de42303305cde9b2e91d499d68f3c61ab546) with autotools



    • Fedora fluidsynth (1.1.11) is probably too low for EasyRPG (version 2.x.x required ?)



      • solved(?) by building (https://github.com/FluidSynth/fluidsynth/commit/c76949e6d33527fea2a4b5cdc7ff2421bb58537a)



Building both dependencies above from source doesn't take me much farther as I am getting:

make  all-am
make[1]: Entering directory '/tmp/Player'
  CXX      src/libeasyrpg_player_a-decoder_fluidsynth.o
  CXX      src/libeasyrpg_player_a-decoder_wav.o
  CXX      src/libeasyrpg_player_a-decoder_midigeneric.o
  CXX      src/libeasyrpg_player_a-decoder_libsndfile.o
  CXX      src/libeasyrpg_player_a-decoder_opus.o
  CXX      src/libeasyrpg_player_a-decoder_wildmidi.o
  CXX      src/libeasyrpg_player_a-decoder_mpg123.o
  CXX      src/libeasyrpg_player_a-decoder_oggvorbis.o
  CXX      src/libeasyrpg_player_a-decoder_xmp.o
  CXX      src/libeasyrpg_player_a-drawable.o
  CXX      src/libeasyrpg_player_a-drawable_list.o
  CXX      src/libeasyrpg_player_a-drawable_mgr.o
  CXX      src/libeasyrpg_player_a-exe_reader.o
  CXX      src/libeasyrpg_player_a-filefinder.o
  CXX      src/libeasyrpg_player_a-filesystem.o
  CXX      src/libeasyrpg_player_a-font.o
  CXX      src/libeasyrpg_player_a-fps_overlay.o
src/decoder_fluidsynth.cpp: In static member function ‘static bool FluidSynthDecoder::Initialize(std::string&)’:
src/decoder_fluidsynth.cpp:173:15: error: invalid conversion from ‘int (*)(void*, int, void*)’ to ‘fluid_sfloader_callback_read_t’ {aka ‘int (*)(void*, long long int, void*)’} [-fpermissive]
  173 |     vio_open, vio_read, vio_seek, vio_tell, vio_close);
      |               ^~~~~~~~
      |               |
      |               int (*)(void*, int, void*)
In file included from /tmp/Player/build/include/fluidsynth.h:99,
                 from src/decoder_fluidsynth.h:33,
                 from src/decoder_fluidsynth.cpp:19:
/tmp/Player/build/include/fluidsynth/sfont.h:151:40: note:   initializing argument 3 of ‘int fluid_sfloader_set_callbacks(fluid_sfloader_t*, fluid_sfloader_callback_open_t, fluid_sfloader_callback_read_t, fluid_sfloader_callback_seek_t, fluid_sfloader_callback_tell_t, fluid_sfloader_callback_close_t)’
  151 |         fluid_sfloader_callback_read_t read,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
src/decoder_fluidsynth.cpp:173:25: error: invalid conversion from ‘int (*)(void*, long int, int)’ to ‘fluid_sfloader_callback_seek_t’ {aka ‘int (*)(void*, long long int, int)’} [-fpermissive]
  173 |     vio_open, vio_read, vio_seek, vio_tell, vio_close);
      |                         ^~~~~~~~
      |                         |
      |                         int (*)(void*, long int, int)
In file included from /tmp/Player/build/include/fluidsynth.h:99,
                 from src/decoder_fluidsynth.h:33,
                 from src/decoder_fluidsynth.cpp:19:
/tmp/Player/build/include/fluidsynth/sfont.h:152:40: note:   initializing argument 4 of ‘int fluid_sfloader_set_callbacks(fluid_sfloader_t*, fluid_sfloader_callback_open_t, fluid_sfloader_callback_read_t, fluid_sfloader_callback_seek_t, fluid_sfloader_callback_tell_t, fluid_sfloader_callback_close_t)’
  152 |         fluid_sfloader_callback_seek_t seek,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
src/decoder_fluidsynth.cpp:173:35: error: invalid conversion from ‘long int (*)(void*)’ to ‘fluid_sfloader_callback_tell_t’ {aka ‘long long int (*)(void*)’} [-fpermissive]
  173 |     vio_open, vio_read, vio_seek, vio_tell, vio_close);
      |                                   ^~~~~~~~
      |                                   |
      |                                   long int (*)(void*)
In file included from /tmp/Player/build/include/fluidsynth.h:99,
                 from src/decoder_fluidsynth.h:33,
                 from src/decoder_fluidsynth.cpp:19:
/tmp/Player/build/include/fluidsynth/sfont.h:153:40: note:   initializing argument 5 of ‘int fluid_sfloader_set_callbacks(fluid_sfloader_t*, fluid_sfloader_callback_open_t, fluid_sfloader_callback_read_t, fluid_sfloader_callback_seek_t, fluid_sfloader_callback_tell_t, fluid_sfloader_callback_close_t)’
  153 |         fluid_sfloader_callback_tell_t tell,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
make[1]: *** [Makefile:2218: src/libeasyrpg_player_a-decoder_fluidsynth.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: Leaving directory '/tmp/Player'
make: *** [Makefile:1259: all] Error 2

Hi, I use Fedora 32, too. I did this instead:

wget https://kojipkgs.fedoraproject.org//packages/fluidsynth/2.1.1/4.fc33/x86_64/fluidsynth-2.1.1-4.fc33.x86_64.rpm
wget https://kojipkgs.fedoraproject.org//packages/fluidsynth/2.1.1/4.fc33/x86_64/fluidsynth-devel-2.1.1-4.fc33.x86_64.rpm
wget https://kojipkgs.fedoraproject.org//packages/fluidsynth/2.1.1/4.fc33/x86_64/fluidsynth-libs-2.1.1-4.fc33.x86_64.rpm
sudo dnf install ./fluidsynth-*.rpm

I needed to uninstall some packages requiring 1.11.1 in my case to continue, but after re-running ./configure worked for me.

Same result after using the fluidsynth RPMs.

Ugh there are still old versions of fluidsynth < 2 in the wild? 🙈

I only compiled on Arch Linux. There it works. Hm

When you use cmake you can also get latest lcf with -DPLAYER_BUILD_LIBLCF=ON btw

I'd suggest a workspace cleanup if you used autotools. It worked here with the autotools method and 2.1.1 RPMs.

With cmake I needed speexdsp-devel installed otherwise I'd get:

[ 98%] Linking CXX static library libEasyRPG_Player.a
[ 98%] Built target EasyRPG_Player
Scanning dependencies of target EasyRPG_Player_exe
[100%] Building CXX object CMakeFiles/EasyRPG_Player_exe.dir/src/main.cpp.o
[100%] Linking CXX executable easyrpg-player
/usr/bin/ld: libEasyRPG_Player.a(audio_midi.cpp.o): in function `std::_MakeUniq<AudioResampler>::__single_object std::make_unique<AudioResampler, std::unique_ptr<AudioDecoder, std::default_delete<AudioDecoder> > >(std::unique_ptr<AudioDecoder, std::default_delete<AudioDecoder> >&&)':
audio_midi.cpp:(.text._ZSt11make_uniqueI14AudioResamplerJSt10unique_ptrI12AudioDecoderSt14default_deleteIS2_EEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_[_ZSt11make_uniqueI14AudioResamplerJSt10unique_ptrI12AudioDecoderSt14default_deleteIS2_EEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_]+0x4d): undefined reference to `AudioResampler::AudioResampler(std::unique_ptr<AudioDecoder, std::default_delete<AudioDecoder> >, AudioResampler::Quality)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/EasyRPG_Player_exe.dir/build.make:118: easyrpg-player] Error 1
make[1]: *** [CMakeFiles/Makefile2:184: CMakeFiles/EasyRPG_Player_exe.dir/all] Error 2
make: *** [Makefile:150: all] Error 2

Test details

  • With _scc1t2.sf2_ soundfont
$ sha256sum easyrpg.soundfont 
865f15ed7097d68539c4556ceea629658148e5d8fcc9d15a4eb13144653e9cb8  easyrpg.soundfont

Video: HMC.zip (audio clip untouched)

  • Audio Looping works
  • The sound is much closer to the original
  • (minor) Audio artefact when loading stage
  • There's some crackling noise during playback

Oh the speexdsp error is a missing ifdef. Thanks for finding this!
Though you likely want speexdsp. Except for Midi there will be resampling issues for WAV files and pitch won't work except for Midi.

Audio Looping works

As expected :+1:

The sound is much closer to the original

:partying_face:

(minor) Audio artefact when loading stage

Yeah this is a known issue.

There's some crackling noise during playback

So the crackling is also with Fluidsynth? Good to know we already suspected that this is a FluidLite bug but is also in "real" Fluidsynth it seems.

Closing. All fixed except "minor Audio artifact". This is tracked in #2300 because this bug is FluidLite/Synth specific.

Was this page helpful?
0 / 5 - 0 ratings