VOGONS


help using Fluidsynth patch with Dosbox 0.74 by clestrade

Topic actions

  • This topic is locked. You cannot reply or edit posts.

First post, by gaula92

User metadata
Rank Newbie
Rank
Newbie

Hello there

I found a nice patch to use libfluidsynth as a MIDI device in Dosbox in the sourceforge project page. It's a simple patch, but I can't get it to compile with 0.74 sources (I had to manually apply it to some files).

I'm getting errors while compiling dosbox, but they have no sense to me. gcc seems to complain about undefined functions that are indeed defined in fluidsynth.h!

This is my src/gui/midi_synth.h

#include "mixer.h"
#include <fluidsynth.h>

extern "C" {
typedef struct _fluid_midi_parser_t fluid_midi_parser_t;

fluid_midi_parser_t *new_fluid_midi_parser(void);
fluid_midi_event_t *fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c);
int delete_fluid_midi_parser(fluid_midi_parser_t* parser);

void fluid_log_config(void);
}

static MixerChannel *synthchan;

static fluid_synth_t *synth_soft;
static fluid_midi_parser_t *synth_parser;

static int synthsamplerate;

static void synth_CallBack (Bitu len) {


fluid_synth_write_s16(synth_soft, len, MixTemp, 0, 2, MixTemp, 1, 2);
synthchan->AddSamples_s16(len,(Bit16s *)MixTemp);
}

static void synth_log(int level, char *message, void *data) {
switch (level) {
case FLUID_PANIC:
case FLUID_ERR:
LOG(LOG_ALL,LOG_ERROR)(message);
break;

case FLUID_WARN:
LOG(LOG_ALL,LOG_WARN)(message);
break;

default:
LOG(LOG_ALL,LOG_NORMAL)(message);
break;
}
}


class MidiHandler_synth: public MidiHandler {

private:
fluid_settings_t *settings;
fluid_midi_router_t *router;
int sfont_id;
bool isOpen;

public:

MidiHandler_synth() : isOpen(false),MidiHandler() {};
char * GetName(void) { return "synth"; };
bool Open(const char *conf) {

/* Sound font file required */
Show last 114 lines
		if (!conf || (conf[0] == '\0')) {
LOG_MSG("SYNTH: Specify .SF2 sound font file with config=");
return false;
}

fluid_log_config();
fluid_set_log_function(FLUID_PANIC, synth_log, NULL);
fluid_set_log_function(FLUID_ERR, synth_log, NULL);
fluid_set_log_function(FLUID_WARN, synth_log, NULL);
fluid_set_log_function(FLUID_INFO, synth_log, NULL);
fluid_set_log_function(FLUID_DBG, synth_log, NULL);

/* Create the settings. */
settings = new_fluid_settings();
if (settings == NULL) {
LOG_MSG("SYNTH: Error allocating MIDI soft synth settings");
return false;
}

fluid_settings_setstr(settings, "audio.sample-format", "16bits");

if (synthsamplerate == 0) {
synthsamplerate = 44100;
}

fluid_settings_setnum(settings,
"synth.sample-rate", (double)synthsamplerate);

/* Create the synthesizer. */
synth_soft = new_fluid_synth(settings);
if (synth_soft == NULL) {
LOG_MSG("SYNTH: Error initialising MIDI soft synth");
delete_fluid_settings(settings);
return false;
}

/* Load a SoundFont */
sfont_id = fluid_synth_sfload(synth_soft, conf, 0);
if (sfont_id == -1) {
LOG_MSG("SYNTH: Failed to load MIDI sound font file \"%s\"",
conf);
delete_fluid_synth(synth_soft);
delete_fluid_settings(settings);
return false;
}

/* Allocate one event to store the input data */
synth_parser = new_fluid_midi_parser();
if (synth_parser == NULL) {
LOG_MSG("SYNTH: Failed to allocate MIDI parser");
delete_fluid_synth(synth_soft);
delete_fluid_settings(settings);
return false;
}

router = new_fluid_midi_router(settings,
fluid_synth_handle_midi_event,
(void*)synth_soft);
if (router == NULL) {
LOG_MSG("SYNTH: Failed to initialise MIDI router");
delete_fluid_midi_parser(synth_parser);
delete_fluid_synth(synth_soft);
delete_fluid_settings(settings);
return false;
}

synthchan=MIXER_AddChannel(synth_CallBack, synthsamplerate, "SYNTH");
synthchan->Enable(false);
isOpen = true;
return true;
};
void Close(void) {
if (!isOpen) return;
delete_fluid_midi_router(router);
delete_fluid_midi_parser(synth_parser);
delete_fluid_synth(synth_soft);
delete_fluid_settings(settings);
isOpen=false;
};
void PlayMsg(Bit8u *msg) {
fluid_midi_event_t *evt;
Bitu len;
int i;

len=MIDI_evt_len[*msg];
synthchan->Enable(true);

/* let the parser convert the data into events */
for (i = 0; i < len; i++) {
evt = fluid_midi_parser_parse(synth_parser, msg[i]);
if (evt != NULL) {
/* send the event to the next link in the chain */
fluid_midi_router_handle_midi_event(router, evt);
}
}
};
void PlaySysex(Bit8u *sysex, Bitu len) {
fluid_midi_event_t *evt;
int i;

/* let the parser convert the data into events */
for (i = 0; i < len; i++) {
evt = fluid_midi_parser_parse(synth_parser, sysex[i]);
if (evt != NULL) {
/* send the event to the next link in the chain */
fluid_midi_router_handle_midi_event(router, evt);
}
}
};
};

MidiHandler_synth Midi_synth;

And this is the kind of errors GCC is throwing at me:


