Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sfMidi 1.1 - Play MIDI in SFML  (Read 22370 times)

0 Members and 1 Guest are viewing this topic.

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
sfMidi - Play MIDI in SFML
« Reply #15 on: February 25, 2012, 06:26:53 pm »
About openal32, yes, I should need this, I left it out by accident (same goes to libsndfile actually, I only realized this when I tried to test it just now), but for openal32, there's a possibility that it is in a directory in PATH, but it shouldn't be the case for libfluidsynth, since I'm quite positive that I do not have it in any PATH directory, and my sister wouldn't even have such dll on her computer.

I link to SFML dynamically.


Edit:
Ah, I know what's going on now, there's a flaw in my test program, probably due to compiler optimization or so. If I put if (false), the compiler probably removed all the code under it, since I would never reach there, however, if I put if (static_cast<unsigned int>(time(NULL)) < 1000), which would almost always be false, obviously, but since there is a possibility that it may be true, so the compiler does not remove the code under it, and I get the missing dll error. I can also avoid the compiler optimization by compiling under debug, or just disable it, so it's my mistake that I did not tried testing under debug.

As for openal32.dll and libsndfile-1.dll, I found that they're in my PATH variable, under MinGW. That explains why.

Anyway, thanks for clearing this up for me, seems like we have to be careful of compiler optimization.

Now time to add the 2 missing dlls into the example files. >.<

On the other hand, have you thought of integrating sfMod? It relies on libmodplug, but libmodplug is under public domain, and I have it statically linked (no, actually I just added the source files into the sfMod project). It would be great if SFML supports module files natively. Also sfMod is a cleaner piece of code than sfMidi, without all the workarounds since everything I need is available in libmodplug.

greeniekin

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
sfMidi - Play MIDI in SFML
« Reply #16 on: March 02, 2012, 04:13:06 am »
This is something I thought mentioning.

There is a library called rtMidi. The license is not restrictive. Apart from if there are any changes to rtMidi post them to the creator. It does not synthesise but deals with receiving and sending midi messages. Which would make seeking, pausing and dynamic music easy. With no large sound fonts.

On windows this means you can use the built in midi synth. Which actually sounds pretty good.

On linux of course the problem is linux can have nothing. There are packages that give midi synth and that can be installed and it should work.

Mac I have no idea about. Well they can always plug into an external synth ><.

Obviously your method has less requirements(regarding operating system). Code reuse from sfml sound would not really be an issue as very little code is need to make rtMidi work.

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
sfMidi - Play MIDI in SFML
« Reply #17 on: March 02, 2012, 05:21:33 am »
Yes, I am aware of that library.

But it seems to me that it does not support loading .mid files. It's only handles midi input and output, but not actually loading the files. At least I can't find anything about loading midi files on the website.

Also, one of the main reason I chose Fluidsynth, was for the SoundFont 2 support. It was meant to rely on sound fonts.

On the other hand, I found another 2 libraries, PortMidi, and PortSMF, one for realtime midi i/o, probably like rtMidi, one for midi file i/o.
Perhaps I can add this into sfMidi as an option to play Midi files without sound fonts.

greeniekin

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
sfMidi - Play MIDI in SFML
« Reply #18 on: March 02, 2012, 02:07:46 pm »
That is true. It does not have support for loading midi files.
I do think your current method is better for just playing midi files. More reliable cross platform.

I had not heard of portMidi.
They look like really good libraries.
The license may actually better. In that your not required to send changes back to the creator.

Plus the fact that it can be used with portsmf(midi file reader/writer/data-structure) and scorealign(aligning audo and midi). plus the portmedia project which these are apart of has stuff for audio api and vidio api.

I know you know this zorexx. Just wanted to mention this for other readers.

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
sfMidi - Play MIDI in SFML
« Reply #19 on: March 02, 2012, 03:54:15 pm »
Ok, I will look into PortMidi when I manage to find the time to do so.  :D

Tenry

  • Full Member
  • ***
  • Posts: 120
  • Experienced Programmer
    • View Profile
    • Simon-Burchert.com
