summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2020-02-07 17:06:48 +0100
committerNiels Martin Hansen <nielsm@indvikleren.dk>2020-02-07 21:01:11 +0100
commit04ce1f0713952131014c4347e9fa9f265aebcea3 (patch)
treeb45906af64281785153775f06c0b6292ffd26b91
parent107283748ab599a1ae8a01f91c09e9f9a3e4bd06 (diff)
downloadopenttd-04ce1f0713952131014c4347e9fa9f265aebcea3.tar.xz
Fix #7885: [Fluidsynth] Use recommended method of setting sample rate
-rw-r--r--src/music/fluidsynth.cpp39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/music/fluidsynth.cpp b/src/music/fluidsynth.cpp
index 89cb7273f..64abe0e53 100644
--- a/src/music/fluidsynth.cpp
+++ b/src/music/fluidsynth.cpp
@@ -15,11 +15,13 @@
#include "midifile.hpp"
#include <fluidsynth.h>
#include "../mixer.h"
+#include <mutex>
static struct {
fluid_settings_t* settings; ///< FluidSynth settings handle
fluid_synth_t* synth; ///< FluidSynth synthesizer handle
fluid_player_t* player; ///< FluidSynth MIDI player handle
+ std::mutex synth_mutex; ///< Guard mutex for synth access
} _midi; ///< Metadata about the midi we're playing.
/** Factory for the FluidSynth driver. */
@@ -42,12 +44,16 @@ static const char *default_sf[] = {
static void RenderMusicStream(int16 *buffer, size_t samples)
{
- if (!_midi.synth || !_midi.player) return;
+ std::unique_lock<std::mutex> lock{ _midi.synth_mutex, std::try_to_lock };
+
+ if (!lock.owns_lock() || !_midi.synth || !_midi.player) return;
fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2);
}
const char *MusicDriver_FluidSynth::Start(const char * const *param)
{
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
+
const char *sfont_name = GetDriverParam(param, "soundfont");
int sfont_id;
@@ -59,6 +65,11 @@ const char *MusicDriver_FluidSynth::Start(const char * const *param)
/* Don't try to lock sample data in memory, OTTD usually does not run with privileges allowing that */
fluid_settings_setint(_midi.settings, "synth.lock-memory", 0);
+ /* Install the music render routine and set up the samplerate */
+ uint32 samplerate = MxSetMusicSource(RenderMusicStream);
+ fluid_settings_setnum(_midi.settings, "synth.sample-rate", samplerate);
+ DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate);
+
/* Create the synthesizer. */
_midi.synth = new_fluid_synth(_midi.settings);
if (!_midi.synth) return "Could not open synth";
@@ -81,19 +92,23 @@ const char *MusicDriver_FluidSynth::Start(const char * const *param)
_midi.player = nullptr;
- uint32 samplerate = MxSetMusicSource(RenderMusicStream);
- fluid_synth_set_sample_rate(_midi.synth, samplerate);
- DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate);
-
return nullptr;
}
void MusicDriver_FluidSynth::Stop()
{
MxSetMusicSource(nullptr);
- this->StopSong();
- delete_fluid_synth(_midi.synth);
- delete_fluid_settings(_midi.settings);
+
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
+
+ if (_midi.player != nullptr) delete_fluid_player(_midi.player);
+ _midi.player = nullptr;
+
+ if (_midi.synth != nullptr) delete_fluid_synth(_midi.synth);
+ _midi.synth = nullptr;
+
+ if (_midi.settings != nullptr) delete_fluid_settings(_midi.settings);
+ _midi.settings = nullptr;
}
void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song)
@@ -106,6 +121,8 @@ void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song)
return;
}
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
+
_midi.player = new_fluid_player(_midi.synth);
if (!_midi.player) {
DEBUG(driver, 0, "Could not create midi player");
@@ -128,6 +145,8 @@ void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song)
void MusicDriver_FluidSynth::StopSong()
{
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
+
if (!_midi.player) return;
fluid_player_stop(_midi.player);
@@ -142,6 +161,7 @@ void MusicDriver_FluidSynth::StopSong()
bool MusicDriver_FluidSynth::IsSongPlaying()
{
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
if (!_midi.player) return false;
return fluid_player_get_status(_midi.player) == FLUID_PLAYER_PLAYING;
@@ -149,6 +169,9 @@ bool MusicDriver_FluidSynth::IsSongPlaying()
void MusicDriver_FluidSynth::SetVolume(byte vol)
{
+ std::lock_guard<std::mutex> lock{ _midi.synth_mutex };
+ if (_midi.settings == nullptr) return;
+
/* Allowed range of synth.gain is 0.0 to 10.0 */
/* fluidsynth's default gain is 0.2, so use this as "full
* volume". Set gain using OpenTTD's volume, as a number between 0