mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 06:15:04 +00:00
Add: Fluidsynth music driver support (jmak)
This commit is contained in:
parent
1e68b9b3e6
commit
0c619b7c4b
16
config.lib
16
config.lib
@ -83,6 +83,7 @@ set_default() {
|
|||||||
with_midi=""
|
with_midi=""
|
||||||
with_midi_arg=""
|
with_midi_arg=""
|
||||||
with_libtimidity="1"
|
with_libtimidity="1"
|
||||||
|
with_fluidsynth="1"
|
||||||
with_freetype="1"
|
with_freetype="1"
|
||||||
with_fontconfig="1"
|
with_fontconfig="1"
|
||||||
with_icu_layout="1"
|
with_icu_layout="1"
|
||||||
@ -160,6 +161,7 @@ set_default() {
|
|||||||
with_midi
|
with_midi
|
||||||
with_midi_arg
|
with_midi_arg
|
||||||
with_libtimidity
|
with_libtimidity
|
||||||
|
with_fluidsynth
|
||||||
with_freetype
|
with_freetype
|
||||||
with_fontconfig
|
with_fontconfig
|
||||||
with_icu_layout
|
with_icu_layout
|
||||||
@ -372,6 +374,9 @@ detect_params() {
|
|||||||
--without-libtimidity) with_libtimidity="0";;
|
--without-libtimidity) with_libtimidity="0";;
|
||||||
--with-libtimidity=*) with_libtimidity="$optarg";;
|
--with-libtimidity=*) with_libtimidity="$optarg";;
|
||||||
|
|
||||||
|
--with-fluidsynth) with_fluidsynth="2";;
|
||||||
|
--without-fluidsynth) with_fluidsynth="0";;
|
||||||
|
|
||||||
--with-freetype) with_freetype="2";;
|
--with-freetype) with_freetype="2";;
|
||||||
--without-freetype) with_freetype="0";;
|
--without-freetype) with_freetype="0";;
|
||||||
--with-freetype=*) with_freetype="$optarg";;
|
--with-freetype=*) with_freetype="$optarg";;
|
||||||
@ -890,6 +895,7 @@ check_params() {
|
|||||||
detect_icu_layout
|
detect_icu_layout
|
||||||
detect_icu_sort
|
detect_icu_sort
|
||||||
detect_libtimidity
|
detect_libtimidity
|
||||||
|
detect_fluidsynth
|
||||||
|
|
||||||
if [ "$with_direct_music" != "0" ]; then
|
if [ "$with_direct_music" != "0" ]; then
|
||||||
if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then
|
if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then
|
||||||
@ -1839,6 +1845,11 @@ make_cflags_and_ldflags() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$fluidsynth" ]; then
|
||||||
|
LIBS="$LIBS -lfluidsynth"
|
||||||
|
CFLAGS="$CFLAGS -DFLUIDSYNTH"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$with_iconv" != "0" ]; then
|
if [ "$with_iconv" != "0" ]; then
|
||||||
CFLAGS="$CFLAGS -DWITH_ICONV"
|
CFLAGS="$CFLAGS -DWITH_ICONV"
|
||||||
if [ "$link_to_iconv" = "yes" ]; then
|
if [ "$link_to_iconv" = "yes" ]; then
|
||||||
@ -2775,6 +2786,10 @@ detect_libtimidity() {
|
|||||||
detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity_config" "0.1" "1"
|
detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity_config" "0.1" "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detect_fluidsynth() {
|
||||||
|
detect_library "$with_fluidsynth" "fluidsynth" "" "" "fluidsynth.h"
|
||||||
|
}
|
||||||
|
|
||||||
detect_pkg_config() {
|
detect_pkg_config() {
|
||||||
# $1 - config-param ($with_lzma value)
|
# $1 - config-param ($with_lzma value)
|
||||||
# $2 - package name ('liblzma')
|
# $2 - package name ('liblzma')
|
||||||
@ -3543,6 +3558,7 @@ showhelp() {
|
|||||||
echo " midi-player"
|
echo " midi-player"
|
||||||
echo " --with-libtimidity[=\"pkg-config libtimidity\"]"
|
echo " --with-libtimidity[=\"pkg-config libtimidity\"]"
|
||||||
echo " enables libtimidity support"
|
echo " enables libtimidity support"
|
||||||
|
echo " --with-fluidsynth enables fluidsynth support"
|
||||||
echo " --with-allegro[=\"pkg-config allegro\"]"
|
echo " --with-allegro[=\"pkg-config allegro\"]"
|
||||||
echo " enables Allegro video driver support"
|
echo " enables Allegro video driver support"
|
||||||
echo " --with-cocoa enables COCOA video driver (OSX ONLY)"
|
echo " --with-cocoa enables COCOA video driver (OSX ONLY)"
|
||||||
|
1
configure
vendored
1
configure
vendored
@ -125,6 +125,7 @@ AWKCOMMAND='
|
|||||||
if ($0 == "MSVC" && "'$os'" != "MSVC") { next; }
|
if ($0 == "MSVC" && "'$os'" != "MSVC") { next; }
|
||||||
if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; }
|
if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; }
|
||||||
if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; }
|
if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; }
|
||||||
|
if ($0 == "FLUIDSYNTH" && "'$fluidsynth'" == "" ) { next; }
|
||||||
if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; }
|
if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; }
|
||||||
if ($0 == "SSE" && "'$with_sse'" != "1") { next; }
|
if ($0 == "SSE" && "'$with_sse'" != "1") { next; }
|
||||||
|
|
||||||
|
@ -407,6 +407,7 @@ music/bemidi.h
|
|||||||
music/cocoa_m.h
|
music/cocoa_m.h
|
||||||
music/extmidi.h
|
music/extmidi.h
|
||||||
music/libtimidity.h
|
music/libtimidity.h
|
||||||
|
music/fluidsynth.h
|
||||||
music/os2_m.h
|
music/os2_m.h
|
||||||
music/qtmidi.h
|
music/qtmidi.h
|
||||||
os/macosx/macos.h
|
os/macosx/macos.h
|
||||||
@ -1127,6 +1128,9 @@ music/midifile.cpp
|
|||||||
#if LIBTIMIDITY
|
#if LIBTIMIDITY
|
||||||
music/libtimidity.cpp
|
music/libtimidity.cpp
|
||||||
#end
|
#end
|
||||||
|
#if FLUIDSYNTH
|
||||||
|
music/fluidsynth.cpp
|
||||||
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
# Sound
|
# Sound
|
||||||
|
157
src/music/fluidsynth.cpp
Normal file
157
src/music/fluidsynth.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file fluidsynth.cpp Playing music via the fluidsynth library. */
|
||||||
|
|
||||||
|
#include "../stdafx.h"
|
||||||
|
#include "../openttd.h"
|
||||||
|
#include "../sound_type.h"
|
||||||
|
#include "../debug.h"
|
||||||
|
#include "fluidsynth.h"
|
||||||
|
#include "midifile.hpp"
|
||||||
|
#include <fluidsynth.h>
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
fluid_settings_t* settings; ///< FluidSynth settings handle
|
||||||
|
fluid_synth_t* synth; ///< FluidSynth synthesizer handle
|
||||||
|
fluid_audio_driver_t* adriver; ///< FluidSynth audio driver handle
|
||||||
|
fluid_player_t* player; ///< FluidSynth MIDI player handle
|
||||||
|
} _midi; ///< Metadata about the midi we're playing.
|
||||||
|
|
||||||
|
/** Factory for the FluidSynth driver. */
|
||||||
|
static FMusicDriver_FluidSynth iFMusicDriver_FluidSynth;
|
||||||
|
|
||||||
|
/** List of sound fonts to try by default. */
|
||||||
|
static const char *default_sf[] = {
|
||||||
|
/* Debian/Ubuntu/OpenSUSE preferred */
|
||||||
|
"/usr/share/sounds/sf2/FluidR3_GM.sf2",
|
||||||
|
|
||||||
|
/* RedHat/Fedora/Arch preferred */
|
||||||
|
"/usr/share/soundfonts/FluidR3_GM.sf2",
|
||||||
|
|
||||||
|
/* Debian/Ubuntu/OpenSUSE alternatives */
|
||||||
|
"/usr/share/sounds/sf2/TimGM6mb.sf2",
|
||||||
|
"/usr/share/sounds/sf2/FluidR3_GS.sf2",
|
||||||
|
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *MusicDriver_FluidSynth::Start(const char * const *param)
|
||||||
|
{
|
||||||
|
const char *driver_name = GetDriverParam(param, "driver");
|
||||||
|
const char *sfont_name = GetDriverParam(param, "soundfont");
|
||||||
|
int sfont_id;
|
||||||
|
|
||||||
|
if (!driver_name) driver_name = "alsa";
|
||||||
|
|
||||||
|
DEBUG(driver, 1, "Fluidsynth: driver %s, sf %s", driver_name, sfont_name);
|
||||||
|
|
||||||
|
/* Create the settings. */
|
||||||
|
_midi.settings = new_fluid_settings();
|
||||||
|
if (!_midi.settings) return "Could not create midi settings";
|
||||||
|
|
||||||
|
if (fluid_settings_setstr(_midi.settings, "audio.driver", driver_name) != 1) {
|
||||||
|
return "Could not set audio driver name";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the synthesizer. */
|
||||||
|
_midi.synth = new_fluid_synth(_midi.settings);
|
||||||
|
if (!_midi.synth) return "Could not open synth";
|
||||||
|
|
||||||
|
/* Create the audio driver. The synthesizer starts playing as soon
|
||||||
|
as the driver is created. */
|
||||||
|
_midi.adriver = new_fluid_audio_driver(_midi.settings, _midi.synth);
|
||||||
|
if (!_midi.adriver) return "Could not open audio driver";
|
||||||
|
|
||||||
|
/* Load a SoundFont and reset presets (so that new instruments
|
||||||
|
* get used from the SoundFont) */
|
||||||
|
if (!sfont_name) {
|
||||||
|
int i;
|
||||||
|
sfont_id = FLUID_FAILED;
|
||||||
|
for (i = 0; default_sf[i]; i++) {
|
||||||
|
if (!fluid_is_soundfont(default_sf[i])) continue;
|
||||||
|
sfont_id = fluid_synth_sfload(_midi.synth, default_sf[i], 1);
|
||||||
|
if (sfont_id != FLUID_FAILED) break;
|
||||||
|
}
|
||||||
|
if (sfont_id == FLUID_FAILED) return "Could not open any sound font";
|
||||||
|
} else {
|
||||||
|
sfont_id = fluid_synth_sfload(_midi.synth, sfont_name, 1);
|
||||||
|
if (sfont_id == FLUID_FAILED) return "Could not open sound font";
|
||||||
|
}
|
||||||
|
|
||||||
|
_midi.player = NULL;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicDriver_FluidSynth::Stop()
|
||||||
|
{
|
||||||
|
this->StopSong();
|
||||||
|
delete_fluid_audio_driver(_midi.adriver);
|
||||||
|
delete_fluid_synth(_midi.synth);
|
||||||
|
delete_fluid_settings(_midi.settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song)
|
||||||
|
{
|
||||||
|
std::string filename = MidiFile::GetSMFFile(song);
|
||||||
|
|
||||||
|
this->StopSong();
|
||||||
|
|
||||||
|
if (filename.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_midi.player = new_fluid_player(_midi.synth);
|
||||||
|
if (!_midi.player) {
|
||||||
|
DEBUG(driver, 0, "Could not create midi player");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fluid_player_add(_midi.player, filename.c_str()) != FLUID_OK) {
|
||||||
|
DEBUG(driver, 0, "Could not open music file");
|
||||||
|
delete_fluid_player(_midi.player);
|
||||||
|
_midi.player = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fluid_player_play(_midi.player) != FLUID_OK) {
|
||||||
|
DEBUG(driver, 0, "Could not start midi player");
|
||||||
|
delete_fluid_player(_midi.player);
|
||||||
|
_midi.player = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicDriver_FluidSynth::StopSong()
|
||||||
|
{
|
||||||
|
if (!_midi.player) return;
|
||||||
|
|
||||||
|
fluid_player_stop(_midi.player);
|
||||||
|
if (fluid_player_join(_midi.player) != FLUID_OK) {
|
||||||
|
DEBUG(driver, 0, "Could not join player");
|
||||||
|
}
|
||||||
|
delete_fluid_player(_midi.player);
|
||||||
|
fluid_synth_system_reset(_midi.synth);
|
||||||
|
_midi.player = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MusicDriver_FluidSynth::IsSongPlaying()
|
||||||
|
{
|
||||||
|
if (!_midi.player) return false;
|
||||||
|
|
||||||
|
return fluid_player_get_status(_midi.player) == FLUID_PLAYER_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicDriver_FluidSynth::SetVolume(byte vol)
|
||||||
|
{
|
||||||
|
/* Allowed range of synth.gain is 0.0 to 10.0 */
|
||||||
|
if (fluid_settings_setnum(_midi.settings, "synth.gain", 1.0 * vol / 128.0) != 1) {
|
||||||
|
DEBUG(driver, 0, "Could not set volume");
|
||||||
|
}
|
||||||
|
}
|
41
src/music/fluidsynth.h
Normal file
41
src/music/fluidsynth.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file fluidsynth.h Base for FluidSynth music playback. */
|
||||||
|
|
||||||
|
#ifndef MUSIC_FLUIDSYNTH_H
|
||||||
|
#define MUSIC_FLUIDSYNTH_H
|
||||||
|
|
||||||
|
#include "music_driver.hpp"
|
||||||
|
|
||||||
|
/** Music driver making use of FluidSynth. */
|
||||||
|
class MusicDriver_FluidSynth : public MusicDriver {
|
||||||
|
public:
|
||||||
|
/* virtual */ const char *Start(const char * const *param);
|
||||||
|
|
||||||
|
/* virtual */ void Stop();
|
||||||
|
|
||||||
|
/* virtual */ void PlaySong(const MusicSongInfo &song);
|
||||||
|
|
||||||
|
/* virtual */ void StopSong();
|
||||||
|
|
||||||
|
/* virtual */ bool IsSongPlaying();
|
||||||
|
|
||||||
|
/* virtual */ void SetVolume(byte vol);
|
||||||
|
/* virtual */ const char *GetName() const { return "fluidsynth"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Factory for the fluidsynth driver. */
|
||||||
|
class FMusicDriver_FluidSynth : public DriverFactoryBase {
|
||||||
|
public:
|
||||||
|
FMusicDriver_FluidSynth() : DriverFactoryBase(Driver::DT_MUSIC, 5, "fluidsynth", "FluidSynth MIDI Driver") {}
|
||||||
|
/* virtual */ Driver *CreateInstance() const { return new MusicDriver_FluidSynth(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MUSIC_FLUIDSYNTH_H */
|
Loading…
Reference in New Issue
Block a user