Merge lp:~mgiuca/dosbox/fluidsynth into lp:~mgiuca/dosbox/trunk

Proposed by Matt Giuca
Status: Needs review
Proposed branch: lp:~mgiuca/dosbox/fluidsynth
Merge into: lp:~mgiuca/dosbox/trunk
Diff against target: 335 lines (+278/-2)
5 files modified
acinclude.m4 (+120/-0)
configure.in (+13/-0)
src/dosbox.cpp (+2/-2)
src/gui/midi.cpp (+6/-0)
src/gui/midi_fluidsynth.h (+137/-0)
To merge this branch: bzr merge lp:~mgiuca/dosbox/fluidsynth
Reviewer Review Type Date Requested Status
Matt Giuca Pending
Review via email: mp+96296@code.launchpad.net

Commit message

Added a new MIDI driver 'fluidsynth', for DOSBox to send MIDI commands directly to the FluidSynth API.

Description of the change

Added a new MIDI driver 'fluidsynth', which allows DOSBox's MPU-401 MIDI system to talk directly to the FluidSynth software synthesiser API, rather than sending MIDI commands to the system.

This provides a reliable software synthesiser back-end for DOSBox without having to manually set up a FluidSynth server and work out the correct ALSA port.

To post a comment you must log in.

Unmerged revisions

3696. By Matt Giuca

midi: Move FluidSynth to the top, so it is searched last when searching for the default driver.

3695. By Matt Giuca

midi_fluidsynth: Formatting to conform to DOSBox coding style.

3694. By Matt Giuca

midi_fluidsynth: The 'midiconfig' for this driver now contains the driver:soundfont pair separated by a colon.
This allows the user to specify the FluidSynth audio driver; it is no longer hard-coded to alsa.

3693. By Matt Giuca

midi_fluidsynth: Implemented PlaySysex and PlayMsg.
MIDI messages are now routed through to the FluidSynth API, so it all works.

3692. By Matt Giuca

midi_fluidsynth: Implemented Open and Close.
Now creates and destroys the FluidSynth driver, loading the soundfont from midiconfig.

3691. By Matt Giuca

gui/midi: Only include fluidsynth driver if HAVE_FLUID is defined.

3690. By Matt Giuca

Added FluidSynth to build scripts.

3689. By Matt Giuca

Added fluidsynth as a type of mididevice.
Currently just stubs (logs all method calls).

3688. By qbix79

Add patch 3461824: Readme fixes by clem

3687. By qbix79