sfMidi - Play MIDI in SFML
« Reply #20 on: March 11, 2012, 03:57:53 pm »
I am getting undefined reference errors, even though I am linking to the sfMidi library :(


My .bat file:
Code: [Select]
g++ -o main.o -c main.cpp -IsfMidi-1.0/include -ID:/dev/SFML-1.6/include
g++ -o test.exe main.o -LsfMidi-1.0/lib -LD:/dev/SFML-1.6/lib -lsfMidi -lsfml-audio
@pause


some error messages:
Quote
undefined reference to `sfMidi::Midi::Midi()'
undefined reference to `sfMidi::Midi::LoadMidiFromFile(std::string const&)'
Please note that my previous display name was "Shy Guy".

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
sfMidi - Play MIDI in SFML
« Reply #21 on: March 11, 2012, 05:17:34 pm »
The compiled libs I provided are compiled with SFML 2 and will not work with SFML1.6. You'll have to recompile them yourself.

I also realize that there was a bug when compiling with SFML1.6, so I fixed it and uploaded it as version 1.0.2.

I also compiled a SFML1.6 version for you:
http://www.zorexxlkl/files/downloads/sfMidi-1.0.2-sfml1.6.zip

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #22 on: April 05, 2012, 07:35:11 am »
I'm finally done adapting sfMidi to the latest SFML naming conventions.

I also added a new error handling system (the same one as sfTheora and sfMod).

Dropped SFML 1.6 support as well, since SFML 2.0 will be released as a stable version soon.

See the changelog for the full list of changes.

On a side note, about PortMidi, I've decided to not implement it in sfMidi.
However, there is a chance that I will write another library (sfPortMidi), which will utilize PortMidi.
The main reason is because things will get pretty confusing and/or messy if I introduce PortMidi into sfMidi.
There will be 2 Midi classes, one which uses FluidSynth, and another which uses PortMidi, thus, a name clash (2 Midi classes).
I thought of renaming the current Midi class to SfMidi (SoundFont Midi), but then that will cause confusion in the Music and Loader classes.
I also thought of using the same class, and if you don't load a SoundFont, it will use PortMidi, otherwise it will use FluidSynth, but then every function will have to check if a SoundFont is loaded, then decide what to do, which will create some unnecessary overhead.
Either way, there isn't a clean and simple way to introduce PortMidi in sfMidi.
Hence, I will either drop it or write a new library.
If I do have the time to do so, I will try to write sfPortMidi, but I can't promise anything.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #23 on: April 05, 2012, 09:11:48 am »
I also thought of using the same class, and if you don't load a SoundFont, it will use PortMidi, otherwise it will use FluidSynth, but then every function will have to check if a SoundFont is loaded, then decide what to do, which will create some unnecessary overhead.
While I have no idea about the MIDI libraries you've mentioned (actually MIDI at all), wouldn't it be possible to write an interface providing the necessary operations, that actually points to a class of one library? So the frontend code would just call virtual functions, no case differentiations are necessary.

This design is often used, for example in 3D graphic engines to implement OpenGL and DirectX backends or in SFML to abstract platform-dependent code.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #24 on: April 05, 2012, 09:32:45 am »
I'm not sure if I understand exactly what you mean, but how does that solve the problem of differentiation being necessary. Since one library requires SoundFonts to work while the other does not, even if the user don't have to choose between which to use, the internal code will still have to do so somewhere.

Also, since probably nobody will ever use both in the same project (to use SoundFont and to not), there shouldn't be have both in the same library (forcing the user to include both dlls, or recompiling them without either 1).

To my understanding, SFML to abstract platform-dependant code is done during compile time, meaning that it will adapt to whichever platform it is compiled on, not run on, so once it's compiled, it no longer needs to differentiate between which backend to use.
However, in sfMidi's case, sfMidi will have to decide which backend to use depending on whether the programmer provides SoundFont or not, the user may end up using both backends in 1 project for all we know.

Hence, in this case, it would be much better to provide 2 separate libraries.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #25 on: April 05, 2012, 09:39:39 am »
I think he was referring to this kind of solution:

class MidiBackend
{
    // whatever is required as virtual functions
};

class FluidSynthBackend : public MidiBackend
{
    // implement virtual functions
};

class PortMidiBackend : public MidiBackend
{
    // implement virtual functions
};

class sfMidi
{
public:

    void loadFromFile(std::string filename)
    {
        delete m_backend;
        m_backend = new PortMidiBackend(filename);
        ...
    }

    void loadFromFile(std::string filename, std::string soundfont)
    {
        delete m_backend;
        m_backend = new FluidSynthBackend(filename, soundfont);
        ...
    }

private:

    MidiBackend* m_backend;
};
Laurent Gomila - SFML developer

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #26 on: April 05, 2012, 09:47:42 am »
Oh right, I was stuck with the thought that I have to provide a loadSoundFontFromFile function.
But I do think that function is pretty important, since SoundFonts are reusable, you can unload the midi file and load another midi file without having to reload the SoundFont, and this is pretty important because SoundFont takes a long time to load.

I still think it's cleaner to separate it into 2 libraries, since they work quite differently, and then again there is the multiple dlls problem.
It will also make things easier to manage in the future.  :)