make[3]: Entering directory `/usr/src/dos/dosbox-0.74-fluidsynth/src'
g++ -g -O2 -o dosbox dosbox.o cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a -lSDL_sound -lSDL -lpthread -lpng -lz -lSDL_net -lX11 -lGL
gui/libgui.a(midi.o): In function `synth_CallBack':
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:24: undefined reference to `fluid_synth_write_s16'
gui/libgui.a(midi.o): In function `MidiHandler_synth::PlaySysex(unsigned char*, unsigned int)':
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:163: undefined reference to `fluid_midi_parser_parse'
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:166: undefined reference to `fluid_midi_router_handle_midi_event'
gui/libgui.a(midi.o): In function `MidiHandler_synth::PlayMsg(unsigned char*)':
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:150: undefined reference to `fluid_midi_parser_parse'
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:153: undefined reference to `fluid_midi_router_handle_midi_event'
gui/libgui.a(midi.o): In function `MidiHandler_synth::Close()':
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:134: undefined reference to `delete_fluid_midi_router'
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:135: undefined reference to `delete_fluid_midi_parser'
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:136: undefined reference to `delete_fluid_synth'
/usr/src/dos/dosbox-0.74-fluidsynth/src/gui/midi_synth.h:137: undefined reference to `delete_fluid_settings'

Can someone please help me fixing my midi_synth.h file so it compiles and works?

regards

Reply 1 of 16, by HunterZ

User metadata
Rank l33t++
Rank
l33t++

I don't see those functions/methods defined in the .h file that you posted, but I see them being called there.

Your gcc output doesn't show any fluid libraries being linked. My guess is that you've patched in glue code that is meant to bridge fluidsynth to DOSBox, but that you're not linking in the actual fluidsynth implementation itself. In other words, you're missing a library or source code for fluidsynth that contains the implementation the missing functions/methods.

Edit: Also, if you're running under Linux or MacOS you can probably run fluidsynth standalone as a system MIDI device and then direct stock DOSBox to use it via dosbox.conf, no messing with code required.

Reply 2 of 16, by gaula92

User metadata
Rank Newbie
Rank
Newbie

I fixed it. I just needed to add the necessary -lfluidsynth parameter in the Makefile (since the configure script doesn't have an option to add it).
I also had to tweak src/misc/setup.cpp, since bool Prop_string::CheckValue insisted in saying my mididevice=synth entry in prince2.conf wasn't a valid value 😁

You should listen Prince Of Persia 2 with Airfont380 Final... it's just AWESOME 😁

The solution you sugested is not valid for me: my kernel doesn't have alsa midi sequencer enabled, and I think fluidsynth is better run from within dosbox so I can run dosbox with realtime priority and forget about fluidsynth's priority outside it.
And yes, I'm on Linux.

Would you please add Fluidsynth midi device into DOSBOX baseline?
Scummvm does indeed use it with very god results, and I can tell you it belongs in DOSBOX too 😀

Reply 3 of 16, by HunterZ

User metadata
Rank l33t++
Rank
l33t++

I'm just forum staff, not a DOSBox developer. I think it's a reasonable idea, but the DOSBox devs are much more conservative about what gets added to the base build.

You should make a recording of PoP2 and post it... I gave up on playing with softsynths around 5 years ago after I bought real SC-88 and MT-32 synthesizers from eBay, but it's still fun to listen to what other people come up with 😀

Reply 4 of 16, by Yushatak

User metadata
Rank Member
Rank
Member

Quite an understatement. We've got pretty good glide wrapper implementations for DOSBox, MT-32 support, LPT passthrough, NE2000 emulation passthrough (I understand it's not crossplatform, but it could be made to be) and all of this isn't integrated due to their views. I'm glad there are private builds of DOSBox like gulikoza's, ykhwong's, and H-A-L-9000's to rectify this.

If you're unable to convince the base devs to integrate your found patch, you might persuade one of the above mentioned builds to integrate it.

~Yushatak

I'm notorious for repeatedly editing posts, so please excuse me if new information just pops up while you're writing your post... xD

Reply 8 of 16, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

I was quite an advocate for fluidsynth until I looked at the hooror of needed libs to get fluidsynth running. This horror of libs would bloat an OS X release of Dosbox a lot, if it even were doable to build a static Dosbox with all the libs fluidsynth drags in.
And wd is right about the other mentioned stuff. None of those are in a state I would like to implement into dosbox, especially non-cross platform stuff is a no go...
Btw. Dosbox DOES have good Mt32 support (nitpicking, yes, but true) 😉

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox

Reply 10 of 16, by Yushatak

User metadata
Rank Member
Rank
Member

I wasn't trying to piss anybody off, just stating my opinion and observation.

NE2000 support is quite integral to some games if they don't use IPX or if you wish to network with a non-DOSBox machine, and Glide is definitely game-related (though I know there's a memory leak issue with the currently distributed implementation, it could be fixed were it targeted as a proper addition to DOSBox).

As you are likely aware of, DOSBox is also used (whether intended or no) as a general replacement for NTVDM on 64-bit systems. In this regard, NE2000 support and LPT redirection are quite helpful.

~Yushatak

I'm notorious for repeatedly editing posts, so please excuse me if new information just pops up while you're writing your post... xD

Reply 14 of 16, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

Yes, it's pedantic but it really is something different, mt32 support and mt32. Especially if you are on OS X since on that mt32 support is not as old as on Windows (perhaps only since 0.73). And if you have that in mind such a confusion is too good to let it pass...

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox

Reply 15 of 16, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

munt is far from finished, though the work is highly respected due to the complexity.

as a general replacement for NTVDM on 64-bit systems. In this regard, NE2000 support and LPT redirection are quite helpful.

I don't care if you use it as a NTVDM replacement.