Ticket #8413: fluidsynth3.diff

File fluidsynth3.diff, 10.5 KB (added by eriktorbjorn, 18 years ago)

Patch against an April 7 CVS snapshot

  • configure

    diff -urN ScummVM-cvs20050407/configure ScummVM-cvs20050407+hack/configure
    old new  
    2020_alsa=auto
    2121_zlib=auto
    2222_mpeg2=auto
     23_fluidsynth=auto
    2324_mt32emu=yes
    2425# default option behaviour yes/no
    2526_build_scumm=yes
     
    294295  --with-mpeg2-prefix=DIR  Prefix where libmpeg2 is installed (optional)
    295296  --disable-mpeg2          disable mpeg2 codec for cutscenes [autodetect]
    296297
     298  --with-fluidsynth-prefix=DIR  Prefix where libfluidsynth is installed (optional)
     299  --disable-fluidsynth     disable fluidsynth MIDI driver [autodetect]
     300
    297301  --with-sdl-prefix=DIR    Prefix where the sdl-config script is installed (optional)
    298302
    299303  --with-nasm-prefix=DIR   Prefix where nasm executable is installed (optional)
     
    338342      --enable-nasm)            _nasm=yes       ;;
    339343      --disable-nasm)           _nasm=no        ;;
    340344      --disable-mpeg2)          _mpeg2=no       ;;
     345      --disable-fluidsynth)     _fluidsynth=no  ;;
    341346      --enable-plugins)         _build_plugins=yes ;;
    342347      --enable-mt32emu)         _mt32emu=yes    ;;
    343348      --disable-mt32emu)        _mt32emu=no     ;;
     349      --with-fluidsynth-prefix=*)
     350        _prefix=`echo $ac_option | cut -d '=' -f 2`
     351        FLUIDSYNTH_CFLAGS="-I$_prefix/include"
     352        FLUIDSYNTH_LIBS="-L$_prefix/lib"
     353        ;;
    344354      --with-mpeg2-prefix=*)
    345355        _prefix=`echo $ac_option | cut -d '=' -f 2`
    346356        MPEG2_CFLAGS="-I$_prefix/include"
     
    9911001rm -f $TMPC $TMPO$EXEEXT
    9921002
    9931003#
     1004# Check for libfluidsynth
     1005#
     1006echocheck "libfluidsynth"
     1007if test "$_fluidsynth" = auto ; then
     1008        _fluidsynth=no
     1009        cat > $TMPC << EOF
     1010#include <fluidsynth.h>
     1011int main(void) { return 0; }
     1012EOF
     1013        cc_check $LDFLAGS $CXXFLAGS $FLUIDSYNTH_CFLAGS $FLUIDSYNTH_LIBS -lfluidsynth && _fluidsynth=yes
     1014fi
     1015if test "$_fluidsynth" = yes ; then
     1016        _def_fluidsynth='#define USE_FLUIDSYNTH'
     1017        LIBS="$LIBS $FLUIDSYNTH_LIBS -lfluidsynth"
     1018        INCLUDE="$INCLUDES $FLUIDSYNTH_CFLAGS"
     1019else
     1020        _def_fluidsynth='#undef USE_FLUIDSYNTH'
     1021fi
     1022echo "$_fluidsynth"
     1023rm -f $TMPC $TMPO$EXEEXT
     1024
     1025#
    9941026# Check for nasm
    9951027#
    9961028if test "$_have_x86" = yes ; then
     
    11261158$_def_alsa
    11271159$_def_zlib
    11281160$_def_mpeg2
     1161$_def_fluidsynth
    11291162$_def_mt32emu
    11301163
    11311164/* Whether we should use i386 assembly routines */
  • sound/mididrv.cpp

    diff -urN ScummVM-cvs20050407/sound/mididrv.cpp ScummVM-cvs20050407+hack/sound/mididrv.cpp
    old new  
    5858        {"towns", "FM Towns", MD_TOWNS},
    5959        {"pcspk", "PC Speaker", MD_PCSPK},
    6060        {"pcjr", "IBM PCjr", MD_PCJR},
     61#ifdef USE_FLUIDSYNTH
     62        {"fluidsynth", "FluidSynth", MD_FLUIDSYNTH},
     63#endif
    6164#ifdef USE_MT32EMU
    6265        {"mt32", "MT-32", MD_MT32},
    6366#endif
     
    172175        // driver.
    173176        case MD_ADLIB:     return NULL;
    174177
     178#ifdef USE_FLUIDSYNTH
     179        case MD_FLUIDSYNTH:     return MidiDriver_FluidSynth_create(g_engine->_mixer);
     180#endif
    175181#ifdef USE_MT32EMU
    176182        case MD_MT32:      return MidiDriver_MT32_create(g_engine->_mixer);
    177183#endif
  • sound/mididrv.h

    diff -urN ScummVM-cvs20050407/sound/mididrv.h ScummVM-cvs20050407+hack/sound/mididrv.h
    old new  
    4848        MD_TOWNS = 13,
    4949        MD_YPA1 = 14, // PalmOS
    5050        MD_ZODIAC = 15, // PalmOS
    51         MD_MT32 = 16
     51        MD_MT32 = 16,
     52        MD_FLUIDSYNTH = 17
    5253};
    5354
    5455enum MidiDriverType {
     
    195196extern MidiDriver *MidiDriver_ETUDE_create();
    196197extern MidiDriver *MidiDriver_ALSA_create();
    197198extern MidiDriver *MidiDriver_YM2612_create(SoundMixer *mixer);
     199#ifdef USE_FLUIDSYNTH
     200extern MidiDriver *MidiDriver_FluidSynth_create(SoundMixer *mixer);
     201#endif
    198202#ifdef USE_MT32EMU
    199203extern MidiDriver *MidiDriver_MT32_create(SoundMixer *mixer);
    200204#endif
  • sound/module.mk

    diff -urN ScummVM-cvs20050407/sound/module.mk ScummVM-cvs20050407+hack/sound/module.mk
    old new  
    1818        sound/wave.o \
    1919        sound/softsynth/adlib.o \
    2020        sound/softsynth/ym2612.o \
     21        sound/softsynth/fluidsynth.o \
    2122        sound/softsynth/mt32.o \
    2223
    2324MODULE_DIRS += \
  • sound/softsynth/fluidsynth.cpp

    diff -urN ScummVM-cvs20050407/sound/softsynth/fluidsynth.cpp ScummVM-cvs20050407+hack/sound/softsynth/fluidsynth.cpp
    old new  
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2001-2005 The ScummVM project
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8 *
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17 *
     18 * $Header$
     19 */
     20
     21#if defined(HAVE_CONFIG_H)
     22#include "config.h"
     23#endif
     24
     25#ifdef USE_FLUIDSYNTH
     26
     27#include "stdafx.h"
     28#include "common/config-manager.h"
     29#include "sound/mpu401.h"
     30#include "sound/softsynth/emumidi.h"
     31
     32#include <fluidsynth.h>
     33
     34class MidiDriver_FluidSynth : public MidiDriver_Emulated {
     35private:
     36        MidiChannel_MPU401 _midiChannels[16];
     37        fluid_settings_t *_settings;
     38        fluid_synth_t *_synth;
     39        int _soundFont;
     40        int _outputRate;
     41        SoundHandle _handle;
     42
     43protected:
     44        // Because GCC complains about casting from const to non-const...
     45        void setInt(const char *name, int val);
     46        void setNum(const char *name, double num);
     47        void setStr(const char *name, const char *str);
     48
     49        void generateSamples(int16 *buf, int len);
     50
     51public:
     52        MidiDriver_FluidSynth(SoundMixer *mixer);
     53
     54        int open();
     55        void close();
     56        void send(uint32 b);
     57
     58        MidiChannel *allocateChannel();
     59        MidiChannel *getPercussionChannel();
     60
     61        // AudioStream API
     62        bool isStereo() const { return true; }
     63        int getRate() const { return _outputRate; }
     64};
     65
     66// MidiDriver method implementations
     67
     68MidiDriver_FluidSynth::MidiDriver_FluidSynth(SoundMixer *mixer)
     69        : MidiDriver_Emulated(mixer) {
     70
     71        for (int i = 0; i < ARRAYSIZE(_midiChannels); i++) {
     72                _midiChannels[i].init(this, i);
     73        }
     74
     75        // It ought to be possible to get FluidSynth to generate samples at
     76        // lower
     77
     78        _outputRate = _mixer->getOutputRate();
     79        if (_outputRate < 22050)
     80                _outputRate = 22050;
     81        else if (_outputRate > 96000)
     82                _outputRate = 96000;
     83}
     84
     85void MidiDriver_FluidSynth::setInt(const char *name, int val) {
     86        char *name2 = strdup(name);
     87
     88        fluid_settings_setint(_settings, name2, val);
     89        free(name2);
     90}
     91
     92void MidiDriver_FluidSynth::setNum(const char *name, double val) {
     93        char *name2 = strdup(name);
     94
     95        fluid_settings_setnum(_settings, name2, val);
     96        free(name2);
     97}
     98
     99void MidiDriver_FluidSynth::setStr(const char *name, const char *val) {
     100        char *name2 = strdup(name);
     101        char *val2 = strdup(val);
     102
     103        fluid_settings_setstr(_settings, name2, val2);
     104        free(name2);
     105        free(val2);
     106}
     107
     108int MidiDriver_FluidSynth::open() {
     109        if (_isOpen)
     110                return MERR_ALREADY_OPEN;
     111
     112        if (!ConfMan.hasKey("soundfont"))
     113                error("FluidSynth recquires a 'soundfont' setting");
     114
     115        _settings = new_fluid_settings();
     116
     117        // The default gain setting is ridiculously low, but we can't set it
     118        // too high either or sound will be clipped. This may need tuning...
     119
     120        setNum("synth.gain", 2.1);
     121        setNum("synth.sample-rate", _outputRate);
     122
     123        _synth = new_fluid_synth(_settings);
     124
     125        // In theory, this ought to reduce CPU load... but it doesn't make any
     126        // noticeable difference for me, so disable it for now.
     127
     128        // fluid_synth_set_interp_method(_synth, -1, FLUID_INTERP_LINEAR);
     129        // fluid_synth_set_reverb_on(_synth, 0);
     130        // fluid_synth_set_chorus_on(_synth, 0);
     131
     132        const char *soundfont = ConfMan.get("soundfont").c_str();
     133
     134        _soundFont = fluid_synth_sfload(_synth, soundfont, 1);
     135        if (_soundFont == -1)
     136                error("Failed loading custom sound font '%s'", soundfont);
     137
     138        MidiDriver_Emulated::open();
     139
     140        // The MT-32 emulator uses kSFXSoundType here. I don't know why.
     141        _mixer->playInputStream(SoundMixer::kMusicSoundType, &_handle, this, -1, 255, 0, false, true);
     142        return 0;
     143}
     144
     145void MidiDriver_FluidSynth::close() {
     146        if (!_isOpen)
     147                return;
     148        _isOpen = false;
     149
     150        _mixer->stopHandle(_handle);
     151
     152        if (_soundFont != -1)
     153                fluid_synth_sfunload(_synth, _soundFont, 1);
     154
     155        delete_fluid_synth(_synth);
     156        delete_fluid_settings(_settings);
     157}
     158
     159void MidiDriver_FluidSynth::send(uint32 b) {
     160        //byte param3 = (byte) ((b >> 24) & 0xFF);
     161        uint param2 = (byte) ((b >> 16) & 0xFF);
     162        uint param1 = (byte) ((b >>  8) & 0xFF);
     163        byte cmd    = (byte) (b & 0xF0);
     164        byte chan   = (byte) (b & 0x0F);
     165
     166        switch (cmd) {
     167        case 0x80:      // Note Off
     168                fluid_synth_noteoff(_synth, chan, param1);
     169                break;
     170        case 0x90:      // Note On
     171                fluid_synth_noteon(_synth, chan, param1, param2);
     172                break;
     173        case 0xA0:      // Aftertouch
     174                break;
     175        case 0xB0:      // Control Change
     176                fluid_synth_cc(_synth, chan, param1, param2);
     177                break;
     178        case 0xC0:      // Program Change
     179                fluid_synth_program_change(_synth, chan, param1);
     180                break;
     181        case 0xD0:      // Channel Pressure
     182                break;
     183        case 0xE0:      // Pitch Bend
     184                fluid_synth_pitch_bend(_synth, chan, (param2 << 7) | param1);
     185                break;
     186        case 0xF0:      // SysEx
     187                // We should never get here! SysEx information has to be
     188                // sent via high-level semantic methods.
     189                warning("MidiDriver_FluidSynth: Receiving SysEx command on a send() call");
     190                break;
     191        default:
     192                warning("MidiDriver_FluidSynth: Unknown send() command 0x%02X", cmd);
     193                break;
     194        }
     195}
     196
     197MidiChannel *MidiDriver_FluidSynth::allocateChannel() {
     198        for (int i = 0; i < ARRAYSIZE(_midiChannels); i++) {
     199                if (i != 9 && _midiChannels[i].allocate())
     200                        return &_midiChannels[i];
     201        }
     202        return NULL;
     203}
     204
     205MidiChannel *MidiDriver_FluidSynth::getPercussionChannel() {
     206        return &_midiChannels[9];
     207}
     208
     209MidiDriver *MidiDriver_FluidSynth_create(SoundMixer *mixer) {
     210        return new MidiDriver_FluidSynth(mixer);
     211}
     212
     213void MidiDriver_FluidSynth::generateSamples(int16 *data, int len) {
     214        fluid_synth_write_s16(_synth, len, data, 0, 2, data, 1, 2);
     215}
     216
     217#endif