Edit: Actually, I just realize my first point (in this reply) doesn't change anything since I could make the decision of which backend to use when the loadMidiFromFile function is called, but I still don't see why I should not separate them into 2 libraries.
« Last Edit: April 05, 2012, 09:49:24 am by zorexx »

Tenry

  • Full Member
  • ***
  • Posts: 120
  • Experienced Programmer
    • View Profile
    • Simon-Burchert.com
Re: sfMidi - Play MIDI in SFML
« Reply #27 on: April 10, 2012, 07:05:36 pm »
The compiled libs I provided are compiled with SFML 2 and will not work with SFML1.6. You'll have to recompile them yourself.

I also realize that there was a bug when compiling with SFML1.6, so I fixed it and uploaded it as version 1.0.2.

I also compiled a SFML1.6 version for you:
http://www.zorexxlkl/files/downloads/sfMidi-1.0.2-sfml1.6.zip

I've switched to SFML 2.0 and downloaded sfMidi 1.1. Still undefined references :(

midiTest>midiTest>g++ -c main.cpp -o main.o -IsfMidi-1.1/include -ID:/dev/SFML-2.0/include

midiTest>g++ main.o -o test.exe -LsfMidi-1.1/lib -LD:/dev/SFML-2.0/lib -lsfMidi -lsfml-audio
main.o:main.cpp:(.text+0x1b): undefined reference to `sfmidi::Midi::Midi()'
main.o:main.cpp:(.text+0x57): undefined reference to `sfmidi::Midi::loadMidiFrom
File(std::string const&)'
main.o:main.cpp:(.text+0x93): undefined reference to `sfmidi::Midi::play()'
main.o:main.cpp:(.text+0xc1): undefined reference to `sfmidi::Midi::~Midi()'
main.o:main.cpp:(.text+0xdd): undefined reference to `sfmidi::Midi::~Midi()'
collect2: ld returned 1 exit status
Please note that my previous display name was "Shy Guy".

zorexx

  • Full Member
  • ***
  • Posts: 109
    • View Profile
    • zorexx@site
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #28 on: April 11, 2012, 05:05:03 am »
Oh, I didn't realize you were using g++ earlier. >.<
Since the libraries were compiled under MSVC++, I don't think it'll work for g++.
g++ uses libraries which are under the extension .a if I remember correctly. MSVC++ uses .lib files.

Have you tried the CMake version of sfMidi?

Tenry

  • Full Member
  • ***
  • Posts: 120
  • Experienced Programmer
    • View Profile
    • Simon-Burchert.com
Re: sfMidi 1.1 - Play MIDI in SFML
« Reply #29 on: April 11, 2012, 03:22:04 pm »
Oh, I didn't realize you were using g++ earlier. >.<
Since the libraries were compiled under MSVC++, I don't think it'll work for g++.
g++ uses libraries which are under the extension .a if I remember correctly. MSVC++ uses .lib files.

Have you tried the CMake version of sfMidi?
Okay, that's the reason I think. There's another object oriented library compiled with MSVC++, and the oo code only works with MSVC++. Other users have to use the C style version without any classes :(

I tried cmake and everything seems fine. But for compiling I finally need fluidsynth, right?
I never got fluidsynth compiled yet (and there seems not to be a precompiled version), and even with just having the header files only on my system sfMidi can't locate fluidsynth.h >.<

error: fluidsynth.h: No such file or directory

I put the includes to D:/dev/fluidsynth-1.1.5/include and rebuilt everything with cmake before compiling. Nothing changed :(
Please note that my previous display name was "Shy Guy".