Add cmd-q => exit for Mac OS X

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'acinclude.m4'
--- acinclude.m4 2011-04-26 09:34:55 +0000
+++ acinclude.m4 2012-03-07 05:50:24 +0000
@@ -303,6 +303,126 @@
303AC_SUBST(ALSA_LIBS)303AC_SUBST(ALSA_LIBS)
304])304])
305305
306dnl Configure Paths for FluidSynth
307dnl Modified from the ALSA code above by Matt Giuca <matt.giuca@gmail.com>
308dnl Test for libfluidsynth, and define FLUID_CFLAGS and FLUID_LIBS as
309dnl appropriate.
310dnl AM_PATH_FLUID([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
311dnl enables arguments --with-fluid-prefix=
312dnl --with-fluid-inc-prefix=
313dnl
314dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
315dnl and the FluidSynth libraries are not found, a fatal AC_MSG_ERROR() will
316dnl result.
317dnl
318AC_DEFUN([AM_PATH_FLUID],
319[dnl Save the original CFLAGS, LDFLAGS, and LIBS
320fluid_save_CFLAGS="$CFLAGS"
321fluid_save_LDFLAGS="$LDFLAGS"
322fluid_save_LIBS="$LIBS"
323fluid_found=yes
324
325dnl
326dnl Get the cflags and libraries for fluidsynth
327dnl
328AC_ARG_WITH(fluid-prefix,
329[ --with-fluid-prefix=PFX Prefix where FluidSynth library is installed (optional)],
330[fluid_prefix="$withval"], [fluid_prefix=""])
331
332AC_ARG_WITH(fluid-inc-prefix,
333[ --with-fluid-inc-prefix=PFX Prefix where include libraries are (optional)],
334[fluid_inc_prefix="$withval"], [fluid_inc_prefix=""])
335
336dnl Add any special include directories
337AC_MSG_CHECKING(for FluidSynth CFLAGS)
338if test "$fluid_inc_prefix" != "" ; then
339 FLUID_CFLAGS="$FLUID_CFLAGS -I$fluid_inc_prefix"
340 CFLAGS="$CFLAGS -I$fluid_inc_prefix"
341fi
342AC_MSG_RESULT($FLUID_CFLAGS)
343
344dnl add any special lib dirs
345AC_MSG_CHECKING(for FluidSynth LDFLAGS)
346if test "$fluid_prefix" != "" ; then
347 FLUID_LIBS="$FLUID_LIBS -L$fluid_prefix"
348 LDFLAGS="$LDFLAGS $FLUID_LIBS"
349fi
350
351dnl add the fluidsynth library
352FLUID_LIBS="$FLUID_LIBS -lfluidsynth"
353LIBS="$FLUID_LIBS $LIBS"
354AC_MSG_RESULT($FLUID_LIBS)
355
356dnl Check for a working version of libfluidsynth that is of the right version.
357min_fluid_version=ifelse([$1], ,1.1.2,$1)
358AC_MSG_CHECKING(for libfluidsynth headers version >= $min_fluid_version)
359no_fluid=""
360 fluid_min_major_version=`echo $min_fluid_version | \
361 sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
362 fluid_min_minor_version=`echo $min_fluid_version | \
363 sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
364 fluid_min_micro_version=`echo $min_fluid_version | \
365 sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
366
367AC_LANG_SAVE
368AC_LANG_C
369AC_TRY_COMPILE([
370#include <fluidsynth.h>
371], [
372# if(FLUIDSYNTH_VERSION_MAJOR > $fluid_min_major_version)
373 exit(0);
374# else
375# if(FLUIDSYNTH_VERSION_MAJOR < $fluid_min_major_version)
376# error not present
377# endif
378
379# if(FLUIDSYNTH_VERSION_MINOR > $fluid_min_minor_version)
380 exit(0);
381# else
382# if(FLUIDSYNTH_VERSION_MINOR < $fluid_min_minor_version)
383# error not present
384# endif
385
386# if(FLUIDSYNTH_VERSION_MICRO < $fluid_min_micro_version)
387# error not present
388# endif
389# endif
390# endif
391exit(0);
392],
393 [AC_MSG_RESULT(found.)],
394 [AC_MSG_RESULT(not present.)
395 ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libfluidsynth not found.)])
396 fluid_found=no]
397)
398AC_LANG_RESTORE
399
400dnl Now that we know that we have the right version, let's see if we have the library and not just the headers.
401AC_CHECK_LIB([fluidsynth], [new_fluid_synth],,
402 [ifelse([$3], , [AC_MSG_ERROR(No linkable libfluidsynth was found.)])
403 fluid_found=no]
404)
405
406if test "x$fluid_found" = "xyes" ; then
407 ifelse([$2], , :, [$2])
408 LIBS=`echo $LIBS | sed 's/-lfluidsynth//g'`
409 LIBS=`echo $LIBS | sed 's/ //'`
410 LIBS="-lfluidsynth $LIBS"
411fi
412if test "x$fluid_found" = "xno" ; then
413 ifelse([$3], , :, [$3])
414 CFLAGS="$fluid_save_CFLAGS"
415 LDFLAGS="$fluid_save_LDFLAGS"
416 LIBS="$fluid_save_LIBS"
417 FLUID_CFLAGS=""
418 FLUID_LIBS=""
419fi
420
421dnl That should be it. Now just export out symbols:
422AC_SUBST(FLUID_CFLAGS)
423AC_SUBST(FLUID_LIBS)
424])
425
306AH_TOP([426AH_TOP([
307/*427/*
308 * Copyright (C) 2002-2011 The DOSBox Team428 * Copyright (C) 2002-2011 The DOSBox Team
309429
=== modified file 'configure.in'
--- configure.in 2011-06-12 13:58:27 +0000
+++ configure.in 2012-03-07 05:50:24 +0000
@@ -182,6 +182,19 @@
182 CXXFLAGS="$CXXFLAGS $ALSA_CFLAGS"182 CXXFLAGS="$CXXFLAGS $ALSA_CFLAGS"
183fi183fi
184184
185dnl enable disable fluidsynth and pass it's cflags to CXXFLAGS
186AC_ARG_ENABLE(fluidsynth-midi,
187AC_HELP_STRING([--enable-fluidsynth-midi],[compile with fluidsynth midi support (default yes)]),
188[ case "${enableval}" in
189 yes) fluid_midi=true;;
190 no) fluid_midi=false;;
191esac],
192[fluid_midi=true])
193if test x$fluid_midi = xtrue ; then
194 AM_PATH_FLUID(1.1.2, AC_DEFINE(HAVE_FLUID,1,[Define to 1 to use FluidSynth for MIDI]) , : )
195 CXXFLAGS="$CXXFLAGS $FLUID_CFLAGS"
196fi
197
185#Check for big endian machine, should #define WORDS_BIGENDIAN if so198#Check for big endian machine, should #define WORDS_BIGENDIAN if so
186AC_C_BIGENDIAN199AC_C_BIGENDIAN
187200
188201
=== modified file 'src/dosbox.cpp'
--- src/dosbox.cpp 2011-11-01 17:00:19 +0000
+++ src/dosbox.cpp 2012-03-07 05:50:24 +0000
@@ -480,7 +480,7 @@
480 480
481 const char* mputypes[] = { "intelligent", "uart", "none",0};481 const char* mputypes[] = { "intelligent", "uart", "none",0};
482 // FIXME: add some way to offer the actually available choices.482 // FIXME: add some way to offer the actually available choices.
483 const char *devices[] = { "default", "win32", "alsa", "oss", "coreaudio", "coremidi","none", 0};483 const char *devices[] = { "default", "win32", "alsa", "oss", "fluidsynth", "coreaudio", "coremidi","none", 0};
484 Pstring = secprop->Add_string("mpu401",Property::Changeable::WhenIdle,"intelligent");484 Pstring = secprop->Add_string("mpu401",Property::Changeable::WhenIdle,"intelligent");
485 Pstring->Set_values(mputypes);485 Pstring->Set_values(mputypes);
486 Pstring->Set_help("Type of MPU-401 to emulate.");486 Pstring->Set_help("Type of MPU-401 to emulate.");
@@ -491,7 +491,7 @@
491491
492 Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,"");492 Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,"");
493 Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n"493 Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n"
494 " or in the case of coreaudio, you can specify a soundfont here.\n"494 " or in the case of coreaudio or fluidsynth, you can specify a soundfont here.\n"
495 " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n"495 " When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n"
496 " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n"496 " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n"
497 " See the README/Manual for more details.");497 " See the README/Manual for more details.");
498498
=== modified file 'src/gui/midi.cpp'
--- src/gui/midi.cpp 2011-04-26 09:34:55 +0000
+++ src/gui/midi.cpp 2012-03-07 05:50:24 +0000
@@ -82,6 +82,12 @@
8282
83/* Include different midi drivers, lowest ones get checked first for default */83/* Include different midi drivers, lowest ones get checked first for default */
8484
85#if defined (HAVE_FLUID)
86
87#include "midi_fluidsynth.h"
88
89#endif
90
85#if defined(MACOSX)91#if defined(MACOSX)
8692
87#include "midi_coremidi.h"93#include "midi_coremidi.h"
8894
=== added file 'src/gui/midi_fluidsynth.h'
--- src/gui/midi_fluidsynth.h 1970-01-01 00:00:00 +0000
+++ src/gui/midi_fluidsynth.h 2012-03-07 05:50:24 +0000
@@ -0,0 +1,137 @@
1/*
2 * Copyright (C) 2002-2011 The DOSBox Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (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
19#include <fluidsynth.h>
20#include <ctype.h>
21#include <string>
22#include <sstream>
23
24class MidiHandler_fluidsynth : public MidiHandler {
25private:
26 std::string audio_driver;
27 std::string soundfont;
28 int soundfont_id;
29 fluid_settings_t *settings;
30 fluid_synth_t *synth;
31 fluid_audio_driver_t* adriver;
32public:
33 MidiHandler_fluidsynth() : MidiHandler() {};
34 const char* GetName(void) { return "fluidsynth"; }
35 void PlaySysex(Bit8u * sysex,Bitu len) {
36 fluid_synth_sysex(synth, (char*) sysex, len, NULL, NULL, NULL, 0);
37 }
38
39 void PlayMsg(Bit8u * msg) {
40 unsigned char chanID = msg[0] & 0x0F;
41 switch (msg[0] & 0xF0) {
42 case 0x80:
43 fluid_synth_noteoff(synth, chanID, msg[1]);
44 break;
45 case 0x90:
46 fluid_synth_noteon(synth, chanID, msg[1], msg[2]);
47 break;
48 case 0xB0:
49 fluid_synth_cc(synth, chanID, msg[1], msg[2]);
50 break;
51 case 0xC0:
52 fluid_synth_program_change(synth, chanID, msg[1]);
53 break;
54 case 0xD0:
55 fluid_synth_channel_pressure(synth, chanID, msg[1]);
56 break;
57 case 0xE0:{
58 long theBend = ((long)msg[1] + (long)(msg[2] << 7));
59 fluid_synth_pitch_bend(synth, chanID, theBend);
60 }
61 break;
62 default:
63 LOG(LOG_MISC,LOG_WARN)("MIDI:fluidsynth: Unknown Command: %08lx", (long)msg);
64 break;
65 }
66 }
67
68 void Close(void) {
69 if (soundfont_id >= 0) {
70 fluid_synth_sfunload(synth, soundfont_id, 0);
71 }
72 delete_fluid_audio_driver(adriver);
73 delete_fluid_synth(synth);
74 delete_fluid_settings(settings);
75 }
76
77 bool Open(const char * conf) {
78 /* The 'midiconfig' for the fluidsynth driver is a string of the
79 * following format:
80 * audio_driver:soundfont
81 * The audio_driver is the name of the FluidSynth audio driver (e.g.,
82 * "jack" or "alsa"). The soundfont is the filename to the soundfont
83 * to load.
84 * If there is no colon, the whole string is the driver, and no
85 * soundfont is loaded. If midiconfig is missing or empty, the driver
86 * is the default.
87 */
88 if (conf && conf[0]) {
89 std::string conf_str(conf);
90 size_t delim_pos = conf_str.find(':');
91 if (delim_pos == std::string::npos) {
92 /* No colon; whole string is driver */
93 audio_driver = conf_str;
94 } else {
95 /* Split string based on position of colon */
96 audio_driver.assign(conf_str, 0, delim_pos);
97 soundfont.assign(conf_str.c_str() + delim_pos + 1);
98 }
99 }
100 settings = new_fluid_settings();
101 if (!audio_driver.empty()) {
102 fluid_settings_setstr(settings, "audio.driver", audio_driver.c_str());
103 }
104 synth = new_fluid_synth(settings);
105 if (!synth) {
106 LOG_MSG("MIDI:fluidsynth: Can't open synthesiser");
107 delete_fluid_settings(settings);
108 return false;
109 }
110 adriver = new_fluid_audio_driver(settings, synth);
111 if (!adriver) {
112 LOG_MSG("MIDI:fluidsynth: Can't create audio driver");
113 delete_fluid_synth(synth);
114 delete_fluid_settings(settings);
115 return false;
116 }
117
118 /* Optionally load a soundfont */
119 if (!soundfont.empty()) {
120 soundfont_id = fluid_synth_sfload(synth, soundfont.c_str(), 1);
121 if (soundfont_id == FLUID_FAILED) {
122 /* Just consider this a warning (fluidsynth already prints) */
123 soundfont.clear();
124 soundfont_id = -1;
125 } else {
126 LOG_MSG("MIDI:fluidsynth: loaded soundfont: %s",
127 soundfont.c_str());
128 }
129 } else {
130 soundfont_id = -1;
131 LOG_MSG("MIDI:fluidsynth: no soundfont loaded");
132 }
133 return true;
134 }
135};
136
137MidiHandler_fluidsynth Midi_fluidsynth;

Subscribers

People subscribed via source and target branches

to all changes: